@vessel-dsp/runtime 0.2.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 +178 -0
- package/dist/admission.d.ts +94 -0
- package/dist/admission.d.ts.map +1 -0
- package/dist/admission.js +209 -0
- package/dist/admission.js.map +1 -0
- package/dist/calibrate.d.ts +104 -0
- package/dist/calibrate.d.ts.map +1 -0
- package/dist/calibrate.js +420 -0
- package/dist/calibrate.js.map +1 -0
- package/dist/chain-advisories.d.ts +71 -0
- package/dist/chain-advisories.d.ts.map +1 -0
- package/dist/chain-advisories.js +268 -0
- package/dist/chain-advisories.js.map +1 -0
- package/dist/chain-scale.d.ts +82 -0
- package/dist/chain-scale.d.ts.map +1 -0
- package/dist/chain-scale.js +121 -0
- package/dist/chain-scale.js.map +1 -0
- package/dist/chain-slot.d.ts +130 -0
- package/dist/chain-slot.d.ts.map +1 -0
- package/dist/chain-slot.js +105 -0
- package/dist/chain-slot.js.map +1 -0
- package/dist/chain.d.ts +113 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +355 -0
- package/dist/chain.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/numeric-pivot.d.ts +4 -0
- package/dist/numeric-pivot.d.ts.map +1 -0
- package/dist/numeric-pivot.js +192 -0
- package/dist/numeric-pivot.js.map +1 -0
- package/dist/reference-runtime.d.ts +1080 -0
- package/dist/reference-runtime.d.ts.map +1 -0
- package/dist/reference-runtime.js +6743 -0
- package/dist/reference-runtime.js.map +1 -0
- package/dist/settle.d.ts +359 -0
- package/dist/settle.d.ts.map +1 -0
- package/dist/settle.js +900 -0
- package/dist/settle.js.map +1 -0
- package/dist/supply-ground.d.ts +22 -0
- package/dist/supply-ground.d.ts.map +1 -0
- package/dist/supply-ground.js +62 -0
- package/dist/supply-ground.js.map +1 -0
- package/dist/supply.d.ts +30 -0
- package/dist/supply.d.ts.map +1 -0
- package/dist/supply.js +10 -0
- package/dist/supply.js.map +1 -0
- package/dist/taper.d.ts +10 -0
- package/dist/taper.d.ts.map +1 -0
- package/dist/taper.js +34 -0
- package/dist/taper.js.map +1 -0
- package/dist/v2-wasm-engine.d.ts +91 -0
- package/dist/v2-wasm-engine.d.ts.map +1 -0
- package/dist/v2-wasm-engine.js +296 -0
- package/dist/v2-wasm-engine.js.map +1 -0
- package/dist/wasm/v2_dsp.cjs +22 -0
- package/dist/wasm/v2_dsp.wasm +0 -0
- package/package.json +62 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
// Runtime calibration harness: measure this host's own dense-solve cost per
|
|
2
|
+
// unknown count, so the admission check in `./admission.ts` can be enforced.
|
|
3
|
+
//
|
|
4
|
+
// Method (the whole measurement, stated once so a reader can audit it).
|
|
5
|
+
// For each system size, in ascending order:
|
|
6
|
+
// 1. Call the caller-supplied factory once to prepare one workload, then run
|
|
7
|
+
// `warmupSolves` untimed solves so caches, JIT state, and branch
|
|
8
|
+
// predictors settle before any reading is taken.
|
|
9
|
+
// 2. Time batches of solves. A batch starts at `solvesPerSample` solves and
|
|
10
|
+
// grows by factors of ten until the batch elapsed time is at least one
|
|
11
|
+
// hundred times the stated timer resolution, so the clock resolution is
|
|
12
|
+
// under one percent of every timed batch. Growth stops at
|
|
13
|
+
// MAX_SOLVES_PER_SAMPLE; if even that batch is unresolved, calibration
|
|
14
|
+
// refuses with `timer-too-coarse` instead of reporting a number the clock
|
|
15
|
+
// cannot support. Probe batches are discarded, never counted as samples.
|
|
16
|
+
// 3. Take `samples` timed batches. Each sample is the batch elapsed time
|
|
17
|
+
// divided by the batch solve count, in nanoseconds per solve.
|
|
18
|
+
// 4. Report the MEDIAN of the samples as the size's cost. Median, not mean:
|
|
19
|
+
// a single huge sample (a scheduling pause, a garbage collection, a
|
|
20
|
+
// thermal excursion) moves the mean by a large fraction and barely moves
|
|
21
|
+
// the median, and with a handful of samples the median stays
|
|
22
|
+
// representative of the sustained cost admission must budget for.
|
|
23
|
+
// 5. Report spread as the interquartile range over the median
|
|
24
|
+
// (`spreadFraction = (q3 - q1) / median`, Tukey hinges: q1 is the median
|
|
25
|
+
// of the lower floor(n/2) samples, q3 the median of the upper
|
|
26
|
+
// floor(n/2)). A single sample gives spread zero.
|
|
27
|
+
// 6. Enforce a monotone non-decreasing envelope across sizes: a larger
|
|
28
|
+
// system never reports cheaper than a smaller one. Correction is a
|
|
29
|
+
// running maximum over ascending sizes (each size is raised to the
|
|
30
|
+
// largest median seen so far, never lowered), and every correction is
|
|
31
|
+
// listed in `corrections` with both the measured and the reported
|
|
32
|
+
// figure, so no adjustment is silent.
|
|
33
|
+
//
|
|
34
|
+
// The `nsPerSolve` curve interpolates log-log between measured sizes,
|
|
35
|
+
// clamps below the smallest measured size (a tiny system is charged at the
|
|
36
|
+
// smallest measured cost, which is conservative), and extrapolates beyond
|
|
37
|
+
// the largest measured size with one fitted exponent: the least-squares
|
|
38
|
+
// slope of log cost on log size over the whole corrected table, anchored at
|
|
39
|
+
// the largest measured point so the curve is continuous there. A
|
|
40
|
+
// single-size table is constant everywhere. Non-positive or non-finite
|
|
41
|
+
// counts throw a RangeError.
|
|
42
|
+
//
|
|
43
|
+
// This module is ENGINE-AGNOSTIC. The caller passes the thing to time (a
|
|
44
|
+
// factory returning a one-solve function), so today it times a TypeScript
|
|
45
|
+
// solve and later the WebAssembly console. It invents no engine numbers:
|
|
46
|
+
// every nanosecond in the table was read off the injected clock.
|
|
47
|
+
//
|
|
48
|
+
// Clocks. `now` returns NANOSECONDS. The default wraps `performance.now`
|
|
49
|
+
// (which reports milliseconds) with the millisecond-to-nanosecond factor.
|
|
50
|
+
// `minTimerResolutionNs` is the smallest difference the clock can honestly
|
|
51
|
+
// report; the batch-growth loop enforces the one-percent rule against it.
|
|
52
|
+
/** Sizes measured when the caller states none. */
|
|
53
|
+
export const DEFAULT_CALIBRATION_SIZES = [2, 4, 8, 16, 32, 64];
|
|
54
|
+
/** Batches never grow past this many solves; beyond it the clock is refused. */
|
|
55
|
+
const MAX_SOLVES_PER_SAMPLE = 1_000_000;
|
|
56
|
+
/** A timed batch must last at least this many times the stated resolution. */
|
|
57
|
+
const BATCH_RESOLUTION_MARGIN = 100;
|
|
58
|
+
/** Default assumed resolution of a `performance.now`-derived clock. */
|
|
59
|
+
const DEFAULT_TIMER_RESOLUTION_NS = 1000;
|
|
60
|
+
function defaultNowNs() {
|
|
61
|
+
return performance.now() * 1e6;
|
|
62
|
+
}
|
|
63
|
+
function isPositiveInt(value) {
|
|
64
|
+
return Number.isInteger(value) && value > 0;
|
|
65
|
+
}
|
|
66
|
+
function medianOfSorted(sorted) {
|
|
67
|
+
const n = sorted.length;
|
|
68
|
+
const mid = Math.floor(n / 2);
|
|
69
|
+
if (n % 2 === 1) {
|
|
70
|
+
return sorted[mid];
|
|
71
|
+
}
|
|
72
|
+
return (sorted[mid - 1] + sorted[mid]) / 2;
|
|
73
|
+
}
|
|
74
|
+
/** Least-squares slope of log(cost) on log(size); 0 when no slope exists. */
|
|
75
|
+
function fitLogLogExponent(points) {
|
|
76
|
+
const usable = points.filter((p) => p.unknownCount > 0 && p.costNs > 0);
|
|
77
|
+
if (usable.length < 2) {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
let sumX = 0;
|
|
81
|
+
let sumY = 0;
|
|
82
|
+
let sumXX = 0;
|
|
83
|
+
let sumXY = 0;
|
|
84
|
+
for (const p of usable) {
|
|
85
|
+
const x = Math.log(p.unknownCount);
|
|
86
|
+
const y = Math.log(p.costNs);
|
|
87
|
+
sumX += x;
|
|
88
|
+
sumY += y;
|
|
89
|
+
sumXX += x * x;
|
|
90
|
+
sumXY += x * y;
|
|
91
|
+
}
|
|
92
|
+
const m = usable.length;
|
|
93
|
+
const denominator = m * sumXX - sumX * sumX;
|
|
94
|
+
if (denominator === 0 || !Number.isFinite(denominator)) {
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
const slope = (m * sumXY - sumX * sumY) / denominator;
|
|
98
|
+
return Number.isFinite(slope) ? slope : 0;
|
|
99
|
+
}
|
|
100
|
+
function buildNsPerSolve(rows) {
|
|
101
|
+
const bySize = new Map();
|
|
102
|
+
for (const row of rows) {
|
|
103
|
+
bySize.set(row.unknownCount, row.costNs);
|
|
104
|
+
}
|
|
105
|
+
const ascending = [...rows].sort((a, b) => a.unknownCount - b.unknownCount);
|
|
106
|
+
const exponent = fitLogLogExponent(ascending);
|
|
107
|
+
const smallest = ascending[0];
|
|
108
|
+
const largest = ascending[ascending.length - 1];
|
|
109
|
+
return (unknownCount) => {
|
|
110
|
+
if (!Number.isFinite(unknownCount) || unknownCount <= 0) {
|
|
111
|
+
throw new RangeError(`nsPerSolve requires a positive finite unknown count, got ${unknownCount}`);
|
|
112
|
+
}
|
|
113
|
+
const exact = bySize.get(unknownCount);
|
|
114
|
+
if (exact !== undefined) {
|
|
115
|
+
return exact;
|
|
116
|
+
}
|
|
117
|
+
if (unknownCount < smallest.unknownCount) {
|
|
118
|
+
return smallest.costNs;
|
|
119
|
+
}
|
|
120
|
+
if (ascending.length === 1) {
|
|
121
|
+
return smallest.costNs;
|
|
122
|
+
}
|
|
123
|
+
for (let i = 0; i < ascending.length - 1; i++) {
|
|
124
|
+
const lo = ascending[i];
|
|
125
|
+
const hi = ascending[i + 1];
|
|
126
|
+
if (unknownCount > lo.unknownCount && unknownCount < hi.unknownCount) {
|
|
127
|
+
const t = (Math.log(unknownCount) - Math.log(lo.unknownCount)) /
|
|
128
|
+
(Math.log(hi.unknownCount) - Math.log(lo.unknownCount));
|
|
129
|
+
return Math.exp(Math.log(lo.costNs) + t * (Math.log(hi.costNs) - Math.log(lo.costNs)));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return largest.costNs * (unknownCount / largest.unknownCount) ** exponent;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Measure this host's dense-solve cost per unknown count. Refuses with a
|
|
137
|
+
* typed reason instead of reporting a number the inputs cannot support.
|
|
138
|
+
*/
|
|
139
|
+
export function calibrateNsPerSolve(options) {
|
|
140
|
+
const solve = options.solve;
|
|
141
|
+
if (typeof solve !== "function") {
|
|
142
|
+
throw new TypeError("calibrateNsPerSolve requires a solve factory");
|
|
143
|
+
}
|
|
144
|
+
const sizes = options.sizes ?? DEFAULT_CALIBRATION_SIZES;
|
|
145
|
+
if (sizes.length === 0) {
|
|
146
|
+
return { ok: false, reason: "no-sizes" };
|
|
147
|
+
}
|
|
148
|
+
for (const [index, size] of sizes.entries()) {
|
|
149
|
+
if (!isPositiveInt(size)) {
|
|
150
|
+
return { ok: false, reason: "bad-size", size, index };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const warmupSolves = options.warmupSolves ?? 50;
|
|
154
|
+
if (!Number.isInteger(warmupSolves) || warmupSolves < 0 || !Number.isFinite(warmupSolves)) {
|
|
155
|
+
return {
|
|
156
|
+
ok: false,
|
|
157
|
+
reason: "zero-solves",
|
|
158
|
+
field: "warmupSolves",
|
|
159
|
+
value: warmupSolves,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const solvesPerSample = options.solvesPerSample ?? 100;
|
|
163
|
+
if (!isPositiveInt(solvesPerSample)) {
|
|
164
|
+
return {
|
|
165
|
+
ok: false,
|
|
166
|
+
reason: "zero-solves",
|
|
167
|
+
field: "solvesPerSample",
|
|
168
|
+
value: solvesPerSample,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
const samples = options.samples ?? 7;
|
|
172
|
+
if (!isPositiveInt(samples)) {
|
|
173
|
+
return {
|
|
174
|
+
ok: false,
|
|
175
|
+
reason: "zero-solves",
|
|
176
|
+
field: "samples",
|
|
177
|
+
value: samples,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const now = options.now ?? defaultNowNs;
|
|
181
|
+
const resolutionNs = options.minTimerResolutionNs ?? DEFAULT_TIMER_RESOLUTION_NS;
|
|
182
|
+
if (!Number.isFinite(resolutionNs) || resolutionNs < 0) {
|
|
183
|
+
throw new RangeError(`minTimerResolutionNs must be a finite number at least 0, got ${resolutionNs}`);
|
|
184
|
+
}
|
|
185
|
+
const requiredBatchNs = BATCH_RESOLUTION_MARGIN * resolutionNs;
|
|
186
|
+
const ordered = [...sizes].sort((a, b) => a - b);
|
|
187
|
+
const measured = [];
|
|
188
|
+
for (const unknownCount of ordered) {
|
|
189
|
+
let run;
|
|
190
|
+
try {
|
|
191
|
+
run = solve(unknownCount);
|
|
192
|
+
}
|
|
193
|
+
catch (thrown) {
|
|
194
|
+
return { ok: false, reason: "solve-threw", unknownCount, thrown };
|
|
195
|
+
}
|
|
196
|
+
if (typeof run !== "function") {
|
|
197
|
+
return {
|
|
198
|
+
ok: false,
|
|
199
|
+
reason: "solve-threw",
|
|
200
|
+
unknownCount,
|
|
201
|
+
thrown: new TypeError(`solve factory for ${unknownCount} unknowns did not return a function`),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
for (let i = 0; i < warmupSolves; i++) {
|
|
206
|
+
run();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch (thrown) {
|
|
210
|
+
return { ok: false, reason: "solve-threw", unknownCount, thrown };
|
|
211
|
+
}
|
|
212
|
+
// Grow the batch until the clock resolves it with margin, or refuse.
|
|
213
|
+
let batch = solvesPerSample;
|
|
214
|
+
let elapsedNs = 0;
|
|
215
|
+
for (;;) {
|
|
216
|
+
let t0Ns;
|
|
217
|
+
let t1Ns;
|
|
218
|
+
try {
|
|
219
|
+
t0Ns = now();
|
|
220
|
+
for (let i = 0; i < batch; i++) {
|
|
221
|
+
run();
|
|
222
|
+
}
|
|
223
|
+
t1Ns = now();
|
|
224
|
+
}
|
|
225
|
+
catch (thrown) {
|
|
226
|
+
return { ok: false, reason: "solve-threw", unknownCount, thrown };
|
|
227
|
+
}
|
|
228
|
+
if (!Number.isFinite(t0Ns) ||
|
|
229
|
+
!Number.isFinite(t1Ns) ||
|
|
230
|
+
!Number.isFinite(t1Ns - t0Ns) ||
|
|
231
|
+
t1Ns - t0Ns < 0) {
|
|
232
|
+
return {
|
|
233
|
+
ok: false,
|
|
234
|
+
reason: "non-finite-time",
|
|
235
|
+
unknownCount,
|
|
236
|
+
t0Ns,
|
|
237
|
+
t1Ns,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
elapsedNs = t1Ns - t0Ns;
|
|
241
|
+
if (elapsedNs >= requiredBatchNs) {
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
if (batch >= MAX_SOLVES_PER_SAMPLE) {
|
|
245
|
+
return {
|
|
246
|
+
ok: false,
|
|
247
|
+
reason: "timer-too-coarse",
|
|
248
|
+
unknownCount,
|
|
249
|
+
resolutionNs,
|
|
250
|
+
largestBatchSolves: batch,
|
|
251
|
+
elapsedNs,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
batch = Math.min(batch * 10, MAX_SOLVES_PER_SAMPLE);
|
|
255
|
+
}
|
|
256
|
+
const perSolve = [];
|
|
257
|
+
for (let s = 0; s < samples; s++) {
|
|
258
|
+
let t0Ns;
|
|
259
|
+
let t1Ns;
|
|
260
|
+
try {
|
|
261
|
+
t0Ns = now();
|
|
262
|
+
for (let i = 0; i < batch; i++) {
|
|
263
|
+
run();
|
|
264
|
+
}
|
|
265
|
+
t1Ns = now();
|
|
266
|
+
}
|
|
267
|
+
catch (thrown) {
|
|
268
|
+
return { ok: false, reason: "solve-threw", unknownCount, thrown };
|
|
269
|
+
}
|
|
270
|
+
if (!Number.isFinite(t0Ns) ||
|
|
271
|
+
!Number.isFinite(t1Ns) ||
|
|
272
|
+
!Number.isFinite(t1Ns - t0Ns) ||
|
|
273
|
+
t1Ns - t0Ns < 0) {
|
|
274
|
+
return {
|
|
275
|
+
ok: false,
|
|
276
|
+
reason: "non-finite-time",
|
|
277
|
+
unknownCount,
|
|
278
|
+
t0Ns,
|
|
279
|
+
t1Ns,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
perSolve.push((t1Ns - t0Ns) / batch);
|
|
283
|
+
}
|
|
284
|
+
const sorted = [...perSolve].sort((a, b) => a - b);
|
|
285
|
+
const median = medianOfSorted(sorted);
|
|
286
|
+
const half = Math.floor(sorted.length / 2);
|
|
287
|
+
const q1 = medianOfSorted(sorted.slice(0, half === 0 ? 1 : half));
|
|
288
|
+
const q3 = medianOfSorted(sorted.slice(sorted.length - (half === 0 ? 1 : half)));
|
|
289
|
+
const spread = median > 0 ? (q3 - q1) / median : 0;
|
|
290
|
+
measured.push({ unknownCount, median, spread });
|
|
291
|
+
}
|
|
292
|
+
// Monotone non-decreasing envelope over ascending sizes, reporting fixes.
|
|
293
|
+
const table = [];
|
|
294
|
+
const corrections = [];
|
|
295
|
+
let ceiling = 0;
|
|
296
|
+
for (const row of measured) {
|
|
297
|
+
const corrected = Math.max(row.median, ceiling);
|
|
298
|
+
if (corrected > row.median) {
|
|
299
|
+
corrections.push({
|
|
300
|
+
unknownCount: row.unknownCount,
|
|
301
|
+
measuredNsPerSolve: row.median,
|
|
302
|
+
correctedNsPerSolve: corrected,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
ceiling = corrected;
|
|
306
|
+
table.push({
|
|
307
|
+
unknownCount: row.unknownCount,
|
|
308
|
+
medianNsPerSolve: corrected,
|
|
309
|
+
spreadFraction: row.spread,
|
|
310
|
+
samples,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
const nsPerSolve = buildNsPerSolve(table.map((row) => ({
|
|
314
|
+
unknownCount: row.unknownCount,
|
|
315
|
+
costNs: row.medianNsPerSolve,
|
|
316
|
+
})));
|
|
317
|
+
return {
|
|
318
|
+
ok: true,
|
|
319
|
+
table,
|
|
320
|
+
corrections,
|
|
321
|
+
nsPerSolve,
|
|
322
|
+
toRealtimeBudget: (args) => {
|
|
323
|
+
const budget = {
|
|
324
|
+
nsPerSolve,
|
|
325
|
+
nsPerMacroSample: args.nsPerMacroSample,
|
|
326
|
+
};
|
|
327
|
+
return {
|
|
328
|
+
...budget,
|
|
329
|
+
...(args.budgetedIterationsPerSample !== undefined
|
|
330
|
+
? {
|
|
331
|
+
budgetedIterationsPerSample: args.budgetedIterationsPerSample,
|
|
332
|
+
}
|
|
333
|
+
: {}),
|
|
334
|
+
...(args.cpuBudgetFraction !== undefined
|
|
335
|
+
? { cpuBudgetFraction: args.cpuBudgetFraction }
|
|
336
|
+
: {}),
|
|
337
|
+
};
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
// Sink the timed solution checksum here so the solve loop stays observable
|
|
342
|
+
// work no engine may legally skip. Module-private: it is a DCE guard, not
|
|
343
|
+
// part of the interface.
|
|
344
|
+
let denseSolveSink = 0;
|
|
345
|
+
/**
|
|
346
|
+
* A TEST WORKLOAD for calibration, not a claim about the real engine. It
|
|
347
|
+
* performs one dense Gaussian elimination with partial pivoting on a fixed
|
|
348
|
+
* well-conditioned diagonally dominant n by n system in plain TypeScript,
|
|
349
|
+
* deterministically (same entries every call), with no allocation inside the
|
|
350
|
+
* timed function (all working buffers are preallocated by the factory).
|
|
351
|
+
* Later the same harness times the WebAssembly console instead; figures from
|
|
352
|
+
* this workload describe the TypeScript loop under the calibrating host and
|
|
353
|
+
* nothing else.
|
|
354
|
+
*/
|
|
355
|
+
export function denseLinearSolveWorkload(unknownCount) {
|
|
356
|
+
if (!isPositiveInt(unknownCount)) {
|
|
357
|
+
throw new RangeError(`denseLinearSolveWorkload requires a positive integer unknown count, got ${unknownCount}`);
|
|
358
|
+
}
|
|
359
|
+
const n = unknownCount;
|
|
360
|
+
const base = new Float64Array(n * n);
|
|
361
|
+
const rhs = new Float64Array(n);
|
|
362
|
+
for (let i = 0; i < n; i++) {
|
|
363
|
+
for (let j = 0; j < n; j++) {
|
|
364
|
+
// Diagonal 2n dominates the harmonic off-diagonal tail, so the
|
|
365
|
+
// system is strictly diagonally dominant and well-conditioned.
|
|
366
|
+
base[i * n + j] = i === j ? 2 * n : 1 / (1 + Math.abs(i - j));
|
|
367
|
+
}
|
|
368
|
+
rhs[i] = 1 + (i % 7);
|
|
369
|
+
}
|
|
370
|
+
const lu = new Float64Array(n * n);
|
|
371
|
+
const x = new Float64Array(n);
|
|
372
|
+
return () => {
|
|
373
|
+
lu.set(base);
|
|
374
|
+
x.set(rhs);
|
|
375
|
+
for (let col = 0; col < n; col++) {
|
|
376
|
+
let pivot = col;
|
|
377
|
+
let best = Math.abs(lu[col * n + col]);
|
|
378
|
+
for (let row = col + 1; row < n; row++) {
|
|
379
|
+
const mag = Math.abs(lu[row * n + col]);
|
|
380
|
+
if (mag > best) {
|
|
381
|
+
best = mag;
|
|
382
|
+
pivot = row;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (pivot !== col) {
|
|
386
|
+
for (let k = col; k < n; k++) {
|
|
387
|
+
const tmp = lu[col * n + k];
|
|
388
|
+
lu[col * n + k] = lu[pivot * n + k];
|
|
389
|
+
lu[pivot * n + k] = tmp;
|
|
390
|
+
}
|
|
391
|
+
const tmp = x[col];
|
|
392
|
+
x[col] = x[pivot];
|
|
393
|
+
x[pivot] = tmp;
|
|
394
|
+
}
|
|
395
|
+
const diag = lu[col * n + col];
|
|
396
|
+
for (let row = col + 1; row < n; row++) {
|
|
397
|
+
const factor = lu[row * n + col] / diag;
|
|
398
|
+
lu[row * n + col] = factor;
|
|
399
|
+
for (let k = col + 1; k < n; k++) {
|
|
400
|
+
lu[row * n + k] =
|
|
401
|
+
lu[row * n + k] - factor * lu[col * n + k];
|
|
402
|
+
}
|
|
403
|
+
x[row] = x[row] - factor * x[col];
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
for (let row = n - 1; row >= 0; row--) {
|
|
407
|
+
let sum = x[row];
|
|
408
|
+
for (let k = row + 1; k < n; k++) {
|
|
409
|
+
sum -= lu[row * n + k] * x[k];
|
|
410
|
+
}
|
|
411
|
+
x[row] = sum / lu[row * n + row];
|
|
412
|
+
}
|
|
413
|
+
let checksum = 0;
|
|
414
|
+
for (let i = 0; i < n; i++) {
|
|
415
|
+
checksum += x[i];
|
|
416
|
+
}
|
|
417
|
+
denseSolveSink += checksum;
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
//# sourceMappingURL=calibrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calibrate.js","sourceRoot":"","sources":["../src/calibrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { SlotContract } from "./chain-slot";
|
|
2
|
+
/** One thing wrong with a chain, with the slots a host needs to point at. */
|
|
3
|
+
export type ChainAdvisory = {
|
|
4
|
+
/**
|
|
5
|
+
* A closed code so a host can group or filter without reading the sentence.
|
|
6
|
+
*
|
|
7
|
+
* `unscalable-seam` — one side states no full scale, so the signal crosses unscaled.
|
|
8
|
+
* `speaker-signal-into-input` — a speaker terminal feeds a slot expecting instrument level.
|
|
9
|
+
* `cab-after-miked` — an already-miked signal is sent through a cabinet stage again.
|
|
10
|
+
* `undividable-seam` — one electrical side declares a port impedance and the other does not.
|
|
11
|
+
* `instrument-into-speaker-stage` — a stage wanting a speaker terminal is fed instrument level.
|
|
12
|
+
* `bypass-not-modelled` — a chain bypass was requested on a slot whose packet declares
|
|
13
|
+
* `audio.bypass: "none"` — the circuit has no bypass switch, so the slot is wired through.
|
|
14
|
+
*/
|
|
15
|
+
readonly code: "unscalable-seam" | "speaker-signal-into-input" | "cab-after-miked" | "undividable-seam" | "instrument-into-speaker-stage" | "bypass-not-modelled";
|
|
16
|
+
/** The slot whose output crosses the seam, and the slot receiving it. */
|
|
17
|
+
readonly slots: readonly [number, number];
|
|
18
|
+
readonly message: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Seams where one side states no full scale. Pure, so a host can ask before playing.
|
|
22
|
+
*
|
|
23
|
+
* A one-slot chain has no seam and never reports.
|
|
24
|
+
*/
|
|
25
|
+
export declare function chainAdvisories(chain: readonly SlotContract[]): readonly ChainAdvisory[];
|
|
26
|
+
/**
|
|
27
|
+
* Bypass requested on a packet that declares no bypass switch.
|
|
28
|
+
*
|
|
29
|
+
* `audio.bypass: "none"` is a declared absence (37 core-only lanes + 1 passive volume, 38 total
|
|
30
|
+
* after backfill) — not a missing field. A chain "bypass" on such a slot has nothing in the
|
|
31
|
+
* circuit to mean; wire is the only honest choice, and the slot must say so via advisory, not
|
|
32
|
+
* log. Hard-coded to the Program's carried declaration when present; missing field (pre-backfill
|
|
33
|
+
* programs) is treated as "switch" (has bypass) until Y lands `program.bypass`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function bypassNotModelledAdvisories(slots: readonly import("./chain-slot").ChainSlot[]): readonly ChainAdvisory[];
|
|
36
|
+
/**
|
|
37
|
+
* The multiplier applied to the signal crossing into `slot`.
|
|
38
|
+
*
|
|
39
|
+
* Two independent factors, multiplied:
|
|
40
|
+
*
|
|
41
|
+
* - the **full-scale ratio**, converting between the two slots' own voltage normalisations, or 1
|
|
42
|
+
* where either side states no supply to derive a bound from;
|
|
43
|
+
* - the **impedance divider** `Zin / (Zout + Zin)`, the loading one slot's input puts on the
|
|
44
|
+
* previous slot's output, or 1 where either electrical side declares none.
|
|
45
|
+
*
|
|
46
|
+
* They are separate questions and neither substitutes for the other: full scale is about the units
|
|
47
|
+
* a number is in, loading is about how much of the signal survives the connection. A seam can scale
|
|
48
|
+
* and not divide, or divide and not scale.
|
|
49
|
+
*/
|
|
50
|
+
export declare function seamScale(chain: readonly SlotContract[], slot: number): number;
|
|
51
|
+
/**
|
|
52
|
+
* The resistive divider at a seam, or `1` when it cannot be computed.
|
|
53
|
+
*
|
|
54
|
+
* **Resistive and one-directional, which is a stated approximation rather than an oversight.** Real
|
|
55
|
+
* interaction between two stages is bidirectional and frequency-dependent, and only co-solving the
|
|
56
|
+
* adjacent blocks captures it -- the fidelity ceiling the unified plan §5.3 names and this
|
|
57
|
+
* deliberately does not attempt. What this does capture is the audible first-order half: a fuzz with
|
|
58
|
+
* a low input impedance loads the pickup or the pedal ahead of it, which is a large part of what that
|
|
59
|
+
* pedal *is*.
|
|
60
|
+
*
|
|
61
|
+
* **No default is invented anywhere.** A missing impedance yields 1, never an assumed "standard
|
|
62
|
+
* 1 MΩ input" -- a fabricated convention would be indistinguishable from a measurement in every
|
|
63
|
+
* downstream number. Measured on the corpus as of 2026-08-21 that means this returns 1 for every
|
|
64
|
+
* seam: **zero input jacks declare a typed impedance**, and the only four declarations anywhere are
|
|
65
|
+
* output impedances (`marshall-blues-breaker` 1 MΩ, `mxr-m117r-flanger` 1 kΩ,
|
|
66
|
+
* `mxr-noise-gate-line-driver` 10 kΩ, `pigtronix-philosophers-tone` 150 Ω). The mechanism is
|
|
67
|
+
* therefore inert until sources carry the input side, and `undividable-seam` is what says so out
|
|
68
|
+
* loud on a chain built from one of those four.
|
|
69
|
+
*/
|
|
70
|
+
export declare function seamDivider(chain: readonly SlotContract[], slot: number): number;
|
|
71
|
+
//# sourceMappingURL=chain-advisories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain-advisories.d.ts","sourceRoot":"","sources":["../src/chain-advisories.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,cAAc,CAAC;AAkBhE,6EAA6E;AAC7E,MAAM,MAAM,aAAa,GAAG;IAC3B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,IAAI,EACV,iBAAiB,GACjB,2BAA2B,GAC3B,iBAAiB,GACjB,kBAAkB,GAClB,+BAA+B,GAC/B,qBAAqB,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,SAAS,YAAY,EAAE,GAC5B,SAAS,aAAa,EAAE,CA8J1B;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,SAAS,OAAO,cAAc,EAAE,SAAS,EAAE,GAAG,SAAS,aAAa,EAAE,CAuBxH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACxB,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,IAAI,EAAE,MAAM,GACV,MAAM,CAQR;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAC1B,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,IAAI,EAAE,MAAM,GACV,MAAM,CAUR"}
|