mathjs 11.8.2 → 11.9.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/HISTORY.md +17 -0
- package/lib/browser/math.js +1 -1
- package/lib/browser/math.js.LICENSE.txt +2 -2
- package/lib/browser/math.js.map +1 -1
- package/lib/cjs/entry/dependenciesAny/dependenciesFreqz.generated.js +28 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesRange.generated.js +4 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesRangeTransform.generated.js +4 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesSolveODE.generated.js +46 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesZpk2tf.generated.js +26 -0
- package/lib/cjs/entry/dependenciesAny.generated.js +21 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesRange.generated.js +4 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesRangeTransform.generated.js +4 -0
- package/lib/cjs/entry/impureFunctionsAny.generated.js +35 -30
- package/lib/cjs/entry/impureFunctionsNumber.generated.js +2 -0
- package/lib/cjs/entry/pureFunctionsAny.generated.js +82 -45
- package/lib/cjs/entry/pureFunctionsNumber.generated.js +2 -0
- package/lib/cjs/expression/embeddedDocs/core/typed.js +1 -1
- package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +11 -3
- package/lib/cjs/expression/embeddedDocs/function/{matrix → algebra}/lyap.js +2 -2
- package/lib/cjs/expression/embeddedDocs/function/algebra/polynomialRoot.js +1 -1
- package/lib/cjs/expression/embeddedDocs/function/{matrix → algebra}/schur.js +2 -2
- package/lib/cjs/expression/embeddedDocs/function/algebra/simplifyConstant.js +1 -1
- package/lib/cjs/expression/embeddedDocs/function/{matrix → algebra}/sylvester.js +2 -2
- package/lib/cjs/expression/embeddedDocs/function/arithmetic/invmod.js +1 -1
- package/lib/cjs/expression/embeddedDocs/function/expression/evaluate.js +2 -2
- package/lib/cjs/expression/embeddedDocs/function/matrix/diff.js +1 -1
- package/lib/cjs/expression/embeddedDocs/function/matrix/range.js +1 -1
- package/lib/cjs/expression/embeddedDocs/function/numeric/solveODE.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/signal/freqz.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/signal/zpk2tf.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/utils/numeric.js +1 -1
- package/lib/cjs/expression/transform/range.transform.js +7 -3
- package/lib/cjs/factoriesAny.js +21 -0
- package/lib/cjs/function/algebra/simplify.js +3 -0
- package/lib/cjs/function/matrix/range.js +34 -110
- package/lib/cjs/function/numeric/solveODE.js +315 -0
- package/lib/cjs/function/signal/freqz.js +117 -0
- package/lib/cjs/function/signal/zpk2tf.js +95 -0
- package/lib/cjs/header.js +2 -2
- package/lib/cjs/type/unit/Unit.js +15 -13
- package/lib/cjs/version.js +1 -1
- package/lib/esm/entry/dependenciesAny/dependenciesFreqz.generated.js +20 -0
- package/lib/esm/entry/dependenciesAny/dependenciesRange.generated.js +4 -0
- package/lib/esm/entry/dependenciesAny/dependenciesRangeTransform.generated.js +4 -0
- package/lib/esm/entry/dependenciesAny/dependenciesSolveODE.generated.js +38 -0
- package/lib/esm/entry/dependenciesAny/dependenciesZpk2tf.generated.js +18 -0
- package/lib/esm/entry/dependenciesAny.generated.js +3 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesRange.generated.js +4 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesRangeTransform.generated.js +4 -0
- package/lib/esm/entry/impureFunctionsAny.generated.js +34 -29
- package/lib/esm/entry/impureFunctionsNumber.generated.js +2 -0
- package/lib/esm/entry/pureFunctionsAny.generated.js +70 -36
- package/lib/esm/entry/pureFunctionsNumber.generated.js +2 -0
- package/lib/esm/expression/embeddedDocs/core/typed.js +1 -1
- package/lib/esm/expression/embeddedDocs/embeddedDocs.js +11 -3
- package/lib/esm/expression/embeddedDocs/function/{matrix → algebra}/lyap.js +2 -2
- package/lib/esm/expression/embeddedDocs/function/algebra/polynomialRoot.js +1 -1
- package/lib/esm/expression/embeddedDocs/function/{matrix → algebra}/schur.js +2 -2
- package/lib/esm/expression/embeddedDocs/function/algebra/simplifyConstant.js +1 -1
- package/lib/esm/expression/embeddedDocs/function/{matrix → algebra}/sylvester.js +2 -2
- package/lib/esm/expression/embeddedDocs/function/arithmetic/invmod.js +1 -1
- package/lib/esm/expression/embeddedDocs/function/expression/evaluate.js +2 -2
- package/lib/esm/expression/embeddedDocs/function/matrix/diff.js +1 -1
- package/lib/esm/expression/embeddedDocs/function/matrix/range.js +1 -1
- package/lib/esm/expression/embeddedDocs/function/numeric/solveODE.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/signal/freqz.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/signal/zpk2tf.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/utils/numeric.js +1 -1
- package/lib/esm/expression/transform/range.transform.js +7 -3
- package/lib/esm/factoriesAny.js +3 -0
- package/lib/esm/function/algebra/simplify.js +3 -0
- package/lib/esm/function/matrix/range.js +34 -110
- package/lib/esm/function/numeric/solveODE.js +284 -0
- package/lib/esm/function/signal/freqz.js +115 -0
- package/lib/esm/function/signal/zpk2tf.js +82 -0
- package/lib/esm/type/unit/Unit.js +15 -13
- package/lib/esm/version.js +1 -1
- package/package.json +1 -1
- package/types/index.d.ts +51 -6
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export var evaluateDocs = {
|
|
2
2
|
name: 'evaluate',
|
|
3
3
|
category: 'Expression',
|
|
4
|
-
syntax: ['evaluate(expression)', 'evaluate([expr1, expr2, expr3, ...])'],
|
|
4
|
+
syntax: ['evaluate(expression)', 'evaluate(expression, scope)', 'evaluate([expr1, expr2, expr3, ...])', 'evaluate([expr1, expr2, expr3, ...], scope)'],
|
|
5
5
|
description: 'Evaluate an expression or an array with expressions.',
|
|
6
|
-
examples: ['evaluate("2 + 3")', 'evaluate("sqrt("
|
|
6
|
+
examples: ['evaluate("2 + 3")', 'evaluate("sqrt(16)")', 'evaluate("2 inch to cm")', 'evaluate("sin(x * pi)", { "x": 1/2 })', 'evaluate(["width=2", "height=4","width*height"])'],
|
|
7
7
|
seealso: []
|
|
8
8
|
};
|
|
@@ -3,6 +3,6 @@ export var diffDocs = {
|
|
|
3
3
|
category: 'Matrix',
|
|
4
4
|
syntax: ['diff(arr)', 'diff(arr, dim)'],
|
|
5
5
|
description: ['Create a new matrix or array with the difference of the passed matrix or array.', 'Dim parameter is optional and used to indicant the dimension of the array/matrix to apply the difference', 'If no dimension parameter is passed it is assumed as dimension 0', 'Dimension is zero-based in javascript and one-based in the parser', 'Arrays must be \'rectangular\' meaning arrays like [1, 2]', 'If something is passed as a matrix it will be returned as a matrix but other than that all matrices are converted to arrays'],
|
|
6
|
-
examples: ['
|
|
6
|
+
examples: ['A = [1, 2, 4, 7, 0]', 'diff(A)', 'diff(A, 1)', 'B = [[1, 2], [3, 4]]', 'diff(B)', 'diff(B, 1)', 'diff(B, 2)', 'diff(B, bignumber(2))', 'diff([[1, 2], matrix([3, 4])], 2)'],
|
|
7
7
|
seealso: ['subtract', 'partitionSelect']
|
|
8
8
|
};
|
|
@@ -3,6 +3,6 @@ export var rangeDocs = {
|
|
|
3
3
|
category: 'Type',
|
|
4
4
|
syntax: ['start:end', 'start:step:end', 'range(start, end)', 'range(start, end, step)', 'range(string)'],
|
|
5
5
|
description: 'Create a range. Lower bound of the range is included, upper bound is excluded.',
|
|
6
|
-
examples: ['1:5', '3:-1:-3', 'range(3, 7)', 'range(0, 12, 2)', 'range("4:10")', 'a = [1, 2, 3, 4; 5, 6, 7, 8]', 'a[1:2, 1:2]'],
|
|
6
|
+
examples: ['1:5', '3:-1:-3', 'range(3, 7)', 'range(0, 12, 2)', 'range("4:10")', 'range(1m, 1m, 3m)', 'a = [1, 2, 3, 4; 5, 6, 7, 8]', 'a[1:2, 1:2]'],
|
|
7
7
|
seealso: ['concat', 'det', 'diag', 'identity', 'inv', 'ones', 'size', 'squeeze', 'subset', 'trace', 'transpose', 'zeros']
|
|
8
8
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export var solveODEDocs = {
|
|
2
|
+
name: 'solveODE',
|
|
3
|
+
category: 'Numeric',
|
|
4
|
+
syntax: ['solveODE(func, tspan, y0)', 'solveODE(func, tspan, y0, options)'],
|
|
5
|
+
description: 'Numerical Integration of Ordinary Differential Equations.',
|
|
6
|
+
examples: ['f(t,y) = y', 'tspan = [0, 4]', 'solveODE(f, tspan, 1)', 'solveODE(f, tspan, [1, 2])', 'solveODE(f, tspan, 1, { method:"RK23", maxStep:0.1 })'],
|
|
7
|
+
seealso: ['derivative', 'simplifyCore']
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export var freqzDocs = {
|
|
2
|
+
name: 'freqz',
|
|
3
|
+
category: 'Signal',
|
|
4
|
+
syntax: ['freqz(b, a)', 'freqz(b, a, w)'],
|
|
5
|
+
description: 'Calculates the frequency response of a filter given its numerator and denominator coefficients.',
|
|
6
|
+
examples: ['freqz([1, 2], [1, 2, 3])', 'freqz([1, 2], [1, 2, 3], [0, 1])', 'freqz([1, 2], [1, 2, 3], 512)'],
|
|
7
|
+
seealso: []
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export var zpk2tfDocs = {
|
|
2
|
+
name: 'zpk2tf',
|
|
3
|
+
category: 'Signal',
|
|
4
|
+
syntax: ['zpk2tf(z, p, k)'],
|
|
5
|
+
description: 'Compute the transfer function of a zero-pole-gain model.',
|
|
6
|
+
examples: ['zpk2tf([1, 2], [-1, -2], 1)', 'zpk2tf([1, 2], [-1, -2])', 'zpk2tf([1 - 3i, 2 + 2i], [-1, -2])'],
|
|
7
|
+
seealso: []
|
|
8
|
+
};
|
|
@@ -3,6 +3,6 @@ export var numericDocs = {
|
|
|
3
3
|
category: 'Utils',
|
|
4
4
|
syntax: ['numeric(x)'],
|
|
5
5
|
description: 'Convert a numeric input to a specific numeric type: number, BigNumber, or Fraction.',
|
|
6
|
-
examples: ['numeric("4")', 'numeric("4", "number")', 'numeric("4", "BigNumber")', 'numeric("4", "Fraction)', 'numeric(4, "Fraction")', 'numeric(fraction(2, 5), "number)'],
|
|
6
|
+
examples: ['numeric("4")', 'numeric("4", "number")', 'numeric("4", "BigNumber")', 'numeric("4", "Fraction")', 'numeric(4, "Fraction")', 'numeric(fraction(2, 5), "number")'],
|
|
7
7
|
seealso: ['number', 'fraction', 'bignumber', 'string', 'format']
|
|
8
8
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { factory } from '../../utils/factory.js';
|
|
2
2
|
import { createRange } from '../../function/matrix/range.js';
|
|
3
3
|
var name = 'range';
|
|
4
|
-
var dependencies = ['typed', 'config', '?matrix', '?bignumber', 'smaller', 'smallerEq', 'larger', 'largerEq'];
|
|
4
|
+
var dependencies = ['typed', 'config', '?matrix', '?bignumber', 'smaller', 'smallerEq', 'larger', 'largerEq', 'add', 'isPositive'];
|
|
5
5
|
export var createRangeTransform = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
6
6
|
var {
|
|
7
7
|
typed,
|
|
@@ -11,7 +11,9 @@ export var createRangeTransform = /* #__PURE__ */factory(name, dependencies, _re
|
|
|
11
11
|
smaller,
|
|
12
12
|
smallerEq,
|
|
13
13
|
larger,
|
|
14
|
-
largerEq
|
|
14
|
+
largerEq,
|
|
15
|
+
add,
|
|
16
|
+
isPositive
|
|
15
17
|
} = _ref;
|
|
16
18
|
var range = createRange({
|
|
17
19
|
typed,
|
|
@@ -21,7 +23,9 @@ export var createRangeTransform = /* #__PURE__ */factory(name, dependencies, _re
|
|
|
21
23
|
smaller,
|
|
22
24
|
smallerEq,
|
|
23
25
|
larger,
|
|
24
|
-
largerEq
|
|
26
|
+
largerEq,
|
|
27
|
+
add,
|
|
28
|
+
isPositive
|
|
25
29
|
});
|
|
26
30
|
|
|
27
31
|
/**
|
package/lib/esm/factoriesAny.js
CHANGED
|
@@ -94,6 +94,7 @@ export { createCtranspose } from './function/matrix/ctranspose.js';
|
|
|
94
94
|
export { createZeros } from './function/matrix/zeros.js';
|
|
95
95
|
export { createFft } from './function/matrix/fft.js';
|
|
96
96
|
export { createIfft } from './function/matrix/ifft.js';
|
|
97
|
+
export { createSolveODE } from './function/numeric/solveODE.js';
|
|
97
98
|
export { createErf } from './function/special/erf.js';
|
|
98
99
|
export { createMode } from './function/statistics/mode.js';
|
|
99
100
|
export { createProd } from './function/statistics/prod.js';
|
|
@@ -258,6 +259,8 @@ export { createResolve } from './function/algebra/resolve.js';
|
|
|
258
259
|
export { createSymbolicEqual } from './function/algebra/symbolicEqual.js';
|
|
259
260
|
export { createDerivative } from './function/algebra/derivative.js';
|
|
260
261
|
export { createRationalize } from './function/algebra/rationalize.js';
|
|
262
|
+
export { createZpk2tf } from './function/signal/zpk2tf.js';
|
|
263
|
+
export { createFreqz } from './function/signal/freqz.js';
|
|
261
264
|
export { createReviver } from './json/reviver.js';
|
|
262
265
|
export { createReplacer } from './json/replacer.js';
|
|
263
266
|
export { createE, createUppercaseE, createFalse, createI, createInfinity, createLN10, createLN2, createLOG10E, createLOG2E, createNaN, createNull, createPhi, createPi, createUppercasePi, createSQRT1_2,
|
|
@@ -533,6 +533,9 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
533
533
|
},
|
|
534
534
|
// undo replace 'subtract'
|
|
535
535
|
{
|
|
536
|
+
l: 'n+-(n1)',
|
|
537
|
+
r: 'n-(n1)'
|
|
538
|
+
}, {
|
|
536
539
|
s: 'n*(n1^-1) -> n/n1',
|
|
537
540
|
// undo replace 'divide'; for * commutative
|
|
538
541
|
assuming: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { factory } from '../../utils/factory.js';
|
|
2
2
|
import { noBignumber, noMatrix } from '../../utils/noop.js';
|
|
3
3
|
var name = 'range';
|
|
4
|
-
var dependencies = ['typed', 'config', '?matrix', '?bignumber', 'smaller', 'smallerEq', 'larger', 'largerEq'];
|
|
4
|
+
var dependencies = ['typed', 'config', '?matrix', '?bignumber', 'smaller', 'smallerEq', 'larger', 'largerEq', 'add', 'isPositive'];
|
|
5
5
|
export var createRange = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
6
6
|
var {
|
|
7
7
|
typed,
|
|
@@ -11,7 +11,9 @@ export var createRange = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
11
11
|
smaller,
|
|
12
12
|
smallerEq,
|
|
13
13
|
larger,
|
|
14
|
-
largerEq
|
|
14
|
+
largerEq,
|
|
15
|
+
add,
|
|
16
|
+
isPositive
|
|
15
17
|
} = _ref;
|
|
16
18
|
/**
|
|
17
19
|
* Create an array from a range.
|
|
@@ -33,11 +35,11 @@ export var createRange = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
33
35
|
*
|
|
34
36
|
* - `str: string`
|
|
35
37
|
* A string 'start:end' or 'start:step:end'
|
|
36
|
-
* - `start: {number | BigNumber}`
|
|
38
|
+
* - `start: {number | BigNumber | Unit}`
|
|
37
39
|
* Start of the range
|
|
38
|
-
* - `end: number | BigNumber`
|
|
40
|
+
* - `end: number | BigNumber | Unit`
|
|
39
41
|
* End of the range, excluded by default, included when parameter includeEnd=true
|
|
40
|
-
* - `step: number | BigNumber`
|
|
42
|
+
* - `step: number | BigNumber | Unit`
|
|
41
43
|
* Step size. Default value is 1.
|
|
42
44
|
* - `includeEnd: boolean`
|
|
43
45
|
* Option to specify whether to include the end or not. False by default.
|
|
@@ -48,6 +50,7 @@ export var createRange = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
48
50
|
* math.range(2, -3, -1) // [2, 1, 0, -1, -2]
|
|
49
51
|
* math.range('2:1:6') // [2, 3, 4, 5]
|
|
50
52
|
* math.range(2, 6, true) // [2, 3, 4, 5, 6]
|
|
53
|
+
* math.range(math.unit(2, 'm'), math.unit(-3, 'm'), math.unit(-1, 'm')) // [2 m, 1 m, 0 m , -1 m, -2 m]
|
|
51
54
|
*
|
|
52
55
|
* See also:
|
|
53
56
|
*
|
|
@@ -63,30 +66,36 @@ export var createRange = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
63
66
|
string: _strRange,
|
|
64
67
|
'string, boolean': _strRange,
|
|
65
68
|
'number, number': function numberNumber(start, end) {
|
|
66
|
-
return _out(
|
|
69
|
+
return _out(_range(start, end, 1, false));
|
|
67
70
|
},
|
|
68
71
|
'number, number, number': function numberNumberNumber(start, end, step) {
|
|
69
|
-
return _out(
|
|
72
|
+
return _out(_range(start, end, step, false));
|
|
70
73
|
},
|
|
71
74
|
'number, number, boolean': function numberNumberBoolean(start, end, includeEnd) {
|
|
72
|
-
return
|
|
75
|
+
return _out(_range(start, end, 1, includeEnd));
|
|
73
76
|
},
|
|
74
77
|
'number, number, number, boolean': function numberNumberNumberBoolean(start, end, step, includeEnd) {
|
|
75
|
-
return
|
|
78
|
+
return _out(_range(start, end, step, includeEnd));
|
|
76
79
|
},
|
|
77
80
|
'BigNumber, BigNumber': function BigNumberBigNumber(start, end) {
|
|
78
81
|
var BigNumber = start.constructor;
|
|
79
|
-
return _out(
|
|
82
|
+
return _out(_range(start, end, new BigNumber(1), false));
|
|
80
83
|
},
|
|
81
84
|
'BigNumber, BigNumber, BigNumber': function BigNumberBigNumberBigNumber(start, end, step) {
|
|
82
|
-
return _out(
|
|
85
|
+
return _out(_range(start, end, step, false));
|
|
83
86
|
},
|
|
84
87
|
'BigNumber, BigNumber, boolean': function BigNumberBigNumberBoolean(start, end, includeEnd) {
|
|
85
88
|
var BigNumber = start.constructor;
|
|
86
|
-
return
|
|
89
|
+
return _out(_range(start, end, new BigNumber(1), includeEnd));
|
|
87
90
|
},
|
|
88
91
|
'BigNumber, BigNumber, BigNumber, boolean': function BigNumberBigNumberBigNumberBoolean(start, end, step, includeEnd) {
|
|
89
|
-
return
|
|
92
|
+
return _out(_range(start, end, step, includeEnd));
|
|
93
|
+
},
|
|
94
|
+
'Unit, Unit, Unit': function UnitUnitUnit(start, end, step) {
|
|
95
|
+
return _out(_range(start, end, step, false));
|
|
96
|
+
},
|
|
97
|
+
'Unit, Unit, Unit, boolean': function UnitUnitUnitBoolean(start, end, step, includeEnd) {
|
|
98
|
+
return _out(_range(start, end, step, includeEnd));
|
|
90
99
|
}
|
|
91
100
|
});
|
|
92
101
|
function _out(arr) {
|
|
@@ -100,117 +109,32 @@ export var createRange = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
100
109
|
if (!r) {
|
|
101
110
|
throw new SyntaxError('String "' + str + '" is no valid range');
|
|
102
111
|
}
|
|
103
|
-
var fn;
|
|
104
112
|
if (config.number === 'BigNumber') {
|
|
105
113
|
if (bignumber === undefined) {
|
|
106
114
|
noBignumber();
|
|
107
115
|
}
|
|
108
|
-
|
|
109
|
-
return _out(fn(bignumber(r.start), bignumber(r.end), bignumber(r.step)));
|
|
116
|
+
return _out(_range(bignumber(r.start), bignumber(r.end), bignumber(r.step)), includeEnd);
|
|
110
117
|
} else {
|
|
111
|
-
|
|
112
|
-
return _out(fn(r.start, r.end, r.step));
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Create a range with numbers. End is excluded
|
|
118
|
-
* @param {number} start
|
|
119
|
-
* @param {number} end
|
|
120
|
-
* @param {number} step
|
|
121
|
-
* @returns {Array} range
|
|
122
|
-
* @private
|
|
123
|
-
*/
|
|
124
|
-
function _rangeEx(start, end, step) {
|
|
125
|
-
var array = [];
|
|
126
|
-
var x = start;
|
|
127
|
-
if (step > 0) {
|
|
128
|
-
while (smaller(x, end)) {
|
|
129
|
-
array.push(x);
|
|
130
|
-
x += step;
|
|
131
|
-
}
|
|
132
|
-
} else if (step < 0) {
|
|
133
|
-
while (larger(x, end)) {
|
|
134
|
-
array.push(x);
|
|
135
|
-
x += step;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return array;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Create a range with numbers. End is included
|
|
143
|
-
* @param {number} start
|
|
144
|
-
* @param {number} end
|
|
145
|
-
* @param {number} step
|
|
146
|
-
* @returns {Array} range
|
|
147
|
-
* @private
|
|
148
|
-
*/
|
|
149
|
-
function _rangeInc(start, end, step) {
|
|
150
|
-
var array = [];
|
|
151
|
-
var x = start;
|
|
152
|
-
if (step > 0) {
|
|
153
|
-
while (smallerEq(x, end)) {
|
|
154
|
-
array.push(x);
|
|
155
|
-
x += step;
|
|
156
|
-
}
|
|
157
|
-
} else if (step < 0) {
|
|
158
|
-
while (largerEq(x, end)) {
|
|
159
|
-
array.push(x);
|
|
160
|
-
x += step;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return array;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Create a range with big numbers. End is excluded
|
|
168
|
-
* @param {BigNumber} start
|
|
169
|
-
* @param {BigNumber} end
|
|
170
|
-
* @param {BigNumber} step
|
|
171
|
-
* @returns {Array} range
|
|
172
|
-
* @private
|
|
173
|
-
*/
|
|
174
|
-
function _bigRangeEx(start, end, step) {
|
|
175
|
-
var zero = bignumber(0);
|
|
176
|
-
var array = [];
|
|
177
|
-
var x = start;
|
|
178
|
-
if (step.gt(zero)) {
|
|
179
|
-
while (smaller(x, end)) {
|
|
180
|
-
array.push(x);
|
|
181
|
-
x = x.plus(step);
|
|
182
|
-
}
|
|
183
|
-
} else if (step.lt(zero)) {
|
|
184
|
-
while (larger(x, end)) {
|
|
185
|
-
array.push(x);
|
|
186
|
-
x = x.plus(step);
|
|
187
|
-
}
|
|
118
|
+
return _out(_range(r.start, r.end, r.step, includeEnd));
|
|
188
119
|
}
|
|
189
|
-
return array;
|
|
190
120
|
}
|
|
191
121
|
|
|
192
122
|
/**
|
|
193
|
-
* Create a range with
|
|
194
|
-
* @param {BigNumber} start
|
|
195
|
-
* @param {BigNumber} end
|
|
196
|
-
* @param {BigNumber} step
|
|
123
|
+
* Create a range with numbers or BigNumbers
|
|
124
|
+
* @param {number | BigNumber | Unit} start
|
|
125
|
+
* @param {number | BigNumber | Unit} end
|
|
126
|
+
* @param {number | BigNumber | Unit} step
|
|
127
|
+
* @param {boolean} includeEnd
|
|
197
128
|
* @returns {Array} range
|
|
198
129
|
* @private
|
|
199
130
|
*/
|
|
200
|
-
function
|
|
201
|
-
var zero = bignumber(0);
|
|
131
|
+
function _range(start, end, step, includeEnd) {
|
|
202
132
|
var array = [];
|
|
133
|
+
var ongoing = isPositive(step) ? includeEnd ? smallerEq : smaller : includeEnd ? largerEq : larger;
|
|
203
134
|
var x = start;
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
x = x.plus(step);
|
|
208
|
-
}
|
|
209
|
-
} else if (step.lt(zero)) {
|
|
210
|
-
while (largerEq(x, end)) {
|
|
211
|
-
array.push(x);
|
|
212
|
-
x = x.plus(step);
|
|
213
|
-
}
|
|
135
|
+
while (ongoing(x, end)) {
|
|
136
|
+
array.push(x);
|
|
137
|
+
x = add(x, step);
|
|
214
138
|
}
|
|
215
139
|
return array;
|
|
216
140
|
}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
3
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
4
|
+
import { isUnit, isNumber, isBigNumber } from '../../utils/is.js';
|
|
5
|
+
import { factory } from '../../utils/factory.js';
|
|
6
|
+
var name = 'solveODE';
|
|
7
|
+
var dependencies = ['typed', 'add', 'subtract', 'multiply', 'divide', 'max', 'map', 'abs', 'isPositive', 'isNegative', 'larger', 'smaller', 'matrix', 'bignumber', 'unaryMinus'];
|
|
8
|
+
export var createSolveODE = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
9
|
+
var {
|
|
10
|
+
typed,
|
|
11
|
+
add,
|
|
12
|
+
subtract,
|
|
13
|
+
multiply,
|
|
14
|
+
divide,
|
|
15
|
+
max,
|
|
16
|
+
map,
|
|
17
|
+
abs,
|
|
18
|
+
isPositive,
|
|
19
|
+
isNegative,
|
|
20
|
+
larger,
|
|
21
|
+
smaller,
|
|
22
|
+
matrix,
|
|
23
|
+
bignumber,
|
|
24
|
+
unaryMinus
|
|
25
|
+
} = _ref;
|
|
26
|
+
/**
|
|
27
|
+
* Numerical Integration of Ordinary Differential Equations
|
|
28
|
+
*
|
|
29
|
+
* Two variable step methods are provided:
|
|
30
|
+
* - "RK23": Bogacki–Shampine method
|
|
31
|
+
* - "RK45": Dormand-Prince method RK5(4)7M (default)
|
|
32
|
+
*
|
|
33
|
+
* The arguments are expected as follows.
|
|
34
|
+
*
|
|
35
|
+
* - `func` should be the forcing function `f(t, y)`
|
|
36
|
+
* - `tspan` should be a vector of two numbers or units `[tStart, tEnd]`
|
|
37
|
+
* - `y0` the initial state values, should be a scalar or a flat array
|
|
38
|
+
* - `options` should be an object with the following information:
|
|
39
|
+
* - `method` ('RK45'): ['RK23', 'RK45']
|
|
40
|
+
* - `tol` (1e-3): Numeric tolerance of the method, the solver keeps the error estimates less than this value
|
|
41
|
+
* - `firstStep`: Initial step size
|
|
42
|
+
* - `minStep`: minimum step size of the method
|
|
43
|
+
* - `maxStep`: maximum step size of the method
|
|
44
|
+
* - `minDelta` (0.2): minimum ratio of change for the step
|
|
45
|
+
* - `maxDelta` (5): maximum ratio of change for the step
|
|
46
|
+
* - `maxIter` (1e4): maximum number of iterations
|
|
47
|
+
*
|
|
48
|
+
* The returned value is an object with `{t, y}` please note that even though `t` means time, it can represent any other independant variable like `x`:
|
|
49
|
+
* - `t` an array of size `[n]`
|
|
50
|
+
* - `y` the states array can be in two ways
|
|
51
|
+
* - **if `y0` is a scalar:** returns an array-like of size `[n]`
|
|
52
|
+
* - **if `y0` is a flat array-like of size [m]:** returns an array like of size `[n, m]`
|
|
53
|
+
*
|
|
54
|
+
* Syntax:
|
|
55
|
+
*
|
|
56
|
+
* math.solveODE(func, tspan, y0)
|
|
57
|
+
* math.solveODE(func, tspan, y0, options)
|
|
58
|
+
*
|
|
59
|
+
* Examples:
|
|
60
|
+
*
|
|
61
|
+
* function func(t, y) {return y}
|
|
62
|
+
* const tspan = [0, 4]
|
|
63
|
+
* const y0 = 1
|
|
64
|
+
* math.solveODE(func, tspan, y0)
|
|
65
|
+
* math.solveODE(func, tspan, [1, 2])
|
|
66
|
+
* math.solveODE(func, tspan, y0, { method:"RK23", maxStep:0.1 })
|
|
67
|
+
*
|
|
68
|
+
* See also:
|
|
69
|
+
*
|
|
70
|
+
* derivative, simplifyCore
|
|
71
|
+
*
|
|
72
|
+
* @param {function} func The forcing function f(t,y)
|
|
73
|
+
* @param {Array | Matrix} tspan The time span
|
|
74
|
+
* @param {number | BigNumber | Unit | Array | Matrix} y0 The initial value
|
|
75
|
+
* @param {Object} [options] Optional configuration options
|
|
76
|
+
* @return {Object} Return an object with t and y values as arrays
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
function _rk(butcherTableau) {
|
|
80
|
+
// generates an adaptive runge kutta method from it's butcher tableau
|
|
81
|
+
|
|
82
|
+
return function (f, tspan, y0, options) {
|
|
83
|
+
// adaptive runge kutta methods
|
|
84
|
+
var wrongTSpan = !(tspan.length === 2 && (tspan.every(isNumOrBig) || tspan.every(isUnit)));
|
|
85
|
+
if (wrongTSpan) {
|
|
86
|
+
throw new Error('"tspan" must be an Array of two numeric values or two units [tStart, tEnd]');
|
|
87
|
+
}
|
|
88
|
+
var t0 = tspan[0]; // initial time
|
|
89
|
+
var tf = tspan[1]; // final time
|
|
90
|
+
var isForwards = larger(tf, t0);
|
|
91
|
+
var firstStep = options.firstStep;
|
|
92
|
+
if (firstStep !== undefined && !isPositive(firstStep)) {
|
|
93
|
+
throw new Error('"firstStep" must be positive');
|
|
94
|
+
}
|
|
95
|
+
var maxStep = options.maxStep;
|
|
96
|
+
if (maxStep !== undefined && !isPositive(maxStep)) {
|
|
97
|
+
throw new Error('"maxStep" must be positive');
|
|
98
|
+
}
|
|
99
|
+
var minStep = options.minStep;
|
|
100
|
+
if (minStep && isNegative(minStep)) {
|
|
101
|
+
throw new Error('"minStep" must be positive or zero');
|
|
102
|
+
}
|
|
103
|
+
var timeVars = [t0, tf, firstStep, minStep, maxStep].filter(x => x !== undefined);
|
|
104
|
+
if (!(timeVars.every(isNumOrBig) || timeVars.every(isUnit))) {
|
|
105
|
+
throw new Error('Inconsistent type of "t" dependant variables');
|
|
106
|
+
}
|
|
107
|
+
var steps = 1; // divide time in this number of steps
|
|
108
|
+
var tol = options.tol ? options.tol : 1e-4; // define a tolerance (must be an option)
|
|
109
|
+
var minDelta = options.minDelta ? options.minDelta : 0.2;
|
|
110
|
+
var maxDelta = options.maxDelta ? options.maxDelta : 5;
|
|
111
|
+
var maxIter = options.maxIter ? options.maxIter : 10000; // stop inifite evaluation if something goes wrong
|
|
112
|
+
var hasBigNumbers = [t0, tf, ...y0, maxStep, minStep].some(isBigNumber);
|
|
113
|
+
var [a, c, b, bp] = hasBigNumbers ? [bignumber(butcherTableau.a), bignumber(butcherTableau.c), bignumber(butcherTableau.b), bignumber(butcherTableau.bp)] : [butcherTableau.a, butcherTableau.c, butcherTableau.b, butcherTableau.bp];
|
|
114
|
+
var h = firstStep ? isForwards ? firstStep : unaryMinus(firstStep) : divide(subtract(tf, t0), steps); // define the first step size
|
|
115
|
+
var t = [t0]; // start the time array
|
|
116
|
+
var y = [y0]; // start the solution array
|
|
117
|
+
|
|
118
|
+
var deltaB = subtract(b, bp); // b - bp
|
|
119
|
+
|
|
120
|
+
var n = 0;
|
|
121
|
+
var iter = 0;
|
|
122
|
+
var ongoing = _createOngoing(isForwards);
|
|
123
|
+
var trimStep = _createTrimStep(isForwards);
|
|
124
|
+
// iterate unitil it reaches either the final time or maximum iterations
|
|
125
|
+
while (ongoing(t[n], tf)) {
|
|
126
|
+
var k = [];
|
|
127
|
+
|
|
128
|
+
// trim the time step so that it doesn't overshoot
|
|
129
|
+
h = trimStep(t[n], tf, h);
|
|
130
|
+
|
|
131
|
+
// calculate the first value of k
|
|
132
|
+
k.push(f(t[n], y[n]));
|
|
133
|
+
|
|
134
|
+
// calculate the rest of the values of k
|
|
135
|
+
for (var i = 1; i < c.length; ++i) {
|
|
136
|
+
k.push(f(add(t[n], multiply(c[i], h)), add(y[n], multiply(h, a[i], k))));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// estimate the error by comparing solutions of different orders
|
|
140
|
+
var TE = max(abs(map(multiply(deltaB, k), X => isUnit(X) ? X.value : X)));
|
|
141
|
+
if (TE < tol && tol / TE > 1 / 4) {
|
|
142
|
+
// push solution if within tol
|
|
143
|
+
t.push(add(t[n], h));
|
|
144
|
+
y.push(add(y[n], multiply(h, b, k)));
|
|
145
|
+
n++;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// estimate the delta value that will affect the step size
|
|
149
|
+
var delta = 0.84 * (tol / TE) ** (1 / 5);
|
|
150
|
+
if (smaller(delta, minDelta)) {
|
|
151
|
+
delta = minDelta;
|
|
152
|
+
} else if (larger(delta, maxDelta)) {
|
|
153
|
+
delta = maxDelta;
|
|
154
|
+
}
|
|
155
|
+
delta = hasBigNumbers ? bignumber(delta) : delta;
|
|
156
|
+
h = multiply(h, delta);
|
|
157
|
+
if (maxStep && larger(abs(h), maxStep)) {
|
|
158
|
+
h = isForwards ? maxStep : unaryMinus(maxStep);
|
|
159
|
+
} else if (minStep && smaller(abs(h), minStep)) {
|
|
160
|
+
h = isForwards ? minStep : unaryMinus(minStep);
|
|
161
|
+
}
|
|
162
|
+
iter++;
|
|
163
|
+
if (iter > maxIter) {
|
|
164
|
+
throw new Error('Maximum number of iterations reached, try changing options');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
t,
|
|
169
|
+
y
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function _rk23(f, tspan, y0, options) {
|
|
174
|
+
// Bogacki–Shampine method
|
|
175
|
+
|
|
176
|
+
// Define the butcher table
|
|
177
|
+
var a = [[], [1 / 2], [0, 3 / 4], [2 / 9, 1 / 3, 4 / 9]];
|
|
178
|
+
var c = [null, 1 / 2, 3 / 4, 1];
|
|
179
|
+
var b = [2 / 9, 1 / 3, 4 / 9, 0];
|
|
180
|
+
var bp = [7 / 24, 1 / 4, 1 / 3, 1 / 8];
|
|
181
|
+
var butcherTableau = {
|
|
182
|
+
a,
|
|
183
|
+
c,
|
|
184
|
+
b,
|
|
185
|
+
bp
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// Solve an adaptive step size rk method
|
|
189
|
+
return _rk(butcherTableau)(f, tspan, y0, options);
|
|
190
|
+
}
|
|
191
|
+
function _rk45(f, tspan, y0, options) {
|
|
192
|
+
// Dormand Prince method
|
|
193
|
+
|
|
194
|
+
// Define the butcher tableau
|
|
195
|
+
var a = [[], [1 / 5], [3 / 40, 9 / 40], [44 / 45, -56 / 15, 32 / 9], [19372 / 6561, -25360 / 2187, 64448 / 6561, -212 / 729], [9017 / 3168, -355 / 33, 46732 / 5247, 49 / 176, -5103 / 18656], [35 / 384, 0, 500 / 1113, 125 / 192, -2187 / 6784, 11 / 84]];
|
|
196
|
+
var c = [null, 1 / 5, 3 / 10, 4 / 5, 8 / 9, 1, 1];
|
|
197
|
+
var b = [35 / 384, 0, 500 / 1113, 125 / 192, -2187 / 6784, 11 / 84, 0];
|
|
198
|
+
var bp = [5179 / 57600, 0, 7571 / 16695, 393 / 640, -92097 / 339200, 187 / 2100, 1 / 40];
|
|
199
|
+
var butcherTableau = {
|
|
200
|
+
a,
|
|
201
|
+
c,
|
|
202
|
+
b,
|
|
203
|
+
bp
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// Solve an adaptive step size rk method
|
|
207
|
+
return _rk(butcherTableau)(f, tspan, y0, options);
|
|
208
|
+
}
|
|
209
|
+
function _solveODE(f, tspan, y0, opt) {
|
|
210
|
+
var method = opt.method ? opt.method : 'RK45';
|
|
211
|
+
var methods = {
|
|
212
|
+
RK23: _rk23,
|
|
213
|
+
RK45: _rk45
|
|
214
|
+
};
|
|
215
|
+
if (method.toUpperCase() in methods) {
|
|
216
|
+
var methodOptions = _objectSpread({}, opt); // clone the options object
|
|
217
|
+
delete methodOptions.method; // delete the method as it won't be needed
|
|
218
|
+
return methods[method.toUpperCase()](f, tspan, y0, methodOptions);
|
|
219
|
+
} else {
|
|
220
|
+
// throw an error indicating there is no such method
|
|
221
|
+
var methodsWithQuotes = Object.keys(methods).map(x => "\"".concat(x, "\""));
|
|
222
|
+
// generates a string of methods like: "BDF", "RK23" and "RK45"
|
|
223
|
+
var availableMethodsString = "".concat(methodsWithQuotes.slice(0, -1).join(', '), " and ").concat(methodsWithQuotes.slice(-1));
|
|
224
|
+
throw new Error("Unavailable method \"".concat(method, "\". Available methods are ").concat(availableMethodsString));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function _createOngoing(isForwards) {
|
|
228
|
+
// returns the correct function to test if it's still iterating
|
|
229
|
+
return isForwards ? smaller : larger;
|
|
230
|
+
}
|
|
231
|
+
function _createTrimStep(isForwards) {
|
|
232
|
+
var outOfBounds = isForwards ? larger : smaller;
|
|
233
|
+
return function (t, tf, h) {
|
|
234
|
+
var next = add(t, h);
|
|
235
|
+
return outOfBounds(next, tf) ? subtract(tf, t) : h;
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function isNumOrBig(x) {
|
|
239
|
+
// checks if it's a number or bignumber
|
|
240
|
+
return isBigNumber(x) || isNumber(x);
|
|
241
|
+
}
|
|
242
|
+
function _matrixSolveODE(f, T, y0, options) {
|
|
243
|
+
// receives matrices and returns matrices
|
|
244
|
+
var sol = _solveODE(f, T.toArray(), y0.toArray(), options);
|
|
245
|
+
return {
|
|
246
|
+
t: matrix(sol.t),
|
|
247
|
+
y: matrix(sol.y)
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
return typed('solveODE', {
|
|
251
|
+
'function, Array, Array, Object': _solveODE,
|
|
252
|
+
'function, Matrix, Matrix, Object': _matrixSolveODE,
|
|
253
|
+
'function, Array, Array': (f, T, y0) => _solveODE(f, T, y0, {}),
|
|
254
|
+
'function, Matrix, Matrix': (f, T, y0) => _matrixSolveODE(f, T, y0, {}),
|
|
255
|
+
'function, Array, number | BigNumber | Unit': (f, T, y0) => {
|
|
256
|
+
var sol = _solveODE(f, T, [y0], {});
|
|
257
|
+
return {
|
|
258
|
+
t: sol.t,
|
|
259
|
+
y: sol.y.map(Y => Y[0])
|
|
260
|
+
};
|
|
261
|
+
},
|
|
262
|
+
'function, Matrix, number | BigNumber | Unit': (f, T, y0) => {
|
|
263
|
+
var sol = _solveODE(f, T.toArray(), [y0], {});
|
|
264
|
+
return {
|
|
265
|
+
t: matrix(sol.t),
|
|
266
|
+
y: matrix(sol.y.map(Y => Y[0]))
|
|
267
|
+
};
|
|
268
|
+
},
|
|
269
|
+
'function, Array, number | BigNumber | Unit, Object': (f, T, y0, options) => {
|
|
270
|
+
var sol = _solveODE(f, T, [y0], options);
|
|
271
|
+
return {
|
|
272
|
+
t: sol.t,
|
|
273
|
+
y: sol.y.map(Y => Y[0])
|
|
274
|
+
};
|
|
275
|
+
},
|
|
276
|
+
'function, Matrix, number | BigNumber | Unit, Object': (f, T, y0, options) => {
|
|
277
|
+
var sol = _solveODE(f, T.toArray(), [y0], options);
|
|
278
|
+
return {
|
|
279
|
+
t: matrix(sol.t),
|
|
280
|
+
y: matrix(sol.y.map(Y => Y[0]))
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
});
|