nerdamer 1.1.13 → 2.0.0-rc.2
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/BREAKING_CHANGES.md +244 -5
- package/LICENSE.md +184 -0
- package/README.md +232 -318
- 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 +2248 -0
- package/index.d.ts +10 -426
- package/output/algebra/adapters.d.ts +3 -0
- package/output/algebra/adapters.js +11 -0
- package/output/algebra/algorithms/arith.d.ts +84 -0
- package/output/algebra/algorithms/arith.js +324 -0
- package/output/algebra/algorithms/groebnerBase.d.ts +161 -0
- package/output/algebra/algorithms/groebnerBase.js +929 -0
- package/output/algebra/dispatch.d.ts +1 -0
- package/output/algebra/dispatch.js +25 -0
- package/output/algebra/factor/factor.d.ts +77 -0
- package/output/algebra/factor/factor.js +245 -0
- package/output/algebra/gcd/gcd.d.ts +30 -0
- package/output/algebra/gcd/gcd.js +95 -0
- package/output/algebra/groebner.d.ts +21 -0
- package/output/algebra/groebner.js +36 -0
- package/output/algebra/partfrac.d.ts +19 -0
- package/output/algebra/partfrac.js +365 -0
- package/output/algebra/polynomial/ModularSparsePolynomial.d.ts +131 -0
- package/output/algebra/polynomial/ModularSparsePolynomial.js +378 -0
- package/output/algebra/polynomial/ModularSparsePolynomialFactor.d.ts +40 -0
- package/output/algebra/polynomial/ModularSparsePolynomialFactor.js +661 -0
- package/output/algebra/polynomial/SparsePolynomialFactor.d.ts +64 -0
- package/output/algebra/polynomial/SparsePolynomialFactor.js +492 -0
- package/output/algebra/polynomial/SparsePolynomialGcd.d.ts +29 -0
- package/output/algebra/polynomial/SparsePolynomialGcd.js +259 -0
- package/output/algebra/polynomial/SparsePolynomialMultivariateFactor.d.ts +82 -0
- package/output/algebra/polynomial/SparsePolynomialMultivariateFactor.js +604 -0
- package/output/algebra/polynomial/modularGcd.d.ts +40 -0
- package/output/algebra/polynomial/modularGcd.js +365 -0
- package/output/algebra/polynomialize.d.ts +20 -0
- package/output/algebra/polynomialize.js +26 -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 +237 -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 +8 -0
- package/output/api/advanced.js +18 -0
- package/output/api/algebra.d.ts +17 -0
- package/output/api/algebra.js +35 -0
- package/output/api/assumptions.d.ts +4 -0
- package/output/api/assumptions.js +11 -0
- package/output/api/calculus.d.ts +10 -0
- package/output/api/calculus.js +22 -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/languages/deu.d.ts +3 -0
- package/output/api/languages/deu.js +266 -0
- package/output/api/languages/fra.d.ts +3 -0
- package/output/api/languages/fra.js +266 -0
- package/output/api/languages/ita.d.ts +3 -0
- package/output/api/languages/ita.js +266 -0
- package/output/api/languages/nld.d.ts +3 -0
- package/output/api/languages/nld.js +266 -0
- package/output/api/languages/por.d.ts +3 -0
- package/output/api/languages/por.js +266 -0
- package/output/api/languages/spa.d.ts +3 -0
- package/output/api/languages/spa.js +266 -0
- package/output/api/parser.d.ts +93 -0
- package/output/api/parser.js +18 -0
- package/output/api/solve.d.ts +10 -0
- package/output/api/solve.js +17 -0
- package/output/api/structures.d.ts +10 -0
- package/output/api/structures.js +23 -0
- package/output/calculus/adapters.d.ts +8 -0
- package/output/calculus/adapters.js +41 -0
- package/output/calculus/derivative/diff.d.ts +30 -0
- package/output/calculus/derivative/diff.js +241 -0
- package/output/calculus/dispatch.d.ts +1 -0
- package/output/calculus/dispatch.js +25 -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/classes/assumption/Assumption.d.ts +218 -0
- package/output/core/classes/assumption/Assumption.js +609 -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/assumption/dispatch.d.ts +1 -0
- package/output/core/classes/assumption/dispatch.js +11 -0
- package/output/core/classes/collection/Collection.d.ts +107 -0
- package/output/core/classes/collection/Collection.js +240 -0
- package/output/core/classes/complex/Complex.d.ts +109 -0
- package/output/core/classes/complex/Complex.js +153 -0
- package/output/core/classes/decimalSet/DecimalSet.d.ts +226 -0
- package/output/core/classes/decimalSet/DecimalSet.js +454 -0
- package/output/core/classes/dictionary/Dictionary.d.ts +102 -0
- package/output/core/classes/dictionary/Dictionary.js +216 -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 +197 -0
- package/output/core/classes/expression/Expression.d.ts +1691 -0
- package/output/core/classes/expression/Expression.js +2381 -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 +54 -0
- package/output/core/classes/expression/format.js +340 -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 +61 -0
- package/output/core/classes/expression/utils.js +235 -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 +901 -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/dispatch.d.ts +1 -0
- package/output/core/classes/matrix/dispatch.js +19 -0
- package/output/core/classes/matrix/functions.d.ts +28 -0
- package/output/core/classes/matrix/functions.js +57 -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 +493 -0
- package/output/core/classes/parser/Parser.js +1863 -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 +162 -0
- package/output/core/classes/parser/constants.js +229 -0
- package/output/core/classes/parser/controlFlowSignals.d.ts +38 -0
- package/output/core/classes/parser/controlFlowSignals.js +60 -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 +236 -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 +474 -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 +438 -0
- package/output/core/classes/parser/operations/multiply.d.ts +11 -0
- package/output/core/classes/parser/operations/multiply.js +328 -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 +36 -0
- package/output/core/classes/parser/preprocess.d.ts +7 -0
- package/output/core/classes/parser/preprocess.js +246 -0
- package/output/core/classes/parser/scripting/controlFlow.d.ts +23 -0
- package/output/core/classes/parser/scripting/controlFlow.js +279 -0
- package/output/core/classes/parser/scripting/deferred.d.ts +4 -0
- package/output/core/classes/parser/scripting/deferred.js +65 -0
- package/output/core/classes/parser/scripting/dispatch.d.ts +1 -0
- package/output/core/classes/parser/scripting/dispatch.js +62 -0
- package/output/core/classes/parser/scripting/evaluate.d.ts +23 -0
- package/output/core/classes/parser/scripting/evaluate.js +128 -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 +8 -0
- package/output/core/classes/parser/scripting/scope.js +132 -0
- package/output/core/classes/parser/types.d.ts +130 -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 +504 -0
- package/output/core/classes/polynomial/Polynomial.js +1195 -0
- package/output/core/classes/polynomial/SparsePolynomial.d.ts +221 -0
- package/output/core/classes/polynomial/SparsePolynomial.js +824 -0
- package/output/core/classes/polynomial/SparsePolynomialAdapter.d.ts +56 -0
- package/output/core/classes/polynomial/SparsePolynomialAdapter.js +241 -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/adapters.d.ts +18 -0
- package/output/core/classes/polynomial/adapters.js +33 -0
- package/output/core/classes/polynomial/dispatch.d.ts +1 -0
- package/output/core/classes/polynomial/dispatch.js +14 -0
- package/output/core/classes/polynomial/functions.d.ts +77 -0
- package/output/core/classes/polynomial/functions.js +189 -0
- package/output/core/classes/polynomial/utils.d.ts +62 -0
- package/output/core/classes/polynomial/utils.js +207 -0
- package/output/core/classes/rational/Rational.d.ts +501 -0
- package/output/core/classes/rational/Rational.js +829 -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 +187 -0
- package/output/core/classes/valuesSet/ValuesSet.js +399 -0
- package/output/core/classes/vector/Vector.d.ts +222 -0
- package/output/core/classes/vector/Vector.js +501 -0
- package/output/core/classes/vector/dispatch.d.ts +1 -0
- package/output/core/classes/vector/dispatch.js +11 -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 +149 -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 +62 -0
- package/output/core/common/common.js +74 -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 +806 -0
- package/output/core/converters/Pattern.d.ts +71 -0
- package/output/core/converters/Pattern.js +302 -0
- package/output/core/dispatch.d.ts +52 -0
- package/output/core/dispatch.js +26 -0
- package/output/core/errors.d.ts +316 -0
- package/output/core/errors.js +349 -0
- package/output/core/fullFunctions.d.ts +7 -0
- package/output/core/fullFunctions.js +31 -0
- package/output/core/functions/bigint/bigint.d.ts +133 -0
- package/output/core/functions/bigint/bigint.js +444 -0
- package/output/core/functions/bigint/primeFactor.d.ts +51 -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 +139 -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.dispatch.d.ts +1 -0
- package/output/core/functions/complex.dispatch.js +16 -0
- package/output/core/functions/complex.js +482 -0
- package/output/core/functions/decimal.d.ts +24 -0
- package/output/core/functions/decimal.js +665 -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 +102 -0
- package/output/core/functions/subst.d.ts +90 -0
- package/output/core/functions/subst.js +506 -0
- package/output/core/functions/utils.d.ts +24 -0
- package/output/core/functions/utils.js +51 -0
- package/output/core/parserFunctions.d.ts +7 -0
- package/output/core/parserFunctions.js +25 -0
- package/output/core/types.d.ts +48 -0
- package/output/core/types.js +2 -0
- package/output/index.d.ts +359 -0
- package/output/index.js +739 -0
- package/output/math/defint/defint.d.ts +18 -0
- package/output/math/defint/defint.js +60 -0
- package/output/math/defint/defintDecimal.d.ts +37 -0
- package/output/math/defint/defintDecimal.js +321 -0
- package/output/math/defint/defintNative.d.ts +57 -0
- package/output/math/defint/defintNative.js +281 -0
- package/output/math/dispatch.d.ts +1 -0
- package/output/math/dispatch.js +101 -0
- package/output/math/geometry.d.ts +12 -0
- package/output/math/geometry.js +55 -0
- package/output/math/math.d.ts +695 -0
- package/output/math/math.js +1955 -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 +66 -0
- package/output/math/utils.js +219 -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 +104 -0
- package/output/solve/classes/PolynomialSolver.js +492 -0
- package/output/solve/classes/SolutionSet.d.ts +172 -0
- package/output/solve/classes/SolutionSet.js +434 -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/dispatch.d.ts +1 -0
- package/output/solve/dispatch.js +13 -0
- package/output/solve/linsolve.d.ts +53 -0
- package/output/solve/linsolve.js +233 -0
- package/output/solve/solve.d.ts +44 -0
- package/output/solve/solve.js +368 -0
- package/output/solve/solveSystem.d.ts +31 -0
- package/output/solve/solveSystem.js +266 -0
- package/output/solve/utils.d.ts +10 -0
- package/output/solve/utils.js +58 -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 +296 -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 +178 -57
- package/.travis.yml +0 -3
- package/Algebra.js +0 -4568
- 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,434 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SolutionSet = void 0;
|
|
7
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
8
|
+
const Expression_1 = require("../../core/classes/expression/Expression");
|
|
9
|
+
const constants_1 = require("../../core/classes/parser/constants");
|
|
10
|
+
const ValuesSet_1 = require("../../core/classes/valuesSet/ValuesSet");
|
|
11
|
+
const common_1 = require("../../core/common/common");
|
|
12
|
+
const errors_1 = require("../../core/errors");
|
|
13
|
+
/**
|
|
14
|
+
* A finite set of solution descriptors with solver-specific metadata.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* `SolutionSet` inherits the finite-set storage semantics of {@link ValuesSet}: accepted
|
|
18
|
+
* descriptors are unique by symbolic equality, insertion order has no mathematical meaning,
|
|
19
|
+
* and values exposed through {@link elements} are copies rather than mutable references into
|
|
20
|
+
* the set. A descriptor normally represents one solution, but a descriptor containing the
|
|
21
|
+
* reserved `_n` index represents a parameterized family where `_n` ranges over the integers.
|
|
22
|
+
* The special `all` descriptor represents every value of the solved variable. Consequently,
|
|
23
|
+
* {@link count} reports the number of stored descriptors, not the cardinality of the
|
|
24
|
+
* mathematical solution set.
|
|
25
|
+
*
|
|
26
|
+
* {@link solutionsType} records solver provenance: whether accepted descriptors came from
|
|
27
|
+
* numerical strategies, symbolic/exact strategies, or both. It is not inferred from the
|
|
28
|
+
* printed shape of a descriptor, so a symbolic strategy may produce a value such as `1`.
|
|
29
|
+
* The orthogonal {@link solutionForm} property is derived from representation and distinguishes
|
|
30
|
+
* finite results, `_n`-indexed parametric families, and the `all` result.
|
|
31
|
+
*
|
|
32
|
+
* The class narrows membership to {@link Expression} values and keeps rejected singular
|
|
33
|
+
* candidates and numerical root metadata alongside the accepted solutions.
|
|
34
|
+
*
|
|
35
|
+
* Excluded values are enforced solver state, not merely advisory metadata. Once a value is excluded,
|
|
36
|
+
* adding the same value does not reintroduce it; excluding an already accepted value removes
|
|
37
|
+
* it from the solution set. {@link copy} preserves accepted values, exclusions, raw roots,
|
|
38
|
+
* partial-result state, solution type, and the unresolved expression when one is present.
|
|
39
|
+
*/
|
|
40
|
+
class SolutionSet extends ValuesSet_1.ValuesSet {
|
|
41
|
+
excluded = new ValuesSet_1.ValuesSet();
|
|
42
|
+
roots = [];
|
|
43
|
+
dataType = constants_1.SOLUTIONS_SET;
|
|
44
|
+
partial = false;
|
|
45
|
+
/** Solver provenance for the currently accepted descriptors. */
|
|
46
|
+
solutionsType = undefined;
|
|
47
|
+
unsolved;
|
|
48
|
+
constructor(values) {
|
|
49
|
+
super();
|
|
50
|
+
if (values) {
|
|
51
|
+
for (const v of values) {
|
|
52
|
+
this.add(v);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Tests whether a value is specifically a solver `SolutionSet`. */
|
|
57
|
+
static isSolutionSet(obj) {
|
|
58
|
+
return (0, common_1.isNerdamerNativeType)(obj, constants_1.SOLUTIONS_SET);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Combines numerical/symbolic provenance without changing any other solver state.
|
|
62
|
+
*/
|
|
63
|
+
mergeSolutionsType(solutionsType) {
|
|
64
|
+
if (this.solutionsType === undefined) {
|
|
65
|
+
this.solutionsType = solutionsType;
|
|
66
|
+
}
|
|
67
|
+
else if (solutionsType !== undefined && this.solutionsType !== solutionsType) {
|
|
68
|
+
this.solutionsType = 'mixed';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Verifies and admits one candidate, reporting whether it belongs to this result after
|
|
73
|
+
* verification. Keeping this decision inside the same path used by {@link addSolution}
|
|
74
|
+
* avoids mistaking a pre-existing equal descriptor for a newly verified source candidate.
|
|
75
|
+
*/
|
|
76
|
+
verifyAndAddSolution(solution, forFunction, variable) {
|
|
77
|
+
let retval = false;
|
|
78
|
+
try {
|
|
79
|
+
const evaluated = forFunction
|
|
80
|
+
.evaluate({ [variable]: solution.evaluate() })
|
|
81
|
+
.expand();
|
|
82
|
+
const isClosed = evaluated.variables().length === 0;
|
|
83
|
+
// Preserve parameterized candidates that cannot yet be verified, but
|
|
84
|
+
// require every closed residual, including complex values, to be zero.
|
|
85
|
+
if ((isClosed && evaluated.isNearlyZero()) || !isClosed) {
|
|
86
|
+
const excluded = this.excluded.has(solution);
|
|
87
|
+
this.add(solution);
|
|
88
|
+
retval = !excluded;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
if (e instanceof errors_1.DivisionByZeroError) {
|
|
93
|
+
this.excluded.add(solution);
|
|
94
|
+
this.delete(solution);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return retval;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Replaces a parser-indexed solution while preserving Expression-only membership and
|
|
101
|
+
* uniqueness.
|
|
102
|
+
*/
|
|
103
|
+
__set__(indices, value) {
|
|
104
|
+
if (!Expression_1.Expression.isExpression(value)) {
|
|
105
|
+
throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: value.dataType }));
|
|
106
|
+
}
|
|
107
|
+
if (this.excluded.has(value)) {
|
|
108
|
+
const index = indices[0];
|
|
109
|
+
if (index < 0 || index >= this.count()) {
|
|
110
|
+
throw new RangeError((0, errors_1.message)('indexOutOfBounds', {
|
|
111
|
+
index: String(index),
|
|
112
|
+
type: String(this.dataType),
|
|
113
|
+
length: String(this.count()),
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
const current = this.at(index);
|
|
117
|
+
if (current) {
|
|
118
|
+
this.delete(current);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
super.__set__(indices, value);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Adds an accepted solution unless it is already present or explicitly excluded.
|
|
127
|
+
*/
|
|
128
|
+
add(x) {
|
|
129
|
+
if (!Expression_1.Expression.isExpression(x)) {
|
|
130
|
+
const entity = x;
|
|
131
|
+
throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: entity.dataType }));
|
|
132
|
+
}
|
|
133
|
+
if (!this.excluded.has(x)) {
|
|
134
|
+
super.add(x);
|
|
135
|
+
}
|
|
136
|
+
return this;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Adds accepted solutions while preserving uniqueness and exclusions.
|
|
140
|
+
* The iterable is validated before the set is changed, so invalid input cannot leave a
|
|
141
|
+
* partially updated result.
|
|
142
|
+
*/
|
|
143
|
+
addMany(x) {
|
|
144
|
+
const values = [...x];
|
|
145
|
+
for (const value of values) {
|
|
146
|
+
if (!Expression_1.Expression.isExpression(value)) {
|
|
147
|
+
const entity = value;
|
|
148
|
+
throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: entity.dataType }));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
for (const value of values) {
|
|
152
|
+
this.add(value);
|
|
153
|
+
}
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Stores numerical root-refinement metadata independently of the caller's object.
|
|
158
|
+
*/
|
|
159
|
+
addRawRoot(root) {
|
|
160
|
+
this.roots.push({
|
|
161
|
+
root: new decimal_js_1.default(root.root),
|
|
162
|
+
iterations: root.iterations,
|
|
163
|
+
converged: root.converged,
|
|
164
|
+
error: new decimal_js_1.default(root.error),
|
|
165
|
+
errorMsg: root.errorMsg,
|
|
166
|
+
});
|
|
167
|
+
return this;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Verifies a candidate against the source expression before admitting it to the set.
|
|
171
|
+
*
|
|
172
|
+
* Parameterized candidates that cannot yet be closed numerically are preserved. Closed
|
|
173
|
+
* residuals must evaluate nearly to zero. Candidates that encounter exact division by
|
|
174
|
+
* zero are recorded as exclusions instead.
|
|
175
|
+
*/
|
|
176
|
+
addSolution(solution, forFunction, variable) {
|
|
177
|
+
this.verifyAndAddSolution(solution, forFunction, variable);
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Verifies and adds every candidate in an array or another `SolutionSet`.
|
|
182
|
+
*
|
|
183
|
+
* When the source is a `SolutionSet`, its numerical/symbolic provenance is retained if
|
|
184
|
+
* at least one source descriptor survives verification. Context-specific metadata such as
|
|
185
|
+
* exclusions, raw roots, partial state, and unresolved expressions is not transferred;
|
|
186
|
+
* use {@link append} when the complete solver result should be merged without revalidation.
|
|
187
|
+
*/
|
|
188
|
+
addSolutions(arr, forFunction, variable) {
|
|
189
|
+
let source;
|
|
190
|
+
let solutions;
|
|
191
|
+
if (SolutionSet.isSolutionSet(arr)) {
|
|
192
|
+
source = arr;
|
|
193
|
+
solutions = arr.elements;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
solutions = arr;
|
|
197
|
+
}
|
|
198
|
+
let sourceAccepted = false;
|
|
199
|
+
for (const sol of solutions) {
|
|
200
|
+
if (this.verifyAndAddSolution(sol, forFunction, variable)) {
|
|
201
|
+
sourceAccepted = true;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (source && sourceAccepted) {
|
|
205
|
+
this.mergeSolutionsType(source.solutionsType);
|
|
206
|
+
}
|
|
207
|
+
return this;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Adds a batch of numerical solutions that has already been validated against its source
|
|
211
|
+
* polynomial. Incoming values are deduplicated by their exact numeric components before
|
|
212
|
+
* storage so a numerical root batch does not require pairwise symbolic equality checks.
|
|
213
|
+
*
|
|
214
|
+
* @internal
|
|
215
|
+
*/
|
|
216
|
+
addValidatedNumericalSolutions(values) {
|
|
217
|
+
const candidates = [...values];
|
|
218
|
+
const existing = this.elements;
|
|
219
|
+
const keys = new Set();
|
|
220
|
+
for (const value of candidates) {
|
|
221
|
+
if (!Expression_1.Expression.isExpression(value)) {
|
|
222
|
+
const entity = value;
|
|
223
|
+
throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: entity.dataType }));
|
|
224
|
+
}
|
|
225
|
+
const real = value.isComplex() ? value.realPart() : value;
|
|
226
|
+
const imaginary = value.isComplex() ? value.imagPart() : Expression_1.Expression.Number(0);
|
|
227
|
+
if (!real.isNUM() || !imaginary.isNUM()) {
|
|
228
|
+
throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: value.dataType }));
|
|
229
|
+
}
|
|
230
|
+
const realMultiplier = real.getMultiplier();
|
|
231
|
+
const imaginaryMultiplier = imaginary.getMultiplier();
|
|
232
|
+
const key = `${realMultiplier.numerator}/${realMultiplier.denominator}|` +
|
|
233
|
+
`${imaginaryMultiplier.numerator}/${imaginaryMultiplier.denominator}`;
|
|
234
|
+
if (keys.has(key) || this.excluded.has(value)) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
let present = false;
|
|
238
|
+
for (const stored of existing) {
|
|
239
|
+
if (stored.eq(value) && value.eq(stored)) {
|
|
240
|
+
present = true;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (!present) {
|
|
245
|
+
this.addKnownUnique(value);
|
|
246
|
+
keys.add(key);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return this;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Appends another solution result while preserving set and solver metadata.
|
|
253
|
+
*
|
|
254
|
+
* @remarks
|
|
255
|
+
* Exclusions are merged before accepted values so an excluded candidate cannot be
|
|
256
|
+
* reintroduced. Raw numerical-root records are copied. `partial` is combined with logical
|
|
257
|
+
* OR and differing defined solution types become `mixed`. If this set has no `unsolved`
|
|
258
|
+
* expression, the appended set's unresolved expression is copied; when both sets already
|
|
259
|
+
* carry different unresolved expressions, the receiver's value is retained because the
|
|
260
|
+
* current data model can represent only one such expression.
|
|
261
|
+
*/
|
|
262
|
+
append(s) {
|
|
263
|
+
const transferUnique = this.count() === 0 && this.excluded.count() === 0;
|
|
264
|
+
this.exclude(s.getExcluded());
|
|
265
|
+
if (transferUnique) {
|
|
266
|
+
for (const solution of s.elements) {
|
|
267
|
+
this.addKnownUnique(solution);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
this.addMany(s.elements);
|
|
272
|
+
}
|
|
273
|
+
for (const root of s.getRawRoots()) {
|
|
274
|
+
this.addRawRoot(root);
|
|
275
|
+
}
|
|
276
|
+
this.partial = this.partial || s.partial;
|
|
277
|
+
this.mergeSolutionsType(s.solutionsType);
|
|
278
|
+
if (!this.unsolved && s.unsolved) {
|
|
279
|
+
this.unsolved = s.unsolved.copy();
|
|
280
|
+
}
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Appends numerical solutions that were already validated by a numerical solver.
|
|
285
|
+
*
|
|
286
|
+
* This follows the same metadata and exclusion handling as {@link append}, but avoids
|
|
287
|
+
* repeating symbolic membership checks for a batch that has already been numerically
|
|
288
|
+
* validated and deduplicated.
|
|
289
|
+
*
|
|
290
|
+
* @internal
|
|
291
|
+
*/
|
|
292
|
+
appendValidatedNumerical(s) {
|
|
293
|
+
this.exclude(s.getExcluded());
|
|
294
|
+
this.addValidatedNumericalSolutions(s.elements);
|
|
295
|
+
for (const root of s.getRawRoots()) {
|
|
296
|
+
this.addRawRoot(root);
|
|
297
|
+
}
|
|
298
|
+
this.partial = this.partial || s.partial;
|
|
299
|
+
this.mergeSolutionsType(s.solutionsType);
|
|
300
|
+
if (!this.unsolved && s.unsolved) {
|
|
301
|
+
this.unsolved = s.unsolved.copy();
|
|
302
|
+
}
|
|
303
|
+
return this;
|
|
304
|
+
}
|
|
305
|
+
/** Returns an independent Expression copy at the requested insertion-order index. */
|
|
306
|
+
at(i) {
|
|
307
|
+
return super.at(i);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Removes accepted solutions and all solver state so the instance can be reused.
|
|
311
|
+
*/
|
|
312
|
+
clear() {
|
|
313
|
+
super.clear();
|
|
314
|
+
this.excluded.clear();
|
|
315
|
+
this.roots.length = 0;
|
|
316
|
+
this.partial = false;
|
|
317
|
+
this.solutionsType = undefined;
|
|
318
|
+
this.unsolved = undefined;
|
|
319
|
+
return this;
|
|
320
|
+
}
|
|
321
|
+
/** Returns an independent copy including exclusions and raw-root metadata. */
|
|
322
|
+
copy() {
|
|
323
|
+
const copy = new SolutionSet(this.elements);
|
|
324
|
+
copy.excluded = this.excluded.copy();
|
|
325
|
+
copy.roots = this.getRawRoots();
|
|
326
|
+
copy.solutionsType = this.solutionsType;
|
|
327
|
+
copy.partial = this.partial;
|
|
328
|
+
if (this.unsolved) {
|
|
329
|
+
copy.unsolved = this.unsolved.copy();
|
|
330
|
+
}
|
|
331
|
+
return copy;
|
|
332
|
+
}
|
|
333
|
+
each(callback) {
|
|
334
|
+
super.each((e, i, j) => {
|
|
335
|
+
if (!Expression_1.Expression.isExpression(e)) {
|
|
336
|
+
throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: e.dataType }));
|
|
337
|
+
}
|
|
338
|
+
const mapped = callback(e, i, j);
|
|
339
|
+
if (mapped === undefined) {
|
|
340
|
+
return e;
|
|
341
|
+
}
|
|
342
|
+
if (!Expression_1.Expression.isExpression(mapped)) {
|
|
343
|
+
throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: mapped.dataType }));
|
|
344
|
+
}
|
|
345
|
+
return mapped;
|
|
346
|
+
});
|
|
347
|
+
for (const value of this.excluded.elements) {
|
|
348
|
+
this.delete(value);
|
|
349
|
+
}
|
|
350
|
+
return this;
|
|
351
|
+
}
|
|
352
|
+
/** Returns deep-copied accepted solution descriptors in deterministic insertion order. */
|
|
353
|
+
get elements() {
|
|
354
|
+
return super.elements;
|
|
355
|
+
}
|
|
356
|
+
evaluate(values) {
|
|
357
|
+
return this.copy().each(e => e.evaluate(values));
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Adds exclusions and removes any matching values that were already accepted.
|
|
361
|
+
*/
|
|
362
|
+
exclude(set) {
|
|
363
|
+
const values = set.elements;
|
|
364
|
+
for (const value of values) {
|
|
365
|
+
if (!Expression_1.Expression.isExpression(value)) {
|
|
366
|
+
throw new errors_1.UnexpectedDataType((0, errors_1.message)('expressionExpected', { type: value.dataType }));
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
for (const value of values) {
|
|
370
|
+
this.excluded.add(value);
|
|
371
|
+
this.delete(value);
|
|
372
|
+
}
|
|
373
|
+
return this;
|
|
374
|
+
}
|
|
375
|
+
expand() {
|
|
376
|
+
return this.copy().each(e => e.expand());
|
|
377
|
+
}
|
|
378
|
+
/** Visits independent Expression copies without changing this solution set. */
|
|
379
|
+
forEach(callback) {
|
|
380
|
+
const values = this.elements;
|
|
381
|
+
for (let i = 0; i < values.length; i++) {
|
|
382
|
+
callback(values[i], i);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/** Returns an independent copy of the currently excluded values. */
|
|
386
|
+
getExcluded() {
|
|
387
|
+
return this.excluded.copy();
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Returns independent copies of the stored numerical root-refinement records.
|
|
391
|
+
*/
|
|
392
|
+
getRawRoots() {
|
|
393
|
+
return this.roots.map(root => ({
|
|
394
|
+
root: new decimal_js_1.default(root.root),
|
|
395
|
+
iterations: root.iterations,
|
|
396
|
+
converged: root.converged,
|
|
397
|
+
error: new decimal_js_1.default(root.error),
|
|
398
|
+
errorMsg: root.errorMsg,
|
|
399
|
+
}));
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Classifies the mathematical result represented by the stored descriptors.
|
|
403
|
+
*
|
|
404
|
+
* Arbitrary symbolic parameters do not make a result parametric in this sense. The
|
|
405
|
+
* `parametric` form is reserved for solver-generated families that contain `_n`, where
|
|
406
|
+
* `_n` represents an integer index. The special `all` descriptor takes precedence if
|
|
407
|
+
* present.
|
|
408
|
+
*/
|
|
409
|
+
get solutionForm() {
|
|
410
|
+
let retval = 'finite';
|
|
411
|
+
for (const solution of this.elements) {
|
|
412
|
+
if (solution.eq(constants_1.ALL_SYMBOL)) {
|
|
413
|
+
retval = 'all';
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
if (solution.hasVariable(constants_1.INDEX_VARIABLE)) {
|
|
417
|
+
retval = 'parametric';
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return retval;
|
|
421
|
+
}
|
|
422
|
+
/** Iterates over independent Expression copies of the accepted solutions. */
|
|
423
|
+
[Symbol.iterator]() {
|
|
424
|
+
return this.elements[Symbol.iterator]();
|
|
425
|
+
}
|
|
426
|
+
text() {
|
|
427
|
+
return super.text();
|
|
428
|
+
}
|
|
429
|
+
/** Returns deep-copied accepted solutions as a plain array. */
|
|
430
|
+
toArray() {
|
|
431
|
+
return this.elements;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
exports.SolutionSet = SolutionSet;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Expression } from '../../core/classes/expression/Expression';
|
|
2
|
+
import type { ExpressionInput } from '../../core/types';
|
|
3
|
+
import type Decimal from 'decimal.js';
|
|
4
|
+
export declare class Solver {
|
|
5
|
+
epsilon: number;
|
|
6
|
+
newtonEpsilon: number;
|
|
7
|
+
newtonMaxIterations: number;
|
|
8
|
+
newtonMaxSymbolicIterations: number;
|
|
9
|
+
rootsPerSide: number;
|
|
10
|
+
searchRadius: number;
|
|
11
|
+
symbolicEpsilon: number;
|
|
12
|
+
getPoints(f: (x: number) => number, start?: number, step?: number): number[];
|
|
13
|
+
newton(f: (x: number) => number, point: number): number | undefined;
|
|
14
|
+
newtonSymbolic(f: Expression, p: Expression, variable: string): Decimal | undefined;
|
|
15
|
+
solve(f: ExpressionInput): number[];
|
|
16
|
+
solveSymbolic(f: ExpressionInput): Decimal[];
|
|
17
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Solver = void 0;
|
|
4
|
+
const diff_1 = require("../../calculus/derivative/diff");
|
|
5
|
+
const Expression_1 = require("../../core/classes/expression/Expression");
|
|
6
|
+
const numeric_1 = require("../../core/functions/numeric");
|
|
7
|
+
class Solver {
|
|
8
|
+
// The numeric epsilon to be used
|
|
9
|
+
epsilon = 1e-13;
|
|
10
|
+
// The epsilon to be used when solving newton
|
|
11
|
+
newtonEpsilon = Number.EPSILON * 2;
|
|
12
|
+
// The maximum number of iteration for newton
|
|
13
|
+
newtonMaxIterations = 200;
|
|
14
|
+
newtonMaxSymbolicIterations = 50;
|
|
15
|
+
// The maximum roots to search for at each side
|
|
16
|
+
rootsPerSide = 10;
|
|
17
|
+
// The extend to which roots will be searched for
|
|
18
|
+
searchRadius = 100;
|
|
19
|
+
// const f = (x) => { return x ** 3 + 2 * x ** 2 - 1 }; // Gives false positives
|
|
20
|
+
symbolicEpsilon = 1e-16;
|
|
21
|
+
getPoints(f, start = 0, step = 1) {
|
|
22
|
+
const points = [];
|
|
23
|
+
// Roots found. This should be reset for each side
|
|
24
|
+
let roots = 0;
|
|
25
|
+
const testAndAdd = (point) => {
|
|
26
|
+
// Test if it's zero at that point
|
|
27
|
+
if (f(point) === 0 || Math.sign(f(point - step)) !== Math.sign(f(point + step))) {
|
|
28
|
+
points.push(point);
|
|
29
|
+
roots++;
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
};
|
|
34
|
+
const leftEnd = start - this.searchRadius;
|
|
35
|
+
const rightEnd = start + this.searchRadius;
|
|
36
|
+
// Test the right side
|
|
37
|
+
let n = start;
|
|
38
|
+
while (n < rightEnd) {
|
|
39
|
+
testAndAdd(n);
|
|
40
|
+
if (roots === this.rootsPerSide) {
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
n += step;
|
|
44
|
+
}
|
|
45
|
+
// Test the left side
|
|
46
|
+
n = start;
|
|
47
|
+
roots = 0;
|
|
48
|
+
while (n > leftEnd) {
|
|
49
|
+
testAndAdd(n);
|
|
50
|
+
if (roots === this.rootsPerSide) {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
n -= step;
|
|
54
|
+
}
|
|
55
|
+
return points;
|
|
56
|
+
}
|
|
57
|
+
newton(f, point) {
|
|
58
|
+
let iters = 0;
|
|
59
|
+
let x0 = point;
|
|
60
|
+
const fp = (0, numeric_1.diff)(f);
|
|
61
|
+
let x;
|
|
62
|
+
let e;
|
|
63
|
+
do {
|
|
64
|
+
const fx0 = f(x0); //store the result of the function
|
|
65
|
+
//if the value is zero then we're done because 0 - (0/d f(x0)) = 0
|
|
66
|
+
if (x0 === 0 && fx0 === 0) {
|
|
67
|
+
x = 0;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
iters++;
|
|
71
|
+
if (iters > this.newtonMaxIterations) {
|
|
72
|
+
return;
|
|
73
|
+
} //maximum iterations reached
|
|
74
|
+
x = x0 - fx0 / fp(x0);
|
|
75
|
+
e = Math.abs(x - x0);
|
|
76
|
+
x0 = x;
|
|
77
|
+
} while (e > this.newtonEpsilon);
|
|
78
|
+
//check if the number is indeed zero. 1e-13 seems to give the most accurate results
|
|
79
|
+
if (Math.abs(f(x)) <= this.epsilon) {
|
|
80
|
+
return x;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
newtonSymbolic(f, p, variable) {
|
|
84
|
+
let iters = 0;
|
|
85
|
+
let x0 = p.getMultiplier().toDecimal();
|
|
86
|
+
const fp = (0, diff_1.diff)(f, variable);
|
|
87
|
+
const values = { [variable]: p };
|
|
88
|
+
let x;
|
|
89
|
+
let e;
|
|
90
|
+
do {
|
|
91
|
+
const fx0 = f.evaluate(values);
|
|
92
|
+
if (iters++ > this.newtonMaxSymbolicIterations) {
|
|
93
|
+
return;
|
|
94
|
+
} //maximum iterations reached
|
|
95
|
+
x = x0.minus(fx0.div(fp.evaluate(values)).text({ decimal: true }));
|
|
96
|
+
// tracker = tracker.minus(fx0S.div(Expression.create(fp, values)))
|
|
97
|
+
e = x.minus(x0).abs();
|
|
98
|
+
x0 = x;
|
|
99
|
+
values[variable] = x0.isFinite() ? Expression_1.Expression.Number(x0) : x0.toString();
|
|
100
|
+
} while (e.abs().gte(this.symbolicEpsilon));
|
|
101
|
+
// console.log(tracker.toString())
|
|
102
|
+
return x;
|
|
103
|
+
}
|
|
104
|
+
solve(f) {
|
|
105
|
+
f = Expression_1.Expression.create(f);
|
|
106
|
+
const g = f.buildFunction();
|
|
107
|
+
const points = this.getPoints(g);
|
|
108
|
+
const solutions = [];
|
|
109
|
+
for (const p of points) {
|
|
110
|
+
const solution = this.newton(g, p);
|
|
111
|
+
if (solution !== undefined) {
|
|
112
|
+
solutions.push(solution);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return [...new Set(solutions)];
|
|
116
|
+
}
|
|
117
|
+
solveSymbolic(f) {
|
|
118
|
+
f = Expression_1.Expression.create(f);
|
|
119
|
+
const g = f.buildFunction();
|
|
120
|
+
const points = this.getPoints(g);
|
|
121
|
+
const variable = f.variables()[0];
|
|
122
|
+
const solutions = {};
|
|
123
|
+
for (const p of points) {
|
|
124
|
+
const solution = this.newtonSymbolic(f, Expression_1.Expression.Number(p), variable);
|
|
125
|
+
if (solution !== undefined) {
|
|
126
|
+
solutions[solution.toString()] = solution;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return Object.values(solutions);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
exports.Solver = Solver;
|
|
@@ -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
|
+
}
|