@justinelliottcobb/amari-wasm 0.16.0 → 0.17.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 +226 -1
- package/amari_wasm.d.ts +4669 -0
- package/amari_wasm.js +11063 -0
- package/amari_wasm_bg.wasm +0 -0
- package/package.json +21 -26
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @justinelliottcobb/amari-wasm v0.
|
|
1
|
+
# @justinelliottcobb/amari-wasm v0.17.0
|
|
2
2
|
|
|
3
3
|
**Unified Mathematical Computing Library with High-Precision WebAssembly Support**
|
|
4
4
|
|
|
@@ -20,6 +20,7 @@ Amari is a comprehensive mathematical computing library that brings advanced alg
|
|
|
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
22
|
- **Computational Topology** *(v0.16.0)*: Simplicial complexes, homology computation, persistent homology, and Morse theory
|
|
23
|
+
- **Dynamical Systems** *(v0.17.0)*: ODE solvers, stability analysis, bifurcation diagrams, Lyapunov exponents, and phase portraits
|
|
23
24
|
- **Probability Theory** *(v0.13.0)*: Distributions on multivector spaces, MCMC sampling, and Monte Carlo estimation
|
|
24
25
|
- **Relativistic Physics**: Spacetime algebra (Cl(1,3)) with WebAssembly-compatible precision
|
|
25
26
|
- **Spacecraft Orbital Mechanics**: Full-precision trajectory calculations in browsers
|
|
@@ -719,6 +720,212 @@ async function topologyDemo() {
|
|
|
719
720
|
topologyDemo();
|
|
720
721
|
```
|
|
721
722
|
|
|
723
|
+
### Dynamical Systems *(v0.17.0)*
|
|
724
|
+
|
|
725
|
+
Analyze chaotic systems, compute bifurcation diagrams, and explore phase space:
|
|
726
|
+
|
|
727
|
+
```typescript
|
|
728
|
+
import init, {
|
|
729
|
+
WasmLorenzSystem,
|
|
730
|
+
WasmVanDerPolOscillator,
|
|
731
|
+
WasmDuffingOscillator,
|
|
732
|
+
WasmRungeKutta4,
|
|
733
|
+
WasmLyapunovSpectrum,
|
|
734
|
+
WasmBifurcationDiagram,
|
|
735
|
+
WasmPhasePortrait,
|
|
736
|
+
WasmStabilityAnalysis,
|
|
737
|
+
computeLyapunovExponents,
|
|
738
|
+
findFixedPoints
|
|
739
|
+
} from '@justinelliottcobb/amari-wasm';
|
|
740
|
+
|
|
741
|
+
async function dynamicsDemo() {
|
|
742
|
+
await init();
|
|
743
|
+
|
|
744
|
+
// ========================================
|
|
745
|
+
// Lorenz Attractor
|
|
746
|
+
// ========================================
|
|
747
|
+
|
|
748
|
+
// Create classic Lorenz system (sigma=10, rho=28, beta=8/3)
|
|
749
|
+
const lorenz = WasmLorenzSystem.classic();
|
|
750
|
+
console.log(`Lorenz parameters: σ=${lorenz.sigma}, ρ=${lorenz.rho}, β=${lorenz.beta}`);
|
|
751
|
+
|
|
752
|
+
// Create RK4 solver
|
|
753
|
+
const solver = new WasmRungeKutta4();
|
|
754
|
+
|
|
755
|
+
// Integrate trajectory from initial condition
|
|
756
|
+
const initial = [1.0, 1.0, 1.0];
|
|
757
|
+
const trajectory = solver.solve(lorenz, initial, 0.0, 50.0, 5000);
|
|
758
|
+
|
|
759
|
+
console.log(`Trajectory has ${trajectory.length} points`);
|
|
760
|
+
|
|
761
|
+
// Get final state
|
|
762
|
+
const finalState = trajectory[trajectory.length - 1];
|
|
763
|
+
console.log(`Final state: (${finalState[0].toFixed(3)}, ${finalState[1].toFixed(3)}, ${finalState[2].toFixed(3)})`);
|
|
764
|
+
|
|
765
|
+
// ========================================
|
|
766
|
+
// Van der Pol Limit Cycle
|
|
767
|
+
// ========================================
|
|
768
|
+
|
|
769
|
+
// Create Van der Pol oscillator with mu = 1.0
|
|
770
|
+
const vdp = WasmVanDerPolOscillator.new(1.0);
|
|
771
|
+
|
|
772
|
+
// Small initial displacement
|
|
773
|
+
const vdpTrajectory = solver.solve(vdp, [0.1, 0.0], 0.0, 50.0, 5000);
|
|
774
|
+
|
|
775
|
+
// Check limit cycle amplitude
|
|
776
|
+
const vdpFinal = vdpTrajectory[vdpTrajectory.length - 1];
|
|
777
|
+
console.log(`Van der Pol final amplitude: ${Math.abs(vdpFinal[0]).toFixed(3)}`);
|
|
778
|
+
|
|
779
|
+
// ========================================
|
|
780
|
+
// Lyapunov Exponents
|
|
781
|
+
// ========================================
|
|
782
|
+
|
|
783
|
+
// Compute Lyapunov spectrum for Lorenz system
|
|
784
|
+
const lyapunov = computeLyapunovExponents(lorenz, initial, 10000, 0.01);
|
|
785
|
+
|
|
786
|
+
console.log(`Lyapunov exponents: [${lyapunov.exponents.map(e => e.toFixed(4)).join(', ')}]`);
|
|
787
|
+
console.log(`Sum: ${lyapunov.sum().toFixed(4)} (negative = dissipative)`);
|
|
788
|
+
|
|
789
|
+
if (lyapunov.exponents[0] > 0) {
|
|
790
|
+
console.log('System is chaotic!');
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// Kaplan-Yorke dimension
|
|
794
|
+
console.log(`Kaplan-Yorke dimension: ${lyapunov.kaplanYorkeDimension().toFixed(3)}`);
|
|
795
|
+
|
|
796
|
+
// ========================================
|
|
797
|
+
// Bifurcation Diagram
|
|
798
|
+
// ========================================
|
|
799
|
+
|
|
800
|
+
// Compute bifurcation diagram for logistic map
|
|
801
|
+
const bifurcation = WasmBifurcationDiagram.compute(
|
|
802
|
+
'logistic',
|
|
803
|
+
2.5, // r_min
|
|
804
|
+
4.0, // r_max
|
|
805
|
+
1000, // num_parameters
|
|
806
|
+
500, // transient iterations
|
|
807
|
+
100 // sample points per parameter
|
|
808
|
+
);
|
|
809
|
+
|
|
810
|
+
console.log(`Bifurcation diagram: ${bifurcation.parameterCount()} parameter values`);
|
|
811
|
+
|
|
812
|
+
// Get attractor points at specific parameter
|
|
813
|
+
const attractorAt3_5 = bifurcation.attractorPoints(3.5);
|
|
814
|
+
console.log(`Attractor at r=3.5: ${attractorAt3_5.length} points`);
|
|
815
|
+
|
|
816
|
+
// ========================================
|
|
817
|
+
// Stability Analysis
|
|
818
|
+
// ========================================
|
|
819
|
+
|
|
820
|
+
// Find fixed points of Van der Pol oscillator
|
|
821
|
+
const fixedPoints = findFixedPoints(vdp, [[0.0, 0.0]], 1e-10);
|
|
822
|
+
|
|
823
|
+
for (const fp of fixedPoints) {
|
|
824
|
+
console.log(`Fixed point: (${fp.point[0].toFixed(6)}, ${fp.point[1].toFixed(6)})`);
|
|
825
|
+
|
|
826
|
+
// Analyze stability
|
|
827
|
+
const stability = WasmStabilityAnalysis.analyze(vdp, fp.point);
|
|
828
|
+
console.log(` Stability: ${stability.stabilityType}`);
|
|
829
|
+
console.log(` Eigenvalues: ${stability.eigenvalues.map(e => `${e.real.toFixed(4)}+${e.imag.toFixed(4)}i`).join(', ')}`);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// ========================================
|
|
833
|
+
// Phase Portrait
|
|
834
|
+
// ========================================
|
|
835
|
+
|
|
836
|
+
// Generate phase portrait for Duffing oscillator
|
|
837
|
+
const duffing = WasmDuffingOscillator.new(1.0, -1.0, 0.2, 0.3, 1.2);
|
|
838
|
+
const portrait = WasmPhasePortrait.generate(
|
|
839
|
+
duffing,
|
|
840
|
+
[-2.0, 2.0], // x range
|
|
841
|
+
[-2.0, 2.0], // y range
|
|
842
|
+
20, // grid resolution
|
|
843
|
+
5.0, // integration time
|
|
844
|
+
0.01 // dt
|
|
845
|
+
);
|
|
846
|
+
|
|
847
|
+
console.log(`Phase portrait: ${portrait.trajectoryCount()} trajectories`);
|
|
848
|
+
|
|
849
|
+
// Get nullclines
|
|
850
|
+
const nullclines = portrait.nullclines();
|
|
851
|
+
console.log(`x-nullcline: ${nullclines.x.length} points`);
|
|
852
|
+
console.log(`y-nullcline: ${nullclines.y.length} points`);
|
|
853
|
+
|
|
854
|
+
// Clean up WASM memory
|
|
855
|
+
lorenz.free();
|
|
856
|
+
vdp.free();
|
|
857
|
+
duffing.free();
|
|
858
|
+
solver.free();
|
|
859
|
+
bifurcation.free();
|
|
860
|
+
portrait.free();
|
|
861
|
+
fixedPoints.forEach(fp => fp.free());
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
dynamicsDemo();
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
#### Dynamics API
|
|
868
|
+
|
|
869
|
+
**WasmLorenzSystem:**
|
|
870
|
+
- `classic()`: Create with σ=10, ρ=28, β=8/3
|
|
871
|
+
- `new(sigma, rho, beta)`: Create with custom parameters
|
|
872
|
+
- `sigma`, `rho`, `beta`: Parameter getters
|
|
873
|
+
- `vectorField(state)`: Evaluate dx/dt at state
|
|
874
|
+
|
|
875
|
+
**WasmVanDerPolOscillator:**
|
|
876
|
+
- `new(mu)`: Create with damping parameter μ
|
|
877
|
+
- `mu`: Parameter getter
|
|
878
|
+
- `vectorField(state)`: Evaluate dx/dt at state
|
|
879
|
+
|
|
880
|
+
**WasmDuffingOscillator:**
|
|
881
|
+
- `new(alpha, beta, delta, gamma, omega)`: Create driven Duffing oscillator
|
|
882
|
+
- `vectorField(state, t)`: Evaluate dx/dt at state and time t
|
|
883
|
+
|
|
884
|
+
**WasmRosslerSystem:**
|
|
885
|
+
- `new(a, b, c)`: Create Rossler attractor
|
|
886
|
+
- `classic()`: Create with a=0.2, b=0.2, c=5.7
|
|
887
|
+
|
|
888
|
+
**WasmHenonMap:**
|
|
889
|
+
- `new(a, b)`: Create Henon map
|
|
890
|
+
- `classic()`: Create with a=1.4, b=0.3
|
|
891
|
+
- `iterate(state)`: Apply one map iteration
|
|
892
|
+
|
|
893
|
+
**WasmRungeKutta4:**
|
|
894
|
+
- `new()`: Create RK4 solver
|
|
895
|
+
- `solve(system, initial, t0, t1, steps)`: Integrate trajectory
|
|
896
|
+
- `step(system, state, t, dt)`: Single integration step
|
|
897
|
+
|
|
898
|
+
**WasmAdaptiveSolver:**
|
|
899
|
+
- `rkf45()`: Create RKF45 adaptive solver
|
|
900
|
+
- `dormandPrince()`: Create Dormand-Prince solver
|
|
901
|
+
- `solve(system, initial, t0, t1, tolerance)`: Adaptive integration
|
|
902
|
+
|
|
903
|
+
**Lyapunov Functions:**
|
|
904
|
+
- `computeLyapunovExponents(system, initial, steps, dt)`: Compute spectrum
|
|
905
|
+
- Returns: `{ exponents, sum(), kaplanYorkeDimension(), isChaotic() }`
|
|
906
|
+
|
|
907
|
+
**WasmBifurcationDiagram:**
|
|
908
|
+
- `compute(systemType, paramMin, paramMax, numParams, transient, samples)`: Generate diagram
|
|
909
|
+
- `parameterCount()`: Number of parameter values
|
|
910
|
+
- `attractorPoints(param)`: Get attractor at specific parameter
|
|
911
|
+
- `branches()`: Get all (parameter, points) pairs
|
|
912
|
+
|
|
913
|
+
**WasmStabilityAnalysis:**
|
|
914
|
+
- `analyze(system, point)`: Analyze stability at point
|
|
915
|
+
- `stabilityType`: 'stable_node', 'stable_spiral', 'unstable_node', 'unstable_spiral', 'saddle', 'center'
|
|
916
|
+
- `eigenvalues`: Array of {real, imag} pairs
|
|
917
|
+
- `isStable()`: True if asymptotically stable
|
|
918
|
+
|
|
919
|
+
**findFixedPoints:**
|
|
920
|
+
- `findFixedPoints(system, initialGuesses, tolerance)`: Find fixed points via Newton's method
|
|
921
|
+
- Returns array of `{ point, converged, iterations }`
|
|
922
|
+
|
|
923
|
+
**WasmPhasePortrait:**
|
|
924
|
+
- `generate(system, xRange, yRange, resolution, tMax, dt)`: Generate portrait
|
|
925
|
+
- `trajectoryCount()`: Number of trajectories
|
|
926
|
+
- `trajectories()`: Get all trajectory arrays
|
|
927
|
+
- `nullclines()`: Get {x, y} nullcline point arrays
|
|
928
|
+
|
|
722
929
|
#### Topology API
|
|
723
930
|
|
|
724
931
|
**WasmSimplex:**
|
|
@@ -881,6 +1088,9 @@ topologyDemo();
|
|
|
881
1088
|
- **Topological Data Analysis**: Persistent homology for shape and feature detection
|
|
882
1089
|
- **Computational Biology**: Protein structure analysis via simplicial complexes
|
|
883
1090
|
- **Sensor Networks**: Coverage analysis using homology
|
|
1091
|
+
- **Chaos Theory**: Lorenz attractors, bifurcation diagrams, Lyapunov exponents
|
|
1092
|
+
- **Control Systems**: Stability analysis and phase portraits for dynamical systems
|
|
1093
|
+
- **Climate Modeling**: Sensitivity analysis via Lyapunov spectrum computation
|
|
884
1094
|
|
|
885
1095
|
## API Reference
|
|
886
1096
|
|
|
@@ -974,6 +1184,21 @@ topologyDemo();
|
|
|
974
1184
|
- `ripsFromDistances(n, dim, distances)`: Build Rips filtration
|
|
975
1185
|
- `findCriticalPoints2D(...)`: Find Morse critical points
|
|
976
1186
|
|
|
1187
|
+
### Dynamics Operations
|
|
1188
|
+
|
|
1189
|
+
- `WasmLorenzSystem.classic()`: Create classic Lorenz attractor
|
|
1190
|
+
- `WasmVanDerPolOscillator.new(mu)`: Create Van der Pol oscillator
|
|
1191
|
+
- `WasmDuffingOscillator.new(alpha, beta, delta, gamma, omega)`: Create Duffing oscillator
|
|
1192
|
+
- `WasmRosslerSystem.classic()`: Create Rossler attractor
|
|
1193
|
+
- `WasmHenonMap.classic()`: Create Henon map
|
|
1194
|
+
- `WasmRungeKutta4.solve(system, initial, t0, t1, steps)`: Integrate trajectory
|
|
1195
|
+
- `WasmAdaptiveSolver.rkf45()`: Create adaptive RKF45 solver
|
|
1196
|
+
- `computeLyapunovExponents(system, initial, steps, dt)`: Compute Lyapunov spectrum
|
|
1197
|
+
- `WasmBifurcationDiagram.compute(type, paramMin, paramMax, n, transient, samples)`: Generate bifurcation diagram
|
|
1198
|
+
- `WasmStabilityAnalysis.analyze(system, point)`: Analyze fixed point stability
|
|
1199
|
+
- `findFixedPoints(system, guesses, tolerance)`: Find fixed points
|
|
1200
|
+
- `WasmPhasePortrait.generate(system, xRange, yRange, res, tMax, dt)`: Generate phase portrait
|
|
1201
|
+
|
|
977
1202
|
## Examples
|
|
978
1203
|
|
|
979
1204
|
Check out the [examples directory](https://github.com/justinelliottcobb/Amari/tree/master/examples) for more detailed usage:
|