@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.
- package/README.md +224 -0
- package/dist/egpt-math-sdk.browser.js +5 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.js +985 -0
- package/dist/notebooks/arithmetic-basics.html +166 -0
- package/dist/notebooks/complex-twiddle.html +148 -0
- package/dist/notebooks/double-slit-rosetta-qft.html +154 -0
- package/dist/notebooks/egpt-fft-test.html +202 -0
- package/dist/notebooks/egpt-matrix-test.html +241 -0
- package/dist/notebooks/egpt-polynomial-test.html +703 -0
- package/dist/notebooks/egpt-prime-composite-test.html +561 -0
- package/dist/notebooks/egpt-test-suite.html +1387 -0
- package/dist/notebooks/egpt-topology-test.html +410 -0
- package/dist/notebooks/factorization-basics.html +131 -0
- package/dist/notebooks/fft.html +155 -0
- package/dist/notebooks/frqtl-qft-benchmark.html +207 -0
- package/dist/notebooks/gallery-atomic-model.html +51 -0
- package/dist/notebooks/gallery-big-bang.html +62 -0
- package/dist/notebooks/gallery-blackbody.html +52 -0
- package/dist/notebooks/gallery-circuit-sat.html +104 -0
- package/dist/notebooks/gallery-collision-matrix-3d.html +51 -0
- package/dist/notebooks/gallery-double-slit.html +53 -0
- package/dist/notebooks/gallery-gun-chamber.html +62 -0
- package/dist/notebooks/gallery-particle-walk-3d.html +53 -0
- package/dist/notebooks/gallery-wave-interference.html +52 -0
- package/dist/notebooks/getting-started-hello-frqtl.html +53 -0
- package/dist/notebooks/iso-canonical-chain.html +203 -0
- package/dist/notebooks/iso-entropy-log.html +127 -0
- package/dist/notebooks/iso-fft-polynomial.html +136 -0
- package/dist/notebooks/iso-matrix-four-views.html +131 -0
- package/dist/notebooks/iso-number-theory-four-views.html +99 -0
- package/dist/notebooks/iso-pi-log-fraction-loop.html +140 -0
- package/dist/notebooks/matrix.html +202 -0
- package/dist/notebooks/notebooks.json +240 -0
- package/dist/notebooks/polynomials.html +201 -0
- package/dist/notebooks/prime-composite.html +268 -0
- package/dist/notebooks/rational-core.html +179 -0
- package/dist/notebooks/reference-egpt-fft-test.html +187 -0
- package/dist/notebooks/reference-order-finder-test.html +196 -0
- package/dist/notebooks/reference-prime-atom-polynomial-test.html +542 -0
- package/dist/notebooks/reference-solve-polynomial-system-test.html +471 -0
- package/dist/notebooks/scaled-vectors.html +112 -0
- package/dist/notebooks/stats.html +206 -0
- package/dist/notebooks/transcendentals.html +195 -0
- package/dist/notebooks/view-vendored-d3.html +78 -0
- package/dist/vendor/d3-array/src/array.js +4 -0
- package/dist/vendor/d3-array/src/ascending.js +3 -0
- package/dist/vendor/d3-array/src/bin.js +125 -0
- package/dist/vendor/d3-array/src/bisect.js +9 -0
- package/dist/vendor/d3-array/src/bisector.js +56 -0
- package/dist/vendor/d3-array/src/blur.js +115 -0
- package/dist/vendor/d3-array/src/constant.js +3 -0
- package/dist/vendor/d3-array/src/count.js +18 -0
- package/dist/vendor/d3-array/src/cross.js +33 -0
- package/dist/vendor/d3-array/src/cumsum.js +6 -0
- package/dist/vendor/d3-array/src/descending.js +7 -0
- package/dist/vendor/d3-array/src/deviation.js +6 -0
- package/dist/vendor/d3-array/src/difference.js +11 -0
- package/dist/vendor/d3-array/src/disjoint.js +15 -0
- package/dist/vendor/d3-array/src/every.js +10 -0
- package/dist/vendor/d3-array/src/extent.js +29 -0
- package/dist/vendor/d3-array/src/filter.js +11 -0
- package/dist/vendor/d3-array/src/fsum.js +69 -0
- package/dist/vendor/d3-array/src/greatest.js +29 -0
- package/dist/vendor/d3-array/src/greatestIndex.js +19 -0
- package/dist/vendor/d3-array/src/group.js +65 -0
- package/dist/vendor/d3-array/src/groupSort.js +10 -0
- package/dist/vendor/d3-array/src/identity.js +3 -0
- package/dist/vendor/d3-array/src/index.js +57 -0
- package/dist/vendor/d3-array/src/intersection.js +19 -0
- package/dist/vendor/d3-array/src/least.js +29 -0
- package/dist/vendor/d3-array/src/leastIndex.js +19 -0
- package/dist/vendor/d3-array/src/map.js +5 -0
- package/dist/vendor/d3-array/src/max.js +20 -0
- package/dist/vendor/d3-array/src/maxIndex.js +22 -0
- package/dist/vendor/d3-array/src/mean.js +19 -0
- package/dist/vendor/d3-array/src/median.js +9 -0
- package/dist/vendor/d3-array/src/merge.js +9 -0
- package/dist/vendor/d3-array/src/min.js +20 -0
- package/dist/vendor/d3-array/src/minIndex.js +22 -0
- package/dist/vendor/d3-array/src/mode.js +28 -0
- package/dist/vendor/d3-array/src/nice.js +18 -0
- package/dist/vendor/d3-array/src/number.js +20 -0
- package/dist/vendor/d3-array/src/pairs.js +15 -0
- package/dist/vendor/d3-array/src/permute.js +3 -0
- package/dist/vendor/d3-array/src/quantile.js +47 -0
- package/dist/vendor/d3-array/src/quickselect.js +53 -0
- package/dist/vendor/d3-array/src/range.js +13 -0
- package/dist/vendor/d3-array/src/rank.js +24 -0
- package/dist/vendor/d3-array/src/reduce.js +14 -0
- package/dist/vendor/d3-array/src/reverse.js +4 -0
- package/dist/vendor/d3-array/src/scan.js +6 -0
- package/dist/vendor/d3-array/src/shuffle.js +13 -0
- package/dist/vendor/d3-array/src/some.js +10 -0
- package/dist/vendor/d3-array/src/sort.js +39 -0
- package/dist/vendor/d3-array/src/subset.js +5 -0
- package/dist/vendor/d3-array/src/sum.js +18 -0
- package/dist/vendor/d3-array/src/superset.js +19 -0
- package/dist/vendor/d3-array/src/threshold/freedmanDiaconis.js +7 -0
- package/dist/vendor/d3-array/src/threshold/scott.js +7 -0
- package/dist/vendor/d3-array/src/threshold/sturges.js +5 -0
- package/dist/vendor/d3-array/src/ticks.js +55 -0
- package/dist/vendor/d3-array/src/transpose.js +15 -0
- package/dist/vendor/d3-array/src/union.js +11 -0
- package/dist/vendor/d3-array/src/variance.js +25 -0
- package/dist/vendor/d3-array/src/zip.js +5 -0
- package/dist/vendor/internmap/src/index.js +61 -0
- package/dist/vendor/manifest.json +11 -0
- package/dist/wasm/egpt_math_sdk_wasm.d.ts +214 -0
- package/dist/wasm/egpt_math_sdk_wasm.js +1120 -0
- package/dist/wasm/egpt_math_sdk_wasm_bg.wasm +0 -0
- package/dist/wasm/egpt_math_sdk_wasm_bg.wasm.d.ts +66 -0
- package/dist/wasm/manifest.json +5 -0
- package/package.json +53 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
<frqtl-notebook version="1" title="Topology-Native Function Tests — sin, cos, exp, and FFT roots from the n-gon">
|
|
2
|
+
|
|
3
|
+
<cell type="markdown">
|
|
4
|
+
# Topology-Native Function Tests
|
|
5
|
+
|
|
6
|
+
EGPT mathematics replaces the continuous unit circle with a **discrete n-gon topology**.
|
|
7
|
+
In this model, angles are not measured in radians but as rational *phase fractions*
|
|
8
|
+
where `0` = no rotation, `1/2` = half-rotation (π), and `1` = full rotation (τ = 2π).
|
|
9
|
+
|
|
10
|
+
The payoff: sin, cos, exp, and the FFT twiddle factors all yield **exact rational values**
|
|
11
|
+
for the canonical rotation points — no floating-point approximation, no transcendental
|
|
12
|
+
constants in the computation. The topology is verified here by showing that
|
|
13
|
+
cos²(φ) + sin²(φ) = 1/2, not 1, for a diagonal phase — the signature of the 8-vertex
|
|
14
|
+
discrete square, not a continuous circle.
|
|
15
|
+
|
|
16
|
+
Ported from `sdk/egpt-math-sdk/src/editor/tests/EGPTTopologyTestSuite.js`.
|
|
17
|
+
`EGPTReal`, `EGPTMath`, `EGPTranscendental`, `ComplexEGPTReal`, `EGPTComplex` come from
|
|
18
|
+
`caps.math`. The `TestFramework` class is inlined (it is a local helper in the source,
|
|
19
|
+
not part of the SDK surface).
|
|
20
|
+
</cell>
|
|
21
|
+
|
|
22
|
+
<cell type="markdown">
|
|
23
|
+
## Setup — test harness
|
|
24
|
+
|
|
25
|
+
A minimal inline `TestFramework` mirrors the one used in the source file.
|
|
26
|
+
Each phase cell receives `suite` and appends its results; the final cell prints
|
|
27
|
+
the overall summary.
|
|
28
|
+
</cell>
|
|
29
|
+
|
|
30
|
+
<cell type="js" lane="math" id="topo-setup" out="suite">
|
|
31
|
+
const { math } = caps;
|
|
32
|
+
const { EGPTReal, EGPTMath, EGPTranscendental, ComplexEGPTReal, EGPTComplex } = math;
|
|
33
|
+
|
|
34
|
+
class TestFramework {
|
|
35
|
+
constructor() {
|
|
36
|
+
this.tests = [];
|
|
37
|
+
this.categories = {};
|
|
38
|
+
}
|
|
39
|
+
test(description, category, testFunction) {
|
|
40
|
+
const result = { description, category, passed: false, error: null };
|
|
41
|
+
try {
|
|
42
|
+
result.passed = testFunction();
|
|
43
|
+
if (result.passed === undefined) result.passed = true;
|
|
44
|
+
} catch (e) {
|
|
45
|
+
result.passed = false;
|
|
46
|
+
result.error = e.message;
|
|
47
|
+
}
|
|
48
|
+
this.tests.push(result);
|
|
49
|
+
if (!this.categories[category]) this.categories[category] = [];
|
|
50
|
+
this.categories[category].push(result);
|
|
51
|
+
const status = result.passed ? '✅ PASS' : '❌ FAIL';
|
|
52
|
+
const errMsg = result.error ? ` (${result.error})` : '';
|
|
53
|
+
console.log(`${status}: ${description}${errMsg}`);
|
|
54
|
+
}
|
|
55
|
+
printSummary() {
|
|
56
|
+
const total = this.tests.length;
|
|
57
|
+
const passed = this.tests.filter(t => t.passed).length;
|
|
58
|
+
console.log('='.repeat(60));
|
|
59
|
+
console.log('TEST SUMMARY');
|
|
60
|
+
console.log('='.repeat(60));
|
|
61
|
+
for (const [cat, catTests] of Object.entries(this.categories)) {
|
|
62
|
+
const p = catTests.filter(t => t.passed).length;
|
|
63
|
+
console.log(`${cat}: ${p}/${catTests.length} passed`);
|
|
64
|
+
}
|
|
65
|
+
console.log('-'.repeat(60));
|
|
66
|
+
console.log(`TOTAL: ${passed}/${total} tests passed`);
|
|
67
|
+
console.log(`SUCCESS RATE: ${((passed / total) * 100).toFixed(1)}%`);
|
|
68
|
+
if (passed < total) {
|
|
69
|
+
console.log('\n❌ FAILED TESTS:');
|
|
70
|
+
this.tests.filter(t => !t.passed).forEach(t => {
|
|
71
|
+
console.log(` ${t.category}: ${t.description}`);
|
|
72
|
+
if (t.error) console.log(` Error: ${t.error}`);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return { total, passed };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const test = new TestFramework();
|
|
80
|
+
return { suite: { test, EGPTReal, EGPTMath, EGPTranscendental, ComplexEGPTReal, EGPTComplex } };
|
|
81
|
+
</cell>
|
|
82
|
+
|
|
83
|
+
<cell type="markdown">
|
|
84
|
+
## Phase T1 — Geometric Constants (Phases)
|
|
85
|
+
|
|
86
|
+
In the n-gon topology, π and τ are not irrational constants. They are exact rational
|
|
87
|
+
*phase fractions*:
|
|
88
|
+
|
|
89
|
+
- `PI_PHASE = 1/2` — a half-rotation
|
|
90
|
+
- `TAU_PHASE = 1` — a full rotation
|
|
91
|
+
|
|
92
|
+
All trig and exponential work operates on these rational fractions, not on floating-point
|
|
93
|
+
approximations of π.
|
|
94
|
+
</cell>
|
|
95
|
+
|
|
96
|
+
<cell type="js" lane="math" id="topo-t1" in="suite" out="suite">
|
|
97
|
+
const { test, EGPTReal, EGPTranscendental } = inputs.suite;
|
|
98
|
+
|
|
99
|
+
console.log('=== PHASE T1: GEOMETRIC CONSTANTS ===');
|
|
100
|
+
|
|
101
|
+
test.test('EGPTranscendental.PI_PHASE represents a half-rotation (1/2)', 'Geometric Constants', () => {
|
|
102
|
+
const pi_phase = EGPTranscendental.PI_PHASE;
|
|
103
|
+
const expected = EGPTReal.fromRational(1n, 2n);
|
|
104
|
+
return pi_phase.equals(expected);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test.test('EGPTranscendental.TAU_PHASE represents a full-rotation (1)', 'Geometric Constants', () => {
|
|
108
|
+
const tau_phase = EGPTranscendental.TAU_PHASE;
|
|
109
|
+
const expected = EGPTReal.fromBigInt(1n);
|
|
110
|
+
return tau_phase.equals(expected);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return { suite: inputs.suite };
|
|
114
|
+
</cell>
|
|
115
|
+
|
|
116
|
+
<cell type="markdown">
|
|
117
|
+
## Phase T2 — Topology-Native Trigonometric Functions
|
|
118
|
+
|
|
119
|
+
Because the phase is rational, the canonical rotation points return exact integers or
|
|
120
|
+
simple fractions — no approximation:
|
|
121
|
+
|
|
122
|
+
| Phase | Rotation | cos | sin |
|
|
123
|
+
|---|---|---|---|
|
|
124
|
+
| 0 | 0° | 1 | 0 |
|
|
125
|
+
| 1/4 | 90° | 0 | 1 |
|
|
126
|
+
| 1/2 | 180° | −1 | 0 |
|
|
127
|
+
| 1 | 360° | 1 | 0 |
|
|
128
|
+
</cell>
|
|
129
|
+
|
|
130
|
+
<cell type="js" lane="math" id="topo-t2" in="suite" out="suite">
|
|
131
|
+
const { test, EGPTReal, EGPTMath, EGPTranscendental } = inputs.suite;
|
|
132
|
+
|
|
133
|
+
console.log('=== PHASE T2: TOPOLOGY-NATIVE TRIGONOMETRY ===');
|
|
134
|
+
|
|
135
|
+
test.test('cos(0) = 1', 'N-Gon Trigonometry', () => {
|
|
136
|
+
const phase = EGPTReal.fromBigInt(0n);
|
|
137
|
+
const result = EGPTranscendental.cos(phase);
|
|
138
|
+
return result.equals(EGPTReal.fromBigInt(1n));
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test.test('sin(0) = 0', 'N-Gon Trigonometry', () => {
|
|
142
|
+
const phase = EGPTReal.fromBigInt(0n);
|
|
143
|
+
const result = EGPTranscendental.sin(phase);
|
|
144
|
+
return result.equals(EGPTReal.fromBigInt(0n));
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test.test('cos(PI_PHASE) = -1 (half-rotation)', 'N-Gon Trigonometry', () => {
|
|
148
|
+
const result = EGPTranscendental.cos(EGPTranscendental.PI_PHASE);
|
|
149
|
+
return result.equals(EGPTReal.fromBigInt(-1n));
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test.test('sin(PI_PHASE) = 0 (half-rotation)', 'N-Gon Trigonometry', () => {
|
|
153
|
+
const result = EGPTranscendental.sin(EGPTranscendental.PI_PHASE);
|
|
154
|
+
return result.equals(EGPTReal.fromBigInt(0n));
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test.test('cos(PI_PHASE / 2) = 0 (quarter-rotation)', 'N-Gon Trigonometry', () => {
|
|
158
|
+
const quarter_phase = EGPTMath.divide(EGPTranscendental.PI_PHASE, EGPTReal.fromBigInt(2n));
|
|
159
|
+
const result = EGPTranscendental.cos(quarter_phase);
|
|
160
|
+
return result.equals(EGPTReal.fromBigInt(0n));
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test.test('sin(PI_PHASE / 2) = 1 (quarter-rotation)', 'N-Gon Trigonometry', () => {
|
|
164
|
+
const quarter_phase = EGPTMath.divide(EGPTranscendental.PI_PHASE, EGPTReal.fromBigInt(2n));
|
|
165
|
+
const result = EGPTranscendental.sin(quarter_phase);
|
|
166
|
+
return result.equals(EGPTReal.fromBigInt(1n));
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test.test('cos(TAU_PHASE) = 1 (full-rotation)', 'N-Gon Trigonometry', () => {
|
|
170
|
+
const result = EGPTranscendental.cos(EGPTranscendental.TAU_PHASE);
|
|
171
|
+
return result.equals(EGPTReal.fromBigInt(1n));
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
return { suite: inputs.suite };
|
|
175
|
+
</cell>
|
|
176
|
+
|
|
177
|
+
<cell type="markdown">
|
|
178
|
+
## Phase T3 — Verifying the N-Gon (Discrete Vertex) Topology
|
|
179
|
+
|
|
180
|
+
The Pythagorean identity cos²(φ) + sin²(φ) = 1 holds on the **continuous** unit circle.
|
|
181
|
+
On the **discrete** 8-vertex square (phase 1/8 = a diagonal), both cos and sin equal 1/2,
|
|
182
|
+
so their squares sum to 1/4 + 1/4 = **1/2**, not 1.
|
|
183
|
+
|
|
184
|
+
This is not an approximation error — it is the exact signature of the discrete vertex
|
|
185
|
+
topology. The cell confirms this distinguishing property.
|
|
186
|
+
</cell>
|
|
187
|
+
|
|
188
|
+
<cell type="js" lane="math" id="topo-t3" in="suite" out="suite">
|
|
189
|
+
const { test, EGPTReal, EGPTMath, EGPTranscendental } = inputs.suite;
|
|
190
|
+
|
|
191
|
+
console.log('=== PHASE T3: N-GON TOPOLOGY VERIFICATION ===');
|
|
192
|
+
|
|
193
|
+
test.test('cos²(phase) + sin²(phase) != 1 for diagonal phases', 'N-Gon Topology Verification', () => {
|
|
194
|
+
// Phase 1/8 is a diagonal on the discrete vertex topology
|
|
195
|
+
const diagonal_phase = EGPTReal.fromRational(1n, 8n);
|
|
196
|
+
const cos_val = EGPTranscendental.cos(diagonal_phase); // 1/2 in discrete topology
|
|
197
|
+
const sin_val = EGPTranscendental.sin(diagonal_phase); // 1/2 in discrete topology
|
|
198
|
+
const cos_sq = EGPTMath.multiply(cos_val, cos_val); // 1/4
|
|
199
|
+
const sin_sq = EGPTMath.multiply(sin_val, sin_val); // 1/4
|
|
200
|
+
const sum = EGPTMath.add(cos_sq, sin_sq); // 1/2 (not 1)
|
|
201
|
+
const H_one = EGPTReal.fromBigInt(1n);
|
|
202
|
+
// Sum should be 1/2, confirming the discrete vertex topology
|
|
203
|
+
return !sum.equals(H_one) && sum.equals(EGPTReal.fromRational(1n, 2n));
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test.test('cos(phase 1/8) = 1/2', 'N-Gon Topology Verification', () => {
|
|
207
|
+
const phase = EGPTReal.fromRational(1n, 8n);
|
|
208
|
+
const result = EGPTranscendental.cos(phase);
|
|
209
|
+
return result.equals(EGPTReal.fromRational(1n, 2n));
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test.test('sin(phase 1/8) = 1/2', 'N-Gon Topology Verification', () => {
|
|
213
|
+
const phase = EGPTReal.fromRational(1n, 8n);
|
|
214
|
+
const result = EGPTranscendental.sin(phase);
|
|
215
|
+
return result.equals(EGPTReal.fromRational(1n, 2n));
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
return { suite: inputs.suite };
|
|
219
|
+
</cell>
|
|
220
|
+
|
|
221
|
+
<cell type="markdown">
|
|
222
|
+
## Phase T4 — Geometric Exponential Function
|
|
223
|
+
|
|
224
|
+
The complex exponential `exp(a + i·b)` in the n-gon topology:
|
|
225
|
+
|
|
226
|
+
- Maps imaginary exponent `i·b` to the rotation by phase `b` → exact Euler's identity
|
|
227
|
+
- Acts as a **frequency multiplier**: the output phase is `b × 2^(−a)`
|
|
228
|
+
- Computes exact factorial values for small `n` via direct iteration
|
|
229
|
+
- Provides a Stirling approximation for large `n` using topology-native π and e
|
|
230
|
+
|
|
231
|
+
Euler's identity becomes `exp(i·PI_PHASE) = −1 + 0i` with exact rational arithmetic —
|
|
232
|
+
no floating-point π involved.
|
|
233
|
+
</cell>
|
|
234
|
+
|
|
235
|
+
<cell type="js" lane="math" id="topo-t4" in="suite" out="suite">
|
|
236
|
+
const { test, EGPTReal, EGPTMath, EGPTranscendental, ComplexEGPTReal, EGPTComplex } = inputs.suite;
|
|
237
|
+
|
|
238
|
+
console.log('=== PHASE T4: GEOMETRIC EXPONENTIAL ===');
|
|
239
|
+
|
|
240
|
+
test.test("exp(i * PI_PHASE) = -1 (Euler's Identity)", 'Geometric Exponential', () => {
|
|
241
|
+
const H_ZERO = EGPTReal.fromBigInt(0n);
|
|
242
|
+
const z = new ComplexEGPTReal(H_ZERO, EGPTranscendental.PI_PHASE);
|
|
243
|
+
const result = EGPTComplex.exp(z);
|
|
244
|
+
const expected = new ComplexEGPTReal(EGPTReal.fromBigInt(-1n), EGPTReal.fromBigInt(0n));
|
|
245
|
+
return result.equals(expected);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test.test('exp(i * PI_PHASE / 2) = i (Quarter Turn)', 'Geometric Exponential', () => {
|
|
249
|
+
const H_ZERO = EGPTReal.fromBigInt(0n);
|
|
250
|
+
const quarter_phase = EGPTMath.divide(EGPTranscendental.PI_PHASE, EGPTReal.fromBigInt(2n));
|
|
251
|
+
const z = new ComplexEGPTReal(H_ZERO, quarter_phase);
|
|
252
|
+
const result = EGPTComplex.exp(z);
|
|
253
|
+
const expected = new ComplexEGPTReal(EGPTReal.fromBigInt(0n), EGPTReal.fromBigInt(1n));
|
|
254
|
+
return result.equals(expected);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
test.test('Unit Circle Identity: |exp(z)| == 1 (L1 norm)', 'Geometric Exponential', () => {
|
|
258
|
+
// a=2, b=1/8: in the discrete topology the L1 magnitude is |x|+|y|
|
|
259
|
+
const z = new ComplexEGPTReal(EGPTReal.fromBigInt(2n), EGPTReal.fromRational(1n, 8n));
|
|
260
|
+
const result = EGPTComplex.exp(z);
|
|
261
|
+
const abs_x = EGPTMath.abs(result.real);
|
|
262
|
+
const abs_y = EGPTMath.abs(result.imag);
|
|
263
|
+
const magnitude = EGPTMath.add(abs_x, abs_y);
|
|
264
|
+
return magnitude.equals(EGPTReal.fromBigInt(1n));
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
test.test('exp(a) acts as frequency multiplier 2^-a', 'Geometric Exponential', () => {
|
|
268
|
+
const H_a = EGPTReal.fromBigInt(1n);
|
|
269
|
+
const H_b = EGPTReal.fromRational(1n, 8n);
|
|
270
|
+
const z = new ComplexEGPTReal(H_a, H_b);
|
|
271
|
+
const result = EGPTComplex.exp(z);
|
|
272
|
+
const result_phase = result.getPhase();
|
|
273
|
+
// Expected phase = b * 2^(-a) = (1/8) * (1/2) = 1/16
|
|
274
|
+
const H_neg_a = EGPTReal.negate(H_a);
|
|
275
|
+
const H_freq_multiplier = EGPTranscendental.exp2(H_neg_a);
|
|
276
|
+
const H_expected_phase = EGPTMath.normalMultiply(H_b, H_freq_multiplier);
|
|
277
|
+
return result_phase.equals(H_expected_phase);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
test.test('Factorial computation: 5! = 120 using topology-native operations', 'Geometric Exponential', () => {
|
|
281
|
+
const n = 5n;
|
|
282
|
+
const H_result = EGPTranscendental.factorial(n);
|
|
283
|
+
const H_expected = EGPTReal.fromBigInt(120n);
|
|
284
|
+
return EGPTMath.equals(H_result, H_expected);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test.test("Factorial Stirling approximation: 97! computed via topology-native formula", 'Geometric Exponential', () => {
|
|
288
|
+
// Compute 97! exactly via iterative multiplication
|
|
289
|
+
const n = 97n;
|
|
290
|
+
let en_97_factorial = EGPTReal.fromBigInt(1n);
|
|
291
|
+
for (let i = 2n; i <= n; i++) {
|
|
292
|
+
en_97_factorial = EGPTMath.multiply(en_97_factorial, EGPTReal.fromBigInt(i));
|
|
293
|
+
}
|
|
294
|
+
// Compute via Stirling's approximation
|
|
295
|
+
const H_stirling_result = EGPTranscendental.factorial(n);
|
|
296
|
+
// Compare: relative error = |exact - approx| / exact
|
|
297
|
+
const H_diff = EGPTMath.subtract(en_97_factorial, H_stirling_result);
|
|
298
|
+
const H_abs_diff = EGPTMath.abs(H_diff);
|
|
299
|
+
const H_relative_error = EGPTMath.normalDivide(H_abs_diff, en_97_factorial);
|
|
300
|
+
const relative_error = H_relative_error.breakSymbolicToApproximateJSNumber();
|
|
301
|
+
console.log(` 97! (Stirling) relative error: ${isFinite(relative_error) ? (relative_error * 100).toFixed(4) + '%' : 'Infinity (scaled vector — see note)'}`);
|
|
302
|
+
return relative_error < 0.01;
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
return { suite: inputs.suite };
|
|
306
|
+
</cell>
|
|
307
|
+
|
|
308
|
+
<cell type="markdown">
|
|
309
|
+
## Phase T5 — FFT / FAT Foundational Elements
|
|
310
|
+
|
|
311
|
+
The Discrete Fourier Transform uses **roots of unity** ω_N^k = exp(i · 2π · k/N).
|
|
312
|
+
In the n-gon topology, these are `EGPTComplex.exp(0 + i · TAU_PHASE · (k/N))` and
|
|
313
|
+
evaluate to exact rational complex numbers at every lattice point.
|
|
314
|
+
|
|
315
|
+
Key properties verified:
|
|
316
|
+
- **ω_N^0 = 1** for any N (identity)
|
|
317
|
+
- **ω_N^N = 1** (full-period periodicity)
|
|
318
|
+
- **ω_N^k and ω_N^(N−k) are conjugates** (symmetry that halves real FFT work)
|
|
319
|
+
- **DC component** X[0] = Σ x[n] (sum of all inputs)
|
|
320
|
+
- **Unnormalized inverse** of normalized = N × original
|
|
321
|
+
</cell>
|
|
322
|
+
|
|
323
|
+
<cell type="js" lane="math" id="topo-t5" in="suite" out="suite">
|
|
324
|
+
const { test, EGPTReal, EGPTMath, EGPTranscendental, ComplexEGPTReal, EGPTComplex } = inputs.suite;
|
|
325
|
+
|
|
326
|
+
console.log('=== PHASE T5: FFT FOUNDATIONAL ELEMENTS ===');
|
|
327
|
+
|
|
328
|
+
test.test('Roots of unity: ω_N^0 = 1 for any N', 'FFT Foundations', () => {
|
|
329
|
+
const N = 8;
|
|
330
|
+
const phase = EGPTReal.fromRational(0n, BigInt(N));
|
|
331
|
+
const root = EGPTComplex.exp(new ComplexEGPTReal(
|
|
332
|
+
EGPTReal.fromBigInt(0n),
|
|
333
|
+
EGPTMath.multiply(EGPTranscendental.TAU_PHASE, phase)
|
|
334
|
+
));
|
|
335
|
+
const one = new ComplexEGPTReal(EGPTReal.fromBigInt(1n), EGPTReal.fromBigInt(0n));
|
|
336
|
+
return root.equals(one);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
test.test('Roots of unity: ω_N^N = 1 (periodicity)', 'FFT Foundations', () => {
|
|
340
|
+
const N = 8;
|
|
341
|
+
const phase = EGPTReal.fromRational(BigInt(N), BigInt(N)); // full rotation = 1
|
|
342
|
+
const root = EGPTComplex.exp(new ComplexEGPTReal(
|
|
343
|
+
EGPTReal.fromBigInt(0n),
|
|
344
|
+
EGPTMath.multiply(EGPTranscendental.TAU_PHASE, phase)
|
|
345
|
+
));
|
|
346
|
+
const one = new ComplexEGPTReal(EGPTReal.fromBigInt(1n), EGPTReal.fromBigInt(0n));
|
|
347
|
+
return root.equals(one);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
test.test('Roots of unity: ω_N^k and ω_N^(N-k) are conjugates', 'FFT Foundations', () => {
|
|
351
|
+
const N = 8, k = 2;
|
|
352
|
+
const phase_k = EGPTReal.fromRational(BigInt(k), BigInt(N));
|
|
353
|
+
const phase_Nk = EGPTReal.fromRational(BigInt(N - k), BigInt(N));
|
|
354
|
+
const root_k = EGPTComplex.exp(new ComplexEGPTReal(
|
|
355
|
+
EGPTReal.fromBigInt(0n),
|
|
356
|
+
EGPTMath.multiply(EGPTranscendental.TAU_PHASE, phase_k)
|
|
357
|
+
));
|
|
358
|
+
const root_Nk = EGPTComplex.exp(new ComplexEGPTReal(
|
|
359
|
+
EGPTReal.fromBigInt(0n),
|
|
360
|
+
EGPTMath.multiply(EGPTranscendental.TAU_PHASE, phase_Nk)
|
|
361
|
+
));
|
|
362
|
+
return root_k.conjugate().equals(root_Nk);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test.test('Forward FFT: DC component = sum of all inputs', 'FFT Foundations', () => {
|
|
366
|
+
// X[0] = Σ x[n] for n = 0 to N-1; signal = [1, 2, 3, 4]
|
|
367
|
+
const N = 4;
|
|
368
|
+
const signal = [];
|
|
369
|
+
for (let i = 0; i < N; i++) {
|
|
370
|
+
signal.push(new ComplexEGPTReal(EGPTReal.fromBigInt(BigInt(i + 1)), EGPTReal.fromBigInt(0n)));
|
|
371
|
+
}
|
|
372
|
+
let sum = EGPTReal.fromBigInt(0n);
|
|
373
|
+
for (const s of signal) { sum = EGPTMath.add(sum, s.real); }
|
|
374
|
+
return sum.equals(EGPTReal.fromBigInt(10n)); // 1+2+3+4 = 10
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
test.test('Inverse FFT normalization: unnormalized result = N * original', 'FFT Foundations', () => {
|
|
378
|
+
// IEQFT without normalization: N * original
|
|
379
|
+
const N = 4;
|
|
380
|
+
const scale = EGPTReal.fromBigInt(BigInt(N));
|
|
381
|
+
const original = EGPTReal.fromBigInt(5n);
|
|
382
|
+
const scaled = EGPTMath.multiply(original, scale);
|
|
383
|
+
return scaled.equals(EGPTReal.fromBigInt(20n)); // 4 * 5 = 20
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
return { suite: inputs.suite };
|
|
387
|
+
</cell>
|
|
388
|
+
|
|
389
|
+
<cell type="markdown">
|
|
390
|
+
## Summary
|
|
391
|
+
|
|
392
|
+
The final cell accumulates results from all phases and prints the suite totals.
|
|
393
|
+
</cell>
|
|
394
|
+
|
|
395
|
+
<cell type="js" lane="math" id="topo-summary" in="suite">
|
|
396
|
+
const { test } = inputs.suite;
|
|
397
|
+
|
|
398
|
+
console.log('\n' + '='.repeat(60));
|
|
399
|
+
const { total, passed } = test.printSummary();
|
|
400
|
+
console.log('='.repeat(60));
|
|
401
|
+
|
|
402
|
+
const failed = total - passed;
|
|
403
|
+
if (failed === 0) {
|
|
404
|
+
console.log('All topology-native functions validated.');
|
|
405
|
+
} else {
|
|
406
|
+
console.log(`${failed} test(s) failed — see FAILED TESTS list above.`);
|
|
407
|
+
}
|
|
408
|
+
</cell>
|
|
409
|
+
|
|
410
|
+
</frqtl-notebook>
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<frqtl-notebook version="1" title="Factorization Basics — How EGPTReal Encodes Integers as Prime-Factor Vectors">
|
|
2
|
+
|
|
3
|
+
<cell type="markdown">
|
|
4
|
+
# Factorization Basics — How EGPTReal Encodes Integers as Prime-Factor Vectors
|
|
5
|
+
|
|
6
|
+
Every integer has a unique factorization into prime powers — the Fundamental Theorem of Arithmetic. EGPT makes this canonical: `EGPTReal.fromBigInt(n)` does not store `n` as a single integer; it encodes `n` as a **PPF (Prime-Power Factorization) vector**, where each dimension corresponds to one prime and the coordinate is that prime's exponent.
|
|
7
|
+
|
|
8
|
+
This is the foundation of every EGPT operation. Multiplication becomes vector addition, division becomes vector subtraction, and equality becomes exact component-wise comparison — no floating-point, no rounding, no approximation.
|
|
9
|
+
|
|
10
|
+
This notebook demonstrates that encoding on three representative integers: a composite with small factors (12), a power of two (64), and a prime (97).
|
|
11
|
+
|
|
12
|
+
Every computation runs through the injected `math` builtin. No URLs are imported; the live math backend is reported by the SDK itself.
|
|
13
|
+
</cell>
|
|
14
|
+
|
|
15
|
+
<cell type="js" lane="math" id="backend">
|
|
16
|
+
// Report the active math backend — DERIVED from the SDK, never asserted.
|
|
17
|
+
const { math, display } = caps;
|
|
18
|
+
const backend = math.activeMathBackend;
|
|
19
|
+
display(`Active math backend (derived from MathBackendRegistry): ${backend}`);
|
|
20
|
+
</cell>
|
|
21
|
+
|
|
22
|
+
<cell type="markdown">
|
|
23
|
+
## 1. What is a PPF vector?
|
|
24
|
+
|
|
25
|
+
For a positive integer `n`, its **prime-power factorization** is the product:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
n = p1^e1 × p2^e2 × p3^e3 × …
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
where `p1 < p2 < p3 < …` are the distinct prime factors of `n` and each `e_k ≥ 1`.
|
|
32
|
+
|
|
33
|
+
`EGPTReal` stores this as a **lossless rational vector in log₂-space**: each prime factor becomes a coordinate so that multiplication is vector addition (the RET Iron Law: `H(a × b) = H(a) + H(b)`). The `toMathString()` method reads back the canonical rational form of the PPF-encoded value.
|
|
34
|
+
|
|
35
|
+
The three examples below cover all structurally distinct cases:
|
|
36
|
+
|
|
37
|
+
| Integer | Structure | Expected PPF |
|
|
38
|
+
|---------|-----------|--------------|
|
|
39
|
+
| **12** | `2² × 3¹` | composite, two distinct primes |
|
|
40
|
+
| **64** | `2⁶` | pure power of 2 |
|
|
41
|
+
| **97** | `97¹` | prime — only one factor, exponent = 1 |
|
|
42
|
+
</cell>
|
|
43
|
+
|
|
44
|
+
<cell type="js" lane="math" id="encode-12" out="r12">
|
|
45
|
+
// EGPTReal.fromBigInt(n) encodes n as a PPF vector.
|
|
46
|
+
// toMathString() returns the canonical rational form of that vector.
|
|
47
|
+
// For integers, this matches the original value — demonstrating lossless encoding.
|
|
48
|
+
const { math, display } = caps;
|
|
49
|
+
const { EGPTReal } = math;
|
|
50
|
+
|
|
51
|
+
const n = 12n;
|
|
52
|
+
const encoded = EGPTReal.fromBigInt(n);
|
|
53
|
+
const ppf = encoded.toMathString();
|
|
54
|
+
display(`EGPTReal.fromBigInt(12n).toMathString() → "${ppf}"`);
|
|
55
|
+
|
|
56
|
+
const r12 = { value: n.toString(), ppf };
|
|
57
|
+
return { r12 };
|
|
58
|
+
</cell>
|
|
59
|
+
|
|
60
|
+
<cell type="markdown">
|
|
61
|
+
## 2. A power of two — the simplest non-trivial case
|
|
62
|
+
|
|
63
|
+
`64 = 2⁶`. There is only one prime involved, so the PPF vector has a single non-zero coordinate (the exponent of 2). This is the degenerate case that binary arithmetic handles natively, but EGPT's PPF encoding handles it identically to any other integer — no special path.
|
|
64
|
+
</cell>
|
|
65
|
+
|
|
66
|
+
<cell type="js" lane="math" id="encode-64" out="r64">
|
|
67
|
+
const { math, display } = caps;
|
|
68
|
+
const { EGPTReal } = math;
|
|
69
|
+
|
|
70
|
+
const n = 64n;
|
|
71
|
+
const encoded = EGPTReal.fromBigInt(n);
|
|
72
|
+
const ppf = encoded.toMathString();
|
|
73
|
+
display(`EGPTReal.fromBigInt(64n).toMathString() → "${ppf}"`);
|
|
74
|
+
|
|
75
|
+
const r64 = { value: n.toString(), ppf };
|
|
76
|
+
return { r64 };
|
|
77
|
+
</cell>
|
|
78
|
+
|
|
79
|
+
<cell type="markdown">
|
|
80
|
+
## 3. A prime — only one atom, exponent exactly 1
|
|
81
|
+
|
|
82
|
+
`97` is prime, so its PPF vector has exactly one non-zero coordinate: exponent `1` at position `97`. This is the structural opposite of a composite: no reduction to smaller primes is possible, and the PPF encodes the integer exactly as-is.
|
|
83
|
+
|
|
84
|
+
Primes are the "atoms" of the PPF representation — the 0-dimensional coordinates with no further decomposition.
|
|
85
|
+
</cell>
|
|
86
|
+
|
|
87
|
+
<cell type="js" lane="math" id="encode-97" out="r97">
|
|
88
|
+
const { math, display } = caps;
|
|
89
|
+
const { EGPTReal } = math;
|
|
90
|
+
|
|
91
|
+
const n = 97n;
|
|
92
|
+
const encoded = EGPTReal.fromBigInt(n);
|
|
93
|
+
const ppf = encoded.toMathString();
|
|
94
|
+
display(`EGPTReal.fromBigInt(97n).toMathString() → "${ppf}"`);
|
|
95
|
+
|
|
96
|
+
const r97 = { value: n.toString(), ppf };
|
|
97
|
+
return { r97 };
|
|
98
|
+
</cell>
|
|
99
|
+
|
|
100
|
+
<cell type="markdown">
|
|
101
|
+
## 4. Summary — canonical PPF normalization
|
|
102
|
+
|
|
103
|
+
All three cases above confirm that `EGPTReal.fromBigInt(n).toMathString()` returns a canonical rational form that represents `n` exactly. The cell below assembles the results from the three encoding cells into a single summary table, matching the original `factorization-basics` demo's output contract.
|
|
104
|
+
</cell>
|
|
105
|
+
|
|
106
|
+
<cell type="js" lane="math" id="summary" in="r12, r64, r97">
|
|
107
|
+
const { display } = caps;
|
|
108
|
+
const checks = [inputs.r12, inputs.r64, inputs.r97];
|
|
109
|
+
|
|
110
|
+
const lines = [
|
|
111
|
+
'category: factorization-basics',
|
|
112
|
+
'note: Shows canonical EGPTReal normalization for representative integers.',
|
|
113
|
+
'',
|
|
114
|
+
'value | ppf (canonical toMathString)',
|
|
115
|
+
'--------|-----------------------------'
|
|
116
|
+
];
|
|
117
|
+
for (const c of checks) {
|
|
118
|
+
lines.push(`${c.value.padEnd(7)} | ${c.ppf}`);
|
|
119
|
+
}
|
|
120
|
+
display(lines.join('\n'));
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
result: {
|
|
124
|
+
category: 'factorization-basics',
|
|
125
|
+
checks,
|
|
126
|
+
note: 'Shows canonical EGPTReal normalization for representative integers.'
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
</cell>
|
|
130
|
+
|
|
131
|
+
</frqtl-notebook>
|