mathjs 11.8.1 → 11.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. package/HISTORY.md +25 -0
  2. package/lib/browser/math.js +1 -1
  3. package/lib/browser/math.js.LICENSE.txt +2 -2
  4. package/lib/browser/math.js.map +1 -1
  5. package/lib/cjs/entry/dependenciesAny/dependenciesFreqz.generated.js +28 -0
  6. package/lib/cjs/entry/dependenciesAny/dependenciesRange.generated.js +4 -0
  7. package/lib/cjs/entry/dependenciesAny/dependenciesRangeTransform.generated.js +4 -0
  8. package/lib/cjs/entry/dependenciesAny/dependenciesSolveODE.generated.js +46 -0
  9. package/lib/cjs/entry/dependenciesAny/dependenciesZpk2tf.generated.js +26 -0
  10. package/lib/cjs/entry/dependenciesAny.generated.js +21 -0
  11. package/lib/cjs/entry/dependenciesNumber/dependenciesRange.generated.js +4 -0
  12. package/lib/cjs/entry/dependenciesNumber/dependenciesRangeTransform.generated.js +4 -0
  13. package/lib/cjs/entry/impureFunctionsAny.generated.js +35 -30
  14. package/lib/cjs/entry/impureFunctionsNumber.generated.js +2 -0
  15. package/lib/cjs/entry/pureFunctionsAny.generated.js +82 -45
  16. package/lib/cjs/entry/pureFunctionsNumber.generated.js +2 -0
  17. package/lib/cjs/expression/embeddedDocs/core/typed.js +1 -1
  18. package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +11 -3
  19. package/lib/cjs/expression/embeddedDocs/function/{matrix → algebra}/lyap.js +2 -2
  20. package/lib/cjs/expression/embeddedDocs/function/algebra/polynomialRoot.js +1 -1
  21. package/lib/cjs/expression/embeddedDocs/function/{matrix → algebra}/schur.js +2 -2
  22. package/lib/cjs/expression/embeddedDocs/function/algebra/simplifyConstant.js +1 -1
  23. package/lib/cjs/expression/embeddedDocs/function/{matrix → algebra}/sylvester.js +2 -2
  24. package/lib/cjs/expression/embeddedDocs/function/arithmetic/invmod.js +1 -1
  25. package/lib/cjs/expression/embeddedDocs/function/expression/evaluate.js +2 -2
  26. package/lib/cjs/expression/embeddedDocs/function/matrix/diff.js +1 -1
  27. package/lib/cjs/expression/embeddedDocs/function/matrix/range.js +1 -1
  28. package/lib/cjs/expression/embeddedDocs/function/numeric/solveODE.js +15 -0
  29. package/lib/cjs/expression/embeddedDocs/function/signal/freqz.js +15 -0
  30. package/lib/cjs/expression/embeddedDocs/function/signal/zpk2tf.js +15 -0
  31. package/lib/cjs/expression/embeddedDocs/function/utils/numeric.js +1 -1
  32. package/lib/cjs/expression/transform/range.transform.js +7 -3
  33. package/lib/cjs/factoriesAny.js +21 -0
  34. package/lib/cjs/function/algebra/simplify.js +3 -0
  35. package/lib/cjs/function/matrix/range.js +34 -110
  36. package/lib/cjs/function/numeric/solveODE.js +315 -0
  37. package/lib/cjs/function/signal/freqz.js +117 -0
  38. package/lib/cjs/function/signal/zpk2tf.js +95 -0
  39. package/lib/cjs/header.js +2 -2
  40. package/lib/cjs/type/unit/Unit.js +15 -13
  41. package/lib/cjs/version.js +1 -1
  42. package/lib/esm/entry/dependenciesAny/dependenciesFreqz.generated.js +20 -0
  43. package/lib/esm/entry/dependenciesAny/dependenciesRange.generated.js +4 -0
  44. package/lib/esm/entry/dependenciesAny/dependenciesRangeTransform.generated.js +4 -0
  45. package/lib/esm/entry/dependenciesAny/dependenciesSolveODE.generated.js +38 -0
  46. package/lib/esm/entry/dependenciesAny/dependenciesZpk2tf.generated.js +18 -0
  47. package/lib/esm/entry/dependenciesAny.generated.js +3 -0
  48. package/lib/esm/entry/dependenciesNumber/dependenciesRange.generated.js +4 -0
  49. package/lib/esm/entry/dependenciesNumber/dependenciesRangeTransform.generated.js +4 -0
  50. package/lib/esm/entry/impureFunctionsAny.generated.js +34 -29
  51. package/lib/esm/entry/impureFunctionsNumber.generated.js +2 -0
  52. package/lib/esm/entry/pureFunctionsAny.generated.js +70 -36
  53. package/lib/esm/entry/pureFunctionsNumber.generated.js +2 -0
  54. package/lib/esm/expression/embeddedDocs/core/typed.js +1 -1
  55. package/lib/esm/expression/embeddedDocs/embeddedDocs.js +11 -3
  56. package/lib/esm/expression/embeddedDocs/function/{matrix → algebra}/lyap.js +2 -2
  57. package/lib/esm/expression/embeddedDocs/function/algebra/polynomialRoot.js +1 -1
  58. package/lib/esm/expression/embeddedDocs/function/{matrix → algebra}/schur.js +2 -2
  59. package/lib/esm/expression/embeddedDocs/function/algebra/simplifyConstant.js +1 -1
  60. package/lib/esm/expression/embeddedDocs/function/{matrix → algebra}/sylvester.js +2 -2
  61. package/lib/esm/expression/embeddedDocs/function/arithmetic/invmod.js +1 -1
  62. package/lib/esm/expression/embeddedDocs/function/expression/evaluate.js +2 -2
  63. package/lib/esm/expression/embeddedDocs/function/matrix/diff.js +1 -1
  64. package/lib/esm/expression/embeddedDocs/function/matrix/range.js +1 -1
  65. package/lib/esm/expression/embeddedDocs/function/numeric/solveODE.js +8 -0
  66. package/lib/esm/expression/embeddedDocs/function/signal/freqz.js +8 -0
  67. package/lib/esm/expression/embeddedDocs/function/signal/zpk2tf.js +8 -0
  68. package/lib/esm/expression/embeddedDocs/function/utils/numeric.js +1 -1
  69. package/lib/esm/expression/transform/range.transform.js +7 -3
  70. package/lib/esm/factoriesAny.js +3 -0
  71. package/lib/esm/function/algebra/simplify.js +3 -0
  72. package/lib/esm/function/matrix/range.js +34 -110
  73. package/lib/esm/function/numeric/solveODE.js +284 -0
  74. package/lib/esm/function/signal/freqz.js +115 -0
  75. package/lib/esm/function/signal/zpk2tf.js +82 -0
  76. package/lib/esm/type/unit/Unit.js +15 -13
  77. package/lib/esm/version.js +1 -1
  78. package/package.json +6 -6
  79. 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(" + 4 + ")")'],
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: ['diff([1, 2, 4, 7, 0])', 'diff([1, 2, 4, 7, 0], 0)', 'diff(matrix([1, 2, 4, 7, 0]))', 'diff([[1, 2], [3, 4]])', 'diff([[1, 2], [3, 4]], 0)', 'diff([[1, 2], [3, 4]], 1)', 'diff([[1, 2], [3, 4]], bignumber(1))', 'diff(matrix([[1, 2], [3, 4]]), 1)', 'diff([[1, 2], matrix([3, 4])], 1)'],
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
  /**
@@ -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(_rangeEx(start, end, 1));
69
+ return _out(_range(start, end, 1, false));
67
70
  },
68
71
  'number, number, number': function numberNumberNumber(start, end, step) {
69
- return _out(_rangeEx(start, end, step));
72
+ return _out(_range(start, end, step, false));
70
73
  },
71
74
  'number, number, boolean': function numberNumberBoolean(start, end, includeEnd) {
72
- return includeEnd ? _out(_rangeInc(start, end, 1)) : _out(_rangeEx(start, end, 1));
75
+ return _out(_range(start, end, 1, includeEnd));
73
76
  },
74
77
  'number, number, number, boolean': function numberNumberNumberBoolean(start, end, step, includeEnd) {
75
- return includeEnd ? _out(_rangeInc(start, end, step)) : _out(_rangeEx(start, end, step));
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(_bigRangeEx(start, end, new BigNumber(1)));
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(_bigRangeEx(start, end, step));
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 includeEnd ? _out(_bigRangeInc(start, end, new BigNumber(1))) : _out(_bigRangeEx(start, end, new BigNumber(1)));
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 includeEnd ? _out(_bigRangeInc(start, end, step)) : _out(_bigRangeEx(start, end, step));
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
- fn = includeEnd ? _bigRangeInc : _bigRangeEx;
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
- fn = includeEnd ? _rangeInc : _rangeEx;
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 big numbers. End is included
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 _bigRangeInc(start, end, step) {
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
- if (step.gt(zero)) {
205
- while (smallerEq(x, end)) {
206
- array.push(x);
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
+ });