mathjs 10.0.2 → 10.1.0

Sign up to get free protection for your applications and to get access to all the features.
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;