jiangchengfeiyi-xiaochengxu/node_modules/mathjs/lib/cjs/function/matrix/subset.js
2025-01-02 11:13:50 +08:00

279 lines
9.3 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createSubset = void 0;
var _is = require("../../utils/is.js");
var _object = require("../../utils/object.js");
var _array = require("../../utils/array.js");
var _customs = require("../../utils/customs.js");
var _DimensionError = require("../../error/DimensionError.js");
var _factory = require("../../utils/factory.js");
const name = 'subset';
const dependencies = ['typed', 'matrix', 'zeros', 'add'];
const createSubset = exports.createSubset = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
let {
typed,
matrix,
zeros,
add
} = _ref;
/**
* Get or set a subset of a matrix or string.
*
* Syntax:
* math.subset(value, index) // retrieve a subset
* math.subset(value, index, replacement [, defaultValue]) // replace a subset
*
* Examples:
*
* // get a subset
* const d = [[1, 2], [3, 4]]
* math.subset(d, math.index(1, 0)) // returns 3
* math.subset(d, math.index([0, 1], 1)) // returns [[2], [4]]
* math.subset(d, math.index([false, true], 0)) // returns [[3]]
*
* // replace a subset
* const e = []
* const f = math.subset(e, math.index(0, [0, 2]), [5, 6]) // f = [[5, 0, 6]]
* const g = math.subset(f, math.index(1, 1), 7, 0) // g = [[5, 0, 6], [0, 7, 0]]
* math.subset(g, math.index([false, true], 1), 8) // returns [[5, 0, 6], [0, 8, 0]]
*
* // get submatrix using ranges
* const M = [
* [1,2,3],
* [4,5,6],
* [7,8,9]
* ]
* math.subset(M, math.index(math.range(0,2), math.range(0,3))) // [[1, 2, 3], [4, 5, 6]]
*
* See also:
*
* size, resize, squeeze, index
*
* @param {Array | Matrix | string} matrix An array, matrix, or string
* @param {Index} index
* For each dimension of the target, specifies an index or a list of
* indices to fetch or set. `subset` uses the cartesian product of
* the indices specified in each dimension.
* @param {*} [replacement] An array, matrix, or scalar.
* If provided, the subset is replaced with replacement.
* If not provided, the subset is returned
* @param {*} [defaultValue=undefined] Default value, filled in on new entries when
* the matrix is resized. If not provided,
* math.matrix elements will be left undefined.
* @return {Array | Matrix | string} Either the retrieved subset or the updated matrix.
*/
return typed(name, {
// get subset
'Matrix, Index': function (value, index) {
if ((0, _array.isEmptyIndex)(index)) {
return matrix();
}
(0, _array.validateIndexSourceSize)(value, index);
return value.subset(index);
},
'Array, Index': typed.referTo('Matrix, Index', function (subsetRef) {
return function (value, index) {
const subsetResult = subsetRef(matrix(value), index);
return index.isScalar() ? subsetResult : subsetResult.valueOf();
};
}),
'Object, Index': _getObjectProperty,
'string, Index': _getSubstring,
// set subset
'Matrix, Index, any, any': function (value, index, replacement, defaultValue) {
if ((0, _array.isEmptyIndex)(index)) {
return value;
}
(0, _array.validateIndexSourceSize)(value, index);
return value.clone().subset(index, _broadcastReplacement(replacement, index), defaultValue);
},
'Array, Index, any, any': typed.referTo('Matrix, Index, any, any', function (subsetRef) {
return function (value, index, replacement, defaultValue) {
const subsetResult = subsetRef(matrix(value), index, replacement, defaultValue);
return subsetResult.isMatrix ? subsetResult.valueOf() : subsetResult;
};
}),
'Array, Index, any': typed.referTo('Matrix, Index, any, any', function (subsetRef) {
return function (value, index, replacement) {
return subsetRef(matrix(value), index, replacement, undefined).valueOf();
};
}),
'Matrix, Index, any': typed.referTo('Matrix, Index, any, any', function (subsetRef) {
return function (value, index, replacement) {
return subsetRef(value, index, replacement, undefined);
};
}),
'string, Index, string': _setSubstring,
'string, Index, string, string': _setSubstring,
'Object, Index, any': _setObjectProperty
});
/**
* Broadcasts a replacment value to be the same size as index
* @param {number | BigNumber | Array | Matrix} replacement Replacement value to try to broadcast
* @param {*} index Index value
* @returns broadcasted replacement that matches the size of index
*/
function _broadcastReplacement(replacement, index) {
if (typeof replacement === 'string') {
throw new Error('can\'t boradcast a string');
}
if (index._isScalar) {
return replacement;
}
const indexSize = index.size();
if (indexSize.every(d => d > 0)) {
try {
return add(replacement, zeros(indexSize));
} catch (error) {
return replacement;
}
} else {
return replacement;
}
}
});
/**
* Retrieve a subset of a string
* @param {string} str string from which to get a substring
* @param {Index} index An index or list of indices (character positions)
* @returns {string} substring
* @private
*/
function _getSubstring(str, index) {
if (!(0, _is.isIndex)(index)) {
// TODO: better error message
throw new TypeError('Index expected');
}
if ((0, _array.isEmptyIndex)(index)) {
return '';
}
(0, _array.validateIndexSourceSize)(Array.from(str), index);
if (index.size().length !== 1) {
throw new _DimensionError.DimensionError(index.size().length, 1);
}
// validate whether the range is out of range
const strLen = str.length;
(0, _array.validateIndex)(index.min()[0], strLen);
(0, _array.validateIndex)(index.max()[0], strLen);
const range = index.dimension(0);
let substr = '';
range.forEach(function (v) {
substr += str.charAt(v);
});
return substr;
}
/**
* Replace a substring in a string
* @param {string} str string to be replaced
* @param {Index} index An index or list of indices (character positions)
* @param {string} replacement Replacement string
* @param {string} [defaultValue] Default value to be used when resizing
* the string. is ' ' by default
* @returns {string} result
* @private
*/
function _setSubstring(str, index, replacement, defaultValue) {
if (!index || index.isIndex !== true) {
// TODO: better error message
throw new TypeError('Index expected');
}
if ((0, _array.isEmptyIndex)(index)) {
return str;
}
(0, _array.validateIndexSourceSize)(Array.from(str), index);
if (index.size().length !== 1) {
throw new _DimensionError.DimensionError(index.size().length, 1);
}
if (defaultValue !== undefined) {
if (typeof defaultValue !== 'string' || defaultValue.length !== 1) {
throw new TypeError('Single character expected as defaultValue');
}
} else {
defaultValue = ' ';
}
const range = index.dimension(0);
const len = range.size()[0];
if (len !== replacement.length) {
throw new _DimensionError.DimensionError(range.size()[0], replacement.length);
}
// validate whether the range is out of range
const strLen = str.length;
(0, _array.validateIndex)(index.min()[0]);
(0, _array.validateIndex)(index.max()[0]);
// copy the string into an array with characters
const chars = [];
for (let i = 0; i < strLen; i++) {
chars[i] = str.charAt(i);
}
range.forEach(function (v, i) {
chars[v] = replacement.charAt(i[0]);
});
// initialize undefined characters with a space
if (chars.length > strLen) {
for (let i = strLen - 1, len = chars.length; i < len; i++) {
if (!chars[i]) {
chars[i] = defaultValue;
}
}
}
return chars.join('');
}
/**
* Retrieve a property from an object
* @param {Object} object
* @param {Index} index
* @return {*} Returns the value of the property
* @private
*/
function _getObjectProperty(object, index) {
if ((0, _array.isEmptyIndex)(index)) {
return undefined;
}
if (index.size().length !== 1) {
throw new _DimensionError.DimensionError(index.size(), 1);
}
const key = index.dimension(0);
if (typeof key !== 'string') {
throw new TypeError('String expected as index to retrieve an object property');
}
return (0, _customs.getSafeProperty)(object, key);
}
/**
* Set a property on an object
* @param {Object} object
* @param {Index} index
* @param {*} replacement
* @return {*} Returns the updated object
* @private
*/
function _setObjectProperty(object, index, replacement) {
if ((0, _array.isEmptyIndex)(index)) {
return object;
}
if (index.size().length !== 1) {
throw new _DimensionError.DimensionError(index.size(), 1);
}
const key = index.dimension(0);
if (typeof key !== 'string') {
throw new TypeError('String expected as index to retrieve an object property');
}
// clone the object, and apply the property to the clone
const updated = (0, _object.clone)(object);
(0, _customs.setSafeProperty)(updated, key, replacement);
return updated;
}