@johnhenry/math-sample 0.0.1 → 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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @johnhenry/math-sample
2
2
 
3
- Sampling for plots, as a library with no DOM in it. Give it a `(x) => number`
3
+ Sampling for plots (1D curves, 2D implicit/contour/gradient fields, 3D meshes, complex rasters, ODEs, series), as a library with no DOM in it. Give it a `(x) => number`
4
4
  (or an `@johnhenry/math` expression) and a viewport; get back `Float64Array`s
5
5
  with the poles and jumps already turned into gaps, plus the viewport maths,
6
6
  "nice" ticks and SVG path output a plot needs. Pure ESM, zero runtime
@@ -111,14 +111,122 @@ dependency**; the main entry never imports it. In a Worker: post the source
111
111
  string and params, compile there, sample, and `postMessage` the arrays with
112
112
  `[s.x.buffer, s.y.buffer]` as transferables.
113
113
 
114
+ ## 2D and 3D samplers, ODEs, series (part 2/3)
115
+
116
+ All of these take plain functions, return typed arrays, and never draw spikes: a
117
+ non-finite value is a **hole** (a gap row in curves, a skipped vertex in meshes,
118
+ `NaN` in rasters). The grid and field samplers (`sampleSurface`, `sampleParametricSurface`,
119
+ `sampleSpaceCurve`, `sampleVectorField3`, `sampleComplexRaster`, `findZerosAndPoles`, `sampleSlopeField`,
120
+ `samplePhasePortrait` (field pass), `sampleImplicit`, `sampleContours`, `sampleGradient`) accept a
121
+ **budget** and the cancellation options of part 1 (`signal`, `isCancelled`, which throw
122
+ `SampleCancelledError`). `conformalGrid`, the ODE integrators, and the series/Fourier samplers do not take a budget
123
+ (they are bounded by their own `samplesPerLine`, `maxSteps`, `samples` arguments):
124
+
125
+ ```ts
126
+ { maxCells?: number; maxMillis?: number; now?: () => number }
127
+ ```
128
+
129
+ When the budget runs out the sampler stops at a row (or slab) boundary and
130
+ **returns what it has** with `progress: { rows, of, complete, reason? }`
131
+ (`reason` is `"cells"` or `"time"`), so a UI can say "stopped at row 120 of 161:
132
+ the time limit". The time limit is checked per row, so one row can overrun it.
133
+
134
+ ### 3D (typed-array meshes)
135
+
136
+ | Function | Returns |
137
+ |---|---|
138
+ | `sampleSurface(f(x, y), xDomain, yDomain, { columns, rows, zRange, ...budget })` | `Mesh` for `z = f(x, y)` |
139
+ | `sampleParametricSurface(f(u, v) => [x, y, z], uDomain, vDomain, opts)` | `Mesh` |
140
+ | `sampleSpaceCurve(f(t) => [x, y, z], tDomain, { samples, maxStep, ...budget })` | `Curve3` |
141
+ | `curve3Runs(curve)` | `[start, end)` row ranges of consecutive data |
142
+ | `sampleVectorField3(f(x, y, z) => [a, b, c], xD, yD, zD, { grid, ...budget })` | `VectorField3` |
143
+
144
+ `Mesh` is `{ positions: Float32Array, normals: Float32Array, indices: Uint32Array, valid: Uint8Array,
145
+ vertexCount, columns, rows, bounds, progress }` (3 floats per vertex; triangles are counter-clockwise
146
+ seen from the side the normals point to, which is `+z` for `sampleSurface`, and `dP/du x dP/dv` for a
147
+ parametric surface). A hole vertex has `NaN` position, zero normal and `valid = 0`, and **no triangle
148
+ references it**, so GPU upload needs no special casing. `zRange` also turns a pole's huge but finite
149
+ shoulders into holes. A quad with one hole corner keeps its other triangle. `bounds` covers valid vertices
150
+ (`NaN`s when there are none). A valid vertex whose own normal degenerates (the poles of a sphere parameterisation) borrows
151
+ a neighbouring vertex's normal. Mind the sign: `dP/du x dP/dv` on the usual sphere parameterisation
152
+ `(sin v cos u, sin v sin u, cos v)` points **inward**; swap the arguments or negate a component for outward normals.
153
+ `Curve3` is `{ positions: Float64Array (3 per row), t, count, progress }` with `NaN` rows as gaps (never first,
154
+ last or adjacent). `VectorField3` is `{ origins, vectors, magnitudes: Float32Array, maxMagnitude, count,
155
+ skipped, progress }`; points where the field is non-finite are dropped and counted in `skipped`.
156
+
157
+ ### Complex functions
158
+
159
+ `ComplexFn` is `(re, im) => [re, im]`.
160
+
161
+ - `sampleComplexRaster(f, reDomain, imDomain, { width, height })`: `{ re, im, abs, arg: Float32Array,
162
+ width, height, progress }` sampled at cell centres, row 0 at the smallest imaginary part; `arg` in
163
+ `(-PI, PI]`. Colour it yourself (hue from `arg`, brightness from `abs`).
164
+ - `conformalGrid(f, reDomain, imDomain, { reLines, imLines, samplesPerLine, bound, maxStep })`: the image of a
165
+ rectangular grid of lines as `{ kind: "re" | "im", value, x, y }[]`; `NaN` gaps where `|f| > bound` (a pole)
166
+ or a step exceeds `maxStep` (a branch cut).
167
+ - `findZerosAndPoles(f, reDomain, imDomain, { grid, tolerance })`: argument principle on every grid cell
168
+ (winding number = zeros - poles), then Newton on `f` or `1/f` scaled by the multiplicity. Returns
169
+ `{ items: { re, im, kind, order, refined }[] }`. A zero and a pole in one cell cancel, and two distinct
170
+ roots in one cell are reported as one root of the combined order (Newton's step scaled by that order may fail to converge,
171
+ giving `refined: false` at the cell centre): raise `grid` if you suspect it. A genuine multiple root (`z^3`) reports
172
+ its multiplicity once with `refined: true`. The search grid is offset by an irrational fraction of a cell and
173
+ extended past the rectangle, so roots and poles on round-number domains and on grid vertices are found; results
174
+ outside the rectangle are dropped.
175
+
176
+ ### ODEs
177
+
178
+ - `sampleSlopeField(f(x, y), xDomain, yDomain, { columns, rows })`: slopes and unit directions
179
+ (`dirX`, `dirY`; vertical slopes are `(0, +-1)`; `NaN` where undefined).
180
+ - `integrateRk4(f(t, y[]) => number[], t0, y0[], tEnd, { steps })` and `integrateAdaptive(...,
181
+ { atol, rtol, hMin, hMax })` (Dormand-Prince 5(4)): a `Trajectory { t, y (steps x dim), dim, steps,
182
+ reason }` where `reason` is `"end" | "blowup" | "maxSteps" | "stopped" | "stepTooSmall"`. Either direction in
183
+ `t`. `stop(t, y)` ends the run; `blowup` (default 1e12) catches finite-time singularities cleanly.
184
+ - `sampleSolutionCurve(f(x, y), x0, y0, xDomain, { method: "adaptive" | "rk4" })`: the solution through a
185
+ point both ways as `Samples`, ending (not spiking) at an asymptote.
186
+ - `samplePhasePortrait(F(x, y) => [dx, dy], xDomain, yDomain, { grid, seeds, tMax, fixedPointStarts })`:
187
+ `{ field, trajectories, fixedPoints, progress }`. Fixed points are found by Newton from a grid of starts
188
+ and classified from the Jacobian by `classifyFixedPoint(J)`: `stable/unstable node`, `saddle`,
189
+ `stable/unstable spiral`, `center`, the star/degenerate case, or `non-hyperbolic` (det ~ 0; linearisation
190
+ says nothing). A `center` is a linear classification: the nonlinear system may spiral.
191
+
192
+ ### Series
193
+
194
+ - `taylorCoefficients(expr, x0, order)` (in `/expr`, needs `@johnhenry/math`; computed by power-series arithmetic, so order
195
+ 12 or more is instant for `+ - * /`, powers, `exp ln sqrt sin cos tan sinh cosh tanh atan asin acos`; any other function
196
+ falls back to repeated symbolic differentiation, keep `order` <= 8 there) then
197
+ `sampleTaylorPartialSums(coefficients, x0, domain, orders, samples)`: one curve per order.
198
+ - `sampleSeriesPartialSums(term(k, x), from, domain, orders, samples)`: function-series partial sums in
199
+ one pass over `k` (each term evaluated once per sample).
200
+ - `partialSums(term(k), from, to)`: numeric partial sums plus an Aitken delta-squared `limitEstimate`
201
+ (a hint, not a convergence proof).
202
+ - `fourierCoefficients(f, { min, max }, terms)` (midpoint rule on 4096 samples by default; the interval is one
203
+ period), `evaluateFourier`, `sampleFourierPartialSums(coefficients, domain, orders)`. Trig form
204
+ `a0/2 + sum a_k cos(k pi (x - c) / L) + b_k sin(...)`. A function with jumps shows the Gibbs overshoot, as it should.
205
+
206
+ ### 2D (implicit, contours, gradient)
207
+
208
+ - `sampleImplicit(f(x, y), xDomain, yDomain, { grid, level })`: marching squares, saddle cells settled by the
209
+ centre value. Segments come back as `Samples` rows: two endpoints then a `NaN` row per segment, so
210
+ `runsOf` gives one run per segment. Cells with a non-finite corner are skipped.
211
+ - `sampleContours(f, xDomain, yDomain, { grid, levels | count })`: one pass for all levels; default levels are
212
+ spread strictly between the grid's least and greatest value.
213
+ - `sampleGradient(fx, fy, xDomain, yDomain, { grid })`: arrow tails and components with magnitudes.
214
+
114
215
  ## What it does not do (yet)
115
216
 
116
217
  - **Implicit multiplication is opt-in.** `2x` fails to parse by default; write
117
218
  `2*x`, or pass `compileExpression(src, { implicitMultiplication: true })`
118
219
  (needs `@johnhenry/math` 0.1.0+; multi-letter variable names such as `theta`
119
220
  then become products, use `x_1`).
120
- - **1D `y = f(x)` only.** Implicit/interval curves, parametric and polar,
121
- surfaces, ODEs and series samplers are planned as later parts.
221
+ - **No interval-robust implicit mode.** `sampleImplicit` is a plain grid; thin features narrower
222
+ than a cell and isolated points can be missed (the quadtree/interval variant needs
223
+ `Symbolic.evaluateInterval`, johnhenry/math#108). Segments are not joined into long polylines.
224
+ - **Meshes are uniform grids.** No adaptive refinement for surfaces or space curves; normals come from
225
+ finite differences of the vertex grid (one-sided at holes and edges), not from analytic gradients.
226
+ - **Budgets stop at row boundaries**, and the time limit is only checked there. The ODE integrators take
227
+ `maxSteps`, not a budget.
228
+ - **Polar/parametric 2D curves and 3D adaptive sampling** are not here; wrap `sampleSpaceCurve`
229
+ (with `z = 0`) or sample a parametric function through `sampleUniform` on each coordinate.
122
230
  - **Gaps from steep or fast-oscillating functions.** Jump detection is a
123
231
  heuristic; a function that oscillates faster than the grid resolves can read
124
232
  as a jump. Raise the resolution or `maxDepth`, or set `jumpFraction: Infinity`.
@@ -0,0 +1,47 @@
1
+ import { type CancelSignal } from "./sample.ts";
2
+ /**
3
+ * A work limit for the 2D/3D samplers. When it runs out the sampler stops at a
4
+ * row boundary and returns what it has, with a {@link Progress} saying where
5
+ * it stopped (it does not throw).
6
+ */
7
+ export interface Budget {
8
+ /** Most function evaluations ("cells") the call may spend. Checked per row/slab. */
9
+ maxCells?: number;
10
+ /** Wall-clock limit in milliseconds. Checked per row/slab, so a single row can overrun it. */
11
+ maxMillis?: number;
12
+ /** Clock override for tests; default `performance.now` when present, else `Date.now`. */
13
+ now?: () => number;
14
+ }
15
+ export interface Cancellable {
16
+ signal?: CancelSignal;
17
+ isCancelled?: () => boolean;
18
+ }
19
+ export interface Progress {
20
+ /** Rows (or slabs, or steps) completed. */
21
+ rows: number;
22
+ /** Rows the full job needed. */
23
+ of: number;
24
+ complete: boolean;
25
+ /** Why it stopped early. Absent when `complete`. */
26
+ reason?: "cells" | "time";
27
+ }
28
+ /** Tracks a {@link Budget} and cancellation for one call. */
29
+ export declare class Meter {
30
+ private readonly start;
31
+ private spent;
32
+ private readonly now;
33
+ private readonly budget;
34
+ private readonly cancel;
35
+ constructor(budget: Budget | undefined, cancel: Cancellable | undefined);
36
+ /** Throws on cancellation; returns a reason when the budget cannot afford `cost` more evaluations. */
37
+ check(cost: number): "cells" | "time" | undefined;
38
+ spend(n: number): void;
39
+ get cells(): number;
40
+ }
41
+ export declare function progress(rows: number, of: number, reason?: "cells" | "time"): Progress;
42
+ export declare function assertCount(name: string, n: number, min?: number): void;
43
+ export declare function assertRange(name: string, d: {
44
+ min: number;
45
+ max: number;
46
+ }): void;
47
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAwB,MAAM,aAAa,CAAC;AAEtE;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC3B;AAED,6DAA6D;AAC7D,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;gBACrC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS;IAMvE,sGAAsG;IACtG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS;IAOjD,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAGtB,IAAI,KAAK,IAAI,MAAM,CAElB;CACF;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAEtF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,SAAI,GAAG,IAAI,CAElE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAG/E"}
package/dist/budget.js ADDED
@@ -0,0 +1,44 @@
1
+ import { SampleCancelledError } from "./sample.js";
2
+ /** Tracks a {@link Budget} and cancellation for one call. */
3
+ export class Meter {
4
+ start;
5
+ spent = 0;
6
+ now;
7
+ budget;
8
+ cancel;
9
+ constructor(budget, cancel) {
10
+ this.budget = budget;
11
+ this.cancel = cancel;
12
+ this.now = budget?.now ?? (typeof performance !== "undefined" ? () => performance.now() : () => Date.now());
13
+ this.start = this.now();
14
+ }
15
+ /** Throws on cancellation; returns a reason when the budget cannot afford `cost` more evaluations. */
16
+ check(cost) {
17
+ if (this.cancel?.signal?.aborted || this.cancel?.isCancelled?.())
18
+ throw new SampleCancelledError();
19
+ const b = this.budget;
20
+ if (b?.maxCells !== undefined && this.spent + cost > b.maxCells)
21
+ return "cells";
22
+ if (b?.maxMillis !== undefined && this.now() - this.start > b.maxMillis)
23
+ return "time";
24
+ return undefined;
25
+ }
26
+ spend(n) {
27
+ this.spent += n;
28
+ }
29
+ get cells() {
30
+ return this.spent;
31
+ }
32
+ }
33
+ export function progress(rows, of, reason) {
34
+ return reason === undefined ? { rows, of, complete: rows >= of } : { rows, of, complete: false, reason };
35
+ }
36
+ export function assertCount(name, n, min = 2) {
37
+ if (!Number.isInteger(n) || n < min)
38
+ throw new RangeError(`${name} must be an integer >= ${min}, got ${n}`);
39
+ }
40
+ export function assertRange(name, d) {
41
+ if (!Number.isFinite(d.min) || !Number.isFinite(d.max) || !(d.min < d.max))
42
+ throw new RangeError(`${name} must be finite with min < max`);
43
+ }
44
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA+BtE,6DAA6D;AAC7D,MAAM,OAAO,KAAK;IACC,KAAK,CAAS;IACvB,KAAK,GAAG,CAAC,CAAC;IACD,GAAG,CAAe;IAClB,MAAM,CAAqB;IAC3B,MAAM,CAA0B;IACjD,YAAY,MAA0B,EAAE,MAA+B;QACrE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,GAAG,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5G,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC1B,CAAC;IACD,sGAAsG;IACtG,KAAK,CAAC,IAAY;QAChB,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;YAAE,MAAM,IAAI,oBAAoB,EAAE,CAAC;QACnG,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QACtB,IAAI,CAAC,EAAE,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ;YAAE,OAAO,OAAO,CAAC;QAChF,IAAI,CAAC,EAAE,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,SAAS;YAAE,OAAO,MAAM,CAAC;QACvF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,KAAK,CAAC,CAAS;QACb,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;CACF;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,EAAU,EAAE,MAAyB;IAC1E,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3G,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,CAAS,EAAE,GAAG,GAAG,CAAC;IAC1D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG;QAAE,MAAM,IAAI,UAAU,CAAC,GAAG,IAAI,0BAA0B,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;AAC9G,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,CAA+B;IACvE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;QACxE,MAAM,IAAI,UAAU,CAAC,GAAG,IAAI,gCAAgC,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,79 @@
1
+ import { type Budget, type Cancellable, type Progress } from "./budget.ts";
2
+ import type { Domain } from "./sample.ts";
3
+ /** A complex function over plain numbers: `(re, im) -> [re, im]`. */
4
+ export type ComplexFn = (re: number, im: number) => readonly [number, number];
5
+ export interface ComplexRasterOptions extends Budget, Cancellable {
6
+ /** Pixels across (real axis). Default 128. */
7
+ width?: number;
8
+ /** Pixels down (imaginary axis). Default 128. */
9
+ height?: number;
10
+ }
11
+ /**
12
+ * Grid of `f(z)` values for domain colouring. Row 0 is the *smallest* imaginary part (mathematical
13
+ * orientation); flip when drawing to a canvas. Cells where `f` is not finite hold `NaN` in all four arrays
14
+ * (a pole shows as `abs = Infinity` only if `f` returned an infinite modulus with finite parts; otherwise NaN).
15
+ * `arg` is in `(-PI, PI]`.
16
+ */
17
+ export interface ComplexRaster {
18
+ width: number;
19
+ /** Rows completed (may be fewer than requested when the budget ran out). */
20
+ height: number;
21
+ re: Float32Array;
22
+ im: Float32Array;
23
+ abs: Float32Array;
24
+ arg: Float32Array;
25
+ progress: Progress;
26
+ }
27
+ /** Sample `f` at the centre of each cell of a `width` x `height` grid over the rectangle. */
28
+ export declare function sampleComplexRaster(f: ComplexFn, reDomain: Domain, imDomain: Domain, options?: ComplexRasterOptions): ComplexRaster;
29
+ export interface ConformalLine {
30
+ /** `"re"`: the image of the vertical line `Re z = value`; `"im"`: of the horizontal line `Im z = value`. */
31
+ kind: "re" | "im";
32
+ value: number;
33
+ /** Image points; `NaN` rows are gaps (never first, last or adjacent). */
34
+ x: Float64Array;
35
+ y: Float64Array;
36
+ }
37
+ export interface ConformalGridOptions {
38
+ /** Vertical grid lines (constant real part), evenly spaced including both edges. Default 11. */
39
+ reLines?: number;
40
+ /** Horizontal grid lines (constant imaginary part). Default 11. */
41
+ imLines?: number;
42
+ /** Samples along each line. Default 200. */
43
+ samplesPerLine?: number;
44
+ /** Image points with modulus above this become gaps (poles). Default 1e6. */
45
+ bound?: number;
46
+ /** Segments whose image is longer than this become gaps (branch cuts). Default: no limit. */
47
+ maxStep?: number;
48
+ }
49
+ /** The image under `f` of a rectangular grid of lines: where the grid lines go, drawn as the conformal-map picture. */
50
+ export declare function conformalGrid(f: ComplexFn, reDomain: Domain, imDomain: Domain, options?: ConformalGridOptions): ConformalLine[];
51
+ export interface ZeroOrPole {
52
+ re: number;
53
+ im: number;
54
+ kind: "zero" | "pole";
55
+ /** Multiplicity (zero) or order (pole), from the winding number of the cell it was found in. */
56
+ order: number;
57
+ /** `false` when the local refinement did not converge and `re`/`im` is only the cell centre. */
58
+ refined: boolean;
59
+ }
60
+ export interface ZerosPolesOptions extends Budget, Cancellable {
61
+ /** Cells per side of the search grid. Default 24. */
62
+ grid?: number;
63
+ /** Convergence tolerance on the root position. Default 1e-10 (relative to the rectangle size). */
64
+ tolerance?: number;
65
+ }
66
+ export interface ZerosPoles {
67
+ items: ZeroOrPole[];
68
+ progress: Progress;
69
+ }
70
+ /**
71
+ * Zeros and poles of `f` inside a rectangle, by the argument principle: the winding number of `f` around each
72
+ * grid cell is (zeros - poles) inside it; non-zero cells are refined with Newton's method (on `f` for a
73
+ * zero, on `1/f` for a pole, scaled by the multiplicity). A zero and a pole inside one cell cancel and are missed:
74
+ * raise `grid`. The search grid is offset by an irrational fraction of a cell and extended past the
75
+ * rectangle, so round-number domains do not put roots on cell edges; results inside the rectangle (or on its edge) are
76
+ * kept and results within the tolerance are merged. `progress.rows` counts grid rows searched.
77
+ */
78
+ export declare function findZerosAndPoles(f: ComplexFn, reDomain: Domain, imDomain: Domain, options?: ZerosPolesOptions): ZerosPoles;
79
+ //# sourceMappingURL=complex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complex.d.ts","sourceRoot":"","sources":["../src/complex.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,MAAM,EAAE,KAAK,WAAW,EAAS,KAAK,QAAQ,EAAY,MAAM,aAAa,CAAC;AACtH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,qEAAqE;AACrE,MAAM,MAAM,SAAS,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9E,MAAM,WAAW,oBAAqB,SAAQ,MAAM,EAAE,WAAW;IAC/D,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,YAAY,CAAC;IACjB,EAAE,EAAE,YAAY,CAAC;IACjB,GAAG,EAAE,YAAY,CAAC;IAClB,GAAG,EAAE,YAAY,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,CACjC,CAAC,EAAE,SAAS,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAyCf;AAED,MAAM,WAAW,aAAa;IAC5B,4GAA4G;IAC5G,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,CAAC,EAAE,YAAY,CAAC;IAChB,CAAC,EAAE,YAAY,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,gGAAgG;IAChG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,uHAAuH;AACvH,wBAAgB,aAAa,CAC3B,CAAC,EAAE,SAAS,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,oBAAyB,GACjC,aAAa,EAAE,CAiDjB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,gGAAgG;IAChG,KAAK,EAAE,MAAM,CAAC;IACd,gGAAgG;IAChG,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAkB,SAAQ,MAAM,EAAE,WAAW;IAC5D,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAQD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,SAAS,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,UAAU,CA+HZ"}
@@ -0,0 +1,236 @@
1
+ import { assertCount, assertRange, Meter, progress } from "./budget.js";
2
+ /** Sample `f` at the centre of each cell of a `width` x `height` grid over the rectangle. */
3
+ export function sampleComplexRaster(f, reDomain, imDomain, options = {}) {
4
+ const width = options.width ?? 128;
5
+ const height = options.height ?? 128;
6
+ assertCount("width", width, 1);
7
+ assertCount("height", height, 1);
8
+ assertRange("re domain", reDomain);
9
+ assertRange("im domain", imDomain);
10
+ const meter = new Meter(options, options);
11
+ const re = new Float32Array(width * height).fill(Number.NaN);
12
+ const im = new Float32Array(width * height).fill(Number.NaN);
13
+ const abs = new Float32Array(width * height).fill(Number.NaN);
14
+ const arg = new Float32Array(width * height).fill(Number.NaN);
15
+ let rows = 0;
16
+ let reason;
17
+ for (let j = 0; j < height; j++) {
18
+ reason = meter.check(width);
19
+ if (reason)
20
+ break;
21
+ const y = imDomain.min + ((imDomain.max - imDomain.min) * (j + 0.5)) / height;
22
+ for (let i = 0; i < width; i++) {
23
+ const x = reDomain.min + ((reDomain.max - reDomain.min) * (i + 0.5)) / width;
24
+ const w = f(x, y);
25
+ const k = j * width + i;
26
+ if (Number.isFinite(w[0]) && Number.isFinite(w[1])) {
27
+ re[k] = w[0];
28
+ im[k] = w[1];
29
+ abs[k] = Math.hypot(w[0], w[1]);
30
+ arg[k] = Math.atan2(w[1], w[0]);
31
+ }
32
+ }
33
+ meter.spend(width);
34
+ rows++;
35
+ }
36
+ return {
37
+ width,
38
+ height: rows,
39
+ re: re.slice(0, width * rows),
40
+ im: im.slice(0, width * rows),
41
+ abs: abs.slice(0, width * rows),
42
+ arg: arg.slice(0, width * rows),
43
+ progress: progress(rows, height, reason),
44
+ };
45
+ }
46
+ /** The image under `f` of a rectangular grid of lines: where the grid lines go, drawn as the conformal-map picture. */
47
+ export function conformalGrid(f, reDomain, imDomain, options = {}) {
48
+ const nRe = options.reLines ?? 11;
49
+ const nIm = options.imLines ?? 11;
50
+ const n = options.samplesPerLine ?? 200;
51
+ const bound = options.bound ?? 1e6;
52
+ assertCount("reLines", nRe, 1);
53
+ assertCount("imLines", nIm, 1);
54
+ assertCount("samplesPerLine", n);
55
+ assertRange("re domain", reDomain);
56
+ assertRange("im domain", imDomain);
57
+ const lines = [];
58
+ const trace = (kind, value, d) => {
59
+ const xs = [];
60
+ const ys = [];
61
+ let pending = false;
62
+ let px = Number.NaN;
63
+ let py = Number.NaN;
64
+ for (let k = 0; k < n; k++) {
65
+ const s = k === n - 1 ? d.max : d.min + ((d.max - d.min) * k) / (n - 1);
66
+ const w = kind === "re" ? f(value, s) : f(s, value);
67
+ const good = Number.isFinite(w[0]) && Number.isFinite(w[1]) && Math.hypot(w[0], w[1]) <= bound;
68
+ if (!good) {
69
+ pending = xs.length > 0;
70
+ px = Number.NaN;
71
+ continue;
72
+ }
73
+ const cut = options.maxStep !== undefined && !Number.isNaN(px) && Math.hypot(w[0] - px, w[1] - py) > options.maxStep;
74
+ if ((pending || cut) && xs.length > 0) {
75
+ xs.push(Number.NaN);
76
+ ys.push(Number.NaN);
77
+ }
78
+ xs.push(w[0]);
79
+ ys.push(w[1]);
80
+ px = w[0];
81
+ py = w[1];
82
+ pending = false;
83
+ }
84
+ return { kind, value, x: Float64Array.from(xs), y: Float64Array.from(ys) };
85
+ };
86
+ for (let i = 0; i < nRe; i++)
87
+ lines.push(trace("re", nRe === 1 ? reDomain.min : reDomain.min + ((reDomain.max - reDomain.min) * i) / (nRe - 1), imDomain));
88
+ for (let j = 0; j < nIm; j++)
89
+ lines.push(trace("im", nIm === 1 ? imDomain.min : imDomain.min + ((imDomain.max - imDomain.min) * j) / (nIm - 1), reDomain));
90
+ return lines;
91
+ }
92
+ const wrap = (d) => {
93
+ while (d > Math.PI)
94
+ d -= 2 * Math.PI;
95
+ while (d < -Math.PI)
96
+ d += 2 * Math.PI;
97
+ return d;
98
+ };
99
+ /**
100
+ * Zeros and poles of `f` inside a rectangle, by the argument principle: the winding number of `f` around each
101
+ * grid cell is (zeros - poles) inside it; non-zero cells are refined with Newton's method (on `f` for a
102
+ * zero, on `1/f` for a pole, scaled by the multiplicity). A zero and a pole inside one cell cancel and are missed:
103
+ * raise `grid`. The search grid is offset by an irrational fraction of a cell and extended past the
104
+ * rectangle, so round-number domains do not put roots on cell edges; results inside the rectangle (or on its edge) are
105
+ * kept and results within the tolerance are merged. `progress.rows` counts grid rows searched.
106
+ */
107
+ export function findZerosAndPoles(f, reDomain, imDomain, options = {}) {
108
+ const grid = options.grid ?? 24;
109
+ assertCount("grid", grid, 1);
110
+ assertRange("re domain", reDomain);
111
+ assertRange("im domain", imDomain);
112
+ const size = Math.max(reDomain.max - reDomain.min, imDomain.max - imDomain.min);
113
+ const tol = (options.tolerance ?? 1e-10) * size;
114
+ const meter = new Meter(options, options);
115
+ const dx = (reDomain.max - reDomain.min) / grid;
116
+ const dy = (imDomain.max - imDomain.min) / grid;
117
+ const found = [];
118
+ const argAt = (x, y) => {
119
+ const w = f(x, y);
120
+ if (w[0] === 0 && w[1] === 0)
121
+ return Number.NaN; // an exact zero has no argument
122
+ return Math.atan2(w[1], w[0]);
123
+ };
124
+ // winding of f along segment p->q, subdividing until the phase moves < 1 rad per piece
125
+ const segment = (x0, y0, a0, x1, y1, a1, depth) => {
126
+ const d = wrap(a1 - a0);
127
+ // a minimum depth keeps a high-order root from aliasing a whole turn (3 theta moving 2 pi in one piece)
128
+ if ((depth >= 4 && Math.abs(d) < 1) || depth >= 14)
129
+ return d;
130
+ const xm = (x0 + x1) / 2;
131
+ const ym = (y0 + y1) / 2;
132
+ const am = argAt(xm, ym);
133
+ return segment(x0, y0, a0, xm, ym, am, depth + 1) + segment(xm, ym, am, x1, y1, a1, depth + 1);
134
+ };
135
+ const winding = (x0, y0, x1, y1) => {
136
+ const pts = [
137
+ [x0, y0],
138
+ [x1, y0],
139
+ [x1, y1],
140
+ [x0, y1],
141
+ [x0, y0],
142
+ ];
143
+ const args = pts.map(([x, y]) => argAt(x, y));
144
+ if (args.some((a) => !Number.isFinite(a)))
145
+ return Number.NaN;
146
+ let total = 0;
147
+ for (let k = 0; k < 4; k++) {
148
+ const p = pts[k];
149
+ const q = pts[k + 1];
150
+ total += segment(p[0], p[1], args[k], q[0], q[1], args[k + 1], 0);
151
+ }
152
+ return Math.round(total / (2 * Math.PI));
153
+ };
154
+ const newton = (x, y, kind, order, box) => {
155
+ const g = (a, b) => {
156
+ const w = f(a, b);
157
+ if (kind === "zero")
158
+ return [w[0], w[1]];
159
+ const m = w[0] * w[0] + w[1] * w[1];
160
+ return [w[0] / m, -w[1] / m]; // 1/f
161
+ };
162
+ let zx = x;
163
+ let zy = y;
164
+ for (let it = 0; it < 60; it++) {
165
+ const [gr, gi] = g(zx, zy);
166
+ if (!Number.isFinite(gr) || !Number.isFinite(gi))
167
+ return undefined;
168
+ const h = 1e-7 * Math.max(1, Math.abs(zx), Math.abs(zy));
169
+ const [ar, ai] = g(zx + h, zy);
170
+ const dr = (ar - gr) / h; // derivative of an analytic function = d/dx
171
+ const di = (ai - gi) / h;
172
+ const den = dr * dr + di * di;
173
+ if (!(den > 0) || !Number.isFinite(den))
174
+ return undefined;
175
+ // step = order * g / g'
176
+ const sr = (order * (gr * dr + gi * di)) / den;
177
+ const si = (order * (gi * dr - gr * di)) / den;
178
+ zx -= sr;
179
+ zy -= si;
180
+ if (Math.hypot(sr, si) < tol) {
181
+ const pad = 0.5 * Math.max(dx, dy);
182
+ if (zx < box[0] - pad || zx > box[1] + pad || zy < box[2] - pad || zy > box[3] + pad)
183
+ return undefined;
184
+ return [zx, zy];
185
+ }
186
+ if (!Number.isFinite(zx) || !Number.isFinite(zy))
187
+ return undefined;
188
+ }
189
+ return undefined;
190
+ };
191
+ // The search grid is shifted by an irrational fraction of a cell and extended by one cell on each side, so
192
+ // roots and poles on a round-number domain (z^3 - z on [-2, 2]) sit inside cells, not on their edges or
193
+ // corners. Candidates outside the requested rectangle are discarded at the end.
194
+ const OFFSET = 0.3819660112501051;
195
+ const gx0 = reDomain.min - (1 - OFFSET) * dx;
196
+ const gy0 = imDomain.min - (1 - OFFSET) * dy;
197
+ const cells = grid + 1;
198
+ const slack = 1e-9 * size;
199
+ const insideRect = (x, y) => x >= reDomain.min - slack && x <= reDomain.max + slack && y >= imDomain.min - slack && y <= imDomain.max + slack;
200
+ let rows = 0;
201
+ let reason;
202
+ for (let j = 0; j < cells; j++) {
203
+ reason = meter.check(cells * 4);
204
+ if (reason)
205
+ break;
206
+ for (let i = 0; i < cells; i++) {
207
+ const x0 = gx0 + i * dx;
208
+ const y0 = gy0 + j * dy;
209
+ let w = winding(x0, y0, x0 + dx, y0 + dy);
210
+ let ex = 0;
211
+ if (Number.isNaN(w)) {
212
+ // f is zero or non-finite on this cell's boundary (an exact root/pole on an edge): retry slightly inflated
213
+ ex = 0.0123 * dx;
214
+ w = winding(x0 - ex, y0 - 0.0123 * dy, x0 + dx + ex, y0 + dy + 0.0123 * dy);
215
+ }
216
+ if (!Number.isFinite(w) || w === 0)
217
+ continue;
218
+ const kind = w > 0 ? "zero" : "pole";
219
+ const order = Math.abs(w);
220
+ const cx = x0 + dx / 2;
221
+ const cy = y0 + dy / 2;
222
+ const refined = newton(cx, cy, kind, order, [x0, x0 + dx, y0, y0 + dy]);
223
+ const [rx, ry] = refined ?? [cx, cy];
224
+ if (!insideRect(rx, ry))
225
+ continue;
226
+ if (found.some((p) => p.kind === kind && Math.hypot(p.re - rx, p.im - ry) < Math.max(tol * 1e3, 1e-7 * size)))
227
+ continue;
228
+ found.push({ re: rx, im: ry, kind, order, refined: refined !== undefined });
229
+ }
230
+ meter.spend(cells * 4);
231
+ rows++;
232
+ }
233
+ found.sort((a, b) => a.re - b.re || a.im - b.im);
234
+ return { items: found, progress: progress(rows, cells, reason) };
235
+ }
236
+ //# sourceMappingURL=complex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complex.js","sourceRoot":"","sources":["../src/complex.ts"],"names":[],"mappings":"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"}
package/dist/expr.d.ts CHANGED
@@ -23,4 +23,16 @@ export interface CompileOptions {
23
23
  * `implicitMultiplication: true` to accept `2x`.
24
24
  */
25
25
  export declare function compileExpression(expr: Expr | string, options?: CompileOptions): Fn1;
26
+ /**
27
+ * Taylor coefficients `a_k = f^(k)(x0) / k!` for `k = 0..order` of an expression. They are computed by truncated
28
+ * power-series ("jet") arithmetic, O(order^2) per node, so order 12 of `sin(x)*exp(x)/(1+x^2)` takes well under a
29
+ * millisecond. Supported: `+ - * /`, powers (integer or real exponent, or a variable exponent), and `exp ln sqrt cbrt sin
30
+ * cos tan sinh cosh tanh atan asin acos`. Any other node falls back to repeated symbolic differentiation with
31
+ * simplification after every derivative, which grows quickly: keep `order` at or below 8 there. A coefficient that is
32
+ * not finite at `x0` (a pole, `ln(0)`) is `NaN` or `Infinity`, and the partial sums built on it are gaps.
33
+ */
34
+ export declare function taylorCoefficients(expr: Expr | string, x0: number, order: number, options?: {
35
+ variable?: string;
36
+ params?: Record<string, number>;
37
+ }): Float64Array;
26
38
  //# sourceMappingURL=expr.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"expr.d.ts","sourceRoot":"","sources":["../src/expr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAY,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAEvC,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,GAAG,CAYxF"}
1
+ {"version":3,"file":"expr.d.ts","sourceRoot":"","sources":["../src/expr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAY,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAEvC,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,GAAG,CAYxF;AAqND;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,GAAG,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAO,GACnE,YAAY,CAkBd"}