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
@@ -1,6 +1,7 @@
1
1
  import { Expression } from '../../core/classes/expression/Expression';
2
2
  import { SOLUTIONS_SET } from '../../core/classes/parser/constants';
3
3
  import { ValuesSet } from '../../core/classes/valuesSet/ValuesSet';
4
+ import type { ParserValuesObject } from '../../core/classes/parser/types';
4
5
  import type { ParserEntity } from '../../core/types';
5
6
  import type { Root } from './FunctionSolver';
6
7
  /** Describes whether accepted solutions were produced by numerical strategies, symbolic strategies, or both. */
@@ -91,6 +92,14 @@ export declare class SolutionSet extends ValuesSet {
91
92
  * use {@link append} when the complete solver result should be merged without revalidation.
92
93
  */
93
94
  addSolutions(arr: Expression[] | SolutionSet, forFunction: Expression, variable: string): this;
95
+ /**
96
+ * Adds a batch of numerical solutions that has already been validated against its source
97
+ * polynomial. Incoming values are deduplicated by their exact numeric components before
98
+ * storage so a numerical root batch does not require pairwise symbolic equality checks.
99
+ *
100
+ * @internal
101
+ */
102
+ addValidatedNumericalSolutions(values: Iterable<Expression>): SolutionSet;
94
103
  /**
95
104
  * Appends another solution result while preserving set and solver metadata.
96
105
  *
@@ -103,6 +112,16 @@ export declare class SolutionSet extends ValuesSet {
103
112
  * current data model can represent only one such expression.
104
113
  */
105
114
  append(s: SolutionSet): SolutionSet;
115
+ /**
116
+ * Appends numerical solutions that were already validated by a numerical solver.
117
+ *
118
+ * This follows the same metadata and exclusion handling as {@link append}, but avoids
119
+ * repeating symbolic membership checks for a batch that has already been numerically
120
+ * validated and deduplicated.
121
+ *
122
+ * @internal
123
+ */
124
+ appendValidatedNumerical(s: SolutionSet): SolutionSet;
106
125
  /** Returns an independent Expression copy at the requested insertion-order index. */
107
126
  at(i: number): Expression | undefined;
108
127
  /**
@@ -122,7 +141,7 @@ export declare class SolutionSet extends ValuesSet {
122
141
  each(callback: (e: ParserEntity, i?: string | number, j?: string | number) => ParserEntity | void): this;
123
142
  /** Returns deep-copied accepted solution descriptors in deterministic insertion order. */
124
143
  get elements(): Expression[];
125
- evaluate(): SolutionSet;
144
+ evaluate(values?: ParserValuesObject): SolutionSet;
126
145
  /**
127
146
  * Adds exclusions and removes any matching values that were already accepted.
128
147
  */
@@ -83,8 +83,9 @@ class SolutionSet extends ValuesSet_1.ValuesSet {
83
83
  // Preserve parameterized candidates that cannot yet be verified, but
84
84
  // require every closed residual, including complex values, to be zero.
85
85
  if ((isClosed && evaluated.isNearlyZero()) || !isClosed) {
86
+ const excluded = this.excluded.has(solution);
86
87
  this.add(solution);
87
- retval = this.has(solution);
88
+ retval = !excluded;
88
89
  }
89
90
  }
90
91
  catch (e) {
@@ -106,7 +107,11 @@ class SolutionSet extends ValuesSet_1.ValuesSet {
106
107
  if (this.excluded.has(value)) {
107
108
  const index = indices[0];
108
109
  if (index < 0 || index >= this.count()) {
109
- throw new RangeError(`Index ${index} out of bounds for ${this.dataType} of length ${this.count()}`);
110
+ throw new RangeError((0, errors_1.message)('indexOutOfBounds', {
111
+ index: String(index),
112
+ type: String(this.dataType),
113
+ length: String(this.count()),
114
+ }));
110
115
  }
111
116
  const current = this.at(index);
112
117
  if (current) {
@@ -201,6 +206,48 @@ class SolutionSet extends ValuesSet_1.ValuesSet {
201
206
  }
202
207
  return this;
203
208
  }
209
+ /**
210
+ * Adds a batch of numerical solutions that has already been validated against its source
211
+ * polynomial. Incoming values are deduplicated by their exact numeric components before
212
+ * storage so a numerical root batch does not require pairwise symbolic equality checks.
213
+ *
214
+ * @internal
215
+ */
216
+ addValidatedNumericalSolutions(values) {
217
+ const candidates = [...values];
218
+ const existing = this.elements;
219
+ const keys = new Set();
220
+ for (const value of candidates) {
221
+ if (!Expression_1.Expression.isExpression(value)) {
222
+ const entity = value;
223
+ throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: entity.dataType }));
224
+ }
225
+ const real = value.isComplex() ? value.realPart() : value;
226
+ const imaginary = value.isComplex() ? value.imagPart() : Expression_1.Expression.Number(0);
227
+ if (!real.isNUM() || !imaginary.isNUM()) {
228
+ throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: value.dataType }));
229
+ }
230
+ const realMultiplier = real.getMultiplier();
231
+ const imaginaryMultiplier = imaginary.getMultiplier();
232
+ const key = `${realMultiplier.numerator}/${realMultiplier.denominator}|` +
233
+ `${imaginaryMultiplier.numerator}/${imaginaryMultiplier.denominator}`;
234
+ if (keys.has(key) || this.excluded.has(value)) {
235
+ continue;
236
+ }
237
+ let present = false;
238
+ for (const stored of existing) {
239
+ if (stored.eq(value) && value.eq(stored)) {
240
+ present = true;
241
+ break;
242
+ }
243
+ }
244
+ if (!present) {
245
+ this.addKnownUnique(value);
246
+ keys.add(key);
247
+ }
248
+ }
249
+ return this;
250
+ }
204
251
  /**
205
252
  * Appends another solution result while preserving set and solver metadata.
206
253
  *
@@ -213,8 +260,38 @@ class SolutionSet extends ValuesSet_1.ValuesSet {
213
260
  * current data model can represent only one such expression.
214
261
  */
215
262
  append(s) {
263
+ const transferUnique = this.count() === 0 && this.excluded.count() === 0;
264
+ this.exclude(s.getExcluded());
265
+ if (transferUnique) {
266
+ for (const solution of s.elements) {
267
+ this.addKnownUnique(solution);
268
+ }
269
+ }
270
+ else {
271
+ this.addMany(s.elements);
272
+ }
273
+ for (const root of s.getRawRoots()) {
274
+ this.addRawRoot(root);
275
+ }
276
+ this.partial = this.partial || s.partial;
277
+ this.mergeSolutionsType(s.solutionsType);
278
+ if (!this.unsolved && s.unsolved) {
279
+ this.unsolved = s.unsolved.copy();
280
+ }
281
+ return this;
282
+ }
283
+ /**
284
+ * Appends numerical solutions that were already validated by a numerical solver.
285
+ *
286
+ * This follows the same metadata and exclusion handling as {@link append}, but avoids
287
+ * repeating symbolic membership checks for a batch that has already been numerically
288
+ * validated and deduplicated.
289
+ *
290
+ * @internal
291
+ */
292
+ appendValidatedNumerical(s) {
216
293
  this.exclude(s.getExcluded());
217
- this.addMany(s.elements);
294
+ this.addValidatedNumericalSolutions(s.elements);
218
295
  for (const root of s.getRawRoots()) {
219
296
  this.addRawRoot(root);
220
297
  }
@@ -276,8 +353,8 @@ class SolutionSet extends ValuesSet_1.ValuesSet {
276
353
  get elements() {
277
354
  return super.elements;
278
355
  }
279
- evaluate() {
280
- return this.copy().each(e => e.evaluate());
356
+ evaluate(values) {
357
+ return this.copy().each(e => e.evaluate(values));
281
358
  }
282
359
  /**
283
360
  * Adds exclusions and removes any matching values that were already accepted.
@@ -0,0 +1 @@
1
+ export declare function loadSolveFunctions(): void;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadSolveFunctions = loadSolveFunctions;
4
+ const dispatch_1 = require("../core/dispatch");
5
+ const solve_1 = require("./solve");
6
+ const solveSystem_1 = require("./solveSystem");
7
+ function loadSolveFunctions() {
8
+ Object.assign(dispatch_1.mathFunctionRegistry, {
9
+ solve: (0, dispatch_1.systemFunction)({ fn: solve_1.solve, minArgs: 2, maxArgs: 2, equationArgs: [0], distElWise: false }),
10
+ roots: (0, dispatch_1.systemFunction)({ fn: solve_1.roots, minArgs: 1, maxArgs: 2, distElWise: false }),
11
+ solveeqs: (0, dispatch_1.systemFunction)({ fn: solveSystem_1.solveSystem, minArgs: 1, maxArgs: 1, distElWise: false }),
12
+ });
13
+ }
@@ -19,6 +19,8 @@ export type LinearSystemResult = {
19
19
  } | {
20
20
  type: 'inconsistent';
21
21
  };
22
+ export declare class NonlinearSystemError extends Error {
23
+ }
22
24
  /**
23
25
  * Solves a system of linear equations by symbolic reduced row-echelon form.
24
26
  *
@@ -1,11 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NonlinearSystemError = void 0;
3
4
  exports.solveLinearSystem = solveLinearSystem;
4
5
  const collect_1 = require("../core/classes/expression/collect");
5
6
  const Expression_1 = require("../core/classes/expression/Expression");
6
7
  const shortcuts_1 = require("../core/classes/expression/shortcuts");
7
8
  const Matrix_1 = require("../core/classes/matrix/Matrix");
8
9
  const Vector_1 = require("../core/classes/vector/Vector");
10
+ const errors_1 = require("../core/errors");
11
+ class NonlinearSystemError extends Error {
12
+ }
13
+ exports.NonlinearSystemError = NonlinearSystemError;
9
14
  /**
10
15
  * Solves a system of linear equations by symbolic reduced row-echelon form.
11
16
  *
@@ -202,8 +207,10 @@ function extractCoefficients(exprs, vars) {
202
207
  }
203
208
  else {
204
209
  // Nonlinear term
205
- throw new Error(`Nonlinear term detected in equation ${i + 1}: degree ${totalDegree} term found. ` +
206
- `solveLinearSystem only handles linear systems.`);
210
+ throw new NonlinearSystemError((0, errors_1.message)('solveLinearNonlinearDegree', {
211
+ equation: String(i + 1),
212
+ degree: String(totalDegree),
213
+ }));
207
214
  }
208
215
  });
209
216
  // Validate that no coefficient contains solve variables in non-polynomial positions
@@ -212,9 +219,10 @@ function extractCoefficients(exprs, vars) {
212
219
  for (const c of allCoeffs) {
213
220
  for (const v of vars) {
214
221
  if (c.hasVariable(v)) {
215
- throw new Error(`Nonlinear term detected in equation ${i + 1}: ` +
216
- `variable "${v}" appears in a non-polynomial position. ` +
217
- `solveLinearSystem only handles linear systems.`);
222
+ throw new NonlinearSystemError((0, errors_1.message)('solveLinearNonPolynomialVariable', {
223
+ equation: String(i + 1),
224
+ variable: v,
225
+ }));
218
226
  }
219
227
  }
220
228
  }
@@ -1,7 +1,17 @@
1
+ import { Vector } from '../core/classes/vector/Vector';
1
2
  import { type FunctionSolverOptions } from './classes/FunctionSolver';
2
3
  import { SolutionSet } from './classes/SolutionSet';
3
4
  import type { Equation } from '../core/classes/equation/Equation';
4
5
  import type { ExpressionInput } from '../core/types';
6
+ /**
7
+ * Returns polynomial roots as a Vector.
8
+ *
9
+ * Unlike solve(), which returns a SolutionSet with solver metadata, this function preserves
10
+ * the roots API's Vector return type. Numeric constants retain the historical square-root
11
+ * interpretation. Univariate polynomials delegate to PolynomialSolver and therefore return
12
+ * numerical roots.
13
+ */
14
+ export declare function roots(input: ExpressionInput, variable?: ExpressionInput): Vector;
5
15
  /**
6
16
  * Solves an equation or finds the zeros of an expression in one variable.
7
17
  *
@@ -1,21 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.roots = roots;
3
4
  exports.solve = solve;
4
5
  const factor_1 = require("../algebra/factor/factor");
5
6
  const factorCommon_1 = require("../algebra/simplify/factorCommon");
6
7
  const ratsimp_1 = require("../algebra/simplify/ratsimp");
7
8
  const Expression_1 = require("../core/classes/expression/Expression");
8
9
  const shortcuts_1 = require("../core/classes/expression/shortcuts");
10
+ const utils_1 = require("../core/classes/expression/utils");
9
11
  const constants_1 = require("../core/classes/parser/constants");
10
- const Polynomial_1 = require("../core/classes/polynomial/Polynomial");
12
+ const Vector_1 = require("../core/classes/vector/Vector");
11
13
  const trig_1 = require("../math/trig");
12
14
  const FunctionSolver_1 = require("./classes/FunctionSolver");
13
15
  const PolynomialSolver_1 = require("./classes/PolynomialSolver");
14
16
  const SolutionSet_1 = require("./classes/SolutionSet");
15
17
  const SymbolicSolver_1 = require("./classes/SymbolicSolver");
16
- const utils_1 = require("./utils");
17
- function calculateSolutions(factors, variable) {
18
- const solutionSet = new SolutionSet_1.SolutionSet();
18
+ const utils_2 = require("./utils");
19
+ /**
20
+ * Accumulates roots from distinct exact polynomial factors.
21
+ *
22
+ * Each factor result has already enforced uniqueness within that factor. Exact univariate
23
+ * factorization proves separate factors coprime, so their accepted roots can be copied
24
+ * without repeating general symbolic equality checks across factors.
25
+ */
26
+ class FactorRootAccumulator extends SolutionSet_1.SolutionSet {
27
+ appendFactorSolutions(solutions) {
28
+ for (const solution of solutions.elements) {
29
+ this.addKnownUnique(solution);
30
+ }
31
+ if (this.solutionsType === undefined) {
32
+ this.solutionsType = solutions.solutionsType;
33
+ }
34
+ else if (solutions.solutionsType !== undefined &&
35
+ this.solutionsType !== solutions.solutionsType) {
36
+ this.solutionsType = 'mixed';
37
+ }
38
+ }
39
+ }
40
+ function calculateSolutions(factors, variable, disjointPolynomialFactors = false) {
41
+ const solutionSet = disjointPolynomialFactors
42
+ ? new FactorRootAccumulator()
43
+ : new SolutionSet_1.SolutionSet();
19
44
  // We loop through each element (factor) and try to solve it. If we were successful,
20
45
  // then we return 0. If we fail then we return the value
21
46
  const firstPass = factors
@@ -30,15 +55,25 @@ function calculateSolutions(factors, variable) {
30
55
  else if (fn.hasVariable(variable)) {
31
56
  // First Symbolically
32
57
  let solutions = new SymbolicSolver_1.SymbolicSolver(fn, variable).solve();
33
- if (solutions.unsolved && fn.isPolynomialLike() && fn.getPower().gt(4)) {
58
+ if (solutions.unsolved && fn.isPolynomialLike() && fn.getPower().gt((0, shortcuts_1.four)())) {
34
59
  const linearPoly = fn.toLinearAndUnitMultiplier();
35
60
  // See if you can solve the linear polynomial
36
61
  solutions = new SymbolicSolver_1.SymbolicSolver(linearPoly, variable).solve();
37
62
  }
38
63
  if (!solutions.unsolved) {
39
- const symbolicSolutions = new SolutionSet_1.SolutionSet(solutions.solutions);
40
- symbolicSolutions.solutionsType = 'symbolic';
41
- solutionSet.addSolutions(symbolicSolutions, fn, variable);
64
+ if (disjointPolynomialFactors) {
65
+ const factorSolutions = new SolutionSet_1.SolutionSet();
66
+ factorSolutions.addSolutions(solutions.solutions, fn, variable);
67
+ if (factorSolutions.count() > 0) {
68
+ factorSolutions.solutionsType = 'symbolic';
69
+ solutionSet.appendFactorSolutions(factorSolutions);
70
+ }
71
+ }
72
+ else {
73
+ const symbolicSolutions = new SolutionSet_1.SolutionSet(solutions.solutions);
74
+ symbolicSolutions.solutionsType = 'symbolic';
75
+ solutionSet.addSolutions(symbolicSolutions, fn, variable);
76
+ }
42
77
  retval = (0, shortcuts_1.zero)();
43
78
  }
44
79
  }
@@ -53,11 +88,22 @@ function calculateSolutions(factors, variable) {
53
88
  // we need to check as not to waste time.
54
89
  const vars = fn.variables();
55
90
  if (vars.length === 1 && vars[0] === variable && fn.isPolynomialLike()) {
56
- const solutions = new PolynomialSolver_1.PolynomialSolver(new Polynomial_1.Polynomial(fn), variable).roots();
91
+ const solutions = new PolynomialSolver_1.PolynomialSolver(fn, variable).validatedRoots();
57
92
  if (solutions.length > 0) {
58
- const numericSolutions = new SolutionSet_1.SolutionSet(solutions.map(solution => solution.evaluate()));
59
- numericSolutions.solutionsType = 'numeric';
60
- solutionSet.append(numericSolutions);
93
+ if (disjointPolynomialFactors) {
94
+ const factorSolutions = new SolutionSet_1.SolutionSet();
95
+ factorSolutions.addValidatedNumericalSolutions(solutions);
96
+ factorSolutions.solutionsType = 'numeric';
97
+ solutionSet.appendFactorSolutions(factorSolutions);
98
+ }
99
+ else {
100
+ solutionSet.addValidatedNumericalSolutions(solutions);
101
+ solutionSet.solutionsType =
102
+ solutionSet.solutionsType === undefined ||
103
+ solutionSet.solutionsType === 'numeric'
104
+ ? 'numeric'
105
+ : 'mixed';
106
+ }
61
107
  }
62
108
  retval = (0, shortcuts_1.zero)();
63
109
  }
@@ -73,14 +119,49 @@ function calculateSolutions(factors, variable) {
73
119
  if (vars.length === 1 && vars[0] === variable) {
74
120
  const solutions = new FunctionSolver_1.FunctionSolver(fn, variable, options).roots();
75
121
  if (solutions.length > 0) {
76
- const numericSolutions = new SolutionSet_1.SolutionSet(solutions);
77
- numericSolutions.solutionsType = 'numeric';
78
- solutionSet.append(numericSolutions);
122
+ for (const solution of solutions) {
123
+ solutionSet.add(solution);
124
+ }
125
+ solutionSet.solutionsType =
126
+ solutionSet.solutionsType === undefined ||
127
+ solutionSet.solutionsType === 'numeric'
128
+ ? 'numeric'
129
+ : 'mixed';
79
130
  }
80
131
  }
81
132
  }
82
133
  return solutionSet;
83
134
  }
135
+ /**
136
+ * Returns polynomial roots as a Vector.
137
+ *
138
+ * Unlike solve(), which returns a SolutionSet with solver metadata, this function preserves
139
+ * the roots API's Vector return type. Numeric constants retain the historical square-root
140
+ * interpretation. Univariate polynomials delegate to PolynomialSolver and therefore return
141
+ * numerical roots.
142
+ */
143
+ function roots(input, variable) {
144
+ const expression = Expression_1.Expression.create(input);
145
+ const variables = expression.variables();
146
+ if (variables.length === 0 && expression.isConstant()) {
147
+ const evaluated = expression.evaluate();
148
+ if (evaluated.isNUM()) {
149
+ const magnitude = evaluated.abs();
150
+ const root = magnitude.pow((0, shortcuts_1.half)());
151
+ const positive = evaluated.sign() < 0
152
+ ? root.times(Expression_1.Expression.Img())
153
+ : root;
154
+ return new Vector_1.Vector([positive, positive.neg()]);
155
+ }
156
+ }
157
+ const variableName = variable === undefined
158
+ ? variables[0]
159
+ : (0, utils_1.assertPlainVariableAndGetString)(Expression_1.Expression.create(variable));
160
+ if (variableName === undefined) {
161
+ return new Vector_1.Vector([expression]);
162
+ }
163
+ return new Vector_1.Vector(new PolynomialSolver_1.PolynomialSolver(expression, variableName).validatedRoots());
164
+ }
84
165
  /**
85
166
  * Solves an equation or finds the zeros of an expression in one variable.
86
167
  *
@@ -117,7 +198,7 @@ function solve(input, variable, _options) {
117
198
  // Try to solve the equation.
118
199
  try {
119
200
  // Prepare the inputs
120
- const { expression, x } = (0, utils_1.prepareSolverInputs)(input, variable);
201
+ const { expression, x } = (0, utils_2.prepareSolverInputs)(input, variable);
121
202
  asDecimal = expression.hasDecimal();
122
203
  // Get the variables
123
204
  const vars = expression.variables();
@@ -159,6 +240,10 @@ function solve(input, variable, _options) {
159
240
  const directCoeffs = expression.isPolynomialLike()
160
241
  ? expression.coeffs(x).toArray()
161
242
  : undefined;
243
+ const isNumericUnivariatePolynomial = directCoeffs !== undefined &&
244
+ vars.length === 1 &&
245
+ vars[0] === x &&
246
+ directCoeffs.every(coefficient => coefficient.isNUM());
162
247
  let directPowerBinomialSolutions;
163
248
  if (directCoeffs) {
164
249
  const degree = directCoeffs.length - 1;
@@ -223,7 +308,17 @@ function solve(input, variable, _options) {
223
308
  else if (commonFactors) {
224
309
  solutions.addSolution((0, shortcuts_1.zero)(), expression, x);
225
310
  solutions.solutionsType = 'symbolic';
226
- solutions.addSolutions(calculateSolutions(commonFactors, x), expression, x);
311
+ const commonSolutions = calculateSolutions(commonFactors, x);
312
+ if (isNumericUnivariatePolynomial &&
313
+ commonSolutions.solutionsType === 'numeric') {
314
+ solutions.appendValidatedNumerical(commonSolutions);
315
+ }
316
+ else if (isNumericUnivariatePolynomial) {
317
+ solutions.append(commonSolutions);
318
+ }
319
+ else {
320
+ solutions.addSolutions(commonSolutions, expression, x);
321
+ }
227
322
  }
228
323
  else if (direct && !direct.unsolved) {
229
324
  const symbolicSolutions = new SolutionSet_1.SolutionSet(direct.solutions);
@@ -240,12 +335,25 @@ function solve(input, variable, _options) {
240
335
  else {
241
336
  // Get the factors object
242
337
  const factorObj = (0, factor_1.factorExpressionParts)(expression);
338
+ // Exact univariate factorization returns distinct irreducible factors with
339
+ // repeated factors represented by powers. Their solution sets can therefore
340
+ // be combined without proving cross-factor equality again.
341
+ const disjointPolynomialFactors = isNumericUnivariatePolynomial;
243
342
  // Get the extraneous roots
244
- const extraneous = calculateSolutions(factorObj.denominator, x);
343
+ const extraneous = calculateSolutions(factorObj.denominator, x, disjointPolynomialFactors);
245
344
  solutions.exclude(extraneous);
246
345
  // Get the solutions in the numerator
247
- const numSolutions = calculateSolutions(factorObj.numerator, x);
248
- solutions.addSolutions(numSolutions, expression, x);
346
+ const numSolutions = calculateSolutions(factorObj.numerator, x, disjointPolynomialFactors);
347
+ if (isNumericUnivariatePolynomial &&
348
+ numSolutions.solutionsType === 'numeric') {
349
+ solutions.appendValidatedNumerical(numSolutions);
350
+ }
351
+ else if (isNumericUnivariatePolynomial) {
352
+ solutions.append(numSolutions);
353
+ }
354
+ else {
355
+ solutions.addSolutions(numSolutions, expression, x);
356
+ }
249
357
  }
250
358
  }
251
359
  }
@@ -1,5 +1,5 @@
1
- import { Equation } from '../core/classes/equation/Equation';
2
1
  import { Vector } from '../core/classes/vector/Vector';
2
+ import type { Equation } from '../core/classes/equation/Equation';
3
3
  import type { ExpressionInput } from '../core/types';
4
4
  /**
5
5
  * Solves a system of expressions or equations for an ordered set of variables.
@@ -1,48 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.solveSystem = solveSystem;
4
- const adapters_1 = require("../algebra/adapters");
5
4
  const groebnerBase_1 = require("../algebra/algorithms/groebnerBase");
6
5
  const ratsimp_1 = require("../algebra/simplify/ratsimp");
7
6
  const Dictionary_1 = require("../core/classes/dictionary/Dictionary");
8
- const Equation_1 = require("../core/classes/equation/Equation");
9
- const analysis_1 = require("../core/classes/expression/analysis");
10
7
  const collect_1 = require("../core/classes/expression/collect");
11
- const Expression_1 = require("../core/classes/expression/Expression");
12
8
  const shortcuts_1 = require("../core/classes/expression/shortcuts");
13
- const constants_1 = require("../core/classes/parser/constants");
14
- const Parser_1 = require("../core/classes/parser/Parser");
15
- const Polynomial_1 = require("../core/classes/polynomial/Polynomial");
9
+ const SparsePolynomialAdapter_1 = require("../core/classes/polynomial/SparsePolynomialAdapter");
16
10
  const Vector_1 = require("../core/classes/vector/Vector");
17
11
  const errors_1 = require("../core/errors");
18
12
  const MultivariateSolver_1 = require("./classes/MultivariateSolver");
19
13
  const linsolve_1 = require("./linsolve");
20
14
  const solve_1 = require("./solve");
21
- function toExpression(input) {
22
- if (Equation_1.Equation.isEquation(input)) {
23
- return input.toLHS().LHS;
24
- }
25
- if (Expression_1.Expression.isExpression(input)) {
26
- return input;
27
- }
28
- const parsed = Parser_1.Parser.parse(String(input));
29
- if (Equation_1.Equation.isEquation(parsed)) {
30
- return parsed.toLHS().LHS;
31
- }
32
- if (Expression_1.Expression.isExpression(parsed)) {
33
- return parsed;
34
- }
35
- throw new errors_1.UnexpectedInputError((0, errors_1.message)('expressionExpected', { type: constants_1.dataTypes[parsed.dataType] }));
36
- }
15
+ const utils_1 = require("./utils");
37
16
  function normalizeEquations(equations) {
38
17
  if (Vector_1.Vector.isVector(equations)) {
39
18
  const result = [];
40
19
  for (let i = 0; i < equations.count(); i++) {
41
- result.push(toExpression(equations.__get__([i])));
20
+ result.push((0, utils_1.normalizeSolverExpression)(equations.__get__([i])));
42
21
  }
43
22
  return result;
44
23
  }
45
- return equations.map(eq => toExpression(eq));
24
+ return equations.map(eq => (0, utils_1.normalizeSolverExpression)(eq));
46
25
  }
47
26
  function symbolicBackSubstitution(basisExprs, vars) {
48
27
  let partials = [
@@ -248,7 +227,7 @@ function solveSystem(equations, variables) {
248
227
  }
249
228
  }
250
229
  catch (error) {
251
- if (!(error instanceof Error) || !error.message.includes('Nonlinear term detected')) {
230
+ if (!(error instanceof linsolve_1.NonlinearSystemError)) {
252
231
  throw error;
253
232
  }
254
233
  }
@@ -256,15 +235,12 @@ function solveSystem(equations, variables) {
256
235
  const allPolynomial = symbolicExpressions.every(e => e.isPolynomialLike());
257
236
  if (allPolynomial) {
258
237
  try {
259
- const polys = symbolicExpressions.map(expression => {
260
- const cleared = (0, analysis_1.normalizeMultiplierDenominators)(expression);
261
- return (0, adapters_1.polynomialToMultiPoly)(new Polynomial_1.Polynomial(cleared, vars), vars).poly;
262
- });
263
- const basis = (0, groebnerBase_1.Groebner)(polys, vars, 'LEX', true);
238
+ const polys = symbolicExpressions.map(expression => (0, SparsePolynomialAdapter_1.expressionToIntegerSparsePolynomial)(expression, vars).polynomial);
239
+ const basis = (0, groebnerBase_1.Groebner)(polys, 'LEX', true);
264
240
  if (basis.length === 1 && basis[0].isConstant() && basis[0].constantTerm() !== 0n) {
265
241
  return new Vector_1.Vector([]);
266
242
  }
267
- const basisExprs = basis.map(p => (0, adapters_1.multiPolyToExpression)(p, vars));
243
+ const basisExprs = basis.map(p => (0, SparsePolynomialAdapter_1.sparsePolynomialToExpression)(p, vars));
268
244
  let solutions = symbolicBackSubstitution(basisExprs, vars);
269
245
  if (hasRationalRewrite) {
270
246
  solutions = solutions.filter(solution => isSystemSolution(expressions, domainRestrictions, solution));
@@ -1,9 +1,10 @@
1
1
  import { Equation } from '../core/classes/equation/Equation';
2
2
  import { Expression } from '../core/classes/expression/Expression';
3
- import type { ExpressionInput } from '../core/types';
3
+ import type { ExpressionInput, NerdamerInput } from '../core/types';
4
4
  export interface SolverInputs {
5
5
  x: string;
6
6
  expression: Expression;
7
7
  }
8
+ export declare function normalizeSolverExpression(input: NerdamerInput): Expression;
8
9
  export declare function extractVariable(variable: ExpressionInput): string;
9
10
  export declare function prepareSolverInputs(input: ExpressionInput | Equation | string, variable?: ExpressionInput): SolverInputs;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeSolverExpression = normalizeSolverExpression;
3
4
  exports.extractVariable = extractVariable;
4
5
  exports.prepareSolverInputs = prepareSolverInputs;
5
6
  const Equation_1 = require("../core/classes/equation/Equation");
@@ -7,6 +8,22 @@ const Expression_1 = require("../core/classes/expression/Expression");
7
8
  const constants_1 = require("../core/classes/parser/constants");
8
9
  const Parser_1 = require("../core/classes/parser/Parser");
9
10
  const errors_1 = require("../core/errors");
11
+ function normalizeSolverExpression(input) {
12
+ if (Equation_1.Equation.isEquation(input)) {
13
+ return input.toLHS().LHS;
14
+ }
15
+ if (Expression_1.Expression.isExpression(input)) {
16
+ return input;
17
+ }
18
+ const parsed = Parser_1.Parser.parse(String(input));
19
+ if (Equation_1.Equation.isEquation(parsed)) {
20
+ return parsed.toLHS().LHS;
21
+ }
22
+ if (Expression_1.Expression.isExpression(parsed)) {
23
+ return parsed;
24
+ }
25
+ throw new errors_1.UnexpectedInputError((0, errors_1.message)('expressionExpected', { type: constants_1.dataTypes[parsed.dataType] }));
26
+ }
10
27
  function extractVariable(variable) {
11
28
  variable = Expression_1.Expression.create(variable);
12
29
  if (!variable.isPlainVariable()) {
@@ -15,28 +32,7 @@ function extractVariable(variable) {
15
32
  return variable.value;
16
33
  }
17
34
  function prepareSolverInputs(input, variable) {
18
- let expression;
19
- if (Equation_1.Equation.isEquation(input)) {
20
- expression = input.toLHS().LHS;
21
- }
22
- else if (!Expression_1.Expression.isExpression(input)) {
23
- // Cast them all to string
24
- const parsed = Parser_1.Parser.parse(String(input));
25
- // Was it an equation string?
26
- if (Equation_1.Equation.isEquation(parsed)) {
27
- expression = parsed.toLHS().LHS;
28
- }
29
- else if (!Expression_1.Expression.isExpression(parsed)) {
30
- // Complain for any other types
31
- throw new errors_1.UnexpectedInputError((0, errors_1.message)('expressionExpected', { type: constants_1.dataTypes[parsed.dataType] }));
32
- }
33
- else {
34
- expression = parsed;
35
- }
36
- }
37
- else {
38
- expression = input;
39
- }
35
+ const expression = normalizeSolverExpression(input);
40
36
  const vars = expression.variables();
41
37
  let x;
42
38
  // Get the variable to solve for
@@ -38,5 +38,5 @@ export declare function intersection<T>(arr1: T[], arr2: T[]): T[];
38
38
  * @param compareFn
39
39
  * @returns
40
40
  */
41
- export declare function syncSort<T>(arr1: T[], arr2: T[], compareFn: (a: T, b: T) => number): T[][];
41
+ export declare function syncSort<T, U>(arr1: T[], arr2: U[], compareFn: (a: T, b: T) => number): [T[], U[]];
42
42
  export declare function allEqual<T>(arr: T[]): boolean;