mathjs 10.2.0 → 10.4.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 +43 -0
- package/docs/expressions/syntax.md +31 -2
- package/docs/reference/functions/cumsum.md +57 -0
- package/docs/reference/functions/format.md +1 -1
- package/docs/reference/functions/map.md +22 -5
- package/docs/reference/functions/subset.md +10 -2
- package/docs/reference/functions/sum.md +2 -1
- package/docs/reference/functions/symbolicEqual.md +62 -0
- package/docs/reference/functions.md +3 -1
- package/lib/browser/math.js +6 -6
- package/lib/browser/math.js.map +1 -1
- package/lib/cjs/entry/dependenciesAny/dependenciesCumSum.generated.js +26 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesCumSumTransform.generated.js +26 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesSymbolicEqual.generated.js +29 -0
- package/lib/cjs/entry/dependenciesAny.generated.js +24 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesCumSum.generated.js +26 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesCumSumTransform.generated.js +26 -0
- package/lib/cjs/entry/dependenciesNumber.generated.js +16 -0
- package/lib/cjs/entry/impureFunctionsAny.generated.js +22 -8
- package/lib/cjs/entry/impureFunctionsNumber.generated.js +6 -0
- package/lib/cjs/entry/pureFunctionsAny.generated.js +18 -12
- package/lib/cjs/entry/pureFunctionsNumber.generated.js +8 -2
- package/lib/cjs/expression/embeddedDocs/construction/fraction.js +3 -3
- package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +240 -234
- package/lib/cjs/expression/embeddedDocs/function/algebra/symbolicEqual.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/matrix/subset.js +2 -2
- package/lib/cjs/expression/embeddedDocs/function/statistics/cumsum.js +15 -0
- package/lib/cjs/expression/node/FunctionNode.js +74 -55
- package/lib/cjs/expression/parse.js +12 -8
- package/lib/cjs/expression/transform/cumsum.transform.js +57 -0
- package/lib/cjs/expression/transform/sum.transform.js +1 -1
- package/lib/cjs/factoriesAny.js +24 -0
- package/lib/cjs/factoriesNumber.js +18 -2
- package/lib/cjs/function/algebra/simplify.js +8 -0
- package/lib/cjs/function/algebra/simplifyCore.js +2 -2
- package/lib/cjs/function/algebra/symbolicEqual.js +88 -0
- package/lib/cjs/function/matrix/eigs/complexEigs.js +39 -28
- package/lib/cjs/function/matrix/map.js +53 -15
- package/lib/cjs/function/matrix/subset.js +15 -5
- package/lib/cjs/function/statistics/cumsum.js +151 -0
- package/lib/cjs/function/statistics/sum.js +1 -1
- package/lib/cjs/function/string/format.js +1 -1
- package/lib/cjs/header.js +2 -2
- package/lib/cjs/type/fraction/function/fraction.js +20 -8
- package/lib/cjs/utils/collection.js +3 -27
- package/lib/cjs/utils/switch.js +31 -0
- package/lib/cjs/version.js +1 -1
- package/lib/esm/entry/dependenciesAny/dependenciesCumSum.generated.js +14 -0
- package/lib/esm/entry/dependenciesAny/dependenciesCumSumTransform.generated.js +14 -0
- package/lib/esm/entry/dependenciesAny/dependenciesSymbolicEqual.generated.js +16 -0
- package/lib/esm/entry/dependenciesAny.generated.js +3 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesCumSum.generated.js +14 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesCumSumTransform.generated.js +14 -0
- package/lib/esm/entry/dependenciesNumber.generated.js +2 -0
- package/lib/esm/entry/impureFunctionsAny.generated.js +22 -9
- package/lib/esm/entry/impureFunctionsNumber.generated.js +8 -2
- package/lib/esm/entry/pureFunctionsAny.generated.js +13 -8
- package/lib/esm/entry/pureFunctionsNumber.generated.js +6 -1
- package/lib/esm/expression/embeddedDocs/construction/fraction.js +3 -3
- package/lib/esm/expression/embeddedDocs/embeddedDocs.js +220 -216
- package/lib/esm/expression/embeddedDocs/function/algebra/symbolicEqual.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/matrix/subset.js +2 -2
- package/lib/esm/expression/embeddedDocs/function/statistics/cumsum.js +8 -0
- package/lib/esm/expression/node/FunctionNode.js +70 -53
- package/lib/esm/expression/parse.js +12 -8
- package/lib/esm/expression/transform/cumsum.transform.js +48 -0
- package/lib/esm/expression/transform/sum.transform.js +1 -1
- package/lib/esm/factoriesAny.js +3 -0
- package/lib/esm/factoriesNumber.js +2 -0
- package/lib/esm/function/algebra/simplify.js +8 -0
- package/lib/esm/function/algebra/simplifyCore.js +2 -2
- package/lib/esm/function/algebra/symbolicEqual.js +80 -0
- package/lib/esm/function/matrix/eigs/complexEigs.js +36 -25
- package/lib/esm/function/matrix/map.js +53 -15
- package/lib/esm/function/matrix/subset.js +15 -5
- package/lib/esm/function/statistics/cumsum.js +139 -0
- package/lib/esm/function/statistics/sum.js +1 -1
- package/lib/esm/function/string/format.js +1 -1
- package/lib/esm/type/fraction/function/fraction.js +20 -8
- package/lib/esm/utils/collection.js +1 -26
- package/lib/esm/utils/switch.js +24 -0
- package/lib/esm/version.js +1 -1
- package/package.json +15 -11
- package/types/index.d.ts +209 -23
- package/types/index.ts +274 -57
- package/types/tsconfig.json +2 -1
|
@@ -77,76 +77,93 @@ export var createFunctionNode = /* #__PURE__ */factory(name, dependencies, _ref
|
|
|
77
77
|
var evalArgs = this.args.map(arg => arg._compile(math, argNames));
|
|
78
78
|
|
|
79
79
|
if (isSymbolNode(this.fn)) {
|
|
80
|
-
// we can statically determine whether the function has an rawArgs property
|
|
81
80
|
var _name = this.fn.name;
|
|
82
|
-
var fn = _name in math ? getSafeProperty(math, _name) : undefined;
|
|
83
|
-
var isRaw = typeof fn === 'function' && fn.rawArgs === true;
|
|
84
81
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
if (!argNames[_name]) {
|
|
83
|
+
// we can statically determine whether the function has an rawArgs property
|
|
84
|
+
var fn = _name in math ? getSafeProperty(math, _name) : undefined;
|
|
85
|
+
var isRaw = typeof fn === 'function' && fn.rawArgs === true;
|
|
89
86
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
var resolveFn = scope => {
|
|
88
|
+
if (scope.has(_name)) {
|
|
89
|
+
return scope.get(_name);
|
|
90
|
+
}
|
|
93
91
|
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
if (_name in math) {
|
|
93
|
+
return getSafeProperty(math, _name);
|
|
94
|
+
}
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
// pass unevaluated parameters (nodes) to the function
|
|
99
|
-
// "raw" evaluation
|
|
100
|
-
var rawArgs = this.args;
|
|
101
|
-
return function evalFunctionNode(scope, args, context) {
|
|
102
|
-
var fn = resolveFn(scope);
|
|
103
|
-
return fn(rawArgs, math, createSubScope(scope, args), scope);
|
|
96
|
+
return FunctionNode.onUndefinedFunction(_name);
|
|
104
97
|
};
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
98
|
+
|
|
99
|
+
if (isRaw) {
|
|
100
|
+
// pass unevaluated parameters (nodes) to the function
|
|
101
|
+
// "raw" evaluation
|
|
102
|
+
var rawArgs = this.args;
|
|
103
|
+
return function evalFunctionNode(scope, args, context) {
|
|
104
|
+
var fn = resolveFn(scope);
|
|
105
|
+
return fn(rawArgs, math, createSubScope(scope, args), scope);
|
|
106
|
+
};
|
|
107
|
+
} else {
|
|
108
|
+
// "regular" evaluation
|
|
109
|
+
switch (evalArgs.length) {
|
|
110
|
+
case 0:
|
|
111
|
+
return function evalFunctionNode(scope, args, context) {
|
|
112
|
+
var fn = resolveFn(scope);
|
|
113
|
+
return fn();
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
case 1:
|
|
117
|
+
return function evalFunctionNode(scope, args, context) {
|
|
118
|
+
var fn = resolveFn(scope);
|
|
119
|
+
var evalArg0 = evalArgs[0];
|
|
120
|
+
return fn(evalArg0(scope, args, context));
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
case 2:
|
|
124
|
+
return function evalFunctionNode(scope, args, context) {
|
|
125
|
+
var fn = resolveFn(scope);
|
|
126
|
+
var evalArg0 = evalArgs[0];
|
|
127
|
+
var evalArg1 = evalArgs[1];
|
|
128
|
+
return fn(evalArg0(scope, args, context), evalArg1(scope, args, context));
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
default:
|
|
132
|
+
return function evalFunctionNode(scope, args, context) {
|
|
133
|
+
var fn = resolveFn(scope);
|
|
134
|
+
var values = evalArgs.map(evalArg => evalArg(scope, args, context));
|
|
135
|
+
return fn(...values);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
135
138
|
}
|
|
139
|
+
} else {
|
|
140
|
+
// the function symbol is an argName
|
|
141
|
+
var _rawArgs = this.args;
|
|
142
|
+
return function evalFunctionNode(scope, args, context) {
|
|
143
|
+
var fn = args[_name];
|
|
144
|
+
var isRaw = fn && fn.rawArgs;
|
|
145
|
+
|
|
146
|
+
if (isRaw) {
|
|
147
|
+
return fn(_rawArgs, math, createSubScope(scope, args), scope); // "raw" evaluation
|
|
148
|
+
} else {
|
|
149
|
+
var values = evalArgs.map(evalArg => evalArg(scope, args, context));
|
|
150
|
+
return fn.apply(fn, values);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
136
153
|
}
|
|
137
154
|
} else if (isAccessorNode(this.fn) && isIndexNode(this.fn.index) && this.fn.index.isObjectProperty()) {
|
|
138
155
|
// execute the function with the right context: the object of the AccessorNode
|
|
139
156
|
var evalObject = this.fn.object._compile(math, argNames);
|
|
140
157
|
|
|
141
158
|
var prop = this.fn.index.getObjectProperty();
|
|
142
|
-
var
|
|
159
|
+
var _rawArgs2 = this.args;
|
|
143
160
|
return function evalFunctionNode(scope, args, context) {
|
|
144
161
|
var object = evalObject(scope, args, context);
|
|
145
162
|
validateSafeMethod(object, prop);
|
|
146
163
|
var isRaw = object[prop] && object[prop].rawArgs;
|
|
147
164
|
|
|
148
165
|
if (isRaw) {
|
|
149
|
-
return object[prop](
|
|
166
|
+
return object[prop](_rawArgs2, math, createSubScope(scope, args), scope); // "raw" evaluation
|
|
150
167
|
} else {
|
|
151
168
|
// "regular" evaluation
|
|
152
169
|
var values = evalArgs.map(evalArg => evalArg(scope, args, context));
|
|
@@ -158,13 +175,13 @@ export var createFunctionNode = /* #__PURE__ */factory(name, dependencies, _ref
|
|
|
158
175
|
// we have to dynamically determine whether the function has a rawArgs property
|
|
159
176
|
var evalFn = this.fn._compile(math, argNames);
|
|
160
177
|
|
|
161
|
-
var
|
|
178
|
+
var _rawArgs3 = this.args;
|
|
162
179
|
return function evalFunctionNode(scope, args, context) {
|
|
163
180
|
var fn = evalFn(scope, args, context);
|
|
164
181
|
var isRaw = fn && fn.rawArgs;
|
|
165
182
|
|
|
166
183
|
if (isRaw) {
|
|
167
|
-
return fn(
|
|
184
|
+
return fn(_rawArgs3, math, createSubScope(scope, args), scope); // "raw" evaluation
|
|
168
185
|
} else {
|
|
169
186
|
// "regular" evaluation
|
|
170
187
|
var values = evalArgs.map(evalArg => evalArg(scope, args, context));
|
|
@@ -241,18 +241,22 @@ export var createParse = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
241
241
|
function getToken(state) {
|
|
242
242
|
state.tokenType = TOKENTYPE.NULL;
|
|
243
243
|
state.token = '';
|
|
244
|
-
state.comment = ''; // skip over
|
|
245
|
-
// space, tab, and newline when inside parameters
|
|
244
|
+
state.comment = ''; // skip over ignored characters:
|
|
246
245
|
|
|
247
|
-
while (
|
|
248
|
-
|
|
249
|
-
|
|
246
|
+
while (true) {
|
|
247
|
+
// comments:
|
|
248
|
+
if (currentCharacter(state) === '#') {
|
|
249
|
+
while (currentCharacter(state) !== '\n' && currentCharacter(state) !== '') {
|
|
250
|
+
state.comment += currentCharacter(state);
|
|
251
|
+
next(state);
|
|
252
|
+
}
|
|
253
|
+
} // whitespace: space, tab, and newline when inside parameters
|
|
250
254
|
|
|
251
255
|
|
|
252
|
-
|
|
253
|
-
while (currentCharacter(state) !== '\n' && currentCharacter(state) !== '') {
|
|
254
|
-
state.comment += currentCharacter(state);
|
|
256
|
+
if (parse.isWhitespace(currentCharacter(state), state.nestingLevel)) {
|
|
255
257
|
next(state);
|
|
258
|
+
} else {
|
|
259
|
+
break;
|
|
256
260
|
}
|
|
257
261
|
} // check for end of expression
|
|
258
262
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { isBigNumber, isCollection, isNumber } from '../../utils/is.js';
|
|
2
|
+
import { factory } from '../../utils/factory.js';
|
|
3
|
+
import { errorTransform } from './utils/errorTransform.js';
|
|
4
|
+
import { createCumSum } from '../../function/statistics/cumsum.js';
|
|
5
|
+
/**
|
|
6
|
+
* Attach a transform function to math.sum
|
|
7
|
+
* Adds a property transform containing the transform function.
|
|
8
|
+
*
|
|
9
|
+
* This transform changed the last `dim` parameter of function sum
|
|
10
|
+
* from one-based to zero based
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
var name = 'cumsum';
|
|
14
|
+
var dependencies = ['typed', 'add', 'unaryPlus'];
|
|
15
|
+
export var createCumSumTransform = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
16
|
+
var {
|
|
17
|
+
typed,
|
|
18
|
+
add,
|
|
19
|
+
unaryPlus
|
|
20
|
+
} = _ref;
|
|
21
|
+
var cumsum = createCumSum({
|
|
22
|
+
typed,
|
|
23
|
+
add,
|
|
24
|
+
unaryPlus
|
|
25
|
+
});
|
|
26
|
+
return typed(name, {
|
|
27
|
+
'...any': function any(args) {
|
|
28
|
+
// change last argument dim from one-based to zero-based
|
|
29
|
+
if (args.length === 2 && isCollection(args[0])) {
|
|
30
|
+
var dim = args[1];
|
|
31
|
+
|
|
32
|
+
if (isNumber(dim)) {
|
|
33
|
+
args[1] = dim - 1;
|
|
34
|
+
} else if (isBigNumber(dim)) {
|
|
35
|
+
args[1] = dim.minus(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
return cumsum.apply(null, args);
|
|
41
|
+
} catch (err) {
|
|
42
|
+
throw errorTransform(err);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}, {
|
|
47
|
+
isTransformFunction: true
|
|
48
|
+
});
|
|
@@ -6,7 +6,7 @@ import { lastDimToZeroBase } from './utils/lastDimToZeroBase.js';
|
|
|
6
6
|
* Attach a transform function to math.sum
|
|
7
7
|
* Adds a property transform containing the transform function.
|
|
8
8
|
*
|
|
9
|
-
* This transform changed the last `dim` parameter of function
|
|
9
|
+
* This transform changed the last `dim` parameter of function sum
|
|
10
10
|
* from one-based to zero based
|
|
11
11
|
*/
|
|
12
12
|
|
package/lib/esm/factoriesAny.js
CHANGED
|
@@ -221,6 +221,7 @@ export { createDivide } from './function/arithmetic/divide.js';
|
|
|
221
221
|
export { createDistance } from './function/geometry/distance.js';
|
|
222
222
|
export { createIntersect } from './function/geometry/intersect.js';
|
|
223
223
|
export { createSum } from './function/statistics/sum.js';
|
|
224
|
+
export { createCumSum } from './function/statistics/cumsum.js';
|
|
224
225
|
export { createMean } from './function/statistics/mean.js';
|
|
225
226
|
export { createMedian } from './function/statistics/median.js';
|
|
226
227
|
export { createMad } from './function/statistics/mad.js';
|
|
@@ -245,6 +246,7 @@ export { createLeafCount } from './function/algebra/leafCount.js';
|
|
|
245
246
|
export { createSimplify } from './function/algebra/simplify.js';
|
|
246
247
|
export { createSimplifyCore } from './function/algebra/simplifyCore.js';
|
|
247
248
|
export { createResolve } from './function/algebra/resolve.js';
|
|
249
|
+
export { createSymbolicEqual } from './function/algebra/symbolicEqual.js';
|
|
248
250
|
export { createDerivative } from './function/algebra/derivative.js';
|
|
249
251
|
export { createRationalize } from './function/algebra/rationalize.js';
|
|
250
252
|
export { createReviver } from './json/reviver.js';
|
|
@@ -268,4 +270,5 @@ export { createConcatTransform } from './expression/transform/concat.transform.j
|
|
|
268
270
|
export { createDiffTransform } from './expression/transform/diff.transform.js';
|
|
269
271
|
export { createStdTransform } from './expression/transform/std.transform.js';
|
|
270
272
|
export { createSumTransform } from './expression/transform/sum.transform.js';
|
|
273
|
+
export { createCumSumTransform } from './expression/transform/cumsum.transform.js';
|
|
271
274
|
export { createVarianceTransform } from './expression/transform/variance.transform.js';
|
|
@@ -146,6 +146,7 @@ export { createProd } from './function/statistics/prod.js';
|
|
|
146
146
|
export { createMax } from './function/statistics/max.js';
|
|
147
147
|
export { createMin } from './function/statistics/min.js';
|
|
148
148
|
export { createSum } from './function/statistics/sum.js';
|
|
149
|
+
export { createCumSum } from './function/statistics/cumsum.js';
|
|
149
150
|
export { createMean } from './function/statistics/mean.js';
|
|
150
151
|
export { createMedian } from './function/statistics/median.js';
|
|
151
152
|
export { createMad } from './function/statistics/mad.js';
|
|
@@ -195,6 +196,7 @@ export var createSubsetTransform = /* #__PURE__ */factory('subset', [], () => no
|
|
|
195
196
|
});
|
|
196
197
|
export { createStdTransform } from './expression/transform/std.transform.js';
|
|
197
198
|
export { createSumTransform } from './expression/transform/sum.transform.js';
|
|
199
|
+
export { createCumSumTransform } from './expression/transform/cumsum.transform.js';
|
|
198
200
|
export { createVarianceTransform } from './expression/transform/variance.transform.js'; // utils
|
|
199
201
|
|
|
200
202
|
export { createClone } from './function/utils/clone.js';
|
|
@@ -327,6 +327,14 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
327
327
|
total: true
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
|
+
}, {
|
|
331
|
+
s: 'n-n -> 0',
|
|
332
|
+
// partial alternative when we can't always subtract
|
|
333
|
+
assuming: {
|
|
334
|
+
subtract: {
|
|
335
|
+
total: false
|
|
336
|
+
}
|
|
337
|
+
}
|
|
330
338
|
}, {
|
|
331
339
|
s: '-(c*v) -> v * (-c)',
|
|
332
340
|
// make non-constant terms positive
|
|
@@ -206,9 +206,9 @@ export var createSimplifyCore = /* #__PURE__ */factory(name, dependencies, _ref
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
|
-
|
|
210
|
-
return new OperatorNode(node.op, node.fn, [_a, a1]);
|
|
211
209
|
}
|
|
210
|
+
|
|
211
|
+
return new OperatorNode(node.op, node.fn, [_a, a1]);
|
|
212
212
|
} else if (isFunctionNode(node)) {
|
|
213
213
|
return new FunctionNode(simplifyCore(node.fn), node.args.map(n => simplifyCore(n, options)));
|
|
214
214
|
} else if (isArrayNode(node)) {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { isConstantNode } from '../../utils/is.js';
|
|
2
|
+
import { factory } from '../../utils/factory.js';
|
|
3
|
+
var name = 'symbolicEqual';
|
|
4
|
+
var dependencies = ['parse', 'simplify', 'typed', 'OperatorNode'];
|
|
5
|
+
export var createSymbolicEqual = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
6
|
+
var {
|
|
7
|
+
parse,
|
|
8
|
+
simplify,
|
|
9
|
+
typed,
|
|
10
|
+
OperatorNode
|
|
11
|
+
} = _ref;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Attempts to determine if two expressions are symbolically equal, i.e.
|
|
15
|
+
* one is the result of valid algebraic manipulations on the other.
|
|
16
|
+
* Currently, this simply checks if the difference of the two expressions
|
|
17
|
+
* simplifies down to 0. So there are two important caveats:
|
|
18
|
+
* 1. whether two expressions are symbolically equal depends on the
|
|
19
|
+
* manipulations allowed. Therefore, this function takes an optional
|
|
20
|
+
* third argument, which are the options that control the behavior
|
|
21
|
+
* as documented for the `simplify()` function.
|
|
22
|
+
* 2. it is in general intractable to find the minimal simplification of
|
|
23
|
+
* an arbitrarily complicated expression. So while a `true` value
|
|
24
|
+
* of `symbolicEqual` ensures that the two expressions can be manipulated
|
|
25
|
+
* to match each other, a `false` value does not absolutely rule this out.
|
|
26
|
+
*
|
|
27
|
+
* Syntax:
|
|
28
|
+
*
|
|
29
|
+
* symbolicEqual(expr1, expr2)
|
|
30
|
+
* symbolicEqual(expr1, expr2, options)
|
|
31
|
+
*
|
|
32
|
+
* Examples:
|
|
33
|
+
*
|
|
34
|
+
* symbolicEqual('x*y', 'y*x') // true
|
|
35
|
+
* symbolicEqual('x*y', 'y*x', {context: {multiply: {commutative: false}}})
|
|
36
|
+
* //false
|
|
37
|
+
* symbolicEqual('x/y', '(y*x^(-1))^(-1)') // true
|
|
38
|
+
* symbolicEqual('abs(x)','x') // false
|
|
39
|
+
* symbolicEqual('abs(x)','x', simplify.positiveContext) // true
|
|
40
|
+
*
|
|
41
|
+
* See also:
|
|
42
|
+
*
|
|
43
|
+
* simplify, evaluate
|
|
44
|
+
*
|
|
45
|
+
* @param {Node|string} expr1 The first expression to compare
|
|
46
|
+
* @param {Node|string} expr2 The second expression to compare
|
|
47
|
+
* @param {Object} [options] Optional option object, passed to simplify
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
* Returns true if a valid manipulation making the expressions equal
|
|
50
|
+
* is found.
|
|
51
|
+
*/
|
|
52
|
+
return typed(name, {
|
|
53
|
+
'string, string': function stringString(s1, s2) {
|
|
54
|
+
return this(parse(s1), parse(s2), {});
|
|
55
|
+
},
|
|
56
|
+
'string, string, Object': function stringStringObject(s1, s2, options) {
|
|
57
|
+
return this(parse(s1), parse(s2), options);
|
|
58
|
+
},
|
|
59
|
+
'Node, string': function NodeString(e1, s2) {
|
|
60
|
+
return this(e1, parse(s2), {});
|
|
61
|
+
},
|
|
62
|
+
'Node, string, Object': function NodeStringObject(e1, s2, options) {
|
|
63
|
+
return this(e1, parse(s2), options);
|
|
64
|
+
},
|
|
65
|
+
'string, Node': function stringNode(s1, e2) {
|
|
66
|
+
return this(parse(s1), e2, {});
|
|
67
|
+
},
|
|
68
|
+
'string, Node, Object': function stringNodeObject(s1, e2, options) {
|
|
69
|
+
return this(parse(s1), e2, options);
|
|
70
|
+
},
|
|
71
|
+
'Node, Node': function NodeNode(e1, e2) {
|
|
72
|
+
return this(e1, e2, {});
|
|
73
|
+
},
|
|
74
|
+
'Node, Node, Object': function NodeNodeObject(e1, e2, options) {
|
|
75
|
+
var diff = new OperatorNode('-', 'subtract', [e1, e2]);
|
|
76
|
+
var simplified = simplify(diff, {}, options);
|
|
77
|
+
return isConstantNode(simplified) && !simplified.value;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -38,32 +38,36 @@ export function createComplexEigs(_ref) {
|
|
|
38
38
|
} // TODO check if any row/col are zero except the diagonal
|
|
39
39
|
// make sure corresponding rows and columns have similar magnitude
|
|
40
40
|
// important because of numerical stability
|
|
41
|
+
// MODIFIES arr by side effect!
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
var R = balance(arr, N, prec, type, findVectors); // R is the row transformation matrix
|
|
44
|
-
// A' = R A R⁻¹, A is the original matrix
|
|
45
|
+
// arr = A' = R A R⁻¹, A is the original matrix
|
|
45
46
|
// (if findVectors is false, R is undefined)
|
|
47
|
+
// (And so to return to original matrix: A = R⁻¹ arr R)
|
|
46
48
|
// TODO if magnitudes of elements vary over many orders,
|
|
47
49
|
// move greatest elements to the top left corner
|
|
48
50
|
// using similarity transformations, reduce the matrix
|
|
49
51
|
// to Hessenberg form (upper triangular plus one subdiagonal row)
|
|
50
52
|
// updates the transformation matrix R with new row operationsq
|
|
53
|
+
// MODIFIES arr by side effect!
|
|
51
54
|
|
|
52
|
-
reduceToHessenberg(arr, N, prec, type, findVectors, R); //
|
|
55
|
+
reduceToHessenberg(arr, N, prec, type, findVectors, R); // still true that original A = R⁻¹ arr R)
|
|
56
|
+
// find eigenvalues
|
|
53
57
|
|
|
54
58
|
var {
|
|
55
59
|
values,
|
|
56
60
|
C
|
|
57
61
|
} = iterateUntilTriangular(arr, N, prec, type, findVectors); // values is the list of eigenvalues, C is the column
|
|
58
|
-
// transformation matrix that transforms the hessenberg
|
|
59
|
-
// matrix to upper triangular
|
|
60
|
-
//
|
|
62
|
+
// transformation matrix that transforms arr, the hessenberg
|
|
63
|
+
// matrix, to upper triangular
|
|
64
|
+
// (So U = C⁻¹ arr C and the relationship between current arr
|
|
65
|
+
// and original A is unchanged.)
|
|
61
66
|
|
|
62
|
-
C = multiply(inv(R), C);
|
|
63
67
|
var vectors;
|
|
64
68
|
|
|
65
69
|
if (findVectors) {
|
|
66
|
-
vectors = findEigenvectors(arr, N, C, values, prec, type);
|
|
70
|
+
vectors = findEigenvectors(arr, N, C, R, values, prec, type);
|
|
67
71
|
vectors = matrixFromColumns(...vectors);
|
|
68
72
|
}
|
|
69
73
|
|
|
@@ -84,8 +88,9 @@ export function createComplexEigs(_ref) {
|
|
|
84
88
|
function balance(arr, N, prec, type, findVectors) {
|
|
85
89
|
var big = type === 'BigNumber';
|
|
86
90
|
var cplx = type === 'Complex';
|
|
87
|
-
var
|
|
88
|
-
var one = big ? bignumber(1) : cplx ? complex(1) : 1;
|
|
91
|
+
var realzero = big ? bignumber(0) : 0;
|
|
92
|
+
var one = big ? bignumber(1) : cplx ? complex(1) : 1;
|
|
93
|
+
var realone = big ? bignumber(1) : 1; // base of the floating-point arithmetic
|
|
89
94
|
|
|
90
95
|
var radix = big ? bignumber(10) : 2;
|
|
91
96
|
var radixSq = multiplyScalar(radix, radix); // the diagonal transformation matrix R
|
|
@@ -106,12 +111,13 @@ export function createComplexEigs(_ref) {
|
|
|
106
111
|
for (var i = 0; i < N; i++) {
|
|
107
112
|
// compute the taxicab norm of i-th column and row
|
|
108
113
|
// TODO optimize for complex numbers
|
|
109
|
-
var colNorm =
|
|
110
|
-
var rowNorm =
|
|
114
|
+
var colNorm = realzero;
|
|
115
|
+
var rowNorm = realzero;
|
|
111
116
|
|
|
112
117
|
for (var j = 0; j < N; j++) {
|
|
113
118
|
if (i === j) continue;
|
|
114
|
-
var c = abs(arr[i][j]);
|
|
119
|
+
var c = abs(arr[i][j]); // should be real
|
|
120
|
+
|
|
115
121
|
colNorm = addScalar(colNorm, c);
|
|
116
122
|
rowNorm = addScalar(rowNorm, c);
|
|
117
123
|
}
|
|
@@ -120,7 +126,7 @@ export function createComplexEigs(_ref) {
|
|
|
120
126
|
// find integer power closest to balancing the matrix
|
|
121
127
|
// (we want to scale only by integer powers of radix,
|
|
122
128
|
// so that we don't lose any precision due to round-off)
|
|
123
|
-
var f =
|
|
129
|
+
var f = realone;
|
|
124
130
|
var _c = colNorm;
|
|
125
131
|
var rowDivRadix = divideScalar(rowNorm, radix);
|
|
126
132
|
var rowMulRadix = multiplyScalar(rowNorm, radix);
|
|
@@ -392,16 +398,17 @@ export function createComplexEigs(_ref) {
|
|
|
392
398
|
};
|
|
393
399
|
}
|
|
394
400
|
/**
|
|
395
|
-
* @param {Matrix} A
|
|
401
|
+
* @param {Matrix} A hessenberg-form matrix
|
|
396
402
|
* @param {number} N size of A
|
|
397
403
|
* @param {Matrix} C column transformation matrix that turns A into upper triangular
|
|
404
|
+
* @param {Matrix} R similarity that turns original matrix into A
|
|
398
405
|
* @param {number[]} values array of eigenvalues of A
|
|
399
406
|
* @param {'number'|'BigNumber'|'Complex'} type
|
|
400
407
|
* @returns {number[][]} eigenvalues
|
|
401
408
|
*/
|
|
402
409
|
|
|
403
410
|
|
|
404
|
-
function findEigenvectors(A, N, C, values, prec, type) {
|
|
411
|
+
function findEigenvectors(A, N, C, R, values, prec, type) {
|
|
405
412
|
var Cinv = inv(C);
|
|
406
413
|
var U = multiply(Cinv, A, C);
|
|
407
414
|
var big = type === 'BigNumber';
|
|
@@ -434,30 +441,34 @@ export function createComplexEigs(_ref) {
|
|
|
434
441
|
|
|
435
442
|
var failedLambdas = [];
|
|
436
443
|
|
|
437
|
-
|
|
438
|
-
var
|
|
439
|
-
|
|
440
|
-
var _A = subtract(U, multiply(_λ, E)); // the characteristic matrix
|
|
441
|
-
|
|
444
|
+
var _loop = function _loop(_i4) {
|
|
445
|
+
var λ = uniqueValues[_i4];
|
|
446
|
+
var S = subtract(U, multiply(λ, E)); // the characteristic matrix
|
|
442
447
|
|
|
443
|
-
var solutions = usolveAll(
|
|
444
|
-
solutions = solutions.map(v => multiply(C, v));
|
|
448
|
+
var solutions = usolveAll(S, b);
|
|
445
449
|
solutions.shift(); // ignore the null vector
|
|
446
450
|
// looks like we missed something, try inverse iteration
|
|
447
451
|
|
|
448
452
|
while (solutions.length < multiplicities[_i4]) {
|
|
449
|
-
var approxVec = inverseIterate(
|
|
453
|
+
var approxVec = inverseIterate(S, N, solutions, prec, type);
|
|
450
454
|
|
|
451
455
|
if (approxVec == null) {
|
|
452
456
|
// no more vectors were found
|
|
453
|
-
failedLambdas.push(
|
|
457
|
+
failedLambdas.push(λ);
|
|
454
458
|
break;
|
|
455
459
|
}
|
|
456
460
|
|
|
457
461
|
solutions.push(approxVec);
|
|
458
|
-
}
|
|
462
|
+
} // Transform back into original array coordinates
|
|
463
|
+
|
|
459
464
|
|
|
465
|
+
var correction = multiply(inv(R), C);
|
|
466
|
+
solutions = solutions.map(v => multiply(correction, v));
|
|
460
467
|
vectors.push(...solutions.map(v => flatten(v)));
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
for (var _i4 = 0; _i4 < len; _i4++) {
|
|
471
|
+
_loop(_i4);
|
|
461
472
|
}
|
|
462
473
|
|
|
463
474
|
if (failedLambdas.length !== 0) {
|
|
@@ -8,8 +8,15 @@ export var createMap = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
8
8
|
} = _ref;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Create a new matrix or array with the results of
|
|
12
|
-
* each entry of
|
|
11
|
+
* Create a new matrix or array with the results of a callback function executed on
|
|
12
|
+
* each entry of a given matrix/array.
|
|
13
|
+
*
|
|
14
|
+
* For each entry of the input, the callback is invoked with three arguments:
|
|
15
|
+
* the value of the entry, the index at which that entry occurs, and the full
|
|
16
|
+
* matrix/array being traversed. Note that because the matrix/array might be
|
|
17
|
+
* multidimensional, the "index" argument is always an array of numbers giving
|
|
18
|
+
* the index in each dimension. This is true even for vectors: the "index"
|
|
19
|
+
* argument is an array of length 1, rather than simply a number.
|
|
13
20
|
*
|
|
14
21
|
* Syntax:
|
|
15
22
|
*
|
|
@@ -21,15 +28,25 @@ export var createMap = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
21
28
|
* return value * value
|
|
22
29
|
* }) // returns [1, 4, 9]
|
|
23
30
|
*
|
|
31
|
+
* // The calling convention for the callback can cause subtleties:
|
|
32
|
+
* math.map([1, 2, 3], math.format)
|
|
33
|
+
* // throws TypeError: map attempted to call 'format(1,[0])' but argument 2 of type Array does not match expected type number or function or Object or string or boolean
|
|
34
|
+
* // [This happens because `format` _can_ take a second argument,
|
|
35
|
+
* // but its semantics don't match that of the 2nd argument `map` provides]
|
|
36
|
+
*
|
|
37
|
+
* // To avoid this error, use a function that takes exactly the
|
|
38
|
+
* // desired arguments:
|
|
39
|
+
* math.map([1, 2, 3], x => math.format(x)) // returns ['1', '2', '3']
|
|
40
|
+
*
|
|
24
41
|
* See also:
|
|
25
42
|
*
|
|
26
43
|
* filter, forEach, sort
|
|
27
44
|
*
|
|
28
|
-
* @param {Matrix | Array} x The
|
|
29
|
-
* @param {Function} callback
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
45
|
+
* @param {Matrix | Array} x The input to iterate on.
|
|
46
|
+
* @param {Function} callback
|
|
47
|
+
* The function to call (as described above) on each entry of the input
|
|
48
|
+
* @return {Matrix | array}
|
|
49
|
+
* Transformed map of x; always has the same type and shape as x
|
|
33
50
|
*/
|
|
34
51
|
return typed(name, {
|
|
35
52
|
'Array, function': _map,
|
|
@@ -57,14 +74,35 @@ function _map(array, callback) {
|
|
|
57
74
|
return recurse(child, index.concat(i));
|
|
58
75
|
});
|
|
59
76
|
} else {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
77
|
+
try {
|
|
78
|
+
// invoke the callback function with the right number of arguments
|
|
79
|
+
if (args === 1) {
|
|
80
|
+
return callback(value);
|
|
81
|
+
} else if (args === 2) {
|
|
82
|
+
return callback(value, index);
|
|
83
|
+
} else {
|
|
84
|
+
// 3 or -1
|
|
85
|
+
return callback(value, index, array);
|
|
86
|
+
}
|
|
87
|
+
} catch (err) {
|
|
88
|
+
// But maybe the arguments still weren't right
|
|
89
|
+
if (err instanceof TypeError && 'data' in err && err.data.category === 'wrongType') {
|
|
90
|
+
var newmsg = "map attempted to call '".concat(err.data.fn, "(").concat(value);
|
|
91
|
+
var indexString = JSON.stringify(index);
|
|
92
|
+
|
|
93
|
+
if (args === 2) {
|
|
94
|
+
newmsg += ',' + indexString;
|
|
95
|
+
} else if (args !== 1) {
|
|
96
|
+
newmsg += ",".concat(indexString, ",").concat(array);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
newmsg += ")' but argument ".concat(err.data.index + 1, " of type ");
|
|
100
|
+
newmsg += "".concat(err.data.actual, " does not match expected type ");
|
|
101
|
+
newmsg += err.data.expected.join(' or ');
|
|
102
|
+
throw new TypeError(newmsg);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
throw err;
|
|
68
106
|
}
|
|
69
107
|
}
|
|
70
108
|
};
|