@descix/egpt-math-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +224 -0
  2. package/dist/egpt-math-sdk.browser.js +5 -0
  3. package/dist/index.d.ts +100 -0
  4. package/dist/index.js +985 -0
  5. package/dist/notebooks/arithmetic-basics.html +166 -0
  6. package/dist/notebooks/complex-twiddle.html +148 -0
  7. package/dist/notebooks/double-slit-rosetta-qft.html +154 -0
  8. package/dist/notebooks/egpt-fft-test.html +202 -0
  9. package/dist/notebooks/egpt-matrix-test.html +241 -0
  10. package/dist/notebooks/egpt-polynomial-test.html +703 -0
  11. package/dist/notebooks/egpt-prime-composite-test.html +561 -0
  12. package/dist/notebooks/egpt-test-suite.html +1387 -0
  13. package/dist/notebooks/egpt-topology-test.html +410 -0
  14. package/dist/notebooks/factorization-basics.html +131 -0
  15. package/dist/notebooks/fft.html +155 -0
  16. package/dist/notebooks/frqtl-qft-benchmark.html +207 -0
  17. package/dist/notebooks/gallery-atomic-model.html +51 -0
  18. package/dist/notebooks/gallery-big-bang.html +62 -0
  19. package/dist/notebooks/gallery-blackbody.html +52 -0
  20. package/dist/notebooks/gallery-circuit-sat.html +104 -0
  21. package/dist/notebooks/gallery-collision-matrix-3d.html +51 -0
  22. package/dist/notebooks/gallery-double-slit.html +53 -0
  23. package/dist/notebooks/gallery-gun-chamber.html +62 -0
  24. package/dist/notebooks/gallery-particle-walk-3d.html +53 -0
  25. package/dist/notebooks/gallery-wave-interference.html +52 -0
  26. package/dist/notebooks/getting-started-hello-frqtl.html +53 -0
  27. package/dist/notebooks/iso-canonical-chain.html +203 -0
  28. package/dist/notebooks/iso-entropy-log.html +127 -0
  29. package/dist/notebooks/iso-fft-polynomial.html +136 -0
  30. package/dist/notebooks/iso-matrix-four-views.html +131 -0
  31. package/dist/notebooks/iso-number-theory-four-views.html +99 -0
  32. package/dist/notebooks/iso-pi-log-fraction-loop.html +140 -0
  33. package/dist/notebooks/matrix.html +202 -0
  34. package/dist/notebooks/notebooks.json +240 -0
  35. package/dist/notebooks/polynomials.html +201 -0
  36. package/dist/notebooks/prime-composite.html +268 -0
  37. package/dist/notebooks/rational-core.html +179 -0
  38. package/dist/notebooks/reference-egpt-fft-test.html +187 -0
  39. package/dist/notebooks/reference-order-finder-test.html +196 -0
  40. package/dist/notebooks/reference-prime-atom-polynomial-test.html +542 -0
  41. package/dist/notebooks/reference-solve-polynomial-system-test.html +471 -0
  42. package/dist/notebooks/scaled-vectors.html +112 -0
  43. package/dist/notebooks/stats.html +206 -0
  44. package/dist/notebooks/transcendentals.html +195 -0
  45. package/dist/notebooks/view-vendored-d3.html +78 -0
  46. package/dist/vendor/d3-array/src/array.js +4 -0
  47. package/dist/vendor/d3-array/src/ascending.js +3 -0
  48. package/dist/vendor/d3-array/src/bin.js +125 -0
  49. package/dist/vendor/d3-array/src/bisect.js +9 -0
  50. package/dist/vendor/d3-array/src/bisector.js +56 -0
  51. package/dist/vendor/d3-array/src/blur.js +115 -0
  52. package/dist/vendor/d3-array/src/constant.js +3 -0
  53. package/dist/vendor/d3-array/src/count.js +18 -0
  54. package/dist/vendor/d3-array/src/cross.js +33 -0
  55. package/dist/vendor/d3-array/src/cumsum.js +6 -0
  56. package/dist/vendor/d3-array/src/descending.js +7 -0
  57. package/dist/vendor/d3-array/src/deviation.js +6 -0
  58. package/dist/vendor/d3-array/src/difference.js +11 -0
  59. package/dist/vendor/d3-array/src/disjoint.js +15 -0
  60. package/dist/vendor/d3-array/src/every.js +10 -0
  61. package/dist/vendor/d3-array/src/extent.js +29 -0
  62. package/dist/vendor/d3-array/src/filter.js +11 -0
  63. package/dist/vendor/d3-array/src/fsum.js +69 -0
  64. package/dist/vendor/d3-array/src/greatest.js +29 -0
  65. package/dist/vendor/d3-array/src/greatestIndex.js +19 -0
  66. package/dist/vendor/d3-array/src/group.js +65 -0
  67. package/dist/vendor/d3-array/src/groupSort.js +10 -0
  68. package/dist/vendor/d3-array/src/identity.js +3 -0
  69. package/dist/vendor/d3-array/src/index.js +57 -0
  70. package/dist/vendor/d3-array/src/intersection.js +19 -0
  71. package/dist/vendor/d3-array/src/least.js +29 -0
  72. package/dist/vendor/d3-array/src/leastIndex.js +19 -0
  73. package/dist/vendor/d3-array/src/map.js +5 -0
  74. package/dist/vendor/d3-array/src/max.js +20 -0
  75. package/dist/vendor/d3-array/src/maxIndex.js +22 -0
  76. package/dist/vendor/d3-array/src/mean.js +19 -0
  77. package/dist/vendor/d3-array/src/median.js +9 -0
  78. package/dist/vendor/d3-array/src/merge.js +9 -0
  79. package/dist/vendor/d3-array/src/min.js +20 -0
  80. package/dist/vendor/d3-array/src/minIndex.js +22 -0
  81. package/dist/vendor/d3-array/src/mode.js +28 -0
  82. package/dist/vendor/d3-array/src/nice.js +18 -0
  83. package/dist/vendor/d3-array/src/number.js +20 -0
  84. package/dist/vendor/d3-array/src/pairs.js +15 -0
  85. package/dist/vendor/d3-array/src/permute.js +3 -0
  86. package/dist/vendor/d3-array/src/quantile.js +47 -0
  87. package/dist/vendor/d3-array/src/quickselect.js +53 -0
  88. package/dist/vendor/d3-array/src/range.js +13 -0
  89. package/dist/vendor/d3-array/src/rank.js +24 -0
  90. package/dist/vendor/d3-array/src/reduce.js +14 -0
  91. package/dist/vendor/d3-array/src/reverse.js +4 -0
  92. package/dist/vendor/d3-array/src/scan.js +6 -0
  93. package/dist/vendor/d3-array/src/shuffle.js +13 -0
  94. package/dist/vendor/d3-array/src/some.js +10 -0
  95. package/dist/vendor/d3-array/src/sort.js +39 -0
  96. package/dist/vendor/d3-array/src/subset.js +5 -0
  97. package/dist/vendor/d3-array/src/sum.js +18 -0
  98. package/dist/vendor/d3-array/src/superset.js +19 -0
  99. package/dist/vendor/d3-array/src/threshold/freedmanDiaconis.js +7 -0
  100. package/dist/vendor/d3-array/src/threshold/scott.js +7 -0
  101. package/dist/vendor/d3-array/src/threshold/sturges.js +5 -0
  102. package/dist/vendor/d3-array/src/ticks.js +55 -0
  103. package/dist/vendor/d3-array/src/transpose.js +15 -0
  104. package/dist/vendor/d3-array/src/union.js +11 -0
  105. package/dist/vendor/d3-array/src/variance.js +25 -0
  106. package/dist/vendor/d3-array/src/zip.js +5 -0
  107. package/dist/vendor/internmap/src/index.js +61 -0
  108. package/dist/vendor/manifest.json +11 -0
  109. package/dist/wasm/egpt_math_sdk_wasm.d.ts +214 -0
  110. package/dist/wasm/egpt_math_sdk_wasm.js +1120 -0
  111. package/dist/wasm/egpt_math_sdk_wasm_bg.wasm +0 -0
  112. package/dist/wasm/egpt_math_sdk_wasm_bg.wasm.d.ts +66 -0
  113. package/dist/wasm/manifest.json +5 -0
  114. package/package.json +53 -0
package/dist/index.js ADDED
@@ -0,0 +1,985 @@
1
+ // src/browser/wasm-loader.js
2
+ async function probeWasmArtifact(wasmUrl) {
3
+ if (!wasmUrl) {
4
+ return { ok: false, reason: "missing-wasm-url" };
5
+ }
6
+ try {
7
+ if (typeof process !== "undefined" && wasmUrl.startsWith("file://")) {
8
+ const fs = await import("node:fs/promises");
9
+ const { fileURLToPath } = await import("node:url");
10
+ await fs.access(fileURLToPath(wasmUrl));
11
+ return { ok: true };
12
+ }
13
+ const response = await fetch(wasmUrl, { method: "GET" });
14
+ if (!response.ok) {
15
+ return { ok: false, reason: `artifact-unreachable:${response.status}` };
16
+ }
17
+ return { ok: true };
18
+ } catch (error) {
19
+ return { ok: false, reason: `artifact-fetch-error:${String(error)}` };
20
+ }
21
+ }
22
+ function normalizeBrowserUrl(url) {
23
+ if (!url || typeof document === "undefined") return url;
24
+ return new URL(url, document.baseURI).href;
25
+ }
26
+ async function loadEgptMathWasm({ wasmUrl, wasmModuleUrl } = {}) {
27
+ wasmUrl = normalizeBrowserUrl(wasmUrl);
28
+ wasmModuleUrl = normalizeBrowserUrl(wasmModuleUrl);
29
+ const probe = await probeWasmArtifact(wasmUrl);
30
+ if (!wasmModuleUrl) {
31
+ return {
32
+ mode: probe.ok ? "wasm-skeleton" : "js-compat",
33
+ wasmUrl: wasmUrl ?? null,
34
+ wasmModuleUrl: null,
35
+ warnings: probe.ok ? [] : [probe.reason]
36
+ };
37
+ }
38
+ try {
39
+ const mod = await import(wasmModuleUrl);
40
+ let initArg = wasmUrl;
41
+ if (typeof process !== "undefined" && wasmUrl && wasmUrl.startsWith("file://")) {
42
+ const fs = await import("node:fs/promises");
43
+ const { fileURLToPath } = await import("node:url");
44
+ initArg = await fs.readFile(fileURLToPath(wasmUrl));
45
+ }
46
+ if (typeof mod.default === "function" && wasmUrl) {
47
+ await mod.default(initArg);
48
+ } else if (typeof mod.init === "function" && wasmUrl) {
49
+ await mod.init(initArg);
50
+ }
51
+ return {
52
+ mode: "wasm-bridge",
53
+ wasmUrl: wasmUrl ?? null,
54
+ wasmModuleUrl,
55
+ module: mod,
56
+ warnings: probe.ok ? [] : [probe.reason]
57
+ };
58
+ } catch (error) {
59
+ return {
60
+ mode: "js-compat",
61
+ wasmUrl: wasmUrl ?? null,
62
+ wasmModuleUrl,
63
+ warnings: [`module-load-failed:${String(error)}`, ...probe.ok ? [] : [probe.reason]]
64
+ };
65
+ }
66
+ }
67
+
68
+ // src/browser/wasm-math-provider.js
69
+ var MathBackendRegistrationError = class extends Error {
70
+ constructor(message) {
71
+ super(message);
72
+ this.name = "MathBackendRegistrationError";
73
+ }
74
+ };
75
+ function _localEgptRealToCanonicalStr(h) {
76
+ const { numerator, denominator } = h._getPPFRationalParts();
77
+ if (denominator === 1n || denominator === -1n) {
78
+ return String(denominator < 0n ? -numerator : numerator);
79
+ }
80
+ return `${numerator}/${denominator}`;
81
+ }
82
+ function unwrap(result, opName) {
83
+ if (!result || !result.ok) {
84
+ const msg = result?.error ?? "wasm-result-unknown-error";
85
+ throw new Error(`WasmMathBackendProvider.${opName}: WASM call failed \u2014 ${msg}`);
86
+ }
87
+ return result.value;
88
+ }
89
+ function makeHandle(epoch, idx) {
90
+ return { p: "wasm-math", e: epoch, h: idx };
91
+ }
92
+ function unpackResult(u64BigInt) {
93
+ const n = typeof u64BigInt === "bigint" ? u64BigInt : BigInt(Math.round(Number(u64BigInt)));
94
+ return { e: Number(n >> 32n), h: Number(n & 0xFFFFFFFFn) };
95
+ }
96
+ function packHandle(epoch, idx) {
97
+ return BigInt(epoch) * 0x100000000n + BigInt(idx);
98
+ }
99
+ var _wasmFacade = null;
100
+ function _internStr(canonStr) {
101
+ const r = _wasmFacade.internStr(canonStr);
102
+ const packed = unwrap(r, "_internStr");
103
+ const { e, h } = unpackResult(packed);
104
+ return makeHandle(e, h);
105
+ }
106
+ function _materializeStr(handle, opName) {
107
+ const packed = packHandle(handle.e, handle.h);
108
+ const r = _wasmFacade.materializeStr(packed);
109
+ return unwrap(r, opName + ".materializeStr");
110
+ }
111
+ function extractHandle(h, opName) {
112
+ if (h !== null && typeof h === "object") {
113
+ if (h.p === "wasm-math") {
114
+ return packHandle(h.e, h.h);
115
+ }
116
+ if (typeof h._getPPFRationalParts === "function") {
117
+ const str = _localEgptRealToCanonicalStr(h);
118
+ const r = _wasmFacade.internStr(str);
119
+ const packed = unwrap(r, opName + ".d2-intern");
120
+ return packed;
121
+ }
122
+ }
123
+ throw new TypeError(
124
+ `WasmMathBackendProvider.${opName}: foreign or invalid handle \u2014 expected wasm-math handle {p:'wasm-math',e,h} or EGPTReal instance; got ${typeof h}: ${h === null ? "null" : JSON.stringify(h)}`
125
+ );
126
+ }
127
+ function polyToJson(arr, opName) {
128
+ return JSON.stringify(arr.map((h) => String(extractHandle(h, opName))));
129
+ }
130
+ function jsonToHandles(json) {
131
+ const arr = JSON.parse(json);
132
+ return arr.map((s) => {
133
+ const n = BigInt(s);
134
+ const { e, h } = unpackResult(n);
135
+ return makeHandle(e, h);
136
+ });
137
+ }
138
+ function jsonPolyDivToObj(json) {
139
+ const obj = JSON.parse(json);
140
+ return {
141
+ quotient: obj.quotient.map((s) => {
142
+ const n = BigInt(s);
143
+ const { e, h } = unpackResult(n);
144
+ return makeHandle(e, h);
145
+ }),
146
+ remainder: obj.remainder.map((s) => {
147
+ const n = BigInt(s);
148
+ const { e, h } = unpackResult(n);
149
+ return makeHandle(e, h);
150
+ })
151
+ };
152
+ }
153
+ function _bigintGcd(a, b) {
154
+ a = a < 0n ? -a : a;
155
+ b = b < 0n ? -b : b;
156
+ while (b) {
157
+ [a, b] = [b, a % b];
158
+ }
159
+ return a;
160
+ }
161
+ function buildWasmMathProvider(wasmFacade) {
162
+ if (!wasmFacade || typeof wasmFacade !== "object") {
163
+ throw new MathBackendRegistrationError(
164
+ "buildWasmMathProvider: wasmFacade must be a non-null object (from buildWasmFacade)."
165
+ );
166
+ }
167
+ const requiredArena = ["internStr", "materializeStr", "arenaAdd"];
168
+ const missingArena = requiredArena.filter((fn) => typeof wasmFacade[fn] !== "function");
169
+ if (missingArena.length > 0) {
170
+ throw new MathBackendRegistrationError(
171
+ `buildWasmMathProvider: WASM facade missing V3 arena exports: ${missingArena.join(", ")}. Rebuild the WASM bridge (npm run build:wasm-bridge in sdk/egpt-math-sdk).`
172
+ );
173
+ }
174
+ _wasmFacade = wasmFacade;
175
+ const provider = Object.freeze({
176
+ id: "wasm-math",
177
+ // ── resetScope — per-run arena lifecycle ────────────────────────────────
178
+ // Called by MathBackendRegistry.resetScope() (Runtime's finally block).
179
+ // Provider MUST NOT subscribe to Bus — Runtime calls DOWN via registry.
180
+ resetScope() {
181
+ wasmFacade.resetScope();
182
+ },
183
+ // ── Construction / conversion ──────────────────────────────────────────
184
+ fromBigInt(n) {
185
+ return _internStr(String(n));
186
+ },
187
+ fromRational(num, den) {
188
+ const g = _bigintGcd(num < 0n ? -num : num, den < 0n ? -den : den);
189
+ if (g === 0n) return _internStr("0");
190
+ let rn = num / g;
191
+ let rd = den / g;
192
+ if (rd < 0n) {
193
+ rn = -rn;
194
+ rd = -rd;
195
+ }
196
+ const canonical = rd === 1n ? String(rn) : `${rn}/${rd}`;
197
+ return _internStr(canonical);
198
+ },
199
+ fromRationalStr(str) {
200
+ return _internStr(str.trim());
201
+ },
202
+ toCanonicalStr(h) {
203
+ return _materializeStr(h, "toCanonicalStr");
204
+ },
205
+ // ── Arithmetic ─────────────────────────────────────────────────────────
206
+ add(a, b) {
207
+ const r = wasmFacade.arenaAdd(extractHandle(a, "add"), extractHandle(b, "add"));
208
+ const packed = unwrap(r, "add");
209
+ const { e, h } = unpackResult(packed);
210
+ return makeHandle(e, h);
211
+ },
212
+ subtract(a, b) {
213
+ const r = wasmFacade.arenaSub(extractHandle(a, "subtract"), extractHandle(b, "subtract"));
214
+ const packed = unwrap(r, "subtract");
215
+ const { e, h } = unpackResult(packed);
216
+ return makeHandle(e, h);
217
+ },
218
+ multiply(a, b) {
219
+ const r = wasmFacade.arenaMul(extractHandle(a, "multiply"), extractHandle(b, "multiply"));
220
+ const packed = unwrap(r, "multiply");
221
+ const { e, h } = unpackResult(packed);
222
+ return makeHandle(e, h);
223
+ },
224
+ divide(a, b) {
225
+ const r = wasmFacade.arenaDiv(extractHandle(a, "divide"), extractHandle(b, "divide"));
226
+ const packed = unwrap(r, "divide");
227
+ const { e, h } = unpackResult(packed);
228
+ return makeHandle(e, h);
229
+ },
230
+ normalDivide(a, b) {
231
+ const r = wasmFacade.arenaDiv(extractHandle(a, "normalDivide"), extractHandle(b, "normalDivide"));
232
+ const packed = unwrap(r, "normalDivide");
233
+ const { e, h } = unpackResult(packed);
234
+ return makeHandle(e, h);
235
+ },
236
+ mod(a, b) {
237
+ const r = wasmFacade.arenaMod(extractHandle(a, "mod"), extractHandle(b, "mod"));
238
+ const packed = unwrap(r, "mod");
239
+ const { e, h } = unpackResult(packed);
240
+ return makeHandle(e, h);
241
+ },
242
+ // ── Comparison ─────────────────────────────────────────────────────────
243
+ equals(a, b) {
244
+ const cmp = unwrap(wasmFacade.arenaCmp(extractHandle(a, "equals"), extractHandle(b, "equals")), "equals");
245
+ return cmp === 0;
246
+ },
247
+ compare(a, b) {
248
+ return unwrap(wasmFacade.arenaCmp(extractHandle(a, "compare"), extractHandle(b, "compare")), "compare");
249
+ },
250
+ // ── Exponentiation / roots ──────────────────────────────────────────────
251
+ pow(base, expNum, expDen) {
252
+ const en = Number(expNum);
253
+ const ed = Number(expDen);
254
+ const r = wasmFacade.arenaPow(extractHandle(base, "pow"), en, ed);
255
+ const packed = unwrap(r, "pow");
256
+ const { e, h } = unpackResult(packed);
257
+ return makeHandle(e, h);
258
+ },
259
+ sqrt(a) {
260
+ const r = wasmFacade.arenaSqrt(extractHandle(a, "sqrt"));
261
+ const packed = unwrap(r, "sqrt");
262
+ const { e, h } = unpackResult(packed);
263
+ return makeHandle(e, h);
264
+ },
265
+ // ── Rational-domain transcendentals ─────────────────────────────────────
266
+ exp2(exponent) {
267
+ const r = wasmFacade.arenaExp2(extractHandle(exponent, "exp2"));
268
+ const packed = unwrap(r, "exp2");
269
+ const { e, h } = unpackResult(packed);
270
+ return makeHandle(e, h);
271
+ },
272
+ log2(value) {
273
+ const r = wasmFacade.arenaLog2(extractHandle(value, "log2"));
274
+ const packed = unwrap(r, "log2");
275
+ const { e, h } = unpackResult(packed);
276
+ return makeHandle(e, h);
277
+ },
278
+ // ── PPF encode / decode ─────────────────────────────────────────────────
279
+ ppfEncodeInteger(n) {
280
+ const hN = _internStr(String(n));
281
+ const r = wasmFacade.arenaPpfEncode(packHandle(hN.e, hN.h));
282
+ const jsonStr = unwrap(r, "ppfEncodeInteger");
283
+ const obj = JSON.parse(jsonStr);
284
+ return { N: BigInt(obj.N), offset: BigInt(obj.offset) };
285
+ },
286
+ ppfDecodeInteger(ppf) {
287
+ const json = JSON.stringify({ N: String(ppf.N), offset: String(ppf.offset) });
288
+ const r = wasmFacade.arenaPpfDecode(json);
289
+ const packed = unwrap(r, "ppfDecodeInteger");
290
+ const { e, h } = unpackResult(packed);
291
+ const decoded = _materializeStr(makeHandle(e, h), "ppfDecodeInteger");
292
+ return BigInt(decoded);
293
+ },
294
+ fromPPF(ppfData) {
295
+ const scalar = ppfData.scalar ?? { numerator: 1n, denominator: 1n };
296
+ const json = JSON.stringify({
297
+ numerator: { N: String(ppfData.numerator.N), offset: String(ppfData.numerator.offset) },
298
+ denominator: { N: String(ppfData.denominator.N), offset: String(ppfData.denominator.offset) },
299
+ scalar: { numerator: String(scalar.numerator ?? 1n), denominator: String(scalar.denominator ?? 1n) }
300
+ });
301
+ const r = wasmFacade.arenaFromPpfJson(json);
302
+ const packed = unwrap(r, "fromPPF");
303
+ const { e, h } = unpackResult(packed);
304
+ return makeHandle(e, h);
305
+ },
306
+ // ── Bit-length ──────────────────────────────────────────────────────────
307
+ getIntegerBitLength(n) {
308
+ const r = wasmFacade.arenaGetBitLength(extractHandle(n, "getIntegerBitLength"));
309
+ return BigInt(unwrap(r, "getIntegerBitLength"));
310
+ },
311
+ // ── Break-symbolic exits ────────────────────────────────────────────────
312
+ breakSymbolicToApproximateBigInt(h) {
313
+ const r = wasmFacade.arenaBreakToBigint(extractHandle(h, "breakSymbolicToApproximateBigInt"));
314
+ return BigInt(unwrap(r, "breakSymbolicToApproximateBigInt"));
315
+ },
316
+ breakSymbolicToApproximateJSNumber(h) {
317
+ const r = wasmFacade.arenaBreakToJsNumber(extractHandle(h, "breakSymbolicToApproximateJSNumber"));
318
+ return Number(unwrap(r, "breakSymbolicToApproximateJSNumber"));
319
+ },
320
+ breakSymbolicToString(h) {
321
+ const r = wasmFacade.arenaBreakToString(extractHandle(h, "breakSymbolicToString"));
322
+ return unwrap(r, "breakSymbolicToString");
323
+ },
324
+ // ── Prime-atom boundary ─────────────────────────────────────────────────
325
+ toPrimeAtoms(h) {
326
+ const r = wasmFacade.arenaToPrimeAtoms(extractHandle(h, "toPrimeAtoms"));
327
+ const json = unwrap(r, "toPrimeAtoms");
328
+ const obj = JSON.parse(json);
329
+ return {
330
+ sign: obj.sign,
331
+ factors: obj.factors.map((f) => ({
332
+ prime: BigInt(f.prime),
333
+ exponent: BigInt(f.exponent)
334
+ }))
335
+ };
336
+ },
337
+ fromAtomVec(atomVec) {
338
+ const json = JSON.stringify({
339
+ sign: atomVec.sign,
340
+ factors: (atomVec.factors ?? []).map((f) => ({
341
+ prime: String(typeof f.prime === "bigint" ? f.prime : BigInt(f.prime)),
342
+ exponent: String(typeof f.exponent === "bigint" ? f.exponent : BigInt(f.exponent))
343
+ }))
344
+ });
345
+ const r = wasmFacade.arenaFromAtomVec(json);
346
+ const packed = unwrap(r, "fromAtomVec");
347
+ const { e, h } = unpackResult(packed);
348
+ return makeHandle(e, h);
349
+ },
350
+ toAtomRoot(h) {
351
+ const r = wasmFacade.arenaToAtomRoot(extractHandle(h, "toAtomRoot"));
352
+ const json = unwrap(r, "toAtomRoot");
353
+ const obj = JSON.parse(json);
354
+ return {
355
+ leadingCoeff: _internStr(obj.leadingCoeff),
356
+ roots: obj.roots.map((root) => ({
357
+ value: _internStr(root.value),
358
+ multiplicity: BigInt(root.multiplicity)
359
+ }))
360
+ };
361
+ },
362
+ fromAtomRoot(term) {
363
+ const lcStr = _materializeStr(term.leadingCoeff, "fromAtomRoot.leadingCoeff");
364
+ const rootsArr = (term.roots ?? []).map((root) => ({
365
+ value: _materializeStr(root.value, "fromAtomRoot.root.value"),
366
+ multiplicity: String(root.multiplicity)
367
+ }));
368
+ const json = JSON.stringify({ leadingCoeff: lcStr, roots: rootsArr });
369
+ const r = wasmFacade.arenaFromAtomRoot(json);
370
+ const packed = unwrap(r, "fromAtomRoot");
371
+ const { e, h } = unpackResult(packed);
372
+ return makeHandle(e, h);
373
+ },
374
+ // ── Integer helpers — contract takes bigint inputs ────────────────────────
375
+ //
376
+ // gcd/lcm/modPow at the contract level take bigint inputs (not handles).
377
+ // We intern the BigInts into the arena, compute, then return the result.
378
+ gcd(a, b) {
379
+ const ha = _internStr(String(a));
380
+ const hb = _internStr(String(b));
381
+ const r = wasmFacade.arenaGcd(packHandle(ha.e, ha.h), packHandle(hb.e, hb.h));
382
+ return BigInt(unwrap(r, "gcd"));
383
+ },
384
+ lcm(a, b) {
385
+ const ha = _internStr(String(a));
386
+ const hb = _internStr(String(b));
387
+ const r = wasmFacade.arenaLcm(packHandle(ha.e, ha.h), packHandle(hb.e, hb.h));
388
+ return BigInt(unwrap(r, "lcm"));
389
+ },
390
+ modPow(base, exp, mod) {
391
+ const hBase = _internStr(String(base));
392
+ const hExp = _internStr(String(exp));
393
+ const hMod = _internStr(String(mod));
394
+ const r = wasmFacade.arenaModPow(
395
+ packHandle(hBase.e, hBase.h),
396
+ packHandle(hExp.e, hExp.h),
397
+ packHandle(hMod.e, hMod.h)
398
+ );
399
+ const packed = unwrap(r, "modPow");
400
+ const { e, h } = unpackResult(packed);
401
+ const str = _materializeStr(makeHandle(e, h), "modPow.result");
402
+ return BigInt(str);
403
+ },
404
+ // ── Polynomial ops ──────────────────────────────────────────────────────
405
+ polyAdd(a, b) {
406
+ const r = wasmFacade.arenaPolyAdd(polyToJson(a, "polyAdd"), polyToJson(b, "polyAdd"));
407
+ return jsonToHandles(unwrap(r, "polyAdd"));
408
+ },
409
+ polyMul(a, b) {
410
+ const r = wasmFacade.arenaPolyMul(polyToJson(a, "polyMul"), polyToJson(b, "polyMul"));
411
+ return jsonToHandles(unwrap(r, "polyMul"));
412
+ },
413
+ polyDiv(dividend, divisor) {
414
+ const r = wasmFacade.arenaPolyDiv(polyToJson(dividend, "polyDiv"), polyToJson(divisor, "polyDiv"));
415
+ return jsonPolyDivToObj(unwrap(r, "polyDiv"));
416
+ },
417
+ polyForwardTransform(coeffs, n) {
418
+ const r = wasmFacade.arenaPolyFwd(polyToJson(coeffs, "polyForwardTransform"), n);
419
+ return jsonToHandles(unwrap(r, "polyForwardTransform"));
420
+ },
421
+ polyInverseTransform(samples, n) {
422
+ const r = wasmFacade.arenaPolyInv(polyToJson(samples, "polyInverseTransform"), n);
423
+ return jsonToHandles(unwrap(r, "polyInverseTransform"));
424
+ },
425
+ polyEvaluateAt(poly, x) {
426
+ const r = wasmFacade.arenaPolyEval(polyToJson(poly, "polyEvaluateAt"), extractHandle(x, "polyEvaluateAt"));
427
+ const packed = unwrap(r, "polyEvaluateAt");
428
+ const { e, h } = unpackResult(packed);
429
+ return makeHandle(e, h);
430
+ },
431
+ polyGcd(a, b) {
432
+ const r = wasmFacade.arenaPolyGcd(polyToJson(a, "polyGcd"), polyToJson(b, "polyGcd"));
433
+ return jsonToHandles(unwrap(r, "polyGcd"));
434
+ },
435
+ // ── Handle identity predicate (37th op) ──────────────────────────────────
436
+ // Pure structural type check of the V3 handle shape {p:'wasm-math',e,h}.
437
+ // Never throws. Architect ruling (b), Option-JS-only: isHandle answers a
438
+ // TYPE question, not a LIVENESS question — a structurally-valid but stale
439
+ // handle (dead epoch) still returns TRUE here, so that the FAIL-LOUD
440
+ // arena_get stale-throw stays at the op call site and is never masked by
441
+ // a false-from-this-predicate (that masking would be the FraqtlSession
442
+ // backend-lie class of bug). Does NOT consult arenaStats (DEBUG-ONLY) and
443
+ // makes NO wasm round-trip. A js-reference EGPTReal object → false (it is
444
+ // a HOST value the D2 seam interns, not a wasm-math handle of MY type).
445
+ isHandle(v) {
446
+ return v != null && typeof v === "object" && v.p === "wasm-math" && Number.isInteger(v.e) && Number.isInteger(v.h);
447
+ }
448
+ });
449
+ return provider;
450
+ }
451
+
452
+ // src/browser/wasm-facade.js
453
+ var _provider = null;
454
+ function _setActiveWasmProvider(provider) {
455
+ _provider = provider;
456
+ }
457
+ function _p(opName) {
458
+ if (!_provider) {
459
+ throw new Error(
460
+ `EGPT Math SDK (WASM-only dist): no active WASM math provider (op '${opName}'). createEgptMathSdk() must complete successfully before EGPTReal/EGPTMath/EGPTPolynomial are used \u2014 this build ships no JS math-core fallback.`
461
+ );
462
+ }
463
+ return _provider;
464
+ }
465
+ function _wrap(handle) {
466
+ return new EGPTReal(_CONSTRUCT_TOKEN, handle);
467
+ }
468
+ function _unwrap(v, opName) {
469
+ if (v instanceof EGPTReal) return v._handle;
470
+ throw new TypeError(
471
+ `EGPT Math SDK: ${opName} expected an EGPTReal facade instance, got ${v === null ? "null" : typeof v}`
472
+ );
473
+ }
474
+ var _CONSTRUCT_TOKEN = Symbol("egpt-real-facade-construct");
475
+ var EGPTReal = class _EGPTReal {
476
+ constructor(token, handle) {
477
+ if (token !== _CONSTRUCT_TOKEN) {
478
+ throw new TypeError(
479
+ "EGPTReal: do not construct directly \u2014 use EGPTReal.fromBigInt / .fromRational / .fromRationalStr."
480
+ );
481
+ }
482
+ this._handle = handle;
483
+ }
484
+ /** @param {bigint|number|string} n @returns {EGPTReal} */
485
+ static fromBigInt(n) {
486
+ return new _EGPTReal(_CONSTRUCT_TOKEN, _p("fromBigInt").fromBigInt(BigInt(n)));
487
+ }
488
+ /** @param {bigint|number} num @param {bigint|number} den @returns {EGPTReal} */
489
+ static fromRational(num, den) {
490
+ return new _EGPTReal(_CONSTRUCT_TOKEN, _p("fromRational").fromRational(BigInt(num), BigInt(den)));
491
+ }
492
+ /** @param {string} str — "num" or "num/den" @returns {EGPTReal} */
493
+ static fromRationalStr(str) {
494
+ return new _EGPTReal(_CONSTRUCT_TOKEN, _p("fromRationalStr").fromRationalStr(String(str)));
495
+ }
496
+ static get ZERO() {
497
+ return _EGPTReal.fromBigInt(0n);
498
+ }
499
+ static get ONE() {
500
+ return _EGPTReal.fromBigInt(1n);
501
+ }
502
+ /** Exact canonical rational string ("num" or "num/den") — never decimal projection. */
503
+ toCanonicalStr() {
504
+ return _p("toCanonicalStr").toCanonicalStr(this._handle);
505
+ }
506
+ /** Alias for {@link EGPTReal#toCanonicalStr} — matches the dev-core class's narration method name. */
507
+ toMathString() {
508
+ return this.toCanonicalStr();
509
+ }
510
+ toString() {
511
+ return this.toCanonicalStr();
512
+ }
513
+ /** @param {EGPTReal} other @returns {EGPTReal} */
514
+ add(other) {
515
+ return _wrap(_p("add").add(this._handle, _unwrap(other, "add")));
516
+ }
517
+ /** @param {EGPTReal} other @returns {EGPTReal} */
518
+ subtract(other) {
519
+ return _wrap(_p("subtract").subtract(this._handle, _unwrap(other, "subtract")));
520
+ }
521
+ /** Shannon-space multiply. @param {EGPTReal} other @returns {EGPTReal} */
522
+ multiply(other) {
523
+ return _wrap(_p("multiply").multiply(this._handle, _unwrap(other, "multiply")));
524
+ }
525
+ /** Shannon-space divide. @param {EGPTReal} other @returns {EGPTReal} */
526
+ divide(other) {
527
+ return _wrap(_p("divide").divide(this._handle, _unwrap(other, "divide")));
528
+ }
529
+ /** Normal-space (rational) divide. @param {EGPTReal} other @returns {EGPTReal} */
530
+ normalDivide(other) {
531
+ return _wrap(_p("normalDivide").normalDivide(this._handle, _unwrap(other, "normalDivide")));
532
+ }
533
+ /** @param {EGPTReal} other @returns {EGPTReal} */
534
+ mod(other) {
535
+ return _wrap(_p("mod").mod(this._handle, _unwrap(other, "mod")));
536
+ }
537
+ /** @param {EGPTReal} other @returns {boolean} */
538
+ equals(other) {
539
+ return _p("equals").equals(this._handle, _unwrap(other, "equals"));
540
+ }
541
+ /** @param {EGPTReal} other @returns {-1|0|1} */
542
+ compare(other) {
543
+ return _p("compare").compare(this._handle, _unwrap(other, "compare"));
544
+ }
545
+ /** @param {bigint|number} expNum @param {bigint|number} [expDen=1n] @returns {EGPTReal} */
546
+ pow(expNum, expDen = 1n) {
547
+ return _wrap(_p("pow").pow(this._handle, BigInt(expNum), BigInt(expDen)));
548
+ }
549
+ /** @returns {EGPTReal} */
550
+ sqrt() {
551
+ return _wrap(_p("sqrt").sqrt(this._handle));
552
+ }
553
+ /** Rational-domain exp2. @returns {EGPTReal} */
554
+ exp2() {
555
+ return _wrap(_p("exp2").exp2(this._handle));
556
+ }
557
+ /** Rational-domain log2. @returns {EGPTReal} */
558
+ log2() {
559
+ return _wrap(_p("log2").log2(this._handle));
560
+ }
561
+ /** floor(log2(n)) + 1. @returns {bigint} */
562
+ getIntegerBitLength() {
563
+ return _p("getIntegerBitLength").getIntegerBitLength(this._handle);
564
+ }
565
+ /** @returns {bigint} */
566
+ breakSymbolicToApproximateBigInt() {
567
+ return _p("breakSymbolicToApproximateBigInt").breakSymbolicToApproximateBigInt(this._handle);
568
+ }
569
+ /** @returns {number} */
570
+ breakSymbolicToApproximateJSNumber() {
571
+ return _p("breakSymbolicToApproximateJSNumber").breakSymbolicToApproximateJSNumber(this._handle);
572
+ }
573
+ /** @returns {string} */
574
+ breakSymbolicToString() {
575
+ return _p("breakSymbolicToString").breakSymbolicToString(this._handle);
576
+ }
577
+ /** @returns {{sign:-1|0|1, factors:{prime:bigint,exponent:bigint}[]}} */
578
+ toPrimeAtoms() {
579
+ return _p("toPrimeAtoms").toPrimeAtoms(this._handle);
580
+ }
581
+ /** @returns {{leadingCoeff:EGPTReal, roots:{value:EGPTReal,multiplicity:bigint}[]}} */
582
+ toAtomRoot() {
583
+ const raw = _p("toAtomRoot").toAtomRoot(this._handle);
584
+ return {
585
+ leadingCoeff: _wrap(raw.leadingCoeff),
586
+ roots: raw.roots.map((r) => ({ value: _wrap(r.value), multiplicity: r.multiplicity }))
587
+ };
588
+ }
589
+ /** @param {{sign, factors}} atomVec @returns {EGPTReal} */
590
+ static fromAtomVec(atomVec) {
591
+ return _wrap(_p("fromAtomVec").fromAtomVec(atomVec));
592
+ }
593
+ /** @param {{leadingCoeff:EGPTReal, roots:{value:EGPTReal,multiplicity:bigint}[]}} term @returns {EGPTReal} */
594
+ static fromAtomRoot(term) {
595
+ const p = _p("fromAtomRoot");
596
+ return _wrap(p.fromAtomRoot({
597
+ leadingCoeff: _unwrap(term.leadingCoeff, "fromAtomRoot.leadingCoeff"),
598
+ roots: (term.roots ?? []).map((r) => ({
599
+ value: _unwrap(r.value, "fromAtomRoot.root.value"),
600
+ multiplicity: r.multiplicity
601
+ }))
602
+ }));
603
+ }
604
+ /** Integer gcd (bigint-level, not a rational op). @returns {bigint} */
605
+ static gcd(a, b) {
606
+ return _p("gcd").gcd(BigInt(a), BigInt(b));
607
+ }
608
+ /** Integer lcm (bigint-level, not a rational op). @returns {bigint} */
609
+ static lcm(a, b) {
610
+ return _p("lcm").lcm(BigInt(a), BigInt(b));
611
+ }
612
+ /** @returns {bigint} */
613
+ static modPow(base, exp, mod) {
614
+ return _p("modPow").modPow(BigInt(base), BigInt(exp), BigInt(mod));
615
+ }
616
+ };
617
+ var EGPTMath = Object.freeze({
618
+ add: (a, b) => a.add(b),
619
+ subtract: (a, b) => a.subtract(b),
620
+ multiply: (a, b) => a.multiply(b),
621
+ divide: (a, b) => a.divide(b),
622
+ normalDivide: (a, b) => a.normalDivide(b),
623
+ mod: (a, b) => a.mod(b),
624
+ equals: (a, b) => a.equals(b),
625
+ compare: (a, b) => a.compare(b),
626
+ pow: (base, expNum, expDen) => base.pow(expNum, expDen),
627
+ sqrt: (a) => a.sqrt(),
628
+ getIntegerBitLength: (a) => a.getIntegerBitLength()
629
+ });
630
+ var EGPTPolynomial = Object.freeze({
631
+ /** @param {EGPTReal[]} a @param {EGPTReal[]} b @returns {EGPTReal[]} */
632
+ add(a, b) {
633
+ return _p("polyAdd").polyAdd(a.map((x) => _unwrap(x, "polyAdd")), b.map((x) => _unwrap(x, "polyAdd"))).map(_wrap);
634
+ },
635
+ /** @param {EGPTReal[]} a @param {EGPTReal[]} b @returns {EGPTReal[]} */
636
+ multiply(a, b) {
637
+ return _p("polyMul").polyMul(a.map((x) => _unwrap(x, "polyMul")), b.map((x) => _unwrap(x, "polyMul"))).map(_wrap);
638
+ },
639
+ /** @param {EGPTReal[]} dividend @param {EGPTReal[]} divisor @returns {{quotient:EGPTReal[], remainder:EGPTReal[]}} */
640
+ divide(dividend, divisor) {
641
+ const r = _p("polyDiv").polyDiv(
642
+ dividend.map((x) => _unwrap(x, "polyDiv")),
643
+ divisor.map((x) => _unwrap(x, "polyDiv"))
644
+ );
645
+ return { quotient: r.quotient.map(_wrap), remainder: r.remainder.map(_wrap) };
646
+ },
647
+ /** @param {EGPTReal[]} coeffs @param {number} n @returns {EGPTReal[]} */
648
+ forwardTransform(coeffs, n) {
649
+ return _p("polyForwardTransform").polyForwardTransform(coeffs.map((x) => _unwrap(x, "polyForwardTransform")), n).map(_wrap);
650
+ },
651
+ /** @param {EGPTReal[]} samples @param {number} n @returns {EGPTReal[]} */
652
+ inverseTransform(samples, n) {
653
+ return _p("polyInverseTransform").polyInverseTransform(samples.map((x) => _unwrap(x, "polyInverseTransform")), n).map(_wrap);
654
+ },
655
+ /** @param {EGPTReal[]} poly @param {EGPTReal} x @returns {EGPTReal} */
656
+ evaluateAt(poly, x) {
657
+ return _wrap(
658
+ _p("polyEvaluateAt").polyEvaluateAt(poly.map((c) => _unwrap(c, "polyEvaluateAt")), _unwrap(x, "polyEvaluateAt"))
659
+ );
660
+ },
661
+ /** @param {EGPTReal[]} a @param {EGPTReal[]} b @returns {EGPTReal[]} */
662
+ gcd(a, b) {
663
+ return _p("polyGcd").polyGcd(a.map((x) => _unwrap(x, "polyGcd")), b.map((x) => _unwrap(x, "polyGcd"))).map(_wrap);
664
+ }
665
+ });
666
+ function _matrixZeros(rows, cols) {
667
+ const M = new Array(rows);
668
+ for (let i = 0; i < rows; i++) M[i] = new Array(cols).fill(EGPTReal.ZERO);
669
+ return M;
670
+ }
671
+ function _matrixShape(M) {
672
+ return { rows: M.length, cols: M.length === 0 ? 0 : M[0].length };
673
+ }
674
+ var EGPTMatrix = Object.freeze({
675
+ /** @param {number} rows @param {number} cols @returns {EGPTReal[][]} */
676
+ zeros: _matrixZeros,
677
+ /** @param {number} n @returns {EGPTReal[][]} */
678
+ identity(n) {
679
+ const M = _matrixZeros(n, n);
680
+ for (let i = 0; i < n; i++) M[i][i] = EGPTReal.ONE;
681
+ return M;
682
+ },
683
+ /**
684
+ * Build a matrix from a rectangular array of JS values (BigInt, integer,
685
+ * `[num, den]` tuple, or an existing EGPTReal facade instance).
686
+ * @param {Array<Array>} rows @returns {EGPTReal[][]}
687
+ */
688
+ from(rows) {
689
+ return rows.map((row, i) => row.map((v, j) => {
690
+ if (v instanceof EGPTReal) return v;
691
+ if (Array.isArray(v) && v.length === 2) return EGPTReal.fromRational(BigInt(v[0]), BigInt(v[1]));
692
+ if (typeof v === "bigint") return EGPTReal.fromBigInt(v);
693
+ if (typeof v === "number" && Number.isInteger(v)) return EGPTReal.fromBigInt(BigInt(v));
694
+ throw new Error(`EGPTMatrix.from: unsupported entry at [${i}][${j}]: ${v}`);
695
+ }));
696
+ },
697
+ /** @param {EGPTReal[][]} M @returns {{rows:number, cols:number}} */
698
+ shape: _matrixShape,
699
+ /** @param {EGPTReal[][]} M @returns {EGPTReal[][]} */
700
+ transpose(M) {
701
+ const { rows, cols } = _matrixShape(M);
702
+ const T = _matrixZeros(cols, rows);
703
+ for (let i = 0; i < rows; i++) for (let j = 0; j < cols; j++) T[j][i] = M[i][j];
704
+ return T;
705
+ },
706
+ /** @param {EGPTReal[][]} A @param {EGPTReal[][]} B @returns {boolean} */
707
+ equals(A, B) {
708
+ const a = _matrixShape(A);
709
+ const b = _matrixShape(B);
710
+ if (a.rows !== b.rows || a.cols !== b.cols) return false;
711
+ for (let i = 0; i < a.rows; i++) for (let j = 0; j < a.cols; j++) {
712
+ if (!A[i][j].equals(B[i][j])) return false;
713
+ }
714
+ return true;
715
+ },
716
+ /**
717
+ * Dot product of two equal-length EGPTReal vectors via the polynomial-
718
+ * multiplication identity (the (n-1)-th coefficient of `a(x) * reverse(b)(x)`).
719
+ * @param {EGPTReal[]} a @param {EGPTReal[]} b @returns {EGPTReal}
720
+ */
721
+ dotViaPolynomial(a, b) {
722
+ if (a.length !== b.length) throw new Error(`dotViaPolynomial: length mismatch ${a.length} vs ${b.length}`);
723
+ const n = a.length;
724
+ if (n === 0) return EGPTReal.ZERO;
725
+ const reversed = new Array(n);
726
+ for (let i = 0; i < n; i++) reversed[i] = b[n - 1 - i];
727
+ const product = EGPTPolynomial.multiply(a, reversed);
728
+ return product[n - 1] !== void 0 ? product[n - 1] : EGPTReal.ZERO;
729
+ },
730
+ /** @param {EGPTReal[][]} M @param {EGPTReal[]} v @returns {EGPTReal[]} */
731
+ matVec(M, v) {
732
+ const { rows, cols } = _matrixShape(M);
733
+ if (v.length !== cols) throw new Error(`matVec shape mismatch: M is ${rows}x${cols}, v has length ${v.length}`);
734
+ return M.map((row) => EGPTMatrix.dotViaPolynomial(row, v));
735
+ },
736
+ /**
737
+ * GEMM: `C := alpha * (A . B) + beta * C`.
738
+ * @param {EGPTReal[][]} A @param {EGPTReal[][]} B
739
+ * @param {EGPTReal} [alpha] @param {EGPTReal} [beta] @param {EGPTReal[][]} [C]
740
+ * @returns {EGPTReal[][]}
741
+ */
742
+ gemm(A, B, alpha, beta, C = null) {
743
+ alpha = alpha ?? EGPTReal.ONE;
744
+ beta = beta ?? EGPTReal.ZERO;
745
+ const a = _matrixShape(A);
746
+ const b = _matrixShape(B);
747
+ if (a.cols !== b.rows) throw new Error(`gemm shape mismatch: A is ${a.rows}x${a.cols}, B is ${b.rows}x${b.cols}`);
748
+ if (C === null) {
749
+ C = _matrixZeros(a.rows, b.cols);
750
+ } else {
751
+ const cShape = _matrixShape(C);
752
+ if (cShape.rows !== a.rows || cShape.cols !== b.cols) {
753
+ throw new Error(`gemm: C is ${cShape.rows}x${cShape.cols}, expected ${a.rows}x${b.cols}`);
754
+ }
755
+ }
756
+ const cols = new Array(b.cols);
757
+ for (let j = 0; j < b.cols; j++) {
758
+ const colJ = new Array(a.cols);
759
+ for (let r = 0; r < a.cols; r++) colJ[r] = B[r][j];
760
+ cols[j] = colJ;
761
+ }
762
+ for (let i = 0; i < a.rows; i++) {
763
+ for (let j = 0; j < b.cols; j++) {
764
+ const dotProduct = EGPTMatrix.dotViaPolynomial(A[i], cols[j]);
765
+ const scaled = EGPTMath.multiply(alpha, dotProduct);
766
+ C[i][j] = beta.equals(EGPTReal.ZERO) ? scaled : EGPTMath.add(scaled, EGPTMath.multiply(beta, C[i][j]));
767
+ }
768
+ }
769
+ return C;
770
+ },
771
+ /** Alias for `gemm(A, B)` with default scaling. @returns {EGPTReal[][]} */
772
+ matMul(A, B) {
773
+ return EGPTMatrix.gemm(A, B);
774
+ },
775
+ // toValueReps(M) / fromValueReps(VR) are DELIBERATELY EXCLUDED from this
776
+ // port (unlike every other EGPTMatrix method above). The dev-core versions
777
+ // route through EGPTPolynomial.toValueRepresentation/fromValueRepresentation
778
+ // — evaluation at CANONICAL BASE nodes x = 2^0, 2^1, ..., 2^D via Horner,
779
+ // inverted by Newton divided differences — which is NOT the same operation
780
+ // as polyForwardTransform/polyInverseTransform (those sample at the uniform
781
+ // RATIONAL nodes k/N, the FFT-style basis EGPTFFT below uses). Neither
782
+ // operation is in the 37-op provider contract (lib/egpt/js/model/backend/
783
+ // README.md §1), and substituting the wrong one would silently produce
784
+ // INCORRECT round-trip values — worse than omitting the method. Per the
785
+ // CEO's item-2 escape valve, omission-with-a-loud-error is the correct
786
+ // choice here: a caller hitting this method gets a legible
787
+ // "EGPTMatrix.toValueReps is not a function" (FAIL LOUD), never a silently
788
+ // wrong number. `dotViaPolynomial`/`gemm`/`matMul`/`evaluateRowsAt` above
789
+ // ARE faithful (they route through the SAME polyMultiply/polyEvaluateAt ops
790
+ // the dev-core class uses) and are unaffected by this exclusion.
791
+ /** @param {EGPTReal[][]} M @param {EGPTReal} x @returns {EGPTReal[]} */
792
+ evaluateRowsAt(M, x) {
793
+ return M.map((row) => EGPTPolynomial.evaluateAt(row, x));
794
+ },
795
+ /** @param {EGPTReal[][]} M @param {string} [label] @returns {string} */
796
+ format(M, label) {
797
+ const { rows, cols } = _matrixShape(M);
798
+ const cells = M.map((row) => row.map((v) => v.toCanonicalStr()));
799
+ const widths = new Array(cols).fill(0);
800
+ for (let i = 0; i < rows; i++) for (let j = 0; j < cols; j++) {
801
+ if (cells[i][j].length > widths[j]) widths[j] = cells[i][j].length;
802
+ }
803
+ const lines = cells.map((row) => " [ " + row.map((c, j) => c.padStart(widths[j])).join(" ") + " ]");
804
+ return (label ? `${label} (${rows}x${cols})
805
+ ` : "") + lines.join("\n");
806
+ },
807
+ /** @param {EGPTReal[][]} M @param {string} [label] */
808
+ print(M, label) {
809
+ console.log(EGPTMatrix.format(M, label));
810
+ }
811
+ });
812
+ var EGPTFFT = Object.freeze({
813
+ /** @param {EGPTReal[]} coeffs @param {number} [N] @returns {EGPTReal[]} */
814
+ forward(coeffs, N) {
815
+ return EGPTPolynomial.forwardTransform(coeffs, N === void 0 ? coeffs.length : N);
816
+ },
817
+ /** @param {EGPTReal[]} values @param {number} [N] @returns {EGPTReal[]} */
818
+ inverse(values, N) {
819
+ return EGPTPolynomial.inverseTransform(values, N === void 0 ? values.length : N);
820
+ }
821
+ });
822
+
823
+ // src/examples/qft-benchmark-baseline.js
824
+ var QFT_BENCHMARK_BASELINE = Object.freeze({
825
+ // --- Citation of the published supercomputer result ---
826
+ citation: Object.freeze({
827
+ authors: "Willsch, D.; Willsch, M.; Jin, F.; De Raedt, H.; Michielsen, K.",
828
+ title: "Large-Scale Simulation of Shor's Quantum Factoring Algorithm",
829
+ venue: "Mathematics (MDPI), 11, 4222",
830
+ year: 2023,
831
+ doi: "10.3390/math11194222"
832
+ }),
833
+ // --- Hardware the supercomputer result ran on ---
834
+ hardware: Object.freeze({
835
+ system: "JUWELS Booster supercomputer, J\xFClich Supercomputing Centre",
836
+ gpus: "2048 \xD7 NVIDIA A100 (40 GiB each)",
837
+ // ~80 TiB = aggregate cluster capacity (2048 × 40 GiB). The paper notes the
838
+ // 39/40-qubit run *requires* "slightly larger than 40 TiB" — capacity vs.
839
+ // requirement; see SOURCES memo nuance #3.
840
+ memory: "~80 TiB aggregate GPU memory"
841
+ }),
842
+ // --- Total study compute (the 594 / 49.5 figure; 496-vs-594 resolved → 594) ---
843
+ studyCompute: Object.freeze({
844
+ gpuYears: 49.5,
845
+ coreYears: 594
846
+ }),
847
+ // --- The single benchmark run both sides compute ---
848
+ benchmarkRun: Object.freeze({
849
+ // 39-bit semiprime — the paper's LARGEST successfully-factored case.
850
+ N: "549755813701",
851
+ factors: Object.freeze([712321, 771781]),
852
+ // ~200 s on 2048 A100s (the largest problem) — Willsch et al.
853
+ shorGpuSeconds: 200,
854
+ // ~210 ms on a single 1.2 GHz CPU core / 768 MB — FRAQTL white paper §4.2.
855
+ // (NOT "~10 s": that conflates the 256-bit run, ~39 s §4.3. See SOURCES #2.)
856
+ fraqtlSeconds: 0.21,
857
+ bits: 39
858
+ }),
859
+ // --- What was actually computed (so the comparison is apples-to-apples) ---
860
+ whatWasComputed: "39-bit QFT period extraction (Shor's quantum step)"
861
+ });
862
+ (function assertBaselineComplete(b) {
863
+ const missing = [];
864
+ const req = (path, val, ok = (v) => v !== void 0 && v !== null && v !== "") => {
865
+ if (!ok(val)) missing.push(path);
866
+ };
867
+ req("citation.authors", b.citation?.authors);
868
+ req("citation.title", b.citation?.title);
869
+ req("citation.venue", b.citation?.venue);
870
+ req("citation.year", b.citation?.year, (v) => Number.isFinite(v));
871
+ req("citation.doi", b.citation?.doi);
872
+ req("hardware.system", b.hardware?.system);
873
+ req("hardware.gpus", b.hardware?.gpus);
874
+ req("hardware.memory", b.hardware?.memory);
875
+ req("studyCompute.gpuYears", b.studyCompute?.gpuYears, (v) => Number.isFinite(v));
876
+ req("studyCompute.coreYears", b.studyCompute?.coreYears, (v) => Number.isFinite(v));
877
+ req("benchmarkRun.N", b.benchmarkRun?.N);
878
+ req(
879
+ "benchmarkRun.factors",
880
+ b.benchmarkRun?.factors,
881
+ (v) => Array.isArray(v) && v.length === 2 && v.every((x) => Number.isFinite(x))
882
+ );
883
+ req("benchmarkRun.shorGpuSeconds", b.benchmarkRun?.shorGpuSeconds, (v) => Number.isFinite(v));
884
+ req("benchmarkRun.fraqtlSeconds", b.benchmarkRun?.fraqtlSeconds, (v) => Number.isFinite(v));
885
+ req("benchmarkRun.bits", b.benchmarkRun?.bits, (v) => Number.isFinite(v));
886
+ req("whatWasComputed", b.whatWasComputed);
887
+ if (missing.length) {
888
+ throw new Error(
889
+ "qft-benchmark-baseline.js: incomplete baseline constant \u2014 missing/empty field(s): " + missing.join(", ") + ". A benchmark must not narrate against an absent baseline (FAIL-LOUD)."
890
+ );
891
+ }
892
+ })(QFT_BENCHMARK_BASELINE);
893
+
894
+ // src/browser/dist-entry.js
895
+ function buildWasmFacade(wasmMetadata) {
896
+ const mod = wasmMetadata?.module ?? null;
897
+ const hasFn = (name) => !!mod && typeof mod[name] === "function";
898
+ const safeCall = (name, ...args) => {
899
+ if (!hasFn(name)) {
900
+ return { ok: false, error: `wasm-function-unavailable:${name}`, backend: wasmMetadata.mode };
901
+ }
902
+ try {
903
+ return { ok: true, value: mod[name](...args), backend: wasmMetadata.mode };
904
+ } catch (error) {
905
+ return { ok: false, error: String(error), backend: wasmMetadata.mode };
906
+ }
907
+ };
908
+ return {
909
+ internStr: (s) => safeCall("internStr", s),
910
+ internV2: (b) => safeCall("internV2", b),
911
+ materializeStr: (h) => safeCall("materializeStr", h),
912
+ materializeV2: (h) => safeCall("materializeV2", h),
913
+ releaseHandle: (h) => safeCall("releaseHandle", h),
914
+ resetScope: mod ? () => mod.resetScope() : null,
915
+ arenaStats: mod ? () => mod.arenaStats() : null,
916
+ arenaAdd: (a, b) => safeCall("arenaAdd", a, b),
917
+ arenaSub: (a, b) => safeCall("arenaSub", a, b),
918
+ arenaMul: (a, b) => safeCall("arenaMul", a, b),
919
+ arenaDiv: (a, b) => safeCall("arenaDiv", a, b),
920
+ arenaMod: (a, b) => safeCall("arenaMod", a, b),
921
+ arenaCmp: (a, b) => safeCall("arenaCmp", a, b),
922
+ arenaPow: (base, expNum, expDen) => safeCall("arenaPow", base, expNum, expDen),
923
+ arenaSqrt: (a) => safeCall("arenaSqrt", a),
924
+ arenaExp2: (a) => safeCall("arenaExp2", a),
925
+ arenaLog2: (a) => safeCall("arenaLog2", a),
926
+ arenaPpfEncode: (a) => safeCall("arenaPpfEncode", a),
927
+ arenaPpfDecode: (a) => safeCall("arenaPpfDecode", a),
928
+ arenaFromPpfJson: (j) => safeCall("arenaFromPpfJson", j),
929
+ arenaGetBitLength: (a) => safeCall("arenaGetBitLength", a),
930
+ arenaBreakToBigint: (a) => safeCall("arenaBreakToBigint", a),
931
+ arenaBreakToJsNumber: (a) => safeCall("arenaBreakToJsNumber", a),
932
+ arenaBreakToString: (a) => safeCall("arenaBreakToString", a),
933
+ arenaToPrimeAtoms: (a) => safeCall("arenaToPrimeAtoms", a),
934
+ arenaFromAtomVec: (j) => safeCall("arenaFromAtomVec", j),
935
+ arenaToAtomRoot: (a) => safeCall("arenaToAtomRoot", a),
936
+ arenaFromAtomRoot: (j) => safeCall("arenaFromAtomRoot", j),
937
+ arenaModPow: (b, e, m) => safeCall("arenaModPow", b, e, m),
938
+ arenaGcd: (a, b) => safeCall("arenaGcd", a, b),
939
+ arenaLcm: (a, b) => safeCall("arenaLcm", a, b),
940
+ arenaPolyAdd: (a, b) => safeCall("arenaPolyAdd", a, b),
941
+ arenaPolyMul: (a, b) => safeCall("arenaPolyMul", a, b),
942
+ arenaPolyDiv: (a, b) => safeCall("arenaPolyDiv", a, b),
943
+ arenaPolyFwd: (j, n) => safeCall("arenaPolyFwd", j, n),
944
+ arenaPolyInv: (j, n) => safeCall("arenaPolyInv", j, n),
945
+ arenaPolyEval: (p, x) => safeCall("arenaPolyEval", p, x),
946
+ arenaPolyGcd: (a, b) => safeCall("arenaPolyGcd", a, b)
947
+ };
948
+ }
949
+ async function createEgptMathSdk({ wasmUrl, wasmModuleUrl } = {}) {
950
+ const wasmMetadata = await loadEgptMathWasm({ wasmUrl, wasmModuleUrl });
951
+ if (wasmMetadata.mode !== "wasm-bridge") {
952
+ const warnings = (wasmMetadata.warnings || []).join("; ") || "(no diagnostic warnings captured)";
953
+ throw new Error(
954
+ `EGPT Math SDK: the WASM engine failed to load (mode='${wasmMetadata.mode}'). This build ships no JS math-core fallback (CEO 2026-07-10 standing rule: WASM-only publish surface). wasmUrl=${JSON.stringify(wasmUrl ?? null)} wasmModuleUrl=${JSON.stringify(wasmModuleUrl ?? null)}. Diagnostics: ${warnings}`
955
+ );
956
+ }
957
+ const wasmFacade = buildWasmFacade(wasmMetadata);
958
+ const wasmProvider = buildWasmMathProvider(wasmFacade);
959
+ _setActiveWasmProvider(wasmProvider);
960
+ return {
961
+ EGPTReal,
962
+ EGPTMath,
963
+ EGPTPolynomial,
964
+ EGPTMatrix,
965
+ EGPTFFT,
966
+ wasm: wasmFacade,
967
+ // Truth-in-labeling: derived from the provider actually built above —
968
+ // never a hardcoded literal. There is exactly one possible value in this
969
+ // dist ('wasm-math'), because createEgptMathSdk() throws above rather than
970
+ // returning an SDK object for any other outcome.
971
+ get activeMathBackend() {
972
+ return wasmProvider.id;
973
+ },
974
+ benchmarks: { qftBaseline: QFT_BENCHMARK_BASELINE },
975
+ metadata: { ...wasmMetadata }
976
+ };
977
+ }
978
+ export {
979
+ EGPTFFT,
980
+ EGPTMath,
981
+ EGPTMatrix,
982
+ EGPTPolynomial,
983
+ EGPTReal,
984
+ createEgptMathSdk
985
+ };