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,56 @@
1
+ /**
2
+ * @module sparsePolynomialAdapter
3
+ *
4
+ * Conversion from Nerdamer's expression-facing polynomial forms to the exact
5
+ * integer sparse polynomial representation.
6
+ */
7
+ import { Expression } from '../expression/Expression';
8
+ import { SparsePolynomial } from './SparsePolynomial';
9
+ import type { Polynomial } from './Polynomial';
10
+ /**
11
+ * Converts an integer-coefficient polynomial expression directly to sparse form.
12
+ *
13
+ * Sums, products, and non-negative integer powers are evaluated with sparse
14
+ * polynomial arithmetic, so callers do not need to construct the legacy Polynomial
15
+ * representation first. Variables are ordered by ascending degree and then by name.
16
+ */
17
+ export declare function expressionToSparsePolynomial(expression: Expression): Readonly<{
18
+ polynomial: SparsePolynomial;
19
+ variables: readonly string[];
20
+ }>;
21
+ /**
22
+ * Converts a rational-coefficient polynomial expression directly to integer sparse form.
23
+ *
24
+ * The supplied variables define the sparse ring coordinates. Rational denominators are
25
+ * carried separately while sums, products, and non-negative integer powers are evaluated,
26
+ * then reduced against common integer coefficient content.
27
+ */
28
+ export declare function expressionToIntegerSparsePolynomial(expression: Expression, variables: readonly string[]): Readonly<{
29
+ polynomial: SparsePolynomial;
30
+ denominator: bigint;
31
+ }>;
32
+ /**
33
+ * Converts a Polynomial with rational numeric coefficients to an integer sparse
34
+ * polynomial by clearing one common positive denominator.
35
+ *
36
+ * The supplied variables define the sparse ring coordinates and must include every
37
+ * variable in the polynomial.
38
+ */
39
+ export declare function polynomialToIntegerSparsePolynomial(polynomial: Polynomial, variables: readonly string[]): Readonly<{
40
+ polynomial: SparsePolynomial;
41
+ denominator: bigint;
42
+ }>;
43
+ /**
44
+ * Converts a Polynomial to an exact sparse polynomial over the integers.
45
+ *
46
+ * Coefficients must already be integers; use
47
+ * {@link polynomialToIntegerSparsePolynomial} when rational coefficients should be
48
+ * cleared first.
49
+ */
50
+ export declare function polynomialToSparsePolynomial(polynomial: Polynomial, variables: readonly string[]): SparsePolynomial;
51
+ /**
52
+ * Converts an exact sparse polynomial directly to an Expression.
53
+ *
54
+ * Conversion does not pass through Polynomial, so bigint exponents remain exact.
55
+ */
56
+ export declare function sparsePolynomialToExpression(polynomial: SparsePolynomial, variables: readonly string[]): Expression;
@@ -0,0 +1,241 @@
1
+ "use strict";
2
+ /**
3
+ * @module sparsePolynomialAdapter
4
+ *
5
+ * Conversion from Nerdamer's expression-facing polynomial forms to the exact
6
+ * integer sparse polynomial representation.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.expressionToSparsePolynomial = expressionToSparsePolynomial;
10
+ exports.expressionToIntegerSparsePolynomial = expressionToIntegerSparsePolynomial;
11
+ exports.polynomialToIntegerSparsePolynomial = polynomialToIntegerSparsePolynomial;
12
+ exports.polynomialToSparsePolynomial = polynomialToSparsePolynomial;
13
+ exports.sparsePolynomialToExpression = sparsePolynomialToExpression;
14
+ const errors_1 = require("../../errors");
15
+ const bigint_1 = require("../../functions/bigint/bigint");
16
+ const Expression_1 = require("../expression/Expression");
17
+ const shortcuts_1 = require("../expression/shortcuts");
18
+ const SparsePolynomial_1 = require("./SparsePolynomial");
19
+ /**
20
+ * Converts an integer-coefficient polynomial expression directly to sparse form.
21
+ *
22
+ * Sums, products, and non-negative integer powers are evaluated with sparse
23
+ * polynomial arithmetic, so callers do not need to construct the legacy Polynomial
24
+ * representation first. Variables are ordered by ascending degree and then by name.
25
+ */
26
+ function expressionToSparsePolynomial(expression) {
27
+ const sourceVariables = expression.variables().sort();
28
+ const variableIndices = new Map(sourceVariables.map((variable, index) => [variable, index]));
29
+ function powerOf(current) {
30
+ const power = current.getPower();
31
+ if (!power.isInteger() || power.sign() < 0) {
32
+ throw new errors_1.PolynomialError((0, errors_1.message)('notAPolynomial'));
33
+ }
34
+ return power.getMultiplier().numerator;
35
+ }
36
+ function integerMultiplier(current) {
37
+ const multiplier = current.getMultiplier();
38
+ if (multiplier.denominator !== 1n) {
39
+ throw new Error((0, errors_1.message)('integerRequired'));
40
+ }
41
+ return multiplier.numerator;
42
+ }
43
+ function convert(current) {
44
+ const variableCount = sourceVariables.length;
45
+ if (current.isNUM()) {
46
+ return SparsePolynomial_1.SparsePolynomial.constant(variableCount, integerMultiplier(current));
47
+ }
48
+ if (current.isVAR()) {
49
+ const variableIndex = variableIndices.get(current.value);
50
+ if (variableIndex === undefined) {
51
+ throw new errors_1.PolynomialError((0, errors_1.message)('notAPolynomial'));
52
+ }
53
+ const exponents = new Array(variableCount).fill(0n);
54
+ exponents[variableIndex] = powerOf(current);
55
+ return SparsePolynomial_1.SparsePolynomial.monomial(variableCount, integerMultiplier(current), exponents);
56
+ }
57
+ if (current.isSum()) {
58
+ let sum = SparsePolynomial_1.SparsePolynomial.zero(variableCount);
59
+ for (const term of current.elementsArray()) {
60
+ sum = sum.add(convert(term));
61
+ }
62
+ return sum.pow(powerOf(current)).scale(integerMultiplier(current));
63
+ }
64
+ if (current.isProduct()) {
65
+ let product = SparsePolynomial_1.SparsePolynomial.constant(variableCount, 1n);
66
+ for (const factor of current.elementsArray()) {
67
+ product = product.multiply(convert(factor));
68
+ }
69
+ return product.pow(powerOf(current)).scale(integerMultiplier(current));
70
+ }
71
+ throw new errors_1.PolynomialError((0, errors_1.message)('notAPolynomial'));
72
+ }
73
+ const source = convert(expression);
74
+ const order = sourceVariables
75
+ .map((variable, index) => ({
76
+ variable,
77
+ index,
78
+ degree: source.degree(index) ?? 0n,
79
+ }))
80
+ .sort((left, right) => {
81
+ if (left.degree < right.degree) {
82
+ return -1;
83
+ }
84
+ if (left.degree > right.degree) {
85
+ return 1;
86
+ }
87
+ return left.variable.localeCompare(right.variable);
88
+ });
89
+ const variables = order.map(entry => entry.variable);
90
+ if (order.every((entry, index) => entry.index === index)) {
91
+ return { polynomial: source, variables };
92
+ }
93
+ const terms = source.terms().map(term => ({
94
+ coefficient: term.coefficient,
95
+ exponents: order.map(entry => term.exponents[entry.index]),
96
+ }));
97
+ return {
98
+ polynomial: new SparsePolynomial_1.SparsePolynomial(source.variableCount, terms),
99
+ variables,
100
+ };
101
+ }
102
+ /**
103
+ * Converts a rational-coefficient polynomial expression directly to integer sparse form.
104
+ *
105
+ * The supplied variables define the sparse ring coordinates. Rational denominators are
106
+ * carried separately while sums, products, and non-negative integer powers are evaluated,
107
+ * then reduced against common integer coefficient content.
108
+ */
109
+ function expressionToIntegerSparsePolynomial(expression, variables) {
110
+ const selected = new Set();
111
+ for (const variable of variables) {
112
+ if (selected.has(variable)) {
113
+ throw new RangeError((0, errors_1.message)('sparseAdapterVariablesUnique'));
114
+ }
115
+ selected.add(variable);
116
+ }
117
+ for (const variable of expression.variables()) {
118
+ if (!selected.has(variable)) {
119
+ throw new RangeError((0, errors_1.message)('sparseAdapterVariablesIncludeEvery'));
120
+ }
121
+ }
122
+ const variableCount = variables.length;
123
+ const variableIndices = new Map(variables.map((variable, index) => [variable, index]));
124
+ function powerOf(current) {
125
+ const power = current.getPower();
126
+ if (!power.isInteger() || power.sign() < 0) {
127
+ throw new errors_1.PolynomialError((0, errors_1.message)('notAPolynomial'));
128
+ }
129
+ return power.getMultiplier().numerator;
130
+ }
131
+ function normalize(polynomial, denominator) {
132
+ if (polynomial.isZero()) {
133
+ return { polynomial, denominator: 1n };
134
+ }
135
+ const divisor = (0, bigint_1.GCD)(polynomial.content(), denominator);
136
+ return divisor === 1n
137
+ ? { polynomial, denominator }
138
+ : {
139
+ polynomial: polynomial.divideByScalarExact(divisor),
140
+ denominator: denominator / divisor,
141
+ };
142
+ }
143
+ function applyPowerAndMultiplier(current, polynomial, denominator) {
144
+ const exponent = powerOf(current);
145
+ const multiplier = current.getMultiplier();
146
+ return normalize(polynomial.pow(exponent).scale(multiplier.numerator), denominator ** exponent * multiplier.denominator);
147
+ }
148
+ function convert(current) {
149
+ const multiplier = current.getMultiplier();
150
+ if (current.isNUM()) {
151
+ return normalize(SparsePolynomial_1.SparsePolynomial.constant(variableCount, multiplier.numerator), multiplier.denominator);
152
+ }
153
+ if (current.isVAR()) {
154
+ const variableIndex = variableIndices.get(current.value);
155
+ if (variableIndex === undefined) {
156
+ throw new errors_1.PolynomialError((0, errors_1.message)('notAPolynomial'));
157
+ }
158
+ const exponents = new Array(variableCount).fill(0n);
159
+ exponents[variableIndex] = powerOf(current);
160
+ return normalize(SparsePolynomial_1.SparsePolynomial.monomial(variableCount, multiplier.numerator, exponents), multiplier.denominator);
161
+ }
162
+ if (current.isSum()) {
163
+ let polynomial = SparsePolynomial_1.SparsePolynomial.zero(variableCount);
164
+ let denominator = 1n;
165
+ for (const term of current.elementsArray()) {
166
+ const converted = convert(term);
167
+ const commonDenominator = (0, bigint_1.LCM)(denominator, converted.denominator);
168
+ polynomial = polynomial
169
+ .scale(commonDenominator / denominator)
170
+ .add(converted.polynomial.scale(commonDenominator / converted.denominator));
171
+ denominator = commonDenominator;
172
+ }
173
+ return applyPowerAndMultiplier(current, polynomial, denominator);
174
+ }
175
+ if (current.isProduct()) {
176
+ let polynomial = SparsePolynomial_1.SparsePolynomial.constant(variableCount, 1n);
177
+ let denominator = 1n;
178
+ for (const factor of current.elementsArray()) {
179
+ const converted = convert(factor);
180
+ polynomial = polynomial.multiply(converted.polynomial);
181
+ denominator *= converted.denominator;
182
+ }
183
+ return applyPowerAndMultiplier(current, polynomial, denominator);
184
+ }
185
+ throw new errors_1.PolynomialError((0, errors_1.message)('notAPolynomial'));
186
+ }
187
+ const converted = convert(expression);
188
+ const terms = [...converted.polynomial.terms()].sort((left, right) => -SparsePolynomial_1.SparsePolynomial.compareMonomials(left.exponents, right.exponents, 'lex'));
189
+ return {
190
+ polynomial: new SparsePolynomial_1.SparsePolynomial(variableCount, terms),
191
+ denominator: converted.denominator,
192
+ };
193
+ }
194
+ /**
195
+ * Converts a Polynomial with rational numeric coefficients to an integer sparse
196
+ * polynomial by clearing one common positive denominator.
197
+ *
198
+ * The supplied variables define the sparse ring coordinates and must include every
199
+ * variable in the polynomial.
200
+ */
201
+ function polynomialToIntegerSparsePolynomial(polynomial, variables) {
202
+ return expressionToIntegerSparsePolynomial(polynomial.getExpression(), variables);
203
+ }
204
+ /**
205
+ * Converts a Polynomial to an exact sparse polynomial over the integers.
206
+ *
207
+ * Coefficients must already be integers; use
208
+ * {@link polynomialToIntegerSparsePolynomial} when rational coefficients should be
209
+ * cleared first.
210
+ */
211
+ function polynomialToSparsePolynomial(polynomial, variables) {
212
+ const converted = polynomialToIntegerSparsePolynomial(polynomial, variables);
213
+ if (converted.denominator !== 1n) {
214
+ throw new Error((0, errors_1.message)('integerRequired'));
215
+ }
216
+ return converted.polynomial;
217
+ }
218
+ /**
219
+ * Converts an exact sparse polynomial directly to an Expression.
220
+ *
221
+ * Conversion does not pass through Polynomial, so bigint exponents remain exact.
222
+ */
223
+ function sparsePolynomialToExpression(polynomial, variables) {
224
+ if (variables.length !== polynomial.variableCount) {
225
+ throw new RangeError((0, errors_1.message)('sparseExpressionConversionNameCount'));
226
+ }
227
+ let result = (0, shortcuts_1.zero)();
228
+ for (const term of polynomial.terms()) {
229
+ let expression = Expression_1.Expression.Number(term.coefficient);
230
+ for (let variableIndex = 0; variableIndex < variables.length; variableIndex++) {
231
+ const exponent = term.exponents[variableIndex];
232
+ if (exponent === 0n) {
233
+ continue;
234
+ }
235
+ const variable = Expression_1.Expression.Variable(variables[variableIndex]);
236
+ expression = expression.times(exponent === 1n ? variable : variable.pow(Expression_1.Expression.Number(exponent)));
237
+ }
238
+ result = result.plus(expression);
239
+ }
240
+ return result;
241
+ }
@@ -132,7 +132,7 @@ class Term {
132
132
  * @returns A term with copied coefficient, powers, and variable array. Lazy caches are rebuilt on demand.
133
133
  */
134
134
  copy() {
135
- return new Term(new Expression_1.Expression(this.coeff), { ...this.powers }, this.variables);
135
+ return new Term(this.coeff.copy(), { ...this.powers }, this.variables);
136
136
  }
137
137
  deg(v, value) {
138
138
  if (value !== undefined) {
@@ -238,7 +238,7 @@ class Term {
238
238
  */
239
239
  getExpression() {
240
240
  if (this.expression === undefined) {
241
- let expression = new Expression_1.Expression(this.coeff);
241
+ let expression = this.coeff.copy();
242
242
  for (const variable of this.variables) {
243
243
  const power = this.deg(variable);
244
244
  if (power !== 0) {
@@ -1,5 +1,5 @@
1
- import { Polynomial } from './classes/polynomial/Polynomial';
2
- import type { ExpressionInput } from './types';
1
+ import { Polynomial } from './Polynomial';
2
+ import type { ExpressionInput } from '../../types';
3
3
  /**
4
4
  * Extracts the Z Polynomial from Q.
5
5
  * Given a polynomial with rational coefficients, returns:
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.expressionToZPoly = expressionToZPoly;
4
+ const Expression_1 = require("../expression/Expression");
5
+ const Polynomial_1 = require("./Polynomial");
6
+ const SparsePolynomialAdapter_1 = require("./SparsePolynomialAdapter");
7
+ /**
8
+ * Extracts the Z Polynomial from Q.
9
+ * Given a polynomial with rational coefficients, returns:
10
+ * - zPoly: the polynomial scaled to have integer coefficients (primitive part)
11
+ * - content: the GCD of the integer coefficients after clearing denominators
12
+ * - denominator: the common denominator used to clear fractions
13
+ *
14
+ * The relationship is: original = (content / denominator) * zPoly
15
+ *
16
+ * @param x
17
+ */
18
+ function expressionToZPoly(x) {
19
+ const expression = Expression_1.Expression.create(x);
20
+ const variables = expression.variables().sort();
21
+ const converted = (0, SparsePolynomialAdapter_1.expressionToIntegerSparsePolynomial)(expression, variables);
22
+ const coefficientContent = converted.polynomial.isZero()
23
+ ? 1n
24
+ : converted.polynomial.content();
25
+ const primitive = coefficientContent === 1n
26
+ ? converted.polynomial
27
+ : converted.polynomial.divideByScalarExact(coefficientContent);
28
+ return {
29
+ zPoly: new Polynomial_1.Polynomial((0, SparsePolynomialAdapter_1.sparsePolynomialToExpression)(primitive, variables), [...variables], 'lex'),
30
+ content: new Polynomial_1.Polynomial(Expression_1.Expression.Number(coefficientContent)),
31
+ denominator: new Polynomial_1.Polynomial(Expression_1.Expression.Number(converted.denominator)),
32
+ };
33
+ }
@@ -0,0 +1 @@
1
+ export declare function loadPolynomialFunctions(): void;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadPolynomialFunctions = loadPolynomialFunctions;
4
+ const dispatch_1 = require("../../dispatch");
5
+ const functions_1 = require("./functions");
6
+ function loadPolynomialFunctions() {
7
+ Object.assign(dispatch_1.mathFunctionRegistry, {
8
+ deg: (0, dispatch_1.systemFunction)({ fn: functions_1.deg, minArgs: 1, maxArgs: 2, distElWise: true }),
9
+ content: (0, dispatch_1.systemFunction)({ fn: functions_1.content, minArgs: 1, maxArgs: 1, distElWise: true }),
10
+ coeffs: (0, dispatch_1.systemFunction)({ fn: functions_1.coeffs, minArgs: 1, maxArgs: 2, distElWise: false }),
11
+ div: (0, dispatch_1.systemFunction)({ fn: functions_1.div, minArgs: 2, maxArgs: 2, distElWise: false }),
12
+ divide: (0, dispatch_1.systemFunction)({ fn: functions_1.divide, minArgs: 2, maxArgs: 2, distElWise: false }),
13
+ });
14
+ }
@@ -42,6 +42,14 @@ export declare function deg(x: ExpressionInput | Polynomial, variable?: Expressi
42
42
  * ```
43
43
  */
44
44
  export declare function content(x: ExpressionInput | Polynomial): Expression;
45
+ /**
46
+ * Returns polynomial coefficients as a dense Vector ordered by ascending power.
47
+ *
48
+ * When no variable is supplied, the first variable in the expression is used, matching
49
+ * the legacy parser helper. A constant expression therefore has the single coefficient
50
+ * at power zero.
51
+ */
52
+ export declare function coeffs(x: ExpressionInput, variable?: ExpressionInput): Vector;
45
53
  /**
46
54
  * Returns the quotient and remainder of polynomial division.
47
55
  *
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deg = deg;
4
4
  exports.content = content;
5
+ exports.coeffs = coeffs;
5
6
  exports.div = div;
6
7
  exports.divide = divide;
7
8
  const Expression_1 = require("../expression/Expression");
@@ -10,6 +11,7 @@ const utils_1 = require("../expression/utils");
10
11
  const constants_1 = require("../parser/constants");
11
12
  const Vector_1 = require("../vector/Vector");
12
13
  const Polynomial_1 = require("./Polynomial");
14
+ const SparsePolynomialAdapter_1 = require("./SparsePolynomialAdapter");
13
15
  const utils_2 = require("./utils");
14
16
  /**
15
17
  * Returns the degree of a polynomial expression.
@@ -39,11 +41,34 @@ function deg(x, variable) {
39
41
  variableName = (0, utils_1.assertPlainVariableAndGetString)(variableExpression);
40
42
  }
41
43
  let retval = undefined;
42
- try {
43
- const polynomial = Polynomial_1.Polynomial.isPolynomial(x) ? x : new Polynomial_1.Polynomial(x);
44
- retval = Expression_1.Expression.create(polynomial.deg(variableName));
44
+ if (Polynomial_1.Polynomial.isPolynomial(x)) {
45
+ retval = Expression_1.Expression.create(x.deg(variableName));
46
+ }
47
+ else {
48
+ const inputExpression = Expression_1.Expression.create(x);
49
+ try {
50
+ const variables = inputExpression.variables().sort();
51
+ const converted = (0, SparsePolynomialAdapter_1.expressionToIntegerSparsePolynomial)(inputExpression, variables);
52
+ let degree;
53
+ if (variableName === undefined) {
54
+ degree = converted.polynomial.totalDegree() ?? 0n;
55
+ }
56
+ else {
57
+ const variableIndex = variables.indexOf(variableName);
58
+ degree =
59
+ variableIndex === -1
60
+ ? 0n
61
+ : (converted.polynomial.degree(variableIndex) ?? 0n);
62
+ }
63
+ retval = Expression_1.Expression.Number(degree);
64
+ }
65
+ catch {
66
+ try {
67
+ retval = Expression_1.Expression.create(new Polynomial_1.Polynomial(inputExpression).deg(variableName));
68
+ }
69
+ catch { }
70
+ }
45
71
  }
46
- catch { }
47
72
  const input = Polynomial_1.Polynomial.isPolynomial(x) ? x.getExpression() : x;
48
73
  const args = variableExpression === undefined ? [input] : [input, variableExpression];
49
74
  return retval ?? Expression_1.Expression.toFunction(constants_1.DEG, args);
@@ -68,13 +93,51 @@ function deg(x, variable) {
68
93
  */
69
94
  function content(x) {
70
95
  let retval = undefined;
71
- try {
72
- const polynomial = Polynomial_1.Polynomial.isPolynomial(x) ? x : new Polynomial_1.Polynomial(x);
73
- retval = Expression_1.Expression.create(polynomial.content());
96
+ if (Polynomial_1.Polynomial.isPolynomial(x)) {
97
+ retval = Expression_1.Expression.create(x.content());
98
+ }
99
+ else {
100
+ const inputExpression = Expression_1.Expression.create(x);
101
+ try {
102
+ if (inputExpression.isZero()) {
103
+ retval = Expression_1.Expression.create(new Polynomial_1.Polynomial(inputExpression).content());
104
+ }
105
+ else {
106
+ const variables = inputExpression.variables().sort();
107
+ const converted = (0, SparsePolynomialAdapter_1.expressionToIntegerSparsePolynomial)(inputExpression, variables);
108
+ retval = Expression_1.Expression.Number(converted.polynomial.content()).div(Expression_1.Expression.Number(converted.denominator));
109
+ retval.getMultiplier().asDecimal = inputExpression.hasDecimal();
110
+ }
111
+ }
112
+ catch {
113
+ try {
114
+ retval = Expression_1.Expression.create(new Polynomial_1.Polynomial(inputExpression).content());
115
+ }
116
+ catch { }
117
+ }
74
118
  }
75
- catch { }
76
119
  return retval ?? Expression_1.Expression.toFunction(constants_1.CONTENT, [Polynomial_1.Polynomial.isPolynomial(x) ? x.getExpression() : x]);
77
120
  }
121
+ /**
122
+ * Returns polynomial coefficients as a dense Vector ordered by ascending power.
123
+ *
124
+ * When no variable is supplied, the first variable in the expression is used, matching
125
+ * the legacy parser helper. A constant expression therefore has the single coefficient
126
+ * at power zero.
127
+ */
128
+ function coeffs(x, variable) {
129
+ const expression = Expression_1.Expression.create(x);
130
+ let variableName;
131
+ if (variable !== undefined) {
132
+ variableName = (0, utils_1.assertPlainVariableAndGetString)(Expression_1.Expression.create(variable));
133
+ }
134
+ else {
135
+ variableName = expression.variables()[0];
136
+ }
137
+ return variableName === undefined
138
+ ? new Vector_1.Vector([expression.copy()])
139
+ : expression.coeffs(variableName).toVector();
140
+ }
78
141
  /**
79
142
  * Returns the quotient and remainder of polynomial division.
80
143
  *
@@ -7,6 +7,7 @@ exports.combinePolynomialVariables = combinePolynomialVariables;
7
7
  exports.polyMod = polyMod;
8
8
  exports.maxCommonVariableOccurrence = maxCommonVariableOccurrence;
9
9
  exports.polynomialFromNumber = polynomialFromNumber;
10
+ const errors_1 = require("../../errors");
10
11
  const utils_1 = require("../../functions/utils");
11
12
  const shortcuts_1 = require("../expression/shortcuts");
12
13
  const Polynomial_1 = require("./Polynomial");
@@ -53,7 +54,7 @@ function polyDiv(Fs, g, ordering, variables) {
53
54
  // Begin
54
55
  while (!p.isZero()) {
55
56
  if (iter++ > maxIter) {
56
- throw new Error('Maximum iterations reached');
57
+ throw new Error((0, errors_1.message)('polynomialMaximumIterations'));
57
58
  }
58
59
  let divisionOccurred = false;
59
60
  const s = F.length;
@@ -2,6 +2,9 @@ import Decimal from 'decimal.js';
2
2
  import { Expression } from '../expression/Expression';
3
3
  import { RATIONAL } from '../parser/constants';
4
4
  import type { OptionsObject } from '../parser/types';
5
+ /** Maximum scientific significant-digit count accepted by decimal.js. */
6
+ export declare const MAX_SCIENTIFIC_SIGNIFICANT_DIGITS = 1000000000;
7
+ export declare function validateScientificSignificantDigits(value: unknown, received?: string): number;
5
8
  /**
6
9
  * Represents an exact rational value as a `bigint` numerator and denominator.
7
10
  *
@@ -151,14 +154,6 @@ export declare class Rational {
151
154
  * @returns The pairwise rational LCM.
152
155
  */
153
156
  static LCM(...args: Rational[]): Rational;
154
- /**
155
- * Copies a rational's representation and presentation metadata.
156
- *
157
- * @param x - Rational to copy.
158
- * @returns A distinct `Rational` with the same numerator, denominator, `value`, and
159
- * decimal-presentation flag.
160
- */
161
- static makeCopy(x: Rational): Rational;
162
157
  /**
163
158
  * Updates shared numeric settings used by rational decimal conversion.
164
159
  *
@@ -418,14 +413,16 @@ export declare class Rational {
418
413
  * Formats this rational as fraction, integer, or decimal text.
419
414
  *
420
415
  * @remarks
421
- * Decimal formatting is selected when {@link Rational.asDecimal} is set or when
416
+ * Scientific formatting is selected when `options.scientific` supplies an integer significant-digit
417
+ * count from 1 through 1e9. The requested count is preserved in the coefficient, including
418
+ * trailing zeroes. Otherwise decimal formatting is selected when {@link Rational.asDecimal} is set or when
422
419
  * `options.decimal` is truthy. Non-integer decimal output uses `decimal.js`; an optional
423
420
  * `options.precision` temporarily controls its significant-digit precision for this conversion.
424
421
  * Integer decimal output includes a `.0` suffix. Without decimal formatting, non-integer
425
422
  * fractions are emitted from the stored numerator and denominator, and integers as plain text.
426
423
  *
427
- * @param options - Formatting options. `decimal` forces decimal output and `precision` controls
428
- * decimal conversion precision when applicable.
424
+ * @param options - Formatting options. `scientific` selects significant-digit scientific output;
425
+ * `decimal` forces decimal output and `precision` controls decimal conversion precision when applicable.
429
426
  * @returns The formatted numeric text.
430
427
  */
431
428
  text(options?: OptionsObject): string;