Skip to content

Releases: Routhleck/canns-lib

Release v0.7.0: Plotting Styles and RatInABox API Parity

19 Jan 09:18

Choose a tag to compare

What's New

🎨 Enhanced Plotting System with Style Presets

  • Flexible plotting style system with three predefined styles: simulation, scientific, and publication
  • Full RatInABox API compatibility for agent parameters and environment plotting
  • New example scripts demonstrating plotting capabilities and API parity

📖 Comprehensive Contribution Guidelines

  • Detailed CONTRIBUTING.md with development setup, code style, and testing procedures
  • Clear pull request process and community guidelines

Major Features / Key Changes

🎨 Plotting Style System

  • Style presets: Three predefined plotting styles (simulation, scientific, publication) for spatial plots with customizable colors, markers, and visual properties
  • Environment plotting: New env.plot_environment() method for visualizing spatial environments
  • Style selection: All plotting functions now support style parameter for consistent visualization across your project
from canns_lib.spatial import Environment, Agent

# Create environment and agent
env = Environment()
agent = Agent(env)

# Plot with different styles
env.plot_environment(style='scientific')  # Clean, publication-ready plots
env.plot_environment(style='simulation')  # Colorful, detailed visualization
env.plot_environment(style='publication') # High-contrast, print-optimized

🗺️ RatInABox API Parity

  • Agent parameter access: Full compatibility with RatInABox API for accessing agent parameters (e.g., agent.dt, agent.speed_mean, agent.speed_std, agent.rotational_velocity_std)
  • Property getters: Direct access to agent configuration without breaking encapsulation
  • API compatibility: Seamless migration path for RatInABox users
from canns_lib.spatial import Agent, Environment

env = Environment()
agent = Agent(env, dt=0.01, speed_mean=0.1)

# Access parameters using RatInABox-compatible API
print(f"Time step: {agent.dt}")
print(f"Speed mean: {agent.speed_mean}")
print(f"Speed std: {agent.speed_std}")

📖 Documentation Improvements

  • CONTRIBUTING.md: Comprehensive 433-line guide covering development environment setup, code style guidelines for Python and Rust, testing requirements, and PR process
  • Community guidelines: Best practices for contributing to the project
  • Updated README: Maintenance badge updated for 2026

New Components Added

  • python/canns_lib/spatial/plotting_styles.py - Plotting style definitions and configuration
  • example/ratinabox_comparison.py - Demonstrates RatInABox API compatibility (271 lines)
  • example/style_comparison.py - Shows all three plotting styles side-by-side (110 lines)
  • tests/test_spatial_api_parity.py - Tests for RatInABox API compatibility (77 lines)
  • CONTRIBUTING.md - Contribution guidelines (433 lines)

Technical Improvements

  • Rust backend enhancements: Added 56 lines to src/spatial/agent.rs for property getter support
  • Python API expansion: Enhanced python/canns_lib/spatial/__init__.py with 205 new lines for plotting and API parity
  • Test coverage: New tests verify API compatibility with RatInABox

Breaking Changes

None - all additions are backward compatible.

Technical Notes

  • The plotting style system is designed to be extensible - custom styles can be defined following the same pattern
  • RatInABox API parity focuses on read-only parameter access; full behavioral compatibility may require additional work
  • All new features include example scripts and tests for verification

Files Added/Modified

  • Added: CONTRIBUTING.md, example/ratinabox_comparison.py, example/style_comparison.py, python/canns_lib/spatial/plotting_styles.py, tests/test_spatial_api_parity.py
  • Modified: README.md, python/canns_lib/spatial/__init__.py, src/spatial/agent.rs
  • Total changes: 8 files changed, 1,301 insertions(+), 12 deletions(-)

Use Cases

  • Researchers: Use publication-ready plotting styles for papers and presentations
  • RatInABox users: Migrate existing code with minimal changes using compatible API
  • Contributors: Follow clear guidelines for contributing to the project
  • Developers: Customize plotting styles for specific visualization needs

Full Changelog: v0.6.5...v0.7.0

Release v0.6.5: Agent API Enhancements and Drift Velocity Demonstrations

30 Dec 13:41

Choose a tag to compare

What's New

🎯 Enhanced Agent API for Easier Property Access

  • New agent.position property getter (alias for agent.pos)
  • Exposed agent.rotational_velocity for advanced motion control
  • Simplified access to agent state without using history dictionary

📖 Comprehensive Drift Velocity Demonstrations

  • New demonstration script showing systematic exploration and motion control
  • Enhanced trajectory comparison with dynamic drift velocity callbacks
  • Expanded documentation with practical usage examples

Major Features / Key Changes

Enhanced Agent Property Access

  • agent.position: New property getter providing clearer semantic access to current position (alias for agent.pos)
  • agent.rotational_velocity: Exposed internal rotational velocity state (angular velocity in rad/s for 2D agents)
  • Simplified API: Direct property access eliminates the need to use agent.history["pos"][-1] patterns
from canns_lib.spatial import Environment, Agent
import numpy as np

env = Environment(dimensionality="2D", boundary_conditions="periodic")
agent = Agent(env, rng_seed=42)

# New simplified access
current_pos = agent.position      # Instead of agent.history["pos"][-1]
current_vel = agent.velocity       # Direct access
hd_angle = np.arctan2(agent.head_direction[1], agent.head_direction[0])

📖 Drift Velocity Demonstrations

  • example/drift_velocity_demo.py: Comprehensive demonstration script (500+ lines) showcasing:
    • Systematic grid exploration with drift velocity control
    • Directional biasing and circular motion patterns
    • Interactive visualization of agent trajectories
  • Enhanced example/trajectory_comparison.py: Added support for dynamic drift velocity via callback functions
  • README updates: Expanded documentation with drift_velocity usage examples and parameter explanations

🔧 Bug Fixes and Improvements

  • Windows compatibility: Fixed ZeroDivisionError in test_greedy_algorithms_status when computation is too fast
  • Code quality: Translated remaining Chinese comments to English for better international collaboration
  • Rust formatting: Applied consistent code formatting across the codebase

🚀 CI/CD Updates

  • Updated macOS Intel runner to macos-15-intel (official replacement for deprecated macos-13)
  • Improved CI reliability for cross-platform testing

Technical Notes

  • All new property getters return cloned data, maintaining safe ownership semantics
  • The position property is an alias for pos to provide clearer API semantics
  • rotational_velocity exposes the internal OU process state for advanced use cases
  • No breaking changes - all additions are backward compatible

Files Modified

  • src/spatial/agent.rs: Added property getters for position and rotational_velocity
  • example/drift_velocity_demo.py: New comprehensive demonstration script
  • example/trajectory_comparison.py: Enhanced with drift velocity callback support
  • README.md: Expanded documentation for drift_velocity usage
  • tests/test_complex_topology.py: Windows compatibility fix
  • python/canns_lib/_version.py: Version bump to 0.6.5
  • Cargo.toml: Version bump to 0.6.5

Use Cases

  • Researchers: Direct property access simplifies data collection during experiments
  • Developers: Cleaner API for building applications on top of spatial navigation
  • Students: Drift velocity demonstrations provide ready-to-run examples for learning

Full Changelog: v0.6.4...v0.6.5

Release 0.6.4 - Wall Collision Physics & CI Improvements

25 Dec 06:05

Choose a tag to compare

🎯 Major Improvements

Wall Collision Physics (Critical Fix)

  • Fixed wall penetration bug where agents could pass through walls
    • Corrected parametric equation sign error in collision detection
    • Fixed position reference (using instead of )
    • Prevented from overwriting collision results
    • Result: Zero wall violations across all test cases
  • Implemented elastic wall bounce physics matching RatInABox behavior
    • Velocity reflection with proper parallel/perpendicular decomposition
    • Speed reduction to 0.5 × speed_mean after collision
    • Iterative collision handling with normal distribution noise for numerical stability

Trajectory Generation Enhancements

  • Rayleigh distribution for 2D speed magnitudes
    • Correct statistical distribution for 2D random walks
    • CDF transformations: Rayleigh ↔ Normal for OU process updates
    • Significant improvement in RatInABox parity metrics
  • Added measured rotational velocity tracking
    • Distinction between dynamical and measured angular velocities
    • Proper angle difference normalization to [-π, π]

Performance Improvements

Trajectory similarity improvements across test cases:

  • case2_walls: 36% improvement (0.041 → 0.026)
  • case4_thigmotaxis: 35% improvement (0.024 → 0.016)
  • case5_periodic: Perfect match (0.0 → 0.0)
  • case8_hole: 28% improvement (0.657 → 0.472)

🔧 CI/CD Improvements

GitHub Actions Updates

  • Updated macOS Intel runner: macos-13macos-15-intel
    • macos-13 retired by GitHub in December 2025
    • Using official recommended replacement for Intel builds
  • Fixed Windows CI test failure
    • Handle zero-time computation in speedup calculations
    • Prevent ZeroDivisionError in performance tests

Code Quality

  • Translated all Chinese comments to English
  • Fixed Rust formatting (cargo fmt compliance)
  • Enhanced inline documentation with physics explanations

📦 Distribution

Pre-built wheels available for:

  • Linux: x86_64, aarch64
  • macOS: x86_64 (Intel), arm64 (Apple Silicon)
  • Windows: x86_64
  • Python versions: 3.11, 3.12, 3.13

🔬 Technical Details

New Dependencies

  • statrs = 0.16 - Statistical distributions (Rayleigh, Normal CDF/inverse CDF)

Algorithm Changes

  • Rayleigh-to-Normal transformation for velocity updates
  • Wall bounce reflection using vector decomposition
  • Collision detection with parametric line segment intersection
  • Numerical stability via 1e-9 scale normal noise

📚 Documentation

  • Comprehensive inline comments explaining physics principles
  • Detailed algorithm descriptions in geometry utilities
  • Updated build and test instructions

🙏 Acknowledgments

Thanks to the RatInABox project for the reference implementation and algorithm design.


Full Changelog: v0.6.3...v0.6.4

v0.6.3

29 Oct 07:41

Choose a tag to compare

Bump version to 0.6.3

Updated version numbers in Cargo.toml and _version.py to 0.6.3 for a new release.

canns-lib 0.6.2

29 Oct 06:34

Choose a tag to compare

Highlights

  • Spatial agent state/history now mirrors RatInABox behaviour, eliminating warm-start samples and aligning head-direction smoothing.
  • Ornstein–Uhlenbeck updates respect zero-noise settings, keeping deterministic constant-speed trajectories intact.

Spatial Navigation

  • Switched OU integration to incremental updates so drift/noise handling matches RatInABox, especially when speed_std = 0.
  • Deferred history recording until the first update, ensuring agent.history["pos"] and related fields stay empty right after init.
  • Updated spatial unit tests to cover the new history semantics and explicit update paths.

Examples & Diagnostics

  • example/trajectory_comparison.py now logs per-field history shapes directly from agent.history[...] and emits trajectory delta summaries.
  • Added a constant-speed comparison sweep over seeds [0, 1, 5, 10, 42] for quick regression checks.

Versioning

  • Bumped crate and Python package version to 0.6.2.

Checks

  • cargo check

v0.6.1: Spatial plotting parity

28 Oct 13:45

Choose a tag to compare

Highlights

  • RatInABox-style trajectory plotting with gradients, head direction markers, and multi-agent overlays
  • New plotting helpers: heatmap, speed and rotational velocity histograms with parity tests
  • Updated example and README guidance for visualization workflows

Testing

  • uv run --no-sync python -m pytest tests/test_spatial_basic.py
  • uv run --no-sync python example/spatial_plotting_demo.py

v0.6.0: Spatial Navigation Module

28 Oct 06:19

Choose a tag to compare

Release v0.6.0: Spatial Navigation Module

A major release featuring complete architectural restructuring and a new spatial navigation module with full RatInABox parity.

🎉 What's New

🧭 Spatial Navigation Module

This release introduces a brand new spatial navigation module that provides high-performance Rust implementations of spatial navigation primitives with full compatibility with RatInABox.

Features:

  • Environment: Support for arbitrary polygonal boundaries, walls, holes, and objects
  • Agent: Brownian motion with drift, wall repulsion, thigmotaxis, and configurable dynamics
  • Trajectory Management: Import trajectories, set positions/velocities, history tracking
  • Python API: Drop-in replacement for RatInABox's Environment and Agent classes

Performance:

  • 10-50x faster than pure Python implementations
  • Efficient geometry calculations and collision detection
  • Optimized random walk generation

🏗️ Architecture Restructuring

Complete reorganization of the project structure for better maintainability and unified builds:

Before:

canns-lib/
├── Cargo.toml (workspace)
├── crates/
│   ├── ripser/
│   └── spatial/

After:

canns-lib/
├── Cargo.toml (single package)
└── src/
    ├── lib.rs (unified entry)
    ├── ripser/
    └── spatial/

Benefits:

  • Single build command for all modules
  • Simplified dependency management
  • Cleaner project structure
  • Faster compilation times

📊 Statistics

  • 53 files changed, 10,568 insertions(+), 190 deletions(-)
  • New spatial module: ~2,500 lines of Rust code
  • Comprehensive test suite: 300+ test cases
  • Full RatInABox parity validation

🔧 Improvements

Module Management

  • Unified Python extension loading for both _ripser_core and _spatial_core
  • Centralized version management in python/canns_lib/_version.py
  • Module registration pattern for cleaner architecture

Dependencies

  • Moved rand to main dependencies
  • Added rand_distr for spatial module
  • Updated all dependencies to latest stable versions

Python API

  • Enhanced spatial wrapper with type hints
  • Added plot_environment() helper function
  • Better error messages and documentation

🧪 Testing

All tests pass for both modules:

# Ripser module tests
uv run python tests/test_basic.py

# Spatial module tests
uv run python tests/test_spatial_basic.py
uv run python tests/test_spatial_vs_ratinabox.py

# Trajectory comparison
uv run python example/trajectory_comparison.py

📦 Installation

pip install canns-lib==0.6.0

Or with uv:

uv pip install canns-lib==0.6.0

🔄 Migration Guide

For Existing Users

No breaking changes! The Ripser API remains fully compatible. Simply upgrade:

pip install --upgrade canns-lib

For New Spatial Module Users

from canns_lib.spatial import Environment, Agent

# Create environment
env = Environment(
    dimensionality="2D",
    boundary_conditions="periodic",
    scale=1.0,
)

# Create agent
agent = Agent(env)

# Run simulation
for _ in range(1000):
    agent.update(dt=0.01)

# Get trajectory
positions = agent.history_positions()

See the spatial navigation documentation for more details.

🙏 Acknowledgments

This release includes major contributions:

  • Spatial navigation module design and implementation
  • RatInABox parity testing and validation
  • Architecture restructuring and optimization

Special thanks to the RatInABox team for their excellent work that inspired this module.

📝 Full Changelog

See PR #1 for complete details of all changes.

🐛 Known Issues

None currently. Please report any issues on GitHub Issues.


Full Documentation: https://github.com/Routhleck/canns-lib

🤖 Generated with Claude Code

v0.5.0: Major Restructuring to canns-lib

27 Oct 06:23

Choose a tag to compare

🚀 Release v0.5.0: Major Restructuring to canns-lib

This is a major restructuring release that transforms canns-ripser into canns-lib, a modular computational acceleration library for CANNS (Continuous Attractor Neural Networks).

⚠️ Breaking Changes

Package Renamed: canns-ripsercanns-lib

Migration Guide:

# ❌ Old API (v0.4.x and earlier)
import canns_ripser
result = canns_ripser.ripser(data, maxdim=2)

# ✅ New API (v0.5.0+)
from canns_lib.ripser import ripser
result = ripser(data, maxdim=2)

# Alternative import style
from canns_lib import ripser
result = ripser.ripser(data, maxdim=2)

🏗️ New Modular Architecture

Current Modules

  • canns_lib.ripser: High-performance topological data analysis
    • Full compatibility with ripser.py
    • Optimized Rust implementation
    • Mean speedup: 1.13x across benchmarks
    • Peak speedup: up to 1.82x

Coming Soon

  • canns_lib.fastann: Approximate nearest neighbor search
  • canns_lib.dynamics: Neural network dynamics computation
  • canns_lib.spatial: Spatial indexing and queries
  • And more computational accelerations for CANNS!

📦 What's Changed

Package Structure

  • Modular organization: Ripser is now a submodule under canns_lib.ripser
  • Rust codebase: Moved to crates/ripser/src/ for better organization
  • Python bindings: Updated to canns_lib._ripser_core
  • Future-ready: Infrastructure for adding new acceleration modules

Documentation

  • README: Completely rewritten to reflect modular library concept
  • CLAUDE.md: Updated with new architecture and development guidelines
  • Examples: Updated to use new import paths

CI/CD

  • Updated workflows for new package name
  • All tests migrated to new import structure
  • Release automation configured for PyPI publishing

✅ Maintained Compatibility

100% API Compatibility: All ripser functionality remains fully compatible with ripser.py. Only the import path has changed.

  • ✅ Same function signatures
  • ✅ Same return values
  • ✅ Same numerical accuracy
  • ✅ Full feature parity with ripser.py

📊 Performance Highlights

The ripser module continues to deliver excellent performance:

  • Mean speedup: 1.13x across 54 benchmarks vs ripser.py
  • Peak speedup: Up to 1.82x on certain datasets
  • Memory efficiency: 1.01x memory ratio (stable usage)
  • Perfect accuracy: 100% match with ripser.py results

Top Performing Scenarios

Dataset Type Configuration Speedup
Random N(0,I) d=2, n=500, maxdim=2 1.82x
Two moons n=400, noise=0.08, maxdim=2 1.77x
Random N(0,I) d=2, n=200, maxdim=2 1.72x

🔧 Installation

From PyPI

pip install canns-lib

From Source

git clone https://github.com/Routhleck/canns-lib.git
cd canns-lib
pip install maturin
maturin develop --release

🧪 Quick Start

import numpy as np
from canns_lib.ripser import ripser

# Generate sample data
data = np.random.rand(100, 3)

# Compute persistence diagrams
result = ripser(data, maxdim=2)
diagrams = result['dgms']

print(f"H0: {len(diagrams[0])} features")
print(f"H1: {len(diagrams[1])} features")
print(f"H2: {len(diagrams[2])} features")

📝 Technical Details

Commits in This Release

  • Restructure: canns-ripser → canns-lib
  • Fix CI workflow to use new canns_lib package structure
  • Fix typo in CANNs acronym in README.md
  • Fix test imports to use new canns_lib package structure
  • Bump version to 0.5.0 for major restructuring release

Repository Changes

  • Repository URL: Updated to https://github.com/Routhleck/canns-lib
  • Package name: canns-lib on PyPI
  • Module name: canns_lib in Python

🙏 Acknowledgments

Ripser Module

  • Ulrich Bauer: Original Ripser algorithm and C++ implementation
  • Christopher Tralie & Nathaniel Saul: ripser.py Python implementation
  • Rust community: Amazing ecosystem of high-performance libraries

📚 Resources


🤖 Generated with Claude Code

v0.4.4 - Core Refactoring and Cocycles Fix

04 Sep 02:35

Choose a tag to compare

🚀 Major Updates

Core Architecture Refactoring

  • Modular Structure: Split monolithic ripser.rs into organized modules:
    • algorithm.rs - Main Ripser algorithm coordination
    • reduction.rs - Matrix reduction operations
    • assembly.rs - Column assembly logic
  • Improved Code Organization: Enhanced maintainability and readability
  • Better Separation of Concerns: Each module has clear responsibilities

🐛 Cocycles Compatibility Fix

  • Fixed Empty Cocycles Issue: Resolved bug where cocycles were returning empty results
  • Format Compatibility: Cocycles now match original ripser.py format exactly
  • Proper Vertex and Coefficient Handling: Cocycles now correctly include edge vertices and normalized coefficients
  • 2D Array Format: Cocycles are returned as (n_simplices, 3) arrays matching original ripser

🧪 Comprehensive Testing

  • New Test Suite: Added test_cocycles.py with 11 comprehensive test cases
  • Multiple Scenarios: Tests cover single holes, multiple holes, empty cases, sparse matrices
  • Compatibility Verification: Direct comparison with original ripser.py
  • Edge Case Handling: Tests for various coefficient fields and higher dimensions

📊 Test Coverage

✅ test_square_cocycles - Basic cocycle functionality
✅ test_triangle_no_cocycles - No holes case  
✅ test_no_cocycles_flag - Flag disabled case
✅ test_cocycles_compatibility_with_original - Direct ripser.py comparison
✅ test_higher_dimensional_cocycles - H2 and beyond
✅ test_cocycles_with_different_coefficients - Various modulus values
✅ test_multiple_cocycles - Multiple independent holes
✅ test_cocycles_format_consistency - Format validation
✅ test_cocycles_empty_cases - Edge cases
✅ test_cocycles_sparse_matrix - Sparse matrix support
✅ test_cocycles_comprehensive_comparison - Multi-case validation

🔧 Technical Improvements

  • Enhanced Python Interface: Better handling of cocycle format conversion
  • Memory Efficiency: Optimized cocycle storage and processing
  • Error Handling: Improved robustness in edge cases
  • Code Quality: Better documentation and structure

📈 Performance

  • Maintained Speed: Refactoring preserved high-performance characteristics
  • Better Cache Locality: Improved data structure organization
  • Optimized Memory Usage: More efficient cocycle representation

Full Changelog: v0.4.3...v0.4.4

Release v0.4.3: Enhance sparse matrix support and benchmarking

25 Aug 04:10

Choose a tag to compare

🚀 What's New in v0.4.3

Features & Improvements

  • Sparse Matrix Support: Added comprehensive sparse matrix input support and testing
  • Enhanced Benchmarking: Introduced sparse matrix benchmarking capabilities
  • Improved Error Handling: Refactored error handling using the ? operator for better code clarity
  • Dataset Optimization: Balanced and expanded benchmark dataset categories

Technical Changes

  • Removed SparseSimplexCoboundaryEnumerator implementation for code simplification
  • Enhanced test coverage for sparse matrix operations
  • Improved benchmark infrastructure

Full Changelog

Since v0.4.2:

  • 749bc10 Balance and expand benchmark dataset categories
  • 473bbb3 Refactor error handling with '?' operator
  • ea3e42a Remove SparseSimplexCoboundaryEnumerator implementation
  • 3a787d1 Add support and tests for sparse matrix input
  • c70291c Add sparse matrix benchmarking support

Star this project if you find it useful!
🐛 Report issues on our GitHub Issues page