|
# U — Canonical Chain Unified
Every case is an instance of the same commuting diagram:
> input ─encode─► EGPTReal[] ─engine─► EGPTReal[] ─decode─► output
The "engine" column names which `EGPTPolynomial` primitive does the work. The same handful of primitives — `forwardTransform`/`inverseTransform`, `multiply`/`add`, `divide` (→ GCD), `evaluateAt` — power number theory, linear algebra, and signal processing alike:
- **U1** `forwardTransform` ≡ pointwise `evaluateAt` at k/N (T1 / F1)
- **U2** `inverseTransform(forwardTransform(c)) = c` (M2 / F2)
- **U3** `multiply` + dense `matMul` on polynomial systems (T2 / K1–K6)
- **U4** iterated `divide` = polynomial GCD (T3 / M6 shared factor)
- **U5** `evaluateAt` on the atom-root polynomial = factor detection (N1 / N2)
- **U6** orbit polynomial + `evaluateAt` = order finding ≡ period (N3 / N4)
- **U7** one example (N=15), all three lenses at once
*(Ported from `theorems/U_CanonicalChainUnified.js`. `EGPTReal/EGPTMath/EGPTPolynomial/PrimeAtomPolynomial/OrderFinder/matMul` come from `caps.math` — no imports. Render + atom/orbit helpers inlined.)*
|
## Setup — inline helpers
`renderVec`/`matricesEqual` and the atom-root / orbit polynomial builders are inlined (they call only `caps.math` primitives). Exposed as a binding for the engine cells.
|
const { math } = caps;
const { EGPTReal, EGPTPolynomial, PrimeAtomPolynomial } = math;
const ZERO = EGPTReal.fromBigInt(0n);
const ONE = EGPTReal.fromBigInt(1n);
const intN = (n) => EGPTReal.fromBigInt(BigInt(n));
const frac = (n, d) => EGPTReal.fromRational(BigInt(n), BigInt(d));
const isZero = (e) => e.equals(ZERO);
function renderValue(v) {
if (v == null) return String(v);
if (typeof v._getPPFRationalParts === 'function') {
const { numerator, denominator } = v._getPPFRationalParts();
if (denominator === 1n || denominator === -1n) return String(denominator < 0n ? -numerator : numerator);
return `${numerator}/${denominator}`;
}
return String(v);
}
function showVec(v) { return '[ ' + v.map(renderValue).join(', ') + ' ]'; }
function matricesEqual(X, Y) {
if (X.length !== Y.length) return false;
for (let i = 0; i < X.length; i++) {
if (X[i].length !== Y[i].length) return false;
for (let j = 0; j < X[i].length; j++) if (!X[i][j].equals(Y[i][j])) return false;
}
return true;
}
function polyGCDMonic(a, b) {
let A = a.slice(), B = b.slice();
while (!B.every(isZero)) { const { remainder } = EGPTPolynomial.divide(A, B); A = B; B = EGPTPolynomial.trimZeros(remainder); }
A = EGPTPolynomial.trimZeros(A);
const lead = A[A.length - 1];
if (isZero(lead)) return A;
return EGPTPolynomial.divide(A, [lead]).quotient;
}
function buildAtomRootPolynomial(N) {
const factors = PrimeAtomPolynomial.factorize(N);
let poly = [ONE];
for (const { prime, exponent } of factors) { const linear = [intN(-prime), ONE]; for (let k = 0n; k < exponent; k++) poly = EGPTPolynomial.multiply(poly, linear); }
return poly;
}
function buildOrbitPolynomial(a, N) {
const aBi = BigInt(a), NBi = BigInt(N);
let poly = [ONE], current = 1n; const seen = new Set([1n]);
while (true) { current = (current * aBi) % NBi; if (current === 1n) break; if (seen.has(current)) break; seen.add(current); poly = EGPTPolynomial.multiply(poly, [intN(-Number(current)), ONE]); }
return EGPTPolynomial.multiply(poly, [intN(-1), ONE]);
}
return { uhelp: { renderValue, showVec, matricesEqual, polyGCDMonic, buildAtomRootPolynomial, buildOrbitPolynomial, intN, frac } };
|
## U1 / U2 — forwardTransform ≡ evaluateAt, and the inverse round-trip
`forwardTransform(c, N)` is per-point `evaluateAt(c, k/N)`; `inverseTransform` recovers `c` exactly.
|
const { math, display } = caps;
const { EGPTPolynomial, EGPTReal } = math;
const { showVec, intN, frac } = inputs.uhelp;
const ONE = EGPTReal.fromBigInt(1n);
function check(label, cond) { display((cond ? ' ✓ ' : ' ✗ ') + label); if (!cond) throw new Error('U1/U2 FAILED: ' + label); }
function veq(u, v) { if (u.length !== v.length) return false; for (let i = 0; i < u.length; i++) if (!u[i].equals(v[i])) return false; return true; }
// U1
const coeffs = [frac(1, 3), frac(-7, 6), ONE];
const N = 8;
const samples = EGPTPolynomial.forwardTransform(coeffs, N);
display('U1 forwardTransform(c,8) = ' + showVec(samples));
const manual = []; for (let k = 0; k < N; k++) manual.push(EGPTPolynomial.evaluateAt(coeffs, EGPTReal.fromRational(BigInt(k), BigInt(N))));
check('forwardTransform ≡ per-point evaluateAt at k/N (T1 / F1)', veq(manual, samples));
// U2
const c2 = [frac(1, 3), frac(-7, 6), ONE];
const s2 = EGPTPolynomial.forwardTransform(c2, c2.length);
const rec = EGPTPolynomial.inverseTransform(s2, c2.length);
display('U2 inverseTransform(forward(c)) = ' + showVec(rec));
check('inverseTransform(forwardTransform(c)) = c (bit-exact round trip)', veq(rec, c2));
|
## U3 — multiply + dense matMul on polynomial systems
Convolution (T2) is one `multiply` call; a dense 2×2 `matMul` (K1) treats rows as polynomials and accumulates via `multiply` + `add`, matching the explicit dot-product reference.
|
const { math, display } = caps;
const { EGPTPolynomial, EGPTMath, matMul } = math;
const { showVec, matricesEqual, intN } = inputs.uhelp;
function check(label, cond) { display((cond ? ' ✓ ' : ' ✗ ') + label); if (!cond) throw new Error('U3 FAILED: ' + label); }
const a = [intN(1), intN(2)], b = [intN(3), intN(4)];
const ab = EGPTPolynomial.multiply(a, b);
display('T2 multiply([1,2],[3,4]) = ' + showVec(ab));
check('T2 convolution ≡ one multiply call', ab.length === 3 && ab[0].equals(intN(3)) && ab[1].equals(intN(10)) && ab[2].equals(intN(8)));
const A = [[intN(1), intN(2)], [intN(3), intN(4)]];
const B = [[intN(5), intN(6)], [intN(7), intN(8)]];
const C = matMul(A, B);
const Cref = [
[EGPTMath.add(EGPTMath.multiply(A[0][0], B[0][0]), EGPTMath.multiply(A[0][1], B[1][0])),
EGPTMath.add(EGPTMath.multiply(A[0][0], B[0][1]), EGPTMath.multiply(A[0][1], B[1][1]))],
[EGPTMath.add(EGPTMath.multiply(A[1][0], B[0][0]), EGPTMath.multiply(A[1][1], B[1][0])),
EGPTMath.add(EGPTMath.multiply(A[1][0], B[0][1]), EGPTMath.multiply(A[1][1], B[1][1]))]
];
display('K1 dense matMul rows-are-polynomials C = [[' + showVec(C[0]) + ',' + showVec(C[1]) + ']]');
check('K1 dense matMul via polynomial-system form matches reference', matricesEqual(C, Cref));
|
## U4 — iterated divide = polynomial GCD (shared factor)
Two polynomials f1, f2 both vanishing at 1/2; the Euclidean walk (iterated `divide`) recovers the monic gcd `x − 1/2` — the T3 resultant / M6 shared-factor view.
|
const { math, display } = caps;
const { EGPTPolynomial, EGPTReal } = math;
const { showVec, polyGCDMonic, frac } = inputs.uhelp;
const ZERO = EGPTReal.fromBigInt(0n);
const ONE = EGPTReal.fromBigInt(1n);
function check(label, cond) { display((cond ? ' ✓ ' : ' ✗ ') + label); if (!cond) throw new Error('U4 FAILED: ' + label); }
const f1 = [frac(1, 3), frac(-7, 6), ONE];
const f2 = [frac(1, 6), frac(-5, 6), ONE];
const g = polyGCDMonic(f1, f2);
display('U4 monic gcd(f1,f2) = ' + showVec(g) + ' (expected x − 1/2)');
check('gcd agrees with T3 resultant — exactly x − 1/2', g.length === 2 && g[0].equals(frac(-1, 2)) && g[1].equals(ONE));
check('gcd vanishes at the shared root 1/2', EGPTPolynomial.evaluateAt(g, frac(1, 2)).equals(ZERO));
|
## U5 / U6 / U7 — factor detection, order finding, all-lenses example
U5: roots of the atom-root polynomial of N=60 are exactly its prime factors. U6: the orbit polynomial of (3 mod 8) has degree = order. U7: N=15 — factoring, order finding, and A·I=A all run on the one engine.
|
const { math, display } = caps;
const { EGPTPolynomial, EGPTReal, PrimeAtomPolynomial, OrderFinder, matMul } = math;
const { showVec, matricesEqual, buildAtomRootPolynomial, buildOrbitPolynomial, intN } = inputs.uhelp;
const ZERO = EGPTReal.fromBigInt(0n);
function check(label, cond) { display((cond ? ' ✓ ' : ' ✗ ') + label); if (!cond) throw new Error('U5/6/7 FAILED: ' + label); }
// U5 — N=60
const N5 = 60n;
const P5 = buildAtomRootPolynomial(N5);
display('U5 P_60 = ' + showVec(P5));
for (const { prime } of PrimeAtomPolynomial.factorize(N5)) check(`P_60(${prime}) = 0 (N1/N2 coincide)`, EGPTPolynomial.evaluateAt(P5, intN(prime)).equals(ZERO));
check('P_60(7) ≠ 0 (7 is not a factor of 60)', !EGPTPolynomial.evaluateAt(P5, intN(7)).equals(ZERO));
// U6 — (3 mod 8)
const Q = buildOrbitPolynomial(3n, 8n);
const r = Number(OrderFinder.findOrder(3n, 8n));
display(`U6 orbit polynomial Q = ${showVec(Q)} order(3 mod 8) = ${r}`);
check(`deg(Q) = order(3 mod 8) = ${r} (N3 ≡ N4)`, EGPTPolynomial.degree(Q) === r);
// U7 — N=15, all lenses
const atomP = buildAtomRootPolynomial(15n);
const orbitP = buildOrbitPolynomial(7n, 15n);
const order = Number(OrderFinder.findOrder(7n, 15n));
const A = [[intN(1), intN(2)], [intN(3), intN(4)]];
const I = [[intN(1), intN(0)], [intN(0), intN(1)]];
const AI = matMul(A, I);
check('U7 N1/N2: prime 3 is a root of P_15', EGPTPolynomial.evaluateAt(atomP, intN(3)).equals(ZERO));
check('U7 N1/N2: prime 5 is a root of P_15', EGPTPolynomial.evaluateAt(atomP, intN(5)).equals(ZERO));
check('U7 N3/N4: orbit polynomial degree equals order(7 mod 15)', EGPTPolynomial.degree(orbitP) === order);
check('U7 T/K: A · I = A (one EGPTPolynomial.multiply)', matricesEqual(AI, A));
|
const { display } = caps;
display('QED — one engine (EGPTPolynomial primitives), three lenses (number theory, linear algebra, signal processing).');
|