mathjs 10.0.0 → 10.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +37 -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/constants.md +1 -1
- package/docs/reference/functions/invmod.md +41 -0
- package/docs/reference/functions/simplify.md +8 -5
- package/docs/reference/functions.md +1 -0
- package/examples/expressions.js +1 -1
- package/lib/browser/math.js +7 -7
- package/lib/browser/math.js.map +1 -1
- package/lib/cjs/entry/dependenciesAny/dependenciesIntersect.generated.js +6 -0
- 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 +16 -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 +103 -30
- package/lib/cjs/function/arithmetic/invmod.js +73 -0
- package/lib/cjs/function/arithmetic/round.js +2 -2
- package/lib/cjs/function/geometry/intersect.js +12 -13
- package/lib/cjs/function/probability/gamma.js +28 -30
- package/lib/cjs/header.js +3 -3
- package/lib/cjs/type/matrix/SparseMatrix.js +19 -15
- package/lib/cjs/type/unit/Unit.js +2 -2
- package/lib/cjs/utils/number.js +1 -1
- package/lib/cjs/utils/snapshot.js +2 -2
- package/lib/cjs/version.js +1 -1
- package/lib/esm/entry/dependenciesAny/dependenciesIntersect.generated.js +4 -0
- 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 +14 -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 +103 -30
- package/lib/esm/function/arithmetic/invmod.js +57 -0
- package/lib/esm/function/arithmetic/round.js +2 -2
- package/lib/esm/function/geometry/intersect.js +12 -12
- package/lib/esm/function/probability/gamma.js +28 -30
- package/lib/esm/header.js +1 -1
- package/lib/esm/type/matrix/SparseMatrix.js +19 -15
- package/lib/esm/type/unit/Unit.js +2 -2
- package/lib/esm/utils/number.js +1 -1
- package/lib/esm/utils/snapshot.js +2 -2
- package/lib/esm/version.js +1 -1
- package/package.json +15 -14
- package/types/index.d.ts +4 -4
@@ -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
|
-
|
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', '
|
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
|
-
|
42
|
-
|
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
|
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(
|
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
|
-
|
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
|
-
|
199
|
-
|
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 (
|
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
|
-
|
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
|
-
|
469
|
+
return _foldAccessor(foldFraction(node.object, options), foldFraction(node.index, options), options);
|
300
470
|
|
301
471
|
case 'ArrayNode':
|
302
|
-
|
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', '
|
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
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
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)({
|
@@ -124,11 +138,14 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
124
138
|
* - [Symbolic computation - Simplification (Wikipedia)](https://en.wikipedia.org/wiki/Symbolic_computation#Simplification)
|
125
139
|
*
|
126
140
|
* An optional `options` argument can be passed as last argument of `simplify`.
|
127
|
-
*
|
128
|
-
* - `
|
129
|
-
|
130
|
-
*
|
131
|
-
|
141
|
+
* Currently available options (defaults in parentheses):
|
142
|
+
* - `consoleDebug` (false): whether to write the expression being simplified
|
143
|
+
and any changes to it, along with the rule responsible, to console
|
144
|
+
* - `exactFractions` (true): whether to try to convert all constants to
|
145
|
+
exact rational numbers.
|
146
|
+
* - `fractionsLimit` (10000): when `exactFractions` is true, constants will
|
147
|
+
be expressed as fractions only when both numerator and denominator
|
148
|
+
are smaller than `fractionsLimit`.
|
132
149
|
*
|
133
150
|
* Syntax:
|
134
151
|
*
|
@@ -199,6 +216,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
199
216
|
return this(expr, rules, (0, _map.createMap)(scope), options);
|
200
217
|
},
|
201
218
|
'Node, Array, Map, Object': function NodeArrayMapObject(expr, rules, scope, options) {
|
219
|
+
var debug = options.consoleDebug;
|
202
220
|
rules = _buildRules(rules);
|
203
221
|
var res = resolve(expr, scope);
|
204
222
|
res = removeParens(res);
|
@@ -211,12 +229,33 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
211
229
|
visited[str] = true;
|
212
230
|
_lastsym = 0; // counter for placeholder symbols
|
213
231
|
|
232
|
+
var laststr = str;
|
233
|
+
if (debug) console.log('Working on: ', str);
|
234
|
+
|
214
235
|
for (var i = 0; i < rules.length; i++) {
|
236
|
+
var rulestr = '';
|
237
|
+
|
215
238
|
if (typeof rules[i] === 'function') {
|
216
239
|
res = rules[i](res, options);
|
240
|
+
if (debug) rulestr = rules[i].name;
|
217
241
|
} else {
|
218
242
|
flatten(res);
|
219
243
|
res = applyRule(res, rules[i]);
|
244
|
+
|
245
|
+
if (debug) {
|
246
|
+
rulestr = "".concat(rules[i].l.toString(), " -> ").concat(rules[i].r.toString());
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
if (debug) {
|
251
|
+
var newstr = res.toString({
|
252
|
+
parenthesis: 'all'
|
253
|
+
});
|
254
|
+
|
255
|
+
if (newstr !== laststr) {
|
256
|
+
console.log('Applying', rulestr, 'produced', newstr);
|
257
|
+
laststr = newstr;
|
258
|
+
}
|
220
259
|
}
|
221
260
|
|
222
261
|
unflattenl(res); // using left-heavy binary tree here since custom rule functions may expect it
|
@@ -280,17 +319,19 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
280
319
|
l: 'log(e)',
|
281
320
|
r: '1'
|
282
321
|
}, // temporary rules
|
322
|
+
// Note initially we tend constants to the right because like-term
|
323
|
+
// collection prefers the left, and we would rather collect nonconstants
|
283
324
|
{
|
284
325
|
l: 'n-n1',
|
285
326
|
r: 'n+-n1'
|
286
327
|
}, // temporarily replace 'subtract' so we can further flatten the 'add' operator
|
287
328
|
{
|
288
329
|
l: '-(c*v)',
|
289
|
-
r: '(-c)
|
330
|
+
r: 'v * (-c)'
|
290
331
|
}, // make non-constant terms positive
|
291
332
|
{
|
292
333
|
l: '-v',
|
293
|
-
r: '(-1)
|
334
|
+
r: 'v * (-1)'
|
294
335
|
}, {
|
295
336
|
l: 'n/n1^n2',
|
296
337
|
r: 'n*n1^-n2'
|
@@ -298,7 +339,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
298
339
|
{
|
299
340
|
l: 'n/n1',
|
300
341
|
r: 'n*n1^-1'
|
301
|
-
}, // expand nested exponentiation
|
342
|
+
}, simplifyConstant, // expand nested exponentiation
|
302
343
|
{
|
303
344
|
l: '(n ^ n1) ^ n2',
|
304
345
|
r: 'n ^ (n1 * n2)'
|
@@ -320,20 +361,29 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
320
361
|
l: 'n+-n',
|
321
362
|
r: '0'
|
322
363
|
}, {
|
323
|
-
l: '
|
324
|
-
r: '(
|
325
|
-
},
|
326
|
-
|
327
|
-
|
328
|
-
|
364
|
+
l: 'v*n + v',
|
365
|
+
r: 'v*(n+1)'
|
366
|
+
}, // NOTE: leftmost position is special:
|
367
|
+
{
|
368
|
+
l: 'n3*n1 + n3*n2',
|
369
|
+
r: 'n3*(n1+n2)'
|
370
|
+
}, // All sub-monomials tried there.
|
371
|
+
{
|
372
|
+
l: 'n*c + c',
|
373
|
+
r: '(n+1)*c'
|
374
|
+
}, // remove parenthesis in the case of negating a quantity
|
375
|
+
// (It might seem this rule should precede collecting like terms,
|
376
|
+
// but putting it after gives another chance of noticing like terms,
|
377
|
+
// and any new like terms produced by this will be collected
|
378
|
+
// on the next pass through all the rules.)
|
379
|
+
{
|
380
|
+
l: 'n1 + (n2 + n3)*(-1)',
|
381
|
+
r: 'n1 + n2*(-1) + n3*(-1)'
|
382
|
+
}, // make factors positive (and undo 'make non-constant terms positive')
|
329
383
|
{
|
330
|
-
l: 'n1 + -1 * (n2 + n3)',
|
331
|
-
r: 'n1 + -1 * n2 + -1 * n3'
|
332
|
-
}, simplifyConstant, {
|
333
384
|
l: '(-n)*n1',
|
334
385
|
r: '-(n*n1)'
|
335
|
-
}, //
|
336
|
-
// ordering of constants
|
386
|
+
}, // final ordering of constants
|
337
387
|
{
|
338
388
|
l: 'c+v',
|
339
389
|
r: 'v+c',
|
@@ -383,6 +433,9 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
383
433
|
{
|
384
434
|
l: 'n1/(n2/n3)',
|
385
435
|
r: '(n1*n3)/n2'
|
436
|
+
}, {
|
437
|
+
l: 'n1/(-n2)',
|
438
|
+
r: '-n1/n2'
|
386
439
|
}];
|
387
440
|
/**
|
388
441
|
* Parse the string array of rules into nodes
|
@@ -434,7 +487,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
434
487
|
};
|
435
488
|
|
436
489
|
if (rule.context) {
|
437
|
-
newRule.
|
490
|
+
newRule.context = rule.context;
|
438
491
|
}
|
439
492
|
|
440
493
|
if (rule.evaluate) {
|
@@ -478,6 +531,14 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
478
531
|
function _getExpandPlaceholderSymbol() {
|
479
532
|
return new SymbolNode('_p' + _lastsym++);
|
480
533
|
}
|
534
|
+
|
535
|
+
function mapRule(nodes, rule) {
|
536
|
+
if (nodes) {
|
537
|
+
for (var i = 0; i < nodes.length; ++i) {
|
538
|
+
nodes[i] = applyRule(nodes[i], rule);
|
539
|
+
}
|
540
|
+
}
|
541
|
+
}
|
481
542
|
/**
|
482
543
|
* Returns a simplfied form of node, or the original node if no simplification was possible.
|
483
544
|
*
|
@@ -491,19 +552,31 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
491
552
|
// console.log('Entering applyRule(' + node.toString() + ')')
|
492
553
|
// Do not clone node unless we find a match
|
493
554
|
var res = node; // First replace our child nodes with their simplified versions
|
494
|
-
// If a child could not be simplified, the
|
495
|
-
// no effect since the node is returned unchanged
|
555
|
+
// If a child could not be simplified, applying the rule to it
|
556
|
+
// will have no effect since the node is returned unchanged
|
496
557
|
|
497
558
|
if (res instanceof OperatorNode || res instanceof FunctionNode) {
|
498
|
-
|
499
|
-
for (var i = 0; i < res.args.length; i++) {
|
500
|
-
res.args[i] = applyRule(res.args[i], rule);
|
501
|
-
}
|
502
|
-
}
|
559
|
+
mapRule(res.args, rule);
|
503
560
|
} else if (res instanceof ParenthesisNode) {
|
504
561
|
if (res.content) {
|
505
562
|
res.content = applyRule(res.content, rule);
|
506
563
|
}
|
564
|
+
} else if (res instanceof ArrayNode) {
|
565
|
+
mapRule(res.items, rule);
|
566
|
+
} else if (res instanceof AccessorNode) {
|
567
|
+
if (res.object) {
|
568
|
+
res.object = applyRule(res.object, rule);
|
569
|
+
}
|
570
|
+
|
571
|
+
if (res.index) {
|
572
|
+
res.index = applyRule(res.index, rule);
|
573
|
+
}
|
574
|
+
} else if (res instanceof IndexNode) {
|
575
|
+
mapRule(res.dimensions, rule);
|
576
|
+
} else if (res instanceof ObjectNode) {
|
577
|
+
for (var prop in res.properties) {
|
578
|
+
res.properties[prop] = applyRule(res.properties[prop], rule);
|
579
|
+
}
|
507
580
|
} // Try to match a rule against this node
|
508
581
|
|
509
582
|
|