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,339 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tryIntegrationByParts = tryIntegrationByParts;
|
|
4
|
+
const Expression_1 = require("../../core/classes/expression/Expression");
|
|
5
|
+
const shortcuts_1 = require("../../core/classes/expression/shortcuts");
|
|
6
|
+
const trig_1 = require("../../core/classes/expression/trig");
|
|
7
|
+
const constants_1 = require("../../core/classes/parser/constants");
|
|
8
|
+
const math_1 = require("../../math/math");
|
|
9
|
+
const diff_1 = require("../derivative/diff");
|
|
10
|
+
/**
|
|
11
|
+
* LIATE priority constants.
|
|
12
|
+
* Higher number = should be chosen as u.
|
|
13
|
+
*/
|
|
14
|
+
const LIATE = {
|
|
15
|
+
EXP: 0,
|
|
16
|
+
TRIG: 1,
|
|
17
|
+
ALGEBRAIC: 2,
|
|
18
|
+
INVERSE_TRIG: 3,
|
|
19
|
+
LOG: 4,
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Maximum number of recursive IBP applications within a single
|
|
23
|
+
* integration attempt. This is independent of integrate's own
|
|
24
|
+
* MAX_DEPTH and exists to prevent runaway recursion from
|
|
25
|
+
* pathological integrands like e^x·tan(x).
|
|
26
|
+
*/
|
|
27
|
+
const MAX_IBP_DEPTH = 4;
|
|
28
|
+
/**
|
|
29
|
+
* Extracts the maximum power of the integration variable in an expression.
|
|
30
|
+
* For a product like x^3·sin(x), returns 3. For a sum produced by
|
|
31
|
+
* linearity (e.g. 2·x·sin(x) + ...), returns the maximum across terms.
|
|
32
|
+
* Returns 0 if the variable does not appear algebraically (e.g. pure sin(x)).
|
|
33
|
+
*/
|
|
34
|
+
function maxAlgebraicDegree(expr, v) {
|
|
35
|
+
let retval = undefined;
|
|
36
|
+
if (expr.isVAR() && expr.hasVariable(v)) {
|
|
37
|
+
// x^n — getPower() returns the exponent
|
|
38
|
+
retval = expr.getPower();
|
|
39
|
+
}
|
|
40
|
+
else if (expr.isProduct()) {
|
|
41
|
+
let maxDeg = (0, shortcuts_1.zero)();
|
|
42
|
+
for (const factor of expr.elementsArray()) {
|
|
43
|
+
if (factor.isVAR() && factor.hasVariable(v)) {
|
|
44
|
+
const p = factor.getPower();
|
|
45
|
+
maxDeg = (0, math_1.max)(maxDeg, p);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
retval = maxDeg;
|
|
49
|
+
}
|
|
50
|
+
else if (expr.isSum()) {
|
|
51
|
+
let maxDeg = (0, shortcuts_1.zero)();
|
|
52
|
+
expr.each((term) => {
|
|
53
|
+
maxDeg = (0, math_1.max)(maxDeg, maxAlgebraicDegree(term, v));
|
|
54
|
+
});
|
|
55
|
+
retval = maxDeg;
|
|
56
|
+
}
|
|
57
|
+
return retval ?? (0, shortcuts_1.zero)();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Counts the number of function applications (sin, cos, log, etc.)
|
|
61
|
+
* in an expression. Used as a structural complexity measure for
|
|
62
|
+
* non-algebraic IBP progress checking.
|
|
63
|
+
*/
|
|
64
|
+
function functionCount(expr) {
|
|
65
|
+
let count = 0;
|
|
66
|
+
if (expr.isFunction()) {
|
|
67
|
+
count = 1;
|
|
68
|
+
}
|
|
69
|
+
if (expr.isProduct() || expr.isSum()) {
|
|
70
|
+
expr.each((child) => {
|
|
71
|
+
count += functionCount(child);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return count;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Determines whether IBP has made progress by producing a simpler
|
|
78
|
+
* remainder integrand. The definition of "progress" depends on the
|
|
79
|
+
* LIATE category of u:
|
|
80
|
+
*
|
|
81
|
+
* - ALGEBRAIC u (polynomial × trig/exp): progress means the polynomial
|
|
82
|
+
* degree in the integration variable strictly decreased. This is the
|
|
83
|
+
* fundamental guarantee of IBP for x^n·f(x) — each round reduces
|
|
84
|
+
* the degree by 1, terminating after n rounds.
|
|
85
|
+
*
|
|
86
|
+
* - LOG or INVERSE_TRIG u: one round of IBP eliminates the
|
|
87
|
+
* transcendental factor, replacing it with an algebraic derivative.
|
|
88
|
+
* Progress means the new integrand has fewer function nodes than
|
|
89
|
+
* the original.
|
|
90
|
+
*
|
|
91
|
+
* - Anything else: fallback to a structural comparison — the new
|
|
92
|
+
* integrand must have strictly fewer function nodes.
|
|
93
|
+
*
|
|
94
|
+
* Returns true if the new integrand represents progress.
|
|
95
|
+
*/
|
|
96
|
+
function isProgress(original, newIntegrand, uCategory, v) {
|
|
97
|
+
if (uCategory === LIATE.ALGEBRAIC) {
|
|
98
|
+
// Polynomial degree must strictly decrease
|
|
99
|
+
const oldDeg = maxAlgebraicDegree(original, v);
|
|
100
|
+
const newDeg = maxAlgebraicDegree(newIntegrand, v);
|
|
101
|
+
return newDeg < oldDeg;
|
|
102
|
+
}
|
|
103
|
+
if (uCategory === LIATE.LOG || uCategory === LIATE.INVERSE_TRIG) {
|
|
104
|
+
// Function count must decrease (log/invtrig disappears after differentiation)
|
|
105
|
+
return functionCount(newIntegrand) < functionCount(original);
|
|
106
|
+
}
|
|
107
|
+
// Fallback: structural complexity must decrease
|
|
108
|
+
return functionCount(newIntegrand) < functionCount(original);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Classifies an expression by LIATE category.
|
|
112
|
+
* Returns -1 if unclassifiable.
|
|
113
|
+
*/
|
|
114
|
+
function liatePriority(expr) {
|
|
115
|
+
// Algebraic: x^n (variable with a power)
|
|
116
|
+
if (expr.isVAR()) {
|
|
117
|
+
return LIATE.ALGEBRAIC;
|
|
118
|
+
}
|
|
119
|
+
// Exponential: e^(ax) or a^(bx)
|
|
120
|
+
if (expr.isEXP()) {
|
|
121
|
+
return LIATE.EXP;
|
|
122
|
+
}
|
|
123
|
+
if (expr.isFunction()) {
|
|
124
|
+
const name = expr.name;
|
|
125
|
+
// Logarithmic
|
|
126
|
+
if (name === constants_1.LOG || name === constants_1.LN) {
|
|
127
|
+
return LIATE.LOG;
|
|
128
|
+
}
|
|
129
|
+
// Inverse trig
|
|
130
|
+
if ((0, trig_1.isInverseTrig)(expr)) {
|
|
131
|
+
return LIATE.INVERSE_TRIG;
|
|
132
|
+
}
|
|
133
|
+
// Trigonometric
|
|
134
|
+
if ((0, trig_1.isTrig)(expr)) {
|
|
135
|
+
return LIATE.TRIG;
|
|
136
|
+
}
|
|
137
|
+
// Hyperbolic (treat like trig for LIATE purposes)
|
|
138
|
+
if ((0, trig_1.isHyperbolicTrig)(expr)) {
|
|
139
|
+
return LIATE.TRIG;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return -1;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Detects whether a pair of LIATE categories is known to produce
|
|
146
|
+
* non-terminating IBP recursion. This goes beyond the simple
|
|
147
|
+
* same-category check to catch cross-category pathological pairs.
|
|
148
|
+
*
|
|
149
|
+
* Known problematic pairs:
|
|
150
|
+
* - TRIG + TRIG: e.g. sin(x)·cos(x) — cyclic
|
|
151
|
+
* - EXP + EXP: e.g. e^x·2^x — cyclic
|
|
152
|
+
* - EXP + TRIG with non-integrable trig: e.g. e^x·tan(x) —
|
|
153
|
+
* produces increasingly complex trig powers
|
|
154
|
+
*
|
|
155
|
+
* LOG + EXP (e.g. e^x·log(x)) and LOG + TRIG (e.g. sin(x)·log(x))
|
|
156
|
+
* are NOT blocked here. After one IBP round, the remainder is of the
|
|
157
|
+
* form f(x)/x which maps to special functions (Ei, Si, Ci) via the
|
|
158
|
+
* integration table. The isProgress guard prevents spiraling if the
|
|
159
|
+
* table entry is missing.
|
|
160
|
+
*
|
|
161
|
+
* The EXP+TRIG pair is only problematic when the trig function
|
|
162
|
+
* is not one whose integral stays in the same family (sin/cos).
|
|
163
|
+
* e^x·sin(x) and e^x·cos(x) are handled by the table, so they
|
|
164
|
+
* never reach IBP. But e^x·tan(x), e^x·sec(x), etc. spiral.
|
|
165
|
+
*/
|
|
166
|
+
function isCyclicPair(p0, p1, u, dv) {
|
|
167
|
+
// Same category: trig+trig or exp+exp
|
|
168
|
+
if (p0 === p1 && (p0 === LIATE.TRIG || p0 === LIATE.EXP)) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
// EXP + TRIG where the trig function is not sin/cos
|
|
172
|
+
// (sin/cos pairs are handled by the integration table and never reach here,
|
|
173
|
+
// but tan, sec, csc, cot produce ever-growing powers under IBP)
|
|
174
|
+
if ((p0 === LIATE.EXP && p1 === LIATE.TRIG) || (p0 === LIATE.TRIG && p1 === LIATE.EXP)) {
|
|
175
|
+
const trigFactor = p0 === LIATE.TRIG ? u : dv;
|
|
176
|
+
if (trigFactor.isFunction()) {
|
|
177
|
+
const name = trigFactor.name;
|
|
178
|
+
// sin and cos are safe (table handles e^x·sin/cos directly)
|
|
179
|
+
// Everything else spirals
|
|
180
|
+
if (name !== constants_1.SIN && name !== constants_1.COS) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
function tryMergeDerivativePair(varFactors, v) {
|
|
188
|
+
if (varFactors.length < 3) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
const dx = Expression_1.Expression.create(v);
|
|
192
|
+
for (let i = 0; i < varFactors.length; i++) {
|
|
193
|
+
const candidate = varFactors[i];
|
|
194
|
+
const dCandidate = (0, diff_1.diff)(candidate, dx);
|
|
195
|
+
if (dCandidate.isFunction(constants_1.DIFF)) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
for (let j = 0; j < varFactors.length; j++) {
|
|
199
|
+
if (j === i) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
let rest;
|
|
203
|
+
for (let k = 0; k < varFactors.length; k++) {
|
|
204
|
+
if (k === i || k === j) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
rest = rest ? rest.times(varFactors[k]) : varFactors[k];
|
|
208
|
+
}
|
|
209
|
+
if (!rest) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
// Check whether dCandidate is proportional to rest
|
|
213
|
+
const q = dCandidate.div(rest);
|
|
214
|
+
if (!q.hasVariable(v)) {
|
|
215
|
+
return [candidate, varFactors[j]];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Attempts integration by parts for a product with two variable-dependent factors.
|
|
223
|
+
*
|
|
224
|
+
* LIATE priority selects `u`; independent multipliers are preserved separately.
|
|
225
|
+
* Category-specific progress checks and a dedicated recursion bound reject
|
|
226
|
+
* cyclic or increasingly complex decompositions.
|
|
227
|
+
*
|
|
228
|
+
* @param x - Product integrand.
|
|
229
|
+
* @param v - Integration variable.
|
|
230
|
+
* @param integrate - Recursive integration strategy supplied by the caller.
|
|
231
|
+
* @param depth - Current outer integration depth.
|
|
232
|
+
* @param ibpDepth - Current integration-by-parts depth.
|
|
233
|
+
* @returns An antiderivative when the transformation makes progress, otherwise
|
|
234
|
+
* `undefined` so another strategy can run.
|
|
235
|
+
*/
|
|
236
|
+
function tryIntegrationByParts(x, v, integrate, depth = 0, ibpDepth = 0) {
|
|
237
|
+
if (!x.isProduct()) {
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
240
|
+
// IBP-specific depth guard: prevent runaway recursion independent of
|
|
241
|
+
// integrate's own MAX_DEPTH. This fires much sooner and avoids the
|
|
242
|
+
// long delays caused by exhausting the global depth limit.
|
|
243
|
+
if (ibpDepth >= MAX_IBP_DEPTH) {
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
const factors = x.elementsArray();
|
|
247
|
+
// Extract the overall multiplier and variable-containing factors
|
|
248
|
+
const varFactors = [];
|
|
249
|
+
// IMPORTANT: elementsArray() does not include the product's own multiplier, so pull it from the expression.
|
|
250
|
+
let coefficient = x.getMultiplier(true);
|
|
251
|
+
for (let factor of factors) {
|
|
252
|
+
if (!factor.hasVariable(v)) {
|
|
253
|
+
// Constant factor: fold it into the coefficient
|
|
254
|
+
coefficient = coefficient.times(factor);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
// Variable factor: also peel off its own multiplier so it doesn't get dropped in recursive IBP.
|
|
258
|
+
// Example: 3*x^2*e^x can appear with the 3 sitting on the product multiplier OR on the factor.
|
|
259
|
+
const m = factor.getMultiplier(true);
|
|
260
|
+
if (!m.isOne()) {
|
|
261
|
+
coefficient = coefficient.times(m);
|
|
262
|
+
factor = factor.div(m);
|
|
263
|
+
}
|
|
264
|
+
varFactors.push(factor);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (varFactors.length > 2) {
|
|
268
|
+
const merged = tryMergeDerivativePair(varFactors, v);
|
|
269
|
+
if (merged) {
|
|
270
|
+
varFactors.length = 0;
|
|
271
|
+
varFactors.push(...merged);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// IBP needs exactly 2 variable-containing factors
|
|
275
|
+
if (varFactors.length !== 2) {
|
|
276
|
+
return undefined;
|
|
277
|
+
}
|
|
278
|
+
// Classify and assign u and dv using LIATE priority
|
|
279
|
+
const p0 = liatePriority(varFactors[0]);
|
|
280
|
+
const p1 = liatePriority(varFactors[1]);
|
|
281
|
+
// If either factor is unclassified, bail
|
|
282
|
+
if (p0 < 0 || p1 < 0) {
|
|
283
|
+
return undefined;
|
|
284
|
+
}
|
|
285
|
+
// Higher priority → u (differentiates to something simpler)
|
|
286
|
+
let u, dv;
|
|
287
|
+
if (p0 >= p1) {
|
|
288
|
+
u = varFactors[0];
|
|
289
|
+
dv = varFactors[1];
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
u = varFactors[1];
|
|
293
|
+
dv = varFactors[0];
|
|
294
|
+
}
|
|
295
|
+
// Detect cyclic or pathological LIATE pairings that will never converge
|
|
296
|
+
const uCategory = p0 >= p1 ? p0 : p1;
|
|
297
|
+
if (isCyclicPair(p0, p1, u, dv)) {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
// Compute du = d/dx(u)
|
|
301
|
+
const du = (0, diff_1.diff)(u, Expression_1.Expression.create(v));
|
|
302
|
+
// If diff returned a symbolic diff(...) expression, it couldn't compute the derivative
|
|
303
|
+
if (du.isFunction(constants_1.DIFF)) {
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
// Compute v_result = ∫ dv dx
|
|
307
|
+
const vResult = integrate(dv, v, depth);
|
|
308
|
+
if (vResult.isFunction(constants_1.INTEGRATE)) {
|
|
309
|
+
return undefined;
|
|
310
|
+
} // dv can't be integrated
|
|
311
|
+
// ∫ u·dv = u·v - ∫ v·du
|
|
312
|
+
const uv = coefficient.times(u).times(vResult);
|
|
313
|
+
// Build the new integrand: v·du (with the original coefficient)
|
|
314
|
+
const newIntegrand = coefficient.times(vResult).times(du);
|
|
315
|
+
// Progress guard: verify IBP is actually simplifying the integrand.
|
|
316
|
+
// The definition of "progress" is LIATE-category-aware:
|
|
317
|
+
// - Algebraic u: polynomial degree must decrease
|
|
318
|
+
// - Log/InvTrig u: function count must decrease
|
|
319
|
+
// - Fallback: structural function count must decrease
|
|
320
|
+
if (!isProgress(x, newIntegrand, uCategory, v)) {
|
|
321
|
+
return undefined;
|
|
322
|
+
}
|
|
323
|
+
// Try to integrate v·du
|
|
324
|
+
const remainder = integrate(newIntegrand, v, depth);
|
|
325
|
+
// If the remainder is fully symbolic (nothing was integrated), IBP didn't help
|
|
326
|
+
// But allow partial results (some terms integrated via linearity)
|
|
327
|
+
let retval;
|
|
328
|
+
if (remainder.isFunction(constants_1.INTEGRATE)) {
|
|
329
|
+
// One more check: try IBP recursively on the remainder
|
|
330
|
+
const innerResult = tryIntegrationByParts(newIntegrand, v, integrate, depth + 1, ibpDepth + 1);
|
|
331
|
+
if (innerResult !== undefined) {
|
|
332
|
+
retval = uv.plus(innerResult.times((0, shortcuts_1.minusOne)()));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
retval = uv.plus(remainder.times((0, shortcuts_1.minusOne)()));
|
|
337
|
+
}
|
|
338
|
+
return retval;
|
|
339
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Expression } from '../../core/classes/expression/Expression';
|
|
2
|
+
/**
|
|
3
|
+
* Attempts to detect an f(x)·f'(x) substitution structure from a list of
|
|
4
|
+
* multiplicative factors.
|
|
5
|
+
*
|
|
6
|
+
* The algorithm performs a contiguous range search over the factors.
|
|
7
|
+
* For each contiguous block it builds a candidate f(x) and compares it
|
|
8
|
+
* against the remaining factors.
|
|
9
|
+
*
|
|
10
|
+
* Example structure detected:
|
|
11
|
+
*
|
|
12
|
+
* (a^x*log(a)*cos(x) - a^x*sin(x)) * a^x*cos(x)
|
|
13
|
+
*
|
|
14
|
+
* which matches
|
|
15
|
+
*
|
|
16
|
+
* f(x) = a^x*cos(x)
|
|
17
|
+
* f'(x) = a^x*log(a)*cos(x) - a^x*sin(x)
|
|
18
|
+
*
|
|
19
|
+
* yielding
|
|
20
|
+
*
|
|
21
|
+
* ∫ f f' dx = f² / 2
|
|
22
|
+
*
|
|
23
|
+
* To reduce symbolic overhead:
|
|
24
|
+
*
|
|
25
|
+
* - The total product is computed once.
|
|
26
|
+
* - The left candidate product grows incrementally.
|
|
27
|
+
* - The complementary product is obtained via division.
|
|
28
|
+
*
|
|
29
|
+
* @param factors multiplicative factors of the integrand
|
|
30
|
+
* @param x integration variable
|
|
31
|
+
* @returns substitution match or undefined if none found
|
|
32
|
+
*/
|
|
33
|
+
export declare function bySubstitution(factors: Expression[], x: string): {
|
|
34
|
+
fx: Expression;
|
|
35
|
+
constant: Expression;
|
|
36
|
+
power: Expression;
|
|
37
|
+
} | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Attempts to integrate an expression using product-style substitution.
|
|
40
|
+
*
|
|
41
|
+
* This function prepares the expression for substitution detection
|
|
42
|
+
* by extracting multiplicative factors and then delegating to
|
|
43
|
+
* {@link bySubstitution}.
|
|
44
|
+
*
|
|
45
|
+
* The method specifically searches for integrands of the form
|
|
46
|
+
*
|
|
47
|
+
* c * f(x) * f'(x)
|
|
48
|
+
*
|
|
49
|
+
* which integrate to
|
|
50
|
+
*
|
|
51
|
+
* c * f(x)² / 2
|
|
52
|
+
*
|
|
53
|
+
* Factorization is only performed when necessary to avoid the
|
|
54
|
+
* significant cost of factoring expressions unnecessarily.
|
|
55
|
+
*
|
|
56
|
+
* @param fx expression to integrate
|
|
57
|
+
* @param x integration variable
|
|
58
|
+
* @returns substitution match information or undefined
|
|
59
|
+
*/
|
|
60
|
+
export declare function tryIntegrateBySubstitution(fx: Expression, x: string): {
|
|
61
|
+
fx: Expression;
|
|
62
|
+
constant: Expression;
|
|
63
|
+
power: Expression;
|
|
64
|
+
} | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Attempts substitution when one factor wraps an inner expression and the
|
|
67
|
+
* remaining factors are proportional to its derivative.
|
|
68
|
+
*
|
|
69
|
+
* @param fx - Complete product integrand, used to select a fresh variable.
|
|
70
|
+
* @param factors - Multiplicative factors to test.
|
|
71
|
+
* @param x - Integration variable.
|
|
72
|
+
* @returns The back-substituted antiderivative, or `undefined` when the outer
|
|
73
|
+
* factor is not covered by the integration table.
|
|
74
|
+
*/
|
|
75
|
+
export declare function tryIntegrateByWrappedFactorSubstitution(fx: Expression, factors: Expression[], x: string): Expression | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Attempts to detect a logarithmic substitution structure of the form
|
|
78
|
+
*
|
|
79
|
+
* c * f'(x) / f(x)
|
|
80
|
+
*
|
|
81
|
+
* by extracting the numerator and denominator of the expression and
|
|
82
|
+
* testing whether the numerator is proportional to the derivative of
|
|
83
|
+
* the denominator.
|
|
84
|
+
*
|
|
85
|
+
* This is much cheaper than the contiguous-factor search used for
|
|
86
|
+
* product-style substitution because the denominator already provides
|
|
87
|
+
* the natural candidate for f(x).
|
|
88
|
+
*
|
|
89
|
+
* Examples:
|
|
90
|
+
*
|
|
91
|
+
* (2*x)/(1+x^2) -> f(x) = 1+x^2, constant = 1
|
|
92
|
+
* cos(x)/sin(x) -> f(x) = sin(x), constant = 1
|
|
93
|
+
* 3*cos(x)/sin(x) -> f(x) = sin(x), constant = 3
|
|
94
|
+
*
|
|
95
|
+
* Non-example:
|
|
96
|
+
*
|
|
97
|
+
* f(x)/f'(x)
|
|
98
|
+
*
|
|
99
|
+
* That is not the logarithmic rule and should not be handled here.
|
|
100
|
+
*
|
|
101
|
+
* @param fx expression to analyze
|
|
102
|
+
* @param x integration variable
|
|
103
|
+
* @returns logarithmic substitution match information or undefined
|
|
104
|
+
*/
|
|
105
|
+
export declare function tryIntegrateByLogSubstitution(fx: Expression, x: string): {
|
|
106
|
+
fx: Expression;
|
|
107
|
+
constant: Expression;
|
|
108
|
+
} | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* Attempts to detect a generalized power-quotient substitution structure:
|
|
111
|
+
*
|
|
112
|
+
* integrand = c * f'(x) / f(x)^n
|
|
113
|
+
*
|
|
114
|
+
* which integrates to
|
|
115
|
+
*
|
|
116
|
+
* c * f(x)^(1-n) / (1-n) for n ≠ 1
|
|
117
|
+
*
|
|
118
|
+
* The n=1 case is the logarithmic substitution handled by
|
|
119
|
+
* tryIntegrateByLogSubstitution. This function handles n ≠ 1,
|
|
120
|
+
* including fractional powers like n=1/2 (square root denominators).
|
|
121
|
+
*
|
|
122
|
+
* This catches integrands like:
|
|
123
|
+
*
|
|
124
|
+
* x / sqrt(1-x²) → f = 1-x², f' = -2x, n = 1/2
|
|
125
|
+
* x / (1+x²)² → f = 1+x², f' = 2x, n = 2
|
|
126
|
+
*
|
|
127
|
+
* @param fx expression to analyze
|
|
128
|
+
* @param x integration variable
|
|
129
|
+
* @returns match with fx (the inner function), constant, and power (the denominator exponent n)
|
|
130
|
+
*/
|
|
131
|
+
export declare function tryIntegrateByPowerSubstitution(fx: Expression, x: string): {
|
|
132
|
+
fx: Expression;
|
|
133
|
+
constant: Expression;
|
|
134
|
+
power: Expression;
|
|
135
|
+
} | undefined;
|