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,673 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.power = power;
|
|
4
|
+
exports.setPower = setPower;
|
|
5
|
+
exports.sqrtToPow = sqrtToPow;
|
|
6
|
+
exports.powToSqrt = powToSqrt;
|
|
7
|
+
exports.nthPow = nthPow;
|
|
8
|
+
exports.rationalizeRadical = rationalizeRadical;
|
|
9
|
+
const math_1 = require("../../../../math/math");
|
|
10
|
+
const trig_1 = require("../../../../math/trig");
|
|
11
|
+
const errors_1 = require("../../../errors");
|
|
12
|
+
const bigint_1 = require("../../../functions/bigint/bigint");
|
|
13
|
+
const bigint_2 = require("../../../functions/bigint/bigint");
|
|
14
|
+
const primeFactor_1 = require("../../../functions/bigint/primeFactor");
|
|
15
|
+
const complex_1 = require("../../../functions/complex");
|
|
16
|
+
const complex_2 = require("../../../functions/complex");
|
|
17
|
+
const Settings_1 = require("../../../Settings");
|
|
18
|
+
const Expression_1 = require("../../expression/Expression");
|
|
19
|
+
const shortcuts_1 = require("../../expression/shortcuts");
|
|
20
|
+
const utils_1 = require("../../expression/utils");
|
|
21
|
+
const constants_1 = require("../constants");
|
|
22
|
+
const compare_1 = require("./compare");
|
|
23
|
+
const multiply_1 = require("./multiply");
|
|
24
|
+
const reciprocalFunctions = {
|
|
25
|
+
[constants_1.COS]: constants_1.SEC,
|
|
26
|
+
[constants_1.SEC]: constants_1.COS,
|
|
27
|
+
[constants_1.SIN]: constants_1.CSC,
|
|
28
|
+
[constants_1.CSC]: constants_1.SIN,
|
|
29
|
+
[constants_1.TAN]: constants_1.COT,
|
|
30
|
+
[constants_1.COT]: constants_1.TAN,
|
|
31
|
+
[constants_1.COSH]: constants_1.SECH,
|
|
32
|
+
[constants_1.SECH]: constants_1.COSH,
|
|
33
|
+
[constants_1.SINH]: constants_1.CSCH,
|
|
34
|
+
[constants_1.CSCH]: constants_1.SINH,
|
|
35
|
+
[constants_1.TANH]: constants_1.COTH,
|
|
36
|
+
[constants_1.COTH]: constants_1.TANH,
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* IMPORTANT: Expressions of type EXP carry a sign in their value.
|
|
40
|
+
* @param a
|
|
41
|
+
* @param b
|
|
42
|
+
* @returns
|
|
43
|
+
*/
|
|
44
|
+
function power(a, b) {
|
|
45
|
+
let retval;
|
|
46
|
+
if (a.isZero() && b.isZero()) {
|
|
47
|
+
throw new errors_1.ZeroToZeroPowerError((0, errors_1.message)('zeroToZeroPower'));
|
|
48
|
+
}
|
|
49
|
+
if (Settings_1.Settings.DEFER_SIMPLIFICATION) {
|
|
50
|
+
retval = new Expression_1.Expression(a);
|
|
51
|
+
// Convert it to an EXP
|
|
52
|
+
retval = Expression_1.Expression.toEXP(retval, new Expression_1.Expression(b));
|
|
53
|
+
retval.deferred = true;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Simplify powers of i immediately
|
|
57
|
+
if (a.isI() && b.isInteger()) {
|
|
58
|
+
retval = (0, complex_1.simplifyImaginary)(setPower(a, b));
|
|
59
|
+
}
|
|
60
|
+
// Handle e^(i*pi)
|
|
61
|
+
else if (a.isE() && b.isComplex()) {
|
|
62
|
+
const p = new Expression_1.Expression(b);
|
|
63
|
+
const m = p.getMultiplier();
|
|
64
|
+
delete p.multiplier;
|
|
65
|
+
if ((0, compare_1.equal)(p, `${Expression_1.Expression.imaginary}*${constants_1.PI[0]}`)) {
|
|
66
|
+
if (m.isInteger()) {
|
|
67
|
+
const sgn = Expression_1.Expression.Number(m.evenNumerator() ? '1' : '-1');
|
|
68
|
+
retval = (0, multiply_1.multiply)(Expression_1.Expression.fromRational(a.getMultiplier()), sgn);
|
|
69
|
+
}
|
|
70
|
+
else if (m.denominator.toString() === '2') {
|
|
71
|
+
const sgn = Expression_1.Expression.Number(m.abs().mod('4').numerator === 1n ? '1' : '-1');
|
|
72
|
+
// Remember that this only occur for odd numerators
|
|
73
|
+
retval = (0, multiply_1.multiply)((0, multiply_1.multiply)(Expression_1.Expression.fromRational(a.getMultiplier()), Expression_1.Expression.Img()), sgn);
|
|
74
|
+
if (m.isNegative()) {
|
|
75
|
+
retval = retval.neg();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Evaluate the expression if requested
|
|
81
|
+
else if (Settings_1.Settings.EVALUATE) {
|
|
82
|
+
// Reciprocal function naming is an evaluation-time canonicalization. Keep
|
|
83
|
+
// ordinary parsing in power form so symbolic cancellation is unaffected.
|
|
84
|
+
if (a.isFunction() &&
|
|
85
|
+
b.isMinusOne() &&
|
|
86
|
+
a.getMultiplier().isOne() &&
|
|
87
|
+
a.getPower().isOne() &&
|
|
88
|
+
reciprocalFunctions[a.name]) {
|
|
89
|
+
retval = Expression_1.Expression.toFunction(reciprocalFunctions[a.name], a.getArguments());
|
|
90
|
+
}
|
|
91
|
+
// Deal with cases where evaluate is called
|
|
92
|
+
else if (a.isNUM() && b.isNUM()) {
|
|
93
|
+
// Check if it's a negative number
|
|
94
|
+
const isNegative = a.sign() === -1;
|
|
95
|
+
// Check if it's inverted
|
|
96
|
+
const inverted = b.sign() === -1;
|
|
97
|
+
// Get the base and exponent and positive numbers
|
|
98
|
+
let base = a.abs();
|
|
99
|
+
const exponent = b.abs();
|
|
100
|
+
// First simplify if a or be is negative
|
|
101
|
+
if (isNegative) {
|
|
102
|
+
let theta = exponent.times(Expression_1.Expression.Pi());
|
|
103
|
+
// If the power is negative then invert the base and negate the theta
|
|
104
|
+
if (inverted) {
|
|
105
|
+
base = base.invert();
|
|
106
|
+
theta = theta.neg();
|
|
107
|
+
}
|
|
108
|
+
const c = Expression_1.Expression.Number(base.getMultiplier().toDecimal().pow(exponent.getMultiplier().toDecimal()));
|
|
109
|
+
const re = (0, trig_1.cos)(theta).times(c);
|
|
110
|
+
const im = (0, trig_1.sin)(theta).times(c).times(Expression_1.Expression.Img());
|
|
111
|
+
retval = re.plus(im);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
retval = Expression_1.Expression.fromRational(base.getMultiplier().pow(exponent.getMultiplier()));
|
|
115
|
+
// Flip it back if it's inverted.
|
|
116
|
+
if (inverted) {
|
|
117
|
+
retval = retval.invert();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Complex numbers e.g. 6+i
|
|
122
|
+
else if (a.isComplex()) {
|
|
123
|
+
if (b.isComplex()) {
|
|
124
|
+
const [r, theta] = (0, complex_2.toPolarFormArray)(a);
|
|
125
|
+
const re = (0, complex_1.realPart)(b);
|
|
126
|
+
const im = (0, complex_1.imagPart)(b);
|
|
127
|
+
const q = re.times(theta).plus(im.times((0, math_1.log)(r)));
|
|
128
|
+
retval = power(r, re)
|
|
129
|
+
.times(Expression_1.Expression.E().pow(im.neg().times(theta)))
|
|
130
|
+
.times((0, trig_1.cos)(q).plus(Expression_1.Expression.Img().times((0, trig_1.sin)(q))));
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// TODO: Move this to its own function - complexToTrig
|
|
134
|
+
const base = a.distributeMultiplier();
|
|
135
|
+
const [rp, tp] = (0, complex_2.toPolarFormArray)(base);
|
|
136
|
+
const theta = tp.times(b);
|
|
137
|
+
const r = rp.pow(b);
|
|
138
|
+
retval = r.times((0, trig_1.cos)(theta)).plus(r.times(Expression_1.Expression.Img().times((0, trig_1.sin)(theta))));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Complex power e.g. e^(i+2)
|
|
142
|
+
// For the expression in the form c*n^(re+im*i) apply the formula
|
|
143
|
+
// c*n^re*cos(log(n^im))+c*n^re*sin(log(n^im))*i
|
|
144
|
+
else if (b.isComplex()) {
|
|
145
|
+
const n = a.pow(b.realPart());
|
|
146
|
+
const x = a.pow(b.imagPart());
|
|
147
|
+
retval = n.times((0, trig_1.cos)((0, math_1.log)(x))).plus(n.times((0, trig_1.sin)((0, math_1.log)(x))).times(Expression_1.Expression.Img()));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Store check since it occurs on almost every check and definitely on the first.
|
|
152
|
+
const bIsInf = b.isInf();
|
|
153
|
+
// Handle one but not Infinity. 1^n = 1
|
|
154
|
+
if (a.isOne() && !bIsInf) {
|
|
155
|
+
retval = (0, shortcuts_1.one)();
|
|
156
|
+
}
|
|
157
|
+
// Handle zero but leave infinity for later
|
|
158
|
+
else if (a.isZero() && !(bIsInf || b.isZero())) {
|
|
159
|
+
retval = Expression_1.Expression.Number('0');
|
|
160
|
+
}
|
|
161
|
+
// Leave numbers and infinity for later.
|
|
162
|
+
else if (b.isZero() && !(a.isInf() || a.isNUM())) {
|
|
163
|
+
retval = (0, shortcuts_1.one)();
|
|
164
|
+
}
|
|
165
|
+
else if (b.isOne()) {
|
|
166
|
+
retval = new Expression_1.Expression(a);
|
|
167
|
+
}
|
|
168
|
+
else if (a.isInf() || bIsInf) {
|
|
169
|
+
const aIsInf = a.isInf();
|
|
170
|
+
const bIsInf = b.isInf();
|
|
171
|
+
if (aIsInf && bIsInf) {
|
|
172
|
+
throw new errors_1.UndefinedError((0, errors_1.message)('infinityToInfinity'));
|
|
173
|
+
}
|
|
174
|
+
if (a.isNUM()) {
|
|
175
|
+
const m = a.getMultiplier();
|
|
176
|
+
// n^Inf
|
|
177
|
+
if ((m.gt('1') && b.isPosInf()) || (a.isPosInf() && b.isPosInf())) {
|
|
178
|
+
// It's Infinity for positive Infinity but zero otherwise
|
|
179
|
+
retval = Expression_1.Expression.Inf();
|
|
180
|
+
}
|
|
181
|
+
else if ((m.gt('1') && b.isNegInf()) || (m.eq('0') && b.isPosInf())) {
|
|
182
|
+
retval = Expression_1.Expression.Number('0');
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
throw new errors_1.UndefinedError((0, errors_1.message)('valueToInfinityUndefined', {
|
|
186
|
+
value: m.lt('0') ? `(${a})` : `${a}`,
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (b.isZero()) {
|
|
191
|
+
throw new errors_1.UndefinedError((0, errors_1.message)('infinityToPowerZero'));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Integer powers can be distributed across products without changing branches.
|
|
195
|
+
else if (a.isProduct() &&
|
|
196
|
+
((a.isLinear() && b.isInteger()) ||
|
|
197
|
+
(a.isConstant() && !a.isComplex() && a.sign() > 0))) {
|
|
198
|
+
retval = Expression_1.Expression.fromRational(a.getMultiplier()).pow(b);
|
|
199
|
+
const elements = a.getElements();
|
|
200
|
+
for (const x in elements) {
|
|
201
|
+
retval = retval.times(elements[x].pow(b));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// Positive real magnitude does not change the principal argument, so it
|
|
205
|
+
// can be pulled out of a noninteger power. Keep a negative sign attached
|
|
206
|
+
// to the symbolic part instead of raising that sign separately.
|
|
207
|
+
else if (b.isNUM() &&
|
|
208
|
+
!b.isInteger() &&
|
|
209
|
+
!a.isNUM() &&
|
|
210
|
+
!a.getMultiplier().abs().isOne()) {
|
|
211
|
+
const m = a.getMultiplier();
|
|
212
|
+
const magnitude = m.abs();
|
|
213
|
+
let base = a.toUnitMultiplier();
|
|
214
|
+
if (m.isNegative()) {
|
|
215
|
+
base = base.neg();
|
|
216
|
+
}
|
|
217
|
+
retval = power(base, b).times(power(Expression_1.Expression.fromRational(magnitude), b));
|
|
218
|
+
}
|
|
219
|
+
// Positive real factors can be pulled out of a principal power even when
|
|
220
|
+
// the remaining product has an unknown branch. Keep all other factors
|
|
221
|
+
// grouped so their combined argument is preserved.
|
|
222
|
+
else if (b.isNUM() && !b.isInteger() && a.isProduct() && a.isLinear()) {
|
|
223
|
+
let extracted = (0, shortcuts_1.one)();
|
|
224
|
+
let remainder = (0, shortcuts_1.one)();
|
|
225
|
+
let changed = false;
|
|
226
|
+
for (const element of a.elementsArray()) {
|
|
227
|
+
if (!element.isComplex() && element.gt(0)) {
|
|
228
|
+
extracted = extracted.times(power(element, b));
|
|
229
|
+
changed = true;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
remainder = remainder.times(element);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (changed) {
|
|
236
|
+
retval = remainder.isOne() ? extracted : extracted.times(power(remainder, b));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else if (b.isNUM()) {
|
|
240
|
+
// 0^n where n > 0
|
|
241
|
+
if (a.isZero()) {
|
|
242
|
+
retval = Expression_1.Expression.Number('0');
|
|
243
|
+
}
|
|
244
|
+
else if (a.isMinusOne() && b.isInteger() && b.isOdd()) {
|
|
245
|
+
retval = (0, shortcuts_1.one)().neg();
|
|
246
|
+
}
|
|
247
|
+
// n^0 is 1 for any number
|
|
248
|
+
else if (b.isZero()) {
|
|
249
|
+
retval = (0, shortcuts_1.one)();
|
|
250
|
+
}
|
|
251
|
+
// Simplify exponential functions which aren't numbers and the exponent is an integer
|
|
252
|
+
else if (a.isEXP() && !a.getBase().isNUM() && b.isInteger()) {
|
|
253
|
+
const p = (0, multiply_1.multiply)(a.getPower(), b);
|
|
254
|
+
if (p.isOne()) {
|
|
255
|
+
retval = a.getBase().times(a.getMultiplier());
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
retval = new Expression_1.Expression(a);
|
|
259
|
+
retval.power = p;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
// We know that b is a number so we only need to deal with its multiplier
|
|
264
|
+
const exponent = b.abs();
|
|
265
|
+
const p = exponent.getMultiplier();
|
|
266
|
+
const pow = p.numerator;
|
|
267
|
+
const root = p.denominator;
|
|
268
|
+
// First deal with the multiplier
|
|
269
|
+
const m = a.getMultiplier().abs();
|
|
270
|
+
const n = m.numerator ** pow;
|
|
271
|
+
const d = m.denominator ** pow;
|
|
272
|
+
// Raise it to the power and then pull the roots. This will be wrapped in Expressions
|
|
273
|
+
// If the number is too large then this will hang. Provide a warning and exit
|
|
274
|
+
if (n <= Settings_1.Settings.MAX_FRAC_INT && d <= Settings_1.Settings.MAX_FRAC_INT) {
|
|
275
|
+
const num = nthPow(n, root);
|
|
276
|
+
const den = nthPow(d, root);
|
|
277
|
+
const evenPow = (0, bigint_1.isEven)(pow);
|
|
278
|
+
// printE({ num: num, den: den, sign: b.sign() });
|
|
279
|
+
// Rebuild the coefficient
|
|
280
|
+
// Use:
|
|
281
|
+
let c;
|
|
282
|
+
if (b.sign() === -1) {
|
|
283
|
+
c = den.times(num.invert());
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
c = num.times(den.invert());
|
|
287
|
+
}
|
|
288
|
+
// A negative sign is part of the principal argument for noninteger
|
|
289
|
+
// powers. Positive magnitude has already been extracted for symbolic
|
|
290
|
+
// bases, while numeric bases keep their exact magnitude in c.
|
|
291
|
+
if (root !== 1n && !a.isNUM() && a.getMultiplier().isNegative()) {
|
|
292
|
+
retval = Expression_1.Expression.toEXP(new Expression_1.Expression(a), b);
|
|
293
|
+
retval = retval.times(c);
|
|
294
|
+
retval = rationalizeRadical(retval);
|
|
295
|
+
}
|
|
296
|
+
else if (root !== 1n && root !== 2n && a.isNUM() && a.sign() === -1) {
|
|
297
|
+
retval = Expression_1.Expression.toEXP((0, shortcuts_1.minusOne)(), b).times(c);
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
retval = a.toUnitMultiplier();
|
|
301
|
+
if (retval.isOne() && a.sign() === -1 && root === 2n) {
|
|
302
|
+
retval = retval.times(Expression_1.Expression.Img());
|
|
303
|
+
// Negate for alternating odd powers. Negative exponents use the
|
|
304
|
+
// reciprocal principal value, so the imaginary phase is inverted too.
|
|
305
|
+
if (pow % 4n === 3n) {
|
|
306
|
+
retval = retval.neg();
|
|
307
|
+
}
|
|
308
|
+
if (b.sign() === -1) {
|
|
309
|
+
retval = retval.invert();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
// NOTE: This is one of the issues that arises with the schema being used with the library. Ideally, the power
|
|
314
|
+
// on any variable is a power and the multiplier is factored our and treated separately. We run into a problem
|
|
315
|
+
// with even roots which cannot factor out the multiplier. In this case we cast the entire thing to an EXP e.g. (-x)^(1/2)
|
|
316
|
+
if (a.sign() === -1 && !evenPow) {
|
|
317
|
+
retval = retval.neg();
|
|
318
|
+
const bIsInteger = b.isInteger();
|
|
319
|
+
// Finalize the normalized variable. The coefficient has already been
|
|
320
|
+
// raised into c and must not be reintroduced here.
|
|
321
|
+
if (a.isVAR() && bIsInteger) {
|
|
322
|
+
retval = Expression_1.Expression.setPower(retval, b);
|
|
323
|
+
}
|
|
324
|
+
else if (!(retval.isMinusOne() && bIsInteger)) {
|
|
325
|
+
retval = Expression_1.Expression.toEXP(retval, b);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
const innerPower = retval.getPower();
|
|
330
|
+
const p = innerPower.times(b);
|
|
331
|
+
if (p.isZero()) {
|
|
332
|
+
retval = (0, shortcuts_1.one)();
|
|
333
|
+
}
|
|
334
|
+
else if (p.isNUM()) {
|
|
335
|
+
const innerMagnitude = innerPower.getMultiplier().abs();
|
|
336
|
+
const canCombine = b.isInteger() || innerPower.isOne() || innerMagnitude.lt('1');
|
|
337
|
+
// An even integer power of a real expression is nonnegative. For a
|
|
338
|
+
// noninteger outer power, preserve that fact explicitly with abs().
|
|
339
|
+
if (!b.isInteger() &&
|
|
340
|
+
innerPower.isInteger() &&
|
|
341
|
+
innerPower.isEven() &&
|
|
342
|
+
!(0, utils_1.stripPower)(retval).isComplex()) {
|
|
343
|
+
retval = (0, math_1.abs)((0, utils_1.stripPower)(retval));
|
|
344
|
+
retval = Expression_1.Expression.setPower(retval, p);
|
|
345
|
+
}
|
|
346
|
+
else if (canCombine) {
|
|
347
|
+
if (retval.isEXP()) {
|
|
348
|
+
retval = power(retval.getBase(), p).times(retval.getMultiplier());
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
// The abs is redundant for even powers.
|
|
352
|
+
if (retval.isFunction(constants_1.ABS)) {
|
|
353
|
+
if ((0, bigint_1.isEven)(p.getMultiplier().numerator)) {
|
|
354
|
+
retval = retval
|
|
355
|
+
.getArguments()[0]
|
|
356
|
+
.times(retval.getMultiplier());
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
retval = Expression_1.Expression.setPower(retval, p);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
retval = Expression_1.Expression.toEXP(retval, b);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// ** Cannot simplify since more info about x is required. Just return EXP
|
|
367
|
+
else if (!retval.getPower().isNUM()) {
|
|
368
|
+
retval = Expression_1.Expression.toEXP(retval, b);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
// Otherwise we're dealing with an EXP. Set powerLess to true to delete the power when creating the EXP
|
|
372
|
+
retval = Expression_1.Expression.toEXP(retval, p, true);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
retval = retval.times(c);
|
|
377
|
+
retval = rationalizeRadical(retval);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// Deal with all cases involving Infinity
|
|
383
|
+
// https://www.superprof.co.uk/resources/academic/maths/calculus/limits/properties-of-infinity.html
|
|
384
|
+
else if (a.isInf() || b.isInf()) {
|
|
385
|
+
const aIsInf = a.isInf();
|
|
386
|
+
const bIsInf = b.isInf();
|
|
387
|
+
if (aIsInf && bIsInf) {
|
|
388
|
+
throw new errors_1.UndefinedError((0, errors_1.message)('infinityToInfinity'));
|
|
389
|
+
}
|
|
390
|
+
if (a.isNUM()) {
|
|
391
|
+
const m = a.getMultiplier();
|
|
392
|
+
// n^Inf
|
|
393
|
+
if ((m.gt('1') && b.isPosInf()) || (a.isPosInf() && b.isPosInf())) {
|
|
394
|
+
// It's Infinity for positive Infinity but zero otherwise
|
|
395
|
+
retval = Expression_1.Expression.Inf();
|
|
396
|
+
}
|
|
397
|
+
else if ((m.gt('1') && b.isNegInf()) || (m.eq('0') && b.isPosInf())) {
|
|
398
|
+
retval = Expression_1.Expression.Number('0');
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
throw new errors_1.UndefinedError((0, errors_1.message)('valueToInfinityUndefined', {
|
|
402
|
+
value: m.lt('0') ? `(${a})` : `${a}`,
|
|
403
|
+
}));
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
else if (b.isZero()) {
|
|
407
|
+
throw new errors_1.UndefinedError((0, errors_1.message)('infinityToPowerZero'));
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
const p = a.getPower();
|
|
412
|
+
const pow = b.times(p);
|
|
413
|
+
if (p.isNUM() && !pow.isNUM()) {
|
|
414
|
+
const m = a.getMultiplier();
|
|
415
|
+
const absPower = p.getMultiplier().abs();
|
|
416
|
+
const base = (0, utils_1.stripPower)(a.toUnitMultiplier());
|
|
417
|
+
// An even integer power of a real expression is nonnegative, so it can
|
|
418
|
+
// be represented through abs() before applying a symbolic outer power.
|
|
419
|
+
if (!m.isNegative() &&
|
|
420
|
+
p.isInteger() &&
|
|
421
|
+
p.isEven() &&
|
|
422
|
+
!base.isComplex()) {
|
|
423
|
+
retval = (0, math_1.abs)(base);
|
|
424
|
+
retval = Expression_1.Expression.toEXP(retval, pow);
|
|
425
|
+
if (!m.isOne()) {
|
|
426
|
+
retval = retval.times(Expression_1.Expression.toEXP(Expression_1.Expression.fromRational(m), b));
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
// A real inner power with magnitude below one stays inside the
|
|
430
|
+
// principal argument range, so roots can still combine with a
|
|
431
|
+
// symbolic outer power. Power one is the trivial safe case.
|
|
432
|
+
else if (!m.isNegative() && (p.isOne() || absPower.lt('1'))) {
|
|
433
|
+
retval = Expression_1.Expression.toEXP(base, pow);
|
|
434
|
+
if (!m.isOne()) {
|
|
435
|
+
retval = retval.times(Expression_1.Expression.toEXP(Expression_1.Expression.fromRational(m), b));
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// If not handled then just return a^b. This ensures that we're always returning a
|
|
442
|
+
// Expression raised to a power
|
|
443
|
+
if (!retval) {
|
|
444
|
+
retval = setPower(a, b);
|
|
445
|
+
}
|
|
446
|
+
// This can be in simplify but yields better overall results when kept here.
|
|
447
|
+
if (retval.isI()) {
|
|
448
|
+
retval = (0, complex_1.simplifyImaginary)(retval);
|
|
449
|
+
}
|
|
450
|
+
if (a.hasDecimal()) {
|
|
451
|
+
const decimalCarrier = retval.isEXP() ? retval.getBase() : retval;
|
|
452
|
+
decimalCarrier.getMultiplier().asDecimal = true;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return retval;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Sets the power of a Expression by converting it to an exponential.
|
|
459
|
+
* This functions assumes that no negatives roots or exponents are provided.
|
|
460
|
+
* If EVALUATE is set it returns the evaluate value
|
|
461
|
+
*
|
|
462
|
+
* @param a
|
|
463
|
+
* @param b
|
|
464
|
+
*/
|
|
465
|
+
function setPower(a, b) {
|
|
466
|
+
let retval;
|
|
467
|
+
/**
|
|
468
|
+
* Although numbers can technically carry a Rational as their power, we'll just have them
|
|
469
|
+
* be an EXP instead. This eliminates the need to create another type to bridge numbers
|
|
470
|
+
* with a power != 1 and other types. We start with b == NUM
|
|
471
|
+
*/
|
|
472
|
+
if (Settings_1.Settings.EVALUATE &&
|
|
473
|
+
a.isNUM() &&
|
|
474
|
+
b.isNUM() &&
|
|
475
|
+
!a.getMultiplier().isNegative() &&
|
|
476
|
+
!b.getMultiplier().isNegative()) {
|
|
477
|
+
retval = Expression_1.Expression.fromRational(a.getMultiplier().pow(b.getMultiplier()));
|
|
478
|
+
}
|
|
479
|
+
else if (a.isNUM()) {
|
|
480
|
+
retval = Expression_1.Expression.toEXP(a.getMultiplier(), b);
|
|
481
|
+
}
|
|
482
|
+
else if (b.isNUM() && !a.isEXP()) {
|
|
483
|
+
retval = a.toUnitMultiplier();
|
|
484
|
+
// (2*x)^2 = 4*x^2 or 2^-2 = 1/4
|
|
485
|
+
const sgn = b.getMultiplier().sign();
|
|
486
|
+
// Get the absolute value so we can pull the power and then we'll invert it back.
|
|
487
|
+
const exponent = b.getMultiplier().abs();
|
|
488
|
+
let m = a.getMultiplier();
|
|
489
|
+
// Think sqrt((-y)^2)
|
|
490
|
+
if (m.isNegative()) {
|
|
491
|
+
// Pull the power
|
|
492
|
+
retval.power = retval.getPower().times(exponent);
|
|
493
|
+
// Move the negative sign out
|
|
494
|
+
retval = retval.times((0, shortcuts_1.minusOne)().pow(exponent));
|
|
495
|
+
// Remove the sign from the multiplier
|
|
496
|
+
m = m.abs();
|
|
497
|
+
}
|
|
498
|
+
// Preserve only the sign contribution that may have been pulled out above.
|
|
499
|
+
// The magnitude is rebuilt from m so it is not counted twice.
|
|
500
|
+
const multiplier = m.pow(exponent);
|
|
501
|
+
retval.multiplier = retval.getMultiplier().isNegative() ? multiplier.neg() : multiplier;
|
|
502
|
+
if (sgn === -1) {
|
|
503
|
+
retval.multiplier = retval.getMultiplier().invert();
|
|
504
|
+
}
|
|
505
|
+
retval = Expression_1.Expression.setPower(retval, a.getPower().times(b.getMultiplier()));
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
// See if a nested power can be simplified without crossing the
|
|
509
|
+
// principal branch. A positive real base raised to a real power stays
|
|
510
|
+
// positive, so symbolic exponent cancellation is safe in that case.
|
|
511
|
+
const p = a.getPower().times(b);
|
|
512
|
+
if (p.isNUM() &&
|
|
513
|
+
a.isEXP() &&
|
|
514
|
+
!a.getBase().isComplex() &&
|
|
515
|
+
a.getBase().gt(0) &&
|
|
516
|
+
(0, complex_1.imagPart)(a.getPower()).isZero()) {
|
|
517
|
+
retval = power(a.getBase(), p).times(a.getMultiplier());
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
const m = a.getMultiplier();
|
|
521
|
+
const magnitude = m.abs();
|
|
522
|
+
let base = a.toUnitMultiplier();
|
|
523
|
+
// Positive real magnitude can always be factored from a principal
|
|
524
|
+
// power. Keep a negative sign attached to the symbolic base because
|
|
525
|
+
// separating it would change the principal argument.
|
|
526
|
+
if (m.isNegative()) {
|
|
527
|
+
base = base.neg();
|
|
528
|
+
}
|
|
529
|
+
retval = Expression_1.Expression.toEXP(base, b);
|
|
530
|
+
if (!magnitude.isOne()) {
|
|
531
|
+
retval = retval.times(Expression_1.Expression.toEXP(magnitude, b));
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return retval;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Converts the square root to power form
|
|
539
|
+
*
|
|
540
|
+
* @param x
|
|
541
|
+
*/
|
|
542
|
+
function sqrtToPow(x) {
|
|
543
|
+
let retval;
|
|
544
|
+
if (x.isFunction(constants_1.SQRT)) {
|
|
545
|
+
retval = new Expression_1.Expression(x.getArguments()[0]);
|
|
546
|
+
// The the power. Pass in true to get it as a Expression
|
|
547
|
+
const pow = x.getPower();
|
|
548
|
+
// set the power
|
|
549
|
+
retval = setPower(retval, pow.div((0, shortcuts_1.two)()));
|
|
550
|
+
// Put back the multiplier
|
|
551
|
+
retval.multiplier = x.getMultiplier().copy();
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
retval = new Expression_1.Expression(x);
|
|
555
|
+
}
|
|
556
|
+
return retval;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Converts a function from power to sqrt form
|
|
560
|
+
*
|
|
561
|
+
* @param x
|
|
562
|
+
*/
|
|
563
|
+
function powToSqrt(x) {
|
|
564
|
+
let retval;
|
|
565
|
+
if (x.power &&
|
|
566
|
+
x.power.dataType === constants_1.RATIONAL &&
|
|
567
|
+
(0, bigint_1.isEven)(x.getPower().getMultiplier().denominator)) {
|
|
568
|
+
// Create a temporary value with the power raised to two to remove 1/2n from the root
|
|
569
|
+
const t = power(x.toUnitMultiplier(), (0, shortcuts_1.two)());
|
|
570
|
+
// Wrap it in a function. Call it recursively to wrap any additional values in sqrt as well.
|
|
571
|
+
retval = Expression_1.Expression.toFunction(constants_1.SQRT, [powToSqrt(t)]);
|
|
572
|
+
// Put back the multiplier
|
|
573
|
+
retval.multiplier = x.getMultiplier().copy();
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
retval = new Expression_1.Expression(x);
|
|
577
|
+
}
|
|
578
|
+
return retval;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Removes factors of two.
|
|
582
|
+
*
|
|
583
|
+
* @param n
|
|
584
|
+
* @returns
|
|
585
|
+
*/
|
|
586
|
+
function nthPow(x, root) {
|
|
587
|
+
let retval;
|
|
588
|
+
if (root === 1n && typeof x === 'bigint') {
|
|
589
|
+
retval = Expression_1.Expression.Number(x);
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
let w = 1n;
|
|
593
|
+
const rem = {};
|
|
594
|
+
// We first grab all the prime factors. We can then start placing them back.
|
|
595
|
+
// Let's take 4320 as an example. The counts will be 2: 5n, 3: 3n, 5: 1n. The factor 2 has 2 perfect
|
|
596
|
+
// squares 3 has 1 and 5 has 0. We divide those out and raise the factor to that square. It then gets
|
|
597
|
+
// multiplied to the whole.
|
|
598
|
+
const factorCounts = typeof x === 'bigint' ? (0, primeFactor_1.primeFactorCounts)(x) : x;
|
|
599
|
+
for (const factor in factorCounts) {
|
|
600
|
+
const count = factorCounts[factor];
|
|
601
|
+
const f = BigInt(factor);
|
|
602
|
+
// Divide out the perfect square and add them to the whole
|
|
603
|
+
const e = count / root;
|
|
604
|
+
// Remove the wholes and keep the remainder
|
|
605
|
+
const r = count - e * root;
|
|
606
|
+
// Add it to the wholes
|
|
607
|
+
w *= f ** e;
|
|
608
|
+
// Add the remainder to rem so we can have it in the form (factor)^(power/root)
|
|
609
|
+
if (r > 0n) {
|
|
610
|
+
rem[factor] = r;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
// Combine the like power & roots. Instead of having sqrt(3)*sqrt(2), we combine it to sqrt(6)
|
|
614
|
+
const combined = {};
|
|
615
|
+
for (const factor in rem) {
|
|
616
|
+
const p = String(rem[factor]);
|
|
617
|
+
combined[p] = !combined[p] ? BigInt(factor) : BigInt(factor) * combined[p];
|
|
618
|
+
}
|
|
619
|
+
// Wrap them in Expressions
|
|
620
|
+
retval = w === 1n ? (0, shortcuts_1.one)() : Expression_1.Expression.Number(w);
|
|
621
|
+
// Raise the remaining roots to the radical
|
|
622
|
+
for (const power in combined) {
|
|
623
|
+
const factor = combined[power];
|
|
624
|
+
const exponent = Expression_1.Expression.Number(BigInt(power)).div(Expression_1.Expression.Number(root));
|
|
625
|
+
retval = retval.times(Expression_1.Expression.toEXP(Expression_1.Expression.Number(factor), exponent));
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return retval;
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Rationalizes a numeric expression with a negative fractional power.
|
|
632
|
+
* Rewrites a^(-p/q) as a^((kq-p)/q) * a^(-k) where k = ceil(p/q),
|
|
633
|
+
* removing the radical from the denominator.
|
|
634
|
+
*
|
|
635
|
+
* Example: 5^(-2/3) → 5^(1/3) * 5^(-1) = 5^(1/3) / 5
|
|
636
|
+
*
|
|
637
|
+
* @param x An EXP expression like 5^(-2/3)
|
|
638
|
+
* @returns The rationalized expression
|
|
639
|
+
*/
|
|
640
|
+
function rationalizeRadical(x, canonical = false) {
|
|
641
|
+
if (!x.isEXP() || !x.hasRadical()) {
|
|
642
|
+
return x;
|
|
643
|
+
}
|
|
644
|
+
const m = x.getPower().getMultiplier();
|
|
645
|
+
// Only rationalize negative fractional powers
|
|
646
|
+
if (!m.isNegative()) {
|
|
647
|
+
return x;
|
|
648
|
+
}
|
|
649
|
+
const base = x.getBase();
|
|
650
|
+
// Get absolute values of numerator and denominator
|
|
651
|
+
const p = (0, bigint_2.abs)(m.numerator);
|
|
652
|
+
const q = (0, bigint_2.abs)(m.denominator);
|
|
653
|
+
// k = ceil(p/q)
|
|
654
|
+
const k = (p + q - 1n) / q;
|
|
655
|
+
// New radical power: (kq - p) / q
|
|
656
|
+
const newNum = k * q - p;
|
|
657
|
+
// Only rationalize if the result is simpler or equal,
|
|
658
|
+
// unless canonical mode is requested
|
|
659
|
+
if (!canonical && newNum > p) {
|
|
660
|
+
return x;
|
|
661
|
+
}
|
|
662
|
+
// Radical part: base^(newNum/q) — this has a positive fractional power
|
|
663
|
+
let radicalPart;
|
|
664
|
+
if (newNum === 0n) {
|
|
665
|
+
radicalPart = (0, shortcuts_1.one)();
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
radicalPart = base.pow(Expression_1.Expression.Number(newNum).div(Expression_1.Expression.Number(q)));
|
|
669
|
+
}
|
|
670
|
+
// Integer part: base^(-k)
|
|
671
|
+
const integerPart = base.pow(Expression_1.Expression.Number(-k));
|
|
672
|
+
return radicalPart.times(integerPart).times(x.getMultiplier());
|
|
673
|
+
}
|