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,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isPrimeBig = isPrimeBig;
|
|
4
|
+
exports.trialDivisionBig = trialDivisionBig;
|
|
5
|
+
exports.pollardRhoBig = pollardRhoBig;
|
|
6
|
+
exports.primeFactorsBig = primeFactorsBig;
|
|
7
|
+
exports.primeFactorCounts = primeFactorCounts;
|
|
8
|
+
exports.mergeFactors = mergeFactors;
|
|
9
|
+
exports.getFactors = getFactors;
|
|
10
|
+
const bigint_1 = require("./bigint");
|
|
11
|
+
/**
|
|
12
|
+
* Calculates and array of prime factors
|
|
13
|
+
*
|
|
14
|
+
* @see https://stackoverflow.com/questions/39899072/how-can-i-find-the-prime-factors-of-an-integer-in-javascript by @TheChiporpoise
|
|
15
|
+
* @param num
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
// export function primeFactors(num: bigint, toNumbers: true): { sign: number, factors: number[] };
|
|
19
|
+
// export function primeFactors(num: bigint, toNumbers: false | void): { sign: number, factors: bigint[] };
|
|
20
|
+
// export function primeFactors(num: bigint, toNumbers?: boolean | void) {
|
|
21
|
+
// const factors: bigint[] = [];
|
|
22
|
+
// const sgn = sign(num);
|
|
23
|
+
// num = abs(num)
|
|
24
|
+
// /* since 2 is the only even prime, it's easier to factor it out
|
|
25
|
+
// * separately from the odd factor loop (for loop doesn't need to
|
|
26
|
+
// * check whether or not to add 1 or 2 to f).
|
|
27
|
+
// * The condition is essentially checking if the number is even
|
|
28
|
+
// * (bitwise "&" operator compares the bits of 2 numbers in binary
|
|
29
|
+
// * and outputs a binary number with 1's where their digits are the
|
|
30
|
+
// * same and 0's where they differ. In this case it only checks if
|
|
31
|
+
// * the final digit for num in binary is 1, which would mean the
|
|
32
|
+
// * number is odd, in which case the output would be 1, which is
|
|
33
|
+
// * interpreted as true, otherwise the output will be 0, which is
|
|
34
|
+
// * interpreted as false. "!" returns the opposite boolean, so this
|
|
35
|
+
// * means that '!(num & 1)' is true when the num is not odd)
|
|
36
|
+
// */
|
|
37
|
+
// while (!(num & 1n)) {
|
|
38
|
+
// factors.push(2n);
|
|
39
|
+
// num /= 2n;
|
|
40
|
+
// }
|
|
41
|
+
// // 'f*f <= num' is faster than 'f <= Math.sqrt(num)'
|
|
42
|
+
// for (let f = 3n; f * f <= num; f += 2n) {
|
|
43
|
+
// while (!(num % f)) { // remainder of 'num / f' isn't 0
|
|
44
|
+
// factors.push(f);
|
|
45
|
+
// num /= f;
|
|
46
|
+
// }
|
|
47
|
+
// }
|
|
48
|
+
// /* if the number is already prime, then this adds it to factors so
|
|
49
|
+
// * an empty array isn't returned
|
|
50
|
+
// */
|
|
51
|
+
// if (num !== 1n) {
|
|
52
|
+
// factors.push(num);
|
|
53
|
+
// }
|
|
54
|
+
// return {
|
|
55
|
+
// sign: sgn,
|
|
56
|
+
// factors: toNumbers ? factors.map((n) => Number(n)) : factors
|
|
57
|
+
// }
|
|
58
|
+
// }
|
|
59
|
+
// Miller-Rabin primality test
|
|
60
|
+
function isPrimeBig(num) {
|
|
61
|
+
if (num < 2n) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (num === 2n || num === 3n) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (num % 2n === 0n) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
let r = 0n;
|
|
71
|
+
let d = num - 1n;
|
|
72
|
+
while (d % 2n === 0n) {
|
|
73
|
+
r++;
|
|
74
|
+
d /= 2n;
|
|
75
|
+
}
|
|
76
|
+
const modPow = (base, exp, mod) => {
|
|
77
|
+
let result = 1n;
|
|
78
|
+
base %= mod;
|
|
79
|
+
while (exp > 0n) {
|
|
80
|
+
if (exp % 2n === 1n) {
|
|
81
|
+
result = (result * base) % mod;
|
|
82
|
+
}
|
|
83
|
+
base = (base * base) % mod;
|
|
84
|
+
exp /= 2n;
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
};
|
|
88
|
+
// These witnesses are deterministic for every unsigned 64-bit integer. For larger
|
|
89
|
+
// BigInts they remain a stable probable-prime test rather than a randomized result.
|
|
90
|
+
const witnesses = num < 18446744073709551616n
|
|
91
|
+
? [2n, 325n, 9375n, 28178n, 450775n, 9780504n, 1795265022n]
|
|
92
|
+
: [2n, 3n, 5n, 7n, 11n, 13n, 17n, 19n, 23n, 29n, 31n, 37n];
|
|
93
|
+
for (const witness of witnesses) {
|
|
94
|
+
const a = witness % num;
|
|
95
|
+
if (a < 2n) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
let x = modPow(a, d, num);
|
|
99
|
+
if (x === 1n || x === num - 1n) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
let proceed = false;
|
|
103
|
+
for (let j = 0n; j < r - 1n; j++) {
|
|
104
|
+
x = (x * x) % num;
|
|
105
|
+
if (x === num - 1n) {
|
|
106
|
+
proceed = true;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (!proceed) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Fast prime factorization using trial division with optimizations
|
|
118
|
+
*/
|
|
119
|
+
function trialDivisionBig(n) {
|
|
120
|
+
if (n <= 1n) {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
const factors = [];
|
|
124
|
+
// Handle factor of 2
|
|
125
|
+
while (n % 2n === 0n) {
|
|
126
|
+
factors.push(2n);
|
|
127
|
+
n /= 2n;
|
|
128
|
+
}
|
|
129
|
+
// Handle odd factors from 3 onwards
|
|
130
|
+
let i = 3n;
|
|
131
|
+
const sqrt = (num) => {
|
|
132
|
+
if (num < 2n) {
|
|
133
|
+
return num;
|
|
134
|
+
}
|
|
135
|
+
let x = num;
|
|
136
|
+
let y = (x + 1n) / 2n;
|
|
137
|
+
while (y < x) {
|
|
138
|
+
x = y;
|
|
139
|
+
y = (x + num / x) / 2n;
|
|
140
|
+
}
|
|
141
|
+
return x;
|
|
142
|
+
};
|
|
143
|
+
const limit = sqrt(n);
|
|
144
|
+
while (i <= limit) {
|
|
145
|
+
while (n % i === 0n) {
|
|
146
|
+
factors.push(i);
|
|
147
|
+
n /= i;
|
|
148
|
+
}
|
|
149
|
+
i += 2n; // Skip even numbers
|
|
150
|
+
}
|
|
151
|
+
// If n is still greater than 1, it's a prime factor
|
|
152
|
+
if (n > 1n) {
|
|
153
|
+
factors.push(n);
|
|
154
|
+
}
|
|
155
|
+
return factors;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Pollard's rho algorithm for faster factorization of large numbers
|
|
159
|
+
*/
|
|
160
|
+
function pollardRhoBig(n) {
|
|
161
|
+
if (n % 2n === 0n) {
|
|
162
|
+
return 2n;
|
|
163
|
+
}
|
|
164
|
+
let x = 2n;
|
|
165
|
+
let y = 2n;
|
|
166
|
+
let d = 1n;
|
|
167
|
+
const f = (val) => (val * val + 1n) % n;
|
|
168
|
+
const gcd = (a, b) => {
|
|
169
|
+
while (b !== 0n) {
|
|
170
|
+
[a, b] = [b, a % b];
|
|
171
|
+
}
|
|
172
|
+
return a;
|
|
173
|
+
};
|
|
174
|
+
while (d === 1n) {
|
|
175
|
+
x = f(x);
|
|
176
|
+
y = f(f(y));
|
|
177
|
+
d = gcd(x > y ? x - y : y - x, n);
|
|
178
|
+
}
|
|
179
|
+
return d === n ? 0n : d;
|
|
180
|
+
}
|
|
181
|
+
function primeFactorsBig(n, toNumbers) {
|
|
182
|
+
const sgn = (0, bigint_1.sign)(n);
|
|
183
|
+
n = (0, bigint_1.abs)(n);
|
|
184
|
+
const factors = [];
|
|
185
|
+
if (n === 1n || n === 2n || isPrimeBig(n)) {
|
|
186
|
+
factors.push(n);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const factorize = (num) => {
|
|
190
|
+
if (num === 1n) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (isPrimeBig(num)) {
|
|
194
|
+
factors.push(num);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const divisor = pollardRhoBig(num);
|
|
198
|
+
if (divisor === 0n) {
|
|
199
|
+
// Fallback to trial division
|
|
200
|
+
const simple = trialDivisionBig(num);
|
|
201
|
+
factors.push(...simple);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
factorize(divisor);
|
|
205
|
+
factorize(num / divisor);
|
|
206
|
+
};
|
|
207
|
+
factorize(n);
|
|
208
|
+
}
|
|
209
|
+
factors.sort((a, b) => (a < b ? -1 : 1));
|
|
210
|
+
return {
|
|
211
|
+
sign: sgn,
|
|
212
|
+
factors: toNumbers ? factors.map(x => Number(x)) : factors,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Places the prime factors in an object and counts their occurrences
|
|
217
|
+
*
|
|
218
|
+
* @param n
|
|
219
|
+
*/
|
|
220
|
+
function primeFactorCounts(n) {
|
|
221
|
+
const counts = {};
|
|
222
|
+
const factors = primeFactorsBig(n).factors;
|
|
223
|
+
for (const factor of factors) {
|
|
224
|
+
const f = String(factor);
|
|
225
|
+
if (!(f in counts)) {
|
|
226
|
+
counts[f] = 1n;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
counts[f]++;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return counts;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Merges two factor counts into one object
|
|
236
|
+
*
|
|
237
|
+
* @param a
|
|
238
|
+
* @param b
|
|
239
|
+
*/
|
|
240
|
+
function mergeFactors(a, b) {
|
|
241
|
+
// Make a copy of a
|
|
242
|
+
const retval = Object.assign(a, {});
|
|
243
|
+
// Merge their counts
|
|
244
|
+
for (const factor in b) {
|
|
245
|
+
retval[factor] = factor in retval ? retval[factor] + b[factor] : b[factor];
|
|
246
|
+
}
|
|
247
|
+
return retval;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Gets prime factors that can be used to create a number. The number one is
|
|
251
|
+
* included since 1 * n is a possible combination.
|
|
252
|
+
*
|
|
253
|
+
* @param n The number for which the factors are being retrieved
|
|
254
|
+
* @returns
|
|
255
|
+
*/
|
|
256
|
+
function getFactors(n) {
|
|
257
|
+
const { sign: sgn, factors } = primeFactorsBig(BigInt(n), true);
|
|
258
|
+
// Add the one since 1 * p is a combination
|
|
259
|
+
factors.unshift(1);
|
|
260
|
+
if (sgn === -1) {
|
|
261
|
+
const l = factors.length;
|
|
262
|
+
for (let i = 0; i < l; i++) {
|
|
263
|
+
factors.push(-factors[i]);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return factors;
|
|
267
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PRIMES_100: bigint[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PRIMES_100 = void 0;
|
|
4
|
+
// prettier-ignore
|
|
5
|
+
exports.PRIMES_100 = [
|
|
6
|
+
2n, 3n, 5n, 7n, 11n, 13n, 17n, 19n, 23n, 29n, 31n, 37n, 41n, 43n, 47n, 53n, 59n, 61n, 67n, 71n, 73n, 79n, 83n, 89n, 97n,
|
|
7
|
+
101n, 103n, 107n, 109n, 113n, 127n, 131n, 137n, 139n, 149n, 151n, 157n, 163n, 167n, 173n, 179n, 181n, 191n, 193n, 197n, 199n, 211n, 223n,
|
|
8
|
+
227n, 229n, 233n, 239n, 241n, 251n, 257n, 263n, 269n, 271n, 277n, 281n, 283n, 293n, 307n, 311n, 313n, 317n, 331n, 337n, 347n, 349n, 353n,
|
|
9
|
+
359n, 367n, 373n, 379n, 383n, 389n, 397n, 401n, 409n, 419n, 421n, 431n, 433n, 439n, 443n, 449n, 457n, 461n, 463n, 467n, 479n, 487n, 491n,
|
|
10
|
+
499n, 503n, 509n, 521n, 523n, 541n
|
|
11
|
+
];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { JsFunction } from '../../classes/parser/types';
|
|
2
|
+
/**
|
|
3
|
+
* Numerical function implementations available to `buildFunction`.
|
|
4
|
+
*
|
|
5
|
+
* Every function body must either be self-contained or list each free function dependency
|
|
6
|
+
* by its registry name so `buildFunction` can serialize the complete implementation. Functions
|
|
7
|
+
* whose meaning depends on symbolic variables, structured entities, or complex-valued runtime
|
|
8
|
+
* objects are absent and are rejected by the compiler.
|
|
9
|
+
*/
|
|
10
|
+
export declare const definitions: {
|
|
11
|
+
[name: string]: [f: JsFunction, dependencies?: string[]];
|
|
12
|
+
};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.definitions = void 0;
|
|
4
|
+
const fresnelNumeric_1 = require("../fresnelNumeric");
|
|
5
|
+
const numeric_1 = require("../numeric");
|
|
6
|
+
/**
|
|
7
|
+
* Numerical function implementations available to `buildFunction`.
|
|
8
|
+
*
|
|
9
|
+
* Every function body must either be self-contained or list each free function dependency
|
|
10
|
+
* by its registry name so `buildFunction` can serialize the complete implementation. Functions
|
|
11
|
+
* whose meaning depends on symbolic variables, structured entities, or complex-valued runtime
|
|
12
|
+
* objects are absent and are rejected by the compiler.
|
|
13
|
+
*/
|
|
14
|
+
exports.definitions = {
|
|
15
|
+
// Trigonometric functions
|
|
16
|
+
cos: [x => Math.cos(x)],
|
|
17
|
+
sin: [x => Math.sin(x)],
|
|
18
|
+
tan: [x => Math.tan(x)],
|
|
19
|
+
sec: [x => 1 / Math.cos(x)],
|
|
20
|
+
csc: [x => (x === 0 ? NaN : 1 / Math.sin(x))],
|
|
21
|
+
cot: [x => (x === 0 ? NaN : 1 / Math.tan(x))],
|
|
22
|
+
acos: [x => Math.acos(x)],
|
|
23
|
+
asin: [x => Math.asin(x)],
|
|
24
|
+
atan: [x => Math.atan(x)],
|
|
25
|
+
asec: [x => Math.acos(1 / x)],
|
|
26
|
+
acsc: [x => Math.asin(1 / x)],
|
|
27
|
+
acot: [x => (x < 0 ? Math.PI + Math.atan(1 / x) : Math.atan(1 / x))],
|
|
28
|
+
atan2: [
|
|
29
|
+
(y, x) => (y === 0 && x === 0) || (!Number.isFinite(y) && !Number.isFinite(x))
|
|
30
|
+
? NaN
|
|
31
|
+
: Math.atan2(y, x),
|
|
32
|
+
],
|
|
33
|
+
// Hyperbolic functions
|
|
34
|
+
cosh: [x => Math.cosh(x)],
|
|
35
|
+
sinh: [x => Math.sinh(x)],
|
|
36
|
+
tanh: [x => Math.tanh(x)],
|
|
37
|
+
sech: [x => 1 / Math.cosh(x)],
|
|
38
|
+
csch: [x => (x === 0 ? NaN : 1 / Math.sinh(x))],
|
|
39
|
+
coth: [x => (x === 0 ? NaN : 1 / Math.tanh(x))],
|
|
40
|
+
acosh: [x => Math.acosh(x)],
|
|
41
|
+
asinh: [x => Math.asinh(x)],
|
|
42
|
+
atanh: [x => (x === 1 ? NaN : Math.atanh(x))],
|
|
43
|
+
asech: [x => (x === 0 ? NaN : Math.acosh(1 / x))],
|
|
44
|
+
acsch: [x => (x === 0 ? NaN : Math.asinh(1 / x))],
|
|
45
|
+
acoth: [x => Math.atanh(1 / x)],
|
|
46
|
+
// Scalar arithmetic and elementary functions
|
|
47
|
+
abs: [x => Math.abs(x)],
|
|
48
|
+
sqrt: [x => Math.sqrt(x)],
|
|
49
|
+
cbrt: [x => Math.cbrt(x)],
|
|
50
|
+
nthroot: [(x, n) => (n === 0 ? NaN : Math.pow(x, 1 / n))],
|
|
51
|
+
log: [
|
|
52
|
+
(x, base) => base === undefined
|
|
53
|
+
? Math.log(x)
|
|
54
|
+
: base <= 0 || base === 1
|
|
55
|
+
? NaN
|
|
56
|
+
: Math.log(x) / Math.log(base),
|
|
57
|
+
],
|
|
58
|
+
exp: [x => Math.exp(x)],
|
|
59
|
+
hypot: [(a, b) => Math.hypot(a, b)],
|
|
60
|
+
round: [numeric_1.round, ['isInt']],
|
|
61
|
+
sign: [x => Math.sign(x)],
|
|
62
|
+
floor: [x => Math.floor(x)],
|
|
63
|
+
ceil: [x => Math.ceil(x)],
|
|
64
|
+
ceiling: [x => Math.ceil(x)],
|
|
65
|
+
trunc: [x => Math.trunc(x)],
|
|
66
|
+
mod: [numeric_1.mod],
|
|
67
|
+
modinv: [numeric_1.modInv, ['mod']],
|
|
68
|
+
max: [(...args) => Math.max(...args)],
|
|
69
|
+
min: [(...args) => Math.min(...args)],
|
|
70
|
+
avg: [(...args) => args.reduce((total, value) => total + value, 0) / args.length],
|
|
71
|
+
heaviside: [numeric_1.heaviside],
|
|
72
|
+
// Complex-component helpers are limited to real JavaScript-number inputs. This is
|
|
73
|
+
// faithful to buildFunction's scalar runtime function without pretending to provide
|
|
74
|
+
// a JavaScript-number representation for genuinely complex values.
|
|
75
|
+
realpart: [x => x],
|
|
76
|
+
imagpart: [() => 0],
|
|
77
|
+
arg: [x => (Number.isNaN(x) ? NaN : x < 0 ? Math.PI : 0)],
|
|
78
|
+
conjugate: [x => x],
|
|
79
|
+
polarform: [x => x],
|
|
80
|
+
rectform: [x => x],
|
|
81
|
+
csgn: [x => Math.sign(x)],
|
|
82
|
+
// Integer-valued helpers. Keep internal dependency names available because the
|
|
83
|
+
// emitted function bodies reference these identifiers directly.
|
|
84
|
+
isInt: [numeric_1.isInt],
|
|
85
|
+
GCD: [numeric_1.GCD],
|
|
86
|
+
gcd: [numeric_1.GCD],
|
|
87
|
+
LCM: [numeric_1.LCM, ['GCD']],
|
|
88
|
+
lcm: [numeric_1.LCM, ['GCD']],
|
|
89
|
+
modInv: [numeric_1.modInv, ['mod']],
|
|
90
|
+
isPrime: [numeric_1.isPrime],
|
|
91
|
+
isprime: [numeric_1.isPrime],
|
|
92
|
+
fib: [
|
|
93
|
+
x => {
|
|
94
|
+
let retval = NaN;
|
|
95
|
+
if (Number.isSafeInteger(x)) {
|
|
96
|
+
const isNegative = x < 0;
|
|
97
|
+
const index = Math.abs(x);
|
|
98
|
+
let a = 0;
|
|
99
|
+
let b = 1;
|
|
100
|
+
for (let i = 0; i < index; i++) {
|
|
101
|
+
const next = a + b;
|
|
102
|
+
a = b;
|
|
103
|
+
b = next;
|
|
104
|
+
if (!Number.isSafeInteger(a)) {
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (Number.isSafeInteger(a)) {
|
|
109
|
+
retval = isNegative && index % 2 === 0 ? -a : a;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return retval;
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
fact: [numeric_1.factorial, ['isInt', 'gamma']],
|
|
116
|
+
factorial: [numeric_1.factorial, ['isInt', 'gamma']],
|
|
117
|
+
dfact: [numeric_1.doubleFactorial, ['isInt', 'gamma']],
|
|
118
|
+
// Special functions
|
|
119
|
+
erf: [numeric_1.erf, ['erfc']],
|
|
120
|
+
erfc: [numeric_1.erfc],
|
|
121
|
+
gammaLN: [numeric_1.gammaLN],
|
|
122
|
+
gamma: [numeric_1.gamma, ['gammaLN', 'isInt', 'factorial']],
|
|
123
|
+
sinc: [numeric_1.sinc],
|
|
124
|
+
Si: [numeric_1.Si],
|
|
125
|
+
Shi: [numeric_1.Shi],
|
|
126
|
+
Ci: [numeric_1.Ci],
|
|
127
|
+
Chi: [numeric_1.Chi],
|
|
128
|
+
Ei: [numeric_1.Ei],
|
|
129
|
+
Li: [numeric_1.Li],
|
|
130
|
+
fresnelIntegral: [fresnelNumeric_1.fresnelIntegral],
|
|
131
|
+
S: [fresnelNumeric_1.fresnelS, ['fresnelIntegral']],
|
|
132
|
+
C: [fresnelNumeric_1.fresnelC, ['fresnelIntegral']],
|
|
133
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ExpressionInput } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Compiles an expression into a native JavaScript-number function for repeated evaluation.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Function calls are linked to Nerdamer's internal numerical implementation registry, including
|
|
7
|
+
* any dependencies those implementations require. The compiler supports scalar JavaScript-number
|
|
8
|
+
* semantics rather than Nerdamer's full symbolic or structured object model. Symbolic-only
|
|
9
|
+
* operations such as indexed sums/products, solvers, and matrix operations are rejected if they
|
|
10
|
+
* remain in the expression at compilation time.
|
|
11
|
+
*
|
|
12
|
+
* `buildFunction` is the only Nerdamer runtime path that performs dynamic JavaScript code
|
|
13
|
+
* generation. Normal parsing, simplification, solving, evaluation, and symbolic manipulation do
|
|
14
|
+
* not use `eval()` or `new Function`. This compiler uses `new Function`, so it may be unavailable
|
|
15
|
+
* under a Content Security Policy that forbids dynamic JavaScript evaluation.
|
|
16
|
+
*
|
|
17
|
+
* When `argsArray` is omitted, free variables are sorted alphabetically.
|
|
18
|
+
*
|
|
19
|
+
* @param x - The expression being converted to a function.
|
|
20
|
+
* @param argsArray - Variable names in the positional order expected by the compiled function.
|
|
21
|
+
* @returns The compiled JavaScript-number function.
|
|
22
|
+
* @throws {@link core!UnsupportedOperationError} If the expression contains the imaginary unit or a
|
|
23
|
+
* function for which no faithful JavaScript-number implementation is registered.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* build('x-y')(9, 7); // 2
|
|
28
|
+
* build('x-y', ['y', 'x'])(9, 7); // -2
|
|
29
|
+
* build('erf(x)+2')(9) // 3
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function build(x: ExpressionInput, argsArray?: string[]): (...args: number[]) => number;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.build = build;
|
|
4
|
+
const Expression_1 = require("../../classes/expression/Expression");
|
|
5
|
+
const constants_1 = require("../../classes/parser/constants");
|
|
6
|
+
const errors_1 = require("../../errors");
|
|
7
|
+
const numeric_1 = require("../numeric");
|
|
8
|
+
const definitions_1 = require("./definitions");
|
|
9
|
+
/**
|
|
10
|
+
* Compiles an expression into a native JavaScript-number function for repeated evaluation.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Function calls are linked to Nerdamer's internal numerical implementation registry, including
|
|
14
|
+
* any dependencies those implementations require. The compiler supports scalar JavaScript-number
|
|
15
|
+
* semantics rather than Nerdamer's full symbolic or structured object model. Symbolic-only
|
|
16
|
+
* operations such as indexed sums/products, solvers, and matrix operations are rejected if they
|
|
17
|
+
* remain in the expression at compilation time.
|
|
18
|
+
*
|
|
19
|
+
* `buildFunction` is the only Nerdamer runtime path that performs dynamic JavaScript code
|
|
20
|
+
* generation. Normal parsing, simplification, solving, evaluation, and symbolic manipulation do
|
|
21
|
+
* not use `eval()` or `new Function`. This compiler uses `new Function`, so it may be unavailable
|
|
22
|
+
* under a Content Security Policy that forbids dynamic JavaScript evaluation.
|
|
23
|
+
*
|
|
24
|
+
* When `argsArray` is omitted, free variables are sorted alphabetically.
|
|
25
|
+
*
|
|
26
|
+
* @param x - The expression being converted to a function.
|
|
27
|
+
* @param argsArray - Variable names in the positional order expected by the compiled function.
|
|
28
|
+
* @returns The compiled JavaScript-number function.
|
|
29
|
+
* @throws {@link core!UnsupportedOperationError} If the expression contains the imaginary unit or a
|
|
30
|
+
* function for which no faithful JavaScript-number implementation is registered.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* build('x-y')(9, 7); // 2
|
|
35
|
+
* build('x-y', ['y', 'x'])(9, 7); // -2
|
|
36
|
+
* build('erf(x)+2')(9) // 3
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
function build(x, argsArray) {
|
|
40
|
+
x = Expression_1.Expression.create(x);
|
|
41
|
+
if (x.hasVariable(Expression_1.Expression.imaginary)) {
|
|
42
|
+
throw new errors_1.UnsupportedOperationError((0, errors_1.message)('buildFunctionComplexUnsupported'));
|
|
43
|
+
}
|
|
44
|
+
// Collect the constants such as e, pi, or any other constants defined by the functions.
|
|
45
|
+
const constants = collectConstants(x);
|
|
46
|
+
/**
|
|
47
|
+
* The body for the most part is just a expression. The function definitions get loaded
|
|
48
|
+
* from the numeric functions object.
|
|
49
|
+
*/
|
|
50
|
+
const body = `${x.text({ wrapPow: true })};`
|
|
51
|
+
//The caret symbol gets replaced because it has an entirely different meaning to JavaScript
|
|
52
|
+
.replace(/\^/g, '**');
|
|
53
|
+
/**
|
|
54
|
+
* Collect the functions in the string and import their definitions. Basically for each
|
|
55
|
+
* function call in the expression a definition in the form const fn = ...; is added
|
|
56
|
+
*/
|
|
57
|
+
const imports = [[], []];
|
|
58
|
+
x.functions().forEach((e) => {
|
|
59
|
+
importDeps(e, imports);
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Compile the imports string
|
|
63
|
+
*/
|
|
64
|
+
let compiledImports = '';
|
|
65
|
+
for (let i = 0; i < imports[0].length; i++) {
|
|
66
|
+
compiledImports += `var ${imports[0][i]} = ${imports[1][i]};\n`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* If no variables array is provided then it's generated;
|
|
70
|
+
*/
|
|
71
|
+
const functionArgs = argsArray || x.variables().sort();
|
|
72
|
+
// Construction the function definition
|
|
73
|
+
const functionDef = `${constants}${compiledImports} return ${body}`;
|
|
74
|
+
return new Function(...functionArgs, functionDef);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Recursively collects functions and their dependencies.
|
|
78
|
+
*
|
|
79
|
+
* @param name - Function name emitted by the expression converter.
|
|
80
|
+
* @param imports - Ordered names and implementations that will be inserted into the function body.
|
|
81
|
+
* @param visiting - Function names on the current dependency path.
|
|
82
|
+
* @returns The same imports tuple after adding the requested definition and its dependencies.
|
|
83
|
+
*/
|
|
84
|
+
function importDeps(name, imports, visiting = new Set()) {
|
|
85
|
+
// Parentheses are represented internally as a function with an empty name. They are
|
|
86
|
+
// already valid JavaScript syntax and do not need a numerical implementation.
|
|
87
|
+
if (name === '') {
|
|
88
|
+
return imports;
|
|
89
|
+
}
|
|
90
|
+
const names = imports[0];
|
|
91
|
+
const fns = imports[1];
|
|
92
|
+
if (names.includes(name)) {
|
|
93
|
+
return imports;
|
|
94
|
+
}
|
|
95
|
+
const definition = definitions_1.definitions[name];
|
|
96
|
+
if (definition === undefined) {
|
|
97
|
+
throw new errors_1.UnsupportedOperationError((0, errors_1.message)('buildFunctionUnsupportedFunction', { function: name }));
|
|
98
|
+
}
|
|
99
|
+
// Numerical definitions can depend on one another. Track the active dependency path so
|
|
100
|
+
// mutually recursive definitions cannot recurse forever while the function is compiled.
|
|
101
|
+
if (visiting.has(name)) {
|
|
102
|
+
return imports;
|
|
103
|
+
}
|
|
104
|
+
visiting.add(name);
|
|
105
|
+
const [f, deps] = definition;
|
|
106
|
+
if (deps !== undefined) {
|
|
107
|
+
for (const dep of deps) {
|
|
108
|
+
importDeps(dep, imports, visiting);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
visiting.delete(name);
|
|
112
|
+
if (!names.includes(name)) {
|
|
113
|
+
names.push(name);
|
|
114
|
+
fns.push(f);
|
|
115
|
+
}
|
|
116
|
+
return imports;
|
|
117
|
+
}
|
|
118
|
+
function collectConstants(x) {
|
|
119
|
+
const EULER_GAMMA_IDENTIFIER = 'EULER_GAMMA';
|
|
120
|
+
const constants = [];
|
|
121
|
+
const nativeConstants = { [constants_1.PI_NAME]: Math.PI, [constants_1.E]: Math.E };
|
|
122
|
+
function setConstant(name, value) {
|
|
123
|
+
constants.push(`var ${name} = ${value};\n`);
|
|
124
|
+
}
|
|
125
|
+
// Add the constants pi and e
|
|
126
|
+
[constants_1.PI_NAME, constants_1.E].forEach(e => {
|
|
127
|
+
if (x.hasVariable(e)) {
|
|
128
|
+
setConstant(e, nativeConstants[e]);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
// Add constants for special functions
|
|
132
|
+
if ([constants_1.CI, constants_1.CHI, constants_1.SI, constants_1.SHI, constants_1.LI, constants_1.EI].some(f => x.hasFunction(f, true))) {
|
|
133
|
+
setConstant(EULER_GAMMA_IDENTIFIER, numeric_1.EULER_GAMMA);
|
|
134
|
+
}
|
|
135
|
+
return constants.join(' ');
|
|
136
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Expression } from '../classes/expression/Expression';
|
|
2
|
+
import type { ExpressionInput } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Retrieves the real part of a complex number
|
|
5
|
+
*
|
|
6
|
+
* @param a
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Retrieves the real part of a complex number
|
|
11
|
+
*
|
|
12
|
+
* @param a
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
export declare function realPart(a: Expression): Expression;
|
|
16
|
+
/**
|
|
17
|
+
* Retrieves the imaginary part of a complex number
|
|
18
|
+
*
|
|
19
|
+
* @param a
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
export declare function imagPart(a: Expression): Expression;
|
|
23
|
+
/**
|
|
24
|
+
* Simplifies a*i^n with numeric powers and coefficients
|
|
25
|
+
*
|
|
26
|
+
* @param x
|
|
27
|
+
*/
|
|
28
|
+
export declare function simplifyImaginary(x: Expression): Expression;
|
|
29
|
+
export declare function toPolarFormArray(x: Expression): Expression[];
|
|
30
|
+
/**
|
|
31
|
+
* Calculates the polar from of a complex number
|
|
32
|
+
* //IMPROVE: Potential speed boost by just returning i.
|
|
33
|
+
*
|
|
34
|
+
* @param x
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
export declare function polarForm(x: Expression): Expression;
|
|
38
|
+
/**
|
|
39
|
+
* Attempts to convert a polar form complex to rectangular form. If no exact identity
|
|
40
|
+
* is found, the decimal representation in rectangular form is returned.
|
|
41
|
+
*
|
|
42
|
+
* @param x
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
export declare function rectForm(x: ExpressionInput): Expression;
|
|
46
|
+
/**
|
|
47
|
+
* Returns the argument of an expression
|
|
48
|
+
*
|
|
49
|
+
* @param x
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
export declare function arg(x: ExpressionInput): Expression;
|
|
53
|
+
/**
|
|
54
|
+
* Returns the complex conjugate of an expression.
|
|
55
|
+
* For a complex number z = a + bi, the conjugate is a - bi.
|
|
56
|
+
* Distributes over sums, products, integer powers, and powers whose
|
|
57
|
+
* constant base is known not to lie on the principal logarithm's branch cut.
|
|
58
|
+
*
|
|
59
|
+
* @param expr - The expression to conjugate
|
|
60
|
+
* @returns The complex conjugate of the expression
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* conjugate('3+2*i') // 3-2*i
|
|
64
|
+
* conjugate('i') // -i
|
|
65
|
+
* conjugate('a+b*i') // a-b*i
|
|
66
|
+
* conjugate('(1+i)^i') // (1-i)^(-i)
|
|
67
|
+
*/
|
|
68
|
+
export declare function conjugate(x: ExpressionInput): Expression;
|
|
69
|
+
/**
|
|
70
|
+
* Returns the complex signum (csgn) of an expression, following the
|
|
71
|
+
* Maple/SymPy convention. Returns 1 if Re(z) > 0, -1 if Re(z) < 0,
|
|
72
|
+
* and sgn(Im(z)) if Re(z) = 0. Returns 0 for z = 0.
|
|
73
|
+
*
|
|
74
|
+
* For expressions containing free variables where the sign cannot be
|
|
75
|
+
* determined, returns an unevaluated symbolic csgn(z).
|
|
76
|
+
*
|
|
77
|
+
* Useful for branch cut decisions in sqrt, log, and power simplification.
|
|
78
|
+
*
|
|
79
|
+
* @param expr - The expression to evaluate the complex sign of
|
|
80
|
+
* @returns 1, -1, 0, or an unevaluated csgn expression
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* csgn('3+2*i') // 1
|
|
84
|
+
* csgn('-1+3*i') // -1
|
|
85
|
+
* csgn('2*i') // 1
|
|
86
|
+
* csgn('-5*i') // -1
|
|
87
|
+
* csgn('0') // 0
|
|
88
|
+
* csgn('x+2*i') // csgn(x+2*i)
|
|
89
|
+
*/
|
|
90
|
+
export declare function csgn(x: ExpressionInput): Expression;
|