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,652 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.integrate = integrate;
|
|
4
|
+
const partfrac_1 = require("../../algebra/partfrac");
|
|
5
|
+
const simplify_1 = require("../../algebra/simplify/simplify");
|
|
6
|
+
const trigrewrite_1 = require("../../algebra/simplify/trigrewrite");
|
|
7
|
+
const Expression_1 = require("../../core/classes/expression/Expression");
|
|
8
|
+
const products_1 = require("../../core/classes/expression/products");
|
|
9
|
+
const shortcuts_1 = require("../../core/classes/expression/shortcuts");
|
|
10
|
+
const utils_1 = require("../../core/classes/expression/utils");
|
|
11
|
+
const constants_1 = require("../../core/classes/parser/constants");
|
|
12
|
+
const Polynomial_1 = require("../../core/classes/polynomial/Polynomial");
|
|
13
|
+
const utils_2 = require("../../core/classes/polynomial/utils");
|
|
14
|
+
const Pattern_1 = require("../../core/converters/Pattern");
|
|
15
|
+
const subst_1 = require("../../core/functions/subst");
|
|
16
|
+
const math_1 = require("../../math/math");
|
|
17
|
+
const trig_1 = require("../../math/trig");
|
|
18
|
+
const byParts_1 = require("./byParts");
|
|
19
|
+
const bySubstitution_1 = require("./bySubstitution");
|
|
20
|
+
const integrationTable_1 = require("./integrationTable");
|
|
21
|
+
const utils_3 = require("./utils");
|
|
22
|
+
const MAX_DEPTH = 10;
|
|
23
|
+
/**
|
|
24
|
+
* Finds a symbolic indefinite integral with respect to a plain variable.
|
|
25
|
+
*
|
|
26
|
+
* Constants and linear sums are separated first. The remaining integrand is
|
|
27
|
+
* tried against the integral table and bounded strategies for radical and
|
|
28
|
+
* algebraic substitution, quadratic radicals, integration by parts,
|
|
29
|
+
* derivative-pattern substitution, rational decomposition, and the
|
|
30
|
+
* Weierstrass tangent half-angle substitution.
|
|
31
|
+
*
|
|
32
|
+
* @remarks
|
|
33
|
+
* This function returns an antiderivative only; it does not append a constant
|
|
34
|
+
* of integration and it does not accept definite-integration bounds. An
|
|
35
|
+
* unsupported integral, or a strategy that reaches the recursion guard, is
|
|
36
|
+
* represented as an unevaluated `integrate(expr, dx)` Expression rather than an
|
|
37
|
+
* exception.
|
|
38
|
+
*
|
|
39
|
+
* Branch-sensitive transformations are limited to patterns recognized by the
|
|
40
|
+
* implementation. The result should not be read as a global statement about
|
|
41
|
+
* every real or complex branch outside those supported patterns.
|
|
42
|
+
*
|
|
43
|
+
* `depth` is the internal strategy-recursion counter and should normally be
|
|
44
|
+
* omitted by direct callers.
|
|
45
|
+
*
|
|
46
|
+
* @param expr - Integrand to normalize and integrate.
|
|
47
|
+
* @param dx - Plain integration variable.
|
|
48
|
+
* @param depth - Internal recursion depth. Defaults to zero.
|
|
49
|
+
* @returns A symbolic antiderivative without an integration constant, or an
|
|
50
|
+
* unevaluated `integrate(...)` Expression.
|
|
51
|
+
* @throws {@link core!UnexpectedInputError} If `dx` is not a plain variable.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* integrate('2*x*cos(x^2)', 'x').text();
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
function integrate(expr, dx, depth = 0) {
|
|
59
|
+
expr = Expression_1.Expression.create(expr);
|
|
60
|
+
dx = (0, utils_1.assertPlainVariableAndGetString)(Expression_1.Expression.create(dx));
|
|
61
|
+
const fn = Expression_1.Expression.create(expr);
|
|
62
|
+
let retval;
|
|
63
|
+
if (depth++ > MAX_DEPTH) {
|
|
64
|
+
retval = Expression_1.Expression.toFunction(constants_1.INTEGRATE, [fn, dx]);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
let constants;
|
|
68
|
+
({ constants, expression: expr } = (0, products_1.constantsFreeProduct)(expr, dx));
|
|
69
|
+
if (!expr.hasVariable(dx)) {
|
|
70
|
+
retval = expr.times(dx);
|
|
71
|
+
}
|
|
72
|
+
else if (expr.isSum() && expr.isLinear()) {
|
|
73
|
+
let sum = (0, shortcuts_1.zero)();
|
|
74
|
+
expr.each((e) => {
|
|
75
|
+
sum = sum.plus(integrate(e, dx, depth));
|
|
76
|
+
});
|
|
77
|
+
retval = sum;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
retval = integrationTable_1.tableOfIntegrals.lookup(new Pattern_1.Pattern(expr, [dx]), depth);
|
|
81
|
+
}
|
|
82
|
+
if (!retval) {
|
|
83
|
+
retval = tryIntegrateLogPower(expr, dx, depth);
|
|
84
|
+
}
|
|
85
|
+
if (!retval) {
|
|
86
|
+
retval = tryIntegrateByRadicalSubstitutionFastPath(expr, dx, depth);
|
|
87
|
+
}
|
|
88
|
+
if (!retval) {
|
|
89
|
+
retval = tryIntegrateSqrtQuadratic(expr, dx);
|
|
90
|
+
}
|
|
91
|
+
if (!retval && expr.isProduct()) {
|
|
92
|
+
const wrapped = (0, bySubstitution_1.tryIntegrateByWrappedFactorSubstitution)(expr, expr.elementsArray(), dx);
|
|
93
|
+
if (wrapped) {
|
|
94
|
+
retval = wrapped;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (!retval && expr.isProduct()) {
|
|
98
|
+
// If any factor of the product is a sum, expand and retry.
|
|
99
|
+
// This distributes e.g. x*sec(u)^2*(1+tan(u)^2) into
|
|
100
|
+
// x*sec(u)^2 + x*sec(u)^2*tan(u)^2, enabling linearity.
|
|
101
|
+
let hasSumFactor = false;
|
|
102
|
+
for (const factor of expr.elementsArray()) {
|
|
103
|
+
if (factor.isSum() && (0, utils_3.hasTranscendental)(factor, dx)) {
|
|
104
|
+
hasSumFactor = true;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (hasSumFactor) {
|
|
109
|
+
const expanded = expr.expand();
|
|
110
|
+
if (expanded.isSum() && expanded.isLinear()) {
|
|
111
|
+
let expandedResult = (0, shortcuts_1.zero)();
|
|
112
|
+
let allResolved = true;
|
|
113
|
+
expanded.each((term) => {
|
|
114
|
+
const termResult = integrate(term, dx, depth);
|
|
115
|
+
if (termResult.isFunction(constants_1.INTEGRATE)) {
|
|
116
|
+
allResolved = false;
|
|
117
|
+
}
|
|
118
|
+
expandedResult = expandedResult.plus(termResult);
|
|
119
|
+
});
|
|
120
|
+
if (allResolved) {
|
|
121
|
+
retval = expandedResult;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!retval) {
|
|
127
|
+
const result = (0, byParts_1.tryIntegrationByParts)(expr, dx, integrate, depth);
|
|
128
|
+
if (result) {
|
|
129
|
+
retval = result;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (!retval) {
|
|
133
|
+
const logResult = (0, bySubstitution_1.tryIntegrateByLogSubstitution)(expr, dx);
|
|
134
|
+
if (logResult) {
|
|
135
|
+
retval = (0, math_1.log)(logResult.fx).times(logResult.constant);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (!retval) {
|
|
139
|
+
const subsResult = (0, bySubstitution_1.tryIntegrateBySubstitution)(expr, dx);
|
|
140
|
+
if (subsResult) {
|
|
141
|
+
const n = subsResult.power;
|
|
142
|
+
const nPlusOne = n.plus((0, shortcuts_1.one)());
|
|
143
|
+
retval = subsResult.fx.pow(nPlusOne).div(nPlusOne).times(subsResult.constant);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (!retval) {
|
|
147
|
+
retval = tryIntegratePolynomial(expr, dx);
|
|
148
|
+
}
|
|
149
|
+
if (!retval) {
|
|
150
|
+
retval = tryIntegratePowerQuotient(expr, dx, depth);
|
|
151
|
+
}
|
|
152
|
+
if (!retval) {
|
|
153
|
+
retval = tryIntegrateRational(expr, dx, depth);
|
|
154
|
+
}
|
|
155
|
+
if (!retval) {
|
|
156
|
+
retval = tryIntegrateByWeierstrass(expr, dx, depth);
|
|
157
|
+
}
|
|
158
|
+
if (retval) {
|
|
159
|
+
retval = retval.times(constants);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return retval ?? Expression_1.Expression.toFunction(constants_1.INTEGRATE, [fn, dx]);
|
|
163
|
+
}
|
|
164
|
+
function tryIntegratePolynomial(expr, dx) {
|
|
165
|
+
if (!expr.isPolynomialLike() || (0, utils_3.hasTranscendental)(expr, dx)) {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
let polynomial;
|
|
169
|
+
try {
|
|
170
|
+
polynomial = new Polynomial_1.Polynomial(expr, [dx]);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
const coeffs = polynomial.toArray(false, dx);
|
|
176
|
+
const x = Expression_1.Expression.create(dx);
|
|
177
|
+
let retval = (0, shortcuts_1.zero)();
|
|
178
|
+
for (let i = 0; i < coeffs.length; i++) {
|
|
179
|
+
const coeff = coeffs[i] ?? (0, shortcuts_1.zero)();
|
|
180
|
+
if (!coeff.isZero()) {
|
|
181
|
+
const power = i + 1;
|
|
182
|
+
retval = retval.plus(coeff.times(x.pow(power)).div(power));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return retval;
|
|
186
|
+
}
|
|
187
|
+
function tryIntegrateLogPower(expr, dx, depth) {
|
|
188
|
+
if (!expr.isFunction(constants_1.LOG)) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
const power = expr.getPower();
|
|
192
|
+
if (!power.isInteger() || !power.gt((0, shortcuts_1.one)())) {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
const args = expr.getArguments();
|
|
196
|
+
if (args.length !== 1) {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
let argumentPolynomial;
|
|
200
|
+
try {
|
|
201
|
+
argumentPolynomial = new Polynomial_1.Polynomial(args[0], [dx]);
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
if (argumentPolynomial.deg() !== 1) {
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
const coeffs = argumentPolynomial.toArray(false, dx);
|
|
210
|
+
const linearCoefficient = coeffs[1] ?? (0, shortcuts_1.zero)();
|
|
211
|
+
if (linearCoefficient.isZero()) {
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
const lowerPower = expr.getBase().pow(power.minus((0, shortcuts_1.one)()));
|
|
215
|
+
const lowerIntegral = integrate(lowerPower, dx, depth);
|
|
216
|
+
if (lowerIntegral.isFunction(constants_1.INTEGRATE)) {
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
const leadingTerm = args[0].div(linearCoefficient).times(expr);
|
|
220
|
+
return leadingTerm.minus(power.times(lowerIntegral));
|
|
221
|
+
}
|
|
222
|
+
function isRationalFunctionInVariable(expr, variable) {
|
|
223
|
+
try {
|
|
224
|
+
new Polynomial_1.Polynomial(expr.getNumerator(), [variable]);
|
|
225
|
+
new Polynomial_1.Polynomial(expr.getDenominator(), [variable]);
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function tryIntegrateByRadicalSubstitutionFastPath(expr, dx, depth) {
|
|
233
|
+
const newVariable = (0, subst_1.getU)(expr);
|
|
234
|
+
const sub = (0, utils_3.radicalSubstitution)(expr, dx, newVariable);
|
|
235
|
+
if (!sub) {
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
const transformed = (0, simplify_1.simplify)(sub.integrand);
|
|
239
|
+
if (!isRationalFunctionInVariable(transformed, sub.newVariable)) {
|
|
240
|
+
return undefined;
|
|
241
|
+
}
|
|
242
|
+
const inner = tryIntegrateRational(transformed, sub.newVariable, depth);
|
|
243
|
+
if (!inner || inner.isFunction(constants_1.INTEGRATE)) {
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
return (0, simplify_1.simplify)((0, subst_1.subst)(inner, Expression_1.Expression.create(sub.newVariable), sub.backSub));
|
|
247
|
+
}
|
|
248
|
+
function tryIntegrateSqrtQuadratic(expr, dx) {
|
|
249
|
+
const power = expr.getPower();
|
|
250
|
+
if (!power.eq((0, shortcuts_1.half)())) {
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
const base = expr.getBase();
|
|
254
|
+
if ((0, utils_3.hasTranscendental)(base, dx)) {
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
let p;
|
|
258
|
+
try {
|
|
259
|
+
p = new Polynomial_1.Polynomial(base, [dx]);
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
if (p.deg() !== 2) {
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
const coeffs = p.toArray(false, dx);
|
|
268
|
+
const c = coeffs[0] ?? (0, shortcuts_1.zero)();
|
|
269
|
+
const b = coeffs[1] ?? (0, shortcuts_1.zero)();
|
|
270
|
+
const a = coeffs[2] ?? (0, shortcuts_1.zero)();
|
|
271
|
+
if (a.isZero()) {
|
|
272
|
+
return undefined;
|
|
273
|
+
}
|
|
274
|
+
const x = Expression_1.Expression.create(dx);
|
|
275
|
+
const u = x.plus(b.div((0, shortcuts_1.two)().times(a)));
|
|
276
|
+
const k = c.minus(b.pow((0, shortcuts_1.two)()).div((0, shortcuts_1.four)().times(a)));
|
|
277
|
+
const sqrtQ = expr;
|
|
278
|
+
const leadingTerm = (0, shortcuts_1.half)().times(u).times(sqrtQ);
|
|
279
|
+
if (k.isZero()) {
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
if (a.gt((0, shortcuts_1.zero)())) {
|
|
283
|
+
const sqrtA = a.pow((0, shortcuts_1.half)());
|
|
284
|
+
if (k.gt((0, shortcuts_1.zero)())) {
|
|
285
|
+
const sqrtK = k.pow((0, shortcuts_1.half)());
|
|
286
|
+
const arg = sqrtA.times(u).div(sqrtK);
|
|
287
|
+
return leadingTerm.plus(k.div((0, shortcuts_1.two)().times(sqrtA)).times(Expression_1.Expression.toFunction(constants_1.ASINH, [arg])));
|
|
288
|
+
}
|
|
289
|
+
if (k.lt((0, shortcuts_1.zero)())) {
|
|
290
|
+
const arg = sqrtA.times(u).plus(sqrtQ);
|
|
291
|
+
return leadingTerm.plus(k.div((0, shortcuts_1.two)().times(sqrtA)).times((0, math_1.log)(arg)));
|
|
292
|
+
}
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
if (a.lt((0, shortcuts_1.zero)()) && k.gt((0, shortcuts_1.zero)())) {
|
|
296
|
+
const sqrtNegA = a.times('-1').pow((0, shortcuts_1.half)());
|
|
297
|
+
const sqrtK = k.pow((0, shortcuts_1.half)());
|
|
298
|
+
const arg = sqrtNegA.times(u).div(sqrtK);
|
|
299
|
+
return leadingTerm.plus(k.div((0, shortcuts_1.two)().times(sqrtNegA)).times(Expression_1.Expression.toFunction(constants_1.ASIN, [arg])));
|
|
300
|
+
}
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
303
|
+
function tryIntegrateRational(expr, dx, depth) {
|
|
304
|
+
const num = expr.getNumerator();
|
|
305
|
+
const den = expr.getDenominator();
|
|
306
|
+
if (den.isOne() || !den.hasVariable(dx)) {
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
if ((0, utils_3.hasTranscendental)(num, dx) || (0, utils_3.hasTranscendental)(den, dx)) {
|
|
310
|
+
return undefined;
|
|
311
|
+
}
|
|
312
|
+
let pNum;
|
|
313
|
+
let pDen;
|
|
314
|
+
try {
|
|
315
|
+
pNum = new Polynomial_1.Polynomial(num, [dx]);
|
|
316
|
+
pDen = new Polynomial_1.Polynomial(den, [dx]);
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
321
|
+
const degNum = pNum.deg();
|
|
322
|
+
const degDen = pDen.deg();
|
|
323
|
+
if (degDen < 2) {
|
|
324
|
+
return undefined;
|
|
325
|
+
}
|
|
326
|
+
let result = (0, shortcuts_1.zero)();
|
|
327
|
+
let remainder = num;
|
|
328
|
+
if (degNum >= degDen) {
|
|
329
|
+
try {
|
|
330
|
+
const [quotient, rem] = (0, utils_2.divide)(num, den, undefined, [dx]);
|
|
331
|
+
const polyIntegral = integrate(quotient, dx, depth);
|
|
332
|
+
if (polyIntegral.isFunction(constants_1.INTEGRATE)) {
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
result = result.plus(polyIntegral);
|
|
336
|
+
remainder = rem;
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
return undefined;
|
|
340
|
+
}
|
|
341
|
+
if (Expression_1.Expression.create(remainder).isZero()) {
|
|
342
|
+
return result;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
const properFraction = Expression_1.Expression.create(remainder).div(den);
|
|
346
|
+
if (degNum >= degDen) {
|
|
347
|
+
const directIntegral = integrate(properFraction, dx, depth);
|
|
348
|
+
if (!directIntegral.isFunction(constants_1.INTEGRATE)) {
|
|
349
|
+
result = result.plus(directIntegral);
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const quadraticIntegral = tryIntegrateLinearOverQuadratic(properFraction, dx);
|
|
354
|
+
if (quadraticIntegral) {
|
|
355
|
+
return result.plus(quadraticIntegral);
|
|
356
|
+
}
|
|
357
|
+
let decomposed;
|
|
358
|
+
try {
|
|
359
|
+
decomposed = (0, partfrac_1.partfrac)(properFraction, dx);
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
return undefined;
|
|
363
|
+
}
|
|
364
|
+
if (decomposed.text() === properFraction.text()) {
|
|
365
|
+
return undefined;
|
|
366
|
+
}
|
|
367
|
+
const decomposedIntegral = integrate(decomposed, dx, depth);
|
|
368
|
+
if (decomposedIntegral.isFunction(constants_1.INTEGRATE)) {
|
|
369
|
+
return undefined;
|
|
370
|
+
}
|
|
371
|
+
return result.plus(decomposedIntegral);
|
|
372
|
+
}
|
|
373
|
+
function tryIntegrateLinearOverQuadratic(expr, dx) {
|
|
374
|
+
const num = expr.getNumerator();
|
|
375
|
+
const den = expr.getDenominator();
|
|
376
|
+
if (den.isOne() || !den.hasVariable(dx)) {
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
if ((0, utils_3.hasTranscendental)(num, dx) || (0, utils_3.hasTranscendental)(den, dx)) {
|
|
380
|
+
return undefined;
|
|
381
|
+
}
|
|
382
|
+
let nCoeffs;
|
|
383
|
+
let dCoeffs;
|
|
384
|
+
try {
|
|
385
|
+
const nc = num.coeffs(dx);
|
|
386
|
+
const dc = den.coeffs(dx);
|
|
387
|
+
if (dc.max() !== 2 || nc.max() > 1) {
|
|
388
|
+
return undefined;
|
|
389
|
+
}
|
|
390
|
+
nCoeffs = nc.toArray();
|
|
391
|
+
dCoeffs = dc.toArray();
|
|
392
|
+
}
|
|
393
|
+
catch {
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
const a = dCoeffs[2] ?? (0, shortcuts_1.zero)();
|
|
397
|
+
const b = dCoeffs[1] ?? (0, shortcuts_1.zero)();
|
|
398
|
+
const c = dCoeffs[0] ?? (0, shortcuts_1.zero)();
|
|
399
|
+
const m = nCoeffs[1] ?? (0, shortcuts_1.zero)();
|
|
400
|
+
const n = nCoeffs[0] ?? (0, shortcuts_1.zero)();
|
|
401
|
+
if (a.isZero()) {
|
|
402
|
+
return undefined;
|
|
403
|
+
}
|
|
404
|
+
const x = Expression_1.Expression.create(dx);
|
|
405
|
+
const A = m.div((0, shortcuts_1.two)().times(a));
|
|
406
|
+
const B = n.minus(A.times(b));
|
|
407
|
+
let result = (0, shortcuts_1.zero)();
|
|
408
|
+
if (!A.isZero()) {
|
|
409
|
+
result = result.plus(A.times((0, math_1.log)(den)));
|
|
410
|
+
}
|
|
411
|
+
if (B.isZero()) {
|
|
412
|
+
return result;
|
|
413
|
+
}
|
|
414
|
+
const twoAxPlusB = (0, shortcuts_1.two)().times(a).times(x).plus(b);
|
|
415
|
+
const delta = (0, shortcuts_1.four)().times(a).times(c).minus(b.pow('2'));
|
|
416
|
+
let reciprocalIntegral;
|
|
417
|
+
if (delta.isZero()) {
|
|
418
|
+
reciprocalIntegral = (0, shortcuts_1.two)().times('-1').div(twoAxPlusB);
|
|
419
|
+
}
|
|
420
|
+
else if (delta.gt((0, shortcuts_1.zero)())) {
|
|
421
|
+
const sqrtDelta = delta.pow((0, shortcuts_1.half)());
|
|
422
|
+
const arg = twoAxPlusB.div(sqrtDelta);
|
|
423
|
+
reciprocalIntegral = (0, shortcuts_1.two)()
|
|
424
|
+
.div(sqrtDelta)
|
|
425
|
+
.times(Expression_1.Expression.toFunction(constants_1.ATAN, [arg]));
|
|
426
|
+
}
|
|
427
|
+
else if (delta.lt((0, shortcuts_1.zero)())) {
|
|
428
|
+
const sqrtNegDelta = delta.times('-1').pow((0, shortcuts_1.half)());
|
|
429
|
+
const ratio = twoAxPlusB.minus(sqrtNegDelta).div(twoAxPlusB.plus(sqrtNegDelta));
|
|
430
|
+
reciprocalIntegral = (0, math_1.log)(ratio).div(sqrtNegDelta);
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
return undefined;
|
|
434
|
+
}
|
|
435
|
+
return result.plus(B.times(reciprocalIntegral));
|
|
436
|
+
}
|
|
437
|
+
function tryIntegratePowerQuotient(expr, dx, depth) {
|
|
438
|
+
const powResult = (0, bySubstitution_1.tryIntegrateByPowerSubstitution)(expr, dx);
|
|
439
|
+
if (powResult) {
|
|
440
|
+
const n = powResult.power;
|
|
441
|
+
const oneMinusN = (0, shortcuts_1.one)().plus(n.times((0, shortcuts_1.minusOne)()));
|
|
442
|
+
return powResult.fx.pow(oneMinusN).div(oneMinusN).times(powResult.constant);
|
|
443
|
+
}
|
|
444
|
+
const num = expr.getNumerator();
|
|
445
|
+
const den = expr.getDenominator();
|
|
446
|
+
if (den.isOne() || !den.hasVariable(dx)) {
|
|
447
|
+
return undefined;
|
|
448
|
+
}
|
|
449
|
+
const denBase = den.getBase();
|
|
450
|
+
const denPower = den.getPower();
|
|
451
|
+
if (denPower.isOne()) {
|
|
452
|
+
return undefined;
|
|
453
|
+
}
|
|
454
|
+
if ((0, utils_3.hasTranscendental)(num, dx) || (0, utils_3.hasTranscendental)(denBase, dx)) {
|
|
455
|
+
return undefined;
|
|
456
|
+
}
|
|
457
|
+
let pNum;
|
|
458
|
+
try {
|
|
459
|
+
pNum = new Polynomial_1.Polynomial(num, [dx]);
|
|
460
|
+
new Polynomial_1.Polynomial(denBase, [dx]);
|
|
461
|
+
}
|
|
462
|
+
catch {
|
|
463
|
+
return undefined;
|
|
464
|
+
}
|
|
465
|
+
if (pNum.deg() < 1) {
|
|
466
|
+
return undefined;
|
|
467
|
+
}
|
|
468
|
+
let quotient;
|
|
469
|
+
let remainder;
|
|
470
|
+
try {
|
|
471
|
+
[quotient, remainder] = (0, utils_2.divide)(num, denBase, undefined, [dx]);
|
|
472
|
+
}
|
|
473
|
+
catch {
|
|
474
|
+
return undefined;
|
|
475
|
+
}
|
|
476
|
+
if (Expression_1.Expression.create(quotient).isZero()) {
|
|
477
|
+
return undefined;
|
|
478
|
+
}
|
|
479
|
+
const term1 = Expression_1.Expression.create(quotient).times(denBase.pow((0, shortcuts_1.one)().plus(denPower.times((0, shortcuts_1.minusOne)()))));
|
|
480
|
+
const term2Num = Expression_1.Expression.create(remainder);
|
|
481
|
+
const term2 = term2Num.isZero() ? (0, shortcuts_1.zero)() : term2Num.div(den);
|
|
482
|
+
const integral1 = integrate(term1, dx, depth);
|
|
483
|
+
if (integral1.isFunction(constants_1.INTEGRATE)) {
|
|
484
|
+
return undefined;
|
|
485
|
+
}
|
|
486
|
+
let result = integral1;
|
|
487
|
+
if (!term2Num.isZero()) {
|
|
488
|
+
const integral2 = integrate(term2, dx, depth);
|
|
489
|
+
if (integral2.isFunction(constants_1.INTEGRATE)) {
|
|
490
|
+
return undefined;
|
|
491
|
+
}
|
|
492
|
+
result = result.plus(integral2);
|
|
493
|
+
}
|
|
494
|
+
return result;
|
|
495
|
+
}
|
|
496
|
+
// ============================================================================
|
|
497
|
+
// Weierstrass substitution (tangent half-angle substitution)
|
|
498
|
+
//
|
|
499
|
+
// For integrands that are rational functions of sin(x) and cos(x),
|
|
500
|
+
// the substitution t = tan(x/2) converts to a rational function of t:
|
|
501
|
+
//
|
|
502
|
+
// sin(x) = 2t/(1+t²)
|
|
503
|
+
// cos(x) = (1-t²)/(1+t²)
|
|
504
|
+
// dx = 2/(1+t²) dt
|
|
505
|
+
//
|
|
506
|
+
// The resulting rational function can be integrated via partial fractions.
|
|
507
|
+
//
|
|
508
|
+
// More generally, for trig functions with argument (a*x+b):
|
|
509
|
+
// t = tan((a*x+b)/2)
|
|
510
|
+
// sin(a*x+b) = 2t/(1+t²)
|
|
511
|
+
// cos(a*x+b) = (1-t²)/(1+t²)
|
|
512
|
+
// dx = 2/(a*(1+t²)) dt
|
|
513
|
+
// ============================================================================
|
|
514
|
+
/**
|
|
515
|
+
* Determines whether an expression is a rational function of sin and cos
|
|
516
|
+
* with a common linear argument in the integration variable.
|
|
517
|
+
*
|
|
518
|
+
* Returns the common trig argument if so, or undefined if not.
|
|
519
|
+
*
|
|
520
|
+
* The expression must have all occurrences of the integration variable
|
|
521
|
+
* wrapped inside sin(x) or cos(x) calls (after rewriting tan/sec/csc/cot),
|
|
522
|
+
* and all such calls must share the same argument. Reuse trig rewrite from simplify.
|
|
523
|
+
*/
|
|
524
|
+
function getTrigArgIfRationalInTrig(expr, dx) {
|
|
525
|
+
let commonArg;
|
|
526
|
+
let valid = true;
|
|
527
|
+
function walk(e) {
|
|
528
|
+
if (!valid) {
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
if (e.isFunction(constants_1.SIN) || e.isFunction(constants_1.COS)) {
|
|
532
|
+
const args = e.getArguments();
|
|
533
|
+
if (args.length === 1 && args[0].hasVariable(dx)) {
|
|
534
|
+
if (commonArg === undefined) {
|
|
535
|
+
commonArg = args[0];
|
|
536
|
+
}
|
|
537
|
+
else if (!commonArg.eq(args[0])) {
|
|
538
|
+
valid = false;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
// Don't descend into the trig argument — it's been accounted for
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
// If we encounter a bare variable outside of sin/cos, this is not
|
|
545
|
+
// purely rational in trig
|
|
546
|
+
if (e.isVAR() && e.hasVariable(dx)) {
|
|
547
|
+
valid = false;
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
// Descend into sums, products
|
|
551
|
+
if (e.isSum() || e.isProduct()) {
|
|
552
|
+
for (const child of e.elementsArray()) {
|
|
553
|
+
walk(child);
|
|
554
|
+
}
|
|
555
|
+
// Also check the power. It should not contain the variable
|
|
556
|
+
const p = e.getPower();
|
|
557
|
+
if (p.hasVariable(dx)) {
|
|
558
|
+
valid = false;
|
|
559
|
+
}
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
// For any other function containing the variable (e.g. log, exp),
|
|
563
|
+
// this is not rational in trig
|
|
564
|
+
if (e.isFunction() && e.hasVariable(dx)) {
|
|
565
|
+
valid = false;
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
if (e.isEXP() && e.hasVariable(dx)) {
|
|
569
|
+
valid = false;
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
walk(expr);
|
|
574
|
+
if (valid && commonArg !== undefined) {
|
|
575
|
+
return commonArg;
|
|
576
|
+
}
|
|
577
|
+
return undefined;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Extracts the linear coefficient from a trig argument of the form a*x+b.
|
|
581
|
+
* Returns the coefficient `a` such that d/dx[a*x+b] = a.
|
|
582
|
+
* Returns undefined if the argument is not linear in dx.
|
|
583
|
+
*/
|
|
584
|
+
function getLinearCoefficient(arg, dx) {
|
|
585
|
+
try {
|
|
586
|
+
const p = new Polynomial_1.Polynomial(arg, [dx]);
|
|
587
|
+
if (p.deg() !== 1) {
|
|
588
|
+
return undefined;
|
|
589
|
+
}
|
|
590
|
+
const coeffs = p.toArray(false, dx);
|
|
591
|
+
return coeffs[1] ?? undefined;
|
|
592
|
+
}
|
|
593
|
+
catch {
|
|
594
|
+
return undefined;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Attempts to integrate a rational function of trig via Weierstrass substitution.
|
|
599
|
+
*
|
|
600
|
+
* The substitution t = tan(arg/2) transforms the integrand into a rational
|
|
601
|
+
* function of t, which can then be integrated using the existing rational
|
|
602
|
+
* function machinery (partial fractions, etc.).
|
|
603
|
+
*/
|
|
604
|
+
function tryIntegrateByWeierstrass(expr, dx, depth) {
|
|
605
|
+
// Step 1: Rewrite tan/sec/csc/cot to sin/cos
|
|
606
|
+
let working = expr;
|
|
607
|
+
if ((0, trigrewrite_1.hasDerivedTrig)(working)) {
|
|
608
|
+
working = (0, trigrewrite_1.rewrite)(working);
|
|
609
|
+
}
|
|
610
|
+
// Step 2: Check if the result is rational in sin/cos with a common argument
|
|
611
|
+
const trigArg = getTrigArgIfRationalInTrig(working, dx);
|
|
612
|
+
if (!trigArg) {
|
|
613
|
+
return undefined;
|
|
614
|
+
}
|
|
615
|
+
// Step 3: Extract the linear coefficient of the argument
|
|
616
|
+
const a = getLinearCoefficient(trigArg, dx);
|
|
617
|
+
if (!a) {
|
|
618
|
+
return undefined;
|
|
619
|
+
}
|
|
620
|
+
// Step 4: Pick a fresh variable for the substitution
|
|
621
|
+
const tName = (0, subst_1.getU)(expr);
|
|
622
|
+
const t = Expression_1.Expression.create(tName);
|
|
623
|
+
const tSq = t.pow((0, shortcuts_1.two)());
|
|
624
|
+
const onePlusTSq = (0, shortcuts_1.one)().plus(tSq);
|
|
625
|
+
// Step 5: Perform the substitution
|
|
626
|
+
// sin(x) → 2t/(1+t²)
|
|
627
|
+
// cos(x) → (1-t²)/(1+t²)
|
|
628
|
+
const sinReplacement = (0, shortcuts_1.two)().times(t).div(onePlusTSq);
|
|
629
|
+
const cosReplacement = (0, shortcuts_1.one)().minus(tSq).div(onePlusTSq);
|
|
630
|
+
let substituted = (0, subst_1.subst)(working, (0, trig_1.sin)(trigArg), sinReplacement);
|
|
631
|
+
substituted = (0, subst_1.subst)(substituted, (0, trig_1.cos)(trigArg), cosReplacement);
|
|
632
|
+
// Multiply by the Jacobian: dx = 2/(a*(1+t²)) dt
|
|
633
|
+
const jacobian = (0, shortcuts_1.two)().div(a.times(onePlusTSq));
|
|
634
|
+
substituted = substituted.times(jacobian);
|
|
635
|
+
// Step 6: Simplify — should collapse to a rational function of t
|
|
636
|
+
substituted = (0, simplify_1.simplify)(substituted);
|
|
637
|
+
// Verify it's actually rational in t (no leftover trig or transcendentals)
|
|
638
|
+
if (substituted.hasVariable(dx)) {
|
|
639
|
+
return undefined;
|
|
640
|
+
}
|
|
641
|
+
if (!isRationalFunctionInVariable(substituted, tName)) {
|
|
642
|
+
return undefined;
|
|
643
|
+
}
|
|
644
|
+
// Step 7: Integrate the rational function
|
|
645
|
+
const rational = integrate(substituted, tName, depth);
|
|
646
|
+
if (rational.isFunction(constants_1.INTEGRATE)) {
|
|
647
|
+
return undefined;
|
|
648
|
+
}
|
|
649
|
+
// Step 8: Back-substitute t → tan(arg/2)
|
|
650
|
+
const backSub = (0, trig_1.tan)(trigArg.div((0, shortcuts_1.two)()));
|
|
651
|
+
return (0, simplify_1.simplify)((0, subst_1.subst)(rational, t, backSub));
|
|
652
|
+
}
|