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
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.createSolveODE = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
11
|
+
var _is = require("../../utils/is.js");
|
|
12
|
+
var _factory = require("../../utils/factory.js");
|
|
13
|
+
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; }
|
|
14
|
+
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) { (0, _defineProperty2["default"])(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; }
|
|
15
|
+
var name = 'solveODE';
|
|
16
|
+
var dependencies = ['typed', 'add', 'subtract', 'multiply', 'divide', 'max', 'map', 'abs', 'isPositive', 'isNegative', 'larger', 'smaller', 'matrix', 'bignumber', 'unaryMinus'];
|
|
17
|
+
var createSolveODE = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
|
|
18
|
+
var typed = _ref.typed,
|
|
19
|
+
add = _ref.add,
|
|
20
|
+
subtract = _ref.subtract,
|
|
21
|
+
multiply = _ref.multiply,
|
|
22
|
+
divide = _ref.divide,
|
|
23
|
+
max = _ref.max,
|
|
24
|
+
map = _ref.map,
|
|
25
|
+
abs = _ref.abs,
|
|
26
|
+
isPositive = _ref.isPositive,
|
|
27
|
+
isNegative = _ref.isNegative,
|
|
28
|
+
larger = _ref.larger,
|
|
29
|
+
smaller = _ref.smaller,
|
|
30
|
+
matrix = _ref.matrix,
|
|
31
|
+
bignumber = _ref.bignumber,
|
|
32
|
+
unaryMinus = _ref.unaryMinus;
|
|
33
|
+
/**
|
|
34
|
+
* Numerical Integration of Ordinary Differential Equations
|
|
35
|
+
*
|
|
36
|
+
* Two variable step methods are provided:
|
|
37
|
+
* - "RK23": Bogacki–Shampine method
|
|
38
|
+
* - "RK45": Dormand-Prince method RK5(4)7M (default)
|
|
39
|
+
*
|
|
40
|
+
* The arguments are expected as follows.
|
|
41
|
+
*
|
|
42
|
+
* - `func` should be the forcing function `f(t, y)`
|
|
43
|
+
* - `tspan` should be a vector of two numbers or units `[tStart, tEnd]`
|
|
44
|
+
* - `y0` the initial state values, should be a scalar or a flat array
|
|
45
|
+
* - `options` should be an object with the following information:
|
|
46
|
+
* - `method` ('RK45'): ['RK23', 'RK45']
|
|
47
|
+
* - `tol` (1e-3): Numeric tolerance of the method, the solver keeps the error estimates less than this value
|
|
48
|
+
* - `firstStep`: Initial step size
|
|
49
|
+
* - `minStep`: minimum step size of the method
|
|
50
|
+
* - `maxStep`: maximum step size of the method
|
|
51
|
+
* - `minDelta` (0.2): minimum ratio of change for the step
|
|
52
|
+
* - `maxDelta` (5): maximum ratio of change for the step
|
|
53
|
+
* - `maxIter` (1e4): maximum number of iterations
|
|
54
|
+
*
|
|
55
|
+
* 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`:
|
|
56
|
+
* - `t` an array of size `[n]`
|
|
57
|
+
* - `y` the states array can be in two ways
|
|
58
|
+
* - **if `y0` is a scalar:** returns an array-like of size `[n]`
|
|
59
|
+
* - **if `y0` is a flat array-like of size [m]:** returns an array like of size `[n, m]`
|
|
60
|
+
*
|
|
61
|
+
* Syntax:
|
|
62
|
+
*
|
|
63
|
+
* math.solveODE(func, tspan, y0)
|
|
64
|
+
* math.solveODE(func, tspan, y0, options)
|
|
65
|
+
*
|
|
66
|
+
* Examples:
|
|
67
|
+
*
|
|
68
|
+
* function func(t, y) {return y}
|
|
69
|
+
* const tspan = [0, 4]
|
|
70
|
+
* const y0 = 1
|
|
71
|
+
* math.solveODE(func, tspan, y0)
|
|
72
|
+
* math.solveODE(func, tspan, [1, 2])
|
|
73
|
+
* math.solveODE(func, tspan, y0, { method:"RK23", maxStep:0.1 })
|
|
74
|
+
*
|
|
75
|
+
* See also:
|
|
76
|
+
*
|
|
77
|
+
* derivative, simplifyCore
|
|
78
|
+
*
|
|
79
|
+
* @param {function} func The forcing function f(t,y)
|
|
80
|
+
* @param {Array | Matrix} tspan The time span
|
|
81
|
+
* @param {number | BigNumber | Unit | Array | Matrix} y0 The initial value
|
|
82
|
+
* @param {Object} [options] Optional configuration options
|
|
83
|
+
* @return {Object} Return an object with t and y values as arrays
|
|
84
|
+
*/
|
|
85
|
+
|
|
86
|
+
function _rk(butcherTableau) {
|
|
87
|
+
// generates an adaptive runge kutta method from it's butcher tableau
|
|
88
|
+
|
|
89
|
+
return function (f, tspan, y0, options) {
|
|
90
|
+
// adaptive runge kutta methods
|
|
91
|
+
var wrongTSpan = !(tspan.length === 2 && (tspan.every(isNumOrBig) || tspan.every(_is.isUnit)));
|
|
92
|
+
if (wrongTSpan) {
|
|
93
|
+
throw new Error('"tspan" must be an Array of two numeric values or two units [tStart, tEnd]');
|
|
94
|
+
}
|
|
95
|
+
var t0 = tspan[0]; // initial time
|
|
96
|
+
var tf = tspan[1]; // final time
|
|
97
|
+
var isForwards = larger(tf, t0);
|
|
98
|
+
var firstStep = options.firstStep;
|
|
99
|
+
if (firstStep !== undefined && !isPositive(firstStep)) {
|
|
100
|
+
throw new Error('"firstStep" must be positive');
|
|
101
|
+
}
|
|
102
|
+
var maxStep = options.maxStep;
|
|
103
|
+
if (maxStep !== undefined && !isPositive(maxStep)) {
|
|
104
|
+
throw new Error('"maxStep" must be positive');
|
|
105
|
+
}
|
|
106
|
+
var minStep = options.minStep;
|
|
107
|
+
if (minStep && isNegative(minStep)) {
|
|
108
|
+
throw new Error('"minStep" must be positive or zero');
|
|
109
|
+
}
|
|
110
|
+
var timeVars = [t0, tf, firstStep, minStep, maxStep].filter(function (x) {
|
|
111
|
+
return x !== undefined;
|
|
112
|
+
});
|
|
113
|
+
if (!(timeVars.every(isNumOrBig) || timeVars.every(_is.isUnit))) {
|
|
114
|
+
throw new Error('Inconsistent type of "t" dependant variables');
|
|
115
|
+
}
|
|
116
|
+
var steps = 1; // divide time in this number of steps
|
|
117
|
+
var tol = options.tol ? options.tol : 1e-4; // define a tolerance (must be an option)
|
|
118
|
+
var minDelta = options.minDelta ? options.minDelta : 0.2;
|
|
119
|
+
var maxDelta = options.maxDelta ? options.maxDelta : 5;
|
|
120
|
+
var maxIter = options.maxIter ? options.maxIter : 10000; // stop inifite evaluation if something goes wrong
|
|
121
|
+
var hasBigNumbers = [t0, tf].concat((0, _toConsumableArray2["default"])(y0), [maxStep, minStep]).some(_is.isBigNumber);
|
|
122
|
+
var _ref2 = hasBigNumbers ? [bignumber(butcherTableau.a), bignumber(butcherTableau.c), bignumber(butcherTableau.b), bignumber(butcherTableau.bp)] : [butcherTableau.a, butcherTableau.c, butcherTableau.b, butcherTableau.bp],
|
|
123
|
+
_ref3 = (0, _slicedToArray2["default"])(_ref2, 4),
|
|
124
|
+
a = _ref3[0],
|
|
125
|
+
c = _ref3[1],
|
|
126
|
+
b = _ref3[2],
|
|
127
|
+
bp = _ref3[3];
|
|
128
|
+
var h = firstStep ? isForwards ? firstStep : unaryMinus(firstStep) : divide(subtract(tf, t0), steps); // define the first step size
|
|
129
|
+
var t = [t0]; // start the time array
|
|
130
|
+
var y = [y0]; // start the solution array
|
|
131
|
+
|
|
132
|
+
var deltaB = subtract(b, bp); // b - bp
|
|
133
|
+
|
|
134
|
+
var n = 0;
|
|
135
|
+
var iter = 0;
|
|
136
|
+
var ongoing = _createOngoing(isForwards);
|
|
137
|
+
var trimStep = _createTrimStep(isForwards);
|
|
138
|
+
// iterate unitil it reaches either the final time or maximum iterations
|
|
139
|
+
while (ongoing(t[n], tf)) {
|
|
140
|
+
var k = [];
|
|
141
|
+
|
|
142
|
+
// trim the time step so that it doesn't overshoot
|
|
143
|
+
h = trimStep(t[n], tf, h);
|
|
144
|
+
|
|
145
|
+
// calculate the first value of k
|
|
146
|
+
k.push(f(t[n], y[n]));
|
|
147
|
+
|
|
148
|
+
// calculate the rest of the values of k
|
|
149
|
+
for (var i = 1; i < c.length; ++i) {
|
|
150
|
+
k.push(f(add(t[n], multiply(c[i], h)), add(y[n], multiply(h, a[i], k))));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// estimate the error by comparing solutions of different orders
|
|
154
|
+
var TE = max(abs(map(multiply(deltaB, k), function (X) {
|
|
155
|
+
return (0, _is.isUnit)(X) ? X.value : X;
|
|
156
|
+
})));
|
|
157
|
+
if (TE < tol && tol / TE > 1 / 4) {
|
|
158
|
+
// push solution if within tol
|
|
159
|
+
t.push(add(t[n], h));
|
|
160
|
+
y.push(add(y[n], multiply(h, b, k)));
|
|
161
|
+
n++;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// estimate the delta value that will affect the step size
|
|
165
|
+
var delta = 0.84 * Math.pow(tol / TE, 1 / 5);
|
|
166
|
+
if (smaller(delta, minDelta)) {
|
|
167
|
+
delta = minDelta;
|
|
168
|
+
} else if (larger(delta, maxDelta)) {
|
|
169
|
+
delta = maxDelta;
|
|
170
|
+
}
|
|
171
|
+
delta = hasBigNumbers ? bignumber(delta) : delta;
|
|
172
|
+
h = multiply(h, delta);
|
|
173
|
+
if (maxStep && larger(abs(h), maxStep)) {
|
|
174
|
+
h = isForwards ? maxStep : unaryMinus(maxStep);
|
|
175
|
+
} else if (minStep && smaller(abs(h), minStep)) {
|
|
176
|
+
h = isForwards ? minStep : unaryMinus(minStep);
|
|
177
|
+
}
|
|
178
|
+
iter++;
|
|
179
|
+
if (iter > maxIter) {
|
|
180
|
+
throw new Error('Maximum number of iterations reached, try changing options');
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
t: t,
|
|
185
|
+
y: y
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function _rk23(f, tspan, y0, options) {
|
|
190
|
+
// Bogacki–Shampine method
|
|
191
|
+
|
|
192
|
+
// Define the butcher table
|
|
193
|
+
var a = [[], [1 / 2], [0, 3 / 4], [2 / 9, 1 / 3, 4 / 9]];
|
|
194
|
+
var c = [null, 1 / 2, 3 / 4, 1];
|
|
195
|
+
var b = [2 / 9, 1 / 3, 4 / 9, 0];
|
|
196
|
+
var bp = [7 / 24, 1 / 4, 1 / 3, 1 / 8];
|
|
197
|
+
var butcherTableau = {
|
|
198
|
+
a: a,
|
|
199
|
+
c: c,
|
|
200
|
+
b: b,
|
|
201
|
+
bp: bp
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// Solve an adaptive step size rk method
|
|
205
|
+
return _rk(butcherTableau)(f, tspan, y0, options);
|
|
206
|
+
}
|
|
207
|
+
function _rk45(f, tspan, y0, options) {
|
|
208
|
+
// Dormand Prince method
|
|
209
|
+
|
|
210
|
+
// Define the butcher tableau
|
|
211
|
+
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]];
|
|
212
|
+
var c = [null, 1 / 5, 3 / 10, 4 / 5, 8 / 9, 1, 1];
|
|
213
|
+
var b = [35 / 384, 0, 500 / 1113, 125 / 192, -2187 / 6784, 11 / 84, 0];
|
|
214
|
+
var bp = [5179 / 57600, 0, 7571 / 16695, 393 / 640, -92097 / 339200, 187 / 2100, 1 / 40];
|
|
215
|
+
var butcherTableau = {
|
|
216
|
+
a: a,
|
|
217
|
+
c: c,
|
|
218
|
+
b: b,
|
|
219
|
+
bp: bp
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// Solve an adaptive step size rk method
|
|
223
|
+
return _rk(butcherTableau)(f, tspan, y0, options);
|
|
224
|
+
}
|
|
225
|
+
function _solveODE(f, tspan, y0, opt) {
|
|
226
|
+
var method = opt.method ? opt.method : 'RK45';
|
|
227
|
+
var methods = {
|
|
228
|
+
RK23: _rk23,
|
|
229
|
+
RK45: _rk45
|
|
230
|
+
};
|
|
231
|
+
if (method.toUpperCase() in methods) {
|
|
232
|
+
var methodOptions = _objectSpread({}, opt); // clone the options object
|
|
233
|
+
delete methodOptions.method; // delete the method as it won't be needed
|
|
234
|
+
return methods[method.toUpperCase()](f, tspan, y0, methodOptions);
|
|
235
|
+
} else {
|
|
236
|
+
// throw an error indicating there is no such method
|
|
237
|
+
var methodsWithQuotes = Object.keys(methods).map(function (x) {
|
|
238
|
+
return "\"".concat(x, "\"");
|
|
239
|
+
});
|
|
240
|
+
// generates a string of methods like: "BDF", "RK23" and "RK45"
|
|
241
|
+
var availableMethodsString = "".concat(methodsWithQuotes.slice(0, -1).join(', '), " and ").concat(methodsWithQuotes.slice(-1));
|
|
242
|
+
throw new Error("Unavailable method \"".concat(method, "\". Available methods are ").concat(availableMethodsString));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function _createOngoing(isForwards) {
|
|
246
|
+
// returns the correct function to test if it's still iterating
|
|
247
|
+
return isForwards ? smaller : larger;
|
|
248
|
+
}
|
|
249
|
+
function _createTrimStep(isForwards) {
|
|
250
|
+
var outOfBounds = isForwards ? larger : smaller;
|
|
251
|
+
return function (t, tf, h) {
|
|
252
|
+
var next = add(t, h);
|
|
253
|
+
return outOfBounds(next, tf) ? subtract(tf, t) : h;
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function isNumOrBig(x) {
|
|
257
|
+
// checks if it's a number or bignumber
|
|
258
|
+
return (0, _is.isBigNumber)(x) || (0, _is.isNumber)(x);
|
|
259
|
+
}
|
|
260
|
+
function _matrixSolveODE(f, T, y0, options) {
|
|
261
|
+
// receives matrices and returns matrices
|
|
262
|
+
var sol = _solveODE(f, T.toArray(), y0.toArray(), options);
|
|
263
|
+
return {
|
|
264
|
+
t: matrix(sol.t),
|
|
265
|
+
y: matrix(sol.y)
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
return typed('solveODE', {
|
|
269
|
+
'function, Array, Array, Object': _solveODE,
|
|
270
|
+
'function, Matrix, Matrix, Object': _matrixSolveODE,
|
|
271
|
+
'function, Array, Array': function functionArrayArray(f, T, y0) {
|
|
272
|
+
return _solveODE(f, T, y0, {});
|
|
273
|
+
},
|
|
274
|
+
'function, Matrix, Matrix': function functionMatrixMatrix(f, T, y0) {
|
|
275
|
+
return _matrixSolveODE(f, T, y0, {});
|
|
276
|
+
},
|
|
277
|
+
'function, Array, number | BigNumber | Unit': function functionArrayNumberBigNumberUnit(f, T, y0) {
|
|
278
|
+
var sol = _solveODE(f, T, [y0], {});
|
|
279
|
+
return {
|
|
280
|
+
t: sol.t,
|
|
281
|
+
y: sol.y.map(function (Y) {
|
|
282
|
+
return Y[0];
|
|
283
|
+
})
|
|
284
|
+
};
|
|
285
|
+
},
|
|
286
|
+
'function, Matrix, number | BigNumber | Unit': function functionMatrixNumberBigNumberUnit(f, T, y0) {
|
|
287
|
+
var sol = _solveODE(f, T.toArray(), [y0], {});
|
|
288
|
+
return {
|
|
289
|
+
t: matrix(sol.t),
|
|
290
|
+
y: matrix(sol.y.map(function (Y) {
|
|
291
|
+
return Y[0];
|
|
292
|
+
}))
|
|
293
|
+
};
|
|
294
|
+
},
|
|
295
|
+
'function, Array, number | BigNumber | Unit, Object': function functionArrayNumberBigNumberUnitObject(f, T, y0, options) {
|
|
296
|
+
var sol = _solveODE(f, T, [y0], options);
|
|
297
|
+
return {
|
|
298
|
+
t: sol.t,
|
|
299
|
+
y: sol.y.map(function (Y) {
|
|
300
|
+
return Y[0];
|
|
301
|
+
})
|
|
302
|
+
};
|
|
303
|
+
},
|
|
304
|
+
'function, Matrix, number | BigNumber | Unit, Object': function functionMatrixNumberBigNumberUnitObject(f, T, y0, options) {
|
|
305
|
+
var sol = _solveODE(f, T.toArray(), [y0], options);
|
|
306
|
+
return {
|
|
307
|
+
t: matrix(sol.t),
|
|
308
|
+
y: matrix(sol.y.map(function (Y) {
|
|
309
|
+
return Y[0];
|
|
310
|
+
}))
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
exports.createSolveODE = createSolveODE;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createFreqz = void 0;
|
|
7
|
+
var _factory = require("../../utils/factory.js");
|
|
8
|
+
var name = 'freqz';
|
|
9
|
+
var dependencies = ['typed', 'add', 'multiply', 'Complex', 'divide', 'matrix'];
|
|
10
|
+
var createFreqz = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
|
|
11
|
+
var typed = _ref.typed,
|
|
12
|
+
add = _ref.add,
|
|
13
|
+
multiply = _ref.multiply,
|
|
14
|
+
Complex = _ref.Complex,
|
|
15
|
+
divide = _ref.divide,
|
|
16
|
+
matrix = _ref.matrix;
|
|
17
|
+
/**
|
|
18
|
+
* Calculates the frequency response of a filter given its numerator and denominator coefficients.
|
|
19
|
+
*
|
|
20
|
+
* Syntax:
|
|
21
|
+
* math.freqz(b, a)
|
|
22
|
+
* math.freqz(b, a, w)
|
|
23
|
+
*
|
|
24
|
+
* Examples:
|
|
25
|
+
* math.freqz([1, 2], [1, 2, 3], 4) // returns { h: [0.5 + 0i, 0.4768589245763655 + 0.2861153547458193i, 0.25000000000000006 + 0.75i, -0.770976571635189 + 0.4625859429811135i], w: [0, 0.7853981633974483, 1.5707963267948966, 2.356194490192345 ] }
|
|
26
|
+
* math.freqz([1, 2], [1, 2, 3], [0, 1]) // returns { h: [0.5 + 0i, 0.45436781 + 0.38598051i], w: [0, 1] }
|
|
27
|
+
*
|
|
28
|
+
* See also:
|
|
29
|
+
* zpk2tf
|
|
30
|
+
*
|
|
31
|
+
* @param {Array.<number>} b The numerator coefficients of the filter.
|
|
32
|
+
* @param {Array.<number>} a The denominator coefficients of the filter.
|
|
33
|
+
* @param {Array.<number>} [w] A vector of frequencies (in radians/sample) at which the frequency response is to be computed or the number of points to compute (if a number is not provided, the default is 512 points)
|
|
34
|
+
* @returns {Object} An object with two properties: h, a vector containing the complex frequency response, and w, a vector containing the normalized frequencies (in radians/sample) at which the response was computed.
|
|
35
|
+
*
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
38
|
+
return typed(name, {
|
|
39
|
+
'Array, Array': function ArrayArray(b, a) {
|
|
40
|
+
var w = createBins(512);
|
|
41
|
+
return _freqz(b, a, w);
|
|
42
|
+
},
|
|
43
|
+
'Array, Array, Array': function ArrayArrayArray(b, a, w) {
|
|
44
|
+
return _freqz(b, a, w);
|
|
45
|
+
},
|
|
46
|
+
'Array, Array, number': function ArrayArrayNumber(b, a, w) {
|
|
47
|
+
if (w < 0) {
|
|
48
|
+
throw new Error('w must be a positive number');
|
|
49
|
+
}
|
|
50
|
+
var w2 = createBins(w);
|
|
51
|
+
return _freqz(b, a, w2);
|
|
52
|
+
},
|
|
53
|
+
'Matrix, Matrix': function MatrixMatrix(b, a) {
|
|
54
|
+
// console.log('here')
|
|
55
|
+
var _w = createBins(512);
|
|
56
|
+
var _freqz2 = _freqz(b.valueOf(), a.valueOf(), _w),
|
|
57
|
+
w = _freqz2.w,
|
|
58
|
+
h = _freqz2.h;
|
|
59
|
+
return {
|
|
60
|
+
w: matrix(w),
|
|
61
|
+
h: matrix(h)
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
'Matrix, Matrix, Matrix': function MatrixMatrixMatrix(b, a, w) {
|
|
65
|
+
var _freqz3 = _freqz(b.valueOf(), a.valueOf(), w.valueOf()),
|
|
66
|
+
h = _freqz3.h;
|
|
67
|
+
return {
|
|
68
|
+
h: matrix(h),
|
|
69
|
+
w: matrix(w)
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
'Matrix, Matrix, number': function MatrixMatrixNumber(b, a, w) {
|
|
73
|
+
if (w < 0) {
|
|
74
|
+
throw new Error('w must be a positive number');
|
|
75
|
+
}
|
|
76
|
+
var _w = createBins(w);
|
|
77
|
+
var _freqz4 = _freqz(b.valueOf(), a.valueOf(), _w),
|
|
78
|
+
h = _freqz4.h;
|
|
79
|
+
return {
|
|
80
|
+
h: matrix(h),
|
|
81
|
+
w: matrix(_w)
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
function _freqz(b, a, w) {
|
|
86
|
+
var num = [];
|
|
87
|
+
var den = [];
|
|
88
|
+
for (var i = 0; i < w.length; i++) {
|
|
89
|
+
var sumNum = Complex(0, 0);
|
|
90
|
+
var sumDen = Complex(0, 0);
|
|
91
|
+
for (var j = 0; j < b.length; j++) {
|
|
92
|
+
sumNum = add(sumNum, multiply(b[j], Complex(Math.cos(-j * w[i]), Math.sin(-j * w[i]))));
|
|
93
|
+
}
|
|
94
|
+
for (var _j = 0; _j < a.length; _j++) {
|
|
95
|
+
sumDen = add(sumDen, multiply(a[_j], Complex(Math.cos(-_j * w[i]), Math.sin(-_j * w[i]))));
|
|
96
|
+
}
|
|
97
|
+
num.push(sumNum);
|
|
98
|
+
den.push(sumDen);
|
|
99
|
+
}
|
|
100
|
+
var h = [];
|
|
101
|
+
for (var _i = 0; _i < num.length; _i++) {
|
|
102
|
+
h.push(divide(num[_i], den[_i]));
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
h: h,
|
|
106
|
+
w: w
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function createBins(n) {
|
|
110
|
+
var bins = [];
|
|
111
|
+
for (var i = 0; i < n; i++) {
|
|
112
|
+
bins.push(i / n * Math.PI);
|
|
113
|
+
}
|
|
114
|
+
return bins;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
exports.createFreqz = createFreqz;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createZpk2tf = void 0;
|
|
7
|
+
var _factory = require("../../utils/factory.js");
|
|
8
|
+
var name = 'zpk2tf';
|
|
9
|
+
var dependencies = ['typed', 'add', 'multiply', 'Complex', 'number'];
|
|
10
|
+
var createZpk2tf = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
|
|
11
|
+
var typed = _ref.typed,
|
|
12
|
+
add = _ref.add,
|
|
13
|
+
multiply = _ref.multiply,
|
|
14
|
+
Complex = _ref.Complex,
|
|
15
|
+
number = _ref.number;
|
|
16
|
+
/**
|
|
17
|
+
* Compute the transfer function of a zero-pole-gain model.
|
|
18
|
+
*
|
|
19
|
+
* Syntax:
|
|
20
|
+
* math.zpk2tf(z, p, k)
|
|
21
|
+
*
|
|
22
|
+
* Examples:
|
|
23
|
+
* math.zpk2tf([1, 2], [-1, -2], 1) // returns [[1, -3, 2], [1, 3, 2]]
|
|
24
|
+
*
|
|
25
|
+
* See also:
|
|
26
|
+
* freqz
|
|
27
|
+
*
|
|
28
|
+
* @param {Array} z Array of zeros values
|
|
29
|
+
* @param {Array} p Array of poles values
|
|
30
|
+
* @param {number} k Gain value
|
|
31
|
+
* @return {Array} Two dimensional array containing the numerator (first row) and denominator (second row) polynomials
|
|
32
|
+
*
|
|
33
|
+
*/
|
|
34
|
+
return typed(name, {
|
|
35
|
+
'Array,Array,number': function ArrayArrayNumber(z, p, k) {
|
|
36
|
+
return _zpk2tf(z, p, k);
|
|
37
|
+
},
|
|
38
|
+
'Array,Array': function ArrayArray(z, p) {
|
|
39
|
+
return _zpk2tf(z, p, 1);
|
|
40
|
+
},
|
|
41
|
+
'Matrix,Matrix,number': function MatrixMatrixNumber(z, p, k) {
|
|
42
|
+
return _zpk2tf(z.valueOf(), p.valueOf(), k);
|
|
43
|
+
},
|
|
44
|
+
'Matrix,Matrix': function MatrixMatrix(z, p) {
|
|
45
|
+
return _zpk2tf(z.valueOf(), p.valueOf(), 1);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
function _zpk2tf(z, p, k) {
|
|
49
|
+
// if z is bignumber, convert it to number
|
|
50
|
+
if (z.some(function (el) {
|
|
51
|
+
return el.type === 'BigNumber';
|
|
52
|
+
})) {
|
|
53
|
+
z = z.map(function (el) {
|
|
54
|
+
return number(el);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// if p is bignumber, convert it to number
|
|
58
|
+
if (p.some(function (el) {
|
|
59
|
+
return el.type === 'BigNumber';
|
|
60
|
+
})) {
|
|
61
|
+
p = p.map(function (el) {
|
|
62
|
+
return number(el);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
var num = [Complex(1, 0)];
|
|
66
|
+
var den = [Complex(1, 0)];
|
|
67
|
+
for (var i = 0; i < z.length; i++) {
|
|
68
|
+
var zero = z[i];
|
|
69
|
+
if (typeof zero === 'number') zero = Complex(zero, 0);
|
|
70
|
+
num = _multiply(num, [Complex(1, 0), Complex(-zero.re, -zero.im)]);
|
|
71
|
+
}
|
|
72
|
+
for (var _i = 0; _i < p.length; _i++) {
|
|
73
|
+
var pole = p[_i];
|
|
74
|
+
if (typeof pole === 'number') pole = Complex(pole, 0);
|
|
75
|
+
den = _multiply(den, [Complex(1, 0), Complex(-pole.re, -pole.im)]);
|
|
76
|
+
}
|
|
77
|
+
for (var _i2 = 0; _i2 < num.length; _i2++) {
|
|
78
|
+
num[_i2] = multiply(num[_i2], k);
|
|
79
|
+
}
|
|
80
|
+
return [num, den];
|
|
81
|
+
}
|
|
82
|
+
function _multiply(a, b) {
|
|
83
|
+
var c = [];
|
|
84
|
+
for (var i = 0; i < a.length + b.length - 1; i++) {
|
|
85
|
+
c[i] = Complex(0, 0);
|
|
86
|
+
for (var j = 0; j < a.length; j++) {
|
|
87
|
+
if (i - j >= 0 && i - j < b.length) {
|
|
88
|
+
c[i] = add(c[i], multiply(a[j], b[i - j]));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return c;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
exports.createZpk2tf = createZpk2tf;
|
package/lib/cjs/header.js
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* It features real and complex numbers, units, matrices, a large set of
|
|
7
7
|
* mathematical functions, and a flexible expression parser.
|
|
8
8
|
*
|
|
9
|
-
* @version 11.
|
|
10
|
-
* @date 2023-
|
|
9
|
+
* @version 11.9.0
|
|
10
|
+
* @date 2023-07-19
|
|
11
11
|
*
|
|
12
12
|
* @license
|
|
13
13
|
* Copyright (C) 2013-2023 Jos de Jong <wjosdejong@gmail.com>
|
|
@@ -32,11 +32,11 @@ var createUnitClass = /* #__PURE__ */(0, _factory.factory)(name, dependencies, f
|
|
|
32
32
|
equal = _ref.equal,
|
|
33
33
|
isNumeric = _ref.isNumeric,
|
|
34
34
|
format = _ref.format,
|
|
35
|
-
|
|
35
|
+
_number = _ref.number,
|
|
36
36
|
Complex = _ref.Complex,
|
|
37
37
|
_BigNumber = _ref.BigNumber,
|
|
38
38
|
_Fraction = _ref.Fraction;
|
|
39
|
-
var toNumber =
|
|
39
|
+
var toNumber = _number;
|
|
40
40
|
/**
|
|
41
41
|
* A unit can be constructed in the following ways:
|
|
42
42
|
*
|
|
@@ -792,13 +792,13 @@ var createUnitClass = /* #__PURE__ */(0, _factory.factory)(name, dependencies, f
|
|
|
792
792
|
/* Need to adjust value by difference in offset to convert */
|
|
793
793
|
var convert = Unit._getNumberConverter((0, _is.typeOf)(value)); // convert to Fraction or BigNumber if needed
|
|
794
794
|
|
|
795
|
-
var thisUnitValue =
|
|
796
|
-
var thisNominalOffset =
|
|
795
|
+
var thisUnitValue = this.units[0].unit.value;
|
|
796
|
+
var thisNominalOffset = this.units[0].unit.offset;
|
|
797
797
|
var thisUnitOffset = multiplyScalar(thisUnitValue, thisNominalOffset);
|
|
798
|
-
var otherUnitValue =
|
|
799
|
-
var otherNominalOffset =
|
|
798
|
+
var otherUnitValue = other.units[0].unit.value;
|
|
799
|
+
var otherNominalOffset = other.units[0].unit.offset;
|
|
800
800
|
var otherUnitOffset = multiplyScalar(otherUnitValue, otherNominalOffset);
|
|
801
|
-
other.value =
|
|
801
|
+
other.value = addScalar(value, convert(subtract(thisUnitOffset, otherUnitOffset)));
|
|
802
802
|
}
|
|
803
803
|
other.fixPrefix = true;
|
|
804
804
|
other.skipAutomaticSimplification = true;
|
|
@@ -2748,8 +2748,8 @@ var createUnitClass = /* #__PURE__ */(0, _factory.factory)(name, dependencies, f
|
|
|
2748
2748
|
},
|
|
2749
2749
|
// Temperature
|
|
2750
2750
|
// K(C) = °C + 273.15
|
|
2751
|
-
// K(F) = (°F + 459.67) /
|
|
2752
|
-
// K(R) = °R /
|
|
2751
|
+
// K(F) = (°F + 459.67) * (5 / 9)
|
|
2752
|
+
// K(R) = °R * (5 / 9)
|
|
2753
2753
|
K: {
|
|
2754
2754
|
name: 'K',
|
|
2755
2755
|
base: BASE_UNITS.TEMPERATURE,
|
|
@@ -2768,14 +2768,14 @@ var createUnitClass = /* #__PURE__ */(0, _factory.factory)(name, dependencies, f
|
|
|
2768
2768
|
name: 'degF',
|
|
2769
2769
|
base: BASE_UNITS.TEMPERATURE,
|
|
2770
2770
|
prefixes: PREFIXES.SHORT,
|
|
2771
|
-
value:
|
|
2771
|
+
value: new _Fraction(5, 9),
|
|
2772
2772
|
offset: 459.67
|
|
2773
2773
|
},
|
|
2774
2774
|
degR: {
|
|
2775
2775
|
name: 'degR',
|
|
2776
2776
|
base: BASE_UNITS.TEMPERATURE,
|
|
2777
2777
|
prefixes: PREFIXES.SHORT,
|
|
2778
|
-
value:
|
|
2778
|
+
value: new _Fraction(5, 9),
|
|
2779
2779
|
offset: 0
|
|
2780
2780
|
},
|
|
2781
2781
|
kelvin: {
|
|
@@ -2796,14 +2796,14 @@ var createUnitClass = /* #__PURE__ */(0, _factory.factory)(name, dependencies, f
|
|
|
2796
2796
|
name: 'fahrenheit',
|
|
2797
2797
|
base: BASE_UNITS.TEMPERATURE,
|
|
2798
2798
|
prefixes: PREFIXES.LONG,
|
|
2799
|
-
value:
|
|
2799
|
+
value: new _Fraction(5, 9),
|
|
2800
2800
|
offset: 459.67
|
|
2801
2801
|
},
|
|
2802
2802
|
rankine: {
|
|
2803
2803
|
name: 'rankine',
|
|
2804
2804
|
base: BASE_UNITS.TEMPERATURE,
|
|
2805
2805
|
prefixes: PREFIXES.LONG,
|
|
2806
|
-
value:
|
|
2806
|
+
value: new _Fraction(5, 9),
|
|
2807
2807
|
offset: 0
|
|
2808
2808
|
},
|
|
2809
2809
|
// amount of substance
|
|
@@ -3524,6 +3524,7 @@ var createUnitClass = /* #__PURE__ */(0, _factory.factory)(name, dependencies, f
|
|
|
3524
3524
|
*/
|
|
3525
3525
|
Unit.typeConverters = {
|
|
3526
3526
|
BigNumber: function BigNumber(x) {
|
|
3527
|
+
if (x !== null && x !== void 0 && x.isFraction) return new _BigNumber(x.n).div(x.d).times(x.s);
|
|
3527
3528
|
return new _BigNumber(x + ''); // stringify to prevent constructor error
|
|
3528
3529
|
},
|
|
3529
3530
|
|
|
@@ -3534,6 +3535,7 @@ var createUnitClass = /* #__PURE__ */(0, _factory.factory)(name, dependencies, f
|
|
|
3534
3535
|
return x;
|
|
3535
3536
|
},
|
|
3536
3537
|
number: function number(x) {
|
|
3538
|
+
if (x !== null && x !== void 0 && x.isFraction) return _number(x);
|
|
3537
3539
|
return x;
|
|
3538
3540
|
}
|
|
3539
3541
|
};
|
package/lib/cjs/version.js
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.version = void 0;
|
|
7
|
-
var version = '11.
|
|
7
|
+
var version = '11.9.0';
|
|
8
8
|
// Note: This file is automatically generated when building math.js.
|
|
9
9
|
// Changes made in this file will be overwritten.
|
|
10
10
|
exports.version = version;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THIS FILE IS AUTO-GENERATED
|
|
3
|
+
* DON'T MAKE CHANGES HERE
|
|
4
|
+
*/
|
|
5
|
+
import { ComplexDependencies } from './dependenciesComplexClass.generated.js';
|
|
6
|
+
import { addDependencies } from './dependenciesAdd.generated.js';
|
|
7
|
+
import { divideDependencies } from './dependenciesDivide.generated.js';
|
|
8
|
+
import { matrixDependencies } from './dependenciesMatrix.generated.js';
|
|
9
|
+
import { multiplyDependencies } from './dependenciesMultiply.generated.js';
|
|
10
|
+
import { typedDependencies } from './dependenciesTyped.generated.js';
|
|
11
|
+
import { createFreqz } from '../../factoriesAny.js';
|
|
12
|
+
export var freqzDependencies = {
|
|
13
|
+
ComplexDependencies,
|
|
14
|
+
addDependencies,
|
|
15
|
+
divideDependencies,
|
|
16
|
+
matrixDependencies,
|
|
17
|
+
multiplyDependencies,
|
|
18
|
+
typedDependencies,
|
|
19
|
+
createFreqz
|
|
20
|
+
};
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { bignumberDependencies } from './dependenciesBignumber.generated.js';
|
|
6
6
|
import { matrixDependencies } from './dependenciesMatrix.generated.js';
|
|
7
|
+
import { addDependencies } from './dependenciesAdd.generated.js';
|
|
8
|
+
import { isPositiveDependencies } from './dependenciesIsPositive.generated.js';
|
|
7
9
|
import { largerDependencies } from './dependenciesLarger.generated.js';
|
|
8
10
|
import { largerEqDependencies } from './dependenciesLargerEq.generated.js';
|
|
9
11
|
import { smallerDependencies } from './dependenciesSmaller.generated.js';
|
|
@@ -13,6 +15,8 @@ import { createRange } from '../../factoriesAny.js';
|
|
|
13
15
|
export var rangeDependencies = {
|
|
14
16
|
bignumberDependencies,
|
|
15
17
|
matrixDependencies,
|
|
18
|
+
addDependencies,
|
|
19
|
+
isPositiveDependencies,
|
|
16
20
|
largerDependencies,
|
|
17
21
|
largerEqDependencies,
|
|
18
22
|
smallerDependencies,
|