| Crates.io | tda |
| lib.rs | tda |
| version | 0.1.0 |
| created_at | 2025-11-10 21:27:06.903238+00 |
| updated_at | 2025-11-10 21:27:06.903238+00 |
| description | Topological Data Analysis for neural networks - persistent homology and topological features |
| homepage | |
| repository | https://github.com/Yatrogenesis/cortexia-workspace |
| max_upload_size | |
| id | 1926226 |
| size | 153,433 |
A comprehensive Rust library for Topological Data Analysis (TDA) with specialized tools for neuroscience applications.
Persistent Homology: Compute topological features across scales
Persistence Diagrams: Visualize and analyze topological features
Simplicial Complexes: Build and manipulate topological structures
Mapper Algorithm: Create graph-based visualizations of high-dimensional data
Point Cloud Distances:
Spike Train Distances:
Spike Train Analysis:
Temporal Analysis:
Cell Assembly Detection:
Functional Connectivity:
Add this to your Cargo.toml:
[dependencies]
tda = "0.1.0"
nalgebra = "0.33"
use nalgebra::DMatrix;
use tda::prelude::*;
// Create a circle point cloud
let n = 20;
let mut points = Vec::new();
for i in 0..n {
let angle = 2.0 * std::f64::consts::PI * (i as f64) / (n as f64);
points.push(angle.cos());
points.push(angle.sin());
}
let point_matrix = DMatrix::from_row_slice(n, 2, &points);
// Compute distance matrix
let dist = euclidean_distance_matrix(&point_matrix)?;
// Compute persistent homology
let pairs = persistent_homology_rips(&dist, 2.0, 1)?;
// Create persistence diagram
let diagram = PersistenceDiagram::from_pairs(&pairs, Some(1));
// Analyze features
for (birth, death) in diagram.points_by_dimension(1) {
println!("Loop: birth={:.3}, death={:.3}, persistence={:.3}",
birth, death, death - birth);
}
use tda::distances::SpikeTrain;
use tda::neural_tda::NeuralPopulation;
// Create spike trains for multiple neurons
let train1 = SpikeTrain::new(vec![1.0, 2.5, 4.0, 5.5, 7.0])?;
let train2 = SpikeTrain::new(vec![1.1, 2.6, 4.1, 5.6, 7.1])?;
let train3 = SpikeTrain::new(vec![10.0, 11.0, 12.0, 13.0])?;
// Create neural population
let population = NeuralPopulation::new(vec![train1, train2, train3])?;
// Compute persistence diagram using Victor-Purpura distance
let diagram = population.persistence_diagram_vp(1.0, 5.0, 1)?;
println!("Detected {} topological features", diagram.len());
// Extract topological features for ML
let features = topological_features(&population, 1.0, 5.0, 1)?;
println!("Feature vector: {:?}", features);
use tda::neural_tda::{NeuralPopulation, detect_cell_assemblies};
// Create population with correlated neurons
let population = NeuralPopulation::new(spike_trains)?;
// Detect assemblies using clique topology
let assemblies = detect_cell_assemblies(
&population,
0.7, // correlation threshold
3 // minimum assembly size
)?;
for (i, assembly) in assemblies.iter().enumerate() {
println!("Assembly {}: {} neurons, strength={:.3}",
i, assembly.neurons.len(), assembly.strength);
}
use tda::neural_tda::SlidingWindowAnalysis;
// Configure sliding window
let window = SlidingWindowAnalysis::new(
1.0, // window size
0.5, // step size
0.0, // start time
10.0 // end time
)?;
// Analyze population over time
let results = window.analyze_population(&population, 1.0, 5.0, 1)?;
for (time, diagram) in results {
println!("Time {:.2}: {} features", time, diagram.len());
}
use tda::mapper::{MapperBuilder, filters, CoverStrategy, ClusteringMethod};
let data = DMatrix::from_row_slice(100, 10, &data_array);
let dist = euclidean_distance_matrix(&data)?;
// Build Mapper graph
let graph = MapperBuilder::new()
.filter(filters::eccentricity())
.cover(CoverStrategy::Uniform {
num_intervals: 10,
overlap_percent: 0.5,
})
.clustering(ClusteringMethod::SingleLinkage { threshold: 0.5 })
.build(&data, &dist)?;
println!("Mapper graph: {} nodes, {} edges",
graph.node_count(), graph.edge_count());
// Access node information
for node in graph.node_weights() {
println!("Cluster: {} points, representative={:?}",
node.size, node.representative_value);
}
use tda::neural_tda::functional_connectivity;
use std::collections::HashMap;
// Compute functional connectivity matrix
let mut params = HashMap::new();
params.insert("q".to_string(), 1.0);
let conn_matrix = functional_connectivity(
&population,
"victor-purpura",
¶ms
)?;
println!("Connectivity matrix shape: {}x{}",
conn_matrix.nrows(), conn_matrix.ncols());
Persistent homology computes topological features (connected components, loops, voids) of data across multiple scales. For a point cloud:
Betti Numbers: β₀ counts connected components, β₁ counts loops, β₂ counts voids, etc.
At scale r, the Rips complex contains:
Spike train metric based on edit distance:
Creates a topological summary:
tda/
├── src/
│ ├── lib.rs # Main API and documentation
│ ├── error.rs # Error types
│ ├── distances.rs # Distance metrics
│ ├── simplicial_complex.rs # Simplicial complex structures
│ ├── persistent_homology.rs # Homology computation
│ ├── persistence_diagram.rs # Diagram operations and distances
│ ├── mapper.rs # Mapper algorithm
│ └── neural_tda.rs # Neuroscience-specific tools
├── Cargo.toml
└── README.md
The library includes comprehensive tests:
cargo test
Tests cover:
MIT OR Apache-2.0
This library is part of the CORTEXIA neuroscience workspace. Contributions are welcome!