@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 CHANGED
@@ -1,4 +1,4 @@
1
- # @justinelliottcobb/amari-wasm v0.16.0
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: