mathjs 11.3.3 → 11.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. package/HISTORY.md +14 -0
  2. package/lib/browser/math.js +1 -1
  3. package/lib/browser/math.js.LICENSE.txt +2 -2
  4. package/lib/browser/math.js.map +1 -1
  5. package/lib/cjs/entry/dependenciesAny/dependenciesLyap.generated.js +26 -0
  6. package/lib/cjs/entry/dependenciesAny/dependenciesPolynomialRoot.generated.js +42 -0
  7. package/lib/cjs/entry/dependenciesAny/dependenciesSchur.generated.js +30 -0
  8. package/lib/cjs/entry/dependenciesAny/dependenciesSylvester.generated.js +46 -0
  9. package/lib/cjs/entry/dependenciesAny.generated.js +28 -0
  10. package/lib/cjs/entry/impureFunctionsAny.generated.js +21 -17
  11. package/lib/cjs/entry/pureFunctionsAny.generated.js +100 -48
  12. package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +8 -0
  13. package/lib/cjs/expression/embeddedDocs/function/algebra/polynomialRoot.js +15 -0
  14. package/lib/cjs/expression/embeddedDocs/function/matrix/lyap.js +15 -0
  15. package/lib/cjs/expression/embeddedDocs/function/matrix/schur.js +15 -0
  16. package/lib/cjs/expression/embeddedDocs/function/matrix/sylvester.js +15 -0
  17. package/lib/cjs/factoriesAny.js +28 -0
  18. package/lib/cjs/function/algebra/decomposition/schur.js +75 -0
  19. package/lib/cjs/function/algebra/lyap.js +57 -0
  20. package/lib/cjs/function/algebra/polynomialRoot.js +139 -0
  21. package/lib/cjs/function/algebra/simplify/wildcards.js +38 -0
  22. package/lib/cjs/function/algebra/simplify.js +104 -44
  23. package/lib/cjs/function/algebra/simplifyConstant.js +29 -12
  24. package/lib/cjs/function/algebra/sylvester.js +127 -0
  25. package/lib/cjs/function/matrix/forEach.js +1 -1
  26. package/lib/cjs/header.js +2 -2
  27. package/lib/cjs/version.js +1 -1
  28. package/lib/esm/entry/dependenciesAny/dependenciesLyap.generated.js +18 -0
  29. package/lib/esm/entry/dependenciesAny/dependenciesPolynomialRoot.generated.js +34 -0
  30. package/lib/esm/entry/dependenciesAny/dependenciesSchur.generated.js +22 -0
  31. package/lib/esm/entry/dependenciesAny/dependenciesSylvester.generated.js +38 -0
  32. package/lib/esm/entry/dependenciesAny.generated.js +4 -0
  33. package/lib/esm/entry/impureFunctionsAny.generated.js +22 -18
  34. package/lib/esm/entry/pureFunctionsAny.generated.js +87 -39
  35. package/lib/esm/expression/embeddedDocs/embeddedDocs.js +8 -0
  36. package/lib/esm/expression/embeddedDocs/function/algebra/polynomialRoot.js +8 -0
  37. package/lib/esm/expression/embeddedDocs/function/matrix/lyap.js +8 -0
  38. package/lib/esm/expression/embeddedDocs/function/matrix/schur.js +8 -0
  39. package/lib/esm/expression/embeddedDocs/function/matrix/sylvester.js +8 -0
  40. package/lib/esm/factoriesAny.js +4 -0
  41. package/lib/esm/function/algebra/decomposition/schur.js +70 -0
  42. package/lib/esm/function/algebra/lyap.js +52 -0
  43. package/lib/esm/function/algebra/polynomialRoot.js +122 -0
  44. package/lib/esm/function/algebra/simplify/wildcards.js +20 -0
  45. package/lib/esm/function/algebra/simplify.js +105 -45
  46. package/lib/esm/function/algebra/simplifyConstant.js +29 -12
  47. package/lib/esm/function/algebra/sylvester.js +118 -0
  48. package/lib/esm/function/matrix/forEach.js +1 -1
  49. package/lib/esm/version.js +1 -1
  50. package/package.json +8 -8
  51. package/types/index.d.ts +83 -5
@@ -1083,6 +1083,12 @@ Object.defineProperty(exports, "createLusolve", {
1083
1083
  return _lusolve.createLusolve;
1084
1084
  }
1085
1085
  });
1086
+ Object.defineProperty(exports, "createLyap", {
1087
+ enumerable: true,
1088
+ get: function get() {
1089
+ return _lyap.createLyap;
1090
+ }
1091
+ });
1086
1092
  Object.defineProperty(exports, "createMad", {
1087
1093
  enumerable: true,
1088
1094
  get: function get() {
@@ -1431,6 +1437,12 @@ Object.defineProperty(exports, "createPlanckTime", {
1431
1437
  return _physicalConstants.createPlanckTime;
1432
1438
  }
1433
1439
  });
1440
+ Object.defineProperty(exports, "createPolynomialRoot", {
1441
+ enumerable: true,
1442
+ get: function get() {
1443
+ return _polynomialRoot.createPolynomialRoot;
1444
+ }
1445
+ });
1434
1446
  Object.defineProperty(exports, "createPow", {
1435
1447
  enumerable: true,
1436
1448
  get: function get() {
@@ -1635,6 +1647,12 @@ Object.defineProperty(exports, "createSackurTetrode", {
1635
1647
  return _physicalConstants.createSackurTetrode;
1636
1648
  }
1637
1649
  });
1650
+ Object.defineProperty(exports, "createSchur", {
1651
+ enumerable: true,
1652
+ get: function get() {
1653
+ return _schur.createSchur;
1654
+ }
1655
+ });
1638
1656
  Object.defineProperty(exports, "createSec", {
1639
1657
  enumerable: true,
1640
1658
  get: function get() {
@@ -1893,6 +1911,12 @@ Object.defineProperty(exports, "createSumTransform", {
1893
1911
  return _sumTransform.createSumTransform;
1894
1912
  }
1895
1913
  });
1914
+ Object.defineProperty(exports, "createSylvester", {
1915
+ enumerable: true,
1916
+ get: function get() {
1917
+ return _sylvester.createSylvester;
1918
+ }
1919
+ });
1896
1920
  Object.defineProperty(exports, "createSymbolNode", {
1897
1921
  enumerable: true,
1898
1922
  get: function get() {
@@ -2285,6 +2309,7 @@ var _lup = require("./function/algebra/decomposition/lup.js");
2285
2309
  var _qr = require("./function/algebra/decomposition/qr.js");
2286
2310
  var _slu = require("./function/algebra/decomposition/slu.js");
2287
2311
  var _lusolve = require("./function/algebra/solver/lusolve.js");
2312
+ var _polynomialRoot = require("./function/algebra/polynomialRoot.js");
2288
2313
  var _Help = require("./expression/Help.js");
2289
2314
  var _Chain = require("./type/chain/Chain.js");
2290
2315
  var _help = require("./expression/function/help.js");
@@ -2295,6 +2320,9 @@ var _pinv = require("./function/matrix/pinv.js");
2295
2320
  var _eigs = require("./function/matrix/eigs.js");
2296
2321
  var _expm2 = require("./function/matrix/expm.js");
2297
2322
  var _sqrtm = require("./function/matrix/sqrtm.js");
2323
+ var _sylvester = require("./function/algebra/sylvester.js");
2324
+ var _schur = require("./function/algebra/decomposition/schur.js");
2325
+ var _lyap = require("./function/algebra/lyap.js");
2298
2326
  var _divide = require("./function/arithmetic/divide.js");
2299
2327
  var _distance = require("./function/geometry/distance.js");
2300
2328
  var _intersect = require("./function/geometry/intersect.js");
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createSchur = void 0;
7
+ var _factory = require("../../../utils/factory.js");
8
+ var name = 'schur';
9
+ var dependencies = ['typed', 'matrix', 'identity', 'multiply', 'qr', 'norm', 'subtract'];
10
+ var createSchur = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
11
+ var typed = _ref.typed,
12
+ matrix = _ref.matrix,
13
+ identity = _ref.identity,
14
+ multiply = _ref.multiply,
15
+ qr = _ref.qr,
16
+ norm = _ref.norm,
17
+ subtract = _ref.subtract;
18
+ /**
19
+ *
20
+ * Performs a real Schur decomposition of the real matrix A = UTU' where U is orthogonal
21
+ * and T is upper quasi-triangular.
22
+ * https://en.wikipedia.org/wiki/Schur_decomposition
23
+ *
24
+ * Syntax:
25
+ *
26
+ * math.schur(A)
27
+ *
28
+ * Examples:
29
+ *
30
+ * const A = [[1, 0], [-4, 3]]
31
+ * math.schur(A) // returns {T: [[3, 4], [0, 1]], R: [[0, 1], [-1, 0]]}
32
+ *
33
+ * See also:
34
+ *
35
+ * sylvester, lyap, qr
36
+ *
37
+ * @param {Array | Matrix} A Matrix A
38
+ * @return {{U: Array | Matrix, T: Array | Matrix}} Object containing both matrix U and T of the Schur Decomposition A=UTU'
39
+ */
40
+ return typed(name, {
41
+ Array: function Array(X) {
42
+ var r = _schur(matrix(X));
43
+ return {
44
+ U: r.U.valueOf(),
45
+ T: r.T.valueOf()
46
+ };
47
+ },
48
+ Matrix: function Matrix(X) {
49
+ return _schur(X);
50
+ }
51
+ });
52
+ function _schur(X) {
53
+ var n = X.size()[0];
54
+ var A = X;
55
+ var U = identity(n);
56
+ var k = 0;
57
+ var A0;
58
+ do {
59
+ A0 = A;
60
+ var QR = qr(A);
61
+ var Q = QR.Q;
62
+ var R = QR.R;
63
+ A = multiply(R, Q);
64
+ U = multiply(U, Q);
65
+ if (k++ > 100) {
66
+ break;
67
+ }
68
+ } while (norm(subtract(A, A0)) > 1e-4);
69
+ return {
70
+ U: U,
71
+ T: A
72
+ };
73
+ }
74
+ });
75
+ exports.createSchur = createSchur;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createLyap = void 0;
7
+ var _factory = require("../../utils/factory.js");
8
+ var name = 'lyap';
9
+ var dependencies = ['typed', 'matrix', 'sylvester', 'multiply', 'transpose'];
10
+ var createLyap = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
11
+ var typed = _ref.typed,
12
+ matrix = _ref.matrix,
13
+ sylvester = _ref.sylvester,
14
+ multiply = _ref.multiply,
15
+ transpose = _ref.transpose;
16
+ /**
17
+ *
18
+ * Solves the Continuous-time Lyapunov equation AP+PA'+Q=0 for P, where
19
+ * Q is an input matrix. When Q is symmetric, P is also symmetric. Notice
20
+ * that different equivalent definitions exist for the Continuous-time
21
+ * Lyapunov equation.
22
+ * https://en.wikipedia.org/wiki/Lyapunov_equation
23
+ *
24
+ * Syntax:
25
+ *
26
+ * math.lyap(A, Q)
27
+ *
28
+ * Examples:
29
+ *
30
+ * const A = [[-2, 0], [1, -4]]
31
+ * const Q = [[3, 1], [1, 3]]
32
+ * const P = math.lyap(A, Q)
33
+ *
34
+ * See also:
35
+ *
36
+ * sylvester, schur
37
+ *
38
+ * @param {Matrix | Array} A Matrix A
39
+ * @param {Matrix | Array} Q Matrix Q
40
+ * @return {Matrix | Array} Matrix P solution to the Continuous-time Lyapunov equation AP+PA'=Q
41
+ */
42
+ return typed(name, {
43
+ 'Matrix, Matrix': function MatrixMatrix(A, Q) {
44
+ return sylvester(A, transpose(A), multiply(-1, Q));
45
+ },
46
+ 'Array, Matrix': function ArrayMatrix(A, Q) {
47
+ return sylvester(matrix(A), transpose(matrix(A)), multiply(-1, Q));
48
+ },
49
+ 'Matrix, Array': function MatrixArray(A, Q) {
50
+ return sylvester(A, transpose(matrix(A)), matrix(multiply(-1, Q)));
51
+ },
52
+ 'Array, Array': function ArrayArray(A, Q) {
53
+ return sylvester(matrix(A), transpose(matrix(A)), matrix(multiply(-1, Q))).toArray();
54
+ }
55
+ });
56
+ });
57
+ exports.createLyap = createLyap;
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.createPolynomialRoot = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
+ var _factory = require("../../utils/factory.js");
11
+ var name = 'polynomialRoot';
12
+ var dependencies = ['typed', 'isZero', 'equalScalar', 'add', 'subtract', 'multiply', 'divide', 'sqrt', 'unaryMinus', 'cbrt', 'typeOf', 'im', 're'];
13
+ var createPolynomialRoot = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
14
+ var typed = _ref.typed,
15
+ isZero = _ref.isZero,
16
+ equalScalar = _ref.equalScalar,
17
+ add = _ref.add,
18
+ subtract = _ref.subtract,
19
+ multiply = _ref.multiply,
20
+ divide = _ref.divide,
21
+ sqrt = _ref.sqrt,
22
+ unaryMinus = _ref.unaryMinus,
23
+ cbrt = _ref.cbrt,
24
+ typeOf = _ref.typeOf,
25
+ im = _ref.im,
26
+ re = _ref.re;
27
+ /**
28
+ * Finds the numerical values of the distinct roots of a polynomial with real or complex coefficients.
29
+ * Currently operates only on linear, quadratic, and cubic polynomials using the standard
30
+ * formulas for the roots.
31
+ *
32
+ * Syntax:
33
+ *
34
+ * polynomialRoot(constant, linearCoeff, quadraticCoeff, cubicCoeff)
35
+ *
36
+ * Examples:
37
+ * // linear
38
+ * math.polynomialRoot(6, 3) // [-2]
39
+ * math.polynomialRoot(math.complex(6,3), 3) // [-2 - i]
40
+ * math.polynomialRoot(math.complex(6,3), math.complex(2,1)) // [-3 + 0i]
41
+ * // quadratic
42
+ * math.polynomialRoot(2, -3, 1) // [2, 1]
43
+ * math.polynomialRoot(8, 8, 2) // [-2]
44
+ * math.polynomialRoot(-2, 0, 1) // [1.4142135623730951, -1.4142135623730951]
45
+ * math.polynomialRoot(2, -2, 1) // [1 + i, 1 - i]
46
+ * math.polynomialRoot(math.complex(1,3), math.complex(-3, -2), 1) // [2 + i, 1 + i]
47
+ * // cubic
48
+ * math.polynomialRoot(-6, 11, -6, 1) // [1, 3, 2]
49
+ * math.polynomialRoot(-8, 0, 0, 1) // [-1 - 1.7320508075688774i, 2, -1 + 1.7320508075688774i]
50
+ * math.polynomialRoot(0, 8, 8, 2) // [0, -2]
51
+ * math.polynomialRoot(1, 1, 1, 1) // [-1 + 0i, 0 - i, 0 + i]
52
+ *
53
+ * See also:
54
+ * cbrt, sqrt
55
+ *
56
+ * @param {... number | Complex} coeffs
57
+ * The coefficients of the polynomial, starting with with the constant coefficent, followed
58
+ * by the linear coefficient and subsequent coefficients of increasing powers.
59
+ * @return {Array} The distinct roots of the polynomial
60
+ */
61
+
62
+ return typed(name, {
63
+ 'number|Complex, ...number|Complex': function numberComplexNumberComplex(constant, restCoeffs) {
64
+ var coeffs = [constant].concat((0, _toConsumableArray2["default"])(restCoeffs));
65
+ while (coeffs.length > 0 && isZero(coeffs[coeffs.length - 1])) {
66
+ coeffs.pop();
67
+ }
68
+ if (coeffs.length < 2) {
69
+ throw new RangeError("Polynomial [".concat(constant, ", ").concat(restCoeffs, "] must have a non-zero non-constant coefficient"));
70
+ }
71
+ switch (coeffs.length) {
72
+ case 2:
73
+ // linear
74
+ return [unaryMinus(divide(coeffs[0], coeffs[1]))];
75
+ case 3:
76
+ {
77
+ // quadratic
78
+ var _coeffs = (0, _slicedToArray2["default"])(coeffs, 3),
79
+ c = _coeffs[0],
80
+ b = _coeffs[1],
81
+ a = _coeffs[2];
82
+ var denom = multiply(2, a);
83
+ var d1 = multiply(b, b);
84
+ var d2 = multiply(4, a, c);
85
+ if (equalScalar(d1, d2)) return [divide(unaryMinus(b), denom)];
86
+ var discriminant = sqrt(subtract(d1, d2));
87
+ return [divide(subtract(discriminant, b), denom), divide(subtract(unaryMinus(discriminant), b), denom)];
88
+ }
89
+ case 4:
90
+ {
91
+ // cubic, cf. https://en.wikipedia.org/wiki/Cubic_equation
92
+ var _coeffs2 = (0, _slicedToArray2["default"])(coeffs, 4),
93
+ d = _coeffs2[0],
94
+ _c = _coeffs2[1],
95
+ _b = _coeffs2[2],
96
+ _a = _coeffs2[3];
97
+ var _denom = unaryMinus(multiply(3, _a));
98
+ var D0_1 = multiply(_b, _b);
99
+ var D0_2 = multiply(3, _a, _c);
100
+ var D1_1 = add(multiply(2, _b, _b, _b), multiply(27, _a, _a, d));
101
+ var D1_2 = multiply(9, _a, _b, _c);
102
+ if (equalScalar(D0_1, D0_2) && equalScalar(D1_1, D1_2)) {
103
+ return [divide(_b, _denom)];
104
+ }
105
+ var Delta0 = subtract(D0_1, D0_2);
106
+ var Delta1 = subtract(D1_1, D1_2);
107
+ var discriminant1 = add(multiply(18, _a, _b, _c, d), multiply(_b, _b, _c, _c));
108
+ var discriminant2 = add(multiply(4, _b, _b, _b, d), multiply(4, _a, _c, _c, _c), multiply(27, _a, _a, d, d));
109
+ if (equalScalar(discriminant1, discriminant2)) {
110
+ return [divide(subtract(multiply(4, _a, _b, _c), add(multiply(9, _a, _a, d), multiply(_b, _b, _b))), multiply(_a, Delta0)),
111
+ // simple root
112
+ divide(subtract(multiply(9, _a, d), multiply(_b, _c)), multiply(2, Delta0)) // double root
113
+ ];
114
+ }
115
+ // OK, we have three distinct roots
116
+ var Ccubed;
117
+ if (equalScalar(D0_1, D0_2)) {
118
+ Ccubed = Delta1;
119
+ } else {
120
+ Ccubed = divide(add(Delta1, sqrt(subtract(multiply(Delta1, Delta1), multiply(4, Delta0, Delta0, Delta0)))), 2);
121
+ }
122
+ var allRoots = true;
123
+ var rawRoots = cbrt(Ccubed, allRoots).toArray().map(function (C) {
124
+ return divide(add(_b, C, divide(Delta0, C)), _denom);
125
+ });
126
+ return rawRoots.map(function (r) {
127
+ if (typeOf(r) === 'Complex' && equalScalar(re(r), re(r) + im(r))) {
128
+ return re(r);
129
+ }
130
+ return r;
131
+ });
132
+ }
133
+ default:
134
+ throw new RangeError("only implemented for cubic or lower-order polynomials, not ".concat(coeffs));
135
+ }
136
+ }
137
+ });
138
+ });
139
+ exports.createPolynomialRoot = createPolynomialRoot;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isConstantExpression = isConstantExpression;
7
+ Object.defineProperty(exports, "isConstantNode", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _is.isConstantNode;
11
+ }
12
+ });
13
+ exports.isNumericNode = isNumericNode;
14
+ Object.defineProperty(exports, "isVariableNode", {
15
+ enumerable: true,
16
+ get: function get() {
17
+ return _is.isSymbolNode;
18
+ }
19
+ });
20
+ var _is = require("../../../utils/is.js");
21
+ function isNumericNode(x) {
22
+ return (0, _is.isConstantNode)(x) || (0, _is.isOperatorNode)(x) && x.isUnary() && (0, _is.isConstantNode)(x.args[0]);
23
+ }
24
+ function isConstantExpression(x) {
25
+ if ((0, _is.isConstantNode)(x)) {
26
+ // Basic Constant types
27
+ return true;
28
+ }
29
+ if (((0, _is.isFunctionNode)(x) || (0, _is.isOperatorNode)(x)) && x.args.every(isConstantExpression)) {
30
+ // Can be constant depending on arguments
31
+ return true;
32
+ }
33
+ if ((0, _is.isParenthesisNode)(x) && isConstantExpression(x.content)) {
34
+ // Parenthesis are transparent
35
+ return true;
36
+ }
37
+ return false; // Probably missing some edge cases
38
+ }
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.createSimplify = void 0;
8
8
  var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
9
9
  var _is = require("../../utils/is.js");
10
+ var _wildcards = require("./simplify/wildcards.js");
10
11
  var _factory = require("../../utils/factory.js");
11
12
  var _util = require("./simplify/util.js");
12
13
  var _object = require("../../utils/object.js");
@@ -80,9 +81,15 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
80
81
  * expression is that variables starting with the following characters are
81
82
  * interpreted as wildcards:
82
83
  *
83
- * - 'n' - matches any Node
84
- * - 'c' - matches any ConstantNode
85
- * - 'v' - matches any Node that is not a ConstantNode
84
+ * - 'n' - Matches any node [Node]
85
+ * - 'c' - Matches a constant literal (5 or 3.2) [ConstantNode]
86
+ * - 'cl' - Matches a constant literal; same as c [ConstantNode]
87
+ * - 'cd' - Matches a decimal literal (5 or -3.2) [ConstantNode or unaryMinus wrapping a ConstantNode]
88
+ * - 'ce' - Matches a constant expression (-5 or √3) [Expressions consisting of only ConstantNodes, functions, and operators]
89
+ * - 'v' - Matches a variable; anything not matched by c (-5 or x) [Node that is not a ConstantNode]
90
+ * - 'vl' - Matches a variable literal (x or y) [SymbolNode]
91
+ * - 'vd' - Matches a non-decimal expression; anything not matched by cd (x or √3) [Node that is not a ConstantNode or unaryMinus that is wrapping a ConstantNode]
92
+ * - 've' - Matches a variable expression; anything not matched by ce (x or 2x) [Expressions that contain a SymbolNode or other non-constant term]
86
93
  *
87
94
  * The default list of rules is exposed on the function as `simplify.rules`
88
95
  * and can be used as a basis to built a set of custom rules. Note that since
@@ -259,7 +266,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
259
266
  }
260
267
  }
261
268
  }, {
262
- s: '-(c*v) -> v * (-c)',
269
+ s: '-(cl*v) -> v * (-cl)',
263
270
  // make non-constant terms positive
264
271
  assuming: {
265
272
  multiply: {
@@ -270,7 +277,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
270
277
  }
271
278
  }
272
279
  }, {
273
- s: '-(c*v) -> (-c) * v',
280
+ s: '-(cl*v) -> (-cl) * v',
274
281
  // non-commutative version, part 1
275
282
  assuming: {
276
283
  multiply: {
@@ -281,7 +288,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
281
288
  }
282
289
  }
283
290
  }, {
284
- s: '-(v*c) -> v * (-c)',
291
+ s: '-(v*cl) -> v * (-cl)',
285
292
  // non-commutative version, part 2
286
293
  assuming: {
287
294
  multiply: {
@@ -339,24 +346,24 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
339
346
  },
340
347
  // collect like factors; into a sum, only do this for nonconstants
341
348
  {
342
- l: ' v * ( v * n1 + n2)',
343
- r: 'v^2 * n1 + v * n2'
349
+ l: ' vd * ( vd * n1 + n2)',
350
+ r: 'vd^2 * n1 + vd * n2'
344
351
  }, {
345
- s: ' v * (v^n4 * n1 + n2) -> v^(1+n4) * n1 + v * n2',
352
+ s: ' vd * (vd^n4 * n1 + n2) -> vd^(1+n4) * n1 + vd * n2',
346
353
  assuming: {
347
354
  divide: {
348
355
  total: true
349
356
  }
350
357
  } // v*1/v = v^(1+-1) needs 1/v
351
358
  }, {
352
- s: 'v^n3 * ( v * n1 + n2) -> v^(n3+1) * n1 + v^n3 * n2',
359
+ s: 'vd^n3 * ( vd * n1 + n2) -> vd^(n3+1) * n1 + vd^n3 * n2',
353
360
  assuming: {
354
361
  divide: {
355
362
  total: true
356
363
  }
357
364
  }
358
365
  }, {
359
- s: 'v^n3 * (v^n4 * n1 + n2) -> v^(n3+n4) * n1 + v^n3 * n2',
366
+ s: 'vd^n3 * (vd^n4 * n1 + n2) -> vd^(n3+n4) * n1 + vd^n3 * n2',
360
367
  assuming: {
361
368
  divide: {
362
369
  total: true
@@ -399,8 +406,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
399
406
  l: 'n+-n',
400
407
  r: '0'
401
408
  }, {
402
- l: 'v*n + v',
403
- r: 'v*(n+1)'
409
+ l: 'vd*n + vd',
410
+ r: 'vd*(n+1)'
404
411
  },
405
412
  // NOTE: leftmost position is special:
406
413
  {
@@ -415,7 +422,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
415
422
  l: 'n3^(-n4)*n1 + n3^n5 * n2',
416
423
  r: 'n3^(-n4)*(n1 + n3^(n4+n5)*n2)'
417
424
  }, {
418
- s: 'n*v + v -> (n+1)*v',
425
+ s: 'n*vd + vd -> (n+1)*vd',
419
426
  // noncommutative additional cases
420
427
  assuming: {
421
428
  multiply: {
@@ -444,10 +451,10 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
444
451
  }
445
452
  }
446
453
  }, {
447
- l: 'n*c + c',
448
- r: '(n+1)*c'
454
+ l: 'n*cd + cd',
455
+ r: '(n+1)*cd'
449
456
  }, {
450
- s: 'c*n + c -> c*(n+1)',
457
+ s: 'cd*n + cd -> cd*(n+1)',
451
458
  assuming: {
452
459
  multiply: {
453
460
  commutative: false
@@ -478,7 +485,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
478
485
  },
479
486
  // final ordering of constants
480
487
  {
481
- s: 'c+v -> v+c',
488
+ s: 'ce+ve -> ve+ce',
482
489
  assuming: {
483
490
  add: {
484
491
  commutative: true
@@ -490,7 +497,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
490
497
  }
491
498
  }
492
499
  }, {
493
- s: 'v*c -> c*v',
500
+ s: 'vd*cd -> cd*vd',
494
501
  assuming: {
495
502
  multiply: {
496
503
  commutative: true
@@ -1057,9 +1064,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
1057
1064
  }
1058
1065
  } else if (rule instanceof SymbolNode) {
1059
1066
  // If the rule is a SymbolNode, then it carries a special meaning
1060
- // according to the first character of the symbol node name.
1061
- // c.* matches a ConstantNode
1062
- // n.* matches any node
1067
+ // according to the first one or two characters of the symbol node name.
1068
+ // These meanings are expalined in the documentation for simplify()
1063
1069
  if (rule.name.length === 0) {
1064
1070
  throw new Error('Symbol in rule has 0 length...!?');
1065
1071
  }
@@ -1068,29 +1074,83 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
1068
1074
  if (rule.name !== node.name) {
1069
1075
  return [];
1070
1076
  }
1071
- } else if (rule.name[0] === 'n' || rule.name.substring(0, 2) === '_p') {
1072
- // rule matches _anything_, so assign this node to the rule.name placeholder
1073
- // Assign node to the rule.name placeholder.
1074
- // Our parent will check for matches among placeholders.
1075
- res[0].placeholders[rule.name] = node;
1076
- } else if (rule.name[0] === 'v') {
1077
- // rule matches any variable thing (not a ConstantNode)
1078
- if (!(0, _is.isConstantNode)(node)) {
1079
- res[0].placeholders[rule.name] = node;
1080
- } else {
1081
- // Mis-match: rule was expecting something other than a ConstantNode
1082
- return [];
1083
- }
1084
- } else if (rule.name[0] === 'c') {
1085
- // rule matches any ConstantNode
1086
- if (node instanceof ConstantNode) {
1087
- res[0].placeholders[rule.name] = node;
1088
- } else {
1089
- // Mis-match: rule was expecting a ConstantNode
1090
- return [];
1091
- }
1092
1077
  } else {
1093
- throw new Error('Invalid symbol in rule: ' + rule.name);
1078
+ // wildcards are composed of up to two alphabetic or underscore characters
1079
+ switch (rule.name[1] >= 'a' && rule.name[1] <= 'z' ? rule.name.substring(0, 2) : rule.name[0]) {
1080
+ case 'n':
1081
+ case '_p':
1082
+ // rule matches _anything_, so assign this node to the rule.name placeholder
1083
+ // Assign node to the rule.name placeholder.
1084
+ // Our parent will check for matches among placeholders.
1085
+ res[0].placeholders[rule.name] = node;
1086
+ break;
1087
+ case 'c':
1088
+ case 'cl':
1089
+ // rule matches a ConstantNode
1090
+ if ((0, _wildcards.isConstantNode)(node)) {
1091
+ res[0].placeholders[rule.name] = node;
1092
+ } else {
1093
+ // mis-match: rule does not encompass current node
1094
+ return [];
1095
+ }
1096
+ break;
1097
+ case 'v':
1098
+ // rule matches anything other than a ConstantNode
1099
+ if (!(0, _wildcards.isConstantNode)(node)) {
1100
+ res[0].placeholders[rule.name] = node;
1101
+ } else {
1102
+ // mis-match: rule does not encompass current node
1103
+ return [];
1104
+ }
1105
+ break;
1106
+ case 'vl':
1107
+ // rule matches VariableNode
1108
+ if ((0, _wildcards.isVariableNode)(node)) {
1109
+ res[0].placeholders[rule.name] = node;
1110
+ } else {
1111
+ // mis-match: rule does not encompass current node
1112
+ return [];
1113
+ }
1114
+ break;
1115
+ case 'cd':
1116
+ // rule matches a ConstantNode or unaryMinus-wrapped ConstantNode
1117
+ if ((0, _wildcards.isNumericNode)(node)) {
1118
+ res[0].placeholders[rule.name] = node;
1119
+ } else {
1120
+ // mis-match: rule does not encompass current node
1121
+ return [];
1122
+ }
1123
+ break;
1124
+ case 'vd':
1125
+ // rule matches anything other than a ConstantNode or unaryMinus-wrapped ConstantNode
1126
+ if (!(0, _wildcards.isNumericNode)(node)) {
1127
+ res[0].placeholders[rule.name] = node;
1128
+ } else {
1129
+ // mis-match: rule does not encompass current node
1130
+ return [];
1131
+ }
1132
+ break;
1133
+ case 'ce':
1134
+ // rule matches expressions that have a constant value
1135
+ if ((0, _wildcards.isConstantExpression)(node)) {
1136
+ res[0].placeholders[rule.name] = node;
1137
+ } else {
1138
+ // mis-match: rule does not encompass current node
1139
+ return [];
1140
+ }
1141
+ break;
1142
+ case 've':
1143
+ // rule matches expressions that do not have a constant value
1144
+ if (!(0, _wildcards.isConstantExpression)(node)) {
1145
+ res[0].placeholders[rule.name] = node;
1146
+ } else {
1147
+ // mis-match: rule does not encompass current node
1148
+ return [];
1149
+ }
1150
+ break;
1151
+ default:
1152
+ throw new Error('Invalid symbol in rule: ' + rule.name);
1153
+ }
1094
1154
  }
1095
1155
  } else if (rule instanceof ConstantNode) {
1096
1156
  // Literal constant must match exactly
@@ -307,20 +307,37 @@ var createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependen
307
307
  * @return - Either a Node representing a binary expression or Fraction
308
308
  */
309
309
  function foldOp(fn, args, makeNode, options) {
310
- return args.reduce(function (a, b) {
311
- if (!(0, _is.isNode)(a) && !(0, _is.isNode)(b)) {
310
+ var first = args.shift();
311
+
312
+ // In the following reduction, sofar always has one of the three following
313
+ // forms: [NODE], [CONSTANT], or [NODE, CONSTANT]
314
+ var reduction = args.reduce(function (sofar, next) {
315
+ if (!(0, _is.isNode)(next)) {
316
+ var last = sofar.pop();
317
+ if ((0, _is.isNode)(last)) {
318
+ return [last, next];
319
+ }
320
+ // Two constants in a row, try to fold them into one
312
321
  try {
313
- return _eval(fn, [a, b], options);
314
- } catch (ignoreandcontinue) {}
315
- a = _toNode(a);
316
- b = _toNode(b);
317
- } else if (!(0, _is.isNode)(a)) {
318
- a = _toNode(a);
319
- } else if (!(0, _is.isNode)(b)) {
320
- b = _toNode(b);
322
+ sofar.push(_eval(fn, [last, next], options));
323
+ return sofar;
324
+ } catch (ignoreandcontinue) {
325
+ sofar.push(last);
326
+ // fall through to Node case
327
+ }
321
328
  }
322
- return makeNode([a, b]);
323
- });
329
+
330
+ // Encountered a Node, or failed folding --
331
+ // collapse everything so far into a single tree:
332
+ sofar.push(_ensureNode(sofar.pop()));
333
+ var newtree = sofar.length === 1 ? sofar[0] : makeNode(sofar);
334
+ return [makeNode([newtree, _ensureNode(next)])];
335
+ }, [first]);
336
+ if (reduction.length === 1) {
337
+ return reduction[0];
338
+ }
339
+ // Might end up with a tree and a constant at the end:
340
+ return makeNode([reduction[0], _toNode(reduction[1])]);
324
341
  }
325
342
 
326
343
  // destroys the original node and returns a folded one