mathjs 10.0.2 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/HISTORY.md +11 -0
  2. package/NOTICE +1 -1
  3. package/README.md +10 -2
  4. package/bin/cli.js +1 -1
  5. package/docs/expressions/syntax.md +1 -1
  6. package/docs/reference/functions/invmod.md +41 -0
  7. package/docs/reference/functions.md +1 -0
  8. package/lib/browser/math.js +6 -6
  9. package/lib/browser/math.js.map +1 -1
  10. package/lib/cjs/entry/dependenciesAny/dependenciesInvmod.generated.js +41 -0
  11. package/lib/cjs/entry/dependenciesAny/dependenciesRationalize.generated.js +15 -0
  12. package/lib/cjs/entry/dependenciesAny/dependenciesSimplify.generated.js +15 -0
  13. package/lib/cjs/entry/dependenciesAny.generated.js +8 -0
  14. package/lib/cjs/entry/dependenciesNumber/dependenciesRationalize.generated.js +15 -0
  15. package/lib/cjs/entry/dependenciesNumber/dependenciesSimplify.generated.js +15 -0
  16. package/lib/cjs/entry/impureFunctionsAny.generated.js +11 -0
  17. package/lib/cjs/entry/impureFunctionsNumber.generated.js +10 -0
  18. package/lib/cjs/entry/pureFunctionsAny.generated.js +14 -2
  19. package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +6 -1
  20. package/lib/cjs/expression/embeddedDocs/function/arithmetic/invmod.js +15 -0
  21. package/lib/cjs/expression/embeddedDocs/function/matrix/forEach.js +1 -1
  22. package/lib/cjs/factoriesAny.js +8 -0
  23. package/lib/cjs/function/algebra/rationalize.js +18 -4
  24. package/lib/cjs/function/algebra/simplify/simplifyConstant.js +223 -29
  25. package/lib/cjs/function/algebra/simplify/simplifyCore.js +34 -6
  26. package/lib/cjs/function/algebra/simplify.js +70 -22
  27. package/lib/cjs/function/arithmetic/invmod.js +73 -0
  28. package/lib/cjs/header.js +3 -3
  29. package/lib/cjs/version.js +1 -1
  30. package/lib/esm/entry/dependenciesAny/dependenciesInvmod.generated.js +24 -0
  31. package/lib/esm/entry/dependenciesAny/dependenciesRationalize.generated.js +10 -0
  32. package/lib/esm/entry/dependenciesAny/dependenciesSimplify.generated.js +10 -0
  33. package/lib/esm/entry/dependenciesAny.generated.js +1 -0
  34. package/lib/esm/entry/dependenciesNumber/dependenciesRationalize.generated.js +10 -0
  35. package/lib/esm/entry/dependenciesNumber/dependenciesSimplify.generated.js +10 -0
  36. package/lib/esm/entry/impureFunctionsAny.generated.js +12 -1
  37. package/lib/esm/entry/impureFunctionsNumber.generated.js +10 -0
  38. package/lib/esm/entry/pureFunctionsAny.generated.js +12 -1
  39. package/lib/esm/expression/embeddedDocs/embeddedDocs.js +4 -1
  40. package/lib/esm/expression/embeddedDocs/function/arithmetic/invmod.js +8 -0
  41. package/lib/esm/expression/embeddedDocs/function/matrix/forEach.js +1 -1
  42. package/lib/esm/factoriesAny.js +1 -0
  43. package/lib/esm/function/algebra/rationalize.js +18 -4
  44. package/lib/esm/function/algebra/simplify/simplifyConstant.js +197 -29
  45. package/lib/esm/function/algebra/simplify/simplifyCore.js +35 -7
  46. package/lib/esm/function/algebra/simplify.js +70 -22
  47. package/lib/esm/function/arithmetic/invmod.js +57 -0
  48. package/lib/esm/header.js +1 -1
  49. package/lib/esm/version.js +1 -1
  50. 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', 'ConstantNode', 'OperatorNode', 'FunctionNode', 'SymbolNode'];
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
- var res = foldFraction(expr, options);
33
- return isNode(res) ? res : _toNode(res);
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 _toNumber(mathWithTransform[fnname].apply(null, args), options);
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(function (x) {
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
- }); // convert a number to a fraction only if it can be expressed exactly,
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
- if (typeof node.value === 'number' || !isNaN(node.value)) {
190
- return _toNumber(node.value, options);
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 (ignoreandcontine) {}
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
- args = args.map(function (arg) {
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
- /* falls through */
432
+ return _foldAccessor(foldFraction(node.object, options), foldFraction(node.index, options), options);
285
433
 
286
434
  case 'ArrayNode':
287
- /* falls through */
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', 'ConstantNode', 'OperatorNode', 'FunctionNode', 'ParenthesisNode'];
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
- var args = node.args.map(simplifyCore).map(function (arg) {
181
- return isParenthesisNode(arg) ? arg.content : arg;
182
- });
183
- return new FunctionNode(simplifyCore(node.fn), args);
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) * v'
287
+ r: 'v * (-c)'
272
288
  }, // make non-constant terms positive
273
289
  {
274
290
  l: '-v',
275
- r: '(-1) * v'
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: 'n1*n2 + n2',
306
- r: '(n1+1)*n2'
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 + -1 * (n2 + n3)',
313
- r: 'n1 + -1 * n2 + -1 * n3'
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.evaluate = rule.context;
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 assignments will have
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
- if (res.args) {
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-2021 Jos de Jong <wjosdejong@gmail.com>
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
@@ -1,2 +1,2 @@
1
- export var version = '10.0.2'; // Note: This file is automatically generated when building math.js.
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.2",
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",