mathjs 11.8.2 → 11.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,
|