mathjs 13.2.3 → 14.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. package/HISTORY.md +24 -0
  2. package/lib/browser/math.js +1 -1
  3. package/lib/browser/math.js.LICENSE.txt +2 -10
  4. package/lib/browser/math.js.map +1 -1
  5. package/lib/cjs/core/function/import.js +4 -1
  6. package/lib/cjs/core/function/typed.js +1 -1
  7. package/lib/cjs/entry/dependenciesAny/dependenciesBitXor.generated.js +2 -0
  8. package/lib/cjs/entry/dependenciesAny/dependenciesDotDivide.generated.js +2 -0
  9. package/lib/cjs/entry/dependenciesAny/dependenciesDotPow.generated.js +2 -0
  10. package/lib/cjs/entry/dependenciesAny/dependenciesEqual.generated.js +2 -0
  11. package/lib/cjs/entry/dependenciesAny/dependenciesLarger.generated.js +2 -0
  12. package/lib/cjs/entry/dependenciesAny/dependenciesLargerEq.generated.js +2 -0
  13. package/lib/cjs/entry/dependenciesAny/dependenciesLog.generated.js +2 -0
  14. package/lib/cjs/entry/dependenciesAny/dependenciesSimplify.generated.js +2 -0
  15. package/lib/cjs/entry/dependenciesAny/dependenciesSmaller.generated.js +2 -0
  16. package/lib/cjs/entry/dependenciesAny/dependenciesSmallerEq.generated.js +2 -0
  17. package/lib/cjs/entry/dependenciesAny/dependenciesUnequal.generated.js +2 -0
  18. package/lib/cjs/entry/dependenciesAny/dependenciesXor.generated.js +2 -0
  19. package/lib/cjs/entry/dependenciesNumber/dependenciesSimplify.generated.js +2 -0
  20. package/lib/cjs/entry/impureFunctionsAny.generated.js +1 -0
  21. package/lib/cjs/entry/impureFunctionsNumber.generated.js +1 -0
  22. package/lib/cjs/entry/pureFunctionsAny.generated.js +11 -0
  23. package/lib/cjs/expression/embeddedDocs/function/arithmetic/ceil.js +2 -2
  24. package/lib/cjs/expression/embeddedDocs/function/arithmetic/fix.js +2 -2
  25. package/lib/cjs/expression/embeddedDocs/function/arithmetic/floor.js +2 -2
  26. package/lib/cjs/expression/parse.js +26 -36
  27. package/lib/cjs/function/algebra/derivative.js +64 -77
  28. package/lib/cjs/function/algebra/simplify.js +4 -3
  29. package/lib/cjs/function/algebra/simplifyConstant.js +5 -11
  30. package/lib/cjs/function/arithmetic/ceil.js +21 -2
  31. package/lib/cjs/function/arithmetic/dotDivide.js +4 -3
  32. package/lib/cjs/function/arithmetic/dotPow.js +4 -3
  33. package/lib/cjs/function/arithmetic/fix.js +24 -5
  34. package/lib/cjs/function/arithmetic/floor.js +21 -2
  35. package/lib/cjs/function/arithmetic/log.js +12 -4
  36. package/lib/cjs/function/arithmetic/pow.js +2 -2
  37. package/lib/cjs/function/arithmetic/round.js +3 -5
  38. package/lib/cjs/function/arithmetic/sign.js +1 -1
  39. package/lib/cjs/function/bitwise/bitXor.js +4 -3
  40. package/lib/cjs/function/logical/xor.js +4 -3
  41. package/lib/cjs/function/relational/equal.js +4 -3
  42. package/lib/cjs/function/relational/larger.js +4 -3
  43. package/lib/cjs/function/relational/largerEq.js +4 -3
  44. package/lib/cjs/function/relational/smaller.js +4 -3
  45. package/lib/cjs/function/relational/smallerEq.js +4 -3
  46. package/lib/cjs/function/relational/unequal.js +4 -3
  47. package/lib/cjs/function/utils/isInteger.js +1 -1
  48. package/lib/cjs/function/utils/isNegative.js +1 -1
  49. package/lib/cjs/function/utils/isPositive.js +1 -1
  50. package/lib/cjs/header.js +2 -2
  51. package/lib/cjs/type/bignumber/function/bignumber.js +2 -2
  52. package/lib/cjs/type/fraction/Fraction.js +4 -4
  53. package/lib/cjs/type/fraction/function/fraction.js +3 -0
  54. package/lib/cjs/type/matrix/utils/matAlgo07xSSf.js +39 -43
  55. package/lib/cjs/type/unit/Unit.js +1 -1
  56. package/lib/cjs/utils/string.js +2 -2
  57. package/lib/cjs/version.js +1 -1
  58. package/lib/esm/core/function/import.js +4 -1
  59. package/lib/esm/core/function/typed.js +1 -1
  60. package/lib/esm/entry/dependenciesAny/dependenciesBitXor.generated.js +2 -0
  61. package/lib/esm/entry/dependenciesAny/dependenciesDotDivide.generated.js +2 -0
  62. package/lib/esm/entry/dependenciesAny/dependenciesDotPow.generated.js +2 -0
  63. package/lib/esm/entry/dependenciesAny/dependenciesEqual.generated.js +2 -0
  64. package/lib/esm/entry/dependenciesAny/dependenciesLarger.generated.js +2 -0
  65. package/lib/esm/entry/dependenciesAny/dependenciesLargerEq.generated.js +2 -0
  66. package/lib/esm/entry/dependenciesAny/dependenciesLog.generated.js +2 -0
  67. package/lib/esm/entry/dependenciesAny/dependenciesSimplify.generated.js +2 -0
  68. package/lib/esm/entry/dependenciesAny/dependenciesSmaller.generated.js +2 -0
  69. package/lib/esm/entry/dependenciesAny/dependenciesSmallerEq.generated.js +2 -0
  70. package/lib/esm/entry/dependenciesAny/dependenciesUnequal.generated.js +2 -0
  71. package/lib/esm/entry/dependenciesAny/dependenciesXor.generated.js +2 -0
  72. package/lib/esm/entry/dependenciesNumber/dependenciesSimplify.generated.js +2 -0
  73. package/lib/esm/entry/impureFunctionsAny.generated.js +1 -0
  74. package/lib/esm/entry/impureFunctionsNumber.generated.js +1 -0
  75. package/lib/esm/entry/pureFunctionsAny.generated.js +11 -0
  76. package/lib/esm/expression/embeddedDocs/function/arithmetic/ceil.js +2 -2
  77. package/lib/esm/expression/embeddedDocs/function/arithmetic/fix.js +2 -2
  78. package/lib/esm/expression/embeddedDocs/function/arithmetic/floor.js +2 -2
  79. package/lib/esm/expression/parse.js +26 -36
  80. package/lib/esm/function/algebra/derivative.js +64 -77
  81. package/lib/esm/function/algebra/simplify.js +4 -3
  82. package/lib/esm/function/algebra/simplifyConstant.js +5 -11
  83. package/lib/esm/function/arithmetic/ceil.js +21 -2
  84. package/lib/esm/function/arithmetic/dotDivide.js +4 -3
  85. package/lib/esm/function/arithmetic/dotPow.js +4 -3
  86. package/lib/esm/function/arithmetic/fix.js +24 -5
  87. package/lib/esm/function/arithmetic/floor.js +21 -2
  88. package/lib/esm/function/arithmetic/log.js +12 -4
  89. package/lib/esm/function/arithmetic/pow.js +2 -2
  90. package/lib/esm/function/arithmetic/round.js +3 -5
  91. package/lib/esm/function/arithmetic/sign.js +1 -1
  92. package/lib/esm/function/bitwise/bitXor.js +4 -3
  93. package/lib/esm/function/logical/xor.js +4 -3
  94. package/lib/esm/function/relational/equal.js +4 -3
  95. package/lib/esm/function/relational/larger.js +4 -3
  96. package/lib/esm/function/relational/largerEq.js +4 -3
  97. package/lib/esm/function/relational/smaller.js +4 -3
  98. package/lib/esm/function/relational/smallerEq.js +4 -3
  99. package/lib/esm/function/relational/unequal.js +4 -3
  100. package/lib/esm/function/utils/isInteger.js +1 -1
  101. package/lib/esm/function/utils/isNegative.js +1 -1
  102. package/lib/esm/function/utils/isPositive.js +1 -1
  103. package/lib/esm/type/bignumber/function/bignumber.js +2 -2
  104. package/lib/esm/type/fraction/Fraction.js +4 -4
  105. package/lib/esm/type/fraction/function/fraction.js +3 -0
  106. package/lib/esm/type/matrix/utils/matAlgo07xSSf.js +39 -43
  107. package/lib/esm/type/unit/Unit.js +1 -1
  108. package/lib/esm/utils/string.js +2 -2
  109. package/lib/esm/version.js +1 -1
  110. package/package.json +13 -13
  111. package/types/index.d.ts +112 -23
@@ -66,9 +66,18 @@ const createDerivative = exports.createDerivative = /* #__PURE__ */(0, _factory.
66
66
  let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
67
67
  simplify: true
68
68
  };
69
- const constNodes = {};
70
- constTag(constNodes, expr, variable.name);
71
- const res = _derivative(expr, constNodes);
69
+ const cache = new Map();
70
+ const variableName = variable.name;
71
+ function isConstCached(node) {
72
+ const cached = cache.get(node);
73
+ if (cached !== undefined) {
74
+ return cached;
75
+ }
76
+ const res = _isConst(isConstCached, node, variableName);
77
+ cache.set(node, res);
78
+ return res;
79
+ }
80
+ const res = _derivative(expr, isConstCached);
72
81
  return options.simplify ? simplify(res) : res;
73
82
  }
74
83
  function parseIdentifier(string) {
@@ -88,9 +97,8 @@ const createDerivative = exports.createDerivative = /* #__PURE__ */(0, _factory.
88
97
  'Node, SymbolNode, ConstantNode': function (expr, variable, {order}) {
89
98
  let res = expr
90
99
  for (let i = 0; i < order; i++) {
91
- let constNodes = {}
92
- constTag(constNodes, expr, variable.name)
93
- res = _derivative(res, constNodes)
100
+ <create caching isConst>
101
+ res = _derivative(res, isConst)
94
102
  }
95
103
  return res
96
104
  }
@@ -133,56 +141,39 @@ const createDerivative = exports.createDerivative = /* #__PURE__ */(0, _factory.
133
141
  });
134
142
 
135
143
  /**
136
- * Does a depth-first search on the expression tree to identify what Nodes
137
- * are constants (e.g. 2 + 2), and stores the ones that are constants in
138
- * constNodes. Classification is done as follows:
144
+ * Checks if a node is constants (e.g. 2 + 2).
145
+ * Accepts (usually memoized) version of self as the first parameter for recursive calls.
146
+ * Classification is done as follows:
139
147
  *
140
148
  * 1. ConstantNodes are constants.
141
149
  * 2. If there exists a SymbolNode, of which we are differentiating over,
142
150
  * in the subtree it is not constant.
143
151
  *
144
- * @param {Object} constNodes Holds the nodes that are constant
152
+ * @param {function} isConst Function that tells whether sub-expression is a constant
145
153
  * @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
146
154
  * @param {string} varName Variable that we are differentiating
147
155
  * @return {boolean} if node is constant
148
156
  */
149
- // TODO: can we rewrite constTag into a pure function?
150
- const constTag = typed('constTag', {
151
- 'Object, ConstantNode, string': function (constNodes, node) {
152
- constNodes[node] = true;
157
+ const _isConst = typed('_isConst', {
158
+ 'function, ConstantNode, string': function () {
153
159
  return true;
154
160
  },
155
- 'Object, SymbolNode, string': function (constNodes, node, varName) {
161
+ 'function, SymbolNode, string': function (isConst, node, varName) {
156
162
  // Treat other variables like constants. For reasoning, see:
157
163
  // https://en.wikipedia.org/wiki/Partial_derivative
158
- if (node.name !== varName) {
159
- constNodes[node] = true;
160
- return true;
161
- }
162
- return false;
164
+ return node.name !== varName;
163
165
  },
164
- 'Object, ParenthesisNode, string': function (constNodes, node, varName) {
165
- return constTag(constNodes, node.content, varName);
166
+ 'function, ParenthesisNode, string': function (isConst, node, varName) {
167
+ return isConst(node.content, varName);
166
168
  },
167
- 'Object, FunctionAssignmentNode, string': function (constNodes, node, varName) {
169
+ 'function, FunctionAssignmentNode, string': function (isConst, node, varName) {
168
170
  if (!node.params.includes(varName)) {
169
- constNodes[node] = true;
170
171
  return true;
171
172
  }
172
- return constTag(constNodes, node.expr, varName);
173
+ return isConst(node.expr, varName);
173
174
  },
174
- 'Object, FunctionNode | OperatorNode, string': function (constNodes, node, varName) {
175
- if (node.args.length > 0) {
176
- let isConst = constTag(constNodes, node.args[0], varName);
177
- for (let i = 1; i < node.args.length; ++i) {
178
- isConst = constTag(constNodes, node.args[i], varName) && isConst;
179
- }
180
- if (isConst) {
181
- constNodes[node] = true;
182
- return true;
183
- }
184
- }
185
- return false;
175
+ 'function, FunctionNode | OperatorNode, string': function (isConst, node, varName) {
176
+ return node.args.every(arg => isConst(arg, varName));
186
177
  }
187
178
  });
188
179
 
@@ -190,30 +181,30 @@ const createDerivative = exports.createDerivative = /* #__PURE__ */(0, _factory.
190
181
  * Applies differentiation rules.
191
182
  *
192
183
  * @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
193
- * @param {Object} constNodes Holds the nodes that are constant
184
+ * @param {function} isConst Function that tells if a node is constant
194
185
  * @return {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} The derivative of `expr`
195
186
  */
196
187
  const _derivative = typed('_derivative', {
197
- 'ConstantNode, Object': function (node) {
188
+ 'ConstantNode, function': function () {
198
189
  return createConstantNode(0);
199
190
  },
200
- 'SymbolNode, Object': function (node, constNodes) {
201
- if (constNodes[node] !== undefined) {
191
+ 'SymbolNode, function': function (node, isConst) {
192
+ if (isConst(node)) {
202
193
  return createConstantNode(0);
203
194
  }
204
195
  return createConstantNode(1);
205
196
  },
206
- 'ParenthesisNode, Object': function (node, constNodes) {
207
- return new ParenthesisNode(_derivative(node.content, constNodes));
197
+ 'ParenthesisNode, function': function (node, isConst) {
198
+ return new ParenthesisNode(_derivative(node.content, isConst));
208
199
  },
209
- 'FunctionAssignmentNode, Object': function (node, constNodes) {
210
- if (constNodes[node] !== undefined) {
200
+ 'FunctionAssignmentNode, function': function (node, isConst) {
201
+ if (isConst(node)) {
211
202
  return createConstantNode(0);
212
203
  }
213
- return _derivative(node.expr, constNodes);
204
+ return _derivative(node.expr, isConst);
214
205
  },
215
- 'FunctionNode, Object': function (node, constNodes) {
216
- if (constNodes[node] !== undefined) {
206
+ 'FunctionNode, function': function (node, isConst) {
207
+ if (isConst(node)) {
217
208
  return createConstantNode(0);
218
209
  }
219
210
  const arg0 = node.args[0];
@@ -237,10 +228,7 @@ const createDerivative = exports.createDerivative = /* #__PURE__ */(0, _factory.
237
228
  } else if (node.args.length === 2) {
238
229
  // Rearrange from nthRoot(x, a) -> x^(1/a)
239
230
  arg1 = new OperatorNode('/', 'divide', [createConstantNode(1), node.args[1]]);
240
-
241
- // Is a variable?
242
- constNodes[arg1] = constNodes[node.args[1]];
243
- return _derivative(new OperatorNode('^', 'pow', [arg0, arg1]), constNodes);
231
+ return _derivative(new OperatorNode('^', 'pow', [arg0, arg1]), isConst);
244
232
  }
245
233
  break;
246
234
  case 'log10':
@@ -251,20 +239,19 @@ const createDerivative = exports.createDerivative = /* #__PURE__ */(0, _factory.
251
239
  // d/dx(log(x)) = 1 / x
252
240
  funcDerivative = arg0.clone();
253
241
  div = true;
254
- } else if (node.args.length === 1 && arg1 || node.args.length === 2 && constNodes[node.args[1]] !== undefined) {
242
+ } else if (node.args.length === 1 && arg1 || node.args.length === 2 && isConst(node.args[1])) {
255
243
  // d/dx(log(x, c)) = 1 / (x*ln(c))
256
244
  funcDerivative = new OperatorNode('*', 'multiply', [arg0.clone(), new FunctionNode('log', [arg1 || node.args[1]])]);
257
245
  div = true;
258
246
  } else if (node.args.length === 2) {
259
247
  // d/dx(log(f(x), g(x))) = d/dx(log(f(x)) / log(g(x)))
260
- return _derivative(new OperatorNode('/', 'divide', [new FunctionNode('log', [arg0]), new FunctionNode('log', [node.args[1]])]), constNodes);
248
+ return _derivative(new OperatorNode('/', 'divide', [new FunctionNode('log', [arg0]), new FunctionNode('log', [node.args[1]])]), isConst);
261
249
  }
262
250
  break;
263
251
  case 'pow':
264
252
  if (node.args.length === 2) {
265
- constNodes[arg1] = constNodes[node.args[1]];
266
253
  // Pass to pow operator node parser
267
- return _derivative(new OperatorNode('^', 'pow', [arg0, node.args[1]]), constNodes);
254
+ return _derivative(new OperatorNode('^', 'pow', [arg0, node.args[1]]), isConst);
268
255
  }
269
256
  break;
270
257
  case 'exp':
@@ -410,51 +397,51 @@ const createDerivative = exports.createDerivative = /* #__PURE__ */(0, _factory.
410
397
  /* Apply chain rule to all functions:
411
398
  F(x) = f(g(x))
412
399
  F'(x) = g'(x)*f'(g(x)) */
413
- let chainDerivative = _derivative(arg0, constNodes);
400
+ let chainDerivative = _derivative(arg0, isConst);
414
401
  if (negative) {
415
402
  chainDerivative = new OperatorNode('-', 'unaryMinus', [chainDerivative]);
416
403
  }
417
404
  return new OperatorNode(op, func, [chainDerivative, funcDerivative]);
418
405
  },
419
- 'OperatorNode, Object': function (node, constNodes) {
420
- if (constNodes[node] !== undefined) {
406
+ 'OperatorNode, function': function (node, isConst) {
407
+ if (isConst(node)) {
421
408
  return createConstantNode(0);
422
409
  }
423
410
  if (node.op === '+') {
424
411
  // d/dx(sum(f(x)) = sum(f'(x))
425
412
  return new OperatorNode(node.op, node.fn, node.args.map(function (arg) {
426
- return _derivative(arg, constNodes);
413
+ return _derivative(arg, isConst);
427
414
  }));
428
415
  }
429
416
  if (node.op === '-') {
430
417
  // d/dx(+/-f(x)) = +/-f'(x)
431
418
  if (node.isUnary()) {
432
- return new OperatorNode(node.op, node.fn, [_derivative(node.args[0], constNodes)]);
419
+ return new OperatorNode(node.op, node.fn, [_derivative(node.args[0], isConst)]);
433
420
  }
434
421
 
435
422
  // Linearity of differentiation, d/dx(f(x) +/- g(x)) = f'(x) +/- g'(x)
436
423
  if (node.isBinary()) {
437
- return new OperatorNode(node.op, node.fn, [_derivative(node.args[0], constNodes), _derivative(node.args[1], constNodes)]);
424
+ return new OperatorNode(node.op, node.fn, [_derivative(node.args[0], isConst), _derivative(node.args[1], isConst)]);
438
425
  }
439
426
  }
440
427
  if (node.op === '*') {
441
428
  // d/dx(c*f(x)) = c*f'(x)
442
429
  const constantTerms = node.args.filter(function (arg) {
443
- return constNodes[arg] !== undefined;
430
+ return isConst(arg);
444
431
  });
445
432
  if (constantTerms.length > 0) {
446
433
  const nonConstantTerms = node.args.filter(function (arg) {
447
- return constNodes[arg] === undefined;
434
+ return !isConst(arg);
448
435
  });
449
436
  const nonConstantNode = nonConstantTerms.length === 1 ? nonConstantTerms[0] : new OperatorNode('*', 'multiply', nonConstantTerms);
450
- const newArgs = constantTerms.concat(_derivative(nonConstantNode, constNodes));
437
+ const newArgs = constantTerms.concat(_derivative(nonConstantNode, isConst));
451
438
  return new OperatorNode('*', 'multiply', newArgs);
452
439
  }
453
440
 
454
441
  // Product Rule, d/dx(f(x)*g(x)) = f'(x)*g(x) + f(x)*g'(x)
455
442
  return new OperatorNode('+', 'add', node.args.map(function (argOuter) {
456
443
  return new OperatorNode('*', 'multiply', node.args.map(function (argInner) {
457
- return argInner === argOuter ? _derivative(argInner, constNodes) : argInner.clone();
444
+ return argInner === argOuter ? _derivative(argInner, isConst) : argInner.clone();
458
445
  }));
459
446
  }));
460
447
  }
@@ -463,31 +450,31 @@ const createDerivative = exports.createDerivative = /* #__PURE__ */(0, _factory.
463
450
  const arg1 = node.args[1];
464
451
 
465
452
  // d/dx(f(x) / c) = f'(x) / c
466
- if (constNodes[arg1] !== undefined) {
467
- return new OperatorNode('/', 'divide', [_derivative(arg0, constNodes), arg1]);
453
+ if (isConst(arg1)) {
454
+ return new OperatorNode('/', 'divide', [_derivative(arg0, isConst), arg1]);
468
455
  }
469
456
 
470
457
  // Reciprocal Rule, d/dx(c / f(x)) = -c(f'(x)/f(x)^2)
471
- if (constNodes[arg0] !== undefined) {
472
- return new OperatorNode('*', 'multiply', [new OperatorNode('-', 'unaryMinus', [arg0]), new OperatorNode('/', 'divide', [_derivative(arg1, constNodes), new OperatorNode('^', 'pow', [arg1.clone(), createConstantNode(2)])])]);
458
+ if (isConst(arg0)) {
459
+ return new OperatorNode('*', 'multiply', [new OperatorNode('-', 'unaryMinus', [arg0]), new OperatorNode('/', 'divide', [_derivative(arg1, isConst), new OperatorNode('^', 'pow', [arg1.clone(), createConstantNode(2)])])]);
473
460
  }
474
461
 
475
462
  // Quotient rule, d/dx(f(x) / g(x)) = (f'(x)g(x) - f(x)g'(x)) / g(x)^2
476
- return new OperatorNode('/', 'divide', [new OperatorNode('-', 'subtract', [new OperatorNode('*', 'multiply', [_derivative(arg0, constNodes), arg1.clone()]), new OperatorNode('*', 'multiply', [arg0.clone(), _derivative(arg1, constNodes)])]), new OperatorNode('^', 'pow', [arg1.clone(), createConstantNode(2)])]);
463
+ return new OperatorNode('/', 'divide', [new OperatorNode('-', 'subtract', [new OperatorNode('*', 'multiply', [_derivative(arg0, isConst), arg1.clone()]), new OperatorNode('*', 'multiply', [arg0.clone(), _derivative(arg1, isConst)])]), new OperatorNode('^', 'pow', [arg1.clone(), createConstantNode(2)])]);
477
464
  }
478
465
  if (node.op === '^' && node.isBinary()) {
479
466
  const arg0 = node.args[0];
480
467
  const arg1 = node.args[1];
481
- if (constNodes[arg0] !== undefined) {
468
+ if (isConst(arg0)) {
482
469
  // If is secretly constant; 0^f(x) = 1 (in JS), 1^f(x) = 1
483
470
  if ((0, _is.isConstantNode)(arg0) && (isZero(arg0.value) || equal(arg0.value, 1))) {
484
471
  return createConstantNode(0);
485
472
  }
486
473
 
487
474
  // d/dx(c^f(x)) = c^f(x)*ln(c)*f'(x)
488
- return new OperatorNode('*', 'multiply', [node, new OperatorNode('*', 'multiply', [new FunctionNode('log', [arg0.clone()]), _derivative(arg1.clone(), constNodes)])]);
475
+ return new OperatorNode('*', 'multiply', [node, new OperatorNode('*', 'multiply', [new FunctionNode('log', [arg0.clone()]), _derivative(arg1.clone(), isConst)])]);
489
476
  }
490
- if (constNodes[arg1] !== undefined) {
477
+ if (isConst(arg1)) {
491
478
  if ((0, _is.isConstantNode)(arg1)) {
492
479
  // If is secretly constant; f(x)^0 = 1 -> d/dx(1) = 0
493
480
  if (isZero(arg1.value)) {
@@ -495,17 +482,17 @@ const createDerivative = exports.createDerivative = /* #__PURE__ */(0, _factory.
495
482
  }
496
483
  // Ignore exponent; f(x)^1 = f(x)
497
484
  if (equal(arg1.value, 1)) {
498
- return _derivative(arg0, constNodes);
485
+ return _derivative(arg0, isConst);
499
486
  }
500
487
  }
501
488
 
502
489
  // Elementary Power Rule, d/dx(f(x)^c) = c*f'(x)*f(x)^(c-1)
503
490
  const powMinusOne = new OperatorNode('^', 'pow', [arg0.clone(), new OperatorNode('-', 'subtract', [arg1, createConstantNode(1)])]);
504
- return new OperatorNode('*', 'multiply', [arg1.clone(), new OperatorNode('*', 'multiply', [_derivative(arg0, constNodes), powMinusOne])]);
491
+ return new OperatorNode('*', 'multiply', [arg1.clone(), new OperatorNode('*', 'multiply', [_derivative(arg0, isConst), powMinusOne])]);
505
492
  }
506
493
 
507
494
  // Functional Power Rule, d/dx(f^g) = f^g*[f'*(g/f) + g'ln(f)]
508
- return new OperatorNode('*', 'multiply', [new OperatorNode('^', 'pow', [arg0.clone(), arg1.clone()]), new OperatorNode('+', 'add', [new OperatorNode('*', 'multiply', [_derivative(arg0, constNodes), new OperatorNode('/', 'divide', [arg1.clone(), arg0.clone()])]), new OperatorNode('*', 'multiply', [_derivative(arg1, constNodes), new FunctionNode('log', [arg0.clone()])])])]);
495
+ return new OperatorNode('*', 'multiply', [new OperatorNode('^', 'pow', [arg0.clone(), arg1.clone()]), new OperatorNode('+', 'add', [new OperatorNode('*', 'multiply', [_derivative(arg0, isConst), new OperatorNode('/', 'divide', [arg1.clone(), arg0.clone()])]), new OperatorNode('*', 'multiply', [_derivative(arg1, isConst), new FunctionNode('log', [arg0.clone()])])])]);
509
496
  }
510
497
  throw new Error('Cannot process operator "' + node.op + '" in derivative: ' + 'the operator is not supported, undefined, or the number of arguments passed to it are not supported');
511
498
  }
@@ -11,7 +11,7 @@ var _util = require("./simplify/util.js");
11
11
  var _object = require("../../utils/object.js");
12
12
  var _map = require("../../utils/map.js");
13
13
  const name = 'simplify';
14
- const dependencies = ['typed', 'parse', 'equal', 'resolve', 'simplifyConstant', 'simplifyCore', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode'];
14
+ const dependencies = ['typed', 'parse', 'equal', 'resolve', 'simplifyConstant', 'simplifyCore', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode', 'replacer'];
15
15
  const createSimplify = exports.createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
16
16
  let {
17
17
  typed,
@@ -28,7 +28,8 @@ const createSimplify = exports.createSimplify = /* #__PURE__ */(0, _factory.fact
28
28
  ObjectNode,
29
29
  OperatorNode,
30
30
  ParenthesisNode,
31
- SymbolNode
31
+ SymbolNode,
32
+ replacer
32
33
  } = _ref;
33
34
  const {
34
35
  hasProperty,
@@ -1004,7 +1005,7 @@ const createSimplify = exports.createSimplify = /* #__PURE__ */(0, _factory.fact
1004
1005
  const uniqueSets = [];
1005
1006
  const unique = {};
1006
1007
  for (let i = 0; i < sets.length; i++) {
1007
- const s = JSON.stringify(sets[i]);
1008
+ const s = JSON.stringify(sets[i], replacer);
1008
1009
  if (!unique[s]) {
1009
1010
  unique[s] = true;
1010
1011
  uniqueSets.push(sets[i]);
@@ -200,17 +200,11 @@ const createSimplifyConstant = exports.createSimplifyConstant = /* #__PURE__ */(
200
200
  return new OperatorNode('-', 'unaryMinus', [n]);
201
201
  }
202
202
  function _fractionToNode(f) {
203
- let n;
204
- const vn = f.s * f.n;
205
- if (vn < 0) {
206
- n = new OperatorNode('-', 'unaryMinus', [new ConstantNode(-vn)]);
207
- } else {
208
- n = new ConstantNode(vn);
209
- }
210
- if (f.d === 1) {
211
- return n;
212
- }
213
- return new OperatorNode('/', 'divide', [n, new ConstantNode(f.d)]);
203
+ // note: we convert await from bigint values, because bigint values gives issues with divisions: 1n/2n=0n and not 0.5
204
+ const fromBigInt = value => config.number === 'BigNumber' && bignumber ? bignumber(value) : Number(value);
205
+ const numeratorValue = f.s * f.n;
206
+ const numeratorNode = numeratorValue < 0n ? new OperatorNode('-', 'unaryMinus', [new ConstantNode(-fromBigInt(numeratorValue))]) : new ConstantNode(fromBigInt(numeratorValue));
207
+ return f.d === 1n ? numeratorNode : new OperatorNode('/', 'divide', [numeratorNode, new ConstantNode(fromBigInt(f.d))]);
214
208
  }
215
209
 
216
210
  /* Handles constant indexing of ArrayNodes, matrices, and ObjectNodes */
@@ -76,6 +76,8 @@ const createCeil = exports.createCeil = /* #__PURE__ */(0, _factory.factory)(nam
76
76
  *
77
77
  * math.ceil(x)
78
78
  * math.ceil(x, n)
79
+ * math.ceil(unit, valuelessUnit)
80
+ * math.ceil(unit, n, valuelessUnit)
79
81
  *
80
82
  * Examples:
81
83
  *
@@ -93,6 +95,12 @@ const createCeil = exports.createCeil = /* #__PURE__ */(0, _factory.factory)(nam
93
95
  * math.ceil(c) // returns Complex 4 - 2i
94
96
  * math.ceil(c, 1) // returns Complex 3.3 - 2.7i
95
97
  *
98
+ * const unit = math.unit('3.241 cm')
99
+ * const cm = math.unit('cm')
100
+ * const mm = math.unit('mm')
101
+ * math.ceil(unit, 1, cm) // returns Unit 3.3 cm
102
+ * math.ceil(unit, 1, mm) // returns Unit 32.5 mm
103
+ *
96
104
  * math.ceil([3.2, 3.8, -4.7]) // returns Array [4, 4, -4]
97
105
  * math.ceil([3.21, 3.82, -4.71], 1) // returns Array [3.3, 3.9, -4.7]
98
106
  *
@@ -100,9 +108,10 @@ const createCeil = exports.createCeil = /* #__PURE__ */(0, _factory.factory)(nam
100
108
  *
101
109
  * floor, fix, round
102
110
  *
103
- * @param {number | BigNumber | Fraction | Complex | Array | Matrix} x Number to be rounded
111
+ * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x Value to be rounded
104
112
  * @param {number | BigNumber | Array} [n=0] Number of decimals
105
- * @return {number | BigNumber | Fraction | Complex | Array | Matrix} Rounded value
113
+ * @param {Unit} [valuelessUnit] A valueless unit
114
+ * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Rounded value
106
115
  */
107
116
  return typed('ceil', {
108
117
  number: ceilNumber.signatures.number,
@@ -139,6 +148,16 @@ const createCeil = exports.createCeil = /* #__PURE__ */(0, _factory.factory)(nam
139
148
  'Fraction, BigNumber': function (x, n) {
140
149
  return x.ceil(n.toNumber());
141
150
  },
151
+ 'Unit, number, Unit': typed.referToSelf(self => function (x, n, unit) {
152
+ const valueless = x.toNumeric(unit);
153
+ return unit.multiply(self(valueless, n));
154
+ }),
155
+ 'Unit, BigNumber, Unit': typed.referToSelf(self => (x, n, unit) => self(x, n.toNumber(), unit)),
156
+ 'Array | Matrix, number | BigNumber, Unit': typed.referToSelf(self => (x, n, unit) => {
157
+ // deep map collection, skip zeros since ceil(0) = 0
158
+ return (0, _collection.deepMap)(x, value => self(value, n, unit), true);
159
+ }),
160
+ 'Array | Matrix | Unit, Unit': typed.referToSelf(self => (x, unit) => self(x, 0, unit)),
142
161
  'Array | Matrix': typed.referToSelf(self => x => {
143
162
  // deep map collection, skip zeros since ceil(0) = 0
144
163
  return (0, _collection.deepMap)(x, self, true);
@@ -12,7 +12,7 @@ var _matAlgo11xS0s = require("../../type/matrix/utils/matAlgo11xS0s.js");
12
12
  var _matAlgo12xSfs = require("../../type/matrix/utils/matAlgo12xSfs.js");
13
13
  var _matrixAlgorithmSuite = require("../../type/matrix/utils/matrixAlgorithmSuite.js");
14
14
  const name = 'dotDivide';
15
- const dependencies = ['typed', 'matrix', 'equalScalar', 'divideScalar', 'DenseMatrix', 'concat'];
15
+ const dependencies = ['typed', 'matrix', 'equalScalar', 'divideScalar', 'DenseMatrix', 'concat', 'SparseMatrix'];
16
16
  const createDotDivide = exports.createDotDivide = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
17
17
  let {
18
18
  typed,
@@ -20,7 +20,8 @@ const createDotDivide = exports.createDotDivide = /* #__PURE__ */(0, _factory.fa
20
20
  equalScalar,
21
21
  divideScalar,
22
22
  DenseMatrix,
23
- concat
23
+ concat,
24
+ SparseMatrix
24
25
  } = _ref;
25
26
  const matAlgo02xDS0 = (0, _matAlgo02xDS.createMatAlgo02xDS0)({
26
27
  typed,
@@ -31,7 +32,7 @@ const createDotDivide = exports.createDotDivide = /* #__PURE__ */(0, _factory.fa
31
32
  });
32
33
  const matAlgo07xSSf = (0, _matAlgo07xSSf.createMatAlgo07xSSf)({
33
34
  typed,
34
- DenseMatrix
35
+ SparseMatrix
35
36
  });
36
37
  const matAlgo11xS0s = (0, _matAlgo11xS0s.createMatAlgo11xS0s)({
37
38
  typed,
@@ -11,7 +11,7 @@ var _matAlgo11xS0s = require("../../type/matrix/utils/matAlgo11xS0s.js");
11
11
  var _matAlgo12xSfs = require("../../type/matrix/utils/matAlgo12xSfs.js");
12
12
  var _matrixAlgorithmSuite = require("../../type/matrix/utils/matrixAlgorithmSuite.js");
13
13
  const name = 'dotPow';
14
- const dependencies = ['typed', 'equalScalar', 'matrix', 'pow', 'DenseMatrix', 'concat'];
14
+ const dependencies = ['typed', 'equalScalar', 'matrix', 'pow', 'DenseMatrix', 'concat', 'SparseMatrix'];
15
15
  const createDotPow = exports.createDotPow = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
16
16
  let {
17
17
  typed,
@@ -19,14 +19,15 @@ const createDotPow = exports.createDotPow = /* #__PURE__ */(0, _factory.factory)
19
19
  matrix,
20
20
  pow,
21
21
  DenseMatrix,
22
- concat
22
+ concat,
23
+ SparseMatrix
23
24
  } = _ref;
24
25
  const matAlgo03xDSf = (0, _matAlgo03xDSf.createMatAlgo03xDSf)({
25
26
  typed
26
27
  });
27
28
  const matAlgo07xSSf = (0, _matAlgo07xSSf.createMatAlgo07xSSf)({
28
29
  typed,
29
- DenseMatrix
30
+ SparseMatrix
30
31
  });
31
32
  const matAlgo11xS0s = (0, _matAlgo11xS0s.createMatAlgo11xS0s)({
32
33
  typed,
@@ -56,6 +56,8 @@ const createFix = exports.createFix = /* #__PURE__ */(0, _factory.factory)(name,
56
56
  *
57
57
  * math.fix(x)
58
58
  * math.fix(x,n)
59
+ * math.fix(unit, valuelessUnit)
60
+ * math.fix(unit, n, valuelessUnit)
59
61
  *
60
62
  * Examples:
61
63
  *
@@ -73,6 +75,12 @@ const createFix = exports.createFix = /* #__PURE__ */(0, _factory.factory)(name,
73
75
  * math.fix(c) // returns Complex 3 - 2i
74
76
  * math.fix(c, 1) // returns Complex 3.2 -2.7i
75
77
  *
78
+ * const unit = math.unit('3.241 cm')
79
+ * const cm = math.unit('cm')
80
+ * const mm = math.unit('mm')
81
+ * math.fix(unit, 1, cm) // returns Unit 3.2 cm
82
+ * math.fix(unit, 1, mm) // returns Unit 32.4 mm
83
+ *
76
84
  * math.fix([3.2, 3.8, -4.7]) // returns Array [3, 3, -4]
77
85
  * math.fix([3.2, 3.8, -4.7], 1) // returns Array [3.2, 3.8, -4.7]
78
86
  *
@@ -80,9 +88,10 @@ const createFix = exports.createFix = /* #__PURE__ */(0, _factory.factory)(name,
80
88
  *
81
89
  * ceil, floor, round
82
90
  *
83
- * @param {number | BigNumber | Fraction | Complex | Array | Matrix} x Number to be rounded
84
- * @param {number | BigNumber | Array} [n=0] Number of decimals
85
- * @return {number | BigNumber | Fraction | Complex | Array | Matrix} Rounded value
91
+ * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x Value to be rounded
92
+ * @param {number | BigNumber | Array} [n=0] Number of decimals
93
+ * @param {Unit} [valuelessUnit] A valueless unit
94
+ * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Rounded value
86
95
  */
87
96
  return typed('fix', {
88
97
  number: fixNumber.signatures.number,
@@ -104,11 +113,21 @@ const createFix = exports.createFix = /* #__PURE__ */(0, _factory.factory)(name,
104
113
  return x.isNegative() ? ceil(x, n) : floor(x, n);
105
114
  },
106
115
  Fraction: function (x) {
107
- return x.s < 0 ? x.ceil() : x.floor();
116
+ return x.s < 0n ? x.ceil() : x.floor();
108
117
  },
109
118
  'Fraction, number | BigNumber': function (x, n) {
110
- return x.s < 0 ? ceil(x, n) : floor(x, n);
119
+ return x.s < 0n ? ceil(x, n) : floor(x, n);
111
120
  },
121
+ 'Unit, number, Unit': typed.referToSelf(self => function (x, n, unit) {
122
+ const valueless = x.toNumeric(unit);
123
+ return unit.multiply(self(valueless, n));
124
+ }),
125
+ 'Unit, BigNumber, Unit': typed.referToSelf(self => (x, n, unit) => self(x, n.toNumber(), unit)),
126
+ 'Array | Matrix, number | BigNumber, Unit': typed.referToSelf(self => (x, n, unit) => {
127
+ // deep map collection, skip zeros since fix(0) = 0
128
+ return (0, _collection.deepMap)(x, value => self(value, n, unit), true);
129
+ }),
130
+ 'Array | Matrix | Unit, Unit': typed.referToSelf(self => (x, unit) => self(x, 0, unit)),
112
131
  'Array | Matrix': typed.referToSelf(self => x => {
113
132
  // deep map collection, skip zeros since fix(0) = 0
114
133
  return (0, _collection.deepMap)(x, self, true);
@@ -75,6 +75,8 @@ const createFloor = exports.createFloor = /* #__PURE__ */(0, _factory.factory)(n
75
75
  *
76
76
  * math.floor(x)
77
77
  * math.floor(x, n)
78
+ * math.floor(unit, valuelessUnit)
79
+ * math.floor(unit, n, valuelessUnit)
78
80
  *
79
81
  * Examples:
80
82
  *
@@ -92,6 +94,12 @@ const createFloor = exports.createFloor = /* #__PURE__ */(0, _factory.factory)(n
92
94
  * math.floor(c) // returns Complex 3 - 3i
93
95
  * math.floor(c, 1) // returns Complex 3.2 -2.8i
94
96
  *
97
+ * const unit = math.unit('3.241 cm')
98
+ * const cm = math.unit('cm')
99
+ * const mm = math.unit('mm')
100
+ * math.floor(unit, 1, cm) // returns Unit 3.2 cm
101
+ * math.floor(unit, 1, mm) // returns Unit 32.4 mm
102
+ *
95
103
  * math.floor([3.2, 3.8, -4.7]) // returns Array [3, 3, -5]
96
104
  * math.floor([3.21, 3.82, -4.71], 1) // returns Array [3.2, 3.8, -4.8]
97
105
  *
@@ -103,9 +111,10 @@ const createFloor = exports.createFloor = /* #__PURE__ */(0, _factory.factory)(n
103
111
  *
104
112
  * ceil, fix, round
105
113
  *
106
- * @param {number | BigNumber | Fraction | Complex | Array | Matrix} x Number to be rounded
114
+ * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x Value to be rounded
107
115
  * @param {number | BigNumber | Array} [n=0] Number of decimals
108
- * @return {number | BigNumber | Fraction | Complex | Array | Matrix} Rounded value
116
+ * @param {Unit} [valuelessUnit] A valueless unit
117
+ * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Rounded value
109
118
  */
110
119
  return typed('floor', {
111
120
  number: floorNumber.signatures.number,
@@ -142,6 +151,16 @@ const createFloor = exports.createFloor = /* #__PURE__ */(0, _factory.factory)(n
142
151
  'Fraction, BigNumber': function (x, n) {
143
152
  return x.floor(n.toNumber());
144
153
  },
154
+ 'Unit, number, Unit': typed.referToSelf(self => function (x, n, unit) {
155
+ const valueless = x.toNumeric(unit);
156
+ return unit.multiply(self(valueless, n));
157
+ }),
158
+ 'Unit, BigNumber, Unit': typed.referToSelf(self => (x, n, unit) => self(x, n.toNumber(), unit)),
159
+ 'Array | Matrix, number | BigNumber, Unit': typed.referToSelf(self => (x, n, unit) => {
160
+ // deep map collection, skip zeros since floor(0) = 0
161
+ return (0, _collection.deepMap)(x, value => self(value, n, unit), true);
162
+ }),
163
+ 'Array | Matrix | Unit, Unit': typed.referToSelf(self => (x, unit) => self(x, 0, unit)),
145
164
  'Array | Matrix': typed.referToSelf(self => x => {
146
165
  // deep map collection, skip zeros since floor(0) = 0
147
166
  return (0, _collection.deepMap)(x, self, true);
@@ -7,10 +7,11 @@ exports.createLog = void 0;
7
7
  var _factory = require("../../utils/factory.js");
8
8
  var _index = require("../../plain/number/index.js");
9
9
  const name = 'log';
10
- const dependencies = ['config', 'typed', 'divideScalar', 'Complex'];
10
+ const dependencies = ['config', 'typed', 'typeOf', 'divideScalar', 'Complex'];
11
11
  const createLog = exports.createLog = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
12
12
  let {
13
13
  typed,
14
+ typeOf,
14
15
  config,
15
16
  divideScalar,
16
17
  Complex
@@ -42,12 +43,12 @@ const createLog = exports.createLog = /* #__PURE__ */(0, _factory.factory)(name,
42
43
  *
43
44
  * exp, log2, log10, log1p
44
45
  *
45
- * @param {number | BigNumber | Complex} x
46
+ * @param {number | BigNumber | Fraction | Complex} x
46
47
  * Value for which to calculate the logarithm.
47
- * @param {number | BigNumber | Complex} [base=e]
48
+ * @param {number | BigNumber | Fraction | Complex} [base=e]
48
49
  * Optional base for the logarithm. If not provided, the natural
49
50
  * logarithm of `x` is calculated.
50
- * @return {number | BigNumber | Complex}
51
+ * @return {number | BigNumber | Fraction | Complex}
51
52
  * Returns the logarithm of `x`
52
53
  */
53
54
  return typed(name, {
@@ -72,6 +73,13 @@ const createLog = exports.createLog = /* #__PURE__ */(0, _factory.factory)(name,
72
73
  },
73
74
  'any, any': typed.referToSelf(self => (x, base) => {
74
75
  // calculate logarithm for a specified base, log(x, base)
76
+
77
+ if (typeOf(x) === 'Fraction' && typeOf(base) === 'Fraction') {
78
+ const result = x.log(base);
79
+ if (result !== null) {
80
+ return result;
81
+ }
82
+ }
75
83
  return divideScalar(self(x), self(base));
76
84
  })
77
85
  });
@@ -113,8 +113,8 @@ const createPow = exports.createPow = /* #__PURE__ */(0, _factory.factory)(name,
113
113
  const yFrac = fraction(y);
114
114
  const yNum = number(yFrac);
115
115
  if (y === yNum || Math.abs((y - yNum) / y) < 1e-14) {
116
- if (yFrac.d % 2 === 1) {
117
- return (yFrac.n % 2 === 0 ? 1 : -1) * Math.pow(-x, y);
116
+ if (yFrac.d % 2n === 1n) {
117
+ return (yFrac.n % 2n === 0n ? 1 : -1) * Math.pow(-x, y);
118
118
  }
119
119
  }
120
120
  } catch (ex) {