Release v0.3.1: Critical Bug Fixes
CANNS-Ripser v0.3.1 - Critical Bug Fixes
This release addresses two major stability issues that were causing problems in cocycle computation.
π§ Critical Bug Fixes
β Matrix Reduction Infinite Loop (CRITICAL)
Problem: Matrix reduction algorithm entered infinite loops when processing certain topological structures with cocycle computation enabled, causing the program to hang indefinitely.
Root Cause:
- Incorrect modular arithmetic leading to
factor=0situations - HashSet deduplication removing columns necessary for matrix reduction
- H0 edge sorting incompatibility with C++ reference implementation
Solution:
- Implemented proper
modp()function for correct modular arithmetic - Fixed H0 edge sorting to use descending index order (matching C++ behavior)
- Removed problematic HashSet deduplication in
assemble_columns_to_reduce - Updated all coefficient calculations to use robust modular arithmetic
β Empty Cocycle Output (HIGH)
Problem: Cocycle computation appeared to work internally (debug showed correct calculations) but returned empty results to the Python layer.
Root Cause: Python bindings were reading structured cocycle format while the API expected flat format compatible with original ripser.py.
Solution:
- Added
flat_cocycles_by_dimfield toRipsResultsstruct - Updated
copy_results()to populate flat format directly - Modified Python bindings to expose and use flat cocycle format
- Maintained full backward compatibility with ripser.py API
π§ͺ Test Results
All critical test cases now pass:
- 6-point circle (previously infinite loop): β Completes in <1 second with correct cocycles
- 8-point circle (previously empty cocycles): β Returns expected cocycle data
- Core functionality: β Remains stable and accurate
- Sparse matrix support: β Unaffected by changes
- Performance: β No regression in computation speed
ποΈ Implementation Details
- All fixes follow the C++ reference implementation exactly
- Maintains full API compatibility with existing code
- Robust error handling prevents similar issues in the future
- Comprehensive test coverage for regression prevention
π Before vs After
Before v0.3.1:
# This would hang indefinitely
result = canns_ripser.ripser(circle_6pts, do_cocycles=True)
# Program stuck in infinite loop...
# This would return empty cocycles
result = canns_ripser.ripser(circle_8pts, do_cocycles=True)
print(len(result["cocycles"][1])) # Output: 0 βAfter v0.3.1:
# Fast and reliable
result = canns_ripser.ripser(circle_6pts, do_cocycles=True)
print(f"H1 cocycles: {len(result['cocycles'][1])}") # Output: 1 β
# Correct cocycle output
result = canns_ripser.ripser(circle_8pts, do_cocycles=True)
print(len(result["cocycles"][1])) # Output: 1 β
π Upgrade Guide
This is a recommended upgrade for all users, especially those using cocycle computation:
pip install --upgrade canns-ripserBreaking Changes: None - full backward compatibility maintained.
New Features: Reliable cocycle computation for all topological structures.
Full Changelog: v0.3.0...v0.3.1