@justinelliottcobb/amari-wasm 0.14.0 → 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 +538 -1
- package/package.json +26 -21
- package/amari_wasm.d.ts +0 -3554
- package/amari_wasm.js +0 -8519
- package/amari_wasm_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @justinelliottcobb/amari-wasm v0.
|
|
1
|
+
# @justinelliottcobb/amari-wasm v0.16.0
|
|
2
2
|
|
|
3
3
|
**Unified Mathematical Computing Library with High-Precision WebAssembly Support**
|
|
4
4
|
|
|
@@ -17,6 +17,9 @@ Amari is a comprehensive mathematical computing library that brings advanced alg
|
|
|
17
17
|
- **Automatic Differentiation**: Forward-mode AD with dual numbers for exact derivatives
|
|
18
18
|
- **Measure Theory** *(v0.10.0)*: Lebesgue integration, probability measures, and measure-theoretic foundations
|
|
19
19
|
- **Holographic Memory** *(v0.12.3)*: Vector Symbolic Architecture for associative memory with binding and bundling operations
|
|
20
|
+
- **Functional Analysis** *(v0.15.0)*: Hilbert spaces, linear operators, spectral decomposition, and Sobolev spaces
|
|
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
|
|
20
23
|
- **Probability Theory** *(v0.13.0)*: Distributions on multivector spaces, MCMC sampling, and Monte Carlo estimation
|
|
21
24
|
- **Relativistic Physics**: Spacetime algebra (Cl(1,3)) with WebAssembly-compatible precision
|
|
22
25
|
- **Spacecraft Orbital Mechanics**: Full-precision trajectory calculations in browsers
|
|
@@ -334,6 +337,488 @@ async function probabilisticDemo() {
|
|
|
334
337
|
probabilisticDemo();
|
|
335
338
|
```
|
|
336
339
|
|
|
340
|
+
### Functional Analysis *(v0.15.0)*
|
|
341
|
+
|
|
342
|
+
Work with Hilbert spaces, linear operators, and spectral decomposition on multivector spaces:
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import init, {
|
|
346
|
+
WasmHilbertSpace,
|
|
347
|
+
WasmMatrixOperator,
|
|
348
|
+
WasmSpectralDecomposition,
|
|
349
|
+
WasmSobolevSpace,
|
|
350
|
+
powerMethod,
|
|
351
|
+
computeEigenvalues
|
|
352
|
+
} from '@justinelliottcobb/amari-wasm';
|
|
353
|
+
|
|
354
|
+
async function functionalDemo() {
|
|
355
|
+
await init();
|
|
356
|
+
|
|
357
|
+
// Create a Hilbert space Cl(2,0,0) ≅ ℝ⁴
|
|
358
|
+
const hilbert = new WasmHilbertSpace();
|
|
359
|
+
console.log(`Dimension: ${hilbert.dimension()}`); // 4
|
|
360
|
+
console.log(`Signature: ${hilbert.signature()}`); // [2, 0, 0]
|
|
361
|
+
|
|
362
|
+
// Create multivectors from coefficients [scalar, e1, e2, e12]
|
|
363
|
+
const x = hilbert.fromCoefficients([1.0, 2.0, 3.0, 4.0]);
|
|
364
|
+
const y = hilbert.fromCoefficients([0.5, 1.5, 2.5, 3.5]);
|
|
365
|
+
|
|
366
|
+
// Inner product and norm
|
|
367
|
+
const inner = hilbert.innerProduct(x, y);
|
|
368
|
+
console.log(`⟨x, y⟩ = ${inner}`);
|
|
369
|
+
|
|
370
|
+
const norm = hilbert.norm(x);
|
|
371
|
+
console.log(`‖x‖ = ${norm}`);
|
|
372
|
+
|
|
373
|
+
// Orthogonal projection
|
|
374
|
+
const proj = hilbert.project(x, y);
|
|
375
|
+
console.log(`proj_y(x) = ${proj}`);
|
|
376
|
+
|
|
377
|
+
// Create a matrix operator (4x4 matrix in row-major order)
|
|
378
|
+
const A = new WasmMatrixOperator([
|
|
379
|
+
4, 1, 0, 0,
|
|
380
|
+
1, 3, 1, 0,
|
|
381
|
+
0, 1, 2, 1,
|
|
382
|
+
0, 0, 1, 1
|
|
383
|
+
]);
|
|
384
|
+
|
|
385
|
+
// Apply operator to a vector
|
|
386
|
+
const Ax = A.apply(x);
|
|
387
|
+
console.log(`Ax = ${Ax}`);
|
|
388
|
+
|
|
389
|
+
// Operator properties
|
|
390
|
+
console.log(`‖A‖ = ${A.operatorNorm()}`);
|
|
391
|
+
console.log(`tr(A) = ${A.trace()}`);
|
|
392
|
+
console.log(`Symmetric: ${A.isSymmetric(1e-10)}`);
|
|
393
|
+
|
|
394
|
+
// Spectral decomposition for symmetric matrices
|
|
395
|
+
const decomp = WasmSpectralDecomposition.compute(A, 100, 1e-10);
|
|
396
|
+
const eigenvalues = decomp.eigenvalues();
|
|
397
|
+
console.log(`Eigenvalues: ${eigenvalues}`);
|
|
398
|
+
console.log(`Spectral radius: ${decomp.spectralRadius()}`);
|
|
399
|
+
console.log(`Condition number: ${decomp.conditionNumber()}`);
|
|
400
|
+
|
|
401
|
+
// Functional calculus: apply f(A) = exp(A)
|
|
402
|
+
const expAx = decomp.applyFunction((lambda) => Math.exp(lambda), x);
|
|
403
|
+
console.log(`exp(A)x = ${expAx}`);
|
|
404
|
+
|
|
405
|
+
// Power method for dominant eigenvalue
|
|
406
|
+
const dominant = powerMethod(A, null, 100, 1e-10);
|
|
407
|
+
console.log(`Dominant eigenvalue: ${dominant[0]}`);
|
|
408
|
+
|
|
409
|
+
// Sobolev spaces for PDE analysis
|
|
410
|
+
const h1 = new WasmSobolevSpace(1, 0.0, 1.0); // H^1([0,1])
|
|
411
|
+
console.log(`Poincaré constant: ${h1.poincareConstant()}`);
|
|
412
|
+
|
|
413
|
+
// Compute H^1 norm of sin(πx)
|
|
414
|
+
const f = (x: number) => Math.sin(Math.PI * x);
|
|
415
|
+
const df = (x: number) => Math.PI * Math.cos(Math.PI * x);
|
|
416
|
+
const h1Norm = h1.h1Norm(f, df);
|
|
417
|
+
console.log(`‖sin(πx)‖_{H^1} = ${h1Norm}`);
|
|
418
|
+
|
|
419
|
+
// Clean up WASM memory
|
|
420
|
+
hilbert.free();
|
|
421
|
+
A.free();
|
|
422
|
+
decomp.free();
|
|
423
|
+
h1.free();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
functionalDemo();
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### Functional Analysis API
|
|
430
|
+
|
|
431
|
+
**WasmHilbertSpace:**
|
|
432
|
+
- `new()`: Create Hilbert space Cl(2,0,0) ≅ ℝ⁴
|
|
433
|
+
- `dimension()`: Get space dimension
|
|
434
|
+
- `signature()`: Get Clifford algebra signature [p, q, r]
|
|
435
|
+
- `fromCoefficients(coeffs)`: Create multivector from coefficients
|
|
436
|
+
- `innerProduct(x, y)`: Compute ⟨x, y⟩
|
|
437
|
+
- `norm(x)`: Compute ‖x‖
|
|
438
|
+
- `distance(x, y)`: Compute d(x, y) = ‖x - y‖
|
|
439
|
+
- `normalize(x)`: Normalize to unit length
|
|
440
|
+
- `project(x, y)`: Orthogonal projection of x onto y
|
|
441
|
+
- `isOrthogonal(x, y, tol)`: Check orthogonality
|
|
442
|
+
|
|
443
|
+
**WasmMatrixOperator:**
|
|
444
|
+
- `new(entries)`: Create from 16 entries (4×4 row-major)
|
|
445
|
+
- `identity()`: Create identity operator
|
|
446
|
+
- `zero()`: Create zero operator
|
|
447
|
+
- `diagonal(entries)`: Create diagonal matrix
|
|
448
|
+
- `scaling(lambda)`: Create λI
|
|
449
|
+
- `apply(x)`: Apply operator T(x)
|
|
450
|
+
- `operatorNorm()`: Compute ‖T‖
|
|
451
|
+
- `isSymmetric(tol)`: Check symmetry
|
|
452
|
+
- `add(other)`: Add operators
|
|
453
|
+
- `compose(other)`: Compose operators (matrix multiply)
|
|
454
|
+
- `scale(lambda)`: Scale by scalar
|
|
455
|
+
- `transpose()`: Compute transpose
|
|
456
|
+
- `trace()`: Compute trace
|
|
457
|
+
|
|
458
|
+
**WasmSpectralDecomposition:**
|
|
459
|
+
- `compute(matrix, maxIter, tol)`: Compute eigenvalue decomposition
|
|
460
|
+
- `eigenvalues()`: Get eigenvalues
|
|
461
|
+
- `eigenvectors()`: Get eigenvectors (flattened)
|
|
462
|
+
- `isComplete()`: Check if decomposition is complete
|
|
463
|
+
- `spectralRadius()`: Get largest |eigenvalue|
|
|
464
|
+
- `conditionNumber()`: Get condition number
|
|
465
|
+
- `isPositiveDefinite()`: Check positive definiteness
|
|
466
|
+
- `apply(x)`: Apply reconstructed operator
|
|
467
|
+
- `applyFunction(f, x)`: Functional calculus f(T)x
|
|
468
|
+
|
|
469
|
+
**WasmSobolevSpace:**
|
|
470
|
+
- `new(order, lower, upper)`: Create H^k([a,b])
|
|
471
|
+
- `h1UnitInterval()`: Create H^1([0,1])
|
|
472
|
+
- `h2UnitInterval()`: Create H^2([0,1])
|
|
473
|
+
- `poincareConstant()`: Get Poincaré constant
|
|
474
|
+
- `h1Norm(f, df)`: Compute H^1 norm
|
|
475
|
+
- `h1Seminorm(df)`: Compute H^1 seminorm |f|_{H^1}
|
|
476
|
+
- `l2Norm(f)`: Compute L^2 norm
|
|
477
|
+
- `l2InnerProduct(f, g)`: Compute L^2 inner product
|
|
478
|
+
|
|
479
|
+
**Standalone Functions:**
|
|
480
|
+
- `powerMethod(matrix, initial, maxIter, tol)`: Dominant eigenvalue
|
|
481
|
+
- `inverseIteration(matrix, shift, initial, maxIter, tol)`: Eigenvalue near shift
|
|
482
|
+
- `computeEigenvalues(matrix, maxIter, tol)`: All eigenvalues
|
|
483
|
+
|
|
484
|
+
### Optical Field Operations *(v0.15.1)*
|
|
485
|
+
|
|
486
|
+
Encode optical fields as binary holograms for DMD displays using geometric algebra:
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
import init, {
|
|
490
|
+
WasmOpticalRotorField,
|
|
491
|
+
WasmBinaryHologram,
|
|
492
|
+
WasmGeometricLeeEncoder,
|
|
493
|
+
WasmOpticalFieldAlgebra,
|
|
494
|
+
WasmOpticalCodebook,
|
|
495
|
+
WasmTropicalOpticalAlgebra
|
|
496
|
+
} from '@justinelliottcobb/amari-wasm';
|
|
497
|
+
|
|
498
|
+
async function opticalDemo() {
|
|
499
|
+
await init();
|
|
500
|
+
|
|
501
|
+
// Create optical rotor fields (phase + amplitude on a grid)
|
|
502
|
+
const field1 = WasmOpticalRotorField.random(256, 256, 12345n);
|
|
503
|
+
const field2 = WasmOpticalRotorField.random(256, 256, 67890n);
|
|
504
|
+
const uniform = WasmOpticalRotorField.uniform(0.0, 0.5, 256, 256);
|
|
505
|
+
|
|
506
|
+
console.log(`Field dimensions: ${field1.width} x ${field1.height}`);
|
|
507
|
+
console.log(`Total energy: ${field1.totalEnergy()}`);
|
|
508
|
+
|
|
509
|
+
// Lee hologram encoding for DMD display
|
|
510
|
+
const encoder = WasmGeometricLeeEncoder.withFrequency(256, 256, 0.25);
|
|
511
|
+
const hologram = encoder.encode(uniform);
|
|
512
|
+
|
|
513
|
+
console.log(`Hologram fill factor: ${hologram.fillFactor()}`);
|
|
514
|
+
console.log(`Theoretical efficiency: ${encoder.theoreticalEfficiency(uniform)}`);
|
|
515
|
+
|
|
516
|
+
// Get binary data for hardware interface
|
|
517
|
+
const binaryData = hologram.asBytes();
|
|
518
|
+
console.log(`Packed binary size: ${binaryData.length} bytes`);
|
|
519
|
+
|
|
520
|
+
// VSA operations on optical fields
|
|
521
|
+
const algebra = new WasmOpticalFieldAlgebra(256, 256);
|
|
522
|
+
|
|
523
|
+
// Bind two fields (rotor multiplication = phase addition)
|
|
524
|
+
const bound = algebra.bind(field1, field2);
|
|
525
|
+
|
|
526
|
+
// Compute similarity between fields
|
|
527
|
+
const similarity = algebra.similarity(field1, field1); // Self-similarity = 1.0
|
|
528
|
+
console.log(`Self-similarity: ${similarity}`);
|
|
529
|
+
|
|
530
|
+
// Unbind to retrieve original field
|
|
531
|
+
const retrieved = algebra.unbind(field1, bound);
|
|
532
|
+
const retrievalSim = algebra.similarity(retrieved, field2);
|
|
533
|
+
console.log(`Retrieval similarity: ${retrievalSim}`);
|
|
534
|
+
|
|
535
|
+
// Seed-based symbol codebook for VSA
|
|
536
|
+
const codebook = new WasmOpticalCodebook(64, 64, 42n);
|
|
537
|
+
codebook.register("AGENT");
|
|
538
|
+
codebook.register("ACTION");
|
|
539
|
+
codebook.register("TARGET");
|
|
540
|
+
|
|
541
|
+
const agentField = codebook.get("AGENT");
|
|
542
|
+
const actionField = codebook.get("ACTION");
|
|
543
|
+
console.log(`Registered symbols: ${codebook.symbols()}`);
|
|
544
|
+
|
|
545
|
+
// Tropical operations for attractor dynamics
|
|
546
|
+
const tropical = new WasmTropicalOpticalAlgebra(64, 64);
|
|
547
|
+
|
|
548
|
+
// Tropical add: pointwise minimum of phase magnitudes
|
|
549
|
+
const tropicalSum = tropical.tropicalAdd(field1, field2);
|
|
550
|
+
|
|
551
|
+
// Soft tropical add with temperature parameter
|
|
552
|
+
const softSum = tropical.softTropicalAdd(field1, field2, 10.0);
|
|
553
|
+
|
|
554
|
+
// Phase distance between fields
|
|
555
|
+
const distance = tropical.phaseDistance(field1, field2);
|
|
556
|
+
console.log(`Phase distance: ${distance}`);
|
|
557
|
+
|
|
558
|
+
// Clean up WASM memory
|
|
559
|
+
field1.free();
|
|
560
|
+
field2.free();
|
|
561
|
+
uniform.free();
|
|
562
|
+
hologram.free();
|
|
563
|
+
bound.free();
|
|
564
|
+
retrieved.free();
|
|
565
|
+
agentField.free();
|
|
566
|
+
actionField.free();
|
|
567
|
+
tropicalSum.free();
|
|
568
|
+
softSum.free();
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
opticalDemo();
|
|
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
|
+
|
|
770
|
+
#### Optical Field API
|
|
771
|
+
|
|
772
|
+
**WasmOpticalRotorField:**
|
|
773
|
+
- `random(width, height, seed)`: Create random phase field
|
|
774
|
+
- `uniform(phase, amplitude, width, height)`: Uniform field
|
|
775
|
+
- `identity(width, height)`: Identity field (phase = 0)
|
|
776
|
+
- `fromPhase(phases, width, height)`: Create from phase array
|
|
777
|
+
- `phaseAt(x, y)`: Get phase at point (radians)
|
|
778
|
+
- `amplitudeAt(x, y)`: Get amplitude at point
|
|
779
|
+
- `totalEnergy()`: Sum of squared amplitudes
|
|
780
|
+
- `normalized()`: Normalized copy (energy = 1)
|
|
781
|
+
|
|
782
|
+
**WasmGeometricLeeEncoder:**
|
|
783
|
+
- `withFrequency(width, height, frequency)`: Create horizontal carrier encoder
|
|
784
|
+
- `new(width, height, frequency, angle)`: Create with angled carrier
|
|
785
|
+
- `encode(field)`: Encode to binary hologram
|
|
786
|
+
- `modulate(field)`: Get modulated field before thresholding
|
|
787
|
+
- `theoreticalEfficiency(field)`: Compute diffraction efficiency
|
|
788
|
+
|
|
789
|
+
**WasmBinaryHologram:**
|
|
790
|
+
- `get(x, y)`: Get pixel value
|
|
791
|
+
- `set(x, y, value)`: Set pixel value
|
|
792
|
+
- `fillFactor()`: Fraction of "on" pixels
|
|
793
|
+
- `hammingDistance(other)`: Compute Hamming distance
|
|
794
|
+
- `asBytes()`: Get packed binary data
|
|
795
|
+
- `inverted()`: Create inverted copy
|
|
796
|
+
|
|
797
|
+
**WasmOpticalFieldAlgebra:**
|
|
798
|
+
- `bind(a, b)`: Rotor multiplication (phase addition)
|
|
799
|
+
- `unbind(key, bound)`: Retrieve associated field
|
|
800
|
+
- `bundle(fields, weights)`: Weighted superposition
|
|
801
|
+
- `bundleUniform(fields)`: Equal-weight bundle
|
|
802
|
+
- `similarity(a, b)`: Normalized inner product
|
|
803
|
+
- `inverse(field)`: Phase negation
|
|
804
|
+
- `scale(field, factor)`: Amplitude scaling
|
|
805
|
+
- `addPhase(field, phase)`: Add constant phase
|
|
806
|
+
|
|
807
|
+
**WasmOpticalCodebook:**
|
|
808
|
+
- `new(width, height, baseSeed)`: Create codebook
|
|
809
|
+
- `register(symbol)`: Register symbol with auto-seed
|
|
810
|
+
- `get(symbol)`: Get or generate field for symbol
|
|
811
|
+
- `contains(symbol)`: Check if symbol is registered
|
|
812
|
+
- `symbols()`: Get all registered symbol names
|
|
813
|
+
|
|
814
|
+
**WasmTropicalOpticalAlgebra:**
|
|
815
|
+
- `tropicalAdd(a, b)`: Pointwise minimum phase magnitude
|
|
816
|
+
- `tropicalMax(a, b)`: Pointwise maximum phase magnitude
|
|
817
|
+
- `tropicalMul(a, b)`: Binding (phase addition)
|
|
818
|
+
- `softTropicalAdd(a, b, beta)`: Soft minimum with temperature
|
|
819
|
+
- `phaseDistance(a, b)`: Sum of absolute phase differences
|
|
820
|
+
- `attractorConverge(initial, attractors, maxIter, tol)`: Attractor dynamics
|
|
821
|
+
|
|
337
822
|
#### Probability API
|
|
338
823
|
|
|
339
824
|
**WasmGaussianMultivector:**
|
|
@@ -391,6 +876,11 @@ probabilisticDemo();
|
|
|
391
876
|
- **Symbolic AI**: Holographic memory for associative reasoning and concept binding
|
|
392
877
|
- **Cognitive Architectures**: Brain-inspired memory systems for AI agents
|
|
393
878
|
- **Embedding Retrieval**: Content-addressable semantic search in vector databases
|
|
879
|
+
- **Holographic Displays**: Lee hologram encoding for DMD and SLM devices
|
|
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
|
|
394
884
|
|
|
395
885
|
## API Reference
|
|
396
886
|
|
|
@@ -437,6 +927,53 @@ probabilisticDemo();
|
|
|
437
927
|
- `WasmUniformMultivector.sample()`: Draw random sample
|
|
438
928
|
- `WasmMonteCarloEstimator.estimate(fn, dist, n)`: Monte Carlo expectation
|
|
439
929
|
|
|
930
|
+
### Functional Analysis Operations
|
|
931
|
+
|
|
932
|
+
- `WasmHilbertSpace.new()`: Create Hilbert space Cl(2,0,0)
|
|
933
|
+
- `WasmHilbertSpace.innerProduct(x, y)`: Compute inner product
|
|
934
|
+
- `WasmHilbertSpace.norm(x)`: Compute norm
|
|
935
|
+
- `WasmHilbertSpace.project(x, y)`: Orthogonal projection
|
|
936
|
+
- `WasmMatrixOperator.new(entries)`: Create matrix operator
|
|
937
|
+
- `WasmMatrixOperator.apply(x)`: Apply operator to vector
|
|
938
|
+
- `WasmMatrixOperator.operatorNorm()`: Compute operator norm
|
|
939
|
+
- `WasmSpectralDecomposition.compute(matrix, maxIter, tol)`: Eigenvalue decomposition
|
|
940
|
+
- `WasmSpectralDecomposition.eigenvalues()`: Get eigenvalues
|
|
941
|
+
- `WasmSpectralDecomposition.applyFunction(f, x)`: Functional calculus
|
|
942
|
+
- `WasmSobolevSpace.new(order, lower, upper)`: Create Sobolev space
|
|
943
|
+
- `WasmSobolevSpace.h1Norm(f, df)`: Compute H^1 norm
|
|
944
|
+
- `powerMethod(matrix, initial, maxIter, tol)`: Dominant eigenvalue
|
|
945
|
+
- `computeEigenvalues(matrix, maxIter, tol)`: All eigenvalues
|
|
946
|
+
|
|
947
|
+
### Optical Field Operations
|
|
948
|
+
|
|
949
|
+
- `WasmOpticalRotorField.random(width, height, seed)`: Create random phase field
|
|
950
|
+
- `WasmOpticalRotorField.uniform(phase, amplitude, width, height)`: Uniform field
|
|
951
|
+
- `WasmGeometricLeeEncoder.withFrequency(width, height, freq)`: Create Lee encoder
|
|
952
|
+
- `WasmGeometricLeeEncoder.encode(field)`: Encode to binary hologram
|
|
953
|
+
- `WasmBinaryHologram.fillFactor()`: Fraction of "on" pixels
|
|
954
|
+
- `WasmBinaryHologram.asBytes()`: Get packed binary data for hardware
|
|
955
|
+
- `WasmOpticalFieldAlgebra.bind(a, b)`: Rotor product (phase addition)
|
|
956
|
+
- `WasmOpticalFieldAlgebra.unbind(key, bound)`: Retrieve associated field
|
|
957
|
+
- `WasmOpticalFieldAlgebra.similarity(a, b)`: Normalized inner product
|
|
958
|
+
- `WasmOpticalCodebook.register(symbol)`: Register symbol with auto-seed
|
|
959
|
+
- `WasmOpticalCodebook.get(symbol)`: Get field for symbol
|
|
960
|
+
- `WasmTropicalOpticalAlgebra.tropicalAdd(a, b)`: Pointwise minimum phase
|
|
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
|
+
|
|
440
977
|
## Examples
|
|
441
978
|
|
|
442
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
|
-
"
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
"
|
|
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
|
}
|