mathjs 13.1.0 → 13.2.0

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.
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
@@ -2,6 +2,7 @@ import { factory } from '../../utils/factory.js';
2
2
  import { isFunctionAssignmentNode, isSymbolNode } from '../../utils/is.js';
3
3
  import { createMap } from '../../function/matrix/map.js';
4
4
  import { compileInlineExpression } from './utils/compileInlineExpression.js';
5
+ import { createTransformCallback } from './utils/transformCallback.js';
5
6
  var name = 'map';
6
7
  var dependencies = ['typed'];
7
8
  export var createMapTransform = /* #__PURE__ */factory(name, dependencies, _ref => {
@@ -17,6 +18,9 @@ export var createMapTransform = /* #__PURE__ */factory(name, dependencies, _ref
17
18
  var map = createMap({
18
19
  typed
19
20
  });
21
+ var transformCallback = createTransformCallback({
22
+ typed
23
+ });
20
24
  function mapTransform(args, math, scope) {
21
25
  if (args.length === 0) {
22
26
  return map();
@@ -25,9 +29,8 @@ export var createMapTransform = /* #__PURE__ */factory(name, dependencies, _ref
25
29
  return map(args[0]);
26
30
  }
27
31
  var N = args.length - 1;
28
- var X, callback;
29
- callback = args[N];
30
- X = args.slice(0, N);
32
+ var X = args.slice(0, N);
33
+ var callback = args[N];
31
34
  X = X.map(arg => _compileAndEvaluate(arg, scope));
32
35
  if (callback) {
33
36
  if (isSymbolNode(callback) || isFunctionAssignmentNode(callback)) {
@@ -38,101 +41,13 @@ export var createMapTransform = /* #__PURE__ */factory(name, dependencies, _ref
38
41
  callback = compileInlineExpression(callback, math, scope);
39
42
  }
40
43
  }
41
- return map(...X, _transformCallback(callback, N));
44
+ return map(...X, transformCallback(callback, N));
42
45
  function _compileAndEvaluate(arg, scope) {
43
46
  return arg.compile().evaluate(scope);
44
47
  }
45
48
  }
46
49
  mapTransform.rawArgs = true;
47
50
  return mapTransform;
48
-
49
- /**
50
- * Transforms the given callback function based on its type and number of arrays.
51
- *
52
- * @param {Function} callback - The callback function to transform.
53
- * @param {number} numberOfArrays - The number of arrays to pass to the callback function.
54
- * @returns {*} - The transformed callback function.
55
- */
56
- function _transformCallback(callback, numberOfArrays) {
57
- if (typed.isTypedFunction(callback)) {
58
- return _transformTypedCallbackFunction(callback, numberOfArrays);
59
- } else {
60
- return _transformCallbackFunction(callback, callback.length, numberOfArrays);
61
- }
62
- }
63
-
64
- /**
65
- * Transforms the given typed callback function based on the number of arrays.
66
- *
67
- * @param {Function} typedFunction - The typed callback function to transform.
68
- * @param {number} numberOfArrays - The number of arrays to pass to the callback function.
69
- * @returns {*} - The transformed typed callback function.
70
- */
71
- function _transformTypedCallbackFunction(typedFunction, numberOfArrays) {
72
- var signatures = Object.fromEntries(Object.entries(typedFunction.signatures).map(_ref2 => {
73
- var [signature, callbackFunction] = _ref2;
74
- var numberOfCallbackInputs = signature.split(',').length;
75
- if (typed.isTypedFunction(callbackFunction)) {
76
- return [signature, _transformTypedCallbackFunction(callbackFunction, numberOfArrays)];
77
- } else {
78
- return [signature, _transformCallbackFunction(callbackFunction, numberOfCallbackInputs, numberOfArrays)];
79
- }
80
- }));
81
- if (typeof typedFunction.name === 'string') {
82
- return typed(typedFunction.name, signatures);
83
- } else {
84
- return typed(signatures);
85
- }
86
- }
87
51
  }, {
88
52
  isTransformFunction: true
89
- });
90
-
91
- /**
92
- * Transforms the callback function based on the number of callback inputs and arrays.
93
- * There are three cases:
94
- * 1. The callback function has N arguments.
95
- * 2. The callback function has N+1 arguments.
96
- * 3. The callback function has 2N+1 arguments.
97
- *
98
- * @param {Function} callbackFunction - The callback function to transform.
99
- * @param {number} numberOfCallbackInputs - The number of callback inputs.
100
- * @param {number} numberOfArrays - The number of arrays.
101
- * @returns {Function} The transformed callback function.
102
- */
103
- function _transformCallbackFunction(callbackFunction, numberOfCallbackInputs, numberOfArrays) {
104
- if (numberOfCallbackInputs === numberOfArrays) {
105
- return callbackFunction;
106
- } else if (numberOfCallbackInputs === numberOfArrays + 1) {
107
- return function () {
108
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
109
- args[_key] = arguments[_key];
110
- }
111
- var vals = args.slice(0, numberOfArrays);
112
- var idx = _transformDims(args[numberOfArrays]);
113
- return callbackFunction(...vals, idx);
114
- };
115
- } else if (numberOfCallbackInputs > numberOfArrays + 1) {
116
- return function () {
117
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
118
- args[_key2] = arguments[_key2];
119
- }
120
- var vals = args.slice(0, numberOfArrays);
121
- var idx = _transformDims(args[numberOfArrays]);
122
- var rest = args.slice(numberOfArrays + 1);
123
- return callbackFunction(...vals, idx, ...rest);
124
- };
125
- } else {
126
- return callbackFunction;
127
- }
128
- }
129
-
130
- /**
131
- * Transforms the dimensions by adding 1 to each dimension.
132
- *
133
- * @param {Array} dims - The dimensions to transform.
134
- * @returns {Array} The transformed dimensions.
135
- */
136
- function _transformDims(dims) {
137
- return dims.map(dim => dim.isBigNumber ? dim.plus(1) : dim + 1);
138
- }
53
+ });
@@ -0,0 +1,95 @@
1
+ import { factory } from '../../../utils/factory.js';
2
+ var name = 'transformCallback';
3
+ var dependencies = ['typed'];
4
+ export var createTransformCallback = /* #__PURE__ */factory(name, dependencies, _ref => {
5
+ var {
6
+ typed
7
+ } = _ref;
8
+ /**
9
+ * Transforms the given callback function based on its type and number of arrays.
10
+ *
11
+ * @param {Function} callback - The callback function to transform.
12
+ * @param {number} numberOfArrays - The number of arrays to pass to the callback function.
13
+ * @returns {*} - The transformed callback function.
14
+ */
15
+ return function (callback, numberOfArrays) {
16
+ if (typed.isTypedFunction(callback)) {
17
+ return _transformTypedCallbackFunction(callback, numberOfArrays);
18
+ } else {
19
+ return _transformCallbackFunction(callback, callback.length, numberOfArrays);
20
+ }
21
+ };
22
+
23
+ /**
24
+ * Transforms the given typed callback function based on the number of arrays.
25
+ *
26
+ * @param {Function} typedFunction - The typed callback function to transform.
27
+ * @param {number} numberOfArrays - The number of arrays to pass to the callback function.
28
+ * @returns {*} - The transformed callback function.
29
+ */
30
+ function _transformTypedCallbackFunction(typedFunction, numberOfArrays) {
31
+ var signatures = Object.fromEntries(Object.entries(typedFunction.signatures).map(_ref2 => {
32
+ var [signature, callbackFunction] = _ref2;
33
+ var numberOfCallbackInputs = signature.split(',').length;
34
+ if (typed.isTypedFunction(callbackFunction)) {
35
+ return [signature, _transformTypedCallbackFunction(callbackFunction, numberOfArrays)];
36
+ } else {
37
+ return [signature, _transformCallbackFunction(callbackFunction, numberOfCallbackInputs, numberOfArrays)];
38
+ }
39
+ }));
40
+ if (typeof typedFunction.name === 'string') {
41
+ return typed(typedFunction.name, signatures);
42
+ } else {
43
+ return typed(signatures);
44
+ }
45
+ }
46
+ });
47
+
48
+ /**
49
+ * Transforms the callback function based on the number of callback inputs and arrays.
50
+ * There are three cases:
51
+ * 1. The callback function has N arguments.
52
+ * 2. The callback function has N+1 arguments.
53
+ * 3. The callback function has 2N+1 arguments.
54
+ *
55
+ * @param {Function} callbackFunction - The callback function to transform.
56
+ * @param {number} numberOfCallbackInputs - The number of callback inputs.
57
+ * @param {number} numberOfArrays - The number of arrays.
58
+ * @returns {Function} The transformed callback function.
59
+ */
60
+ function _transformCallbackFunction(callbackFunction, numberOfCallbackInputs, numberOfArrays) {
61
+ if (numberOfCallbackInputs === numberOfArrays) {
62
+ return callbackFunction;
63
+ } else if (numberOfCallbackInputs === numberOfArrays + 1) {
64
+ return function () {
65
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
66
+ args[_key] = arguments[_key];
67
+ }
68
+ var vals = args.slice(0, numberOfArrays);
69
+ var idx = _transformDims(args[numberOfArrays]);
70
+ return callbackFunction(...vals, idx);
71
+ };
72
+ } else if (numberOfCallbackInputs > numberOfArrays + 1) {
73
+ return function () {
74
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
75
+ args[_key2] = arguments[_key2];
76
+ }
77
+ var vals = args.slice(0, numberOfArrays);
78
+ var idx = _transformDims(args[numberOfArrays]);
79
+ var rest = args.slice(numberOfArrays + 1);
80
+ return callbackFunction(...vals, idx, ...rest);
81
+ };
82
+ } else {
83
+ return callbackFunction;
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Transforms the dimensions by adding 1 to each dimension.
89
+ *
90
+ * @param {Array} dims - The dimensions to transform.
91
+ * @returns {Array} The transformed dimensions.
92
+ */
93
+ function _transformDims(dims) {
94
+ return dims.map(dim => dim + 1);
95
+ }
@@ -65,14 +65,18 @@ export var createDerivative = /* #__PURE__ */factory(name, dependencies, _ref =>
65
65
  var res = _derivative(expr, constNodes);
66
66
  return options.simplify ? simplify(res) : res;
67
67
  }
68
- typed.addConversion({
69
- from: 'identifier',
70
- to: 'SymbolNode',
71
- convert: parse
72
- });
68
+ function parseIdentifier(string) {
69
+ var symbol = parse(string);
70
+ if (!symbol.isSymbolNode) {
71
+ throw new TypeError('Invalid variable. ' + "Cannot parse ".concat(JSON.stringify(string), " into a variable in function derivative"));
72
+ }
73
+ return symbol;
74
+ }
73
75
  var derivative = typed(name, {
74
76
  'Node, SymbolNode': plainDerivative,
75
- 'Node, SymbolNode, Object': plainDerivative
77
+ 'Node, SymbolNode, Object': plainDerivative,
78
+ 'Node, string': (node, symbol) => plainDerivative(node, parseIdentifier(symbol)),
79
+ 'Node, string, Object': (node, symbol, options) => plainDerivative(node, parseIdentifier(symbol), options)
76
80
 
77
81
  /* TODO: implement and test syntax with order of derivatives -> implement as an option {order: number}
78
82
  'Node, SymbolNode, ConstantNode': function (expr, variable, {order}) {
@@ -86,11 +90,6 @@ export var createDerivative = /* #__PURE__ */factory(name, dependencies, _ref =>
86
90
  }
87
91
  */
88
92
  });
89
- typed.removeConversion({
90
- from: 'identifier',
91
- to: 'SymbolNode',
92
- convert: parse
93
- });
94
93
  derivative._simplify = true;
95
94
  derivative.toTex = function (deriv) {
96
95
  return _derivTex.apply(null, deriv.args);
@@ -1,4 +1,4 @@
1
- import { applyCallback } from '../../utils/applyCallback.js';
1
+ import { optimizeCallback } from '../../utils/optimizeCallback.js';
2
2
  import { filter, filterRegExp } from '../../utils/array.js';
3
3
  import { factory } from '../../utils/factory.js';
4
4
  var name = 'filter';
@@ -56,8 +56,9 @@ export var createFilter = /* #__PURE__ */factory(name, dependencies, _ref => {
56
56
  * @private
57
57
  */
58
58
  function _filterCallback(x, callback) {
59
+ var fastCallback = optimizeCallback(callback, x, 'filter');
59
60
  return filter(x, function (value, index, array) {
60
61
  // invoke the callback function with the right number of arguments
61
- return applyCallback(callback, value, [index], array, 'filter');
62
+ return fastCallback(value, [index], array);
62
63
  });
63
64
  }
@@ -1,6 +1,6 @@
1
- import { applyCallback } from '../../utils/applyCallback.js';
2
- import { forEach as forEachArray } from '../../utils/array.js';
1
+ import { optimizeCallback } from '../../utils/optimizeCallback.js';
3
2
  import { factory } from '../../utils/factory.js';
3
+ import { recurse } from '../../utils/array.js';
4
4
  var name = 'forEach';
5
5
  var dependencies = ['typed'];
6
6
  export var createForEach = /* #__PURE__ */factory(name, dependencies, _ref => {
@@ -45,16 +45,5 @@ export var createForEach = /* #__PURE__ */factory(name, dependencies, _ref => {
45
45
  * @private
46
46
  */
47
47
  function _forEach(array, callback) {
48
- var _recurse = function recurse(value, index) {
49
- if (Array.isArray(value)) {
50
- forEachArray(value, function (child, i) {
51
- // we create a copy of the index array and append the new index value
52
- _recurse(child, index.concat(i));
53
- });
54
- } else {
55
- // invoke the callback function with the right number of arguments
56
- return applyCallback(callback, value, index, array, 'forEach');
57
- }
58
- };
59
- _recurse(array, []);
48
+ recurse(array, [], array, optimizeCallback(callback, array, name));
60
49
  }
@@ -1,5 +1,5 @@
1
- import { applyCallback } from '../../utils/applyCallback.js';
2
- import { arraySize, broadcastSizes, broadcastTo, get } from '../../utils/array.js';
1
+ import { optimizeCallback } from '../../utils/optimizeCallback.js';
2
+ import { arraySize, broadcastSizes, broadcastTo, get, recurse } from '../../utils/array.js';
3
3
  import { factory } from '../../utils/factory.js';
4
4
  var name = 'map';
5
5
  var dependencies = ['typed'];
@@ -129,36 +129,14 @@ export var createMap = /* #__PURE__ */factory(name, dependencies, _ref => {
129
129
  return 0;
130
130
  }
131
131
  }
132
- });
133
-
134
- /**
135
- * Map for a multi dimensional array
136
- * @param {Array} array
137
- * @param {Function} callback
138
- * @return {Array}
139
- * @private
140
- */
141
- function _mapArray(array, callback) {
142
- return _recurse(array, [], array, callback);
143
- }
144
-
145
- /**
146
- * Recursive function to map a multi-dimensional array.
147
- *
148
- * @param {*} value - The current value being processed in the array.
149
- * @param {Array} index - The index of the current value being processed in the array.
150
- * @param {Array} array - The array being processed.
151
- * @param {Function} callback - Function that produces the element of the new Array, taking three arguments: the value of the element, the index of the element, and the Array being processed.
152
- * @returns {*} The new array with each element being the result of the callback function.
153
- */
154
- function _recurse(value, index, array, callback) {
155
- if (Array.isArray(value)) {
156
- return value.map(function (child, i) {
157
- // we create a copy of the index array and append the new index value
158
- return _recurse(child, index.concat(i), array, callback);
159
- });
160
- } else {
161
- // invoke the callback function with the right number of arguments
162
- return applyCallback(callback, value, index, array, 'map');
132
+ /**
133
+ * Map for a multi dimensional array
134
+ * @param {Array} array
135
+ * @param {Function} callback
136
+ * @return {Array}
137
+ * @private
138
+ */
139
+ function _mapArray(array, callback) {
140
+ return recurse(array, [], array, optimizeCallback(callback, array, name));
163
141
  }
164
- }
142
+ });
@@ -1,3 +1,4 @@
1
+ // deno-lint-ignore-file no-this-alias
1
2
  import { isArray, isBigNumber, isCollection, isIndex, isMatrix, isNumber, isString, typeOf } from '../../utils/is.js';
2
3
  import { arraySize, getArrayDataType, processSizesWildcard, reshape, resize, unsqueeze, validate, validateIndex, broadcastTo, get } from '../../utils/array.js';
3
4
  import { format } from '../../utils/string.js';
@@ -5,7 +6,7 @@ import { isInteger } from '../../utils/number.js';
5
6
  import { clone, deepStrictEqual } from '../../utils/object.js';
6
7
  import { DimensionError } from '../../error/DimensionError.js';
7
8
  import { factory } from '../../utils/factory.js';
8
- import { applyCallback } from '../../utils/applyCallback.js';
9
+ import { optimizeCallback } from '../../utils/optimizeCallback.js';
9
10
  var name = 'DenseMatrix';
10
11
  var dependencies = ['Matrix'];
11
12
  export var createDenseMatrixClass = /* #__PURE__ */factory(name, dependencies, _ref => {
@@ -516,6 +517,66 @@ export var createDenseMatrixClass = /* #__PURE__ */factory(name, dependencies, _
516
517
  return this._size.slice(0); // return a clone of _size
517
518
  };
518
519
 
520
+ /**
521
+ * Applies a callback function to a reference to each element of the matrix
522
+ * @memberof DenseMatrix
523
+ * @param {Function} callback The callback function is invoked with three
524
+ * parameters: an array, an integer index to that
525
+ * array, and the Matrix being traversed.
526
+ */
527
+ DenseMatrix.prototype._forEach = function (callback) {
528
+ // matrix instance
529
+ var me = this;
530
+ var s = me.size();
531
+
532
+ // if there is only one dimension, just loop through it
533
+ if (s.length === 1) {
534
+ for (var i = 0; i < s[0]; i++) {
535
+ callback(me._data, i, [i]);
536
+ }
537
+ return;
538
+ }
539
+
540
+ // keep track of the current index permutation
541
+ var index = Array(s.length).fill(0);
542
+
543
+ // store a reference of each dimension of the matrix for faster access
544
+ var data = Array(s.length - 1);
545
+ var last = data.length - 1;
546
+ data[0] = me._data[0];
547
+ for (var _i = 0; _i < last; _i++) {
548
+ data[_i + 1] = data[_i][0];
549
+ }
550
+ index[last] = -1;
551
+ while (true) {
552
+ var _i2 = void 0;
553
+ for (_i2 = last; _i2 >= 0; _i2--) {
554
+ // march index to the next permutation
555
+ index[_i2]++;
556
+ if (index[_i2] === s[_i2]) {
557
+ index[_i2] = 0;
558
+ continue;
559
+ }
560
+
561
+ // update references to matrix dimensions
562
+ data[_i2] = _i2 === 0 ? me._data[index[_i2]] : data[_i2 - 1][index[_i2]];
563
+ for (var j = _i2; j < last; j++) {
564
+ data[j + 1] = data[j][0];
565
+ }
566
+
567
+ // loop through the last dimension and map each value
568
+ for (var _j = 0; _j < s[data.length]; _j++) {
569
+ index[data.length] = _j;
570
+ callback(data[last], _j, index.slice(0));
571
+ }
572
+ break;
573
+ }
574
+ if (_i2 === -1) {
575
+ break;
576
+ }
577
+ }
578
+ };
579
+
519
580
  /**
520
581
  * Create a new matrix with the results of the callback function executed on
521
582
  * each entry of the matrix.
@@ -527,24 +588,13 @@ export var createDenseMatrixClass = /* #__PURE__ */factory(name, dependencies, _
527
588
  * @return {DenseMatrix} matrix
528
589
  */
529
590
  DenseMatrix.prototype.map = function (callback) {
530
- // matrix instance
531
591
  var me = this;
532
- var _recurse = function recurse(value, index) {
533
- if (isArray(value)) {
534
- return value.map(function (child, i) {
535
- return _recurse(child, index.concat(i));
536
- });
537
- } else {
538
- // invoke the callback function with the right number of arguments
539
- return applyCallback(callback, value, index, me, 'map');
540
- }
541
- };
542
-
543
- // determine the new datatype when the original matrix has datatype defined
544
- // TODO: should be done in matrix constructor instead
545
- var data = _recurse(this._data, []);
546
- var datatype = this._datatype !== undefined ? getArrayDataType(data, typeOf) : undefined;
547
- return new DenseMatrix(data, datatype);
592
+ var result = new DenseMatrix(me);
593
+ var fastCallback = optimizeCallback(callback, me._data, 'map');
594
+ result._forEach(function (arr, i, index) {
595
+ arr[i] = fastCallback(arr[i], index, me);
596
+ });
597
+ return result;
548
598
  };
549
599
 
550
600
  /**
@@ -555,18 +605,11 @@ export var createDenseMatrixClass = /* #__PURE__ */factory(name, dependencies, _
555
605
  * of the element, and the Matrix being traversed.
556
606
  */
557
607
  DenseMatrix.prototype.forEach = function (callback) {
558
- // matrix instance
559
608
  var me = this;
560
- var _recurse2 = function recurse(value, index) {
561
- if (isArray(value)) {
562
- value.forEach(function (child, i) {
563
- _recurse2(child, index.concat(i));
564
- });
565
- } else {
566
- callback(value, index, me);
567
- }
568
- };
569
- _recurse2(this._data, []);
609
+ var fastCallback = optimizeCallback(callback, me._data, 'map');
610
+ me._forEach(function (arr, i, index) {
611
+ fastCallback(arr[i], index, me);
612
+ });
570
613
  };
571
614
 
572
615
  /**
@@ -574,10 +617,10 @@ export var createDenseMatrixClass = /* #__PURE__ */factory(name, dependencies, _
574
617
  * @return {Iterable<{ value, index: number[] }>}
575
618
  */
576
619
  DenseMatrix.prototype[Symbol.iterator] = function* () {
577
- var _recurse3 = function* recurse(value, index) {
620
+ var _recurse = function* recurse(value, index) {
578
621
  if (isArray(value)) {
579
622
  for (var i = 0; i < value.length; i++) {
580
- yield* _recurse3(value[i], index.concat(i));
623
+ yield* _recurse(value[i], index.concat(i));
581
624
  }
582
625
  } else {
583
626
  yield {
@@ -586,7 +629,7 @@ export var createDenseMatrixClass = /* #__PURE__ */factory(name, dependencies, _
586
629
  };
587
630
  }
588
631
  };
589
- yield* _recurse3(this._data, []);
632
+ yield* _recurse(this._data, []);
590
633
  };
591
634
 
592
635
  /**
@@ -5,7 +5,7 @@ import { clone, deepStrictEqual } from '../../utils/object.js';
5
5
  import { arraySize, getArrayDataType, processSizesWildcard, unsqueeze, validateIndex } from '../../utils/array.js';
6
6
  import { factory } from '../../utils/factory.js';
7
7
  import { DimensionError } from '../../error/DimensionError.js';
8
- import { applyCallback } from '../../utils/applyCallback.js';
8
+ import { optimizeCallback } from '../../utils/optimizeCallback.js';
9
9
  var name = 'SparseMatrix';
10
10
  var dependencies = ['typed', 'equalScalar', 'Matrix'];
11
11
  export var createSparseMatrixClass = /* #__PURE__ */factory(name, dependencies, _ref => {
@@ -872,10 +872,11 @@ export var createSparseMatrixClass = /* #__PURE__ */factory(name, dependencies,
872
872
  // rows and columns
873
873
  var rows = this._size[0];
874
874
  var columns = this._size[1];
875
+ var fastCallback = optimizeCallback(callback, me, 'map');
875
876
  // invoke callback
876
877
  var invoke = function invoke(v, i, j) {
877
878
  // invoke callback
878
- return applyCallback(callback, v, [i, j], me, 'map');
879
+ return fastCallback(v, [i, j], me);
879
880
  };
880
881
  // invoke _map
881
882
  return _map(this, 0, rows - 1, 0, columns - 1, invoke, skipZeros);
@@ -980,6 +981,7 @@ export var createSparseMatrixClass = /* #__PURE__ */factory(name, dependencies,
980
981
  // rows and columns
981
982
  var rows = this._size[0];
982
983
  var columns = this._size[1];
984
+ var fastCallback = optimizeCallback(callback, me, 'forEach');
983
985
  // loop columns
984
986
  for (var j = 0; j < columns; j++) {
985
987
  // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
@@ -992,7 +994,7 @@ export var createSparseMatrixClass = /* #__PURE__ */factory(name, dependencies,
992
994
  var i = this._index[k];
993
995
 
994
996
  // value @ k
995
- callback(this._values[k], [i, j], me);
997
+ fastCallback(this._values[k], [i, j], me);
996
998
  }
997
999
  } else {
998
1000
  // create a cache holding all defined values
@@ -1006,7 +1008,7 @@ export var createSparseMatrixClass = /* #__PURE__ */factory(name, dependencies,
1006
1008
  // and either read the value or zero
1007
1009
  for (var _i7 = 0; _i7 < rows; _i7++) {
1008
1010
  var value = _i7 in values ? values[_i7] : 0;
1009
- callback(value, [_i7, j], me);
1011
+ fastCallback(value, [_i7, j], me);
1010
1012
  }
1011
1013
  }
1012
1014
  }
@@ -1405,6 +1407,7 @@ export var createSparseMatrixClass = /* #__PURE__ */factory(name, dependencies,
1405
1407
  // indeces for column j
1406
1408
  var k0 = ptr[j];
1407
1409
  var k1 = ptr[j + 1];
1410
+
1408
1411
  // loop
1409
1412
  for (var k = k0; k < k1; k++) {
1410
1413
  // invoke callback
@@ -806,6 +806,27 @@ export function get(array, index) {
806
806
  return index.reduce((acc, curr) => acc[curr], array);
807
807
  }
808
808
 
809
+ /**
810
+ * Recursive function to map a multi-dimensional array.
811
+ *
812
+ * @param {*} value - The current value being processed in the array.
813
+ * @param {Array} index - The index of the current value being processed in the array.
814
+ * @param {Array} array - The array being processed.
815
+ * @param {Function} callback - Function that produces the element of the new Array, taking three arguments: the value of the element, the index of the element, and the Array being processed.
816
+ * @returns {*} The new array with each element being the result of the callback function.
817
+ */
818
+ export function recurse(value, index, array, callback) {
819
+ if (Array.isArray(value)) {
820
+ return value.map(function (child, i) {
821
+ // we create a copy of the index array and append the new index value
822
+ return recurse(child, index.concat(i), array, callback);
823
+ });
824
+ } else {
825
+ // invoke the callback function with the right number of arguments
826
+ return callback(value, index, array);
827
+ }
828
+ }
829
+
809
830
  /**
810
831
  * Deep clones a multidimensional array
811
832
  * @param {Array} array
@@ -10,7 +10,7 @@ import { hasOwnProperty } from './object.js';
10
10
  */
11
11
  function getSafeProperty(object, prop) {
12
12
  // only allow getting safe properties of a plain object
13
- if (isPlainObject(object) && isSafeProperty(object, prop)) {
13
+ if (isSafeProperty(object, prop)) {
14
14
  return object[prop];
15
15
  }
16
16
  if (typeof object[prop] === 'function' && isSafeMethod(object, prop)) {
@@ -31,27 +31,22 @@ function getSafeProperty(object, prop) {
31
31
  // TODO: merge this function into access.js?
32
32
  function setSafeProperty(object, prop, value) {
33
33
  // only allow setting safe properties of a plain object
34
- if (isPlainObject(object) && isSafeProperty(object, prop)) {
34
+ if (isSafeProperty(object, prop)) {
35
35
  object[prop] = value;
36
36
  return value;
37
37
  }
38
38
  throw new Error('No access to property "' + prop + '"');
39
39
  }
40
- function getSafeProperties(object) {
41
- return Object.keys(object).filter(prop => hasOwnProperty(object, prop));
42
- }
43
- function hasSafeProperty(object, prop) {
44
- return prop in object;
45
- }
46
40
 
47
41
  /**
48
- * Test whether a property is safe to use for an object.
42
+ * Test whether a property is safe to use on an object or Array.
49
43
  * For example .toString and .constructor are not safe
44
+ * @param {Object | Array} object
50
45
  * @param {string} prop
51
46
  * @return {boolean} Returns true when safe
52
47
  */
53
48
  function isSafeProperty(object, prop) {
54
- if (!object || typeof object !== 'object') {
49
+ if (!isPlainObject(object) && !Array.isArray(object)) {
55
50
  return false;
56
51
  }
57
52
  // SAFE: whitelisted
@@ -147,8 +142,6 @@ var safeNativeMethods = {
147
142
  export { getSafeProperty };
148
143
  export { setSafeProperty };
149
144
  export { isSafeProperty };
150
- export { hasSafeProperty };
151
- export { getSafeProperties };
152
145
  export { getSafeMethod };
153
146
  export { isSafeMethod };
154
147
  export { isPlainObject };