mathjs 10.0.2 → 10.1.0
Sign up to get free protection for your applications and to get access to all the features.
- package/HISTORY.md +11 -0
- package/NOTICE +1 -1
- package/README.md +10 -2
- package/bin/cli.js +1 -1
- package/docs/expressions/syntax.md +1 -1
- package/docs/reference/functions/invmod.md +41 -0
- package/docs/reference/functions.md +1 -0
- package/lib/browser/math.js +6 -6
- package/lib/browser/math.js.map +1 -1
- package/lib/cjs/entry/dependenciesAny/dependenciesInvmod.generated.js +41 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesRationalize.generated.js +15 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesSimplify.generated.js +15 -0
- package/lib/cjs/entry/dependenciesAny.generated.js +8 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesRationalize.generated.js +15 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesSimplify.generated.js +15 -0
- package/lib/cjs/entry/impureFunctionsAny.generated.js +11 -0
- package/lib/cjs/entry/impureFunctionsNumber.generated.js +10 -0
- package/lib/cjs/entry/pureFunctionsAny.generated.js +14 -2
- package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +6 -1
- package/lib/cjs/expression/embeddedDocs/function/arithmetic/invmod.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/matrix/forEach.js +1 -1
- package/lib/cjs/factoriesAny.js +8 -0
- package/lib/cjs/function/algebra/rationalize.js +18 -4
- package/lib/cjs/function/algebra/simplify/simplifyConstant.js +223 -29
- package/lib/cjs/function/algebra/simplify/simplifyCore.js +34 -6
- package/lib/cjs/function/algebra/simplify.js +70 -22
- package/lib/cjs/function/arithmetic/invmod.js +73 -0
- package/lib/cjs/header.js +3 -3
- package/lib/cjs/version.js +1 -1
- package/lib/esm/entry/dependenciesAny/dependenciesInvmod.generated.js +24 -0
- package/lib/esm/entry/dependenciesAny/dependenciesRationalize.generated.js +10 -0
- package/lib/esm/entry/dependenciesAny/dependenciesSimplify.generated.js +10 -0
- package/lib/esm/entry/dependenciesAny.generated.js +1 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesRationalize.generated.js +10 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesSimplify.generated.js +10 -0
- package/lib/esm/entry/impureFunctionsAny.generated.js +12 -1
- package/lib/esm/entry/impureFunctionsNumber.generated.js +10 -0
- package/lib/esm/entry/pureFunctionsAny.generated.js +12 -1
- package/lib/esm/expression/embeddedDocs/embeddedDocs.js +4 -1
- package/lib/esm/expression/embeddedDocs/function/arithmetic/invmod.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/matrix/forEach.js +1 -1
- package/lib/esm/factoriesAny.js +1 -0
- package/lib/esm/function/algebra/rationalize.js +18 -4
- package/lib/esm/function/algebra/simplify/simplifyConstant.js +197 -29
- package/lib/esm/function/algebra/simplify/simplifyCore.js +35 -7
- package/lib/esm/function/algebra/simplify.js +70 -22
- package/lib/esm/function/arithmetic/invmod.js +57 -0
- package/lib/esm/header.js +1 -1
- package/lib/esm/version.js +1 -1
- package/package.json +2 -1
@@ -1,20 +1,25 @@
|
|
1
1
|
// TODO this could be improved by simplifying seperated constants under associative and commutative operators
|
2
|
-
import { isFraction, isNode, isOperatorNode } from '../../../utils/is.js';
|
2
|
+
import { isFraction, isMatrix, isNode, isArrayNode, isConstantNode, isIndexNode, isObjectNode, isOperatorNode } from '../../../utils/is.js';
|
3
3
|
import { factory } from '../../../utils/factory.js';
|
4
4
|
import { createUtil } from './util.js';
|
5
5
|
import { noBignumber, noFraction } from '../../../utils/noop.js';
|
6
6
|
var name = 'simplifyConstant';
|
7
|
-
var dependencies = ['typed', 'config', 'mathWithTransform', '?fraction', '?bignumber', '
|
7
|
+
var dependencies = ['typed', 'config', 'mathWithTransform', 'matrix', '?fraction', '?bignumber', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'SymbolNode'];
|
8
8
|
export var createSimplifyConstant = /* #__PURE__ */factory(name, dependencies, _ref => {
|
9
9
|
var {
|
10
10
|
typed,
|
11
11
|
config,
|
12
12
|
mathWithTransform,
|
13
|
+
matrix,
|
13
14
|
fraction,
|
14
15
|
bignumber,
|
16
|
+
AccessorNode,
|
17
|
+
ArrayNode,
|
15
18
|
ConstantNode,
|
16
|
-
OperatorNode,
|
17
19
|
FunctionNode,
|
20
|
+
IndexNode,
|
21
|
+
ObjectNode,
|
22
|
+
OperatorNode,
|
18
23
|
SymbolNode
|
19
24
|
} = _ref;
|
20
25
|
var {
|
@@ -29,22 +34,31 @@ export var createSimplifyConstant = /* #__PURE__ */factory(name, dependencies, _
|
|
29
34
|
});
|
30
35
|
|
31
36
|
function simplifyConstant(expr, options) {
|
32
|
-
|
33
|
-
|
37
|
+
return _ensureNode(foldFraction(expr, options));
|
38
|
+
}
|
39
|
+
|
40
|
+
function _removeFractions(thing) {
|
41
|
+
if (isFraction(thing)) {
|
42
|
+
return thing.valueOf();
|
43
|
+
}
|
44
|
+
|
45
|
+
if (thing instanceof Array) {
|
46
|
+
return thing.map(_removeFractions);
|
47
|
+
}
|
48
|
+
|
49
|
+
if (isMatrix(thing)) {
|
50
|
+
return matrix(_removeFractions(thing.valueOf()));
|
51
|
+
}
|
52
|
+
|
53
|
+
return thing;
|
34
54
|
}
|
35
55
|
|
36
56
|
function _eval(fnname, args, options) {
|
37
57
|
try {
|
38
|
-
return
|
58
|
+
return mathWithTransform[fnname].apply(null, args);
|
39
59
|
} catch (ignore) {
|
40
60
|
// sometimes the implicit type conversion causes the evaluation to fail, so we'll try again after removing Fractions
|
41
|
-
args = args.map(
|
42
|
-
if (isFraction(x)) {
|
43
|
-
return x.valueOf();
|
44
|
-
}
|
45
|
-
|
46
|
-
return x;
|
47
|
-
});
|
61
|
+
args = args.map(_removeFractions);
|
48
62
|
return _toNumber(mathWithTransform[fnname].apply(null, args), options);
|
49
63
|
}
|
50
64
|
}
|
@@ -67,8 +81,22 @@ export var createSimplifyConstant = /* #__PURE__ */factory(name, dependencies, _
|
|
67
81
|
},
|
68
82
|
Complex: function Complex(s) {
|
69
83
|
throw new Error('Cannot convert Complex number to Node');
|
84
|
+
},
|
85
|
+
string: function string(s) {
|
86
|
+
return new ConstantNode(s);
|
87
|
+
},
|
88
|
+
Matrix: function Matrix(m) {
|
89
|
+
return new ArrayNode(m.valueOf().map(e => _toNode(e)));
|
90
|
+
}
|
91
|
+
});
|
92
|
+
|
93
|
+
function _ensureNode(thing) {
|
94
|
+
if (isNode(thing)) {
|
95
|
+
return thing;
|
70
96
|
}
|
71
|
-
|
97
|
+
|
98
|
+
return _toNode(thing);
|
99
|
+
} // convert a number to a fraction only if it can be expressed exactly,
|
72
100
|
// and when both numerator and denominator are small enough
|
73
101
|
|
74
102
|
|
@@ -125,6 +153,12 @@ export var createSimplifyConstant = /* #__PURE__ */factory(name, dependencies, _
|
|
125
153
|
}
|
126
154
|
|
127
155
|
return _exactFraction(s.re, options);
|
156
|
+
},
|
157
|
+
'Matrix, Object': function MatrixObject(s, options) {
|
158
|
+
return matrix(_exactFraction(s.valueOf()));
|
159
|
+
},
|
160
|
+
'Array, Object': function ArrayObject(s, options) {
|
161
|
+
return s.map(_exactFraction);
|
128
162
|
}
|
129
163
|
});
|
130
164
|
|
@@ -148,6 +182,103 @@ export var createSimplifyConstant = /* #__PURE__ */factory(name, dependencies, _
|
|
148
182
|
|
149
183
|
return new OperatorNode('/', 'divide', [n, new ConstantNode(f.d)]);
|
150
184
|
}
|
185
|
+
/* Handles constant indexing of ArrayNodes, matrices, and ObjectNodes */
|
186
|
+
|
187
|
+
|
188
|
+
function _foldAccessor(obj, index, options) {
|
189
|
+
if (!isIndexNode(index)) {
|
190
|
+
// don't know what to do with that...
|
191
|
+
return new AccessorNode(_ensureNode(obj), _ensureNode(index));
|
192
|
+
}
|
193
|
+
|
194
|
+
if (isArrayNode(obj) || isMatrix(obj)) {
|
195
|
+
var remainingDims = Array.from(index.dimensions);
|
196
|
+
/* We will resolve constant indices one at a time, looking
|
197
|
+
* just in the first or second dimensions because (a) arrays
|
198
|
+
* of more than two dimensions are likely rare, and (b) pulling
|
199
|
+
* out the third or higher dimension would be pretty intricate.
|
200
|
+
* The price is that we miss simplifying [..3d array][x,y,1]
|
201
|
+
*/
|
202
|
+
|
203
|
+
while (remainingDims.length > 0) {
|
204
|
+
if (isConstantNode(remainingDims[0]) && typeof remainingDims[0].value !== 'string') {
|
205
|
+
var first = _toNumber(remainingDims.shift().value, options);
|
206
|
+
|
207
|
+
if (isArrayNode(obj)) {
|
208
|
+
obj = obj.items[first - 1];
|
209
|
+
} else {
|
210
|
+
// matrix
|
211
|
+
obj = obj.valueOf()[first - 1];
|
212
|
+
|
213
|
+
if (obj instanceof Array) {
|
214
|
+
obj = matrix(obj);
|
215
|
+
}
|
216
|
+
}
|
217
|
+
} else if (remainingDims.length > 1 && isConstantNode(remainingDims[1]) && typeof remainingDims[1].value !== 'string') {
|
218
|
+
var second = _toNumber(remainingDims[1].value, options);
|
219
|
+
|
220
|
+
var tryItems = [];
|
221
|
+
var fromItems = isArrayNode(obj) ? obj.items : obj.valueOf();
|
222
|
+
|
223
|
+
for (var item of fromItems) {
|
224
|
+
if (isArrayNode(item)) {
|
225
|
+
tryItems.push(item.items[second - 1]);
|
226
|
+
} else if (isMatrix(obj)) {
|
227
|
+
tryItems.push(item[second - 1]);
|
228
|
+
} else {
|
229
|
+
break;
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
if (tryItems.length === fromItems.length) {
|
234
|
+
if (isArrayNode(obj)) {
|
235
|
+
obj = new ArrayNode(tryItems);
|
236
|
+
} else {
|
237
|
+
// matrix
|
238
|
+
obj = matrix(tryItems);
|
239
|
+
}
|
240
|
+
|
241
|
+
remainingDims.splice(1, 1);
|
242
|
+
} else {
|
243
|
+
// extracting slice along 2nd dimension failed, give up
|
244
|
+
break;
|
245
|
+
}
|
246
|
+
} else {
|
247
|
+
// neither 1st or 2nd dimension is constant, give up
|
248
|
+
break;
|
249
|
+
}
|
250
|
+
}
|
251
|
+
|
252
|
+
if (remainingDims.length === index.dimensions.length) {
|
253
|
+
/* No successful constant indexing */
|
254
|
+
return new AccessorNode(_ensureNode(obj), index);
|
255
|
+
}
|
256
|
+
|
257
|
+
if (remainingDims.length > 0) {
|
258
|
+
/* Indexed some but not all dimensions */
|
259
|
+
index = new IndexNode(remainingDims);
|
260
|
+
return new AccessorNode(_ensureNode(obj), index);
|
261
|
+
}
|
262
|
+
/* All dimensions were constant, access completely resolved */
|
263
|
+
|
264
|
+
|
265
|
+
return obj;
|
266
|
+
}
|
267
|
+
|
268
|
+
if (isObjectNode(obj) && index.dimensions.length === 1 && isConstantNode(index.dimensions[0])) {
|
269
|
+
var key = index.dimensions[0].value;
|
270
|
+
|
271
|
+
if (key in obj.properties) {
|
272
|
+
return obj.properties[key];
|
273
|
+
}
|
274
|
+
|
275
|
+
return new ConstantNode(); // undefined
|
276
|
+
}
|
277
|
+
/* Don't know how to index this sort of obj, at least not with this index */
|
278
|
+
|
279
|
+
|
280
|
+
return new AccessorNode(_ensureNode(obj), index);
|
281
|
+
}
|
151
282
|
/*
|
152
283
|
* Create a binary tree from a list of Fractions and Nodes.
|
153
284
|
* Tries to fold Fractions by evaluating them until the first Node in the list is hit, so
|
@@ -186,8 +317,15 @@ export var createSimplifyConstant = /* #__PURE__ */factory(name, dependencies, _
|
|
186
317
|
return node;
|
187
318
|
|
188
319
|
case 'ConstantNode':
|
189
|
-
|
190
|
-
|
320
|
+
switch (typeof node.value) {
|
321
|
+
case 'number':
|
322
|
+
return _toNumber(node.value, options);
|
323
|
+
|
324
|
+
case 'string':
|
325
|
+
return node.value;
|
326
|
+
|
327
|
+
default:
|
328
|
+
if (!isNaN(node.value)) return _toNumber(node.value, options);
|
191
329
|
}
|
192
330
|
|
193
331
|
return node;
|
@@ -207,14 +345,24 @@ export var createSimplifyConstant = /* #__PURE__ */factory(name, dependencies, _
|
|
207
345
|
if (!args.some(isNode)) {
|
208
346
|
try {
|
209
347
|
return _eval(node.name, args, options);
|
210
|
-
} catch (
|
348
|
+
} catch (ignoreandcontinue) {}
|
349
|
+
} // Size of a matrix does not depend on entries
|
350
|
+
|
351
|
+
|
352
|
+
if (node.name === 'size' && args.length === 1 && isArrayNode(args[0])) {
|
353
|
+
var sz = [];
|
354
|
+
var section = args[0];
|
355
|
+
|
356
|
+
while (isArrayNode(section)) {
|
357
|
+
sz.push(section.items.length);
|
358
|
+
section = section.items[0];
|
359
|
+
}
|
360
|
+
|
361
|
+
return matrix(sz);
|
211
362
|
} // Convert all args to nodes and construct a symbolic function call
|
212
363
|
|
213
364
|
|
214
|
-
|
215
|
-
return isNode(arg) ? arg : _toNode(arg);
|
216
|
-
});
|
217
|
-
return new FunctionNode(node.name, args);
|
365
|
+
return new FunctionNode(node.name, args.map(_ensureNode));
|
218
366
|
} else {// treat as operator
|
219
367
|
}
|
220
368
|
}
|
@@ -281,10 +429,36 @@ export var createSimplifyConstant = /* #__PURE__ */factory(name, dependencies, _
|
|
281
429
|
return foldFraction(node.content, options);
|
282
430
|
|
283
431
|
case 'AccessorNode':
|
284
|
-
|
432
|
+
return _foldAccessor(foldFraction(node.object, options), foldFraction(node.index, options), options);
|
285
433
|
|
286
434
|
case 'ArrayNode':
|
287
|
-
|
435
|
+
{
|
436
|
+
var foldItems = node.items.map(item => foldFraction(item, options));
|
437
|
+
|
438
|
+
if (foldItems.some(isNode)) {
|
439
|
+
return new ArrayNode(foldItems.map(_ensureNode));
|
440
|
+
}
|
441
|
+
/* All literals -- return a Matrix so we can operate on it */
|
442
|
+
|
443
|
+
|
444
|
+
return matrix(foldItems);
|
445
|
+
}
|
446
|
+
|
447
|
+
case 'IndexNode':
|
448
|
+
{
|
449
|
+
return new IndexNode(node.dimensions.map(n => simplifyConstant(n, options)));
|
450
|
+
}
|
451
|
+
|
452
|
+
case 'ObjectNode':
|
453
|
+
{
|
454
|
+
var foldProps = {};
|
455
|
+
|
456
|
+
for (var prop in node.properties) {
|
457
|
+
foldProps[prop] = simplifyConstant(node.properties[prop], options);
|
458
|
+
}
|
459
|
+
|
460
|
+
return new ObjectNode(foldProps);
|
461
|
+
}
|
288
462
|
|
289
463
|
case 'AssignmentNode':
|
290
464
|
/* falls through */
|
@@ -295,12 +469,6 @@ export var createSimplifyConstant = /* #__PURE__ */factory(name, dependencies, _
|
|
295
469
|
case 'FunctionAssignmentNode':
|
296
470
|
/* falls through */
|
297
471
|
|
298
|
-
case 'IndexNode':
|
299
|
-
/* falls through */
|
300
|
-
|
301
|
-
case 'ObjectNode':
|
302
|
-
/* falls through */
|
303
|
-
|
304
472
|
case 'RangeNode':
|
305
473
|
/* falls through */
|
306
474
|
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import { isConstantNode, isFunctionNode, isOperatorNode, isParenthesisNode, isSymbolNode } from '../../../utils/is.js';
|
1
|
+
import { isAccessorNode, isArrayNode, isConstantNode, isFunctionNode, isIndexNode, isObjectNode, isOperatorNode, isParenthesisNode, isSymbolNode } from '../../../utils/is.js';
|
2
2
|
import { factory } from '../../../utils/factory.js';
|
3
3
|
var name = 'simplifyCore';
|
4
|
-
var dependencies = ['equal', 'isZero', 'add', 'subtract', 'multiply', 'divide', 'pow', '
|
4
|
+
var dependencies = ['equal', 'isZero', 'add', 'subtract', 'multiply', 'divide', 'pow', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode'];
|
5
5
|
export var createSimplifyCore = /* #__PURE__ */factory(name, dependencies, _ref => {
|
6
6
|
var {
|
7
7
|
equal,
|
@@ -11,13 +11,23 @@ export var createSimplifyCore = /* #__PURE__ */factory(name, dependencies, _ref
|
|
11
11
|
multiply,
|
12
12
|
divide,
|
13
13
|
pow,
|
14
|
+
AccessorNode,
|
15
|
+
ArrayNode,
|
14
16
|
ConstantNode,
|
15
|
-
OperatorNode,
|
16
17
|
FunctionNode,
|
18
|
+
IndexNode,
|
19
|
+
ObjectNode,
|
20
|
+
OperatorNode,
|
17
21
|
ParenthesisNode
|
18
22
|
} = _ref;
|
19
23
|
var node0 = new ConstantNode(0);
|
20
24
|
var node1 = new ConstantNode(1);
|
25
|
+
|
26
|
+
function mapSimplifyCore(nodeArray) {
|
27
|
+
return nodeArray.map(simplifyCore).map(function (arg) {
|
28
|
+
return isParenthesisNode(arg) ? arg.content : arg;
|
29
|
+
});
|
30
|
+
}
|
21
31
|
/**
|
22
32
|
* simplifyCore() performs single pass simplification suitable for
|
23
33
|
* applications requiring ultimate performance. In contrast, simplify()
|
@@ -42,6 +52,7 @@ export var createSimplifyCore = /* #__PURE__ */factory(name, dependencies, _ref
|
|
42
52
|
* The expression to be simplified
|
43
53
|
*/
|
44
54
|
|
55
|
+
|
45
56
|
function simplifyCore(node) {
|
46
57
|
if (isOperatorNode(node) && node.isUnary()) {
|
47
58
|
var a0 = simplifyCore(node.args[0]);
|
@@ -177,10 +188,27 @@ export var createSimplifyCore = /* #__PURE__ */factory(name, dependencies, _ref
|
|
177
188
|
|
178
189
|
return new ParenthesisNode(c);
|
179
190
|
} else if (isFunctionNode(node)) {
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
191
|
+
return new FunctionNode(simplifyCore(node.fn), mapSimplifyCore(node.args));
|
192
|
+
} else if (isArrayNode(node)) {
|
193
|
+
return new ArrayNode(mapSimplifyCore(node.items));
|
194
|
+
} else if (isAccessorNode(node)) {
|
195
|
+
var obj = mapSimplifyCore(node.object);
|
196
|
+
|
197
|
+
if (isParenthesisNode(obj)) {
|
198
|
+
obj = obj.content;
|
199
|
+
}
|
200
|
+
|
201
|
+
return new AccessorNode(obj, simplifyCore(node.index));
|
202
|
+
} else if (isIndexNode(node)) {
|
203
|
+
return new IndexNode(mapSimplifyCore(node.dimensions));
|
204
|
+
} else if (isObjectNode(node)) {
|
205
|
+
var newProps = {};
|
206
|
+
|
207
|
+
for (var prop in node.properties) {
|
208
|
+
newProps[prop] = simplifyCore(node.properties[prop]);
|
209
|
+
}
|
210
|
+
|
211
|
+
return new ObjectNode(newProps);
|
184
212
|
} else {// cannot simplify
|
185
213
|
}
|
186
214
|
|
@@ -7,7 +7,7 @@ import { createResolve } from './simplify/resolve.js';
|
|
7
7
|
import { hasOwnProperty } from '../../utils/object.js';
|
8
8
|
import { createEmptyMap, createMap } from '../../utils/map.js';
|
9
9
|
var name = 'simplify';
|
10
|
-
var dependencies = ['config', 'typed', 'parse', 'add', 'subtract', 'multiply', 'divide', 'pow', 'isZero', 'equal', '?fraction', '?bignumber', 'mathWithTransform', 'ConstantNode', 'FunctionNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode'];
|
10
|
+
var dependencies = ['config', 'typed', 'parse', 'add', 'subtract', 'multiply', 'divide', 'pow', 'isZero', 'equal', '?fraction', '?bignumber', 'mathWithTransform', 'matrix', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode'];
|
11
11
|
export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
12
12
|
var {
|
13
13
|
config,
|
@@ -23,8 +23,13 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
23
23
|
fraction,
|
24
24
|
bignumber,
|
25
25
|
mathWithTransform,
|
26
|
+
matrix,
|
27
|
+
AccessorNode,
|
28
|
+
ArrayNode,
|
26
29
|
ConstantNode,
|
27
30
|
FunctionNode,
|
31
|
+
IndexNode,
|
32
|
+
ObjectNode,
|
28
33
|
OperatorNode,
|
29
34
|
ParenthesisNode,
|
30
35
|
SymbolNode
|
@@ -33,11 +38,16 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
33
38
|
typed,
|
34
39
|
config,
|
35
40
|
mathWithTransform,
|
41
|
+
matrix,
|
36
42
|
fraction,
|
37
43
|
bignumber,
|
44
|
+
AccessorNode,
|
45
|
+
ArrayNode,
|
38
46
|
ConstantNode,
|
39
|
-
OperatorNode,
|
40
47
|
FunctionNode,
|
48
|
+
IndexNode,
|
49
|
+
ObjectNode,
|
50
|
+
OperatorNode,
|
41
51
|
SymbolNode
|
42
52
|
});
|
43
53
|
var simplifyCore = createSimplifyCore({
|
@@ -48,9 +58,13 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
48
58
|
multiply,
|
49
59
|
divide,
|
50
60
|
pow,
|
61
|
+
AccessorNode,
|
62
|
+
ArrayNode,
|
51
63
|
ConstantNode,
|
52
|
-
OperatorNode,
|
53
64
|
FunctionNode,
|
65
|
+
IndexNode,
|
66
|
+
ObjectNode,
|
67
|
+
OperatorNode,
|
54
68
|
ParenthesisNode
|
55
69
|
});
|
56
70
|
var resolve = createResolve({
|
@@ -262,17 +276,19 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
262
276
|
l: 'log(e)',
|
263
277
|
r: '1'
|
264
278
|
}, // temporary rules
|
279
|
+
// Note initially we tend constants to the right because like-term
|
280
|
+
// collection prefers the left, and we would rather collect nonconstants
|
265
281
|
{
|
266
282
|
l: 'n-n1',
|
267
283
|
r: 'n+-n1'
|
268
284
|
}, // temporarily replace 'subtract' so we can further flatten the 'add' operator
|
269
285
|
{
|
270
286
|
l: '-(c*v)',
|
271
|
-
r: '(-c)
|
287
|
+
r: 'v * (-c)'
|
272
288
|
}, // make non-constant terms positive
|
273
289
|
{
|
274
290
|
l: '-v',
|
275
|
-
r: '(-1)
|
291
|
+
r: 'v * (-1)'
|
276
292
|
}, {
|
277
293
|
l: 'n/n1^n2',
|
278
294
|
r: 'n*n1^-n2'
|
@@ -280,6 +296,17 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
280
296
|
{
|
281
297
|
l: 'n/n1',
|
282
298
|
r: 'n*n1^-1'
|
299
|
+
}, // remove parenthesis in the case of negating a quantity
|
300
|
+
{
|
301
|
+
l: 'n1 + (n2 + n3)*(-1)',
|
302
|
+
r: 'n1 + n2*(-1) + n3*(-1)'
|
303
|
+
}, // subsume resulting -1 into constants where possible
|
304
|
+
{
|
305
|
+
l: '(-1) * c',
|
306
|
+
r: '-c'
|
307
|
+
}, {
|
308
|
+
l: '(-1) * (-c)',
|
309
|
+
r: 'c'
|
283
310
|
}, // expand nested exponentiation
|
284
311
|
{
|
285
312
|
l: '(n ^ n1) ^ n2',
|
@@ -302,20 +329,21 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
302
329
|
l: 'n+-n',
|
303
330
|
r: '0'
|
304
331
|
}, {
|
305
|
-
l: '
|
306
|
-
r: '(
|
307
|
-
},
|
308
|
-
l: 'n1*n3 + n2*n3',
|
309
|
-
r: '(n1+n2)*n3'
|
310
|
-
}, // remove parenthesis in the case of negating a quantitiy
|
332
|
+
l: 'v*n + v',
|
333
|
+
r: 'v*(n+1)'
|
334
|
+
}, // NOTE: leftmost position is special:
|
311
335
|
{
|
312
|
-
l: 'n1 +
|
313
|
-
r: 'n1
|
336
|
+
l: 'n3*n1 + n3*n2',
|
337
|
+
r: 'n3*(n1+n2)'
|
338
|
+
}, // All sub-monomials tried there.
|
339
|
+
{
|
340
|
+
l: 'n*c + c',
|
341
|
+
r: '(n+1)*c'
|
314
342
|
}, simplifyConstant, {
|
315
343
|
l: '(-n)*n1',
|
316
344
|
r: '-(n*n1)'
|
317
345
|
}, // make factors positive (and undo 'make non-constant terms positive')
|
318
|
-
// ordering of constants
|
346
|
+
// final ordering of constants
|
319
347
|
{
|
320
348
|
l: 'c+v',
|
321
349
|
r: 'v+c',
|
@@ -419,7 +447,7 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
419
447
|
};
|
420
448
|
|
421
449
|
if (rule.context) {
|
422
|
-
newRule.
|
450
|
+
newRule.context = rule.context;
|
423
451
|
}
|
424
452
|
|
425
453
|
if (rule.evaluate) {
|
@@ -463,6 +491,14 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
463
491
|
function _getExpandPlaceholderSymbol() {
|
464
492
|
return new SymbolNode('_p' + _lastsym++);
|
465
493
|
}
|
494
|
+
|
495
|
+
function mapRule(nodes, rule) {
|
496
|
+
if (nodes) {
|
497
|
+
for (var i = 0; i < nodes.length; ++i) {
|
498
|
+
nodes[i] = applyRule(nodes[i], rule);
|
499
|
+
}
|
500
|
+
}
|
501
|
+
}
|
466
502
|
/**
|
467
503
|
* Returns a simplfied form of node, or the original node if no simplification was possible.
|
468
504
|
*
|
@@ -476,19 +512,31 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
476
512
|
// console.log('Entering applyRule(' + node.toString() + ')')
|
477
513
|
// Do not clone node unless we find a match
|
478
514
|
var res = node; // First replace our child nodes with their simplified versions
|
479
|
-
// If a child could not be simplified, the
|
480
|
-
// no effect since the node is returned unchanged
|
515
|
+
// If a child could not be simplified, applying the rule to it
|
516
|
+
// will have no effect since the node is returned unchanged
|
481
517
|
|
482
518
|
if (res instanceof OperatorNode || res instanceof FunctionNode) {
|
483
|
-
|
484
|
-
for (var i = 0; i < res.args.length; i++) {
|
485
|
-
res.args[i] = applyRule(res.args[i], rule);
|
486
|
-
}
|
487
|
-
}
|
519
|
+
mapRule(res.args, rule);
|
488
520
|
} else if (res instanceof ParenthesisNode) {
|
489
521
|
if (res.content) {
|
490
522
|
res.content = applyRule(res.content, rule);
|
491
523
|
}
|
524
|
+
} else if (res instanceof ArrayNode) {
|
525
|
+
mapRule(res.items, rule);
|
526
|
+
} else if (res instanceof AccessorNode) {
|
527
|
+
if (res.object) {
|
528
|
+
res.object = applyRule(res.object, rule);
|
529
|
+
}
|
530
|
+
|
531
|
+
if (res.index) {
|
532
|
+
res.index = applyRule(res.index, rule);
|
533
|
+
}
|
534
|
+
} else if (res instanceof IndexNode) {
|
535
|
+
mapRule(res.dimensions, rule);
|
536
|
+
} else if (res instanceof ObjectNode) {
|
537
|
+
for (var prop in res.properties) {
|
538
|
+
res.properties[prop] = applyRule(res.properties[prop], rule);
|
539
|
+
}
|
492
540
|
} // Try to match a rule against this node
|
493
541
|
|
494
542
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import { factory } from '../../utils/factory.js';
|
2
|
+
var name = 'invmod';
|
3
|
+
var dependencies = ['typed', 'config', 'BigNumber', 'xgcd', 'equal', 'smaller', 'mod', 'add', 'isInteger'];
|
4
|
+
export var createInvmod = /* #__PURE__ */factory(name, dependencies, _ref => {
|
5
|
+
var {
|
6
|
+
typed,
|
7
|
+
config,
|
8
|
+
BigNumber,
|
9
|
+
xgcd,
|
10
|
+
equal,
|
11
|
+
smaller,
|
12
|
+
mod,
|
13
|
+
add,
|
14
|
+
isInteger
|
15
|
+
} = _ref;
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Calculate the (modular) multiplicative inverse of a modulo b. Solution to the equation `ax ≣ 1 (mod b)`
|
19
|
+
* See https://en.wikipedia.org/wiki/Modular_multiplicative_inverse.
|
20
|
+
*
|
21
|
+
* Syntax:
|
22
|
+
*
|
23
|
+
* math.invmod(a, b)
|
24
|
+
*
|
25
|
+
* Examples:
|
26
|
+
*
|
27
|
+
* math.invmod(8, 12) // returns NaN
|
28
|
+
* math.invmod(7, 13) // return 2
|
29
|
+
* math.invmod(15151, 15122) // returns 10429
|
30
|
+
*
|
31
|
+
* See also:
|
32
|
+
*
|
33
|
+
* gcd, xgcd
|
34
|
+
*
|
35
|
+
* @param {number | BigNumber} a An integer number
|
36
|
+
* @param {number | BigNumber} b An integer number
|
37
|
+
* @return {number | BigNumber } Returns an integer number
|
38
|
+
* where `invmod(a,b)*a ≣ 1 (mod b)`
|
39
|
+
*/
|
40
|
+
return typed(name, {
|
41
|
+
'number, number': invmod,
|
42
|
+
'BigNumber, BigNumber': invmod
|
43
|
+
});
|
44
|
+
|
45
|
+
function invmod(a, b) {
|
46
|
+
if (!isInteger(a) || !isInteger(b)) throw new Error('Parameters in function invmod must be integer numbers');
|
47
|
+
a = mod(a, b);
|
48
|
+
if (equal(b, 0)) throw new Error('Divisor must be non zero');
|
49
|
+
var res = xgcd(a, b);
|
50
|
+
res = res.valueOf();
|
51
|
+
var [gcd, inv] = res;
|
52
|
+
if (!equal(gcd, BigNumber(1))) return NaN;
|
53
|
+
inv = mod(inv, b);
|
54
|
+
if (smaller(inv, BigNumber(0))) inv = add(inv, b);
|
55
|
+
return inv;
|
56
|
+
}
|
57
|
+
});
|
package/lib/esm/header.js
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
* @date @@date
|
11
11
|
*
|
12
12
|
* @license
|
13
|
-
* Copyright (C) 2013-
|
13
|
+
* Copyright (C) 2013-2022 Jos de Jong <wjosdejong@gmail.com>
|
14
14
|
*
|
15
15
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
16
16
|
* use this file except in compliance with the License. You may obtain a copy
|
package/lib/esm/version.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
export var version = '10.0
|
1
|
+
export var version = '10.1.0'; // Note: This file is automatically generated when building math.js.
|
2
2
|
// Changes made in this file will be overwritten.
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "mathjs",
|
3
|
-
"version": "10.0
|
3
|
+
"version": "10.1.0",
|
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",
|
@@ -131,6 +131,7 @@
|
|
131
131
|
"compile": "gulp --gulpfile gulpfile.cjs compile",
|
132
132
|
"watch": "gulp --gulpfile gulpfile.cjs watch",
|
133
133
|
"lint": "standard --env=mocha --env=worker",
|
134
|
+
"format": "npm run lint -- --fix",
|
134
135
|
"validate:ascii": "gulp --gulpfile gulpfile.cjs validate:ascii",
|
135
136
|
"test": "npm run test:src && npm run lint",
|
136
137
|
"test:src": "mocha test/unit-tests",
|