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.
- package/HISTORY.md +30 -0
- package/bin/cli.js +24 -10
- package/lib/browser/math.js +1 -1
- package/lib/browser/math.js.LICENSE.txt +2 -2
- package/lib/browser/math.js.map +1 -1
- package/lib/cjs/core/function/typed.js +1 -0
- package/lib/cjs/expression/node/FunctionNode.js +9 -1
- package/lib/cjs/expression/parse.js +1 -1
- package/lib/cjs/expression/transform/filter.transform.js +28 -40
- package/lib/cjs/expression/transform/forEach.transform.js +29 -30
- package/lib/cjs/expression/transform/map.transform.js +8 -93
- package/lib/cjs/expression/transform/utils/transformCallback.js +101 -0
- package/lib/cjs/function/algebra/derivative.js +10 -11
- package/lib/cjs/function/matrix/filter.js +3 -2
- package/lib/cjs/function/matrix/forEach.js +3 -14
- package/lib/cjs/function/matrix/map.js +11 -33
- package/lib/cjs/header.js +2 -2
- package/lib/cjs/type/matrix/DenseMatrix.js +73 -29
- package/lib/cjs/type/matrix/SparseMatrix.js +7 -4
- package/lib/cjs/utils/array.js +22 -0
- package/lib/cjs/utils/customs.js +5 -12
- package/lib/cjs/utils/map.js +5 -3
- package/lib/cjs/utils/optimizeCallback.js +94 -0
- package/lib/cjs/version.js +1 -1
- package/lib/esm/core/function/typed.js +1 -0
- package/lib/esm/expression/node/FunctionNode.js +9 -1
- package/lib/esm/expression/parse.js +1 -1
- package/lib/esm/expression/transform/filter.transform.js +28 -40
- package/lib/esm/expression/transform/forEach.transform.js +29 -30
- package/lib/esm/expression/transform/map.transform.js +8 -93
- package/lib/esm/expression/transform/utils/transformCallback.js +95 -0
- package/lib/esm/function/algebra/derivative.js +10 -11
- package/lib/esm/function/matrix/filter.js +3 -2
- package/lib/esm/function/matrix/forEach.js +3 -14
- package/lib/esm/function/matrix/map.js +12 -34
- package/lib/esm/type/matrix/DenseMatrix.js +75 -32
- package/lib/esm/type/matrix/SparseMatrix.js +7 -4
- package/lib/esm/utils/array.js +21 -0
- package/lib/esm/utils/customs.js +5 -12
- package/lib/esm/utils/map.js +6 -4
- package/lib/esm/utils/optimizeCallback.js +88 -0
- package/lib/esm/version.js +1 -1
- package/package.json +7 -7
- package/types/index.d.ts +50 -12
- package/lib/cjs/utils/applyCallback.js +0 -73
- 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,
|
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,
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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 {
|
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
|
62
|
+
return fastCallback(value, [index], array);
|
62
63
|
});
|
63
64
|
}
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import {
|
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
|
-
|
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 {
|
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
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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 {
|
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
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
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
|
561
|
-
|
562
|
-
|
563
|
-
|
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
|
620
|
+
var _recurse = function* recurse(value, index) {
|
578
621
|
if (isArray(value)) {
|
579
622
|
for (var i = 0; i < value.length; i++) {
|
580
|
-
yield*
|
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*
|
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 {
|
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
|
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
|
-
|
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
|
-
|
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
|
package/lib/esm/utils/array.js
CHANGED
@@ -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
|
package/lib/esm/utils/customs.js
CHANGED
@@ -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 (
|
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 (
|
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
|
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
|
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 };
|