nerdamer 2.0.0-rc.1 → 2.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.
Files changed (236) hide show
  1. package/BREAKING_CHANGES.md +244 -0
  2. package/README.md +168 -229
  3. package/dist/bundle.js +1 -1
  4. package/dist/bundle.js.LICENSE.txt +6 -6
  5. package/output/algebra/adapters.d.ts +3 -33
  6. package/output/algebra/adapters.js +7 -105
  7. package/output/algebra/algorithms/arith.js +10 -9
  8. package/output/algebra/algorithms/groebnerBase.d.ts +24 -20
  9. package/output/algebra/algorithms/groebnerBase.js +486 -723
  10. package/output/algebra/dispatch.d.ts +1 -0
  11. package/output/algebra/dispatch.js +25 -0
  12. package/output/algebra/factor/factor.d.ts +15 -0
  13. package/output/algebra/factor/factor.js +99 -12
  14. package/output/algebra/gcd/gcd.d.ts +8 -7
  15. package/output/algebra/gcd/gcd.js +32 -78
  16. package/output/algebra/groebner.d.ts +2 -2
  17. package/output/algebra/groebner.js +6 -12
  18. package/output/algebra/partfrac.d.ts +3 -3
  19. package/output/algebra/partfrac.js +28 -61
  20. package/output/algebra/polynomial/ModularSparsePolynomial.d.ts +131 -0
  21. package/output/algebra/polynomial/ModularSparsePolynomial.js +378 -0
  22. package/output/algebra/polynomial/ModularSparsePolynomialFactor.d.ts +40 -0
  23. package/output/algebra/polynomial/ModularSparsePolynomialFactor.js +661 -0
  24. package/output/algebra/polynomial/SparsePolynomialFactor.d.ts +64 -0
  25. package/output/algebra/polynomial/SparsePolynomialFactor.js +492 -0
  26. package/output/algebra/polynomial/SparsePolynomialGcd.d.ts +29 -0
  27. package/output/algebra/polynomial/SparsePolynomialGcd.js +259 -0
  28. package/output/algebra/polynomial/SparsePolynomialMultivariateFactor.d.ts +82 -0
  29. package/output/algebra/polynomial/SparsePolynomialMultivariateFactor.js +604 -0
  30. package/output/algebra/polynomial/modularGcd.d.ts +40 -0
  31. package/output/algebra/polynomial/modularGcd.js +365 -0
  32. package/output/algebra/polynomialize.js +4 -2
  33. package/output/algebra/simplify/funcsimp.js +1 -1
  34. package/output/algebra/simplify/ratsimp.js +1 -1
  35. package/output/algebra/simplify/simplify.js +11 -2
  36. package/output/algebra/utils.d.ts +1 -1
  37. package/output/algebra/utils.js +3 -3
  38. package/output/api/advanced.d.ts +2 -1
  39. package/output/api/advanced.js +3 -3
  40. package/output/api/algebra.d.ts +21 -4
  41. package/output/api/algebra.js +22 -3
  42. package/output/api/assumptions.d.ts +1 -1
  43. package/output/api/assumptions.js +2 -1
  44. package/output/api/calculus.d.ts +2 -1
  45. package/output/api/calculus.js +2 -1
  46. package/output/api/core.d.ts +28 -7
  47. package/output/api/core.js +28 -2
  48. package/output/api/languages/deu.d.ts +3 -0
  49. package/output/api/languages/deu.js +266 -0
  50. package/output/api/languages/fra.d.ts +3 -0
  51. package/output/api/languages/fra.js +266 -0
  52. package/output/api/languages/ita.d.ts +3 -0
  53. package/output/api/languages/ita.js +266 -0
  54. package/output/api/languages/nld.d.ts +3 -0
  55. package/output/api/languages/nld.js +266 -0
  56. package/output/api/languages/por.d.ts +3 -0
  57. package/output/api/languages/por.js +266 -0
  58. package/output/api/languages/spa.d.ts +3 -0
  59. package/output/api/languages/spa.js +266 -0
  60. package/output/api/parser.d.ts +10 -2
  61. package/output/api/parser.js +2 -0
  62. package/output/api/solve.d.ts +1 -1
  63. package/output/api/solve.js +2 -1
  64. package/output/api/structures.d.ts +1 -1
  65. package/output/api/structures.js +2 -1
  66. package/output/calculus/adapters.d.ts +8 -0
  67. package/output/calculus/adapters.js +41 -0
  68. package/output/calculus/derivative/diff.js +6 -3
  69. package/output/calculus/dispatch.d.ts +1 -0
  70. package/output/calculus/dispatch.js +25 -0
  71. package/output/calculus/integrate/integrate.js +4 -4
  72. package/output/calculus/integrate/integrationTable.js +16 -16
  73. package/output/calculus/laplace/ilaplace.js +1 -1
  74. package/output/calculus/laplace/ilaplaceTable.js +18 -17
  75. package/output/calculus/laplace/laplaceTable.js +3 -2
  76. package/output/calculus/limit/limit.js +1 -1
  77. package/output/core/classes/assumption/Assumption.js +14 -10
  78. package/output/core/classes/assumption/assume.d.ts +6 -0
  79. package/output/core/classes/assumption/assume.js +9 -0
  80. package/output/core/classes/assumption/dispatch.d.ts +1 -0
  81. package/output/core/classes/assumption/dispatch.js +11 -0
  82. package/output/core/classes/collection/Collection.js +11 -2
  83. package/output/core/classes/complex/Complex.d.ts +10 -0
  84. package/output/core/classes/complex/Complex.js +19 -1
  85. package/output/core/classes/decimalSet/DecimalSet.js +5 -4
  86. package/output/core/classes/dictionary/Dictionary.js +4 -1
  87. package/output/core/classes/expression/CoeffObject.d.ts +1 -1
  88. package/output/core/classes/expression/CoeffObject.js +1 -2
  89. package/output/core/classes/expression/Expression.d.ts +35 -26
  90. package/output/core/classes/expression/Expression.js +77 -50
  91. package/output/core/classes/expression/analysis.d.ts +1 -1
  92. package/output/core/classes/expression/analysis.js +7 -7
  93. package/output/core/classes/expression/format.d.ts +9 -0
  94. package/output/core/classes/expression/format.js +130 -7
  95. package/output/core/classes/expression/utils.d.ts +9 -0
  96. package/output/core/classes/expression/utils.js +52 -6
  97. package/output/core/classes/matrix/Matrix.d.ts +2 -3
  98. package/output/core/classes/matrix/Matrix.js +26 -23
  99. package/output/core/classes/matrix/dispatch.d.ts +1 -0
  100. package/output/core/classes/matrix/dispatch.js +19 -0
  101. package/output/core/classes/matrix/functions.d.ts +2 -0
  102. package/output/core/classes/matrix/functions.js +5 -0
  103. package/output/core/classes/parser/Parser.d.ts +31 -5
  104. package/output/core/classes/parser/Parser.js +357 -444
  105. package/output/core/classes/parser/constants.d.ts +2 -0
  106. package/output/core/classes/parser/constants.js +4 -2
  107. package/output/core/classes/parser/controlFlowSignals.d.ts +38 -0
  108. package/output/core/classes/parser/controlFlowSignals.js +60 -0
  109. package/output/core/classes/parser/operations/add.js +14 -16
  110. package/output/core/classes/parser/operations/compare.js +13 -0
  111. package/output/core/classes/parser/operations/functions.d.ts +3 -4
  112. package/output/core/classes/parser/operations/functions.js +48 -102
  113. package/output/core/classes/parser/operations/multiply.js +22 -15
  114. package/output/core/classes/parser/operations/power.js +11 -11
  115. package/output/core/classes/parser/operations/subtract.js +2 -1
  116. package/output/core/classes/parser/preprocess.d.ts +0 -7
  117. package/output/core/classes/parser/preprocess.js +33 -39
  118. package/output/core/classes/parser/scripting/controlFlow.d.ts +4 -102
  119. package/output/core/classes/parser/scripting/controlFlow.js +134 -186
  120. package/output/core/classes/parser/scripting/deferred.d.ts +4 -0
  121. package/output/core/classes/parser/scripting/deferred.js +65 -0
  122. package/output/core/classes/parser/scripting/dispatch.d.ts +1 -0
  123. package/output/core/classes/parser/scripting/dispatch.js +62 -0
  124. package/output/core/classes/parser/scripting/evaluate.d.ts +13 -0
  125. package/output/core/classes/parser/scripting/evaluate.js +17 -1
  126. package/output/core/classes/parser/scripting/scope.d.ts +1 -28
  127. package/output/core/classes/parser/scripting/scope.js +36 -40
  128. package/output/core/classes/parser/types.d.ts +5 -5
  129. package/output/core/classes/parser/wrappers/IndexedReference.d.ts +4 -3
  130. package/output/core/classes/parser/wrappers/IndexedReference.js +8 -0
  131. package/output/core/classes/parser/wrappers/KeyValuePair.d.ts +2 -2
  132. package/output/core/classes/polynomial/Polynomial.d.ts +5 -1
  133. package/output/core/classes/polynomial/Polynomial.js +53 -7
  134. package/output/core/classes/polynomial/SparsePolynomial.d.ts +221 -0
  135. package/output/core/classes/polynomial/SparsePolynomial.js +824 -0
  136. package/output/core/classes/polynomial/SparsePolynomialAdapter.d.ts +56 -0
  137. package/output/core/classes/polynomial/SparsePolynomialAdapter.js +241 -0
  138. package/output/core/classes/polynomial/Term.js +2 -2
  139. package/output/core/{adapters.d.ts → classes/polynomial/adapters.d.ts} +2 -2
  140. package/output/core/classes/polynomial/adapters.js +33 -0
  141. package/output/core/classes/polynomial/dispatch.d.ts +1 -0
  142. package/output/core/classes/polynomial/dispatch.js +14 -0
  143. package/output/core/classes/polynomial/functions.d.ts +8 -0
  144. package/output/core/classes/polynomial/functions.js +71 -8
  145. package/output/core/classes/polynomial/utils.js +2 -1
  146. package/output/core/classes/rational/Rational.d.ts +8 -11
  147. package/output/core/classes/rational/Rational.js +70 -20
  148. package/output/core/classes/seq/SEQ.js +4 -4
  149. package/output/core/classes/valuesSet/ValuesSet.d.ts +9 -1
  150. package/output/core/classes/valuesSet/ValuesSet.js +22 -4
  151. package/output/core/classes/vector/Vector.d.ts +2 -3
  152. package/output/core/classes/vector/Vector.js +11 -15
  153. package/output/core/classes/vector/dispatch.d.ts +1 -0
  154. package/output/core/classes/vector/dispatch.js +11 -0
  155. package/output/core/common/classes/MathematicalAggregate.js +11 -2
  156. package/output/core/common/classes/StructuredEntity.d.ts +0 -17
  157. package/output/core/common/classes/StructuredEntity.js +3 -64
  158. package/output/core/common/common.d.ts +0 -1
  159. package/output/core/common/common.js +29 -234
  160. package/output/core/converters/BaseConverter.js +3 -2
  161. package/output/core/converters/Converter.js +9 -5
  162. package/output/core/converters/Pattern.js +1 -1
  163. package/output/core/dispatch.d.ts +18 -0
  164. package/output/core/dispatch.js +3 -281
  165. package/output/core/errors.d.ts +259 -474
  166. package/output/core/errors.js +270 -542
  167. package/output/core/fullFunctions.d.ts +7 -0
  168. package/output/core/fullFunctions.js +31 -0
  169. package/output/core/functions/bigint/bigint.d.ts +13 -1
  170. package/output/core/functions/bigint/bigint.js +56 -4
  171. package/output/core/functions/bigint/primeFactor.d.ts +2 -0
  172. package/output/core/functions/bigint/primeFactor.js +13 -13
  173. package/output/core/functions/build/definitions.js +6 -0
  174. package/output/core/functions/complex.d.ts +2 -2
  175. package/output/core/functions/complex.dispatch.d.ts +1 -0
  176. package/output/core/functions/complex.dispatch.js +16 -0
  177. package/output/core/functions/complex.js +7 -7
  178. package/output/core/functions/decimal.js +2 -1
  179. package/output/core/functions/expand/expand.js +2 -2
  180. package/output/core/functions/numeric.d.ts +1 -1
  181. package/output/core/functions/string.js +2 -1
  182. package/output/core/functions/subst.js +21 -13
  183. package/output/core/parserFunctions.d.ts +7 -0
  184. package/output/core/parserFunctions.js +25 -0
  185. package/output/index.d.ts +50 -30
  186. package/output/index.js +147 -19
  187. package/output/math/defint/defint.d.ts +18 -0
  188. package/output/math/defint/defint.js +60 -0
  189. package/output/math/defint/defintDecimal.js +6 -5
  190. package/output/math/defint/defintNative.js +7 -18
  191. package/output/math/dispatch.d.ts +1 -0
  192. package/output/math/dispatch.js +101 -0
  193. package/output/math/geometry.d.ts +4 -0
  194. package/output/math/geometry.js +23 -0
  195. package/output/math/math.d.ts +59 -19
  196. package/output/math/math.js +244 -100
  197. package/output/math/trig.js +4 -4
  198. package/output/math/utils.d.ts +6 -0
  199. package/output/math/utils.js +39 -0
  200. package/output/solve/classes/PolynomialSolver.d.ts +33 -14
  201. package/output/solve/classes/PolynomialSolver.js +267 -67
  202. package/output/solve/classes/SolutionSet.d.ts +20 -1
  203. package/output/solve/classes/SolutionSet.js +82 -5
  204. package/output/solve/dispatch.d.ts +1 -0
  205. package/output/solve/dispatch.js +13 -0
  206. package/output/solve/linsolve.d.ts +2 -0
  207. package/output/solve/linsolve.js +13 -5
  208. package/output/solve/solve.d.ts +10 -0
  209. package/output/solve/solve.js +128 -20
  210. package/output/solve/solveSystem.d.ts +1 -1
  211. package/output/solve/solveSystem.js +8 -32
  212. package/output/solve/utils.d.ts +2 -1
  213. package/output/solve/utils.js +18 -22
  214. package/output/utils/array.d.ts +1 -1
  215. package/output/utils/debug.js +2 -1
  216. package/package.json +22 -38
  217. package/dist/parser.js +0 -2
  218. package/dist/parser.js.LICENSE.txt +0 -7
  219. package/docs-data/parser-functions.json +0 -1960
  220. package/output/algebra/algorithms/factor.d.ts +0 -3
  221. package/output/algebra/algorithms/factor.js +0 -5
  222. package/output/algebra/algorithms/factorMultivariate.d.ts +0 -23
  223. package/output/algebra/algorithms/factorMultivariate.js +0 -2393
  224. package/output/algebra/algorithms/factorUnivariate.d.ts +0 -72
  225. package/output/algebra/algorithms/factorUnivariate.js +0 -1072
  226. package/output/algebra/algorithms/gcd.d.ts +0 -22
  227. package/output/algebra/algorithms/gcd.js +0 -690
  228. package/output/algebra/algorithms/multiPoly/MultiPoly.d.ts +0 -137
  229. package/output/algebra/algorithms/multiPoly/MultiPoly.js +0 -346
  230. package/output/algebra/algorithms/poly.d.ts +0 -228
  231. package/output/algebra/algorithms/poly.js +0 -1299
  232. package/output/algebra/algorithms/rational.d.ts +0 -17
  233. package/output/algebra/algorithms/rational.js +0 -115
  234. package/output/core/adapters.js +0 -40
  235. package/output/core/classes/parser/operations/comma.d.ts +0 -7
  236. package/output/core/classes/parser/operations/comma.js +0 -11
@@ -0,0 +1,131 @@
1
+ /**
2
+ * @module modularSparsePolynomial
3
+ *
4
+ * Sparse polynomial arithmetic over integer residue classes.
5
+ *
6
+ * External references consulted for modular coefficient arithmetic and sparse
7
+ * polynomial division:
8
+ * - SymPy finite-field polynomial arithmetic:
9
+ * https://github.com/sympy/sympy/blob/120ee85f346f6292b763cc195afda4f907260d4a/sympy/polys/galoistools.py
10
+ * - SymPy sparse polynomial substitution, evaluation, and term division:
11
+ * https://github.com/sympy/sympy/blob/120ee85f346f6292b763cc195afda4f907260d4a/sympy/polys/sparsetools.py
12
+ * - SymPy variable-relative leading coefficient operations used by modular GCD:
13
+ * https://github.com/sympy/sympy/blob/120ee85f346f6292b763cc195afda4f907260d4a/sympy/polys/zippel.py
14
+ */
15
+ import { SparsePolynomial, type MonomialOrder, type SparsePolynomialTerm } from '../../core/classes/polynomial/SparsePolynomial';
16
+ /**
17
+ * Sparse polynomial whose coefficients are stored as canonical residues modulo
18
+ * a positive integer greater than one.
19
+ *
20
+ * The modulus is part of the polynomial ring. Prime moduli provide finite-field
21
+ * arithmetic; composite moduli remain valid for addition and multiplication but
22
+ * may not provide multiplicative inverses required by monic normalization or
23
+ * polynomial division.
24
+ */
25
+ export declare class ModularSparsePolynomial {
26
+ private readonly polynomial;
27
+ readonly modulus: bigint;
28
+ readonly variableCount: number;
29
+ constructor(variableCount: number, modulus: bigint, terms?: Iterable<SparsePolynomialTerm> | SparsePolynomial);
30
+ /** Creates a constant polynomial in the selected residue ring. */
31
+ static constant(variableCount: number, modulus: bigint, coefficient: bigint): ModularSparsePolynomial;
32
+ /**
33
+ * Reconstructs a polynomial in one variable from specialized images.
34
+ *
35
+ * Each sample polynomial must be independent of the interpolated variable.
36
+ * Evaluation values are compared as residues in the shared coefficient ring.
37
+ */
38
+ static interpolateVariable(variableIndex: number, samples: ReadonlyArray<Readonly<{
39
+ value: bigint;
40
+ polynomial: ModularSparsePolynomial;
41
+ }>>): ModularSparsePolynomial;
42
+ /** Creates a one-term polynomial in the selected residue ring. */
43
+ static monomial(variableCount: number, modulus: bigint, coefficient: bigint, exponents: readonly bigint[]): ModularSparsePolynomial;
44
+ /** Creates one polynomial variable with coefficient one. */
45
+ static variable(variableCount: number, modulus: bigint, variableIndex: number): ModularSparsePolynomial;
46
+ /** Creates the zero polynomial in the selected residue ring. */
47
+ static zero(variableCount: number, modulus: bigint): ModularSparsePolynomial;
48
+ /** Verifies that another polynomial belongs to the same residue ring. */
49
+ private assertCompatible;
50
+ /** Adds another polynomial in the same residue ring. */
51
+ add(other: ModularSparsePolynomial): ModularSparsePolynomial;
52
+ /** Returns the canonical residue coefficient of one monomial. */
53
+ coefficient(exponents: readonly bigint[]): bigint;
54
+ /**
55
+ * Returns the coefficient polynomial at one exact power of a selected variable.
56
+ *
57
+ * The selected variable remains in the ring with exponent zero.
58
+ */
59
+ coefficientIn(variableIndex: number, exponent: bigint): ModularSparsePolynomial;
60
+ /** Returns the canonical residue of the constant coefficient. */
61
+ constantTerm(): bigint;
62
+ /** Returns the degree in one variable, or null for the zero polynomial. */
63
+ degree(variableIndex: number): bigint | null;
64
+ /**
65
+ * Differentiates with respect to one ring variable in the residue ring.
66
+ */
67
+ derivative(variableIndex: number): ModularSparsePolynomial;
68
+ /**
69
+ * Divides by one polynomial when the remainder is zero.
70
+ */
71
+ divideExact(divisor: ModularSparsePolynomial, order?: MonomialOrder): ModularSparsePolynomial | null;
72
+ /**
73
+ * Divides by one polynomial and returns quotient and remainder.
74
+ *
75
+ * The leading coefficient of the divisor must be invertible modulo the ring
76
+ * modulus.
77
+ */
78
+ divideWithRemainder(divisor: ModularSparsePolynomial, order?: MonomialOrder): Readonly<{
79
+ quotient: ModularSparsePolynomial;
80
+ remainder: ModularSparsePolynomial;
81
+ }>;
82
+ /** Returns whether two polynomials have the same residue ring and exact terms. */
83
+ equals(other: ModularSparsePolynomial): boolean;
84
+ /**
85
+ * Substitutes one variable with a residue while keeping the same ring dimension.
86
+ *
87
+ * Terms that become like terms after substitution are combined by the sparse
88
+ * polynomial constructor.
89
+ */
90
+ evaluateVariable(variableIndex: number, value: bigint): ModularSparsePolynomial;
91
+ /** Returns whether the polynomial is zero or contains only a constant term. */
92
+ isConstant(): boolean;
93
+ /** Returns whether the polynomial has no nonzero terms. */
94
+ isZero(): boolean;
95
+ /**
96
+ * Returns the coefficient polynomial of the highest power of one variable.
97
+ *
98
+ * The selected variable remains in the ring with exponent zero so recursive
99
+ * algorithms can preserve a stable variable layout.
100
+ */
101
+ leadingCoefficientIn(variableIndex: number): ModularSparsePolynomial | null;
102
+ /** Returns the leading term under the requested monomial order. */
103
+ leadingTerm(order?: MonomialOrder): SparsePolynomialTerm | null;
104
+ /**
105
+ * Scales the polynomial so its leading coefficient is one.
106
+ *
107
+ * Zero remains zero. A nonzero leading coefficient that has no inverse modulo
108
+ * the modulus is rejected.
109
+ */
110
+ monic(order?: MonomialOrder): ModularSparsePolynomial;
111
+ /** Multiplies by another polynomial in the same residue ring. */
112
+ multiply(other: ModularSparsePolynomial): ModularSparsePolynomial;
113
+ /** Returns the additive inverse in the residue ring. */
114
+ negate(): ModularSparsePolynomial;
115
+ /** Raises the polynomial to a non-negative exact integer power. */
116
+ pow(exponent: bigint): ModularSparsePolynomial;
117
+ /** Multiplies every coefficient by one residue-ring scalar. */
118
+ scale(scalar: bigint): ModularSparsePolynomial;
119
+ /** Subtracts another polynomial in the same residue ring. */
120
+ subtract(other: ModularSparsePolynomial): ModularSparsePolynomial;
121
+ /** Number of stored nonzero terms. */
122
+ get termCount(): number;
123
+ /** Returns the stored canonical residue terms. */
124
+ terms(): readonly SparsePolynomialTerm[];
125
+ /** Converts canonical residues to centered integer representatives. */
126
+ toSymmetricIntegerPolynomial(): SparsePolynomial;
127
+ /** Returns the largest total degree, or null for the zero polynomial. */
128
+ totalDegree(): bigint | null;
129
+ /** Returns the variable indices that occur with a positive exponent. */
130
+ variables(): readonly number[];
131
+ }
@@ -0,0 +1,378 @@
1
+ "use strict";
2
+ /**
3
+ * @module modularSparsePolynomial
4
+ *
5
+ * Sparse polynomial arithmetic over integer residue classes.
6
+ *
7
+ * External references consulted for modular coefficient arithmetic and sparse
8
+ * polynomial division:
9
+ * - SymPy finite-field polynomial arithmetic:
10
+ * https://github.com/sympy/sympy/blob/120ee85f346f6292b763cc195afda4f907260d4a/sympy/polys/galoistools.py
11
+ * - SymPy sparse polynomial substitution, evaluation, and term division:
12
+ * https://github.com/sympy/sympy/blob/120ee85f346f6292b763cc195afda4f907260d4a/sympy/polys/sparsetools.py
13
+ * - SymPy variable-relative leading coefficient operations used by modular GCD:
14
+ * https://github.com/sympy/sympy/blob/120ee85f346f6292b763cc195afda4f907260d4a/sympy/polys/zippel.py
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.ModularSparsePolynomial = void 0;
18
+ const SparsePolynomial_1 = require("../../core/classes/polynomial/SparsePolynomial");
19
+ const errors_1 = require("../../core/errors");
20
+ const bigint_1 = require("../../core/functions/bigint/bigint");
21
+ /**
22
+ * Sparse polynomial whose coefficients are stored as canonical residues modulo
23
+ * a positive integer greater than one.
24
+ *
25
+ * The modulus is part of the polynomial ring. Prime moduli provide finite-field
26
+ * arithmetic; composite moduli remain valid for addition and multiplication but
27
+ * may not provide multiplicative inverses required by monic normalization or
28
+ * polynomial division.
29
+ */
30
+ class ModularSparsePolynomial {
31
+ polynomial;
32
+ modulus;
33
+ variableCount;
34
+ constructor(variableCount, modulus, terms = []) {
35
+ if (modulus <= 1n) {
36
+ throw new RangeError((0, errors_1.message)('polyModulusGreaterThanOne'));
37
+ }
38
+ let combined;
39
+ if (terms instanceof SparsePolynomial_1.SparsePolynomial) {
40
+ if (terms.variableCount !== variableCount) {
41
+ throw new RangeError((0, errors_1.message)('polyVariableCountMatch'));
42
+ }
43
+ combined = terms;
44
+ }
45
+ else {
46
+ combined = new SparsePolynomial_1.SparsePolynomial(variableCount, terms);
47
+ }
48
+ this.modulus = modulus;
49
+ this.polynomial = combined.mapCoefficients(coefficient => (0, bigint_1.mod)(coefficient, modulus));
50
+ this.variableCount = this.polynomial.variableCount;
51
+ }
52
+ /** Creates a constant polynomial in the selected residue ring. */
53
+ static constant(variableCount, modulus, coefficient) {
54
+ return new ModularSparsePolynomial(variableCount, modulus, [
55
+ {
56
+ coefficient,
57
+ exponents: new Array(variableCount).fill(0n),
58
+ },
59
+ ]);
60
+ }
61
+ /**
62
+ * Reconstructs a polynomial in one variable from specialized images.
63
+ *
64
+ * Each sample polynomial must be independent of the interpolated variable.
65
+ * Evaluation values are compared as residues in the shared coefficient ring.
66
+ */
67
+ static interpolateVariable(variableIndex, samples) {
68
+ if (samples.length === 0) {
69
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'ModularSparsePolynomial interpolation', requirement: (0, errors_1.message)('polyReqAtLeastOneSample') }));
70
+ }
71
+ const first = samples[0].polynomial;
72
+ first.degree(variableIndex);
73
+ const x = ModularSparsePolynomial.variable(first.variableCount, first.modulus, variableIndex);
74
+ let result = ModularSparsePolynomial.zero(first.variableCount, first.modulus);
75
+ for (let i = 0; i < samples.length; i++) {
76
+ const sample = samples[i];
77
+ first.assertCompatible(sample.polynomial);
78
+ const sampleDegree = sample.polynomial.degree(variableIndex);
79
+ if (sampleDegree !== null && sampleDegree !== 0n) {
80
+ throw new RangeError((0, errors_1.message)('polyInterpolationCannotDepend'));
81
+ }
82
+ const value = (0, bigint_1.mod)(sample.value, first.modulus);
83
+ let denominator = 1n;
84
+ let basis = ModularSparsePolynomial.constant(first.variableCount, first.modulus, 1n);
85
+ for (let j = 0; j < samples.length; j++) {
86
+ if (i === j) {
87
+ continue;
88
+ }
89
+ const otherValue = (0, bigint_1.mod)(samples[j].value, first.modulus);
90
+ basis = basis.multiply(x.subtract(ModularSparsePolynomial.constant(first.variableCount, first.modulus, otherValue)));
91
+ denominator = (0, bigint_1.mod)(denominator * (0, bigint_1.mod)(value - otherValue, first.modulus), first.modulus);
92
+ }
93
+ const inverse = (0, bigint_1.invMod)(denominator, first.modulus);
94
+ if (inverse < 0n) {
95
+ throw new RangeError((0, errors_1.message)('polyInterpolationInvertibleDifferences'));
96
+ }
97
+ result = result.add(sample.polynomial.multiply(basis.scale(inverse)));
98
+ }
99
+ return result;
100
+ }
101
+ /** Creates a one-term polynomial in the selected residue ring. */
102
+ static monomial(variableCount, modulus, coefficient, exponents) {
103
+ return new ModularSparsePolynomial(variableCount, modulus, [{ coefficient, exponents }]);
104
+ }
105
+ /** Creates one polynomial variable with coefficient one. */
106
+ static variable(variableCount, modulus, variableIndex) {
107
+ const variable = SparsePolynomial_1.SparsePolynomial.variable(variableCount, variableIndex);
108
+ return new ModularSparsePolynomial(variableCount, modulus, variable);
109
+ }
110
+ /** Creates the zero polynomial in the selected residue ring. */
111
+ static zero(variableCount, modulus) {
112
+ return new ModularSparsePolynomial(variableCount, modulus);
113
+ }
114
+ /** Verifies that another polynomial belongs to the same residue ring. */
115
+ assertCompatible(other) {
116
+ if (this.variableCount !== other.variableCount || this.modulus !== other.modulus) {
117
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'ModularSparsePolynomial operations', requirement: (0, errors_1.message)('polyReqSamePolynomialRing') }));
118
+ }
119
+ }
120
+ /** Adds another polynomial in the same residue ring. */
121
+ add(other) {
122
+ this.assertCompatible(other);
123
+ const sum = this.polynomial.add(other.polynomial);
124
+ return new ModularSparsePolynomial(this.variableCount, this.modulus, sum);
125
+ }
126
+ /** Returns the canonical residue coefficient of one monomial. */
127
+ coefficient(exponents) {
128
+ return this.polynomial.coefficient(exponents);
129
+ }
130
+ /**
131
+ * Returns the coefficient polynomial at one exact power of a selected variable.
132
+ *
133
+ * The selected variable remains in the ring with exponent zero.
134
+ */
135
+ coefficientIn(variableIndex, exponent) {
136
+ this.polynomial.degree(variableIndex);
137
+ if (exponent < 0n) {
138
+ throw new RangeError((0, errors_1.message)('polyCoefficientExponentNonnegative'));
139
+ }
140
+ const terms = [];
141
+ for (const term of this.polynomial.terms()) {
142
+ if (term.exponents[variableIndex] === exponent) {
143
+ const exponents = [...term.exponents];
144
+ exponents[variableIndex] = 0n;
145
+ terms.push({
146
+ coefficient: term.coefficient,
147
+ exponents,
148
+ });
149
+ }
150
+ }
151
+ return new ModularSparsePolynomial(this.variableCount, this.modulus, terms);
152
+ }
153
+ /** Returns the canonical residue of the constant coefficient. */
154
+ constantTerm() {
155
+ return this.polynomial.constantTerm();
156
+ }
157
+ /** Returns the degree in one variable, or null for the zero polynomial. */
158
+ degree(variableIndex) {
159
+ return this.polynomial.degree(variableIndex);
160
+ }
161
+ /**
162
+ * Differentiates with respect to one ring variable in the residue ring.
163
+ */
164
+ derivative(variableIndex) {
165
+ this.polynomial.degree(variableIndex);
166
+ const terms = [];
167
+ for (const term of this.polynomial.terms()) {
168
+ const exponent = term.exponents[variableIndex];
169
+ if (exponent === 0n) {
170
+ continue;
171
+ }
172
+ const exponents = [...term.exponents];
173
+ exponents[variableIndex] = exponent - 1n;
174
+ terms.push({
175
+ coefficient: (0, bigint_1.mod)(term.coefficient * exponent, this.modulus),
176
+ exponents,
177
+ });
178
+ }
179
+ return new ModularSparsePolynomial(this.variableCount, this.modulus, terms);
180
+ }
181
+ /**
182
+ * Divides by one polynomial when the remainder is zero.
183
+ */
184
+ divideExact(divisor, order = 'lex') {
185
+ const division = this.divideWithRemainder(divisor, order);
186
+ return division.remainder.isZero() ? division.quotient : null;
187
+ }
188
+ /**
189
+ * Divides by one polynomial and returns quotient and remainder.
190
+ *
191
+ * The leading coefficient of the divisor must be invertible modulo the ring
192
+ * modulus.
193
+ */
194
+ divideWithRemainder(divisor, order = 'lex') {
195
+ this.assertCompatible(divisor);
196
+ const divisorLeading = divisor.leadingTerm(order);
197
+ if (divisorLeading === null) {
198
+ throw new RangeError((0, errors_1.message)('polyCannotDivideZero'));
199
+ }
200
+ const divisorLeadingInverse = (0, bigint_1.invMod)(divisorLeading.coefficient, this.modulus);
201
+ if (divisorLeadingInverse < 0n) {
202
+ throw new RangeError((0, errors_1.message)('polyDivisorLeadingCoefficientInvertible'));
203
+ }
204
+ let quotient = ModularSparsePolynomial.zero(this.variableCount, this.modulus);
205
+ let remainder = ModularSparsePolynomial.zero(this.variableCount, this.modulus);
206
+ let working = new ModularSparsePolynomial(this.variableCount, this.modulus, this.polynomial);
207
+ while (!working.isZero()) {
208
+ const leading = working.leadingTerm(order);
209
+ if (leading === null) {
210
+ break;
211
+ }
212
+ let divides = true;
213
+ const exponents = new Array(this.variableCount);
214
+ for (let variableIndex = 0; variableIndex < this.variableCount; variableIndex++) {
215
+ if (leading.exponents[variableIndex] < divisorLeading.exponents[variableIndex]) {
216
+ divides = false;
217
+ break;
218
+ }
219
+ exponents[variableIndex] =
220
+ leading.exponents[variableIndex] - divisorLeading.exponents[variableIndex];
221
+ }
222
+ if (divides) {
223
+ const coefficient = (0, bigint_1.mod)(leading.coefficient * divisorLeadingInverse, this.modulus);
224
+ const quotientTerm = ModularSparsePolynomial.monomial(this.variableCount, this.modulus, coefficient, exponents);
225
+ quotient = quotient.add(quotientTerm);
226
+ working = working.subtract(divisor.multiply(quotientTerm));
227
+ }
228
+ else {
229
+ const remainderTerm = ModularSparsePolynomial.monomial(this.variableCount, this.modulus, leading.coefficient, leading.exponents);
230
+ remainder = remainder.add(remainderTerm);
231
+ working = working.subtract(remainderTerm);
232
+ }
233
+ }
234
+ return { quotient, remainder };
235
+ }
236
+ /** Returns whether two polynomials have the same residue ring and exact terms. */
237
+ equals(other) {
238
+ return this.modulus === other.modulus && this.polynomial.equals(other.polynomial);
239
+ }
240
+ /**
241
+ * Substitutes one variable with a residue while keeping the same ring dimension.
242
+ *
243
+ * Terms that become like terms after substitution are combined by the sparse
244
+ * polynomial constructor.
245
+ */
246
+ evaluateVariable(variableIndex, value) {
247
+ this.polynomial.degree(variableIndex);
248
+ const residue = (0, bigint_1.mod)(value, this.modulus);
249
+ const terms = [];
250
+ for (const term of this.polynomial.terms()) {
251
+ const exponent = term.exponents[variableIndex];
252
+ const exponents = [...term.exponents];
253
+ exponents[variableIndex] = 0n;
254
+ terms.push({
255
+ coefficient: (0, bigint_1.mod)(term.coefficient * (0, bigint_1.powMod)(residue, exponent, this.modulus), this.modulus),
256
+ exponents,
257
+ });
258
+ }
259
+ return new ModularSparsePolynomial(this.variableCount, this.modulus, terms);
260
+ }
261
+ /** Returns whether the polynomial is zero or contains only a constant term. */
262
+ isConstant() {
263
+ return this.polynomial.isConstant();
264
+ }
265
+ /** Returns whether the polynomial has no nonzero terms. */
266
+ isZero() {
267
+ return this.polynomial.isZero();
268
+ }
269
+ /**
270
+ * Returns the coefficient polynomial of the highest power of one variable.
271
+ *
272
+ * The selected variable remains in the ring with exponent zero so recursive
273
+ * algorithms can preserve a stable variable layout.
274
+ */
275
+ leadingCoefficientIn(variableIndex) {
276
+ const degree = this.degree(variableIndex);
277
+ return degree === null ? null : this.coefficientIn(variableIndex, degree);
278
+ }
279
+ /** Returns the leading term under the requested monomial order. */
280
+ leadingTerm(order = 'lex') {
281
+ return this.polynomial.leadingTerm(order);
282
+ }
283
+ /**
284
+ * Scales the polynomial so its leading coefficient is one.
285
+ *
286
+ * Zero remains zero. A nonzero leading coefficient that has no inverse modulo
287
+ * the modulus is rejected.
288
+ */
289
+ monic(order = 'lex') {
290
+ const leading = this.leadingTerm(order);
291
+ if (leading === null || leading.coefficient === 1n) {
292
+ return this;
293
+ }
294
+ const inverse = (0, bigint_1.invMod)(leading.coefficient, this.modulus);
295
+ if (inverse < 0n) {
296
+ throw new RangeError((0, errors_1.message)('polyLeadingCoefficientInvertible'));
297
+ }
298
+ return this.scale(inverse);
299
+ }
300
+ /** Multiplies by another polynomial in the same residue ring. */
301
+ multiply(other) {
302
+ this.assertCompatible(other);
303
+ const product = this.polynomial.multiply(other.polynomial);
304
+ return new ModularSparsePolynomial(this.variableCount, this.modulus, product);
305
+ }
306
+ /** Returns the additive inverse in the residue ring. */
307
+ negate() {
308
+ const negated = this.polynomial.negate();
309
+ return new ModularSparsePolynomial(this.variableCount, this.modulus, negated);
310
+ }
311
+ /** Raises the polynomial to a non-negative exact integer power. */
312
+ pow(exponent) {
313
+ if (exponent < 0n) {
314
+ throw new RangeError((0, errors_1.message)('polyExponentNonnegative'));
315
+ }
316
+ let result = ModularSparsePolynomial.constant(this.variableCount, this.modulus, 1n);
317
+ let power = exponent;
318
+ if (power === 0n) {
319
+ return result;
320
+ }
321
+ if ((power & 1n) === 1n) {
322
+ result = result.multiply(this);
323
+ }
324
+ power >>= 1n;
325
+ if (power === 0n) {
326
+ return result;
327
+ }
328
+ let factor = this.multiply(this);
329
+ while (power > 0n) {
330
+ if ((power & 1n) === 1n) {
331
+ result = result.multiply(factor);
332
+ }
333
+ power >>= 1n;
334
+ if (power > 0n) {
335
+ factor = factor.multiply(factor);
336
+ }
337
+ }
338
+ return result;
339
+ }
340
+ /** Multiplies every coefficient by one residue-ring scalar. */
341
+ scale(scalar) {
342
+ const scaled = this.polynomial.scale((0, bigint_1.mod)(scalar, this.modulus));
343
+ return new ModularSparsePolynomial(this.variableCount, this.modulus, scaled);
344
+ }
345
+ /** Subtracts another polynomial in the same residue ring. */
346
+ subtract(other) {
347
+ this.assertCompatible(other);
348
+ const difference = this.polynomial.subtract(other.polynomial);
349
+ return new ModularSparsePolynomial(this.variableCount, this.modulus, difference);
350
+ }
351
+ /** Number of stored nonzero terms. */
352
+ get termCount() {
353
+ return this.polynomial.termCount;
354
+ }
355
+ /** Returns the stored canonical residue terms. */
356
+ terms() {
357
+ return this.polynomial.terms();
358
+ }
359
+ /** Converts canonical residues to centered integer representatives. */
360
+ toSymmetricIntegerPolynomial() {
361
+ const half = this.modulus / 2n;
362
+ return new SparsePolynomial_1.SparsePolynomial(this.variableCount, this.terms().map(term => ({
363
+ coefficient: term.coefficient > half
364
+ ? term.coefficient - this.modulus
365
+ : term.coefficient,
366
+ exponents: term.exponents,
367
+ })));
368
+ }
369
+ /** Returns the largest total degree, or null for the zero polynomial. */
370
+ totalDegree() {
371
+ return this.polynomial.totalDegree();
372
+ }
373
+ /** Returns the variable indices that occur with a positive exponent. */
374
+ variables() {
375
+ return this.polynomial.variables();
376
+ }
377
+ }
378
+ exports.ModularSparsePolynomial = ModularSparsePolynomial;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @module modularSparsePolynomialFactor
3
+ *
4
+ * Finite-field factorization and Hensel lifting for sparse polynomials.
5
+ *
6
+ * External references consulted for Berlekamp factorization:
7
+ * - SymPy finite-field factorization:
8
+ * https://github.com/sympy/sympy/blob/120ee85f346f6292b763cc195afda4f907260d4a/sympy/polys/galoistools.py
9
+ */
10
+ import { ModularSparsePolynomial } from './ModularSparsePolynomial';
11
+ import type { SparsePolynomial } from '../../core/classes/polynomial/SparsePolynomial';
12
+ export declare function modularExtendedGcdUnivariate(left: ModularSparsePolynomial, right: ModularSparsePolynomial, variableIndex: number): Readonly<{
13
+ gcd: ModularSparsePolynomial;
14
+ leftCoefficient: ModularSparsePolynomial;
15
+ rightCoefficient: ModularSparsePolynomial;
16
+ }>;
17
+ /**
18
+ * Lifts specialized factors through one or more tail variables modulo a prime.
19
+ *
20
+ * Callers supply the fully specialized factors, the corresponding main-variable
21
+ * leading coefficients, and one evaluation value for each tail variable. The factors
22
+ * are lifted one tail variable at a time and verified against the target after every
23
+ * stage.
24
+ */
25
+ export declare function henselLiftMultivariateFactors(polynomial: SparsePolynomial, factors: readonly SparsePolynomial[], leadingCoefficients: readonly SparsePolynomial[], variables: readonly number[], evaluationValues: readonly bigint[], prime: bigint): readonly SparsePolynomial[] | null;
26
+ /**
27
+ * Lifts pairwise-coprime monic factors from F_p[x] to a larger prime-power modulus.
28
+ *
29
+ * The achieved modulus is obtained by repeated quadratic Hensel steps, so callers
30
+ * should pass a prime power of the form p^(2^k). The lifted factors remain monic and
31
+ * reconstruct the integer polynomial after multiplication by its leading coefficient.
32
+ */
33
+ export declare function henselLiftUnivariateFactors(polynomial: SparsePolynomial, prime: bigint, factors: readonly ModularSparsePolynomial[], variableIndex: number, targetModulus: bigint): readonly ModularSparsePolynomial[];
34
+ /**
35
+ * Factors a square-free univariate polynomial over a prime field with Berlekamp's method.
36
+ *
37
+ * The result contains monic irreducible factors whose product is the monic input.
38
+ * Constants return an empty list.
39
+ */
40
+ export declare function factorSquareFreeUnivariateFiniteField(polynomial: ModularSparsePolynomial, variableIndex: number): readonly ModularSparsePolynomial[];