Rust Analysis Engine -- 22 Modules, 597 Tests

May 20, 2026 · View on GitHub

Pure Rust implementations of all 22 spike_stats analysis modules, exposed to Python via PyO3 bindings. Zero NumPy or SciPy dependency on the Rust side -- all linear algebra (eigendecomposition, matrix inversion, Gaussian elimination), FFT (via rustfft), and stochastic processes (via rand_distr) are implemented natively.

Architecture

engine/src/analysis/
  mod.rs              -- 22 pub mod declarations
  basic.rs            -- spike_times, isi, firing_rate, spike_count, bin_spike_train
  rate.rs             -- instantaneous_rate, psth, population_rate
  variability.rs      -- cv_isi, cv2, local_variation, fano_factor, entropies, Hurst
  correlation.rs      -- cross_correlation, STTC, coherence, covariance
  distance.rs         -- van_rossum, victor_purpura, ISI/SPIKE distances
  information.rs      -- mutual_information, transfer_entropy, KL MI
  causality.rs        -- pairwise/conditional/spectral Granger, PDC, DTF
  decoding.rs         -- population_vector, Bayesian, MLE, LDA, naive Bayes
  network.rs          -- functional_connectivity, unitary_events, assemblies
  surrogates.rs       -- ISI shuffle, dither, Poisson, gamma, compound Poisson
  temporal.rs         -- burst_detection, latency, onset, change points
  patterns.rs         -- spike_directionality, spike_train_order, C3
  spectral.rs         -- power_spectrum (FFT via rustfft)
  waveform.rs         -- width, amplitude, slopes, halfwidth, PT ratio
  point_process.rs    -- conditional_intensity, hazard, survivor, renewal
  statistics.rs       -- significance_bootstrap (Rust-only, takes fn pointer)
  stimulus.rs         -- STA, STC, spatial_information, place fields, tuning
  lfp.rs              -- phase_locking_value, spike_field_coherence, phase histogram
  sorting_quality.rs  -- isolation_distance, L-ratio, silhouette, d', SNR, drift
  dimensionality.rs   -- PCA, demixed PCA, factor analysis (Jacobi eigendecomp)
  gpfa.rs             -- GPFA via EM with squared-exponential GP priors
  spade.rs            -- SPADE: Apriori itemset mining + surrogate significance

Dependency Map

External crates used by analysis modules:

CrateVersionUsed by
rustfft6.2spectral.rs, lfp.rs, correlation.rs
rand_distr0.6surrogates.rs

All other computation (eigendecomposition, matrix inversion, complex arithmetic, Hilbert transforms, histogram binning) is self-contained.

Custom Linear Algebra

Several modules implement their own numerical primitives to avoid external LAPACK/BLAS dependencies:

  • Jacobi eigendecomposition (dimensionality.rs): symmetric eigenvalues + eigenvectors via iterative rotations, O(n^3) per sweep.
  • Gauss-Jordan inverse (sorting_quality.rs, gpfa.rs, dimensionality.rs, causality.rs): partial-pivot elimination on augmented [A|I] matrix.
  • Gaussian elimination solver (gpfa.rs, causality.rs, decoding.rs): solves Ax = b with partial pivoting.
  • Complex matrix ops (causality.rs): C64 type with inverse, determinant, multiply for spectral Granger.

PyO3 Bindings

96 functions are exposed to Python via #[pyfunction] wrappers in engine/src/lib.rs. The sole exception is significance_bootstrap in statistics.rs which takes a Fn(&[f64], &[f64]) -> f64 pointer and cannot cross the PyO3 boundary.

Functions NOT exposed via PyO3

FunctionReason
significance_bootstrapTakes Fn pointer
generalized_victor_purpuraTakes fn(f64) -> f64
time_rescaling_ks_testTakes fn(f64) -> f64
inhomogeneous_poissonTakes fn(f64) -> f64
surrogate_trial_shuffleReturns permutation indices only

These are callable from Rust code and tests but require Python-side wrappers with closures.

Module Reference

basic

Core spike train operations used by most other modules.

FunctionSignatureDescription
spike_times(&[i32], f64) -> Vec<f64>Extract spike times (s) from binary array
isi(&[i32], f64) -> Vec<f64>Inter-spike intervals (s)
firing_rate(&[i32], f64) -> f64Mean firing rate (Hz)
spike_count(&[i32]) -> i64Total spike count
bin_spike_train(&[i32], usize) -> Vec<i64>Bin into spike counts

spectral

FunctionSignatureDescription
power_spectrum(&[i32], f64) -> (Vec<f64>, Vec<f64>)PSD via FFT, returns (psd, freqs_hz)

waveform

Spike waveform shape analysis. All functions take &[f64] waveform samples and dt (sample interval, default 1/30000 s).

FunctionReturnsReference
waveform_widthf64Trough-to-peak width (s). Bartho et al. 2004
waveform_amplitudef64Peak-to-trough amplitude
waveform_repolarization_slopef64Max dV/dt after trough. Bean 2007
waveform_recovery_slopef64Min dV/dt after peak. Bean 2007
waveform_halfwidthf64Duration at half-minimum. Bartho et al. 2004
waveform_pt_ratiof64Post-trough peak / trough amplitude

point_process

Point process models and hazard functions.

FunctionReturnsReference
conditional_intensityVec<f64>Moving-window Poisson rate (Hz). Brown et al. 2004
isi_hazard_function(Vec<f64>, Vec<f64>)h(t) = f(t)/S(t). Tuckwell 1988
isi_survivor_function(Vec<f64>, Vec<f64>)S(t) = P(ISI > t)
renewal_density(Vec<f64>, Vec<f64>)Normalised by mean rate. Cox 1962

statistics

FunctionSignatureNotes
significance_bootstrap(F, &[f64], &[f64], usize, u64) -> (f64, f64)Rust-only. Permutation test with splitmix64 PRNG

stimulus

Spike-triggered analysis and receptive field estimation.

FunctionReturnsReference
spike_triggered_averageVec<f64>Mean pre-spike stimulus snippet
spike_triggered_covarianceVec<f64> (flat matrix)Covariance of pre-spike stimulus. Schwartz et al. 2006
spatial_informationf64 (bits/spike)Skaggs et al. 1993
place_field_detectionVec<(f64, f64)>Contiguous high-rate bins. O'Keefe & Dostrovsky 1971
tuning_curve(Vec<f64>, Vec<f64>)Rate vs stimulus value. Dayan & Abbott 2001

lfp

Spike-LFP coupling via analytic signal (Hilbert transform with rustfft).

FunctionReturnsDescription
phase_locking_valuef64PLV =
spike_field_coherence(Vec<f64>, Vec<f64>)SFC =
spike_phase_histogram(Vec<i64>, Vec<f64>)Phase histogram in [-pi, pi]

sorting_quality

Spike sorting quality metrics. Cluster/noise inputs are row-major (n_points, n_features) flat arrays.

FunctionReturnsReference
isolation_distancef64Mahalanobis at rank n_cluster. Harris et al. 2001
l_ratiof64Normalised chi2-approximation. Schmitzer-Torbert et al. 2005
silhouette_scoref64Mean (b-a)/max(a,b). Rousseeuw 1987
d_primef64Projected sensitivity index. Green & Swets 1966
isi_violation_ratef64Fraction below refractory. Hill et al. 2011
presence_ratiof64Fraction of occupied bins. IBL 2019
amplitude_cutofff64Estimated missing spikes. Hill et al. 2011
snrf64Peak / noise_std. Suner et al. 2005
nn_hit_ratef64k-NN cluster purity. Chung et al. 2017
drift_metricf64Amplitude drift over time. IBL 2019

dimensionality

Dimensionality reduction with built-in Jacobi eigendecomposition (no LAPACK required).

FunctionReturnsReference
spike_train_pca(Vec<f64>, Vec<f64>)(projected, explained_variance_ratio)
demixed_pca(Vec<f64>, Vec<f64>)Condition-dependent variance. Kobak et al. 2016
factor_analysis(Vec<f64>, Vec<f64>)(loadings, uniquenesses). Rubin & Thayer 1982

gpfa

Gaussian Process Factor Analysis. Full EM implementation with squared-exponential GP kernels, block-structured precision matrices, and approximate log-likelihood monitoring.

FunctionReturnsReference
gpfaGpfaResult structTrajectories, C, d, R, tau, log-likelihoods. Yu et al. 2009
gpfa_transformVec<f64>Project new data with learned parameters

GpfaResult fields: trajectories, c, d, r, tau, log_likelihoods, n_latents, n_bins, n_neurons.

spade

Spike Pattern Detection and Evaluation. Apriori-style frequent itemset mining extended to spatiotemporal patterns with lag search and surrogate significance testing.

FunctionReturnsReference
spade_detectVec<SpadePattern>Significant patterns with p-values. Torre et al. 2013

SpadePattern fields: neurons, lags, count, p_value.

Test Coverage

597 tests across all modules. Every public function has at least:

  • Positive case (typical input producing expected output)
  • Edge case (empty input, single element, degenerate dimensions)
  • Numerical accuracy check (comparison against known values or bounds)

Run tests:

export PATH="$HOME/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin:$PATH"
cd engine && cargo test --lib

Run a single module's tests:

cargo test --lib analysis::spectral
cargo test --lib analysis::gpfa

Benchmark Results

Measured with Criterion on i5-11600K @ 3.90 GHz, DDR4-3200. Values are median latency. Pure CPU benchmarks.

Last measured: 2026-05-02 (cargo bench --bench analysis_bench)

basic

Function10010K100K
spike_times86 ns5.4 µs85.0 µs
isi106 ns5.6 µs86.3 µs
firing_rate13 ns1.2 µs15.3 µs
bin_spike_train36 ns2.5 µs29.0 µs

rate

Function10010K100K
instantaneous_rate4.3 µs352 µs3.5 ms

variability

Function10010K100K
cv_isi108 ns6.5 µs94.7 µs
fano_factor76 ns4.8 µs50.7 µs
sample_entropy32.6 µs3.23 msO(n²) — not benchmarked

correlation

Function10010K
cross_correlation1.46 µs213 µs
event_synchronization142 ns63.1 µs

distance

Function1005K
van_rossum1.07 µs314 µs
victor_purpura162 ns274 µs
isi_distance165 ns5.95 µs

information

Function10010K
mutual_information714 ns48.7 µs
transfer_entropy1.03 µs60.8 µs

causality

Function1005K
pairwise_granger102 ns81.7 µs

decoding

FunctionLatency
population_vector_decode14.9 µs
bayesian_decode11.0 µs

network

FunctionLatency
functional_connectivity (10n)814 µs

surrogates

Function1K100K
isi_shuffle865 ns103 µs
homogeneous_poisson2.55 µs242 µs

temporal

Function1K100K
burst_detection708 ns91.4 µs
change_point_detection296 ns31.8 µs

patterns

FunctionLatency
spike_directionality (5K)3.85 µs
cubic_higher_order (5K)409 µs

spectral

Function25610K100K
power_spectrum3.81 µs177 µs4.91 ms

waveform (50 samples)

FunctionLatency
waveform_width64 ns
waveform_amplitude38 ns
waveform_repolarization_slope72 ns
waveform_halfwidth168 ns
waveform_pt_ratio58 ns

point_process

Function1K100K
conditional_intensity22.9 µs2.33 ms
isi_hazard1.07 µs103 µs

statistics

FunctionLatency
significance_bootstrap (200 surr)661 µs

stimulus

Function1K50K
STA1.18 µs67.8 µs
spatial_information3.89 µs205 µs

lfp

Function50010K
phase_locking_value26.2 µs540 µs
spike_field_coherence11.9 µs237 µs

sorting_quality

FunctionLatency
isolation_distance (50 pts, 4D)6.82 µs
isolation_distance (200 pts, 4D)27.0 µs
silhouette_score (50 pts, 4D)35.8 µs
silhouette_score (200 pts, 4D)536 µs
isi_violation_rate (5K)2.93 µs

dimensionality

FunctionLatency
PCA (10n, 2000t)43.4 µs
factor_analysis (10n, 2000t)408 µs

gpfa

FunctionLatency
GPFA (4n, 500t, 5 EM iter)4.84 ms

spade

FunctionLatency
SPADE detect (3n, 500t, 50 surr)748 µs

Performance Notes

All functions are single-threaded pure CPU. Benchmarks run via cargo bench --bench analysis_bench. Parallelisation is left to the Python caller via concurrent.futures or joblib.

Full benchmark results with scaling analysis are maintained as internal release evidence. Public performance claims on this page are limited to the curated benchmark tables above until the corresponding public benchmark packet is published.