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,10 +1,14 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
3
5
  Object.defineProperty(exports, "__esModule", {
4
6
  value: true
5
7
  });
6
8
  exports.createSimplifyConstant = void 0;
7
9
 
10
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
+
8
12
  var _is = require("../../../utils/is.js");
9
13
 
10
14
  var _factory = require("../../../utils/factory.js");
@@ -13,18 +17,28 @@ var _util = require("./util.js");
13
17
 
14
18
  var _noop = require("../../../utils/noop.js");
15
19
 
16
- // TODO this could be improved by simplifying seperated constants under associative and commutative operators
20
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
21
+
22
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
23
+
24
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
25
+
17
26
  var name = 'simplifyConstant';
18
- var dependencies = ['typed', 'config', 'mathWithTransform', '?fraction', '?bignumber', 'ConstantNode', 'OperatorNode', 'FunctionNode', 'SymbolNode'];
27
+ var dependencies = ['typed', 'config', 'mathWithTransform', 'matrix', '?fraction', '?bignumber', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'SymbolNode'];
19
28
  var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
20
29
  var typed = _ref.typed,
21
30
  config = _ref.config,
22
31
  mathWithTransform = _ref.mathWithTransform,
32
+ matrix = _ref.matrix,
23
33
  fraction = _ref.fraction,
24
34
  bignumber = _ref.bignumber,
35
+ AccessorNode = _ref.AccessorNode,
36
+ ArrayNode = _ref.ArrayNode,
25
37
  ConstantNode = _ref.ConstantNode,
26
- OperatorNode = _ref.OperatorNode,
27
38
  FunctionNode = _ref.FunctionNode,
39
+ IndexNode = _ref.IndexNode,
40
+ ObjectNode = _ref.ObjectNode,
41
+ OperatorNode = _ref.OperatorNode,
28
42
  SymbolNode = _ref.SymbolNode;
29
43
 
30
44
  var _createUtil = (0, _util.createUtil)({
@@ -38,22 +52,31 @@ var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependen
38
52
  createMakeNodeFunction = _createUtil.createMakeNodeFunction;
39
53
 
40
54
  function simplifyConstant(expr, options) {
41
- var res = foldFraction(expr, options);
42
- return (0, _is.isNode)(res) ? res : _toNode(res);
55
+ return _ensureNode(foldFraction(expr, options));
56
+ }
57
+
58
+ function _removeFractions(thing) {
59
+ if ((0, _is.isFraction)(thing)) {
60
+ return thing.valueOf();
61
+ }
62
+
63
+ if (thing instanceof Array) {
64
+ return thing.map(_removeFractions);
65
+ }
66
+
67
+ if ((0, _is.isMatrix)(thing)) {
68
+ return matrix(_removeFractions(thing.valueOf()));
69
+ }
70
+
71
+ return thing;
43
72
  }
44
73
 
45
74
  function _eval(fnname, args, options) {
46
75
  try {
47
- return _toNumber(mathWithTransform[fnname].apply(null, args), options);
76
+ return mathWithTransform[fnname].apply(null, args);
48
77
  } catch (ignore) {
49
78
  // sometimes the implicit type conversion causes the evaluation to fail, so we'll try again after removing Fractions
50
- args = args.map(function (x) {
51
- if ((0, _is.isFraction)(x)) {
52
- return x.valueOf();
53
- }
54
-
55
- return x;
56
- });
79
+ args = args.map(_removeFractions);
57
80
  return _toNumber(mathWithTransform[fnname].apply(null, args), options);
58
81
  }
59
82
  }
@@ -76,8 +99,24 @@ var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependen
76
99
  },
77
100
  Complex: function Complex(s) {
78
101
  throw new Error('Cannot convert Complex number to Node');
102
+ },
103
+ string: function string(s) {
104
+ return new ConstantNode(s);
105
+ },
106
+ Matrix: function Matrix(m) {
107
+ return new ArrayNode(m.valueOf().map(function (e) {
108
+ return _toNode(e);
109
+ }));
110
+ }
111
+ });
112
+
113
+ function _ensureNode(thing) {
114
+ if ((0, _is.isNode)(thing)) {
115
+ return thing;
79
116
  }
80
- }); // convert a number to a fraction only if it can be expressed exactly,
117
+
118
+ return _toNode(thing);
119
+ } // convert a number to a fraction only if it can be expressed exactly,
81
120
  // and when both numerator and denominator are small enough
82
121
 
83
122
 
@@ -134,6 +173,12 @@ var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependen
134
173
  }
135
174
 
136
175
  return _exactFraction(s.re, options);
176
+ },
177
+ 'Matrix, Object': function MatrixObject(s, options) {
178
+ return matrix(_exactFraction(s.valueOf()));
179
+ },
180
+ 'Array, Object': function ArrayObject(s, options) {
181
+ return s.map(_exactFraction);
137
182
  }
138
183
  });
139
184
 
@@ -157,6 +202,114 @@ var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependen
157
202
 
158
203
  return new OperatorNode('/', 'divide', [n, new ConstantNode(f.d)]);
159
204
  }
205
+ /* Handles constant indexing of ArrayNodes, matrices, and ObjectNodes */
206
+
207
+
208
+ function _foldAccessor(obj, index, options) {
209
+ if (!(0, _is.isIndexNode)(index)) {
210
+ // don't know what to do with that...
211
+ return new AccessorNode(_ensureNode(obj), _ensureNode(index));
212
+ }
213
+
214
+ if ((0, _is.isArrayNode)(obj) || (0, _is.isMatrix)(obj)) {
215
+ var remainingDims = Array.from(index.dimensions);
216
+ /* We will resolve constant indices one at a time, looking
217
+ * just in the first or second dimensions because (a) arrays
218
+ * of more than two dimensions are likely rare, and (b) pulling
219
+ * out the third or higher dimension would be pretty intricate.
220
+ * The price is that we miss simplifying [..3d array][x,y,1]
221
+ */
222
+
223
+ while (remainingDims.length > 0) {
224
+ if ((0, _is.isConstantNode)(remainingDims[0]) && typeof remainingDims[0].value !== 'string') {
225
+ var first = _toNumber(remainingDims.shift().value, options);
226
+
227
+ if ((0, _is.isArrayNode)(obj)) {
228
+ obj = obj.items[first - 1];
229
+ } else {
230
+ // matrix
231
+ obj = obj.valueOf()[first - 1];
232
+
233
+ if (obj instanceof Array) {
234
+ obj = matrix(obj);
235
+ }
236
+ }
237
+ } else if (remainingDims.length > 1 && (0, _is.isConstantNode)(remainingDims[1]) && typeof remainingDims[1].value !== 'string') {
238
+ var second = _toNumber(remainingDims[1].value, options);
239
+
240
+ var tryItems = [];
241
+ var fromItems = (0, _is.isArrayNode)(obj) ? obj.items : obj.valueOf();
242
+
243
+ var _iterator = _createForOfIteratorHelper(fromItems),
244
+ _step;
245
+
246
+ try {
247
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
248
+ var item = _step.value;
249
+
250
+ if ((0, _is.isArrayNode)(item)) {
251
+ tryItems.push(item.items[second - 1]);
252
+ } else if ((0, _is.isMatrix)(obj)) {
253
+ tryItems.push(item[second - 1]);
254
+ } else {
255
+ break;
256
+ }
257
+ }
258
+ } catch (err) {
259
+ _iterator.e(err);
260
+ } finally {
261
+ _iterator.f();
262
+ }
263
+
264
+ if (tryItems.length === fromItems.length) {
265
+ if ((0, _is.isArrayNode)(obj)) {
266
+ obj = new ArrayNode(tryItems);
267
+ } else {
268
+ // matrix
269
+ obj = matrix(tryItems);
270
+ }
271
+
272
+ remainingDims.splice(1, 1);
273
+ } else {
274
+ // extracting slice along 2nd dimension failed, give up
275
+ break;
276
+ }
277
+ } else {
278
+ // neither 1st or 2nd dimension is constant, give up
279
+ break;
280
+ }
281
+ }
282
+
283
+ if (remainingDims.length === index.dimensions.length) {
284
+ /* No successful constant indexing */
285
+ return new AccessorNode(_ensureNode(obj), index);
286
+ }
287
+
288
+ if (remainingDims.length > 0) {
289
+ /* Indexed some but not all dimensions */
290
+ index = new IndexNode(remainingDims);
291
+ return new AccessorNode(_ensureNode(obj), index);
292
+ }
293
+ /* All dimensions were constant, access completely resolved */
294
+
295
+
296
+ return obj;
297
+ }
298
+
299
+ if ((0, _is.isObjectNode)(obj) && index.dimensions.length === 1 && (0, _is.isConstantNode)(index.dimensions[0])) {
300
+ var key = index.dimensions[0].value;
301
+
302
+ if (key in obj.properties) {
303
+ return obj.properties[key];
304
+ }
305
+
306
+ return new ConstantNode(); // undefined
307
+ }
308
+ /* Don't know how to index this sort of obj, at least not with this index */
309
+
310
+
311
+ return new AccessorNode(_ensureNode(obj), index);
312
+ }
160
313
  /*
161
314
  * Create a binary tree from a list of Fractions and Nodes.
162
315
  * Tries to fold Fractions by evaluating them until the first Node in the list is hit, so
@@ -195,8 +348,15 @@ var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependen
195
348
  return node;
196
349
 
197
350
  case 'ConstantNode':
198
- if (typeof node.value === 'number' || !isNaN(node.value)) {
199
- return _toNumber(node.value, options);
351
+ switch ((0, _typeof2["default"])(node.value)) {
352
+ case 'number':
353
+ return _toNumber(node.value, options);
354
+
355
+ case 'string':
356
+ return node.value;
357
+
358
+ default:
359
+ if (!isNaN(node.value)) return _toNumber(node.value, options);
200
360
  }
201
361
 
202
362
  return node;
@@ -218,14 +378,24 @@ var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependen
218
378
  if (!args.some(_is.isNode)) {
219
379
  try {
220
380
  return _eval(node.name, args, options);
221
- } catch (ignoreandcontine) {}
381
+ } catch (ignoreandcontinue) {}
382
+ } // Size of a matrix does not depend on entries
383
+
384
+
385
+ if (node.name === 'size' && args.length === 1 && (0, _is.isArrayNode)(args[0])) {
386
+ var sz = [];
387
+ var section = args[0];
388
+
389
+ while ((0, _is.isArrayNode)(section)) {
390
+ sz.push(section.items.length);
391
+ section = section.items[0];
392
+ }
393
+
394
+ return matrix(sz);
222
395
  } // Convert all args to nodes and construct a symbolic function call
223
396
 
224
397
 
225
- args = args.map(function (arg) {
226
- return (0, _is.isNode)(arg) ? arg : _toNode(arg);
227
- });
228
- return new FunctionNode(node.name, args);
398
+ return new FunctionNode(node.name, args.map(_ensureNode));
229
399
  } else {// treat as operator
230
400
  }
231
401
  }
@@ -296,10 +466,40 @@ var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependen
296
466
  return foldFraction(node.content, options);
297
467
 
298
468
  case 'AccessorNode':
299
- /* falls through */
469
+ return _foldAccessor(foldFraction(node.object, options), foldFraction(node.index, options), options);
300
470
 
301
471
  case 'ArrayNode':
302
- /* falls through */
472
+ {
473
+ var foldItems = node.items.map(function (item) {
474
+ return foldFraction(item, options);
475
+ });
476
+
477
+ if (foldItems.some(_is.isNode)) {
478
+ return new ArrayNode(foldItems.map(_ensureNode));
479
+ }
480
+ /* All literals -- return a Matrix so we can operate on it */
481
+
482
+
483
+ return matrix(foldItems);
484
+ }
485
+
486
+ case 'IndexNode':
487
+ {
488
+ return new IndexNode(node.dimensions.map(function (n) {
489
+ return simplifyConstant(n, options);
490
+ }));
491
+ }
492
+
493
+ case 'ObjectNode':
494
+ {
495
+ var foldProps = {};
496
+
497
+ for (var prop in node.properties) {
498
+ foldProps[prop] = simplifyConstant(node.properties[prop], options);
499
+ }
500
+
501
+ return new ObjectNode(foldProps);
502
+ }
303
503
 
304
504
  case 'AssignmentNode':
305
505
  /* falls through */
@@ -310,12 +510,6 @@ var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependen
310
510
  case 'FunctionAssignmentNode':
311
511
  /* falls through */
312
512
 
313
- case 'IndexNode':
314
- /* falls through */
315
-
316
- case 'ObjectNode':
317
- /* falls through */
318
-
319
513
  case 'RangeNode':
320
514
  /* falls through */
321
515
 
@@ -10,7 +10,7 @@ var _is = require("../../../utils/is.js");
10
10
  var _factory = require("../../../utils/factory.js");
11
11
 
12
12
  var name = 'simplifyCore';
13
- var dependencies = ['equal', 'isZero', 'add', 'subtract', 'multiply', 'divide', 'pow', 'ConstantNode', 'OperatorNode', 'FunctionNode', 'ParenthesisNode'];
13
+ var dependencies = ['equal', 'isZero', 'add', 'subtract', 'multiply', 'divide', 'pow', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode'];
14
14
  var createSimplifyCore = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
15
15
  var equal = _ref.equal,
16
16
  isZero = _ref.isZero,
@@ -19,12 +19,22 @@ var createSimplifyCore = /* #__PURE__ */(0, _factory.factory)(name, dependencies
19
19
  multiply = _ref.multiply,
20
20
  divide = _ref.divide,
21
21
  pow = _ref.pow,
22
+ AccessorNode = _ref.AccessorNode,
23
+ ArrayNode = _ref.ArrayNode,
22
24
  ConstantNode = _ref.ConstantNode,
23
- OperatorNode = _ref.OperatorNode,
24
25
  FunctionNode = _ref.FunctionNode,
26
+ IndexNode = _ref.IndexNode,
27
+ ObjectNode = _ref.ObjectNode,
28
+ OperatorNode = _ref.OperatorNode,
25
29
  ParenthesisNode = _ref.ParenthesisNode;
26
30
  var node0 = new ConstantNode(0);
27
31
  var node1 = new ConstantNode(1);
32
+
33
+ function mapSimplifyCore(nodeArray) {
34
+ return nodeArray.map(simplifyCore).map(function (arg) {
35
+ return (0, _is.isParenthesisNode)(arg) ? arg.content : arg;
36
+ });
37
+ }
28
38
  /**
29
39
  * simplifyCore() performs single pass simplification suitable for
30
40
  * applications requiring ultimate performance. In contrast, simplify()
@@ -49,6 +59,7 @@ var createSimplifyCore = /* #__PURE__ */(0, _factory.factory)(name, dependencies
49
59
  * The expression to be simplified
50
60
  */
51
61
 
62
+
52
63
  function simplifyCore(node) {
53
64
  if ((0, _is.isOperatorNode)(node) && node.isUnary()) {
54
65
  var a0 = simplifyCore(node.args[0]);
@@ -184,10 +195,27 @@ var createSimplifyCore = /* #__PURE__ */(0, _factory.factory)(name, dependencies
184
195
 
185
196
  return new ParenthesisNode(c);
186
197
  } else if ((0, _is.isFunctionNode)(node)) {
187
- var args = node.args.map(simplifyCore).map(function (arg) {
188
- return (0, _is.isParenthesisNode)(arg) ? arg.content : arg;
189
- });
190
- return new FunctionNode(simplifyCore(node.fn), args);
198
+ return new FunctionNode(simplifyCore(node.fn), mapSimplifyCore(node.args));
199
+ } else if ((0, _is.isArrayNode)(node)) {
200
+ return new ArrayNode(mapSimplifyCore(node.items));
201
+ } else if ((0, _is.isAccessorNode)(node)) {
202
+ var obj = mapSimplifyCore(node.object);
203
+
204
+ if ((0, _is.isParenthesisNode)(obj)) {
205
+ obj = obj.content;
206
+ }
207
+
208
+ return new AccessorNode(obj, simplifyCore(node.index));
209
+ } else if ((0, _is.isIndexNode)(node)) {
210
+ return new IndexNode(mapSimplifyCore(node.dimensions));
211
+ } else if ((0, _is.isObjectNode)(node)) {
212
+ var newProps = {};
213
+
214
+ for (var prop in node.properties) {
215
+ newProps[prop] = simplifyCore(node.properties[prop]);
216
+ }
217
+
218
+ return new ObjectNode(newProps);
191
219
  } else {// cannot simplify
192
220
  }
193
221
 
@@ -26,7 +26,7 @@ var _object = require("../../utils/object.js");
26
26
  var _map = require("../../utils/map.js");
27
27
 
28
28
  var name = 'simplify';
29
- var dependencies = ['config', 'typed', 'parse', 'add', 'subtract', 'multiply', 'divide', 'pow', 'isZero', 'equal', '?fraction', '?bignumber', 'mathWithTransform', 'ConstantNode', 'FunctionNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode'];
29
+ 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'];
30
30
  var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
31
31
  var config = _ref.config,
32
32
  typed = _ref.typed,
@@ -41,8 +41,13 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
41
41
  fraction = _ref.fraction,
42
42
  bignumber = _ref.bignumber,
43
43
  mathWithTransform = _ref.mathWithTransform,
44
+ matrix = _ref.matrix,
45
+ AccessorNode = _ref.AccessorNode,
46
+ ArrayNode = _ref.ArrayNode,
44
47
  ConstantNode = _ref.ConstantNode,
45
48
  FunctionNode = _ref.FunctionNode,
49
+ IndexNode = _ref.IndexNode,
50
+ ObjectNode = _ref.ObjectNode,
46
51
  OperatorNode = _ref.OperatorNode,
47
52
  ParenthesisNode = _ref.ParenthesisNode,
48
53
  SymbolNode = _ref.SymbolNode;
@@ -50,11 +55,16 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
50
55
  typed: typed,
51
56
  config: config,
52
57
  mathWithTransform: mathWithTransform,
58
+ matrix: matrix,
53
59
  fraction: fraction,
54
60
  bignumber: bignumber,
61
+ AccessorNode: AccessorNode,
62
+ ArrayNode: ArrayNode,
55
63
  ConstantNode: ConstantNode,
56
- OperatorNode: OperatorNode,
57
64
  FunctionNode: FunctionNode,
65
+ IndexNode: IndexNode,
66
+ ObjectNode: ObjectNode,
67
+ OperatorNode: OperatorNode,
58
68
  SymbolNode: SymbolNode
59
69
  });
60
70
  var simplifyCore = (0, _simplifyCore.createSimplifyCore)({
@@ -65,9 +75,13 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
65
75
  multiply: multiply,
66
76
  divide: divide,
67
77
  pow: pow,
78
+ AccessorNode: AccessorNode,
79
+ ArrayNode: ArrayNode,
68
80
  ConstantNode: ConstantNode,
69
- OperatorNode: OperatorNode,
70
81
  FunctionNode: FunctionNode,
82
+ IndexNode: IndexNode,
83
+ ObjectNode: ObjectNode,
84
+ OperatorNode: OperatorNode,
71
85
  ParenthesisNode: ParenthesisNode
72
86
  });
73
87
  var resolve = (0, _resolve.createResolve)({
@@ -280,17 +294,19 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
280
294
  l: 'log(e)',
281
295
  r: '1'
282
296
  }, // temporary rules
297
+ // Note initially we tend constants to the right because like-term
298
+ // collection prefers the left, and we would rather collect nonconstants
283
299
  {
284
300
  l: 'n-n1',
285
301
  r: 'n+-n1'
286
302
  }, // temporarily replace 'subtract' so we can further flatten the 'add' operator
287
303
  {
288
304
  l: '-(c*v)',
289
- r: '(-c) * v'
305
+ r: 'v * (-c)'
290
306
  }, // make non-constant terms positive
291
307
  {
292
308
  l: '-v',
293
- r: '(-1) * v'
309
+ r: 'v * (-1)'
294
310
  }, {
295
311
  l: 'n/n1^n2',
296
312
  r: 'n*n1^-n2'
@@ -298,6 +314,17 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
298
314
  {
299
315
  l: 'n/n1',
300
316
  r: 'n*n1^-1'
317
+ }, // remove parenthesis in the case of negating a quantity
318
+ {
319
+ l: 'n1 + (n2 + n3)*(-1)',
320
+ r: 'n1 + n2*(-1) + n3*(-1)'
321
+ }, // subsume resulting -1 into constants where possible
322
+ {
323
+ l: '(-1) * c',
324
+ r: '-c'
325
+ }, {
326
+ l: '(-1) * (-c)',
327
+ r: 'c'
301
328
  }, // expand nested exponentiation
302
329
  {
303
330
  l: '(n ^ n1) ^ n2',
@@ -320,20 +347,21 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
320
347
  l: 'n+-n',
321
348
  r: '0'
322
349
  }, {
323
- l: 'n1*n2 + n2',
324
- r: '(n1+1)*n2'
325
- }, {
326
- l: 'n1*n3 + n2*n3',
327
- r: '(n1+n2)*n3'
328
- }, // remove parenthesis in the case of negating a quantitiy
350
+ l: 'v*n + v',
351
+ r: 'v*(n+1)'
352
+ }, // NOTE: leftmost position is special:
329
353
  {
330
- l: 'n1 + -1 * (n2 + n3)',
331
- r: 'n1 + -1 * n2 + -1 * n3'
354
+ l: 'n3*n1 + n3*n2',
355
+ r: 'n3*(n1+n2)'
356
+ }, // All sub-monomials tried there.
357
+ {
358
+ l: 'n*c + c',
359
+ r: '(n+1)*c'
332
360
  }, simplifyConstant, {
333
361
  l: '(-n)*n1',
334
362
  r: '-(n*n1)'
335
363
  }, // make factors positive (and undo 'make non-constant terms positive')
336
- // ordering of constants
364
+ // final ordering of constants
337
365
  {
338
366
  l: 'c+v',
339
367
  r: 'v+c',
@@ -437,7 +465,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
437
465
  };
438
466
 
439
467
  if (rule.context) {
440
- newRule.evaluate = rule.context;
468
+ newRule.context = rule.context;
441
469
  }
442
470
 
443
471
  if (rule.evaluate) {
@@ -481,6 +509,14 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
481
509
  function _getExpandPlaceholderSymbol() {
482
510
  return new SymbolNode('_p' + _lastsym++);
483
511
  }
512
+
513
+ function mapRule(nodes, rule) {
514
+ if (nodes) {
515
+ for (var i = 0; i < nodes.length; ++i) {
516
+ nodes[i] = applyRule(nodes[i], rule);
517
+ }
518
+ }
519
+ }
484
520
  /**
485
521
  * Returns a simplfied form of node, or the original node if no simplification was possible.
486
522
  *
@@ -494,19 +530,31 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
494
530
  // console.log('Entering applyRule(' + node.toString() + ')')
495
531
  // Do not clone node unless we find a match
496
532
  var res = node; // First replace our child nodes with their simplified versions
497
- // If a child could not be simplified, the assignments will have
498
- // no effect since the node is returned unchanged
533
+ // If a child could not be simplified, applying the rule to it
534
+ // will have no effect since the node is returned unchanged
499
535
 
500
536
  if (res instanceof OperatorNode || res instanceof FunctionNode) {
501
- if (res.args) {
502
- for (var i = 0; i < res.args.length; i++) {
503
- res.args[i] = applyRule(res.args[i], rule);
504
- }
505
- }
537
+ mapRule(res.args, rule);
506
538
  } else if (res instanceof ParenthesisNode) {
507
539
  if (res.content) {
508
540
  res.content = applyRule(res.content, rule);
509
541
  }
542
+ } else if (res instanceof ArrayNode) {
543
+ mapRule(res.items, rule);
544
+ } else if (res instanceof AccessorNode) {
545
+ if (res.object) {
546
+ res.object = applyRule(res.object, rule);
547
+ }
548
+
549
+ if (res.index) {
550
+ res.index = applyRule(res.index, rule);
551
+ }
552
+ } else if (res instanceof IndexNode) {
553
+ mapRule(res.dimensions, rule);
554
+ } else if (res instanceof ObjectNode) {
555
+ for (var prop in res.properties) {
556
+ res.properties[prop] = applyRule(res.properties[prop], rule);
557
+ }
510
558
  } // Try to match a rule against this node
511
559
 
512
560
 
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.createInvmod = void 0;
9
+
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+
12
+ var _factory = require("../../utils/factory.js");
13
+
14
+ var name = 'invmod';
15
+ var dependencies = ['typed', 'config', 'BigNumber', 'xgcd', 'equal', 'smaller', 'mod', 'add', 'isInteger'];
16
+ var createInvmod = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
17
+ var typed = _ref.typed,
18
+ config = _ref.config,
19
+ BigNumber = _ref.BigNumber,
20
+ xgcd = _ref.xgcd,
21
+ equal = _ref.equal,
22
+ smaller = _ref.smaller,
23
+ mod = _ref.mod,
24
+ add = _ref.add,
25
+ isInteger = _ref.isInteger;
26
+
27
+ /**
28
+ * Calculate the (modular) multiplicative inverse of a modulo b. Solution to the equation `ax ≣ 1 (mod b)`
29
+ * See https://en.wikipedia.org/wiki/Modular_multiplicative_inverse.
30
+ *
31
+ * Syntax:
32
+ *
33
+ * math.invmod(a, b)
34
+ *
35
+ * Examples:
36
+ *
37
+ * math.invmod(8, 12) // returns NaN
38
+ * math.invmod(7, 13) // return 2
39
+ * math.invmod(15151, 15122) // returns 10429
40
+ *
41
+ * See also:
42
+ *
43
+ * gcd, xgcd
44
+ *
45
+ * @param {number | BigNumber} a An integer number
46
+ * @param {number | BigNumber} b An integer number
47
+ * @return {number | BigNumber } Returns an integer number
48
+ * where `invmod(a,b)*a ≣ 1 (mod b)`
49
+ */
50
+ return typed(name, {
51
+ 'number, number': invmod,
52
+ 'BigNumber, BigNumber': invmod
53
+ });
54
+
55
+ function invmod(a, b) {
56
+ if (!isInteger(a) || !isInteger(b)) throw new Error('Parameters in function invmod must be integer numbers');
57
+ a = mod(a, b);
58
+ if (equal(b, 0)) throw new Error('Divisor must be non zero');
59
+ var res = xgcd(a, b);
60
+ res = res.valueOf();
61
+
62
+ var _res = res,
63
+ _res2 = (0, _slicedToArray2["default"])(_res, 2),
64
+ gcd = _res2[0],
65
+ inv = _res2[1];
66
+
67
+ if (!equal(gcd, BigNumber(1))) return NaN;
68
+ inv = mod(inv, b);
69
+ if (smaller(inv, BigNumber(0))) inv = add(inv, b);
70
+ return inv;
71
+ }
72
+ });
73
+ exports.createInvmod = createInvmod;