@johnhenry/math-sample 0.0.0-stage → 0.1.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.
Files changed (62) hide show
  1. package/README.md +244 -2
  2. package/dist/budget.d.ts +47 -0
  3. package/dist/budget.d.ts.map +1 -0
  4. package/dist/budget.js +44 -0
  5. package/dist/budget.js.map +1 -0
  6. package/dist/complex.d.ts +79 -0
  7. package/dist/complex.d.ts.map +1 -0
  8. package/dist/complex.js +236 -0
  9. package/dist/complex.js.map +1 -0
  10. package/dist/expr.d.ts +38 -0
  11. package/dist/expr.d.ts.map +1 -0
  12. package/dist/expr.js +264 -0
  13. package/dist/expr.js.map +1 -0
  14. package/dist/field2d.d.ts +58 -0
  15. package/dist/field2d.d.ts.map +1 -0
  16. package/dist/field2d.js +199 -0
  17. package/dist/field2d.js.map +1 -0
  18. package/dist/index.d.ts +11 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +10 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/mesh.d.ts +90 -0
  23. package/dist/mesh.d.ts.map +1 -0
  24. package/dist/mesh.js +294 -0
  25. package/dist/mesh.js.map +1 -0
  26. package/dist/ode.d.ts +147 -0
  27. package/dist/ode.d.ts.map +1 -0
  28. package/dist/ode.js +466 -0
  29. package/dist/ode.js.map +1 -0
  30. package/dist/sample.d.ts +114 -0
  31. package/dist/sample.d.ts.map +1 -0
  32. package/dist/sample.js +308 -0
  33. package/dist/sample.js.map +1 -0
  34. package/dist/series.d.ts +53 -0
  35. package/dist/series.d.ts.map +1 -0
  36. package/dist/series.js +158 -0
  37. package/dist/series.js.map +1 -0
  38. package/dist/svg.d.ts +37 -0
  39. package/dist/svg.d.ts.map +1 -0
  40. package/dist/svg.js +82 -0
  41. package/dist/svg.js.map +1 -0
  42. package/dist/ticks.d.ts +17 -0
  43. package/dist/ticks.d.ts.map +1 -0
  44. package/dist/ticks.js +47 -0
  45. package/dist/ticks.js.map +1 -0
  46. package/dist/viewport.d.ts +59 -0
  47. package/dist/viewport.d.ts.map +1 -0
  48. package/dist/viewport.js +111 -0
  49. package/dist/viewport.js.map +1 -0
  50. package/package.json +70 -4
  51. package/src/budget.ts +72 -0
  52. package/src/complex.ts +327 -0
  53. package/src/expr.ts +283 -0
  54. package/src/field2d.ts +259 -0
  55. package/src/index.ts +112 -0
  56. package/src/mesh.ts +376 -0
  57. package/src/ode.ts +633 -0
  58. package/src/sample.ts +391 -0
  59. package/src/series.ts +209 -0
  60. package/src/svg.ts +124 -0
  61. package/src/ticks.ts +46 -0
  62. package/src/viewport.ts +150 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh.js","sourceRoot":"","sources":["../src/mesh.ts"],"names":[],"mappings":"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"}
package/dist/ode.d.ts ADDED
@@ -0,0 +1,147 @@
1
+ import { type Budget, type Cancellable, type Progress } from "./budget.ts";
2
+ import { type Domain, type Samples } from "./sample.ts";
3
+ /** `dy/dx = f(x, y)` for a scalar equation. */
4
+ export type Slope = (x: number, y: number) => number;
5
+ /** `dy/dt = f(t, y)` for a system; returns a new array (or the same-length output) of derivatives. */
6
+ export type System = (t: number, y: readonly number[]) => readonly number[];
7
+ /** Autonomous planar system `[dx/dt, dy/dt] = F(x, y)`. */
8
+ export type Field2 = (x: number, y: number) => readonly [number, number];
9
+ export interface SlopeField {
10
+ columns: number;
11
+ rows: number;
12
+ /** Grid points (cell centres when `centered`, else grid nodes), `columns * rows` each, row-major from the smallest y. */
13
+ x: Float64Array;
14
+ y: Float64Array;
15
+ slope: Float64Array;
16
+ /**
17
+ * Unit direction `(dirX, dirY)` of each segment in data space (`(1, m) / |(1, m)|`; a vertical slope `+-Infinity`
18
+ * is `(0, +-1)`). `NaN` where the slope is `NaN` (undefined there).
19
+ */
20
+ dirX: Float64Array;
21
+ dirY: Float64Array;
22
+ progress: Progress;
23
+ }
24
+ export interface SlopeFieldOptions extends Budget, Cancellable {
25
+ columns?: number;
26
+ rows?: number;
27
+ }
28
+ /** Evaluate the slope field of `dy/dx = f(x, y)` on a `columns` x `rows` grid including both edges. */
29
+ export declare function sampleSlopeField(f: Slope, xDomain: Domain, yDomain: Domain, options?: SlopeFieldOptions): SlopeField;
30
+ export type StopReason = "end" | "blowup" | "maxSteps" | "stopped" | "stepTooSmall";
31
+ export interface Trajectory {
32
+ /** Times of the accepted steps, including the start. */
33
+ t: Float64Array;
34
+ /** `steps * dim` states, row-major. */
35
+ y: Float64Array;
36
+ dim: number;
37
+ steps: number;
38
+ reason: StopReason;
39
+ }
40
+ export interface OdeOptions extends Cancellable {
41
+ /** Stop (reason `"stopped"`) when this returns true for an accepted state. */
42
+ stop?: (t: number, y: readonly number[]) => boolean;
43
+ /** Abort with `"blowup"` when any component is non-finite or its magnitude exceeds this. Default 1e12. */
44
+ blowup?: number;
45
+ /** Hard cap on accepted steps. Default 100000. */
46
+ maxSteps?: number;
47
+ }
48
+ export interface Rk4Options extends OdeOptions {
49
+ /** Number of equal steps from `t0` to `tEnd`. Default 200. */
50
+ steps?: number;
51
+ }
52
+ export interface AdaptiveOdeOptions extends OdeOptions {
53
+ /** Absolute tolerance per step. Default 1e-8. */
54
+ atol?: number;
55
+ /** Relative tolerance per step. Default 1e-6. */
56
+ rtol?: number;
57
+ /** First step size; default `|tEnd - t0| / 100`. */
58
+ h0?: number;
59
+ /** Smallest step; below it the integration stops with `"stepTooSmall"`. Default `|tEnd - t0| * 1e-12`. */
60
+ hMin?: number;
61
+ /** Largest step. Default `|tEnd - t0|`. */
62
+ hMax?: number;
63
+ }
64
+ /**
65
+ * Fixed-step classical Runge-Kutta (order 4) for a system `y' = f(t, y)` from `t0` to `tEnd` (which may be
66
+ * smaller than `t0`: integrates backward). Stops early, with a reason, on blow-up or `options.stop`.
67
+ */
68
+ export declare function integrateRk4(f: System, t0: number, y0: readonly number[], tEnd: number, options?: Rk4Options): Trajectory;
69
+ /**
70
+ * Adaptive Dormand-Prince (RK45) with error control, forward or backward in `t`. Stops with `"blowup"` near a
71
+ * finite-time singularity, or `"stepTooSmall"` when the step would fall below `hMin`.
72
+ */
73
+ export declare function integrateAdaptive(f: System, t0: number, y0: readonly number[], tEnd: number, options?: AdaptiveOdeOptions): Trajectory;
74
+ export interface SolutionCurveOptions extends AdaptiveOdeOptions {
75
+ /** `"adaptive"` (default) or `"rk4"` with `steps` per direction. */
76
+ method?: "adaptive" | "rk4";
77
+ steps?: number;
78
+ /** Curve points with |y| beyond this end the curve (a blow-up asymptote). Default 1e6. */
79
+ yLimit?: number;
80
+ }
81
+ /**
82
+ * The solution curve of `dy/dx = f(x, y)` through `(x0, y0)`, extended both ways across `xDomain`, as
83
+ * `Samples` (x ascending). It ends where the solution blows up, so a vertical asymptote leaves a clean
84
+ * end, not a spike. `reasonBefore` / `reasonAfter` say why each side stopped.
85
+ */
86
+ export declare function sampleSolutionCurve(f: Slope, x0: number, y0: number, xDomain: Domain, options?: SolutionCurveOptions): Samples & {
87
+ reasonBefore: StopReason;
88
+ reasonAfter: StopReason;
89
+ };
90
+ export type FixedPointType = "stable node" | "unstable node" | "saddle" | "stable spiral" | "unstable spiral" | "center" | "stable star or degenerate node" | "unstable star or degenerate node" | "non-hyperbolic";
91
+ export interface FixedPoint {
92
+ x: number;
93
+ y: number;
94
+ /** `[[dFx/dx, dFx/dy], [dFy/dx, dFy/dy]]` by central differences. */
95
+ jacobian: [[number, number], [number, number]];
96
+ trace: number;
97
+ determinant: number;
98
+ /** Eigenvalues as `[re, im]` pairs (complex conjugates for a spiral or center). */
99
+ eigenvalues: [[number, number], [number, number]];
100
+ type: FixedPointType;
101
+ }
102
+ /** Numerical Jacobian of a planar field at a point, by central differences. */
103
+ export declare function jacobian2(F: Field2, x: number, y: number): [[number, number], [number, number]];
104
+ /** Classify an equilibrium from its 2x2 Jacobian (linearisation; `tolerance` is the zero threshold, default 1e-7). */
105
+ export declare function classifyFixedPoint(J: [[number, number], [number, number]], tolerance?: number): Pick<FixedPoint, "trace" | "determinant" | "eigenvalues" | "type">;
106
+ export interface PhasePortraitOptions extends Budget, Cancellable {
107
+ /** Field arrows per axis (`[columns, rows]` or one number). Default 15. */
108
+ grid?: number | [number, number];
109
+ /** Trajectory start points. Default: a 5 x 5 interior grid. */
110
+ seeds?: Array<[number, number]>;
111
+ /** Integrate each seed forward to `+tMax` and backward to `-tMax`. Default: 10. */
112
+ tMax?: number;
113
+ /** Search for fixed points with Newton from this many starts per axis. Default 8. 0 disables. */
114
+ fixedPointStarts?: number;
115
+ /** Trajectories are cut when they leave the window grown by this factor on each side. Default 0.5. */
116
+ margin?: number;
117
+ }
118
+ export interface PhasePortrait {
119
+ field: {
120
+ columns: number;
121
+ rows: number;
122
+ x: Float64Array;
123
+ y: Float64Array;
124
+ /** The vector at each node; `NaN` where `F` is non-finite. */
125
+ u: Float64Array;
126
+ v: Float64Array;
127
+ magnitude: Float64Array;
128
+ };
129
+ /** One entry per seed: backward half reversed then forward half, joined at the seed. */
130
+ trajectories: Array<{
131
+ seed: [number, number];
132
+ x: Float64Array;
133
+ y: Float64Array;
134
+ reasonBefore: StopReason;
135
+ reasonAfter: StopReason;
136
+ }>;
137
+ fixedPoints: FixedPoint[];
138
+ progress: Progress;
139
+ }
140
+ /**
141
+ * Phase portrait of an autonomous planar system: the vector field on a grid, trajectories from seed points
142
+ * (forward and backward, cut at the window's margin or at blow-up), and fixed points classified from the Jacobian.
143
+ * With a budget, `progress.rows` counts field rows and the trajectories and fixed points are only computed
144
+ * when the field finished.
145
+ */
146
+ export declare function samplePhasePortrait(F: Field2, xDomain: Domain, yDomain: Domain, options?: PhasePortraitOptions): PhasePortrait;
147
+ //# sourceMappingURL=ode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ode.d.ts","sourceRoot":"","sources":["../src/ode.ts"],"names":[],"mappings":"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"}
package/dist/ode.js ADDED
@@ -0,0 +1,466 @@
1
+ import { assertCount, assertRange, Meter, progress } from "./budget.js";
2
+ import { SampleCancelledError } from "./sample.js";
3
+ /** Evaluate the slope field of `dy/dx = f(x, y)` on a `columns` x `rows` grid including both edges. */
4
+ export function sampleSlopeField(f, xDomain, yDomain, options = {}) {
5
+ const columns = options.columns ?? 20;
6
+ const rows = options.rows ?? 20;
7
+ assertCount("columns", columns);
8
+ assertCount("rows", rows);
9
+ assertRange("x domain", xDomain);
10
+ assertRange("y domain", yDomain);
11
+ const meter = new Meter(options, options);
12
+ const n = columns * rows;
13
+ const x = new Float64Array(n);
14
+ const y = new Float64Array(n);
15
+ const slope = new Float64Array(n).fill(Number.NaN);
16
+ const dirX = new Float64Array(n).fill(Number.NaN);
17
+ const dirY = new Float64Array(n).fill(Number.NaN);
18
+ let done = 0;
19
+ let reason;
20
+ for (let j = 0; j < rows; j++) {
21
+ reason = meter.check(columns);
22
+ if (reason)
23
+ break;
24
+ const yy = j === rows - 1 ? yDomain.max : yDomain.min + ((yDomain.max - yDomain.min) * j) / (rows - 1);
25
+ for (let i = 0; i < columns; i++) {
26
+ const xx = i === columns - 1 ? xDomain.max : xDomain.min + ((xDomain.max - xDomain.min) * i) / (columns - 1);
27
+ const k = j * columns + i;
28
+ x[k] = xx;
29
+ y[k] = yy;
30
+ const m = f(xx, yy);
31
+ slope[k] = m;
32
+ if (Number.isNaN(m))
33
+ continue;
34
+ if (!Number.isFinite(m)) {
35
+ dirX[k] = 0;
36
+ dirY[k] = m > 0 ? 1 : -1;
37
+ }
38
+ else {
39
+ const len = Math.hypot(1, m);
40
+ dirX[k] = 1 / len;
41
+ dirY[k] = m / len;
42
+ }
43
+ }
44
+ meter.spend(columns);
45
+ done++;
46
+ }
47
+ const m = columns * done;
48
+ return {
49
+ columns,
50
+ rows: done,
51
+ x: x.slice(0, m),
52
+ y: y.slice(0, m),
53
+ slope: slope.slice(0, m),
54
+ dirX: dirX.slice(0, m),
55
+ dirY: dirY.slice(0, m),
56
+ progress: progress(done, rows, reason),
57
+ };
58
+ }
59
+ function bad(y, limit) {
60
+ for (const v of y)
61
+ if (!Number.isFinite(v) || Math.abs(v) > limit)
62
+ return true;
63
+ return false;
64
+ }
65
+ function collect(ts, ys, dim, reason) {
66
+ return { t: Float64Array.from(ts), y: Float64Array.from(ys), dim, steps: ts.length, reason };
67
+ }
68
+ function check(opts) {
69
+ if (opts.signal?.aborted || opts.isCancelled?.())
70
+ throw new SampleCancelledError();
71
+ }
72
+ /** One classical RK4 step. */
73
+ function rk4Step(f, t, y, h) {
74
+ const n = y.length;
75
+ const k1 = f(t, y);
76
+ const k2 = f(t + h / 2, y.map((v, i) => v + (h / 2) * k1[i]));
77
+ const k3 = f(t + h / 2, y.map((v, i) => v + (h / 2) * k2[i]));
78
+ const k4 = f(t + h, y.map((v, i) => v + h * k3[i]));
79
+ const out = new Array(n);
80
+ for (let i = 0; i < n; i++)
81
+ out[i] =
82
+ y[i] +
83
+ (h / 6) * (k1[i] + 2 * k2[i] + 2 * k3[i] + k4[i]);
84
+ return out;
85
+ }
86
+ /**
87
+ * Fixed-step classical Runge-Kutta (order 4) for a system `y' = f(t, y)` from `t0` to `tEnd` (which may be
88
+ * smaller than `t0`: integrates backward). Stops early, with a reason, on blow-up or `options.stop`.
89
+ */
90
+ export function integrateRk4(f, t0, y0, tEnd, options = {}) {
91
+ const steps = options.steps ?? 200;
92
+ assertCount("steps", steps, 1);
93
+ if (!Number.isFinite(t0) || !Number.isFinite(tEnd))
94
+ throw new RangeError("t0 and tEnd must be finite");
95
+ const limit = options.blowup ?? 1e12;
96
+ const maxSteps = Math.max(options.maxSteps ?? 100000, steps + 1); // never truncate a run the caller asked for
97
+ const dim = y0.length;
98
+ const h = (tEnd - t0) / steps;
99
+ const ts = [t0];
100
+ const ys = [...y0];
101
+ let y = y0;
102
+ let reason = "end";
103
+ for (let k = 0; k < steps; k++) {
104
+ if (ts.length >= maxSteps) {
105
+ reason = "maxSteps";
106
+ break;
107
+ }
108
+ if (k % 64 === 0)
109
+ check(options);
110
+ const t = t0 + k * h;
111
+ const next = rk4Step(f, t, y, h);
112
+ if (bad(next, limit)) {
113
+ reason = "blowup";
114
+ break;
115
+ }
116
+ y = next;
117
+ const tn = k === steps - 1 ? tEnd : t0 + (k + 1) * h;
118
+ ts.push(tn);
119
+ ys.push(...y);
120
+ if (options.stop?.(tn, y)) {
121
+ reason = "stopped";
122
+ break;
123
+ }
124
+ }
125
+ return collect(ts, ys, dim, reason);
126
+ }
127
+ // Dormand-Prince 5(4)
128
+ const C = [0, 1 / 5, 3 / 10, 4 / 5, 8 / 9, 1, 1];
129
+ const A = [
130
+ [],
131
+ [1 / 5],
132
+ [3 / 40, 9 / 40],
133
+ [44 / 45, -56 / 15, 32 / 9],
134
+ [19372 / 6561, -25360 / 2187, 64448 / 6561, -212 / 729],
135
+ [9017 / 3168, -355 / 33, 46732 / 5247, 49 / 176, -5103 / 18656],
136
+ [35 / 384, 0, 500 / 1113, 125 / 192, -2187 / 6784, 11 / 84],
137
+ ];
138
+ const B5 = [35 / 384, 0, 500 / 1113, 125 / 192, -2187 / 6784, 11 / 84, 0];
139
+ const B4 = [5179 / 57600, 0, 7571 / 16695, 393 / 640, -92097 / 339200, 187 / 2100, 1 / 40];
140
+ /**
141
+ * Adaptive Dormand-Prince (RK45) with error control, forward or backward in `t`. Stops with `"blowup"` near a
142
+ * finite-time singularity, or `"stepTooSmall"` when the step would fall below `hMin`.
143
+ */
144
+ export function integrateAdaptive(f, t0, y0, tEnd, options = {}) {
145
+ if (!Number.isFinite(t0) || !Number.isFinite(tEnd))
146
+ throw new RangeError("t0 and tEnd must be finite");
147
+ const span = Math.abs(tEnd - t0);
148
+ const dir = tEnd >= t0 ? 1 : -1;
149
+ const dim = y0.length;
150
+ const atol = options.atol ?? 1e-8;
151
+ const rtol = options.rtol ?? 1e-6;
152
+ const limit = options.blowup ?? 1e12;
153
+ const maxSteps = options.maxSteps ?? 100000;
154
+ const hMin = options.hMin ?? span * 1e-12;
155
+ const hMax = options.hMax ?? span;
156
+ let h = Math.min(options.h0 ?? span / 100, hMax);
157
+ const ts = [t0];
158
+ const ys = [...y0];
159
+ if (span === 0)
160
+ return collect(ts, ys, dim, "end");
161
+ let t = t0;
162
+ let y = y0;
163
+ let reason = "end";
164
+ let iterations = 0;
165
+ let badSteps = 0;
166
+ let sinceBad = Number.POSITIVE_INFINITY;
167
+ while (dir * (tEnd - t) > 0) {
168
+ if (ts.length >= maxSteps || iterations++ > maxSteps * 20) {
169
+ reason = "maxSteps";
170
+ break;
171
+ }
172
+ if (iterations % 64 === 0)
173
+ check(options);
174
+ if (h < hMin) {
175
+ reason = "stepTooSmall";
176
+ break;
177
+ }
178
+ const last = dir * (t + dir * h - tEnd) >= 0;
179
+ const hh = last ? Math.abs(tEnd - t) : h;
180
+ const step = dir * hh;
181
+ const k = [];
182
+ for (let s = 0; s < 7; s++) {
183
+ const arg = y.map((v, i) => {
184
+ let acc = 0;
185
+ for (let m = 0; m < s; m++)
186
+ acc += A[s]?.[m] * k[m][i];
187
+ return v + step * acc;
188
+ });
189
+ k.push(f(t + C[s] * step, arg));
190
+ }
191
+ const y5 = y.map((v, i) => v + step * B5.reduce((acc, b, s) => acc + b * k[s][i], 0));
192
+ const y4 = y.map((v, i) => v + step * B4.reduce((acc, b, s) => acc + b * k[s][i], 0));
193
+ if (bad(y5, limit)) {
194
+ // may be a bad step rather than a blow-up: try smaller before giving up
195
+ // bad steps count only while they recur within 10 accepted steps (a Zeno approach to the limit);
196
+ // isolated ones over a long run are forgiven
197
+ if (sinceBad > 10)
198
+ badSteps = 0;
199
+ sinceBad = 0;
200
+ if (++badSteps > 12 || hh <= hMin * 2) {
201
+ reason = "blowup";
202
+ break;
203
+ }
204
+ h = hh / 4;
205
+ continue;
206
+ }
207
+ let err = 0;
208
+ for (let i = 0; i < dim; i++) {
209
+ const sc = atol + rtol * Math.max(Math.abs(y[i]), Math.abs(y5[i]));
210
+ err = Math.max(err, Math.abs(y5[i] - y4[i]) / sc);
211
+ }
212
+ if (err <= 1 || hh <= hMin) {
213
+ t = last ? tEnd : t + step;
214
+ y = y5;
215
+ sinceBad++;
216
+ ts.push(t);
217
+ ys.push(...y);
218
+ if (options.stop?.(t, y)) {
219
+ reason = "stopped";
220
+ break;
221
+ }
222
+ }
223
+ const factor = err === 0 ? 5 : Math.min(5, Math.max(0.2, 0.9 * err ** -0.2));
224
+ h = Math.min(hMax, hh * factor);
225
+ }
226
+ return collect(ts, ys, dim, reason);
227
+ }
228
+ /**
229
+ * The solution curve of `dy/dx = f(x, y)` through `(x0, y0)`, extended both ways across `xDomain`, as
230
+ * `Samples` (x ascending). It ends where the solution blows up, so a vertical asymptote leaves a clean
231
+ * end, not a spike. `reasonBefore` / `reasonAfter` say why each side stopped.
232
+ */
233
+ export function sampleSolutionCurve(f, x0, y0, xDomain, options = {}) {
234
+ assertRange("x domain", xDomain);
235
+ const sys = (t, y) => [f(t, y[0])];
236
+ const limit = options.yLimit ?? 1e6;
237
+ const run = (end) => {
238
+ const o = { ...options, blowup: limit };
239
+ return options.method === "rk4"
240
+ ? integrateRk4(sys, x0, [y0], end, { ...o, steps: options.steps ?? 200 })
241
+ : integrateAdaptive(sys, x0, [y0], end, o);
242
+ };
243
+ const xs = [];
244
+ const ys = [];
245
+ let reasonBefore = "end";
246
+ let reasonAfter = "end";
247
+ // A start outside the window is first carried to the nearest edge, so the curve begins exactly at the edge.
248
+ if (x0 < xDomain.min || x0 > xDomain.max) {
249
+ const edge = x0 < xDomain.min ? xDomain.min : xDomain.max;
250
+ const toEdge = run(edge);
251
+ if (toEdge.reason !== "end") {
252
+ const r = toEdge.reason;
253
+ return { x: new Float64Array(0), y: new Float64Array(0), reasonBefore: r, reasonAfter: r };
254
+ }
255
+ x0 = edge;
256
+ y0 = toEdge.y[toEdge.steps - 1];
257
+ }
258
+ if (x0 > xDomain.min) {
259
+ const back = run(xDomain.min);
260
+ reasonBefore = back.reason;
261
+ for (let k = back.steps - 1; k >= 1; k--) {
262
+ xs.push(back.t[k]);
263
+ ys.push(back.y[k]);
264
+ }
265
+ }
266
+ xs.push(x0);
267
+ ys.push(y0);
268
+ if (x0 < xDomain.max) {
269
+ const fwd = run(xDomain.max);
270
+ reasonAfter = fwd.reason;
271
+ for (let k = 1; k < fwd.steps; k++) {
272
+ xs.push(fwd.t[k]);
273
+ ys.push(fwd.y[k]);
274
+ }
275
+ }
276
+ return { x: Float64Array.from(xs), y: Float64Array.from(ys), reasonBefore, reasonAfter };
277
+ }
278
+ /** Numerical Jacobian of a planar field at a point, by central differences. */
279
+ export function jacobian2(F, x, y) {
280
+ const h = 1e-6 * Math.max(1, Math.abs(x), Math.abs(y));
281
+ const xp = F(x + h, y);
282
+ const xm = F(x - h, y);
283
+ const yp = F(x, y + h);
284
+ const ym = F(x, y - h);
285
+ return [
286
+ [(xp[0] - xm[0]) / (2 * h), (yp[0] - ym[0]) / (2 * h)],
287
+ [(xp[1] - xm[1]) / (2 * h), (yp[1] - ym[1]) / (2 * h)],
288
+ ];
289
+ }
290
+ /** Classify an equilibrium from its 2x2 Jacobian (linearisation; `tolerance` is the zero threshold, default 1e-7). */
291
+ export function classifyFixedPoint(J, tolerance = 1e-7) {
292
+ const tr = J[0][0] + J[1][1];
293
+ const det = J[0][0] * J[1][1] - J[0][1] * J[1][0];
294
+ const disc = tr * tr - 4 * det;
295
+ const scale = Math.max(1, Math.abs(tr), Math.abs(det));
296
+ let eigenvalues;
297
+ if (disc >= 0) {
298
+ const s = Math.sqrt(disc);
299
+ eigenvalues = [
300
+ [(tr + s) / 2, 0],
301
+ [(tr - s) / 2, 0],
302
+ ];
303
+ }
304
+ else {
305
+ const s = Math.sqrt(-disc) / 2;
306
+ eigenvalues = [
307
+ [tr / 2, s],
308
+ [tr / 2, -s],
309
+ ];
310
+ }
311
+ let type;
312
+ if (Math.abs(det) <= tolerance * scale)
313
+ type = "non-hyperbolic";
314
+ else if (det < 0)
315
+ type = "saddle";
316
+ else if (Math.abs(tr) <= tolerance * scale)
317
+ type = "center";
318
+ else if (disc > tolerance * scale * scale)
319
+ type = tr < 0 ? "stable node" : "unstable node";
320
+ else if (disc >= -tolerance * scale * scale)
321
+ type = tr < 0 ? "stable star or degenerate node" : "unstable star or degenerate node";
322
+ else
323
+ type = tr < 0 ? "stable spiral" : "unstable spiral";
324
+ return { trace: tr, determinant: det, eigenvalues, type };
325
+ }
326
+ /**
327
+ * Phase portrait of an autonomous planar system: the vector field on a grid, trajectories from seed points
328
+ * (forward and backward, cut at the window's margin or at blow-up), and fixed points classified from the Jacobian.
329
+ * With a budget, `progress.rows` counts field rows and the trajectories and fixed points are only computed
330
+ * when the field finished.
331
+ */
332
+ export function samplePhasePortrait(F, xDomain, yDomain, options = {}) {
333
+ assertRange("x domain", xDomain);
334
+ assertRange("y domain", yDomain);
335
+ const g = options.grid ?? 15;
336
+ const [columns, rows] = typeof g === "number" ? [g, g] : g;
337
+ assertCount("columns", columns);
338
+ assertCount("rows", rows);
339
+ const meter = new Meter(options, options);
340
+ const n = columns * rows;
341
+ const fx = new Float64Array(n);
342
+ const fy = new Float64Array(n);
343
+ const u = new Float64Array(n).fill(Number.NaN);
344
+ const v = new Float64Array(n).fill(Number.NaN);
345
+ const mag = new Float64Array(n).fill(Number.NaN);
346
+ let done = 0;
347
+ let reason;
348
+ for (let j = 0; j < rows; j++) {
349
+ reason = meter.check(columns);
350
+ if (reason)
351
+ break;
352
+ const y = j === rows - 1 ? yDomain.max : yDomain.min + ((yDomain.max - yDomain.min) * j) / (rows - 1);
353
+ for (let i = 0; i < columns; i++) {
354
+ const x = i === columns - 1 ? xDomain.max : xDomain.min + ((xDomain.max - xDomain.min) * i) / (columns - 1);
355
+ const k = j * columns + i;
356
+ fx[k] = x;
357
+ fy[k] = y;
358
+ const w = F(x, y);
359
+ if (Number.isFinite(w[0]) && Number.isFinite(w[1])) {
360
+ u[k] = w[0];
361
+ v[k] = w[1];
362
+ mag[k] = Math.hypot(w[0], w[1]);
363
+ }
364
+ }
365
+ meter.spend(columns);
366
+ done++;
367
+ }
368
+ const m = columns * done;
369
+ const out = {
370
+ field: {
371
+ columns,
372
+ rows: done,
373
+ x: fx.slice(0, m),
374
+ y: fy.slice(0, m),
375
+ u: u.slice(0, m),
376
+ v: v.slice(0, m),
377
+ magnitude: mag.slice(0, m),
378
+ },
379
+ trajectories: [],
380
+ fixedPoints: [],
381
+ progress: progress(done, rows, reason),
382
+ };
383
+ if (reason)
384
+ return out;
385
+ const w = xDomain.max - xDomain.min;
386
+ const hgt = yDomain.max - yDomain.min;
387
+ const mar = options.margin ?? 0.5;
388
+ const inside = (x, y) => x >= xDomain.min - mar * w &&
389
+ x <= xDomain.max + mar * w &&
390
+ y >= yDomain.min - mar * hgt &&
391
+ y <= yDomain.max + mar * hgt;
392
+ const sys = (_t, s) => {
393
+ const r = F(s[0], s[1]);
394
+ return [r[0], r[1]];
395
+ };
396
+ const tMax = options.tMax ?? 10;
397
+ const seeds = options.seeds ??
398
+ Array.from({ length: 25 }, (_, q) => [
399
+ xDomain.min + (w * ((q % 5) + 0.5)) / 5,
400
+ yDomain.min + (hgt * (Math.floor(q / 5) + 0.5)) / 5,
401
+ ]);
402
+ for (const seed of seeds) {
403
+ const o = {
404
+ ...options,
405
+ stop: (_t, s) => !inside(s[0], s[1]),
406
+ hMax: tMax / 20,
407
+ };
408
+ const fwd = integrateAdaptive(sys, 0, seed, tMax, o);
409
+ const bwd = integrateAdaptive(sys, 0, seed, -tMax, o);
410
+ const xs = [];
411
+ const ys = [];
412
+ for (let k = bwd.steps - 1; k >= 1; k--) {
413
+ xs.push(bwd.y[2 * k]);
414
+ ys.push(bwd.y[2 * k + 1]);
415
+ }
416
+ for (let k = 0; k < fwd.steps; k++) {
417
+ xs.push(fwd.y[2 * k]);
418
+ ys.push(fwd.y[2 * k + 1]);
419
+ }
420
+ out.trajectories.push({
421
+ seed,
422
+ x: Float64Array.from(xs),
423
+ y: Float64Array.from(ys),
424
+ reasonBefore: bwd.reason,
425
+ reasonAfter: fwd.reason,
426
+ });
427
+ }
428
+ const starts = options.fixedPointStarts ?? 8;
429
+ const eps = 1e-8 * Math.max(w, hgt);
430
+ for (let a = 0; a < starts && starts > 0; a++) {
431
+ for (let b = 0; b < starts; b++) {
432
+ let x = xDomain.min + (w * (a + 0.5)) / starts;
433
+ let y = yDomain.min + (hgt * (b + 0.5)) / starts;
434
+ let ok = false;
435
+ for (let it = 0; it < 50; it++) {
436
+ const r = F(x, y);
437
+ if (!Number.isFinite(r[0]) || !Number.isFinite(r[1]))
438
+ break;
439
+ const J = jacobian2(F, x, y);
440
+ const det = J[0][0] * J[1][1] - J[0][1] * J[1][0];
441
+ if (!Number.isFinite(det) || Math.abs(det) < 1e-14)
442
+ break;
443
+ const dx = (J[1][1] * r[0] - J[0][1] * r[1]) / det;
444
+ const dy = (-J[1][0] * r[0] + J[0][0] * r[1]) / det;
445
+ x -= dx;
446
+ y -= dy;
447
+ if (Math.hypot(dx, dy) < eps) {
448
+ ok = true;
449
+ break;
450
+ }
451
+ }
452
+ if (!ok || !inside(x, y) || x < xDomain.min || x > xDomain.max || y < yDomain.min || y > yDomain.max)
453
+ continue;
454
+ const r = F(x, y);
455
+ if (Math.hypot(r[0], r[1]) > 1e-6)
456
+ continue;
457
+ if (out.fixedPoints.some((p) => Math.hypot(p.x - x, p.y - y) < 1e-5 * Math.max(w, hgt)))
458
+ continue;
459
+ const J = jacobian2(F, x, y);
460
+ out.fixedPoints.push({ x, y, jacobian: J, ...classifyFixedPoint(J) });
461
+ }
462
+ }
463
+ out.fixedPoints.sort((p, q) => p.x - q.x || p.y - q.y);
464
+ return out;
465
+ }
466
+ //# sourceMappingURL=ode.js.map