solve-engine 1.1.0 → 1.2.0
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/dist/{EngineError-B61GS1jp.d.cts → EngineError-CNA_rHY-.d.cts} +6 -0
- package/dist/{EngineError-B61GS1jp.d.ts → EngineError-CNA_rHY-.d.ts} +6 -0
- package/dist/{Lexer-BOs7euZe.d.cts → Lexer-B4C1qHXu.d.cts} +1 -1
- package/dist/{Lexer-CSI_lwbW.d.ts → Lexer-DKMlj7Sy.d.ts} +1 -1
- package/dist/{PackageCompatibility-B-7rK1TD.d.cts → PackageCompatibility-B6NX9IaN.d.cts} +1 -1
- package/dist/{PackageCompatibility-Dh59eF-X.d.ts → PackageCompatibility-Ceg5XdAp.d.ts} +1 -1
- package/dist/{PackageRegistry-BHWJP83F.d.cts → PackageRegistry-DnJYVw9G.d.cts} +55 -8
- package/dist/{PackageRegistry-_8rDlvxI.d.ts → PackageRegistry-DrCPQNyy.d.ts} +55 -8
- package/dist/{Parselet-BBT8riYh.d.ts → Parselet-Bhf7d0_W.d.ts} +2 -2
- package/dist/{Parselet-BHcgK9S7.d.cts → Parselet-Cv7S7KRt.d.cts} +2 -2
- package/dist/{ScopeManager-CxA24W5n.d.ts → ScopeManager-Bzq87GfA.d.ts} +10 -3
- package/dist/{ScopeManager-8vf02dwj.d.cts → ScopeManager-DRDBVfan.d.cts} +10 -3
- package/dist/{Token-B1hdkedD.d.cts → Token-CbP_OutD.d.cts} +9 -0
- package/dist/{Token-B1hdkedD.d.ts → Token-CbP_OutD.d.ts} +9 -0
- package/dist/{TokenNormalizer-C6VzZgHa.d.ts → TokenNormalizer-DCWdZjGz.d.ts} +1 -1
- package/dist/{TokenNormalizer-DRc1Js1V.d.cts → TokenNormalizer-DnlL7_8c.d.cts} +1 -1
- package/dist/{VMCheckpoints-MK--EBH2.d.ts → VMCheckpoints-C6c17Hbo.d.ts} +2 -2
- package/dist/{VMCheckpoints-ELYqITdF.d.cts → VMCheckpoints-dZxSMGHG.d.cts} +2 -2
- package/dist/{Value-BUi1RA3S.d.cts → Value-DZNQ_PU7.d.cts} +32 -5
- package/dist/{Value-BUi1RA3S.d.ts → Value-DZNQ_PU7.d.ts} +32 -5
- package/dist/{WorkerError-_-RkoQ5P.d.ts → WorkerError-B7t7R2-m.d.ts} +1 -1
- package/dist/{WorkerError-gzmaopj2.d.cts → WorkerError-Djd7GGGa.d.cts} +1 -1
- package/dist/{chunk-SSV46KFA.cjs → chunk-4K5W7EH2.cjs} +6 -6
- package/dist/{chunk-SSV46KFA.cjs.map → chunk-4K5W7EH2.cjs.map} +1 -1
- package/dist/{chunk-267JPOTF.js → chunk-5EFKSKMA.js} +11 -4
- package/dist/chunk-5EFKSKMA.js.map +1 -0
- package/dist/{chunk-536WPM2V.cjs → chunk-7AXJNQMF.cjs} +17 -3
- package/dist/chunk-7AXJNQMF.cjs.map +1 -0
- package/dist/{chunk-GUG7SNSV.js → chunk-7JM3F4KL.js} +39 -8
- package/dist/chunk-7JM3F4KL.js.map +1 -0
- package/dist/{chunk-XJGJCF2R.cjs → chunk-7USV76HV.cjs} +6 -6
- package/dist/{chunk-XJGJCF2R.cjs.map → chunk-7USV76HV.cjs.map} +1 -1
- package/dist/{chunk-HIQ5HSZL.cjs → chunk-A2DZ5BEJ.cjs} +53 -46
- package/dist/{chunk-HIQ5HSZL.cjs.map → chunk-A2DZ5BEJ.cjs.map} +1 -1
- package/dist/{chunk-CKQMXMHR.cjs → chunk-AKNGX4TZ.cjs} +28 -11
- package/dist/chunk-AKNGX4TZ.cjs.map +1 -0
- package/dist/{chunk-I4GAWIPW.js → chunk-AOH6UR2L.js} +6 -6
- package/dist/{chunk-I4GAWIPW.js.map → chunk-AOH6UR2L.js.map} +1 -1
- package/dist/{chunk-MG6Q3DUO.cjs → chunk-BESTLPRK.cjs} +326 -214
- package/dist/chunk-BESTLPRK.cjs.map +1 -0
- package/dist/{chunk-Z7XGGLI2.js → chunk-BSPXMGIS.js} +3 -3
- package/dist/{chunk-Z7XGGLI2.js.map → chunk-BSPXMGIS.js.map} +1 -1
- package/dist/{chunk-SRGQ72IR.cjs → chunk-C2OMO3WN.cjs} +376 -370
- package/dist/chunk-C2OMO3WN.cjs.map +1 -0
- package/dist/{chunk-G7Z4HJQA.js → chunk-CSDQMDU2.js} +4 -4
- package/dist/{chunk-G7Z4HJQA.js.map → chunk-CSDQMDU2.js.map} +1 -1
- package/dist/{chunk-7KYSUDQO.js → chunk-F4UB4XIL.js} +4 -4
- package/dist/{chunk-7KYSUDQO.js.map → chunk-F4UB4XIL.js.map} +1 -1
- package/dist/{chunk-WXEHD6TT.js → chunk-FE4RC37D.js} +15 -9
- package/dist/chunk-FE4RC37D.js.map +1 -0
- package/dist/{chunk-7ZX6B7SY.cjs → chunk-FR7RNOPT.cjs} +637 -556
- package/dist/chunk-FR7RNOPT.cjs.map +1 -0
- package/dist/{chunk-QFTDTX6K.cjs → chunk-G2YPPLGX.cjs} +29 -2
- package/dist/chunk-G2YPPLGX.cjs.map +1 -0
- package/dist/{chunk-HVRVSI2Z.cjs → chunk-GDEU72RG.cjs} +86 -86
- package/dist/{chunk-HVRVSI2Z.cjs.map → chunk-GDEU72RG.cjs.map} +1 -1
- package/dist/{chunk-OTN6SZOD.cjs → chunk-HKTQCQ4Z.cjs} +860 -489
- package/dist/chunk-HKTQCQ4Z.cjs.map +1 -0
- package/dist/{chunk-XA4CKRML.cjs → chunk-HWHU642X.cjs} +2 -2
- package/dist/{chunk-XA4CKRML.cjs.map → chunk-HWHU642X.cjs.map} +1 -1
- package/dist/{chunk-C75AFGVD.cjs → chunk-ICEKS6YC.cjs} +11 -11
- package/dist/{chunk-C75AFGVD.cjs.map → chunk-ICEKS6YC.cjs.map} +1 -1
- package/dist/{chunk-JIPATHVY.js → chunk-IJGOFP2J.js} +138 -26
- package/dist/chunk-IJGOFP2J.js.map +1 -0
- package/dist/{chunk-ENKKJYD3.js → chunk-IQJGDZOP.js} +4 -4
- package/dist/{chunk-ENKKJYD3.js.map → chunk-IQJGDZOP.js.map} +1 -1
- package/dist/{chunk-2TZKENDH.cjs → chunk-IT74O4BE.cjs} +15 -7
- package/dist/chunk-IT74O4BE.cjs.map +1 -0
- package/dist/{chunk-ZVTWQLK4.cjs → chunk-KXDQKVNX.cjs} +10 -10
- package/dist/{chunk-ZVTWQLK4.cjs.map → chunk-KXDQKVNX.cjs.map} +1 -1
- package/dist/{chunk-JJIXHXFQ.js → chunk-L5YHV6BQ.js} +5 -5
- package/dist/{chunk-JJIXHXFQ.js.map → chunk-L5YHV6BQ.js.map} +1 -1
- package/dist/{chunk-ZXCESUJS.cjs → chunk-LO7HU5WB.cjs} +8 -8
- package/dist/{chunk-ZXCESUJS.cjs.map → chunk-LO7HU5WB.cjs.map} +1 -1
- package/dist/{chunk-UO6BUV6K.js → chunk-LSALB3IN.js} +17 -3
- package/dist/chunk-LSALB3IN.js.map +1 -0
- package/dist/{chunk-J45BCEZ4.cjs → chunk-MI7OTUHL.cjs} +27 -27
- package/dist/{chunk-J45BCEZ4.cjs.map → chunk-MI7OTUHL.cjs.map} +1 -1
- package/dist/{chunk-B4HBEFTB.cjs → chunk-MIGXCBXT.cjs} +8 -2
- package/dist/chunk-MIGXCBXT.cjs.map +1 -0
- package/dist/{chunk-ERCOHGXD.js → chunk-N7OA4WPJ.js} +8 -2
- package/dist/chunk-N7OA4WPJ.js.map +1 -0
- package/dist/{chunk-4D6NIHE2.js → chunk-NAWZATKT.js} +29 -2
- package/dist/chunk-NAWZATKT.js.map +1 -0
- package/dist/{chunk-GQMUHVE3.js → chunk-ORM7CHYZ.js} +36 -5
- package/dist/chunk-ORM7CHYZ.js.map +1 -0
- package/dist/{chunk-B7NLZMQ3.cjs → chunk-PCZVMMWU.cjs} +8 -8
- package/dist/{chunk-B7NLZMQ3.cjs.map → chunk-PCZVMMWU.cjs.map} +1 -1
- package/dist/{chunk-OADDUPT3.js → chunk-RNKDIXDV.js} +4 -4
- package/dist/{chunk-OADDUPT3.js.map → chunk-RNKDIXDV.js.map} +1 -1
- package/dist/{chunk-SNHVVOJK.cjs → chunk-TC6BTUSU.cjs} +55 -24
- package/dist/chunk-TC6BTUSU.cjs.map +1 -0
- package/dist/{chunk-RRLHC37V.js → chunk-TPOK3UNI.js} +387 -17
- package/dist/chunk-TPOK3UNI.js.map +1 -0
- package/dist/{chunk-CCBZZQAE.js → chunk-UF6JG5SG.js} +2 -2
- package/dist/{chunk-CCBZZQAE.js.map → chunk-UF6JG5SG.js.map} +1 -1
- package/dist/{chunk-NKW7LKYU.js → chunk-WMQRJTAO.js} +88 -7
- package/dist/chunk-WMQRJTAO.js.map +1 -0
- package/dist/{chunk-YTIYVHL7.cjs → chunk-YJHY7CMN.cjs} +108 -77
- package/dist/chunk-YJHY7CMN.cjs.map +1 -0
- package/dist/{chunk-3OWCDIPN.js → chunk-YNIWOYW6.js} +21 -4
- package/dist/chunk-YNIWOYW6.js.map +1 -0
- package/dist/{chunk-WWQEY7BV.js → chunk-ZN6YYPIW.js} +3 -3
- package/dist/{chunk-WWQEY7BV.js.map → chunk-ZN6YYPIW.js.map} +1 -1
- package/dist/{chunk-NNQ2TYDF.js → chunk-ZNFFTYWH.js} +11 -5
- package/dist/chunk-ZNFFTYWH.js.map +1 -0
- package/dist/constants.cjs +5 -5
- package/dist/constants.js +2 -2
- package/dist/engine.cjs +33 -33
- package/dist/engine.d.cts +27 -11
- package/dist/engine.d.ts +27 -11
- package/dist/engine.js +20 -20
- package/dist/errors.cjs +26 -26
- package/dist/errors.d.cts +3 -3
- package/dist/errors.d.ts +3 -3
- package/dist/errors.js +2 -2
- package/dist/format.cjs +7 -7
- package/dist/format.d.cts +1 -1
- package/dist/format.d.ts +1 -1
- package/dist/format.js +4 -4
- package/dist/index.cjs +48 -48
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +21 -21
- package/dist/language.cjs +7 -7
- package/dist/language.d.cts +10 -10
- package/dist/language.d.ts +10 -10
- package/dist/language.js +2 -2
- package/dist/lexer.cjs +16 -16
- package/dist/lexer.d.cts +3 -3
- package/dist/lexer.d.ts +3 -3
- package/dist/lexer.js +5 -5
- package/dist/normalizer.cjs +10 -10
- package/dist/normalizer.d.cts +3 -3
- package/dist/normalizer.d.ts +3 -3
- package/dist/normalizer.js +4 -4
- package/dist/packages.cjs +40 -36
- package/dist/packages.d.cts +37 -11
- package/dist/packages.d.ts +37 -11
- package/dist/packages.js +11 -11
- package/dist/parser.cjs +13 -13
- package/dist/parser.d.cts +4 -4
- package/dist/parser.d.ts +4 -4
- package/dist/parser.js +5 -5
- package/dist/{pipeline-CtfJtPQc.d.cts → pipeline-D-PS9gVw.d.ts} +3 -3
- package/dist/{pipeline-DCd5M6Gk.d.ts → pipeline-DtSBJ8TS.d.cts} +3 -3
- package/dist/resolvers.d.cts +2 -2
- package/dist/resolvers.d.ts +2 -2
- package/dist/testing.cjs +26 -26
- package/dist/testing.d.cts +10 -10
- package/dist/testing.d.ts +10 -10
- package/dist/testing.js +19 -19
- package/dist/uom.cjs +8 -8
- package/dist/uom.d.cts +2 -2
- package/dist/uom.d.ts +2 -2
- package/dist/uom.js +4 -4
- package/dist/vm.cjs +32 -32
- package/dist/vm.d.cts +7 -7
- package/dist/vm.d.ts +7 -7
- package/dist/vm.js +7 -7
- package/dist/worker.cjs +38 -38
- package/dist/worker.d.cts +10 -10
- package/dist/worker.d.ts +10 -10
- package/dist/worker.js +20 -20
- package/package.json +1 -1
- package/dist/chunk-267JPOTF.js.map +0 -1
- package/dist/chunk-2TZKENDH.cjs.map +0 -1
- package/dist/chunk-3OWCDIPN.js.map +0 -1
- package/dist/chunk-4D6NIHE2.js.map +0 -1
- package/dist/chunk-536WPM2V.cjs.map +0 -1
- package/dist/chunk-7ZX6B7SY.cjs.map +0 -1
- package/dist/chunk-B4HBEFTB.cjs.map +0 -1
- package/dist/chunk-CKQMXMHR.cjs.map +0 -1
- package/dist/chunk-ERCOHGXD.js.map +0 -1
- package/dist/chunk-GQMUHVE3.js.map +0 -1
- package/dist/chunk-GUG7SNSV.js.map +0 -1
- package/dist/chunk-JIPATHVY.js.map +0 -1
- package/dist/chunk-MG6Q3DUO.cjs.map +0 -1
- package/dist/chunk-NKW7LKYU.js.map +0 -1
- package/dist/chunk-NNQ2TYDF.js.map +0 -1
- package/dist/chunk-OTN6SZOD.cjs.map +0 -1
- package/dist/chunk-QFTDTX6K.cjs.map +0 -1
- package/dist/chunk-RRLHC37V.js.map +0 -1
- package/dist/chunk-SNHVVOJK.cjs.map +0 -1
- package/dist/chunk-SRGQ72IR.cjs.map +0 -1
- package/dist/chunk-UO6BUV6K.js.map +0 -1
- package/dist/chunk-WXEHD6TT.js.map +0 -1
- package/dist/chunk-YTIYVHL7.cjs.map +0 -1
|
@@ -1,63 +1,63 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkFEAIOR7N_cjs = require('./chunk-FEAIOR7N.cjs');
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
4
|
+
var chunkKXDQKVNX_cjs = require('./chunk-KXDQKVNX.cjs');
|
|
5
|
+
var chunkA2DZ5BEJ_cjs = require('./chunk-A2DZ5BEJ.cjs');
|
|
6
|
+
var chunkIT74O4BE_cjs = require('./chunk-IT74O4BE.cjs');
|
|
7
7
|
var chunkEJ3ILXX6_cjs = require('./chunk-EJ3ILXX6.cjs');
|
|
8
8
|
var chunkAMOJYLG2_cjs = require('./chunk-AMOJYLG2.cjs');
|
|
9
|
-
var
|
|
9
|
+
var chunkMIGXCBXT_cjs = require('./chunk-MIGXCBXT.cjs');
|
|
10
10
|
|
|
11
11
|
// src/symbolic/MultivariateFactor.ts
|
|
12
12
|
function exactRoot(value, degree) {
|
|
13
|
-
const rootOf = degree === 2 ?
|
|
13
|
+
const rootOf = degree === 2 ? chunkA2DZ5BEJ_cjs.exactIntegerSqrt : chunkA2DZ5BEJ_cjs.exactIntegerCbrt;
|
|
14
14
|
const numerator = rootOf(value.n);
|
|
15
15
|
const denominator = rootOf(value.d);
|
|
16
16
|
return numerator === null || denominator === null ? null : { n: numerator, d: denominator };
|
|
17
17
|
}
|
|
18
18
|
function monomialRoot(key, degree) {
|
|
19
|
-
const monomial =
|
|
19
|
+
const monomial = chunkA2DZ5BEJ_cjs.monomialFromKey(key);
|
|
20
20
|
const root = /* @__PURE__ */ new Map();
|
|
21
21
|
for (const [name, exponent] of monomial) {
|
|
22
22
|
if (exponent % degree !== 0) return null;
|
|
23
23
|
root.set(name, exponent / degree);
|
|
24
24
|
}
|
|
25
|
-
return
|
|
25
|
+
return chunkA2DZ5BEJ_cjs.monomialToKey(root);
|
|
26
26
|
}
|
|
27
27
|
function monomialMul(a, b) {
|
|
28
|
-
const product2 =
|
|
29
|
-
for (const [name, exponent] of
|
|
28
|
+
const product2 = chunkA2DZ5BEJ_cjs.monomialFromKey(a);
|
|
29
|
+
for (const [name, exponent] of chunkA2DZ5BEJ_cjs.monomialFromKey(b)) {
|
|
30
30
|
product2.set(name, (product2.get(name) ?? 0) + exponent);
|
|
31
31
|
}
|
|
32
|
-
return
|
|
32
|
+
return chunkA2DZ5BEJ_cjs.monomialToKey(product2);
|
|
33
33
|
}
|
|
34
34
|
function monomialDiv(a, b) {
|
|
35
|
-
const quotient =
|
|
36
|
-
for (const [name, exponent] of
|
|
35
|
+
const quotient = chunkA2DZ5BEJ_cjs.monomialFromKey(a);
|
|
36
|
+
for (const [name, exponent] of chunkA2DZ5BEJ_cjs.monomialFromKey(b)) {
|
|
37
37
|
const remaining = (quotient.get(name) ?? 0) - exponent;
|
|
38
38
|
if (remaining <= 0) quotient.delete(name);
|
|
39
39
|
else quotient.set(name, remaining);
|
|
40
40
|
}
|
|
41
|
-
return
|
|
41
|
+
return chunkA2DZ5BEJ_cjs.monomialToKey(quotient);
|
|
42
42
|
}
|
|
43
43
|
function monomialGcd(a, b) {
|
|
44
|
-
const left =
|
|
44
|
+
const left = chunkA2DZ5BEJ_cjs.monomialFromKey(a);
|
|
45
45
|
const shared = /* @__PURE__ */ new Map();
|
|
46
|
-
for (const [name, exponent] of
|
|
46
|
+
for (const [name, exponent] of chunkA2DZ5BEJ_cjs.monomialFromKey(b)) {
|
|
47
47
|
const other = left.get(name);
|
|
48
48
|
if (other !== void 0) shared.set(name, Math.min(other, exponent));
|
|
49
49
|
}
|
|
50
|
-
return
|
|
50
|
+
return chunkA2DZ5BEJ_cjs.monomialToKey(shared);
|
|
51
51
|
}
|
|
52
52
|
function namesOf(keys) {
|
|
53
53
|
const names = /* @__PURE__ */ new Set();
|
|
54
|
-
for (const key of keys) for (const name of
|
|
54
|
+
for (const key of keys) for (const name of chunkA2DZ5BEJ_cjs.monomialFromKey(key).keys()) names.add(name);
|
|
55
55
|
return [...names].sort();
|
|
56
56
|
}
|
|
57
57
|
function termsToNode(terms) {
|
|
58
58
|
const map = /* @__PURE__ */ new Map();
|
|
59
59
|
for (const term of terms) map.set(term.key, term.coefficient);
|
|
60
|
-
return
|
|
60
|
+
return chunkA2DZ5BEJ_cjs.fromPolynomial({ terms: map, vars: namesOf(terms.map((term) => term.key)) });
|
|
61
61
|
}
|
|
62
62
|
function product(factors) {
|
|
63
63
|
let result = factors[0];
|
|
@@ -66,7 +66,7 @@ function product(factors) {
|
|
|
66
66
|
}
|
|
67
67
|
function orderedTerms(p) {
|
|
68
68
|
const terms = [...p.terms].map(([key, coefficient]) => ({ key, coefficient }));
|
|
69
|
-
return terms.sort((a, b) =>
|
|
69
|
+
return terms.sort((a, b) => chunkA2DZ5BEJ_cjs.compareMonomials(a.key, b.key, p.vars));
|
|
70
70
|
}
|
|
71
71
|
function factorMultivariate(p) {
|
|
72
72
|
if (p.vars.length < 2) return null;
|
|
@@ -94,7 +94,7 @@ function factorBinomial(first, second) {
|
|
|
94
94
|
return product([linear, termsToNode([squareOf(cubes.a), middle, squareOf(cubes.b)])]);
|
|
95
95
|
}
|
|
96
96
|
function asPowerPair(first, second, degree) {
|
|
97
|
-
const magnitude2 = second.coefficient.n < 0n ?
|
|
97
|
+
const magnitude2 = second.coefficient.n < 0n ? chunkA2DZ5BEJ_cjs.rationalNeg(second.coefficient) : second.coefficient;
|
|
98
98
|
const firstRoot = exactRoot(first.coefficient, degree);
|
|
99
99
|
const secondRoot = exactRoot(magnitude2, degree);
|
|
100
100
|
if (firstRoot === null || secondRoot === null) return null;
|
|
@@ -104,10 +104,10 @@ function asPowerPair(first, second, degree) {
|
|
|
104
104
|
return { a: { key: firstKey, coefficient: firstRoot }, b: { key: secondKey, coefficient: secondRoot } };
|
|
105
105
|
}
|
|
106
106
|
function negated(term) {
|
|
107
|
-
return { key: term.key, coefficient:
|
|
107
|
+
return { key: term.key, coefficient: chunkA2DZ5BEJ_cjs.rationalNeg(term.coefficient) };
|
|
108
108
|
}
|
|
109
109
|
function multiplyTerms(a, b) {
|
|
110
|
-
return { key: monomialMul(a.key, b.key), coefficient:
|
|
110
|
+
return { key: monomialMul(a.key, b.key), coefficient: chunkA2DZ5BEJ_cjs.rationalMul(a.coefficient, b.coefficient) };
|
|
111
111
|
}
|
|
112
112
|
function squareOf(term) {
|
|
113
113
|
return multiplyTerms(term, term);
|
|
@@ -119,12 +119,12 @@ function factorPerfectSquare(terms) {
|
|
|
119
119
|
if (roots === null) return null;
|
|
120
120
|
const cross = multiplyTerms(roots.a, roots.b);
|
|
121
121
|
if (cross.key !== middle.key) return null;
|
|
122
|
-
const twice =
|
|
122
|
+
const twice = chunkA2DZ5BEJ_cjs.rationalMul(cross.coefficient, { n: 2n, d: 1n });
|
|
123
123
|
const negative = middle.coefficient.n < 0n;
|
|
124
|
-
const magnitude2 = negative ?
|
|
125
|
-
if (!
|
|
124
|
+
const magnitude2 = negative ? chunkA2DZ5BEJ_cjs.rationalNeg(middle.coefficient) : middle.coefficient;
|
|
125
|
+
if (!chunkA2DZ5BEJ_cjs.isRationalOne(chunkA2DZ5BEJ_cjs.rationalDiv(magnitude2, twice))) return null;
|
|
126
126
|
const base = termsToNode([roots.a, negative ? negated(roots.b) : roots.b]);
|
|
127
|
-
return { kind: "pow", base, exponent:
|
|
127
|
+
return { kind: "pow", base, exponent: chunkA2DZ5BEJ_cjs.constNode(2) };
|
|
128
128
|
}
|
|
129
129
|
function factorByGrouping(terms) {
|
|
130
130
|
const pairings = [
|
|
@@ -149,7 +149,7 @@ function splitPair(first, second) {
|
|
|
149
149
|
const common = { key: shared, coefficient: first.coefficient };
|
|
150
150
|
const cofactor = [
|
|
151
151
|
{ key: monomialDiv(first.key, shared), coefficient: { n: 1n, d: 1n } },
|
|
152
|
-
{ key: monomialDiv(second.key, shared), coefficient:
|
|
152
|
+
{ key: monomialDiv(second.key, shared), coefficient: chunkA2DZ5BEJ_cjs.rationalDiv(second.coefficient, first.coefficient) }
|
|
153
153
|
];
|
|
154
154
|
return cofactor[0].key === cofactor[1].key ? null : { common, cofactor };
|
|
155
155
|
}
|
|
@@ -189,14 +189,14 @@ function divisors(value) {
|
|
|
189
189
|
return found;
|
|
190
190
|
}
|
|
191
191
|
function evaluateAt(descending, x) {
|
|
192
|
-
let total =
|
|
193
|
-
for (const coeff of descending) total =
|
|
192
|
+
let total = chunkA2DZ5BEJ_cjs.RATIONAL_ZERO;
|
|
193
|
+
for (const coeff of descending) total = chunkA2DZ5BEJ_cjs.rationalAdd(chunkA2DZ5BEJ_cjs.rationalMul(total, x), coeff);
|
|
194
194
|
return total;
|
|
195
195
|
}
|
|
196
196
|
function divideByRoot(descending, root) {
|
|
197
197
|
const quotient = [descending[0]];
|
|
198
198
|
for (let i = 1; i < descending.length - 1; i++) {
|
|
199
|
-
quotient.push(
|
|
199
|
+
quotient.push(chunkA2DZ5BEJ_cjs.rationalAdd(descending[i], chunkA2DZ5BEJ_cjs.rationalMul(quotient[i - 1], root)));
|
|
200
200
|
}
|
|
201
201
|
return quotient;
|
|
202
202
|
}
|
|
@@ -211,14 +211,14 @@ function rationalRoots(descending) {
|
|
|
211
211
|
const numeratorDivisors = divisors(trailing);
|
|
212
212
|
const denominatorDivisors = divisors(leading);
|
|
213
213
|
if (numeratorDivisors === null || denominatorDivisors === null) {
|
|
214
|
-
throw
|
|
214
|
+
throw chunkMIGXCBXT_cjs.ErrorFactory.execution(
|
|
215
215
|
"SYMBOLIC_FACTOR_LIMIT_EXCEEDED",
|
|
216
216
|
"This polynomial's coefficients have too many divisors to search for rational roots.",
|
|
217
217
|
{ limit: FACTOR_MAX_ROOT_CANDIDATES }
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
220
|
if (numeratorDivisors.length * denominatorDivisors.length > FACTOR_MAX_ROOT_CANDIDATES) {
|
|
221
|
-
throw
|
|
221
|
+
throw chunkMIGXCBXT_cjs.ErrorFactory.execution(
|
|
222
222
|
"SYMBOLIC_FACTOR_LIMIT_EXCEEDED",
|
|
223
223
|
"This polynomial has too many candidate rational roots to test.",
|
|
224
224
|
{ limit: FACTOR_MAX_ROOT_CANDIDATES }
|
|
@@ -233,25 +233,25 @@ function rationalRoots(descending) {
|
|
|
233
233
|
const key = `${candidate.n}/${candidate.d}`;
|
|
234
234
|
if (seen.has(key)) continue;
|
|
235
235
|
seen.add(key);
|
|
236
|
-
if (
|
|
236
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(evaluateAt(descending, candidate))) roots.push(candidate);
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
return roots;
|
|
241
241
|
}
|
|
242
242
|
function linearFactorNode(variable, root) {
|
|
243
|
-
if (
|
|
244
|
-
return root.n > 0n ? { kind: "sub", left:
|
|
243
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(root)) return chunkA2DZ5BEJ_cjs.varNode(variable);
|
|
244
|
+
return root.n > 0n ? { kind: "sub", left: chunkA2DZ5BEJ_cjs.varNode(variable), right: chunkA2DZ5BEJ_cjs.constNode(root) } : { kind: "add", left: chunkA2DZ5BEJ_cjs.varNode(variable), right: chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalNeg(root)) };
|
|
245
245
|
}
|
|
246
246
|
function coefficientsToNode(descending, variable) {
|
|
247
247
|
const degree = descending.length - 1;
|
|
248
248
|
const terms = /* @__PURE__ */ new Map();
|
|
249
249
|
descending.forEach((coeff, index) => {
|
|
250
|
-
if (
|
|
250
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(coeff)) return;
|
|
251
251
|
const power3 = degree - index;
|
|
252
252
|
terms.set(power3 === 0 ? "" : power3 === 1 ? variable : `${variable}^${power3}`, coeff);
|
|
253
253
|
});
|
|
254
|
-
return
|
|
254
|
+
return chunkA2DZ5BEJ_cjs.fromPolynomial({ terms, vars: terms.size > 0 ? [variable] : [] });
|
|
255
255
|
}
|
|
256
256
|
function factorUnivariate(descending, variable) {
|
|
257
257
|
const factors = [];
|
|
@@ -260,7 +260,7 @@ function factorUnivariate(descending, variable) {
|
|
|
260
260
|
while (roots.length > 0 && remaining.length > 2) {
|
|
261
261
|
for (const root of roots) {
|
|
262
262
|
let multiplicity = 0;
|
|
263
|
-
while (remaining.length > 1 &&
|
|
263
|
+
while (remaining.length > 1 && chunkA2DZ5BEJ_cjs.isRationalZero(evaluateAt(remaining, root))) {
|
|
264
264
|
remaining = divideByRoot(remaining, root);
|
|
265
265
|
multiplicity++;
|
|
266
266
|
}
|
|
@@ -271,17 +271,17 @@ function factorUnivariate(descending, variable) {
|
|
|
271
271
|
const leftoverDegree = remaining.length - 1;
|
|
272
272
|
if (leftoverDegree >= 1) {
|
|
273
273
|
factors.push({ base: coefficientsToNode(remaining, variable), power: 1 });
|
|
274
|
-
return { content:
|
|
274
|
+
return { content: chunkA2DZ5BEJ_cjs.RATIONAL_ONE, factors };
|
|
275
275
|
}
|
|
276
|
-
return { content: remaining.length === 1 ? remaining[0] :
|
|
276
|
+
return { content: remaining.length === 1 ? remaining[0] : chunkA2DZ5BEJ_cjs.RATIONAL_ONE, factors };
|
|
277
277
|
}
|
|
278
278
|
function factorizationToNode(factorization) {
|
|
279
279
|
const pieces = [];
|
|
280
|
-
if (!
|
|
280
|
+
if (!chunkA2DZ5BEJ_cjs.isRationalOne(factorization.content)) pieces.push(chunkA2DZ5BEJ_cjs.constNode(factorization.content));
|
|
281
281
|
for (const factor of factorization.factors) {
|
|
282
|
-
pieces.push(factor.power === 1 ? factor.base :
|
|
282
|
+
pieces.push(factor.power === 1 ? factor.base : chunkA2DZ5BEJ_cjs.powNode(factor.base, chunkA2DZ5BEJ_cjs.constNode({ n: BigInt(factor.power), d: 1n })));
|
|
283
283
|
}
|
|
284
|
-
if (pieces.length === 0) return
|
|
284
|
+
if (pieces.length === 0) return chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.RATIONAL_ONE);
|
|
285
285
|
let result = pieces[0];
|
|
286
286
|
for (let i = 1; i < pieces.length; i++) result = { kind: "mul", left: result, right: pieces[i] };
|
|
287
287
|
return result;
|
|
@@ -293,7 +293,7 @@ function contentOf(p) {
|
|
|
293
293
|
numeratorGcd = gcd(numeratorGcd, coeff.n);
|
|
294
294
|
denominatorLcm = lcm(denominatorLcm, coeff.d);
|
|
295
295
|
}
|
|
296
|
-
if (numeratorGcd === 0n) return
|
|
296
|
+
if (numeratorGcd === 0n) return chunkA2DZ5BEJ_cjs.RATIONAL_ONE;
|
|
297
297
|
return { n: numeratorGcd, d: denominatorLcm };
|
|
298
298
|
}
|
|
299
299
|
function extractCommonMonomial(p) {
|
|
@@ -339,48 +339,48 @@ function monomialNode(monomial) {
|
|
|
339
339
|
let result = null;
|
|
340
340
|
for (const name of names) {
|
|
341
341
|
const exponent = monomial.get(name);
|
|
342
|
-
const factor = exponent === 1 ?
|
|
342
|
+
const factor = exponent === 1 ? chunkA2DZ5BEJ_cjs.varNode(name) : chunkA2DZ5BEJ_cjs.powNode(chunkA2DZ5BEJ_cjs.varNode(name), chunkA2DZ5BEJ_cjs.constNode({ n: BigInt(exponent), d: 1n }));
|
|
343
343
|
result = result === null ? factor : { kind: "mul", left: result, right: factor };
|
|
344
344
|
}
|
|
345
345
|
return result;
|
|
346
346
|
}
|
|
347
347
|
function factorSymbolic(node) {
|
|
348
|
-
const polynomial =
|
|
348
|
+
const polynomial = chunkA2DZ5BEJ_cjs.toPolynomial(node);
|
|
349
349
|
if (polynomial === null || polynomial.terms.size === 0) return node;
|
|
350
|
-
if (
|
|
350
|
+
if (chunkA2DZ5BEJ_cjs.polyDegree(polynomial) > FACTOR_MAX_DEGREE) return node;
|
|
351
351
|
if (polynomial.vars.length === 0) return node;
|
|
352
352
|
const content = contentOf(polynomial);
|
|
353
|
-
const primitive =
|
|
353
|
+
const primitive = chunkA2DZ5BEJ_cjs.isRationalOne(content) ? polynomial : scaleTerms(polynomial, chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.RATIONAL_ONE, content));
|
|
354
354
|
const { monomial, reduced } = extractCommonMonomial(primitive);
|
|
355
355
|
const monomialFactor = monomialNode(monomial);
|
|
356
|
-
const variable =
|
|
356
|
+
const variable = chunkA2DZ5BEJ_cjs.polyUnivariateVar(reduced);
|
|
357
357
|
if (variable === null) {
|
|
358
358
|
const patterned = factorMultivariate(reduced);
|
|
359
359
|
if (patterned !== null) return assemble(content, monomialFactor, patterned);
|
|
360
360
|
const pieces2 = buildPieces(content, monomialFactor, reduced);
|
|
361
361
|
return pieces2 ?? node;
|
|
362
362
|
}
|
|
363
|
-
const descending = [...
|
|
363
|
+
const descending = [...chunkA2DZ5BEJ_cjs.polyCoefficients(reduced, variable)].reverse();
|
|
364
364
|
const factorization = factorUnivariate(descending, variable);
|
|
365
|
-
const combinedContent =
|
|
366
|
-
const isUnchanged = factorization.factors.length <= 1 && (factorization.factors[0]?.power ?? 1) === 1 && monomialFactor === null &&
|
|
365
|
+
const combinedContent = chunkA2DZ5BEJ_cjs.rationalMul(content, factorization.content);
|
|
366
|
+
const isUnchanged = factorization.factors.length <= 1 && (factorization.factors[0]?.power ?? 1) === 1 && monomialFactor === null && chunkA2DZ5BEJ_cjs.isRationalOne(combinedContent);
|
|
367
367
|
if (isUnchanged) return node;
|
|
368
368
|
const pieces = [];
|
|
369
|
-
if (!
|
|
369
|
+
if (!chunkA2DZ5BEJ_cjs.isRationalOne(combinedContent)) pieces.push(chunkA2DZ5BEJ_cjs.constNode(combinedContent));
|
|
370
370
|
if (monomialFactor !== null) pieces.push(monomialFactor);
|
|
371
|
-
pieces.push(factorizationToNode({ content:
|
|
371
|
+
pieces.push(factorizationToNode({ content: chunkA2DZ5BEJ_cjs.RATIONAL_ONE, factors: factorization.factors }));
|
|
372
372
|
let result = pieces[0];
|
|
373
373
|
for (let i = 1; i < pieces.length; i++) result = { kind: "mul", left: result, right: pieces[i] };
|
|
374
374
|
return result;
|
|
375
375
|
}
|
|
376
376
|
function scaleTerms(p, k) {
|
|
377
377
|
const terms = /* @__PURE__ */ new Map();
|
|
378
|
-
for (const [key, coeff] of p.terms) terms.set(key,
|
|
378
|
+
for (const [key, coeff] of p.terms) terms.set(key, chunkA2DZ5BEJ_cjs.rationalMul(coeff, k));
|
|
379
379
|
return { terms, vars: p.vars };
|
|
380
380
|
}
|
|
381
381
|
function assemble(content, monomialFactor, factored) {
|
|
382
382
|
const pieces = [];
|
|
383
|
-
if (!
|
|
383
|
+
if (!chunkA2DZ5BEJ_cjs.isRationalOne(content)) pieces.push(chunkA2DZ5BEJ_cjs.constNode(content));
|
|
384
384
|
if (monomialFactor !== null) pieces.push(monomialFactor);
|
|
385
385
|
pieces.push(factored);
|
|
386
386
|
let result = pieces[0];
|
|
@@ -388,11 +388,11 @@ function assemble(content, monomialFactor, factored) {
|
|
|
388
388
|
return result;
|
|
389
389
|
}
|
|
390
390
|
function buildPieces(content, monomialFactor, reduced) {
|
|
391
|
-
if (monomialFactor === null &&
|
|
391
|
+
if (monomialFactor === null && chunkA2DZ5BEJ_cjs.isRationalOne(content)) return null;
|
|
392
392
|
const pieces = [];
|
|
393
|
-
if (!
|
|
393
|
+
if (!chunkA2DZ5BEJ_cjs.isRationalOne(content)) pieces.push(chunkA2DZ5BEJ_cjs.constNode(content));
|
|
394
394
|
if (monomialFactor !== null) pieces.push(monomialFactor);
|
|
395
|
-
pieces.push(
|
|
395
|
+
pieces.push(chunkA2DZ5BEJ_cjs.fromPolynomial(reduced));
|
|
396
396
|
let result = pieces[0];
|
|
397
397
|
for (let i = 1; i < pieces.length; i++) result = { kind: "mul", left: result, right: pieces[i] };
|
|
398
398
|
return result;
|
|
@@ -403,103 +403,103 @@ var TWO = { n: 2n, d: 1n };
|
|
|
403
403
|
var THREE = { n: 3n, d: 1n };
|
|
404
404
|
var FOUR = { n: 4n, d: 1n };
|
|
405
405
|
function depressCubic(a, b, c, d) {
|
|
406
|
-
const shift =
|
|
407
|
-
const p =
|
|
408
|
-
|
|
409
|
-
|
|
406
|
+
const shift = chunkA2DZ5BEJ_cjs.rationalNeg(chunkA2DZ5BEJ_cjs.rationalDiv(b, chunkA2DZ5BEJ_cjs.rationalMul(THREE, a)));
|
|
407
|
+
const p = chunkA2DZ5BEJ_cjs.rationalDiv(
|
|
408
|
+
chunkA2DZ5BEJ_cjs.rationalSub(chunkA2DZ5BEJ_cjs.rationalMul(THREE, chunkA2DZ5BEJ_cjs.rationalMul(a, c)), chunkA2DZ5BEJ_cjs.rationalMul(b, b)),
|
|
409
|
+
chunkA2DZ5BEJ_cjs.rationalMul(THREE, chunkA2DZ5BEJ_cjs.rationalMul(a, a))
|
|
410
410
|
);
|
|
411
|
-
const twoBCubed =
|
|
412
|
-
const nineABC =
|
|
413
|
-
const twentySevenAAD =
|
|
414
|
-
const q =
|
|
415
|
-
|
|
416
|
-
|
|
411
|
+
const twoBCubed = chunkA2DZ5BEJ_cjs.rationalMul(TWO, chunkA2DZ5BEJ_cjs.rationalMul(b, chunkA2DZ5BEJ_cjs.rationalMul(b, b)));
|
|
412
|
+
const nineABC = chunkA2DZ5BEJ_cjs.rationalMul({ n: 9n, d: 1n }, chunkA2DZ5BEJ_cjs.rationalMul(a, chunkA2DZ5BEJ_cjs.rationalMul(b, c)));
|
|
413
|
+
const twentySevenAAD = chunkA2DZ5BEJ_cjs.rationalMul({ n: 27n, d: 1n }, chunkA2DZ5BEJ_cjs.rationalMul(chunkA2DZ5BEJ_cjs.rationalMul(a, a), d));
|
|
414
|
+
const q = chunkA2DZ5BEJ_cjs.rationalDiv(
|
|
415
|
+
chunkA2DZ5BEJ_cjs.rationalAdd(chunkA2DZ5BEJ_cjs.rationalSub(twoBCubed, nineABC), twentySevenAAD),
|
|
416
|
+
chunkA2DZ5BEJ_cjs.rationalMul({ n: 27n, d: 1n }, chunkA2DZ5BEJ_cjs.rationalMul(a, chunkA2DZ5BEJ_cjs.rationalMul(a, a)))
|
|
417
417
|
);
|
|
418
418
|
return { p, q, shift };
|
|
419
419
|
}
|
|
420
420
|
function solveCubic(a, b, c, d) {
|
|
421
421
|
const { p, q, shift } = depressCubic(a, b, c, d);
|
|
422
|
-
const discriminant =
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
422
|
+
const discriminant = chunkA2DZ5BEJ_cjs.rationalNeg(
|
|
423
|
+
chunkA2DZ5BEJ_cjs.rationalAdd(
|
|
424
|
+
chunkA2DZ5BEJ_cjs.rationalMul(FOUR, chunkA2DZ5BEJ_cjs.rationalMul(p, chunkA2DZ5BEJ_cjs.rationalMul(p, p))),
|
|
425
|
+
chunkA2DZ5BEJ_cjs.rationalMul({ n: 27n, d: 1n }, chunkA2DZ5BEJ_cjs.rationalMul(q, q))
|
|
426
426
|
)
|
|
427
427
|
);
|
|
428
|
-
if (
|
|
428
|
+
if (chunkA2DZ5BEJ_cjs.rationalCompare(discriminant, chunkA2DZ5BEJ_cjs.RATIONAL_ZERO) > 0) {
|
|
429
429
|
return { exact: [], approximate: trigonometricRoots(p, q, shift) };
|
|
430
430
|
}
|
|
431
|
-
if (
|
|
431
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(discriminant)) return { exact: repeatedCubicRoots(p, q, shift), approximate: [] };
|
|
432
432
|
return { exact: cardanoRoots(p, q, shift), approximate: [] };
|
|
433
433
|
}
|
|
434
434
|
function repeatedCubicRoots(p, q, shift) {
|
|
435
|
-
if (
|
|
436
|
-
const simple =
|
|
437
|
-
const repeated =
|
|
438
|
-
const ordered = [simple, repeated].sort(
|
|
439
|
-
return ordered.map(
|
|
435
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(p)) return [chunkA2DZ5BEJ_cjs.constNode(shift)];
|
|
436
|
+
const simple = chunkA2DZ5BEJ_cjs.rationalAdd(chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalMul(THREE, q), p), shift);
|
|
437
|
+
const repeated = chunkA2DZ5BEJ_cjs.rationalAdd(chunkA2DZ5BEJ_cjs.rationalNeg(chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalMul(THREE, q), chunkA2DZ5BEJ_cjs.rationalMul(TWO, p))), shift);
|
|
438
|
+
const ordered = [simple, repeated].sort(chunkA2DZ5BEJ_cjs.rationalCompare);
|
|
439
|
+
return ordered.map(chunkA2DZ5BEJ_cjs.constNode);
|
|
440
440
|
}
|
|
441
441
|
function cardanoRoots(p, q, shift) {
|
|
442
|
-
const half =
|
|
443
|
-
const radicand =
|
|
444
|
-
|
|
445
|
-
|
|
442
|
+
const half = chunkA2DZ5BEJ_cjs.rationalNeg(chunkA2DZ5BEJ_cjs.rationalDiv(q, TWO));
|
|
443
|
+
const radicand = chunkA2DZ5BEJ_cjs.rationalAdd(
|
|
444
|
+
chunkA2DZ5BEJ_cjs.rationalMul(chunkA2DZ5BEJ_cjs.rationalDiv(q, TWO), chunkA2DZ5BEJ_cjs.rationalDiv(q, TWO)),
|
|
445
|
+
chunkA2DZ5BEJ_cjs.rationalMul(chunkA2DZ5BEJ_cjs.rationalDiv(p, THREE), chunkA2DZ5BEJ_cjs.rationalMul(chunkA2DZ5BEJ_cjs.rationalDiv(p, THREE), chunkA2DZ5BEJ_cjs.rationalDiv(p, THREE)))
|
|
446
446
|
);
|
|
447
|
-
const inner =
|
|
448
|
-
const u = { kind: "call", name: "cbrt", args: [{ kind: "add", left:
|
|
449
|
-
const v = { kind: "call", name: "cbrt", args: [{ kind: "sub", left:
|
|
447
|
+
const inner = chunkA2DZ5BEJ_cjs.surdNode(radicand);
|
|
448
|
+
const u = { kind: "call", name: "cbrt", args: [{ kind: "add", left: chunkA2DZ5BEJ_cjs.constNode(half), right: inner }] };
|
|
449
|
+
const v = { kind: "call", name: "cbrt", args: [{ kind: "sub", left: chunkA2DZ5BEJ_cjs.constNode(half), right: inner }] };
|
|
450
450
|
const sum = { kind: "add", left: u, right: v };
|
|
451
451
|
const difference = { kind: "sub", left: u, right: v };
|
|
452
|
-
const real = { kind: "add", left:
|
|
452
|
+
const real = { kind: "add", left: chunkA2DZ5BEJ_cjs.constNode(shift), right: { kind: "div", left: { kind: "neg", operand: sum }, right: chunkA2DZ5BEJ_cjs.constNode(TWO) } };
|
|
453
453
|
const imaginary = {
|
|
454
454
|
kind: "mul",
|
|
455
|
-
left: { kind: "div", left: { kind: "mul", left: difference, right:
|
|
456
|
-
right:
|
|
455
|
+
left: { kind: "div", left: { kind: "mul", left: difference, right: chunkA2DZ5BEJ_cjs.surdNode(THREE) }, right: chunkA2DZ5BEJ_cjs.constNode(TWO) },
|
|
456
|
+
right: chunkA2DZ5BEJ_cjs.complexNode(chunkA2DZ5BEJ_cjs.COMPLEX_I)
|
|
457
457
|
};
|
|
458
458
|
return [
|
|
459
|
-
{ kind: "add", left:
|
|
459
|
+
{ kind: "add", left: chunkA2DZ5BEJ_cjs.constNode(shift), right: sum },
|
|
460
460
|
{ kind: "sub", left: real, right: imaginary },
|
|
461
461
|
{ kind: "add", left: real, right: imaginary }
|
|
462
462
|
];
|
|
463
463
|
}
|
|
464
464
|
function trigonometricRoots(p, q, shift) {
|
|
465
|
-
const pNumber =
|
|
466
|
-
const qNumber =
|
|
467
|
-
const shiftNumber =
|
|
465
|
+
const pNumber = chunkA2DZ5BEJ_cjs.rationalToNumber(p);
|
|
466
|
+
const qNumber = chunkA2DZ5BEJ_cjs.rationalToNumber(q);
|
|
467
|
+
const shiftNumber = chunkA2DZ5BEJ_cjs.rationalToNumber(shift);
|
|
468
468
|
const magnitude2 = 2 * Math.sqrt(-pNumber / 3);
|
|
469
469
|
const ratio = 3 * qNumber / (2 * pNumber) * Math.sqrt(-3 / pNumber);
|
|
470
470
|
const angle = Math.acos(Math.min(1, Math.max(-1, ratio))) / 3;
|
|
471
471
|
return [0, 1, 2].map((k) => magnitude2 * Math.cos(angle - 2 * Math.PI * k / 3) + shiftNumber).sort((left, right) => left - right);
|
|
472
472
|
}
|
|
473
473
|
function depressQuartic(b, c, d, e) {
|
|
474
|
-
const shift =
|
|
475
|
-
const bb =
|
|
476
|
-
const p =
|
|
477
|
-
const q =
|
|
478
|
-
|
|
479
|
-
|
|
474
|
+
const shift = chunkA2DZ5BEJ_cjs.rationalNeg(chunkA2DZ5BEJ_cjs.rationalDiv(b, FOUR));
|
|
475
|
+
const bb = chunkA2DZ5BEJ_cjs.rationalMul(b, b);
|
|
476
|
+
const p = chunkA2DZ5BEJ_cjs.rationalSub(c, chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalMul(THREE, bb), { n: 8n, d: 1n }));
|
|
477
|
+
const q = chunkA2DZ5BEJ_cjs.rationalAdd(
|
|
478
|
+
chunkA2DZ5BEJ_cjs.rationalSub(d, chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalMul(b, c), TWO)),
|
|
479
|
+
chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalMul(bb, b), { n: 8n, d: 1n })
|
|
480
480
|
);
|
|
481
|
-
const r =
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
481
|
+
const r = chunkA2DZ5BEJ_cjs.rationalSub(
|
|
482
|
+
chunkA2DZ5BEJ_cjs.rationalAdd(
|
|
483
|
+
chunkA2DZ5BEJ_cjs.rationalSub(e, chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalMul(b, d), FOUR)),
|
|
484
|
+
chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalMul(bb, c), { n: 16n, d: 1n })
|
|
485
485
|
),
|
|
486
|
-
|
|
486
|
+
chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalMul(THREE, chunkA2DZ5BEJ_cjs.rationalMul(bb, bb)), { n: 256n, d: 1n })
|
|
487
487
|
);
|
|
488
488
|
return { p, q, r, shift };
|
|
489
489
|
}
|
|
490
490
|
function solveQuartic(a, b, c, d, e, solveQuadratic2) {
|
|
491
|
-
const monic = (value) =>
|
|
491
|
+
const monic = (value) => chunkA2DZ5BEJ_cjs.rationalDiv(value, a);
|
|
492
492
|
const { p, q, r, shift } = depressQuartic(monic(b), monic(c), monic(d), monic(e));
|
|
493
|
-
const roots =
|
|
493
|
+
const roots = chunkA2DZ5BEJ_cjs.isRationalZero(q) ? biquadraticRoots(p, r) : splitQuarticRoots(p, q, r, solveQuadratic2);
|
|
494
494
|
if (roots === null) return null;
|
|
495
|
-
const shifted =
|
|
495
|
+
const shifted = chunkA2DZ5BEJ_cjs.isRationalZero(shift) ? roots : roots.map((root) => ({ kind: "add", left: chunkA2DZ5BEJ_cjs.constNode(shift), right: root }));
|
|
496
496
|
return { exact: distinct(shifted), approximate: [] };
|
|
497
497
|
}
|
|
498
498
|
function distinct(roots) {
|
|
499
499
|
const seen = /* @__PURE__ */ new Set();
|
|
500
500
|
const unique = [];
|
|
501
501
|
for (const root of roots) {
|
|
502
|
-
const key =
|
|
502
|
+
const key = chunkA2DZ5BEJ_cjs.symbolicKey(chunkA2DZ5BEJ_cjs.simplifySymbolic(root));
|
|
503
503
|
if (seen.has(key)) continue;
|
|
504
504
|
seen.add(key);
|
|
505
505
|
unique.push(root);
|
|
@@ -507,51 +507,51 @@ function distinct(roots) {
|
|
|
507
507
|
return unique;
|
|
508
508
|
}
|
|
509
509
|
function biquadraticRoots(p, r) {
|
|
510
|
-
const discriminant =
|
|
511
|
-
if (
|
|
512
|
-
const root =
|
|
513
|
-
if (root !== null) return rationalSquareRoots(
|
|
510
|
+
const discriminant = chunkA2DZ5BEJ_cjs.rationalSub(chunkA2DZ5BEJ_cjs.rationalMul(p, p), chunkA2DZ5BEJ_cjs.rationalMul(FOUR, r));
|
|
511
|
+
if (chunkA2DZ5BEJ_cjs.rationalCompare(discriminant, chunkA2DZ5BEJ_cjs.RATIONAL_ZERO) < 0) return complexBiquadraticRoots(p, r);
|
|
512
|
+
const root = chunkA2DZ5BEJ_cjs.exactRationalSqrt(discriminant);
|
|
513
|
+
if (root !== null) return rationalSquareRoots(chunkA2DZ5BEJ_cjs.rationalNeg(p), root, chunkA2DZ5BEJ_cjs.isRationalZero(discriminant));
|
|
514
514
|
return nestedSquareRoots(p, r, discriminant);
|
|
515
515
|
}
|
|
516
516
|
function rationalSquareRoots(negatedP, root, repeated) {
|
|
517
|
-
const values = repeated ? [
|
|
517
|
+
const values = repeated ? [chunkA2DZ5BEJ_cjs.rationalDiv(negatedP, TWO)] : [chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalAdd(negatedP, root), TWO), chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalSub(negatedP, root), TWO)];
|
|
518
518
|
const roots = [];
|
|
519
519
|
for (const value of values) {
|
|
520
|
-
if (
|
|
521
|
-
roots.push(
|
|
520
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(value)) {
|
|
521
|
+
roots.push(chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.RATIONAL_ZERO));
|
|
522
522
|
continue;
|
|
523
523
|
}
|
|
524
|
-
const square =
|
|
524
|
+
const square = chunkA2DZ5BEJ_cjs.signedSurdNode(value);
|
|
525
525
|
roots.push({ kind: "neg", operand: square }, square);
|
|
526
526
|
}
|
|
527
527
|
return roots;
|
|
528
528
|
}
|
|
529
529
|
function nestedSquareRoots(p, r, discriminant) {
|
|
530
|
-
const negatedP =
|
|
531
|
-
const surd =
|
|
532
|
-
const negativeP =
|
|
530
|
+
const negatedP = chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalNeg(p));
|
|
531
|
+
const surd = chunkA2DZ5BEJ_cjs.surdNode(discriminant);
|
|
532
|
+
const negativeP = chunkA2DZ5BEJ_cjs.rationalCompare(p, chunkA2DZ5BEJ_cjs.RATIONAL_ZERO) <= 0;
|
|
533
533
|
const solutions = [
|
|
534
|
-
{ node: halved({ kind: "add", left: negatedP, right: surd }), positive: negativeP ||
|
|
535
|
-
{ node: halved({ kind: "sub", left: negatedP, right: surd }), positive: negativeP &&
|
|
534
|
+
{ node: halved({ kind: "add", left: negatedP, right: surd }), positive: negativeP || chunkA2DZ5BEJ_cjs.rationalCompare(r, chunkA2DZ5BEJ_cjs.RATIONAL_ZERO) <= 0 },
|
|
535
|
+
{ node: halved({ kind: "sub", left: negatedP, right: surd }), positive: negativeP && chunkA2DZ5BEJ_cjs.rationalCompare(r, chunkA2DZ5BEJ_cjs.RATIONAL_ZERO) >= 0 }
|
|
536
536
|
];
|
|
537
537
|
const roots = [];
|
|
538
538
|
for (const { node, positive } of solutions) {
|
|
539
539
|
const radicand = positive ? node : { kind: "neg", operand: node };
|
|
540
540
|
const magnitude2 = { kind: "call", name: "sqrt", args: [radicand] };
|
|
541
|
-
const square = positive ? magnitude2 : { kind: "mul", left: magnitude2, right:
|
|
541
|
+
const square = positive ? magnitude2 : { kind: "mul", left: magnitude2, right: chunkA2DZ5BEJ_cjs.complexNode(chunkA2DZ5BEJ_cjs.COMPLEX_I) };
|
|
542
542
|
roots.push({ kind: "neg", operand: square }, square);
|
|
543
543
|
}
|
|
544
544
|
return roots;
|
|
545
545
|
}
|
|
546
546
|
function halved(node) {
|
|
547
|
-
return { kind: "div", left: node, right:
|
|
547
|
+
return { kind: "div", left: node, right: chunkA2DZ5BEJ_cjs.constNode(TWO) };
|
|
548
548
|
}
|
|
549
549
|
function complexBiquadraticRoots(p, r) {
|
|
550
|
-
const centre =
|
|
551
|
-
const modulus =
|
|
552
|
-
const re = modulus === null ? nestedSurd(
|
|
553
|
-
const imaginaryMagnitude = modulus === null ? nestedSurd(
|
|
554
|
-
const im = { kind: "mul", left: imaginaryMagnitude, right:
|
|
550
|
+
const centre = chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalNeg(p), TWO);
|
|
551
|
+
const modulus = chunkA2DZ5BEJ_cjs.exactRationalSqrt(r);
|
|
552
|
+
const re = modulus === null ? nestedSurd(chunkA2DZ5BEJ_cjs.surdNode(r), centre) : chunkA2DZ5BEJ_cjs.surdNode(chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalAdd(modulus, centre), TWO));
|
|
553
|
+
const imaginaryMagnitude = modulus === null ? nestedSurd(chunkA2DZ5BEJ_cjs.surdNode(r), chunkA2DZ5BEJ_cjs.rationalNeg(centre)) : chunkA2DZ5BEJ_cjs.surdNode(chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalSub(modulus, centre), TWO));
|
|
554
|
+
const im = { kind: "mul", left: imaginaryMagnitude, right: chunkA2DZ5BEJ_cjs.complexNode(chunkA2DZ5BEJ_cjs.COMPLEX_I) };
|
|
555
555
|
const first = { kind: "add", left: re, right: im };
|
|
556
556
|
const second = { kind: "sub", left: re, right: im };
|
|
557
557
|
return [
|
|
@@ -562,28 +562,28 @@ function complexBiquadraticRoots(p, r) {
|
|
|
562
562
|
];
|
|
563
563
|
}
|
|
564
564
|
function nestedSurd(surd, offset) {
|
|
565
|
-
const shifted = offset.n >= 0n ? { kind: "add", left: surd, right:
|
|
565
|
+
const shifted = offset.n >= 0n ? { kind: "add", left: surd, right: chunkA2DZ5BEJ_cjs.constNode(offset) } : { kind: "sub", left: surd, right: chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalNeg(offset)) };
|
|
566
566
|
return { kind: "call", name: "sqrt", args: [halved(shifted)] };
|
|
567
567
|
}
|
|
568
568
|
function splitQuarticRoots(p, q, r, solveQuadratic2) {
|
|
569
569
|
const resolvent = [
|
|
570
570
|
{ n: 1n, d: 1n },
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
571
|
+
chunkA2DZ5BEJ_cjs.rationalMul(TWO, p),
|
|
572
|
+
chunkA2DZ5BEJ_cjs.rationalSub(chunkA2DZ5BEJ_cjs.rationalMul(p, p), chunkA2DZ5BEJ_cjs.rationalMul(FOUR, r)),
|
|
573
|
+
chunkA2DZ5BEJ_cjs.rationalNeg(chunkA2DZ5BEJ_cjs.rationalMul(q, q))
|
|
574
574
|
];
|
|
575
575
|
for (const z of rationalRoots(resolvent)) {
|
|
576
|
-
if (
|
|
577
|
-
const alpha =
|
|
576
|
+
if (chunkA2DZ5BEJ_cjs.rationalCompare(z, chunkA2DZ5BEJ_cjs.RATIONAL_ZERO) <= 0) continue;
|
|
577
|
+
const alpha = chunkA2DZ5BEJ_cjs.exactRationalSqrt(z);
|
|
578
578
|
if (alpha === null) continue;
|
|
579
|
-
const sum =
|
|
580
|
-
const difference =
|
|
581
|
-
const beta =
|
|
582
|
-
const gamma =
|
|
579
|
+
const sum = chunkA2DZ5BEJ_cjs.rationalAdd(p, z);
|
|
580
|
+
const difference = chunkA2DZ5BEJ_cjs.rationalDiv(q, alpha);
|
|
581
|
+
const beta = chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalSub(sum, difference), TWO);
|
|
582
|
+
const gamma = chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalAdd(sum, difference), TWO);
|
|
583
583
|
const one2 = { n: 1n, d: 1n };
|
|
584
584
|
return [
|
|
585
585
|
...solveQuadratic2(one2, alpha, beta),
|
|
586
|
-
...solveQuadratic2(one2,
|
|
586
|
+
...solveQuadratic2(one2, chunkA2DZ5BEJ_cjs.rationalNeg(alpha), gamma)
|
|
587
587
|
];
|
|
588
588
|
}
|
|
589
589
|
return null;
|
|
@@ -640,8 +640,8 @@ function differentiate(descending) {
|
|
|
640
640
|
}
|
|
641
641
|
function squareFreeDoubles(descending) {
|
|
642
642
|
const ascending = [...descending].reverse();
|
|
643
|
-
const squareFree = [...
|
|
644
|
-
const doubles = squareFree.map(
|
|
643
|
+
const squareFree = [...chunkA2DZ5BEJ_cjs.squareFreePart(ascending)].reverse();
|
|
644
|
+
const doubles = squareFree.map(chunkA2DZ5BEJ_cjs.rationalToNumber);
|
|
645
645
|
if (doubles.some((value) => !Number.isFinite(value))) return null;
|
|
646
646
|
return doubles;
|
|
647
647
|
}
|
|
@@ -764,59 +764,59 @@ function approximateRoots(descending) {
|
|
|
764
764
|
// src/symbolic/Solve.ts
|
|
765
765
|
var SOLVE_MAX_DEGREE = 8;
|
|
766
766
|
function evaluateRational(descending, x) {
|
|
767
|
-
let total =
|
|
768
|
-
for (const coeff of descending) total =
|
|
767
|
+
let total = chunkA2DZ5BEJ_cjs.RATIONAL_ZERO;
|
|
768
|
+
for (const coeff of descending) total = chunkA2DZ5BEJ_cjs.rationalAdd(chunkA2DZ5BEJ_cjs.rationalMul(total, x), coeff);
|
|
769
769
|
return total;
|
|
770
770
|
}
|
|
771
771
|
function divideByRoot2(descending, root) {
|
|
772
772
|
const quotient = [descending[0]];
|
|
773
773
|
for (let i = 1; i < descending.length - 1; i++) {
|
|
774
|
-
quotient.push(
|
|
774
|
+
quotient.push(chunkA2DZ5BEJ_cjs.rationalAdd(descending[i], chunkA2DZ5BEJ_cjs.rationalMul(quotient[i - 1], root)));
|
|
775
775
|
}
|
|
776
776
|
return quotient;
|
|
777
777
|
}
|
|
778
778
|
function solveQuadratic(a, b, c) {
|
|
779
|
-
const discriminant =
|
|
780
|
-
const twoA =
|
|
781
|
-
if (
|
|
782
|
-
return complexQuadraticRoots(
|
|
783
|
-
}
|
|
784
|
-
if (
|
|
785
|
-
const rootN =
|
|
786
|
-
const rootD =
|
|
779
|
+
const discriminant = chunkA2DZ5BEJ_cjs.rationalSub(chunkA2DZ5BEJ_cjs.rationalMul(b, b), chunkA2DZ5BEJ_cjs.rationalMul(rational4(), chunkA2DZ5BEJ_cjs.rationalMul(a, c)));
|
|
780
|
+
const twoA = chunkA2DZ5BEJ_cjs.rationalMul(rational2(), a);
|
|
781
|
+
if (chunkA2DZ5BEJ_cjs.rationalCompare(discriminant, chunkA2DZ5BEJ_cjs.RATIONAL_ZERO) < 0) {
|
|
782
|
+
return complexQuadraticRoots(chunkA2DZ5BEJ_cjs.rationalNeg(b), discriminant, twoA);
|
|
783
|
+
}
|
|
784
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(discriminant)) return [chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalNeg(b), twoA))];
|
|
785
|
+
const rootN = chunkA2DZ5BEJ_cjs.exactIntegerSqrt(discriminant.n);
|
|
786
|
+
const rootD = chunkA2DZ5BEJ_cjs.exactIntegerSqrt(discriminant.d);
|
|
787
787
|
if (rootN !== null && rootD !== null) {
|
|
788
788
|
const root = { n: rootN, d: rootD };
|
|
789
|
-
const plus =
|
|
790
|
-
const minus =
|
|
791
|
-
return
|
|
792
|
-
}
|
|
793
|
-
const surd =
|
|
794
|
-
const ascending =
|
|
795
|
-
const lower = { kind: "div", left: { kind: "sub", left:
|
|
796
|
-
const upper = { kind: "div", left: { kind: "add", left:
|
|
789
|
+
const plus = chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalAdd(chunkA2DZ5BEJ_cjs.rationalNeg(b), root), twoA);
|
|
790
|
+
const minus = chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalSub(chunkA2DZ5BEJ_cjs.rationalNeg(b), root), twoA);
|
|
791
|
+
return chunkA2DZ5BEJ_cjs.rationalCompare(minus, plus) <= 0 ? [chunkA2DZ5BEJ_cjs.constNode(minus), chunkA2DZ5BEJ_cjs.constNode(plus)] : [chunkA2DZ5BEJ_cjs.constNode(plus), chunkA2DZ5BEJ_cjs.constNode(minus)];
|
|
792
|
+
}
|
|
793
|
+
const surd = chunkA2DZ5BEJ_cjs.surdNode(discriminant);
|
|
794
|
+
const ascending = chunkA2DZ5BEJ_cjs.rationalCompare(twoA, chunkA2DZ5BEJ_cjs.RATIONAL_ZERO) > 0;
|
|
795
|
+
const lower = { kind: "div", left: { kind: "sub", left: chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalNeg(b)), right: surd }, right: chunkA2DZ5BEJ_cjs.constNode(twoA) };
|
|
796
|
+
const upper = { kind: "div", left: { kind: "add", left: chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalNeg(b)), right: surd }, right: chunkA2DZ5BEJ_cjs.constNode(twoA) };
|
|
797
797
|
return ascending ? [lower, upper] : [upper, lower];
|
|
798
798
|
}
|
|
799
799
|
function complexQuadraticRoots(negatedB, discriminant, twoA) {
|
|
800
|
-
const magnitude2 =
|
|
801
|
-
const rootN =
|
|
802
|
-
const rootD =
|
|
800
|
+
const magnitude2 = chunkA2DZ5BEJ_cjs.rationalNeg(discriminant);
|
|
801
|
+
const rootN = chunkA2DZ5BEJ_cjs.exactIntegerSqrt(magnitude2.n);
|
|
802
|
+
const rootD = chunkA2DZ5BEJ_cjs.exactIntegerSqrt(magnitude2.d);
|
|
803
803
|
if (rootN !== null && rootD !== null) {
|
|
804
|
-
const imaginary2 =
|
|
805
|
-
const real2 =
|
|
804
|
+
const imaginary2 = chunkA2DZ5BEJ_cjs.rationalDiv({ n: rootN, d: rootD }, twoA);
|
|
805
|
+
const real2 = chunkA2DZ5BEJ_cjs.rationalDiv(negatedB, twoA);
|
|
806
806
|
return [
|
|
807
|
-
|
|
808
|
-
|
|
807
|
+
chunkA2DZ5BEJ_cjs.complexNode(chunkA2DZ5BEJ_cjs.complex(real2, chunkA2DZ5BEJ_cjs.rationalNeg(imaginary2))),
|
|
808
|
+
chunkA2DZ5BEJ_cjs.complexNode(chunkA2DZ5BEJ_cjs.complex(real2, imaginary2))
|
|
809
809
|
];
|
|
810
810
|
}
|
|
811
|
-
const real =
|
|
812
|
-
const scaledRadicand =
|
|
813
|
-
const imaginary = { kind: "mul", left:
|
|
814
|
-
if (
|
|
811
|
+
const real = chunkA2DZ5BEJ_cjs.rationalDiv(negatedB, twoA);
|
|
812
|
+
const scaledRadicand = chunkA2DZ5BEJ_cjs.rationalDiv(magnitude2, chunkA2DZ5BEJ_cjs.rationalMul(twoA, twoA));
|
|
813
|
+
const imaginary = { kind: "mul", left: chunkA2DZ5BEJ_cjs.surdNode(scaledRadicand), right: chunkA2DZ5BEJ_cjs.complexNode(chunkA2DZ5BEJ_cjs.COMPLEX_I) };
|
|
814
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(real)) {
|
|
815
815
|
return [{ kind: "neg", operand: imaginary }, imaginary];
|
|
816
816
|
}
|
|
817
817
|
return [
|
|
818
|
-
{ kind: "sub", left:
|
|
819
|
-
{ kind: "add", left:
|
|
818
|
+
{ kind: "sub", left: chunkA2DZ5BEJ_cjs.constNode(real), right: imaginary },
|
|
819
|
+
{ kind: "add", left: chunkA2DZ5BEJ_cjs.constNode(real), right: imaginary }
|
|
820
820
|
];
|
|
821
821
|
}
|
|
822
822
|
function rational2() {
|
|
@@ -829,7 +829,7 @@ function realApproximation(value) {
|
|
|
829
829
|
return { re: value, im: 0 };
|
|
830
830
|
}
|
|
831
831
|
function solveForVariable(lhs, rhs, variable) {
|
|
832
|
-
const polynomial =
|
|
832
|
+
const polynomial = chunkA2DZ5BEJ_cjs.toPolynomial({ kind: "sub", left: lhs, right: rhs });
|
|
833
833
|
if (polynomial === null) {
|
|
834
834
|
return {
|
|
835
835
|
kind: "unsupported",
|
|
@@ -837,7 +837,7 @@ function solveForVariable(lhs, rhs, variable) {
|
|
|
837
837
|
};
|
|
838
838
|
}
|
|
839
839
|
const others = polynomial.vars.filter((name) => name !== variable);
|
|
840
|
-
const degree =
|
|
840
|
+
const degree = chunkA2DZ5BEJ_cjs.polyDegree(polynomial, variable);
|
|
841
841
|
if (others.length > 0) {
|
|
842
842
|
if (degree !== 1) {
|
|
843
843
|
return {
|
|
@@ -853,7 +853,7 @@ function solveForVariable(lhs, rhs, variable) {
|
|
|
853
853
|
if (degree > SOLVE_MAX_DEGREE) {
|
|
854
854
|
return { kind: "unsupported", reason: `degree ${degree} is above the supported maximum of ${SOLVE_MAX_DEGREE}` };
|
|
855
855
|
}
|
|
856
|
-
const descending = [...
|
|
856
|
+
const descending = [...chunkA2DZ5BEJ_cjs.polyCoefficients(polynomial, variable)].reverse();
|
|
857
857
|
return solveUnivariate(descending);
|
|
858
858
|
}
|
|
859
859
|
function solveLinearWithOtherUnknowns(polynomial, variable) {
|
|
@@ -878,8 +878,8 @@ function solveLinearWithOtherUnknowns(polynomial, variable) {
|
|
|
878
878
|
}
|
|
879
879
|
return [...names].sort();
|
|
880
880
|
};
|
|
881
|
-
const coefficient =
|
|
882
|
-
const constant =
|
|
881
|
+
const coefficient = chunkA2DZ5BEJ_cjs.fromPolynomial({ terms: coefficientTerms, vars: namesOf2(coefficientTerms) });
|
|
882
|
+
const constant = chunkA2DZ5BEJ_cjs.fromPolynomial({ terms: constantTerms, vars: namesOf2(constantTerms) });
|
|
883
883
|
return {
|
|
884
884
|
kind: "roots",
|
|
885
885
|
exact: [{ kind: "div", left: { kind: "neg", operand: constant }, right: coefficient }],
|
|
@@ -899,34 +899,34 @@ function extractRationalRoots(descending) {
|
|
|
899
899
|
const roots = [];
|
|
900
900
|
let remaining = [...descending];
|
|
901
901
|
let powersOfX = 0;
|
|
902
|
-
while (remaining.length > 1 &&
|
|
902
|
+
while (remaining.length > 1 && chunkA2DZ5BEJ_cjs.isRationalZero(remaining[remaining.length - 1])) {
|
|
903
903
|
remaining = remaining.slice(0, -1);
|
|
904
904
|
powersOfX++;
|
|
905
905
|
}
|
|
906
|
-
if (powersOfX > 0) roots.push(
|
|
906
|
+
if (powersOfX > 0) roots.push(chunkA2DZ5BEJ_cjs.RATIONAL_ZERO);
|
|
907
907
|
while (remaining.length > 1) {
|
|
908
908
|
const found = rationalRoots(remaining);
|
|
909
909
|
if (found.length === 0) break;
|
|
910
910
|
for (const root of found) {
|
|
911
911
|
let multiplicity = 0;
|
|
912
|
-
while (remaining.length > 1 &&
|
|
912
|
+
while (remaining.length > 1 && chunkA2DZ5BEJ_cjs.isRationalZero(evaluateRational(remaining, root))) {
|
|
913
913
|
remaining = divideByRoot2(remaining, root);
|
|
914
914
|
multiplicity++;
|
|
915
915
|
}
|
|
916
916
|
if (multiplicity > 0) roots.push(root);
|
|
917
917
|
}
|
|
918
918
|
}
|
|
919
|
-
return { roots: roots.sort(
|
|
919
|
+
return { roots: roots.sort(chunkA2DZ5BEJ_cjs.rationalCompare), remaining };
|
|
920
920
|
}
|
|
921
921
|
function solveUnivariate(descending) {
|
|
922
922
|
const { roots, remaining } = extractRationalRoots(descending);
|
|
923
|
-
const exact = roots.map(
|
|
923
|
+
const exact = roots.map(chunkA2DZ5BEJ_cjs.constNode);
|
|
924
924
|
const approximate = [];
|
|
925
925
|
const leftoverDegree = remaining.length - 1;
|
|
926
926
|
const solvedDegree = descending.length - remaining.length;
|
|
927
927
|
if (leftoverDegree <= 0) return finish(exact, approximate, solvedDegree, 0, "");
|
|
928
928
|
if (leftoverDegree === 1) {
|
|
929
|
-
exact.push(
|
|
929
|
+
exact.push(chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalDiv(chunkA2DZ5BEJ_cjs.rationalNeg(remaining[1]), remaining[0])));
|
|
930
930
|
return finish(exact, approximate, solvedDegree + 1, 0, "");
|
|
931
931
|
}
|
|
932
932
|
if (leftoverDegree === 2) {
|
|
@@ -1014,15 +1014,15 @@ function valueToSymbolic(v) {
|
|
|
1014
1014
|
if (v.type === 13 /* Error */ || v.type === 12 /* Pending */) return null;
|
|
1015
1015
|
const numeric = v.toNumber();
|
|
1016
1016
|
if (!Number.isFinite(numeric)) return null;
|
|
1017
|
-
return
|
|
1017
|
+
return chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalFromNumber(numeric));
|
|
1018
1018
|
}
|
|
1019
1019
|
function symbolicToValue(node) {
|
|
1020
|
-
const simplified =
|
|
1021
|
-
if (simplified.kind === "const") return
|
|
1022
|
-
return
|
|
1020
|
+
const simplified = chunkA2DZ5BEJ_cjs.simplifySymbolic(node);
|
|
1021
|
+
if (simplified.kind === "const") return chunkIT74O4BE_cjs.numberValue(chunkA2DZ5BEJ_cjs.rationalToNumber(simplified.value));
|
|
1022
|
+
return chunkIT74O4BE_cjs.symbolicValue(simplified);
|
|
1023
1023
|
}
|
|
1024
1024
|
function unsupported(what) {
|
|
1025
|
-
return
|
|
1025
|
+
return chunkIT74O4BE_cjs.errorValue(
|
|
1026
1026
|
"SYMBOLIC_UNSUPPORTED_FUNCTION",
|
|
1027
1027
|
`"${what}" cannot be applied to an expression that still contains an unknown.`
|
|
1028
1028
|
);
|
|
@@ -1031,7 +1031,7 @@ function symbolicPow(l, r) {
|
|
|
1031
1031
|
const base = valueToSymbolic(l);
|
|
1032
1032
|
const exponent = valueToSymbolic(r);
|
|
1033
1033
|
if (base === null || exponent === null) return unsupported("^");
|
|
1034
|
-
return symbolicToValue(
|
|
1034
|
+
return symbolicToValue(chunkA2DZ5BEJ_cjs.powNode(base, exponent));
|
|
1035
1035
|
}
|
|
1036
1036
|
function symbolicNeg(v) {
|
|
1037
1037
|
const operand = valueToSymbolic(v);
|
|
@@ -1041,39 +1041,39 @@ function symbolicNeg(v) {
|
|
|
1041
1041
|
function symbolicBuiltin(index, args) {
|
|
1042
1042
|
const nodes = [];
|
|
1043
1043
|
for (const arg of args) {
|
|
1044
|
-
const faulted =
|
|
1044
|
+
const faulted = chunkIT74O4BE_cjs.faultedOperand(arg);
|
|
1045
1045
|
if (faulted) return faulted;
|
|
1046
1046
|
const node = valueToSymbolic(arg);
|
|
1047
1047
|
if (node === null) return unsupported(SYMBOLIC_BUILTIN_NAMES[index] ?? `builtin ${index}`);
|
|
1048
1048
|
nodes.push(node);
|
|
1049
1049
|
}
|
|
1050
1050
|
if (index === POW_BUILTIN_INDEX && nodes.length === 2) {
|
|
1051
|
-
return symbolicToValue(
|
|
1051
|
+
return symbolicToValue(chunkA2DZ5BEJ_cjs.powNode(nodes[0], nodes[1]));
|
|
1052
1052
|
}
|
|
1053
1053
|
const name = SYMBOLIC_BUILTIN_NAMES[index];
|
|
1054
1054
|
if (name === void 0) return unsupported(`builtin ${index}`);
|
|
1055
|
-
return symbolicToValue(
|
|
1055
|
+
return symbolicToValue(chunkA2DZ5BEJ_cjs.callNode(name, nodes));
|
|
1056
1056
|
}
|
|
1057
1057
|
function rootToValue(root) {
|
|
1058
1058
|
const value = symbolicToValue(root);
|
|
1059
|
-
if (value.type === 0 /* Number */ && !Number.isInteger(value.toNumber())) return
|
|
1059
|
+
if (value.type === 0 /* Number */ && !Number.isInteger(value.toNumber())) return chunkIT74O4BE_cjs.symbolicValue(root);
|
|
1060
1060
|
return value;
|
|
1061
1061
|
}
|
|
1062
1062
|
function approximateRootToValue(root) {
|
|
1063
|
-
if (root.im === 0) return
|
|
1064
|
-
return
|
|
1063
|
+
if (root.im === 0) return chunkIT74O4BE_cjs.numberValue(root.re);
|
|
1064
|
+
return chunkIT74O4BE_cjs.symbolicValue(chunkA2DZ5BEJ_cjs.complexNode(chunkA2DZ5BEJ_cjs.complex(chunkA2DZ5BEJ_cjs.rationalFromNumber(root.re), chunkA2DZ5BEJ_cjs.rationalFromNumber(root.im))));
|
|
1065
1065
|
}
|
|
1066
1066
|
function solveOutcomeToValue(outcome) {
|
|
1067
1067
|
switch (outcome.kind) {
|
|
1068
1068
|
case "identity":
|
|
1069
|
-
return
|
|
1069
|
+
return chunkIT74O4BE_cjs.stringValue("true for every value");
|
|
1070
1070
|
case "contradiction":
|
|
1071
|
-
return
|
|
1071
|
+
return chunkIT74O4BE_cjs.stringValue("no solution");
|
|
1072
1072
|
case "unsupported":
|
|
1073
|
-
return
|
|
1073
|
+
return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_SOLVE_UNSUPPORTED", `Cannot solve this equation: ${outcome.reason}.`);
|
|
1074
1074
|
case "incomplete": {
|
|
1075
1075
|
const found = outcome.exact.length + outcome.approximate.length;
|
|
1076
|
-
return
|
|
1076
|
+
return chunkIT74O4BE_cjs.errorValue(
|
|
1077
1077
|
"SYMBOLIC_SOLVE_INCOMPLETE",
|
|
1078
1078
|
`Only ${found} of this equation's ${found + outcome.missing} roots could be found: ${outcome.reason}.`
|
|
1079
1079
|
);
|
|
@@ -1081,9 +1081,9 @@ function solveOutcomeToValue(outcome) {
|
|
|
1081
1081
|
case "roots": {
|
|
1082
1082
|
const values = outcome.exact.map(rootToValue);
|
|
1083
1083
|
for (const approximate of outcome.approximate) values.push(approximateRootToValue(approximate));
|
|
1084
|
-
if (values.length === 0) return
|
|
1084
|
+
if (values.length === 0) return chunkIT74O4BE_cjs.stringValue("no solution");
|
|
1085
1085
|
if (values.length === 1) return values[0];
|
|
1086
|
-
return
|
|
1086
|
+
return chunkIT74O4BE_cjs.matrixValue(1, values.length, values.map((v) => v.type === 9 /* Symbolic */ ? v.value : v.toNumber()));
|
|
1087
1087
|
}
|
|
1088
1088
|
}
|
|
1089
1089
|
}
|
|
@@ -1091,7 +1091,7 @@ function solveEquationValues(lhsValue, rhsValue, variable) {
|
|
|
1091
1091
|
const lhs = valueToSymbolic(lhsValue);
|
|
1092
1092
|
const rhs = valueToSymbolic(rhsValue);
|
|
1093
1093
|
if (lhs === null || rhs === null) {
|
|
1094
|
-
return
|
|
1094
|
+
return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "An equation side has no exact value to solve with.");
|
|
1095
1095
|
}
|
|
1096
1096
|
return solveOutcomeToValue(solveForVariable(lhs, rhs, variable));
|
|
1097
1097
|
}
|
|
@@ -1104,13 +1104,13 @@ function unifyUom(l, r) {
|
|
|
1104
1104
|
}
|
|
1105
1105
|
const lMeasure = chunkEJ3ILXX6_cjs.getMeasure(l.unit);
|
|
1106
1106
|
const rMeasure = chunkEJ3ILXX6_cjs.getMeasure(r.unit);
|
|
1107
|
-
const isCurrency =
|
|
1107
|
+
const isCurrency = chunkKXDQKVNX_cjs.sharedCurrencyExchange.isCurrency(l.unit) && chunkKXDQKVNX_cjs.sharedCurrencyExchange.isCurrency(r.unit);
|
|
1108
1108
|
if (lMeasure && lMeasure === rMeasure) {
|
|
1109
1109
|
const rvConverted = chunkEJ3ILXX6_cjs.convertUnit(r.toNumber(), r.unit, l.unit);
|
|
1110
1110
|
return { lv: l.toNumber(), rv: rvConverted, unit: l.unit, sameMeasure: true };
|
|
1111
1111
|
}
|
|
1112
1112
|
if (isCurrency) {
|
|
1113
|
-
const rvConverted =
|
|
1113
|
+
const rvConverted = chunkKXDQKVNX_cjs.sharedCurrencyExchange.convertSync(r.toNumber(), r.unit, l.unit);
|
|
1114
1114
|
if (rvConverted !== null) {
|
|
1115
1115
|
return { lv: l.toNumber(), rv: rvConverted, unit: l.unit, sameMeasure: true };
|
|
1116
1116
|
}
|
|
@@ -1136,8 +1136,8 @@ function largestFiniteMagnitude(a, b, c) {
|
|
|
1136
1136
|
function compareUom(l, r) {
|
|
1137
1137
|
const { lv, rv, sameMeasure } = unifyUom(l, r);
|
|
1138
1138
|
if (!sameMeasure) return { lv, rv, equal: false, sameMeasure: false };
|
|
1139
|
-
if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */ && l.unit !== void 0 && l.unit === r.unit && l.exact !== void 0 && r.exact !== void 0 &&
|
|
1140
|
-
return { lv, rv, equal:
|
|
1139
|
+
if (l.type === 6 /* Uom */ && r.type === 6 /* Uom */ && l.unit !== void 0 && l.unit === r.unit && l.exact !== void 0 && r.exact !== void 0 && chunkKXDQKVNX_cjs.sharedCurrencyExchange.isCurrency(l.unit)) {
|
|
1140
|
+
return { lv, rv, equal: chunkA2DZ5BEJ_cjs.decimalCompare(l.exact, r.exact) === 0, sameMeasure: true };
|
|
1141
1141
|
}
|
|
1142
1142
|
if (lv === rv) return { lv, rv, equal: true, sameMeasure: true };
|
|
1143
1143
|
if (!Number.isFinite(lv) || !Number.isFinite(rv)) return { lv, rv, equal: false, sameMeasure: true };
|
|
@@ -1156,7 +1156,7 @@ var COMBINE_VERBS = {
|
|
|
1156
1156
|
div: "divided"
|
|
1157
1157
|
};
|
|
1158
1158
|
function describeMeasure(unit) {
|
|
1159
|
-
if (
|
|
1159
|
+
if (chunkKXDQKVNX_cjs.sharedCurrencyExchange.isCurrency(unit)) return "money";
|
|
1160
1160
|
const measure = chunkEJ3ILXX6_cjs.getMeasure(unit);
|
|
1161
1161
|
if (measure === void 0) return void 0;
|
|
1162
1162
|
return MEASURE_NOUNS[measure] ?? measure;
|
|
@@ -1188,14 +1188,14 @@ function incomparableUnitsError(l, r) {
|
|
|
1188
1188
|
const lUnit = l.type === 6 /* Uom */ ? l.unit : void 0;
|
|
1189
1189
|
const rUnit = r.type === 6 /* Uom */ ? r.unit : void 0;
|
|
1190
1190
|
const named = describeMeasureMismatch(lUnit, rUnit, "compared");
|
|
1191
|
-
return
|
|
1191
|
+
return chunkIT74O4BE_cjs.errorValue("INCOMPATIBLE_UNITS", named ?? `Cannot compare incompatible units: ${lUnit ?? "?"} and ${rUnit ?? "?"}`);
|
|
1192
1192
|
}
|
|
1193
1193
|
function toBigIntOperand(v) {
|
|
1194
1194
|
if (v.type === 2 /* BigInt */) return v.value;
|
|
1195
1195
|
const n = v.toNumber();
|
|
1196
1196
|
if (!Number.isInteger(n)) {
|
|
1197
1197
|
const shown = Number.isNaN(n) ? "NaN" : String(n);
|
|
1198
|
-
throw
|
|
1198
|
+
throw chunkMIGXCBXT_cjs.ErrorFactory.execution(
|
|
1199
1199
|
"BIGINT_INEXACT_OPERAND",
|
|
1200
1200
|
`A whole-number (n) value can only be combined with another whole number, and ${shown} is not one`,
|
|
1201
1201
|
{ operand: shown }
|
|
@@ -1204,7 +1204,7 @@ function toBigIntOperand(v) {
|
|
|
1204
1204
|
return BigInt(n);
|
|
1205
1205
|
}
|
|
1206
1206
|
function bigIntDivisionByZero() {
|
|
1207
|
-
return
|
|
1207
|
+
return chunkMIGXCBXT_cjs.ErrorFactory.execution(
|
|
1208
1208
|
"BIGINT_DIVISION_BY_ZERO",
|
|
1209
1209
|
"Division by zero: a whole-number (n) division is exact integer division, which has no answer at zero, unlike 1 / 0 which is Infinity"
|
|
1210
1210
|
);
|
|
@@ -1230,11 +1230,11 @@ function power(base, exponent) {
|
|
|
1230
1230
|
}
|
|
1231
1231
|
function operandExactDecimal(v) {
|
|
1232
1232
|
if (v.exact !== void 0) return v.exact;
|
|
1233
|
-
return
|
|
1233
|
+
return chunkA2DZ5BEJ_cjs.decimalFromNumberIfExact(v.toNumber());
|
|
1234
1234
|
}
|
|
1235
1235
|
function exactMoneyOp(l, r, op) {
|
|
1236
|
-
const lMoney = l.type === 6 /* Uom */ && l.unit !== void 0 && l.exact !== void 0 &&
|
|
1237
|
-
const rMoney = r.type === 6 /* Uom */ && r.unit !== void 0 && r.exact !== void 0 &&
|
|
1236
|
+
const lMoney = l.type === 6 /* Uom */ && l.unit !== void 0 && l.exact !== void 0 && chunkKXDQKVNX_cjs.sharedCurrencyExchange.isCurrency(l.unit);
|
|
1237
|
+
const rMoney = r.type === 6 /* Uom */ && r.unit !== void 0 && r.exact !== void 0 && chunkKXDQKVNX_cjs.sharedCurrencyExchange.isCurrency(r.unit);
|
|
1238
1238
|
if (!lMoney && !rMoney) return null;
|
|
1239
1239
|
let ld;
|
|
1240
1240
|
let rd;
|
|
@@ -1259,25 +1259,25 @@ function exactMoneyOp(l, r, op) {
|
|
|
1259
1259
|
let result;
|
|
1260
1260
|
switch (op) {
|
|
1261
1261
|
case "add":
|
|
1262
|
-
result =
|
|
1262
|
+
result = chunkA2DZ5BEJ_cjs.decimalAdd(ld, rd);
|
|
1263
1263
|
break;
|
|
1264
1264
|
case "sub":
|
|
1265
|
-
result =
|
|
1265
|
+
result = chunkA2DZ5BEJ_cjs.decimalSubtract(ld, rd);
|
|
1266
1266
|
break;
|
|
1267
1267
|
case "mul":
|
|
1268
|
-
result =
|
|
1268
|
+
result = chunkA2DZ5BEJ_cjs.decimalMultiply(ld, rd);
|
|
1269
1269
|
break;
|
|
1270
1270
|
case "div":
|
|
1271
|
-
if (
|
|
1272
|
-
result =
|
|
1271
|
+
if (chunkA2DZ5BEJ_cjs.decimalIsZero(rd)) return null;
|
|
1272
|
+
result = chunkA2DZ5BEJ_cjs.decimalDivide(ld, rd);
|
|
1273
1273
|
break;
|
|
1274
1274
|
}
|
|
1275
|
-
return
|
|
1275
|
+
return chunkIT74O4BE_cjs.uomValueExact(chunkA2DZ5BEJ_cjs.decimalToNumber(result), unit, result);
|
|
1276
1276
|
}
|
|
1277
1277
|
function operandRational(v) {
|
|
1278
1278
|
if (v.rational !== void 0) return v.rational;
|
|
1279
1279
|
if ((v.type === 0 /* Number */ || v.type === 1 /* Hex */) && typeof v.value === "number" && Number.isInteger(v.value)) {
|
|
1280
|
-
return
|
|
1280
|
+
return chunkA2DZ5BEJ_cjs.rational(BigInt(v.value));
|
|
1281
1281
|
}
|
|
1282
1282
|
return null;
|
|
1283
1283
|
}
|
|
@@ -1286,27 +1286,27 @@ function exactRationalOp(l, r, op) {
|
|
|
1286
1286
|
if (lr === null) return null;
|
|
1287
1287
|
const rr = operandRational(r);
|
|
1288
1288
|
if (rr === null) return null;
|
|
1289
|
-
if (op === "div" &&
|
|
1289
|
+
if (op === "div" && chunkA2DZ5BEJ_cjs.isRationalZero(rr)) return null;
|
|
1290
1290
|
let result;
|
|
1291
1291
|
try {
|
|
1292
1292
|
switch (op) {
|
|
1293
1293
|
case "add":
|
|
1294
|
-
result =
|
|
1294
|
+
result = chunkA2DZ5BEJ_cjs.rationalAdd(lr, rr);
|
|
1295
1295
|
break;
|
|
1296
1296
|
case "sub":
|
|
1297
|
-
result =
|
|
1297
|
+
result = chunkA2DZ5BEJ_cjs.rationalSub(lr, rr);
|
|
1298
1298
|
break;
|
|
1299
1299
|
case "mul":
|
|
1300
|
-
result =
|
|
1300
|
+
result = chunkA2DZ5BEJ_cjs.rationalMul(lr, rr);
|
|
1301
1301
|
break;
|
|
1302
1302
|
case "div":
|
|
1303
|
-
result =
|
|
1303
|
+
result = chunkA2DZ5BEJ_cjs.rationalDiv(lr, rr);
|
|
1304
1304
|
break;
|
|
1305
1305
|
}
|
|
1306
1306
|
} catch {
|
|
1307
1307
|
return null;
|
|
1308
1308
|
}
|
|
1309
|
-
return
|
|
1309
|
+
return chunkIT74O4BE_cjs.numberValueRational(chunkA2DZ5BEJ_cjs.rationalToNumber(result), result);
|
|
1310
1310
|
}
|
|
1311
1311
|
function uncertainOp(l, r, op) {
|
|
1312
1312
|
if (l.type !== 0 /* Number */ || r.type !== 0 /* Number */) return null;
|
|
@@ -1334,14 +1334,14 @@ function uncertainOp(l, r, op) {
|
|
|
1334
1334
|
sigma = Math.hypot(sa / b, a * sb / (b * b));
|
|
1335
1335
|
break;
|
|
1336
1336
|
}
|
|
1337
|
-
return
|
|
1337
|
+
return chunkIT74O4BE_cjs.numberValueUncertain(center, sigma);
|
|
1338
1338
|
}
|
|
1339
1339
|
function compareRationalOperands(l, r) {
|
|
1340
1340
|
const lr = operandRational(l);
|
|
1341
1341
|
if (lr === null) return null;
|
|
1342
1342
|
const rr = operandRational(r);
|
|
1343
1343
|
if (rr === null) return null;
|
|
1344
|
-
return
|
|
1344
|
+
return chunkA2DZ5BEJ_cjs.rationalCompare(lr, rr);
|
|
1345
1345
|
}
|
|
1346
1346
|
function binaryOp(l, r, op, bigOp, symbolicOp) {
|
|
1347
1347
|
if (l.type === 13 /* Error */) return l;
|
|
@@ -1352,22 +1352,22 @@ function binaryOp(l, r, op, bigOp, symbolicOp) {
|
|
|
1352
1352
|
const left = valueToSymbolic(l);
|
|
1353
1353
|
const right = valueToSymbolic(r);
|
|
1354
1354
|
if (left === null || right === null) {
|
|
1355
|
-
return
|
|
1355
|
+
return chunkIT74O4BE_cjs.errorValue(
|
|
1356
1356
|
"SYMBOLIC_NONFINITE_OPERAND",
|
|
1357
1357
|
"A symbolic expression cannot combine with a value that has no exact number (NaN or infinity)."
|
|
1358
1358
|
);
|
|
1359
1359
|
}
|
|
1360
1360
|
const node = { kind: symbolicOp, left, right };
|
|
1361
|
-
return
|
|
1361
|
+
return chunkIT74O4BE_cjs.symbolicValue(chunkA2DZ5BEJ_cjs.simplifySymbolic(node));
|
|
1362
1362
|
}
|
|
1363
1363
|
if (l.type === 0 /* Number */ && r.type === 0 /* Number */) {
|
|
1364
|
-
return
|
|
1364
|
+
return chunkIT74O4BE_cjs.numberValue(op(l.value, r.value));
|
|
1365
1365
|
}
|
|
1366
1366
|
if (l.type === 2 /* BigInt */ || r.type === 2 /* BigInt */) {
|
|
1367
1367
|
const lb = toBigIntOperand(l);
|
|
1368
1368
|
const rb = toBigIntOperand(r);
|
|
1369
|
-
if (bigOp) return
|
|
1370
|
-
return
|
|
1369
|
+
if (bigOp) return chunkIT74O4BE_cjs.bigIntValue(bigOp(lb, rb));
|
|
1370
|
+
return chunkIT74O4BE_cjs.bigIntValue(lb + rb);
|
|
1371
1371
|
}
|
|
1372
1372
|
if (l.type === 6 /* Uom */ || r.type === 6 /* Uom */) {
|
|
1373
1373
|
if (symbolicOp) {
|
|
@@ -1379,33 +1379,33 @@ function binaryOp(l, r, op, bigOp, symbolicOp) {
|
|
|
1379
1379
|
const lUnit = l.type === 6 /* Uom */ ? l.unit : void 0;
|
|
1380
1380
|
const rUnit = r.type === 6 /* Uom */ ? r.unit : void 0;
|
|
1381
1381
|
const named = describeMeasureMismatch(lUnit, rUnit, combineVerb(symbolicOp));
|
|
1382
|
-
return
|
|
1382
|
+
return chunkIT74O4BE_cjs.errorValue("INCOMPATIBLE_UNITS", named ?? `Cannot combine incompatible units: ${lUnit ?? "?"} and ${rUnit ?? "?"}`);
|
|
1383
1383
|
}
|
|
1384
|
-
return
|
|
1384
|
+
return chunkIT74O4BE_cjs.uomValue(op(lv, rv), unit);
|
|
1385
1385
|
}
|
|
1386
1386
|
if (l.type === 7 /* Matrix */ && r.type === 7 /* Matrix */) {
|
|
1387
1387
|
const lm = l.value;
|
|
1388
1388
|
const rm = r.value;
|
|
1389
|
-
if (!
|
|
1390
|
-
return
|
|
1389
|
+
if (!chunkA2DZ5BEJ_cjs.sameShape(lm, rm)) {
|
|
1390
|
+
return chunkIT74O4BE_cjs.errorValue("DIMENSION_MISMATCH", `Cannot combine matrices of different shapes: ${lm.rows}x${lm.cols} and ${rm.rows}x${rm.cols}`);
|
|
1391
1391
|
}
|
|
1392
1392
|
const result = new Array(lm.data.length);
|
|
1393
1393
|
for (let i = 0; i < lm.data.length; i++) result[i] = op(lm.data[i], rm.data[i]);
|
|
1394
|
-
return
|
|
1394
|
+
return chunkIT74O4BE_cjs.matrixValue(lm.rows, lm.cols, result);
|
|
1395
1395
|
}
|
|
1396
1396
|
if (l.type === 7 /* Matrix */) {
|
|
1397
1397
|
const lm = l.value;
|
|
1398
1398
|
const scalar = r.toNumber();
|
|
1399
1399
|
const result = lm.data.map((v) => op(v, scalar));
|
|
1400
|
-
return
|
|
1400
|
+
return chunkIT74O4BE_cjs.matrixValue(lm.rows, lm.cols, result);
|
|
1401
1401
|
}
|
|
1402
1402
|
if (r.type === 7 /* Matrix */) {
|
|
1403
1403
|
const rm = r.value;
|
|
1404
1404
|
const scalar = l.toNumber();
|
|
1405
1405
|
const result = rm.data.map((v) => op(scalar, v));
|
|
1406
|
-
return
|
|
1406
|
+
return chunkIT74O4BE_cjs.matrixValue(rm.rows, rm.cols, result);
|
|
1407
1407
|
}
|
|
1408
|
-
return
|
|
1408
|
+
return chunkIT74O4BE_cjs.numberValue(op(l.toNumber(), r.toNumber()));
|
|
1409
1409
|
}
|
|
1410
1410
|
|
|
1411
1411
|
// src/vm/OpRegistry.ts
|
|
@@ -1444,7 +1444,7 @@ var OpRegistry = class {
|
|
|
1444
1444
|
*/
|
|
1445
1445
|
allocateOpcode() {
|
|
1446
1446
|
if (this.nextOpcode > MAX_OPCODE) {
|
|
1447
|
-
throw
|
|
1447
|
+
throw chunkMIGXCBXT_cjs.ErrorFactory.config(
|
|
1448
1448
|
"OPCODE_POOL_EXHAUSTED",
|
|
1449
1449
|
`OpRegistry: dynamic opcode pool exhausted (max ${MAX_OPCODE - DYNAMIC_OPCODE_START} allocations).`
|
|
1450
1450
|
);
|
|
@@ -1455,88 +1455,111 @@ var OpRegistry = class {
|
|
|
1455
1455
|
var sharedOpRegistry = new OpRegistry();
|
|
1456
1456
|
|
|
1457
1457
|
// src/vm/MoneyExact.ts
|
|
1458
|
-
var ONE_DECIMAL =
|
|
1458
|
+
var ONE_DECIMAL = chunkA2DZ5BEJ_cjs.decimalFromInteger(1);
|
|
1459
1459
|
function moneyExactMagnitude(operand, unit) {
|
|
1460
|
-
if (!
|
|
1461
|
-
return operand.exact ??
|
|
1460
|
+
if (!chunkKXDQKVNX_cjs.sharedCurrencyExchange.isCurrency(unit)) return null;
|
|
1461
|
+
return operand.exact ?? chunkA2DZ5BEJ_cjs.decimalFromNumberIfExact(operand.toNumber());
|
|
1462
1462
|
}
|
|
1463
1463
|
function decimalFromShortDecimal(n) {
|
|
1464
1464
|
if (!Number.isFinite(n)) return null;
|
|
1465
|
-
if (Number.isInteger(n)) return
|
|
1465
|
+
if (Number.isInteger(n)) return chunkA2DZ5BEJ_cjs.decimalFromInteger(BigInt(n));
|
|
1466
1466
|
const s = String(n);
|
|
1467
1467
|
if (!/^-?\d+\.\d+$/.test(s)) return null;
|
|
1468
|
-
return
|
|
1468
|
+
return chunkA2DZ5BEJ_cjs.decimalFromLiteral(s);
|
|
1469
1469
|
}
|
|
1470
1470
|
function scaleMoneyExact(amount, factor, unit) {
|
|
1471
1471
|
const base = moneyExactMagnitude(amount, unit);
|
|
1472
1472
|
const factorDecimal = decimalFromShortDecimal(factor);
|
|
1473
1473
|
if (base !== null && factorDecimal !== null) {
|
|
1474
|
-
const result =
|
|
1475
|
-
return
|
|
1474
|
+
const result = chunkA2DZ5BEJ_cjs.decimalMultiply(base, factorDecimal);
|
|
1475
|
+
return chunkIT74O4BE_cjs.uomValueExact(chunkA2DZ5BEJ_cjs.decimalToNumber(result), unit, result);
|
|
1476
1476
|
}
|
|
1477
|
-
return
|
|
1477
|
+
return chunkIT74O4BE_cjs.uomValue(amount.toNumber() * factor, unit);
|
|
1478
1478
|
}
|
|
1479
1479
|
function scaleMoneyByPercent(money, unit, percent, sign) {
|
|
1480
1480
|
const base = moneyExactMagnitude(money, unit);
|
|
1481
1481
|
const percentDecimal = decimalFromShortDecimal(percent);
|
|
1482
1482
|
if (base !== null && percentDecimal !== null) {
|
|
1483
|
-
const factor =
|
|
1484
|
-
const result =
|
|
1485
|
-
return
|
|
1483
|
+
const factor = chunkA2DZ5BEJ_cjs.decimalAdd(ONE_DECIMAL, sign === 1 ? percentDecimal : chunkA2DZ5BEJ_cjs.decimalNegate(percentDecimal));
|
|
1484
|
+
const result = chunkA2DZ5BEJ_cjs.decimalMultiply(base, factor);
|
|
1485
|
+
return chunkIT74O4BE_cjs.uomValueExact(chunkA2DZ5BEJ_cjs.decimalToNumber(result), unit, result);
|
|
1486
1486
|
}
|
|
1487
|
-
return
|
|
1487
|
+
return chunkIT74O4BE_cjs.uomValue(money.toNumber() * (1 + sign * percent), unit);
|
|
1488
1488
|
}
|
|
1489
1489
|
function onePlusRateDecimal(rate) {
|
|
1490
1490
|
const rateDecimal = decimalFromShortDecimal(rate);
|
|
1491
|
-
return rateDecimal === null ? null :
|
|
1491
|
+
return rateDecimal === null ? null : chunkA2DZ5BEJ_cjs.decimalAdd(ONE_DECIMAL, rateDecimal);
|
|
1492
1492
|
}
|
|
1493
1493
|
function removeTaxExact(money, unit, rate) {
|
|
1494
1494
|
const base = moneyExactMagnitude(money, unit);
|
|
1495
1495
|
const divisor = onePlusRateDecimal(rate);
|
|
1496
|
-
if (base === null || divisor === null ||
|
|
1497
|
-
const quotient =
|
|
1498
|
-
return
|
|
1496
|
+
if (base === null || divisor === null || chunkA2DZ5BEJ_cjs.decimalIsZero(divisor)) return null;
|
|
1497
|
+
const quotient = chunkA2DZ5BEJ_cjs.decimalDivide(base, divisor);
|
|
1498
|
+
return chunkIT74O4BE_cjs.uomValueExact(chunkA2DZ5BEJ_cjs.decimalToNumber(quotient), unit, quotient);
|
|
1499
1499
|
}
|
|
1500
1500
|
function taxInExact(money, unit, rate) {
|
|
1501
1501
|
const base = moneyExactMagnitude(money, unit);
|
|
1502
1502
|
const divisor = onePlusRateDecimal(rate);
|
|
1503
|
-
if (base === null || divisor === null ||
|
|
1504
|
-
const tax =
|
|
1505
|
-
return
|
|
1503
|
+
if (base === null || divisor === null || chunkA2DZ5BEJ_cjs.decimalIsZero(divisor)) return null;
|
|
1504
|
+
const tax = chunkA2DZ5BEJ_cjs.decimalSubtract(base, chunkA2DZ5BEJ_cjs.decimalDivide(base, divisor));
|
|
1505
|
+
return chunkIT74O4BE_cjs.uomValueExact(chunkA2DZ5BEJ_cjs.decimalToNumber(tax), unit, tax);
|
|
1506
|
+
}
|
|
1507
|
+
function splitEachExact(amount, n) {
|
|
1508
|
+
const unit = amount.unit;
|
|
1509
|
+
const cents = unit !== void 0 && chunkKXDQKVNX_cjs.sharedCurrencyExchange.isCurrency(unit) ? centsOfMoney(amount, unit) : null;
|
|
1510
|
+
if (cents === null) {
|
|
1511
|
+
return { unit, shares: [{ value: amount.toNumber() / n, count: n }] };
|
|
1512
|
+
}
|
|
1513
|
+
const divisor = BigInt(n);
|
|
1514
|
+
const baseCents = cents / divisor;
|
|
1515
|
+
const remainder = cents - baseCents * divisor;
|
|
1516
|
+
const extraShares = Number(remainder < 0n ? -remainder : remainder);
|
|
1517
|
+
const step = cents < 0n ? -1n : 1n;
|
|
1518
|
+
const base = centShare(baseCents, n - extraShares);
|
|
1519
|
+
if (extraShares === 0) return { unit, shares: [base] };
|
|
1520
|
+
return { unit, shares: [base, centShare(baseCents + step, extraShares)] };
|
|
1521
|
+
}
|
|
1522
|
+
function centShare(cents, count) {
|
|
1523
|
+
const exact = chunkA2DZ5BEJ_cjs.makeDecimal(cents, 2);
|
|
1524
|
+
return { value: chunkA2DZ5BEJ_cjs.decimalToNumber(exact), exact, count };
|
|
1525
|
+
}
|
|
1526
|
+
function centsOfMoney(amount, unit) {
|
|
1527
|
+
const base = moneyExactMagnitude(amount, unit);
|
|
1528
|
+
return base === null ? null : chunkA2DZ5BEJ_cjs.decimalRound(base, 2).coef;
|
|
1506
1529
|
}
|
|
1507
1530
|
|
|
1508
1531
|
// src/symbolic/PartialFractions.ts
|
|
1509
1532
|
var APART_MAX_DEGREE = 12;
|
|
1510
1533
|
function multiply2(a, b) {
|
|
1511
1534
|
if (a.length === 0 || b.length === 0) return [];
|
|
1512
|
-
const product2 = new Array(a.length + b.length - 1).fill(
|
|
1535
|
+
const product2 = new Array(a.length + b.length - 1).fill(chunkA2DZ5BEJ_cjs.RATIONAL_ZERO);
|
|
1513
1536
|
a.forEach((left, i) => {
|
|
1514
1537
|
b.forEach((right, j) => {
|
|
1515
|
-
product2[i + j] =
|
|
1538
|
+
product2[i + j] = chunkA2DZ5BEJ_cjs.rationalAdd(product2[i + j], chunkA2DZ5BEJ_cjs.rationalMul(left, right));
|
|
1516
1539
|
});
|
|
1517
1540
|
});
|
|
1518
1541
|
return product2;
|
|
1519
1542
|
}
|
|
1520
1543
|
function power2(base, exponent) {
|
|
1521
|
-
let result = [
|
|
1544
|
+
let result = [chunkA2DZ5BEJ_cjs.RATIONAL_ONE];
|
|
1522
1545
|
for (let i = 0; i < exponent; i++) result = multiply2(result, base);
|
|
1523
1546
|
return result;
|
|
1524
1547
|
}
|
|
1525
1548
|
function scale(coefficients, factor) {
|
|
1526
|
-
return coefficients.map((coefficient) =>
|
|
1549
|
+
return coefficients.map((coefficient) => chunkA2DZ5BEJ_cjs.rationalDiv(coefficient, factor));
|
|
1527
1550
|
}
|
|
1528
1551
|
function denominatorFactors(ascending, variable) {
|
|
1529
1552
|
const factors = [];
|
|
1530
1553
|
let lowest = 0;
|
|
1531
|
-
while (lowest < ascending.length &&
|
|
1532
|
-
if (lowest > 0) factors.push({ base: [
|
|
1554
|
+
while (lowest < ascending.length && chunkA2DZ5BEJ_cjs.isRationalZero(ascending[lowest])) lowest++;
|
|
1555
|
+
if (lowest > 0) factors.push({ base: [chunkA2DZ5BEJ_cjs.RATIONAL_ZERO, chunkA2DZ5BEJ_cjs.RATIONAL_ONE], power: lowest });
|
|
1533
1556
|
const remaining = ascending.slice(lowest);
|
|
1534
1557
|
if (remaining.length > 1) {
|
|
1535
1558
|
const factorization = factorUnivariate([...remaining].reverse(), variable);
|
|
1536
1559
|
for (const factor of factorization.factors) {
|
|
1537
|
-
const polynomial =
|
|
1560
|
+
const polynomial = chunkA2DZ5BEJ_cjs.toPolynomial(factor.base);
|
|
1538
1561
|
if (polynomial === null) return null;
|
|
1539
|
-
factors.push({ base: [...
|
|
1562
|
+
factors.push({ base: [...chunkA2DZ5BEJ_cjs.polyCoefficients(polynomial, variable)], power: factor.power });
|
|
1540
1563
|
}
|
|
1541
1564
|
}
|
|
1542
1565
|
return factors.length > 0 ? factors : null;
|
|
@@ -1555,10 +1578,10 @@ function enumerateUnknowns(factors) {
|
|
|
1555
1578
|
}
|
|
1556
1579
|
function unknownColumn(unknown, factors, denominator) {
|
|
1557
1580
|
const divisor = power2(factors[unknown.factor].base, unknown.power);
|
|
1558
|
-
const { quotient, remainder } =
|
|
1559
|
-
if (!
|
|
1560
|
-
const shift = new Array(unknown.degree).fill(
|
|
1561
|
-
shift.push(
|
|
1581
|
+
const { quotient, remainder } = chunkA2DZ5BEJ_cjs.polynomialDivide(denominator, divisor);
|
|
1582
|
+
if (!chunkA2DZ5BEJ_cjs.isZeroPolynomial(remainder)) return null;
|
|
1583
|
+
const shift = new Array(unknown.degree).fill(chunkA2DZ5BEJ_cjs.RATIONAL_ZERO);
|
|
1584
|
+
shift.push(chunkA2DZ5BEJ_cjs.RATIONAL_ONE);
|
|
1562
1585
|
return multiply2(quotient, shift);
|
|
1563
1586
|
}
|
|
1564
1587
|
function solveLinearSystem(matrix, target) {
|
|
@@ -1566,7 +1589,7 @@ function solveLinearSystem(matrix, target) {
|
|
|
1566
1589
|
for (let column = 0; column < size; column++) {
|
|
1567
1590
|
let pivot = -1;
|
|
1568
1591
|
for (let row = column; row < size; row++) {
|
|
1569
|
-
if (!
|
|
1592
|
+
if (!chunkA2DZ5BEJ_cjs.isRationalZero(matrix[row][column])) {
|
|
1570
1593
|
pivot = row;
|
|
1571
1594
|
break;
|
|
1572
1595
|
}
|
|
@@ -1575,21 +1598,21 @@ function solveLinearSystem(matrix, target) {
|
|
|
1575
1598
|
[matrix[column], matrix[pivot]] = [matrix[pivot], matrix[column]];
|
|
1576
1599
|
[target[column], target[pivot]] = [target[pivot], target[column]];
|
|
1577
1600
|
for (let row = 0; row < size; row++) {
|
|
1578
|
-
if (row === column ||
|
|
1579
|
-
const factor =
|
|
1601
|
+
if (row === column || chunkA2DZ5BEJ_cjs.isRationalZero(matrix[row][column])) continue;
|
|
1602
|
+
const factor = chunkA2DZ5BEJ_cjs.rationalDiv(matrix[row][column], matrix[column][column]);
|
|
1580
1603
|
for (let k = column; k < size; k++) {
|
|
1581
|
-
matrix[row][k] =
|
|
1604
|
+
matrix[row][k] = chunkA2DZ5BEJ_cjs.rationalSub(matrix[row][k], chunkA2DZ5BEJ_cjs.rationalMul(factor, matrix[column][k]));
|
|
1582
1605
|
}
|
|
1583
|
-
target[row] =
|
|
1606
|
+
target[row] = chunkA2DZ5BEJ_cjs.rationalSub(target[row], chunkA2DZ5BEJ_cjs.rationalMul(factor, target[column]));
|
|
1584
1607
|
}
|
|
1585
1608
|
}
|
|
1586
|
-
return target.map((value, index) =>
|
|
1609
|
+
return target.map((value, index) => chunkA2DZ5BEJ_cjs.rationalDiv(value, matrix[index][index]));
|
|
1587
1610
|
}
|
|
1588
1611
|
function partialFractions(numerator, denominator, variable) {
|
|
1589
1612
|
if (denominator.length < 2 || denominator.length - 1 > APART_MAX_DEGREE) return null;
|
|
1590
|
-
const shared =
|
|
1591
|
-
const reducedNumerator = shared.length > 1 ?
|
|
1592
|
-
const reducedDenominator = shared.length > 1 ?
|
|
1613
|
+
const shared = chunkA2DZ5BEJ_cjs.coefficientGcd(numerator, denominator);
|
|
1614
|
+
const reducedNumerator = shared.length > 1 ? chunkA2DZ5BEJ_cjs.polynomialDivide(numerator, shared).quotient : [...numerator];
|
|
1615
|
+
const reducedDenominator = shared.length > 1 ? chunkA2DZ5BEJ_cjs.polynomialDivide(denominator, shared).quotient : [...denominator];
|
|
1593
1616
|
if (reducedDenominator.length === 1) {
|
|
1594
1617
|
return { polynomial: scale(reducedNumerator, reducedDenominator[0]), terms: [] };
|
|
1595
1618
|
}
|
|
@@ -1597,8 +1620,8 @@ function partialFractions(numerator, denominator, variable) {
|
|
|
1597
1620
|
const leading = reducedDenominator[reducedDenominator.length - 1];
|
|
1598
1621
|
const monicDenominator = scale(reducedDenominator, leading);
|
|
1599
1622
|
const scaledNumerator = scale(reducedNumerator, leading);
|
|
1600
|
-
const { quotient, remainder } =
|
|
1601
|
-
if (
|
|
1623
|
+
const { quotient, remainder } = chunkA2DZ5BEJ_cjs.polynomialDivide(scaledNumerator, monicDenominator);
|
|
1624
|
+
if (chunkA2DZ5BEJ_cjs.isZeroPolynomial(remainder)) return { polynomial: quotient, terms: [] };
|
|
1602
1625
|
const factors = denominatorFactors(monicDenominator, variable);
|
|
1603
1626
|
if (factors === null) return null;
|
|
1604
1627
|
const terms = solveForNumerators(factors, monicDenominator, remainder);
|
|
@@ -1616,10 +1639,10 @@ function solveForNumerators(factors, denominator, remainder) {
|
|
|
1616
1639
|
}
|
|
1617
1640
|
const matrix = [];
|
|
1618
1641
|
for (let row = 0; row < size; row++) {
|
|
1619
|
-
matrix.push(columns.map((column) => column[row] ??
|
|
1642
|
+
matrix.push(columns.map((column) => column[row] ?? chunkA2DZ5BEJ_cjs.RATIONAL_ZERO));
|
|
1620
1643
|
}
|
|
1621
1644
|
const target = [];
|
|
1622
|
-
for (let row = 0; row < size; row++) target.push(remainder[row] ??
|
|
1645
|
+
for (let row = 0; row < size; row++) target.push(remainder[row] ?? chunkA2DZ5BEJ_cjs.RATIONAL_ZERO);
|
|
1623
1646
|
const solution = solveLinearSystem(matrix, target);
|
|
1624
1647
|
if (solution === null) return null;
|
|
1625
1648
|
return groupSolution(unknowns, solution, factors);
|
|
@@ -1635,8 +1658,8 @@ function groupSolution(unknowns, solution, factors) {
|
|
|
1635
1658
|
const terms = [];
|
|
1636
1659
|
for (const [key, coefficients] of grouped) {
|
|
1637
1660
|
const [factorIndex, termPower] = key.split(":").map(Number);
|
|
1638
|
-
const filled = [...coefficients].map((value) => value ??
|
|
1639
|
-
if (filled.every(
|
|
1661
|
+
const filled = [...coefficients].map((value) => value ?? chunkA2DZ5BEJ_cjs.RATIONAL_ZERO);
|
|
1662
|
+
if (filled.every(chunkA2DZ5BEJ_cjs.isRationalZero)) continue;
|
|
1640
1663
|
terms.push({ numerator: filled, base: factors[factorIndex].base, power: termPower });
|
|
1641
1664
|
}
|
|
1642
1665
|
return terms;
|
|
@@ -1644,11 +1667,11 @@ function groupSolution(unknowns, solution, factors) {
|
|
|
1644
1667
|
function coefficientsToNode2(coefficients, variable) {
|
|
1645
1668
|
const terms = /* @__PURE__ */ new Map();
|
|
1646
1669
|
coefficients.forEach((coefficient, exponent) => {
|
|
1647
|
-
if (
|
|
1670
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(coefficient)) return;
|
|
1648
1671
|
terms.set(exponent === 0 ? "" : exponent === 1 ? variable : `${variable}^${exponent}`, coefficient);
|
|
1649
1672
|
});
|
|
1650
|
-
if (terms.size === 0) return
|
|
1651
|
-
return
|
|
1673
|
+
if (terms.size === 0) return chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.RATIONAL_ZERO);
|
|
1674
|
+
return chunkA2DZ5BEJ_cjs.fromPolynomial({ terms, vars: coefficients.length > 1 ? [variable] : [] });
|
|
1652
1675
|
}
|
|
1653
1676
|
function apartSymbolic(node) {
|
|
1654
1677
|
const parts = asRationalFunction(node);
|
|
@@ -1658,9 +1681,9 @@ function apartSymbolic(node) {
|
|
|
1658
1681
|
let result = decomposition.polynomial.length > 0 ? coefficientsToNode2(decomposition.polynomial, parts.variable) : null;
|
|
1659
1682
|
for (const term of decomposition.terms) {
|
|
1660
1683
|
const base = coefficientsToNode2(term.base, parts.variable);
|
|
1661
|
-
const denominator = term.power === 1 ? base :
|
|
1684
|
+
const denominator = term.power === 1 ? base : chunkA2DZ5BEJ_cjs.powNode(base, chunkA2DZ5BEJ_cjs.constNode({ n: BigInt(term.power), d: 1n }));
|
|
1662
1685
|
const negative = isNegativeNumerator(term.numerator);
|
|
1663
|
-
const numerator = negative ? term.numerator.map((coefficient) =>
|
|
1686
|
+
const numerator = negative ? term.numerator.map((coefficient) => chunkA2DZ5BEJ_cjs.rationalNeg(coefficient)) : term.numerator;
|
|
1664
1687
|
const piece = {
|
|
1665
1688
|
kind: "div",
|
|
1666
1689
|
left: coefficientsToNode2(numerator, parts.variable),
|
|
@@ -1669,22 +1692,22 @@ function apartSymbolic(node) {
|
|
|
1669
1692
|
if (result === null) result = negative ? { kind: "neg", operand: piece } : piece;
|
|
1670
1693
|
else result = { kind: negative ? "sub" : "add", left: result, right: piece };
|
|
1671
1694
|
}
|
|
1672
|
-
return result === null ? node :
|
|
1695
|
+
return result === null ? node : chunkA2DZ5BEJ_cjs.simplifySymbolic(result);
|
|
1673
1696
|
}
|
|
1674
1697
|
function isNegativeNumerator(coefficients) {
|
|
1675
1698
|
return coefficients.some((coefficient) => coefficient.n < 0n) && coefficients.every((coefficient) => coefficient.n <= 0n);
|
|
1676
1699
|
}
|
|
1677
1700
|
function asRationalFunction(node) {
|
|
1678
1701
|
if (node.kind !== "div") return null;
|
|
1679
|
-
const numerator =
|
|
1680
|
-
const denominator =
|
|
1702
|
+
const numerator = chunkA2DZ5BEJ_cjs.toPolynomial(node.left);
|
|
1703
|
+
const denominator = chunkA2DZ5BEJ_cjs.toPolynomial(node.right);
|
|
1681
1704
|
if (numerator === null || denominator === null) return null;
|
|
1682
|
-
const variable =
|
|
1705
|
+
const variable = chunkA2DZ5BEJ_cjs.polyUnivariateVar(denominator);
|
|
1683
1706
|
if (variable === null) return null;
|
|
1684
1707
|
if (numerator.vars.some((name) => name !== variable)) return null;
|
|
1685
1708
|
return {
|
|
1686
|
-
numerator:
|
|
1687
|
-
denominator:
|
|
1709
|
+
numerator: chunkA2DZ5BEJ_cjs.polyCoefficients(numerator, variable),
|
|
1710
|
+
denominator: chunkA2DZ5BEJ_cjs.polyCoefficients(denominator, variable),
|
|
1688
1711
|
variable
|
|
1689
1712
|
};
|
|
1690
1713
|
}
|
|
@@ -1692,66 +1715,66 @@ function asRationalFunction(node) {
|
|
|
1692
1715
|
// src/symbolic/Derivative.ts
|
|
1693
1716
|
var DERIVATIVE_MAX_ORDER = 16;
|
|
1694
1717
|
function zero() {
|
|
1695
|
-
return
|
|
1718
|
+
return chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.RATIONAL_ZERO);
|
|
1696
1719
|
}
|
|
1697
1720
|
function one() {
|
|
1698
|
-
return
|
|
1721
|
+
return chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.RATIONAL_ONE);
|
|
1699
1722
|
}
|
|
1700
1723
|
function functionDerivative(name, argument) {
|
|
1701
1724
|
switch (name) {
|
|
1702
1725
|
case "sin":
|
|
1703
|
-
return
|
|
1726
|
+
return chunkA2DZ5BEJ_cjs.callNode("cos", [argument]);
|
|
1704
1727
|
case "cos":
|
|
1705
|
-
return { kind: "neg", operand:
|
|
1728
|
+
return { kind: "neg", operand: chunkA2DZ5BEJ_cjs.callNode("sin", [argument]) };
|
|
1706
1729
|
case "tan":
|
|
1707
|
-
return { kind: "div", left: one(), right:
|
|
1730
|
+
return { kind: "div", left: one(), right: chunkA2DZ5BEJ_cjs.powNode(chunkA2DZ5BEJ_cjs.callNode("cos", [argument]), chunkA2DZ5BEJ_cjs.constNode(2)) };
|
|
1708
1731
|
case "exp":
|
|
1709
|
-
return
|
|
1732
|
+
return chunkA2DZ5BEJ_cjs.callNode("exp", [argument]);
|
|
1710
1733
|
case "log":
|
|
1711
1734
|
return { kind: "div", left: one(), right: argument };
|
|
1712
1735
|
case "sqrt":
|
|
1713
1736
|
return {
|
|
1714
1737
|
kind: "div",
|
|
1715
1738
|
left: one(),
|
|
1716
|
-
right: { kind: "mul", left:
|
|
1739
|
+
right: { kind: "mul", left: chunkA2DZ5BEJ_cjs.constNode(2), right: chunkA2DZ5BEJ_cjs.callNode("sqrt", [argument]) }
|
|
1717
1740
|
};
|
|
1718
1741
|
case "asin":
|
|
1719
|
-
return { kind: "div", left: one(), right:
|
|
1742
|
+
return { kind: "div", left: one(), right: chunkA2DZ5BEJ_cjs.callNode("sqrt", [oneMinusSquare(argument)]) };
|
|
1720
1743
|
case "acos":
|
|
1721
|
-
return { kind: "neg", operand: { kind: "div", left: one(), right:
|
|
1744
|
+
return { kind: "neg", operand: { kind: "div", left: one(), right: chunkA2DZ5BEJ_cjs.callNode("sqrt", [oneMinusSquare(argument)]) } };
|
|
1722
1745
|
case "atan":
|
|
1723
1746
|
return { kind: "div", left: one(), right: onePlusSquare(argument) };
|
|
1724
1747
|
case "sinh":
|
|
1725
|
-
return
|
|
1748
|
+
return chunkA2DZ5BEJ_cjs.callNode("cosh", [argument]);
|
|
1726
1749
|
case "cosh":
|
|
1727
|
-
return
|
|
1750
|
+
return chunkA2DZ5BEJ_cjs.callNode("sinh", [argument]);
|
|
1728
1751
|
case "tanh":
|
|
1729
|
-
return { kind: "div", left: one(), right:
|
|
1752
|
+
return { kind: "div", left: one(), right: chunkA2DZ5BEJ_cjs.powNode(chunkA2DZ5BEJ_cjs.callNode("cosh", [argument]), chunkA2DZ5BEJ_cjs.constNode(2)) };
|
|
1730
1753
|
case "abs":
|
|
1731
|
-
return
|
|
1754
|
+
return chunkA2DZ5BEJ_cjs.callNode("sign", [argument]);
|
|
1732
1755
|
default:
|
|
1733
1756
|
return null;
|
|
1734
1757
|
}
|
|
1735
1758
|
}
|
|
1736
1759
|
function oneMinusSquare(argument) {
|
|
1737
|
-
return { kind: "sub", left: one(), right:
|
|
1760
|
+
return { kind: "sub", left: one(), right: chunkA2DZ5BEJ_cjs.powNode(argument, chunkA2DZ5BEJ_cjs.constNode(2)) };
|
|
1738
1761
|
}
|
|
1739
1762
|
function onePlusSquare(argument) {
|
|
1740
|
-
return { kind: "add", left: one(), right:
|
|
1763
|
+
return { kind: "add", left: one(), right: chunkA2DZ5BEJ_cjs.powNode(argument, chunkA2DZ5BEJ_cjs.constNode(2)) };
|
|
1741
1764
|
}
|
|
1742
1765
|
function differentiate2(node, variable, order = 1) {
|
|
1743
1766
|
if (order < 0 || !Number.isInteger(order)) {
|
|
1744
|
-
throw
|
|
1767
|
+
throw chunkMIGXCBXT_cjs.ErrorFactory.execution("SYMBOLIC_DERIVATIVE_ORDER_LIMIT", "A derivative order must be a whole number, at least zero.");
|
|
1745
1768
|
}
|
|
1746
1769
|
if (order > DERIVATIVE_MAX_ORDER) {
|
|
1747
|
-
throw
|
|
1770
|
+
throw chunkMIGXCBXT_cjs.ErrorFactory.execution(
|
|
1748
1771
|
"SYMBOLIC_DERIVATIVE_ORDER_LIMIT",
|
|
1749
1772
|
`A derivative order above ${DERIVATIVE_MAX_ORDER} is not supported.`,
|
|
1750
1773
|
{ limit: DERIVATIVE_MAX_ORDER }
|
|
1751
1774
|
);
|
|
1752
1775
|
}
|
|
1753
|
-
let result =
|
|
1754
|
-
for (let i = 0; i < order; i++) result =
|
|
1776
|
+
let result = chunkA2DZ5BEJ_cjs.simplifySymbolic(node);
|
|
1777
|
+
for (let i = 0; i < order; i++) result = chunkA2DZ5BEJ_cjs.simplifySymbolic(derive(result, variable));
|
|
1755
1778
|
return result;
|
|
1756
1779
|
}
|
|
1757
1780
|
function derive(node, variable) {
|
|
@@ -1781,7 +1804,7 @@ function derive(node, variable) {
|
|
|
1781
1804
|
left: { kind: "mul", left: derive(node.left, variable), right: node.right },
|
|
1782
1805
|
right: { kind: "mul", left: node.left, right: derive(node.right, variable) }
|
|
1783
1806
|
},
|
|
1784
|
-
right:
|
|
1807
|
+
right: chunkA2DZ5BEJ_cjs.powNode(node.right, chunkA2DZ5BEJ_cjs.constNode(2))
|
|
1785
1808
|
};
|
|
1786
1809
|
case "pow":
|
|
1787
1810
|
return derivePow(node, variable);
|
|
@@ -1795,79 +1818,79 @@ function derive(node, variable) {
|
|
|
1795
1818
|
}
|
|
1796
1819
|
function derivePow(node, variable) {
|
|
1797
1820
|
if (node.exponent.kind === "const") {
|
|
1798
|
-
const reduced =
|
|
1821
|
+
const reduced = chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalSub(node.exponent.value, chunkA2DZ5BEJ_cjs.RATIONAL_ONE));
|
|
1799
1822
|
return {
|
|
1800
1823
|
kind: "mul",
|
|
1801
|
-
left: { kind: "mul", left: node.exponent, right:
|
|
1824
|
+
left: { kind: "mul", left: node.exponent, right: chunkA2DZ5BEJ_cjs.powNode(node.base, reduced) },
|
|
1802
1825
|
right: derive(node.base, variable)
|
|
1803
1826
|
};
|
|
1804
1827
|
}
|
|
1805
1828
|
if (node.base.kind === "const" && node.base.value.n > 0n) {
|
|
1806
1829
|
return {
|
|
1807
1830
|
kind: "mul",
|
|
1808
|
-
left: { kind: "mul", left: node, right:
|
|
1831
|
+
left: { kind: "mul", left: node, right: chunkA2DZ5BEJ_cjs.callNode("log", [node.base]) },
|
|
1809
1832
|
right: derive(node.exponent, variable)
|
|
1810
1833
|
};
|
|
1811
1834
|
}
|
|
1812
1835
|
return unevaluated(node, variable);
|
|
1813
1836
|
}
|
|
1814
1837
|
function unevaluated(node, variable) {
|
|
1815
|
-
return
|
|
1838
|
+
return chunkA2DZ5BEJ_cjs.callNode("der", [node, chunkA2DZ5BEJ_cjs.varNode(variable)]);
|
|
1816
1839
|
}
|
|
1817
1840
|
|
|
1818
1841
|
// src/symbolic/Integral.ts
|
|
1819
1842
|
function asLinear(node, variable) {
|
|
1820
|
-
const polynomial =
|
|
1843
|
+
const polynomial = chunkA2DZ5BEJ_cjs.toPolynomial(node);
|
|
1821
1844
|
if (polynomial === null) return null;
|
|
1822
1845
|
const others = polynomial.vars.filter((name) => name !== variable);
|
|
1823
1846
|
if (others.length > 0) return null;
|
|
1824
|
-
if (
|
|
1825
|
-
const ascending =
|
|
1847
|
+
if (chunkA2DZ5BEJ_cjs.polyDegree(polynomial, variable) > 1) return null;
|
|
1848
|
+
const ascending = chunkA2DZ5BEJ_cjs.polyCoefficients(polynomial, variable);
|
|
1826
1849
|
const intercept = ascending[0] ?? { n: 0n, d: 1n };
|
|
1827
1850
|
const slope = ascending[1] ?? { n: 0n, d: 1n };
|
|
1828
|
-
return
|
|
1851
|
+
return chunkA2DZ5BEJ_cjs.isRationalZero(slope) ? null : { slope, intercept };
|
|
1829
1852
|
}
|
|
1830
1853
|
function integratePolynomial(node, variable) {
|
|
1831
|
-
const polynomial =
|
|
1854
|
+
const polynomial = chunkA2DZ5BEJ_cjs.toPolynomial(node);
|
|
1832
1855
|
if (polynomial === null) return null;
|
|
1833
1856
|
const others = polynomial.vars.filter((name) => name !== variable);
|
|
1834
1857
|
if (others.length > 0) {
|
|
1835
1858
|
return { ok: false, reason: `it involves more than one unknown (${others.join(", ")})` };
|
|
1836
1859
|
}
|
|
1837
|
-
const ascending =
|
|
1838
|
-
let result =
|
|
1860
|
+
const ascending = chunkA2DZ5BEJ_cjs.polyCoefficients(polynomial, variable);
|
|
1861
|
+
let result = chunkA2DZ5BEJ_cjs.constNode(0);
|
|
1839
1862
|
ascending.forEach((coeff, power3) => {
|
|
1840
|
-
if (
|
|
1863
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(coeff)) return;
|
|
1841
1864
|
const nextPower = power3 + 1;
|
|
1842
|
-
const scaled =
|
|
1865
|
+
const scaled = chunkA2DZ5BEJ_cjs.rationalDiv(coeff, { n: BigInt(nextPower), d: 1n });
|
|
1843
1866
|
const term = {
|
|
1844
1867
|
kind: "mul",
|
|
1845
|
-
left:
|
|
1846
|
-
right: nextPower === 1 ?
|
|
1868
|
+
left: chunkA2DZ5BEJ_cjs.constNode(scaled),
|
|
1869
|
+
right: nextPower === 1 ? chunkA2DZ5BEJ_cjs.varNode(variable) : chunkA2DZ5BEJ_cjs.powNode(chunkA2DZ5BEJ_cjs.varNode(variable), chunkA2DZ5BEJ_cjs.constNode(nextPower))
|
|
1847
1870
|
};
|
|
1848
1871
|
result = { kind: "add", left: result, right: term };
|
|
1849
1872
|
});
|
|
1850
|
-
return { ok: true, value:
|
|
1873
|
+
return { ok: true, value: chunkA2DZ5BEJ_cjs.simplifySymbolic(result) };
|
|
1851
1874
|
}
|
|
1852
1875
|
function integrateStandardForm(node, variable) {
|
|
1853
1876
|
if (node.kind !== "call" || node.args.length !== 1) return null;
|
|
1854
1877
|
const linear = asLinear(node.args[0], variable);
|
|
1855
1878
|
if (linear === null) return null;
|
|
1856
1879
|
const inner = node.args[0];
|
|
1857
|
-
const divideBySlope = (value) =>
|
|
1880
|
+
const divideBySlope = (value) => chunkA2DZ5BEJ_cjs.simplifySymbolic({ kind: "div", left: value, right: chunkA2DZ5BEJ_cjs.constNode(linear.slope) });
|
|
1858
1881
|
switch (node.name) {
|
|
1859
1882
|
case "exp":
|
|
1860
|
-
return { ok: true, value: divideBySlope(
|
|
1883
|
+
return { ok: true, value: divideBySlope(chunkA2DZ5BEJ_cjs.callNode("exp", [inner])) };
|
|
1861
1884
|
case "sin":
|
|
1862
|
-
return { ok: true, value: divideBySlope({ kind: "neg", operand:
|
|
1885
|
+
return { ok: true, value: divideBySlope({ kind: "neg", operand: chunkA2DZ5BEJ_cjs.callNode("cos", [inner]) }) };
|
|
1863
1886
|
case "cos":
|
|
1864
|
-
return { ok: true, value: divideBySlope(
|
|
1887
|
+
return { ok: true, value: divideBySlope(chunkA2DZ5BEJ_cjs.callNode("sin", [inner])) };
|
|
1865
1888
|
case "log":
|
|
1866
1889
|
return {
|
|
1867
1890
|
ok: true,
|
|
1868
1891
|
value: divideBySlope({
|
|
1869
1892
|
kind: "sub",
|
|
1870
|
-
left: { kind: "mul", left: inner, right:
|
|
1893
|
+
left: { kind: "mul", left: inner, right: chunkA2DZ5BEJ_cjs.callNode("log", [inner]) },
|
|
1871
1894
|
right: inner
|
|
1872
1895
|
})
|
|
1873
1896
|
};
|
|
@@ -1882,18 +1905,18 @@ function integrateReciprocalForms(node, variable) {
|
|
|
1882
1905
|
if (linear !== null) {
|
|
1883
1906
|
return {
|
|
1884
1907
|
ok: true,
|
|
1885
|
-
value:
|
|
1908
|
+
value: chunkA2DZ5BEJ_cjs.simplifySymbolic({
|
|
1886
1909
|
kind: "div",
|
|
1887
|
-
left:
|
|
1888
|
-
right:
|
|
1910
|
+
left: chunkA2DZ5BEJ_cjs.callNode("log", [node.right]),
|
|
1911
|
+
right: chunkA2DZ5BEJ_cjs.constNode(linear.slope)
|
|
1889
1912
|
})
|
|
1890
1913
|
};
|
|
1891
1914
|
}
|
|
1892
|
-
const denominator =
|
|
1915
|
+
const denominator = chunkA2DZ5BEJ_cjs.toPolynomial(node.right);
|
|
1893
1916
|
if (denominator !== null && denominator.vars.length === 1 && denominator.vars[0] === variable) {
|
|
1894
|
-
const ascending =
|
|
1895
|
-
const isOnePlusSquare = ascending.length === 3 && isRationalOneNode(ascending[0]) &&
|
|
1896
|
-
if (isOnePlusSquare) return { ok: true, value:
|
|
1917
|
+
const ascending = chunkA2DZ5BEJ_cjs.polyCoefficients(denominator, variable);
|
|
1918
|
+
const isOnePlusSquare = ascending.length === 3 && isRationalOneNode(ascending[0]) && chunkA2DZ5BEJ_cjs.isRationalZero(ascending[1]) && isRationalOneNode(ascending[2]);
|
|
1919
|
+
if (isOnePlusSquare) return { ok: true, value: chunkA2DZ5BEJ_cjs.callNode("atan", [chunkA2DZ5BEJ_cjs.varNode(variable)]) };
|
|
1897
1920
|
}
|
|
1898
1921
|
return null;
|
|
1899
1922
|
}
|
|
@@ -1905,7 +1928,7 @@ function integrateRationalFunction(node, variable) {
|
|
|
1905
1928
|
if (parts === null || parts.variable !== variable) return null;
|
|
1906
1929
|
const decomposition = partialFractions(parts.numerator, parts.denominator, variable);
|
|
1907
1930
|
if (decomposition === null) return null;
|
|
1908
|
-
let result = decomposition.polynomial.length > 0 ? polynomialAntiderivative(decomposition.polynomial, variable) :
|
|
1931
|
+
let result = decomposition.polynomial.length > 0 ? polynomialAntiderivative(decomposition.polynomial, variable) : chunkA2DZ5BEJ_cjs.constNode(0);
|
|
1909
1932
|
for (const term of decomposition.terms) {
|
|
1910
1933
|
const piece = integrateTerm(term, variable);
|
|
1911
1934
|
if (piece === null) {
|
|
@@ -1916,72 +1939,72 @@ function integrateRationalFunction(node, variable) {
|
|
|
1916
1939
|
}
|
|
1917
1940
|
result = { kind: "add", left: result, right: piece };
|
|
1918
1941
|
}
|
|
1919
|
-
return { ok: true, value:
|
|
1942
|
+
return { ok: true, value: chunkA2DZ5BEJ_cjs.simplifySymbolic(result) };
|
|
1920
1943
|
}
|
|
1921
1944
|
function integrateTerm(term, variable) {
|
|
1922
1945
|
const baseDegree = term.base.length - 1;
|
|
1923
1946
|
const base = coefficientsToNode2(term.base, variable);
|
|
1924
1947
|
if (baseDegree === 1) {
|
|
1925
|
-
const coefficient = term.numerator[0] ??
|
|
1948
|
+
const coefficient = term.numerator[0] ?? chunkA2DZ5BEJ_cjs.RATIONAL_ZERO;
|
|
1926
1949
|
if (term.power === 1) {
|
|
1927
|
-
return { kind: "mul", left:
|
|
1950
|
+
return { kind: "mul", left: chunkA2DZ5BEJ_cjs.constNode(coefficient), right: chunkA2DZ5BEJ_cjs.callNode("log", [base]) };
|
|
1928
1951
|
}
|
|
1929
1952
|
const reduced = term.power - 1;
|
|
1930
|
-
const scaled =
|
|
1953
|
+
const scaled = chunkA2DZ5BEJ_cjs.rationalDiv(coefficient, { n: BigInt(-reduced), d: 1n });
|
|
1931
1954
|
return {
|
|
1932
1955
|
kind: "div",
|
|
1933
|
-
left:
|
|
1934
|
-
right:
|
|
1956
|
+
left: chunkA2DZ5BEJ_cjs.constNode(scaled),
|
|
1957
|
+
right: chunkA2DZ5BEJ_cjs.powNode(base, chunkA2DZ5BEJ_cjs.constNode({ n: BigInt(reduced), d: 1n }))
|
|
1935
1958
|
};
|
|
1936
1959
|
}
|
|
1937
1960
|
if (baseDegree !== 2 || term.power !== 1) return null;
|
|
1938
1961
|
return integrateQuadraticTerm(term, variable, base);
|
|
1939
1962
|
}
|
|
1940
1963
|
function integrateQuadraticTerm(term, variable, base) {
|
|
1941
|
-
const constant = term.numerator[0] ??
|
|
1942
|
-
const linear = term.numerator[1] ??
|
|
1964
|
+
const constant = term.numerator[0] ?? chunkA2DZ5BEJ_cjs.RATIONAL_ZERO;
|
|
1965
|
+
const linear = term.numerator[1] ?? chunkA2DZ5BEJ_cjs.RATIONAL_ZERO;
|
|
1943
1966
|
const [q, p] = term.base;
|
|
1944
1967
|
const half = { n: 1n, d: 2n };
|
|
1945
|
-
const halfP =
|
|
1968
|
+
const halfP = chunkA2DZ5BEJ_cjs.rationalMul(p, half);
|
|
1946
1969
|
const logarithm = {
|
|
1947
1970
|
kind: "mul",
|
|
1948
|
-
left:
|
|
1949
|
-
right:
|
|
1971
|
+
left: chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.rationalMul(linear, half)),
|
|
1972
|
+
right: chunkA2DZ5BEJ_cjs.callNode("log", [base])
|
|
1950
1973
|
};
|
|
1951
|
-
const leftover =
|
|
1952
|
-
if (
|
|
1953
|
-
const width =
|
|
1974
|
+
const leftover = chunkA2DZ5BEJ_cjs.rationalSub(constant, chunkA2DZ5BEJ_cjs.rationalMul(linear, halfP));
|
|
1975
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(leftover)) return logarithm;
|
|
1976
|
+
const width = chunkA2DZ5BEJ_cjs.surdNode(chunkA2DZ5BEJ_cjs.rationalSub(q, chunkA2DZ5BEJ_cjs.rationalMul(halfP, halfP)));
|
|
1954
1977
|
const shifted = {
|
|
1955
1978
|
kind: "add",
|
|
1956
|
-
left:
|
|
1957
|
-
right:
|
|
1979
|
+
left: chunkA2DZ5BEJ_cjs.varNode(variable),
|
|
1980
|
+
right: chunkA2DZ5BEJ_cjs.constNode(halfP)
|
|
1958
1981
|
};
|
|
1959
1982
|
const arctangent = {
|
|
1960
1983
|
kind: "mul",
|
|
1961
|
-
left: { kind: "div", left:
|
|
1962
|
-
right:
|
|
1984
|
+
left: { kind: "div", left: chunkA2DZ5BEJ_cjs.constNode(leftover), right: width },
|
|
1985
|
+
right: chunkA2DZ5BEJ_cjs.callNode("atan", [{ kind: "div", left: shifted, right: width }])
|
|
1963
1986
|
};
|
|
1964
|
-
return
|
|
1987
|
+
return chunkA2DZ5BEJ_cjs.isRationalZero(linear) ? arctangent : { kind: "add", left: logarithm, right: arctangent };
|
|
1965
1988
|
}
|
|
1966
1989
|
function polynomialAntiderivative(ascending, variable) {
|
|
1967
|
-
let result =
|
|
1990
|
+
let result = chunkA2DZ5BEJ_cjs.constNode(0);
|
|
1968
1991
|
ascending.forEach((coeff, exponent) => {
|
|
1969
|
-
if (
|
|
1992
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(coeff)) return;
|
|
1970
1993
|
const nextPower = exponent + 1;
|
|
1971
|
-
const scaled =
|
|
1994
|
+
const scaled = chunkA2DZ5BEJ_cjs.rationalDiv(coeff, { n: BigInt(nextPower), d: 1n });
|
|
1972
1995
|
const term = {
|
|
1973
1996
|
kind: "mul",
|
|
1974
|
-
left:
|
|
1975
|
-
right: nextPower === 1 ?
|
|
1997
|
+
left: chunkA2DZ5BEJ_cjs.constNode(scaled),
|
|
1998
|
+
right: nextPower === 1 ? chunkA2DZ5BEJ_cjs.varNode(variable) : chunkA2DZ5BEJ_cjs.powNode(chunkA2DZ5BEJ_cjs.varNode(variable), chunkA2DZ5BEJ_cjs.constNode(nextPower))
|
|
1976
1999
|
};
|
|
1977
2000
|
result = { kind: "add", left: result, right: term };
|
|
1978
2001
|
});
|
|
1979
2002
|
return result;
|
|
1980
2003
|
}
|
|
1981
2004
|
function integrate(node, variable) {
|
|
1982
|
-
const simplified =
|
|
1983
|
-
if (!
|
|
1984
|
-
return { ok: true, value:
|
|
2005
|
+
const simplified = chunkA2DZ5BEJ_cjs.simplifySymbolic(node);
|
|
2006
|
+
if (!chunkA2DZ5BEJ_cjs.freeVariables(simplified).has(variable)) {
|
|
2007
|
+
return { ok: true, value: chunkA2DZ5BEJ_cjs.simplifySymbolic({ kind: "mul", left: simplified, right: chunkA2DZ5BEJ_cjs.varNode(variable) }) };
|
|
1985
2008
|
}
|
|
1986
2009
|
const polynomial = integratePolynomial(simplified, variable);
|
|
1987
2010
|
if (polynomial !== null) return polynomial;
|
|
@@ -1998,13 +2021,13 @@ function integrate(node, variable) {
|
|
|
1998
2021
|
if (!right.ok) return right;
|
|
1999
2022
|
return {
|
|
2000
2023
|
ok: true,
|
|
2001
|
-
value:
|
|
2024
|
+
value: chunkA2DZ5BEJ_cjs.simplifySymbolic({ kind: simplified.kind, left: left.value, right: right.value })
|
|
2002
2025
|
};
|
|
2003
2026
|
}
|
|
2004
2027
|
if (simplified.kind === "mul" && simplified.left.kind === "const") {
|
|
2005
2028
|
const inner = integrate(simplified.right, variable);
|
|
2006
2029
|
if (!inner.ok) return inner;
|
|
2007
|
-
return { ok: true, value:
|
|
2030
|
+
return { ok: true, value: chunkA2DZ5BEJ_cjs.simplifySymbolic({ kind: "mul", left: simplified.left, right: inner.value }) };
|
|
2008
2031
|
}
|
|
2009
2032
|
return {
|
|
2010
2033
|
ok: false,
|
|
@@ -2016,33 +2039,33 @@ function integrate(node, variable) {
|
|
|
2016
2039
|
var TAYLOR_MAX_DEGREE = 16;
|
|
2017
2040
|
function taylorSeries(node, variable, point, degree) {
|
|
2018
2041
|
if (degree < 0 || !Number.isInteger(degree) || degree > TAYLOR_MAX_DEGREE) {
|
|
2019
|
-
throw
|
|
2042
|
+
throw chunkMIGXCBXT_cjs.ErrorFactory.execution(
|
|
2020
2043
|
"SYMBOLIC_TAYLOR_DEGREE_LIMIT",
|
|
2021
2044
|
`A Taylor degree must be a whole number from 0 to ${TAYLOR_MAX_DEGREE}.`,
|
|
2022
2045
|
{ limit: TAYLOR_MAX_DEGREE }
|
|
2023
2046
|
);
|
|
2024
2047
|
}
|
|
2025
|
-
const pointNode =
|
|
2048
|
+
const pointNode = chunkA2DZ5BEJ_cjs.constNode(point);
|
|
2026
2049
|
let factorial = 1n;
|
|
2027
|
-
let result =
|
|
2050
|
+
let result = chunkA2DZ5BEJ_cjs.constNode(chunkA2DZ5BEJ_cjs.RATIONAL_ZERO);
|
|
2028
2051
|
for (let order = 0; order <= degree; order++) {
|
|
2029
2052
|
if (order > 0) factorial *= BigInt(order);
|
|
2030
2053
|
const derivative = differentiate2(node, variable, order);
|
|
2031
|
-
const atPoint =
|
|
2054
|
+
const atPoint = chunkA2DZ5BEJ_cjs.simplifySymbolic(chunkA2DZ5BEJ_cjs.substitute(derivative, variable, pointNode));
|
|
2032
2055
|
if (atPoint.kind !== "const") {
|
|
2033
|
-
throw
|
|
2056
|
+
throw chunkMIGXCBXT_cjs.ErrorFactory.execution(
|
|
2034
2057
|
"SYMBOLIC_TAYLOR_INEXACT",
|
|
2035
2058
|
`The derivative of order ${order} does not reduce to an exact number at the expansion point, so this series cannot be computed exactly.`,
|
|
2036
2059
|
{ order }
|
|
2037
2060
|
);
|
|
2038
2061
|
}
|
|
2039
|
-
const coefficient =
|
|
2040
|
-
if (
|
|
2041
|
-
const shifted =
|
|
2042
|
-
const power3 = order === 0 ?
|
|
2043
|
-
result = { kind: "add", left: result, right: { kind: "mul", left:
|
|
2062
|
+
const coefficient = chunkA2DZ5BEJ_cjs.rationalDiv(atPoint.value, { n: factorial, d: 1n });
|
|
2063
|
+
if (chunkA2DZ5BEJ_cjs.isRationalZero(coefficient)) continue;
|
|
2064
|
+
const shifted = chunkA2DZ5BEJ_cjs.isRationalZero(point) ? chunkA2DZ5BEJ_cjs.varNode(variable) : { kind: "sub", left: chunkA2DZ5BEJ_cjs.varNode(variable), right: pointNode };
|
|
2065
|
+
const power3 = order === 0 ? chunkA2DZ5BEJ_cjs.constNode(1) : order === 1 ? shifted : chunkA2DZ5BEJ_cjs.powNode(shifted, chunkA2DZ5BEJ_cjs.constNode(order));
|
|
2066
|
+
result = { kind: "add", left: result, right: { kind: "mul", left: chunkA2DZ5BEJ_cjs.constNode(coefficient), right: power3 } };
|
|
2044
2067
|
}
|
|
2045
|
-
return
|
|
2068
|
+
return chunkA2DZ5BEJ_cjs.simplifySymbolic(result);
|
|
2046
2069
|
}
|
|
2047
2070
|
function jacobian(functions, variables) {
|
|
2048
2071
|
return functions.map((fn) => variables.map((variable) => differentiate2(fn, variable)));
|
|
@@ -2176,26 +2199,26 @@ function extremum(args, wantLargest) {
|
|
|
2176
2199
|
const bestUnit = best.type === 6 /* Uom */ ? best.unit : void 0;
|
|
2177
2200
|
const otherUnit = a.type === 6 /* Uom */ ? a.unit : void 0;
|
|
2178
2201
|
const named = describeMeasureMismatch(bestUnit, otherUnit, "compared");
|
|
2179
|
-
return
|
|
2202
|
+
return chunkIT74O4BE_cjs.errorValue(
|
|
2180
2203
|
"INCOMPATIBLE_UNITS",
|
|
2181
2204
|
named ?? `Cannot compare incompatible units: ${bestUnit ?? "?"} and ${otherUnit ?? "?"}`
|
|
2182
2205
|
);
|
|
2183
2206
|
}
|
|
2184
2207
|
if (wantLargest ? rv > lv : rv < lv) best = a;
|
|
2185
2208
|
}
|
|
2186
|
-
if (hasNaN) return
|
|
2187
|
-
if (best === void 0) return
|
|
2188
|
-
return best.type === 6 /* Uom */ ? best :
|
|
2209
|
+
if (hasNaN) return chunkIT74O4BE_cjs.numberValue(NaN);
|
|
2210
|
+
if (best === void 0) return chunkIT74O4BE_cjs.numberValue(wantLargest ? -Infinity : Infinity);
|
|
2211
|
+
return best.type === 6 /* Uom */ ? best : chunkIT74O4BE_cjs.numberValue(best.toNumber());
|
|
2189
2212
|
}
|
|
2190
2213
|
function keepUnit(operand, magnitude2) {
|
|
2191
|
-
if (operand.type === 6 /* Uom */ && operand.unit !== void 0) return
|
|
2192
|
-
return
|
|
2214
|
+
if (operand.type === 6 /* Uom */ && operand.unit !== void 0) return chunkIT74O4BE_cjs.uomValue(magnitude2, operand.unit);
|
|
2215
|
+
return chunkIT74O4BE_cjs.numberValue(magnitude2);
|
|
2193
2216
|
}
|
|
2194
2217
|
function roundToPlaces(source, places) {
|
|
2195
2218
|
const p = Number.isFinite(places) ? Math.min(100, Math.max(0, Math.trunc(places))) : 0;
|
|
2196
2219
|
if (source.exact !== void 0) {
|
|
2197
|
-
const rounded =
|
|
2198
|
-
return withPlaces(source,
|
|
2220
|
+
const rounded = chunkA2DZ5BEJ_cjs.decimalRound(source.exact, p);
|
|
2221
|
+
return withPlaces(source, chunkA2DZ5BEJ_cjs.decimalToNumber(rounded), p, rounded);
|
|
2199
2222
|
}
|
|
2200
2223
|
const value = source.toNumber();
|
|
2201
2224
|
if (!Number.isFinite(value)) return withPlaces(source, value, p);
|
|
@@ -2205,7 +2228,7 @@ function roundToPlaces(source, places) {
|
|
|
2205
2228
|
return withPlaces(source, Math.round(scaled) / scale2, p);
|
|
2206
2229
|
}
|
|
2207
2230
|
function withPlaces(source, magnitude2, places, exact) {
|
|
2208
|
-
const result = source.type === 6 /* Uom */ && source.unit !== void 0 ?
|
|
2231
|
+
const result = source.type === 6 /* Uom */ && source.unit !== void 0 ? chunkIT74O4BE_cjs.uomValue(magnitude2, source.unit) : chunkIT74O4BE_cjs.numberValue(magnitude2);
|
|
2209
2232
|
result.decimalPlaces = places;
|
|
2210
2233
|
if (exact !== void 0) result.exact = exact;
|
|
2211
2234
|
return result;
|
|
@@ -2213,7 +2236,7 @@ function withPlaces(source, magnitude2, places, exact) {
|
|
|
2213
2236
|
function nonFiniteEuclidOperand(a, b, name) {
|
|
2214
2237
|
if (Number.isFinite(a) && Number.isFinite(b)) return null;
|
|
2215
2238
|
const culprit = Number.isFinite(a) ? b : a;
|
|
2216
|
-
return
|
|
2239
|
+
return chunkIT74O4BE_cjs.errorValue(
|
|
2217
2240
|
"INVALID_INTEGER_OPERAND",
|
|
2218
2241
|
`${name} needs two whole numbers, and ${Number.isNaN(culprit) ? "one of them has no value" : "one of them is infinite"}`
|
|
2219
2242
|
);
|
|
@@ -2235,18 +2258,18 @@ var builtinFunctions = {
|
|
|
2235
2258
|
// first, so sqrt(-4) is 2i rather than an approximation.
|
|
2236
2259
|
0: (args) => {
|
|
2237
2260
|
const value = args[0].toNumber();
|
|
2238
|
-
if (value >= 0) return
|
|
2239
|
-
return symbolicToValue(
|
|
2261
|
+
if (value >= 0) return chunkIT74O4BE_cjs.numberValue(Math.sqrt(value));
|
|
2262
|
+
return symbolicToValue(chunkA2DZ5BEJ_cjs.callNode("sqrt", [chunkA2DZ5BEJ_cjs.constNode(value)]));
|
|
2240
2263
|
},
|
|
2241
2264
|
// abs(a): for a Matrix, "|a|" (Calca's determinant-pipe notation) is a
|
|
2242
2265
|
// valid alias for det(a) (index 64), reusing the SAME implementation
|
|
2243
2266
|
// not a separate one. Plain-number abs is unaffected.
|
|
2244
|
-
1: (args) => args[0].type === 7 /* Matrix */ ?
|
|
2267
|
+
1: (args) => args[0].type === 7 /* Matrix */ ? chunkA2DZ5BEJ_cjs.determinant(args[0].value) : keepUnit(args[0], Math.abs(args[0].toNumber())),
|
|
2245
2268
|
// sin/cos/tan accept an angle with a unit; see angleInRadians().
|
|
2246
|
-
2: (args) =>
|
|
2247
|
-
3: (args) =>
|
|
2248
|
-
4: (args) =>
|
|
2249
|
-
5: (args) =>
|
|
2269
|
+
2: (args) => chunkIT74O4BE_cjs.numberValue(Math.sin(angleInRadians(args[0]))),
|
|
2270
|
+
3: (args) => chunkIT74O4BE_cjs.numberValue(Math.cos(angleInRadians(args[0]))),
|
|
2271
|
+
4: (args) => chunkIT74O4BE_cjs.numberValue(Math.tan(angleInRadians(args[0]))),
|
|
2272
|
+
5: (args) => chunkIT74O4BE_cjs.numberValue(Math.log(args[0].toNumber())),
|
|
2250
2273
|
// round/ceil/floor keep a unit for the same reason abs does; see keepUnit().
|
|
2251
2274
|
6: (args) => keepUnit(args[0], Math.ceil(args[0].toNumber())),
|
|
2252
2275
|
7: (args) => keepUnit(args[0], Math.floor(args[0].toNumber())),
|
|
@@ -2261,31 +2284,31 @@ var builtinFunctions = {
|
|
|
2261
2284
|
// rather than as a running number.
|
|
2262
2285
|
9: (args) => extremum(args, false),
|
|
2263
2286
|
10: (args) => extremum(args, true),
|
|
2264
|
-
11: (args) =>
|
|
2265
|
-
12: (args) =>
|
|
2266
|
-
13: (args) =>
|
|
2267
|
-
14: (args) =>
|
|
2268
|
-
15: (args) =>
|
|
2269
|
-
16: (args) =>
|
|
2270
|
-
17: (args) =>
|
|
2271
|
-
18: (args) =>
|
|
2272
|
-
19: (args) =>
|
|
2273
|
-
20: (args) =>
|
|
2274
|
-
21: (args) =>
|
|
2275
|
-
22: (args) =>
|
|
2276
|
-
23: (args) =>
|
|
2277
|
-
24: (args) =>
|
|
2278
|
-
25: (args) =>
|
|
2287
|
+
11: (args) => chunkIT74O4BE_cjs.numberValue(Math.asin(args[0].toNumber())),
|
|
2288
|
+
12: (args) => chunkIT74O4BE_cjs.numberValue(Math.acos(args[0].toNumber())),
|
|
2289
|
+
13: (args) => chunkIT74O4BE_cjs.numberValue(Math.atan(args[0].toNumber())),
|
|
2290
|
+
14: (args) => chunkIT74O4BE_cjs.numberValue(Math.atan2(args[0].toNumber(), args[1].toNumber())),
|
|
2291
|
+
15: (args) => chunkIT74O4BE_cjs.numberValue(Math.sinh(args[0].toNumber())),
|
|
2292
|
+
16: (args) => chunkIT74O4BE_cjs.numberValue(Math.cosh(args[0].toNumber())),
|
|
2293
|
+
17: (args) => chunkIT74O4BE_cjs.numberValue(Math.tanh(args[0].toNumber())),
|
|
2294
|
+
18: (args) => chunkIT74O4BE_cjs.numberValue(Math.asinh(args[0].toNumber())),
|
|
2295
|
+
19: (args) => chunkIT74O4BE_cjs.numberValue(Math.acosh(args[0].toNumber())),
|
|
2296
|
+
20: (args) => chunkIT74O4BE_cjs.numberValue(Math.atanh(args[0].toNumber())),
|
|
2297
|
+
21: (args) => chunkIT74O4BE_cjs.numberValue(Math.cbrt(args[0].toNumber())),
|
|
2298
|
+
22: (args) => chunkIT74O4BE_cjs.numberValue(Math.clz32(args[0].toNumber())),
|
|
2299
|
+
23: (args) => chunkIT74O4BE_cjs.numberValue(Math.expm1(args[0].toNumber())),
|
|
2300
|
+
24: (args) => chunkIT74O4BE_cjs.numberValue(Math.exp(args[0].toNumber())),
|
|
2301
|
+
25: (args) => chunkIT74O4BE_cjs.numberValue(Math.fround(args[0].toNumber())),
|
|
2279
2302
|
// hypot: left as .map()+spread (unlike min/max above), Math.hypot uses
|
|
2280
2303
|
// a numerically-stable scaling algorithm internally to avoid overflow
|
|
2281
2304
|
// for very large/small inputs; a naive manual reimplementation risks
|
|
2282
2305
|
// silently changing results at the extremes, so the tiny array
|
|
2283
2306
|
// allocation here is the safer trade.
|
|
2284
|
-
26: (args) =>
|
|
2285
|
-
27: (args) =>
|
|
2286
|
-
28: (args) =>
|
|
2287
|
-
29: (args) =>
|
|
2288
|
-
30: (args) =>
|
|
2307
|
+
26: (args) => chunkIT74O4BE_cjs.numberValue(Math.hypot(...args.map((a) => a.toNumber()))),
|
|
2308
|
+
27: (args) => chunkIT74O4BE_cjs.numberValue(Math.imul(args[0].toNumber(), args[1].toNumber())),
|
|
2309
|
+
28: (args) => chunkIT74O4BE_cjs.numberValue(Math.log10(args[0].toNumber())),
|
|
2310
|
+
29: (args) => chunkIT74O4BE_cjs.numberValue(Math.log1p(args[0].toNumber())),
|
|
2311
|
+
30: (args) => chunkIT74O4BE_cjs.numberValue(Math.log2(args[0].toNumber())),
|
|
2289
2312
|
// pow(): the spelled-out form of `^`, so a Matrix base means the same
|
|
2290
2313
|
// repeated matrix multiplication `^` means. Without this branch
|
|
2291
2314
|
// `pow([1,2;3,4], 2)` was Math.pow of a value whose toNumber() is 0, and
|
|
@@ -2293,21 +2316,21 @@ var builtinFunctions = {
|
|
|
2293
2316
|
31: (args) => {
|
|
2294
2317
|
if (args[0].type === 7 /* Matrix */) {
|
|
2295
2318
|
if (args[1].type !== 0 /* Number */) {
|
|
2296
|
-
return
|
|
2319
|
+
return chunkIT74O4BE_cjs.errorValue("MATRIX_POWER_UNSUPPORTED", `pow: a matrix's exponent must be a whole number, as in "pow([1,2;3,4], 2)".`);
|
|
2297
2320
|
}
|
|
2298
|
-
return
|
|
2321
|
+
return chunkA2DZ5BEJ_cjs.matrixPower(args[0].value, args[1].value);
|
|
2299
2322
|
}
|
|
2300
2323
|
if (args[1].type === 7 /* Matrix */) {
|
|
2301
|
-
return
|
|
2324
|
+
return chunkIT74O4BE_cjs.errorValue("MATRIX_POWER_UNSUPPORTED", `pow: a matrix may only be the base, as in "pow([1,2;3,4], 2)".`);
|
|
2302
2325
|
}
|
|
2303
|
-
return
|
|
2326
|
+
return chunkIT74O4BE_cjs.numberValue(power(args[0].toNumber(), args[1].toNumber()));
|
|
2304
2327
|
},
|
|
2305
|
-
32: () =>
|
|
2328
|
+
32: () => chunkIT74O4BE_cjs.numberValue(Math.random()),
|
|
2306
2329
|
// takes no arguments, unlike its neighbours
|
|
2307
|
-
33: (args) =>
|
|
2308
|
-
34: (args) =>
|
|
2309
|
-
35: (args) =>
|
|
2310
|
-
36: (args) =>
|
|
2330
|
+
33: (args) => chunkIT74O4BE_cjs.numberValue(Math.sign(args[0].toNumber())),
|
|
2331
|
+
34: (args) => chunkIT74O4BE_cjs.numberValue(Math.trunc(args[0].toNumber())),
|
|
2332
|
+
35: (args) => chunkIT74O4BE_cjs.numberValue(args[0].toNumber() * Math.PI / 180),
|
|
2333
|
+
36: (args) => chunkIT74O4BE_cjs.numberValue(args[0].toNumber() * 180 / Math.PI),
|
|
2311
2334
|
// 37: diceRoll(from, to), random integer in range [from, to] inclusive.
|
|
2312
2335
|
// A reversed range (from > to) used to silently produce values outside
|
|
2313
2336
|
// [to, from] via a negative-length Math.random() spread (e.g.
|
|
@@ -2317,9 +2340,9 @@ var builtinFunctions = {
|
|
|
2317
2340
|
const from = args[0].toNumber();
|
|
2318
2341
|
const to = args[1].toNumber();
|
|
2319
2342
|
if (from > to) {
|
|
2320
|
-
return
|
|
2343
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `roll: invalid range, ${from} is greater than ${to}`);
|
|
2321
2344
|
}
|
|
2322
|
-
return
|
|
2345
|
+
return chunkIT74O4BE_cjs.numberValue(Math.floor(Math.random() * (to - from + 1)) + from);
|
|
2323
2346
|
},
|
|
2324
2347
|
// gcd(a, b), Euclidean algorithm. Negative inputs are treated by
|
|
2325
2348
|
// magnitude (gcd is conventionally defined over non-negative integers).
|
|
@@ -2328,7 +2351,7 @@ var builtinFunctions = {
|
|
|
2328
2351
|
const b = Math.trunc(Math.abs(args[1].toNumber()));
|
|
2329
2352
|
const nonFinite = nonFiniteEuclidOperand(a, b, "gcd");
|
|
2330
2353
|
if (nonFinite) return nonFinite;
|
|
2331
|
-
return
|
|
2354
|
+
return chunkIT74O4BE_cjs.numberValue(euclidGcd(a, b));
|
|
2332
2355
|
},
|
|
2333
2356
|
// lcm(a, b) = |a*b| / gcd(a, b), via the same Euclidean gcd inline
|
|
2334
2357
|
// (a standalone gcd() call site, no shared helper needed for two uses).
|
|
@@ -2337,8 +2360,8 @@ var builtinFunctions = {
|
|
|
2337
2360
|
const b = Math.trunc(Math.abs(args[1].toNumber()));
|
|
2338
2361
|
const nonFinite = nonFiniteEuclidOperand(a, b, "lcm");
|
|
2339
2362
|
if (nonFinite) return nonFinite;
|
|
2340
|
-
if (a === 0 || b === 0) return
|
|
2341
|
-
return
|
|
2363
|
+
if (a === 0 || b === 0) return chunkIT74O4BE_cjs.numberValue(0);
|
|
2364
|
+
return chunkIT74O4BE_cjs.numberValue(a / euclidGcd(a, b) * b);
|
|
2342
2365
|
},
|
|
2343
2366
|
// permutation(n, r) = n! / (n-r)!, computed as a running product
|
|
2344
2367
|
// rather than two full factorials, so it stays exact for n well
|
|
@@ -2359,19 +2382,19 @@ var builtinFunctions = {
|
|
|
2359
2382
|
const n = Math.trunc(args[0].toNumber());
|
|
2360
2383
|
const r = Math.trunc(args[1].toNumber());
|
|
2361
2384
|
if (n < 0 || r < 0 || r > n) {
|
|
2362
|
-
return
|
|
2385
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `permutation: invalid n=${n}, r=${r} (require 0 <= r <= n)`);
|
|
2363
2386
|
}
|
|
2364
2387
|
let result = 1;
|
|
2365
2388
|
for (let i = 0; i < r; i++) {
|
|
2366
2389
|
result *= n - i;
|
|
2367
2390
|
if (!Number.isFinite(result)) {
|
|
2368
|
-
return
|
|
2391
|
+
return chunkIT74O4BE_cjs.errorValue(
|
|
2369
2392
|
"PERMUTATION_OVERFLOW",
|
|
2370
2393
|
`permutation: P(${n}, ${r}) exceeds the maximum representable double (it passed it after ${i + 1} of ${r} factors)`
|
|
2371
2394
|
);
|
|
2372
2395
|
}
|
|
2373
2396
|
}
|
|
2374
|
-
return
|
|
2397
|
+
return chunkIT74O4BE_cjs.numberValue(result);
|
|
2375
2398
|
},
|
|
2376
2399
|
// combination(n, r) = n! / (r! * (n-r)!), multiply-then-divide one
|
|
2377
2400
|
// step at a time (standard technique) keeps every intermediate result
|
|
@@ -2387,42 +2410,42 @@ var builtinFunctions = {
|
|
|
2387
2410
|
const n = Math.trunc(args[0].toNumber());
|
|
2388
2411
|
const r = Math.trunc(args[1].toNumber());
|
|
2389
2412
|
if (n < 0 || r < 0 || r > n) {
|
|
2390
|
-
return
|
|
2413
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `combination: invalid n=${n}, r=${r} (require 0 <= r <= n)`);
|
|
2391
2414
|
}
|
|
2392
2415
|
const k = Math.min(r, n - r);
|
|
2393
2416
|
let result = 1;
|
|
2394
2417
|
for (let i = 0; i < k; i++) {
|
|
2395
2418
|
result = result * (n - i) / (i + 1);
|
|
2396
2419
|
if (!Number.isFinite(result)) {
|
|
2397
|
-
return
|
|
2420
|
+
return chunkIT74O4BE_cjs.errorValue(
|
|
2398
2421
|
"COMBINATION_OVERFLOW",
|
|
2399
2422
|
`combination: C(${n}, ${r}) exceeds the maximum representable double (it passed it after ${i + 1} of ${k} steps)`
|
|
2400
2423
|
);
|
|
2401
2424
|
}
|
|
2402
2425
|
}
|
|
2403
|
-
return
|
|
2426
|
+
return chunkIT74O4BE_cjs.numberValue(Math.round(result));
|
|
2404
2427
|
},
|
|
2405
2428
|
// average(...), arithmetic mean of any number of arguments. Backs the
|
|
2406
2429
|
// MathPhrases package's "average of X, Y, Z" (packages/mathphrases/).
|
|
2407
2430
|
42: (args) => {
|
|
2408
|
-
if (args.length === 0) return
|
|
2431
|
+
if (args.length === 0) return chunkIT74O4BE_cjs.numberValue(0);
|
|
2409
2432
|
const sum = args.reduce((acc, a) => acc + a.toNumber(), 0);
|
|
2410
|
-
return
|
|
2433
|
+
return chunkIT74O4BE_cjs.numberValue(sum / args.length);
|
|
2411
2434
|
},
|
|
2412
2435
|
// median(...), middle value; average of the two middle values for an
|
|
2413
2436
|
// even argument count.
|
|
2414
2437
|
43: (args) => {
|
|
2415
|
-
if (args.length === 0) return
|
|
2438
|
+
if (args.length === 0) return chunkIT74O4BE_cjs.numberValue(0);
|
|
2416
2439
|
const sorted = args.map((a) => a.toNumber()).sort((a, b) => a - b);
|
|
2417
2440
|
const mid = Math.floor(sorted.length / 2);
|
|
2418
|
-
return
|
|
2441
|
+
return chunkIT74O4BE_cjs.numberValue(
|
|
2419
2442
|
sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]
|
|
2420
2443
|
);
|
|
2421
2444
|
},
|
|
2422
2445
|
// total(...), sum of any number of arguments.
|
|
2423
|
-
44: (args) =>
|
|
2446
|
+
44: (args) => chunkIT74O4BE_cjs.numberValue(args.reduce((acc, a) => acc + a.toNumber(), 0)),
|
|
2424
2447
|
// count(...), number of arguments passed.
|
|
2425
|
-
45: (args) =>
|
|
2448
|
+
45: (args) => chunkIT74O4BE_cjs.numberValue(args.length),
|
|
2426
2449
|
// proportion(a, b, c) -> d such that a:b = c:d, i.e. d = c * (b/a)
|
|
2427
2450
|
// "A is to B as C is to what". Unit-aware via unifyUom: "5 km is to
|
|
2428
2451
|
// 500m as 5 cm is to what" unifies 5km/500m to a 10:1 ratio (500m ==
|
|
@@ -2433,10 +2456,10 @@ var builtinFunctions = {
|
|
|
2433
2456
|
const [a, b, c] = args;
|
|
2434
2457
|
const { lv: aNum, rv: bNum } = unifyUom(a, b);
|
|
2435
2458
|
if (aNum === 0) {
|
|
2436
|
-
return
|
|
2459
|
+
return chunkIT74O4BE_cjs.errorValue("PROPORTION_DIVIDE_BY_ZERO", `Cannot compute proportion: "${a.value}" is zero`);
|
|
2437
2460
|
}
|
|
2438
2461
|
const result = c.toNumber() * (bNum / aNum);
|
|
2439
|
-
return c.type === 6 /* Uom */ ?
|
|
2462
|
+
return c.type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(result, c.unit) : chunkIT74O4BE_cjs.numberValue(result);
|
|
2440
2463
|
},
|
|
2441
2464
|
// clamp(value, lo, hi), restrict value to [lo, hi]. Backs
|
|
2442
2465
|
// "clamp X between Y and Z" / "clamp X from Y to Z".
|
|
@@ -2445,9 +2468,9 @@ var builtinFunctions = {
|
|
|
2445
2468
|
const lo = args[1].toNumber();
|
|
2446
2469
|
const hi = args[2].toNumber();
|
|
2447
2470
|
if (lo > hi) {
|
|
2448
|
-
return
|
|
2471
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `clamp: invalid range, ${lo} is greater than ${hi}`);
|
|
2449
2472
|
}
|
|
2450
|
-
return
|
|
2473
|
+
return chunkIT74O4BE_cjs.numberValue(Math.min(Math.max(value, lo), hi));
|
|
2451
2474
|
},
|
|
2452
2475
|
// hex(n), Python/JS-style call-syntax hex formatting, e.g. hex(255) ->
|
|
2453
2476
|
// "0xFF". Distinct from the Converters package's `255 as hex` (see
|
|
@@ -2457,16 +2480,16 @@ var builtinFunctions = {
|
|
|
2457
2480
|
// function call that returns an ordinary String value, matching
|
|
2458
2481
|
// Python's hex()/JS convention of a function returning display text,
|
|
2459
2482
|
// not a numeric type.
|
|
2460
|
-
48: (args) =>
|
|
2483
|
+
48: (args) => chunkIT74O4BE_cjs.hexValue(args[0].toNumber()),
|
|
2461
2484
|
// bin(n). Same call-syntax shape as hex() above, e.g. bin(10) -> "0b1010".
|
|
2462
|
-
49: (args) =>
|
|
2485
|
+
49: (args) => chunkIT74O4BE_cjs.hexValue(args[0].toNumber(), "bin"),
|
|
2463
2486
|
// int(x), coerce ANY value (Number, Percentage, Uom, String, Hex, ...)
|
|
2464
2487
|
// to a plain integer Number, truncating any fractional part toward
|
|
2465
2488
|
// zero (Math.trunc semantics: int(5.7) -> 5, int(-5.7) -> -5). Distinct
|
|
2466
2489
|
// from the Converters package's `x as number` (TO_NUMBER opcode),
|
|
2467
2490
|
// which only strips a unit/percentage wrapper and keeps any decimal
|
|
2468
2491
|
// part (e.g. "5.7 as number" -> 5.7), int() additionally truncates.
|
|
2469
|
-
50: (args) =>
|
|
2492
|
+
50: (args) => chunkIT74O4BE_cjs.numberValue(Math.trunc(args[0].toNumber())),
|
|
2470
2493
|
// ── Finance (packages/finance/) ──────────────────────────────────────
|
|
2471
2494
|
// All finance builtins preserve the principal/amount argument's Uom
|
|
2472
2495
|
// unit (e.g. a currency like "$") onto the result, matching
|
|
@@ -2487,10 +2510,10 @@ var builtinFunctions = {
|
|
|
2487
2510
|
const rate = args[1].toNumber();
|
|
2488
2511
|
const years = args[2].toNumber();
|
|
2489
2512
|
if (1 + rate <= 0) {
|
|
2490
|
-
return
|
|
2513
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `compoundInterest: rate ${rate} makes (1 + rate) non-positive`);
|
|
2491
2514
|
}
|
|
2492
2515
|
const fv = principal * Math.pow(1 + rate, years);
|
|
2493
|
-
return args[0].type === 6 /* Uom */ ?
|
|
2516
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(fv, args[0].unit) : chunkIT74O4BE_cjs.numberValue(fv);
|
|
2494
2517
|
},
|
|
2495
2518
|
// compoundInterestEarned(principal, rate, years) -> FV - principal, the
|
|
2496
2519
|
// interest-only portion. Backs "interest on $P over Y years at R%" and
|
|
@@ -2500,10 +2523,10 @@ var builtinFunctions = {
|
|
|
2500
2523
|
const rate = args[1].toNumber();
|
|
2501
2524
|
const years = args[2].toNumber();
|
|
2502
2525
|
if (1 + rate <= 0) {
|
|
2503
|
-
return
|
|
2526
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `interestEarned: rate ${rate} makes (1 + rate) non-positive`);
|
|
2504
2527
|
}
|
|
2505
2528
|
const interest = principal * (Math.pow(1 + rate, years) - 1);
|
|
2506
|
-
return args[0].type === 6 /* Uom */ ?
|
|
2529
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(interest, args[0].unit) : chunkIT74O4BE_cjs.numberValue(interest);
|
|
2507
2530
|
},
|
|
2508
2531
|
// compoundInterestRate(principal, futureValue, years) -> the rate (as a
|
|
2509
2532
|
// decimal fraction) needed to grow principal to futureValue over years.
|
|
@@ -2515,12 +2538,12 @@ var builtinFunctions = {
|
|
|
2515
2538
|
const futureValue = args[1].toNumber();
|
|
2516
2539
|
const years = args[2].toNumber();
|
|
2517
2540
|
if (principal <= 0 || futureValue <= 0) {
|
|
2518
|
-
return
|
|
2541
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `compoundInterestRate: principal and futureValue must both be positive`);
|
|
2519
2542
|
}
|
|
2520
2543
|
if (years <= 0) {
|
|
2521
|
-
return
|
|
2544
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `compoundInterestRate: years must be greater than 0`);
|
|
2522
2545
|
}
|
|
2523
|
-
return
|
|
2546
|
+
return chunkIT74O4BE_cjs.numberValue(Math.pow(futureValue / principal, 1 / years) - 1);
|
|
2524
2547
|
},
|
|
2525
2548
|
// compoundInterestYears(principal, futureValue, rate) -> the number of
|
|
2526
2549
|
// years needed to grow principal to futureValue at a fixed rate.
|
|
@@ -2530,12 +2553,12 @@ var builtinFunctions = {
|
|
|
2530
2553
|
const futureValue = args[1].toNumber();
|
|
2531
2554
|
const rate = args[2].toNumber();
|
|
2532
2555
|
if (principal <= 0 || futureValue <= 0) {
|
|
2533
|
-
return
|
|
2556
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `compoundInterestYears: principal and futureValue must both be positive`);
|
|
2534
2557
|
}
|
|
2535
2558
|
if (1 + rate <= 0 || rate === 0) {
|
|
2536
|
-
return
|
|
2559
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `compoundInterestYears: rate ${rate} is not usable (must be > -1 and not 0)`);
|
|
2537
2560
|
}
|
|
2538
|
-
return
|
|
2561
|
+
return chunkIT74O4BE_cjs.numberValue(Math.log(futureValue / principal) / Math.log(1 + rate));
|
|
2539
2562
|
},
|
|
2540
2563
|
// loanRepayment(principal, rate, years, periodsPerYear), standard
|
|
2541
2564
|
// amortizing-loan repayment (mortgage formula), redistributed evenly
|
|
@@ -2553,13 +2576,13 @@ var builtinFunctions = {
|
|
|
2553
2576
|
const rate = args[1].toNumber();
|
|
2554
2577
|
const years = args[2].toNumber();
|
|
2555
2578
|
const periodsPerYear = args[3].toNumber();
|
|
2556
|
-
if (principal <= 0) return
|
|
2557
|
-
if (years <= 0) return
|
|
2558
|
-
if (rate < 0) return
|
|
2559
|
-
if (periodsPerYear < 0) return
|
|
2579
|
+
if (principal <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `loanRepayment: principal must be positive`);
|
|
2580
|
+
if (years <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `loanRepayment: years must be positive`);
|
|
2581
|
+
if (rate < 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `loanRepayment: rate must not be negative`);
|
|
2582
|
+
if (periodsPerYear < 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `loanRepayment: periodsPerYear must not be negative`);
|
|
2560
2583
|
const { totalRepayment } = amortizeLoan(principal, rate, years);
|
|
2561
2584
|
const result = periodsPerYear === 0 ? totalRepayment : totalRepayment / (years * periodsPerYear);
|
|
2562
|
-
return args[0].type === 6 /* Uom */ ?
|
|
2585
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(result, args[0].unit) : chunkIT74O4BE_cjs.numberValue(result);
|
|
2563
2586
|
},
|
|
2564
2587
|
// loanInterest(principal, rate, years, periodsPerYear), the interest
|
|
2565
2588
|
// portion of index 55's repayment, same periodsPerYear convention.
|
|
@@ -2569,13 +2592,13 @@ var builtinFunctions = {
|
|
|
2569
2592
|
const rate = args[1].toNumber();
|
|
2570
2593
|
const years = args[2].toNumber();
|
|
2571
2594
|
const periodsPerYear = args[3].toNumber();
|
|
2572
|
-
if (principal <= 0) return
|
|
2573
|
-
if (years <= 0) return
|
|
2574
|
-
if (rate < 0) return
|
|
2575
|
-
if (periodsPerYear < 0) return
|
|
2595
|
+
if (principal <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `loanInterest: principal must be positive`);
|
|
2596
|
+
if (years <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `loanInterest: years must be positive`);
|
|
2597
|
+
if (rate < 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `loanInterest: rate must not be negative`);
|
|
2598
|
+
if (periodsPerYear < 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `loanInterest: periodsPerYear must not be negative`);
|
|
2576
2599
|
const { totalInterest } = amortizeLoan(principal, rate, years);
|
|
2577
2600
|
const result = periodsPerYear === 0 ? totalInterest : totalInterest / (years * periodsPerYear);
|
|
2578
|
-
return args[0].type === 6 /* Uom */ ?
|
|
2601
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(result, args[0].unit) : chunkIT74O4BE_cjs.numberValue(result);
|
|
2579
2602
|
},
|
|
2580
2603
|
// monthlyPayment(principal, rate, years), convenience 3-arg wrapper
|
|
2581
2604
|
// around index 55's monthly case, for direct function-call use without
|
|
@@ -2584,11 +2607,11 @@ var builtinFunctions = {
|
|
|
2584
2607
|
const principal = args[0].toNumber();
|
|
2585
2608
|
const rate = args[1].toNumber();
|
|
2586
2609
|
const years = args[2].toNumber();
|
|
2587
|
-
if (principal <= 0) return
|
|
2588
|
-
if (years <= 0) return
|
|
2589
|
-
if (rate < 0) return
|
|
2610
|
+
if (principal <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `monthlyPayment: principal must be positive`);
|
|
2611
|
+
if (years <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `monthlyPayment: years must be positive`);
|
|
2612
|
+
if (rate < 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `monthlyPayment: rate must not be negative`);
|
|
2590
2613
|
const { monthlyPayment } = amortizeLoan(principal, rate, years);
|
|
2591
|
-
return args[0].type === 6 /* Uom */ ?
|
|
2614
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(monthlyPayment, args[0].unit) : chunkIT74O4BE_cjs.numberValue(monthlyPayment);
|
|
2592
2615
|
},
|
|
2593
2616
|
// taxAdd(amount, rate) -> amount * (1 + rate), the tax-inclusive total.
|
|
2594
2617
|
// Backs the taxAdd() function-call form, whose name promises exactly this.
|
|
@@ -2601,7 +2624,7 @@ var builtinFunctions = {
|
|
|
2601
2624
|
const amount = args[0].toNumber();
|
|
2602
2625
|
const rate = args[1].toNumber();
|
|
2603
2626
|
if (args[0].type === 6 /* Uom */) return scaleMoneyByPercent(args[0], args[0].unit, rate, 1);
|
|
2604
|
-
return
|
|
2627
|
+
return chunkIT74O4BE_cjs.numberValue(amount * (1 + rate));
|
|
2605
2628
|
},
|
|
2606
2629
|
// taxRemove(amount, rate) -> amount / (1 + rate), extracts the
|
|
2607
2630
|
// pre-tax amount from a tax-INCLUSIVE total. Backs "tax off $X at R%" /
|
|
@@ -2610,12 +2633,12 @@ var builtinFunctions = {
|
|
|
2610
2633
|
const amount = args[0].toNumber();
|
|
2611
2634
|
const rate = args[1].toNumber();
|
|
2612
2635
|
if (1 + rate <= 0) {
|
|
2613
|
-
return
|
|
2636
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `taxRemove: rate ${rate} makes (1 + rate) non-positive`);
|
|
2614
2637
|
}
|
|
2615
2638
|
if (args[0].type === 6 /* Uom */) {
|
|
2616
|
-
return removeTaxExact(args[0], args[0].unit, rate) ??
|
|
2639
|
+
return removeTaxExact(args[0], args[0].unit, rate) ?? chunkIT74O4BE_cjs.uomValue(amount / (1 + rate), args[0].unit);
|
|
2617
2640
|
}
|
|
2618
|
-
return
|
|
2641
|
+
return chunkIT74O4BE_cjs.numberValue(amount / (1 + rate));
|
|
2619
2642
|
},
|
|
2620
2643
|
// inflationAdjust(amount, fromYear, toYear) -- CPI-based inflation
|
|
2621
2644
|
// adjustment between two arbitrary years, using the bundled CPI-U
|
|
@@ -2635,13 +2658,13 @@ var builtinFunctions = {
|
|
|
2635
2658
|
const toYear = args[2].toNumber();
|
|
2636
2659
|
const ratio = inflationRatio(fromYear, toYear);
|
|
2637
2660
|
if (ratio === void 0) {
|
|
2638
|
-
return
|
|
2661
|
+
return chunkIT74O4BE_cjs.errorValue(
|
|
2639
2662
|
"INFLATION_YEAR_OUT_OF_RANGE",
|
|
2640
2663
|
`inflationAdjust: fromYear ${fromYear} or toYear ${toYear} is outside the bundled CPI table's range (${CPI_MIN_YEAR}-${CPI_MAX_YEAR})`
|
|
2641
2664
|
);
|
|
2642
2665
|
}
|
|
2643
2666
|
const result = amount * ratio;
|
|
2644
|
-
return args[0].type === 6 /* Uom */ ?
|
|
2667
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(result, args[0].unit) : chunkIT74O4BE_cjs.numberValue(result);
|
|
2645
2668
|
},
|
|
2646
2669
|
// root(n, x) -- the n-th root of x (Numi's `root n (x)` phrasing maps
|
|
2647
2670
|
// to this same call-style form; see FunctionCallParselet's name map).
|
|
@@ -2652,7 +2675,7 @@ var builtinFunctions = {
|
|
|
2652
2675
|
61: (args) => {
|
|
2653
2676
|
const n = args[0].toNumber();
|
|
2654
2677
|
const x = args[1].toNumber();
|
|
2655
|
-
return
|
|
2678
|
+
return chunkIT74O4BE_cjs.numberValue(power(x, 1 / n));
|
|
2656
2679
|
},
|
|
2657
2680
|
// fact(n) / factorial(n) -- integer factorial. Deliberately rejects
|
|
2658
2681
|
// negative or non-integer input (factorial isn't defined for either
|
|
@@ -2663,14 +2686,14 @@ var builtinFunctions = {
|
|
|
2663
2686
|
62: (args) => {
|
|
2664
2687
|
const n = args[0].toNumber();
|
|
2665
2688
|
if (!Number.isInteger(n) || n < 0) {
|
|
2666
|
-
return
|
|
2689
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_FACTORIAL_INPUT", `fact: ${n} is not a non-negative integer`);
|
|
2667
2690
|
}
|
|
2668
2691
|
if (n > 170) {
|
|
2669
|
-
return
|
|
2692
|
+
return chunkIT74O4BE_cjs.errorValue("FACTORIAL_OVERFLOW", `fact: ${n}! exceeds the maximum representable double (170! is the largest finite factorial)`);
|
|
2670
2693
|
}
|
|
2671
2694
|
let result = 1;
|
|
2672
2695
|
for (let i = 2; i <= n; i++) result *= i;
|
|
2673
|
-
return
|
|
2696
|
+
return chunkIT74O4BE_cjs.numberValue(result);
|
|
2674
2697
|
},
|
|
2675
2698
|
// ── Matrix (packages/matrix/) ────────────────────────────────────────
|
|
2676
2699
|
// transpose(a)/det(a)/inv(a)/dot(a,b), reachable both via ordinary
|
|
@@ -2683,17 +2706,17 @@ var builtinFunctions = {
|
|
|
2683
2706
|
// own transpose (a 1x1 "matrix" transposed is itself), matches this
|
|
2684
2707
|
// engine's existing convention of treating a scalar as a trivial 1x1
|
|
2685
2708
|
// matrix (see Value.ts's toNumber()/isNaN() 1x1 special case).
|
|
2686
|
-
63: (args) => args[0].type === 7 /* Matrix */ ?
|
|
2709
|
+
63: (args) => args[0].type === 7 /* Matrix */ ? chunkA2DZ5BEJ_cjs.transpose(args[0].value) : args[0],
|
|
2687
2710
|
// det(a), determinant. A plain Number's "determinant" is itself (the
|
|
2688
2711
|
// determinant of a 1x1 matrix [x] is x).
|
|
2689
|
-
64: (args) => args[0].type === 7 /* Matrix */ ?
|
|
2712
|
+
64: (args) => args[0].type === 7 /* Matrix */ ? chunkA2DZ5BEJ_cjs.determinant(args[0].value) : chunkIT74O4BE_cjs.numberValue(args[0].toNumber()),
|
|
2690
2713
|
// inv(a), matrix inverse for a Matrix; for a plain Number, `1/x`
|
|
2691
2714
|
// (byte-identical to `Math.pow(x, -1)`, which is what `x^-1` computed
|
|
2692
2715
|
// before this feature existed. See PrecedenceParser.ts's `^-1`
|
|
2693
2716
|
// special-case doc comment for why this must stay exact).
|
|
2694
2717
|
65: (args) => {
|
|
2695
|
-
if (args[0].type === 7 /* Matrix */) return
|
|
2696
|
-
return
|
|
2718
|
+
if (args[0].type === 7 /* Matrix */) return chunkA2DZ5BEJ_cjs.inverse(args[0].value);
|
|
2719
|
+
return chunkIT74O4BE_cjs.numberValue(1 / args[0].toNumber());
|
|
2697
2720
|
},
|
|
2698
2721
|
// dot(a, b), matrix product / scalar-broadcast, the SAME dispatch as
|
|
2699
2722
|
// the `*` operator between two matrices (vm/VM.ts's MUL case). Plain
|
|
@@ -2703,10 +2726,10 @@ var builtinFunctions = {
|
|
|
2703
2726
|
66: (args) => {
|
|
2704
2727
|
const [a, b] = args;
|
|
2705
2728
|
if (a.type === 0 /* Number */ && b.type === 0 /* Number */) {
|
|
2706
|
-
return
|
|
2729
|
+
return chunkIT74O4BE_cjs.numberValue(a.toNumber() * b.toNumber());
|
|
2707
2730
|
}
|
|
2708
2731
|
const toMatrix = (v) => v.type === 7 /* Matrix */ ? v.value : { rows: 1, cols: 1, data: [v.toNumber()], hasSymbolic: false };
|
|
2709
|
-
return
|
|
2732
|
+
return chunkA2DZ5BEJ_cjs.matrixMultiply(toMatrix(a), toMatrix(b));
|
|
2710
2733
|
},
|
|
2711
2734
|
// ── Symbolic algebra (packages/symbolic/) ──
|
|
2712
2735
|
// expand(expr), multiplying out every product and power. Reached only
|
|
@@ -2720,7 +2743,7 @@ var builtinFunctions = {
|
|
|
2720
2743
|
67: (args) => {
|
|
2721
2744
|
const [value] = args;
|
|
2722
2745
|
if (value.type !== 9 /* Symbolic */) return value;
|
|
2723
|
-
return symbolicToValue(
|
|
2746
|
+
return symbolicToValue(chunkA2DZ5BEJ_cjs.expandSymbolic(value.value));
|
|
2724
2747
|
},
|
|
2725
2748
|
// factor(expr), writing a polynomial as a product of irreducible factors
|
|
2726
2749
|
// over the RATIONALS. x^2-2 and x^2+1 come back unchanged, which is the
|
|
@@ -2737,7 +2760,7 @@ var builtinFunctions = {
|
|
|
2737
2760
|
69: (args) => {
|
|
2738
2761
|
const [lhsValue, rhsValue, variableValue] = args;
|
|
2739
2762
|
if (variableValue?.type !== 3 /* String */) {
|
|
2740
|
-
return
|
|
2763
|
+
return chunkIT74O4BE_cjs.errorValue("SOLVE_REQUIRES_VARIABLE_NAME", "solve's second argument must be the name of the unknown.");
|
|
2741
2764
|
}
|
|
2742
2765
|
return solveEquationValues(lhsValue, rhsValue, variableValue.value);
|
|
2743
2766
|
},
|
|
@@ -2748,7 +2771,7 @@ var builtinFunctions = {
|
|
|
2748
2771
|
const variable = symbolicVariableName(variableValue, "der");
|
|
2749
2772
|
if (typeof variable !== "string") return variable;
|
|
2750
2773
|
const expression = valueToSymbolic(target);
|
|
2751
|
-
if (expression === null) return
|
|
2774
|
+
if (expression === null) return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "der needs an expression with an exact value.");
|
|
2752
2775
|
return symbolicToValue(differentiate2(expression, variable, orderValue?.toNumber() ?? 1));
|
|
2753
2776
|
},
|
|
2754
2777
|
// integral(expr, variable), the indefinite integral without a constant of
|
|
@@ -2759,9 +2782,9 @@ var builtinFunctions = {
|
|
|
2759
2782
|
const variable = symbolicVariableName(variableValue, "integral");
|
|
2760
2783
|
if (typeof variable !== "string") return variable;
|
|
2761
2784
|
const expression = valueToSymbolic(target);
|
|
2762
|
-
if (expression === null) return
|
|
2785
|
+
if (expression === null) return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "integral needs an expression with an exact value.");
|
|
2763
2786
|
const result = integrate(expression, variable);
|
|
2764
|
-
if (!result.ok) return
|
|
2787
|
+
if (!result.ok) return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_INTEGRAL_UNSUPPORTED", `Cannot integrate this: ${result.reason}.`);
|
|
2765
2788
|
return symbolicToValue(result.value);
|
|
2766
2789
|
},
|
|
2767
2790
|
// taylor(expr, variable = point, degree).
|
|
@@ -2772,7 +2795,7 @@ var builtinFunctions = {
|
|
|
2772
2795
|
const expression = valueToSymbolic(target);
|
|
2773
2796
|
const point = valueToSymbolic(pointValue);
|
|
2774
2797
|
if (expression === null || point === null || point.kind !== "const") {
|
|
2775
|
-
return
|
|
2798
|
+
return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "taylor needs an expression and an exact expansion point.");
|
|
2776
2799
|
}
|
|
2777
2800
|
return symbolicToValue(taylorSeries(expression, variable, point.value, degreeValue.toNumber()));
|
|
2778
2801
|
},
|
|
@@ -2782,23 +2805,23 @@ var builtinFunctions = {
|
|
|
2782
2805
|
const functions = [];
|
|
2783
2806
|
for (const arg of args) {
|
|
2784
2807
|
const node = valueToSymbolic(arg);
|
|
2785
|
-
if (node === null) return
|
|
2808
|
+
if (node === null) return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", "jacobian needs expressions with exact values.");
|
|
2786
2809
|
functions.push(node);
|
|
2787
2810
|
}
|
|
2788
2811
|
const variables = /* @__PURE__ */ new Set();
|
|
2789
|
-
for (const fn of functions) for (const name of
|
|
2812
|
+
for (const fn of functions) for (const name of chunkA2DZ5BEJ_cjs.freeVariables(fn)) variables.add(name);
|
|
2790
2813
|
const sorted = [...variables].sort();
|
|
2791
|
-
if (sorted.length === 0) return
|
|
2814
|
+
if (sorted.length === 0) return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_JACOBIAN_NO_VARIABLES", "jacobian needs at least one unknown to differentiate against.");
|
|
2792
2815
|
const rows = jacobian(functions, sorted);
|
|
2793
2816
|
const rowMajor = [];
|
|
2794
2817
|
for (const row of rows) {
|
|
2795
|
-
for (const cell of row) rowMajor.push(
|
|
2818
|
+
for (const cell of row) rowMajor.push(chunkA2DZ5BEJ_cjs.symbolicToEntry(cell));
|
|
2796
2819
|
}
|
|
2797
|
-
return
|
|
2820
|
+
return chunkIT74O4BE_cjs.matrixValue(rows.length, sorted.length, chunkA2DZ5BEJ_cjs.rowMajorToColumnMajor(rows.length, sorted.length, rowMajor));
|
|
2798
2821
|
},
|
|
2799
2822
|
// An imaginary literal, 3i. The parselet pushes the numeric part and this
|
|
2800
2823
|
// turns it into an exact imaginary value.
|
|
2801
|
-
74: (args) => symbolicToValue(
|
|
2824
|
+
74: (args) => symbolicToValue(chunkA2DZ5BEJ_cjs.complexNode(chunkA2DZ5BEJ_cjs.complex(chunkA2DZ5BEJ_cjs.RATIONAL_ZERO, chunkA2DZ5BEJ_cjs.rationalFromNumber(args[0].toNumber())))),
|
|
2802
2825
|
// conj(z), re(z) and im(z). Each folds immediately for a literal and stays
|
|
2803
2826
|
// symbolic for anything still carrying an unknown.
|
|
2804
2827
|
75: (args) => applyComplexAccessor("conj", args[0]),
|
|
@@ -2808,7 +2831,7 @@ var builtinFunctions = {
|
|
|
2808
2831
|
78: (args) => {
|
|
2809
2832
|
const value = args[0];
|
|
2810
2833
|
if (value.type !== 9 /* Symbolic */) return value;
|
|
2811
|
-
return symbolicToValue(
|
|
2834
|
+
return symbolicToValue(chunkA2DZ5BEJ_cjs.cancelSymbolic(value.value));
|
|
2812
2835
|
},
|
|
2813
2836
|
// apart(expr), the partial-fraction decomposition of a rational function.
|
|
2814
2837
|
79: (args) => {
|
|
@@ -2823,13 +2846,13 @@ var builtinFunctions = {
|
|
|
2823
2846
|
const amount = args[0].toNumber();
|
|
2824
2847
|
const rate = args[1].toNumber();
|
|
2825
2848
|
if (1 + rate <= 0) {
|
|
2826
|
-
return
|
|
2849
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `taxIn: rate ${rate} makes (1 + rate) non-positive`);
|
|
2827
2850
|
}
|
|
2828
2851
|
const tax = amount - amount / (1 + rate);
|
|
2829
2852
|
if (args[0].type === 6 /* Uom */) {
|
|
2830
|
-
return taxInExact(args[0], args[0].unit, rate) ??
|
|
2853
|
+
return taxInExact(args[0], args[0].unit, rate) ?? chunkIT74O4BE_cjs.uomValue(tax, args[0].unit);
|
|
2831
2854
|
}
|
|
2832
|
-
return
|
|
2855
|
+
return chunkIT74O4BE_cjs.numberValue(tax);
|
|
2833
2856
|
},
|
|
2834
2857
|
// taxOn(amount, rate) -> amount * rate, the tax itself.
|
|
2835
2858
|
//
|
|
@@ -2842,21 +2865,21 @@ var builtinFunctions = {
|
|
|
2842
2865
|
const amount = args[0].toNumber();
|
|
2843
2866
|
const rate = args[1].toNumber();
|
|
2844
2867
|
if (args[0].type === 6 /* Uom */) return scaleMoneyExact(args[0], rate, args[0].unit);
|
|
2845
|
-
return
|
|
2868
|
+
return chunkIT74O4BE_cjs.numberValue(amount * rate);
|
|
2846
2869
|
},
|
|
2847
2870
|
// ── Degree-taking trig (sind/cosd/tand and the inverses) ──────────────
|
|
2848
2871
|
// The "d" spellings take and return degrees rather than radians, which is
|
|
2849
2872
|
// the convention every scientific calculator uses. sin(90 degrees) is the
|
|
2850
2873
|
// other way to say the same thing; both exist because both get typed.
|
|
2851
|
-
87: (args) =>
|
|
2852
|
-
88: (args) =>
|
|
2853
|
-
89: (args) =>
|
|
2854
|
-
90: (args) =>
|
|
2855
|
-
91: (args) =>
|
|
2856
|
-
92: (args) =>
|
|
2874
|
+
87: (args) => chunkIT74O4BE_cjs.numberValue(Math.sin(args[0].toNumber() * Math.PI / 180)),
|
|
2875
|
+
88: (args) => chunkIT74O4BE_cjs.numberValue(Math.cos(args[0].toNumber() * Math.PI / 180)),
|
|
2876
|
+
89: (args) => chunkIT74O4BE_cjs.numberValue(Math.tan(args[0].toNumber() * Math.PI / 180)),
|
|
2877
|
+
90: (args) => chunkIT74O4BE_cjs.numberValue(Math.asin(args[0].toNumber()) * 180 / Math.PI),
|
|
2878
|
+
91: (args) => chunkIT74O4BE_cjs.numberValue(Math.acos(args[0].toNumber()) * 180 / Math.PI),
|
|
2879
|
+
92: (args) => chunkIT74O4BE_cjs.numberValue(Math.atan(args[0].toNumber()) * 180 / Math.PI),
|
|
2857
2880
|
// daysCount(n) -> n labelled as days. "days in Q3" is a count of days
|
|
2858
2881
|
// and should say so; a bare 92 loses what was being counted.
|
|
2859
|
-
93: (args) =>
|
|
2882
|
+
93: (args) => chunkIT74O4BE_cjs.uomValue(args[0].toNumber(), "days"),
|
|
2860
2883
|
// asTwoUnits(value, majorUnit, minorUnit) -> "12 min 30 s".
|
|
2861
2884
|
//
|
|
2862
2885
|
// "12.5 minutes in minutes and seconds" asks for one quantity split
|
|
@@ -2870,25 +2893,25 @@ var builtinFunctions = {
|
|
|
2870
2893
|
const major = typeof args[1]?.value === "string" ? args[1].value : void 0;
|
|
2871
2894
|
const minor = typeof args[2]?.value === "string" ? args[2].value : void 0;
|
|
2872
2895
|
if (major === void 0 || minor === void 0) {
|
|
2873
|
-
return
|
|
2896
|
+
return chunkIT74O4BE_cjs.errorValue("UNKNOWN_UNIT", 'both units have to be named, as in "12.5 minutes in minutes and seconds"');
|
|
2874
2897
|
}
|
|
2875
2898
|
const majorEntry = chunkAMOJYLG2_cjs.UNIT_TABLE[major.toLowerCase()];
|
|
2876
2899
|
const minorEntry = chunkAMOJYLG2_cjs.UNIT_TABLE[minor.toLowerCase()];
|
|
2877
2900
|
if (majorEntry === void 0 || minorEntry === void 0) {
|
|
2878
|
-
return
|
|
2901
|
+
return chunkIT74O4BE_cjs.errorValue("UNKNOWN_UNIT", `${major} and ${minor}: one of these is not a unit`);
|
|
2879
2902
|
}
|
|
2880
2903
|
if (majorEntry[0] !== minorEntry[0]) {
|
|
2881
|
-
return
|
|
2904
|
+
return chunkIT74O4BE_cjs.errorValue("INCOMPATIBLE_UNITS", `${major} and ${minor} measure different things`);
|
|
2882
2905
|
}
|
|
2883
2906
|
if (minorEntry[1] >= majorEntry[1]) {
|
|
2884
|
-
return
|
|
2907
|
+
return chunkIT74O4BE_cjs.errorValue("INCOMPATIBLE_UNITS", `${major} and ${minor}: name the larger unit first`);
|
|
2885
2908
|
}
|
|
2886
2909
|
const source = args[0];
|
|
2887
2910
|
const sourceEntry = source.type === 6 /* Uom */ && source.unit !== void 0 ? chunkAMOJYLG2_cjs.UNIT_TABLE[source.unit.toLowerCase()] : void 0;
|
|
2888
2911
|
const inBase = source.toNumber() * (sourceEntry?.[1] ?? majorEntry[1]);
|
|
2889
2912
|
const majorCount = Math.floor(inBase / majorEntry[1]);
|
|
2890
2913
|
const minorCount = Math.round((inBase - majorCount * majorEntry[1]) / minorEntry[1] * 1e3) / 1e3;
|
|
2891
|
-
return
|
|
2914
|
+
return chunkIT74O4BE_cjs.stringValue(`${majorCount} ${major} ${minorCount} ${minor}`);
|
|
2892
2915
|
},
|
|
2893
2916
|
// makeRate(value, denominatorUnit) -> value per that unit.
|
|
2894
2917
|
//
|
|
@@ -2904,9 +2927,9 @@ var builtinFunctions = {
|
|
|
2904
2927
|
const denominator = String(args[1].value);
|
|
2905
2928
|
const numerator = source.type === 6 /* Uom */ && source.unit !== void 0 ? source.unit : "";
|
|
2906
2929
|
if (numerator.includes("/")) {
|
|
2907
|
-
return
|
|
2930
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE_UNIT", `${numerator}/${denominator}: that is already a rate`);
|
|
2908
2931
|
}
|
|
2909
|
-
return
|
|
2932
|
+
return chunkIT74O4BE_cjs.uomValue(source.toNumber(), `${numerator}/${denominator}`);
|
|
2910
2933
|
},
|
|
2911
2934
|
// atRate(quantity, rate) -> whichever of the two the question implies.
|
|
2912
2935
|
//
|
|
@@ -2921,7 +2944,7 @@ var builtinFunctions = {
|
|
|
2921
2944
|
const left = args[0];
|
|
2922
2945
|
const rate = args[1];
|
|
2923
2946
|
if (rate.type !== 6 /* Uom */ || rate.unit === void 0 || !rate.unit.includes("/")) {
|
|
2924
|
-
return
|
|
2947
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", 'at: the right-hand side has to be a rate, as in "$30/hour"');
|
|
2925
2948
|
}
|
|
2926
2949
|
const slash = rate.unit.indexOf("/");
|
|
2927
2950
|
const numerator = rate.unit.slice(0, slash);
|
|
@@ -2932,17 +2955,17 @@ var builtinFunctions = {
|
|
|
2932
2955
|
if (leftEntry !== void 0 && denominatorEntry !== void 0 && leftEntry[0] === denominatorEntry[0]) {
|
|
2933
2956
|
const inDenominator = left.toNumber() * leftEntry[1] / denominatorEntry[1];
|
|
2934
2957
|
const total = inDenominator * rate.toNumber();
|
|
2935
|
-
return numerator === "" ?
|
|
2958
|
+
return numerator === "" ? chunkIT74O4BE_cjs.numberValue(total) : chunkIT74O4BE_cjs.uomValue(total, numerator);
|
|
2936
2959
|
}
|
|
2937
2960
|
if (leftUnit !== void 0 && leftUnit === numerator) {
|
|
2938
2961
|
const count = left.toNumber() / rate.toNumber();
|
|
2939
|
-
return
|
|
2962
|
+
return chunkIT74O4BE_cjs.uomValue(count, pluraliseUnit(denominator, count));
|
|
2940
2963
|
}
|
|
2941
2964
|
if (leftUnit === void 0) {
|
|
2942
2965
|
const total = left.toNumber() * rate.toNumber();
|
|
2943
|
-
return numerator === "" ?
|
|
2966
|
+
return numerator === "" ? chunkIT74O4BE_cjs.numberValue(total) : chunkIT74O4BE_cjs.uomValue(total, numerator);
|
|
2944
2967
|
}
|
|
2945
|
-
return
|
|
2968
|
+
return chunkIT74O4BE_cjs.errorValue("INCOMPATIBLE_UNITS", `at: ${leftUnit} matches neither side of ${rate.unit}`);
|
|
2946
2969
|
},
|
|
2947
2970
|
// ── Investments (packages/finance/) ────────────────────────────────────
|
|
2948
2971
|
// compoundFutureValueEvery(principal, rate, years, periodsPerYear)
|
|
@@ -2957,13 +2980,13 @@ var builtinFunctions = {
|
|
|
2957
2980
|
const years = args[2].toNumber();
|
|
2958
2981
|
const perYear = args[3].toNumber();
|
|
2959
2982
|
if (perYear <= 0) {
|
|
2960
|
-
return
|
|
2983
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `compounding: ${perYear} periods per year is not a period`);
|
|
2961
2984
|
}
|
|
2962
2985
|
if (1 + rate / perYear <= 0) {
|
|
2963
|
-
return
|
|
2986
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `compounding: rate ${rate} makes each period non-positive`);
|
|
2964
2987
|
}
|
|
2965
2988
|
const fv = principal * Math.pow(1 + rate / perYear, perYear * years);
|
|
2966
|
-
return args[0].type === 6 /* Uom */ ?
|
|
2989
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(fv, args[0].unit) : chunkIT74O4BE_cjs.numberValue(fv);
|
|
2967
2990
|
},
|
|
2968
2991
|
// compoundInterestEarnedEvery(principal, rate, years, periodsPerYear)
|
|
2969
2992
|
// The interest-only portion of index 80, i.e. FV - P.
|
|
@@ -2973,10 +2996,10 @@ var builtinFunctions = {
|
|
|
2973
2996
|
const years = args[2].toNumber();
|
|
2974
2997
|
const perYear = args[3].toNumber();
|
|
2975
2998
|
if (perYear <= 0 || 1 + rate / perYear <= 0) {
|
|
2976
|
-
return
|
|
2999
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `compounding: rate ${rate} over ${perYear} periods per year is not usable`);
|
|
2977
3000
|
}
|
|
2978
3001
|
const interest = principal * (Math.pow(1 + rate / perYear, perYear * years) - 1);
|
|
2979
|
-
return args[0].type === 6 /* Uom */ ?
|
|
3002
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(interest, args[0].unit) : chunkIT74O4BE_cjs.numberValue(interest);
|
|
2980
3003
|
},
|
|
2981
3004
|
// presentValue(futureValue, rate, years) -> FV / (1 + r)^y, what a sum
|
|
2982
3005
|
// promised in the future is worth today. The inverse of index 51.
|
|
@@ -2985,10 +3008,10 @@ var builtinFunctions = {
|
|
|
2985
3008
|
const rate = args[1].toNumber();
|
|
2986
3009
|
const years = args[2].toNumber();
|
|
2987
3010
|
if (1 + rate <= 0) {
|
|
2988
|
-
return
|
|
3011
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `presentValue: rate ${rate} makes (1 + rate) non-positive`);
|
|
2989
3012
|
}
|
|
2990
3013
|
const pv = future / Math.pow(1 + rate, years);
|
|
2991
|
-
return args[0].type === 6 /* Uom */ ?
|
|
3014
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(pv, args[0].unit) : chunkIT74O4BE_cjs.numberValue(pv);
|
|
2992
3015
|
},
|
|
2993
3016
|
// returnOnInvestment(invested, returned) -> (returned - invested) /
|
|
2994
3017
|
// invested, the gain as a multiple of what was put in. $500 in and $1,500
|
|
@@ -2999,9 +3022,9 @@ var builtinFunctions = {
|
|
|
2999
3022
|
const invested = args[0].toNumber();
|
|
3000
3023
|
const returned = args[1].toNumber();
|
|
3001
3024
|
if (invested === 0) {
|
|
3002
|
-
return
|
|
3025
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", "roi: nothing was invested, so there is no return on it");
|
|
3003
3026
|
}
|
|
3004
|
-
return
|
|
3027
|
+
return chunkIT74O4BE_cjs.numberValue((returned - invested) / invested);
|
|
3005
3028
|
},
|
|
3006
3029
|
// annualisedReturn(invested, returned, years) -> CAGR, the constant
|
|
3007
3030
|
// yearly rate that turns `invested` into `returned` over `years`:
|
|
@@ -3012,15 +3035,15 @@ var builtinFunctions = {
|
|
|
3012
3035
|
const returned = args[1].toNumber();
|
|
3013
3036
|
const years = args[2].toNumber();
|
|
3014
3037
|
if (invested <= 0) {
|
|
3015
|
-
return
|
|
3038
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", "annual return: the amount invested must be positive");
|
|
3016
3039
|
}
|
|
3017
3040
|
if (years <= 0) {
|
|
3018
|
-
return
|
|
3041
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", "annual return: the period must be longer than zero");
|
|
3019
3042
|
}
|
|
3020
3043
|
if (returned <= 0) {
|
|
3021
|
-
return
|
|
3044
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", "annual return: nothing was returned, so there is no annual rate");
|
|
3022
3045
|
}
|
|
3023
|
-
return
|
|
3046
|
+
return chunkIT74O4BE_cjs.percentageValue(Math.pow(returned / invested, 1 / years) - 1);
|
|
3024
3047
|
},
|
|
3025
3048
|
// roundToPlaces(value, places) -> value rounded to that many decimal
|
|
3026
3049
|
// places, backing `<value> to <n> dp` (converters/parselets/
|
|
@@ -3032,16 +3055,74 @@ var builtinFunctions = {
|
|
|
3032
3055
|
// fractional part to round at all, and the round trip through 1e23 was
|
|
3033
3056
|
// pure loss. Asking for fewer decimal places than a number has cannot
|
|
3034
3057
|
// change it, so a value that is already whole is returned untouched.
|
|
3035
|
-
97: (args) => roundToPlaces(args[0], args[1].toNumber())
|
|
3058
|
+
97: (args) => roundToPlaces(args[0], args[1].toNumber()),
|
|
3059
|
+
// splitEach(amount, n): a per-person bill split, `split $180 between 4` and
|
|
3060
|
+
// `$120 + 18% split 3 ways`. Backs both split spellings (see
|
|
3061
|
+
// BillSplitParselets.ts). Money stays exact and the shares add back to the
|
|
3062
|
+
// total to the cent (see splitEachExact in MoneyExact.ts). A bare number
|
|
3063
|
+
// splits to a bare number; the odd penny is named, not rounded away.
|
|
3064
|
+
98: (args) => {
|
|
3065
|
+
const n = args[1].toNumber();
|
|
3066
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
3067
|
+
return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `split: the number of shares must be a whole number of at least 1, not ${args[1].toNumber()}.`);
|
|
3068
|
+
}
|
|
3069
|
+
return chunkIT74O4BE_cjs.splitValue(splitEachExact(args[0], n));
|
|
3070
|
+
},
|
|
3071
|
+
// ── Savings goals ──────────────────────────────────────────────
|
|
3072
|
+
// savingsGoalPayment(target, duration, annualRate): the level contribution
|
|
3073
|
+
// per month that reaches `target` over `duration` (months or years), at an
|
|
3074
|
+
// optional annual rate compounded monthly. Backs "how much per month to
|
|
3075
|
+
// save/reach <target> in <duration> [at <rate>]".
|
|
3076
|
+
99: (args) => {
|
|
3077
|
+
const target = args[0].toNumber();
|
|
3078
|
+
const months = monthsOfDuration(args[1]);
|
|
3079
|
+
const annualRate = args[2].toNumber();
|
|
3080
|
+
if (months === null) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `savings goal: the duration must be in months or years, e.g. "in 2 years".`);
|
|
3081
|
+
if (target <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `savings goal: the target must be positive.`);
|
|
3082
|
+
if (months <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `savings goal: the duration must be positive.`);
|
|
3083
|
+
if (annualRate < 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `savings goal: the rate must not be negative.`);
|
|
3084
|
+
const payment = annuityPayment(target, annualRate / 12, months);
|
|
3085
|
+
return args[0].type === 6 /* Uom */ ? chunkIT74O4BE_cjs.uomValue(payment, args[0].unit) : chunkIT74O4BE_cjs.numberValue(payment);
|
|
3086
|
+
},
|
|
3087
|
+
// savingsGoalPeriods(target, contribution, periodsPerYear, annualRate,
|
|
3088
|
+
// periodUnit): how many whole periods of `contribution` reach `target`,
|
|
3089
|
+
// rounded UP, since a part period has not yet reached the goal. Backs
|
|
3090
|
+
// "how long to save <target> at <amount> <period> [at <rate>]".
|
|
3091
|
+
100: (args) => {
|
|
3092
|
+
const target = args[0].toNumber();
|
|
3093
|
+
const contribution = args[1].toNumber();
|
|
3094
|
+
const periodsPerYear = args[2].toNumber();
|
|
3095
|
+
const annualRate = args[3].toNumber();
|
|
3096
|
+
const unit = typeof args[4]?.value === "string" ? args[4].value : "periods";
|
|
3097
|
+
if (target <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `savings goal: the target must be positive.`);
|
|
3098
|
+
if (contribution <= 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RANGE", `savings goal: the contribution must be positive.`);
|
|
3099
|
+
if (annualRate < 0) return chunkIT74O4BE_cjs.errorValue("INVALID_RATE", `savings goal: the rate must not be negative.`);
|
|
3100
|
+
const periods = annuityPeriods(target, contribution, annualRate / periodsPerYear);
|
|
3101
|
+
return chunkIT74O4BE_cjs.uomValue(periods, unit);
|
|
3102
|
+
}
|
|
3036
3103
|
};
|
|
3104
|
+
function monthsOfDuration(duration) {
|
|
3105
|
+
if (duration.type !== 6 /* Uom */) return null;
|
|
3106
|
+
const unit = duration.unit;
|
|
3107
|
+
if (unit === "months" || unit === "month") return duration.toNumber();
|
|
3108
|
+
if (unit === "years" || unit === "year") return duration.toNumber() * 12;
|
|
3109
|
+
return null;
|
|
3110
|
+
}
|
|
3111
|
+
function annuityPayment(target, i, months) {
|
|
3112
|
+
return i === 0 ? target / months : target * i / (Math.pow(1 + i, months) - 1);
|
|
3113
|
+
}
|
|
3114
|
+
function annuityPeriods(target, contribution, i) {
|
|
3115
|
+
const raw = i === 0 ? target / contribution : Math.log(1 + target * i / contribution) / Math.log(1 + i);
|
|
3116
|
+
return Math.ceil(raw - 1e-9);
|
|
3117
|
+
}
|
|
3037
3118
|
function applyComplexAccessor(name, value) {
|
|
3038
3119
|
const node = valueToSymbolic(value);
|
|
3039
|
-
if (node === null) return
|
|
3040
|
-
return symbolicToValue(
|
|
3120
|
+
if (node === null) return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_NONFINITE_OPERAND", name + " needs a value with an exact number.");
|
|
3121
|
+
return symbolicToValue(chunkA2DZ5BEJ_cjs.callNode(name, [node]));
|
|
3041
3122
|
}
|
|
3042
3123
|
function symbolicVariableName(value, verb) {
|
|
3043
3124
|
if (value?.type !== 3 /* String */) {
|
|
3044
|
-
return
|
|
3125
|
+
return chunkIT74O4BE_cjs.errorValue("SYMBOLIC_REQUIRES_VARIABLE_NAME", `${verb} needs the name of an unknown.`);
|
|
3045
3126
|
}
|
|
3046
3127
|
return value.value;
|
|
3047
3128
|
}
|
|
@@ -3058,7 +3139,7 @@ var MAX_PLUGIN_FUNCTION_INDEX = 255;
|
|
|
3058
3139
|
var nextPluginFunctionIndex = 0;
|
|
3059
3140
|
function allocatePluginFunctionIndex() {
|
|
3060
3141
|
if (nextPluginFunctionIndex > MAX_PLUGIN_FUNCTION_INDEX) {
|
|
3061
|
-
throw
|
|
3142
|
+
throw chunkMIGXCBXT_cjs.ErrorFactory.config(
|
|
3062
3143
|
"PLUGIN_FUNCTION_INDEX_POOL_EXHAUSTED",
|
|
3063
3144
|
`allocatePluginFunctionIndex: pool exhausted (max ${MAX_PLUGIN_FUNCTION_INDEX + 1} allocations).`
|
|
3064
3145
|
);
|
|
@@ -3218,5 +3299,5 @@ exports.toBigIntOperand = toBigIntOperand;
|
|
|
3218
3299
|
exports.uncertainOp = uncertainOp;
|
|
3219
3300
|
exports.unifyUom = unifyUom;
|
|
3220
3301
|
exports.unregisterAsConverter = unregisterAsConverter;
|
|
3221
|
-
//# sourceMappingURL=chunk-
|
|
3222
|
-
//# sourceMappingURL=chunk-
|
|
3302
|
+
//# sourceMappingURL=chunk-FR7RNOPT.cjs.map
|
|
3303
|
+
//# sourceMappingURL=chunk-FR7RNOPT.cjs.map
|