nerdamer 1.1.13 → 2.0.0-rc.1
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.
- package/LICENSE.md +184 -0
- package/README.md +293 -312
- package/dist/bundle.js +2 -0
- package/dist/bundle.js.LICENSE.txt +7 -0
- package/dist/parser.js +2 -0
- package/dist/parser.js.LICENSE.txt +7 -0
- package/docs-data/parser-functions.json +1960 -0
- package/index.d.ts +10 -426
- package/output/algebra/adapters.d.ts +33 -0
- package/output/algebra/adapters.js +109 -0
- package/output/algebra/algorithms/arith.d.ts +84 -0
- package/output/algebra/algorithms/arith.js +323 -0
- package/output/algebra/algorithms/factor.d.ts +3 -0
- package/output/algebra/algorithms/factor.js +5 -0
- package/output/algebra/algorithms/factorMultivariate.d.ts +23 -0
- package/output/algebra/algorithms/factorMultivariate.js +2393 -0
- package/output/algebra/algorithms/factorUnivariate.d.ts +72 -0
- package/output/algebra/algorithms/factorUnivariate.js +1072 -0
- package/output/algebra/algorithms/gcd.d.ts +22 -0
- package/output/algebra/algorithms/gcd.js +690 -0
- package/output/algebra/algorithms/groebnerBase.d.ts +157 -0
- package/output/algebra/algorithms/groebnerBase.js +1166 -0
- package/output/algebra/algorithms/multiPoly/MultiPoly.d.ts +137 -0
- package/output/algebra/algorithms/multiPoly/MultiPoly.js +346 -0
- package/output/algebra/algorithms/poly.d.ts +228 -0
- package/output/algebra/algorithms/poly.js +1299 -0
- package/output/algebra/algorithms/rational.d.ts +17 -0
- package/output/algebra/algorithms/rational.js +115 -0
- package/output/algebra/factor/factor.d.ts +62 -0
- package/output/algebra/factor/factor.js +158 -0
- package/output/algebra/gcd/gcd.d.ts +29 -0
- package/output/algebra/gcd/gcd.js +141 -0
- package/output/algebra/groebner.d.ts +21 -0
- package/output/algebra/groebner.js +42 -0
- package/output/algebra/partfrac.d.ts +19 -0
- package/output/algebra/partfrac.js +398 -0
- package/output/algebra/polynomialize.d.ts +20 -0
- package/output/algebra/polynomialize.js +24 -0
- package/output/algebra/simplify/complexsimp.d.ts +7 -0
- package/output/algebra/simplify/complexsimp.js +24 -0
- package/output/algebra/simplify/factorCommon.d.ts +13 -0
- package/output/algebra/simplify/factorCommon.js +136 -0
- package/output/algebra/simplify/funcsimp.d.ts +26 -0
- package/output/algebra/simplify/funcsimp.js +633 -0
- package/output/algebra/simplify/invtrigrewrite.d.ts +10 -0
- package/output/algebra/simplify/invtrigrewrite.js +96 -0
- package/output/algebra/simplify/ratsimp.d.ts +21 -0
- package/output/algebra/simplify/ratsimp.js +140 -0
- package/output/algebra/simplify/simplify.d.ts +25 -0
- package/output/algebra/simplify/simplify.js +228 -0
- package/output/algebra/simplify/trigreduce.d.ts +38 -0
- package/output/algebra/simplify/trigreduce.js +424 -0
- package/output/algebra/simplify/trigrewrite.d.ts +17 -0
- package/output/algebra/simplify/trigrewrite.js +156 -0
- package/output/algebra/simplify/trigsimp.d.ts +11 -0
- package/output/algebra/simplify/trigsimp.js +369 -0
- package/output/algebra/simplify/utils.d.ts +32 -0
- package/output/algebra/simplify/utils.js +56 -0
- package/output/algebra/utils.d.ts +32 -0
- package/output/algebra/utils.js +48 -0
- package/output/api/advanced.d.ts +7 -0
- package/output/api/advanced.js +18 -0
- package/output/api/algebra.d.ts +17 -0
- package/output/api/algebra.js +32 -0
- package/output/api/assumptions.d.ts +4 -0
- package/output/api/assumptions.js +11 -0
- package/output/api/calculus.d.ts +9 -0
- package/output/api/calculus.js +21 -0
- package/output/api/core.d.ts +17 -0
- package/output/api/core.js +41 -0
- package/output/api/debug.d.ts +16 -0
- package/output/api/debug.js +23 -0
- package/output/api/parser.d.ts +85 -0
- package/output/api/parser.js +16 -0
- package/output/api/solve.d.ts +10 -0
- package/output/api/solve.js +16 -0
- package/output/api/structures.d.ts +10 -0
- package/output/api/structures.js +22 -0
- package/output/calculus/derivative/diff.d.ts +30 -0
- package/output/calculus/derivative/diff.js +238 -0
- package/output/calculus/fresnel.d.ts +16 -0
- package/output/calculus/fresnel.js +39 -0
- package/output/calculus/integrate/byParts.d.ts +18 -0
- package/output/calculus/integrate/byParts.js +339 -0
- package/output/calculus/integrate/bySubstitution.d.ts +135 -0
- package/output/calculus/integrate/bySubstitution.js +411 -0
- package/output/calculus/integrate/integrate.d.ts +38 -0
- package/output/calculus/integrate/integrate.js +652 -0
- package/output/calculus/integrate/integrationTable.d.ts +2 -0
- package/output/calculus/integrate/integrationTable.js +914 -0
- package/output/calculus/integrate/utils.d.ts +28 -0
- package/output/calculus/integrate/utils.js +96 -0
- package/output/calculus/laplace/ilaplace.d.ts +31 -0
- package/output/calculus/laplace/ilaplace.js +192 -0
- package/output/calculus/laplace/ilaplaceTable.d.ts +2 -0
- package/output/calculus/laplace/ilaplaceTable.js +200 -0
- package/output/calculus/laplace/laplace.d.ts +22 -0
- package/output/calculus/laplace/laplace.js +109 -0
- package/output/calculus/laplace/laplaceTable.d.ts +2 -0
- package/output/calculus/laplace/laplaceTable.js +187 -0
- package/output/calculus/limit/limit.d.ts +35 -0
- package/output/calculus/limit/limit.js +1183 -0
- package/output/calculus/limit/limitsTable.d.ts +2 -0
- package/output/calculus/limit/limitsTable.js +7 -0
- package/output/core/Settings.d.ts +32 -0
- package/output/core/Settings.js +68 -0
- package/output/core/adapters.d.ts +18 -0
- package/output/core/adapters.js +40 -0
- package/output/core/classes/assumption/Assumption.d.ts +218 -0
- package/output/core/classes/assumption/Assumption.js +605 -0
- package/output/core/classes/assumption/assertiveFunctions.d.ts +6 -0
- package/output/core/classes/assumption/assertiveFunctions.js +64 -0
- package/output/core/classes/assumption/assume.d.ts +90 -0
- package/output/core/classes/assumption/assume.js +145 -0
- package/output/core/classes/collection/Collection.d.ts +107 -0
- package/output/core/classes/collection/Collection.js +231 -0
- package/output/core/classes/complex/Complex.d.ts +99 -0
- package/output/core/classes/complex/Complex.js +135 -0
- package/output/core/classes/decimalSet/DecimalSet.d.ts +226 -0
- package/output/core/classes/decimalSet/DecimalSet.js +453 -0
- package/output/core/classes/dictionary/Dictionary.d.ts +102 -0
- package/output/core/classes/dictionary/Dictionary.js +213 -0
- package/output/core/classes/equation/Equation.d.ts +256 -0
- package/output/core/classes/equation/Equation.js +350 -0
- package/output/core/classes/expression/CoeffObject.d.ts +100 -0
- package/output/core/classes/expression/CoeffObject.js +198 -0
- package/output/core/classes/expression/Expression.d.ts +1674 -0
- package/output/core/classes/expression/Expression.js +2332 -0
- package/output/core/classes/expression/analysis.d.ts +25 -0
- package/output/core/classes/expression/analysis.js +218 -0
- package/output/core/classes/expression/collect.d.ts +9 -0
- package/output/core/classes/expression/collect.js +49 -0
- package/output/core/classes/expression/format.d.ts +45 -0
- package/output/core/classes/expression/format.js +217 -0
- package/output/core/classes/expression/products.d.ts +23 -0
- package/output/core/classes/expression/products.js +115 -0
- package/output/core/classes/expression/shortcuts.d.ts +35 -0
- package/output/core/classes/expression/shortcuts.js +129 -0
- package/output/core/classes/expression/traversal.d.ts +31 -0
- package/output/core/classes/expression/traversal.js +216 -0
- package/output/core/classes/expression/trig.d.ts +25 -0
- package/output/core/classes/expression/trig.js +40 -0
- package/output/core/classes/expression/utils.d.ts +52 -0
- package/output/core/classes/expression/utils.js +189 -0
- package/output/core/classes/lookupTable/LookupTable.d.ts +12 -0
- package/output/core/classes/lookupTable/LookupTable.js +55 -0
- package/output/core/classes/matrix/Matrix.d.ts +227 -0
- package/output/core/classes/matrix/Matrix.js +889 -0
- package/output/core/classes/matrix/Sylvester.d.ts +11 -0
- package/output/core/classes/matrix/Sylvester.js +54 -0
- package/output/core/classes/matrix/functions.d.ts +26 -0
- package/output/core/classes/matrix/functions.js +52 -0
- package/output/core/classes/matrix/utils.d.ts +9 -0
- package/output/core/classes/matrix/utils.js +22 -0
- package/output/core/classes/parser/Parser.d.ts +480 -0
- package/output/core/classes/parser/Parser.js +1812 -0
- package/output/core/classes/parser/Token.d.ts +58 -0
- package/output/core/classes/parser/Token.js +137 -0
- package/output/core/classes/parser/constants.d.ts +160 -0
- package/output/core/classes/parser/constants.js +227 -0
- package/output/core/classes/parser/helpers.d.ts +21 -0
- package/output/core/classes/parser/helpers.js +42 -0
- package/output/core/classes/parser/operations/add.d.ts +15 -0
- package/output/core/classes/parser/operations/add.js +238 -0
- package/output/core/classes/parser/operations/comma.d.ts +7 -0
- package/output/core/classes/parser/operations/comma.js +11 -0
- package/output/core/classes/parser/operations/compare.d.ts +21 -0
- package/output/core/classes/parser/operations/compare.js +461 -0
- package/output/core/classes/parser/operations/divide.d.ts +2 -0
- package/output/core/classes/parser/operations/divide.js +72 -0
- package/output/core/classes/parser/operations/functions.d.ts +46 -0
- package/output/core/classes/parser/operations/functions.js +430 -0
- package/output/core/classes/parser/operations/multiply.d.ts +11 -0
- package/output/core/classes/parser/operations/multiply.js +321 -0
- package/output/core/classes/parser/operations/power.d.ts +48 -0
- package/output/core/classes/parser/operations/power.js +673 -0
- package/output/core/classes/parser/operations/subtract.d.ts +3 -0
- package/output/core/classes/parser/operations/subtract.js +35 -0
- package/output/core/classes/parser/preprocess.d.ts +14 -0
- package/output/core/classes/parser/preprocess.js +259 -0
- package/output/core/classes/parser/scripting/controlFlow.d.ts +121 -0
- package/output/core/classes/parser/scripting/controlFlow.js +355 -0
- package/output/core/classes/parser/scripting/evaluate.d.ts +10 -0
- package/output/core/classes/parser/scripting/evaluate.js +112 -0
- package/output/core/classes/parser/scripting/functions.d.ts +14 -0
- package/output/core/classes/parser/scripting/functions.js +59 -0
- package/output/core/classes/parser/scripting/scope.d.ts +35 -0
- package/output/core/classes/parser/scripting/scope.js +155 -0
- package/output/core/classes/parser/types.d.ts +125 -0
- package/output/core/classes/parser/types.js +2 -0
- package/output/core/classes/parser/wrappers/IndexedReference.d.ts +31 -0
- package/output/core/classes/parser/wrappers/IndexedReference.js +68 -0
- package/output/core/classes/parser/wrappers/KeyValuePair.d.ts +24 -0
- package/output/core/classes/parser/wrappers/KeyValuePair.js +51 -0
- package/output/core/classes/polynomial/Polynomial.d.ts +500 -0
- package/output/core/classes/polynomial/Polynomial.js +1149 -0
- package/output/core/classes/polynomial/Term.d.ts +222 -0
- package/output/core/classes/polynomial/Term.js +430 -0
- package/output/core/classes/polynomial/functions.d.ts +69 -0
- package/output/core/classes/polynomial/functions.js +126 -0
- package/output/core/classes/polynomial/utils.d.ts +62 -0
- package/output/core/classes/polynomial/utils.js +206 -0
- package/output/core/classes/rational/Rational.d.ts +504 -0
- package/output/core/classes/rational/Rational.js +779 -0
- package/output/core/classes/seq/SEQ.d.ts +13 -0
- package/output/core/classes/seq/SEQ.js +137 -0
- package/output/core/classes/valuesSet/ValuesSet.d.ts +179 -0
- package/output/core/classes/valuesSet/ValuesSet.js +381 -0
- package/output/core/classes/vector/Vector.d.ts +222 -0
- package/output/core/classes/vector/Vector.js +497 -0
- package/output/core/classes/vector/functions.d.ts +28 -0
- package/output/core/classes/vector/functions.js +47 -0
- package/output/core/common/classes/MathematicalAggregate.d.ts +53 -0
- package/output/core/common/classes/MathematicalAggregate.js +140 -0
- package/output/core/common/classes/Scope.d.ts +62 -0
- package/output/core/common/classes/Scope.js +122 -0
- package/output/core/common/classes/StructuredEntity.d.ts +55 -0
- package/output/core/common/classes/StructuredEntity.js +151 -0
- package/output/core/common/common.d.ts +63 -0
- package/output/core/common/common.js +279 -0
- package/output/core/common/functions/functions.d.ts +14 -0
- package/output/core/common/functions/functions.js +33 -0
- package/output/core/common/functions/structuredEntityUtils.d.ts +27 -0
- package/output/core/common/functions/structuredEntityUtils.js +40 -0
- package/output/core/converters/BaseConverter.d.ts +97 -0
- package/output/core/converters/BaseConverter.js +405 -0
- package/output/core/converters/Converter.d.ts +111 -0
- package/output/core/converters/Converter.js +802 -0
- package/output/core/converters/Pattern.d.ts +71 -0
- package/output/core/converters/Pattern.js +302 -0
- package/output/core/dispatch.d.ts +34 -0
- package/output/core/dispatch.js +304 -0
- package/output/core/errors.d.ts +531 -0
- package/output/core/errors.js +621 -0
- package/output/core/functions/bigint/bigint.d.ts +121 -0
- package/output/core/functions/bigint/bigint.js +392 -0
- package/output/core/functions/bigint/primeFactor.d.ts +49 -0
- package/output/core/functions/bigint/primeFactor.js +267 -0
- package/output/core/functions/bigint/primes.d.ts +1 -0
- package/output/core/functions/bigint/primes.js +11 -0
- package/output/core/functions/build/definitions.d.ts +12 -0
- package/output/core/functions/build/definitions.js +133 -0
- package/output/core/functions/build/index.d.ts +32 -0
- package/output/core/functions/build/index.js +136 -0
- package/output/core/functions/complex.d.ts +90 -0
- package/output/core/functions/complex.js +482 -0
- package/output/core/functions/decimal.d.ts +24 -0
- package/output/core/functions/decimal.js +664 -0
- package/output/core/functions/expand/expand.d.ts +42 -0
- package/output/core/functions/expand/expand.js +376 -0
- package/output/core/functions/fresnelNumeric.d.ts +12 -0
- package/output/core/functions/fresnelNumeric.js +123 -0
- package/output/core/functions/numeric.d.ts +140 -0
- package/output/core/functions/numeric.js +790 -0
- package/output/core/functions/rationalNormalization.d.ts +11 -0
- package/output/core/functions/rationalNormalization.js +117 -0
- package/output/core/functions/setFunction.d.ts +19 -0
- package/output/core/functions/setFunction.js +75 -0
- package/output/core/functions/string.d.ts +26 -0
- package/output/core/functions/string.js +101 -0
- package/output/core/functions/subst.d.ts +90 -0
- package/output/core/functions/subst.js +498 -0
- package/output/core/functions/utils.d.ts +24 -0
- package/output/core/functions/utils.js +51 -0
- package/output/core/types.d.ts +48 -0
- package/output/core/types.js +2 -0
- package/output/index.d.ts +339 -0
- package/output/index.js +715 -0
- package/output/math/defint/defintDecimal.d.ts +37 -0
- package/output/math/defint/defintDecimal.js +320 -0
- package/output/math/defint/defintNative.d.ts +57 -0
- package/output/math/defint/defintNative.js +292 -0
- package/output/math/geometry.d.ts +8 -0
- package/output/math/geometry.js +32 -0
- package/output/math/math.d.ts +655 -0
- package/output/math/math.js +1811 -0
- package/output/math/trig.d.ts +518 -0
- package/output/math/trig.js +1444 -0
- package/output/math/trunc.d.ts +19 -0
- package/output/math/trunc.js +36 -0
- package/output/math/utils.d.ts +60 -0
- package/output/math/utils.js +180 -0
- package/output/solve/classes/DecimalMatrix.d.ts +17 -0
- package/output/solve/classes/DecimalMatrix.js +86 -0
- package/output/solve/classes/FunctionSolver.d.ts +135 -0
- package/output/solve/classes/FunctionSolver.js +433 -0
- package/output/solve/classes/MultivariateSolver.d.ts +84 -0
- package/output/solve/classes/MultivariateSolver.js +240 -0
- package/output/solve/classes/PolynomialSolver.d.ts +85 -0
- package/output/solve/classes/PolynomialSolver.js +292 -0
- package/output/solve/classes/SolutionSet.d.ts +153 -0
- package/output/solve/classes/SolutionSet.js +357 -0
- package/output/solve/classes/Solver.d.ts +17 -0
- package/output/solve/classes/Solver.js +132 -0
- package/output/solve/classes/SymbolicSolver.d.ts +74 -0
- package/output/solve/classes/SymbolicSolver.js +601 -0
- package/output/solve/linsolve.d.ts +51 -0
- package/output/solve/linsolve.js +225 -0
- package/output/solve/solve.d.ts +34 -0
- package/output/solve/solve.js +260 -0
- package/output/solve/solveSystem.d.ts +31 -0
- package/output/solve/solveSystem.js +290 -0
- package/output/solve/utils.d.ts +9 -0
- package/output/solve/utils.js +62 -0
- package/output/utils/array.d.ts +42 -0
- package/output/utils/array.js +98 -0
- package/output/utils/debug.d.ts +131 -0
- package/output/utils/debug.js +295 -0
- package/output/utils/decimal.d.ts +3 -0
- package/output/utils/decimal.js +16 -0
- package/output/utils/numeric.d.ts +14 -0
- package/output/utils/numeric.js +51 -0
- package/output/utils/object.d.ts +26 -0
- package/output/utils/object.js +56 -0
- package/package.json +213 -57
- package/.travis.yml +0 -3
- package/Algebra.js +0 -4568
- package/BREAKING_CHANGES.md +0 -5
- package/CODE_OF_CONDUCT.md +0 -46
- package/CONTRIBUTING.md +0 -14
- package/Calculus.js +0 -2675
- package/Extra.js +0 -622
- package/Solve.js +0 -1783
- package/all.js +0 -16
- package/all.min.js +0 -1
- package/gulpfile.js +0 -16
- package/index.html +0 -158
- package/license.txt +0 -19
- package/nerdamer.core.js +0 -12510
- package/spec/LaTeX.spec.js +0 -302
- package/spec/TeXConvert.spec.js +0 -8
- package/spec/algebra.spec.js +0 -287
- package/spec/basic_parser.spec.js +0 -134
- package/spec/build.spec.js +0 -131
- package/spec/calculus.spec.js +0 -183
- package/spec/core.spec.js +0 -2970
- package/spec/extra.spec.js +0 -54
- package/spec/solve.spec.js +0 -126
- package/spec/support/jasmine.json +0 -11
- package/spec/support/utils.js +0 -42
- package/spec/text.spec.js +0 -132
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Expression } from '../core/classes/expression/Expression';
|
|
2
|
+
import { Vector } from '../core/classes/vector/Vector';
|
|
3
|
+
/**
|
|
4
|
+
* Discriminated result of exact symbolic linear-system reduction.
|
|
5
|
+
*
|
|
6
|
+
* - `type: 'unique'` — exactly one solution; `solutions` maps each variable to its value.
|
|
7
|
+
* - `type: 'infinite'` — infinitely many solutions; `solutions` maps pivot variables to
|
|
8
|
+
* Expressions in terms of free variables; `freeVariables` lists the
|
|
9
|
+
* parameter names.
|
|
10
|
+
* - `type: 'inconsistent'` — the system has no solution.
|
|
11
|
+
*/
|
|
12
|
+
export type LinearSystemResult = {
|
|
13
|
+
type: 'unique';
|
|
14
|
+
solutions: Record<string, Expression>;
|
|
15
|
+
} | {
|
|
16
|
+
type: 'infinite';
|
|
17
|
+
solutions: Record<string, Expression>;
|
|
18
|
+
freeVariables: string[];
|
|
19
|
+
} | {
|
|
20
|
+
type: 'inconsistent';
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Solves a system of linear equations by symbolic reduced row-echelon form.
|
|
24
|
+
*
|
|
25
|
+
* Each element of `equations` is an Expression representing `expr = 0`.
|
|
26
|
+
* If `variables` is omitted, the union of all variables across equations is used
|
|
27
|
+
* (sorted alphabetically for deterministic column ordering).
|
|
28
|
+
*
|
|
29
|
+
* Input Expressions and strings are interpreted as equal to zero. Coefficients
|
|
30
|
+
* may be symbolic as long as they do not contain any of the solve variables.
|
|
31
|
+
* For an underdetermined consistent system, free variables map to their own
|
|
32
|
+
* Expression and pivot variables are expressed in terms of them.
|
|
33
|
+
*
|
|
34
|
+
* @param equations - Vector of Expressions, or an array of Expressions and strings.
|
|
35
|
+
* @param variables - Optional ordered list of variable names.
|
|
36
|
+
* @returns A {@link LinearSystemResult} describing a unique, infinite, or
|
|
37
|
+
* inconsistent system.
|
|
38
|
+
* @throws {@link Error} If a solve variable occurs nonlinearly or in a
|
|
39
|
+
* non-polynomial position.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* // x + y - 3 = 0, 2x + 3y - 8 = 0
|
|
44
|
+
* const result = solveLinearSystem(
|
|
45
|
+
* [Expression.create('x+y-3'), Expression.create('2*x+3*y-8')]
|
|
46
|
+
* );
|
|
47
|
+
* // result.type === 'unique'
|
|
48
|
+
* // result.solutions === { x: Expression(1), y: Expression(2) }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function solveLinearSystem(equations: Vector | Array<Expression | string>, variables?: string[]): LinearSystemResult;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.solveLinearSystem = solveLinearSystem;
|
|
4
|
+
const collect_1 = require("../core/classes/expression/collect");
|
|
5
|
+
const Expression_1 = require("../core/classes/expression/Expression");
|
|
6
|
+
const shortcuts_1 = require("../core/classes/expression/shortcuts");
|
|
7
|
+
const Matrix_1 = require("../core/classes/matrix/Matrix");
|
|
8
|
+
const Vector_1 = require("../core/classes/vector/Vector");
|
|
9
|
+
/**
|
|
10
|
+
* Solves a system of linear equations by symbolic reduced row-echelon form.
|
|
11
|
+
*
|
|
12
|
+
* Each element of `equations` is an Expression representing `expr = 0`.
|
|
13
|
+
* If `variables` is omitted, the union of all variables across equations is used
|
|
14
|
+
* (sorted alphabetically for deterministic column ordering).
|
|
15
|
+
*
|
|
16
|
+
* Input Expressions and strings are interpreted as equal to zero. Coefficients
|
|
17
|
+
* may be symbolic as long as they do not contain any of the solve variables.
|
|
18
|
+
* For an underdetermined consistent system, free variables map to their own
|
|
19
|
+
* Expression and pivot variables are expressed in terms of them.
|
|
20
|
+
*
|
|
21
|
+
* @param equations - Vector of Expressions, or an array of Expressions and strings.
|
|
22
|
+
* @param variables - Optional ordered list of variable names.
|
|
23
|
+
* @returns A {@link LinearSystemResult} describing a unique, infinite, or
|
|
24
|
+
* inconsistent system.
|
|
25
|
+
* @throws {@link Error} If a solve variable occurs nonlinearly or in a
|
|
26
|
+
* non-polynomial position.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* // x + y - 3 = 0, 2x + 3y - 8 = 0
|
|
31
|
+
* const result = solveLinearSystem(
|
|
32
|
+
* [Expression.create('x+y-3'), Expression.create('2*x+3*y-8')]
|
|
33
|
+
* );
|
|
34
|
+
* // result.type === 'unique'
|
|
35
|
+
* // result.solutions === { x: Expression(1), y: Expression(2) }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
function solveLinearSystem(equations, variables) {
|
|
39
|
+
// Normalize input
|
|
40
|
+
const exprs = normalizeEquations(equations);
|
|
41
|
+
if (exprs.length === 0) {
|
|
42
|
+
return { type: 'unique', solutions: {} };
|
|
43
|
+
}
|
|
44
|
+
// Determine variables
|
|
45
|
+
const vars = variables ?? (0, collect_1.collectVariablesSet)(exprs);
|
|
46
|
+
if (vars.length === 0) {
|
|
47
|
+
// No variables — check if all equations are trivially 0
|
|
48
|
+
for (const expr of exprs) {
|
|
49
|
+
if (!expr.eq((0, shortcuts_1.zero)())) {
|
|
50
|
+
return { type: 'inconsistent' };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { type: 'unique', solutions: {} };
|
|
54
|
+
}
|
|
55
|
+
// Extract coefficients and build augmented matrix
|
|
56
|
+
const { coeffMatrix, constants } = extractCoefficients(exprs, vars);
|
|
57
|
+
// Build augmented matrix [A | -b] where each equation is a_1*x_1 + ... + a_n*x_n + c = 0
|
|
58
|
+
// so the augmented column is -c
|
|
59
|
+
const numRows = exprs.length;
|
|
60
|
+
const numCols = vars.length;
|
|
61
|
+
const augRows = [];
|
|
62
|
+
for (let i = 0; i < numRows; i++) {
|
|
63
|
+
const row = [];
|
|
64
|
+
for (let j = 0; j < numCols; j++) {
|
|
65
|
+
row.push(coeffMatrix[i][j]);
|
|
66
|
+
}
|
|
67
|
+
// Augmented column: negate the constant
|
|
68
|
+
row.push((0, shortcuts_1.zero)().minus(constants[i]));
|
|
69
|
+
augRows.push(row);
|
|
70
|
+
}
|
|
71
|
+
const augmented = new Matrix_1.Matrix(...augRows);
|
|
72
|
+
// RREF
|
|
73
|
+
const R = augmented.rref();
|
|
74
|
+
const rRows = R.rows();
|
|
75
|
+
// const rCols = R.cols(); // = numCols + 1
|
|
76
|
+
const z = (0, shortcuts_1.zero)();
|
|
77
|
+
// Identify pivots and check consistency
|
|
78
|
+
const pivotCol = []; // pivotCol[i] = column of pivot in row i, or -1
|
|
79
|
+
for (let i = 0; i < rRows; i++) {
|
|
80
|
+
let found = -1;
|
|
81
|
+
for (let j = 0; j < numCols; j++) {
|
|
82
|
+
if (!R.get(i, j).eq(z)) {
|
|
83
|
+
found = j;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (found === -1) {
|
|
88
|
+
// All variable columns are zero — check augmented column
|
|
89
|
+
const rhs = R.get(i, numCols);
|
|
90
|
+
if (!rhs.eq(z)) {
|
|
91
|
+
return { type: 'inconsistent' };
|
|
92
|
+
}
|
|
93
|
+
// Otherwise it's a trivial 0 = 0 row
|
|
94
|
+
pivotCol.push(-1);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
pivotCol.push(found);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Identify pivot vs free variable columns
|
|
101
|
+
const pivotColSet = new Set();
|
|
102
|
+
for (const pc of pivotCol) {
|
|
103
|
+
if (pc !== -1) {
|
|
104
|
+
pivotColSet.add(pc);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const freeColIndices = [];
|
|
108
|
+
for (let j = 0; j < numCols; j++) {
|
|
109
|
+
if (!pivotColSet.has(j)) {
|
|
110
|
+
freeColIndices.push(j);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Unique solution
|
|
114
|
+
if (freeColIndices.length === 0) {
|
|
115
|
+
const solutions = {};
|
|
116
|
+
for (let i = 0; i < rRows; i++) {
|
|
117
|
+
const pc = pivotCol[i];
|
|
118
|
+
if (pc !== -1) {
|
|
119
|
+
solutions[vars[pc]] = R.get(i, numCols);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { type: 'unique', solutions };
|
|
123
|
+
}
|
|
124
|
+
// Infinite solutions
|
|
125
|
+
// Free variables are parameters; pivot variables are expressed in terms of them.
|
|
126
|
+
const freeVariables = freeColIndices.map(j => vars[j]);
|
|
127
|
+
const solutions = {};
|
|
128
|
+
// Free variables map to themselves
|
|
129
|
+
for (const freeVar of freeVariables) {
|
|
130
|
+
solutions[freeVar] = Expression_1.Expression.create(freeVar);
|
|
131
|
+
}
|
|
132
|
+
// Pivot variables: x_pivot = rhs - sum(coeff * freeVar)
|
|
133
|
+
for (let i = 0; i < rRows; i++) {
|
|
134
|
+
const pc = pivotCol[i];
|
|
135
|
+
if (pc === -1) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
let expr = R.get(i, numCols);
|
|
139
|
+
for (const fj of freeColIndices) {
|
|
140
|
+
const coeff = R.get(i, fj);
|
|
141
|
+
if (!coeff.eq(z)) {
|
|
142
|
+
// x_pivot = rhs - coeff * freeVar
|
|
143
|
+
expr = expr.minus(coeff.times(Expression_1.Expression.create(vars[fj])));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
solutions[vars[pc]] = expr;
|
|
147
|
+
}
|
|
148
|
+
return { type: 'infinite', solutions, freeVariables };
|
|
149
|
+
}
|
|
150
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
151
|
+
// Helpers
|
|
152
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
153
|
+
/**
|
|
154
|
+
* Normalizes input to an array of Expressions.
|
|
155
|
+
*/
|
|
156
|
+
function normalizeEquations(equations) {
|
|
157
|
+
if (Vector_1.Vector.isVector(equations)) {
|
|
158
|
+
const result = [];
|
|
159
|
+
for (let i = 0; i < equations.count(); i++) {
|
|
160
|
+
result.push(equations.getExpressionAt(i));
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
return equations.map(e => (Expression_1.Expression.isExpression(e) ? e : Expression_1.Expression.create(e)));
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Extracts the coefficient matrix and constant vector from linear expressions.
|
|
168
|
+
*
|
|
169
|
+
* For each expression, uses `expr.coeffs(...vars)` to get a CoeffObject.
|
|
170
|
+
* The CoeffObject keys are comma-separated multi-degree tuples like "1,0" for x in [x, y].
|
|
171
|
+
* The constant term has the all-zeros key (e.g. "0,0").
|
|
172
|
+
*
|
|
173
|
+
* Throws if any term has degree > 1 in any variable (nonlinear).
|
|
174
|
+
*/
|
|
175
|
+
function extractCoefficients(exprs, vars) {
|
|
176
|
+
const n = vars.length;
|
|
177
|
+
const coeffMatrix = [];
|
|
178
|
+
const constants = [];
|
|
179
|
+
for (let i = 0; i < exprs.length; i++) {
|
|
180
|
+
const expr = exprs[i];
|
|
181
|
+
const coeffObj = expr.coeffs(...vars);
|
|
182
|
+
const row = new Array(n).fill(null).map(() => (0, shortcuts_1.zero)());
|
|
183
|
+
let constant = (0, shortcuts_1.zero)();
|
|
184
|
+
// CoeffObject stores coefficients in .coeffs keyed by comma-separated degree tuples.
|
|
185
|
+
// e.g. for vars [x, y]: "1,0" means x^1*y^0 (coefficient of x),
|
|
186
|
+
// "0,0" is the constant term, "0,1" is coefficient of y, etc.
|
|
187
|
+
// Use .each() to iterate over all entries.
|
|
188
|
+
coeffObj.each((coeff, key) => {
|
|
189
|
+
const degrees = key.split(',').map(Number);
|
|
190
|
+
// Check total degree
|
|
191
|
+
const totalDegree = degrees.reduce((sum, d) => sum + d, 0);
|
|
192
|
+
if (totalDegree === 0) {
|
|
193
|
+
// Constant term
|
|
194
|
+
constant = coeff;
|
|
195
|
+
}
|
|
196
|
+
else if (totalDegree === 1) {
|
|
197
|
+
// Linear term — find which variable
|
|
198
|
+
const varIndex = degrees.findIndex(d => d === 1);
|
|
199
|
+
if (varIndex !== -1) {
|
|
200
|
+
row[varIndex] = coeff;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// Nonlinear term
|
|
205
|
+
throw new Error(`Nonlinear term detected in equation ${i + 1}: degree ${totalDegree} term found. ` +
|
|
206
|
+
`solveLinearSystem only handles linear systems.`);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
// Validate that no coefficient contains solve variables in non-polynomial positions
|
|
210
|
+
// (e.g. sin(x) would be absorbed as a "constant" but still contains x)
|
|
211
|
+
const allCoeffs = [...row, constant];
|
|
212
|
+
for (const c of allCoeffs) {
|
|
213
|
+
for (const v of vars) {
|
|
214
|
+
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.`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
coeffMatrix.push(row);
|
|
222
|
+
constants.push(constant);
|
|
223
|
+
}
|
|
224
|
+
return { coeffMatrix, constants };
|
|
225
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type FunctionSolverOptions } from './classes/FunctionSolver';
|
|
2
|
+
import { SolutionSet } from './classes/SolutionSet';
|
|
3
|
+
import type { Equation } from '../core/classes/equation/Equation';
|
|
4
|
+
import type { ExpressionInput } from '../core/types';
|
|
5
|
+
/**
|
|
6
|
+
* Solves an equation or finds the zeros of an expression in one variable.
|
|
7
|
+
*
|
|
8
|
+
* The solver normalizes the input to `expression = 0`, tries direct symbolic
|
|
9
|
+
* transformations, factors numerator and denominator, and then applies
|
|
10
|
+
* symbolic, polynomial-numeric, and limited-range function-numeric strategies to the
|
|
11
|
+
* factors. Zeros of denominator factors are excluded from the result.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* Numerical fallback is heuristic and searches a finite range, so an empty result does
|
|
15
|
+
* not in general prove that no solution exists. Strategy and input errors are absorbed
|
|
16
|
+
* by this convenience entry point and produce the solutions collected before
|
|
17
|
+
* the failure. Decimal input marks returned solutions for decimal formatting.
|
|
18
|
+
*
|
|
19
|
+
* The `options` parameter is currently reserved and is not forwarded to the
|
|
20
|
+
* numerical strategies.
|
|
21
|
+
*
|
|
22
|
+
* @param input - Expression or equation to solve.
|
|
23
|
+
* @param variable - Variable to solve for. When omitted, input preparation
|
|
24
|
+
* infers it where possible.
|
|
25
|
+
* @param _options - Reserved numerical-solver options.
|
|
26
|
+
* @returns A {@link SolutionSet}. The special `all` expression represents an
|
|
27
|
+
* identity that is true for every value of the variable.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const roots = solve('x^2-1', 'x');
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function solve(input: ExpressionInput | Equation, variable?: ExpressionInput, _options?: FunctionSolverOptions): SolutionSet;
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.solve = solve;
|
|
4
|
+
const factor_1 = require("../algebra/factor/factor");
|
|
5
|
+
const factorCommon_1 = require("../algebra/simplify/factorCommon");
|
|
6
|
+
const ratsimp_1 = require("../algebra/simplify/ratsimp");
|
|
7
|
+
const Expression_1 = require("../core/classes/expression/Expression");
|
|
8
|
+
const shortcuts_1 = require("../core/classes/expression/shortcuts");
|
|
9
|
+
const constants_1 = require("../core/classes/parser/constants");
|
|
10
|
+
const Polynomial_1 = require("../core/classes/polynomial/Polynomial");
|
|
11
|
+
const trig_1 = require("../math/trig");
|
|
12
|
+
const FunctionSolver_1 = require("./classes/FunctionSolver");
|
|
13
|
+
const PolynomialSolver_1 = require("./classes/PolynomialSolver");
|
|
14
|
+
const SolutionSet_1 = require("./classes/SolutionSet");
|
|
15
|
+
const SymbolicSolver_1 = require("./classes/SymbolicSolver");
|
|
16
|
+
const utils_1 = require("./utils");
|
|
17
|
+
function calculateSolutions(factors, variable) {
|
|
18
|
+
const solutionSet = new SolutionSet_1.SolutionSet();
|
|
19
|
+
// We loop through each element (factor) and try to solve it. If we were successful,
|
|
20
|
+
// then we return 0. If we fail then we return the value
|
|
21
|
+
const firstPass = factors
|
|
22
|
+
.map(fn => {
|
|
23
|
+
let retval = fn;
|
|
24
|
+
// The exponential function has no zeros, so an e^u factor contributes no
|
|
25
|
+
// solutions and must not be sent through the numerical scan over a fixed interval.
|
|
26
|
+
if (fn.isEXP() && fn.getBase().isE()) {
|
|
27
|
+
retval = (0, shortcuts_1.zero)();
|
|
28
|
+
}
|
|
29
|
+
// Don't even try to solve the function if it does not have x
|
|
30
|
+
else if (fn.hasVariable(variable)) {
|
|
31
|
+
// First Symbolically
|
|
32
|
+
let solutions = new SymbolicSolver_1.SymbolicSolver(fn, variable).solve();
|
|
33
|
+
if (solutions.unsolved && fn.isPolynomialLike() && fn.getPower().gt(4)) {
|
|
34
|
+
const linearPoly = fn.toLinearAndUnitMultiplier();
|
|
35
|
+
// See if you can solve the linear polynomial
|
|
36
|
+
solutions = new SymbolicSolver_1.SymbolicSolver(linearPoly, variable).solve();
|
|
37
|
+
}
|
|
38
|
+
if (!solutions.unsolved) {
|
|
39
|
+
const symbolicSolutions = new SolutionSet_1.SolutionSet(solutions.solutions);
|
|
40
|
+
symbolicSolutions.solutionsType = 'symbolic';
|
|
41
|
+
solutionSet.addSolutions(symbolicSolutions, fn, variable);
|
|
42
|
+
retval = (0, shortcuts_1.zero)();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return retval;
|
|
46
|
+
})
|
|
47
|
+
.filter(fn => !fn.eq((0, shortcuts_1.zero)()));
|
|
48
|
+
// For the second pass we solve polynomials using polynomials using numerical methods.
|
|
49
|
+
const secondPass = firstPass
|
|
50
|
+
.map(fn => {
|
|
51
|
+
let retval = fn;
|
|
52
|
+
// Numerical methods are only capable of solving univariate polynomials so
|
|
53
|
+
// we need to check as not to waste time.
|
|
54
|
+
const vars = fn.variables();
|
|
55
|
+
if (vars.length === 1 && vars[0] === variable && fn.isPolynomialLike()) {
|
|
56
|
+
const solutions = new PolynomialSolver_1.PolynomialSolver(new Polynomial_1.Polynomial(fn), variable).roots();
|
|
57
|
+
if (solutions.length > 0) {
|
|
58
|
+
const numericSolutions = new SolutionSet_1.SolutionSet(solutions.map(solution => solution.evaluate()));
|
|
59
|
+
numericSolutions.solutionsType = 'numeric';
|
|
60
|
+
solutionSet.append(numericSolutions);
|
|
61
|
+
}
|
|
62
|
+
retval = (0, shortcuts_1.zero)();
|
|
63
|
+
}
|
|
64
|
+
return retval;
|
|
65
|
+
})
|
|
66
|
+
.filter(fn => !fn.eq((0, shortcuts_1.zero)()));
|
|
67
|
+
// We ultimately fall back to numerical methods
|
|
68
|
+
for (const fn of secondPass) {
|
|
69
|
+
// Numerical methods are only capable of solving univariate functions so
|
|
70
|
+
// we need to check as not to waste time.
|
|
71
|
+
const vars = fn.variables();
|
|
72
|
+
const options = { method: 'Brent' };
|
|
73
|
+
if (vars.length === 1 && vars[0] === variable) {
|
|
74
|
+
const solutions = new FunctionSolver_1.FunctionSolver(fn, variable, options).roots();
|
|
75
|
+
if (solutions.length > 0) {
|
|
76
|
+
const numericSolutions = new SolutionSet_1.SolutionSet(solutions);
|
|
77
|
+
numericSolutions.solutionsType = 'numeric';
|
|
78
|
+
solutionSet.append(numericSolutions);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return solutionSet;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Solves an equation or finds the zeros of an expression in one variable.
|
|
86
|
+
*
|
|
87
|
+
* The solver normalizes the input to `expression = 0`, tries direct symbolic
|
|
88
|
+
* transformations, factors numerator and denominator, and then applies
|
|
89
|
+
* symbolic, polynomial-numeric, and limited-range function-numeric strategies to the
|
|
90
|
+
* factors. Zeros of denominator factors are excluded from the result.
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* Numerical fallback is heuristic and searches a finite range, so an empty result does
|
|
94
|
+
* not in general prove that no solution exists. Strategy and input errors are absorbed
|
|
95
|
+
* by this convenience entry point and produce the solutions collected before
|
|
96
|
+
* the failure. Decimal input marks returned solutions for decimal formatting.
|
|
97
|
+
*
|
|
98
|
+
* The `options` parameter is currently reserved and is not forwarded to the
|
|
99
|
+
* numerical strategies.
|
|
100
|
+
*
|
|
101
|
+
* @param input - Expression or equation to solve.
|
|
102
|
+
* @param variable - Variable to solve for. When omitted, input preparation
|
|
103
|
+
* infers it where possible.
|
|
104
|
+
* @param _options - Reserved numerical-solver options.
|
|
105
|
+
* @returns A {@link SolutionSet}. The special `all` expression represents an
|
|
106
|
+
* identity that is true for every value of the variable.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const roots = solve('x^2-1', 'x');
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
function solve(input, variable, _options) {
|
|
114
|
+
// The solution set that's being returned
|
|
115
|
+
const solutions = new SolutionSet_1.SolutionSet();
|
|
116
|
+
let asDecimal = false;
|
|
117
|
+
// Try to solve the equation.
|
|
118
|
+
try {
|
|
119
|
+
// Prepare the inputs
|
|
120
|
+
const { expression, x } = (0, utils_1.prepareSolverInputs)(input, variable);
|
|
121
|
+
asDecimal = expression.hasDecimal();
|
|
122
|
+
// Get the variables
|
|
123
|
+
const vars = expression.variables();
|
|
124
|
+
// Handle the zero polynomial. This has as return type the special value all
|
|
125
|
+
if (expression.isZero()) {
|
|
126
|
+
solutions.addSolution((0, shortcuts_1.all)(), expression, x);
|
|
127
|
+
solutions.solutionsType = 'symbolic';
|
|
128
|
+
}
|
|
129
|
+
// For monomials a*x^n the value is zero for all values of x
|
|
130
|
+
else if (expression.isVAR() || (!vars.includes(x) && !expression.isNUM())) {
|
|
131
|
+
// There's not need to check if the variable matches x as this one done in prepareSolverInputs
|
|
132
|
+
solutions.addSolution((0, shortcuts_1.zero)(), expression, x);
|
|
133
|
+
solutions.solutionsType = 'symbolic';
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// The strategy is a follows:
|
|
137
|
+
// 1. Try the original expression symbolically before factoring. This avoids expensive
|
|
138
|
+
// factorization when the existing symbolic solver can already close the equation.
|
|
139
|
+
// 2. Factor the expression. Take the divide and conquer approach. Solve the smaller parts. The factors function
|
|
140
|
+
// helps by breaking both the numerator and the denominator into their factors.
|
|
141
|
+
// 3. We only need to solve the numerator. The denominator only gives us singularities.
|
|
142
|
+
// We return that as the extraneous roots.
|
|
143
|
+
// 4. Try to solve symbolically with the symbol solver.
|
|
144
|
+
// 5. Try to solve polynomials numerically as a fallback.
|
|
145
|
+
// 6. When all else fails, switch to a numerical solver.
|
|
146
|
+
const containsRadicalTerm = expression.isSum() &&
|
|
147
|
+
expression.elementsArray().some(term => {
|
|
148
|
+
let retval = term.hasVariable(x) && term.getPower().eq((0, shortcuts_1.half)());
|
|
149
|
+
if (!retval && term.isProduct() && term.hasVariable(x)) {
|
|
150
|
+
const variableFactors = term
|
|
151
|
+
.elementsArray()
|
|
152
|
+
.filter(factor => factor.hasVariable(x));
|
|
153
|
+
retval =
|
|
154
|
+
variableFactors.length === 1 &&
|
|
155
|
+
variableFactors[0].getPower().eq((0, shortcuts_1.half)().neg());
|
|
156
|
+
}
|
|
157
|
+
return retval;
|
|
158
|
+
});
|
|
159
|
+
const directCoeffs = expression.isPolynomialLike()
|
|
160
|
+
? expression.coeffs(x).toArray()
|
|
161
|
+
: undefined;
|
|
162
|
+
let directPowerBinomialSolutions;
|
|
163
|
+
if (directCoeffs) {
|
|
164
|
+
const degree = directCoeffs.length - 1;
|
|
165
|
+
const hasSymbolicCoefficients = directCoeffs.some(coefficient => coefficient.variables().length > 0);
|
|
166
|
+
const isPowerBinomial = degree > 4 &&
|
|
167
|
+
hasSymbolicCoefficients &&
|
|
168
|
+
!directCoeffs[0].isZero() &&
|
|
169
|
+
directCoeffs.slice(1, degree).every(coefficient => coefficient.isZero());
|
|
170
|
+
if (isPowerBinomial) {
|
|
171
|
+
const degreeExpression = Expression_1.Expression.create(degree);
|
|
172
|
+
const rootPower = (0, shortcuts_1.one)().div(degreeExpression);
|
|
173
|
+
const radicand = directCoeffs[0].neg().div(directCoeffs[degree]);
|
|
174
|
+
const principalRoot = Expression_1.Expression.toEXP(radicand, rootPower);
|
|
175
|
+
const fullTurn = (0, shortcuts_1.two)().times(Expression_1.Expression.Variable(constants_1.PI_NAME));
|
|
176
|
+
directPowerBinomialSolutions = [];
|
|
177
|
+
for (let k = 0; k < degree; k++) {
|
|
178
|
+
let rotation = (0, shortcuts_1.one)();
|
|
179
|
+
if (k > 0) {
|
|
180
|
+
const angle = fullTurn
|
|
181
|
+
.copy()
|
|
182
|
+
.times(Expression_1.Expression.create(k))
|
|
183
|
+
.div(degreeExpression);
|
|
184
|
+
rotation = (0, trig_1.cos)(angle).plus((0, trig_1.sin)(angle).times(Expression_1.Expression.Img()));
|
|
185
|
+
}
|
|
186
|
+
directPowerBinomialSolutions.push(principalRoot.copy().times(rotation));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const commonFactored = directCoeffs?.length === 3 && directCoeffs[0].isZero()
|
|
191
|
+
? (0, factorCommon_1.factorCommonPower)(expression)
|
|
192
|
+
: undefined;
|
|
193
|
+
const commonFactors = commonFactored?.isProduct()
|
|
194
|
+
? commonFactored.elementsArray()
|
|
195
|
+
: undefined;
|
|
196
|
+
const direct = containsRadicalTerm
|
|
197
|
+
? new SymbolicSolver_1.SymbolicSolver(expression, x).solve()
|
|
198
|
+
: undefined;
|
|
199
|
+
let rationalNumerator;
|
|
200
|
+
let rationalDenominator;
|
|
201
|
+
if (!expression.isPolynomialLike()) {
|
|
202
|
+
try {
|
|
203
|
+
const rational = (0, ratsimp_1.toCommonDenominator)(expression);
|
|
204
|
+
const numerator = rational.getNumerator().expand();
|
|
205
|
+
const denominator = rational.getDenominator().expand();
|
|
206
|
+
if (!denominator.isOne() &&
|
|
207
|
+
numerator.isPolynomialLike() &&
|
|
208
|
+
denominator.isPolynomialLike()) {
|
|
209
|
+
rationalNumerator = numerator;
|
|
210
|
+
rationalDenominator = denominator;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// This is an optimization path. If rational normalization is not supported,
|
|
215
|
+
// continue with the existing factorization and numerical strategies below.
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (directPowerBinomialSolutions) {
|
|
219
|
+
const symbolicSolutions = new SolutionSet_1.SolutionSet(directPowerBinomialSolutions);
|
|
220
|
+
symbolicSolutions.solutionsType = 'symbolic';
|
|
221
|
+
solutions.addSolutions(symbolicSolutions, expression, x);
|
|
222
|
+
}
|
|
223
|
+
else if (commonFactors) {
|
|
224
|
+
solutions.addSolution((0, shortcuts_1.zero)(), expression, x);
|
|
225
|
+
solutions.solutionsType = 'symbolic';
|
|
226
|
+
solutions.addSolutions(calculateSolutions(commonFactors, x), expression, x);
|
|
227
|
+
}
|
|
228
|
+
else if (direct && !direct.unsolved) {
|
|
229
|
+
const symbolicSolutions = new SolutionSet_1.SolutionSet(direct.solutions);
|
|
230
|
+
symbolicSolutions.solutionsType = 'symbolic';
|
|
231
|
+
solutions.addSolutions(symbolicSolutions, expression, x);
|
|
232
|
+
}
|
|
233
|
+
else if (rationalNumerator && rationalDenominator) {
|
|
234
|
+
// A rational expression is zero exactly where its polynomial numerator is zero,
|
|
235
|
+
// except at denominator singularities. Avoid polynomializing the nested quotient again.
|
|
236
|
+
const extraneous = calculateSolutions([rationalDenominator], x);
|
|
237
|
+
solutions.exclude(extraneous);
|
|
238
|
+
solutions.addSolutions(calculateSolutions([rationalNumerator], x), expression, x);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// Get the factors object
|
|
242
|
+
const factorObj = (0, factor_1.factorExpressionParts)(expression);
|
|
243
|
+
// Get the extraneous roots
|
|
244
|
+
const extraneous = calculateSolutions(factorObj.denominator, x);
|
|
245
|
+
solutions.exclude(extraneous);
|
|
246
|
+
// Get the solutions in the numerator
|
|
247
|
+
const numSolutions = calculateSolutions(factorObj.numerator, x);
|
|
248
|
+
solutions.addSolutions(numSolutions, expression, x);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (_e) { }
|
|
253
|
+
if (asDecimal) {
|
|
254
|
+
solutions.each(solution => {
|
|
255
|
+
solution.getMultiplier().asDecimal = true;
|
|
256
|
+
return solution;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return solutions;
|
|
260
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Equation } from '../core/classes/equation/Equation';
|
|
2
|
+
import { Vector } from '../core/classes/vector/Vector';
|
|
3
|
+
import type { ExpressionInput } from '../core/types';
|
|
4
|
+
/**
|
|
5
|
+
* Solves a system of expressions or equations for an ordered set of variables.
|
|
6
|
+
*
|
|
7
|
+
* Expressions are interpreted as equal to zero. The solver first tries exact
|
|
8
|
+
* linear reduction, then a lexicographic Groebner basis with symbolic back
|
|
9
|
+
* substitution for polynomial systems, and finally multivariate Newton-Raphson
|
|
10
|
+
* over a fixed search interval. Rational polynomial systems may have denominators
|
|
11
|
+
* cleared for symbolic work; candidates are checked against the original domain.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* The nonlinear numerical fallback is heuristic and does not guarantee all
|
|
15
|
+
* roots. A returned outer {@link Vector} contains one {@link Dictionary} per
|
|
16
|
+
* solution. An empty system has one empty solution, while no discovered or
|
|
17
|
+
* inconsistent solution is represented by an empty Vector.
|
|
18
|
+
*
|
|
19
|
+
* Infinite nonlinear solution sets are not represented. Underdetermined
|
|
20
|
+
* systems that reach numerical fallback are rejected.
|
|
21
|
+
*
|
|
22
|
+
* @param equations - Vector or array of equations and zero-valued expressions.
|
|
23
|
+
* @param variables - Optional variable order. When omitted, variables are
|
|
24
|
+
* collected from the normalized expressions.
|
|
25
|
+
* @returns A Vector of solution dictionaries keyed by variable name.
|
|
26
|
+
* @throws {@link core!UnexpectedInputError} If an input cannot be normalized to an
|
|
27
|
+
* Expression or Equation.
|
|
28
|
+
* @throws {@link core!UnsupportedOperationError} If a solution is not isolated or an
|
|
29
|
+
* underdetermined nonlinear system reaches numerical fallback.
|
|
30
|
+
*/
|
|
31
|
+
export declare function solveSystem(equations: Vector | Array<ExpressionInput | Equation | string>, variables?: string[]): Vector;
|