@danielsimonjr/mathts-functions 0.71.0 → 0.73.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 (95) hide show
  1. package/README.md +26 -1
  2. package/dist/cas/real-roots.d.ts +30 -0
  3. package/dist/cas/real-roots.d.ts.map +1 -0
  4. package/dist/fit-scalar.d.ts +28 -0
  5. package/dist/fit-scalar.d.ts.map +1 -1
  6. package/dist/geometry/curves.d.ts +48 -0
  7. package/dist/geometry/curves.d.ts.map +1 -0
  8. package/dist/geometry/polygon-ops.d.ts +19 -0
  9. package/dist/geometry/polygon-ops.d.ts.map +1 -0
  10. package/dist/geometry/predicates.d.ts +38 -0
  11. package/dist/geometry/predicates.d.ts.map +1 -0
  12. package/dist/index.d.ts +51 -4
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +5310 -766
  15. package/dist/linalg-extra2.d.ts +36 -0
  16. package/dist/linalg-extra2.d.ts.map +1 -0
  17. package/dist/linalg-special-matrices.d.ts +62 -0
  18. package/dist/linalg-special-matrices.d.ts.map +1 -0
  19. package/dist/numbertheory/arithmetic-functions.d.ts +50 -0
  20. package/dist/numbertheory/arithmetic-functions.d.ts.map +1 -0
  21. package/dist/numbertheory/diophantine.d.ts +43 -0
  22. package/dist/numbertheory/diophantine.d.ts.map +1 -0
  23. package/dist/numbertheory/extra.d.ts +12 -6
  24. package/dist/numbertheory/extra.d.ts.map +1 -1
  25. package/dist/numbertheory/integer-matrices.d.ts +26 -0
  26. package/dist/numbertheory/integer-matrices.d.ts.map +1 -0
  27. package/dist/numbertheory/modular.d.ts +27 -0
  28. package/dist/numbertheory/modular.d.ts.map +1 -0
  29. package/dist/numbertheory/sequences.d.ts +36 -0
  30. package/dist/numbertheory/sequences.d.ts.map +1 -0
  31. package/dist/numeric/constrained.d.ts +42 -0
  32. package/dist/numeric/constrained.d.ts.map +1 -0
  33. package/dist/numeric/finite-differences.d.ts +54 -0
  34. package/dist/numeric/finite-differences.d.ts.map +1 -0
  35. package/dist/numeric/gauss-nodes-extra.d.ts +73 -0
  36. package/dist/numeric/gauss-nodes-extra.d.ts.map +1 -0
  37. package/dist/numeric/global-optimizers.d.ts +64 -0
  38. package/dist/numeric/global-optimizers.d.ts.map +1 -0
  39. package/dist/numeric/quadrature-extra.d.ts +64 -0
  40. package/dist/numeric/quadrature-extra.d.ts.map +1 -0
  41. package/dist/numeric/rational-nullspace.d.ts +2 -2
  42. package/dist/numeric/rational-nullspace.d.ts.map +1 -1
  43. package/dist/scalar-batch-parallel.d.ts +15 -9
  44. package/dist/scalar-batch-parallel.d.ts.map +1 -1
  45. package/dist/scalar-batch-parallel.js +108 -0
  46. package/dist/{scalar-batch-task-CZd6LPg9.js → scalar-batch-task-CL8ex21e.js} +33 -35
  47. package/dist/scalar-batch.worker.js +1 -1
  48. package/dist/scalar-compile.d.ts +4 -4
  49. package/dist/scalar-compile.d.ts.map +1 -1
  50. package/dist/scalar-dimension.d.ts +32 -0
  51. package/dist/scalar-dimension.d.ts.map +1 -1
  52. package/dist/scalar-eval.d.ts +4 -2
  53. package/dist/scalar-eval.d.ts.map +1 -1
  54. package/dist/scalar-node-bridge.d.ts.map +1 -1
  55. package/dist/scalar-search.d.ts +325 -14
  56. package/dist/scalar-search.d.ts.map +1 -1
  57. package/dist/signal/dtw.d.ts +32 -0
  58. package/dist/signal/dtw.d.ts.map +1 -0
  59. package/dist/signal/lomb-scargle.d.ts +25 -0
  60. package/dist/signal/lomb-scargle.d.ts.map +1 -0
  61. package/dist/signal/system-response.d.ts +82 -0
  62. package/dist/signal/system-response.d.ts.map +1 -0
  63. package/dist/signal/waveforms.d.ts +52 -0
  64. package/dist/signal/waveforms.d.ts.map +1 -0
  65. package/dist/signal/windows-extra.d.ts +52 -0
  66. package/dist/signal/windows-extra.d.ts.map +1 -0
  67. package/dist/special/angular-momentum.d.ts +38 -0
  68. package/dist/special/angular-momentum.d.ts.map +1 -0
  69. package/dist/special/erf-extra.d.ts +47 -0
  70. package/dist/special/erf-extra.d.ts.map +1 -0
  71. package/dist/special/exp-integrals.d.ts +38 -0
  72. package/dist/special/exp-integrals.d.ts.map +1 -0
  73. package/dist/special/spherical-bessel.d.ts +28 -0
  74. package/dist/special/spherical-bessel.d.ts.map +1 -0
  75. package/dist/special/zeta-extra.d.ts +36 -0
  76. package/dist/special/zeta-extra.d.ts.map +1 -0
  77. package/dist/stats/distances.d.ts +28 -0
  78. package/dist/stats/distances.d.ts.map +1 -0
  79. package/dist/stats/distributions-extra.d.ts +36 -0
  80. package/dist/stats/distributions-extra.d.ts.map +1 -0
  81. package/dist/stats/effect-sizes.d.ts +21 -0
  82. package/dist/stats/effect-sizes.d.ts.map +1 -0
  83. package/dist/stats/nonparametric-extra.d.ts +52 -0
  84. package/dist/stats/nonparametric-extra.d.ts.map +1 -0
  85. package/dist/stats/robust-stats.d.ts +38 -0
  86. package/dist/stats/robust-stats.d.ts.map +1 -0
  87. package/dist/stats/weighted-stats.d.ts +27 -0
  88. package/dist/stats/weighted-stats.d.ts.map +1 -0
  89. package/dist/typed/arithmetic.d.ts +2 -1
  90. package/dist/typed/arithmetic.d.ts.map +1 -1
  91. package/dist/typed/numeric.d.ts.map +1 -1
  92. package/dist/typed/special.d.ts.map +1 -1
  93. package/dist/wasm/special/scalars.d.ts +27 -0
  94. package/dist/wasm/special/scalars.d.ts.map +1 -1
  95. package/package.json +8 -8
@@ -3,19 +3,29 @@
3
3
  *
4
4
  * `populations` islands each evolve by tournament selection and
5
5
  * {@link weightedMutation}. Each generation breeds `populationSize` offspring per
6
- * island from tournament winners, evaluates them in one batch, and keeps the best
7
- * `populationSize` distinct trees of parents and offspring (elitist truncation, not
8
- * age-based replacement). After every generation the islands exchange their
9
- * best trees (migration). A hall of fame shared by every island keeps the best tree
10
- * per complexity; its Pareto front is reported through {@link paretoFront} and
11
- * {@link scoreFront}.
6
+ * island from tournament winners, evaluates every island's batch at the same time
7
+ * (the score calls overlap in this process when worker scoring is in use; each
8
+ * island keeps its own rng; without `parallel`, or below the row threshold, scoring
9
+ * stays on the caller thread and overlap buys no throughput), and
10
+ * keeps the best `populationSize` distinct trees of parents and offspring per
11
+ * island (elitist truncation, not age-based replacement), applied in island-index
12
+ * order after every island's batch has finished. After every generation the islands
13
+ * exchange their best trees (migration). A hall of fame shared by every island keeps the best loss
14
+ * per complexity among stored trees and one evaluated tree per {@link scalarCanonicalKey}
15
+ * (loss first, then complexity, then first recorded); its Pareto front is reported
16
+ * through {@link paretoFront} and {@link scoreFront}. Subtree crossover
17
+ * ({@link crossoverSubtrees}) is opt-in:
18
+ * {@link ScalarSearchOptions.crossoverProbability} defaults to 0, so the
19
+ * offspring loop stays mutation-only and the default random stream is unchanged.
12
20
  *
13
21
  * @packageDocumentation
14
22
  */
15
23
  import { type SeededRng } from '@danielsimonjr/mathts-core';
16
- import { type ScalarGrammar, type ScalarNode } from '@danielsimonjr/mathts-expression';
24
+ import { type ScalarComplexityWeights, type ScalarGrammar, type ScalarNode } from '@danielsimonjr/mathts-expression';
25
+ import { type NamedScalarLoss } from './fit-scalar.js';
17
26
  import { type ScoredCandidate } from './pareto-front.js';
18
27
  import { type ScalarPopulationParallelOptions } from './scalar-batch-parallel.js';
28
+ import { type RationalDimension } from './scalar-dimension.js';
19
29
  /** Columnar regression target for {@link searchScalars}. */
20
30
  export interface ScalarSearchProblem {
21
31
  /** Names of the input columns, in the order of `columns`. */
@@ -27,6 +37,34 @@ export interface ScalarSearchProblem {
27
37
  /** Fitted constants. Defaults to `grammar.parameters`. */
28
38
  readonly parameters?: readonly string[];
29
39
  }
40
+ /**
41
+ * Opt-in SI dimension filter for the scalar search
42
+ * ({@link ScalarSearchOptions.dimensions}).
43
+ *
44
+ * `symbols` binds variable and parameter names to dimensions. A name omitted
45
+ * from `symbols` is a solver unknown when it is a parameter and
46
+ * `unknown-symbol` when it is a variable. `target` is the dimension the scored
47
+ * tree's root must have. `onUnderdetermined` decides a solve whose parameter
48
+ * dimensions are not fixed by the equations implied by the tree: `'keep'` (the
49
+ * default) scores the tree normally — for example `x^p` with a free exponent
50
+ * parameter stays scorable under any `target` because the solver does not assign
51
+ * a unique dimension to `p`. `'reject'` scores it `Infinity`. Listed grammar
52
+ * parameters that do not appear in the tree are ignored for underdetermined
53
+ * detection. Before the first yield the filter is copied into a frozen snapshot
54
+ * (plain-data `symbols` only, same rules as `complexityWeights`).
55
+ */
56
+ export interface ScalarDimensionFilter {
57
+ readonly symbols: Readonly<Record<string, RationalDimension>>;
58
+ readonly target: RationalDimension;
59
+ readonly onUnderdetermined?: 'keep' | 'reject';
60
+ /** Caller equality for the inferred root dimension and `target` (infer mode only). A `false` result or a throw scores `Infinity`. Omitted: exact per-axis equality. */
61
+ readonly equal?: (left: RationalDimension, right: RationalDimension) => boolean;
62
+ }
63
+ /**
64
+ * When adaptive parsimony records offspring complexities within one generation.
65
+ * @internal Test hook only; not on the package barrel.
66
+ */
67
+ export type FrequencyRecordTiming = 'island-boundary' | 'after-merge' | 'per-offspring';
30
68
  /** Budget and evolution knobs for {@link searchScalars}. */
31
69
  export interface ScalarSearchOptions {
32
70
  readonly grammar: ScalarGrammar;
@@ -40,11 +78,116 @@ export interface ScalarSearchOptions {
40
78
  readonly tournamentP?: number;
41
79
  /** Chance that an evaluated tree has its parameters refitted. Default 0.14. */
42
80
  readonly optimizeProbability?: number;
81
+ /**
82
+ * Residual loss for ranking and for every refit. Default `'l2'`: today's sum of
83
+ * squares, including `+Infinity` when any row is invalid. `'l1'` and `'huber'`
84
+ * reuse {@link fitScalarParameters}'s named losses. Omitted is the default
85
+ * branch, so the seed-7 pin is unchanged.
86
+ */
87
+ readonly loss?: NamedScalarLoss;
88
+ /**
89
+ * Per-row weights for that loss. Length must equal `observed.length`; every
90
+ * weight is finite and `>= 0`. A zero weight drops that row. Omitted: every
91
+ * row weighs 1.
92
+ */
93
+ readonly rowWeights?: Float64Array;
94
+ /**
95
+ * How a tree that is invalid on at least one row is ranked. Default `'reject'`:
96
+ * today's `+Infinity` — such a tree never enters the hall. `'penalize'` scores
97
+ * {@link INVALID_ROW_PENALTY} (the fitter's existing invalid-row penalty) times
98
+ * the number of invalid rows a positive `rowWeights` entry covers, plus the
99
+ * chosen `loss` on the valid rows; a zero-weight row is dropped on both sides.
100
+ * A tree with no valid row reports the penalty times the number of positively
101
+ * weighted rows (each invalid among them adds one penalty). The penalty is
102
+ * absolute, not scaled to the target magnitude. The ranker adds that sum on top
103
+ * of the valid-row loss; the fitter's reported loss counts only valid rows and
104
+ * freezes invalid rows with a squared penalty inside LM — different objectives.
105
+ * Refit acceptance compares both sides with {@link scoreOnProblem} / the ranker.
106
+ * Omitted is the default branch, so the seed-7 pin is unchanged.
107
+ */
108
+ readonly invalidRows?: 'reject' | 'penalize';
109
+ /**
110
+ * Per-node weights for the complexity the hall, the truncation tie-break, and
111
+ * adaptive parsimony rank by. `ScalarComplexityWeights` from
112
+ * `@danielsimonjr/mathts-expression`; omitted fields weigh 1, so `{}` (and an
113
+ * omitted option) is today's node count. Weights are normalized once before the
114
+ * first yield into a frozen snapshot; only plain data objects are accepted at
115
+ * the top level and on `op`, `call`, and per-name `symbol` records (prototype
116
+ * `Object.prototype` or `null`). Own keys are read exactly once via
117
+ * `Reflect.ownKeys`; non-enumerable keys and accessor properties throw
118
+ * `RangeError`. Every weight must be a finite number; weights that would make
119
+ * `grammar.maxSize` nodes sum to a non-finite complexity also throw before the
120
+ * first yield. Zero and negative weights are accepted: they are summed and
121
+ * `Math.round`ed by `scalarComplexity` like any other weight. Nested record
122
+ * keys must use lowered call names (`ln` is stored as `log`); unknown keys are
123
+ * kept in the snapshot but ignored at scoring time.
124
+ */
125
+ readonly complexityWeights?: ScalarComplexityWeights;
126
+ /**
127
+ * Refit knobs forwarded to {@link fitScalarParameters}. An omitted field is
128
+ * today's call: `restarts` 2, `maxIterations` 8, no bounds, the fitter's
129
+ * default algorithm, and `initial` set to the inherited vector (ones for the
130
+ * initial population). The values are forwarded, not reimplemented; a bad
131
+ * bound or length throws the fitter's `RangeError` before the first yield.
132
+ */
133
+ readonly fit?: ScalarFitOptions;
134
+ /**
135
+ * Chance that an offspring is a subtree crossover of two tournament parents
136
+ * instead of a mutation of the first. Default 0: the coin is not drawn, so the
137
+ * random stream matches a search that never had this option. In (0, 1] the
138
+ * island stream draws the coin; on success a second parent is drawn with the
139
+ * same tournament, {@link crossoverSubtrees} runs, and the child is kept when
140
+ * it is non-null and the grammar (including `admit`) accepts it. Otherwise the search falls
141
+ * through to the existing mutation attempts. The inherited parameter vector
142
+ * is always the first parent's.
143
+ */
144
+ readonly crossoverProbability?: number;
145
+ /**
146
+ * Simplify each seed and each bred offspring once, before the grammar check and
147
+ * the score, so the scored tree is the tree whose parameters are fitted. Default
148
+ * `'off'`: neither simplifier runs and the seed-7 pin is unchanged. `'constants'`
149
+ * folds numeric-only subtrees ({@link simplifyConstants}). `'algebraic'` runs the
150
+ * expression simplifier ({@link simplifyScalar}); when it throws
151
+ * `ScalarBuildError`, or its result fails the grammar (including `admit`), the
152
+ * tree keeps its unsimplified shape. Trees that come out of `enumerateScalars`
153
+ * are not simplified. Simplification draws no random numbers, but different
154
+ * accepted trees can change how many mutation attempts succeed, so a run with
155
+ * `simplify` on may diverge from an otherwise identical run with `'off'`; two
156
+ * runs that share the same `simplify` mode and seed still match. Progress event
157
+ * count stays budget-driven (`maxEvaluations`). When the simplified tree fails
158
+ * the grammar, changes the valid/invalid pattern on a positively weighted row,
159
+ * or disagrees in value within tolerance on such a row, the unsimplified tree
160
+ * is kept. `admit` runs on the simplified tree when its canonical key differs;
161
+ * a no-op fold (same key) is checked once. Algebraic simplification costs
162
+ * milliseconds per tree; the option stays off by default and no speed claim is
163
+ * made here.
164
+ */
165
+ readonly simplify?: 'off' | 'constants' | 'algebraic';
166
+ /**
167
+ * Opt-in SI dimension filter. Omitted: no dimension walk and the seed-7 pin is
168
+ * unchanged. Set: after the grammar check (and any simplification) and before
169
+ * the score, the tree that will be scored is checked. With parameters the
170
+ * check is {@link solveParameterDimensions} when the fitted parameter list is
171
+ * non-empty; an empty `problem.parameters` array forces infer mode even when
172
+ * the grammar lists parameters. Without fitted parameters the check is
173
+ * {@link inferScalarDimension}. In both modes the inferred or solved root
174
+ * dimension must equal `target`.
175
+ * An `add-mismatch`, `transcendental-arg-not-dimensionless`,
176
+ * `non-literal-exponent-on-dimensional-base`, or `unknown-symbol` violation,
177
+ * or an `inconsistent` solve, scores `Infinity` and never enters the hall —
178
+ * the same bucket as a numerical failure — but still counts as an evaluation.
179
+ * An underdetermined solve is scored normally (`'keep'`, the default) or
180
+ * scored `Infinity` (`'reject'`). The check draws no random numbers.
181
+ */
182
+ readonly dimensions?: ScalarDimensionFilter;
43
183
  /** Cap on tree evaluations, the initial population included. */
44
184
  readonly maxEvaluations: number;
45
185
  /** Second cap on tree evaluations, reported as `'max-candidates'`. */
46
186
  readonly maxCandidates?: number;
47
- /** Trees injected into the initial population (`seeds`); the grammar filters them. */
187
+ /**
188
+ * Trees injected into the initial population (`seeds`). The grammar's structural
189
+ * rules filter them, and so does `grammar.admit` when it is set.
190
+ */
48
191
  readonly seeds?: readonly ScalarNode[];
49
192
  /** Constant-perturbation scale handed to the mutations. Default 0.25. */
50
193
  readonly perturbationFactor?: number;
@@ -53,9 +196,17 @@ export interface ScalarSearchOptions {
53
196
  /**
54
197
  * Independent islands, each with `populationSize` trees and its own random stream
55
198
  * (`rng.fork('island:' + index)`). Default 1, which draws from `rng.fork('population')`.
56
- * Evaluations are counted across all islands.
199
+ * Evaluations are counted across all islands. The islands' score calls overlap
200
+ * within one generation when worker scoring is active; without `parallel`, or below
201
+ * the row threshold, evaluation stays on the caller thread and overlap does not
202
+ * increase throughput. The merge after the scores runs in island-index order.
57
203
  */
58
204
  readonly populations?: number;
205
+ /**
206
+ * @internal Test hook only: when offspring complexities reach the adaptive-parsimony
207
+ * window within a generation. Default `island-boundary` matches the sequential schedule.
208
+ */
209
+ readonly frequencyRecordTiming?: FrequencyRecordTiming;
59
210
  /**
60
211
  * Expected share of each island replaced by another island's best trees after every
61
212
  * generation, in [0, 1]. The count is the expectation rounded at random. Default 0.00036
@@ -83,11 +234,74 @@ export interface ScalarSearchOptions {
83
234
  * 100 rows; below that, and when omitted, evaluation stays on the caller thread. The
84
235
  * workers return the values the caller thread would compute, bit for bit, and parameter
85
236
  * refits and every random draw stay on the caller thread, so a parallel run equals the
86
- * serial run for the same seed. `timeoutMs` (default 30000, must be positive) bounds each
87
- * worker call. A `pool` you pass is yours to terminate; without one the search starts a
88
- * pool when it first needs it and terminates it when the generator finishes or is closed.
237
+ * serial run for the same seed. Overlapped islands only overlap worker score calls; the
238
+ * caller-thread path does not gain throughput from SR-13. `timeoutMs` (default 30000,
239
+ * must be positive) bounds each worker task, including time queued behind other islands'
240
+ * submissions in the same generation — scale it with `populations` when several islands
241
+ * score together. A `pool` you pass is yours to terminate; without one the search starts
242
+ * a pool when it first needs it and terminates it when the generator finishes or is closed.
89
243
  */
90
244
  readonly parallel?: ScalarPopulationParallelOptions;
245
+ /**
246
+ * Cancellation signal (SR-15). The search checks it before the initial population
247
+ * and between generations, never in the middle of a random draw or a scored batch.
248
+ * Already aborted before the first yield: the result has an empty front,
249
+ * `evaluations: 0`, and `stopReason: 'cancelled'`. Aborted after a yield: the
250
+ * generator returns the last progress as the result with `stopReason: 'cancelled'`
251
+ * and does not start another generation (a generation that was already breeding
252
+ * and scoring runs to completion first). A pool the search owns is still
253
+ * terminated. Omitted: no cancellation and the seed-7 pin is unchanged.
254
+ */
255
+ readonly signal?: AbortSignal;
256
+ /**
257
+ * Optional early stop (SR-15). Omitted: the search always runs to
258
+ * `max-evaluations` (or `'max-candidates'`). Set: after a generation whose best
259
+ * finite hall loss is `<= loss`, and that has stayed true for `generations`
260
+ * consecutive generations, the search returns `stopReason: 'early-stop'` after
261
+ * yielding that generation's progress. The streak is counted over the hall after
262
+ * the generation (the initial population included), and it resets when a
263
+ * generation leaves the best loss above `loss` — the best hall loss can only
264
+ * improve, so a reset happens only while the hall is still empty or the best
265
+ * loss has not yet reached `loss`. `loss` must be finite and `generations` an
266
+ * integer `>= 1` (`RangeError` otherwise). A run that never reaches `loss`
267
+ * still ends on `'max-evaluations'`.
268
+ */
269
+ readonly earlyStop?: {
270
+ readonly loss: number;
271
+ readonly generations: number;
272
+ };
273
+ /**
274
+ * Factor forwarded to {@link selectFrontModel}'s `bestLossFactor` when
275
+ * `modelSelection` is set (SR-16). Omitted: the factor `selectFrontModel`
276
+ * already defaults to (1.5), so today's call is unchanged. A non-finite value
277
+ * throws `RangeError` before the search starts, even when `modelSelection` is
278
+ * omitted. Only read when `modelSelection` is set. Values in `(0, 1)` can make
279
+ * the `'best'` filter keep no row once selection runs, which throws
280
+ * {@link ParetoFrontError} mid-run; `1` is the safe lower boundary (only
281
+ * minimum-loss rows qualify).
282
+ */
283
+ readonly bestLossFactor?: number;
284
+ }
285
+ /** Budget, bounds, and start-vector knobs for the search's parameter refits. */
286
+ export interface ScalarFitOptions {
287
+ /** Restarted fits per refit. Default 2. Must be an integer >= 0. */
288
+ readonly restarts?: number;
289
+ /** Optimizer iterations per fit. Default 8. Must be an integer >= 0. */
290
+ readonly maxIterations?: number;
291
+ /**
292
+ * One `[lo, hi]` pair per parameter. Endpoints are finite or `±Infinity`;
293
+ * `lo` must not exceed `hi`, and the length must equal the parameter count.
294
+ * Default: unbounded.
295
+ */
296
+ readonly bounds?: readonly (readonly [number, number])[];
297
+ /** Optimizer. Default: the fitter's choice (`'lm'` for `'l2'`, `'bfgs'` otherwise). */
298
+ readonly algorithm?: 'lm' | 'bfgs' | 'nelder-mead';
299
+ /**
300
+ * Start vector of every refit. Length must equal the parameter count and every
301
+ * value must be finite. Default: the tree's inherited vector (ones at the
302
+ * initial population).
303
+ */
304
+ readonly initial?: ArrayLike<number>;
91
305
  }
92
306
  /** One progress event; `status` is always `'fitted'`. */
93
307
  export interface SearchProgress {
@@ -101,7 +315,7 @@ export interface SearchProgress {
101
315
  readonly fittedParameters: Float64Array[];
102
316
  readonly selected?: ScoredCandidate<ScalarNode>;
103
317
  }
104
- export type ScalarSearchStopReason = 'max-evaluations' | 'max-candidates';
318
+ export type ScalarSearchStopReason = 'max-evaluations' | 'max-candidates' | 'cancelled' | 'early-stop';
105
319
  /** Final value of the async generator returned by {@link searchScalars}. */
106
320
  export interface ScalarSearchResult {
107
321
  readonly front: ScoredCandidate<ScalarNode>[];
@@ -111,7 +325,21 @@ export interface ScalarSearchResult {
111
325
  readonly evaluations: number;
112
326
  readonly seed: number;
113
327
  readonly selected?: ScoredCandidate<ScalarNode>;
328
+ /**
329
+ * How often a seed or offspring kept its unsimplified shape because simplification
330
+ * threw (other than `ScalarBuildError`), failed the grammar or row-wise evaluation
331
+ * check, or hit a `RangeError` from a deep simplify. Zero when `simplify` is
332
+ * `'off'` or omitted.
333
+ */
334
+ readonly simplifyFallbacks: number;
114
335
  }
336
+ /** @internal Exported for unit tests; not part of the package barrel. */
337
+ export declare function simplifyCandidateForTest(node: ScalarNode, mode: ScalarSearchOptions['simplify'], recordFallback?: () => void): ScalarNode;
338
+ /** @internal Exported for unit tests; not part of the package barrel. */
339
+ export declare function hallFrontForTest(individuals: readonly EvaluatedIndividual[]): {
340
+ front: ScoredCandidate<ScalarNode>[];
341
+ fittedParameters: Float64Array[];
342
+ };
115
343
  /** @internal One evaluated tree; exported for the unit tests, not the package barrel. */
116
344
  export interface EvaluatedIndividual {
117
345
  readonly node: ScalarNode;
@@ -168,9 +396,92 @@ export declare function migrateIslands(islands: Island[], fractionReplaced: numb
168
396
  * The generator yields one {@link SearchProgress} after the initial population
169
397
  * and one after every generation, and returns a {@link ScalarSearchResult}.
170
398
  * Evaluations never exceed `maxEvaluations`. `options.rng` is not advanced, so two
171
- * runs with the same inputs and seed agree bit for bit.
399
+ * runs with the same inputs and seed agree bit for bit. When `grammar.admit` is
400
+ * set it binds seeds and mutation offspring (`scalarGrammarAccepts`, then `admit`).
401
+ * A rejected child is a failed attempt; a rejected seed is skipped. `admit` must
402
+ * be a pure function of the node — a predicate that reads a clock or a random
403
+ * stream makes the run unreproducible. `admitMonotone` is left to enumeration.
404
+ * Ranking and refit share `loss` (`'l2'` by default) and optional `rowWeights`.
405
+ * `invalidRows` defaults to `'reject'` (`+Infinity` on any invalid row); `'penalize'`
406
+ * adds {@link INVALID_ROW_PENALTY} per positively weighted invalid row on top of the
407
+ * valid-row loss (absolute, not target-scaled). Under `'penalize'` the advisory refit
408
+ * still runs when every weighted row is invalid; refit acceptance uses the ranker on
409
+ * both sides. `complexityWeights` weighs the nodes of the complexity the hall, the
410
+ * truncation tie-break, and adaptive parsimony use; omitted, it is today's size.
411
+ * When set, weights are copied into a frozen snapshot before the first yield (plain
412
+ * data objects only; non-enumerable keys and accessors are rejected). Record keys
413
+ * use lowered call names (`ln` → `log`); unknown keys are ignored by
414
+ * `scalarComplexity`. `grammar.maxSize` counts raw nodes, not weighted complexity;
415
+ * `Math.round` on the sum can map distinct trees to one hall slot. The hall keeps one
416
+ * tree per canonical key at add time (best loss, then complexity, then first recorded);
417
+ * elitist truncation already keeps one tree per key in the population with the same
418
+ * loss-first order. Weights change reported complexity only, not which duplicate survives.
419
+ * `fit`
420
+ * forwards `restarts` (default 2), `maxIterations` (default 8), `bounds`,
421
+ * `algorithm`, and `initial` (default the inherited vector) to the fitter; a bad
422
+ * bound or length throws before the first yield. Omitted fields are today's call.
423
+ * `crossoverProbability` defaults to 0 (no coin). A positive probability draws
424
+ * the coin on the island stream and, on success, a second tournament parent.
425
+ * `simplify` defaults to `'off'` (no simplifier runs). `'constants'` folds
426
+ * numeric-only subtrees and `'algebraic'` runs the expression simplifier, once
427
+ * per seed and per bred offspring, before the grammar check and the score; a
428
+ * `ScalarBuildError`, `RangeError`, grammar rejection (including `admit`), or
429
+ * row-wise evaluation mismatch keeps the unsimplified tree. Enumerated trees are
430
+ * not simplified. Simplification draws no random numbers, but different accepted
431
+ * trees can change mutation outcomes, so a run with `simplify` on may diverge from
432
+ * `'off'`; two runs that share the same mode and seed still match. Progress event
433
+ * count stays budget-driven. `dimensions` (opt-in) checks the SI dimension of the
434
+ * tree that will be scored — after the grammar check, before the score — against
435
+ * `target`: a violation or an `inconsistent` solve scores `Infinity` (still an
436
+ * evaluation, never in the hall), an underdetermined solve is kept by default or
437
+ * rejected with `'reject'`, and the check draws no random numbers. `signal`
438
+ * (opt-in) is checked before the initial population and between generations, never
439
+ * mid-draw: already aborted before the first yield the result carries an empty
440
+ * front and `evaluations: 0`; aborted after a yield the last progress is returned
441
+ * as the result, both with `stopReason: 'cancelled'`. `earlyStop` (opt-in) ends
442
+ * the run with `stopReason: 'early-stop'` once the best finite hall loss has been
443
+ * `<= loss` for `generations` consecutive generations (hall after the generation,
444
+ * initial population included).
172
445
  *
173
446
  * @throws {RangeError} A malformed problem or option, or a grammar that admits no tree.
174
447
  */
175
448
  export declare function searchScalars(problem: ScalarSearchProblem, options: ScalarSearchOptions): AsyncGenerator<SearchProgress, ScalarSearchResult>;
449
+ /**
450
+ * Problem input for {@link runScalarSearch}: like {@link ScalarSearchProblem},
451
+ * but `columns` may be a record keyed by variable name instead of the aligned
452
+ * array `searchScalars` requires.
453
+ */
454
+ export interface ScalarSearchRunProblem extends Omit<ScalarSearchProblem, 'columns'> {
455
+ /**
456
+ * One column per variable. Either the aligned array `searchScalars` takes, or a
457
+ * record keyed by the names in `variables`; the wrapper reads a record in
458
+ * `variables` order to build that array. A name without an entry throws
459
+ * `RangeError`. A column whose length differs from `observed.length` throws
460
+ * `RangeError` from `searchScalars` as usual.
461
+ */
462
+ readonly columns: readonly Float64Array[] | Readonly<Record<string, Float64Array>>;
463
+ }
464
+ /**
465
+ * Options for {@link runScalarSearch}: {@link ScalarSearchOptions} with `rng`
466
+ * optional — exactly one of `seed` and `rng` must be set.
467
+ */
468
+ export type ScalarSearchRunOptions = Omit<ScalarSearchOptions, 'rng'> & {
469
+ /** Seed for a fresh {@link createSeededRng}; required when `rng` is omitted. */
470
+ readonly seed?: number;
471
+ /** Caller-owned random stream; required when `seed` is omitted, never advanced. */
472
+ readonly rng?: SeededRng;
473
+ };
474
+ /**
475
+ * Consume {@link searchScalars} to its final {@link ScalarSearchResult} (SR-16).
476
+ * A thin wrapper: when `seed` is set and `rng` is omitted it builds
477
+ * {@link createSeededRng}(seed) and passes that; when both are set, or neither
478
+ * is, it throws `RangeError`. A `columns` record is read in `variables` order.
479
+ * It does not reimplement any search behavior, so every documented default and
480
+ * the seed-7 pin hold unchanged.
481
+ *
482
+ * @throws {RangeError} `seed` and `rng` are both set, neither is set, a variable
483
+ * has no entry in `columns`, `bestLossFactor` is non-finite, or any check
484
+ * {@link searchScalars} itself performs fails.
485
+ */
486
+ export declare function runScalarSearch(problem: ScalarSearchRunProblem, options: ScalarSearchRunOptions): Promise<ScalarSearchResult>;
176
487
  //# sourceMappingURL=scalar-search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scalar-search.d.ts","sourceRoot":"","sources":["../src/scalar-search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scalar-search.d.ts","sourceRoot":"","sources":["../src/scalar-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Dynamic time warping with an optional Sakoe-Chiba band.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ type Vec = readonly number[] | Float64Array;
7
+ /** Options for {@link dtw}. */
8
+ export interface DtwOptions {
9
+ /**
10
+ * Sakoe-Chiba band half-width in samples. Widened automatically to at least
11
+ * |a.length - b.length|. Default: unconstrained.
12
+ */
13
+ window?: number;
14
+ /** Local cost between two samples (default `|x - y|`). */
15
+ dist?: (x: number, y: number) => number;
16
+ }
17
+ /** Result of {@link dtw}. */
18
+ export interface DtwResult {
19
+ /** Accumulated cost of the optimal warping path. */
20
+ distance: number;
21
+ /** Optimal alignment as (i, j) index pairs from [0, 0] to [n-1, m-1]. */
22
+ path: Array<[number, number]>;
23
+ }
24
+ /**
25
+ * Dynamic time warping between two sequences.
26
+ *
27
+ * @example
28
+ * dtw([1, 2, 3], [1, 2, 2, 3]).distance; // 0
29
+ */
30
+ export declare function dtw(a: Vec, b: Vec, opts?: DtwOptions): DtwResult;
31
+ export {};
32
+ //# sourceMappingURL=dtw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dtw.d.ts","sourceRoot":"","sources":["../../src/signal/dtw.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAG5C,+BAA+B;AAC/B,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC;AAED,6BAA6B;AAC7B,MAAM,WAAW,SAAS;IACxB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,CAsDhE"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Lomb-Scargle periodogram for unevenly sampled data (classic Scargle form with
3
+ * the tau time offset, as in scipy.signal.lombscargle).
4
+ *
5
+ * @packageDocumentation
6
+ */
7
+ type Vec = readonly number[] | Float64Array;
8
+ /** Options for {@link lombScargle}. */
9
+ export interface LombScargleOptions {
10
+ /** Scale so that a pure sinusoid of unit amplitude peaks near 1 (default false). */
11
+ normalize?: boolean;
12
+ /** Subtract the mean of y before the transform (default false). */
13
+ precenter?: boolean;
14
+ }
15
+ /**
16
+ * Lomb-Scargle power at each angular frequency in `freqs` (rad per time unit).
17
+ *
18
+ * @param t - Sample times
19
+ * @param y - Sample values, same length as t
20
+ * @param freqs - Angular frequencies omega
21
+ * @returns Power per frequency (unnormalized: 0.5 * sum of squared projections)
22
+ */
23
+ export declare function lombScargle(t: Vec, y: Vec, freqs: Vec, opts?: LombScargleOptions): number[];
24
+ export {};
25
+ //# sourceMappingURL=lomb-scargle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lomb-scargle.d.ts","sourceRoot":"","sources":["../../src/signal/lomb-scargle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAG5C,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,oFAAoF;IACpF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,EAAE,CA0C3F"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * LTI system responses, transfer-function / state-space conversions, and
3
+ * simple IIR notch / peak designs (scipy.signal parity for the covered cases).
4
+ *
5
+ * Transfer-function coefficient arrays are highest-power first (scipy order).
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { ComplexNumber } from './fft.js';
10
+ type Vec = readonly number[] | Float64Array;
11
+ /** Continuous or discrete state-space realisation. */
12
+ export interface StateSpace {
13
+ A: number[][];
14
+ B: number[][];
15
+ C: number[][];
16
+ D: number[][];
17
+ }
18
+ /** Discretisation method for {@link cont2discrete}. */
19
+ export type DiscretizeMethod = 'zoh' | 'bilinear' | 'euler';
20
+ /** Second-order-section filter coefficients. */
21
+ export interface BiquadCoefficients {
22
+ b: number[];
23
+ a: number[];
24
+ }
25
+ /** Impulse response h[0..n-1] of the filter b / a. */
26
+ export declare function impulseResponse(b: Vec, a: Vec, n: number): number[];
27
+ /** Step response y[0..n-1] of the filter b / a. */
28
+ export declare function stepResponse(b: Vec, a: Vec, n: number): number[];
29
+ /**
30
+ * Transfer function to controllable canonical state space (SISO), as scipy.signal.tf2ss.
31
+ *
32
+ * @example
33
+ * tf2ss([1], [1, 3, 2]); // A = [[-3, -2], [1, 0]], B = [[1], [0]], C = [[0, 1]], D = [[0]]
34
+ */
35
+ export declare function tf2ss(b: Vec, a: Vec): StateSpace;
36
+ /**
37
+ * State space to transfer function (SISO), as scipy.signal.ss2tf.
38
+ * num is returned without leading zeros.
39
+ */
40
+ export declare function ss2tf(A: number[][], B: number[][], C: number[][], D: number[][]): {
41
+ num: number[];
42
+ den: number[];
43
+ };
44
+ /**
45
+ * Convert a continuous state-space system to discrete time with sample period dt.
46
+ *
47
+ * - `zoh`: exact zero-order hold, via the exponential of [[A, B], [0, 0]] dt
48
+ * - `bilinear`: Tustin (scipy, alpha = 1/2), with M = (I - A dt/2)^-1:
49
+ * Ad = M (I + A dt/2), Bd = M B dt, Cd = C M, Dd = D + C Bd / 2
50
+ * - `euler`: forward Euler, Ad = I + A dt, Bd = B dt
51
+ */
52
+ export declare function cont2discrete(sys: StateSpace, dt: number, method?: DiscretizeMethod): StateSpace;
53
+ /**
54
+ * Second-order IIR notch at normalised frequency w0 (x pi rad/sample), quality
55
+ * factor Q = w0 / bandwidth (scipy.signal.iirnotch convention: -3 dB bandwidth
56
+ * w0 pi / Q). Zero at w0, unity gain at DC.
57
+ */
58
+ export declare function iirNotch(w0: number, Q: number): BiquadCoefficients;
59
+ /**
60
+ * Second-order IIR peak (band-pass) at w0 (x pi rad/sample), unity gain at w0 and
61
+ * zero gain at DC and Nyquist (scipy.signal.iirpeak convention, Q = w0 / bandwidth).
62
+ */
63
+ export declare function iirPeak(w0: number, Q: number): BiquadCoefficients;
64
+ /**
65
+ * Transfer function to zeros, poles and gain (scipy.signal.tf2zpk). Zeros and
66
+ * poles are sorted by real then imaginary part.
67
+ */
68
+ export declare function tf2zpk(b: Vec, a: Vec): {
69
+ z: ComplexNumber[];
70
+ p: ComplexNumber[];
71
+ k: number;
72
+ };
73
+ /**
74
+ * Cascade of second-order sections to a single transfer function. Each section
75
+ * is [b0, b1, b2, a0, a1, a2]; the result is not normalised by a0.
76
+ */
77
+ export declare function sos2tf(sos: ReadonlyArray<readonly number[]>): {
78
+ b: number[];
79
+ a: number[];
80
+ };
81
+ export {};
82
+ //# sourceMappingURL=system-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-response.d.ts","sourceRoot":"","sources":["../../src/signal/system-response.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAG5C,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CACf;AAED,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,UAAU,GAAG,OAAO,CAAC;AAE5D,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IACjC,CAAC,EAAE,MAAM,EAAE,CAAC;IACZ,CAAC,EAAE,MAAM,EAAE,CAAC;CACb;AAuFD,sDAAsD;AACtD,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAKnE;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhE;AAMD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,GAAG,UAAU,CAqBhD;AAyBD;;;GAGG;AACH,wBAAgB,KAAK,CACnB,CAAC,EAAE,MAAM,EAAE,EAAE,EACb,CAAC,EAAE,MAAM,EAAE,EAAE,EACb,CAAC,EAAE,MAAM,EAAE,EAAE,EACb,CAAC,EAAE,MAAM,EAAE,EAAE,GACZ;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAWlC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,MAAM,EACV,MAAM,GAAE,gBAAwB,GAC/B,UAAU,CA0CZ;AAmBD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAQlE;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAQjE;AAoDD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,GAAG;IAAE,CAAC,EAAE,aAAa,EAAE,CAAC;IAAC,CAAC,EAAE,aAAa,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAM5F;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,SAAS,MAAM,EAAE,CAAC,GAAG;IAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAc1F"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Test waveform generators (scipy.signal.waveforms parity).
3
+ *
4
+ * Phase offsets `phi` are in radians (scipy takes degrees for chirp/sweep_poly).
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ type Vec = readonly number[] | Float64Array;
9
+ /** Frequency sweep method for {@link chirp}. */
10
+ export type ChirpMethod = 'linear' | 'quadratic' | 'logarithmic' | 'hyperbolic';
11
+ /** Options for {@link chirp}. */
12
+ export interface ChirpOptions {
13
+ /** Sweep law (default `'linear'`). */
14
+ method?: ChirpMethod;
15
+ /** Phase offset in radians (default 0). */
16
+ phi?: number;
17
+ }
18
+ /**
19
+ * Cosine chirp sweeping from f0 at t = 0 to f1 at t = t1 (frequencies in Hz).
20
+ *
21
+ * @example
22
+ * chirp([0], 1, 1, 10); // [1]
23
+ */
24
+ export declare function chirp(t: Vec, f0: number, t1: number, f1: number, opts?: ChirpOptions): number[];
25
+ /**
26
+ * Square wave: +1 while frac(t / 2 pi) < duty, otherwise -1.
27
+ */
28
+ export declare function squareWave(t: Vec, duty?: number): number[];
29
+ /**
30
+ * Sawtooth wave: -1 at phase 0 rising to +1 at phase 2 pi * width, then falling
31
+ * back. `width = 1` is a rising ramp; `width = 0.5` is a triangle.
32
+ */
33
+ export declare function sawtooth(t: Vec, width?: number): number[];
34
+ /**
35
+ * Gaussian-modulated cosine pulse.
36
+ *
37
+ * @param fc - Centre frequency (Hz)
38
+ * @param bw - Fractional bandwidth (default 0.5)
39
+ * @param bwr - Reference level in dB for the bandwidth (default -6)
40
+ */
41
+ export declare function gaussPulse(t: Vec, fc: number, bw?: number, bwr?: number): number[];
42
+ /**
43
+ * Discrete unit impulse of length n. `idx` defaults to 0, `'mid'` is floor(n / 2).
44
+ */
45
+ export declare function unitImpulse(n: number, idx?: number | 'mid'): number[];
46
+ /**
47
+ * Cosine with a polynomial instantaneous frequency f(t) = sum_k c_k t^(p-k) Hz.
48
+ * `polyCoeffs` are highest-order first (numpy poly1d order).
49
+ */
50
+ export declare function sweepPoly(t: Vec, polyCoeffs: readonly number[], phi?: number): number[];
51
+ export {};
52
+ //# sourceMappingURL=waveforms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waveforms.d.ts","sourceRoot":"","sources":["../../src/signal/waveforms.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAI5C,gDAAgD;AAChD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,GAAG,YAAY,CAAC;AAEhF,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAM/F;AAuCD;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,GAAE,MAAY,GAAG,MAAM,EAAE,CAM/D;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,GAAE,MAAU,GAAG,MAAM,EAAE,CAO5D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAE,MAAY,EAAE,GAAG,GAAE,MAAW,GAAG,MAAM,EAAE,CAI3F;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,GAAG,KAAS,GAAG,MAAM,EAAE,CASxE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,GAAE,MAAU,GAAG,MAAM,EAAE,CAW1F"}