mathjs 11.8.2 → 11.9.1
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 +24 -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/node/FunctionNode.js +5 -6
- package/lib/cjs/expression/node/ObjectNode.js +5 -7
- package/lib/cjs/expression/node/SymbolNode.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/utils/customs.js +4 -3
- 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/node/FunctionNode.js +6 -7
- package/lib/esm/expression/node/ObjectNode.js +5 -7
- package/lib/esm/expression/node/SymbolNode.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/utils/customs.js +4 -3
- package/lib/esm/version.js +1 -1
- package/package.json +15 -15
- package/types/index.d.ts +51 -6
|
@@ -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
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { factory } from '../../utils/factory.js';
|
|
2
|
+
var name = 'freqz';
|
|
3
|
+
var dependencies = ['typed', 'add', 'multiply', 'Complex', 'divide', 'matrix'];
|
|
4
|
+
export var createFreqz = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
5
|
+
var {
|
|
6
|
+
typed,
|
|
7
|
+
add,
|
|
8
|
+
multiply,
|
|
9
|
+
Complex,
|
|
10
|
+
divide,
|
|
11
|
+
matrix
|
|
12
|
+
} = _ref;
|
|
13
|
+
/**
|
|
14
|
+
* Calculates the frequency response of a filter given its numerator and denominator coefficients.
|
|
15
|
+
*
|
|
16
|
+
* Syntax:
|
|
17
|
+
* math.freqz(b, a)
|
|
18
|
+
* math.freqz(b, a, w)
|
|
19
|
+
*
|
|
20
|
+
* Examples:
|
|
21
|
+
* 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 ] }
|
|
22
|
+
* math.freqz([1, 2], [1, 2, 3], [0, 1]) // returns { h: [0.5 + 0i, 0.45436781 + 0.38598051i], w: [0, 1] }
|
|
23
|
+
*
|
|
24
|
+
* See also:
|
|
25
|
+
* zpk2tf
|
|
26
|
+
*
|
|
27
|
+
* @param {Array.<number>} b The numerator coefficients of the filter.
|
|
28
|
+
* @param {Array.<number>} a The denominator coefficients of the filter.
|
|
29
|
+
* @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)
|
|
30
|
+
* @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.
|
|
31
|
+
*
|
|
32
|
+
*
|
|
33
|
+
*/
|
|
34
|
+
return typed(name, {
|
|
35
|
+
'Array, Array': function ArrayArray(b, a) {
|
|
36
|
+
var w = createBins(512);
|
|
37
|
+
return _freqz(b, a, w);
|
|
38
|
+
},
|
|
39
|
+
'Array, Array, Array': function ArrayArrayArray(b, a, w) {
|
|
40
|
+
return _freqz(b, a, w);
|
|
41
|
+
},
|
|
42
|
+
'Array, Array, number': function ArrayArrayNumber(b, a, w) {
|
|
43
|
+
if (w < 0) {
|
|
44
|
+
throw new Error('w must be a positive number');
|
|
45
|
+
}
|
|
46
|
+
var w2 = createBins(w);
|
|
47
|
+
return _freqz(b, a, w2);
|
|
48
|
+
},
|
|
49
|
+
'Matrix, Matrix': function MatrixMatrix(b, a) {
|
|
50
|
+
// console.log('here')
|
|
51
|
+
var _w = createBins(512);
|
|
52
|
+
var {
|
|
53
|
+
w,
|
|
54
|
+
h
|
|
55
|
+
} = _freqz(b.valueOf(), a.valueOf(), _w);
|
|
56
|
+
return {
|
|
57
|
+
w: matrix(w),
|
|
58
|
+
h: matrix(h)
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
'Matrix, Matrix, Matrix': function MatrixMatrixMatrix(b, a, w) {
|
|
62
|
+
var {
|
|
63
|
+
h
|
|
64
|
+
} = _freqz(b.valueOf(), a.valueOf(), w.valueOf());
|
|
65
|
+
return {
|
|
66
|
+
h: matrix(h),
|
|
67
|
+
w: matrix(w)
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
'Matrix, Matrix, number': function MatrixMatrixNumber(b, a, w) {
|
|
71
|
+
if (w < 0) {
|
|
72
|
+
throw new Error('w must be a positive number');
|
|
73
|
+
}
|
|
74
|
+
var _w = createBins(w);
|
|
75
|
+
var {
|
|
76
|
+
h
|
|
77
|
+
} = _freqz(b.valueOf(), a.valueOf(), _w);
|
|
78
|
+
return {
|
|
79
|
+
h: matrix(h),
|
|
80
|
+
w: matrix(_w)
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
function _freqz(b, a, w) {
|
|
85
|
+
var num = [];
|
|
86
|
+
var den = [];
|
|
87
|
+
for (var i = 0; i < w.length; i++) {
|
|
88
|
+
var sumNum = Complex(0, 0);
|
|
89
|
+
var sumDen = Complex(0, 0);
|
|
90
|
+
for (var j = 0; j < b.length; j++) {
|
|
91
|
+
sumNum = add(sumNum, multiply(b[j], Complex(Math.cos(-j * w[i]), Math.sin(-j * w[i]))));
|
|
92
|
+
}
|
|
93
|
+
for (var _j = 0; _j < a.length; _j++) {
|
|
94
|
+
sumDen = add(sumDen, multiply(a[_j], Complex(Math.cos(-_j * w[i]), Math.sin(-_j * w[i]))));
|
|
95
|
+
}
|
|
96
|
+
num.push(sumNum);
|
|
97
|
+
den.push(sumDen);
|
|
98
|
+
}
|
|
99
|
+
var h = [];
|
|
100
|
+
for (var _i = 0; _i < num.length; _i++) {
|
|
101
|
+
h.push(divide(num[_i], den[_i]));
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
h,
|
|
105
|
+
w
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function createBins(n) {
|
|
109
|
+
var bins = [];
|
|
110
|
+
for (var i = 0; i < n; i++) {
|
|
111
|
+
bins.push(i / n * Math.PI);
|
|
112
|
+
}
|
|
113
|
+
return bins;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { factory } from '../../utils/factory.js';
|
|
2
|
+
var name = 'zpk2tf';
|
|
3
|
+
var dependencies = ['typed', 'add', 'multiply', 'Complex', 'number'];
|
|
4
|
+
export var createZpk2tf = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
5
|
+
var {
|
|
6
|
+
typed,
|
|
7
|
+
add,
|
|
8
|
+
multiply,
|
|
9
|
+
Complex,
|
|
10
|
+
number
|
|
11
|
+
} = _ref;
|
|
12
|
+
/**
|
|
13
|
+
* Compute the transfer function of a zero-pole-gain model.
|
|
14
|
+
*
|
|
15
|
+
* Syntax:
|
|
16
|
+
* math.zpk2tf(z, p, k)
|
|
17
|
+
*
|
|
18
|
+
* Examples:
|
|
19
|
+
* math.zpk2tf([1, 2], [-1, -2], 1) // returns [[1, -3, 2], [1, 3, 2]]
|
|
20
|
+
*
|
|
21
|
+
* See also:
|
|
22
|
+
* freqz
|
|
23
|
+
*
|
|
24
|
+
* @param {Array} z Array of zeros values
|
|
25
|
+
* @param {Array} p Array of poles values
|
|
26
|
+
* @param {number} k Gain value
|
|
27
|
+
* @return {Array} Two dimensional array containing the numerator (first row) and denominator (second row) polynomials
|
|
28
|
+
*
|
|
29
|
+
*/
|
|
30
|
+
return typed(name, {
|
|
31
|
+
'Array,Array,number': function ArrayArrayNumber(z, p, k) {
|
|
32
|
+
return _zpk2tf(z, p, k);
|
|
33
|
+
},
|
|
34
|
+
'Array,Array': function ArrayArray(z, p) {
|
|
35
|
+
return _zpk2tf(z, p, 1);
|
|
36
|
+
},
|
|
37
|
+
'Matrix,Matrix,number': function MatrixMatrixNumber(z, p, k) {
|
|
38
|
+
return _zpk2tf(z.valueOf(), p.valueOf(), k);
|
|
39
|
+
},
|
|
40
|
+
'Matrix,Matrix': function MatrixMatrix(z, p) {
|
|
41
|
+
return _zpk2tf(z.valueOf(), p.valueOf(), 1);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
function _zpk2tf(z, p, k) {
|
|
45
|
+
// if z is bignumber, convert it to number
|
|
46
|
+
if (z.some(el => el.type === 'BigNumber')) {
|
|
47
|
+
z = z.map(el => number(el));
|
|
48
|
+
}
|
|
49
|
+
// if p is bignumber, convert it to number
|
|
50
|
+
if (p.some(el => el.type === 'BigNumber')) {
|
|
51
|
+
p = p.map(el => number(el));
|
|
52
|
+
}
|
|
53
|
+
var num = [Complex(1, 0)];
|
|
54
|
+
var den = [Complex(1, 0)];
|
|
55
|
+
for (var i = 0; i < z.length; i++) {
|
|
56
|
+
var zero = z[i];
|
|
57
|
+
if (typeof zero === 'number') zero = Complex(zero, 0);
|
|
58
|
+
num = _multiply(num, [Complex(1, 0), Complex(-zero.re, -zero.im)]);
|
|
59
|
+
}
|
|
60
|
+
for (var _i = 0; _i < p.length; _i++) {
|
|
61
|
+
var pole = p[_i];
|
|
62
|
+
if (typeof pole === 'number') pole = Complex(pole, 0);
|
|
63
|
+
den = _multiply(den, [Complex(1, 0), Complex(-pole.re, -pole.im)]);
|
|
64
|
+
}
|
|
65
|
+
for (var _i2 = 0; _i2 < num.length; _i2++) {
|
|
66
|
+
num[_i2] = multiply(num[_i2], k);
|
|
67
|
+
}
|
|
68
|
+
return [num, den];
|
|
69
|
+
}
|
|
70
|
+
function _multiply(a, b) {
|
|
71
|
+
var c = [];
|
|
72
|
+
for (var i = 0; i < a.length + b.length - 1; i++) {
|
|
73
|
+
c[i] = Complex(0, 0);
|
|
74
|
+
for (var j = 0; j < a.length; j++) {
|
|
75
|
+
if (i - j >= 0 && i - j < b.length) {
|
|
76
|
+
c[i] = add(c[i], multiply(a[j], b[i - j]));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return c;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
@@ -25,12 +25,12 @@ export var createUnitClass = /* #__PURE__ */factory(name, dependencies, _ref =>
|
|
|
25
25
|
equal,
|
|
26
26
|
isNumeric,
|
|
27
27
|
format,
|
|
28
|
-
number,
|
|
28
|
+
number: _number,
|
|
29
29
|
Complex,
|
|
30
30
|
BigNumber: _BigNumber,
|
|
31
31
|
Fraction: _Fraction
|
|
32
32
|
} = _ref;
|
|
33
|
-
var toNumber =
|
|
33
|
+
var toNumber = _number;
|
|
34
34
|
/**
|
|
35
35
|
* A unit can be constructed in the following ways:
|
|
36
36
|
*
|
|
@@ -780,13 +780,13 @@ export var createUnitClass = /* #__PURE__ */factory(name, dependencies, _ref =>
|
|
|
780
780
|
/* Need to adjust value by difference in offset to convert */
|
|
781
781
|
var convert = Unit._getNumberConverter(typeOf(value)); // convert to Fraction or BigNumber if needed
|
|
782
782
|
|
|
783
|
-
var thisUnitValue =
|
|
784
|
-
var thisNominalOffset =
|
|
783
|
+
var thisUnitValue = this.units[0].unit.value;
|
|
784
|
+
var thisNominalOffset = this.units[0].unit.offset;
|
|
785
785
|
var thisUnitOffset = multiplyScalar(thisUnitValue, thisNominalOffset);
|
|
786
|
-
var otherUnitValue =
|
|
787
|
-
var otherNominalOffset =
|
|
786
|
+
var otherUnitValue = other.units[0].unit.value;
|
|
787
|
+
var otherNominalOffset = other.units[0].unit.offset;
|
|
788
788
|
var otherUnitOffset = multiplyScalar(otherUnitValue, otherNominalOffset);
|
|
789
|
-
other.value =
|
|
789
|
+
other.value = addScalar(value, convert(subtract(thisUnitOffset, otherUnitOffset)));
|
|
790
790
|
}
|
|
791
791
|
other.fixPrefix = true;
|
|
792
792
|
other.skipAutomaticSimplification = true;
|
|
@@ -2734,8 +2734,8 @@ export var createUnitClass = /* #__PURE__ */factory(name, dependencies, _ref =>
|
|
|
2734
2734
|
},
|
|
2735
2735
|
// Temperature
|
|
2736
2736
|
// K(C) = °C + 273.15
|
|
2737
|
-
// K(F) = (°F + 459.67) /
|
|
2738
|
-
// K(R) = °R /
|
|
2737
|
+
// K(F) = (°F + 459.67) * (5 / 9)
|
|
2738
|
+
// K(R) = °R * (5 / 9)
|
|
2739
2739
|
K: {
|
|
2740
2740
|
name: 'K',
|
|
2741
2741
|
base: BASE_UNITS.TEMPERATURE,
|
|
@@ -2754,14 +2754,14 @@ export var createUnitClass = /* #__PURE__ */factory(name, dependencies, _ref =>
|
|
|
2754
2754
|
name: 'degF',
|
|
2755
2755
|
base: BASE_UNITS.TEMPERATURE,
|
|
2756
2756
|
prefixes: PREFIXES.SHORT,
|
|
2757
|
-
value:
|
|
2757
|
+
value: new _Fraction(5, 9),
|
|
2758
2758
|
offset: 459.67
|
|
2759
2759
|
},
|
|
2760
2760
|
degR: {
|
|
2761
2761
|
name: 'degR',
|
|
2762
2762
|
base: BASE_UNITS.TEMPERATURE,
|
|
2763
2763
|
prefixes: PREFIXES.SHORT,
|
|
2764
|
-
value:
|
|
2764
|
+
value: new _Fraction(5, 9),
|
|
2765
2765
|
offset: 0
|
|
2766
2766
|
},
|
|
2767
2767
|
kelvin: {
|
|
@@ -2782,14 +2782,14 @@ export var createUnitClass = /* #__PURE__ */factory(name, dependencies, _ref =>
|
|
|
2782
2782
|
name: 'fahrenheit',
|
|
2783
2783
|
base: BASE_UNITS.TEMPERATURE,
|
|
2784
2784
|
prefixes: PREFIXES.LONG,
|
|
2785
|
-
value:
|
|
2785
|
+
value: new _Fraction(5, 9),
|
|
2786
2786
|
offset: 459.67
|
|
2787
2787
|
},
|
|
2788
2788
|
rankine: {
|
|
2789
2789
|
name: 'rankine',
|
|
2790
2790
|
base: BASE_UNITS.TEMPERATURE,
|
|
2791
2791
|
prefixes: PREFIXES.LONG,
|
|
2792
|
-
value:
|
|
2792
|
+
value: new _Fraction(5, 9),
|
|
2793
2793
|
offset: 0
|
|
2794
2794
|
},
|
|
2795
2795
|
// amount of substance
|
|
@@ -3510,6 +3510,7 @@ export var createUnitClass = /* #__PURE__ */factory(name, dependencies, _ref =>
|
|
|
3510
3510
|
*/
|
|
3511
3511
|
Unit.typeConverters = {
|
|
3512
3512
|
BigNumber: function BigNumber(x) {
|
|
3513
|
+
if (x !== null && x !== void 0 && x.isFraction) return new _BigNumber(x.n).div(x.d).times(x.s);
|
|
3513
3514
|
return new _BigNumber(x + ''); // stringify to prevent constructor error
|
|
3514
3515
|
},
|
|
3515
3516
|
|
|
@@ -3520,6 +3521,7 @@ export var createUnitClass = /* #__PURE__ */factory(name, dependencies, _ref =>
|
|
|
3520
3521
|
return x;
|
|
3521
3522
|
},
|
|
3522
3523
|
number: function number(x) {
|
|
3524
|
+
if (x !== null && x !== void 0 && x.isFraction) return _number(x);
|
|
3523
3525
|
return x;
|
|
3524
3526
|
}
|
|
3525
3527
|
};
|
package/lib/esm/utils/customs.js
CHANGED
|
@@ -83,12 +83,13 @@ function isSafeProperty(object, prop) {
|
|
|
83
83
|
* Throws an error when that's not the case.
|
|
84
84
|
* @param {Object} object
|
|
85
85
|
* @param {string} method
|
|
86
|
+
* @return {function} Returns the method when valid
|
|
86
87
|
*/
|
|
87
|
-
|
|
88
|
-
function validateSafeMethod(object, method) {
|
|
88
|
+
function getSafeMethod(object, method) {
|
|
89
89
|
if (!isSafeMethod(object, method)) {
|
|
90
90
|
throw new Error('No access to method "' + method + '"');
|
|
91
91
|
}
|
|
92
|
+
return object[method];
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
/**
|
|
@@ -148,6 +149,6 @@ export { setSafeProperty };
|
|
|
148
149
|
export { isSafeProperty };
|
|
149
150
|
export { hasSafeProperty };
|
|
150
151
|
export { getSafeProperties };
|
|
151
|
-
export {
|
|
152
|
+
export { getSafeMethod };
|
|
152
153
|
export { isSafeMethod };
|
|
153
154
|
export { isPlainObject };
|
package/lib/esm/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mathjs",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.9.1",
|
|
4
4
|
"description": "Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with different data types like numbers, big numbers, complex numbers, fractions, units, and matrices.",
|
|
5
5
|
"author": "Jos de Jong <wjosdejong@gmail.com> (https://github.com/josdejong)",
|
|
6
6
|
"homepage": "https://mathjs.org",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"unit"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@babel/runtime": "^7.22.
|
|
28
|
+
"@babel/runtime": "^7.22.6",
|
|
29
29
|
"complex.js": "^2.1.1",
|
|
30
30
|
"decimal.js": "^10.4.3",
|
|
31
31
|
"escape-latex": "^1.2.0",
|
|
@@ -36,29 +36,29 @@
|
|
|
36
36
|
"typed-function": "^4.1.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@babel/core": "7.22.
|
|
39
|
+
"@babel/core": "7.22.9",
|
|
40
40
|
"@babel/plugin-transform-object-assign": "7.22.5",
|
|
41
|
-
"@babel/plugin-transform-runtime": "7.22.
|
|
42
|
-
"@babel/preset-env": "7.22.
|
|
41
|
+
"@babel/plugin-transform-runtime": "7.22.9",
|
|
42
|
+
"@babel/preset-env": "7.22.9",
|
|
43
43
|
"@babel/register": "7.22.5",
|
|
44
44
|
"@types/assert": "1.5.6",
|
|
45
45
|
"@types/mocha": "10.0.1",
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "
|
|
47
|
-
"@typescript-eslint/parser": "
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "6.1.0",
|
|
47
|
+
"@typescript-eslint/parser": "6.1.0",
|
|
48
48
|
"assert": "2.0.0",
|
|
49
|
-
"babel-loader": "9.1.
|
|
49
|
+
"babel-loader": "9.1.3",
|
|
50
50
|
"benchmark": "2.1.4",
|
|
51
51
|
"c8": "8.0.0",
|
|
52
52
|
"codecov": "3.8.3",
|
|
53
|
-
"core-js": "3.31.
|
|
53
|
+
"core-js": "3.31.1",
|
|
54
54
|
"del": "6.1.1",
|
|
55
55
|
"dtslint": "4.2.1",
|
|
56
|
-
"eslint": "8.
|
|
56
|
+
"eslint": "8.45.0",
|
|
57
57
|
"eslint-config-prettier": "8.8.0",
|
|
58
58
|
"eslint-config-standard": "17.1.0",
|
|
59
59
|
"eslint-plugin-import": "2.27.5",
|
|
60
60
|
"eslint-plugin-mocha": "10.1.0",
|
|
61
|
-
"eslint-plugin-n": "16.0.
|
|
61
|
+
"eslint-plugin-n": "16.0.1",
|
|
62
62
|
"eslint-plugin-prettier": "4.2.1",
|
|
63
63
|
"eslint-plugin-promise": "6.1.1",
|
|
64
64
|
"expect-type": "0.16.0",
|
|
@@ -75,9 +75,9 @@
|
|
|
75
75
|
"karma-mocha": "2.0.1",
|
|
76
76
|
"karma-mocha-reporter": "2.2.5",
|
|
77
77
|
"karma-webpack": "5.0.0",
|
|
78
|
-
"mkdirp": "
|
|
78
|
+
"mkdirp": "3.0.1",
|
|
79
79
|
"mocha": "10.2.0",
|
|
80
|
-
"mocha-junit-reporter": "2.2.
|
|
80
|
+
"mocha-junit-reporter": "2.2.1",
|
|
81
81
|
"ndarray": "1.0.19",
|
|
82
82
|
"ndarray-determinant": "1.0.0",
|
|
83
83
|
"ndarray-gemm": "1.0.0",
|
|
@@ -89,8 +89,8 @@
|
|
|
89
89
|
"process": "0.11.10",
|
|
90
90
|
"sylvester": "0.0.21",
|
|
91
91
|
"ts-node": "10.9.1",
|
|
92
|
-
"typescript": "5.1.
|
|
93
|
-
"webpack": "5.
|
|
92
|
+
"typescript": "5.1.6",
|
|
93
|
+
"webpack": "5.88.2",
|
|
94
94
|
"zeros": "1.0.0"
|
|
95
95
|
},
|
|
96
96
|
"type": "module",
|