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 @@
1
+ export declare function loadAlgebraFunctions(): void;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadAlgebraFunctions = loadAlgebraFunctions;
4
+ const constants_1 = require("../core/classes/parser/constants");
5
+ const dispatch_1 = require("../core/dispatch");
6
+ const adapters_1 = require("./adapters");
7
+ const factor_1 = require("./factor/factor");
8
+ const gcd_1 = require("./gcd/gcd");
9
+ const groebner_1 = require("./groebner");
10
+ const partfrac_1 = require("./partfrac");
11
+ const simplify_1 = require("./simplify/simplify");
12
+ function loadAlgebraFunctions() {
13
+ Object.assign(dispatch_1.mathFunctionRegistry, {
14
+ polyfactors: (0, dispatch_1.systemFunction)({ fn: factor_1.polyFactors, minArgs: 1, maxArgs: 1, distElWise: false }),
15
+ factor: (0, dispatch_1.systemFunction)({ fn: factor_1.factor, minArgs: 1, maxArgs: 1, distElWise: true }),
16
+ [constants_1.PFACTOR]: (0, dispatch_1.systemFunction)({ fn: factor_1.pfactor, minArgs: 1, maxArgs: 1, distElWise: false }),
17
+ [constants_1.PFACTORD]: (0, dispatch_1.systemFunction)({ fn: factor_1.pfactord, minArgs: 1, maxArgs: 1, distElWise: false }),
18
+ simplify: (0, dispatch_1.systemFunction)({ fn: simplify_1.simplify, minArgs: 1, maxArgs: 1, distElWise: true }),
19
+ partfrac: (0, dispatch_1.systemFunction)({ fn: partfrac_1.partfrac, minArgs: 1, maxArgs: 2, distElWise: true }),
20
+ gcd: (0, dispatch_1.systemFunction)({ fn: gcd_1.gcd, minArgs: 2, maxArgs: 2, distElWise: true }),
21
+ lcm: (0, dispatch_1.systemFunction)({ fn: gcd_1.lcm, minArgs: 2, maxArgs: 2, distElWise: true }),
22
+ groebner: (0, dispatch_1.systemFunction)({ fn: groebner_1.groebner, minArgs: 1, maxArgs: 2, distElWise: false }),
23
+ sqcomp: (0, dispatch_1.systemFunction)({ fn: adapters_1.completeSquare, minArgs: 1, maxArgs: 2, distElWise: true }),
24
+ });
25
+ }
@@ -1,3 +1,4 @@
1
+ import { Dictionary } from '../../core/classes/dictionary/Dictionary';
1
2
  import { Expression } from '../../core/classes/expression/Expression';
2
3
  import { Vector } from '../../core/classes/vector/Vector';
3
4
  import type { ExpressionInput } from '../../core/types';
@@ -15,6 +16,20 @@ import type { ExpressionInput } from '../../core/types';
15
16
  * @returns A factored expression or an unevaluated symbolic `factor` call.
16
17
  */
17
18
  export declare function factor(x: ExpressionInput): Expression;
19
+ /**
20
+ * Returns the prime factors of a positive integer in ascending order.
21
+ *
22
+ * Repeated factors are retained, so `pfactor(100)` returns `[2, 2, 5, 5]`.
23
+ * The value 1 has no prime factors and returns an empty Vector.
24
+ */
25
+ export declare function pfactor(x: ExpressionInput): Vector;
26
+ /**
27
+ * Returns the prime-factor multiplicities of a positive integer.
28
+ *
29
+ * Dictionary keys are prime numbers in ascending order and values are their occurrence
30
+ * counts. For example, `pfactord(100)` returns `{2 => 2, 5 => 2}`.
31
+ */
32
+ export declare function pfactord(x: ExpressionInput): Dictionary;
18
33
  /**
19
34
  * Factors the numerator of polynomial-like input into Expression factors.
20
35
  *
@@ -1,21 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.factor = factor;
4
+ exports.pfactor = pfactor;
5
+ exports.pfactord = pfactord;
4
6
  exports.polyFactorExpressions = polyFactorExpressions;
5
7
  exports.polyFactors = polyFactors;
6
8
  exports.factorExpressionParts = factorExpressionParts;
7
9
  exports.factors = factors;
8
10
  exports.numberFactors = numberFactors;
11
+ const Dictionary_1 = require("../../core/classes/dictionary/Dictionary");
9
12
  const analysis_1 = require("../../core/classes/expression/analysis");
10
13
  const Expression_1 = require("../../core/classes/expression/Expression");
14
+ const shortcuts_1 = require("../../core/classes/expression/shortcuts");
11
15
  const constants_1 = require("../../core/classes/parser/constants");
12
16
  const multiply_1 = require("../../core/classes/parser/operations/multiply");
13
- const Polynomial_1 = require("../../core/classes/polynomial/Polynomial");
17
+ const SparsePolynomialAdapter_1 = require("../../core/classes/polynomial/SparsePolynomialAdapter");
14
18
  const Vector_1 = require("../../core/classes/vector/Vector");
19
+ const errors_1 = require("../../core/errors");
15
20
  const primeFactor_1 = require("../../core/functions/bigint/primeFactor");
16
21
  const subst_1 = require("../../core/functions/subst");
17
- const adapters_1 = require("../adapters");
18
- const factor_1 = require("../algorithms/factor");
22
+ const SparsePolynomialFactor_1 = require("../polynomial/SparsePolynomialFactor");
23
+ const SparsePolynomialMultivariateFactor_1 = require("../polynomial/SparsePolynomialMultivariateFactor");
19
24
  const polynomialize_1 = require("../polynomialize");
20
25
  /**
21
26
  * Factors polynomial-like numerator and denominator components of an expression.
@@ -55,6 +60,15 @@ function factor(x) {
55
60
  else if (x.isVAR()) {
56
61
  retval = x;
57
62
  }
63
+ else if (x.isFunction()) {
64
+ const multiplier = x.getMultiplier();
65
+ const power = x.getPower();
66
+ retval = Expression_1.Expression.toFunction(x.name, x.getArguments().map(argument => factor(argument)));
67
+ retval = retval.pow(power).times(multiplier);
68
+ }
69
+ else if (x.isPolynomialLike()) {
70
+ retval = polyFactors(x).prod();
71
+ }
58
72
  else {
59
73
  const factored = factors(x);
60
74
  retval = factored.numerator.prod().div(factored.denominator.prod());
@@ -65,6 +79,56 @@ function factor(x) {
65
79
  }
66
80
  return retval;
67
81
  }
82
+ /**
83
+ * Returns the prime factors of a positive integer in ascending order.
84
+ *
85
+ * Repeated factors are retained, so `pfactor(100)` returns `[2, 2, 5, 5]`.
86
+ * The value 1 has no prime factors and returns an empty Vector.
87
+ */
88
+ function pfactor(x) {
89
+ const input = Expression_1.Expression.create(x);
90
+ if (!input.isNUM() || !input.isInteger() || input.lte((0, shortcuts_1.zero)())) {
91
+ throw new errors_1.UnexpectedInputError((0, errors_1.message)('wrongInput', {
92
+ expected: 'a positive integer',
93
+ received: input.text(),
94
+ }));
95
+ }
96
+ const value = input.getMultiplier().numerator;
97
+ if (value === 1n) {
98
+ return new Vector_1.Vector();
99
+ }
100
+ const factors = (0, primeFactor_1.primeFactorsBig)(value).factors.map(factor => Expression_1.Expression.Number(factor));
101
+ return new Vector_1.Vector(factors);
102
+ }
103
+ /**
104
+ * Returns the prime-factor multiplicities of a positive integer.
105
+ *
106
+ * Dictionary keys are prime numbers in ascending order and values are their occurrence
107
+ * counts. For example, `pfactord(100)` returns `{2 => 2, 5 => 2}`.
108
+ */
109
+ function pfactord(x) {
110
+ const input = Expression_1.Expression.create(x);
111
+ if (!input.isNUM() || !input.isInteger() || input.lte((0, shortcuts_1.zero)())) {
112
+ throw new errors_1.UnexpectedInputError((0, errors_1.message)('wrongInput', {
113
+ expected: 'a positive integer',
114
+ received: input.text(),
115
+ }));
116
+ }
117
+ const value = input.getMultiplier().numerator;
118
+ if (value === 1n) {
119
+ return new Dictionary_1.Dictionary();
120
+ }
121
+ const counts = (0, primeFactor_1.primeFactorCounts)(value);
122
+ const retval = new Dictionary_1.Dictionary();
123
+ for (const prime of Object.keys(counts).sort((a, b) => {
124
+ const left = BigInt(a);
125
+ const right = BigInt(b);
126
+ return left < right ? -1 : left > right ? 1 : 0;
127
+ })) {
128
+ retval.set(prime, Expression_1.Expression.Number(counts[prime]));
129
+ }
130
+ return retval;
131
+ }
68
132
  /**
69
133
  * Factors the numerator of polynomial-like input into Expression factors.
70
134
  *
@@ -77,16 +141,39 @@ function polyFactorExpressions(x) {
77
141
  const expr = (0, analysis_1.normalizeMultiplierDenominators)(Expression_1.Expression.create(x));
78
142
  const num = expr.getNumerator();
79
143
  const den = expr.getDenominator();
80
- // MultiPoly strictly works in Z. Irrational coefficients
81
- // must first be promoted to variables.
144
+ // Irrational coefficients must first be promoted to variables.
82
145
  const [subbed, map] = (0, subst_1.uSubConstants)(num);
83
- const p = new Polynomial_1.Polynomial(subbed);
84
- const variables = p.variables;
85
- const { poly } = (0, adapters_1.polynomialToMultiPoly)(p);
86
- // Factor it
87
- const factors = (0, factor_1.factorPoly)(poly, variables);
88
- // Remove the u-substitution
89
- retval = (0, adapters_1.factorsToExpressions)(factors, variables).map(f => (0, subst_1.uUnSub)(f, map).div(den));
146
+ const converted = (0, SparsePolynomialAdapter_1.expressionToSparsePolynomial)(subbed);
147
+ const variables = converted.variables;
148
+ const sparse = converted.polynomial;
149
+ if (variables.length === 0) {
150
+ retval = [Expression_1.Expression.Number(sparse.constantTerm())];
151
+ }
152
+ else {
153
+ const variableIndices = variables.map((_variable, index) => index);
154
+ const factorization = variables.length === 1
155
+ ? (0, SparsePolynomialFactor_1.factorUnivariateInteger)(sparse, 0)
156
+ : (0, SparsePolynomialMultivariateFactor_1.factorMultivariateInteger)(sparse, variableIndices);
157
+ retval = [];
158
+ if (factorization.content !== 1n) {
159
+ retval.push(Expression_1.Expression.Number(factorization.content));
160
+ }
161
+ for (const entry of factorization.factors) {
162
+ let factor = (0, SparsePolynomialAdapter_1.sparsePolynomialToExpression)(entry.factor, variables);
163
+ if (entry.multiplicity > 1n) {
164
+ factor = factor.pow(Expression_1.Expression.Number(entry.multiplicity));
165
+ }
166
+ retval.push(factor);
167
+ }
168
+ if (retval.length === 0) {
169
+ throw new Error((0, errors_1.message)('factorizationNoFactors'));
170
+ }
171
+ }
172
+ // Remove the u-substitution and restore the cleared denominator once.
173
+ retval = retval.map(factor => (0, subst_1.uUnSub)(factor, map));
174
+ if (!den.isOne()) {
175
+ retval[0] = retval[0].div(den);
176
+ }
90
177
  }
91
178
  catch {
92
179
  retval = [Expression_1.Expression.create(x)];
@@ -4,11 +4,12 @@ import type { ExpressionInput } from '../../core/types';
4
4
  * Computes a symbolic greatest common divisor over rational polynomial structure.
5
5
  *
6
6
  * @remarks
7
- * Numerators and denominators are polynomialized, function-valued or irrational
8
- * constants may be temporarily substituted, and the multivariate Zippel GCD is
9
- * verified by exact polynomial division. Factoring supplies an expensive final
10
- * fallback. When conversion or the supported polynomial algorithms fail, the
11
- * result remains symbolic as `gcd(x, y)`.
7
+ * Numerators and denominators are polynomialized before exact sparse integer GCD
8
+ * reconstruction. Rational polynomial coefficients are cleared to integers and
9
+ * their shared clearing denominator is restored afterward. Function-valued,
10
+ * exponential, and irrational constants use the existing polynomialization
11
+ * substitutions and are restored after the numerator and denominator GCDs are
12
+ * combined. Unsupported inputs remain symbolic as `gcd(x, y)`.
12
13
  *
13
14
  * @param x - First expression-compatible operand.
14
15
  * @param y - Second expression-compatible operand.
@@ -18,8 +19,8 @@ export declare function gcd(x: ExpressionInput, y: ExpressionInput): Expression;
18
19
  /**
19
20
  * Returns the least common multiple of two expressions.
20
21
  *
21
- * Numeric inputs reuse exact `Rational` arithmetic. Polynomial expressions use
22
- * the existing GCD normalization so shared symbolic factors are retained.
22
+ * Numeric inputs reuse exact Rational arithmetic. Polynomial expressions use
23
+ * the polynomial GCD so shared symbolic factors are retained.
23
24
  *
24
25
  * @param x - First expression-compatible operand.
25
26
  * @param y - Second expression-compatible operand.
@@ -6,22 +6,21 @@ const collect_1 = require("../../core/classes/expression/collect");
6
6
  const Expression_1 = require("../../core/classes/expression/Expression");
7
7
  const shortcuts_1 = require("../../core/classes/expression/shortcuts");
8
8
  const constants_1 = require("../../core/classes/parser/constants");
9
- const Polynomial_1 = require("../../core/classes/polynomial/Polynomial");
10
- const utils_1 = require("../../core/classes/polynomial/utils");
9
+ const SparsePolynomialAdapter_1 = require("../../core/classes/polynomial/SparsePolynomialAdapter");
10
+ const bigint_1 = require("../../core/functions/bigint/bigint");
11
11
  const subst_1 = require("../../core/functions/subst");
12
- const adapters_1 = require("../adapters");
13
- const gcd_1 = require("../algorithms/gcd");
14
- const factor_1 = require("../factor/factor");
12
+ const SparsePolynomialGcd_1 = require("../polynomial/SparsePolynomialGcd");
15
13
  const polynomialize_1 = require("../polynomialize");
16
14
  /**
17
15
  * Computes a symbolic greatest common divisor over rational polynomial structure.
18
16
  *
19
17
  * @remarks
20
- * Numerators and denominators are polynomialized, function-valued or irrational
21
- * constants may be temporarily substituted, and the multivariate Zippel GCD is
22
- * verified by exact polynomial division. Factoring supplies an expensive final
23
- * fallback. When conversion or the supported polynomial algorithms fail, the
24
- * result remains symbolic as `gcd(x, y)`.
18
+ * Numerators and denominators are polynomialized before exact sparse integer GCD
19
+ * reconstruction. Rational polynomial coefficients are cleared to integers and
20
+ * their shared clearing denominator is restored afterward. Function-valued,
21
+ * exponential, and irrational constants use the existing polynomialization
22
+ * substitutions and are restored after the numerator and denominator GCDs are
23
+ * combined. Unsupported inputs remain symbolic as `gcd(x, y)`.
25
24
  *
26
25
  * @param x - First expression-compatible operand.
27
26
  * @param y - Second expression-compatible operand.
@@ -34,10 +33,10 @@ function gcd(x, y) {
34
33
  const asDecimal = x.hasDecimal() || y.hasDecimal();
35
34
  const { numerator: ax, denominator: bx, map } = (0, polynomialize_1.polynomialize)(x);
36
35
  const { numerator: px, denominator: qx, map: finalMap } = (0, polynomialize_1.polynomialize)(y, map);
37
- const vars = (0, collect_1.collectVariablesSet)([ax, bx, px, qx]);
38
- const g0 = expressionGCD(ax, px, vars);
39
- const g1 = expressionGCD(bx, qx, vars);
40
- const retval = (0, subst_1.uUnSub)(g0.div(g1), finalMap);
36
+ const variables = (0, collect_1.collectVariablesSet)([ax, bx, px, qx]);
37
+ const numeratorGcd = expressionGCD(ax, px, variables);
38
+ const denominatorGcd = expressionGCD(bx, qx, variables);
39
+ const retval = (0, subst_1.uUnSub)(numeratorGcd.div(denominatorGcd), finalMap);
41
40
  retval.getMultiplier().asDecimal = asDecimal;
42
41
  return retval;
43
42
  }
@@ -47,8 +46,8 @@ function gcd(x, y) {
47
46
  /**
48
47
  * Returns the least common multiple of two expressions.
49
48
  *
50
- * Numeric inputs reuse exact `Rational` arithmetic. Polynomial expressions use
51
- * the existing GCD normalization so shared symbolic factors are retained.
49
+ * Numeric inputs reuse exact Rational arithmetic. Polynomial expressions use
50
+ * the polynomial GCD so shared symbolic factors are retained.
52
51
  *
53
52
  * @param x - First expression-compatible operand.
54
53
  * @param y - Second expression-compatible operand.
@@ -71,71 +70,26 @@ function lcm(x, y) {
71
70
  return retval;
72
71
  }
73
72
  function expressionGCD(x, y, variables) {
74
- let retval;
75
73
  if (x.isNUM() && y.isNUM()) {
76
- retval = Expression_1.Expression.create(x.getMultiplier().GCD(y.getMultiplier()));
74
+ return Expression_1.Expression.create(x.getMultiplier().GCD(y.getMultiplier()));
77
75
  }
78
- else {
79
- const f = new Polynomial_1.Polynomial(x);
80
- const g = new Polynomial_1.Polynomial(y);
81
- if (f.isZero() && g.isZero()) {
82
- return (0, shortcuts_1.zero)();
83
- }
84
- if (f.isZero()) {
85
- return Expression_1.Expression.create(y);
86
- }
87
- if (g.isZero()) {
88
- return Expression_1.Expression.create(x);
89
- }
90
- const { mGCD, p, q } = f.stripMonomialGCD(g);
91
- variables ??= [...new Set(p.variables.concat(q.variables))].sort();
92
- const { poly: poly1 } = (0, adapters_1.polynomialToMultiPoly)(p, variables);
93
- const { poly: poly2 } = (0, adapters_1.polynomialToMultiPoly)(q, variables);
94
- const g0 = (0, gcd_1.zippelGCDMulti)(poly1, poly2, variables);
95
- retval = (0, adapters_1.multiPolyToExpression)(g0, variables);
96
- // Verify
97
- if (!(0, utils_1.divide)(p, retval)[1].isZero()) {
98
- retval = (0, shortcuts_1.one)();
99
- }
100
- // Don't give up just yet. Try by factor
101
- if (retval.isOne()) {
102
- retval = gcdByCommonFactors(p.getExpression(), q.getExpression());
103
- }
104
- // Put back the monomial gcd
105
- retval = retval.times(mGCD.getExpression());
76
+ if (x.isZero() && y.isZero()) {
77
+ return (0, shortcuts_1.zero)();
106
78
  }
107
- return retval;
108
- }
109
- /**
110
- * Factors both expressions and compares their factors as a last-resort GCD strategy.
111
- *
112
- * Factoring is expensive, so this path runs only after exact polynomial reduction fails
113
- * to find a nontrivial divisor.
114
- */
115
- function gcdByCommonFactors(f, g) {
116
- let retval = (0, shortcuts_1.one)();
117
- if (!f.isProduct()) {
118
- f = (0, factor_1.factor)(f);
79
+ if (x.isZero()) {
80
+ return Expression_1.Expression.create(y);
119
81
  }
120
- if (!g.isProduct()) {
121
- g = (0, factor_1.factor)(g);
82
+ if (y.isZero()) {
83
+ return Expression_1.Expression.create(x);
122
84
  }
123
- // Only proceed if both are products
124
- if (f.isProduct() && g.isProduct()) {
125
- const fArray = f.elementsArray();
126
- const gArray = g.elementsArray();
127
- // Compare them
128
- for (const a of fArray) {
129
- for (const b of gArray) {
130
- // If they're equal then they're a common factor
131
- if (a.eq(b)) {
132
- retval = retval.times(a);
133
- }
134
- else if (a.isProduct() && b.isProduct()) {
135
- return gcd(a, b);
136
- }
137
- }
138
- }
139
- }
140
- return retval;
85
+ variables ??= (0, collect_1.collectVariablesSet)([x, y]);
86
+ const left = (0, SparsePolynomialAdapter_1.expressionToIntegerSparsePolynomial)(x, variables);
87
+ const right = (0, SparsePolynomialAdapter_1.expressionToIntegerSparsePolynomial)(y, variables);
88
+ const variableIndices = variables.map((_variable, index) => index);
89
+ const sparseGcd = (0, SparsePolynomialGcd_1.sparsePolynomialGcd)(left.polynomial, right.polynomial, variableIndices);
90
+ const clearingDenominator = (0, bigint_1.GCD)(left.denominator, right.denominator);
91
+ const retval = (0, SparsePolynomialAdapter_1.sparsePolynomialToExpression)(sparseGcd, variables);
92
+ return clearingDenominator === 1n
93
+ ? retval
94
+ : retval.div(Expression_1.Expression.Number(clearingDenominator));
141
95
  }
@@ -6,8 +6,8 @@ import type { ExpressionInput } from '../core/types';
6
6
  * @remarks
7
7
  * All generators are converted using one variable order so exponent indices remain
8
8
  * consistent. Rational coefficient denominators are cleared per generator before the
9
- * exact integer-coefficient `MultiPoly` engine runs; multiplying a generator by a
10
- * nonzero scalar preserves the generated ideal. When `vars` is omitted, variables are
9
+ * exact integer-coefficient sparse engine runs; multiplying a generator by a nonzero
10
+ * scalar preserves the generated ideal. When `vars` is omitted, variables are
11
11
  * collected across every generator.
12
12
  *
13
13
  * This convenience wrapper uses lexicographic order and a reduced, deterministically
@@ -1,12 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.groebner = groebner;
4
- const analysis_1 = require("../core/classes/expression/analysis");
5
4
  const collect_1 = require("../core/classes/expression/collect");
6
5
  const Expression_1 = require("../core/classes/expression/Expression");
7
- const Polynomial_1 = require("../core/classes/polynomial/Polynomial");
6
+ const SparsePolynomialAdapter_1 = require("../core/classes/polynomial/SparsePolynomialAdapter");
8
7
  const Vector_1 = require("../core/classes/vector/Vector");
9
- const adapters_1 = require("./adapters");
10
8
  const groebnerBase_1 = require("./algorithms/groebnerBase");
11
9
  /**
12
10
  * Computes an expression-facing Groebner basis for polynomial generators.
@@ -14,8 +12,8 @@ const groebnerBase_1 = require("./algorithms/groebnerBase");
14
12
  * @remarks
15
13
  * All generators are converted using one variable order so exponent indices remain
16
14
  * consistent. Rational coefficient denominators are cleared per generator before the
17
- * exact integer-coefficient `MultiPoly` engine runs; multiplying a generator by a
18
- * nonzero scalar preserves the generated ideal. When `vars` is omitted, variables are
15
+ * exact integer-coefficient sparse engine runs; multiplying a generator by a nonzero
16
+ * scalar preserves the generated ideal. When `vars` is omitted, variables are
19
17
  * collected across every generator.
20
18
  *
21
19
  * This convenience wrapper uses lexicographic order and a reduced, deterministically
@@ -32,11 +30,7 @@ function groebner(expressionArray, vars) {
32
30
  // Get the unified variable list across ALL generators
33
31
  vars ??= (0, collect_1.collectVariablesSet)(expressions);
34
32
  // Convert each polynomial using the unified variable list so indices are consistent.
35
- // Since the Groebner core operates on MultiPoly over Z, clear denominators per generator
36
- // before converting so rational-coefficient inputs are lifted into equivalent integer ones.
37
- const polys = expressions.map(e => {
38
- const cleared = (0, analysis_1.normalizeMultiplierDenominators)(e);
39
- return (0, adapters_1.polynomialToMultiPoly)(new Polynomial_1.Polynomial(cleared, vars), vars).poly;
40
- });
41
- return new Vector_1.Vector((0, groebnerBase_1.Groebner)(polys, vars).map(gb => (0, adapters_1.multiPolyToExpression)(gb, vars)));
33
+ // Rational denominators are cleared exactly while converting into the sparse ring.
34
+ const polys = expressions.map(e => (0, SparsePolynomialAdapter_1.expressionToIntegerSparsePolynomial)(e, vars).polynomial);
35
+ return new Vector_1.Vector((0, groebnerBase_1.Groebner)(polys).map(polynomial => (0, SparsePolynomialAdapter_1.sparsePolynomialToExpression)(polynomial, vars)));
42
36
  }
@@ -6,9 +6,9 @@ import type { ExpressionInput } from '../core/types';
6
6
  * @remarks
7
7
  * The routine extracts `P(x)/Q(x)`, performs polynomial long division for an improper
8
8
  * fraction, factors `Q` over the supported exact polynomial domain, and solves the
9
- * undetermined coefficients by exact evaluation and row reduction. Repeated linear
10
- * factors and irreducible quadratic factors are supported. An irreducible factor of
11
- * higher degree, a singular coefficient system, a denominator independent of the
9
+ * undetermined coefficients by exact evaluation and row reduction. Each denominator
10
+ * factor of degree d receives a numerator polynomial of degree less than d, including
11
+ * repeated factors. A singular coefficient system, a denominator independent of the
12
12
  * selected variable, or a factorization that does not expose a useful decomposition
13
13
  * leaves the original expression unchanged.
14
14
  *
@@ -13,9 +13,9 @@ const factor_1 = require("./factor/factor");
13
13
  * @remarks
14
14
  * The routine extracts `P(x)/Q(x)`, performs polynomial long division for an improper
15
15
  * fraction, factors `Q` over the supported exact polynomial domain, and solves the
16
- * undetermined coefficients by exact evaluation and row reduction. Repeated linear
17
- * factors and irreducible quadratic factors are supported. An irreducible factor of
18
- * higher degree, a singular coefficient system, a denominator independent of the
16
+ * undetermined coefficients by exact evaluation and row reduction. Each denominator
17
+ * factor of degree d receives a numerator polynomial of degree less than d, including
18
+ * repeated factors. A singular coefficient system, a denominator independent of the
19
19
  * selected variable, or a factorization that does not expose a useful decomposition
20
20
  * leaves the original expression unchanged.
21
21
  *
@@ -161,53 +161,28 @@ function collectFactors(factors, v) {
161
161
  /**
162
162
  * Decomposes remainder/den into partial fractions given the factored denominator.
163
163
  *
164
- * For each linear factor (ax+b)^k:
165
- * A₁/(ax+b) + A₂/(ax+b)² + ... + Aₖ/(ax+b)^k
166
- *
167
- * For each irreducible quadratic factor (ax²+bx+c)^k:
168
- * (B₁x+C₁)/(ax²+bx+c) + ... + (Bₖx+Cₖ)/(ax²+bx+c)^k
164
+ * For each factor f(x)^k of degree d, the numerator at every power level is
165
+ * a polynomial of degree less than d. For example, a cubic factor receives
166
+ * A*x^2+B*x+C over each repeated power of that factor.
169
167
  *
170
168
  * Uses evaluation at strategic points to solve for coefficients.
171
169
  */
172
170
  function decompose(numerator, denominator, factors, v) {
173
171
  // Build the list of partial fraction terms and count unknowns.
174
- // Each term is: coefficient(s) / factor^power
175
- // For linear: 1 unknown per power level
176
- // For quadratic: 2 unknowns per power level (Bx + C)
172
+ // A factor of degree d contributes d numerator coefficients at each power level.
177
173
  const terms = [];
178
174
  let totalUnknowns = 0;
179
- let supported = true;
180
175
  for (const f of factors) {
181
176
  for (let k = 1; k <= f.power; k++) {
182
- if (f.degree === 1) {
183
- terms.push({
184
- factor: f.expr,
185
- power: k,
186
- degree: f.degree,
187
- unknownIndex: totalUnknowns,
188
- numUnknowns: 1,
189
- });
190
- totalUnknowns += 1;
191
- }
192
- else if (f.degree === 2) {
193
- terms.push({
194
- factor: f.expr,
195
- power: k,
196
- degree: f.degree,
197
- unknownIndex: totalUnknowns,
198
- numUnknowns: 2,
199
- });
200
- totalUnknowns += 2;
201
- }
202
- else {
203
- // Higher-degree irreducible factors — not supported yet
204
- supported = false;
205
- }
177
+ terms.push({
178
+ factor: f.expr,
179
+ power: k,
180
+ unknownIndex: totalUnknowns,
181
+ numUnknowns: f.degree,
182
+ });
183
+ totalUnknowns += f.degree;
206
184
  }
207
185
  }
208
- if (!supported) {
209
- return undefined;
210
- }
211
186
  // We need to solve: P(x)/Q(x) = Σ terms
212
187
  // Multiply both sides by Q(x):
213
188
  // P(x) = Σ (coefficients_i × Q(x) / factor_i^power_i)
@@ -254,15 +229,11 @@ function decompose(numerator, denominator, factors, v) {
254
229
  const row = [];
255
230
  for (let j = 0; j < terms.length; j++) {
256
231
  const term = terms[j];
257
- // The basis for this term: Q(x) / factor^power, evaluated at x
232
+ // The basis for this term: Q(x) / factor^power, evaluated at x.
258
233
  const cofactor = evaluateAt(cofactors[j], v, x);
259
- if (term.numUnknowns === 1) {
260
- row.push(cofactor);
261
- }
262
- else {
263
- // Quadratic: (Bx + C) contributes B*x*cofactor + C*cofactor
264
- row.push(x.times(cofactor)); // coefficient of B
265
- row.push(cofactor); // coefficient of C
234
+ for (let degree = term.numUnknowns - 1; degree >= 0; degree--) {
235
+ const monomial = degree === 0 ? (0, shortcuts_1.one)() : x.pow(Expression_1.Expression.Number(degree));
236
+ row.push(monomial.times(cofactor));
266
237
  }
267
238
  }
268
239
  rows.push(row);
@@ -274,22 +245,18 @@ function decompose(numerator, denominator, factors, v) {
274
245
  }
275
246
  // Build the result expression from the solved coefficients
276
247
  let result = (0, shortcuts_1.zero)();
248
+ const variable = Expression_1.Expression.create(v);
277
249
  for (const term of terms) {
278
250
  const denomPart = term.power === 1 ? term.factor : term.factor.pow(Expression_1.Expression.Number(term.power));
279
- if (term.numUnknowns === 1) {
280
- const A = solution[term.unknownIndex];
281
- if (!A.isZero()) {
282
- result = result.plus(A.div(denomPart));
283
- }
251
+ let numPart = (0, shortcuts_1.zero)();
252
+ for (let i = 0; i < term.numUnknowns; i++) {
253
+ const coefficient = solution[term.unknownIndex + i];
254
+ const degree = term.numUnknowns - 1 - i;
255
+ const monomial = degree === 0 ? (0, shortcuts_1.one)() : variable.pow(Expression_1.Expression.Number(degree));
256
+ numPart = numPart.plus(coefficient.times(monomial));
284
257
  }
285
- else {
286
- const B = solution[term.unknownIndex];
287
- const C = solution[term.unknownIndex + 1];
288
- // (Bx + C) / factor^power
289
- const numPart = B.times(Expression_1.Expression.create(v)).plus(C);
290
- if (!numPart.isZero()) {
291
- result = result.plus(numPart.div(denomPart));
292
- }
258
+ if (!numPart.isZero()) {
259
+ result = result.plus(numPart.div(denomPart));
293
260
  }
294
261
  }
295
262
  return result;
@@ -377,7 +344,7 @@ function solveLinearSystem(A, b) {
377
344
  if (pivot === -1) {
378
345
  continue;
379
346
  }
380
- if (!aug.elements[i][pivot].eq('1')) {
347
+ if (!aug.elements[i][pivot].eq((0, shortcuts_1.one)())) {
381
348
  return undefined;
382
349
  }
383
350
  if (pivotCols.has(pivot)) {