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,37 @@
|
|
|
1
|
+
import Decimal from 'decimal.js';
|
|
2
|
+
export type DecimalFn = (x: Decimal) => Decimal;
|
|
3
|
+
export interface DefIntOptions {
|
|
4
|
+
/** Absolute tolerance target. Default: 1e-(Decimal.precision-5) */
|
|
5
|
+
tolAbs?: Decimal.Value;
|
|
6
|
+
/** Relative tolerance target (scaled to |I|). Default: 1e-(Decimal.precision-5) */
|
|
7
|
+
tolRel?: Decimal.Value;
|
|
8
|
+
/** Max adaptive subdivision depth. Default: 40 */
|
|
9
|
+
maxDepth?: number;
|
|
10
|
+
/** Hard cap on function evaluations. Default: 300_000 */
|
|
11
|
+
maxEvals?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Singular/discontinuous handling:
|
|
14
|
+
* - "auto": try to detect non-finite/NaN spikes and bisect around them (best-effort)
|
|
15
|
+
* - "strict": throw on non-finite/NaN
|
|
16
|
+
* - "ignore": propagate NaN (returns NaN)
|
|
17
|
+
*/
|
|
18
|
+
singular?: 'auto' | 'strict' | 'ignore';
|
|
19
|
+
/**
|
|
20
|
+
* Optional known breakpoints inside (a,b) where f may change behavior (abs, piecewise, etc).
|
|
21
|
+
* Integration runs separately on each segment for robustness.
|
|
22
|
+
*/
|
|
23
|
+
breakpoints?: Decimal.Value[];
|
|
24
|
+
/**
|
|
25
|
+
* For infinite bounds: set to true to support +/-Infinity with variable substitutions.
|
|
26
|
+
* Default false (throws if infinite bounds are used).
|
|
27
|
+
*/
|
|
28
|
+
allowInfinite?: boolean;
|
|
29
|
+
/** If true, returns 0 immediately when a==b (default true). */
|
|
30
|
+
fastZeroWidth?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Definite integral using adaptive Simpson + decimal.js.
|
|
34
|
+
* - Smooth functions: typically very fast.
|
|
35
|
+
* - Nasty cases: supports breakpoints, best-effort singular handling, optional infinite bounds.
|
|
36
|
+
*/
|
|
37
|
+
export declare function definiteIntegrate(f: DecimalFn, a: Decimal.Value, b: Decimal.Value, options?: DefIntOptions): Decimal;
|
|
@@ -0,0 +1,320 @@
|
|
|
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.definiteIntegrate = definiteIntegrate;
|
|
7
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
8
|
+
const TWO = new decimal_js_1.default(2);
|
|
9
|
+
const FOUR = new decimal_js_1.default(4);
|
|
10
|
+
const SIX = new decimal_js_1.default(6);
|
|
11
|
+
const FIFTEEN = new decimal_js_1.default(15);
|
|
12
|
+
const ONE = new decimal_js_1.default(1);
|
|
13
|
+
const ZERO = new decimal_js_1.default(0);
|
|
14
|
+
const MAX_SINGULAR_REFINEMENT_ATTEMPTS = 8;
|
|
15
|
+
const DEFAULT_MAX_DEPTH = 40;
|
|
16
|
+
const DEFAULT_MAX_EVALUATIONS = 300_000;
|
|
17
|
+
const DEFAULT_DECIMAL_PRECISION = 20;
|
|
18
|
+
const TOLERANCE_PRECISION_SLACK = 5;
|
|
19
|
+
const INFINITE_BOUND_PRECISION_SLACK = 2;
|
|
20
|
+
function D(v) {
|
|
21
|
+
return v instanceof decimal_js_1.default ? v : new decimal_js_1.default(v);
|
|
22
|
+
}
|
|
23
|
+
function absD(x) {
|
|
24
|
+
return x.isNeg() ? x.neg() : x;
|
|
25
|
+
}
|
|
26
|
+
function isFiniteDecimal(x) {
|
|
27
|
+
// decimal.js: finite numbers are !isNaN and !isInfinite
|
|
28
|
+
return !x.isNaN() && x.isFinite();
|
|
29
|
+
}
|
|
30
|
+
function defaultTolFromPrecision() {
|
|
31
|
+
// A decent default: about 5 digits of slack vs working precision
|
|
32
|
+
// e.g. precision 50 -> tol ~ 1e-45
|
|
33
|
+
const p = decimal_js_1.default.precision ?? DEFAULT_DECIMAL_PRECISION;
|
|
34
|
+
const e = Math.max(1, p - TOLERANCE_PRECISION_SLACK);
|
|
35
|
+
return new decimal_js_1.default(10).pow(-e);
|
|
36
|
+
}
|
|
37
|
+
function simpson(a, b, fa, fm, fb) {
|
|
38
|
+
// (b-a)/6 * (fa + 4*fm + fb)
|
|
39
|
+
return b
|
|
40
|
+
.sub(a)
|
|
41
|
+
.div(SIX)
|
|
42
|
+
.mul(fa.add(fm.mul(FOUR)).add(fb));
|
|
43
|
+
}
|
|
44
|
+
function withFiniteBounds(f, aIn, bIn, opts) {
|
|
45
|
+
let a = aIn;
|
|
46
|
+
let b = bIn;
|
|
47
|
+
if (a.eq(b)) {
|
|
48
|
+
return ZERO;
|
|
49
|
+
}
|
|
50
|
+
// reverse if needed
|
|
51
|
+
let sign = ONE;
|
|
52
|
+
if (b.lt(a)) {
|
|
53
|
+
sign = sign.neg();
|
|
54
|
+
const t = a;
|
|
55
|
+
a = b;
|
|
56
|
+
b = t;
|
|
57
|
+
}
|
|
58
|
+
let evals = 0;
|
|
59
|
+
const evalF = (x) => {
|
|
60
|
+
if (evals++ > opts.maxEvals) {
|
|
61
|
+
throw new Error(`defint: maxEvals exceeded (${opts.maxEvals}).`);
|
|
62
|
+
}
|
|
63
|
+
const y = f(x);
|
|
64
|
+
if (opts.singular === 'strict') {
|
|
65
|
+
if (!isFiniteDecimal(y)) {
|
|
66
|
+
throw new Error(`defint: non-finite f(x) at x=${x.toString()}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return y;
|
|
70
|
+
};
|
|
71
|
+
const m0 = a.add(b).div(TWO);
|
|
72
|
+
const fa = evalF(a);
|
|
73
|
+
const fm = evalF(m0);
|
|
74
|
+
const fb = evalF(b);
|
|
75
|
+
if (opts.singular === 'ignore') {
|
|
76
|
+
if (fa.isNaN() || fm.isNaN() || fb.isNaN()) {
|
|
77
|
+
return new decimal_js_1.default(NaN);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// If auto and we hit non-finite early, bisect around it (best-effort).
|
|
81
|
+
if (opts.singular === 'auto') {
|
|
82
|
+
if (!isFiniteDecimal(fa) || !isFiniteDecimal(fm) || !isFiniteDecimal(fb)) {
|
|
83
|
+
// Try to integrate by splitting once; if still bad, throw.
|
|
84
|
+
const mid = m0;
|
|
85
|
+
const left = tryAutoSplitFinite(f, a, mid, opts);
|
|
86
|
+
const right = tryAutoSplitFinite(f, mid, b, opts);
|
|
87
|
+
return left.add(right).mul(sign);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const S0 = simpson(a, b, fa, fm, fb);
|
|
91
|
+
const stack = [
|
|
92
|
+
{
|
|
93
|
+
a,
|
|
94
|
+
b,
|
|
95
|
+
m: m0,
|
|
96
|
+
fa,
|
|
97
|
+
fm,
|
|
98
|
+
fb,
|
|
99
|
+
S: S0,
|
|
100
|
+
depth: 0,
|
|
101
|
+
tolAbs: opts.tolAbs,
|
|
102
|
+
tolRel: opts.tolRel,
|
|
103
|
+
singularTries: 0,
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
let acc = ZERO;
|
|
107
|
+
while (stack.length > 0) {
|
|
108
|
+
const fr = stack[stack.length - 1];
|
|
109
|
+
stack.pop();
|
|
110
|
+
const a0 = fr.a;
|
|
111
|
+
const b0 = fr.b;
|
|
112
|
+
const m = fr.m;
|
|
113
|
+
const lm = a0.add(m).div(TWO);
|
|
114
|
+
const rm = m.add(b0).div(TWO);
|
|
115
|
+
const fLM = evalF(lm);
|
|
116
|
+
const fRM = evalF(rm);
|
|
117
|
+
if (opts.singular === 'ignore') {
|
|
118
|
+
if (fLM.isNaN() || fRM.isNaN() || fr.fa.isNaN() || fr.fm.isNaN() || fr.fb.isNaN()) {
|
|
119
|
+
return new decimal_js_1.default(NaN);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (opts.singular === 'auto') {
|
|
123
|
+
// If we encounter a non-finite value, try splitting more locally a few times.
|
|
124
|
+
if (!isFiniteDecimal(fLM) ||
|
|
125
|
+
!isFiniteDecimal(fRM) ||
|
|
126
|
+
!isFiniteDecimal(fr.fa) ||
|
|
127
|
+
!isFiniteDecimal(fr.fm) ||
|
|
128
|
+
!isFiniteDecimal(fr.fb)) {
|
|
129
|
+
if (fr.depth >= opts.maxDepth || fr.singularTries >= MAX_SINGULAR_REFINEMENT_ATTEMPTS) {
|
|
130
|
+
throw new Error(`defint: singular/non-finite encountered near [${a0.toString()}, ${b0.toString()}]`);
|
|
131
|
+
}
|
|
132
|
+
// Push children without using Simpson error test; just refine around the issue.
|
|
133
|
+
const nextDepth = fr.depth + 1;
|
|
134
|
+
const childTolAbs = fr.tolAbs.div(TWO);
|
|
135
|
+
const childTolRel = fr.tolRel.div(TWO);
|
|
136
|
+
// We need f at new midpoints; reuse what we already have when finite.
|
|
137
|
+
// For left child: [a0,m], midpoint=lm, endpoints fa and fm
|
|
138
|
+
// For right child:[m,b0], midpoint=rm, endpoints fm and fb
|
|
139
|
+
stack.push({
|
|
140
|
+
a: m,
|
|
141
|
+
b: b0,
|
|
142
|
+
m: rm,
|
|
143
|
+
fa: fr.fm,
|
|
144
|
+
fm: fRM,
|
|
145
|
+
fb: fr.fb,
|
|
146
|
+
S: simpson(m, b0, fr.fm, fRM, fr.fb),
|
|
147
|
+
depth: nextDepth,
|
|
148
|
+
tolAbs: childTolAbs,
|
|
149
|
+
tolRel: childTolRel,
|
|
150
|
+
singularTries: fr.singularTries + 1,
|
|
151
|
+
});
|
|
152
|
+
stack.push({
|
|
153
|
+
a: a0,
|
|
154
|
+
b: m,
|
|
155
|
+
m: lm,
|
|
156
|
+
fa: fr.fa,
|
|
157
|
+
fm: fLM,
|
|
158
|
+
fb: fr.fm,
|
|
159
|
+
S: simpson(a0, m, fr.fa, fLM, fr.fm),
|
|
160
|
+
depth: nextDepth,
|
|
161
|
+
tolAbs: childTolAbs,
|
|
162
|
+
tolRel: childTolRel,
|
|
163
|
+
singularTries: fr.singularTries + 1,
|
|
164
|
+
});
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const Sleft = simpson(a0, m, fr.fa, fLM, fr.fm);
|
|
169
|
+
const Sright = simpson(m, b0, fr.fm, fRM, fr.fb);
|
|
170
|
+
const S2 = Sleft.add(Sright);
|
|
171
|
+
// Error estimate and acceptance test
|
|
172
|
+
const err = absD(S2.sub(fr.S)).div(FIFTEEN);
|
|
173
|
+
// Relative scaling: accept if err <= tolAbs + tolRel*|S2|
|
|
174
|
+
const scale = fr.tolAbs.add(fr.tolRel.mul(absD(S2)));
|
|
175
|
+
if (err.lte(scale) || fr.depth >= opts.maxDepth) {
|
|
176
|
+
const improved = S2.add(S2.sub(fr.S).div(FIFTEEN)); // Richardson
|
|
177
|
+
acc = acc.add(improved);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const nextDepth = fr.depth + 1;
|
|
181
|
+
const childTolAbs = fr.tolAbs.div(TWO);
|
|
182
|
+
const childTolRel = fr.tolRel.div(TWO);
|
|
183
|
+
// push right then left
|
|
184
|
+
stack.push({
|
|
185
|
+
a: m,
|
|
186
|
+
b: b0,
|
|
187
|
+
m: rm,
|
|
188
|
+
fa: fr.fm,
|
|
189
|
+
fm: fRM,
|
|
190
|
+
fb: fr.fb,
|
|
191
|
+
S: Sright,
|
|
192
|
+
depth: nextDepth,
|
|
193
|
+
tolAbs: childTolAbs,
|
|
194
|
+
tolRel: childTolRel,
|
|
195
|
+
singularTries: fr.singularTries,
|
|
196
|
+
});
|
|
197
|
+
stack.push({
|
|
198
|
+
a: a0,
|
|
199
|
+
b: m,
|
|
200
|
+
m: lm,
|
|
201
|
+
fa: fr.fa,
|
|
202
|
+
fm: fLM,
|
|
203
|
+
fb: fr.fm,
|
|
204
|
+
S: Sleft,
|
|
205
|
+
depth: nextDepth,
|
|
206
|
+
tolAbs: childTolAbs,
|
|
207
|
+
tolRel: childTolRel,
|
|
208
|
+
singularTries: fr.singularTries,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
return acc.mul(sign);
|
|
212
|
+
}
|
|
213
|
+
function tryAutoSplitFinite(f, a, b, opts) {
|
|
214
|
+
// One extra level of protection: split into 4 chunks and integrate those that remain finite.
|
|
215
|
+
const m = a.add(b).div(TWO);
|
|
216
|
+
const q1 = a.add(m).div(TWO);
|
|
217
|
+
const q3 = m.add(b).div(TWO);
|
|
218
|
+
// Integrate each segment with slightly looser tolerances (since we subdivided already).
|
|
219
|
+
const tolAbs = opts.tolAbs.div(FOUR);
|
|
220
|
+
const tolRel = opts.tolRel.div(FOUR);
|
|
221
|
+
return withFiniteBounds(f, a, q1, { ...opts, tolAbs, tolRel })
|
|
222
|
+
.add(withFiniteBounds(f, q1, m, { ...opts, tolAbs, tolRel }))
|
|
223
|
+
.add(withFiniteBounds(f, m, q3, { ...opts, tolAbs, tolRel }))
|
|
224
|
+
.add(withFiniteBounds(f, q3, b, { ...opts, tolAbs, tolRel }));
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Definite integral using adaptive Simpson + decimal.js.
|
|
228
|
+
* - Smooth functions: typically very fast.
|
|
229
|
+
* - Nasty cases: supports breakpoints, best-effort singular handling, optional infinite bounds.
|
|
230
|
+
*/
|
|
231
|
+
function definiteIntegrate(f, a, b, options = {}) {
|
|
232
|
+
const A = D(a);
|
|
233
|
+
const B = D(b);
|
|
234
|
+
const fastZeroWidth = options.fastZeroWidth ?? true;
|
|
235
|
+
if (fastZeroWidth && A.eq(B)) {
|
|
236
|
+
return ZERO;
|
|
237
|
+
}
|
|
238
|
+
// tolerances
|
|
239
|
+
const baseTol = defaultTolFromPrecision();
|
|
240
|
+
const tolAbs = D(options.tolAbs ?? baseTol);
|
|
241
|
+
const tolRel = D(options.tolRel ?? baseTol);
|
|
242
|
+
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
243
|
+
const maxEvals = options.maxEvals ?? DEFAULT_MAX_EVALUATIONS;
|
|
244
|
+
const singular = options.singular ?? 'auto';
|
|
245
|
+
// Optional breakpoints segmentation (recommended for piecewise/abs/kinks/discontinuities)
|
|
246
|
+
const bps = (options.breakpoints ?? [])
|
|
247
|
+
.map(D)
|
|
248
|
+
.filter(x => x.gt(decimal_js_1.default.min(A, B)) && x.lt(decimal_js_1.default.max(A, B)))
|
|
249
|
+
.sort((x, y) => (x.lt(y) ? -1 : x.gt(y) ? 1 : 0));
|
|
250
|
+
const allowInfinite = options.allowInfinite ?? false;
|
|
251
|
+
const isInfA = !A.isFinite() && !A.isNaN();
|
|
252
|
+
const isInfB = !B.isFinite() && !B.isNaN();
|
|
253
|
+
if ((isInfA || isInfB) && !allowInfinite) {
|
|
254
|
+
throw new Error(`defint: infinite bounds require allowInfinite:true`);
|
|
255
|
+
}
|
|
256
|
+
const coreOpts = { tolAbs, tolRel, maxDepth, maxEvals, singular };
|
|
257
|
+
// Handle infinite bounds with standard substitutions:
|
|
258
|
+
// (1) a finite, b = +inf: x = a + t/(1-t), t in [0,1)
|
|
259
|
+
// (2) a = -inf, b finite: x = b - t/(1-t), t in [0,1)
|
|
260
|
+
// (3) a=-inf, b=+inf: x = tan(pi*(t-1/2)), t in (0,1)
|
|
261
|
+
//
|
|
262
|
+
// NOTE: These are robust but may need higher maxDepth for oscillatory/singular functions.
|
|
263
|
+
if (allowInfinite && (isInfA || isInfB)) {
|
|
264
|
+
if (!isInfA && isInfB && B.isPos()) {
|
|
265
|
+
const a0 = A;
|
|
266
|
+
const g = t => {
|
|
267
|
+
// x = a + t/(1-t)
|
|
268
|
+
const oneMinusT = ONE.sub(t);
|
|
269
|
+
const x = a0.add(t.div(oneMinusT));
|
|
270
|
+
// dx/dt = 1/(1-t)^2
|
|
271
|
+
const dxdt = ONE.div(oneMinusT.mul(oneMinusT));
|
|
272
|
+
return f(x).mul(dxdt);
|
|
273
|
+
};
|
|
274
|
+
// integrate t in [0,1] but avoid evaluating at 1 exactly
|
|
275
|
+
const eps = new decimal_js_1.default(10).pow(-(decimal_js_1.default.precision ?? DEFAULT_DECIMAL_PRECISION) + INFINITE_BOUND_PRECISION_SLACK);
|
|
276
|
+
return withFiniteBounds(g, ZERO, ONE.sub(eps), coreOpts);
|
|
277
|
+
}
|
|
278
|
+
if (isInfA && A.isNeg() && !isInfB) {
|
|
279
|
+
const b0 = B;
|
|
280
|
+
const g = t => {
|
|
281
|
+
const oneMinusT = ONE.sub(t);
|
|
282
|
+
const x = b0.sub(t.div(oneMinusT));
|
|
283
|
+
const dxdt = ONE.div(oneMinusT.mul(oneMinusT));
|
|
284
|
+
return f(x).mul(dxdt);
|
|
285
|
+
};
|
|
286
|
+
const eps = new decimal_js_1.default(10).pow(-(decimal_js_1.default.precision ?? DEFAULT_DECIMAL_PRECISION) + INFINITE_BOUND_PRECISION_SLACK);
|
|
287
|
+
return withFiniteBounds(g, ZERO, ONE.sub(eps), coreOpts);
|
|
288
|
+
}
|
|
289
|
+
if (isInfA && A.isNeg() && isInfB && B.isPos()) {
|
|
290
|
+
// x = tan(pi*(t-1/2)), dx/dt = pi*sec^2(...)
|
|
291
|
+
const PI = decimal_js_1.default.acos(-1);
|
|
292
|
+
const g = t => {
|
|
293
|
+
const u = PI.mul(t.sub(new decimal_js_1.default('0.5')));
|
|
294
|
+
const x = decimal_js_1.default.tan(u);
|
|
295
|
+
const sec2 = ONE.div(decimal_js_1.default.cos(u).pow(2));
|
|
296
|
+
const dxdt = PI.mul(sec2);
|
|
297
|
+
return f(x).mul(dxdt);
|
|
298
|
+
};
|
|
299
|
+
const eps = new decimal_js_1.default(10).pow(-(decimal_js_1.default.precision ?? DEFAULT_DECIMAL_PRECISION) + INFINITE_BOUND_PRECISION_SLACK);
|
|
300
|
+
return withFiniteBounds(g, eps, ONE.sub(eps), coreOpts);
|
|
301
|
+
}
|
|
302
|
+
throw new Error(`defint: unsupported infinite bound configuration`);
|
|
303
|
+
}
|
|
304
|
+
// Finite-bounds path, with optional segmentation by breakpoints
|
|
305
|
+
if (bps.length === 0) {
|
|
306
|
+
return withFiniteBounds(f, A, B, coreOpts);
|
|
307
|
+
}
|
|
308
|
+
// Segment integration; allocate tolerance budget across segments
|
|
309
|
+
const nSeg = bps.length + 1;
|
|
310
|
+
const segTolAbs = tolAbs.div(nSeg);
|
|
311
|
+
const segTolRel = tolRel; // keep relative tol the same per segment
|
|
312
|
+
let total = ZERO;
|
|
313
|
+
let start = A;
|
|
314
|
+
for (const bp of bps) {
|
|
315
|
+
total = total.add(withFiniteBounds(f, start, bp, { ...coreOpts, tolAbs: segTolAbs, tolRel: segTolRel }));
|
|
316
|
+
start = bp;
|
|
317
|
+
}
|
|
318
|
+
total = total.add(withFiniteBounds(f, start, B, { ...coreOpts, tolAbs: segTolAbs, tolRel: segTolRel }));
|
|
319
|
+
return total;
|
|
320
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adaptive Simpson definite integration using native `number` arithmetic.
|
|
3
|
+
*
|
|
4
|
+
* Same algorithm as the Decimal.js version (adaptive Simpson with Richardson
|
|
5
|
+
* extrapolation, iterative stack) but 50-100x faster for typical integrands.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Adaptive error control with combined absolute + relative tolerance
|
|
9
|
+
* - Breakpoint segmentation for piecewise/abs/kink functions
|
|
10
|
+
* - Infinite bounds via variable substitution
|
|
11
|
+
* - Best-effort singularity handling
|
|
12
|
+
*/
|
|
13
|
+
export type NumericFn = (x: number) => number;
|
|
14
|
+
export interface DefIntNativeOptions {
|
|
15
|
+
/** Absolute tolerance. Default: 1e-12 */
|
|
16
|
+
tolAbs?: number;
|
|
17
|
+
/** Relative tolerance (scaled to |I|). Default: 1e-12 */
|
|
18
|
+
tolRel?: number;
|
|
19
|
+
/** Max adaptive subdivision depth. Default: 50 */
|
|
20
|
+
maxDepth?: number;
|
|
21
|
+
/** Hard cap on function evaluations. Default: 100_000 */
|
|
22
|
+
maxEvals?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Singular/discontinuous handling:
|
|
25
|
+
* - "auto": detect non-finite spikes and bisect around them
|
|
26
|
+
* - "strict": throw on non-finite
|
|
27
|
+
* - "ignore": propagate NaN
|
|
28
|
+
*/
|
|
29
|
+
singular?: 'auto' | 'strict' | 'ignore';
|
|
30
|
+
/**
|
|
31
|
+
* Known breakpoints inside (a,b) where f may change behavior.
|
|
32
|
+
* Integration runs separately on each segment.
|
|
33
|
+
*/
|
|
34
|
+
breakpoints?: number[];
|
|
35
|
+
/**
|
|
36
|
+
* Support +/-Infinity bounds via variable substitution.
|
|
37
|
+
* Default: false.
|
|
38
|
+
*/
|
|
39
|
+
allowInfinite?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Definite integral of `f` from `a` to `b` using adaptive Simpson's rule
|
|
43
|
+
* with Richardson extrapolation, native `number` arithmetic.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* // ∫₀^π sin(x) dx = 2
|
|
48
|
+
* definiteIntegrate(Math.sin, 0, Math.PI);
|
|
49
|
+
*
|
|
50
|
+
* // With breakpoints for |x|
|
|
51
|
+
* definiteIntegrate(x => Math.abs(x), -1, 1, { breakpoints: [0] });
|
|
52
|
+
*
|
|
53
|
+
* // Improper integral ∫₁^∞ 1/x² dx = 1
|
|
54
|
+
* definiteIntegrate(x => 1/(x*x), 1, Infinity, { allowInfinite: true });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function definiteIntegrateNative(f: NumericFn, a: number, b: number, options?: DefIntNativeOptions): number;
|