@johnhenry/math 0.0.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 +165 -0
- package/dist/Bivector4.d.ts +52 -0
- package/dist/Bivector4.d.ts.map +1 -0
- package/dist/Bivector4.js +105 -0
- package/dist/Bivector4.js.map +1 -0
- package/dist/CellGraph.d.ts +259 -0
- package/dist/CellGraph.d.ts.map +1 -0
- package/dist/CellGraph.js +637 -0
- package/dist/CellGraph.js.map +1 -0
- package/dist/Clifford4Internal.d.ts +35 -0
- package/dist/Clifford4Internal.d.ts.map +1 -0
- package/dist/Clifford4Internal.js +86 -0
- package/dist/Clifford4Internal.js.map +1 -0
- package/dist/Combinatorics.d.ts +61 -0
- package/dist/Combinatorics.d.ts.map +1 -0
- package/dist/Combinatorics.js +186 -0
- package/dist/Combinatorics.js.map +1 -0
- package/dist/CombinatoricsGenerators.d.ts +44 -0
- package/dist/CombinatoricsGenerators.d.ts.map +1 -0
- package/dist/CombinatoricsGenerators.js +148 -0
- package/dist/CombinatoricsGenerators.js.map +1 -0
- package/dist/ComplexMath.d.ts +46 -0
- package/dist/ComplexMath.d.ts.map +1 -0
- package/dist/ComplexMath.js +98 -0
- package/dist/ComplexMath.js.map +1 -0
- package/dist/ComplexNumber.d.ts +174 -0
- package/dist/ComplexNumber.d.ts.map +1 -0
- package/dist/ComplexNumber.js +443 -0
- package/dist/ComplexNumber.js.map +1 -0
- package/dist/Cycle.d.ts +42 -0
- package/dist/Cycle.d.ts.map +1 -0
- package/dist/Cycle.js +120 -0
- package/dist/Cycle.js.map +1 -0
- package/dist/Decimal.d.ts +45 -0
- package/dist/Decimal.d.ts.map +1 -0
- package/dist/Decimal.js +135 -0
- package/dist/Decimal.js.map +1 -0
- package/dist/Distributions.d.ts +55 -0
- package/dist/Distributions.d.ts.map +1 -0
- package/dist/Distributions.js +222 -0
- package/dist/Distributions.js.map +1 -0
- package/dist/DualNumber.d.ts +42 -0
- package/dist/DualNumber.d.ts.map +1 -0
- package/dist/DualNumber.js +91 -0
- package/dist/DualNumber.js.map +1 -0
- package/dist/Environment.d.ts +44 -0
- package/dist/Environment.d.ts.map +1 -0
- package/dist/Environment.js +129 -0
- package/dist/Environment.js.map +1 -0
- package/dist/Expression.d.ts +19 -0
- package/dist/Expression.d.ts.map +1 -0
- package/dist/Expression.js +43 -0
- package/dist/Expression.js.map +1 -0
- package/dist/FFT.d.ts +21 -0
- package/dist/FFT.d.ts.map +1 -0
- package/dist/FFT.js +136 -0
- package/dist/FFT.js.map +1 -0
- package/dist/GeometricAlgebra4.d.ts +73 -0
- package/dist/GeometricAlgebra4.d.ts.map +1 -0
- package/dist/GeometricAlgebra4.js +115 -0
- package/dist/GeometricAlgebra4.js.map +1 -0
- package/dist/Geometry.d.ts +41 -0
- package/dist/Geometry.d.ts.map +1 -0
- package/dist/Geometry.js +167 -0
- package/dist/Geometry.js.map +1 -0
- package/dist/Graph.d.ts +72 -0
- package/dist/Graph.d.ts.map +1 -0
- package/dist/Graph.js +337 -0
- package/dist/Graph.js.map +1 -0
- package/dist/Graph3DUtils.d.ts +80 -0
- package/dist/Graph3DUtils.d.ts.map +1 -0
- package/dist/Graph3DUtils.js +156 -0
- package/dist/Graph3DUtils.js.map +1 -0
- package/dist/GraphUtils.d.ts +67 -0
- package/dist/GraphUtils.d.ts.map +1 -0
- package/dist/GraphUtils.js +72 -0
- package/dist/GraphUtils.js.map +1 -0
- package/dist/GroupTheory.d.ts +73 -0
- package/dist/GroupTheory.d.ts.map +1 -0
- package/dist/GroupTheory.js +194 -0
- package/dist/GroupTheory.js.map +1 -0
- package/dist/IntUtils.d.ts +33 -0
- package/dist/IntUtils.d.ts.map +1 -0
- package/dist/IntUtils.js +185 -0
- package/dist/IntUtils.js.map +1 -0
- package/dist/Interval.d.ts +44 -0
- package/dist/Interval.d.ts.map +1 -0
- package/dist/Interval.js +165 -0
- package/dist/Interval.js.map +1 -0
- package/dist/Lattice.d.ts +48 -0
- package/dist/Lattice.d.ts.map +1 -0
- package/dist/Lattice.js +65 -0
- package/dist/Lattice.js.map +1 -0
- package/dist/Logic.d.ts +22 -0
- package/dist/Logic.d.ts.map +1 -0
- package/dist/Logic.js +34 -0
- package/dist/Logic.js.map +1 -0
- package/dist/MatrixMath.d.ts +71 -0
- package/dist/MatrixMath.d.ts.map +1 -0
- package/dist/MatrixMath.js +302 -0
- package/dist/MatrixMath.js.map +1 -0
- package/dist/NumberTheory.d.ts +49 -0
- package/dist/NumberTheory.d.ts.map +1 -0
- package/dist/NumberTheory.js +230 -0
- package/dist/NumberTheory.js.map +1 -0
- package/dist/Numerical.d.ts +85 -0
- package/dist/Numerical.d.ts.map +1 -0
- package/dist/Numerical.js +343 -0
- package/dist/Numerical.js.map +1 -0
- package/dist/Permutation.d.ts +43 -0
- package/dist/Permutation.d.ts.map +1 -0
- package/dist/Permutation.js +142 -0
- package/dist/Permutation.js.map +1 -0
- package/dist/Polygon.d.ts +64 -0
- package/dist/Polygon.d.ts.map +1 -0
- package/dist/Polygon.js +221 -0
- package/dist/Polygon.js.map +1 -0
- package/dist/PolynomialRing.d.ts +74 -0
- package/dist/PolynomialRing.d.ts.map +1 -0
- package/dist/PolynomialRing.js +231 -0
- package/dist/PolynomialRing.js.map +1 -0
- package/dist/Quaternion.d.ts +37 -0
- package/dist/Quaternion.d.ts.map +1 -0
- package/dist/Quaternion.js +106 -0
- package/dist/Quaternion.js.map +1 -0
- package/dist/Rational.d.ts +34 -0
- package/dist/Rational.d.ts.map +1 -0
- package/dist/Rational.js +136 -0
- package/dist/Rational.js.map +1 -0
- package/dist/RealMath.d.ts +112 -0
- package/dist/RealMath.d.ts.map +1 -0
- package/dist/RealMath.js +262 -0
- package/dist/RealMath.js.map +1 -0
- package/dist/Rotor4.d.ts +180 -0
- package/dist/Rotor4.d.ts.map +1 -0
- package/dist/Rotor4.js +388 -0
- package/dist/Rotor4.js.map +1 -0
- package/dist/SpecialFunctions.d.ts +32 -0
- package/dist/SpecialFunctions.d.ts.map +1 -0
- package/dist/SpecialFunctions.js +161 -0
- package/dist/SpecialFunctions.js.map +1 -0
- package/dist/SpecialOperator.d.ts +21 -0
- package/dist/SpecialOperator.d.ts.map +1 -0
- package/dist/SpecialOperator.js +26 -0
- package/dist/SpecialOperator.js.map +1 -0
- package/dist/Statistics.d.ts +50 -0
- package/dist/Statistics.d.ts.map +1 -0
- package/dist/Statistics.js +131 -0
- package/dist/Statistics.js.map +1 -0
- package/dist/StringEvaluator.d.ts +48 -0
- package/dist/StringEvaluator.d.ts.map +1 -0
- package/dist/StringEvaluator.js +190 -0
- package/dist/StringEvaluator.js.map +1 -0
- package/dist/Structure.d.ts +130 -0
- package/dist/Structure.d.ts.map +1 -0
- package/dist/Structure.js +394 -0
- package/dist/Structure.js.map +1 -0
- package/dist/Symbolic.d.ts +501 -0
- package/dist/Symbolic.d.ts.map +1 -0
- package/dist/Symbolic.js +4077 -0
- package/dist/Symbolic.js.map +1 -0
- package/dist/Type.d.ts +31 -0
- package/dist/Type.d.ts.map +1 -0
- package/dist/Type.js +47 -0
- package/dist/Type.js.map +1 -0
- package/dist/Utilities.d.ts +27 -0
- package/dist/Utilities.d.ts.map +1 -0
- package/dist/Utilities.js +47 -0
- package/dist/Utilities.js.map +1 -0
- package/dist/Vec4.d.ts +39 -0
- package/dist/Vec4.d.ts.map +1 -0
- package/dist/Vec4.js +82 -0
- package/dist/Vec4.js.map +1 -0
- package/dist/Vector.d.ts +83 -0
- package/dist/Vector.d.ts.map +1 -0
- package/dist/Vector.js +173 -0
- package/dist/Vector.js.map +1 -0
- package/dist/VectorCalculus.d.ts +42 -0
- package/dist/VectorCalculus.d.ts.map +1 -0
- package/dist/VectorCalculus.js +82 -0
- package/dist/VectorCalculus.js.map +1 -0
- package/dist/VectorUtils.d.ts +172 -0
- package/dist/VectorUtils.d.ts.map +1 -0
- package/dist/VectorUtils.js +706 -0
- package/dist/VectorUtils.js.map +1 -0
- package/dist/differentiation-rules.d.ts +21 -0
- package/dist/differentiation-rules.d.ts.map +1 -0
- package/dist/differentiation-rules.js +52 -0
- package/dist/differentiation-rules.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -0
- package/src/Bivector4.ts +136 -0
- package/src/CellGraph.ts +669 -0
- package/src/Clifford4Internal.ts +90 -0
- package/src/Combinatorics.ts +183 -0
- package/src/CombinatoricsGenerators.ts +144 -0
- package/src/ComplexMath.ts +162 -0
- package/src/ComplexNumber.ts +491 -0
- package/src/Cycle.ts +126 -0
- package/src/Decimal.ts +145 -0
- package/src/Distributions.ts +269 -0
- package/src/DualNumber.ts +105 -0
- package/src/Environment.ts +127 -0
- package/src/Expression.ts +48 -0
- package/src/FFT.ts +146 -0
- package/src/GeometricAlgebra4.ts +157 -0
- package/src/Geometry.ts +173 -0
- package/src/Graph.ts +337 -0
- package/src/Graph3DUtils.ts +269 -0
- package/src/GraphUtils.ts +159 -0
- package/src/GroupTheory.ts +214 -0
- package/src/IntUtils.ts +200 -0
- package/src/Interval.ts +171 -0
- package/src/Lattice.ts +87 -0
- package/src/Logic.ts +38 -0
- package/src/MatrixMath.ts +326 -0
- package/src/NumberTheory.ts +228 -0
- package/src/Numerical.ts +390 -0
- package/src/Permutation.ts +148 -0
- package/src/Polygon.ts +229 -0
- package/src/PolynomialRing.ts +242 -0
- package/src/Quaternion.ts +125 -0
- package/src/Rational.ts +148 -0
- package/src/RealMath.ts +346 -0
- package/src/Rotor4.ts +440 -0
- package/src/SpecialFunctions.ts +152 -0
- package/src/SpecialOperator.ts +28 -0
- package/src/Statistics.ts +170 -0
- package/src/StringEvaluator.ts +208 -0
- package/src/Structure.ts +481 -0
- package/src/Symbolic.ts +4313 -0
- package/src/Type.ts +48 -0
- package/src/Utilities.ts +49 -0
- package/src/Vec4.ts +98 -0
- package/src/Vector.ts +189 -0
- package/src/VectorCalculus.ts +87 -0
- package/src/VectorUtils.ts +797 -0
- package/src/differentiation-rules.ts +73 -0
- package/src/index.ts +140 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NumberTheory — fast, big-integer number theory: modular exponentiation and
|
|
3
|
+
* inverse, the Chinese Remainder Theorem, Miller-Rabin primality, Pollard-rho
|
|
4
|
+
* factorisation, GCD/LCM, and the Legendre/Jacobi symbols. Everything is
|
|
5
|
+
* `bigint`-based, so it does not overflow for large inputs.
|
|
6
|
+
*/
|
|
7
|
+
export declare class NumberTheory {
|
|
8
|
+
/** `base^exp mod modulus`, computed by square-and-multiply. */
|
|
9
|
+
static modPow(base: bigint | number, exp: bigint | number, modulus: bigint | number): bigint;
|
|
10
|
+
/** Extended Euclid: returns `{ g, x, y }` with `a·x + b·y = g = gcd(a, b)`. */
|
|
11
|
+
static extendedGcd(a: bigint | number, b: bigint | number): {
|
|
12
|
+
g: bigint;
|
|
13
|
+
x: bigint;
|
|
14
|
+
y: bigint;
|
|
15
|
+
};
|
|
16
|
+
/** Modular inverse of `a` mod `m`, or `null` when `gcd(a, m) ≠ 1`. */
|
|
17
|
+
static modInverse(a: bigint | number, m: bigint | number): bigint | null;
|
|
18
|
+
/** Euclidean remainder, always in `[0, m)` for `m > 0`. Throws for `m === 0`. */
|
|
19
|
+
static mod(a: bigint | number, m: bigint | number): bigint;
|
|
20
|
+
/** `gcd(a, b)` (non-negative, `gcd(0, 0) === 0`). */
|
|
21
|
+
static gcd(a: bigint | number, b: bigint | number): bigint;
|
|
22
|
+
/** `lcm(a, b) = |a·b| / gcd(a, b)`, or `0` if either operand is `0`. */
|
|
23
|
+
static lcm(a: bigint | number, b: bigint | number): bigint;
|
|
24
|
+
/** LCM of a list of values (`1` for an empty list). */
|
|
25
|
+
static lcmList(values: Array<bigint | number>): bigint;
|
|
26
|
+
/**
|
|
27
|
+
* Solve a system of congruences `x ≡ remainders[i] (mod moduli[i])` for
|
|
28
|
+
* pairwise-coprime moduli. Returns `{ x, modulus }` or `null` if inconsistent.
|
|
29
|
+
*/
|
|
30
|
+
static crt(remainders: Array<bigint | number>, moduli: Array<bigint | number>): {
|
|
31
|
+
x: bigint;
|
|
32
|
+
modulus: bigint;
|
|
33
|
+
} | null;
|
|
34
|
+
/** Miller-Rabin primality test (deterministic for n < 3.3·10²⁴). */
|
|
35
|
+
static isProbablePrime(n: bigint | number): boolean;
|
|
36
|
+
/** The next prime strictly greater than `n`. */
|
|
37
|
+
static nextPrime(n: bigint | number): bigint;
|
|
38
|
+
/** A single non-trivial factor of composite `n` via Pollard's rho (Brent). */
|
|
39
|
+
static pollardRho(n: bigint | number): bigint;
|
|
40
|
+
/** Full prime factorisation as sorted `[prime, exponent]` pairs. */
|
|
41
|
+
static factorize(n: bigint | number): Array<[bigint, number]>;
|
|
42
|
+
/** Euler's totient φ(n) via factorisation (big-integer safe). */
|
|
43
|
+
static eulerPhi(n: bigint | number): bigint;
|
|
44
|
+
/** The Legendre symbol `(a/p)` for an odd prime `p` (−1, 0, or 1). */
|
|
45
|
+
static legendreSymbol(a: bigint | number, p: bigint | number): number;
|
|
46
|
+
/** The Jacobi symbol `(a/n)` for odd `n > 0` (−1, 0, or 1). */
|
|
47
|
+
static jacobiSymbol(a: bigint | number, n: bigint | number): number;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=NumberTheory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NumberTheory.d.ts","sourceRoot":"","sources":["../src/NumberTheory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,qBAAa,YAAY;IACvB,+DAA+D;IAC/D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAc5F,+EAA+E;IAC/E,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAgB/F,sEAAsE;IACtE,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;IAOxE,iFAAiF;IACjF,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAM1D,qDAAqD;IACrD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAI1D,wEAAwE;IACxE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAO1D,uDAAuD;IACvD,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM;IAItD;;;OAGG;IACH,MAAM,CAAC,GAAG,CACR,UAAU,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,EAClC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAC7B;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAgBxC,oEAAoE;IACpE,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IA0BnD,gDAAgD;IAChD,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAM5C,8EAA8E;IAC9E,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAqB7C,oEAAoE;IACpE,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IA8B7D,iEAAiE;IACjE,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAM3C,sEAAsE;IACtE,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAMrE,+DAA+D;IAC/D,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;CAgBpE"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NumberTheory — fast, big-integer number theory: modular exponentiation and
|
|
3
|
+
* inverse, the Chinese Remainder Theorem, Miller-Rabin primality, Pollard-rho
|
|
4
|
+
* factorisation, GCD/LCM, and the Legendre/Jacobi symbols. Everything is
|
|
5
|
+
* `bigint`-based, so it does not overflow for large inputs.
|
|
6
|
+
*/
|
|
7
|
+
const big = (x) => (typeof x === "bigint" ? x : BigInt(x));
|
|
8
|
+
const babs = (x) => (x < 0n ? -x : x);
|
|
9
|
+
function bgcd(a, b) {
|
|
10
|
+
let x = babs(a);
|
|
11
|
+
let y = babs(b);
|
|
12
|
+
while (y)
|
|
13
|
+
[x, y] = [y, x % y];
|
|
14
|
+
return x;
|
|
15
|
+
}
|
|
16
|
+
// Deterministic Miller-Rabin witnesses (valid for all n < 3.3·10^24).
|
|
17
|
+
const MR_WITNESSES = [2n, 3n, 5n, 7n, 11n, 13n, 17n, 19n, 23n, 29n, 31n, 37n];
|
|
18
|
+
export class NumberTheory {
|
|
19
|
+
/** `base^exp mod modulus`, computed by square-and-multiply. */
|
|
20
|
+
static modPow(base, exp, modulus) {
|
|
21
|
+
const m = big(modulus);
|
|
22
|
+
if (m === 1n)
|
|
23
|
+
return 0n;
|
|
24
|
+
let b = ((big(base) % m) + m) % m;
|
|
25
|
+
let e = big(exp);
|
|
26
|
+
let result = 1n;
|
|
27
|
+
while (e > 0n) {
|
|
28
|
+
if (e & 1n)
|
|
29
|
+
result = (result * b) % m;
|
|
30
|
+
b = (b * b) % m;
|
|
31
|
+
e >>= 1n;
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
/** Extended Euclid: returns `{ g, x, y }` with `a·x + b·y = g = gcd(a, b)`. */
|
|
36
|
+
static extendedGcd(a, b) {
|
|
37
|
+
let [oldR, r] = [big(a), big(b)];
|
|
38
|
+
let [oldS, s] = [1n, 0n];
|
|
39
|
+
let [oldT, t] = [0n, 1n];
|
|
40
|
+
while (r !== 0n) {
|
|
41
|
+
const q = oldR / r;
|
|
42
|
+
[oldR, r] = [r, oldR - q * r];
|
|
43
|
+
[oldS, s] = [s, oldS - q * s];
|
|
44
|
+
[oldT, t] = [t, oldT - q * t];
|
|
45
|
+
}
|
|
46
|
+
// Negative inputs can leave oldR negative even though a*x + b*y = oldR still
|
|
47
|
+
// holds; flip all three signs so g matches gcd()'s non-negative convention.
|
|
48
|
+
if (oldR < 0n)
|
|
49
|
+
return { g: -oldR, x: -oldS, y: -oldT };
|
|
50
|
+
return { g: oldR, x: oldS, y: oldT };
|
|
51
|
+
}
|
|
52
|
+
/** Modular inverse of `a` mod `m`, or `null` when `gcd(a, m) ≠ 1`. */
|
|
53
|
+
static modInverse(a, m) {
|
|
54
|
+
const mod = big(m);
|
|
55
|
+
const { g, x } = NumberTheory.extendedGcd(((big(a) % mod) + mod) % mod, mod);
|
|
56
|
+
if (g !== 1n)
|
|
57
|
+
return null;
|
|
58
|
+
return ((x % mod) + mod) % mod;
|
|
59
|
+
}
|
|
60
|
+
/** Euclidean remainder, always in `[0, m)` for `m > 0`. Throws for `m === 0`. */
|
|
61
|
+
static mod(a, m) {
|
|
62
|
+
const modulus = big(m);
|
|
63
|
+
if (modulus === 0n)
|
|
64
|
+
throw new RangeError("NumberTheory.mod: modulus must be non-zero");
|
|
65
|
+
return ((big(a) % modulus) + modulus) % modulus;
|
|
66
|
+
}
|
|
67
|
+
/** `gcd(a, b)` (non-negative, `gcd(0, 0) === 0`). */
|
|
68
|
+
static gcd(a, b) {
|
|
69
|
+
return bgcd(big(a), big(b));
|
|
70
|
+
}
|
|
71
|
+
/** `lcm(a, b) = |a·b| / gcd(a, b)`, or `0` if either operand is `0`. */
|
|
72
|
+
static lcm(a, b) {
|
|
73
|
+
const A = big(a);
|
|
74
|
+
const B = big(b);
|
|
75
|
+
if (A === 0n || B === 0n)
|
|
76
|
+
return 0n;
|
|
77
|
+
return babs(A * B) / bgcd(A, B);
|
|
78
|
+
}
|
|
79
|
+
/** LCM of a list of values (`1` for an empty list). */
|
|
80
|
+
static lcmList(values) {
|
|
81
|
+
return values.reduce((acc, v) => NumberTheory.lcm(acc, big(v)), 1n);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Solve a system of congruences `x ≡ remainders[i] (mod moduli[i])` for
|
|
85
|
+
* pairwise-coprime moduli. Returns `{ x, modulus }` or `null` if inconsistent.
|
|
86
|
+
*/
|
|
87
|
+
static crt(remainders, moduli) {
|
|
88
|
+
let x = 0n;
|
|
89
|
+
let mod = 1n;
|
|
90
|
+
for (let i = 0; i < remainders.length; i++) {
|
|
91
|
+
const ri = ((big(remainders[i]) % big(moduli[i])) + big(moduli[i])) % big(moduli[i]);
|
|
92
|
+
const mi = big(moduli[i]);
|
|
93
|
+
const inv = NumberTheory.modInverse(mod, mi);
|
|
94
|
+
if (inv === null)
|
|
95
|
+
return null;
|
|
96
|
+
const diff = ((((ri - x) * inv) % mi) + mi) % mi;
|
|
97
|
+
x += mod * diff;
|
|
98
|
+
mod *= mi;
|
|
99
|
+
x = ((x % mod) + mod) % mod;
|
|
100
|
+
}
|
|
101
|
+
return { x, modulus: mod };
|
|
102
|
+
}
|
|
103
|
+
/** Miller-Rabin primality test (deterministic for n < 3.3·10²⁴). */
|
|
104
|
+
static isProbablePrime(n) {
|
|
105
|
+
const num = big(n);
|
|
106
|
+
if (num < 2n)
|
|
107
|
+
return false;
|
|
108
|
+
for (const p of [2n, 3n, 5n, 7n, 11n, 13n, 17n, 19n, 23n, 29n, 31n, 37n]) {
|
|
109
|
+
if (num === p)
|
|
110
|
+
return true;
|
|
111
|
+
if (num % p === 0n)
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
let d = num - 1n;
|
|
115
|
+
let r = 0n;
|
|
116
|
+
while ((d & 1n) === 0n) {
|
|
117
|
+
d >>= 1n;
|
|
118
|
+
r++;
|
|
119
|
+
}
|
|
120
|
+
witness: for (const a of MR_WITNESSES) {
|
|
121
|
+
if (a >= num)
|
|
122
|
+
continue;
|
|
123
|
+
let x = NumberTheory.modPow(a, d, num);
|
|
124
|
+
if (x === 1n || x === num - 1n)
|
|
125
|
+
continue;
|
|
126
|
+
for (let i = 0n; i < r - 1n; i++) {
|
|
127
|
+
x = (x * x) % num;
|
|
128
|
+
if (x === num - 1n)
|
|
129
|
+
continue witness;
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
/** The next prime strictly greater than `n`. */
|
|
136
|
+
static nextPrime(n) {
|
|
137
|
+
let candidate = big(n) + 1n;
|
|
138
|
+
while (!NumberTheory.isProbablePrime(candidate))
|
|
139
|
+
candidate++;
|
|
140
|
+
return candidate;
|
|
141
|
+
}
|
|
142
|
+
/** A single non-trivial factor of composite `n` via Pollard's rho (Brent). */
|
|
143
|
+
static pollardRho(n) {
|
|
144
|
+
const num = big(n);
|
|
145
|
+
// n <= 1 has no non-trivial factor to find: `f(v) = (v*v+c) % 1n` collapses
|
|
146
|
+
// to 0 for every c, so `d = gcd(0, 1) = 1n` forever and the loop below never
|
|
147
|
+
// terminates. Reject degenerate inputs up front instead of hanging.
|
|
148
|
+
if (num <= 1n)
|
|
149
|
+
throw new RangeError("NumberTheory.pollardRho: n must be greater than 1");
|
|
150
|
+
if (num % 2n === 0n)
|
|
151
|
+
return 2n;
|
|
152
|
+
for (let c = 1n;; c++) {
|
|
153
|
+
let x = 2n;
|
|
154
|
+
let y = 2n;
|
|
155
|
+
let d = 1n;
|
|
156
|
+
const f = (v) => (v * v + c) % num;
|
|
157
|
+
while (d === 1n) {
|
|
158
|
+
x = f(x);
|
|
159
|
+
y = f(f(y));
|
|
160
|
+
d = bgcd(babs(x - y), num);
|
|
161
|
+
}
|
|
162
|
+
if (d !== num)
|
|
163
|
+
return d;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/** Full prime factorisation as sorted `[prime, exponent]` pairs. */
|
|
167
|
+
static factorize(n) {
|
|
168
|
+
let num = babs(big(n));
|
|
169
|
+
// 0 has no well-defined prime factorization (every prime divides it, with
|
|
170
|
+
// no finite exponent) -- unlike 1, whose factorization is the empty
|
|
171
|
+
// product. Without this guard `0n % p === 0n` and `0n / p === 0n` forever,
|
|
172
|
+
// so the trial-division loop below never terminates.
|
|
173
|
+
if (num === 0n)
|
|
174
|
+
throw new RangeError("NumberTheory.factorize: n must be non-zero");
|
|
175
|
+
const counts = new Map();
|
|
176
|
+
const add = (p) => counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
177
|
+
for (const p of [2n, 3n, 5n, 7n, 11n, 13n]) {
|
|
178
|
+
while (num % p === 0n) {
|
|
179
|
+
add(p);
|
|
180
|
+
num /= p;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const stack = num > 1n ? [num] : [];
|
|
184
|
+
while (stack.length) {
|
|
185
|
+
const m = stack.pop();
|
|
186
|
+
if (m === 1n)
|
|
187
|
+
continue;
|
|
188
|
+
if (NumberTheory.isProbablePrime(m)) {
|
|
189
|
+
add(m);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
const factor = NumberTheory.pollardRho(m);
|
|
193
|
+
stack.push(factor, m / factor);
|
|
194
|
+
}
|
|
195
|
+
return [...counts.entries()].sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
|
|
196
|
+
}
|
|
197
|
+
/** Euler's totient φ(n) via factorisation (big-integer safe). */
|
|
198
|
+
static eulerPhi(n) {
|
|
199
|
+
let result = babs(big(n));
|
|
200
|
+
for (const [p] of NumberTheory.factorize(n))
|
|
201
|
+
result = (result / p) * (p - 1n);
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
/** The Legendre symbol `(a/p)` for an odd prime `p` (−1, 0, or 1). */
|
|
205
|
+
static legendreSymbol(a, p) {
|
|
206
|
+
const P = big(p);
|
|
207
|
+
const ls = NumberTheory.modPow(a, (P - 1n) / 2n, P);
|
|
208
|
+
return ls === P - 1n ? -1 : Number(ls);
|
|
209
|
+
}
|
|
210
|
+
/** The Jacobi symbol `(a/n)` for odd `n > 0` (−1, 0, or 1). */
|
|
211
|
+
static jacobiSymbol(a, n) {
|
|
212
|
+
let A = ((big(a) % big(n)) + big(n)) % big(n);
|
|
213
|
+
let N = big(n);
|
|
214
|
+
let result = 1;
|
|
215
|
+
while (A !== 0n) {
|
|
216
|
+
while (A % 2n === 0n) {
|
|
217
|
+
A /= 2n;
|
|
218
|
+
const r = N % 8n;
|
|
219
|
+
if (r === 3n || r === 5n)
|
|
220
|
+
result = -result;
|
|
221
|
+
}
|
|
222
|
+
[A, N] = [N, A];
|
|
223
|
+
if (A % 4n === 3n && N % 4n === 3n)
|
|
224
|
+
result = -result;
|
|
225
|
+
A %= N;
|
|
226
|
+
}
|
|
227
|
+
return N === 1n ? result : 0;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=NumberTheory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NumberTheory.js","sourceRoot":"","sources":["../src/NumberTheory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Numerical — numerical-methods toolkit: root finding (bisection, secant,
|
|
3
|
+
* Newton, Brent), quadrature (composite trapezoid/Simpson, adaptive Simpson,
|
|
4
|
+
* Gauss-Legendre), ODE integration (Euler, RK4 for systems), and nonlinear
|
|
5
|
+
* curve fitting (Levenberg-Marquardt). Complements the simpler
|
|
6
|
+
* `integrateN`/`differentiateN`/`solveN` in {@link RealMath}.
|
|
7
|
+
*/
|
|
8
|
+
type Fn = (x: number) => number;
|
|
9
|
+
/** A first-order ODE system `dy/dt = f(t, y)`. */
|
|
10
|
+
type ODE = (t: number, y: number[]) => number[];
|
|
11
|
+
/** A parametric model `y = model(x, params)`, e.g. `(x, [a, b]) => a * Math.exp(b * x)`. */
|
|
12
|
+
type Model = (x: number, params: number[]) => number;
|
|
13
|
+
export interface ODEStep {
|
|
14
|
+
t: number;
|
|
15
|
+
y: number[];
|
|
16
|
+
}
|
|
17
|
+
export interface LevenbergMarquardtResult {
|
|
18
|
+
params: number[];
|
|
19
|
+
/** sqrt of the sum of squared residuals at `params`. */
|
|
20
|
+
residualNorm: number;
|
|
21
|
+
iterations: number;
|
|
22
|
+
converged: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare class Numerical {
|
|
25
|
+
/** Find a root of `f` in `[a, b]` by bisection (requires a sign change). */
|
|
26
|
+
static bisection(f: Fn, a: number, b: number, tolerance?: number, maxIterations?: number): number;
|
|
27
|
+
/** Find a root of `f` by the secant method from two starting guesses. */
|
|
28
|
+
static secant(f: Fn, x0: number, x1: number, tolerance?: number, maxIterations?: number): number;
|
|
29
|
+
/** Newton's method; if `df` is omitted, a numeric derivative is used. */
|
|
30
|
+
static newton(f: Fn, x0: number, df?: Fn, tolerance?: number, maxIterations?: number): number;
|
|
31
|
+
/** Brent's method: robust bracketing root finder combining bisection and interpolation. */
|
|
32
|
+
static brent(f: Fn, a: number, b: number, tolerance?: number, maxIterations?: number): number;
|
|
33
|
+
/** Composite trapezoidal rule with `n` subintervals. */
|
|
34
|
+
static trapezoid(f: Fn, a: number, b: number, n?: number): number;
|
|
35
|
+
/** Composite Simpson's rule with `n` (rounded up to even) subintervals. */
|
|
36
|
+
static simpson(f: Fn, a: number, b: number, n?: number): number;
|
|
37
|
+
/** Adaptive Simpson quadrature to a target error tolerance. */
|
|
38
|
+
static adaptiveSimpson(f: Fn, a: number, b: number, tolerance?: number, maxDepth?: number): number;
|
|
39
|
+
/** 5-point Gauss-Legendre quadrature on `[a, b]`. */
|
|
40
|
+
static gaussLegendre(f: Fn, a: number, b: number): number;
|
|
41
|
+
/** Explicit Euler integration of a first-order system from `t0` to `t1`. */
|
|
42
|
+
static euler(f: ODE, y0: number[], t0: number, t1: number, h?: number): ODEStep[];
|
|
43
|
+
/** Classical fourth-order Runge-Kutta integration of a first-order system. */
|
|
44
|
+
static rk4(f: ODE, y0: number[], t0: number, t1: number, h?: number): ODEStep[];
|
|
45
|
+
/**
|
|
46
|
+
* Nonlinear least-squares curve fitting via Levenberg-Marquardt: finds
|
|
47
|
+
* `params` minimizing `sum((model(xs[i], params) - ys[i])^2)`, starting
|
|
48
|
+
* from `params0`. The Jacobian of `model` with respect to `params` is
|
|
49
|
+
* estimated by central finite differences (generalizes `newton`'s
|
|
50
|
+
* optional-df-else-numeric-derivative convention to a vector of
|
|
51
|
+
* parameters). `lambda` is the Marquardt damping factor -- scaled against
|
|
52
|
+
* each parameter's own row of `JᵀJ` (not a plain identity, the original
|
|
53
|
+
* Levenberg damping) so differently-scaled parameters damp comparably --
|
|
54
|
+
* grown 10x on a rejected step (safer, more like gradient descent) and
|
|
55
|
+
* shrunk 10x on an accepted one (faster, more like Gauss-Newton near the
|
|
56
|
+
* optimum).
|
|
57
|
+
*
|
|
58
|
+
* `converged` is true once *either* the sum of squared residuals itself
|
|
59
|
+
* drops below `tolerance` (a near-exact fit) *or* at least one step has
|
|
60
|
+
* improved it and further steps stop improving it meaningfully (no
|
|
61
|
+
* damped step improves it at all, or the relative improvement has
|
|
62
|
+
* dropped below 1e-12) -- deliberately not "the residual itself is near
|
|
63
|
+
* zero" as the only success criterion, since real (noisy) data's true
|
|
64
|
+
* best fit essentially never drives the residual anywhere near
|
|
65
|
+
* `tolerance`, even when the fit has genuinely converged to the best
|
|
66
|
+
* achievable parameters; requiring near-zero residual would wrongly
|
|
67
|
+
* report `converged: false` for every realistic (as opposed to
|
|
68
|
+
* synthetic/noiseless) dataset.
|
|
69
|
+
*
|
|
70
|
+
* NON-GOALS: no bounds/constraints on `params`; only ever finds one local
|
|
71
|
+
* minimum near `params0`, the same "no guarantee of the global optimum"
|
|
72
|
+
* caveat as `newton`. Returns `converged: false` (with the best `params`
|
|
73
|
+
* found, not a throw) when no step ever improved on `params0` at all --
|
|
74
|
+
* a model/data pairing that can't be fit usefully isn't a numerical error
|
|
75
|
+
* the way a divergent root-find is, but is still worth flagging distinctly
|
|
76
|
+
* from "converged to some local optimum, however good or mediocre."
|
|
77
|
+
*/
|
|
78
|
+
static levenbergMarquardt(model: Model, params0: number[], xs: number[], ys: number[], options?: {
|
|
79
|
+
lambda0?: number;
|
|
80
|
+
tolerance?: number;
|
|
81
|
+
maxIterations?: number;
|
|
82
|
+
}): LevenbergMarquardtResult;
|
|
83
|
+
}
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=Numerical.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Numerical.d.ts","sourceRoot":"","sources":["../src/Numerical.ts"],"names":[],"mappings":"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"}
|