mathjs 13.1.0 → 13.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/HISTORY.md +30 -0
  2. package/bin/cli.js +24 -10
  3. package/lib/browser/math.js +1 -1
  4. package/lib/browser/math.js.LICENSE.txt +2 -2
  5. package/lib/browser/math.js.map +1 -1
  6. package/lib/cjs/core/function/typed.js +1 -0
  7. package/lib/cjs/expression/node/FunctionNode.js +9 -1
  8. package/lib/cjs/expression/parse.js +1 -1
  9. package/lib/cjs/expression/transform/filter.transform.js +28 -40
  10. package/lib/cjs/expression/transform/forEach.transform.js +29 -30
  11. package/lib/cjs/expression/transform/map.transform.js +8 -93
  12. package/lib/cjs/expression/transform/utils/transformCallback.js +101 -0
  13. package/lib/cjs/function/algebra/derivative.js +10 -11
  14. package/lib/cjs/function/matrix/filter.js +3 -2
  15. package/lib/cjs/function/matrix/forEach.js +3 -14
  16. package/lib/cjs/function/matrix/map.js +11 -33
  17. package/lib/cjs/header.js +2 -2
  18. package/lib/cjs/type/matrix/DenseMatrix.js +73 -29
  19. package/lib/cjs/type/matrix/SparseMatrix.js +7 -4
  20. package/lib/cjs/utils/array.js +22 -0
  21. package/lib/cjs/utils/customs.js +5 -12
  22. package/lib/cjs/utils/map.js +5 -3
  23. package/lib/cjs/utils/optimizeCallback.js +94 -0
  24. package/lib/cjs/version.js +1 -1
  25. package/lib/esm/core/function/typed.js +1 -0
  26. package/lib/esm/expression/node/FunctionNode.js +9 -1
  27. package/lib/esm/expression/parse.js +1 -1
  28. package/lib/esm/expression/transform/filter.transform.js +28 -40
  29. package/lib/esm/expression/transform/forEach.transform.js +29 -30
  30. package/lib/esm/expression/transform/map.transform.js +8 -93
  31. package/lib/esm/expression/transform/utils/transformCallback.js +95 -0
  32. package/lib/esm/function/algebra/derivative.js +10 -11
  33. package/lib/esm/function/matrix/filter.js +3 -2
  34. package/lib/esm/function/matrix/forEach.js +3 -14
  35. package/lib/esm/function/matrix/map.js +12 -34
  36. package/lib/esm/type/matrix/DenseMatrix.js +75 -32
  37. package/lib/esm/type/matrix/SparseMatrix.js +7 -4
  38. package/lib/esm/utils/array.js +21 -0
  39. package/lib/esm/utils/customs.js +5 -12
  40. package/lib/esm/utils/map.js +6 -4
  41. package/lib/esm/utils/optimizeCallback.js +88 -0
  42. package/lib/esm/version.js +1 -1
  43. package/package.json +7 -7
  44. package/types/index.d.ts +50 -12
  45. package/lib/cjs/utils/applyCallback.js +0 -73
  46. package/lib/esm/utils/applyCallback.js +0 -67
@@ -1,4 +1,4 @@
1
- import { getSafeProperty, hasSafeProperty, setSafeProperty } from './customs.js';
1
+ import { getSafeProperty, isSafeProperty, setSafeProperty } from './customs.js';
2
2
  import { isMap, isObject } from './is.js';
3
3
 
4
4
  /**
@@ -15,7 +15,7 @@ export class ObjectWrappingMap {
15
15
  this[Symbol.iterator] = this.entries;
16
16
  }
17
17
  keys() {
18
- return Object.keys(this.wrappedObject).values();
18
+ return Object.keys(this.wrappedObject).filter(key => this.has(key)).values();
19
19
  }
20
20
  get(key) {
21
21
  return getSafeProperty(this.wrappedObject, key);
@@ -25,7 +25,7 @@ export class ObjectWrappingMap {
25
25
  return this;
26
26
  }
27
27
  has(key) {
28
- return hasSafeProperty(this.wrappedObject, key);
28
+ return isSafeProperty(this.wrappedObject, key) && key in this.wrappedObject;
29
29
  }
30
30
  entries() {
31
31
  return mapIterator(this.keys(), key => [key, this.get(key)]);
@@ -36,7 +36,9 @@ export class ObjectWrappingMap {
36
36
  }
37
37
  }
38
38
  delete(key) {
39
- delete this.wrappedObject[key];
39
+ if (isSafeProperty(this.wrappedObject, key)) {
40
+ delete this.wrappedObject[key];
41
+ }
40
42
  }
41
43
  clear() {
42
44
  for (var key of this.keys()) {
@@ -0,0 +1,88 @@
1
+ import typed from 'typed-function';
2
+ import { get, arraySize } from './array.js';
3
+ import { typeOf as _typeOf } from './is.js';
4
+
5
+ /**
6
+ * Simplifies a callback function by reducing its complexity and potentially improving its performance.
7
+ *
8
+ * @param {Function} callback The original callback function to simplify.
9
+ * @param {Array|Matrix} array The array that will be used with the callback function.
10
+ * @param {string} name The name of the function that is using the callback.
11
+ * @returns {Function} Returns a simplified version of the callback function.
12
+ */
13
+ export function optimizeCallback(callback, array, name) {
14
+ if (typed.isTypedFunction(callback)) {
15
+ var firstIndex = (array.isMatrix ? array.size() : arraySize(array)).map(() => 0);
16
+ var firstValue = array.isMatrix ? array.get(firstIndex) : get(array, firstIndex);
17
+ var hasSingleSignature = Object.keys(callback.signatures).length === 1;
18
+ var numberOfArguments = _findNumberOfArguments(callback, firstValue, firstIndex, array);
19
+ var fastCallback = hasSingleSignature ? Object.values(callback.signatures)[0] : callback;
20
+ if (numberOfArguments >= 1 && numberOfArguments <= 3) {
21
+ return function () {
22
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
23
+ args[_key] = arguments[_key];
24
+ }
25
+ return _tryFunctionWithArgs(fastCallback, args.slice(0, numberOfArguments), name, callback.name);
26
+ };
27
+ }
28
+ return function () {
29
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
30
+ args[_key2] = arguments[_key2];
31
+ }
32
+ return _tryFunctionWithArgs(fastCallback, args, name, callback.name);
33
+ };
34
+ }
35
+ return callback;
36
+ }
37
+ function _findNumberOfArguments(callback, value, index, array) {
38
+ var testArgs = [value, index, array];
39
+ for (var i = 3; i > 0; i--) {
40
+ var args = testArgs.slice(0, i);
41
+ if (typed.resolve(callback, args) !== null) {
42
+ return i;
43
+ }
44
+ }
45
+ }
46
+
47
+ /**
48
+ * @param {function} func The selected function taken from one of the signatures of the callback function
49
+ * @param {Array} args List with arguments to apply to the selected signature
50
+ * @param {string} mappingFnName the name of the function that is using the callback
51
+ * @param {string} callbackName the name of the callback function
52
+ * @returns {*} Returns the return value of the invoked signature
53
+ * @throws {TypeError} Throws an error when no matching signature was found
54
+ */
55
+ function _tryFunctionWithArgs(func, args, mappingFnName, callbackName) {
56
+ try {
57
+ return func(...args);
58
+ } catch (err) {
59
+ _createCallbackError(err, args, mappingFnName, callbackName);
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Creates and throws a detailed TypeError when a callback function fails.
65
+ *
66
+ * @param {Error} err The original error thrown by the callback function.
67
+ * @param {Array} args The arguments that were passed to the callback function.
68
+ * @param {string} mappingFnName The name of the function that is using the callback.
69
+ * @param {string} callbackName The name of the callback function.
70
+ * @throws {TypeError} Throws a detailed TypeError with enriched error message.
71
+ */
72
+ function _createCallbackError(err, args, mappingFnName, callbackName) {
73
+ var _err$data;
74
+ // Enrich the error message so the user understands that it took place inside the callback function
75
+ if (err instanceof TypeError && ((_err$data = err.data) === null || _err$data === void 0 ? void 0 : _err$data.category) === 'wrongType') {
76
+ var argsDesc = [];
77
+ argsDesc.push("value: ".concat(_typeOf(args[0])));
78
+ if (args.length >= 2) {
79
+ argsDesc.push("index: ".concat(_typeOf(args[1])));
80
+ }
81
+ if (args.length >= 3) {
82
+ argsDesc.push("array: ".concat(_typeOf(args[2])));
83
+ }
84
+ throw new TypeError("Function ".concat(mappingFnName, " cannot apply callback arguments ") + "".concat(callbackName, "(").concat(argsDesc.join(', '), ") at index ").concat(JSON.stringify(args[1])));
85
+ } else {
86
+ throw new TypeError("Function ".concat(mappingFnName, " cannot apply callback arguments ") + "to function ".concat(callbackName, ": ").concat(err.message));
87
+ }
88
+ }
@@ -1,3 +1,3 @@
1
- export var version = '13.1.0';
1
+ export var version = '13.2.0';
2
2
  // Note: This file is automatically generated when building math.js.
3
3
  // Changes made in this file will be overwritten.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mathjs",
3
- "version": "13.1.0",
3
+ "version": "13.2.0",
4
4
  "description": "Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with different data types like numbers, big numbers, complex numbers, fractions, units, and matrices.",
5
5
  "author": "Jos de Jong <wjosdejong@gmail.com> (https://github.com/josdejong)",
6
6
  "homepage": "https://mathjs.org",
@@ -25,7 +25,7 @@
25
25
  "unit"
26
26
  ],
27
27
  "dependencies": {
28
- "@babel/runtime": "^7.25.4",
28
+ "@babel/runtime": "^7.25.6",
29
29
  "complex.js": "^2.1.1",
30
30
  "decimal.js": "^10.4.3",
31
31
  "escape-latex": "^1.2.0",
@@ -43,11 +43,11 @@
43
43
  "@babel/preset-env": "7.25.4",
44
44
  "@babel/register": "7.24.6",
45
45
  "@types/assert": "1.5.10",
46
- "@types/mocha": "10.0.7",
46
+ "@types/mocha": "10.0.8",
47
47
  "@typescript-eslint/eslint-plugin": "7.16.1",
48
48
  "@typescript-eslint/parser": "7.16.1",
49
49
  "assert": "2.1.0",
50
- "babel-loader": "9.1.3",
50
+ "babel-loader": "9.2.1",
51
51
  "benchmark": "2.1.4",
52
52
  "c8": "10.1.2",
53
53
  "codecov": "3.8.3",
@@ -57,7 +57,7 @@
57
57
  "eslint": "8.57.0",
58
58
  "eslint-config-prettier": "9.1.0",
59
59
  "eslint-config-standard": "17.1.0",
60
- "eslint-plugin-import": "2.29.1",
60
+ "eslint-plugin-import": "2.30.0",
61
61
  "eslint-plugin-mocha": "10.5.0",
62
62
  "eslint-plugin-n": "16.6.2",
63
63
  "eslint-plugin-prettier": "5.2.1",
@@ -88,11 +88,11 @@
88
88
  "pad-right": "0.2.2",
89
89
  "prettier": "3.3.3",
90
90
  "process": "0.11.10",
91
- "sinon": "18.0.0",
91
+ "sinon": "19.0.2",
92
92
  "sylvester": "0.0.21",
93
93
  "ts-node": "10.9.2",
94
94
  "typescript": "5.5.4",
95
- "webpack": "5.94.0",
95
+ "webpack": "5.95.0",
96
96
  "zeros": "1.0.0"
97
97
  },
98
98
  "type": "module",
package/types/index.d.ts CHANGED
@@ -246,8 +246,17 @@ export interface ConditionalNodeCtor {
246
246
  ): ConditionalNode
247
247
  }
248
248
 
249
- export interface ConstantNode<TValue extends string | number = number>
250
- extends MathNode {
249
+ export interface ConstantNode<
250
+ TValue extends
251
+ | string
252
+ | number
253
+ | boolean
254
+ | null
255
+ | undefined
256
+ | bigint
257
+ | BigNumber
258
+ | Fraction = number
259
+ > extends MathNode {
251
260
  type: 'ConstantNode'
252
261
  isConstantNode: true
253
262
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -255,7 +264,17 @@ export interface ConstantNode<TValue extends string | number = number>
255
264
  }
256
265
 
257
266
  export interface ConstantNodeCtor {
258
- new <TValue extends string | number = string>(
267
+ new <
268
+ TValue extends
269
+ | string
270
+ | number
271
+ | boolean
272
+ | null
273
+ | undefined
274
+ | bigint
275
+ | BigNumber
276
+ | Fraction = string
277
+ >(
259
278
  value: TValue
260
279
  ): ConstantNode<TValue>
261
280
  }
@@ -1022,6 +1041,15 @@ export interface MathJsInstance extends MathJsFactory {
1022
1041
  simplifyConstant(expr: MathNode | string, options?: SimplifyOptions): MathNode
1023
1042
  simplifyCore(expr: MathNode | string, options?: SimplifyOptions): MathNode
1024
1043
 
1044
+ /**
1045
+ * Gives the number of “leaf nodes” in the parse tree of the given
1046
+ * expression. A leaf node is one that has no subexpressions, essentially
1047
+ * either a symbol or a constant. Note that `5!` has just one leaf, the `5`;
1048
+ * the unary factorial operator does not add a leaf. On the other hand,
1049
+ * function symbols do add leaves, so `sin(x)/cos(x)` has four leaves.
1050
+ */
1051
+ leafCount(expr: MathNode): number
1052
+
1025
1053
  /**
1026
1054
  * Replaces variable nodes with their scoped values
1027
1055
  * @param node Tree to replace variable nodes in
@@ -2531,15 +2559,15 @@ export interface MathJsInstance extends MathJsFactory {
2531
2559
  /**
2532
2560
  * Determines if two expressions are symbolically equal, i.e. one is the
2533
2561
  * result of valid algebraic manipulations on the other.
2534
- * @param {Node|string} expr1 The first expression to compare
2535
- * @param {Node|string} expr2 The second expression to compare
2562
+ * @param {Node} expr1 The first expression to compare
2563
+ * @param {Node} expr2 The second expression to compare
2536
2564
  * @param {Object} [options] Optional option object, passed to simplify
2537
2565
  * @returns {boolean} Returns true if a valid manipulation making the
2538
2566
  * expressions equal is found.
2539
2567
  */
2540
2568
  symbolicEqual(
2541
- expr1: MathNode | string,
2542
- expr2: MathNode | string,
2569
+ expr1: MathNode,
2570
+ expr2: MathNode,
2543
2571
  options?: SimplifyOptions
2544
2572
  ): boolean
2545
2573
 
@@ -4869,6 +4897,15 @@ export interface MathJsChain<TValue> {
4869
4897
  options?: SimplifyOptions
4870
4898
  ): MathJsChain<MathNode>
4871
4899
 
4900
+ /**
4901
+ * Gives the number of “leaf nodes” in the parse tree of the given
4902
+ * expression. A leaf node is one that has no subexpressions, essentially
4903
+ * either a symbol or a constant. Note that `5!` has just one leaf, the `5`;
4904
+ * the unary factorial operator does not add a leaf. On the other hand,
4905
+ * function symbols do add leaves, so `sin(x)/cos(x)` has four leaves.
4906
+ */
4907
+ leafCount(this: MathJsChain<MathNode>): MathJsChain<number>
4908
+
4872
4909
  /**
4873
4910
  * Calculate the Sparse Matrix LU decomposition with full pivoting.
4874
4911
  * Sparse Matrix A is decomposed in two matrices (L, U) and two
@@ -6123,17 +6160,16 @@ export interface MathJsChain<TValue> {
6123
6160
  /**
6124
6161
  * Determines if two expressions are symbolically equal, i.e. one is the
6125
6162
  * result of valid algebraic manipulations on the other.
6126
- * @param {Node|string} expr1 The first expression to compare
6127
- * @param {Node|string} expr2 The second expression to compare
6163
+ * @param {Node} expr2 The second expression to compare
6128
6164
  * @param {Object} [options] Optional option object, passed to simplify
6129
6165
  * @returns {boolean} Returns true if a valid manipulation making the
6130
6166
  * expressions equal is found.
6131
6167
  */
6132
6168
  symbolicEqual(
6133
- this: MathJsChain<MathNode | string>,
6134
- expr2: MathNode | string,
6169
+ this: MathJsChain<MathNode>,
6170
+ expr2: MathNode,
6135
6171
  options?: SimplifyOptions
6136
- ): boolean
6172
+ ): MathJsChain<boolean>
6137
6173
 
6138
6174
  /**
6139
6175
  * Test whether two values are unequal. The function tests whether the
@@ -6966,6 +7002,8 @@ export const {
6966
7002
  simplify,
6967
7003
  simplifyConstant,
6968
7004
  simplifyCore,
7005
+ symbolicEqual,
7006
+ leafCount,
6969
7007
  resolve,
6970
7008
  slu,
6971
7009
  usolve,
@@ -1,73 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.applyCallback = applyCallback;
8
- var _typedFunction = _interopRequireDefault(require("typed-function"));
9
- var _is = require("./is.js");
10
- /**
11
- * Invoke a callback for functions like map and filter with a matching number of arguments
12
- * @param {function} callback
13
- * @param {any} value
14
- * @param {number | number[]} index
15
- * @param {Array} array
16
- * @param {string} mappingFnName The name of the function that is invoking these callbacks, for example "map" or "filter"
17
- * @returns {*}
18
- */
19
- function applyCallback(callback, value, index, array, mappingFnName) {
20
- if (_typedFunction.default.isTypedFunction(callback)) {
21
- // invoke the typed callback function with the matching number of arguments only
22
-
23
- const args3 = [value, index, array];
24
- const signature3 = _typedFunction.default.resolve(callback, args3);
25
- if (signature3) {
26
- return tryWithArgs(signature3.implementation, args3);
27
- }
28
- const args2 = [value, index];
29
- const signature2 = _typedFunction.default.resolve(callback, args2);
30
- if (signature2) {
31
- return tryWithArgs(signature2.implementation, args2);
32
- }
33
- const args1 = [value];
34
- const signature1 = _typedFunction.default.resolve(callback, args1);
35
- if (signature1) {
36
- return tryWithArgs(signature1.implementation, args1);
37
- }
38
-
39
- // fallback (will throw an exception)
40
- return tryWithArgs(callback, args3);
41
- } else {
42
- // A regular JavaScript function
43
- return callback(value, index, array);
44
- }
45
-
46
- /**
47
- * @param {function} signature The selected signature of the typed-function
48
- * @param {Array} args List with arguments to apply to the selected signature
49
- * @returns {*} Returns the return value of the invoked signature
50
- * @throws {TypeError} Throws an error when no matching signature was found
51
- */
52
- function tryWithArgs(signature, args) {
53
- try {
54
- return signature.apply(signature, args);
55
- } catch (err) {
56
- var _err$data;
57
- // Enrich the error message so the user understands that it took place inside the callback function
58
- if (err instanceof TypeError && ((_err$data = err.data) === null || _err$data === void 0 ? void 0 : _err$data.category) === 'wrongType') {
59
- const argsDesc = [];
60
- argsDesc.push(`value: ${(0, _is.typeOf)(value)}`);
61
- if (args.length >= 2) {
62
- argsDesc.push(`index: ${(0, _is.typeOf)(index)}`);
63
- }
64
- if (args.length >= 3) {
65
- argsDesc.push(`array: ${(0, _is.typeOf)(array)}`);
66
- }
67
- throw new TypeError(`Function ${mappingFnName} cannot apply callback arguments ` + `${callback.name}(${argsDesc.join(', ')}) at index ${JSON.stringify(index)}`);
68
- } else {
69
- throw new TypeError(`Function ${mappingFnName} cannot apply callback arguments ` + `to function ${callback.name}: ${err.message}`);
70
- }
71
- }
72
- }
73
- }
@@ -1,67 +0,0 @@
1
- import typed from 'typed-function';
2
- import { typeOf as _typeOf } from './is.js';
3
-
4
- /**
5
- * Invoke a callback for functions like map and filter with a matching number of arguments
6
- * @param {function} callback
7
- * @param {any} value
8
- * @param {number | number[]} index
9
- * @param {Array} array
10
- * @param {string} mappingFnName The name of the function that is invoking these callbacks, for example "map" or "filter"
11
- * @returns {*}
12
- */
13
- export function applyCallback(callback, value, index, array, mappingFnName) {
14
- if (typed.isTypedFunction(callback)) {
15
- // invoke the typed callback function with the matching number of arguments only
16
-
17
- var args3 = [value, index, array];
18
- var signature3 = typed.resolve(callback, args3);
19
- if (signature3) {
20
- return tryWithArgs(signature3.implementation, args3);
21
- }
22
- var args2 = [value, index];
23
- var signature2 = typed.resolve(callback, args2);
24
- if (signature2) {
25
- return tryWithArgs(signature2.implementation, args2);
26
- }
27
- var args1 = [value];
28
- var signature1 = typed.resolve(callback, args1);
29
- if (signature1) {
30
- return tryWithArgs(signature1.implementation, args1);
31
- }
32
-
33
- // fallback (will throw an exception)
34
- return tryWithArgs(callback, args3);
35
- } else {
36
- // A regular JavaScript function
37
- return callback(value, index, array);
38
- }
39
-
40
- /**
41
- * @param {function} signature The selected signature of the typed-function
42
- * @param {Array} args List with arguments to apply to the selected signature
43
- * @returns {*} Returns the return value of the invoked signature
44
- * @throws {TypeError} Throws an error when no matching signature was found
45
- */
46
- function tryWithArgs(signature, args) {
47
- try {
48
- return signature.apply(signature, args);
49
- } catch (err) {
50
- var _err$data;
51
- // Enrich the error message so the user understands that it took place inside the callback function
52
- if (err instanceof TypeError && ((_err$data = err.data) === null || _err$data === void 0 ? void 0 : _err$data.category) === 'wrongType') {
53
- var argsDesc = [];
54
- argsDesc.push("value: ".concat(_typeOf(value)));
55
- if (args.length >= 2) {
56
- argsDesc.push("index: ".concat(_typeOf(index)));
57
- }
58
- if (args.length >= 3) {
59
- argsDesc.push("array: ".concat(_typeOf(array)));
60
- }
61
- throw new TypeError("Function ".concat(mappingFnName, " cannot apply callback arguments ") + "".concat(callback.name, "(").concat(argsDesc.join(', '), ") at index ").concat(JSON.stringify(index)));
62
- } else {
63
- throw new TypeError("Function ".concat(mappingFnName, " cannot apply callback arguments ") + "to function ".concat(callback.name, ": ").concat(err.message));
64
- }
65
- }
66
- }
67
- }