nerdamer 1.1.13 → 2.0.0-rc.2

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 (387) hide show
  1. package/BREAKING_CHANGES.md +244 -5
  2. package/LICENSE.md +184 -0
  3. package/README.md +232 -318
  4. package/dist/bundle.js +2 -0
  5. package/dist/bundle.js.LICENSE.txt +7 -0
  6. package/dist/parser.js +2 -0
  7. package/dist/parser.js.LICENSE.txt +7 -0
  8. package/docs-data/parser-functions.json +2248 -0
  9. package/index.d.ts +10 -426
  10. package/output/algebra/adapters.d.ts +3 -0
  11. package/output/algebra/adapters.js +11 -0
  12. package/output/algebra/algorithms/arith.d.ts +84 -0
  13. package/output/algebra/algorithms/arith.js +324 -0
  14. package/output/algebra/algorithms/groebnerBase.d.ts +161 -0
  15. package/output/algebra/algorithms/groebnerBase.js +929 -0
  16. package/output/algebra/dispatch.d.ts +1 -0
  17. package/output/algebra/dispatch.js +25 -0
  18. package/output/algebra/factor/factor.d.ts +77 -0
  19. package/output/algebra/factor/factor.js +245 -0
  20. package/output/algebra/gcd/gcd.d.ts +30 -0
  21. package/output/algebra/gcd/gcd.js +95 -0
  22. package/output/algebra/groebner.d.ts +21 -0
  23. package/output/algebra/groebner.js +36 -0
  24. package/output/algebra/partfrac.d.ts +19 -0
  25. package/output/algebra/partfrac.js +365 -0
  26. package/output/algebra/polynomial/ModularSparsePolynomial.d.ts +131 -0
  27. package/output/algebra/polynomial/ModularSparsePolynomial.js +378 -0
  28. package/output/algebra/polynomial/ModularSparsePolynomialFactor.d.ts +40 -0
  29. package/output/algebra/polynomial/ModularSparsePolynomialFactor.js +661 -0
  30. package/output/algebra/polynomial/SparsePolynomialFactor.d.ts +64 -0
  31. package/output/algebra/polynomial/SparsePolynomialFactor.js +492 -0
  32. package/output/algebra/polynomial/SparsePolynomialGcd.d.ts +29 -0
  33. package/output/algebra/polynomial/SparsePolynomialGcd.js +259 -0
  34. package/output/algebra/polynomial/SparsePolynomialMultivariateFactor.d.ts +82 -0
  35. package/output/algebra/polynomial/SparsePolynomialMultivariateFactor.js +604 -0
  36. package/output/algebra/polynomial/modularGcd.d.ts +40 -0
  37. package/output/algebra/polynomial/modularGcd.js +365 -0
  38. package/output/algebra/polynomialize.d.ts +20 -0
  39. package/output/algebra/polynomialize.js +26 -0
  40. package/output/algebra/simplify/complexsimp.d.ts +7 -0
  41. package/output/algebra/simplify/complexsimp.js +24 -0
  42. package/output/algebra/simplify/factorCommon.d.ts +13 -0
  43. package/output/algebra/simplify/factorCommon.js +136 -0
  44. package/output/algebra/simplify/funcsimp.d.ts +26 -0
  45. package/output/algebra/simplify/funcsimp.js +633 -0
  46. package/output/algebra/simplify/invtrigrewrite.d.ts +10 -0
  47. package/output/algebra/simplify/invtrigrewrite.js +96 -0
  48. package/output/algebra/simplify/ratsimp.d.ts +21 -0
  49. package/output/algebra/simplify/ratsimp.js +140 -0
  50. package/output/algebra/simplify/simplify.d.ts +25 -0
  51. package/output/algebra/simplify/simplify.js +237 -0
  52. package/output/algebra/simplify/trigreduce.d.ts +38 -0
  53. package/output/algebra/simplify/trigreduce.js +424 -0
  54. package/output/algebra/simplify/trigrewrite.d.ts +17 -0
  55. package/output/algebra/simplify/trigrewrite.js +156 -0
  56. package/output/algebra/simplify/trigsimp.d.ts +11 -0
  57. package/output/algebra/simplify/trigsimp.js +369 -0
  58. package/output/algebra/simplify/utils.d.ts +32 -0
  59. package/output/algebra/simplify/utils.js +56 -0
  60. package/output/algebra/utils.d.ts +32 -0
  61. package/output/algebra/utils.js +48 -0
  62. package/output/api/advanced.d.ts +8 -0
  63. package/output/api/advanced.js +18 -0
  64. package/output/api/algebra.d.ts +17 -0
  65. package/output/api/algebra.js +35 -0
  66. package/output/api/assumptions.d.ts +4 -0
  67. package/output/api/assumptions.js +11 -0
  68. package/output/api/calculus.d.ts +10 -0
  69. package/output/api/calculus.js +22 -0
  70. package/output/api/core.d.ts +17 -0
  71. package/output/api/core.js +41 -0
  72. package/output/api/debug.d.ts +16 -0
  73. package/output/api/debug.js +23 -0
  74. package/output/api/languages/deu.d.ts +3 -0
  75. package/output/api/languages/deu.js +266 -0
  76. package/output/api/languages/fra.d.ts +3 -0
  77. package/output/api/languages/fra.js +266 -0
  78. package/output/api/languages/ita.d.ts +3 -0
  79. package/output/api/languages/ita.js +266 -0
  80. package/output/api/languages/nld.d.ts +3 -0
  81. package/output/api/languages/nld.js +266 -0
  82. package/output/api/languages/por.d.ts +3 -0
  83. package/output/api/languages/por.js +266 -0
  84. package/output/api/languages/spa.d.ts +3 -0
  85. package/output/api/languages/spa.js +266 -0
  86. package/output/api/parser.d.ts +93 -0
  87. package/output/api/parser.js +18 -0
  88. package/output/api/solve.d.ts +10 -0
  89. package/output/api/solve.js +17 -0
  90. package/output/api/structures.d.ts +10 -0
  91. package/output/api/structures.js +23 -0
  92. package/output/calculus/adapters.d.ts +8 -0
  93. package/output/calculus/adapters.js +41 -0
  94. package/output/calculus/derivative/diff.d.ts +30 -0
  95. package/output/calculus/derivative/diff.js +241 -0
  96. package/output/calculus/dispatch.d.ts +1 -0
  97. package/output/calculus/dispatch.js +25 -0
  98. package/output/calculus/fresnel.d.ts +16 -0
  99. package/output/calculus/fresnel.js +39 -0
  100. package/output/calculus/integrate/byParts.d.ts +18 -0
  101. package/output/calculus/integrate/byParts.js +339 -0
  102. package/output/calculus/integrate/bySubstitution.d.ts +135 -0
  103. package/output/calculus/integrate/bySubstitution.js +411 -0
  104. package/output/calculus/integrate/integrate.d.ts +38 -0
  105. package/output/calculus/integrate/integrate.js +652 -0
  106. package/output/calculus/integrate/integrationTable.d.ts +2 -0
  107. package/output/calculus/integrate/integrationTable.js +914 -0
  108. package/output/calculus/integrate/utils.d.ts +28 -0
  109. package/output/calculus/integrate/utils.js +96 -0
  110. package/output/calculus/laplace/ilaplace.d.ts +31 -0
  111. package/output/calculus/laplace/ilaplace.js +192 -0
  112. package/output/calculus/laplace/ilaplaceTable.d.ts +2 -0
  113. package/output/calculus/laplace/ilaplaceTable.js +200 -0
  114. package/output/calculus/laplace/laplace.d.ts +22 -0
  115. package/output/calculus/laplace/laplace.js +109 -0
  116. package/output/calculus/laplace/laplaceTable.d.ts +2 -0
  117. package/output/calculus/laplace/laplaceTable.js +187 -0
  118. package/output/calculus/limit/limit.d.ts +35 -0
  119. package/output/calculus/limit/limit.js +1183 -0
  120. package/output/calculus/limit/limitsTable.d.ts +2 -0
  121. package/output/calculus/limit/limitsTable.js +7 -0
  122. package/output/core/Settings.d.ts +32 -0
  123. package/output/core/Settings.js +68 -0
  124. package/output/core/classes/assumption/Assumption.d.ts +218 -0
  125. package/output/core/classes/assumption/Assumption.js +609 -0
  126. package/output/core/classes/assumption/assertiveFunctions.d.ts +6 -0
  127. package/output/core/classes/assumption/assertiveFunctions.js +64 -0
  128. package/output/core/classes/assumption/assume.d.ts +90 -0
  129. package/output/core/classes/assumption/assume.js +145 -0
  130. package/output/core/classes/assumption/dispatch.d.ts +1 -0
  131. package/output/core/classes/assumption/dispatch.js +11 -0
  132. package/output/core/classes/collection/Collection.d.ts +107 -0
  133. package/output/core/classes/collection/Collection.js +240 -0
  134. package/output/core/classes/complex/Complex.d.ts +109 -0
  135. package/output/core/classes/complex/Complex.js +153 -0
  136. package/output/core/classes/decimalSet/DecimalSet.d.ts +226 -0
  137. package/output/core/classes/decimalSet/DecimalSet.js +454 -0
  138. package/output/core/classes/dictionary/Dictionary.d.ts +102 -0
  139. package/output/core/classes/dictionary/Dictionary.js +216 -0
  140. package/output/core/classes/equation/Equation.d.ts +256 -0
  141. package/output/core/classes/equation/Equation.js +350 -0
  142. package/output/core/classes/expression/CoeffObject.d.ts +100 -0
  143. package/output/core/classes/expression/CoeffObject.js +197 -0
  144. package/output/core/classes/expression/Expression.d.ts +1691 -0
  145. package/output/core/classes/expression/Expression.js +2381 -0
  146. package/output/core/classes/expression/analysis.d.ts +25 -0
  147. package/output/core/classes/expression/analysis.js +218 -0
  148. package/output/core/classes/expression/collect.d.ts +9 -0
  149. package/output/core/classes/expression/collect.js +49 -0
  150. package/output/core/classes/expression/format.d.ts +54 -0
  151. package/output/core/classes/expression/format.js +340 -0
  152. package/output/core/classes/expression/products.d.ts +23 -0
  153. package/output/core/classes/expression/products.js +115 -0
  154. package/output/core/classes/expression/shortcuts.d.ts +35 -0
  155. package/output/core/classes/expression/shortcuts.js +129 -0
  156. package/output/core/classes/expression/traversal.d.ts +31 -0
  157. package/output/core/classes/expression/traversal.js +216 -0
  158. package/output/core/classes/expression/trig.d.ts +25 -0
  159. package/output/core/classes/expression/trig.js +40 -0
  160. package/output/core/classes/expression/utils.d.ts +61 -0
  161. package/output/core/classes/expression/utils.js +235 -0
  162. package/output/core/classes/lookupTable/LookupTable.d.ts +12 -0
  163. package/output/core/classes/lookupTable/LookupTable.js +55 -0
  164. package/output/core/classes/matrix/Matrix.d.ts +227 -0
  165. package/output/core/classes/matrix/Matrix.js +901 -0
  166. package/output/core/classes/matrix/Sylvester.d.ts +11 -0
  167. package/output/core/classes/matrix/Sylvester.js +54 -0
  168. package/output/core/classes/matrix/dispatch.d.ts +1 -0
  169. package/output/core/classes/matrix/dispatch.js +19 -0
  170. package/output/core/classes/matrix/functions.d.ts +28 -0
  171. package/output/core/classes/matrix/functions.js +57 -0
  172. package/output/core/classes/matrix/utils.d.ts +9 -0
  173. package/output/core/classes/matrix/utils.js +22 -0
  174. package/output/core/classes/parser/Parser.d.ts +493 -0
  175. package/output/core/classes/parser/Parser.js +1863 -0
  176. package/output/core/classes/parser/Token.d.ts +58 -0
  177. package/output/core/classes/parser/Token.js +137 -0
  178. package/output/core/classes/parser/constants.d.ts +162 -0
  179. package/output/core/classes/parser/constants.js +229 -0
  180. package/output/core/classes/parser/controlFlowSignals.d.ts +38 -0
  181. package/output/core/classes/parser/controlFlowSignals.js +60 -0
  182. package/output/core/classes/parser/helpers.d.ts +21 -0
  183. package/output/core/classes/parser/helpers.js +42 -0
  184. package/output/core/classes/parser/operations/add.d.ts +15 -0
  185. package/output/core/classes/parser/operations/add.js +236 -0
  186. package/output/core/classes/parser/operations/comma.d.ts +7 -0
  187. package/output/core/classes/parser/operations/comma.js +11 -0
  188. package/output/core/classes/parser/operations/compare.d.ts +21 -0
  189. package/output/core/classes/parser/operations/compare.js +474 -0
  190. package/output/core/classes/parser/operations/divide.d.ts +2 -0
  191. package/output/core/classes/parser/operations/divide.js +72 -0
  192. package/output/core/classes/parser/operations/functions.d.ts +46 -0
  193. package/output/core/classes/parser/operations/functions.js +438 -0
  194. package/output/core/classes/parser/operations/multiply.d.ts +11 -0
  195. package/output/core/classes/parser/operations/multiply.js +328 -0
  196. package/output/core/classes/parser/operations/power.d.ts +48 -0
  197. package/output/core/classes/parser/operations/power.js +673 -0
  198. package/output/core/classes/parser/operations/subtract.d.ts +3 -0
  199. package/output/core/classes/parser/operations/subtract.js +36 -0
  200. package/output/core/classes/parser/preprocess.d.ts +7 -0
  201. package/output/core/classes/parser/preprocess.js +246 -0
  202. package/output/core/classes/parser/scripting/controlFlow.d.ts +23 -0
  203. package/output/core/classes/parser/scripting/controlFlow.js +279 -0
  204. package/output/core/classes/parser/scripting/deferred.d.ts +4 -0
  205. package/output/core/classes/parser/scripting/deferred.js +65 -0
  206. package/output/core/classes/parser/scripting/dispatch.d.ts +1 -0
  207. package/output/core/classes/parser/scripting/dispatch.js +62 -0
  208. package/output/core/classes/parser/scripting/evaluate.d.ts +23 -0
  209. package/output/core/classes/parser/scripting/evaluate.js +128 -0
  210. package/output/core/classes/parser/scripting/functions.d.ts +14 -0
  211. package/output/core/classes/parser/scripting/functions.js +59 -0
  212. package/output/core/classes/parser/scripting/scope.d.ts +8 -0
  213. package/output/core/classes/parser/scripting/scope.js +132 -0
  214. package/output/core/classes/parser/types.d.ts +130 -0
  215. package/output/core/classes/parser/types.js +2 -0
  216. package/output/core/classes/parser/wrappers/IndexedReference.d.ts +31 -0
  217. package/output/core/classes/parser/wrappers/IndexedReference.js +68 -0
  218. package/output/core/classes/parser/wrappers/KeyValuePair.d.ts +24 -0
  219. package/output/core/classes/parser/wrappers/KeyValuePair.js +51 -0
  220. package/output/core/classes/polynomial/Polynomial.d.ts +504 -0
  221. package/output/core/classes/polynomial/Polynomial.js +1195 -0
  222. package/output/core/classes/polynomial/SparsePolynomial.d.ts +221 -0
  223. package/output/core/classes/polynomial/SparsePolynomial.js +824 -0
  224. package/output/core/classes/polynomial/SparsePolynomialAdapter.d.ts +56 -0
  225. package/output/core/classes/polynomial/SparsePolynomialAdapter.js +241 -0
  226. package/output/core/classes/polynomial/Term.d.ts +222 -0
  227. package/output/core/classes/polynomial/Term.js +430 -0
  228. package/output/core/classes/polynomial/adapters.d.ts +18 -0
  229. package/output/core/classes/polynomial/adapters.js +33 -0
  230. package/output/core/classes/polynomial/dispatch.d.ts +1 -0
  231. package/output/core/classes/polynomial/dispatch.js +14 -0
  232. package/output/core/classes/polynomial/functions.d.ts +77 -0
  233. package/output/core/classes/polynomial/functions.js +189 -0
  234. package/output/core/classes/polynomial/utils.d.ts +62 -0
  235. package/output/core/classes/polynomial/utils.js +207 -0
  236. package/output/core/classes/rational/Rational.d.ts +501 -0
  237. package/output/core/classes/rational/Rational.js +829 -0
  238. package/output/core/classes/seq/SEQ.d.ts +13 -0
  239. package/output/core/classes/seq/SEQ.js +137 -0
  240. package/output/core/classes/valuesSet/ValuesSet.d.ts +187 -0
  241. package/output/core/classes/valuesSet/ValuesSet.js +399 -0
  242. package/output/core/classes/vector/Vector.d.ts +222 -0
  243. package/output/core/classes/vector/Vector.js +501 -0
  244. package/output/core/classes/vector/dispatch.d.ts +1 -0
  245. package/output/core/classes/vector/dispatch.js +11 -0
  246. package/output/core/classes/vector/functions.d.ts +28 -0
  247. package/output/core/classes/vector/functions.js +47 -0
  248. package/output/core/common/classes/MathematicalAggregate.d.ts +53 -0
  249. package/output/core/common/classes/MathematicalAggregate.js +149 -0
  250. package/output/core/common/classes/Scope.d.ts +62 -0
  251. package/output/core/common/classes/Scope.js +122 -0
  252. package/output/core/common/classes/StructuredEntity.d.ts +55 -0
  253. package/output/core/common/classes/StructuredEntity.js +151 -0
  254. package/output/core/common/common.d.ts +62 -0
  255. package/output/core/common/common.js +74 -0
  256. package/output/core/common/functions/functions.d.ts +14 -0
  257. package/output/core/common/functions/functions.js +33 -0
  258. package/output/core/common/functions/structuredEntityUtils.d.ts +27 -0
  259. package/output/core/common/functions/structuredEntityUtils.js +40 -0
  260. package/output/core/converters/BaseConverter.d.ts +97 -0
  261. package/output/core/converters/BaseConverter.js +405 -0
  262. package/output/core/converters/Converter.d.ts +111 -0
  263. package/output/core/converters/Converter.js +806 -0
  264. package/output/core/converters/Pattern.d.ts +71 -0
  265. package/output/core/converters/Pattern.js +302 -0
  266. package/output/core/dispatch.d.ts +52 -0
  267. package/output/core/dispatch.js +26 -0
  268. package/output/core/errors.d.ts +316 -0
  269. package/output/core/errors.js +349 -0
  270. package/output/core/fullFunctions.d.ts +7 -0
  271. package/output/core/fullFunctions.js +31 -0
  272. package/output/core/functions/bigint/bigint.d.ts +133 -0
  273. package/output/core/functions/bigint/bigint.js +444 -0
  274. package/output/core/functions/bigint/primeFactor.d.ts +51 -0
  275. package/output/core/functions/bigint/primeFactor.js +267 -0
  276. package/output/core/functions/bigint/primes.d.ts +1 -0
  277. package/output/core/functions/bigint/primes.js +11 -0
  278. package/output/core/functions/build/definitions.d.ts +12 -0
  279. package/output/core/functions/build/definitions.js +139 -0
  280. package/output/core/functions/build/index.d.ts +32 -0
  281. package/output/core/functions/build/index.js +136 -0
  282. package/output/core/functions/complex.d.ts +90 -0
  283. package/output/core/functions/complex.dispatch.d.ts +1 -0
  284. package/output/core/functions/complex.dispatch.js +16 -0
  285. package/output/core/functions/complex.js +482 -0
  286. package/output/core/functions/decimal.d.ts +24 -0
  287. package/output/core/functions/decimal.js +665 -0
  288. package/output/core/functions/expand/expand.d.ts +42 -0
  289. package/output/core/functions/expand/expand.js +376 -0
  290. package/output/core/functions/fresnelNumeric.d.ts +12 -0
  291. package/output/core/functions/fresnelNumeric.js +123 -0
  292. package/output/core/functions/numeric.d.ts +140 -0
  293. package/output/core/functions/numeric.js +790 -0
  294. package/output/core/functions/rationalNormalization.d.ts +11 -0
  295. package/output/core/functions/rationalNormalization.js +117 -0
  296. package/output/core/functions/setFunction.d.ts +19 -0
  297. package/output/core/functions/setFunction.js +75 -0
  298. package/output/core/functions/string.d.ts +26 -0
  299. package/output/core/functions/string.js +102 -0
  300. package/output/core/functions/subst.d.ts +90 -0
  301. package/output/core/functions/subst.js +506 -0
  302. package/output/core/functions/utils.d.ts +24 -0
  303. package/output/core/functions/utils.js +51 -0
  304. package/output/core/parserFunctions.d.ts +7 -0
  305. package/output/core/parserFunctions.js +25 -0
  306. package/output/core/types.d.ts +48 -0
  307. package/output/core/types.js +2 -0
  308. package/output/index.d.ts +359 -0
  309. package/output/index.js +739 -0
  310. package/output/math/defint/defint.d.ts +18 -0
  311. package/output/math/defint/defint.js +60 -0
  312. package/output/math/defint/defintDecimal.d.ts +37 -0
  313. package/output/math/defint/defintDecimal.js +321 -0
  314. package/output/math/defint/defintNative.d.ts +57 -0
  315. package/output/math/defint/defintNative.js +281 -0
  316. package/output/math/dispatch.d.ts +1 -0
  317. package/output/math/dispatch.js +101 -0
  318. package/output/math/geometry.d.ts +12 -0
  319. package/output/math/geometry.js +55 -0
  320. package/output/math/math.d.ts +695 -0
  321. package/output/math/math.js +1955 -0
  322. package/output/math/trig.d.ts +518 -0
  323. package/output/math/trig.js +1444 -0
  324. package/output/math/trunc.d.ts +19 -0
  325. package/output/math/trunc.js +36 -0
  326. package/output/math/utils.d.ts +66 -0
  327. package/output/math/utils.js +219 -0
  328. package/output/solve/classes/DecimalMatrix.d.ts +17 -0
  329. package/output/solve/classes/DecimalMatrix.js +86 -0
  330. package/output/solve/classes/FunctionSolver.d.ts +135 -0
  331. package/output/solve/classes/FunctionSolver.js +433 -0
  332. package/output/solve/classes/MultivariateSolver.d.ts +84 -0
  333. package/output/solve/classes/MultivariateSolver.js +240 -0
  334. package/output/solve/classes/PolynomialSolver.d.ts +104 -0
  335. package/output/solve/classes/PolynomialSolver.js +492 -0
  336. package/output/solve/classes/SolutionSet.d.ts +172 -0
  337. package/output/solve/classes/SolutionSet.js +434 -0
  338. package/output/solve/classes/Solver.d.ts +17 -0
  339. package/output/solve/classes/Solver.js +132 -0
  340. package/output/solve/classes/SymbolicSolver.d.ts +74 -0
  341. package/output/solve/classes/SymbolicSolver.js +601 -0
  342. package/output/solve/dispatch.d.ts +1 -0
  343. package/output/solve/dispatch.js +13 -0
  344. package/output/solve/linsolve.d.ts +53 -0
  345. package/output/solve/linsolve.js +233 -0
  346. package/output/solve/solve.d.ts +44 -0
  347. package/output/solve/solve.js +368 -0
  348. package/output/solve/solveSystem.d.ts +31 -0
  349. package/output/solve/solveSystem.js +266 -0
  350. package/output/solve/utils.d.ts +10 -0
  351. package/output/solve/utils.js +58 -0
  352. package/output/utils/array.d.ts +42 -0
  353. package/output/utils/array.js +98 -0
  354. package/output/utils/debug.d.ts +131 -0
  355. package/output/utils/debug.js +296 -0
  356. package/output/utils/decimal.d.ts +3 -0
  357. package/output/utils/decimal.js +16 -0
  358. package/output/utils/numeric.d.ts +14 -0
  359. package/output/utils/numeric.js +51 -0
  360. package/output/utils/object.d.ts +26 -0
  361. package/output/utils/object.js +56 -0
  362. package/package.json +178 -57
  363. package/.travis.yml +0 -3
  364. package/Algebra.js +0 -4568
  365. package/CODE_OF_CONDUCT.md +0 -46
  366. package/CONTRIBUTING.md +0 -14
  367. package/Calculus.js +0 -2675
  368. package/Extra.js +0 -622
  369. package/Solve.js +0 -1783
  370. package/all.js +0 -16
  371. package/all.min.js +0 -1
  372. package/gulpfile.js +0 -16
  373. package/index.html +0 -158
  374. package/license.txt +0 -19
  375. package/nerdamer.core.js +0 -12510
  376. package/spec/LaTeX.spec.js +0 -302
  377. package/spec/TeXConvert.spec.js +0 -8
  378. package/spec/algebra.spec.js +0 -287
  379. package/spec/basic_parser.spec.js +0 -134
  380. package/spec/build.spec.js +0 -131
  381. package/spec/calculus.spec.js +0 -183
  382. package/spec/core.spec.js +0 -2970
  383. package/spec/extra.spec.js +0 -54
  384. package/spec/solve.spec.js +0 -126
  385. package/spec/support/jasmine.json +0 -11
  386. package/spec/support/utils.js +0 -42
  387. package/spec/text.spec.js +0 -132
@@ -0,0 +1,661 @@
1
+ "use strict";
2
+ /**
3
+ * @module modularSparsePolynomialFactor
4
+ *
5
+ * Finite-field factorization and Hensel lifting for sparse polynomials.
6
+ *
7
+ * External references consulted for Berlekamp factorization:
8
+ * - SymPy finite-field factorization:
9
+ * https://github.com/sympy/sympy/blob/120ee85f346f6292b763cc195afda4f907260d4a/sympy/polys/galoistools.py
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.modularExtendedGcdUnivariate = modularExtendedGcdUnivariate;
13
+ exports.henselLiftMultivariateFactors = henselLiftMultivariateFactors;
14
+ exports.henselLiftUnivariateFactors = henselLiftUnivariateFactors;
15
+ exports.factorSquareFreeUnivariateFiniteField = factorSquareFreeUnivariateFiniteField;
16
+ const errors_1 = require("../../core/errors");
17
+ const bigint_1 = require("../../core/functions/bigint/bigint");
18
+ const primeFactor_1 = require("../../core/functions/bigint/primeFactor");
19
+ const modularGcd_1 = require("./modularGcd");
20
+ const ModularSparsePolynomial_1 = require("./ModularSparsePolynomial");
21
+ function assertSquareFreeUnivariate(polynomial, variableIndex) {
22
+ if (!(0, primeFactor_1.isPrimeBig)(polynomial.modulus)) {
23
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Modular factorization', requirement: (0, errors_1.message)('polyReqPrimeModulus') }));
24
+ }
25
+ const degree = polynomial.degree(variableIndex);
26
+ for (const activeVariable of polynomial.variables()) {
27
+ if (activeVariable !== variableIndex) {
28
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Modular factorization', requirement: (0, errors_1.message)('polyReqUnivariatePolynomial') }));
29
+ }
30
+ }
31
+ if (degree === null || degree === 0n) {
32
+ return 0;
33
+ }
34
+ if (degree > BigInt(Number.MAX_SAFE_INTEGER)) {
35
+ throw new RangeError((0, errors_1.message)('polyDegreeMatrixLimit'));
36
+ }
37
+ const derivativeTerms = [];
38
+ for (const term of polynomial.terms()) {
39
+ const exponent = term.exponents[variableIndex];
40
+ if (exponent === 0n) {
41
+ continue;
42
+ }
43
+ const exponents = [...term.exponents];
44
+ exponents[variableIndex] = exponent - 1n;
45
+ derivativeTerms.push({
46
+ coefficient: (0, bigint_1.mod)(term.coefficient * exponent, polynomial.modulus),
47
+ exponents,
48
+ });
49
+ }
50
+ const derivative = new ModularSparsePolynomial_1.ModularSparsePolynomial(polynomial.variableCount, polynomial.modulus, derivativeTerms);
51
+ const gcd = (0, modularGcd_1.modularGcdUnivariate)(polynomial, derivative, variableIndex);
52
+ if (!gcd.isConstant()) {
53
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Berlekamp factorization', requirement: (0, errors_1.message)('polyReqSquareFreeInput') }));
54
+ }
55
+ return Number(degree);
56
+ }
57
+ function polynomialRemainder(polynomial, modulusPolynomial) {
58
+ return polynomial.divideWithRemainder(modulusPolynomial).remainder;
59
+ }
60
+ function polynomialPowMod(base, exponent, modulusPolynomial) {
61
+ let result = ModularSparsePolynomial_1.ModularSparsePolynomial.constant(base.variableCount, base.modulus, 1n);
62
+ let factor = polynomialRemainder(base, modulusPolynomial);
63
+ let power = exponent;
64
+ while (power > 0n) {
65
+ if ((power & 1n) === 1n) {
66
+ result = polynomialRemainder(result.multiply(factor), modulusPolynomial);
67
+ }
68
+ power >>= 1n;
69
+ if (power > 0n) {
70
+ factor = polynomialRemainder(factor.multiply(factor), modulusPolynomial);
71
+ }
72
+ }
73
+ return result;
74
+ }
75
+ function nullspaceModulo(matrix, modulus) {
76
+ const rowCount = matrix.length;
77
+ const columnCount = rowCount === 0 ? 0 : matrix[0].length;
78
+ const rows = matrix.map(row => row.map(value => (0, bigint_1.mod)(value, modulus)));
79
+ const pivotColumns = [];
80
+ let pivotRow = 0;
81
+ for (let column = 0; column < columnCount && pivotRow < rowCount; column++) {
82
+ let selectedRow = pivotRow;
83
+ while (selectedRow < rowCount && rows[selectedRow][column] === 0n) {
84
+ selectedRow++;
85
+ }
86
+ if (selectedRow === rowCount) {
87
+ continue;
88
+ }
89
+ if (selectedRow !== pivotRow) {
90
+ const temp = rows[pivotRow];
91
+ rows[pivotRow] = rows[selectedRow];
92
+ rows[selectedRow] = temp;
93
+ }
94
+ const inverse = (0, bigint_1.invMod)(rows[pivotRow][column], modulus);
95
+ if (inverse < 0n) {
96
+ throw new RangeError((0, errors_1.message)('polyBerlekampNoninvertiblePivot'));
97
+ }
98
+ for (let c = column; c < columnCount; c++) {
99
+ rows[pivotRow][c] = (0, bigint_1.mod)(rows[pivotRow][c] * inverse, modulus);
100
+ }
101
+ for (let row = 0; row < rowCount; row++) {
102
+ if (row === pivotRow || rows[row][column] === 0n) {
103
+ continue;
104
+ }
105
+ const scale = rows[row][column];
106
+ for (let c = column; c < columnCount; c++) {
107
+ rows[row][c] = (0, bigint_1.mod)(rows[row][c] - scale * rows[pivotRow][c], modulus);
108
+ }
109
+ }
110
+ pivotColumns.push(column);
111
+ pivotRow++;
112
+ }
113
+ const pivotSet = new Set(pivotColumns);
114
+ const basis = [];
115
+ for (let freeColumn = 0; freeColumn < columnCount; freeColumn++) {
116
+ if (pivotSet.has(freeColumn)) {
117
+ continue;
118
+ }
119
+ const vector = new Array(columnCount).fill(0n);
120
+ vector[freeColumn] = 1n;
121
+ for (let row = 0; row < pivotColumns.length; row++) {
122
+ const pivotColumn = pivotColumns[row];
123
+ vector[pivotColumn] = (0, bigint_1.mod)(-rows[row][freeColumn], modulus);
124
+ }
125
+ basis.push(vector);
126
+ }
127
+ return basis;
128
+ }
129
+ function vectorPolynomial(vector, variableCount, modulus, variableIndex) {
130
+ const terms = [];
131
+ for (let exponent = 0; exponent < vector.length; exponent++) {
132
+ const coefficient = vector[exponent];
133
+ if (coefficient === 0n) {
134
+ continue;
135
+ }
136
+ const exponents = new Array(variableCount).fill(0n);
137
+ exponents[variableIndex] = BigInt(exponent);
138
+ terms.push({ coefficient, exponents });
139
+ }
140
+ return new ModularSparsePolynomial_1.ModularSparsePolynomial(variableCount, modulus, terms);
141
+ }
142
+ function changeModulus(polynomial, modulus) {
143
+ return new ModularSparsePolynomial_1.ModularSparsePolynomial(polynomial.variableCount, modulus, polynomial.terms());
144
+ }
145
+ function integerPolynomialModulo(polynomial, modulus) {
146
+ return new ModularSparsePolynomial_1.ModularSparsePolynomial(polynomial.variableCount, modulus, polynomial.terms());
147
+ }
148
+ function modularExtendedGcdUnivariate(left, right, variableIndex) {
149
+ if (left.variableCount !== right.variableCount || left.modulus !== right.modulus) {
150
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Modular extended GCD', requirement: (0, errors_1.message)('polyReqSamePolynomialRing') }));
151
+ }
152
+ left.degree(variableIndex);
153
+ right.degree(variableIndex);
154
+ let oldR = left;
155
+ let r = right;
156
+ let oldS = ModularSparsePolynomial_1.ModularSparsePolynomial.constant(left.variableCount, left.modulus, 1n);
157
+ let s = ModularSparsePolynomial_1.ModularSparsePolynomial.zero(left.variableCount, left.modulus);
158
+ let oldT = ModularSparsePolynomial_1.ModularSparsePolynomial.zero(left.variableCount, left.modulus);
159
+ let t = ModularSparsePolynomial_1.ModularSparsePolynomial.constant(left.variableCount, left.modulus, 1n);
160
+ while (!r.isZero()) {
161
+ const division = oldR.divideWithRemainder(r);
162
+ const nextR = division.remainder;
163
+ const nextS = oldS.subtract(division.quotient.multiply(s));
164
+ const nextT = oldT.subtract(division.quotient.multiply(t));
165
+ oldR = r;
166
+ r = nextR;
167
+ oldS = s;
168
+ s = nextS;
169
+ oldT = t;
170
+ t = nextT;
171
+ }
172
+ const leading = oldR.leadingTerm();
173
+ if (leading === null) {
174
+ throw new RangeError((0, errors_1.message)('polyExtendedGcdTwoZeroUndefined'));
175
+ }
176
+ const inverse = (0, bigint_1.invMod)(leading.coefficient, left.modulus);
177
+ if (inverse < 0n) {
178
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Modular extended GCD', requirement: (0, errors_1.message)('polyReqInvertibleLeadingCoefficient') }));
179
+ }
180
+ return {
181
+ gcd: oldR.scale(inverse),
182
+ leftCoefficient: oldS.scale(inverse),
183
+ rightCoefficient: oldT.scale(inverse),
184
+ };
185
+ }
186
+ function henselPairStep(target, state) {
187
+ const currentModulus = state.g.modulus;
188
+ const nextModulus = currentModulus * currentModulus;
189
+ const f = changeModulus(target, nextModulus);
190
+ const g = changeModulus(state.g, nextModulus);
191
+ const h = changeModulus(state.h, nextModulus);
192
+ const s = changeModulus(state.s, nextModulus);
193
+ const t = changeModulus(state.t, nextModulus);
194
+ const error = f.subtract(g.multiply(h));
195
+ const firstDivision = s.multiply(error).divideWithRemainder(h);
196
+ const u = t
197
+ .multiply(error)
198
+ .add(firstDivision.quotient.multiply(g));
199
+ const liftedG = g.add(u);
200
+ const liftedH = h.add(firstDivision.remainder);
201
+ const bezoutError = s
202
+ .multiply(liftedG)
203
+ .add(t.multiply(liftedH))
204
+ .subtract(ModularSparsePolynomial_1.ModularSparsePolynomial.constant(f.variableCount, nextModulus, 1n));
205
+ const secondDivision = s.multiply(bezoutError).divideWithRemainder(liftedH);
206
+ const correction = t
207
+ .multiply(bezoutError)
208
+ .add(secondDivision.quotient.multiply(liftedG));
209
+ return {
210
+ g: liftedG,
211
+ h: liftedH,
212
+ s: s.subtract(secondDivision.remainder),
213
+ t: t.subtract(correction),
214
+ };
215
+ }
216
+ function productModularFactors(factors, variableCount, modulus) {
217
+ let result = ModularSparsePolynomial_1.ModularSparsePolynomial.constant(variableCount, modulus, 1n);
218
+ for (const factor of factors) {
219
+ result = result.multiply(changeModulus(factor, modulus));
220
+ }
221
+ return result;
222
+ }
223
+ function modularDerivativeOrder(polynomial, variableIndex, order) {
224
+ let result = polynomial;
225
+ let remaining = order;
226
+ while (remaining > 0n) {
227
+ result = result.derivative(variableIndex);
228
+ remaining--;
229
+ }
230
+ return result;
231
+ }
232
+ function factorialModulo(value, modulus) {
233
+ let result = 1n;
234
+ let factor = 2n;
235
+ while (factor <= value) {
236
+ result = (0, bigint_1.mod)(result * factor, modulus);
237
+ factor++;
238
+ }
239
+ return result;
240
+ }
241
+ function buildMultivariateHenselSeeds(leadingCoefficients, evaluationValues, baseFactors, variables, tailIndex, prime) {
242
+ const mainVariable = variables[0];
243
+ const tailVariable = variables[tailIndex + 1];
244
+ const seeds = [];
245
+ for (let index = 0; index < baseFactors.length; index++) {
246
+ const baseFactor = baseFactors[index];
247
+ const degree = baseFactor.degree(mainVariable);
248
+ if (degree === null) {
249
+ return null;
250
+ }
251
+ const lowerTerms = baseFactor
252
+ .terms()
253
+ .filter(term => term.exponents[mainVariable] !== degree);
254
+ const lower = new ModularSparsePolynomial_1.ModularSparsePolynomial(baseFactor.variableCount, prime, lowerTerms);
255
+ let leading = leadingCoefficients[index];
256
+ for (let laterIndex = tailIndex + 1; laterIndex < evaluationValues.length; laterIndex++) {
257
+ leading = leading.evaluateVariable(variables[laterIndex + 1], evaluationValues[laterIndex]);
258
+ }
259
+ const modularLeading = new ModularSparsePolynomial_1.ModularSparsePolynomial(leading.variableCount, prime, leading.terms());
260
+ const mainExponents = new Array(baseFactor.variableCount).fill(0n);
261
+ mainExponents[mainVariable] = degree;
262
+ const mainPower = ModularSparsePolynomial_1.ModularSparsePolynomial.monomial(baseFactor.variableCount, prime, 1n, mainExponents);
263
+ const seed = modularLeading.multiply(mainPower).add(lower);
264
+ const specializedSeed = seed.evaluateVariable(tailVariable, evaluationValues[tailIndex]);
265
+ if (!specializedSeed.equals(baseFactor)) {
266
+ return null;
267
+ }
268
+ seeds.push(seed);
269
+ }
270
+ return seeds;
271
+ }
272
+ function solveUnivariateDiophantine(baseFactors, target, mainVariable) {
273
+ const corrections = [];
274
+ for (let index = 0; index < baseFactors.length; index++) {
275
+ const others = baseFactors.filter((_factor, otherIndex) => otherIndex !== index);
276
+ const complement = productModularFactors(others, baseFactors[index].variableCount, baseFactors[index].modulus);
277
+ const bezout = modularExtendedGcdUnivariate(complement, baseFactors[index], mainVariable);
278
+ if (!bezout.gcd.isConstant()) {
279
+ return null;
280
+ }
281
+ const correction = target
282
+ .multiply(bezout.leftCoefficient)
283
+ .divideWithRemainder(baseFactors[index])
284
+ .remainder;
285
+ corrections.push(correction);
286
+ }
287
+ let reconstructed = ModularSparsePolynomial_1.ModularSparsePolynomial.zero(target.variableCount, target.modulus);
288
+ for (let index = 0; index < baseFactors.length; index++) {
289
+ const others = baseFactors.filter((_factor, otherIndex) => otherIndex !== index);
290
+ const complement = productModularFactors(others, target.variableCount, target.modulus);
291
+ reconstructed = reconstructed.add(corrections[index].multiply(complement));
292
+ }
293
+ if (!reconstructed.equals(target)) {
294
+ return null;
295
+ }
296
+ return corrections;
297
+ }
298
+ function solveMultivariateDiophantine(baseFactors, target, mainVariable, tailVariables, evaluationValues, maxTailDegree) {
299
+ if (tailVariables.length !== evaluationValues.length) {
300
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Multivariate Diophantine solving', requirement: (0, errors_1.message)('polyReqOneEvaluationPerTailVariable') }));
301
+ }
302
+ if (tailVariables.length === 0) {
303
+ return solveUnivariateDiophantine(baseFactors, target, mainVariable);
304
+ }
305
+ const tailVariable = tailVariables[tailVariables.length - 1];
306
+ const evaluationValue = evaluationValues[evaluationValues.length - 1];
307
+ const earlierVariables = tailVariables.slice(0, -1);
308
+ const earlierValues = evaluationValues.slice(0, -1);
309
+ const evaluatedFactors = baseFactors.map(factor => factor.evaluateVariable(tailVariable, evaluationValue));
310
+ const evaluatedTarget = target.evaluateVariable(tailVariable, evaluationValue);
311
+ const initial = solveMultivariateDiophantine(evaluatedFactors, evaluatedTarget, mainVariable, earlierVariables, earlierValues, maxTailDegree);
312
+ if (initial === null) {
313
+ return null;
314
+ }
315
+ const complements = baseFactors.map((_factor, index) => productModularFactors(baseFactors.filter((_other, otherIndex) => otherIndex !== index), target.variableCount, target.modulus));
316
+ let corrections = [...initial];
317
+ const tail = ModularSparsePolynomial_1.ModularSparsePolynomial.variable(target.variableCount, target.modulus, tailVariable);
318
+ const shift = tail.subtract(ModularSparsePolynomial_1.ModularSparsePolynomial.constant(target.variableCount, target.modulus, evaluationValue));
319
+ function residualFor(current) {
320
+ let residual = target;
321
+ for (let index = 0; index < current.length; index++) {
322
+ residual = residual.subtract(current[index].multiply(complements[index]));
323
+ }
324
+ return residual;
325
+ }
326
+ let residual = residualFor(corrections);
327
+ for (let order = 1n; order <= maxTailDegree && !residual.isZero(); order++) {
328
+ const derivative = modularDerivativeOrder(residual, tailVariable, order).evaluateVariable(tailVariable, evaluationValue);
329
+ const factorialInverse = (0, bigint_1.invMod)(factorialModulo(order, target.modulus), target.modulus);
330
+ if (factorialInverse < 0n) {
331
+ return null;
332
+ }
333
+ const coefficientTarget = derivative.scale(factorialInverse);
334
+ if (coefficientTarget.isZero()) {
335
+ continue;
336
+ }
337
+ const next = solveMultivariateDiophantine(evaluatedFactors, coefficientTarget, mainVariable, earlierVariables, earlierValues, maxTailDegree);
338
+ if (next === null) {
339
+ return null;
340
+ }
341
+ const shiftPower = shift.pow(order);
342
+ corrections = corrections.map((correction, index) => correction.add(next[index].multiply(shiftPower)));
343
+ residual = residualFor(corrections);
344
+ }
345
+ return residual.isZero() ? corrections : null;
346
+ }
347
+ /**
348
+ * Lifts specialized factors through one or more tail variables modulo a prime.
349
+ *
350
+ * Callers supply the fully specialized factors, the corresponding main-variable
351
+ * leading coefficients, and one evaluation value for each tail variable. The factors
352
+ * are lifted one tail variable at a time and verified against the target after every
353
+ * stage.
354
+ */
355
+ function henselLiftMultivariateFactors(polynomial, factors, leadingCoefficients, variables, evaluationValues, prime) {
356
+ if (variables.length < 2) {
357
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Multivariate Hensel lifting', requirement: (0, errors_1.message)('polyReqAtLeastTwoSelectedVariables') }));
358
+ }
359
+ if (evaluationValues.length !== variables.length - 1) {
360
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Multivariate Hensel lifting', requirement: (0, errors_1.message)('polyReqOneEvaluationPerTailVariable') }));
361
+ }
362
+ if (factors.length === 0 || factors.length !== leadingCoefficients.length) {
363
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Multivariate Hensel lifting', requirement: (0, errors_1.message)('polyReqMatchingFactorLeadingLists') }));
364
+ }
365
+ if (!(0, primeFactor_1.isPrimeBig)(prime)) {
366
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Multivariate Hensel lifting', requirement: (0, errors_1.message)('polyReqPrimeModulus') }));
367
+ }
368
+ const mainVariable = variables[0];
369
+ let maxTailDegree = 0n;
370
+ for (const variableIndex of variables.slice(1)) {
371
+ const degree = polynomial.degree(variableIndex) ?? 0n;
372
+ if (degree > maxTailDegree) {
373
+ maxTailDegree = degree;
374
+ }
375
+ }
376
+ if (prime <= maxTailDegree) {
377
+ throw new RangeError((0, errors_1.message)('polyHenselPrimeExceedsTailDegree'));
378
+ }
379
+ for (const factor of [...factors, ...leadingCoefficients]) {
380
+ if (factor.variableCount !== polynomial.variableCount) {
381
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Multivariate Hensel lifting inputs', requirement: (0, errors_1.message)('polyReqSamePolynomialRing') }));
382
+ }
383
+ }
384
+ const target = new ModularSparsePolynomial_1.ModularSparsePolynomial(polynomial.variableCount, prime, polynomial.terms());
385
+ let lifted = factors.map(factor => new ModularSparsePolynomial_1.ModularSparsePolynomial(factor.variableCount, prime, factor.terms()));
386
+ let fullySpecializedTarget = target;
387
+ for (let index = 0; index < evaluationValues.length; index++) {
388
+ fullySpecializedTarget = fullySpecializedTarget.evaluateVariable(variables[index + 1], evaluationValues[index]);
389
+ }
390
+ if (!productModularFactors(lifted, target.variableCount, prime).equals(fullySpecializedTarget)) {
391
+ return null;
392
+ }
393
+ for (let index = 0; index < lifted.length; index++) {
394
+ for (let otherIndex = index + 1; otherIndex < lifted.length; otherIndex++) {
395
+ const gcd = modularExtendedGcdUnivariate(lifted[index], lifted[otherIndex], mainVariable).gcd;
396
+ if (!gcd.isConstant()) {
397
+ return null;
398
+ }
399
+ }
400
+ }
401
+ for (let tailIndex = 0; tailIndex < variables.length - 1; tailIndex++) {
402
+ const tailVariable = variables[tailIndex + 1];
403
+ let stageTarget = target;
404
+ for (let laterIndex = tailIndex + 1; laterIndex < evaluationValues.length; laterIndex++) {
405
+ stageTarget = stageTarget.evaluateVariable(variables[laterIndex + 1], evaluationValues[laterIndex]);
406
+ }
407
+ const specializedTarget = stageTarget.evaluateVariable(tailVariable, evaluationValues[tailIndex]);
408
+ if (!productModularFactors(lifted, target.variableCount, prime).equals(specializedTarget)) {
409
+ return null;
410
+ }
411
+ const seeds = buildMultivariateHenselSeeds(leadingCoefficients, evaluationValues, lifted, variables, tailIndex, prime);
412
+ if (seeds === null) {
413
+ return null;
414
+ }
415
+ lifted = [...seeds];
416
+ const tail = ModularSparsePolynomial_1.ModularSparsePolynomial.variable(target.variableCount, prime, tailVariable);
417
+ const shift = tail.subtract(ModularSparsePolynomial_1.ModularSparsePolynomial.constant(target.variableCount, prime, evaluationValues[tailIndex]));
418
+ const tailDegree = stageTarget.degree(tailVariable) ?? 0n;
419
+ const baseFactors = lifted.map(factor => factor.evaluateVariable(tailVariable, evaluationValues[tailIndex]));
420
+ for (let order = 1n; order <= tailDegree; order++) {
421
+ const residual = stageTarget.subtract(productModularFactors(lifted, target.variableCount, prime));
422
+ if (residual.isZero()) {
423
+ break;
424
+ }
425
+ const derivative = modularDerivativeOrder(residual, tailVariable, order).evaluateVariable(tailVariable, evaluationValues[tailIndex]);
426
+ const factorialInverse = (0, bigint_1.invMod)(factorialModulo(order, prime), prime);
427
+ if (factorialInverse < 0n) {
428
+ return null;
429
+ }
430
+ const correctionTarget = derivative.scale(factorialInverse);
431
+ if (correctionTarget.isZero()) {
432
+ continue;
433
+ }
434
+ const corrections = solveMultivariateDiophantine(baseFactors, correctionTarget, mainVariable, variables.slice(1, tailIndex + 1), evaluationValues.slice(0, tailIndex), maxTailDegree);
435
+ if (corrections === null) {
436
+ return null;
437
+ }
438
+ const shiftPower = shift.pow(order);
439
+ lifted = lifted.map((factor, index) => factor.add(corrections[index].multiply(shiftPower)));
440
+ }
441
+ if (!productModularFactors(lifted, target.variableCount, prime).equals(stageTarget)) {
442
+ return null;
443
+ }
444
+ }
445
+ if (!productModularFactors(lifted, target.variableCount, prime).equals(target)) {
446
+ return null;
447
+ }
448
+ return lifted.map(factor => factor.toSymmetricIntegerPolynomial()
449
+ .primitivePart()
450
+ .normalizeLeadingSign('lex'));
451
+ }
452
+ function liftFactorGroup(target, prime, primeFactors, variableIndex, targetModulus) {
453
+ if (primeFactors.length === 1) {
454
+ const targetAtModulus = changeModulus(target, targetModulus);
455
+ const leading = targetAtModulus.leadingTerm();
456
+ if (leading === null) {
457
+ throw new RangeError((0, errors_1.message)('polyHenselZeroFactorGroup'));
458
+ }
459
+ const inverse = (0, bigint_1.invMod)(leading.coefficient, targetModulus);
460
+ if (inverse < 0n) {
461
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Hensel lifting', requirement: (0, errors_1.message)('polyReqInvertibleLeadingCoefficient') }));
462
+ }
463
+ return [targetAtModulus.scale(inverse)];
464
+ }
465
+ const split = Math.floor(primeFactors.length / 2);
466
+ const leftPrimeFactors = primeFactors.slice(0, split);
467
+ const rightPrimeFactors = primeFactors.slice(split);
468
+ const targetPrime = changeModulus(target, prime);
469
+ const targetLeading = targetPrime.leadingTerm();
470
+ if (targetLeading === null) {
471
+ throw new RangeError((0, errors_1.message)('polyHenselCannotLiftZero'));
472
+ }
473
+ const leftProduct = productModularFactors(leftPrimeFactors, target.variableCount, prime).scale(targetLeading.coefficient);
474
+ const rightProduct = productModularFactors(rightPrimeFactors, target.variableCount, prime);
475
+ const bezout = modularExtendedGcdUnivariate(leftProduct, rightProduct, variableIndex);
476
+ if (!bezout.gcd.isConstant()) {
477
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Hensel lifting', requirement: (0, errors_1.message)('polyReqPairwiseCoprimeModularFactors') }));
478
+ }
479
+ let state = {
480
+ g: leftProduct,
481
+ h: rightProduct,
482
+ s: bezout.leftCoefficient,
483
+ t: bezout.rightCoefficient,
484
+ };
485
+ while (state.g.modulus < targetModulus) {
486
+ state = henselPairStep(target, state);
487
+ }
488
+ if (state.g.modulus !== targetModulus) {
489
+ throw new Error((0, errors_1.message)('polyHenselModulusExceeded'));
490
+ }
491
+ return [
492
+ ...liftFactorGroup(state.g, prime, leftPrimeFactors, variableIndex, targetModulus),
493
+ ...liftFactorGroup(state.h, prime, rightPrimeFactors, variableIndex, targetModulus),
494
+ ];
495
+ }
496
+ /**
497
+ * Lifts pairwise-coprime monic factors from F_p[x] to a larger prime-power modulus.
498
+ *
499
+ * The achieved modulus is obtained by repeated quadratic Hensel steps, so callers
500
+ * should pass a prime power of the form p^(2^k). The lifted factors remain monic and
501
+ * reconstruct the integer polynomial after multiplication by its leading coefficient.
502
+ */
503
+ function henselLiftUnivariateFactors(polynomial, prime, factors, variableIndex, targetModulus) {
504
+ if (!(0, primeFactor_1.isPrimeBig)(prime)) {
505
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Hensel lifting', requirement: (0, errors_1.message)('polyReqPrimeBaseModulus') }));
506
+ }
507
+ if (factors.length === 0) {
508
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Hensel lifting', requirement: (0, errors_1.message)('polyReqAtLeastOneModularFactor') }));
509
+ }
510
+ if (targetModulus < prime) {
511
+ throw new RangeError((0, errors_1.message)('polyHenselTargetNotSmaller'));
512
+ }
513
+ polynomial.degree(variableIndex);
514
+ for (const activeVariable of polynomial.variables()) {
515
+ if (activeVariable !== variableIndex) {
516
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Hensel lifting', requirement: (0, errors_1.message)('polyReqUnivariateIntegerPolynomial') }));
517
+ }
518
+ }
519
+ for (const factor of factors) {
520
+ if (factor.variableCount !== polynomial.variableCount ||
521
+ factor.modulus !== prime) {
522
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Hensel lifting', requirement: (0, errors_1.message)('polyReqFactorsSameRingAndPrime') }));
523
+ }
524
+ for (const activeVariable of factor.variables()) {
525
+ if (activeVariable !== variableIndex) {
526
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Hensel lifting', requirement: (0, errors_1.message)('polyReqUnivariateFactors') }));
527
+ }
528
+ }
529
+ if (!factor.equals(factor.monic())) {
530
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Hensel lifting', requirement: (0, errors_1.message)('polyReqMonicModularFactors') }));
531
+ }
532
+ }
533
+ let expectedModulus = prime;
534
+ while (expectedModulus < targetModulus) {
535
+ expectedModulus *= expectedModulus;
536
+ }
537
+ if (expectedModulus !== targetModulus) {
538
+ throw new RangeError((0, errors_1.message)('polyHenselTargetRepeatedSquaring'));
539
+ }
540
+ const polynomialPrime = integerPolynomialModulo(polynomial, prime);
541
+ const leading = polynomialPrime.leadingTerm();
542
+ if (leading === null) {
543
+ throw new RangeError((0, errors_1.message)('polyCannotFactorZeroPolynomial', { operation: 'Hensel lifting' }));
544
+ }
545
+ if ((0, bigint_1.invMod)(leading.coefficient, prime) < 0n) {
546
+ throw new RangeError((0, errors_1.message)('polyRequires', { operation: 'Hensel lifting', requirement: (0, errors_1.message)('polyReqIntegerLeadingCoefficientInvertible') }));
547
+ }
548
+ const modularProduct = productModularFactors(factors, polynomial.variableCount, prime).scale(leading.coefficient);
549
+ if (!modularProduct.equals(polynomialPrime)) {
550
+ throw new RangeError((0, errors_1.message)('polyHenselFactorsReconstructModuloBase'));
551
+ }
552
+ const target = integerPolynomialModulo(polynomial, targetModulus);
553
+ const lifted = liftFactorGroup(target, prime, factors, variableIndex, targetModulus);
554
+ const targetLeading = target.leadingTerm();
555
+ if (targetLeading === null) {
556
+ throw new Error((0, errors_1.message)('polyHenselLeadingLost'));
557
+ }
558
+ const reconstructed = productModularFactors(lifted, polynomial.variableCount, targetModulus).scale(targetLeading.coefficient);
559
+ if (!reconstructed.equals(target)) {
560
+ throw new Error((0, errors_1.message)('polyHenselReconstructionFailed'));
561
+ }
562
+ return lifted;
563
+ }
564
+ /**
565
+ * Factors a square-free univariate polynomial over a prime field with Berlekamp's method.
566
+ *
567
+ * The result contains monic irreducible factors whose product is the monic input.
568
+ * Constants return an empty list.
569
+ */
570
+ function factorSquareFreeUnivariateFiniteField(polynomial, variableIndex) {
571
+ const degree = assertSquareFreeUnivariate(polynomial, variableIndex);
572
+ if (degree === 0) {
573
+ return [];
574
+ }
575
+ const input = polynomial.monic();
576
+ if (degree === 1) {
577
+ return [input];
578
+ }
579
+ const x = ModularSparsePolynomial_1.ModularSparsePolynomial.variable(input.variableCount, input.modulus, variableIndex);
580
+ const xToP = polynomialPowMod(x, input.modulus, input);
581
+ const matrix = Array.from({ length: degree }, () => new Array(degree).fill(0n));
582
+ let columnPolynomial = ModularSparsePolynomial_1.ModularSparsePolynomial.constant(input.variableCount, input.modulus, 1n);
583
+ for (let column = 0; column < degree; column++) {
584
+ for (let row = 0; row < degree; row++) {
585
+ const exponents = new Array(input.variableCount).fill(0n);
586
+ exponents[variableIndex] = BigInt(row);
587
+ matrix[row][column] = columnPolynomial.coefficient(exponents);
588
+ }
589
+ matrix[column][column] = (0, bigint_1.mod)(matrix[column][column] - 1n, input.modulus);
590
+ columnPolynomial = polynomialRemainder(columnPolynomial.multiply(xToP), input);
591
+ }
592
+ const kernel = nullspaceModulo(matrix, input.modulus);
593
+ if (kernel.length <= 1) {
594
+ return [input];
595
+ }
596
+ let factors = [input];
597
+ for (const vector of kernel) {
598
+ if (factors.length >= kernel.length) {
599
+ break;
600
+ }
601
+ const splitter = vectorPolynomial(vector, input.variableCount, input.modulus, variableIndex);
602
+ if (splitter.isConstant()) {
603
+ continue;
604
+ }
605
+ let residue = 0n;
606
+ while (residue < input.modulus && factors.length < kernel.length) {
607
+ const shifted = splitter.subtract(ModularSparsePolynomial_1.ModularSparsePolynomial.constant(input.variableCount, input.modulus, residue));
608
+ const refined = [];
609
+ for (const factor of factors) {
610
+ const factorDegree = factor.degree(variableIndex);
611
+ if (factorDegree === null || factorDegree <= 1n) {
612
+ refined.push(factor);
613
+ continue;
614
+ }
615
+ const divisor = (0, modularGcd_1.modularGcdUnivariate)(factor, shifted, variableIndex);
616
+ if (divisor.isConstant() || divisor.equals(factor)) {
617
+ refined.push(factor);
618
+ continue;
619
+ }
620
+ const quotient = factor.divideExact(divisor);
621
+ if (quotient === null) {
622
+ throw new Error((0, errors_1.message)('polyBerlekampNonExactSplit'));
623
+ }
624
+ refined.push(divisor.monic(), quotient.monic());
625
+ }
626
+ factors = refined;
627
+ residue++;
628
+ }
629
+ }
630
+ if (factors.length !== kernel.length) {
631
+ throw new Error((0, errors_1.message)('polyBerlekampIncompleteSplit'));
632
+ }
633
+ let reconstructed = ModularSparsePolynomial_1.ModularSparsePolynomial.constant(input.variableCount, input.modulus, 1n);
634
+ for (const factor of factors) {
635
+ reconstructed = reconstructed.multiply(factor);
636
+ }
637
+ if (!reconstructed.equals(input)) {
638
+ throw new Error((0, errors_1.message)('polyBerlekampReconstructionFailed'));
639
+ }
640
+ return factors.sort((left, right) => {
641
+ const leftDegree = left.degree(variableIndex) ?? 0n;
642
+ const rightDegree = right.degree(variableIndex) ?? 0n;
643
+ if (leftDegree !== rightDegree) {
644
+ return leftDegree < rightDegree ? -1 : 1;
645
+ }
646
+ const leftTerms = left.terms();
647
+ const rightTerms = right.terms();
648
+ const count = Math.min(leftTerms.length, rightTerms.length);
649
+ for (let index = 0; index < count; index++) {
650
+ const leftExponent = leftTerms[index].exponents[variableIndex];
651
+ const rightExponent = rightTerms[index].exponents[variableIndex];
652
+ if (leftExponent !== rightExponent) {
653
+ return leftExponent < rightExponent ? -1 : 1;
654
+ }
655
+ if (leftTerms[index].coefficient !== rightTerms[index].coefficient) {
656
+ return leftTerms[index].coefficient < rightTerms[index].coefficient ? -1 : 1;
657
+ }
658
+ }
659
+ return leftTerms.length - rightTerms.length;
660
+ });
661
+ }