| Crates.io | amari |
| lib.rs | amari |
| version | 0.17.0 |
| created_at | 2025-10-06 20:48:42.431934+00 |
| updated_at | 2026-01-11 22:48:14.173012+00 |
| description | Advanced mathematical computing library with geometric algebra, tropical algebra, and automatic differentiation |
| homepage | https://github.com/justinelliottcobb/Amari |
| repository | https://github.com/justinelliottcobb/Amari |
| max_upload_size | |
| id | 1870840 |
| size | 2,819,824 |
Comprehensive Mathematical Computing Platform with Geometric Algebra, Differential Calculus, Measure Theory, Probability Theory, Functional Analysis, Algebraic Topology, Dynamical Systems, and Vector Symbolic Architectures
A unified mathematical computing library featuring geometric algebra, differential calculus, measure theory, probability theory on geometric spaces, functional analysis (Hilbert spaces, operators, spectral theory), algebraic topology (homology, persistent homology, Morse theory), dynamical systems analysis (ODE solvers, stability, bifurcations, chaos, Lyapunov exponents), relativistic physics, tropical algebra, automatic differentiation, holographic associative memory (Vector Symbolic Architectures), optical field operations for holographic displays, and information geometry. The library provides multi-GPU infrastructure with intelligent workload distribution and complete WebAssembly support for browser deployment.
Live Examples Suite | API Documentation
Add to your Cargo.toml:
[dependencies]
# Complete library with all features
amari = "0.17.0"
# Or individual crates:
# Core geometric algebra and mathematical foundations
amari-core = "0.17.0"
# Differential calculus with geometric algebra
amari-calculus = "0.17.0"
# Measure theory and integration
amari-measure = "0.17.0"
# Probability theory on geometric algebra spaces
amari-probabilistic = "0.17.0"
# Functional analysis: Hilbert spaces, operators, spectral theory
amari-functional = "0.17.0"
# Algebraic topology: homology, persistent homology, Morse theory
amari-topology = "0.17.0"
# Dynamical systems: ODE solvers, stability, bifurcations, Lyapunov exponents
amari-dynamics = "0.17.0"
# Vector Symbolic Architectures, holographic memory, and optical fields
amari-holographic = "0.17.0"
# High-precision relativistic physics
amari-relativistic = { version = "0.17.0", features = ["high-precision"] }
# GPU acceleration (includes optical field GPU operations)
amari-gpu = "0.17.0"
# Optimization algorithms
amari-optimization = "0.17.0"
# Additional mathematical systems
amari-tropical = "0.17.0"
amari-dual = "0.17.0"
amari-info-geom = "0.17.0"
amari-automata = "0.17.0"
amari-fusion = "0.17.0"
amari-network = "0.17.0"
amari-enumerative = "0.17.0"
npm install @justinelliottcobb/amari-wasm
Or with yarn:
yarn add @justinelliottcobb/amari-wasm
use amari_core::{Multivector, basis::Basis, rotor::Rotor};
// 3D Euclidean Clifford algebra Cl(3,0,0)
type Cl3 = Multivector<3, 0, 0>;
// Create basis vectors
let e1: Cl3 = Basis::e1();
let e2: Cl3 = Basis::e2();
// Geometric product: e1 * e2 = e1 ∧ e2 (bivector)
let e12 = e1.geometric_product(&e2);
// Create rotor for 90° rotation in xy-plane
let rotor = Rotor::from_bivector(&e12, std::f64::consts::PI / 2.0);
// Apply rotation: e1 → e2
let rotated = rotor.apply(&e1);
use amari_calculus::{ScalarField, VectorField, VectorDerivative};
use amari_core::Multivector;
// Define a scalar field f(x,y,z) = x² + y² + z²
let field = ScalarField::<3, 0, 0>::new(|pos| {
pos[0] * pos[0] + pos[1] * pos[1] + pos[2] * pos[2]
});
// Compute gradient at a point
let point = [1.0, 2.0, 3.0];
let gradient = field.gradient(&point, 1e-6);
// Define a vector field
let vector_field = VectorField::<3, 0, 0>::new(|pos| {
[pos[1] * pos[2], pos[0] * pos[2], pos[0] * pos[1]]
});
// Compute divergence and curl
let derivative = VectorDerivative::<3, 0, 0>::new(1e-6);
let div = derivative.divergence(&vector_field, &point);
let curl = derivative.curl(&vector_field, &point);
use amari_tropical::TropicalNumber;
// Create tropical numbers using the constructor
let a = TropicalNumber::new(3.0);
let b = TropicalNumber::new(5.0);
// Tropical operations
let sum = a.tropical_add(&b); // max(3, 5) = 5
let product = a.tropical_mul(&b); // 3 + 5 = 8
// Access values
println!("Tropical sum: {}", sum.value());
println!("Tropical product: {}", product.value());
// Tropical identities
let zero = TropicalNumber::<f64>::tropical_zero(); // -∞ (additive identity)
let one = TropicalNumber::<f64>::tropical_one(); // 0 (multiplicative identity)
use amari_dual::DualNumber;
// Create dual number for differentiation
// f(x) = x² at x = 3, with seed derivative 1
let x = DualNumber::new(3.0, 1.0);
// Compute f(x) = x²
let result = x * x;
// Extract value and derivative
println!("f(3) = {}", result.value()); // 9.0
println!("f'(3) = {}", result.derivative()); // 6.0
// For constants (derivative = 0)
let c = DualNumber::constant(2.0);
let scaled = x * c; // 2x, derivative = 2
use amari_fusion::TropicalDualClifford;
// Create from logits (common in ML applications)
let logits = vec![1.5, 2.0, 0.8, 1.2];
let tdc = TropicalDualClifford::<f64, 4>::from_logits(&logits);
// Evaluate using all three algebras simultaneously
let other = TropicalDualClifford::from_logits(&[2.0, 1.5, 1.0, 0.9]);
let evaluation = tdc.evaluate(&other);
// Extract features from each algebra
let tropical_features = tdc.extract_tropical_features(); // Fast path-finding
let dual_features = tdc.extract_dual_features(); // Automatic gradients
// Perform sensitivity analysis
let sensitivity = tdc.sensitivity_analysis();
let most_sensitive = sensitivity.most_sensitive(2);
println!("Combined score: {}", evaluation.combined_score);
println!("Most sensitive components: {:?}", most_sensitive);
use amari_holographic::{HolographicMemory, ProductCl3x32, BindingAlgebra};
// Create holographic memory with 256-dimensional vectors
let mut memory: HolographicMemory<ProductCl3x32> = HolographicMemory::new();
// Generate random keys and values
let key1 = ProductCl3x32::random();
let value1 = ProductCl3x32::random();
// Store key-value associations via superposition
memory.store(&key1, &value1);
let key2 = ProductCl3x32::random();
let value2 = ProductCl3x32::random();
memory.store(&key2, &value2);
// Retrieve with a query key
let retrieved = memory.retrieve(&key1);
println!("Similarity to original: {:.3}", retrieved.similarity(&value1));
// Binding operations for role-filler structures
let bound = key1.bind(&value1); // key ⊛ value
let recovered = bound.unbind(&key1); // Approximately recovers value1
println!("Recovery similarity: {:.3}", recovered.similarity(&value1));
// Resonator network for cleanup/factorization
use amari_holographic::Resonator;
let codebook = vec![value1.clone(), value2.clone()];
let resonator = Resonator::new(codebook.clone());
let noisy = retrieved.clone(); // Noisy retrieval
let cleaned = resonator.cleanup(&noisy, 10); // 10 iterations
use amari_holographic::optical::{
OpticalRotorField, GeometricLeeEncoder, LeeEncoderConfig,
OpticalFieldAlgebra, OpticalCodebook, TropicalOpticalAlgebra,
};
// Create optical rotor fields (phase + amplitude on a 2D grid)
let field_a = OpticalRotorField::random((256, 256), 42);
let field_b = OpticalRotorField::random((256, 256), 123);
let uniform = OpticalRotorField::uniform(0.0, 0.5, (256, 256));
println!("Field dimensions: {:?}", field_a.dimensions());
println!("Total energy: {:.4}", field_a.total_energy());
// Lee hologram encoding for DMD display
let config = LeeEncoderConfig::new((256, 256), 0.25); // carrier frequency = 0.25
let encoder = GeometricLeeEncoder::new(config);
let hologram = encoder.encode(&uniform);
println!("Hologram fill factor: {:.4}", hologram.fill_factor());
// Get binary data for hardware interface (bit-packed)
let binary_data = hologram.as_bytes();
println!("Packed binary size: {} bytes", binary_data.len());
// VSA operations on optical fields
let algebra = OpticalFieldAlgebra::new((256, 256));
// Bind two fields (rotor multiplication = phase addition)
let bound = algebra.bind(&field_a, &field_b);
// Compute similarity between fields
let similarity = algebra.similarity(&field_a, &field_a); // Self-similarity ≈ 1.0
println!("Self-similarity: {:.4}", similarity);
// Unbind to retrieve original field
let retrieved = algebra.unbind(&field_a, &bound);
let retrieval_sim = algebra.similarity(&retrieved, &field_b);
println!("Retrieval similarity: {:.4}", retrieval_sim);
// Seed-based symbol codebook for reproducible VSA
let mut codebook = OpticalCodebook::new((64, 64), 42);
codebook.register("AGENT");
codebook.register("ACTION");
codebook.register("TARGET");
let agent_field = codebook.get("AGENT");
let action_field = codebook.get("ACTION");
println!("Registered symbols: {:?}", codebook.symbols());
// Tropical operations for attractor dynamics
let tropical = TropicalOpticalAlgebra::new((64, 64));
let tropical_sum = tropical.tropical_add(&field_a, &field_b); // Pointwise min phase
let phase_distance = tropical.phase_distance(&field_a, &field_b);
println!("Phase distance: {:.4}", phase_distance);
use amari_functional::space::{MultivectorHilbertSpace, HilbertSpace, InnerProductSpace};
use amari_functional::operator::MatrixOperator;
use amari_functional::spectral::spectral_decompose;
// Create the Hilbert space Cl(2,0,0) ≅ ℝ⁴
let space: MultivectorHilbertSpace<2, 0, 0> = MultivectorHilbertSpace::new();
// Create orthogonal elements
let x = space.from_coefficients(&[1.0, 2.0, 0.0, 0.0]).unwrap();
let y = space.from_coefficients(&[0.0, 0.0, 3.0, 4.0]).unwrap();
// Inner product and norm
let ip = space.inner_product(&x, &y); // 0.0 (orthogonal)
let norm_x = space.norm(&x); // √5
// Create a symmetric matrix operator (Hamiltonian)
let hamiltonian = MatrixOperator::<2, 0, 0>::diagonal(&[0.0, 1.0, 2.0, 3.0]).unwrap();
// Spectral decomposition: H = Σᵢ λᵢ Pᵢ
let spectral = spectral_decompose(&hamiltonian, 100, 1e-10).unwrap();
let eigenvalues = spectral.eigenvalues();
println!("Energy levels: {:?}", eigenvalues.iter().map(|e| e.value).collect::<Vec<_>>());
// Functional calculus: compute e^{-βH} for thermal states
let beta = 0.5;
let thermal = spectral.apply_function(|E| (-beta * E).exp(), &x);
use amari_topology::{SimplicialComplex, Simplex, Filtration, PersistentHomology};
// Build a simplicial complex (hollow tetrahedron = 2-sphere)
let mut sphere = SimplicialComplex::new();
sphere.add_simplex(Simplex::new(vec![0, 1, 2]));
sphere.add_simplex(Simplex::new(vec![0, 1, 3]));
sphere.add_simplex(Simplex::new(vec![0, 2, 3]));
sphere.add_simplex(Simplex::new(vec![1, 2, 3]));
// Compute Betti numbers
let betti = sphere.betti_numbers();
assert_eq!(betti[0], 1); // 1 connected component
assert_eq!(betti[1], 0); // No 1D holes
assert_eq!(betti[2], 1); // 1 void (sphere encloses space)
// Euler characteristic: χ = V - E + F = 4 - 6 + 4 = 2
assert_eq!(sphere.euler_characteristic(), 2);
// Persistent homology for topological data analysis
let mut filt = Filtration::new();
filt.add(0.0, Simplex::new(vec![0])); // Points born at t=0
filt.add(0.0, Simplex::new(vec![1]));
filt.add(0.0, Simplex::new(vec![2]));
filt.add(1.0, Simplex::new(vec![0, 1])); // Edge connects 0-1 at t=1
filt.add(2.0, Simplex::new(vec![1, 2])); // Edge connects 1-2 at t=2
filt.add(3.0, Simplex::new(vec![0, 2])); // Closes loop at t=3
let ph = PersistentHomology::compute(&mut filt).unwrap();
let betti_t3 = ph.diagram().betti_at(3.5);
// At t=3.5: 1 component (β₀=1), 1 loop (β₁=1)
use amari_probabilistic::distribution::{GaussianMultivector, Distribution, MultivectorDistribution};
use amari_probabilistic::stochastic::{GeometricBrownianMotion, StochasticProcess};
// Gaussian distribution on Cl(3,0,0) - 8-dimensional multivector space
let gaussian = GaussianMultivector::<3, 0, 0>::standard();
// Draw samples
let mut rng = rand::thread_rng();
let sample = gaussian.sample(&mut rng);
println!("Sample: {:?}", sample.to_vec());
// Evaluate log-probability
let log_p = gaussian.log_prob(&sample).unwrap();
println!("Log probability: {:.3}", log_p);
// Grade-concentrated distribution (e.g., only on bivectors)
let bivector_dist = GaussianMultivector::<3, 0, 0>::grade_concentrated(2, 1.0).unwrap();
// Geometric Brownian Motion on multivector space
let gbm = GeometricBrownianMotion::<3, 0, 0>::new(0.1, 0.2); // drift=0.1, volatility=0.2
let path = gbm.sample_path(0.0, 1.0, 100, &mut rng).unwrap();
println!("Path has {} points", path.len());
// MCMC sampling with Metropolis-Hastings
use amari_probabilistic::sampling::MetropolisHastings;
let sampler = MetropolisHastings::new(gaussian.clone(), 0.5); // step_size=0.5
let samples = sampler.sample_n(&mut rng, 1000);
println!("Drew {} MCMC samples", samples.len());
use amari_dynamics::{
LorenzSystem, VanDerPolOscillator, RungeKutta4, ODESolver,
stability::{find_fixed_point, analyze_stability},
lyapunov::compute_lyapunov_spectrum,
bifurcation::{BifurcationDiagram, ContinuationConfig},
};
use amari_core::Multivector;
// Create classic Lorenz system (sigma=10, rho=28, beta=8/3)
let lorenz = LorenzSystem::classic();
// Initial condition as multivector
let mut initial: Multivector<3, 0, 0> = Multivector::zero();
initial.set(1, 1.0); // x
initial.set(2, 1.0); // y
initial.set(4, 1.0); // z
// Integrate trajectory with RK4
let solver = RungeKutta4::new();
let trajectory = solver.solve(&lorenz, initial.clone(), 0.0, 50.0, 5000).unwrap();
println!("Trajectory has {} points", trajectory.len());
let (x, y, z) = (
trajectory.final_state().unwrap().get(1),
trajectory.final_state().unwrap().get(2),
trajectory.final_state().unwrap().get(4),
);
println!("Final state: ({:.3}, {:.3}, {:.3})", x, y, z);
// Compute Lyapunov exponents for chaos detection
let spectrum = compute_lyapunov_spectrum(&lorenz, &initial, 10000, 0.01).unwrap();
println!("Lyapunov exponents: {:?}", spectrum.exponents);
println!("Sum: {:.4} (negative = dissipative)", spectrum.sum());
if spectrum.exponents[0] > 0.0 {
println!("System is chaotic!");
}
// Van der Pol stability analysis
let vdp = VanDerPolOscillator::new(1.0);
let mut guess: Multivector<2, 0, 0> = Multivector::zero();
guess.set(1, 0.1);
guess.set(2, 0.1);
let fp = find_fixed_point(&vdp, &guess, 1e-10).unwrap();
let stability = analyze_stability(&vdp, &fp.point).unwrap();
println!("Fixed point stability: {:?}", stability.stability_type);
// Bifurcation diagram for logistic map
let config = ContinuationConfig {
parameter_range: (2.5, 4.0),
num_points: 1000,
transient: 500,
samples: 100,
..Default::default()
};
let diagram = BifurcationDiagram::compute(|r| LogisticMap::new(r), &config).unwrap();
println!("Bifurcation diagram: {} parameter values", diagram.branches().len());
import init, { WasmMultivector, WasmTropicalNumber, WasmDualNumber } from '@justinelliottcobb/amari-wasm';
async function main() {
// Initialize the WASM module
await init();
// Geometric Algebra: Create and rotate vectors
const e1 = WasmMultivector.basisVector(0);
const e2 = WasmMultivector.basisVector(1);
const bivector = e1.geometricProduct(e2);
console.log('Geometric product:', bivector.toString());
// Tropical Algebra: Neural network operations
const trop1 = WasmTropicalNumber.new(3.0);
const trop2 = WasmTropicalNumber.new(5.0);
const sum = trop1.tropicalAdd(trop2); // max(3, 5) = 5
const product = trop1.tropicalMul(trop2); // 3 + 5 = 8
console.log('Tropical operations:', sum.getValue(), product.getValue());
// Automatic Differentiation: Compute derivatives
const x = WasmDualNumber.new(2.0, 1.0);
const xSquared = x.mul(x); // f(x) = x², f'(x) = 2x
console.log('f(2) =', xSquared.getValue(), "f'(2) =", xSquared.getDerivative());
// Clean up WASM memory
e1.free(); e2.free(); bivector.free();
trop1.free(); trop2.free(); sum.free(); product.free();
x.free(); xSquared.free();
}
main();
Domain Crates (provide mathematical APIs):
amari-core: Core Clifford algebra types and CPU implementationsamari-measure: Measure theory, sigma-algebras, and integrationamari-calculus: Differential calculus with geometric algebraamari-probabilistic: Probability distributions on multivector spaces, stochastic processes, MCMCamari-functional: Hilbert spaces, bounded operators, spectral decomposition, Sobolev spacesamari-topology: Algebraic topology, simplicial complexes, persistent homology, Morse theoryamari-dynamics: Dynamical systems, ODE solvers, stability analysis, bifurcations, Lyapunov exponents, phase portraitsamari-holographic: Vector Symbolic Architectures (VSA), binding algebras, holographic memory, optical field operationsamari-tropical: Tropical (max-plus) algebra for optimizationamari-dual: Dual numbers for automatic differentiationamari-fusion: Unified Tropical-Dual-Clifford systemamari-info-geom: Information geometry and statistical manifoldsamari-automata: Cellular automata with geometric algebraamari-network: Graph neural networks and network analysisamari-relativistic: Spacetime algebra and relativistic physicsamari-enumerative: Enumerative geometry and algebraic curvesamari-optimization: Gradient-based optimization algorithmsamari-flynn: Probabilistic verification contractsIntegration Crates (consume domain APIs):
amari-gpu: Multi-GPU acceleration with WebGPUamari-wasm: WebAssembly bindings for TypeScript/JavaScriptamari: Umbrella crate re-exporting all features// Multivector in Clifford algebra Cl(P,Q,R)
// P: positive signature, Q: negative signature, R: zero signature
Multivector<const P: usize, const Q: usize, const R: usize>
// Tropical numbers (max-plus semiring)
TropicalNumber<T: Float> // Use TropicalNumber::new(value)
// Dual numbers for automatic differentiation
DualNumber<T: Float> // Use DualNumber::new(value, derivative)
// Multi-variable dual numbers
MultiDualNumber<T: Float> // Use MultiDualNumber::new(value, gradients)
// Tropical-Dual-Clifford unified system
TropicalDualClifford<T: Float, const DIM: usize>
// Common algebras
type Cl3 = Multivector<3, 0, 0>; // 3D Euclidean
type Spacetime = Multivector<1, 3, 0>; // Minkowski spacetime
type PGA3D = Multivector<3, 0, 1>; // Projective Geometric Algebra
ab = a·b + a∧b // Geometric product = inner + outer product
a ⊕ b = max(a, b) // Tropical addition
a ⊙ b = a + b // Tropical multiplication
Applications: Path optimization, sequence decoding, dynamic programming
a + εb where ε² = 0
(a + εb) + (c + εd) = (a + c) + ε(b + d)
(a + εb) × (c + εd) = ac + ε(ad + bc)
Applications: Automatic differentiation, gradient computation
Version 0.12.0 introduced significant API improvements for better encapsulation:
// Before (v0.11.x)
let a = TropicalNumber(3.0);
let value = a.0;
let sum = a.tropical_add(b);
// After (v0.12.0+)
let a = TropicalNumber::new(3.0);
let value = a.value();
let sum = a.tropical_add(&b); // Now takes reference
// Before (v0.11.x)
let x = DualNumber { real: 3.0, dual: 1.0 };
let value = x.real;
// After (v0.12.0+)
let x = DualNumber::new(3.0, 1.0);
let value = x.value();
let deriv = x.derivative();
See MIGRATION_v0.12.0.md for complete migration guide.
The Amari Examples Suite provides comprehensive interactive documentation:
Live Visualizations: 19 interactive visualizations demonstrating mathematical concepts
Comprehensive API Reference: 77 classes with 300+ methods fully documented
Interactive Playground: Write and run JavaScript code with live WASM execution
| Module | Status | Feature Flag |
|---|---|---|
| Core GA | ✅ Enabled | default |
| Info Geometry | ✅ Enabled | default |
| Relativistic | ✅ Enabled | default |
| Network | ✅ Enabled | default |
| Measure | ✅ Enabled | measure |
| Calculus | ✅ Enabled | calculus |
| Dual | ✅ Enabled | dual |
| Enumerative | ✅ Enabled | enumerative |
| Automata | ✅ Enabled | automata |
| Fusion | ✅ Enabled | fusion |
| Holographic | ✅ Enabled | holographic |
| Optical Fields | ✅ Enabled | holographic |
| Probabilistic | ✅ Enabled | probabilistic |
| Functional | ✅ Enabled | functional |
| Topology | ✅ Enabled | topology |
| Dynamics | ✅ New in v0.17.0 | dynamics |
| Tropical | ❌ Disabled | - |
Note: Tropical GPU module temporarily disabled due to Rust orphan impl rules. Use CPU implementations from domain crates.
The dynamics feature provides GPU-accelerated dynamical systems operations:
The topology feature provides GPU-accelerated computational topology operations:
The holographic feature includes GPU-accelerated optical field operations:
cargowasm-pack (for WASM builds)# Run all tests
cargo test --workspace
# Run with all features
cargo test --workspace --all-features
# Build documentation
cargo doc --workspace --open
cd amari-wasm
wasm-pack build --target web
The library is optimized for high-performance applications:
Contributions are welcome. For development setup:
git clone https://github.com/justinelliottcobb/Amari.git
cd Amari
cargo test --workspace
This project is licensed under either of:
at your option.
"Geometry is the art of correct reasoning from incorrectly drawn figures." - Henri Poincaré