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,74 @@
|
|
|
1
|
+
import { Expression } from '../../core/classes/expression/Expression';
|
|
2
|
+
import { Polynomial } from '../../core/classes/polynomial/Polynomial';
|
|
3
|
+
import type { ExpressionInput } from '../../core/types';
|
|
4
|
+
/**
|
|
5
|
+
* Applies a defined set of exact transformations to one equation in one variable.
|
|
6
|
+
*
|
|
7
|
+
* Polynomial equations through degree four use closed-form formulas. Other
|
|
8
|
+
* recognized forms are solved by isolating and inverting elementary functions,
|
|
9
|
+
* exponentials, logarithmic sums, or a single square-root term. Unsupported
|
|
10
|
+
* input is reported by {@link solve} as `unsolved` so a caller can select a
|
|
11
|
+
* different strategy.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* This class is the symbolic strategy used by the ordinary solver; it is not a
|
|
15
|
+
* general proof procedure. Inverse-function results follow the symbolic forms
|
|
16
|
+
* implemented here, including parameterized families for direct trigonometric
|
|
17
|
+
* functions. The supplied Expression is retained, while Polynomial input is
|
|
18
|
+
* converted to its Expression representation.
|
|
19
|
+
*/
|
|
20
|
+
export declare class SymbolicSolver {
|
|
21
|
+
private static readonly MAX_FN_SOLVE_STEPS;
|
|
22
|
+
private input;
|
|
23
|
+
private x;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a symbolic solver for `input = 0`.
|
|
26
|
+
*
|
|
27
|
+
* @param input - Polynomial or expression whose zeros are sought.
|
|
28
|
+
* @param v - Plain variable to solve for.
|
|
29
|
+
* @throws {@link core!UnexpectedInputError} If `v` is not a plain variable.
|
|
30
|
+
*/
|
|
31
|
+
constructor(input: Polynomial | string | Expression, v: ExpressionInput);
|
|
32
|
+
/**
|
|
33
|
+
* Solves `coeffs[3]x^3 + coeffs[2]x^2 + coeffs[1]x + coeffs[0] = 0`
|
|
34
|
+
* with Cardano's formula.
|
|
35
|
+
*
|
|
36
|
+
* @param coeffs - Four coefficients in ascending-power order.
|
|
37
|
+
* @returns Three symbolic root expressions.
|
|
38
|
+
*/
|
|
39
|
+
static cubic(coeffs: Expression[]): Expression[];
|
|
40
|
+
/**
|
|
41
|
+
* Solves `coeffs[2]x^2 + coeffs[1]x + coeffs[0] = 0` symbolically.
|
|
42
|
+
*
|
|
43
|
+
* @param coeffs - Three coefficients in ascending-power order.
|
|
44
|
+
* @returns The two quadratic-formula roots.
|
|
45
|
+
*/
|
|
46
|
+
static quadratic(coeffs: Expression[]): Expression[];
|
|
47
|
+
/**
|
|
48
|
+
* Solves a quartic from five ascending-power coefficients with Ferrari's method.
|
|
49
|
+
*
|
|
50
|
+
* @param coeffs - Coefficients from the constant through fourth-degree term.
|
|
51
|
+
* @returns Four symbolic root expressions.
|
|
52
|
+
*/
|
|
53
|
+
static quartic(coeffs: Expression[]): Expression[];
|
|
54
|
+
/**
|
|
55
|
+
* Attempts the supported elementary-function and radical transformations.
|
|
56
|
+
*
|
|
57
|
+
* @returns Symbolic solutions, or `undefined` when no supported transformation
|
|
58
|
+
* closes the equation.
|
|
59
|
+
*/
|
|
60
|
+
private fnSolve;
|
|
61
|
+
private invertFunction;
|
|
62
|
+
/** Returns whether any node in the configured input is a function call. */
|
|
63
|
+
inputContainsFunction(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Attempts polynomial formulas and then supported function transformations.
|
|
66
|
+
*
|
|
67
|
+
* @returns An object containing `solutions` and, when the strategy cannot
|
|
68
|
+
* solve the equation, the original `unsolved` expression.
|
|
69
|
+
*/
|
|
70
|
+
solve(): {
|
|
71
|
+
solutions: Expression[];
|
|
72
|
+
unsolved: Expression | undefined;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SymbolicSolver = void 0;
|
|
4
|
+
const Expression_1 = require("../../core/classes/expression/Expression");
|
|
5
|
+
const shortcuts_1 = require("../../core/classes/expression/shortcuts");
|
|
6
|
+
const constants_1 = require("../../core/classes/parser/constants");
|
|
7
|
+
const Polynomial_1 = require("../../core/classes/polynomial/Polynomial");
|
|
8
|
+
const errors_1 = require("../../core/errors");
|
|
9
|
+
const math_1 = require("../../math/math");
|
|
10
|
+
const trig_1 = require("../../math/trig");
|
|
11
|
+
const utils_1 = require("../../math/utils");
|
|
12
|
+
const solve_1 = require("../solve");
|
|
13
|
+
/**
|
|
14
|
+
* Applies a defined set of exact transformations to one equation in one variable.
|
|
15
|
+
*
|
|
16
|
+
* Polynomial equations through degree four use closed-form formulas. Other
|
|
17
|
+
* recognized forms are solved by isolating and inverting elementary functions,
|
|
18
|
+
* exponentials, logarithmic sums, or a single square-root term. Unsupported
|
|
19
|
+
* input is reported by {@link solve} as `unsolved` so a caller can select a
|
|
20
|
+
* different strategy.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* This class is the symbolic strategy used by the ordinary solver; it is not a
|
|
24
|
+
* general proof procedure. Inverse-function results follow the symbolic forms
|
|
25
|
+
* implemented here, including parameterized families for direct trigonometric
|
|
26
|
+
* functions. The supplied Expression is retained, while Polynomial input is
|
|
27
|
+
* converted to its Expression representation.
|
|
28
|
+
*/
|
|
29
|
+
class SymbolicSolver {
|
|
30
|
+
static MAX_FN_SOLVE_STEPS = 64;
|
|
31
|
+
input;
|
|
32
|
+
x;
|
|
33
|
+
/**
|
|
34
|
+
* Creates a symbolic solver for `input = 0`.
|
|
35
|
+
*
|
|
36
|
+
* @param input - Polynomial or expression whose zeros are sought.
|
|
37
|
+
* @param v - Plain variable to solve for.
|
|
38
|
+
* @throws {@link core!UnexpectedInputError} If `v` is not a plain variable.
|
|
39
|
+
*/
|
|
40
|
+
constructor(input, v) {
|
|
41
|
+
v = Expression_1.Expression.create(v);
|
|
42
|
+
this.x = v.value;
|
|
43
|
+
if (!v.isPlainVariable()) {
|
|
44
|
+
throw new errors_1.UnexpectedInputError((0, errors_1.message)('plainVariableExpected', { input: v.text() }));
|
|
45
|
+
}
|
|
46
|
+
if (typeof input === 'string') {
|
|
47
|
+
// Default to Expression
|
|
48
|
+
this.input = Expression_1.Expression.create(input);
|
|
49
|
+
}
|
|
50
|
+
else if (Polynomial_1.Polynomial.isPolynomial(input)) {
|
|
51
|
+
this.input = input.getExpression();
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.input = input;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Solves `coeffs[3]x^3 + coeffs[2]x^2 + coeffs[1]x + coeffs[0] = 0`
|
|
59
|
+
* with Cardano's formula.
|
|
60
|
+
*
|
|
61
|
+
* @param coeffs - Four coefficients in ascending-power order.
|
|
62
|
+
* @returns Three symbolic root expressions.
|
|
63
|
+
*/
|
|
64
|
+
static cubic(coeffs) {
|
|
65
|
+
const d = coeffs[0];
|
|
66
|
+
const c = coeffs[1];
|
|
67
|
+
const b = coeffs[2];
|
|
68
|
+
const a = coeffs[3];
|
|
69
|
+
// Normalize
|
|
70
|
+
const b1 = b.div(a);
|
|
71
|
+
const c1 = c.div(a);
|
|
72
|
+
const d1 = d.div(a);
|
|
73
|
+
// Depressed cubic coefficients
|
|
74
|
+
const p = c1.minus(b1.pow((0, shortcuts_1.two)()).div((0, shortcuts_1.three)()));
|
|
75
|
+
const q = d1
|
|
76
|
+
.minus(b1.times(c1).div((0, shortcuts_1.three)()))
|
|
77
|
+
.plus((0, shortcuts_1.two)().times(b1.pow((0, shortcuts_1.three)())).div((0, shortcuts_1.twentySeven)()));
|
|
78
|
+
// Discriminant
|
|
79
|
+
const discriminant = q.pow((0, shortcuts_1.two)()).div((0, shortcuts_1.four)()).plus(p.pow((0, shortcuts_1.three)()).div((0, shortcuts_1.twentySeven)()));
|
|
80
|
+
// Shift for converting back from depressed cubic
|
|
81
|
+
const shift = (0, shortcuts_1.zero)().minus(b1).div((0, shortcuts_1.three)());
|
|
82
|
+
// General Cardano solution
|
|
83
|
+
const sqrtDisc = (0, math_1.sqrt)(discriminant);
|
|
84
|
+
const negQOver2 = (0, shortcuts_1.zero)().minus(q).div((0, shortcuts_1.two)());
|
|
85
|
+
const u = (0, math_1.cbrt)(negQOver2.plus(sqrtDisc));
|
|
86
|
+
const v = (0, math_1.cbrt)(negQOver2.minus(sqrtDisc));
|
|
87
|
+
// First root: t = u + v
|
|
88
|
+
const t1 = u.plus(v);
|
|
89
|
+
// Other roots using cube roots of unity
|
|
90
|
+
const sqrt3 = (0, math_1.sqrt)((0, shortcuts_1.three)());
|
|
91
|
+
// const half = one.div(two());
|
|
92
|
+
const negHalf = (0, shortcuts_1.zero)().minus((0, shortcuts_1.half)());
|
|
93
|
+
const i = (0, math_1.sqrt)((0, shortcuts_1.zero)().minus((0, shortcuts_1.one)()));
|
|
94
|
+
const uPlusV = u.plus(v);
|
|
95
|
+
const uMinusV = u.minus(v);
|
|
96
|
+
const t2 = negHalf.times(uPlusV).plus(sqrt3.div((0, shortcuts_1.two)()).times(uMinusV).times(i));
|
|
97
|
+
const t3 = negHalf.times(uPlusV).minus(sqrt3.div((0, shortcuts_1.two)()).times(uMinusV).times(i));
|
|
98
|
+
return [t1.plus(shift), t2.plus(shift), t3.plus(shift)];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Solves `coeffs[2]x^2 + coeffs[1]x + coeffs[0] = 0` symbolically.
|
|
102
|
+
*
|
|
103
|
+
* @param coeffs - Three coefficients in ascending-power order.
|
|
104
|
+
* @returns The two quadratic-formula roots.
|
|
105
|
+
*/
|
|
106
|
+
static quadratic(coeffs) {
|
|
107
|
+
const c = coeffs[0];
|
|
108
|
+
const b = coeffs[1];
|
|
109
|
+
const a = coeffs[2];
|
|
110
|
+
// console.log(`${a}, ${b}, ${c}`);
|
|
111
|
+
const discriminant = b.pow((0, shortcuts_1.two)()).minus((0, shortcuts_1.four)().times(a).times(c));
|
|
112
|
+
const sqrtDisc = (0, math_1.sqrt)(discriminant);
|
|
113
|
+
const twoA = (0, shortcuts_1.two)().times(a);
|
|
114
|
+
const negB = (0, shortcuts_1.zero)().minus(b);
|
|
115
|
+
const root1 = negB.plus(sqrtDisc).div(twoA);
|
|
116
|
+
const root2 = negB.minus(sqrtDisc).div(twoA);
|
|
117
|
+
return [root1, root2];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Solves a quartic from five ascending-power coefficients with Ferrari's method.
|
|
121
|
+
*
|
|
122
|
+
* @param coeffs - Coefficients from the constant through fourth-degree term.
|
|
123
|
+
* @returns Four symbolic root expressions.
|
|
124
|
+
*/
|
|
125
|
+
static quartic(coeffs) {
|
|
126
|
+
const e = coeffs[0];
|
|
127
|
+
const d = coeffs[1];
|
|
128
|
+
const c = coeffs[2];
|
|
129
|
+
const b = coeffs[3];
|
|
130
|
+
const a = coeffs[4];
|
|
131
|
+
// Normalize: x^4 + A x^3 + B x^2 + C x + D = 0
|
|
132
|
+
const A = b.div(a);
|
|
133
|
+
const B = c.div(a);
|
|
134
|
+
const C = d.div(a);
|
|
135
|
+
const D = e.div(a);
|
|
136
|
+
// Depressed quartic: t^4 + p t^2 + q t + r = 0 via x = t - A/4
|
|
137
|
+
const p = B.minus((0, shortcuts_1.three)().times(A.pow((0, shortcuts_1.two)())).div((0, shortcuts_1.eight)()));
|
|
138
|
+
const q = C.minus(A.times(B).div((0, shortcuts_1.two)())).plus(A.pow((0, shortcuts_1.three)()).div((0, shortcuts_1.eight)()));
|
|
139
|
+
const r = D.minus(A.times(C).div((0, shortcuts_1.four)()))
|
|
140
|
+
.plus(A.pow((0, shortcuts_1.two)()).times(B).div((0, shortcuts_1.sixteen)()))
|
|
141
|
+
.minus((0, shortcuts_1.three)().times(A.pow((0, shortcuts_1.four)())).div((0, shortcuts_1.twoHundredFiftySix)()));
|
|
142
|
+
const shift = (0, shortcuts_1.zero)().minus(A).div((0, shortcuts_1.four)());
|
|
143
|
+
// Special case: biquadratic (q == 0) => solve t^4 + p t^2 + r = 0 as quadratic in z = t^2
|
|
144
|
+
// This avoids the Ferrari division by s (and in particular avoids 0/0 when q=0 and y=0 is chosen).
|
|
145
|
+
if (q.isZero()) {
|
|
146
|
+
// z^2 + p z + r = 0
|
|
147
|
+
const zRoots = SymbolicSolver.quadratic([r, p, (0, shortcuts_1.one)()]);
|
|
148
|
+
// Readability + stability for common unit-imaginary cases in biquadratics.
|
|
149
|
+
// Examples:
|
|
150
|
+
// x^4 + 1 => z^2 + 1 = 0 => z = ±i
|
|
151
|
+
// x^4 + 16 => z^2 + 16 = 0 => z = ±4i
|
|
152
|
+
// Using explicit forms avoids ambiguous i^(1/2) formatting and prevents
|
|
153
|
+
// branch-related simplification from collapsing distinct roots.
|
|
154
|
+
const I = Expression_1.Expression.Img();
|
|
155
|
+
const sqrt2 = (0, math_1.sqrt)((0, shortcuts_1.two)());
|
|
156
|
+
const sqrtSpecial = (z) => {
|
|
157
|
+
if (z.value !== Expression_1.Expression.imaginary) {
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
const m = z.getMultiplier();
|
|
161
|
+
if (m.isOne()) {
|
|
162
|
+
return (0, shortcuts_1.one)().plus(I).div(sqrt2);
|
|
163
|
+
} // sqrt(i)
|
|
164
|
+
if (m.isMinusOne()) {
|
|
165
|
+
return (0, shortcuts_1.one)().minus(I).div(sqrt2);
|
|
166
|
+
} // sqrt(-i)
|
|
167
|
+
if (m.eq('4')) {
|
|
168
|
+
return sqrt2.times((0, shortcuts_1.one)().plus(I));
|
|
169
|
+
} // sqrt(4i)
|
|
170
|
+
if (m.eq('-4')) {
|
|
171
|
+
return sqrt2.times((0, shortcuts_1.one)().minus(I));
|
|
172
|
+
} // sqrt(-4i)
|
|
173
|
+
return undefined;
|
|
174
|
+
};
|
|
175
|
+
const tA = sqrtSpecial(zRoots[0]) ?? (0, math_1.sqrt)(zRoots[0]);
|
|
176
|
+
const tB = sqrtSpecial(zRoots[1]) ?? (0, math_1.sqrt)(zRoots[1]);
|
|
177
|
+
return [
|
|
178
|
+
tA.plus(shift),
|
|
179
|
+
(0, shortcuts_1.zero)().minus(tA).plus(shift),
|
|
180
|
+
tB.plus(shift),
|
|
181
|
+
(0, shortcuts_1.zero)().minus(tB).plus(shift),
|
|
182
|
+
];
|
|
183
|
+
}
|
|
184
|
+
// Ferrari's method (general case, q != 0)
|
|
185
|
+
// Resolvent cubic: y^3 + 2 p y^2 + (p^2 - 4 r) y - q^2 = 0
|
|
186
|
+
const cubicCoeffs = [
|
|
187
|
+
(0, shortcuts_1.zero)().minus(q.pow((0, shortcuts_1.two)())), // constant: -q^2
|
|
188
|
+
p.pow((0, shortcuts_1.two)()).minus((0, shortcuts_1.four)().times(r)), // linear: p^2 - 4r
|
|
189
|
+
(0, shortcuts_1.two)().times(p), // quadratic: 2p
|
|
190
|
+
(0, shortcuts_1.one)(), // cubic: 1
|
|
191
|
+
];
|
|
192
|
+
const cubicRoots = SymbolicSolver.cubic(cubicCoeffs);
|
|
193
|
+
// Choose a root y such that s = sqrt(y) is non-zero (required because q != 0).
|
|
194
|
+
let y = undefined;
|
|
195
|
+
for (const rt of cubicRoots) {
|
|
196
|
+
if (!rt.isZero()) {
|
|
197
|
+
y = rt;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
y = y ?? cubicRoots[0];
|
|
202
|
+
let s = (0, math_1.sqrt)(y);
|
|
203
|
+
// Last-resort: if s still ends up zero (can happen if cubic returned 0 first and "isZero" didn't catch),
|
|
204
|
+
// try remaining roots.
|
|
205
|
+
if (s.isZero()) {
|
|
206
|
+
for (const rt of cubicRoots) {
|
|
207
|
+
if (!rt.isZero()) {
|
|
208
|
+
const cand = (0, math_1.sqrt)(rt);
|
|
209
|
+
if (!cand.isZero()) {
|
|
210
|
+
y = rt;
|
|
211
|
+
s = cand;
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// u and v derived from:
|
|
218
|
+
// v - u = q / s, and u + v = p + y
|
|
219
|
+
const pPlusY = p.plus(y);
|
|
220
|
+
const u = pPlusY.div((0, shortcuts_1.two)()).minus(q.div((0, shortcuts_1.two)().times(s)));
|
|
221
|
+
const v = pPlusY.div((0, shortcuts_1.two)()).plus(q.div((0, shortcuts_1.two)().times(s)));
|
|
222
|
+
// Factor: (t^2 + s t + u)(t^2 - s t + v) = 0
|
|
223
|
+
const roots1 = SymbolicSolver.quadratic([u, s, (0, shortcuts_1.one)()]);
|
|
224
|
+
const roots2 = SymbolicSolver.quadratic([v, (0, shortcuts_1.zero)().minus(s), (0, shortcuts_1.one)()]);
|
|
225
|
+
return [
|
|
226
|
+
roots1[0].plus(shift),
|
|
227
|
+
roots1[1].plus(shift),
|
|
228
|
+
roots2[0].plus(shift),
|
|
229
|
+
roots2[1].plus(shift),
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Attempts the supported elementary-function and radical transformations.
|
|
234
|
+
*
|
|
235
|
+
* @returns Symbolic solutions, or `undefined` when no supported transformation
|
|
236
|
+
* closes the equation.
|
|
237
|
+
*/
|
|
238
|
+
fnSolve() {
|
|
239
|
+
const input = this.input;
|
|
240
|
+
const x = this.x;
|
|
241
|
+
const solveForX = (u, value) => {
|
|
242
|
+
const vars = u.variables();
|
|
243
|
+
if (vars.length === 1 && vars[0] === x && u.text() === x && !value.hasVariable(x)) {
|
|
244
|
+
return [value];
|
|
245
|
+
}
|
|
246
|
+
const eq = u.minus(value);
|
|
247
|
+
const solver = new SymbolicSolver(eq, x);
|
|
248
|
+
const result = solver.solve();
|
|
249
|
+
if (!result.unsolved) {
|
|
250
|
+
return result.solutions;
|
|
251
|
+
}
|
|
252
|
+
return (0, solve_1.solve)(eq, x).elements;
|
|
253
|
+
};
|
|
254
|
+
const n = Expression_1.Expression.N();
|
|
255
|
+
const pi = Expression_1.Expression.Pi();
|
|
256
|
+
const nPi = n.times(pi);
|
|
257
|
+
const oddPiOver2 = (0, shortcuts_1.two)().times(n).plus((0, shortcuts_1.one)()).times(pi).div((0, shortcuts_1.two)());
|
|
258
|
+
// Sum decomposition: f(u) + c = 0
|
|
259
|
+
if (input.isSum()) {
|
|
260
|
+
const elements = input.elementsArray();
|
|
261
|
+
const logTerms = elements.filter(e => e.isFunction(constants_1.LOG) &&
|
|
262
|
+
e.isLinear() &&
|
|
263
|
+
e.getMultiplier().isInteger() &&
|
|
264
|
+
e.getArguments().length > 0);
|
|
265
|
+
if (logTerms.length === elements.length && logTerms.some(e => e.hasVariable(x))) {
|
|
266
|
+
let product = (0, shortcuts_1.one)();
|
|
267
|
+
for (const logTerm of logTerms) {
|
|
268
|
+
const exponent = Expression_1.Expression.fromRational(logTerm.getMultiplier());
|
|
269
|
+
product = product.times(logTerm.getArguments()[0].pow(exponent));
|
|
270
|
+
}
|
|
271
|
+
return (0, solve_1.solve)(product.minus((0, shortcuts_1.one)()), x).elements;
|
|
272
|
+
}
|
|
273
|
+
const radicalTerms = elements.filter(e => e.hasVariable(x) && e.getPower().eq((0, shortcuts_1.half)()));
|
|
274
|
+
if (radicalTerms.length === 1) {
|
|
275
|
+
const radicalTerm = radicalTerms[0];
|
|
276
|
+
let remainder = (0, shortcuts_1.zero)();
|
|
277
|
+
for (const element of elements) {
|
|
278
|
+
if (element !== radicalTerm) {
|
|
279
|
+
remainder = remainder.plus(element);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
const base = (0, utils_1.stripPower)(radicalTerm.toUnitMultiplier());
|
|
283
|
+
const isolated = remainder.neg().div(radicalTerm.getMultiplier());
|
|
284
|
+
return (0, solve_1.solve)(base.minus(isolated.sq()), x).elements;
|
|
285
|
+
}
|
|
286
|
+
const negativeHalf = (0, shortcuts_1.half)().neg();
|
|
287
|
+
const reciprocalRadicals = [];
|
|
288
|
+
for (const element of elements) {
|
|
289
|
+
if (element.hasVariable(x)) {
|
|
290
|
+
const factors = element.isProduct() ? element.elementsArray() : [element];
|
|
291
|
+
const variableFactors = factors.filter(factor => factor.hasVariable(x));
|
|
292
|
+
if (variableFactors.length === 1 &&
|
|
293
|
+
variableFactors[0].getPower().eq(negativeHalf)) {
|
|
294
|
+
reciprocalRadicals.push({
|
|
295
|
+
term: element,
|
|
296
|
+
factor: variableFactors[0],
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (reciprocalRadicals.length === 1) {
|
|
302
|
+
const { term: radicalTerm, factor: radicalFactor } = reciprocalRadicals[0];
|
|
303
|
+
let remainder = (0, shortcuts_1.zero)();
|
|
304
|
+
for (const element of elements) {
|
|
305
|
+
if (element !== radicalTerm) {
|
|
306
|
+
remainder = remainder.plus(element);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// A reciprocal square root can be nested inside a product. Isolate only
|
|
310
|
+
// that factor, leaving the established direct-square-root path unchanged.
|
|
311
|
+
const unitFactor = radicalFactor.toUnitMultiplier();
|
|
312
|
+
const coefficient = radicalTerm.div(unitFactor);
|
|
313
|
+
if (!coefficient.hasVariable(x) && !remainder.hasVariable(x)) {
|
|
314
|
+
const base = radicalFactor.getBase();
|
|
315
|
+
const isolated = remainder.neg().div(coefficient);
|
|
316
|
+
return solveForX(base, isolated.pow((0, shortcuts_1.two)().neg()));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (elements.length === 2) {
|
|
320
|
+
let sinArg;
|
|
321
|
+
let sinCoeff;
|
|
322
|
+
let cosArg;
|
|
323
|
+
let cosCoeff;
|
|
324
|
+
let validTrigCombination = true;
|
|
325
|
+
for (const element of elements) {
|
|
326
|
+
const factors = element.isProduct() ? element.elementsArray() : [element];
|
|
327
|
+
const trigFactors = factors.filter(factor => (factor.isFunction(trig_1.SIN) || factor.isFunction(trig_1.COS)) &&
|
|
328
|
+
factor.getPower().isOne());
|
|
329
|
+
if (trigFactors.length !== 1) {
|
|
330
|
+
validTrigCombination = false;
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
const trig = trigFactors[0].toUnitMultiplier();
|
|
334
|
+
const coeff = element.div(trig);
|
|
335
|
+
if (coeff.hasVariable(x)) {
|
|
336
|
+
validTrigCombination = false;
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
if (trigFactors[0].isFunction(trig_1.SIN)) {
|
|
340
|
+
sinArg = trig.getArguments()[0];
|
|
341
|
+
sinCoeff = coeff;
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
cosArg = trig.getArguments()[0];
|
|
345
|
+
cosCoeff = coeff;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (validTrigCombination &&
|
|
349
|
+
sinArg &&
|
|
350
|
+
sinCoeff &&
|
|
351
|
+
cosArg &&
|
|
352
|
+
cosCoeff &&
|
|
353
|
+
sinArg.eq(cosArg) &&
|
|
354
|
+
!sinCoeff.isZero()) {
|
|
355
|
+
return solveForX(sinArg, (0, trig_1.atan)(cosCoeff.neg().div(sinCoeff)));
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const fnTerms = elements.filter((e) => e.isFunction() && e.hasVariable(x));
|
|
359
|
+
if (fnTerms.length === 1) {
|
|
360
|
+
const fnTerm = fnTerms[0];
|
|
361
|
+
let remainder = (0, shortcuts_1.zero)();
|
|
362
|
+
for (const element of elements) {
|
|
363
|
+
if (element !== fnTerm) {
|
|
364
|
+
remainder = remainder.plus(element);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (!remainder.hasVariable(x) || fnTerm.name === constants_1.ABS) {
|
|
368
|
+
const fname = fnTerm.name;
|
|
369
|
+
const u = fnTerm.getArguments()[0];
|
|
370
|
+
const m = fnTerm.getMultiplier();
|
|
371
|
+
const p = fnTerm.getPower();
|
|
372
|
+
// f(u) = -remainder / m
|
|
373
|
+
let c = remainder.neg().div(m);
|
|
374
|
+
// f(u)^n = c => f(u) = c^(1/n)
|
|
375
|
+
if (!p.isOne()) {
|
|
376
|
+
c = c.pow(p.invert());
|
|
377
|
+
}
|
|
378
|
+
const values = this.invertFunction(fname, c);
|
|
379
|
+
if (values !== undefined) {
|
|
380
|
+
const results = [];
|
|
381
|
+
for (const v of values) {
|
|
382
|
+
results.push(...solveForX(u, v));
|
|
383
|
+
}
|
|
384
|
+
return results.length > 0 ? results : undefined;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (elements.length === 2) {
|
|
389
|
+
const expIdx = elements.findIndex(e => {
|
|
390
|
+
let retval = false;
|
|
391
|
+
if (e.isEXP()) {
|
|
392
|
+
const base = e.getBase();
|
|
393
|
+
// Symbolic bases independent of x can use the same formal logarithmic
|
|
394
|
+
// inversion. Explicit numeric bases retain the real-log domain restriction.
|
|
395
|
+
retval =
|
|
396
|
+
e.hasVariable(x) &&
|
|
397
|
+
!base.hasVariable(x) &&
|
|
398
|
+
(!base.isNUM() || (base.gt((0, shortcuts_1.zero)()) && !base.isOne()));
|
|
399
|
+
}
|
|
400
|
+
return retval;
|
|
401
|
+
});
|
|
402
|
+
if (expIdx !== -1) {
|
|
403
|
+
const expTerm = elements[expIdx];
|
|
404
|
+
const constTerm = elements[1 - expIdx];
|
|
405
|
+
if (!constTerm.hasVariable(x)) {
|
|
406
|
+
const base = expTerm.getBase();
|
|
407
|
+
const u = expTerm.getPower();
|
|
408
|
+
const m = expTerm.getMultiplier();
|
|
409
|
+
const c = constTerm.neg().div(m);
|
|
410
|
+
return solveForX(u, (0, math_1.log)(c).div((0, math_1.log)(base)));
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// Direct function: f(u) = 0
|
|
416
|
+
if (input.isFunction(trig_1.SIN)) {
|
|
417
|
+
const u = input.getArguments()[0];
|
|
418
|
+
return solveForX(u, nPi);
|
|
419
|
+
}
|
|
420
|
+
if (input.isFunction(trig_1.COS)) {
|
|
421
|
+
const u = input.getArguments()[0];
|
|
422
|
+
return solveForX(u, oddPiOver2);
|
|
423
|
+
}
|
|
424
|
+
if (input.isFunction(trig_1.TAN)) {
|
|
425
|
+
const u = input.getArguments()[0];
|
|
426
|
+
return solveForX(u, nPi);
|
|
427
|
+
}
|
|
428
|
+
if (input.isFunction(trig_1.COT)) {
|
|
429
|
+
const u = input.getArguments()[0];
|
|
430
|
+
return solveForX(u, oddPiOver2);
|
|
431
|
+
}
|
|
432
|
+
if (input.isFunction(constants_1.LOG)) {
|
|
433
|
+
const u = input.getArguments()[0];
|
|
434
|
+
return solveForX(u, (0, shortcuts_1.one)());
|
|
435
|
+
}
|
|
436
|
+
if (input.isFunction(trig_1.SINH)) {
|
|
437
|
+
const u = input.getArguments()[0];
|
|
438
|
+
return solveForX(u, (0, shortcuts_1.zero)());
|
|
439
|
+
}
|
|
440
|
+
if (input.isFunction(trig_1.TANH)) {
|
|
441
|
+
const u = input.getArguments()[0];
|
|
442
|
+
return solveForX(u, (0, shortcuts_1.zero)());
|
|
443
|
+
}
|
|
444
|
+
if (input.isFunction(trig_1.ASIN)) {
|
|
445
|
+
const u = input.getArguments()[0];
|
|
446
|
+
return solveForX(u, (0, shortcuts_1.zero)());
|
|
447
|
+
}
|
|
448
|
+
if (input.isFunction(trig_1.ACOS)) {
|
|
449
|
+
const u = input.getArguments()[0];
|
|
450
|
+
return solveForX(u, (0, shortcuts_1.one)());
|
|
451
|
+
}
|
|
452
|
+
if (input.isFunction(trig_1.ATAN)) {
|
|
453
|
+
const u = input.getArguments()[0];
|
|
454
|
+
return solveForX(u, (0, shortcuts_1.zero)());
|
|
455
|
+
}
|
|
456
|
+
if (input.isFunction(trig_1.ASEC)) {
|
|
457
|
+
const u = input.getArguments()[0];
|
|
458
|
+
return solveForX(u, (0, shortcuts_1.one)());
|
|
459
|
+
}
|
|
460
|
+
if (input.isFunction(trig_1.ASINH)) {
|
|
461
|
+
const u = input.getArguments()[0];
|
|
462
|
+
return solveForX(u, (0, shortcuts_1.zero)());
|
|
463
|
+
}
|
|
464
|
+
if (input.isFunction(trig_1.ACOSH)) {
|
|
465
|
+
const u = input.getArguments()[0];
|
|
466
|
+
return solveForX(u, (0, shortcuts_1.one)());
|
|
467
|
+
}
|
|
468
|
+
if (input.isFunction(trig_1.ATANH)) {
|
|
469
|
+
const u = input.getArguments()[0];
|
|
470
|
+
return solveForX(u, (0, shortcuts_1.zero)());
|
|
471
|
+
}
|
|
472
|
+
if (input.isFunction(constants_1.ABS)) {
|
|
473
|
+
const u = input.getArguments()[0];
|
|
474
|
+
return solveForX(u, (0, shortcuts_1.zero)());
|
|
475
|
+
}
|
|
476
|
+
return undefined;
|
|
477
|
+
}
|
|
478
|
+
invertFunction(fname, c) {
|
|
479
|
+
switch (fname) {
|
|
480
|
+
case trig_1.SIN:
|
|
481
|
+
return [(0, trig_1.asin)(c)];
|
|
482
|
+
case trig_1.COS:
|
|
483
|
+
return [(0, trig_1.acos)(c)];
|
|
484
|
+
case trig_1.TAN:
|
|
485
|
+
return [(0, trig_1.atan)(c)];
|
|
486
|
+
case trig_1.COT:
|
|
487
|
+
return [(0, trig_1.atan)((0, shortcuts_1.one)().div(c))];
|
|
488
|
+
case constants_1.LOG:
|
|
489
|
+
return [(0, math_1.exp)(c)];
|
|
490
|
+
case trig_1.SINH:
|
|
491
|
+
return [(0, trig_1.asinh)(c)];
|
|
492
|
+
case trig_1.COSH:
|
|
493
|
+
return [(0, trig_1.acosh)(c)];
|
|
494
|
+
case trig_1.TANH:
|
|
495
|
+
return [(0, trig_1.atanh)(c)];
|
|
496
|
+
case trig_1.ASIN:
|
|
497
|
+
return [(0, trig_1.sin)(c)];
|
|
498
|
+
case trig_1.ACOS:
|
|
499
|
+
return [(0, trig_1.cos)(c)];
|
|
500
|
+
case trig_1.ATAN:
|
|
501
|
+
return [(0, trig_1.tan)(c)];
|
|
502
|
+
case trig_1.ASEC:
|
|
503
|
+
return [(0, shortcuts_1.one)().div((0, trig_1.cos)(c))];
|
|
504
|
+
case trig_1.ASINH:
|
|
505
|
+
return [(0, trig_1.sinh)(c)];
|
|
506
|
+
case trig_1.ACOSH:
|
|
507
|
+
return [(0, trig_1.cosh)(c)];
|
|
508
|
+
case trig_1.ATANH:
|
|
509
|
+
return [(0, trig_1.tanh)(c)];
|
|
510
|
+
case constants_1.ABS:
|
|
511
|
+
return [c, (0, shortcuts_1.zero)().minus(c)];
|
|
512
|
+
default:
|
|
513
|
+
return undefined;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
/** Returns whether any node in the configured input is a function call. */
|
|
517
|
+
inputContainsFunction() {
|
|
518
|
+
let found = false;
|
|
519
|
+
this.input.forEveryElement(e => {
|
|
520
|
+
if (e.isFunction()) {
|
|
521
|
+
found = true;
|
|
522
|
+
}
|
|
523
|
+
return e;
|
|
524
|
+
});
|
|
525
|
+
return found;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Attempts polynomial formulas and then supported function transformations.
|
|
529
|
+
*
|
|
530
|
+
* @returns An object containing `solutions` and, when the strategy cannot
|
|
531
|
+
* solve the equation, the original `unsolved` expression.
|
|
532
|
+
*/
|
|
533
|
+
solve() {
|
|
534
|
+
let solutions;
|
|
535
|
+
let unsolved;
|
|
536
|
+
if (this.input.hasVariable(this.x)) {
|
|
537
|
+
let coeffs;
|
|
538
|
+
const negativeHalf = (0, shortcuts_1.half)().neg();
|
|
539
|
+
const containsRadicalTerm = this.input.isSum() &&
|
|
540
|
+
this.input.elementsArray().some(term => {
|
|
541
|
+
let retval = term.hasVariable(this.x) && term.getPower().eq((0, shortcuts_1.half)());
|
|
542
|
+
if (!retval && term.isProduct() && term.hasVariable(this.x)) {
|
|
543
|
+
const variableFactors = term
|
|
544
|
+
.elementsArray()
|
|
545
|
+
.filter(factor => factor.hasVariable(this.x));
|
|
546
|
+
retval =
|
|
547
|
+
variableFactors.length === 1 &&
|
|
548
|
+
variableFactors[0].getPower().eq(negativeHalf);
|
|
549
|
+
}
|
|
550
|
+
return retval;
|
|
551
|
+
});
|
|
552
|
+
if (!containsRadicalTerm) {
|
|
553
|
+
try {
|
|
554
|
+
coeffs = this.input.coeffs(this.x).toArray();
|
|
555
|
+
}
|
|
556
|
+
catch { }
|
|
557
|
+
}
|
|
558
|
+
if (coeffs) {
|
|
559
|
+
const deg = coeffs.length - 1;
|
|
560
|
+
let cleanCoeffs = true;
|
|
561
|
+
for (const c of coeffs) {
|
|
562
|
+
if (c.hasVariable(this.x)) {
|
|
563
|
+
cleanCoeffs = false;
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (cleanCoeffs && deg >= 1 && deg <= 4) {
|
|
568
|
+
switch (deg) {
|
|
569
|
+
case 1:
|
|
570
|
+
solutions = [coeffs[0].neg().div(coeffs[1])];
|
|
571
|
+
break;
|
|
572
|
+
case 2:
|
|
573
|
+
solutions = SymbolicSolver.quadratic(coeffs);
|
|
574
|
+
break;
|
|
575
|
+
case 3:
|
|
576
|
+
solutions = SymbolicSolver.cubic(coeffs);
|
|
577
|
+
break;
|
|
578
|
+
case 4:
|
|
579
|
+
solutions = SymbolicSolver.quartic(coeffs);
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
if (!solutions) {
|
|
585
|
+
solutions = this.fnSolve();
|
|
586
|
+
}
|
|
587
|
+
if (!solutions) {
|
|
588
|
+
unsolved = this.input;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
unsolved = this.input;
|
|
593
|
+
}
|
|
594
|
+
solutions ??= [];
|
|
595
|
+
return {
|
|
596
|
+
solutions,
|
|
597
|
+
unsolved,
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
exports.SymbolicSolver = SymbolicSolver;
|