@justinelliottcobb/amari-wasm 0.15.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @justinelliottcobb/amari-wasm v0.15.1
1
+ # @justinelliottcobb/amari-wasm v0.16.0
2
2
 
3
3
  **Unified Mathematical Computing Library with High-Precision WebAssembly Support**
4
4
 
@@ -19,6 +19,7 @@ Amari is a comprehensive mathematical computing library that brings advanced alg
19
19
  - **Holographic Memory** *(v0.12.3)*: Vector Symbolic Architecture for associative memory with binding and bundling operations
20
20
  - **Functional Analysis** *(v0.15.0)*: Hilbert spaces, linear operators, spectral decomposition, and Sobolev spaces
21
21
  - **Optical Field Operations** *(v0.15.1)*: GA-native Lee hologram encoding for DMD displays and VSA-based optical processing
22
+ - **Computational Topology** *(v0.16.0)*: Simplicial complexes, homology computation, persistent homology, and Morse theory
22
23
  - **Probability Theory** *(v0.13.0)*: Distributions on multivector spaces, MCMC sampling, and Monte Carlo estimation
23
24
  - **Relativistic Physics**: Spacetime algebra (Cl(1,3)) with WebAssembly-compatible precision
24
25
  - **Spacecraft Orbital Mechanics**: Full-precision trajectory calculations in browsers
@@ -570,6 +571,202 @@ async function opticalDemo() {
570
571
  opticalDemo();
571
572
  ```
572
573
 
574
+ ### Computational Topology *(v0.16.0)*
575
+
576
+ Compute homology groups, persistent homology, and analyze topological features of data:
577
+
578
+ ```typescript
579
+ import init, {
580
+ WasmSimplex,
581
+ WasmSimplicialComplex,
582
+ WasmFiltration,
583
+ WasmPersistentHomology,
584
+ ripsFromDistances,
585
+ findCriticalPoints2D,
586
+ WasmMorseComplex
587
+ } from '@justinelliottcobb/amari-wasm';
588
+
589
+ async function topologyDemo() {
590
+ await init();
591
+
592
+ // ========================================
593
+ // Simplicial Complexes and Homology
594
+ // ========================================
595
+
596
+ // Create a triangle (2-simplex with all faces)
597
+ const complex = new WasmSimplicialComplex();
598
+ complex.addSimplex([0, 1, 2]); // Triangle
599
+
600
+ // Closure property: edges and vertices automatically added
601
+ console.log(`Vertices: ${complex.vertexCount()}`); // 3
602
+ console.log(`Edges: ${complex.edgeCount()}`); // 3
603
+ console.log(`Triangles: ${complex.simplexCount(2)}`); // 1
604
+
605
+ // Compute Betti numbers (topological invariants)
606
+ const betti = complex.bettiNumbers();
607
+ console.log(`β₀ = ${betti[0]}`); // 1 (one connected component)
608
+ console.log(`β₁ = ${betti[1]}`); // 0 (no holes - filled triangle)
609
+
610
+ // Euler characteristic: χ = V - E + F
611
+ console.log(`χ = ${complex.eulerCharacteristic()}`); // 1
612
+
613
+ // ========================================
614
+ // Circle (unfilled triangle boundary)
615
+ // ========================================
616
+
617
+ const circle = new WasmSimplicialComplex();
618
+ circle.addSimplex([0, 1]); // Edge 0-1
619
+ circle.addSimplex([1, 2]); // Edge 1-2
620
+ circle.addSimplex([2, 0]); // Edge 2-0
621
+
622
+ const circleBetti = circle.bettiNumbers();
623
+ console.log(`Circle β₀ = ${circleBetti[0]}`); // 1 (connected)
624
+ console.log(`Circle β₁ = ${circleBetti[1]}`); // 1 (one hole!)
625
+
626
+ // ========================================
627
+ // Persistent Homology
628
+ // ========================================
629
+
630
+ // Build a filtration (simplices appearing over time)
631
+ const filt = new WasmFiltration();
632
+ filt.add(0.0, [0]); // Point 0 at t=0
633
+ filt.add(0.0, [1]); // Point 1 at t=0
634
+ filt.add(0.0, [2]); // Point 2 at t=0
635
+ filt.add(1.0, [0, 1]); // Edge 0-1 at t=1
636
+ filt.add(2.0, [1, 2]); // Edge 1-2 at t=2
637
+ filt.add(3.0, [0, 2]); // Edge 0-2 at t=3 (creates loop)
638
+
639
+ // Compute persistent homology
640
+ const ph = WasmPersistentHomology.compute(filt);
641
+
642
+ // Get persistence diagram as [dim, birth, death] triples
643
+ const diagram = ph.getDiagram();
644
+ for (let i = 0; i < diagram.length; i += 3) {
645
+ const dim = diagram[i];
646
+ const birth = diagram[i + 1];
647
+ const death = diagram[i + 2];
648
+ console.log(`H${dim}: born at ${birth}, dies at ${death === Infinity ? '∞' : death}`);
649
+ }
650
+
651
+ // Betti numbers at different times
652
+ console.log(`Betti at t=0.5: ${ph.bettiAt(0.5)}`); // [3, 0] - 3 components
653
+ console.log(`Betti at t=3.5: ${ph.bettiAt(3.5)}`); // [1, 1] - 1 component, 1 loop
654
+
655
+ // ========================================
656
+ // Vietoris-Rips Filtration from Point Cloud
657
+ // ========================================
658
+
659
+ // 3 points forming an equilateral triangle
660
+ // Distances: d(0,1)=1, d(1,2)=1, d(0,2)=1
661
+ const numPoints = 3;
662
+ const maxDim = 2;
663
+ // Upper triangular pairwise distances: [d(0,1), d(0,2), d(1,2)]
664
+ const distances = [1.0, 1.0, 1.0];
665
+
666
+ const ripsFilt = ripsFromDistances(numPoints, maxDim, distances);
667
+ const ripsPH = WasmPersistentHomology.compute(ripsFilt);
668
+ console.log(`Rips intervals in H0: ${ripsPH.intervalCount(0)}`);
669
+ console.log(`Rips intervals in H1: ${ripsPH.intervalCount(1)}`);
670
+
671
+ // ========================================
672
+ // Morse Theory (Critical Points)
673
+ // ========================================
674
+
675
+ // Precompute f(x,y) = x² + y² on a grid
676
+ const resolution = 20;
677
+ const values = [];
678
+ for (let i = 0; i <= resolution; i++) {
679
+ const x = -1.0 + (2.0 * i) / resolution;
680
+ for (let j = 0; j <= resolution; j++) {
681
+ const y = -1.0 + (2.0 * j) / resolution;
682
+ values.push(x * x + y * y);
683
+ }
684
+ }
685
+
686
+ const criticalPoints = findCriticalPoints2D(
687
+ resolution,
688
+ -1.0, 1.0, // x range
689
+ -1.0, 1.0, // y range
690
+ 0.1, // tolerance
691
+ values
692
+ );
693
+
694
+ console.log(`Found ${criticalPoints.length} critical points`);
695
+ for (const cp of criticalPoints) {
696
+ console.log(` ${cp.criticalType} at (${cp.position[0].toFixed(2)}, ${cp.position[1].toFixed(2)}), value=${cp.value.toFixed(2)}`);
697
+ }
698
+
699
+ // Morse complex analysis
700
+ const morse = new WasmMorseComplex(criticalPoints);
701
+ const counts = morse.countsByIndex();
702
+ console.log(`Critical points by index: ${counts}`);
703
+
704
+ // Verify Morse inequalities: c_k >= β_k
705
+ const complexBetti = complex.bettiNumbers();
706
+ console.log(`Weak Morse inequalities hold: ${morse.checkWeakMorseInequalities(complexBetti)}`);
707
+
708
+ // Clean up WASM memory
709
+ complex.free();
710
+ circle.free();
711
+ filt.free();
712
+ ph.free();
713
+ ripsFilt.free();
714
+ ripsPH.free();
715
+ morse.free();
716
+ criticalPoints.forEach(cp => cp.free());
717
+ }
718
+
719
+ topologyDemo();
720
+ ```
721
+
722
+ #### Topology API
723
+
724
+ **WasmSimplex:**
725
+ - `new(vertices)`: Create simplex from vertex indices
726
+ - `dimension()`: Get dimension (vertices - 1)
727
+ - `getVertices()`: Get sorted vertex array
728
+ - `orientation()`: Get orientation sign (+1 or -1)
729
+ - `containsVertex(v)`: Check if vertex is in simplex
730
+ - `faces(k)`: Get all k-dimensional faces
731
+ - `boundaryFaces()`: Get boundary faces with signs
732
+
733
+ **WasmSimplicialComplex:**
734
+ - `new()`: Create empty complex
735
+ - `addSimplex(vertices)`: Add simplex and all its faces
736
+ - `contains(vertices)`: Check if simplex exists
737
+ - `dimension()`: Get maximum simplex dimension
738
+ - `simplexCount(dim)`: Count simplices in dimension
739
+ - `totalSimplexCount()`: Total simplex count
740
+ - `vertexCount()`: Count 0-simplices
741
+ - `edgeCount()`: Count 1-simplices
742
+ - `bettiNumbers()`: Compute [β₀, β₁, β₂, ...]
743
+ - `eulerCharacteristic()`: Compute χ = Σ(-1)^k f_k
744
+ - `fVector()`: Get face counts [f₀, f₁, f₂, ...]
745
+ - `isConnected()`: Check if complex is connected
746
+ - `connectedComponents()`: Count components
747
+
748
+ **WasmFiltration:**
749
+ - `new()`: Create empty filtration
750
+ - `add(time, vertices)`: Add simplex at filtration time
751
+ - `isEmpty()`: Check if filtration is empty
752
+ - `complexAt(time)`: Get complex at given time
753
+ - `bettiAt(time)`: Get Betti numbers at time
754
+
755
+ **WasmPersistentHomology:**
756
+ - `compute(filtration)`: Compute persistent homology
757
+ - `getDiagram()`: Get [dim, birth, death, ...] triples
758
+ - `bettiAt(time)`: Get Betti numbers at time
759
+ - `intervalCount(dim)`: Count intervals in dimension
760
+
761
+ **Standalone Functions:**
762
+ - `ripsFromDistances(numPoints, maxDim, distances)`: Create Rips filtration
763
+ - `findCriticalPoints2D(resolution, xMin, xMax, yMin, yMax, tolerance, values)`: Find critical points
764
+
765
+ **WasmMorseComplex:**
766
+ - `new(criticalPoints)`: Create from critical points
767
+ - `countsByIndex()`: Get counts by Morse index
768
+ - `checkWeakMorseInequalities(betti)`: Verify c_k >= β_k
769
+
573
770
  #### Optical Field API
574
771
 
575
772
  **WasmOpticalRotorField:**
@@ -681,6 +878,9 @@ opticalDemo();
681
878
  - **Embedding Retrieval**: Content-addressable semantic search in vector databases
682
879
  - **Holographic Displays**: Lee hologram encoding for DMD and SLM devices
683
880
  - **Optical Computing**: Phase-encoded VSA operations for optical neural networks
881
+ - **Topological Data Analysis**: Persistent homology for shape and feature detection
882
+ - **Computational Biology**: Protein structure analysis via simplicial complexes
883
+ - **Sensor Networks**: Coverage analysis using homology
684
884
 
685
885
  ## API Reference
686
886
 
@@ -759,6 +959,21 @@ opticalDemo();
759
959
  - `WasmOpticalCodebook.get(symbol)`: Get field for symbol
760
960
  - `WasmTropicalOpticalAlgebra.tropicalAdd(a, b)`: Pointwise minimum phase
761
961
 
962
+ ### Topology Operations
963
+
964
+ - `WasmSimplex.new(vertices)`: Create simplex from vertex array
965
+ - `WasmSimplex.dimension()`: Get simplex dimension
966
+ - `WasmSimplex.faces(k)`: Get k-dimensional faces
967
+ - `WasmSimplicialComplex.new()`: Create empty complex
968
+ - `WasmSimplicialComplex.addSimplex(vertices)`: Add simplex with closure
969
+ - `WasmSimplicialComplex.bettiNumbers()`: Compute Betti numbers
970
+ - `WasmSimplicialComplex.eulerCharacteristic()`: Compute Euler characteristic
971
+ - `WasmFiltration.add(time, vertices)`: Add simplex at filtration time
972
+ - `WasmPersistentHomology.compute(filtration)`: Compute persistence
973
+ - `WasmPersistentHomology.getDiagram()`: Get persistence diagram
974
+ - `ripsFromDistances(n, dim, distances)`: Build Rips filtration
975
+ - `findCriticalPoints2D(...)`: Find Morse critical points
976
+
762
977
  ## Examples
763
978
 
764
979
  Check out the [examples directory](https://github.com/justinelliottcobb/Amari/tree/master/examples) for more detailed usage:
package/package.json CHANGED
@@ -1,32 +1,37 @@
1
1
  {
2
2
  "name": "@justinelliottcobb/amari-wasm",
3
- "type": "module",
4
- "collaborators": [
5
- "Amari Contributors"
6
- ],
7
- "description": "WebAssembly bindings for Amari mathematical computing library - geometric algebra, tropical algebra, automatic differentiation, measure theory, fusion systems, and information geometry",
8
- "version": "0.15.1",
9
- "license": "MIT OR Apache-2.0",
3
+ "version": "0.16.0",
4
+ "description": "WebAssembly bindings for Amari mathematical computing library",
5
+ "scripts": {
6
+ "build": "wasm-pack build --target web --out-dir pkg --scope justinelliottcobb",
7
+ "build-all": "npm run build && npm run build:node && npm run build:bundler",
8
+ "build:node": "wasm-pack build --target nodejs --out-dir pkg-node --scope justinelliottcobb",
9
+ "build:bundler": "wasm-pack build --target bundler --out-dir pkg-bundler --scope justinelliottcobb",
10
+ "test": "wasm-pack test --node",
11
+ "clean": "rm -rf pkg pkg-node pkg-bundler"
12
+ },
10
13
  "repository": {
11
14
  "type": "git",
12
- "url": "https://github.com/justinelliottcobb/Amari"
15
+ "url": "https://github.com/justinelliottcobb/Amari.git"
13
16
  },
14
- "files": [
15
- "amari_wasm_bg.wasm",
16
- "amari_wasm.js",
17
- "amari_wasm.d.ts"
18
- ],
19
- "main": "amari_wasm.js",
20
- "homepage": "https://github.com/justinelliottcobb/Amari",
21
- "types": "amari_wasm.d.ts",
22
- "sideEffects": [
23
- "./snippets/*"
24
- ],
17
+ "license": "MIT OR Apache-2.0",
25
18
  "keywords": [
26
19
  "wasm",
27
20
  "webassembly",
28
21
  "geometric-algebra",
29
22
  "tropical-algebra",
30
- "autodiff"
31
- ]
23
+ "autodiff",
24
+ "mathematics",
25
+ "topology",
26
+ "persistent-homology"
27
+ ],
28
+ "files": [
29
+ "pkg/",
30
+ "pkg-node/",
31
+ "pkg-bundler/"
32
+ ],
33
+ "devDependencies": {},
34
+ "engines": {
35
+ "node": ">=16"
36
+ }
32
37
  }