mathjs 11.8.1 → 11.9.0
Sign up to get free protection for your applications and to get access to all the features.
- package/HISTORY.md +25 -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 +6 -6
- package/types/index.d.ts +194 -50
@@ -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
|
+
});
|