From 14416a0e1575221879c1f7f365219b4cb5a1b0e1 Mon Sep 17 00:00:00 2001 From: Andy Coenen Date: Tue, 31 Aug 2021 11:48:12 -0400 Subject: [PATCH] Update typescript --- lib/umap-js.js | 7231 ++++++++++++++++++++------------------------ lib/umap-js.min.js | 2 +- package-lock.json | 6 +- package.json | 2 +- 4 files changed, 3271 insertions(+), 3970 deletions(-) diff --git a/lib/umap-js.js b/lib/umap-js.js index 93dc913..a465dcb 100644 --- a/lib/umap-js.js +++ b/lib/umap-js.js @@ -91,7 +91,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 5); +/******/ return __webpack_require__(__webpack_require__.s = 4); /******/ }) /************************************************************************/ /******/ ([ @@ -100,33 +100,19 @@ return /******/ (function(modules) { // webpackBootstrap "use strict"; - -const toString = Object.prototype.toString; - -function isAnyArray(object) { - return toString.call(object).endsWith('Array]'); -} - -module.exports = isAnyArray; - - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.reshape2d = exports.rejectionSample = exports.max2d = exports.max = exports.mean = exports.sum = exports.linear = exports.ones = exports.zeros = exports.filled = exports.range = exports.empty = exports.norm = exports.tauRand = exports.tauRandInt = void 0; function tauRandInt(n, random) { return Math.floor(random() * n); } @@ -254,20 +240,33 @@ exports.reshape2d = reshape2d; /***/ }), -/* 2 */ +/* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -var utils = __importStar(__webpack_require__(1)); +exports.smallestFlagged = exports.deheapSort = exports.buildCandidates = exports.uncheckedHeapPush = exports.heapPush = exports.rejectionSample = exports.makeHeap = void 0; +var utils = __importStar(__webpack_require__(0)); function makeHeap(nPoints, size) { var makeArrays = function (fillValue) { return utils.empty(nPoints).map(function () { @@ -461,11 +460,30 @@ exports.smallestFlagged = smallestFlagged; /***/ }), -/* 3 */ +/* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; @@ -482,26 +500,21 @@ var __read = (this && this.__read) || function (o, n) { } return ar; }; -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; -Object.defineProperty(exports, "__esModule", { value: true }); var _a; -var utils = __importStar(__webpack_require__(1)); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getCSR = exports.normalize = exports.eliminateZeros = exports.multiplyScalar = exports.maximum = exports.subtract = exports.add = exports.pairwiseMultiply = exports.identity = exports.transpose = exports.SparseMatrix = void 0; +var utils = __importStar(__webpack_require__(0)); var SparseMatrix = (function () { function SparseMatrix(rows, cols, values, dims) { this.entries = new Map(); @@ -676,8 +689,8 @@ function eliminateZeros(m) { } exports.eliminateZeros = eliminateZeros; function normalize(m, normType) { - if (normType === void 0) { normType = "l2"; } var e_1, _a; + if (normType === void 0) { normType = "l2"; } var normFn = normFns[normType]; var colsByRow = new Map(); m.forEach(function (_, row, col) { @@ -800,11 +813,30 @@ exports.getCSR = getCSR; /***/ }), -/* 4 */ +/* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; @@ -825,25 +857,20 @@ var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; -}; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); -var utils = __importStar(__webpack_require__(1)); +exports.searchFlatTree = exports.makeLeafArray = exports.makeForest = exports.FlatTree = void 0; +var utils = __importStar(__webpack_require__(0)); var FlatTree = (function () { function FlatTree(hyperplanes, offsets, children, indices) { this.hyperplanes = hyperplanes; @@ -1055,27 +1082,47 @@ exports.searchFlatTree = searchFlatTree; /***/ }), -/* 5 */ +/* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var umap_1 = __webpack_require__(6); -exports.UMAP = umap_1.UMAP; +var umap_1 = __webpack_require__(5); +Object.defineProperty(exports, "UMAP", { enumerable: true, get: function () { return umap_1.UMAP; } }); /***/ }), -/* 6 */ +/* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; @@ -1126,29 +1173,23 @@ var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var heap = __importStar(__webpack_require__(2)); -var matrix = __importStar(__webpack_require__(3)); -var nnDescent = __importStar(__webpack_require__(7)); -var tree = __importStar(__webpack_require__(4)); -var utils = __importStar(__webpack_require__(1)); -var ml_levenberg_marquardt_1 = __importDefault(__webpack_require__(8)); +exports.initTransform = exports.resetLocalConnectivity = exports.fastIntersection = exports.findABParams = exports.cosine = exports.euclidean = exports.UMAP = void 0; +var heap = __importStar(__webpack_require__(1)); +var matrix = __importStar(__webpack_require__(2)); +var nnDescent = __importStar(__webpack_require__(6)); +var tree = __importStar(__webpack_require__(3)); +var utils = __importStar(__webpack_require__(0)); +var ml_levenberg_marquardt_1 = __importDefault(__webpack_require__(7)); var SMOOTH_K_TOLERANCE = 1e-5; var MIN_K_DIST_SCALE = 1e-3; var UMAP = (function () { function UMAP(params) { - if (params === void 0) { params = {}; } var _this = this; + if (params === void 0) { params = {}; } this.learningRate = 1.0; this.localConnectivity = 1.0; this.minDist = 0.1; @@ -1824,33 +1865,47 @@ exports.initTransform = initTransform; /***/ }), -/* 7 */ +/* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var __values = (this && this.__values) || function (o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); - return { + if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; -}; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); -var heap = __importStar(__webpack_require__(2)); -var matrix = __importStar(__webpack_require__(3)); -var tree = __importStar(__webpack_require__(4)); -var utils = __importStar(__webpack_require__(1)); +exports.initializeSearch = exports.makeInitializedNNSearch = exports.makeInitializations = exports.makeNNDescent = void 0; +var heap = __importStar(__webpack_require__(1)); +var matrix = __importStar(__webpack_require__(2)); +var tree = __importStar(__webpack_require__(3)); +var utils = __importStar(__webpack_require__(0)); function makeNNDescent(distanceFn, random) { return function nNDescent(data, leafArray, nNeighbors, nIters, maxCandidates, delta, rho, rpTreeInit) { if (nIters === void 0) { nIters = 10; } @@ -1958,7 +2013,7 @@ function makeInitializedNNSearch(distanceFn) { } var candidates = indices.slice(indptr[vertex], indptr[vertex + 1]); try { - for (var candidates_1 = __values(candidates), candidates_1_1 = candidates_1.next(); !candidates_1_1.done; candidates_1_1 = candidates_1.next()) { + for (var candidates_1 = (e_1 = void 0, __values(candidates)), candidates_1_1 = candidates_1.next(); !candidates_1_1.done; candidates_1_1 = candidates_1.next()) { var candidate = candidates_1_1.value; if (candidate === vertex || candidate === -1 || @@ -2008,14 +2063,20 @@ exports.initializeSearch = initializeSearch; /***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { +/* 7 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +// CONCATENATED MODULE: ./node_modules/is-any-array/src/index.js +const src_toString = Object.prototype.toString; -var mlMatrix = __webpack_require__(9); +function isAnyArray(object) { + return src_toString.call(object).endsWith('Array]'); +} +// CONCATENATED MODULE: ./node_modules/ml-levenberg-marquardt/src/errorCalculation.js /** * Calculate current error * @ignore @@ -2027,226 +2088,84 @@ var mlMatrix = __webpack_require__(9); function errorCalculation( data, parameters, - parameterizedFunction + parameterizedFunction, ) { - var error = 0; + let error = 0; const func = parameterizedFunction(parameters); - for (var i = 0; i < data.x.length; i++) { + for (let i = 0; i < data.x.length; i++) { error += Math.abs(data.y[i] - func(data.x[i])); } return error; } -/** - * Difference of the matrix function over the parameters - * @ignore - * @param {{x:Array, y:Array}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ] - * @param {Array} evaluatedData - Array of previous evaluated function values - * @param {Array} params - Array of previous parameter values - * @param {number} gradientDifference - Adjustment for decrease the damping parameter - * @param {function} paramFunction - The parameters and returns a function with the independent variable as a parameter - * @return {Matrix} - */ -function gradientFunction( - data, - evaluatedData, - params, - gradientDifference, - paramFunction -) { - const n = params.length; - const m = data.x.length; - - var ans = new Array(n); +// CONCATENATED MODULE: ./node_modules/ml-array-rescale/node_modules/is-any-array/src/index.js +const is_any_array_src_toString = Object.prototype.toString; + +function src_isAnyArray(object) { + return is_any_array_src_toString.call(object).endsWith('Array]'); +} - for (var param = 0; param < n; param++) { - ans[param] = new Array(m); - var auxParams = params.concat(); - auxParams[param] += gradientDifference; - var funcParam = paramFunction(auxParams); +// CONCATENATED MODULE: ./node_modules/ml-array-max/node_modules/is-any-array/src/index.js +const node_modules_is_any_array_src_toString = Object.prototype.toString; + +function is_any_array_src_isAnyArray(object) { + return node_modules_is_any_array_src_toString.call(object).endsWith('Array]'); +} - for (var point = 0; point < m; point++) { - ans[param][point] = evaluatedData[point] - funcParam(data.x[point]); - } - } - return new mlMatrix.Matrix(ans); -} +// CONCATENATED MODULE: ./node_modules/ml-array-max/lib-es6/index.js -/** - * Matrix function over the samples - * @ignore - * @param {{x:Array, y:Array}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ] - * @param {Array} evaluatedData - Array of previous evaluated function values - * @return {Matrix} - */ -function matrixFunction(data, evaluatedData) { - const m = data.x.length; - var ans = new Array(m); +function lib_es6_max(input) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - for (var point = 0; point < m; point++) { - ans[point] = data.y[point] - evaluatedData[point]; + if (!is_any_array_src_isAnyArray(input)) { + throw new TypeError('input must be an array'); } - return new mlMatrix.Matrix([ans]); -} - -/** - * Iteration for Levenberg-Marquardt - * @ignore - * @param {{x:Array, y:Array}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ] - * @param {Array} params - Array of previous parameter values - * @param {number} damping - Levenberg-Marquardt parameter - * @param {number} gradientDifference - Adjustment for decrease the damping parameter - * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter - * @return {Array} - */ -function step( - data, - params, - damping, - gradientDifference, - parameterizedFunction -) { - var identity = mlMatrix.Matrix.eye(params.length).mul( - damping * gradientDifference * gradientDifference - ); - - var l = data.x.length; - var evaluatedData = new Array(l); - const func = parameterizedFunction(params); - for (var i = 0; i < l; i++) { - evaluatedData[i] = func(data.x[i]); + if (input.length === 0) { + throw new TypeError('input must not be empty'); } - var gradientFunc = gradientFunction( - data, - evaluatedData, - params, - gradientDifference, - parameterizedFunction - ); - var matrixFunc = matrixFunction(data, evaluatedData).transposeView(); - var inverseMatrix = mlMatrix.inverse( - identity.add(gradientFunc.mmul(gradientFunc.transposeView())) - ); - params = new mlMatrix.Matrix([params]); - params = params.sub( - inverseMatrix - .mmul(gradientFunc) - .mmul(matrixFunc) - .mul(gradientDifference) - .transposeView() - ); - return params.to1DArray(); -} - -/** - * Curve fitting algorithm - * @param {{x:Array, y:Array}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ] - * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter - * @param {object} [options] - Options object - * @param {number} [options.damping] - Levenberg-Marquardt parameter - * @param {number} [options.gradientDifference = 10e-2] - Adjustment for decrease the damping parameter - * @param {Array} [options.initialValues] - Array of initial parameter values - * @param {number} [options.maxIterations = 100] - Maximum of allowed iterations - * @param {number} [options.errorTolerance = 10e-3] - Minimum uncertainty allowed for each point - * @return {{parameterValues: Array, parameterError: number, iterations: number}} - */ -function levenbergMarquardt( - data, - parameterizedFunction, - options = {} -) { - let { - maxIterations = 100, - gradientDifference = 10e-2, - damping = 0, - errorTolerance = 10e-3, - initialValues - } = options; + var _options$fromIndex = options.fromIndex, + fromIndex = _options$fromIndex === void 0 ? 0 : _options$fromIndex, + _options$toIndex = options.toIndex, + toIndex = _options$toIndex === void 0 ? input.length : _options$toIndex; - if (damping <= 0) { - throw new Error('The damping option must be a positive number'); - } else if (!data.x || !data.y) { - throw new Error('The data parameter must have x and y elements'); - } else if ( - !Array.isArray(data.x) || - data.x.length < 2 || - !Array.isArray(data.y) || - data.y.length < 2 - ) { - throw new Error( - 'The data parameter elements must be an array with more than 2 points' - ); - } else { - let dataLen = data.x.length; - if (dataLen !== data.y.length) { - throw new Error('The data parameter elements must have the same size'); - } + if (fromIndex < 0 || fromIndex >= input.length || !Number.isInteger(fromIndex)) { + throw new Error('fromIndex must be a positive integer smaller than length'); } - var parameters = - initialValues || new Array(parameterizedFunction.length).fill(1); - - if (!Array.isArray(parameters)) { - throw new Error('initialValues must be an array'); + if (toIndex <= fromIndex || toIndex > input.length || !Number.isInteger(toIndex)) { + throw new Error('toIndex must be an integer greater than fromIndex and at most equal to length'); } - var error = errorCalculation(data, parameters, parameterizedFunction); + var maxValue = input[fromIndex]; - var converged = error <= errorTolerance; - - for ( - var iteration = 0; - iteration < maxIterations && !converged; - iteration++ - ) { - parameters = step( - data, - parameters, - damping, - gradientDifference, - parameterizedFunction - ); - error = errorCalculation(data, parameters, parameterizedFunction); - converged = error <= errorTolerance; + for (var i = fromIndex + 1; i < toIndex; i++) { + if (input[i] > maxValue) maxValue = input[i]; } - return { - parameterValues: parameters, - parameterError: error, - iterations: iteration - }; + return maxValue; } -module.exports = levenbergMarquardt; - - -/***/ }), -/* 9 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); +/* harmony default export */ var lib_es6 = (lib_es6_max); -// EXTERNAL MODULE: ./node_modules/is-any-array/src/index.js -var src = __webpack_require__(0); -var src_default = /*#__PURE__*/__webpack_require__.n(src); +// CONCATENATED MODULE: ./node_modules/ml-array-min/node_modules/is-any-array/src/index.js +const ml_array_min_node_modules_is_any_array_src_toString = Object.prototype.toString; + +function node_modules_is_any_array_src_isAnyArray(object) { + return ml_array_min_node_modules_is_any_array_src_toString.call(object).endsWith('Array]'); +} -// CONCATENATED MODULE: ./node_modules/ml-array-max/lib-es6/index.js +// CONCATENATED MODULE: ./node_modules/ml-array-min/lib-es6/index.js -/** - * Computes the maximum of the given values - * @param {Array} input - * @return {number} - */ +function lib_es6_min(input) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; -function lib_es6_max(input) { - if (!src_default()(input)) { + if (!node_modules_is_any_array_src_isAnyArray(input)) { throw new TypeError('input must be an array'); } @@ -2254,42 +2173,26 @@ function lib_es6_max(input) { throw new TypeError('input must not be empty'); } - var max = input[0]; - - for (var i = 1; i < input.length; i++) { - if (input[i] > max) max = input[i]; - } - - return max; -} - -/* harmony default export */ var lib_es6 = (lib_es6_max); - -// CONCATENATED MODULE: ./node_modules/ml-array-min/lib-es6/index.js - - -/** - * Computes the minimum of the given values - * @param {Array} input - * @return {number} - */ + var _options$fromIndex = options.fromIndex, + fromIndex = _options$fromIndex === void 0 ? 0 : _options$fromIndex, + _options$toIndex = options.toIndex, + toIndex = _options$toIndex === void 0 ? input.length : _options$toIndex; -function lib_es6_min(input) { - if (!src_default()(input)) { - throw new TypeError('input must be an array'); + if (fromIndex < 0 || fromIndex >= input.length || !Number.isInteger(fromIndex)) { + throw new Error('fromIndex must be a positive integer smaller than length'); } - if (input.length === 0) { - throw new TypeError('input must not be empty'); + if (toIndex <= fromIndex || toIndex > input.length || !Number.isInteger(toIndex)) { + throw new Error('toIndex must be an integer greater than fromIndex and at most equal to length'); } - var min = input[0]; + var minValue = input[fromIndex]; - for (var i = 1; i < input.length; i++) { - if (input[i] < min) min = input[i]; + for (var i = fromIndex + 1; i < toIndex; i++) { + if (input[i] < minValue) minValue = input[i]; } - return min; + return minValue; } /* harmony default export */ var ml_array_min_lib_es6 = (lib_es6_min); @@ -2302,7 +2205,7 @@ function lib_es6_min(input) { function rescale(input) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (!src_default()(input)) { + if (!src_isAnyArray(input)) { throw new TypeError('input must be an array'); } else if (input.length === 0) { throw new TypeError('input must not be empty'); @@ -2311,7 +2214,7 @@ function rescale(input) { var output; if (options.output !== undefined) { - if (!src_default()(options.output)) { + if (!src_isAnyArray(options.output)) { throw new TypeError('output option must be an array if specified'); } @@ -2347,828 +2250,887 @@ function rescale(input) { /* harmony default export */ var ml_array_rescale_lib_es6 = (rescale); -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/dc/lu.js - +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/inspect.js +const indent = ' '.repeat(2); +const indentData = ' '.repeat(4); -/** - * @class LuDecomposition - * @link https://github.com/lutzroeder/Mapack/blob/master/Source/LuDecomposition.cs - * @param {Matrix} matrix - */ -class lu_LuDecomposition { - constructor(matrix) { - matrix = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(matrix); +function inspectMatrix() { + return inspectMatrixWithOptions(this); +} - var lu = matrix.clone(); - var rows = lu.rows; - var columns = lu.columns; - var pivotVector = new Array(rows); - var pivotSign = 1; - var i, j, k, p, s, t, v; - var LUcolj, kmax; +function inspectMatrixWithOptions(matrix, options = {}) { + const { maxRows = 15, maxColumns = 10, maxNumSize = 8 } = options; + return `${matrix.constructor.name} { +${indent}[ +${indentData}${inspectData(matrix, maxRows, maxColumns, maxNumSize)} +${indent}] +${indent}rows: ${matrix.rows} +${indent}columns: ${matrix.columns} +}`; +} - for (i = 0; i < rows; i++) { - pivotVector[i] = i; +function inspectData(matrix, maxRows, maxColumns, maxNumSize) { + const { rows, columns } = matrix; + const maxI = Math.min(rows, maxRows); + const maxJ = Math.min(columns, maxColumns); + const result = []; + for (let i = 0; i < maxI; i++) { + let line = []; + for (let j = 0; j < maxJ; j++) { + line.push(formatNumber(matrix.get(i, j), maxNumSize)); } + result.push(`${line.join(' ')}`); + } + if (maxJ !== columns) { + result[result.length - 1] += ` ... ${columns - maxColumns} more columns`; + } + if (maxI !== rows) { + result.push(`... ${rows - maxRows} more rows`); + } + return result.join(`\n${indentData}`); +} - LUcolj = new Array(rows); - - for (j = 0; j < columns; j++) { - for (i = 0; i < rows; i++) { - LUcolj[i] = lu.get(i, j); - } +function formatNumber(num, maxNumSize) { + const numStr = String(num); + if (numStr.length <= maxNumSize) { + return numStr.padEnd(maxNumSize, ' '); + } + const precise = num.toPrecision(maxNumSize - 2); + if (precise.length <= maxNumSize) { + return precise; + } + const exponential = num.toExponential(maxNumSize - 2); + const eIndex = exponential.indexOf('e'); + const e = exponential.slice(eIndex); + return exponential.slice(0, maxNumSize - e.length) + e; +} - for (i = 0; i < rows; i++) { - kmax = Math.min(i, j); - s = 0; - for (k = 0; k < kmax; k++) { - s += lu.get(i, k) * LUcolj[k]; - } - LUcolj[i] -= s; - lu.set(i, j, LUcolj[i]); +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/mathOperations.js +function installMathOperations(AbstractMatrix, Matrix) { + AbstractMatrix.prototype.add = function add(value) { + if (typeof value === 'number') return this.addS(value); + return this.addM(value); + }; + + AbstractMatrix.prototype.addS = function addS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) + value); } + } + return this; + }; - p = j; - for (i = j + 1; i < rows; i++) { - if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) { - p = i; - } + AbstractMatrix.prototype.addM = function addM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) + matrix.get(i, j)); } + } + return this; + }; - if (p !== j) { - for (k = 0; k < columns; k++) { - t = lu.get(p, k); - lu.set(p, k, lu.get(j, k)); - lu.set(j, k, t); - } + AbstractMatrix.add = function add(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.add(value); + }; - v = pivotVector[p]; - pivotVector[p] = pivotVector[j]; - pivotVector[j] = v; + AbstractMatrix.prototype.sub = function sub(value) { + if (typeof value === 'number') return this.subS(value); + return this.subM(value); + }; - pivotSign = -pivotSign; + AbstractMatrix.prototype.subS = function subS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) - value); } + } + return this; + }; - if (j < rows && lu.get(j, j) !== 0) { - for (i = j + 1; i < rows; i++) { - lu.set(i, j, lu.get(i, j) / lu.get(j, j)); - } + AbstractMatrix.prototype.subM = function subM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) - matrix.get(i, j)); } } + return this; + }; - this.LU = lu; - this.pivotVector = pivotVector; - this.pivotSign = pivotSign; - } + AbstractMatrix.sub = function sub(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.sub(value); + }; + AbstractMatrix.prototype.subtract = AbstractMatrix.prototype.sub; + AbstractMatrix.prototype.subtractS = AbstractMatrix.prototype.subS; + AbstractMatrix.prototype.subtractM = AbstractMatrix.prototype.subM; + AbstractMatrix.subtract = AbstractMatrix.sub; + + AbstractMatrix.prototype.mul = function mul(value) { + if (typeof value === 'number') return this.mulS(value); + return this.mulM(value); + }; - /** - * - * @return {boolean} - */ - isSingular() { - var data = this.LU; - var col = data.columns; - for (var j = 0; j < col; j++) { - if (data[j][j] === 0) { - return true; + AbstractMatrix.prototype.mulS = function mulS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) * value); } } - return false; - } - - /** - * - * @param {Matrix} value - * @return {Matrix} - */ - solve(value) { - value = matrix_Matrix.checkMatrix(value); - - var lu = this.LU; - var rows = lu.rows; + return this; + }; - if (rows !== value.rows) { - throw new Error('Invalid matrix dimensions'); + AbstractMatrix.prototype.mulM = function mulM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); } - if (this.isSingular()) { - throw new Error('LU matrix is singular'); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) * matrix.get(i, j)); + } } + return this; + }; - var count = value.columns; - var X = value.subMatrixRow(this.pivotVector, 0, count - 1); - var columns = lu.columns; - var i, j, k; + AbstractMatrix.mul = function mul(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.mul(value); + }; + AbstractMatrix.prototype.multiply = AbstractMatrix.prototype.mul; + AbstractMatrix.prototype.multiplyS = AbstractMatrix.prototype.mulS; + AbstractMatrix.prototype.multiplyM = AbstractMatrix.prototype.mulM; + AbstractMatrix.multiply = AbstractMatrix.mul; + + AbstractMatrix.prototype.div = function div(value) { + if (typeof value === 'number') return this.divS(value); + return this.divM(value); + }; - for (k = 0; k < columns; k++) { - for (i = k + 1; i < columns; i++) { - for (j = 0; j < count; j++) { - X[i][j] -= X[k][j] * lu[i][k]; - } + AbstractMatrix.prototype.divS = function divS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) / value); } } - for (k = columns - 1; k >= 0; k--) { - for (j = 0; j < count; j++) { - X[k][j] /= lu[k][k]; + return this; + }; + + AbstractMatrix.prototype.divM = function divM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) / matrix.get(i, j)); } - for (i = 0; i < k; i++) { - for (j = 0; j < count; j++) { - X[i][j] -= X[k][j] * lu[i][k]; - } + } + return this; + }; + + AbstractMatrix.div = function div(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.div(value); + }; + AbstractMatrix.prototype.divide = AbstractMatrix.prototype.div; + AbstractMatrix.prototype.divideS = AbstractMatrix.prototype.divS; + AbstractMatrix.prototype.divideM = AbstractMatrix.prototype.divM; + AbstractMatrix.divide = AbstractMatrix.div; + + AbstractMatrix.prototype.mod = function mod(value) { + if (typeof value === 'number') return this.modS(value); + return this.modM(value); + }; + + AbstractMatrix.prototype.modS = function modS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) % value); } } - return X; - } + return this; + }; - /** - * - * @return {number} - */ - get determinant() { - var data = this.LU; - if (!data.isSquare()) { - throw new Error('Matrix must be square'); + AbstractMatrix.prototype.modM = function modM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); } - var determinant = this.pivotSign; - var col = data.columns; - for (var j = 0; j < col; j++) { - determinant *= data[j][j]; + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) % matrix.get(i, j)); + } } - return determinant; - } + return this; + }; - /** - * - * @return {Matrix} - */ - get lowerTriangularMatrix() { - var data = this.LU; - var rows = data.rows; - var columns = data.columns; - var X = new matrix_Matrix(rows, columns); - for (var i = 0; i < rows; i++) { - for (var j = 0; j < columns; j++) { - if (i > j) { - X[i][j] = data[i][j]; - } else if (i === j) { - X[i][j] = 1; - } else { - X[i][j] = 0; - } + AbstractMatrix.mod = function mod(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.mod(value); + }; + AbstractMatrix.prototype.modulus = AbstractMatrix.prototype.mod; + AbstractMatrix.prototype.modulusS = AbstractMatrix.prototype.modS; + AbstractMatrix.prototype.modulusM = AbstractMatrix.prototype.modM; + AbstractMatrix.modulus = AbstractMatrix.mod; + + AbstractMatrix.prototype.and = function and(value) { + if (typeof value === 'number') return this.andS(value); + return this.andM(value); + }; + + AbstractMatrix.prototype.andS = function andS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) & value); } } - return X; - } + return this; + }; - /** - * - * @return {Matrix} - */ - get upperTriangularMatrix() { - var data = this.LU; - var rows = data.rows; - var columns = data.columns; - var X = new matrix_Matrix(rows, columns); - for (var i = 0; i < rows; i++) { - for (var j = 0; j < columns; j++) { - if (i <= j) { - X[i][j] = data[i][j]; - } else { - X[i][j] = 0; - } + AbstractMatrix.prototype.andM = function andM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) & matrix.get(i, j)); } } - return X; - } + return this; + }; - /** - * - * @return {Array} - */ - get pivotPermutationVector() { - return this.pivotVector.slice(); - } -} + AbstractMatrix.and = function and(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.and(value); + }; -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/dc/util.js -function hypotenuse(a, b) { - var r = 0; - if (Math.abs(a) > Math.abs(b)) { - r = b / a; - return Math.abs(a) * Math.sqrt(1 + r * r); - } - if (b !== 0) { - r = a / b; - return Math.abs(b) * Math.sqrt(1 + r * r); - } - return 0; -} + AbstractMatrix.prototype.or = function or(value) { + if (typeof value === 'number') return this.orS(value); + return this.orM(value); + }; -function getFilled2DArray(rows, columns, value) { - var array = new Array(rows); - for (var i = 0; i < rows; i++) { - array[i] = new Array(columns); - for (var j = 0; j < columns; j++) { - array[i][j] = value; + AbstractMatrix.prototype.orS = function orS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) | value); + } } - } - return array; -} - -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/dc/svd.js + return this; + }; + AbstractMatrix.prototype.orM = function orM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) | matrix.get(i, j)); + } + } + return this; + }; + AbstractMatrix.or = function or(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.or(value); + }; + AbstractMatrix.prototype.xor = function xor(value) { + if (typeof value === 'number') return this.xorS(value); + return this.xorM(value); + }; -/** - * @class SingularValueDecomposition - * @see https://github.com/accord-net/framework/blob/development/Sources/Accord.Math/Decompositions/SingularValueDecomposition.cs - * @param {Matrix} value - * @param {object} [options] - * @param {boolean} [options.computeLeftSingularVectors=true] - * @param {boolean} [options.computeRightSingularVectors=true] - * @param {boolean} [options.autoTranspose=false] - */ -class svd_SingularValueDecomposition { - constructor(value, options = {}) { - value = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(value); + AbstractMatrix.prototype.xorS = function xorS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) ^ value); + } + } + return this; + }; - var m = value.rows; - var n = value.columns; + AbstractMatrix.prototype.xorM = function xorM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) ^ matrix.get(i, j)); + } + } + return this; + }; - const { - computeLeftSingularVectors = true, - computeRightSingularVectors = true, - autoTranspose = false - } = options; + AbstractMatrix.xor = function xor(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.xor(value); + }; - var wantu = Boolean(computeLeftSingularVectors); - var wantv = Boolean(computeRightSingularVectors); + AbstractMatrix.prototype.leftShift = function leftShift(value) { + if (typeof value === 'number') return this.leftShiftS(value); + return this.leftShiftM(value); + }; - var swapped = false; - var a; - if (m < n) { - if (!autoTranspose) { - a = value.clone(); - // eslint-disable-next-line no-console - console.warn( - 'Computing SVD on a matrix with more columns than rows. Consider enabling autoTranspose' - ); - } else { - a = value.transpose(); - m = a.rows; - n = a.columns; - swapped = true; - var aux = wantu; - wantu = wantv; - wantv = aux; + AbstractMatrix.prototype.leftShiftS = function leftShiftS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) << value); } - } else { - a = value.clone(); } + return this; + }; - var nu = Math.min(m, n); - var ni = Math.min(m + 1, n); - var s = new Array(ni); - var U = getFilled2DArray(m, nu, 0); - var V = getFilled2DArray(n, n, 0); - - var e = new Array(n); - var work = new Array(m); + AbstractMatrix.prototype.leftShiftM = function leftShiftM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) << matrix.get(i, j)); + } + } + return this; + }; - var si = new Array(ni); - for (let i = 0; i < ni; i++) si[i] = i; + AbstractMatrix.leftShift = function leftShift(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.leftShift(value); + }; - var nct = Math.min(m - 1, n); - var nrt = Math.max(0, Math.min(n - 2, m)); - var mrc = Math.max(nct, nrt); + AbstractMatrix.prototype.signPropagatingRightShift = function signPropagatingRightShift(value) { + if (typeof value === 'number') return this.signPropagatingRightShiftS(value); + return this.signPropagatingRightShiftM(value); + }; - for (let k = 0; k < mrc; k++) { - if (k < nct) { - s[k] = 0; - for (let i = k; i < m; i++) { - s[k] = hypotenuse(s[k], a[i][k]); - } - if (s[k] !== 0) { - if (a[k][k] < 0) { - s[k] = -s[k]; - } - for (let i = k; i < m; i++) { - a[i][k] /= s[k]; - } - a[k][k] += 1; - } - s[k] = -s[k]; + AbstractMatrix.prototype.signPropagatingRightShiftS = function signPropagatingRightShiftS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) >> value); } + } + return this; + }; - for (let j = k + 1; j < n; j++) { - if (k < nct && s[k] !== 0) { - let t = 0; - for (let i = k; i < m; i++) { - t += a[i][k] * a[i][j]; - } - t = -t / a[k][k]; - for (let i = k; i < m; i++) { - a[i][j] += t * a[i][k]; - } - } - e[j] = a[k][j]; + AbstractMatrix.prototype.signPropagatingRightShiftM = function signPropagatingRightShiftM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) >> matrix.get(i, j)); } + } + return this; + }; - if (wantu && k < nct) { - for (let i = k; i < m; i++) { - U[i][k] = a[i][k]; - } - } + AbstractMatrix.signPropagatingRightShift = function signPropagatingRightShift(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.signPropagatingRightShift(value); + }; - if (k < nrt) { - e[k] = 0; - for (let i = k + 1; i < n; i++) { - e[k] = hypotenuse(e[k], e[i]); - } - if (e[k] !== 0) { - if (e[k + 1] < 0) { - e[k] = 0 - e[k]; - } - for (let i = k + 1; i < n; i++) { - e[i] /= e[k]; - } - e[k + 1] += 1; - } - e[k] = -e[k]; - if (k + 1 < m && e[k] !== 0) { - for (let i = k + 1; i < m; i++) { - work[i] = 0; - } - for (let i = k + 1; i < m; i++) { - for (let j = k + 1; j < n; j++) { - work[i] += e[j] * a[i][j]; - } - } - for (let j = k + 1; j < n; j++) { - let t = -e[j] / e[k + 1]; - for (let i = k + 1; i < m; i++) { - a[i][j] += t * work[i]; - } - } - } - if (wantv) { - for (let i = k + 1; i < n; i++) { - V[i][k] = e[i]; - } - } + AbstractMatrix.prototype.rightShift = function rightShift(value) { + if (typeof value === 'number') return this.rightShiftS(value); + return this.rightShiftM(value); + }; + + AbstractMatrix.prototype.rightShiftS = function rightShiftS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) >>> value); } } + return this; + }; - let p = Math.min(n, m + 1); - if (nct < n) { - s[nct] = a[nct][nct]; + AbstractMatrix.prototype.rightShiftM = function rightShiftM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); } - if (m < p) { - s[p - 1] = 0; + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) >>> matrix.get(i, j)); + } } - if (nrt + 1 < p) { - e[nrt] = a[nrt][p - 1]; + return this; + }; + + AbstractMatrix.rightShift = function rightShift(matrix, value) { + const newMatrix = new Matrix(matrix); + return newMatrix.rightShift(value); + }; + AbstractMatrix.prototype.zeroFillRightShift = AbstractMatrix.prototype.rightShift; + AbstractMatrix.prototype.zeroFillRightShiftS = AbstractMatrix.prototype.rightShiftS; + AbstractMatrix.prototype.zeroFillRightShiftM = AbstractMatrix.prototype.rightShiftM; + AbstractMatrix.zeroFillRightShift = AbstractMatrix.rightShift; + + AbstractMatrix.prototype.not = function not() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, ~(this.get(i, j))); + } } - e[p - 1] = 0; + return this; + }; - if (wantu) { - for (let j = nct; j < nu; j++) { - for (let i = 0; i < m; i++) { - U[i][j] = 0; - } - U[j][j] = 1; + AbstractMatrix.not = function not(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.not(); + }; + + AbstractMatrix.prototype.abs = function abs() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.abs(this.get(i, j))); } - for (let k = nct - 1; k >= 0; k--) { - if (s[k] !== 0) { - for (let j = k + 1; j < nu; j++) { - let t = 0; - for (let i = k; i < m; i++) { - t += U[i][k] * U[i][j]; - } - t = -t / U[k][k]; - for (let i = k; i < m; i++) { - U[i][j] += t * U[i][k]; - } - } - for (let i = k; i < m; i++) { - U[i][k] = -U[i][k]; - } - U[k][k] = 1 + U[k][k]; - for (let i = 0; i < k - 1; i++) { - U[i][k] = 0; - } - } else { - for (let i = 0; i < m; i++) { - U[i][k] = 0; - } - U[k][k] = 1; - } + } + return this; + }; + + AbstractMatrix.abs = function abs(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.abs(); + }; + + AbstractMatrix.prototype.acos = function acos() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.acos(this.get(i, j))); } } + return this; + }; - if (wantv) { - for (let k = n - 1; k >= 0; k--) { - if (k < nrt && e[k] !== 0) { - for (let j = k + 1; j < n; j++) { - let t = 0; - for (let i = k + 1; i < n; i++) { - t += V[i][k] * V[i][j]; - } - t = -t / V[k + 1][k]; - for (let i = k + 1; i < n; i++) { - V[i][j] += t * V[i][k]; - } - } - } - for (let i = 0; i < n; i++) { - V[i][k] = 0; - } - V[k][k] = 1; + AbstractMatrix.acos = function acos(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.acos(); + }; + + AbstractMatrix.prototype.acosh = function acosh() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.acosh(this.get(i, j))); } } + return this; + }; - var pp = p - 1; - var iter = 0; - var eps = Number.EPSILON; - while (p > 0) { - let k, kase; - for (k = p - 2; k >= -1; k--) { - if (k === -1) { - break; - } - const alpha = - Number.MIN_VALUE + eps * Math.abs(s[k] + Math.abs(s[k + 1])); - if (Math.abs(e[k]) <= alpha || Number.isNaN(e[k])) { - e[k] = 0; - break; - } + AbstractMatrix.acosh = function acosh(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.acosh(); + }; + + AbstractMatrix.prototype.asin = function asin() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.asin(this.get(i, j))); } - if (k === p - 2) { - kase = 4; - } else { - let ks; - for (ks = p - 1; ks >= k; ks--) { - if (ks === k) { - break; - } - let t = - (ks !== p ? Math.abs(e[ks]) : 0) + - (ks !== k + 1 ? Math.abs(e[ks - 1]) : 0); - if (Math.abs(s[ks]) <= eps * t) { - s[ks] = 0; - break; - } - } - if (ks === k) { - kase = 3; - } else if (ks === p - 1) { - kase = 1; - } else { - kase = 2; - k = ks; - } + } + return this; + }; + + AbstractMatrix.asin = function asin(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.asin(); + }; + + AbstractMatrix.prototype.asinh = function asinh() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.asinh(this.get(i, j))); } + } + return this; + }; - k++; + AbstractMatrix.asinh = function asinh(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.asinh(); + }; - switch (kase) { - case 1: { - let f = e[p - 2]; - e[p - 2] = 0; - for (let j = p - 2; j >= k; j--) { - let t = hypotenuse(s[j], f); - let cs = s[j] / t; - let sn = f / t; - s[j] = t; - if (j !== k) { - f = -sn * e[j - 1]; - e[j - 1] = cs * e[j - 1]; - } - if (wantv) { - for (let i = 0; i < n; i++) { - t = cs * V[i][j] + sn * V[i][p - 1]; - V[i][p - 1] = -sn * V[i][j] + cs * V[i][p - 1]; - V[i][j] = t; - } - } - } - break; - } - case 2: { - let f = e[k - 1]; - e[k - 1] = 0; - for (let j = k; j < p; j++) { - let t = hypotenuse(s[j], f); - let cs = s[j] / t; - let sn = f / t; - s[j] = t; - f = -sn * e[j]; - e[j] = cs * e[j]; - if (wantu) { - for (let i = 0; i < m; i++) { - t = cs * U[i][j] + sn * U[i][k - 1]; - U[i][k - 1] = -sn * U[i][j] + cs * U[i][k - 1]; - U[i][j] = t; - } - } - } - break; - } - case 3: { - const scale = Math.max( - Math.abs(s[p - 1]), - Math.abs(s[p - 2]), - Math.abs(e[p - 2]), - Math.abs(s[k]), - Math.abs(e[k]) - ); - const sp = s[p - 1] / scale; - const spm1 = s[p - 2] / scale; - const epm1 = e[p - 2] / scale; - const sk = s[k] / scale; - const ek = e[k] / scale; - const b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2; - const c = sp * epm1 * (sp * epm1); - let shift = 0; - if (b !== 0 || c !== 0) { - if (b < 0) { - shift = 0 - Math.sqrt(b * b + c); - } else { - shift = Math.sqrt(b * b + c); - } - shift = c / (b + shift); - } - let f = (sk + sp) * (sk - sp) + shift; - let g = sk * ek; - for (let j = k; j < p - 1; j++) { - let t = hypotenuse(f, g); - if (t === 0) t = Number.MIN_VALUE; - let cs = f / t; - let sn = g / t; - if (j !== k) { - e[j - 1] = t; - } - f = cs * s[j] + sn * e[j]; - e[j] = cs * e[j] - sn * s[j]; - g = sn * s[j + 1]; - s[j + 1] = cs * s[j + 1]; - if (wantv) { - for (let i = 0; i < n; i++) { - t = cs * V[i][j] + sn * V[i][j + 1]; - V[i][j + 1] = -sn * V[i][j] + cs * V[i][j + 1]; - V[i][j] = t; - } - } - t = hypotenuse(f, g); - if (t === 0) t = Number.MIN_VALUE; - cs = f / t; - sn = g / t; - s[j] = t; - f = cs * e[j] + sn * s[j + 1]; - s[j + 1] = -sn * e[j] + cs * s[j + 1]; - g = sn * e[j + 1]; - e[j + 1] = cs * e[j + 1]; - if (wantu && j < m - 1) { - for (let i = 0; i < m; i++) { - t = cs * U[i][j] + sn * U[i][j + 1]; - U[i][j + 1] = -sn * U[i][j] + cs * U[i][j + 1]; - U[i][j] = t; - } - } - } - e[p - 2] = f; - iter = iter + 1; - break; - } - case 4: { - if (s[k] <= 0) { - s[k] = s[k] < 0 ? -s[k] : 0; - if (wantv) { - for (let i = 0; i <= pp; i++) { - V[i][k] = -V[i][k]; - } - } - } - while (k < pp) { - if (s[k] >= s[k + 1]) { - break; - } - let t = s[k]; - s[k] = s[k + 1]; - s[k + 1] = t; - if (wantv && k < n - 1) { - for (let i = 0; i < n; i++) { - t = V[i][k + 1]; - V[i][k + 1] = V[i][k]; - V[i][k] = t; - } - } - if (wantu && k < m - 1) { - for (let i = 0; i < m; i++) { - t = U[i][k + 1]; - U[i][k + 1] = U[i][k]; - U[i][k] = t; - } - } - k++; - } - iter = 0; - p--; - break; - } - // no default + AbstractMatrix.prototype.atan = function atan() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.atan(this.get(i, j))); + } + } + return this; + }; + + AbstractMatrix.atan = function atan(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.atan(); + }; + + AbstractMatrix.prototype.atanh = function atanh() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.atanh(this.get(i, j))); } } + return this; + }; - if (swapped) { - var tmp = V; - V = U; - U = tmp; + AbstractMatrix.atanh = function atanh(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.atanh(); + }; + + AbstractMatrix.prototype.cbrt = function cbrt() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.cbrt(this.get(i, j))); + } } + return this; + }; - this.m = m; - this.n = n; - this.s = s; - this.U = U; - this.V = V; - } + AbstractMatrix.cbrt = function cbrt(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.cbrt(); + }; - /** - * Solve a problem of least square (Ax=b) by using the SVD. Useful when A is singular. When A is not singular, it would be better to use qr.solve(value). - * Example : We search to approximate x, with A matrix shape m*n, x vector size n, b vector size m (m > n). We will use : - * var svd = SingularValueDecomposition(A); - * var x = svd.solve(b); - * @param {Matrix} value - Matrix 1D which is the vector b (in the equation Ax = b) - * @return {Matrix} - The vector x - */ - solve(value) { - var Y = value; - var e = this.threshold; - var scols = this.s.length; - var Ls = matrix_Matrix.zeros(scols, scols); + AbstractMatrix.prototype.ceil = function ceil() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.ceil(this.get(i, j))); + } + } + return this; + }; - for (let i = 0; i < scols; i++) { - if (Math.abs(this.s[i]) <= e) { - Ls[i][i] = 0; - } else { - Ls[i][i] = 1 / this.s[i]; + AbstractMatrix.ceil = function ceil(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.ceil(); + }; + + AbstractMatrix.prototype.clz32 = function clz32() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.clz32(this.get(i, j))); } } + return this; + }; - var U = this.U; - var V = this.rightSingularVectors; + AbstractMatrix.clz32 = function clz32(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.clz32(); + }; - var VL = V.mmul(Ls); - var vrows = V.rows; - var urows = U.length; - var VLU = matrix_Matrix.zeros(vrows, urows); + AbstractMatrix.prototype.cos = function cos() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.cos(this.get(i, j))); + } + } + return this; + }; - for (let i = 0; i < vrows; i++) { - for (let j = 0; j < urows; j++) { - let sum = 0; - for (let k = 0; k < scols; k++) { - sum += VL[i][k] * U[j][k]; - } - VLU[i][j] = sum; + AbstractMatrix.cos = function cos(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.cos(); + }; + + AbstractMatrix.prototype.cosh = function cosh() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.cosh(this.get(i, j))); } } + return this; + }; - return VLU.mmul(Y); - } + AbstractMatrix.cosh = function cosh(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.cosh(); + }; - /** - * - * @param {Array} value - * @return {Matrix} - */ - solveForDiagonal(value) { - return this.solve(matrix_Matrix.diag(value)); - } + AbstractMatrix.prototype.exp = function exp() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.exp(this.get(i, j))); + } + } + return this; + }; - /** - * Get the inverse of the matrix. We compute the inverse of a matrix using SVD when this matrix is singular or ill-conditioned. Example : - * var svd = SingularValueDecomposition(A); - * var inverseA = svd.inverse(); - * @return {Matrix} - The approximation of the inverse of the matrix - */ - inverse() { - var V = this.V; - var e = this.threshold; - var vrows = V.length; - var vcols = V[0].length; - var X = new matrix_Matrix(vrows, this.s.length); + AbstractMatrix.exp = function exp(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.exp(); + }; - for (let i = 0; i < vrows; i++) { - for (let j = 0; j < vcols; j++) { - if (Math.abs(this.s[j]) > e) { - X[i][j] = V[i][j] / this.s[j]; - } else { - X[i][j] = 0; - } + AbstractMatrix.prototype.expm1 = function expm1() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.expm1(this.get(i, j))); } } + return this; + }; - var U = this.U; + AbstractMatrix.expm1 = function expm1(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.expm1(); + }; - var urows = U.length; - var ucols = U[0].length; - var Y = new matrix_Matrix(vrows, urows); + AbstractMatrix.prototype.floor = function floor() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.floor(this.get(i, j))); + } + } + return this; + }; - for (let i = 0; i < vrows; i++) { - for (let j = 0; j < urows; j++) { - let sum = 0; - for (let k = 0; k < ucols; k++) { - sum += X[i][k] * U[j][k]; - } - Y[i][j] = sum; + AbstractMatrix.floor = function floor(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.floor(); + }; + + AbstractMatrix.prototype.fround = function fround() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.fround(this.get(i, j))); } } + return this; + }; - return Y; - } + AbstractMatrix.fround = function fround(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.fround(); + }; - /** - * - * @return {number} - */ - get condition() { - return this.s[0] / this.s[Math.min(this.m, this.n) - 1]; - } + AbstractMatrix.prototype.log = function log() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.log(this.get(i, j))); + } + } + return this; + }; - /** - * - * @return {number} - */ - get norm2() { - return this.s[0]; - } + AbstractMatrix.log = function log(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.log(); + }; - /** - * - * @return {number} - */ - get rank() { - var tol = Math.max(this.m, this.n) * this.s[0] * Number.EPSILON; - var r = 0; - var s = this.s; - for (var i = 0, ii = s.length; i < ii; i++) { - if (s[i] > tol) { - r++; + AbstractMatrix.prototype.log1p = function log1p() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.log1p(this.get(i, j))); } } - return r; - } + return this; + }; - /** - * - * @return {Array} - */ - get diagonal() { - return this.s; - } + AbstractMatrix.log1p = function log1p(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.log1p(); + }; - /** - * - * @return {number} - */ - get threshold() { - return Number.EPSILON / 2 * Math.max(this.m, this.n) * this.s[0]; - } + AbstractMatrix.prototype.log10 = function log10() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.log10(this.get(i, j))); + } + } + return this; + }; - /** - * - * @return {Matrix} - */ - get leftSingularVectors() { - if (!matrix_Matrix.isMatrix(this.U)) { - this.U = new matrix_Matrix(this.U); + AbstractMatrix.log10 = function log10(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.log10(); + }; + + AbstractMatrix.prototype.log2 = function log2() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.log2(this.get(i, j))); + } } - return this.U; - } + return this; + }; - /** - * - * @return {Matrix} - */ - get rightSingularVectors() { - if (!matrix_Matrix.isMatrix(this.V)) { - this.V = new matrix_Matrix(this.V); + AbstractMatrix.log2 = function log2(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.log2(); + }; + + AbstractMatrix.prototype.round = function round() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.round(this.get(i, j))); + } } - return this.V; - } + return this; + }; - /** - * - * @return {Matrix} - */ - get diagonalMatrix() { - return matrix_Matrix.diag(this.s); - } -} + AbstractMatrix.round = function round(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.round(); + }; -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/util.js + AbstractMatrix.prototype.sign = function sign() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.sign(this.get(i, j))); + } + } + return this; + }; + + AbstractMatrix.sign = function sign(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.sign(); + }; + + AbstractMatrix.prototype.sin = function sin() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.sin(this.get(i, j))); + } + } + return this; + }; + + AbstractMatrix.sin = function sin(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.sin(); + }; + + AbstractMatrix.prototype.sinh = function sinh() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.sinh(this.get(i, j))); + } + } + return this; + }; + + AbstractMatrix.sinh = function sinh(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.sinh(); + }; + + AbstractMatrix.prototype.sqrt = function sqrt() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.sqrt(this.get(i, j))); + } + } + return this; + }; + + AbstractMatrix.sqrt = function sqrt(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.sqrt(); + }; + + AbstractMatrix.prototype.tan = function tan() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.tan(this.get(i, j))); + } + } + return this; + }; + + AbstractMatrix.tan = function tan(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.tan(); + }; + + AbstractMatrix.prototype.tanh = function tanh() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.tanh(this.get(i, j))); + } + } + return this; + }; + + AbstractMatrix.tanh = function tanh(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.tanh(); + }; + + AbstractMatrix.prototype.trunc = function trunc() { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.trunc(this.get(i, j))); + } + } + return this; + }; + + AbstractMatrix.trunc = function trunc(matrix) { + const newMatrix = new Matrix(matrix); + return newMatrix.trunc(); + }; + + AbstractMatrix.pow = function pow(matrix, arg0) { + const newMatrix = new Matrix(matrix); + return newMatrix.pow(arg0); + }; + + AbstractMatrix.prototype.pow = function pow(value) { + if (typeof value === 'number') return this.powS(value); + return this.powM(value); + }; + AbstractMatrix.prototype.powS = function powS(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.pow(this.get(i, j), value)); + } + } + return this; + }; + + AbstractMatrix.prototype.powM = function powM(matrix) { + matrix = Matrix.checkMatrix(matrix); + if (this.rows !== matrix.rows || + this.columns !== matrix.columns) { + throw new RangeError('Matrices dimensions must be equal'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, Math.pow(this.get(i, j), matrix.get(i, j))); + } + } + return this; + }; +} +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/util.js /** * @private * Check that a row index is not out of bounds @@ -3177,7 +3139,7 @@ class svd_SingularValueDecomposition { * @param {boolean} [outer] */ function checkRowIndex(matrix, index, outer) { - var max = outer ? matrix.rows : matrix.rows - 1; + let max = outer ? matrix.rows : matrix.rows - 1; if (index < 0 || index > max) { throw new RangeError('Row index out of range'); } @@ -3191,7 +3153,7 @@ function checkRowIndex(matrix, index, outer) { * @param {boolean} [outer] */ function checkColumnIndex(matrix, index, outer) { - var max = outer ? matrix.columns : matrix.columns - 1; + let max = outer ? matrix.columns : matrix.columns - 1; if (index < 0 || index > max) { throw new RangeError('Column index out of range'); } @@ -3211,7 +3173,7 @@ function checkRowVector(matrix, vector) { } if (vector.length !== matrix.columns) { throw new RangeError( - 'vector size must be the same as the number of columns' + 'vector size must be the same as the number of columns', ); } return vector; @@ -3238,7 +3200,7 @@ function checkColumnVector(matrix, vector) { function checkIndices(matrix, rowIndices, columnIndices) { return { row: checkRowIndices(matrix, rowIndices), - column: checkColumnIndices(matrix, columnIndices) + column: checkColumnIndices(matrix, columnIndices), }; } @@ -3247,7 +3209,7 @@ function checkRowIndices(matrix, rowIndices) { throw new TypeError('unexpected type for row indices'); } - var rowOut = rowIndices.some((r) => { + let rowOut = rowIndices.some((r) => { return r < 0 || r >= matrix.rows; }); @@ -3265,7 +3227,7 @@ function checkColumnIndices(matrix, columnIndices) { throw new TypeError('unexpected type for column indices'); } - var columnOut = columnIndices.some((c) => { + let columnOut = columnIndices.some((c) => { return c < 0 || c >= matrix.columns; }); @@ -3301,2243 +3263,1773 @@ function checkRange(matrix, startRow, endRow, startColumn, endColumn) { } } -function getRange(from, to) { - var arr = new Array(to - from + 1); - for (var i = 0; i < arr.length; i++) { - arr[i] = from + i; +function newArray(length, value = 0) { + let array = []; + for (let i = 0; i < length; i++) { + array.push(value); + } + return array; +} + +function checkNumber(name, value) { + if (typeof value !== 'number') { + throw new TypeError(`${name} must be a number`); + } +} + +function checkNonEmpty(matrix) { + if (matrix.isEmpty()) { + throw new Error('Empty matrix has no elements to index'); } - return arr; } +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/stat.js + + function sumByRow(matrix) { - var sum = matrix_Matrix.zeros(matrix.rows, 1); - for (var i = 0; i < matrix.rows; ++i) { - for (var j = 0; j < matrix.columns; ++j) { - sum.set(i, 0, sum.get(i, 0) + matrix.get(i, j)); + let sum = newArray(matrix.rows); + for (let i = 0; i < matrix.rows; ++i) { + for (let j = 0; j < matrix.columns; ++j) { + sum[i] += matrix.get(i, j); } } return sum; } function sumByColumn(matrix) { - var sum = matrix_Matrix.zeros(1, matrix.columns); - for (var i = 0; i < matrix.rows; ++i) { - for (var j = 0; j < matrix.columns; ++j) { - sum.set(0, j, sum.get(0, j) + matrix.get(i, j)); + let sum = newArray(matrix.columns); + for (let i = 0; i < matrix.rows; ++i) { + for (let j = 0; j < matrix.columns; ++j) { + sum[j] += matrix.get(i, j); } } return sum; } function sumAll(matrix) { - var v = 0; - for (var i = 0; i < matrix.rows; i++) { - for (var j = 0; j < matrix.columns; j++) { + let v = 0; + for (let i = 0; i < matrix.rows; i++) { + for (let j = 0; j < matrix.columns; j++) { v += matrix.get(i, j); } } return v; } -function checkNumber(name, value) { - if (typeof value !== 'number') { - throw new TypeError(`${name} must be a number`); - } -} - -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/base.js - - - -class base_BaseView extends AbstractMatrix() { - constructor(matrix, rows, columns) { - super(); - this.matrix = matrix; - this.rows = rows; - this.columns = columns; - } - - static get [Symbol.species]() { - return matrix_Matrix; +function productByRow(matrix) { + let sum = newArray(matrix.rows, 1); + for (let i = 0; i < matrix.rows; ++i) { + for (let j = 0; j < matrix.columns; ++j) { + sum[i] *= matrix.get(i, j); + } } + return sum; } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/transpose.js - - -class transpose_MatrixTransposeView extends base_BaseView { - constructor(matrix) { - super(matrix, matrix.columns, matrix.rows); - } - - set(rowIndex, columnIndex, value) { - this.matrix.set(columnIndex, rowIndex, value); - return this; - } - - get(rowIndex, columnIndex) { - return this.matrix.get(columnIndex, rowIndex); +function productByColumn(matrix) { + let sum = newArray(matrix.columns, 1); + for (let i = 0; i < matrix.rows; ++i) { + for (let j = 0; j < matrix.columns; ++j) { + sum[j] *= matrix.get(i, j); + } } + return sum; } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/row.js - - -class row_MatrixRowView extends base_BaseView { - constructor(matrix, row) { - super(matrix, 1, matrix.columns); - this.row = row; - } - - set(rowIndex, columnIndex, value) { - this.matrix.set(this.row, columnIndex, value); - return this; - } - - get(rowIndex, columnIndex) { - return this.matrix.get(this.row, columnIndex); +function productAll(matrix) { + let v = 1; + for (let i = 0; i < matrix.rows; i++) { + for (let j = 0; j < matrix.columns; j++) { + v *= matrix.get(i, j); + } } + return v; } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/sub.js - - - - -class sub_MatrixSubView extends base_BaseView { - constructor(matrix, startRow, endRow, startColumn, endColumn) { - checkRange(matrix, startRow, endRow, startColumn, endColumn); - super(matrix, endRow - startRow + 1, endColumn - startColumn + 1); - this.startRow = startRow; - this.startColumn = startColumn; - } - - set(rowIndex, columnIndex, value) { - this.matrix.set( - this.startRow + rowIndex, - this.startColumn + columnIndex, - value - ); - return this; +function varianceByRow(matrix, unbiased, mean) { + const rows = matrix.rows; + const cols = matrix.columns; + const variance = []; + + for (let i = 0; i < rows; i++) { + let sum1 = 0; + let sum2 = 0; + let x = 0; + for (let j = 0; j < cols; j++) { + x = matrix.get(i, j) - mean[i]; + sum1 += x; + sum2 += x * x; + } + if (unbiased) { + variance.push((sum2 - (sum1 * sum1) / cols) / (cols - 1)); + } else { + variance.push((sum2 - (sum1 * sum1) / cols) / cols); + } } + return variance; +} - get(rowIndex, columnIndex) { - return this.matrix.get( - this.startRow + rowIndex, - this.startColumn + columnIndex - ); +function varianceByColumn(matrix, unbiased, mean) { + const rows = matrix.rows; + const cols = matrix.columns; + const variance = []; + + for (let j = 0; j < cols; j++) { + let sum1 = 0; + let sum2 = 0; + let x = 0; + for (let i = 0; i < rows; i++) { + x = matrix.get(i, j) - mean[j]; + sum1 += x; + sum2 += x * x; + } + if (unbiased) { + variance.push((sum2 - (sum1 * sum1) / rows) / (rows - 1)); + } else { + variance.push((sum2 - (sum1 * sum1) / rows) / rows); + } } + return variance; } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/selection.js - - +function varianceAll(matrix, unbiased, mean) { + const rows = matrix.rows; + const cols = matrix.columns; + const size = rows * cols; - -class selection_MatrixSelectionView extends base_BaseView { - constructor(matrix, rowIndices, columnIndices) { - var indices = checkIndices(matrix, rowIndices, columnIndices); - super(matrix, indices.row.length, indices.column.length); - this.rowIndices = indices.row; - this.columnIndices = indices.column; + let sum1 = 0; + let sum2 = 0; + let x = 0; + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + x = matrix.get(i, j) - mean; + sum1 += x; + sum2 += x * x; + } + } + if (unbiased) { + return (sum2 - (sum1 * sum1) / size) / (size - 1); + } else { + return (sum2 - (sum1 * sum1) / size) / size; } +} - set(rowIndex, columnIndex, value) { - this.matrix.set( - this.rowIndices[rowIndex], - this.columnIndices[columnIndex], - value - ); - return this; +function centerByRow(matrix, mean) { + for (let i = 0; i < matrix.rows; i++) { + for (let j = 0; j < matrix.columns; j++) { + matrix.set(i, j, matrix.get(i, j) - mean[i]); + } } +} - get(rowIndex, columnIndex) { - return this.matrix.get( - this.rowIndices[rowIndex], - this.columnIndices[columnIndex] - ); +function centerByColumn(matrix, mean) { + for (let i = 0; i < matrix.rows; i++) { + for (let j = 0; j < matrix.columns; j++) { + matrix.set(i, j, matrix.get(i, j) - mean[j]); + } } } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/rowSelection.js +function centerAll(matrix, mean) { + for (let i = 0; i < matrix.rows; i++) { + for (let j = 0; j < matrix.columns; j++) { + matrix.set(i, j, matrix.get(i, j) - mean); + } + } +} +function getScaleByRow(matrix) { + const scale = []; + for (let i = 0; i < matrix.rows; i++) { + let sum = 0; + for (let j = 0; j < matrix.columns; j++) { + sum += Math.pow(matrix.get(i, j), 2) / (matrix.columns - 1); + } + scale.push(Math.sqrt(sum)); + } + return scale; +} +function scaleByRow(matrix, scale) { + for (let i = 0; i < matrix.rows; i++) { + for (let j = 0; j < matrix.columns; j++) { + matrix.set(i, j, matrix.get(i, j) / scale[i]); + } + } +} +function getScaleByColumn(matrix) { + const scale = []; + for (let j = 0; j < matrix.columns; j++) { + let sum = 0; + for (let i = 0; i < matrix.rows; i++) { + sum += Math.pow(matrix.get(i, j), 2) / (matrix.rows - 1); + } + scale.push(Math.sqrt(sum)); + } + return scale; +} -class rowSelection_MatrixRowSelectionView extends base_BaseView { - constructor(matrix, rowIndices) { - rowIndices = checkRowIndices(matrix, rowIndices); - super(matrix, rowIndices.length, matrix.columns); - this.rowIndices = rowIndices; +function scaleByColumn(matrix, scale) { + for (let i = 0; i < matrix.rows; i++) { + for (let j = 0; j < matrix.columns; j++) { + matrix.set(i, j, matrix.get(i, j) / scale[j]); + } } +} - set(rowIndex, columnIndex, value) { - this.matrix.set(this.rowIndices[rowIndex], columnIndex, value); - return this; +function getScaleAll(matrix) { + const divider = matrix.size - 1; + let sum = 0; + for (let j = 0; j < matrix.columns; j++) { + for (let i = 0; i < matrix.rows; i++) { + sum += Math.pow(matrix.get(i, j), 2) / divider; + } } + return Math.sqrt(sum); +} - get(rowIndex, columnIndex) { - return this.matrix.get(this.rowIndices[rowIndex], columnIndex); +function scaleAll(matrix, scale) { + for (let i = 0; i < matrix.rows; i++) { + for (let j = 0; j < matrix.columns; j++) { + matrix.set(i, j, matrix.get(i, j) / scale); + } } } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/columnSelection.js +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/matrix.js -class columnSelection_MatrixColumnSelectionView extends base_BaseView { - constructor(matrix, columnIndices) { - columnIndices = checkColumnIndices(matrix, columnIndices); - super(matrix, matrix.rows, columnIndices.length); - this.columnIndices = columnIndices; - } - set(rowIndex, columnIndex, value) { - this.matrix.set(rowIndex, this.columnIndices[columnIndex], value); - return this; - } - get(rowIndex, columnIndex) { - return this.matrix.get(rowIndex, this.columnIndices[columnIndex]); + +class matrix_AbstractMatrix { + static from1DArray(newRows, newColumns, newData) { + let length = newRows * newColumns; + if (length !== newData.length) { + throw new RangeError('data length does not match given dimensions'); + } + let newMatrix = new matrix_Matrix(newRows, newColumns); + for (let row = 0; row < newRows; row++) { + for (let column = 0; column < newColumns; column++) { + newMatrix.set(row, column, newData[row * newColumns + column]); + } + } + return newMatrix; } -} -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/column.js + static rowVector(newData) { + let vector = new matrix_Matrix(1, newData.length); + for (let i = 0; i < newData.length; i++) { + vector.set(0, i, newData[i]); + } + return vector; + } + static columnVector(newData) { + let vector = new matrix_Matrix(newData.length, 1); + for (let i = 0; i < newData.length; i++) { + vector.set(i, 0, newData[i]); + } + return vector; + } -class column_MatrixColumnView extends base_BaseView { - constructor(matrix, column) { - super(matrix, matrix.rows, 1); - this.column = column; + static zeros(rows, columns) { + return new matrix_Matrix(rows, columns); } - set(rowIndex, columnIndex, value) { - this.matrix.set(rowIndex, this.column, value); - return this; + static ones(rows, columns) { + return new matrix_Matrix(rows, columns).fill(1); } - get(rowIndex) { - return this.matrix.get(rowIndex, this.column); + static rand(rows, columns, options = {}) { + if (typeof options !== 'object') { + throw new TypeError('options must be an object'); + } + const { random = Math.random } = options; + let matrix = new matrix_Matrix(rows, columns); + for (let i = 0; i < rows; i++) { + for (let j = 0; j < columns; j++) { + matrix.set(i, j, random()); + } + } + return matrix; } -} -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/flipRow.js + static randInt(rows, columns, options = {}) { + if (typeof options !== 'object') { + throw new TypeError('options must be an object'); + } + const { min = 0, max = 1000, random = Math.random } = options; + if (!Number.isInteger(min)) throw new TypeError('min must be an integer'); + if (!Number.isInteger(max)) throw new TypeError('max must be an integer'); + if (min >= max) throw new RangeError('min must be smaller than max'); + let interval = max - min; + let matrix = new matrix_Matrix(rows, columns); + for (let i = 0; i < rows; i++) { + for (let j = 0; j < columns; j++) { + let value = min + Math.round(random() * interval); + matrix.set(i, j, value); + } + } + return matrix; + } + static eye(rows, columns, value) { + if (columns === undefined) columns = rows; + if (value === undefined) value = 1; + let min = Math.min(rows, columns); + let matrix = this.zeros(rows, columns); + for (let i = 0; i < min; i++) { + matrix.set(i, i, value); + } + return matrix; + } -class flipRow_MatrixFlipRowView extends base_BaseView { - constructor(matrix) { - super(matrix, matrix.rows, matrix.columns); + static diag(data, rows, columns) { + let l = data.length; + if (rows === undefined) rows = l; + if (columns === undefined) columns = rows; + let min = Math.min(l, rows, columns); + let matrix = this.zeros(rows, columns); + for (let i = 0; i < min; i++) { + matrix.set(i, i, data[i]); + } + return matrix; } - set(rowIndex, columnIndex, value) { - this.matrix.set(this.rows - rowIndex - 1, columnIndex, value); - return this; + static min(matrix1, matrix2) { + matrix1 = this.checkMatrix(matrix1); + matrix2 = this.checkMatrix(matrix2); + let rows = matrix1.rows; + let columns = matrix1.columns; + let result = new matrix_Matrix(rows, columns); + for (let i = 0; i < rows; i++) { + for (let j = 0; j < columns; j++) { + result.set(i, j, Math.min(matrix1.get(i, j), matrix2.get(i, j))); + } + } + return result; } - get(rowIndex, columnIndex) { - return this.matrix.get(this.rows - rowIndex - 1, columnIndex); + static max(matrix1, matrix2) { + matrix1 = this.checkMatrix(matrix1); + matrix2 = this.checkMatrix(matrix2); + let rows = matrix1.rows; + let columns = matrix1.columns; + let result = new this(rows, columns); + for (let i = 0; i < rows; i++) { + for (let j = 0; j < columns; j++) { + result.set(i, j, Math.max(matrix1.get(i, j), matrix2.get(i, j))); + } + } + return result; } -} -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/views/flipColumn.js + static checkMatrix(value) { + return matrix_AbstractMatrix.isMatrix(value) ? value : new matrix_Matrix(value); + } + static isMatrix(value) { + return value != null && value.klass === 'Matrix'; + } -class flipColumn_MatrixFlipColumnView extends base_BaseView { - constructor(matrix) { - super(matrix, matrix.rows, matrix.columns); + get size() { + return this.rows * this.columns; } - set(rowIndex, columnIndex, value) { - this.matrix.set(rowIndex, this.columns - columnIndex - 1, value); + apply(callback) { + if (typeof callback !== 'function') { + throw new TypeError('callback must be a function'); + } + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + callback.call(this, i, j); + } + } return this; } - get(rowIndex, columnIndex) { - return this.matrix.get(rowIndex, this.columns - columnIndex - 1); + to1DArray() { + let array = []; + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + array.push(this.get(i, j)); + } + } + return array; } -} - -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/abstractMatrix.js - - + to2DArray() { + let copy = []; + for (let i = 0; i < this.rows; i++) { + copy.push([]); + for (let j = 0; j < this.columns; j++) { + copy[i].push(this.get(i, j)); + } + } + return copy; + } + toJSON() { + return this.to2DArray(); + } + isRowVector() { + return this.rows === 1; + } + isColumnVector() { + return this.columns === 1; + } + isVector() { + return this.rows === 1 || this.columns === 1; + } + isSquare() { + return this.rows === this.columns; + } + isEmpty() { + return this.rows === 0 || this.columns === 0; + } + isSymmetric() { + if (this.isSquare()) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j <= i; j++) { + if (this.get(i, j) !== this.get(j, i)) { + return false; + } + } + } + return true; + } + return false; + } + isEchelonForm() { + let i = 0; + let j = 0; + let previousColumn = -1; + let isEchelonForm = true; + let checked = false; + while (i < this.rows && isEchelonForm) { + j = 0; + checked = false; + while (j < this.columns && checked === false) { + if (this.get(i, j) === 0) { + j++; + } else if (this.get(i, j) === 1 && j > previousColumn) { + checked = true; + previousColumn = j; + } else { + isEchelonForm = false; + checked = true; + } + } + i++; + } + return isEchelonForm; + } + + isReducedEchelonForm() { + let i = 0; + let j = 0; + let previousColumn = -1; + let isReducedEchelonForm = true; + let checked = false; + while (i < this.rows && isReducedEchelonForm) { + j = 0; + checked = false; + while (j < this.columns && checked === false) { + if (this.get(i, j) === 0) { + j++; + } else if (this.get(i, j) === 1 && j > previousColumn) { + checked = true; + previousColumn = j; + } else { + isReducedEchelonForm = false; + checked = true; + } + } + for (let k = j + 1; k < this.rows; k++) { + if (this.get(i, k) !== 0) { + isReducedEchelonForm = false; + } + } + i++; + } + return isReducedEchelonForm; + } + echelonForm() { + let result = this.clone(); + let h = 0; + let k = 0; + while (h < result.rows && k < result.columns) { + let iMax = h; + for (let i = h; i < result.rows; i++) { + if (result.get(i, k) > result.get(iMax, k)) { + iMax = i; + } + } + if (result.get(iMax, k) === 0) { + k++; + } else { + result.swapRows(h, iMax); + let tmp = result.get(h, k); + for (let j = k; j < result.columns; j++) { + result.set(h, j, result.get(h, j) / tmp); + } + for (let i = h + 1; i < result.rows; i++) { + let factor = result.get(i, k) / result.get(h, k); + result.set(i, k, 0); + for (let j = k + 1; j < result.columns; j++) { + result.set(i, j, result.get(i, j) - result.get(h, j) * factor); + } + } + h++; + k++; + } + } + return result; + } + reducedEchelonForm() { + let result = this.echelonForm(); + let m = result.columns; + let n = result.rows; + let h = n - 1; + while (h >= 0) { + if (result.maxRow(h) === 0) { + h--; + } else { + let p = 0; + let pivot = false; + while (p < n && pivot === false) { + if (result.get(h, p) === 1) { + pivot = true; + } else { + p++; + } + } + for (let i = 0; i < h; i++) { + let factor = result.get(i, p); + for (let j = p; j < m; j++) { + let tmp = result.get(i, j) - factor * result.get(h, j); + result.set(i, j, tmp); + } + } + h--; + } + } + return result; + } + set() { + throw new Error('set method is unimplemented'); + } -function AbstractMatrix(superCtor) { - if (superCtor === undefined) superCtor = Object; + get() { + throw new Error('get method is unimplemented'); + } - /** - * Real matrix - * @class Matrix - * @param {number|Array|Matrix} nRows - Number of rows of the new matrix, - * 2D array containing the data or Matrix instance to clone - * @param {number} [nColumns] - Number of columns of the new matrix - */ - class Matrix extends superCtor { - static get [Symbol.species]() { - return this; + repeat(options = {}) { + if (typeof options !== 'object') { + throw new TypeError('options must be an object'); } - - /** - * Constructs a Matrix with the chosen dimensions from a 1D array - * @param {number} newRows - Number of rows - * @param {number} newColumns - Number of columns - * @param {Array} newData - A 1D array containing data for the matrix - * @return {Matrix} - The new matrix - */ - static from1DArray(newRows, newColumns, newData) { - var length = newRows * newColumns; - if (length !== newData.length) { - throw new RangeError('Data length does not match given dimensions'); - } - var newMatrix = new this(newRows, newColumns); - for (var row = 0; row < newRows; row++) { - for (var column = 0; column < newColumns; column++) { - newMatrix.set(row, column, newData[row * newColumns + column]); - } - } - return newMatrix; - } - - /** - * Creates a row vector, a matrix with only one row. - * @param {Array} newData - A 1D array containing data for the vector - * @return {Matrix} - The new matrix - */ - static rowVector(newData) { - var vector = new this(1, newData.length); - for (var i = 0; i < newData.length; i++) { - vector.set(0, i, newData[i]); - } - return vector; - } - - /** - * Creates a column vector, a matrix with only one column. - * @param {Array} newData - A 1D array containing data for the vector - * @return {Matrix} - The new matrix - */ - static columnVector(newData) { - var vector = new this(newData.length, 1); - for (var i = 0; i < newData.length; i++) { - vector.set(i, 0, newData[i]); - } - return vector; - } - - /** - * Creates an empty matrix with the given dimensions. Values will be undefined. Same as using new Matrix(rows, columns). - * @param {number} rows - Number of rows - * @param {number} columns - Number of columns - * @return {Matrix} - The new matrix - */ - static empty(rows, columns) { - return new this(rows, columns); - } - - /** - * Creates a matrix with the given dimensions. Values will be set to zero. - * @param {number} rows - Number of rows - * @param {number} columns - Number of columns - * @return {Matrix} - The new matrix - */ - static zeros(rows, columns) { - return this.empty(rows, columns).fill(0); - } - - /** - * Creates a matrix with the given dimensions. Values will be set to one. - * @param {number} rows - Number of rows - * @param {number} columns - Number of columns - * @return {Matrix} - The new matrix - */ - static ones(rows, columns) { - return this.empty(rows, columns).fill(1); - } - - /** - * Creates a matrix with the given dimensions. Values will be randomly set. - * @param {number} rows - Number of rows - * @param {number} columns - Number of columns - * @param {function} [rng=Math.random] - Random number generator - * @return {Matrix} The new matrix - */ - static rand(rows, columns, rng) { - if (rng === undefined) rng = Math.random; - var matrix = this.empty(rows, columns); - for (var i = 0; i < rows; i++) { - for (var j = 0; j < columns; j++) { - matrix.set(i, j, rng()); - } - } - return matrix; - } - - /** - * Creates a matrix with the given dimensions. Values will be random integers. - * @param {number} rows - Number of rows - * @param {number} columns - Number of columns - * @param {number} [maxValue=1000] - Maximum value - * @param {function} [rng=Math.random] - Random number generator - * @return {Matrix} The new matrix - */ - static randInt(rows, columns, maxValue, rng) { - if (maxValue === undefined) maxValue = 1000; - if (rng === undefined) rng = Math.random; - var matrix = this.empty(rows, columns); - for (var i = 0; i < rows; i++) { - for (var j = 0; j < columns; j++) { - var value = Math.floor(rng() * maxValue); - matrix.set(i, j, value); - } - } - return matrix; - } - - /** - * Creates an identity matrix with the given dimension. Values of the diagonal will be 1 and others will be 0. - * @param {number} rows - Number of rows - * @param {number} [columns=rows] - Number of columns - * @param {number} [value=1] - Value to fill the diagonal with - * @return {Matrix} - The new identity matrix - */ - static eye(rows, columns, value) { - if (columns === undefined) columns = rows; - if (value === undefined) value = 1; - var min = Math.min(rows, columns); - var matrix = this.zeros(rows, columns); - for (var i = 0; i < min; i++) { - matrix.set(i, i, value); - } - return matrix; - } - - /** - * Creates a diagonal matrix based on the given array. - * @param {Array} data - Array containing the data for the diagonal - * @param {number} [rows] - Number of rows (Default: data.length) - * @param {number} [columns] - Number of columns (Default: rows) - * @return {Matrix} - The new diagonal matrix - */ - static diag(data, rows, columns) { - var l = data.length; - if (rows === undefined) rows = l; - if (columns === undefined) columns = rows; - var min = Math.min(l, rows, columns); - var matrix = this.zeros(rows, columns); - for (var i = 0; i < min; i++) { - matrix.set(i, i, data[i]); - } - return matrix; - } - - /** - * Returns a matrix whose elements are the minimum between matrix1 and matrix2 - * @param {Matrix} matrix1 - * @param {Matrix} matrix2 - * @return {Matrix} - */ - static min(matrix1, matrix2) { - matrix1 = this.checkMatrix(matrix1); - matrix2 = this.checkMatrix(matrix2); - var rows = matrix1.rows; - var columns = matrix1.columns; - var result = new this(rows, columns); - for (var i = 0; i < rows; i++) { - for (var j = 0; j < columns; j++) { - result.set(i, j, Math.min(matrix1.get(i, j), matrix2.get(i, j))); - } - } - return result; - } - - /** - * Returns a matrix whose elements are the maximum between matrix1 and matrix2 - * @param {Matrix} matrix1 - * @param {Matrix} matrix2 - * @return {Matrix} - */ - static max(matrix1, matrix2) { - matrix1 = this.checkMatrix(matrix1); - matrix2 = this.checkMatrix(matrix2); - var rows = matrix1.rows; - var columns = matrix1.columns; - var result = new this(rows, columns); - for (var i = 0; i < rows; i++) { - for (var j = 0; j < columns; j++) { - result.set(i, j, Math.max(matrix1.get(i, j), matrix2.get(i, j))); - } - } - return result; - } - - /** - * Check that the provided value is a Matrix and tries to instantiate one if not - * @param {*} value - The value to check - * @return {Matrix} - */ - static checkMatrix(value) { - return Matrix.isMatrix(value) ? value : new this(value); - } - - /** - * Returns true if the argument is a Matrix, false otherwise - * @param {*} value - The value to check - * @return {boolean} - */ - static isMatrix(value) { - return (value != null) && (value.klass === 'Matrix'); - } - - /** - * @prop {number} size - The number of elements in the matrix. - */ - get size() { - return this.rows * this.columns; - } - - /** - * Applies a callback for each element of the matrix. The function is called in the matrix (this) context. - * @param {function} callback - Function that will be called with two parameters : i (row) and j (column) - * @return {Matrix} this - */ - apply(callback) { - if (typeof callback !== 'function') { - throw new TypeError('callback must be a function'); - } - var ii = this.rows; - var jj = this.columns; - for (var i = 0; i < ii; i++) { - for (var j = 0; j < jj; j++) { - callback.call(this, i, j); - } + const { rows = 1, columns = 1 } = options; + if (!Number.isInteger(rows) || rows <= 0) { + throw new TypeError('rows must be a positive integer'); + } + if (!Number.isInteger(columns) || columns <= 0) { + throw new TypeError('columns must be a positive integer'); + } + let matrix = new matrix_Matrix(this.rows * rows, this.columns * columns); + for (let i = 0; i < rows; i++) { + for (let j = 0; j < columns; j++) { + matrix.setSubMatrix(this, this.rows * i, this.columns * j); } - return this; } + return matrix; + } - /** - * Returns a new 1D array filled row by row with the matrix values - * @return {Array} - */ - to1DArray() { - var array = new Array(this.size); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - array[i * this.columns + j] = this.get(i, j); - } + fill(value) { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, value); } - return array; } + return this; + } - /** - * Returns a 2D array containing a copy of the data - * @return {Array} - */ - to2DArray() { - var copy = new Array(this.rows); - for (var i = 0; i < this.rows; i++) { - copy[i] = new Array(this.columns); - for (var j = 0; j < this.columns; j++) { - copy[i][j] = this.get(i, j); - } - } - return copy; + neg() { + return this.mulS(-1); + } + + getRow(index) { + checkRowIndex(this, index); + let row = []; + for (let i = 0; i < this.columns; i++) { + row.push(this.get(index, i)); } + return row; + } + + getRowVector(index) { + return matrix_Matrix.rowVector(this.getRow(index)); + } - /** - * @return {boolean} true if the matrix has one row - */ - isRowVector() { - return this.rows === 1; + setRow(index, array) { + checkRowIndex(this, index); + array = checkRowVector(this, array); + for (let i = 0; i < this.columns; i++) { + this.set(index, i, array[i]); } + return this; + } - /** - * @return {boolean} true if the matrix has one column - */ - isColumnVector() { - return this.columns === 1; + swapRows(row1, row2) { + checkRowIndex(this, row1); + checkRowIndex(this, row2); + for (let i = 0; i < this.columns; i++) { + let temp = this.get(row1, i); + this.set(row1, i, this.get(row2, i)); + this.set(row2, i, temp); } + return this; + } - /** - * @return {boolean} true if the matrix has one row or one column - */ - isVector() { - return (this.rows === 1) || (this.columns === 1); + getColumn(index) { + checkColumnIndex(this, index); + let column = []; + for (let i = 0; i < this.rows; i++) { + column.push(this.get(i, index)); } + return column; + } - /** - * @return {boolean} true if the matrix has the same number of rows and columns - */ - isSquare() { - return this.rows === this.columns; + getColumnVector(index) { + return matrix_Matrix.columnVector(this.getColumn(index)); + } + + setColumn(index, array) { + checkColumnIndex(this, index); + array = checkColumnVector(this, array); + for (let i = 0; i < this.rows; i++) { + this.set(i, index, array[i]); } + return this; + } - /** - * @return {boolean} true if the matrix is square and has the same values on both sides of the diagonal - */ - isSymmetric() { - if (this.isSquare()) { - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j <= i; j++) { - if (this.get(i, j) !== this.get(j, i)) { - return false; - } - } - } - return true; - } - return false; - } - - /** - * Sets a given element of the matrix. mat.set(3,4,1) is equivalent to mat[3][4]=1 - * @abstract - * @param {number} rowIndex - Index of the row - * @param {number} columnIndex - Index of the column - * @param {number} value - The new value for the element - * @return {Matrix} this - */ - set(rowIndex, columnIndex, value) { // eslint-disable-line no-unused-vars - throw new Error('set method is unimplemented'); - } - - /** - * Returns the given element of the matrix. mat.get(3,4) is equivalent to matrix[3][4] - * @abstract - * @param {number} rowIndex - Index of the row - * @param {number} columnIndex - Index of the column - * @return {number} - */ - get(rowIndex, columnIndex) { // eslint-disable-line no-unused-vars - throw new Error('get method is unimplemented'); - } - - /** - * Creates a new matrix that is a repetition of the current matrix. New matrix has rowRep times the number of - * rows of the matrix, and colRep times the number of columns of the matrix - * @param {number} rowRep - Number of times the rows should be repeated - * @param {number} colRep - Number of times the columns should be re - * @return {Matrix} - * @example - * var matrix = new Matrix([[1,2]]); - * matrix.repeat(2); // [[1,2],[1,2]] - */ - repeat(rowRep, colRep) { - rowRep = rowRep || 1; - colRep = colRep || 1; - var matrix = new this.constructor[Symbol.species](this.rows * rowRep, this.columns * colRep); - for (var i = 0; i < rowRep; i++) { - for (var j = 0; j < colRep; j++) { - matrix.setSubMatrix(this, this.rows * i, this.columns * j); - } - } - return matrix; - } - - /** - * Fills the matrix with a given value. All elements will be set to this value. - * @param {number} value - New value - * @return {Matrix} this - */ - fill(value) { - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, value); - } - } - return this; + swapColumns(column1, column2) { + checkColumnIndex(this, column1); + checkColumnIndex(this, column2); + for (let i = 0; i < this.rows; i++) { + let temp = this.get(i, column1); + this.set(i, column1, this.get(i, column2)); + this.set(i, column2, temp); } + return this; + } - /** - * Negates the matrix. All elements will be multiplied by (-1) - * @return {Matrix} this - */ - neg() { - return this.mulS(-1); - } - - /** - * Returns a new array from the given row index - * @param {number} index - Row index - * @return {Array} - */ - getRow(index) { - checkRowIndex(this, index); - var row = new Array(this.columns); - for (var i = 0; i < this.columns; i++) { - row[i] = this.get(index, i); - } - return row; - } - - /** - * Returns a new row vector from the given row index - * @param {number} index - Row index - * @return {Matrix} - */ - getRowVector(index) { - return this.constructor.rowVector(this.getRow(index)); - } - - /** - * Sets a row at the given index - * @param {number} index - Row index - * @param {Array|Matrix} array - Array or vector - * @return {Matrix} this - */ - setRow(index, array) { - checkRowIndex(this, index); - array = checkRowVector(this, array); - for (var i = 0; i < this.columns; i++) { - this.set(index, i, array[i]); + addRowVector(vector) { + vector = checkRowVector(this, vector); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) + vector[j]); } - return this; } + return this; + } - /** - * Swaps two rows - * @param {number} row1 - First row index - * @param {number} row2 - Second row index - * @return {Matrix} this - */ - swapRows(row1, row2) { - checkRowIndex(this, row1); - checkRowIndex(this, row2); - for (var i = 0; i < this.columns; i++) { - var temp = this.get(row1, i); - this.set(row1, i, this.get(row2, i)); - this.set(row2, i, temp); + subRowVector(vector) { + vector = checkRowVector(this, vector); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) - vector[j]); } - return this; } + return this; + } - /** - * Returns a new array from the given column index - * @param {number} index - Column index - * @return {Array} - */ - getColumn(index) { - checkColumnIndex(this, index); - var column = new Array(this.rows); - for (var i = 0; i < this.rows; i++) { - column[i] = this.get(i, index); - } - return column; - } - - /** - * Returns a new column vector from the given column index - * @param {number} index - Column index - * @return {Matrix} - */ - getColumnVector(index) { - return this.constructor.columnVector(this.getColumn(index)); - } - - /** - * Sets a column at the given index - * @param {number} index - Column index - * @param {Array|Matrix} array - Array or vector - * @return {Matrix} this - */ - setColumn(index, array) { - checkColumnIndex(this, index); - array = checkColumnVector(this, array); - for (var i = 0; i < this.rows; i++) { - this.set(i, index, array[i]); + mulRowVector(vector) { + vector = checkRowVector(this, vector); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) * vector[j]); } - return this; } + return this; + } - /** - * Swaps two columns - * @param {number} column1 - First column index - * @param {number} column2 - Second column index - * @return {Matrix} this - */ - swapColumns(column1, column2) { - checkColumnIndex(this, column1); - checkColumnIndex(this, column2); - for (var i = 0; i < this.rows; i++) { - var temp = this.get(i, column1); - this.set(i, column1, this.get(i, column2)); - this.set(i, column2, temp); + divRowVector(vector) { + vector = checkRowVector(this, vector); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) / vector[j]); } - return this; } + return this; + } - /** - * Adds the values of a vector to each row - * @param {Array|Matrix} vector - Array or vector - * @return {Matrix} this - */ - addRowVector(vector) { - vector = checkRowVector(this, vector); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) + vector[j]); - } + addColumnVector(vector) { + vector = checkColumnVector(this, vector); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) + vector[i]); } - return this; } + return this; + } - /** - * Subtracts the values of a vector from each row - * @param {Array|Matrix} vector - Array or vector - * @return {Matrix} this - */ - subRowVector(vector) { - vector = checkRowVector(this, vector); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) - vector[j]); - } + subColumnVector(vector) { + vector = checkColumnVector(this, vector); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) - vector[i]); } - return this; } + return this; + } - /** - * Multiplies the values of a vector with each row - * @param {Array|Matrix} vector - Array or vector - * @return {Matrix} this - */ - mulRowVector(vector) { - vector = checkRowVector(this, vector); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) * vector[j]); - } + mulColumnVector(vector) { + vector = checkColumnVector(this, vector); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) * vector[i]); } - return this; } + return this; + } - /** - * Divides the values of each row by those of a vector - * @param {Array|Matrix} vector - Array or vector - * @return {Matrix} this - */ - divRowVector(vector) { - vector = checkRowVector(this, vector); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) / vector[j]); - } + divColumnVector(vector) { + vector = checkColumnVector(this, vector); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + this.set(i, j, this.get(i, j) / vector[i]); } - return this; } + return this; + } + + mulRow(index, value) { + checkRowIndex(this, index); + for (let i = 0; i < this.columns; i++) { + this.set(index, i, this.get(index, i) * value); + } + return this; + } + + mulColumn(index, value) { + checkColumnIndex(this, index); + for (let i = 0; i < this.rows; i++) { + this.set(i, index, this.get(i, index) * value); + } + return this; + } - /** - * Adds the values of a vector to each column - * @param {Array|Matrix} vector - Array or vector - * @return {Matrix} this - */ - addColumnVector(vector) { - vector = checkColumnVector(this, vector); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) + vector[i]); + max() { + if (this.isEmpty()) { + return NaN; + } + let v = this.get(0, 0); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + if (this.get(i, j) > v) { + v = this.get(i, j); } } - return this; } + return v; + } - /** - * Subtracts the values of a vector from each column - * @param {Array|Matrix} vector - Array or vector - * @return {Matrix} this - */ - subColumnVector(vector) { - vector = checkColumnVector(this, vector); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) - vector[i]); + maxIndex() { + checkNonEmpty(this); + let v = this.get(0, 0); + let idx = [0, 0]; + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + if (this.get(i, j) > v) { + v = this.get(i, j); + idx[0] = i; + idx[1] = j; } } - return this; } + return idx; + } - /** - * Multiplies the values of a vector with each column - * @param {Array|Matrix} vector - Array or vector - * @return {Matrix} this - */ - mulColumnVector(vector) { - vector = checkColumnVector(this, vector); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) * vector[i]); + min() { + if (this.isEmpty()) { + return NaN; + } + let v = this.get(0, 0); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + if (this.get(i, j) < v) { + v = this.get(i, j); } } - return this; } + return v; + } - /** - * Divides the values of each column by those of a vector - * @param {Array|Matrix} vector - Array or vector - * @return {Matrix} this - */ - divColumnVector(vector) { - vector = checkColumnVector(this, vector); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) / vector[i]); + minIndex() { + checkNonEmpty(this); + let v = this.get(0, 0); + let idx = [0, 0]; + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + if (this.get(i, j) < v) { + v = this.get(i, j); + idx[0] = i; + idx[1] = j; } } - return this; } + return idx; + } - /** - * Multiplies the values of a row with a scalar - * @param {number} index - Row index - * @param {number} value - * @return {Matrix} this - */ - mulRow(index, value) { - checkRowIndex(this, index); - for (var i = 0; i < this.columns; i++) { - this.set(index, i, this.get(index, i) * value); + maxRow(row) { + checkRowIndex(this, row); + if (this.isEmpty()) { + return NaN; + } + let v = this.get(row, 0); + for (let i = 1; i < this.columns; i++) { + if (this.get(row, i) > v) { + v = this.get(row, i); } - return this; } + return v; + } - /** - * Multiplies the values of a column with a scalar - * @param {number} index - Column index - * @param {number} value - * @return {Matrix} this - */ - mulColumn(index, value) { - checkColumnIndex(this, index); - for (var i = 0; i < this.rows; i++) { - this.set(i, index, this.get(i, index) * value); + maxRowIndex(row) { + checkRowIndex(this, row); + checkNonEmpty(this); + let v = this.get(row, 0); + let idx = [row, 0]; + for (let i = 1; i < this.columns; i++) { + if (this.get(row, i) > v) { + v = this.get(row, i); + idx[1] = i; } - return this; } + return idx; + } - /** - * Returns the maximum value of the matrix - * @return {number} - */ - max() { - var v = this.get(0, 0); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - if (this.get(i, j) > v) { - v = this.get(i, j); - } - } + minRow(row) { + checkRowIndex(this, row); + if (this.isEmpty()) { + return NaN; + } + let v = this.get(row, 0); + for (let i = 1; i < this.columns; i++) { + if (this.get(row, i) < v) { + v = this.get(row, i); } - return v; } + return v; + } - /** - * Returns the index of the maximum value - * @return {Array} - */ - maxIndex() { - var v = this.get(0, 0); - var idx = [0, 0]; - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - if (this.get(i, j) > v) { - v = this.get(i, j); - idx[0] = i; - idx[1] = j; - } - } + minRowIndex(row) { + checkRowIndex(this, row); + checkNonEmpty(this); + let v = this.get(row, 0); + let idx = [row, 0]; + for (let i = 1; i < this.columns; i++) { + if (this.get(row, i) < v) { + v = this.get(row, i); + idx[1] = i; } - return idx; } + return idx; + } - /** - * Returns the minimum value of the matrix - * @return {number} - */ - min() { - var v = this.get(0, 0); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - if (this.get(i, j) < v) { - v = this.get(i, j); - } - } + maxColumn(column) { + checkColumnIndex(this, column); + if (this.isEmpty()) { + return NaN; + } + let v = this.get(0, column); + for (let i = 1; i < this.rows; i++) { + if (this.get(i, column) > v) { + v = this.get(i, column); } - return v; } + return v; + } - /** - * Returns the index of the minimum value - * @return {Array} - */ - minIndex() { - var v = this.get(0, 0); - var idx = [0, 0]; - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - if (this.get(i, j) < v) { - v = this.get(i, j); - idx[0] = i; - idx[1] = j; - } - } + maxColumnIndex(column) { + checkColumnIndex(this, column); + checkNonEmpty(this); + let v = this.get(0, column); + let idx = [0, column]; + for (let i = 1; i < this.rows; i++) { + if (this.get(i, column) > v) { + v = this.get(i, column); + idx[0] = i; } - return idx; - } - - /** - * Returns the maximum value of one row - * @param {number} row - Row index - * @return {number} - */ - maxRow(row) { - checkRowIndex(this, row); - var v = this.get(row, 0); - for (var i = 1; i < this.columns; i++) { - if (this.get(row, i) > v) { - v = this.get(row, i); - } - } - return v; - } - - /** - * Returns the index of the maximum value of one row - * @param {number} row - Row index - * @return {Array} - */ - maxRowIndex(row) { - checkRowIndex(this, row); - var v = this.get(row, 0); - var idx = [row, 0]; - for (var i = 1; i < this.columns; i++) { - if (this.get(row, i) > v) { - v = this.get(row, i); - idx[1] = i; - } - } - return idx; - } - - /** - * Returns the minimum value of one row - * @param {number} row - Row index - * @return {number} - */ - minRow(row) { - checkRowIndex(this, row); - var v = this.get(row, 0); - for (var i = 1; i < this.columns; i++) { - if (this.get(row, i) < v) { - v = this.get(row, i); - } - } - return v; - } - - /** - * Returns the index of the maximum value of one row - * @param {number} row - Row index - * @return {Array} - */ - minRowIndex(row) { - checkRowIndex(this, row); - var v = this.get(row, 0); - var idx = [row, 0]; - for (var i = 1; i < this.columns; i++) { - if (this.get(row, i) < v) { - v = this.get(row, i); - idx[1] = i; - } - } - return idx; - } - - /** - * Returns the maximum value of one column - * @param {number} column - Column index - * @return {number} - */ - maxColumn(column) { - checkColumnIndex(this, column); - var v = this.get(0, column); - for (var i = 1; i < this.rows; i++) { - if (this.get(i, column) > v) { - v = this.get(i, column); - } - } - return v; - } - - /** - * Returns the index of the maximum value of one column - * @param {number} column - Column index - * @return {Array} - */ - maxColumnIndex(column) { - checkColumnIndex(this, column); - var v = this.get(0, column); - var idx = [0, column]; - for (var i = 1; i < this.rows; i++) { - if (this.get(i, column) > v) { - v = this.get(i, column); - idx[0] = i; - } + } + return idx; + } + + minColumn(column) { + checkColumnIndex(this, column); + if (this.isEmpty()) { + return NaN; + } + let v = this.get(0, column); + for (let i = 1; i < this.rows; i++) { + if (this.get(i, column) < v) { + v = this.get(i, column); } - return idx; } + return v; + } - /** - * Returns the minimum value of one column - * @param {number} column - Column index - * @return {number} - */ - minColumn(column) { - checkColumnIndex(this, column); - var v = this.get(0, column); - for (var i = 1; i < this.rows; i++) { - if (this.get(i, column) < v) { - v = this.get(i, column); - } + minColumnIndex(column) { + checkColumnIndex(this, column); + checkNonEmpty(this); + let v = this.get(0, column); + let idx = [0, column]; + for (let i = 1; i < this.rows; i++) { + if (this.get(i, column) < v) { + v = this.get(i, column); + idx[0] = i; } - return v; } + return idx; + } - /** - * Returns the index of the minimum value of one column - * @param {number} column - Column index - * @return {Array} - */ - minColumnIndex(column) { - checkColumnIndex(this, column); - var v = this.get(0, column); - var idx = [0, column]; - for (var i = 1; i < this.rows; i++) { - if (this.get(i, column) < v) { - v = this.get(i, column); - idx[0] = i; - } - } - return idx; - } - - /** - * Returns an array containing the diagonal values of the matrix - * @return {Array} - */ - diag() { - var min = Math.min(this.rows, this.columns); - var diag = new Array(min); - for (var i = 0; i < min; i++) { - diag[i] = this.get(i, i); - } - return diag; - } - - /** - * Returns the sum by the argument given, if no argument given, - * it returns the sum of all elements of the matrix. - * @param {string} by - sum by 'row' or 'column'. - * @return {Matrix|number} - */ - sum(by) { - switch (by) { - case 'row': - return sumByRow(this); - case 'column': - return sumByColumn(this); - default: - return sumAll(this); - } - } - - /** - * Returns the mean of all elements of the matrix - * @return {number} - */ - mean() { - return this.sum() / this.size; - } - - /** - * Returns the product of all elements of the matrix - * @return {number} - */ - prod() { - var prod = 1; - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - prod *= this.get(i, j); - } - } - return prod; - } - - /** - * Returns the norm of a matrix. - * @param {string} type - "frobenius" (default) or "max" return resp. the Frobenius norm and the max norm. - * @return {number} - */ - norm(type = 'frobenius') { - var result = 0; - if (type === 'max') { - return this.max(); - } else if (type === 'frobenius') { - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - result = result + this.get(i, j) * this.get(i, j); - } - } - return Math.sqrt(result); - } else { - throw new RangeError(`unknown norm type: ${type}`); - } + diag() { + let min = Math.min(this.rows, this.columns); + let diag = []; + for (let i = 0; i < min; i++) { + diag.push(this.get(i, i)); } + return diag; + } - /** - * Computes the cumulative sum of the matrix elements (in place, row by row) - * @return {Matrix} this - */ - cumulativeSum() { - var sum = 0; - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - sum += this.get(i, j); - this.set(i, j, sum); + norm(type = 'frobenius') { + let result = 0; + if (type === 'max') { + return this.max(); + } else if (type === 'frobenius') { + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + result = result + this.get(i, j) * this.get(i, j); } } - return this; + return Math.sqrt(result); + } else { + throw new RangeError(`unknown norm type: ${type}`); } + } - /** - * Computes the dot (scalar) product between the matrix and another - * @param {Matrix} vector2 vector - * @return {number} - */ - dot(vector2) { - if (Matrix.isMatrix(vector2)) vector2 = vector2.to1DArray(); - var vector1 = this.to1DArray(); - if (vector1.length !== vector2.length) { - throw new RangeError('vectors do not have the same size'); - } - var dot = 0; - for (var i = 0; i < vector1.length; i++) { - dot += vector1[i] * vector2[i]; - } - return dot; - } - - /** - * Returns the matrix product between this and other - * @param {Matrix} other - * @return {Matrix} - */ - mmul(other) { - other = this.constructor.checkMatrix(other); - if (this.columns !== other.rows) { - // eslint-disable-next-line no-console - console.warn('Number of columns of left matrix are not equal to number of rows of right matrix.'); + cumulativeSum() { + let sum = 0; + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + sum += this.get(i, j); + this.set(i, j, sum); } + } + return this; + } - var m = this.rows; - var n = this.columns; - var p = other.columns; + dot(vector2) { + if (matrix_AbstractMatrix.isMatrix(vector2)) vector2 = vector2.to1DArray(); + let vector1 = this.to1DArray(); + if (vector1.length !== vector2.length) { + throw new RangeError('vectors do not have the same size'); + } + let dot = 0; + for (let i = 0; i < vector1.length; i++) { + dot += vector1[i] * vector2[i]; + } + return dot; + } - var result = new this.constructor[Symbol.species](m, p); + mmul(other) { + other = matrix_Matrix.checkMatrix(other); - var Bcolj = new Array(n); - for (var j = 0; j < p; j++) { - for (var k = 0; k < n; k++) { - Bcolj[k] = other.get(k, j); - } + let m = this.rows; + let n = this.columns; + let p = other.columns; - for (var i = 0; i < m; i++) { - var s = 0; - for (k = 0; k < n; k++) { - s += this.get(i, k) * Bcolj[k]; - } + let result = new matrix_Matrix(m, p); + + let Bcolj = new Float64Array(n); + for (let j = 0; j < p; j++) { + for (let k = 0; k < n; k++) { + Bcolj[k] = other.get(k, j); + } - result.set(i, j, s); + for (let i = 0; i < m; i++) { + let s = 0; + for (let k = 0; k < n; k++) { + s += this.get(i, k) * Bcolj[k]; } + + result.set(i, j, s); } - return result; } + return result; + } - strassen2x2(other) { - var result = new this.constructor[Symbol.species](2, 2); - const a11 = this.get(0, 0); - const b11 = other.get(0, 0); - const a12 = this.get(0, 1); - const b12 = other.get(0, 1); - const a21 = this.get(1, 0); - const b21 = other.get(1, 0); - const a22 = this.get(1, 1); - const b22 = other.get(1, 1); + strassen2x2(other) { + other = matrix_Matrix.checkMatrix(other); + let result = new matrix_Matrix(2, 2); + const a11 = this.get(0, 0); + const b11 = other.get(0, 0); + const a12 = this.get(0, 1); + const b12 = other.get(0, 1); + const a21 = this.get(1, 0); + const b21 = other.get(1, 0); + const a22 = this.get(1, 1); + const b22 = other.get(1, 1); + + // Compute intermediate values. + const m1 = (a11 + a22) * (b11 + b22); + const m2 = (a21 + a22) * b11; + const m3 = a11 * (b12 - b22); + const m4 = a22 * (b21 - b11); + const m5 = (a11 + a12) * b22; + const m6 = (a21 - a11) * (b11 + b12); + const m7 = (a12 - a22) * (b21 + b22); + + // Combine intermediate values into the output. + const c00 = m1 + m4 - m5 + m7; + const c01 = m3 + m5; + const c10 = m2 + m4; + const c11 = m1 - m2 + m3 + m6; + + result.set(0, 0, c00); + result.set(0, 1, c01); + result.set(1, 0, c10); + result.set(1, 1, c11); + return result; + } - // Compute intermediate values. - const m1 = (a11 + a22) * (b11 + b22); - const m2 = (a21 + a22) * b11; - const m3 = a11 * (b12 - b22); - const m4 = a22 * (b21 - b11); - const m5 = (a11 + a12) * b22; - const m6 = (a21 - a11) * (b11 + b12); - const m7 = (a12 - a22) * (b21 + b22); + strassen3x3(other) { + other = matrix_Matrix.checkMatrix(other); + let result = new matrix_Matrix(3, 3); + + const a00 = this.get(0, 0); + const a01 = this.get(0, 1); + const a02 = this.get(0, 2); + const a10 = this.get(1, 0); + const a11 = this.get(1, 1); + const a12 = this.get(1, 2); + const a20 = this.get(2, 0); + const a21 = this.get(2, 1); + const a22 = this.get(2, 2); + + const b00 = other.get(0, 0); + const b01 = other.get(0, 1); + const b02 = other.get(0, 2); + const b10 = other.get(1, 0); + const b11 = other.get(1, 1); + const b12 = other.get(1, 2); + const b20 = other.get(2, 0); + const b21 = other.get(2, 1); + const b22 = other.get(2, 2); + + const m1 = (a00 + a01 + a02 - a10 - a11 - a21 - a22) * b11; + const m2 = (a00 - a10) * (-b01 + b11); + const m3 = a11 * (-b00 + b01 + b10 - b11 - b12 - b20 + b22); + const m4 = (-a00 + a10 + a11) * (b00 - b01 + b11); + const m5 = (a10 + a11) * (-b00 + b01); + const m6 = a00 * b00; + const m7 = (-a00 + a20 + a21) * (b00 - b02 + b12); + const m8 = (-a00 + a20) * (b02 - b12); + const m9 = (a20 + a21) * (-b00 + b02); + const m10 = (a00 + a01 + a02 - a11 - a12 - a20 - a21) * b12; + const m11 = a21 * (-b00 + b02 + b10 - b11 - b12 - b20 + b21); + const m12 = (-a02 + a21 + a22) * (b11 + b20 - b21); + const m13 = (a02 - a22) * (b11 - b21); + const m14 = a02 * b20; + const m15 = (a21 + a22) * (-b20 + b21); + const m16 = (-a02 + a11 + a12) * (b12 + b20 - b22); + const m17 = (a02 - a12) * (b12 - b22); + const m18 = (a11 + a12) * (-b20 + b22); + const m19 = a01 * b10; + const m20 = a12 * b21; + const m21 = a10 * b02; + const m22 = a20 * b01; + const m23 = a22 * b22; + + const c00 = m6 + m14 + m19; + const c01 = m1 + m4 + m5 + m6 + m12 + m14 + m15; + const c02 = m6 + m7 + m9 + m10 + m14 + m16 + m18; + const c10 = m2 + m3 + m4 + m6 + m14 + m16 + m17; + const c11 = m2 + m4 + m5 + m6 + m20; + const c12 = m14 + m16 + m17 + m18 + m21; + const c20 = m6 + m7 + m8 + m11 + m12 + m13 + m14; + const c21 = m12 + m13 + m14 + m15 + m22; + const c22 = m6 + m7 + m8 + m9 + m23; + + result.set(0, 0, c00); + result.set(0, 1, c01); + result.set(0, 2, c02); + result.set(1, 0, c10); + result.set(1, 1, c11); + result.set(1, 2, c12); + result.set(2, 0, c20); + result.set(2, 1, c21); + result.set(2, 2, c22); + return result; + } - // Combine intermediate values into the output. - const c00 = m1 + m4 - m5 + m7; - const c01 = m3 + m5; - const c10 = m2 + m4; - const c11 = m1 - m2 + m3 + m6; - - result.set(0, 0, c00); - result.set(0, 1, c01); - result.set(1, 0, c10); - result.set(1, 1, c11); - return result; - } - - strassen3x3(other) { - var result = new this.constructor[Symbol.species](3, 3); - - const a00 = this.get(0, 0); - const a01 = this.get(0, 1); - const a02 = this.get(0, 2); - const a10 = this.get(1, 0); - const a11 = this.get(1, 1); - const a12 = this.get(1, 2); - const a20 = this.get(2, 0); - const a21 = this.get(2, 1); - const a22 = this.get(2, 2); - - const b00 = other.get(0, 0); - const b01 = other.get(0, 1); - const b02 = other.get(0, 2); - const b10 = other.get(1, 0); - const b11 = other.get(1, 1); - const b12 = other.get(1, 2); - const b20 = other.get(2, 0); - const b21 = other.get(2, 1); - const b22 = other.get(2, 2); - - const m1 = (a00 + a01 + a02 - a10 - a11 - a21 - a22) * b11; - const m2 = (a00 - a10) * (-b01 + b11); - const m3 = a11 * (-b00 + b01 + b10 - b11 - b12 - b20 + b22); - const m4 = (-a00 + a10 + a11) * (b00 - b01 + b11); - const m5 = (a10 + a11) * (-b00 + b01); - const m6 = a00 * b00; - const m7 = (-a00 + a20 + a21) * (b00 - b02 + b12); - const m8 = (-a00 + a20) * (b02 - b12); - const m9 = (a20 + a21) * (-b00 + b02); - const m10 = (a00 + a01 + a02 - a11 - a12 - a20 - a21) * b12; - const m11 = a21 * (-b00 + b02 + b10 - b11 - b12 - b20 + b21); - const m12 = (-a02 + a21 + a22) * (b11 + b20 - b21); - const m13 = (a02 - a22) * (b11 - b21); - const m14 = a02 * b20; - const m15 = (a21 + a22) * (-b20 + b21); - const m16 = (-a02 + a11 + a12) * (b12 + b20 - b22); - const m17 = (a02 - a12) * (b12 - b22); - const m18 = (a11 + a12) * (-b20 + b22); - const m19 = a01 * b10; - const m20 = a12 * b21; - const m21 = a10 * b02; - const m22 = a20 * b01; - const m23 = a22 * b22; - - const c00 = m6 + m14 + m19; - const c01 = m1 + m4 + m5 + m6 + m12 + m14 + m15; - const c02 = m6 + m7 + m9 + m10 + m14 + m16 + m18; - const c10 = m2 + m3 + m4 + m6 + m14 + m16 + m17; - const c11 = m2 + m4 + m5 + m6 + m20; - const c12 = m14 + m16 + m17 + m18 + m21; - const c20 = m6 + m7 + m8 + m11 + m12 + m13 + m14; - const c21 = m12 + m13 + m14 + m15 + m22; - const c22 = m6 + m7 + m8 + m9 + m23; - - result.set(0, 0, c00); - result.set(0, 1, c01); - result.set(0, 2, c02); - result.set(1, 0, c10); - result.set(1, 1, c11); - result.set(1, 2, c12); - result.set(2, 0, c20); - result.set(2, 1, c21); - result.set(2, 2, c22); - return result; - } - - /** - * Returns the matrix product between x and y. More efficient than mmul(other) only when we multiply squared matrix and when the size of the matrix is > 1000. - * @param {Matrix} y - * @return {Matrix} - */ - mmulStrassen(y) { - var x = this.clone(); - var r1 = x.rows; - var c1 = x.columns; - var r2 = y.rows; - var c2 = y.columns; - if (c1 !== r2) { - // eslint-disable-next-line no-console - console.warn(`Multiplying ${r1} x ${c1} and ${r2} x ${c2} matrix: dimensions do not match.`); - } + mmulStrassen(y) { + y = matrix_Matrix.checkMatrix(y); + let x = this.clone(); + let r1 = x.rows; + let c1 = x.columns; + let r2 = y.rows; + let c2 = y.columns; + if (c1 !== r2) { + // eslint-disable-next-line no-console + console.warn( + `Multiplying ${r1} x ${c1} and ${r2} x ${c2} matrix: dimensions do not match.`, + ); + } - // Put a matrix into the top left of a matrix of zeros. - // `rows` and `cols` are the dimensions of the output matrix. - function embed(mat, rows, cols) { - var r = mat.rows; - var c = mat.columns; - if ((r === rows) && (c === cols)) { - return mat; - } else { - var resultat = Matrix.zeros(rows, cols); - resultat = resultat.setSubMatrix(mat, 0, 0); - return resultat; - } - } - - - // Make sure both matrices are the same size. - // This is exclusively for simplicity: - // this algorithm can be implemented with matrices of different sizes. - - var r = Math.max(r1, r2); - var c = Math.max(c1, c2); - x = embed(x, r, c); - y = embed(y, r, c); - - // Our recursive multiplication function. - function blockMult(a, b, rows, cols) { - // For small matrices, resort to naive multiplication. - if (rows <= 512 || cols <= 512) { - return a.mmul(b); // a is equivalent to this - } - - // Apply dynamic padding. - if ((rows % 2 === 1) && (cols % 2 === 1)) { - a = embed(a, rows + 1, cols + 1); - b = embed(b, rows + 1, cols + 1); - } else if (rows % 2 === 1) { - a = embed(a, rows + 1, cols); - b = embed(b, rows + 1, cols); - } else if (cols % 2 === 1) { - a = embed(a, rows, cols + 1); - b = embed(b, rows, cols + 1); - } - - var halfRows = parseInt(a.rows / 2, 10); - var halfCols = parseInt(a.columns / 2, 10); - // Subdivide input matrices. - var a11 = a.subMatrix(0, halfRows - 1, 0, halfCols - 1); - var b11 = b.subMatrix(0, halfRows - 1, 0, halfCols - 1); - - var a12 = a.subMatrix(0, halfRows - 1, halfCols, a.columns - 1); - var b12 = b.subMatrix(0, halfRows - 1, halfCols, b.columns - 1); - - var a21 = a.subMatrix(halfRows, a.rows - 1, 0, halfCols - 1); - var b21 = b.subMatrix(halfRows, b.rows - 1, 0, halfCols - 1); - - var a22 = a.subMatrix(halfRows, a.rows - 1, halfCols, a.columns - 1); - var b22 = b.subMatrix(halfRows, b.rows - 1, halfCols, b.columns - 1); - - // Compute intermediate values. - var m1 = blockMult(Matrix.add(a11, a22), Matrix.add(b11, b22), halfRows, halfCols); - var m2 = blockMult(Matrix.add(a21, a22), b11, halfRows, halfCols); - var m3 = blockMult(a11, Matrix.sub(b12, b22), halfRows, halfCols); - var m4 = blockMult(a22, Matrix.sub(b21, b11), halfRows, halfCols); - var m5 = blockMult(Matrix.add(a11, a12), b22, halfRows, halfCols); - var m6 = blockMult(Matrix.sub(a21, a11), Matrix.add(b11, b12), halfRows, halfCols); - var m7 = blockMult(Matrix.sub(a12, a22), Matrix.add(b21, b22), halfRows, halfCols); - - // Combine intermediate values into the output. - var c11 = Matrix.add(m1, m4); - c11.sub(m5); - c11.add(m7); - var c12 = Matrix.add(m3, m5); - var c21 = Matrix.add(m2, m4); - var c22 = Matrix.sub(m1, m2); - c22.add(m3); - c22.add(m6); - - // Crop output to the desired size (undo dynamic padding). - var resultat = Matrix.zeros(2 * c11.rows, 2 * c11.columns); - resultat = resultat.setSubMatrix(c11, 0, 0); - resultat = resultat.setSubMatrix(c12, c11.rows, 0); - resultat = resultat.setSubMatrix(c21, 0, c11.columns); - resultat = resultat.setSubMatrix(c22, c11.rows, c11.columns); - return resultat.subMatrix(0, rows - 1, 0, cols - 1); - } - return blockMult(x, y, r, c); - } - - /** - * Returns a row-by-row scaled matrix - * @param {number} [min=0] - Minimum scaled value - * @param {number} [max=1] - Maximum scaled value - * @return {Matrix} - The scaled matrix - */ - scaleRows(min, max) { - min = min === undefined ? 0 : min; - max = max === undefined ? 1 : max; - if (min >= max) { - throw new RangeError('min should be strictly smaller than max'); - } - var newMatrix = this.constructor.empty(this.rows, this.columns); - for (var i = 0; i < this.rows; i++) { - var scaled = ml_array_rescale_lib_es6(this.getRow(i), { min, max }); - newMatrix.setRow(i, scaled); - } - return newMatrix; - } - - /** - * Returns a new column-by-column scaled matrix - * @param {number} [min=0] - Minimum scaled value - * @param {number} [max=1] - Maximum scaled value - * @return {Matrix} - The new scaled matrix - * @example - * var matrix = new Matrix([[1,2],[-1,0]]); - * var scaledMatrix = matrix.scaleColumns(); // [[1,1],[0,0]] - */ - scaleColumns(min, max) { - min = min === undefined ? 0 : min; - max = max === undefined ? 1 : max; - if (min >= max) { - throw new RangeError('min should be strictly smaller than max'); - } - var newMatrix = this.constructor.empty(this.rows, this.columns); - for (var i = 0; i < this.columns; i++) { - var scaled = ml_array_rescale_lib_es6(this.getColumn(i), { - min: min, - max: max - }); - newMatrix.setColumn(i, scaled); + // Put a matrix into the top left of a matrix of zeros. + // `rows` and `cols` are the dimensions of the output matrix. + function embed(mat, rows, cols) { + let r = mat.rows; + let c = mat.columns; + if (r === rows && c === cols) { + return mat; + } else { + let resultat = matrix_AbstractMatrix.zeros(rows, cols); + resultat = resultat.setSubMatrix(mat, 0, 0); + return resultat; } - return newMatrix; } + // Make sure both matrices are the same size. + // This is exclusively for simplicity: + // this algorithm can be implemented with matrices of different sizes. - /** - * Returns the Kronecker product (also known as tensor product) between this and other - * See https://en.wikipedia.org/wiki/Kronecker_product - * @param {Matrix} other - * @return {Matrix} - */ - kroneckerProduct(other) { - other = this.constructor.checkMatrix(other); + let r = Math.max(r1, r2); + let c = Math.max(c1, c2); + x = embed(x, r, c); + y = embed(y, r, c); - var m = this.rows; - var n = this.columns; - var p = other.rows; - var q = other.columns; - - var result = new this.constructor[Symbol.species](m * p, n * q); - for (var i = 0; i < m; i++) { - for (var j = 0; j < n; j++) { - for (var k = 0; k < p; k++) { - for (var l = 0; l < q; l++) { - result[p * i + k][q * j + l] = this.get(i, j) * other.get(k, l); - } - } - } + // Our recursive multiplication function. + function blockMult(a, b, rows, cols) { + // For small matrices, resort to naive multiplication. + if (rows <= 512 || cols <= 512) { + return a.mmul(b); // a is equivalent to this } - return result; - } - /** - * Transposes the matrix and returns a new one containing the result - * @return {Matrix} - */ - transpose() { - var result = new this.constructor[Symbol.species](this.columns, this.rows); - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - result.set(j, i, this.get(i, j)); - } + // Apply dynamic padding. + if (rows % 2 === 1 && cols % 2 === 1) { + a = embed(a, rows + 1, cols + 1); + b = embed(b, rows + 1, cols + 1); + } else if (rows % 2 === 1) { + a = embed(a, rows + 1, cols); + b = embed(b, rows + 1, cols); + } else if (cols % 2 === 1) { + a = embed(a, rows, cols + 1); + b = embed(b, rows, cols + 1); } - return result; - } - /** - * Sorts the rows (in place) - * @param {function} compareFunction - usual Array.prototype.sort comparison function - * @return {Matrix} this - */ - sortRows(compareFunction) { - if (compareFunction === undefined) compareFunction = compareNumbers; - for (var i = 0; i < this.rows; i++) { - this.setRow(i, this.getRow(i).sort(compareFunction)); + let halfRows = parseInt(a.rows / 2, 10); + let halfCols = parseInt(a.columns / 2, 10); + // Subdivide input matrices. + let a11 = a.subMatrix(0, halfRows - 1, 0, halfCols - 1); + let b11 = b.subMatrix(0, halfRows - 1, 0, halfCols - 1); + + let a12 = a.subMatrix(0, halfRows - 1, halfCols, a.columns - 1); + let b12 = b.subMatrix(0, halfRows - 1, halfCols, b.columns - 1); + + let a21 = a.subMatrix(halfRows, a.rows - 1, 0, halfCols - 1); + let b21 = b.subMatrix(halfRows, b.rows - 1, 0, halfCols - 1); + + let a22 = a.subMatrix(halfRows, a.rows - 1, halfCols, a.columns - 1); + let b22 = b.subMatrix(halfRows, b.rows - 1, halfCols, b.columns - 1); + + // Compute intermediate values. + let m1 = blockMult( + matrix_AbstractMatrix.add(a11, a22), + matrix_AbstractMatrix.add(b11, b22), + halfRows, + halfCols, + ); + let m2 = blockMult(matrix_AbstractMatrix.add(a21, a22), b11, halfRows, halfCols); + let m3 = blockMult(a11, matrix_AbstractMatrix.sub(b12, b22), halfRows, halfCols); + let m4 = blockMult(a22, matrix_AbstractMatrix.sub(b21, b11), halfRows, halfCols); + let m5 = blockMult(matrix_AbstractMatrix.add(a11, a12), b22, halfRows, halfCols); + let m6 = blockMult( + matrix_AbstractMatrix.sub(a21, a11), + matrix_AbstractMatrix.add(b11, b12), + halfRows, + halfCols, + ); + let m7 = blockMult( + matrix_AbstractMatrix.sub(a12, a22), + matrix_AbstractMatrix.add(b21, b22), + halfRows, + halfCols, + ); + + // Combine intermediate values into the output. + let c11 = matrix_AbstractMatrix.add(m1, m4); + c11.sub(m5); + c11.add(m7); + let c12 = matrix_AbstractMatrix.add(m3, m5); + let c21 = matrix_AbstractMatrix.add(m2, m4); + let c22 = matrix_AbstractMatrix.sub(m1, m2); + c22.add(m3); + c22.add(m6); + + // Crop output to the desired size (undo dynamic padding). + let resultat = matrix_AbstractMatrix.zeros(2 * c11.rows, 2 * c11.columns); + resultat = resultat.setSubMatrix(c11, 0, 0); + resultat = resultat.setSubMatrix(c12, c11.rows, 0); + resultat = resultat.setSubMatrix(c21, 0, c11.columns); + resultat = resultat.setSubMatrix(c22, c11.rows, c11.columns); + return resultat.subMatrix(0, rows - 1, 0, cols - 1); + } + return blockMult(x, y, r, c); + } + + scaleRows(options = {}) { + if (typeof options !== 'object') { + throw new TypeError('options must be an object'); + } + const { min = 0, max = 1 } = options; + if (!Number.isFinite(min)) throw new TypeError('min must be a number'); + if (!Number.isFinite(max)) throw new TypeError('max must be a number'); + if (min >= max) throw new RangeError('min must be smaller than max'); + let newMatrix = new matrix_Matrix(this.rows, this.columns); + for (let i = 0; i < this.rows; i++) { + const row = this.getRow(i); + if (row.length > 0) { + ml_array_rescale_lib_es6(row, { min, max, output: row }); + } + newMatrix.setRow(i, row); + } + return newMatrix; + } + + scaleColumns(options = {}) { + if (typeof options !== 'object') { + throw new TypeError('options must be an object'); + } + const { min = 0, max = 1 } = options; + if (!Number.isFinite(min)) throw new TypeError('min must be a number'); + if (!Number.isFinite(max)) throw new TypeError('max must be a number'); + if (min >= max) throw new RangeError('min must be smaller than max'); + let newMatrix = new matrix_Matrix(this.rows, this.columns); + for (let i = 0; i < this.columns; i++) { + const column = this.getColumn(i); + if (column.length) { + ml_array_rescale_lib_es6(column, { + min: min, + max: max, + output: column, + }); } - return this; + newMatrix.setColumn(i, column); } + return newMatrix; + } - /** - * Sorts the columns (in place) - * @param {function} compareFunction - usual Array.prototype.sort comparison function - * @return {Matrix} this - */ - sortColumns(compareFunction) { - if (compareFunction === undefined) compareFunction = compareNumbers; - for (var i = 0; i < this.columns; i++) { - this.setColumn(i, this.getColumn(i).sort(compareFunction)); + flipRows() { + const middle = Math.ceil(this.columns / 2); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < middle; j++) { + let first = this.get(i, j); + let last = this.get(i, this.columns - 1 - j); + this.set(i, j, last); + this.set(i, this.columns - 1 - j, first); } - return this; } + return this; + } - /** - * Returns a subset of the matrix - * @param {number} startRow - First row index - * @param {number} endRow - Last row index - * @param {number} startColumn - First column index - * @param {number} endColumn - Last column index - * @return {Matrix} - */ - subMatrix(startRow, endRow, startColumn, endColumn) { - checkRange(this, startRow, endRow, startColumn, endColumn); - var newMatrix = new this.constructor[Symbol.species](endRow - startRow + 1, endColumn - startColumn + 1); - for (var i = startRow; i <= endRow; i++) { - for (var j = startColumn; j <= endColumn; j++) { - newMatrix[i - startRow][j - startColumn] = this.get(i, j); - } - } - return newMatrix; - } - - /** - * Returns a subset of the matrix based on an array of row indices - * @param {Array} indices - Array containing the row indices - * @param {number} [startColumn = 0] - First column index - * @param {number} [endColumn = this.columns-1] - Last column index - * @return {Matrix} - */ - subMatrixRow(indices, startColumn, endColumn) { - if (startColumn === undefined) startColumn = 0; - if (endColumn === undefined) endColumn = this.columns - 1; - if ((startColumn > endColumn) || (startColumn < 0) || (startColumn >= this.columns) || (endColumn < 0) || (endColumn >= this.columns)) { - throw new RangeError('Argument out of range'); - } - - var newMatrix = new this.constructor[Symbol.species](indices.length, endColumn - startColumn + 1); - for (var i = 0; i < indices.length; i++) { - for (var j = startColumn; j <= endColumn; j++) { - if (indices[i] < 0 || indices[i] >= this.rows) { - throw new RangeError(`Row index out of range: ${indices[i]}`); - } - newMatrix.set(i, j - startColumn, this.get(indices[i], j)); - } + flipColumns() { + const middle = Math.ceil(this.rows / 2); + for (let j = 0; j < this.columns; j++) { + for (let i = 0; i < middle; i++) { + let first = this.get(i, j); + let last = this.get(this.rows - 1 - i, j); + this.set(i, j, last); + this.set(this.rows - 1 - i, j, first); } - return newMatrix; } + return this; + } - /** - * Returns a subset of the matrix based on an array of column indices - * @param {Array} indices - Array containing the column indices - * @param {number} [startRow = 0] - First row index - * @param {number} [endRow = this.rows-1] - Last row index - * @return {Matrix} - */ - subMatrixColumn(indices, startRow, endRow) { - if (startRow === undefined) startRow = 0; - if (endRow === undefined) endRow = this.rows - 1; - if ((startRow > endRow) || (startRow < 0) || (startRow >= this.rows) || (endRow < 0) || (endRow >= this.rows)) { - throw new RangeError('Argument out of range'); - } + kroneckerProduct(other) { + other = matrix_Matrix.checkMatrix(other); + + let m = this.rows; + let n = this.columns; + let p = other.rows; + let q = other.columns; - var newMatrix = new this.constructor[Symbol.species](endRow - startRow + 1, indices.length); - for (var i = 0; i < indices.length; i++) { - for (var j = startRow; j <= endRow; j++) { - if (indices[i] < 0 || indices[i] >= this.columns) { - throw new RangeError(`Column index out of range: ${indices[i]}`); + let result = new matrix_Matrix(m * p, n * q); + for (let i = 0; i < m; i++) { + for (let j = 0; j < n; j++) { + for (let k = 0; k < p; k++) { + for (let l = 0; l < q; l++) { + result.set(p * i + k, q * j + l, this.get(i, j) * other.get(k, l)); } - newMatrix.set(j - startRow, i, this.get(j, indices[i])); } } - return newMatrix; } + return result; + } - /** - * Set a part of the matrix to the given sub-matrix - * @param {Matrix|Array< Array >} matrix - The source matrix from which to extract values. - * @param {number} startRow - The index of the first row to set - * @param {number} startColumn - The index of the first column to set - * @return {Matrix} - */ - setSubMatrix(matrix, startRow, startColumn) { - matrix = this.constructor.checkMatrix(matrix); - var endRow = startRow + matrix.rows - 1; - var endColumn = startColumn + matrix.columns - 1; - checkRange(this, startRow, endRow, startColumn, endColumn); - for (var i = 0; i < matrix.rows; i++) { - for (var j = 0; j < matrix.columns; j++) { - this[startRow + i][startColumn + j] = matrix.get(i, j); - } - } - return this; + kroneckerSum(other) { + other = matrix_Matrix.checkMatrix(other); + if (!this.isSquare() || !other.isSquare()) { + throw new Error('Kronecker Sum needs two Square Matrices'); } + let m = this.rows; + let n = other.rows; + let AxI = this.kroneckerProduct(matrix_Matrix.eye(n, n)); + let IxB = matrix_Matrix.eye(m, m).kroneckerProduct(other); + return AxI.add(IxB); + } - /** - * Return a new matrix based on a selection of rows and columns - * @param {Array} rowIndices - The row indices to select. Order matters and an index can be more than once. - * @param {Array} columnIndices - The column indices to select. Order matters and an index can be use more than once. - * @return {Matrix} The new matrix - */ - selection(rowIndices, columnIndices) { - var indices = checkIndices(this, rowIndices, columnIndices); - var newMatrix = new this.constructor[Symbol.species](rowIndices.length, columnIndices.length); - for (var i = 0; i < indices.row.length; i++) { - var rowIndex = indices.row[i]; - for (var j = 0; j < indices.column.length; j++) { - var columnIndex = indices.column[j]; - newMatrix[i][j] = this.get(rowIndex, columnIndex); - } - } - return newMatrix; - } - - /** - * Returns the trace of the matrix (sum of the diagonal elements) - * @return {number} - */ - trace() { - var min = Math.min(this.rows, this.columns); - var trace = 0; - for (var i = 0; i < min; i++) { - trace += this.get(i, i); - } - return trace; - } - - /* - Matrix views - */ - - /** - * Returns a view of the transposition of the matrix - * @return {MatrixTransposeView} - */ - transposeView() { - return new transpose_MatrixTransposeView(this); - } - - /** - * Returns a view of the row vector with the given index - * @param {number} row - row index of the vector - * @return {MatrixRowView} - */ - rowView(row) { - checkRowIndex(this, row); - return new row_MatrixRowView(this, row); - } - - /** - * Returns a view of the column vector with the given index - * @param {number} column - column index of the vector - * @return {MatrixColumnView} - */ - columnView(column) { - checkColumnIndex(this, column); - return new column_MatrixColumnView(this, column); - } - - /** - * Returns a view of the matrix flipped in the row axis - * @return {MatrixFlipRowView} - */ - flipRowView() { - return new flipRow_MatrixFlipRowView(this); - } - - /** - * Returns a view of the matrix flipped in the column axis - * @return {MatrixFlipColumnView} - */ - flipColumnView() { - return new flipColumn_MatrixFlipColumnView(this); - } - - /** - * Returns a view of a submatrix giving the index boundaries - * @param {number} startRow - first row index of the submatrix - * @param {number} endRow - last row index of the submatrix - * @param {number} startColumn - first column index of the submatrix - * @param {number} endColumn - last column index of the submatrix - * @return {MatrixSubView} - */ - subMatrixView(startRow, endRow, startColumn, endColumn) { - return new sub_MatrixSubView(this, startRow, endRow, startColumn, endColumn); - } - - /** - * Returns a view of the cross of the row indices and the column indices - * @example - * // resulting vector is [[2], [2]] - * var matrix = new Matrix([[1,2,3], [4,5,6]]).selectionView([0, 0], [1]) - * @param {Array} rowIndices - * @param {Array} columnIndices - * @return {MatrixSelectionView} - */ - selectionView(rowIndices, columnIndices) { - return new selection_MatrixSelectionView(this, rowIndices, columnIndices); - } - - /** - * Returns a view of the row indices - * @example - * // resulting vector is [[1,2,3], [1,2,3]] - * var matrix = new Matrix([[1,2,3], [4,5,6]]).rowSelectionView([0, 0]) - * @param {Array} rowIndices - * @return {MatrixRowSelectionView} - */ - rowSelectionView(rowIndices) { - return new rowSelection_MatrixRowSelectionView(this, rowIndices); - } - - /** - * Returns a view of the column indices - * @example - * // resulting vector is [[2, 2], [5, 5]] - * var matrix = new Matrix([[1,2,3], [4,5,6]]).columnSelectionView([1, 1]) - * @param {Array} columnIndices - * @return {MatrixColumnSelectionView} - */ - columnSelectionView(columnIndices) { - return new columnSelection_MatrixColumnSelectionView(this, columnIndices); - } - - - /** - * Calculates and returns the determinant of a matrix as a Number - * @example - * new Matrix([[1,2,3], [4,5,6]]).det() - * @return {number} - */ - det() { - if (this.isSquare()) { - var a, b, c, d; - if (this.columns === 2) { - // 2 x 2 matrix - a = this.get(0, 0); - b = this.get(0, 1); - c = this.get(1, 0); - d = this.get(1, 1); - - return a * d - (b * c); - } else if (this.columns === 3) { - // 3 x 3 matrix - var subMatrix0, subMatrix1, subMatrix2; - subMatrix0 = this.selectionView([1, 2], [1, 2]); - subMatrix1 = this.selectionView([1, 2], [0, 2]); - subMatrix2 = this.selectionView([1, 2], [0, 1]); - a = this.get(0, 0); - b = this.get(0, 1); - c = this.get(0, 2); - - return a * subMatrix0.det() - b * subMatrix1.det() + c * subMatrix2.det(); - } else { - // general purpose determinant using the LU decomposition - return new lu_LuDecomposition(this).determinant; - } - } else { - throw Error('Determinant can only be calculated for a square matrix.'); + transpose() { + let result = new matrix_Matrix(this.columns, this.rows); + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.columns; j++) { + result.set(j, i, this.get(i, j)); } } + return result; + } - /** - * Returns inverse of a matrix if it exists or the pseudoinverse - * @param {number} threshold - threshold for taking inverse of singular values (default = 1e-15) - * @return {Matrix} the (pseudo)inverted matrix. - */ - pseudoInverse(threshold) { - if (threshold === undefined) threshold = Number.EPSILON; - var svdSolution = new svd_SingularValueDecomposition(this, { autoTranspose: true }); + sortRows(compareFunction = compareNumbers) { + for (let i = 0; i < this.rows; i++) { + this.setRow(i, this.getRow(i).sort(compareFunction)); + } + return this; + } - var U = svdSolution.leftSingularVectors; - var V = svdSolution.rightSingularVectors; - var s = svdSolution.diagonal; + sortColumns(compareFunction = compareNumbers) { + for (let i = 0; i < this.columns; i++) { + this.setColumn(i, this.getColumn(i).sort(compareFunction)); + } + return this; + } - for (var i = 0; i < s.length; i++) { - if (Math.abs(s[i]) > threshold) { - s[i] = 1.0 / s[i]; - } else { - s[i] = 0.0; - } + subMatrix(startRow, endRow, startColumn, endColumn) { + checkRange(this, startRow, endRow, startColumn, endColumn); + let newMatrix = new matrix_Matrix( + endRow - startRow + 1, + endColumn - startColumn + 1, + ); + for (let i = startRow; i <= endRow; i++) { + for (let j = startColumn; j <= endColumn; j++) { + newMatrix.set(i - startRow, j - startColumn, this.get(i, j)); } + } + return newMatrix; + } - // convert list to diagonal - s = this.constructor[Symbol.species].diag(s); - return V.mmul(s.mmul(U.transposeView())); + subMatrixRow(indices, startColumn, endColumn) { + if (startColumn === undefined) startColumn = 0; + if (endColumn === undefined) endColumn = this.columns - 1; + if ( + startColumn > endColumn || + startColumn < 0 || + startColumn >= this.columns || + endColumn < 0 || + endColumn >= this.columns + ) { + throw new RangeError('Argument out of range'); } - /** - * Creates an exact and independent copy of the matrix - * @return {Matrix} - */ - clone() { - var newMatrix = new this.constructor[Symbol.species](this.rows, this.columns); - for (var row = 0; row < this.rows; row++) { - for (var column = 0; column < this.columns; column++) { - newMatrix.set(row, column, this.get(row, column)); + let newMatrix = new matrix_Matrix(indices.length, endColumn - startColumn + 1); + for (let i = 0; i < indices.length; i++) { + for (let j = startColumn; j <= endColumn; j++) { + if (indices[i] < 0 || indices[i] >= this.rows) { + throw new RangeError(`Row index out of range: ${indices[i]}`); } + newMatrix.set(i, j - startColumn, this.get(indices[i], j)); } - return newMatrix; } + return newMatrix; } - Matrix.prototype.klass = 'Matrix'; - - function compareNumbers(a, b) { - return a - b; - } - - /* - Synonyms - */ - - Matrix.random = Matrix.rand; - Matrix.diagonal = Matrix.diag; - Matrix.prototype.diagonal = Matrix.prototype.diag; - Matrix.identity = Matrix.eye; - Matrix.prototype.negate = Matrix.prototype.neg; - Matrix.prototype.tensorProduct = Matrix.prototype.kroneckerProduct; - Matrix.prototype.determinant = Matrix.prototype.det; - - /* - Add dynamically instance and static methods for mathematical operations - */ - - var inplaceOperator = ` -(function %name%(value) { - if (typeof value === 'number') return this.%name%S(value); - return this.%name%M(value); -}) -`; + subMatrixColumn(indices, startRow, endRow) { + if (startRow === undefined) startRow = 0; + if (endRow === undefined) endRow = this.rows - 1; + if ( + startRow > endRow || + startRow < 0 || + startRow >= this.rows || + endRow < 0 || + endRow >= this.rows + ) { + throw new RangeError('Argument out of range'); + } - var inplaceOperatorScalar = ` -(function %name%S(value) { - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) %op% value); + let newMatrix = new matrix_Matrix(endRow - startRow + 1, indices.length); + for (let i = 0; i < indices.length; i++) { + for (let j = startRow; j <= endRow; j++) { + if (indices[i] < 0 || indices[i] >= this.columns) { + throw new RangeError(`Column index out of range: ${indices[i]}`); } + newMatrix.set(j - startRow, i, this.get(j, indices[i])); + } } - return this; -}) -`; + return newMatrix; + } - var inplaceOperatorMatrix = ` -(function %name%M(matrix) { - matrix = this.constructor.checkMatrix(matrix); - if (this.rows !== matrix.rows || - this.columns !== matrix.columns) { - throw new RangeError('Matrices dimensions must be equal'); + setSubMatrix(matrix, startRow, startColumn) { + matrix = matrix_Matrix.checkMatrix(matrix); + if (matrix.isEmpty()) { + return this; } - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, this.get(i, j) %op% matrix.get(i, j)); - } + let endRow = startRow + matrix.rows - 1; + let endColumn = startColumn + matrix.columns - 1; + checkRange(this, startRow, endRow, startColumn, endColumn); + for (let i = 0; i < matrix.rows; i++) { + for (let j = 0; j < matrix.columns; j++) { + this.set(startRow + i, startColumn + j, matrix.get(i, j)); + } } return this; -}) -`; - - var staticOperator = ` -(function %name%(matrix, value) { - var newMatrix = new this[Symbol.species](matrix); - return newMatrix.%name%(value); -}) -`; + } - var inplaceMethod = ` -(function %name%() { - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, %method%(this.get(i, j))); - } + selection(rowIndices, columnIndices) { + let indices = checkIndices(this, rowIndices, columnIndices); + let newMatrix = new matrix_Matrix(rowIndices.length, columnIndices.length); + for (let i = 0; i < indices.row.length; i++) { + let rowIndex = indices.row[i]; + for (let j = 0; j < indices.column.length; j++) { + let columnIndex = indices.column[j]; + newMatrix.set(i, j, this.get(rowIndex, columnIndex)); + } } - return this; -}) -`; + return newMatrix; + } - var staticMethod = ` -(function %name%(matrix) { - var newMatrix = new this[Symbol.species](matrix); - return newMatrix.%name%(); -}) -`; + trace() { + let min = Math.min(this.rows, this.columns); + let trace = 0; + for (let i = 0; i < min; i++) { + trace += this.get(i, i); + } + return trace; + } - var inplaceMethodWithArgs = ` -(function %name%(%args%) { - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, %method%(this.get(i, j), %args%)); - } + clone() { + let newMatrix = new matrix_Matrix(this.rows, this.columns); + for (let row = 0; row < this.rows; row++) { + for (let column = 0; column < this.columns; column++) { + newMatrix.set(row, column, this.get(row, column)); + } } - return this; -}) -`; + return newMatrix; + } - var staticMethodWithArgs = ` -(function %name%(matrix, %args%) { - var newMatrix = new this[Symbol.species](matrix); - return newMatrix.%name%(%args%); -}) -`; + sum(by) { + switch (by) { + case 'row': + return sumByRow(this); + case 'column': + return sumByColumn(this); + case undefined: + return sumAll(this); + default: + throw new Error(`invalid option: ${by}`); + } + } + product(by) { + switch (by) { + case 'row': + return productByRow(this); + case 'column': + return productByColumn(this); + case undefined: + return productAll(this); + default: + throw new Error(`invalid option: ${by}`); + } + } - var inplaceMethodWithOneArgScalar = ` -(function %name%S(value) { - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, %method%(this.get(i, j), value)); + mean(by) { + const sum = this.sum(by); + switch (by) { + case 'row': { + for (let i = 0; i < this.rows; i++) { + sum[i] /= this.columns; + } + return sum; + } + case 'column': { + for (let i = 0; i < this.columns; i++) { + sum[i] /= this.rows; } + return sum; + } + case undefined: + return sum / this.size; + default: + throw new Error(`invalid option: ${by}`); } - return this; -}) -`; - var inplaceMethodWithOneArgMatrix = ` -(function %name%M(matrix) { - matrix = this.constructor.checkMatrix(matrix); - if (this.rows !== matrix.rows || - this.columns !== matrix.columns) { - throw new RangeError('Matrices dimensions must be equal'); + } + + variance(by, options = {}) { + if (typeof by === 'object') { + options = by; + by = undefined; + } + if (typeof options !== 'object') { + throw new TypeError('options must be an object'); } - for (var i = 0; i < this.rows; i++) { - for (var j = 0; j < this.columns; j++) { - this.set(i, j, %method%(this.get(i, j), matrix.get(i, j))); + const { unbiased = true, mean = this.mean(by) } = options; + if (typeof unbiased !== 'boolean') { + throw new TypeError('unbiased must be a boolean'); + } + switch (by) { + case 'row': { + if (!Array.isArray(mean)) { + throw new TypeError('mean must be an array'); + } + return varianceByRow(this, unbiased, mean); + } + case 'column': { + if (!Array.isArray(mean)) { + throw new TypeError('mean must be an array'); + } + return varianceByColumn(this, unbiased, mean); + } + case undefined: { + if (typeof mean !== 'number') { + throw new TypeError('mean must be a number'); } + return varianceAll(this, unbiased, mean); + } + default: + throw new Error(`invalid option: ${by}`); } - return this; -}) -`; - - var inplaceMethodWithOneArg = ` -(function %name%(value) { - if (typeof value === 'number') return this.%name%S(value); - return this.%name%M(value); -}) -`; - - var staticMethodWithOneArg = staticMethodWithArgs; - - var operators = [ - // Arithmetic operators - ['+', 'add'], - ['-', 'sub', 'subtract'], - ['*', 'mul', 'multiply'], - ['/', 'div', 'divide'], - ['%', 'mod', 'modulus'], - // Bitwise operators - ['&', 'and'], - ['|', 'or'], - ['^', 'xor'], - ['<<', 'leftShift'], - ['>>', 'signPropagatingRightShift'], - ['>>>', 'rightShift', 'zeroFillRightShift'] - ]; - - var i; - var eval2 = eval; // eslint-disable-line no-eval - for (var operator of operators) { - var inplaceOp = eval2(fillTemplateFunction(inplaceOperator, { name: operator[1], op: operator[0] })); - var inplaceOpS = eval2(fillTemplateFunction(inplaceOperatorScalar, { name: `${operator[1]}S`, op: operator[0] })); - var inplaceOpM = eval2(fillTemplateFunction(inplaceOperatorMatrix, { name: `${operator[1]}M`, op: operator[0] })); - var staticOp = eval2(fillTemplateFunction(staticOperator, { name: operator[1] })); - for (i = 1; i < operator.length; i++) { - Matrix.prototype[operator[i]] = inplaceOp; - Matrix.prototype[`${operator[i]}S`] = inplaceOpS; - Matrix.prototype[`${operator[i]}M`] = inplaceOpM; - Matrix[operator[i]] = staticOp; - } - } - - var methods = [['~', 'not']]; - - [ - 'abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cbrt', 'ceil', - 'clz32', 'cos', 'cosh', 'exp', 'expm1', 'floor', 'fround', 'log', 'log1p', - 'log10', 'log2', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc' - ].forEach(function (mathMethod) { - methods.push([`Math.${mathMethod}`, mathMethod]); - }); + } - for (var method of methods) { - var inplaceMeth = eval2(fillTemplateFunction(inplaceMethod, { name: method[1], method: method[0] })); - var staticMeth = eval2(fillTemplateFunction(staticMethod, { name: method[1] })); - for (i = 1; i < method.length; i++) { - Matrix.prototype[method[i]] = inplaceMeth; - Matrix[method[i]] = staticMeth; + standardDeviation(by, options) { + if (typeof by === 'object') { + options = by; + by = undefined; + } + const variance = this.variance(by, options); + if (by === undefined) { + return Math.sqrt(variance); + } else { + for (let i = 0; i < variance.length; i++) { + variance[i] = Math.sqrt(variance[i]); + } + return variance; } } - var methodsWithArgs = [['Math.pow', 1, 'pow']]; - - for (var methodWithArg of methodsWithArgs) { - var args = 'arg0'; - for (i = 1; i < methodWithArg[1]; i++) { - args += `, arg${i}`; + center(by, options = {}) { + if (typeof by === 'object') { + options = by; + by = undefined; + } + if (typeof options !== 'object') { + throw new TypeError('options must be an object'); } - if (methodWithArg[1] !== 1) { - var inplaceMethWithArgs = eval2(fillTemplateFunction(inplaceMethodWithArgs, { - name: methodWithArg[2], - method: methodWithArg[0], - args: args - })); - var staticMethWithArgs = eval2(fillTemplateFunction(staticMethodWithArgs, { name: methodWithArg[2], args: args })); - for (i = 2; i < methodWithArg.length; i++) { - Matrix.prototype[methodWithArg[i]] = inplaceMethWithArgs; - Matrix[methodWithArg[i]] = staticMethWithArgs; + const { center = this.mean(by) } = options; + switch (by) { + case 'row': { + if (!Array.isArray(center)) { + throw new TypeError('center must be an array'); + } + centerByRow(this, center); + return this; } - } else { - var tmplVar = { - name: methodWithArg[2], - args: args, - method: methodWithArg[0] - }; - var inplaceMethod2 = eval2(fillTemplateFunction(inplaceMethodWithOneArg, tmplVar)); - var inplaceMethodS = eval2(fillTemplateFunction(inplaceMethodWithOneArgScalar, tmplVar)); - var inplaceMethodM = eval2(fillTemplateFunction(inplaceMethodWithOneArgMatrix, tmplVar)); - var staticMethod2 = eval2(fillTemplateFunction(staticMethodWithOneArg, tmplVar)); - for (i = 2; i < methodWithArg.length; i++) { - Matrix.prototype[methodWithArg[i]] = inplaceMethod2; - Matrix.prototype[`${methodWithArg[i]}M`] = inplaceMethodM; - Matrix.prototype[`${methodWithArg[i]}S`] = inplaceMethodS; - Matrix[methodWithArg[i]] = staticMethod2; + case 'column': { + if (!Array.isArray(center)) { + throw new TypeError('center must be an array'); + } + centerByColumn(this, center); + return this; + } + case undefined: { + if (typeof center !== 'number') { + throw new TypeError('center must be a number'); + } + centerAll(this, center); + return this; } + default: + throw new Error(`invalid option: ${by}`); } } - function fillTemplateFunction(template, values) { - for (var value in values) { - template = template.replace(new RegExp(`%${value}%`, 'g'), values[value]); + scale(by, options = {}) { + if (typeof by === 'object') { + options = by; + by = undefined; + } + if (typeof options !== 'object') { + throw new TypeError('options must be an object'); + } + let scale = options.scale; + switch (by) { + case 'row': { + if (scale === undefined) { + scale = getScaleByRow(this); + } else if (!Array.isArray(scale)) { + throw new TypeError('scale must be an array'); + } + scaleByRow(this, scale); + return this; + } + case 'column': { + if (scale === undefined) { + scale = getScaleByColumn(this); + } else if (!Array.isArray(scale)) { + throw new TypeError('scale must be an array'); + } + scaleByColumn(this, scale); + return this; + } + case undefined: { + if (scale === undefined) { + scale = getScaleAll(this); + } else if (typeof scale !== 'number') { + throw new TypeError('scale must be a number'); + } + scaleAll(this, scale); + return this; + } + default: + throw new Error(`invalid option: ${by}`); } - return template; } - return Matrix; + toString(options) { + return inspectMatrixWithOptions(this, options); + } } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/matrix.js - +matrix_AbstractMatrix.prototype.klass = 'Matrix'; +if (typeof Symbol !== 'undefined') { + matrix_AbstractMatrix.prototype[ + Symbol.for('nodejs.util.inspect.custom') + ] = inspectMatrix; +} +function compareNumbers(a, b) { + return a - b; +} -class matrix_Matrix extends AbstractMatrix(Array) { +// Synonyms +matrix_AbstractMatrix.random = matrix_AbstractMatrix.rand; +matrix_AbstractMatrix.randomInt = matrix_AbstractMatrix.randInt; +matrix_AbstractMatrix.diagonal = matrix_AbstractMatrix.diag; +matrix_AbstractMatrix.prototype.diagonal = matrix_AbstractMatrix.prototype.diag; +matrix_AbstractMatrix.identity = matrix_AbstractMatrix.eye; +matrix_AbstractMatrix.prototype.negate = matrix_AbstractMatrix.prototype.neg; +matrix_AbstractMatrix.prototype.tensorProduct = + matrix_AbstractMatrix.prototype.kroneckerProduct; + +class matrix_Matrix extends matrix_AbstractMatrix { constructor(nRows, nColumns) { - var i; - if (arguments.length === 1 && typeof nRows === 'number') { - return new Array(nRows); - } + super(); if (matrix_Matrix.isMatrix(nRows)) { + // eslint-disable-next-line no-constructor-return return nRows.clone(); - } else if (Number.isInteger(nRows) && nRows > 0) { + } else if (Number.isInteger(nRows) && nRows >= 0) { // Create an empty matrix - super(nRows); - if (Number.isInteger(nColumns) && nColumns > 0) { - for (i = 0; i < nRows; i++) { - this[i] = new Array(nColumns); + this.data = []; + if (Number.isInteger(nColumns) && nColumns >= 0) { + for (let i = 0; i < nRows; i++) { + this.data.push(new Float64Array(nColumns)); } } else { throw new TypeError('nColumns must be a positive integer'); } } else if (Array.isArray(nRows)) { // Copy the values from the 2D array - const matrix = nRows; - nRows = matrix.length; - nColumns = matrix[0].length; - if (typeof nColumns !== 'number' || nColumns === 0) { + const arrayData = nRows; + nRows = arrayData.length; + nColumns = nRows ? arrayData[0].length : 0; + if (typeof nColumns !== 'number') { throw new TypeError( - 'Data must be a 2D array with at least one element' + 'Data must be a 2D array with at least one element', ); } - super(nRows); - for (i = 0; i < nRows; i++) { - if (matrix[i].length !== nColumns) { + this.data = []; + for (let i = 0; i < nRows; i++) { + if (arrayData[i].length !== nColumns) { throw new RangeError('Inconsistent array dimensions'); } - this[i] = [].concat(matrix[i]); + this.data.push(Float64Array.from(arrayData[i])); } } else { throw new TypeError( - 'First argument must be a positive number or an array' + 'First argument must be a positive number or an array', ); } this.rows = nRows; this.columns = nColumns; - return this; } set(rowIndex, columnIndex, value) { - this[rowIndex][columnIndex] = value; + this.data[rowIndex][columnIndex] = value; return this; } get(rowIndex, columnIndex) { - return this[rowIndex][columnIndex]; + return this.data[rowIndex][columnIndex]; } - /** - * Removes a row from the given index - * @param {number} index - Row index - * @return {Matrix} this - */ removeRow(index) { checkRowIndex(this, index); - if (this.rows === 1) { - throw new RangeError('A matrix cannot have less than one row'); - } - this.splice(index, 1); + this.data.splice(index, 1); this.rows -= 1; return this; } - /** - * Adds a row at the given index - * @param {number} [index = this.rows] - Row index - * @param {Array|Matrix} array - Array or vector - * @return {Matrix} this - */ addRow(index, array) { if (array === undefined) { array = index; index = this.rows; } checkRowIndex(this, index, true); - array = checkRowVector(this, array, true); - this.splice(index, 0, array); + array = Float64Array.from(checkRowVector(this, array)); + this.data.splice(index, 0, array); this.rows += 1; return this; } - /** - * Removes a column from the given index - * @param {number} index - Column index - * @return {Matrix} this - */ removeColumn(index) { checkColumnIndex(this, index); - if (this.columns === 1) { - throw new RangeError('A matrix cannot have less than one column'); - } - for (var i = 0; i < this.rows; i++) { - this[i].splice(index, 1); + for (let i = 0; i < this.rows; i++) { + const newRow = new Float64Array(this.columns - 1); + for (let j = 0; j < index; j++) { + newRow[j] = this.data[i][j]; + } + for (let j = index + 1; j < this.columns; j++) { + newRow[j - 1] = this.data[i][j]; + } + this.data[i] = newRow; } this.columns -= 1; return this; } - /** - * Adds a column at the given index - * @param {number} [index = this.columns] - Column index - * @param {Array|Matrix} array - Array or vector - * @return {Matrix} this - */ addColumn(index, array) { if (typeof array === 'undefined') { array = index; @@ -5545,107 +5037,231 @@ class matrix_Matrix extends AbstractMatrix(Array) { } checkColumnIndex(this, index, true); array = checkColumnVector(this, array); - for (var i = 0; i < this.rows; i++) { - this[i].splice(index, 0, array[i]); + for (let i = 0; i < this.rows; i++) { + const newRow = new Float64Array(this.columns + 1); + let j = 0; + for (; j < index; j++) { + newRow[j] = this.data[i][j]; + } + newRow[j++] = array[i]; + for (; j < this.columns + 1; j++) { + newRow[j] = this.data[i][j - 1]; + } + this.data[i] = newRow; } this.columns += 1; return this; } } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/wrap/WrapperMatrix1D.js - +installMathOperations(matrix_AbstractMatrix, matrix_Matrix); +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/wrap/WrapperMatrix2D.js -class WrapperMatrix1D_WrapperMatrix1D extends AbstractMatrix() { - /** - * @class WrapperMatrix1D - * @param {Array} data - * @param {object} [options] - * @param {object} [options.rows = 1] - */ - constructor(data, options = {}) { - const { rows = 1 } = options; - if (data.length % rows !== 0) { - throw new Error('the data length is not divisible by the number of rows'); - } +class WrapperMatrix2D_WrapperMatrix2D extends matrix_AbstractMatrix { + constructor(data) { super(); - this.rows = rows; - this.columns = data.length / rows; this.data = data; + this.rows = data.length; + this.columns = data[0].length; } set(rowIndex, columnIndex, value) { - var index = this._calculateIndex(rowIndex, columnIndex); - this.data[index] = value; + this.data[rowIndex][columnIndex] = value; return this; } get(rowIndex, columnIndex) { - var index = this._calculateIndex(rowIndex, columnIndex); - return this.data[index]; + return this.data[rowIndex][columnIndex]; } +} + +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/dc/lu.js + + + +class lu_LuDecomposition { + constructor(matrix) { + matrix = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(matrix); + + let lu = matrix.clone(); + let rows = lu.rows; + let columns = lu.columns; + let pivotVector = new Float64Array(rows); + let pivotSign = 1; + let i, j, k, p, s, t, v; + let LUcolj, kmax; + + for (i = 0; i < rows; i++) { + pivotVector[i] = i; + } + + LUcolj = new Float64Array(rows); + + for (j = 0; j < columns; j++) { + for (i = 0; i < rows; i++) { + LUcolj[i] = lu.get(i, j); + } + + for (i = 0; i < rows; i++) { + kmax = Math.min(i, j); + s = 0; + for (k = 0; k < kmax; k++) { + s += lu.get(i, k) * LUcolj[k]; + } + LUcolj[i] -= s; + lu.set(i, j, LUcolj[i]); + } + + p = j; + for (i = j + 1; i < rows; i++) { + if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) { + p = i; + } + } + + if (p !== j) { + for (k = 0; k < columns; k++) { + t = lu.get(p, k); + lu.set(p, k, lu.get(j, k)); + lu.set(j, k, t); + } + + v = pivotVector[p]; + pivotVector[p] = pivotVector[j]; + pivotVector[j] = v; + + pivotSign = -pivotSign; + } + + if (j < rows && lu.get(j, j) !== 0) { + for (i = j + 1; i < rows; i++) { + lu.set(i, j, lu.get(i, j) / lu.get(j, j)); + } + } + } - _calculateIndex(row, column) { - return row * this.columns + column; + this.LU = lu; + this.pivotVector = pivotVector; + this.pivotSign = pivotSign; } - static get [Symbol.species]() { - return matrix_Matrix; + isSingular() { + let data = this.LU; + let col = data.columns; + for (let j = 0; j < col; j++) { + if (data.get(j, j) === 0) { + return true; + } + } + return false; } -} -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/wrap/WrapperMatrix2D.js + solve(value) { + value = matrix_Matrix.checkMatrix(value); + + let lu = this.LU; + let rows = lu.rows; + + if (rows !== value.rows) { + throw new Error('Invalid matrix dimensions'); + } + if (this.isSingular()) { + throw new Error('LU matrix is singular'); + } + let count = value.columns; + let X = value.subMatrixRow(this.pivotVector, 0, count - 1); + let columns = lu.columns; + let i, j, k; + for (k = 0; k < columns; k++) { + for (i = k + 1; i < columns; i++) { + for (j = 0; j < count; j++) { + X.set(i, j, X.get(i, j) - X.get(k, j) * lu.get(i, k)); + } + } + } + for (k = columns - 1; k >= 0; k--) { + for (j = 0; j < count; j++) { + X.set(k, j, X.get(k, j) / lu.get(k, k)); + } + for (i = 0; i < k; i++) { + for (j = 0; j < count; j++) { + X.set(i, j, X.get(i, j) - X.get(k, j) * lu.get(i, k)); + } + } + } + return X; + } -class WrapperMatrix2D_WrapperMatrix2D extends AbstractMatrix() { - /** - * @class WrapperMatrix2D - * @param {Array>} data - */ - constructor(data) { - super(); - this.data = data; - this.rows = data.length; - this.columns = data[0].length; + get determinant() { + let data = this.LU; + if (!data.isSquare()) { + throw new Error('Matrix must be square'); + } + let determinant = this.pivotSign; + let col = data.columns; + for (let j = 0; j < col; j++) { + determinant *= data.get(j, j); + } + return determinant; } - set(rowIndex, columnIndex, value) { - this.data[rowIndex][columnIndex] = value; - return this; + get lowerTriangularMatrix() { + let data = this.LU; + let rows = data.rows; + let columns = data.columns; + let X = new matrix_Matrix(rows, columns); + for (let i = 0; i < rows; i++) { + for (let j = 0; j < columns; j++) { + if (i > j) { + X.set(i, j, data.get(i, j)); + } else if (i === j) { + X.set(i, j, 1); + } else { + X.set(i, j, 0); + } + } + } + return X; } - get(rowIndex, columnIndex) { - return this.data[rowIndex][columnIndex]; + get upperTriangularMatrix() { + let data = this.LU; + let rows = data.rows; + let columns = data.columns; + let X = new matrix_Matrix(rows, columns); + for (let i = 0; i < rows; i++) { + for (let j = 0; j < columns; j++) { + if (i <= j) { + X.set(i, j, data.get(i, j)); + } else { + X.set(i, j, 0); + } + } + } + return X; } - static get [Symbol.species]() { - return matrix_Matrix; + get pivotPermutationVector() { + return Array.from(this.pivotVector); } } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/wrap/wrap.js - - - -/** - * @param {Array>|Array} array - * @param {object} [options] - * @param {object} [options.rows = 1] - * @return {WrapperMatrix1D|WrapperMatrix2D} - */ -function wrap(array, options) { - if (Array.isArray(array)) { - if (array[0] && Array.isArray(array[0])) { - return new WrapperMatrix2D_WrapperMatrix2D(array); - } else { - return new WrapperMatrix1D_WrapperMatrix1D(array, options); - } - } else { - throw new Error('the argument is not an array'); +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/dc/util.js +function hypotenuse(a, b) { + let r = 0; + if (Math.abs(a) > Math.abs(b)) { + r = b / a; + return Math.abs(a) * Math.sqrt(1 + r * r); + } + if (b !== 0) { + r = a / b; + return Math.abs(b) * Math.sqrt(1 + r * r); } + return 0; } // CONCATENATED MODULE: ./node_modules/ml-matrix/src/dc/qr.js @@ -5653,23 +5269,19 @@ function wrap(array, options) { -/** - * @class QrDecomposition - * @link https://github.com/lutzroeder/Mapack/blob/master/Source/QrDecomposition.cs - * @param {Matrix} value - */ + class qr_QrDecomposition { constructor(value) { value = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(value); - var qr = value.clone(); - var m = value.rows; - var n = value.columns; - var rdiag = new Array(n); - var i, j, k, s; + let qr = value.clone(); + let m = value.rows; + let n = value.columns; + let rdiag = new Float64Array(n); + let i, j, k, s; for (k = 0; k < n; k++) { - var nrm = 0; + let nrm = 0; for (i = k; i < m; i++) { nrm = hypotenuse(nrm, qr.get(i, k)); } @@ -5699,19 +5311,11 @@ class qr_QrDecomposition { this.Rdiag = rdiag; } - /** - * Solve a problem of least square (Ax=b) by using the QR decomposition. Useful when A is rectangular, but not working when A is singular. - * Example : We search to approximate x, with A matrix shape m*n, x vector size n, b vector size m (m > n). We will use : - * var qr = QrDecomposition(A); - * var x = qr.solve(b); - * @param {Matrix} value - Matrix 1D which is the vector b (in the equation Ax = b) - * @return {Matrix} - The vector x - */ solve(value) { value = matrix_Matrix.checkMatrix(value); - var qr = this.QR; - var m = qr.rows; + let qr = this.QR; + let m = qr.rows; if (value.rows !== m) { throw new Error('Matrix row dimensions must agree'); @@ -5720,30 +5324,30 @@ class qr_QrDecomposition { throw new Error('Matrix is rank deficient'); } - var count = value.columns; - var X = value.clone(); - var n = qr.columns; - var i, j, k, s; + let count = value.columns; + let X = value.clone(); + let n = qr.columns; + let i, j, k, s; for (k = 0; k < n; k++) { for (j = 0; j < count; j++) { s = 0; for (i = k; i < m; i++) { - s += qr[i][k] * X[i][j]; + s += qr.get(i, k) * X.get(i, j); } - s = -s / qr[k][k]; + s = -s / qr.get(k, k); for (i = k; i < m; i++) { - X[i][j] += s * qr[i][k]; + X.set(i, j, X.get(i, j) + s * qr.get(i, k)); } } } for (k = n - 1; k >= 0; k--) { for (j = 0; j < count; j++) { - X[k][j] /= this.Rdiag[k]; + X.set(k, j, X.get(k, j) / this.Rdiag[k]); } for (i = 0; i < k; i++) { for (j = 0; j < count; j++) { - X[i][j] -= X[k][j] * qr[i][k]; + X.set(i, j, X.get(i, j) - X.get(k, j) * qr.get(i, k)); } } } @@ -5751,13 +5355,9 @@ class qr_QrDecomposition { return X.subMatrix(0, n - 1, 0, count - 1); } - /** - * - * @return {boolean} - */ isFullRank() { - var columns = this.QR.columns; - for (var i = 0; i < columns; i++) { + let columns = this.QR.columns; + for (let i = 0; i < columns; i++) { if (this.Rdiag[i] === 0) { return false; } @@ -5765,56 +5365,48 @@ class qr_QrDecomposition { return true; } - /** - * - * @return {Matrix} - */ get upperTriangularMatrix() { - var qr = this.QR; - var n = qr.columns; - var X = new matrix_Matrix(n, n); - var i, j; + let qr = this.QR; + let n = qr.columns; + let X = new matrix_Matrix(n, n); + let i, j; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (i < j) { - X[i][j] = qr[i][j]; + X.set(i, j, qr.get(i, j)); } else if (i === j) { - X[i][j] = this.Rdiag[i]; + X.set(i, j, this.Rdiag[i]); } else { - X[i][j] = 0; + X.set(i, j, 0); } } } return X; } - /** - * - * @return {Matrix} - */ get orthogonalMatrix() { - var qr = this.QR; - var rows = qr.rows; - var columns = qr.columns; - var X = new matrix_Matrix(rows, columns); - var i, j, k, s; + let qr = this.QR; + let rows = qr.rows; + let columns = qr.columns; + let X = new matrix_Matrix(rows, columns); + let i, j, k, s; for (k = columns - 1; k >= 0; k--) { for (i = 0; i < rows; i++) { - X[i][k] = 0; + X.set(i, k, 0); } - X[k][k] = 1; + X.set(k, k, 1); for (j = k; j < columns; j++) { - if (qr[k][k] !== 0) { + if (qr.get(k, k) !== 0) { s = 0; for (i = k; i < rows; i++) { - s += qr[i][k] * X[i][j]; + s += qr.get(i, k) * X.get(i, j); } - s = -s / qr[k][k]; + s = -s / qr.get(k, k); for (i = k; i < rows; i++) { - X[i][j] += s * qr[i][k]; + X.set(i, j, X.get(i, j) + s * qr.get(i, k)); } } } @@ -5823,1061 +5415,770 @@ class qr_QrDecomposition { } } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/decompositions.js - - - - - - -/** - * Computes the inverse of a Matrix - * @param {Matrix} matrix - * @param {boolean} [useSVD=false] - * @return {Matrix} - */ -function inverse(matrix, useSVD = false) { - matrix = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(matrix); - if (useSVD) { - return new svd_SingularValueDecomposition(matrix).inverse(); - } else { - return solve(matrix, matrix_Matrix.eye(matrix.rows)); - } -} - -/** - * - * @param {Matrix} leftHandSide - * @param {Matrix} rightHandSide - * @param {boolean} [useSVD = false] - * @return {Matrix} - */ -function solve(leftHandSide, rightHandSide, useSVD = false) { - leftHandSide = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(leftHandSide); - rightHandSide = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(rightHandSide); - if (useSVD) { - return new svd_SingularValueDecomposition(leftHandSide).solve(rightHandSide); - } else { - return leftHandSide.isSquare() - ? new lu_LuDecomposition(leftHandSide).solve(rightHandSide) - : new qr_QrDecomposition(leftHandSide).solve(rightHandSide); - } -} - -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/linearDependencies.js +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/dc/svd.js -// function used by rowsDependencies -function xrange(n, exception) { - var range = []; - for (var i = 0; i < n; i++) { - if (i !== exception) { - range.push(i); - } - } - return range; -} +class svd_SingularValueDecomposition { + constructor(value, options = {}) { + value = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(value); -// function used by rowsDependencies -function dependenciesOneRow( - error, - matrix, - index, - thresholdValue = 10e-10, - thresholdError = 10e-10 -) { - if (error > thresholdError) { - return new Array(matrix.rows + 1).fill(0); - } else { - var returnArray = matrix.addRow(index, [0]); - for (var i = 0; i < returnArray.rows; i++) { - if (Math.abs(returnArray.get(i, 0)) < thresholdValue) { - returnArray.set(i, 0, 0); - } + if (value.isEmpty()) { + throw new Error('Matrix must be non-empty'); } - return returnArray.to1DArray(); - } -} - -/** - * Creates a matrix which represents the dependencies between rows. - * If a row is a linear combination of others rows, the result will be a row with the coefficients of this combination. - * For example : for A = [[2, 0, 0, 1], [0, 1, 6, 0], [0, 3, 0, 1], [0, 0, 1, 0], [0, 1, 2, 0]], the result will be [[0, 0, 0, 0, 0], [0, 0, 0, 4, 1], [0, 0, 0, 0, 0], [0, 0.25, 0, 0, -0.25], [0, 1, 0, -4, 0]] - * @param {Matrix} matrix - * @param {Object} [options] includes thresholdValue and thresholdError. - * @param {number} [options.thresholdValue = 10e-10] If an absolute value is inferior to this threshold, it will equals zero. - * @param {number} [options.thresholdError = 10e-10] If the error is inferior to that threshold, the linear combination found is accepted and the row is dependent from other rows. - * @return {Matrix} the matrix which represents the dependencies between rows. - */ - -function linearDependencies(matrix, options = {}) { - const { thresholdValue = 10e-10, thresholdError = 10e-10 } = options; - - var n = matrix.rows; - var results = new matrix_Matrix(n, n); - - for (var i = 0; i < n; i++) { - var b = matrix_Matrix.columnVector(matrix.getRow(i)); - var Abis = matrix.subMatrixRow(xrange(n, i)).transposeView(); - var svd = new svd_SingularValueDecomposition(Abis); - var x = svd.solve(b); - var error = lib_es6( - matrix_Matrix.sub(b, Abis.mmul(x)) - .abs() - .to1DArray() - ); - results.setRow( - i, - dependenciesOneRow(error, x, i, thresholdValue, thresholdError) - ); - } - return results; -} - -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/dc/evd.js - - + let m = value.rows; + let n = value.columns; -/** - * @class EigenvalueDecomposition - * @link https://github.com/lutzroeder/Mapack/blob/master/Source/EigenvalueDecomposition.cs - * @param {Matrix} matrix - * @param {object} [options] - * @param {boolean} [options.assumeSymmetric=false] - */ -class evd_EigenvalueDecomposition { - constructor(matrix, options = {}) { - const { assumeSymmetric = false } = options; - - matrix = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(matrix); - if (!matrix.isSquare()) { - throw new Error('Matrix is not a square matrix'); - } - - var n = matrix.columns; - var V = getFilled2DArray(n, n, 0); - var d = new Array(n); - var e = new Array(n); - var value = matrix; - var i, j; + const { + computeLeftSingularVectors = true, + computeRightSingularVectors = true, + autoTranspose = false, + } = options; - var isSymmetric = false; - if (assumeSymmetric) { - isSymmetric = true; - } else { - isSymmetric = matrix.isSymmetric(); - } + let wantu = Boolean(computeLeftSingularVectors); + let wantv = Boolean(computeRightSingularVectors); - if (isSymmetric) { - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - V[i][j] = value.get(i, j); - } + let swapped = false; + let a; + if (m < n) { + if (!autoTranspose) { + a = value.clone(); + // eslint-disable-next-line no-console + console.warn( + 'Computing SVD on a matrix with more columns than rows. Consider enabling autoTranspose', + ); + } else { + a = value.transpose(); + m = a.rows; + n = a.columns; + swapped = true; + let aux = wantu; + wantu = wantv; + wantv = aux; } - tred2(n, e, d, V); - tql2(n, e, d, V); } else { - var H = getFilled2DArray(n, n, 0); - var ort = new Array(n); - for (j = 0; j < n; j++) { - for (i = 0; i < n; i++) { - H[i][j] = value.get(i, j); - } - } - orthes(n, H, ort, V); - hqr2(n, e, d, V, H); - } - - this.n = n; - this.e = e; - this.d = d; - this.V = V; - } - - /** - * - * @return {Array} - */ - get realEigenvalues() { - return this.d; - } - - /** - * - * @return {Array} - */ - get imaginaryEigenvalues() { - return this.e; - } - - /** - * - * @return {Matrix} - */ - get eigenvectorMatrix() { - if (!matrix_Matrix.isMatrix(this.V)) { - this.V = new matrix_Matrix(this.V); - } - return this.V; - } - - /** - * - * @return {Matrix} - */ - get diagonalMatrix() { - var n = this.n; - var e = this.e; - var d = this.d; - var X = new matrix_Matrix(n, n); - var i, j; - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - X[i][j] = 0; - } - X[i][i] = d[i]; - if (e[i] > 0) { - X[i][i + 1] = e[i]; - } else if (e[i] < 0) { - X[i][i - 1] = e[i]; - } + a = value.clone(); } - return X; - } -} - -function tred2(n, e, d, V) { - var f, g, h, i, j, k, hh, scale; - - for (j = 0; j < n; j++) { - d[j] = V[n - 1][j]; - } - for (i = n - 1; i > 0; i--) { - scale = 0; - h = 0; - for (k = 0; k < i; k++) { - scale = scale + Math.abs(d[k]); - } + let nu = Math.min(m, n); + let ni = Math.min(m + 1, n); + let s = new Float64Array(ni); + let U = new matrix_Matrix(m, nu); + let V = new matrix_Matrix(n, n); - if (scale === 0) { - e[i] = d[i - 1]; - for (j = 0; j < i; j++) { - d[j] = V[i - 1][j]; - V[i][j] = 0; - V[j][i] = 0; - } - } else { - for (k = 0; k < i; k++) { - d[k] /= scale; - h += d[k] * d[k]; - } + let e = new Float64Array(n); + let work = new Float64Array(m); - f = d[i - 1]; - g = Math.sqrt(h); - if (f > 0) { - g = -g; - } + let si = new Float64Array(ni); + for (let i = 0; i < ni; i++) si[i] = i; - e[i] = scale * g; - h = h - f * g; - d[i - 1] = f - g; - for (j = 0; j < i; j++) { - e[j] = 0; - } + let nct = Math.min(m - 1, n); + let nrt = Math.max(0, Math.min(n - 2, m)); + let mrc = Math.max(nct, nrt); - for (j = 0; j < i; j++) { - f = d[j]; - V[j][i] = f; - g = e[j] + V[j][j] * f; - for (k = j + 1; k <= i - 1; k++) { - g += V[k][j] * d[k]; - e[k] += V[k][j] * f; + for (let k = 0; k < mrc; k++) { + if (k < nct) { + s[k] = 0; + for (let i = k; i < m; i++) { + s[k] = hypotenuse(s[k], a.get(i, k)); } - e[j] = g; - } - - f = 0; - for (j = 0; j < i; j++) { - e[j] /= h; - f += e[j] * d[j]; - } - - hh = f / (h + h); - for (j = 0; j < i; j++) { - e[j] -= hh * d[j]; + if (s[k] !== 0) { + if (a.get(k, k) < 0) { + s[k] = -s[k]; + } + for (let i = k; i < m; i++) { + a.set(i, k, a.get(i, k) / s[k]); + } + a.set(k, k, a.get(k, k) + 1); + } + s[k] = -s[k]; } - for (j = 0; j < i; j++) { - f = d[j]; - g = e[j]; - for (k = j; k <= i - 1; k++) { - V[k][j] -= f * e[k] + g * d[k]; + for (let j = k + 1; j < n; j++) { + if (k < nct && s[k] !== 0) { + let t = 0; + for (let i = k; i < m; i++) { + t += a.get(i, k) * a.get(i, j); + } + t = -t / a.get(k, k); + for (let i = k; i < m; i++) { + a.set(i, j, a.get(i, j) + t * a.get(i, k)); + } } - d[j] = V[i - 1][j]; - V[i][j] = 0; + e[j] = a.get(k, j); } - } - d[i] = h; - } - for (i = 0; i < n - 1; i++) { - V[n - 1][i] = V[i][i]; - V[i][i] = 1; - h = d[i + 1]; - if (h !== 0) { - for (k = 0; k <= i; k++) { - d[k] = V[k][i + 1] / h; + if (wantu && k < nct) { + for (let i = k; i < m; i++) { + U.set(i, k, a.get(i, k)); + } } - for (j = 0; j <= i; j++) { - g = 0; - for (k = 0; k <= i; k++) { - g += V[k][i + 1] * V[k][j]; + if (k < nrt) { + e[k] = 0; + for (let i = k + 1; i < n; i++) { + e[k] = hypotenuse(e[k], e[i]); + } + if (e[k] !== 0) { + if (e[k + 1] < 0) { + e[k] = 0 - e[k]; + } + for (let i = k + 1; i < n; i++) { + e[i] /= e[k]; + } + e[k + 1] += 1; + } + e[k] = -e[k]; + if (k + 1 < m && e[k] !== 0) { + for (let i = k + 1; i < m; i++) { + work[i] = 0; + } + for (let i = k + 1; i < m; i++) { + for (let j = k + 1; j < n; j++) { + work[i] += e[j] * a.get(i, j); + } + } + for (let j = k + 1; j < n; j++) { + let t = -e[j] / e[k + 1]; + for (let i = k + 1; i < m; i++) { + a.set(i, j, a.get(i, j) + t * work[i]); + } + } } - for (k = 0; k <= i; k++) { - V[k][j] -= g * d[k]; + if (wantv) { + for (let i = k + 1; i < n; i++) { + V.set(i, k, e[i]); + } } } } - for (k = 0; k <= i; k++) { - V[k][i + 1] = 0; + let p = Math.min(n, m + 1); + if (nct < n) { + s[nct] = a.get(nct, nct); } - } - - for (j = 0; j < n; j++) { - d[j] = V[n - 1][j]; - V[n - 1][j] = 0; - } - - V[n - 1][n - 1] = 1; - e[0] = 0; -} - -function tql2(n, e, d, V) { - var g, h, i, j, k, l, m, p, r, dl1, c, c2, c3, el1, s, s2, iter; - - for (i = 1; i < n; i++) { - e[i - 1] = e[i]; - } - - e[n - 1] = 0; - - var f = 0; - var tst1 = 0; - var eps = Number.EPSILON; - - for (l = 0; l < n; l++) { - tst1 = Math.max(tst1, Math.abs(d[l]) + Math.abs(e[l])); - m = l; - while (m < n) { - if (Math.abs(e[m]) <= eps * tst1) { - break; - } - m++; + if (m < p) { + s[p - 1] = 0; } + if (nrt + 1 < p) { + e[nrt] = a.get(nrt, p - 1); + } + e[p - 1] = 0; - if (m > l) { - iter = 0; - do { - iter = iter + 1; - - g = d[l]; - p = (d[l + 1] - g) / (2 * e[l]); - r = hypotenuse(p, 1); - if (p < 0) { - r = -r; - } - - d[l] = e[l] / (p + r); - d[l + 1] = e[l] * (p + r); - dl1 = d[l + 1]; - h = g - d[l]; - for (i = l + 2; i < n; i++) { - d[i] -= h; + if (wantu) { + for (let j = nct; j < nu; j++) { + for (let i = 0; i < m; i++) { + U.set(i, j, 0); } - - f = f + h; - - p = d[m]; - c = 1; - c2 = c; - c3 = c; - el1 = e[l + 1]; - s = 0; - s2 = 0; - for (i = m - 1; i >= l; i--) { - c3 = c2; - c2 = c; - s2 = s; - g = c * e[i]; - h = c * p; - r = hypotenuse(p, e[i]); - e[i + 1] = s * r; - s = e[i] / r; - c = p / r; - p = c * d[i] - s * g; - d[i + 1] = h + s * (c * g + s * d[i]); - - for (k = 0; k < n; k++) { - h = V[k][i + 1]; - V[k][i + 1] = s * V[k][i] + c * h; - V[k][i] = c * V[k][i] - s * h; + U.set(j, j, 1); + } + for (let k = nct - 1; k >= 0; k--) { + if (s[k] !== 0) { + for (let j = k + 1; j < nu; j++) { + let t = 0; + for (let i = k; i < m; i++) { + t += U.get(i, k) * U.get(i, j); + } + t = -t / U.get(k, k); + for (let i = k; i < m; i++) { + U.set(i, j, U.get(i, j) + t * U.get(i, k)); + } + } + for (let i = k; i < m; i++) { + U.set(i, k, -U.get(i, k)); } + U.set(k, k, 1 + U.get(k, k)); + for (let i = 0; i < k - 1; i++) { + U.set(i, k, 0); + } + } else { + for (let i = 0; i < m; i++) { + U.set(i, k, 0); + } + U.set(k, k, 1); } - - p = -s * s2 * c3 * el1 * e[l] / dl1; - e[l] = s * p; - d[l] = c * p; - } while (Math.abs(e[l]) > eps * tst1); - } - d[l] = d[l] + f; - e[l] = 0; - } - - for (i = 0; i < n - 1; i++) { - k = i; - p = d[i]; - for (j = i + 1; j < n; j++) { - if (d[j] < p) { - k = j; - p = d[j]; } } - if (k !== i) { - d[k] = d[i]; - d[i] = p; - for (j = 0; j < n; j++) { - p = V[j][i]; - V[j][i] = V[j][k]; - V[j][k] = p; + if (wantv) { + for (let k = n - 1; k >= 0; k--) { + if (k < nrt && e[k] !== 0) { + for (let j = k + 1; j < n; j++) { + let t = 0; + for (let i = k + 1; i < n; i++) { + t += V.get(i, k) * V.get(i, j); + } + t = -t / V.get(k + 1, k); + for (let i = k + 1; i < n; i++) { + V.set(i, j, V.get(i, j) + t * V.get(i, k)); + } + } + } + for (let i = 0; i < n; i++) { + V.set(i, k, 0); + } + V.set(k, k, 1); } } - } -} - -function orthes(n, H, ort, V) { - var low = 0; - var high = n - 1; - var f, g, h, i, j, m; - var scale; - - for (m = low + 1; m <= high - 1; m++) { - scale = 0; - for (i = m; i <= high; i++) { - scale = scale + Math.abs(H[i][m - 1]); - } - if (scale !== 0) { - h = 0; - for (i = high; i >= m; i--) { - ort[i] = H[i][m - 1] / scale; - h += ort[i] * ort[i]; + let pp = p - 1; + let iter = 0; + let eps = Number.EPSILON; + while (p > 0) { + let k, kase; + for (k = p - 2; k >= -1; k--) { + if (k === -1) { + break; + } + const alpha = + Number.MIN_VALUE + eps * Math.abs(s[k] + Math.abs(s[k + 1])); + if (Math.abs(e[k]) <= alpha || Number.isNaN(e[k])) { + e[k] = 0; + break; + } } - - g = Math.sqrt(h); - if (ort[m] > 0) { - g = -g; + if (k === p - 2) { + kase = 4; + } else { + let ks; + for (ks = p - 1; ks >= k; ks--) { + if (ks === k) { + break; + } + let t = + (ks !== p ? Math.abs(e[ks]) : 0) + + (ks !== k + 1 ? Math.abs(e[ks - 1]) : 0); + if (Math.abs(s[ks]) <= eps * t) { + s[ks] = 0; + break; + } + } + if (ks === k) { + kase = 3; + } else if (ks === p - 1) { + kase = 1; + } else { + kase = 2; + k = ks; + } } - h = h - ort[m] * g; - ort[m] = ort[m] - g; + k++; - for (j = m; j < n; j++) { - f = 0; - for (i = high; i >= m; i--) { - f += ort[i] * H[i][j]; + switch (kase) { + case 1: { + let f = e[p - 2]; + e[p - 2] = 0; + for (let j = p - 2; j >= k; j--) { + let t = hypotenuse(s[j], f); + let cs = s[j] / t; + let sn = f / t; + s[j] = t; + if (j !== k) { + f = -sn * e[j - 1]; + e[j - 1] = cs * e[j - 1]; + } + if (wantv) { + for (let i = 0; i < n; i++) { + t = cs * V.get(i, j) + sn * V.get(i, p - 1); + V.set(i, p - 1, -sn * V.get(i, j) + cs * V.get(i, p - 1)); + V.set(i, j, t); + } + } + } + break; } - - f = f / h; - for (i = m; i <= high; i++) { - H[i][j] -= f * ort[i]; + case 2: { + let f = e[k - 1]; + e[k - 1] = 0; + for (let j = k; j < p; j++) { + let t = hypotenuse(s[j], f); + let cs = s[j] / t; + let sn = f / t; + s[j] = t; + f = -sn * e[j]; + e[j] = cs * e[j]; + if (wantu) { + for (let i = 0; i < m; i++) { + t = cs * U.get(i, j) + sn * U.get(i, k - 1); + U.set(i, k - 1, -sn * U.get(i, j) + cs * U.get(i, k - 1)); + U.set(i, j, t); + } + } + } + break; } - } - - for (i = 0; i <= high; i++) { - f = 0; - for (j = high; j >= m; j--) { - f += ort[j] * H[i][j]; + case 3: { + const scale = Math.max( + Math.abs(s[p - 1]), + Math.abs(s[p - 2]), + Math.abs(e[p - 2]), + Math.abs(s[k]), + Math.abs(e[k]), + ); + const sp = s[p - 1] / scale; + const spm1 = s[p - 2] / scale; + const epm1 = e[p - 2] / scale; + const sk = s[k] / scale; + const ek = e[k] / scale; + const b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2; + const c = sp * epm1 * (sp * epm1); + let shift = 0; + if (b !== 0 || c !== 0) { + if (b < 0) { + shift = 0 - Math.sqrt(b * b + c); + } else { + shift = Math.sqrt(b * b + c); + } + shift = c / (b + shift); + } + let f = (sk + sp) * (sk - sp) + shift; + let g = sk * ek; + for (let j = k; j < p - 1; j++) { + let t = hypotenuse(f, g); + if (t === 0) t = Number.MIN_VALUE; + let cs = f / t; + let sn = g / t; + if (j !== k) { + e[j - 1] = t; + } + f = cs * s[j] + sn * e[j]; + e[j] = cs * e[j] - sn * s[j]; + g = sn * s[j + 1]; + s[j + 1] = cs * s[j + 1]; + if (wantv) { + for (let i = 0; i < n; i++) { + t = cs * V.get(i, j) + sn * V.get(i, j + 1); + V.set(i, j + 1, -sn * V.get(i, j) + cs * V.get(i, j + 1)); + V.set(i, j, t); + } + } + t = hypotenuse(f, g); + if (t === 0) t = Number.MIN_VALUE; + cs = f / t; + sn = g / t; + s[j] = t; + f = cs * e[j] + sn * s[j + 1]; + s[j + 1] = -sn * e[j] + cs * s[j + 1]; + g = sn * e[j + 1]; + e[j + 1] = cs * e[j + 1]; + if (wantu && j < m - 1) { + for (let i = 0; i < m; i++) { + t = cs * U.get(i, j) + sn * U.get(i, j + 1); + U.set(i, j + 1, -sn * U.get(i, j) + cs * U.get(i, j + 1)); + U.set(i, j, t); + } + } + } + e[p - 2] = f; + iter = iter + 1; + break; } - - f = f / h; - for (j = m; j <= high; j++) { - H[i][j] -= f * ort[j]; + case 4: { + if (s[k] <= 0) { + s[k] = s[k] < 0 ? -s[k] : 0; + if (wantv) { + for (let i = 0; i <= pp; i++) { + V.set(i, k, -V.get(i, k)); + } + } + } + while (k < pp) { + if (s[k] >= s[k + 1]) { + break; + } + let t = s[k]; + s[k] = s[k + 1]; + s[k + 1] = t; + if (wantv && k < n - 1) { + for (let i = 0; i < n; i++) { + t = V.get(i, k + 1); + V.set(i, k + 1, V.get(i, k)); + V.set(i, k, t); + } + } + if (wantu && k < m - 1) { + for (let i = 0; i < m; i++) { + t = U.get(i, k + 1); + U.set(i, k + 1, U.get(i, k)); + U.set(i, k, t); + } + } + k++; + } + iter = 0; + p--; + break; } + // no default } - - ort[m] = scale * ort[m]; - H[m][m - 1] = scale * g; } - } - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - V[i][j] = i === j ? 1 : 0; + if (swapped) { + let tmp = V; + V = U; + U = tmp; } - } - - for (m = high - 1; m >= low + 1; m--) { - if (H[m][m - 1] !== 0) { - for (i = m + 1; i <= high; i++) { - ort[i] = H[i][m - 1]; - } - for (j = m; j <= high; j++) { - g = 0; - for (i = m; i <= high; i++) { - g += ort[i] * V[i][j]; - } - - g = g / ort[m] / H[m][m - 1]; - for (i = m; i <= high; i++) { - V[i][j] += g * ort[i]; - } - } - } + this.m = m; + this.n = n; + this.s = s; + this.U = U; + this.V = V; } -} -function hqr2(nn, e, d, V, H) { - var n = nn - 1; - var low = 0; - var high = nn - 1; - var eps = Number.EPSILON; - var exshift = 0; - var norm = 0; - var p = 0; - var q = 0; - var r = 0; - var s = 0; - var z = 0; - var iter = 0; - var i, j, k, l, m, t, w, x, y; - var ra, sa, vr, vi; - var notlast, cdivres; - - for (i = 0; i < nn; i++) { - if (i < low || i > high) { - d[i] = H[i][i]; - e[i] = 0; - } - - for (j = Math.max(i - 1, 0); j < nn; j++) { - norm = norm + Math.abs(H[i][j]); - } - } - - while (n >= low) { - l = n; - while (l > low) { - s = Math.abs(H[l - 1][l - 1]) + Math.abs(H[l][l]); - if (s === 0) { - s = norm; - } - if (Math.abs(H[l][l - 1]) < eps * s) { - break; - } - l--; - } - - if (l === n) { - H[n][n] = H[n][n] + exshift; - d[n] = H[n][n]; - e[n] = 0; - n--; - iter = 0; - } else if (l === n - 1) { - w = H[n][n - 1] * H[n - 1][n]; - p = (H[n - 1][n - 1] - H[n][n]) / 2; - q = p * p + w; - z = Math.sqrt(Math.abs(q)); - H[n][n] = H[n][n] + exshift; - H[n - 1][n - 1] = H[n - 1][n - 1] + exshift; - x = H[n][n]; - - if (q >= 0) { - z = p >= 0 ? p + z : p - z; - d[n - 1] = x + z; - d[n] = d[n - 1]; - if (z !== 0) { - d[n] = x - w / z; - } - e[n - 1] = 0; - e[n] = 0; - x = H[n][n - 1]; - s = Math.abs(x) + Math.abs(z); - p = x / s; - q = z / s; - r = Math.sqrt(p * p + q * q); - p = p / r; - q = q / r; - - for (j = n - 1; j < nn; j++) { - z = H[n - 1][j]; - H[n - 1][j] = q * z + p * H[n][j]; - H[n][j] = q * H[n][j] - p * z; - } - - for (i = 0; i <= n; i++) { - z = H[i][n - 1]; - H[i][n - 1] = q * z + p * H[i][n]; - H[i][n] = q * H[i][n] - p * z; - } - - for (i = low; i <= high; i++) { - z = V[i][n - 1]; - V[i][n - 1] = q * z + p * V[i][n]; - V[i][n] = q * V[i][n] - p * z; - } + solve(value) { + let Y = value; + let e = this.threshold; + let scols = this.s.length; + let Ls = matrix_Matrix.zeros(scols, scols); + + for (let i = 0; i < scols; i++) { + if (Math.abs(this.s[i]) <= e) { + Ls.set(i, i, 0); } else { - d[n - 1] = x + p; - d[n] = x + p; - e[n - 1] = z; - e[n] = -z; + Ls.set(i, i, 1 / this.s[i]); } + } - n = n - 2; - iter = 0; - } else { - x = H[n][n]; - y = 0; - w = 0; - if (l < n) { - y = H[n - 1][n - 1]; - w = H[n][n - 1] * H[n - 1][n]; - } - - if (iter === 10) { - exshift += x; - for (i = low; i <= n; i++) { - H[i][i] -= x; - } - s = Math.abs(H[n][n - 1]) + Math.abs(H[n - 1][n - 2]); - x = y = 0.75 * s; - w = -0.4375 * s * s; - } - - if (iter === 30) { - s = (y - x) / 2; - s = s * s + w; - if (s > 0) { - s = Math.sqrt(s); - if (y < x) { - s = -s; - } - s = x - w / ((y - x) / 2 + s); - for (i = low; i <= n; i++) { - H[i][i] -= s; - } - exshift += s; - x = y = w = 0.964; - } - } - - iter = iter + 1; - - m = n - 2; - while (m >= l) { - z = H[m][m]; - r = x - z; - s = y - z; - p = (r * s - w) / H[m + 1][m] + H[m][m + 1]; - q = H[m + 1][m + 1] - z - r - s; - r = H[m + 2][m + 1]; - s = Math.abs(p) + Math.abs(q) + Math.abs(r); - p = p / s; - q = q / s; - r = r / s; - if (m === l) { - break; - } - if ( - Math.abs(H[m][m - 1]) * (Math.abs(q) + Math.abs(r)) < - eps * - (Math.abs(p) * - (Math.abs(H[m - 1][m - 1]) + - Math.abs(z) + - Math.abs(H[m + 1][m + 1]))) - ) { - break; - } - m--; - } + let U = this.U; + let V = this.rightSingularVectors; + + let VL = V.mmul(Ls); + let vrows = V.rows; + let urows = U.rows; + let VLU = matrix_Matrix.zeros(vrows, urows); - for (i = m + 2; i <= n; i++) { - H[i][i - 2] = 0; - if (i > m + 2) { - H[i][i - 3] = 0; + for (let i = 0; i < vrows; i++) { + for (let j = 0; j < urows; j++) { + let sum = 0; + for (let k = 0; k < scols; k++) { + sum += VL.get(i, k) * U.get(j, k); } + VLU.set(i, j, sum); } + } - for (k = m; k <= n - 1; k++) { - notlast = k !== n - 1; - if (k !== m) { - p = H[k][k - 1]; - q = H[k + 1][k - 1]; - r = notlast ? H[k + 2][k - 1] : 0; - x = Math.abs(p) + Math.abs(q) + Math.abs(r); - if (x !== 0) { - p = p / x; - q = q / x; - r = r / x; - } - } + return VLU.mmul(Y); + } - if (x === 0) { - break; - } + solveForDiagonal(value) { + return this.solve(matrix_Matrix.diag(value)); + } - s = Math.sqrt(p * p + q * q + r * r); - if (p < 0) { - s = -s; + inverse() { + let V = this.V; + let e = this.threshold; + let vrows = V.rows; + let vcols = V.columns; + let X = new matrix_Matrix(vrows, this.s.length); + + for (let i = 0; i < vrows; i++) { + for (let j = 0; j < vcols; j++) { + if (Math.abs(this.s[j]) > e) { + X.set(i, j, V.get(i, j) / this.s[j]); } + } + } - if (s !== 0) { - if (k !== m) { - H[k][k - 1] = -s * x; - } else if (l !== m) { - H[k][k - 1] = -H[k][k - 1]; - } + let U = this.U; - p = p + s; - x = p / s; - y = q / s; - z = r / s; - q = q / p; - r = r / p; - - for (j = k; j < nn; j++) { - p = H[k][j] + q * H[k + 1][j]; - if (notlast) { - p = p + r * H[k + 2][j]; - H[k + 2][j] = H[k + 2][j] - p * z; - } + let urows = U.rows; + let ucols = U.columns; + let Y = new matrix_Matrix(vrows, urows); - H[k][j] = H[k][j] - p * x; - H[k + 1][j] = H[k + 1][j] - p * y; - } + for (let i = 0; i < vrows; i++) { + for (let j = 0; j < urows; j++) { + let sum = 0; + for (let k = 0; k < ucols; k++) { + sum += X.get(i, k) * U.get(j, k); + } + Y.set(i, j, sum); + } + } - for (i = 0; i <= Math.min(n, k + 3); i++) { - p = x * H[i][k] + y * H[i][k + 1]; - if (notlast) { - p = p + z * H[i][k + 2]; - H[i][k + 2] = H[i][k + 2] - p * r; - } + return Y; + } - H[i][k] = H[i][k] - p; - H[i][k + 1] = H[i][k + 1] - p * q; - } + get condition() { + return this.s[0] / this.s[Math.min(this.m, this.n) - 1]; + } - for (i = low; i <= high; i++) { - p = x * V[i][k] + y * V[i][k + 1]; - if (notlast) { - p = p + z * V[i][k + 2]; - V[i][k + 2] = V[i][k + 2] - p * r; - } + get norm2() { + return this.s[0]; + } - V[i][k] = V[i][k] - p; - V[i][k + 1] = V[i][k + 1] - p * q; - } - } + get rank() { + let tol = Math.max(this.m, this.n) * this.s[0] * Number.EPSILON; + let r = 0; + let s = this.s; + for (let i = 0, ii = s.length; i < ii; i++) { + if (s[i] > tol) { + r++; } } + return r; } - if (norm === 0) { - return; + get diagonal() { + return Array.from(this.s); } - for (n = nn - 1; n >= 0; n--) { - p = d[n]; - q = e[n]; + get threshold() { + return (Number.EPSILON / 2) * Math.max(this.m, this.n) * this.s[0]; + } - if (q === 0) { - l = n; - H[n][n] = 1; - for (i = n - 1; i >= 0; i--) { - w = H[i][i] - p; - r = 0; - for (j = l; j <= n; j++) { - r = r + H[i][j] * H[j][n]; - } + get leftSingularVectors() { + return this.U; + } - if (e[i] < 0) { - z = w; - s = r; - } else { - l = i; - if (e[i] === 0) { - H[i][n] = w !== 0 ? -r / w : -r / (eps * norm); - } else { - x = H[i][i + 1]; - y = H[i + 1][i]; - q = (d[i] - p) * (d[i] - p) + e[i] * e[i]; - t = (x * s - z * r) / q; - H[i][n] = t; - H[i + 1][n] = - Math.abs(x) > Math.abs(z) ? (-r - w * t) / x : (-s - y * t) / z; - } + get rightSingularVectors() { + return this.V; + } - t = Math.abs(H[i][n]); - if (eps * t * t > 1) { - for (j = i; j <= n; j++) { - H[j][n] = H[j][n] / t; - } - } - } - } - } else if (q < 0) { - l = n - 1; + get diagonalMatrix() { + return matrix_Matrix.diag(this.s); + } +} - if (Math.abs(H[n][n - 1]) > Math.abs(H[n - 1][n])) { - H[n - 1][n - 1] = q / H[n][n - 1]; - H[n - 1][n] = -(H[n][n] - p) / H[n][n - 1]; - } else { - cdivres = cdiv(0, -H[n - 1][n], H[n - 1][n - 1] - p, q); - H[n - 1][n - 1] = cdivres[0]; - H[n - 1][n] = cdivres[1]; - } +// CONCATENATED MODULE: ./node_modules/ml-matrix/src/decompositions.js - H[n][n - 1] = 0; - H[n][n] = 1; - for (i = n - 2; i >= 0; i--) { - ra = 0; - sa = 0; - for (j = l; j <= n; j++) { - ra = ra + H[i][j] * H[j][n - 1]; - sa = sa + H[i][j] * H[j][n]; - } - w = H[i][i] - p; - if (e[i] < 0) { - z = w; - r = ra; - s = sa; - } else { - l = i; - if (e[i] === 0) { - cdivres = cdiv(-ra, -sa, w, q); - H[i][n - 1] = cdivres[0]; - H[i][n] = cdivres[1]; - } else { - x = H[i][i + 1]; - y = H[i + 1][i]; - vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q; - vi = (d[i] - p) * 2 * q; - if (vr === 0 && vi === 0) { - vr = - eps * - norm * - (Math.abs(w) + - Math.abs(q) + - Math.abs(x) + - Math.abs(y) + - Math.abs(z)); - } - cdivres = cdiv( - x * r - z * ra + q * sa, - x * s - z * sa - q * ra, - vr, - vi - ); - H[i][n - 1] = cdivres[0]; - H[i][n] = cdivres[1]; - if (Math.abs(x) > Math.abs(z) + Math.abs(q)) { - H[i + 1][n - 1] = (-ra - w * H[i][n - 1] + q * H[i][n]) / x; - H[i + 1][n] = (-sa - w * H[i][n] - q * H[i][n - 1]) / x; - } else { - cdivres = cdiv(-r - y * H[i][n - 1], -s - y * H[i][n], z, q); - H[i + 1][n - 1] = cdivres[0]; - H[i + 1][n] = cdivres[1]; - } - } - t = Math.max(Math.abs(H[i][n - 1]), Math.abs(H[i][n])); - if (eps * t * t > 1) { - for (j = i; j <= n; j++) { - H[j][n - 1] = H[j][n - 1] / t; - H[j][n] = H[j][n] / t; - } - } - } - } - } - } - for (i = 0; i < nn; i++) { - if (i < low || i > high) { - for (j = i; j < nn; j++) { - V[i][j] = H[i][j]; - } - } - } - for (j = nn - 1; j >= low; j--) { - for (i = low; i <= high; i++) { - z = 0; - for (k = low; k <= Math.min(j, high); k++) { - z = z + V[i][k] * H[k][j]; - } - V[i][j] = z; - } +function inverse(matrix, useSVD = false) { + matrix = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(matrix); + if (useSVD) { + return new svd_SingularValueDecomposition(matrix).inverse(); + } else { + return solve(matrix, matrix_Matrix.eye(matrix.rows)); } } -function cdiv(xr, xi, yr, yi) { - var r, d; - if (Math.abs(yr) > Math.abs(yi)) { - r = yi / yr; - d = yr + r * yi; - return [(xr + r * xi) / d, (xi - r * xr) / d]; +function solve(leftHandSide, rightHandSide, useSVD = false) { + leftHandSide = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(leftHandSide); + rightHandSide = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(rightHandSide); + if (useSVD) { + return new svd_SingularValueDecomposition(leftHandSide).solve(rightHandSide); } else { - r = yr / yi; - d = yi + r * yr; - return [(r * xr + xi) / d, (r * xi - xr) / d]; + return leftHandSide.isSquare() + ? new lu_LuDecomposition(leftHandSide).solve(rightHandSide) + : new qr_QrDecomposition(leftHandSide).solve(rightHandSide); } } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/dc/cholesky.js +// CONCATENATED MODULE: ./node_modules/ml-levenberg-marquardt/src/step.js /** - * @class CholeskyDecomposition - * @link https://github.com/lutzroeder/Mapack/blob/master/Source/CholeskyDecomposition.cs - * @param {Matrix} value + * Difference of the matrix function over the parameters + * @ignore + * @param {{x:Array, y:Array}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ] + * @param {Array} evaluatedData - Array of previous evaluated function values + * @param {Array} params - Array of previous parameter values + * @param {number} gradientDifference - Adjustment for decrease the damping parameter + * @param {function} paramFunction - The parameters and returns a function with the independent variable as a parameter + * @return {Matrix} */ -class cholesky_CholeskyDecomposition { - constructor(value) { - value = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(value); - if (!value.isSymmetric()) { - throw new Error('Matrix is not symmetric'); - } - - var a = value; - var dimension = a.rows; - var l = new matrix_Matrix(dimension, dimension); - var positiveDefinite = true; - var i, j, k; - - for (j = 0; j < dimension; j++) { - var Lrowj = l[j]; - var d = 0; - for (k = 0; k < j; k++) { - var Lrowk = l[k]; - var s = 0; - for (i = 0; i < k; i++) { - s += Lrowk[i] * Lrowj[i]; - } - Lrowj[k] = s = (a.get(j, k) - s) / l[k][k]; - d = d + s * s; - } +function gradientFunction( + data, + evaluatedData, + params, + gradientDifference, + paramFunction, +) { + const n = params.length; + const m = data.x.length; - d = a.get(j, j) - d; + let ans = new Array(n); - positiveDefinite &= d > 0; - l[j][j] = Math.sqrt(Math.max(d, 0)); - for (k = j + 1; k < dimension; k++) { - l[j][k] = 0; - } - } + for (let param = 0; param < n; param++) { + ans[param] = new Array(m); + let auxParams = params.slice(); + auxParams[param] += gradientDifference; + let funcParam = paramFunction(auxParams); - if (!positiveDefinite) { - throw new Error('Matrix is not positive definite'); + for (let point = 0; point < m; point++) { + ans[param][point] = evaluatedData[point] - funcParam(data.x[point]); } - - this.L = l; } + return new matrix_Matrix(ans); +} - /** - * - * @param {Matrix} value - * @return {Matrix} - */ - solve(value) { - value = WrapperMatrix2D_WrapperMatrix2D.checkMatrix(value); +/** + * Matrix function over the samples + * @ignore + * @param {{x:Array, y:Array}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ] + * @param {Array} evaluatedData - Array of previous evaluated function values + * @return {Matrix} + */ +function matrixFunction(data, evaluatedData) { + const m = data.x.length; - var l = this.L; - var dimension = l.rows; + let ans = new Array(m); - if (value.rows !== dimension) { - throw new Error('Matrix dimensions do not match'); - } + for (let point = 0; point < m; point++) { + ans[point] = [data.y[point] - evaluatedData[point]]; + } - var count = value.columns; - var B = value.clone(); - var i, j, k; + return new matrix_Matrix(ans); +} - for (k = 0; k < dimension; k++) { - for (j = 0; j < count; j++) { - for (i = 0; i < k; i++) { - B[k][j] -= B[i][j] * l[k][i]; - } - B[k][j] /= l[k][k]; - } - } +/** + * Iteration for Levenberg-Marquardt + * @ignore + * @param {{x:Array, y:Array}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ] + * @param {Array} params - Array of previous parameter values + * @param {number} damping - Levenberg-Marquardt parameter + * @param {number} gradientDifference - Adjustment for decrease the damping parameter + * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter + * @return {Array} + */ +function step( + data, + params, + damping, + gradientDifference, + parameterizedFunction, +) { + let value = damping * gradientDifference * gradientDifference; + let identity = matrix_Matrix.eye(params.length, params.length, value); - for (k = dimension - 1; k >= 0; k--) { - for (j = 0; j < count; j++) { - for (i = k + 1; i < dimension; i++) { - B[k][j] -= B[i][j] * l[i][k]; - } - B[k][j] /= l[k][k]; - } - } + const func = parameterizedFunction(params); - return B; + let evaluatedData = new Float64Array(data.x.length); + for (let i = 0; i < data.x.length; i++) { + evaluatedData[i] = func(data.x[i]); } - /** - * - * @return {Matrix} - */ - get lowerTriangularMatrix() { - return this.L; - } + let gradientFunc = gradientFunction( + data, + evaluatedData, + params, + gradientDifference, + parameterizedFunction, + ); + let matrixFunc = matrixFunction(data, evaluatedData); + let inverseMatrix = inverse( + identity.add(gradientFunc.mmul(gradientFunc.transpose())), + ); + + params = new matrix_Matrix([params]); + params = params.sub( + inverseMatrix + .mmul(gradientFunc) + .mmul(matrixFunc) + .mul(gradientDifference) + .transpose(), + ); + + return params.to1DArray(); } -// CONCATENATED MODULE: ./node_modules/ml-matrix/src/index.js -/* concated harmony reexport default */__webpack_require__.d(__webpack_exports__, "default", function() { return matrix_Matrix; }); -/* concated harmony reexport Matrix */__webpack_require__.d(__webpack_exports__, "Matrix", function() { return matrix_Matrix; }); -/* concated harmony reexport abstractMatrix */__webpack_require__.d(__webpack_exports__, "abstractMatrix", function() { return AbstractMatrix; }); -/* concated harmony reexport wrap */__webpack_require__.d(__webpack_exports__, "wrap", function() { return wrap; }); -/* concated harmony reexport WrapperMatrix2D */__webpack_require__.d(__webpack_exports__, "WrapperMatrix2D", function() { return WrapperMatrix2D_WrapperMatrix2D; }); -/* concated harmony reexport WrapperMatrix1D */__webpack_require__.d(__webpack_exports__, "WrapperMatrix1D", function() { return WrapperMatrix1D_WrapperMatrix1D; }); -/* concated harmony reexport solve */__webpack_require__.d(__webpack_exports__, "solve", function() { return solve; }); -/* concated harmony reexport inverse */__webpack_require__.d(__webpack_exports__, "inverse", function() { return inverse; }); -/* concated harmony reexport linearDependencies */__webpack_require__.d(__webpack_exports__, "linearDependencies", function() { return linearDependencies; }); -/* concated harmony reexport SingularValueDecomposition */__webpack_require__.d(__webpack_exports__, "SingularValueDecomposition", function() { return svd_SingularValueDecomposition; }); -/* concated harmony reexport SVD */__webpack_require__.d(__webpack_exports__, "SVD", function() { return svd_SingularValueDecomposition; }); -/* concated harmony reexport EigenvalueDecomposition */__webpack_require__.d(__webpack_exports__, "EigenvalueDecomposition", function() { return evd_EigenvalueDecomposition; }); -/* concated harmony reexport EVD */__webpack_require__.d(__webpack_exports__, "EVD", function() { return evd_EigenvalueDecomposition; }); -/* concated harmony reexport CholeskyDecomposition */__webpack_require__.d(__webpack_exports__, "CholeskyDecomposition", function() { return cholesky_CholeskyDecomposition; }); -/* concated harmony reexport CHO */__webpack_require__.d(__webpack_exports__, "CHO", function() { return cholesky_CholeskyDecomposition; }); -/* concated harmony reexport LuDecomposition */__webpack_require__.d(__webpack_exports__, "LuDecomposition", function() { return lu_LuDecomposition; }); -/* concated harmony reexport LU */__webpack_require__.d(__webpack_exports__, "LU", function() { return lu_LuDecomposition; }); -/* concated harmony reexport QrDecomposition */__webpack_require__.d(__webpack_exports__, "QrDecomposition", function() { return qr_QrDecomposition; }); -/* concated harmony reexport QR */__webpack_require__.d(__webpack_exports__, "QR", function() { return qr_QrDecomposition; }); +// CONCATENATED MODULE: ./node_modules/ml-levenberg-marquardt/src/index.js +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return levenbergMarquardt; }); +/** + * Curve fitting algorithm + * @param {{x:Array, y:Array}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ] + * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter + * @param {object} [options] - Options object + * @param {number} [options.damping] - Levenberg-Marquardt parameter + * @param {number} [options.gradientDifference = 10e-2] - Adjustment for decrease the damping parameter + * @param {Array} [options.minValues] - Minimum allowed values for parameters + * @param {Array} [options.maxValues] - Maximum allowed values for parameters + * @param {Array} [options.initialValues] - Array of initial parameter values + * @param {number} [options.maxIterations = 100] - Maximum of allowed iterations + * @param {number} [options.errorTolerance = 10e-3] - Minimum uncertainty allowed for each point + * @return {{parameterValues: Array, parameterError: number, iterations: number}} + */ +function levenbergMarquardt( + data, + parameterizedFunction, + options = {}, +) { + let { + maxIterations = 100, + gradientDifference = 10e-2, + damping = 0, + errorTolerance = 10e-3, + minValues, + maxValues, + initialValues, + } = options; + + if (damping <= 0) { + throw new Error('The damping option must be a positive number'); + } else if (!data.x || !data.y) { + throw new Error('The data parameter must have x and y elements'); + } else if ( + !isAnyArray(data.x) || + data.x.length < 2 || + !isAnyArray(data.y) || + data.y.length < 2 + ) { + throw new Error( + 'The data parameter elements must be an array with more than 2 points', + ); + } else if (data.x.length !== data.y.length) { + throw new Error('The data parameter elements must have the same size'); + } + let parameters = + initialValues || new Array(parameterizedFunction.length).fill(1); + let parLen = parameters.length; + maxValues = maxValues || new Array(parLen).fill(Number.MAX_SAFE_INTEGER); + minValues = minValues || new Array(parLen).fill(Number.MIN_SAFE_INTEGER); + if (maxValues.length !== minValues.length) { + throw new Error('minValues and maxValues must be the same size'); + } + if (!isAnyArray(parameters)) { + throw new Error('initialValues must be an array'); + } + let error = errorCalculation(data, parameters, parameterizedFunction); + let converged = error <= errorTolerance; + let iteration; + for (iteration = 0; iteration < maxIterations && !converged; iteration++) { + parameters = step( + data, + parameters, + damping, + gradientDifference, + parameterizedFunction, + ); + for (let k = 0; k < parLen; k++) { + parameters[k] = Math.min( + Math.max(minValues[k], parameters[k]), + maxValues[k], + ); + } + error = errorCalculation(data, parameters, parameterizedFunction); + if (isNaN(error)) break; + converged = error <= errorTolerance; + } + return { + parameterValues: parameters, + parameterError: error, + iterations: iteration, + }; +} /***/ }) diff --git a/lib/umap-js.min.js b/lib/umap-js.min.js index 0860b49..b2c5fb0 100644 --- a/lib/umap-js.min.js +++ b/lib/umap-js.min.js @@ -1 +1 @@ -!function(t,r){if("object"==typeof exports&&"object"==typeof module)module.exports=r();else if("function"==typeof define&&define.amd)define([],r);else{var e=r();for(var n in e)("object"==typeof exports?exports:t)[n]=e[n]}}(window,function(){return function(t){var r={};function e(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}return e.m=t,e.c=r,e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{enumerable:!0,get:n})},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,r){if(1&r&&(t=e(t)),8&r)return t;if(4&r&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(e.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&r&&"string"!=typeof t)for(var i in t)e.d(n,i,function(r){return t[r]}.bind(null,i));return n},e.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},e.p="",e(e.s=5)}([function(t,r,e){"use strict";const n=Object.prototype.toString;t.exports=function(t){return n.call(t).endsWith("Array]")}},function(t,r,e){"use strict";var n=this&&this.__values||function(t){var r="function"==typeof Symbol&&t[Symbol.iterator],e=0;return r?r.call(t):{next:function(){return t&&e>=t.length&&(t=void 0),{value:t&&t[e++],done:!t}}}};function i(t,r){return Math.floor(r()*t)}function o(t){for(var r=[],e=0;er?t[e]:r;return r},r.max2d=function(t){for(var r=0,e=0;er?t[e][n]:r;return r},r.rejectionSample=function(t,r,e){for(var n=a(t),o=0;o=s[0])return 0;for(var h=0;h=s[0])return 0;s[0]=e,o[0]=n,a[0]=i;for(var h=0,u=0;;){var l=2*h+1,c=l+1,f=t[0][0].length;if(l>=f)break;if(c>=f){if(!(s[l]>e))break;u=l}else if(s[l]>=s[c]){if(!(ee.length;a++)1===i[a]&&n[a]=0?(i[s]=0,Math.floor(e[s])):-1}},function(t,r,e){"use strict";var n,i=this&&this.__read||function(t,r){var e="function"==typeof Symbol&&t[Symbol.iterator];if(!e)return t;var n,i,o=e.call(t),s=[];try{for(;(void 0===r||r-- >0)&&!(n=o.next()).done;)s.push(n.value)}catch(t){i={error:t}}finally{try{n&&!n.done&&(e=o.return)&&e.call(o)}finally{if(i)throw i.error}}return s},o=this&&this.__values||function(t){var r="function"==typeof Symbol&&t[Symbol.iterator],e=0;return r?r.call(t):{next:function(){return t&&e>=t.length&&(t=void 0),{value:t&&t[e++],done:!t}}}},s=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var r={};if(null!=t)for(var e in t)Object.hasOwnProperty.call(t,e)&&(r[e]=t[e]);return r.default=t,r};Object.defineProperty(r,"__esModule",{value:!0});var a=s(e(1)),h=function(){function t(t,r,e,n){if(this.entries=new Map,this.nRows=0,this.nCols=0,t.length!==r.length||t.length!==e.length)throw new Error("rows, cols and values arrays must all have the same length");this.nRows=n[0],this.nCols=n[1];for(var i=0;ir?t:r})},r.multiplyScalar=function(t,r){return t.map(function(t){return t*r})},r.eliminateZeros=function(t){for(var r=new Set,e=t.getValues(),n=t.getRows(),i=t.getCols(),o=0;or?t[e]:r;return t.map(function(t){return t/r})},n.l1=function(t){for(var r=0,e=0;e0)&&!(n=o.next()).done;)s.push(n.value)}catch(t){i={error:t}}finally{try{n&&!n.done&&(e=o.return)&&e.call(o)}finally{if(i)throw i.error}}return s},i=this&&this.__spread||function(){for(var t=[],r=0;r=t.length&&(t=void 0),{value:t&&t[e++],done:!t}}}},s=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var r={};if(null!=t)for(var e in t)Object.hasOwnProperty.call(t,e)&&(r[e]=t[e]);return r.default=t,r};Object.defineProperty(r,"__esModule",{value:!0});var a=s(e(1)),h=function(){return function(t,r,e,n){this.hyperplanes=t,this.offsets=r,this.children=e,this.indices=n}}();function u(t,r,e,n){for(var i=r,o=0;o0?0:1}r.FlatTree=h,r.makeForest=function(t,r,e,n){var o=Math.max(10,r);return a.range(e).map(function(r,e){return function(t,r,e,n){void 0===r&&(r=30);var i=a.range(t.length);return function t(r,e,n,i,o){if(void 0===n&&(n=30),e.length>n){var s=function(t,r,e){var n=t[0].length,i=a.tauRandInt(r.length,e),o=a.tauRandInt(r.length,e);o=(o+=i===o?1:0)%r.length;for(var s=r[i],h=r[o],u=0,l=a.zeros(n),c=0;c0?(g[c]=0,f+=1):(g[c]=1,m+=1)}var d=a.zeros(f),w=a.zeros(m);f=0,m=0;for(var c=0;c0){var n=[];try{for(var s=o(t),a=s.next();!a.done;a=s.next()){var h=a.value;n.push.apply(n,i(h.indices))}}catch(t){r={error:t}}finally{try{a&&!a.done&&(e=s.return)&&e.call(s)}finally{if(r)throw r.error}}return n}return[[-1]]},r.searchFlatTree=function(t,r,e){for(var n=0;r.children[n][0]>0;)n=0===u(r.hyperplanes[n],r.offsets[n],t,e)?r.children[n][0]:r.children[n][1];var i=-1*r.children[n][0];return r.indices[i]}},function(t,r,e){"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n=e(6);r.UMAP=n.UMAP},function(t,r,e){"use strict";var n=this&&this.__awaiter||function(t,r,e,n){return new(e||(e=Promise))(function(i,o){function s(t){try{h(n.next(t))}catch(t){o(t)}}function a(t){try{h(n.throw(t))}catch(t){o(t)}}function h(t){t.done?i(t.value):new e(function(r){r(t.value)}).then(s,a)}h((n=n.apply(t,r||[])).next())})},i=this&&this.__generator||function(t,r){var e,n,i,o,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function a(o){return function(a){return function(o){if(e)throw new TypeError("Generator is already executing.");for(;s;)try{if(e=1,n&&(i=2&o[0]?n.return:o[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,o[1])).done)return i;switch(n=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return s.label++,{value:o[1],done:!1};case 5:s.label++,n=o[1],o=[0];continue;case 7:o=s.ops.pop(),s.trys.pop();continue;default:if(!(i=(i=s.trys).length>0&&i[i.length-1])&&(6===o[0]||2===o[0])){s=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0)&&!(n=o.next()).done;)s.push(n.value)}catch(t){i={error:t}}finally{try{n&&!n.done&&(e=o.return)&&e.call(o)}finally{if(i)throw i.error}}return s},s=this&&this.__spread||function(){for(var t=[],r=0;r0&&i.set(o,u,c)}var f=l.transpose(i);return l.maximum(i,f)},t.prototype.transform=function(t){var r=this,e=this.X;if(void 0===e||0===e.length)throw new Error("No data has been fit.");var n=Math.floor(this.nNeighbors*this.transformQueueSize);n=Math.min(e.length,n);var i=c.initializeSearch(this.rpForest,e,t,n,this.initFromRandom,this.initFromTree,this.random),o=this.search(e,this.searchGraph,i,t),s=u.deheapSort(o),a=s.indices,h=s.weights;a=a.map(function(t){return t.slice(0,r.nNeighbors)}),h=h.map(function(t){return t.slice(0,r.nNeighbors)});var f=Math.max(0,this.localConnectivity-1),g=this.smoothKNNDistance(h,this.nNeighbors,f),p=g.sigmas,v=g.rhos,d=this.computeMembershipStrengths(a,h,p,v),w=d.rows,y=d.cols,b=d.vals,M=[t.length,e.length],x=new l.SparseMatrix(w,y,b,M),E=l.normalize(x,"l1"),R=l.getCSR(E),k=t.length,z=S(m.reshape2d(R.indices,k,this.nNeighbors),m.reshape2d(R.values,k,this.nNeighbors),this.embedding),N=this.nEpochs?this.nEpochs/3:x.nRows<=1e4?100:30,A=x.getValues().reduce(function(t,r){return r>t?r:t},0);x=x.map(function(t){return t0});if(g.length>=e){var p=Math.floor(e),v=e-p;p>0?(s[h]=g[p-1],v>1e-5&&(s[h]+=v*(g[p]-g[p-1]))):s[h]=v*g[0]}else g.length>0&&(s[h]=m.max(g));for(var d=0;d0?Math.exp(-b/c):1}if(Math.abs(w-o)<1e-5)break;w>o?c=(u+(l=c))/2:(u=c,l===1/0?c*=2:c=(u+l)/2)}if(a[h]=c,s[h]>0){var M=m.mean(f);a[h]<.001*M&&(a[h]=.001*M)}else{var x=m.mean(t.map(m.mean));a[h]<.001*x&&(a[h]=.001*x)}}return{sigmas:a,rhos:s}},t.prototype.computeMembershipStrengths=function(t,r,e,n){for(var i=t.length,o=t[0].length,s=m.zeros(i*o),a=m.zeros(i*o),h=m.zeros(i*o),u=0;u0&&(e[n]=r/i[n])}),e},t.prototype.assignOptimizationStateParameters=function(t){Object.assign(this.optimizationState,t)},t.prototype.prepareForOptimizationLoop=function(){var t=this.repulsionStrength,r=this.learningRate,e=this.negativeSampleRate,n=this.optimizationState,i=n.epochsPerSample,o=n.headEmbedding,a=n.tailEmbedding,h=o[0].length,u=o.length===a.length,l=i.map(function(t){return t/e}),c=s(l),f=s(i);this.assignOptimizationStateParameters({epochOfNextSample:f,epochOfNextNegativeSample:c,epochsPerNegativeSample:l,moveOther:u,initialAlpha:r,alpha:r,gamma:t,dim:h})},t.prototype.initializeOptimization=function(){var t=this.embedding,r=this.embedding,e=this.optimizationState,n=e.head,i=e.tail,o=e.epochsPerSample,s=this.getNEpochs(),a=this.graph.nCols,h=b(this.spread,this.minDist),u=h.a,l=h.b;this.assignOptimizationStateParameters({headEmbedding:t,tailEmbedding:r,head:n,tail:i,epochsPerSample:o,a:u,b:l,nEpochs:s,nVertices:a})},t.prototype.optimizeLayoutStep=function(t){for(var r=this.optimizationState,e=r.head,n=r.tail,i=r.headEmbedding,o=r.tailEmbedding,s=r.epochsPerSample,a=r.epochOfNextSample,h=r.epochOfNextNegativeSample,u=r.epochsPerNegativeSample,l=r.moveOther,c=r.initialAlpha,f=r.alpha,g=r.gamma,p=r.a,v=r.b,d=r.dim,b=r.nEpochs,M=r.nVertices,x=0;xt)){var S=e[x],E=n[x],R=i[S],k=o[E],z=y(R,k),N=0;z>0&&(N=-2*p*v*Math.pow(z,v-1),N/=p*Math.pow(z,v)+1);for(var A=0;A0)O=2*g*v,O/=(.001+I)*(p*Math.pow(I,v)+1);else if(S===P)continue;for(A=0;A0&&(V=w(O*(R[A]-j[A]),4)),R[A]+=V*f}}h[x]+=C*u[x]}return r.alpha=c*(1-t/b),r.currentEpoch+=1,i},t.prototype.optimizeLayoutAsync=function(t){var r=this;return void 0===t&&(t=function(){return!0}),new Promise(function(e,o){var s=function(){return n(r,void 0,void 0,function(){var r,n,a,h,u,l;return i(this,function(i){try{if(r=this.optimizationState,n=r.nEpochs,a=r.currentEpoch,this.embedding=this.optimizeLayoutStep(a),h=this.optimizationState.currentEpoch,u=!1===t(h),l=h===n,u||l)return[2,e(l)];setTimeout(function(){return s()},0)}catch(t){o(t)}return[2]})})};setTimeout(function(){return s()},0)})},t.prototype.optimizeLayout=function(t){void 0===t&&(t=function(){return!0});for(var r=!1,e=[];!r;){var n=this.optimizationState,i=n.nEpochs,o=n.currentEpoch;e=this.optimizeLayoutStep(o);var s=this.optimizationState.currentEpoch,a=!1===t(s);r=s===i||a}return e},t.prototype.getNEpochs=function(){var t=this.graph;if(this.nEpochs>0)return this.nEpochs;var r=t.nRows;return r<=2500?500:r<=5e3?400:r<=7500?300:200},t}();function v(t,r){for(var e=0,n=0;nr?r:t<-r?-r:t}function y(t,r){for(var e=0,n=0;n=r?Math.exp(-(e[i]-r)/t):n}),i={x:e,y:n},s={damping:1.5,initialValues:[.5,.5],gradientDifference:.1,maxIterations:100,errorTolerance:.01},a=g.default(i,function(t){var r=o(t,2),e=r[0],n=r[1];return function(t){return 1/(1+e*Math.pow(t,2*n))}},s).parameterValues,h=o(a,2);return{a:h[0],b:h[1]}}function M(t,r,e,n){return void 0===e&&(e=1),void 0===n&&(n=5),t.map(function(t,i,o){return-1===r[i]||-1===r[o]?t*Math.exp(-e):r[i]!==r[o]?t*Math.exp(-n):t})}function x(t){t=l.normalize(t,"max");var r=l.transpose(t),e=l.pairwiseMultiply(r,t);return t=l.add(t,l.subtract(r,e)),l.eliminateZeros(t)}function S(t,r,e){for(var n=m.zeros(t.length).map(function(t){return m.zeros(e[0].length)}),i=0;i=t.length&&(t=void 0),{value:t&&t[e++],done:!t}}}},i=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var r={};if(null!=t)for(var e in t)Object.hasOwnProperty.call(t,e)&&(r[e]=t[e]);return r.default=t,r};Object.defineProperty(r,"__esModule",{value:!0});var o=i(e(2)),s=i(e(3)),a=i(e(4)),h=i(e(1));r.makeNNDescent=function(t,r){return function(e,n,i,s,a,u,l,c){void 0===s&&(s=10),void 0===a&&(a=50),void 0===u&&(u=.001),void 0===l&&(l=.5),void 0===c&&(c=!0);for(var f=e.length,m=o.makeHeap(e.length,i),g=0;gr&&(r=t[e]);return r};var s=function(t){if(!i()(t))throw new TypeError("input must be an array");if(0===t.length)throw new TypeError("input must not be empty");for(var r=t[0],e=1;e1&&void 0!==arguments[1]?arguments[1]:{};if(!i()(t))throw new TypeError("input must be an array");if(0===t.length)throw new TypeError("input must not be empty");if(void 0!==e.output){if(!i()(e.output))throw new TypeError("output option must be an array if specified");r=e.output}else r=new Array(t.length);var n=s(t),a=o(t);if(n===a)throw new RangeError("minimum and maximum input values are equal. Cannot rescale a constant array");var h=e.min,u=void 0===h?e.autoMinMax?n:0:h,l=e.max,c=void 0===l?e.autoMinMax?a:1:l;if(u>=c)throw new RangeError("min option must be smaller than max option");for(var f=(c-u)/(a-n),m=0;mMath.abs(h[i])&&(i=r);if(i!==e){for(n=0;n=0;i--){for(n=0;no?t[i][o]:i===o?1:0;return n}get upperTriangularMatrix(){for(var t=this.LU,r=t.rows,e=t.columns,n=new _(r,e),i=0;iMath.abs(r)?(e=r/t,Math.abs(t)*Math.sqrt(1+e*e)):0!==r?(e=t/r,Math.abs(r)*Math.sqrt(1+e*e)):0}function l(t,r,e){for(var n=new Array(t),i=0;i=0;t--)if(0!==v[t]){for(let r=t+1;r=0;t--){if(t0;){let t,r;for(t=R-2;t>=-1&&-1!==t;t--){const r=Number.MIN_VALUE+z*Math.abs(v[t]+Math.abs(v[t+1]));if(Math.abs(y[t])<=r||Number.isNaN(y[t])){y[t]=0;break}}if(t===R-2)r=4;else{let e;for(e=R-1;e>=t&&e!==t;e--){let r=(e!==R?Math.abs(y[e]):0)+(e!==t+1?Math.abs(y[e-1]):0);if(Math.abs(v[e])<=z*r){v[e]=0;break}}e===t?r=3:e===R-1?r=1:(r=2,t=e)}switch(t++,r){case 1:{let r=y[R-2];y[R-2]=0;for(let e=R-2;e>=t;e--){let i=u(v[e],r),o=v[e]/i,s=r/i;if(v[e]=i,e!==t&&(r=-s*y[e-1],y[e-1]=o*y[e-1]),c)for(let t=0;t=v[t+1]);){let r=v[t];if(v[t]=v[t+1],v[t+1]=r,c&&tr?i[o][e]=t[o][e]/this.s[e]:i[o][e]=0;var o=this.U,s=o.length,a=o[0].length,h=new _(e,s);for(let t=0;tt&&r++;return r}get diagonal(){return this.s}get threshold(){return Number.EPSILON/2*Math.max(this.m,this.n)*this.s[0]}get leftSingularVectors(){return _.isMatrix(this.U)||(this.U=new _(this.U)),this.U}get rightSingularVectors(){return _.isMatrix(this.V)||(this.V=new _(this.V)),this.V}get diagonalMatrix(){return _.diag(this.s)}}function f(t,r,e){var n=e?t.rows:t.rows-1;if(r<0||r>n)throw new RangeError("Row index out of range")}function m(t,r,e){var n=e?t.columns:t.columns-1;if(r<0||r>n)throw new RangeError("Column index out of range")}function g(t,r){if(r.to1DArray&&(r=r.to1DArray()),r.length!==t.columns)throw new RangeError("vector size must be the same as the number of columns");return r}function p(t,r){if(r.to1DArray&&(r=r.to1DArray()),r.length!==t.rows)throw new RangeError("vector size must be the same as the number of rows");return r}function v(t,r,e){return{row:d(t,r),column:w(t,e)}}function d(t,r){if("object"!=typeof r)throw new TypeError("unexpected type for row indices");if(r.some(r=>r<0||r>=t.rows))throw new RangeError("row indices are out of range");return Array.isArray(r)||(r=Array.from(r)),r}function w(t,r){if("object"!=typeof r)throw new TypeError("unexpected type for column indices");if(r.some(r=>r<0||r>=t.columns))throw new RangeError("column indices are out of range");return Array.isArray(r)||(r=Array.from(r)),r}function y(t,r,e,n,i){if(5!==arguments.length)throw new RangeError("expected 4 arguments");if(b("startRow",r),b("endRow",e),b("startColumn",n),b("endColumn",i),r>e||n>i||r<0||r>=t.rows||e<0||e>=t.rows||n<0||n>=t.columns||i<0||i>=t.columns)throw new RangeError("Submatrix indices are out of range")}function b(t,r){if("number"!=typeof r)throw new TypeError(`${t} must be a number`)}class M extends(C()){constructor(t,r,e){super(),this.matrix=t,this.rows=r,this.columns=e}static get[Symbol.species](){return _}}class x extends M{constructor(t){super(t,t.columns,t.rows)}set(t,r,e){return this.matrix.set(r,t,e),this}get(t,r){return this.matrix.get(r,t)}}class S extends M{constructor(t,r){super(t,1,t.columns),this.row=r}set(t,r,e){return this.matrix.set(this.row,r,e),this}get(t,r){return this.matrix.get(this.row,r)}}class E extends M{constructor(t,r,e,n,i){y(t,r,e,n,i),super(t,e-r+1,i-n+1),this.startRow=r,this.startColumn=n}set(t,r,e){return this.matrix.set(this.startRow+t,this.startColumn+r,e),this}get(t,r){return this.matrix.get(this.startRow+t,this.startColumn+r)}}class R extends M{constructor(t,r,e){var n=v(t,r,e);super(t,n.row.length,n.column.length),this.rowIndices=n.row,this.columnIndices=n.column}set(t,r,e){return this.matrix.set(this.rowIndices[t],this.columnIndices[r],e),this}get(t,r){return this.matrix.get(this.rowIndices[t],this.columnIndices[r])}}class k extends M{constructor(t,r){super(t,(r=d(t,r)).length,t.columns),this.rowIndices=r}set(t,r,e){return this.matrix.set(this.rowIndices[t],r,e),this}get(t,r){return this.matrix.get(this.rowIndices[t],r)}}class z extends M{constructor(t,r){r=w(t,r),super(t,t.rows,r.length),this.columnIndices=r}set(t,r,e){return this.matrix.set(t,this.columnIndices[r],e),this}get(t,r){return this.matrix.get(t,this.columnIndices[r])}}class N extends M{constructor(t,r){super(t,t.rows,1),this.column=r}set(t,r,e){return this.matrix.set(t,this.column,e),this}get(t){return this.matrix.get(t,this.column)}}class A extends M{constructor(t){super(t,t.rows,t.columns)}set(t,r,e){return this.matrix.set(this.rows-t-1,r,e),this}get(t,r){return this.matrix.get(this.rows-t-1,r)}}class V extends M{constructor(t){super(t,t.rows,t.columns)}set(t,r,e){return this.matrix.set(t,this.columns-r-1,e),this}get(t,r){return this.matrix.get(t,this.columns-r-1)}}function C(t){void 0===t&&(t=Object);class r extends t{static get[Symbol.species](){return this}static from1DArray(t,r,e){if(t*r!==e.length)throw new RangeError("Data length does not match given dimensions");for(var n=new this(t,r),i=0;it&&(t=this.get(r,e));return t}maxIndex(){for(var t=this.get(0,0),r=[0,0],e=0;et&&(t=this.get(e,n),r[0]=e,r[1]=n);return r}min(){for(var t=this.get(0,0),r=0;rr&&(r=this.get(t,e));return r}maxRowIndex(t){f(this,t);for(var r=this.get(t,0),e=[t,0],n=1;nr&&(r=this.get(t,n),e[1]=n);return e}minRow(t){f(this,t);for(var r=this.get(t,0),e=1;er&&(r=this.get(e,t));return r}maxColumnIndex(t){m(this,t);for(var r=this.get(0,t),e=[0,t],n=1;nr&&(r=this.get(n,t),e[0]=n);return e}minColumn(t){m(this,t);for(var r=this.get(0,t),e=1;e=(r=void 0===r?1:r))throw new RangeError("min should be strictly smaller than max");for(var e=this.constructor.empty(this.rows,this.columns),n=0;n=(r=void 0===r?1:r))throw new RangeError("min should be strictly smaller than max");for(var e=this.constructor.empty(this.rows,this.columns),n=0;ne||r<0||r>=this.columns||e<0||e>=this.columns)throw new RangeError("Argument out of range");for(var n=new this.constructor[Symbol.species](t.length,e-r+1),i=0;i=this.rows)throw new RangeError(`Row index out of range: ${t[i]}`);n.set(i,o-r,this.get(t[i],o))}return n}subMatrixColumn(t,r,e){if(void 0===r&&(r=0),void 0===e&&(e=this.rows-1),r>e||r<0||r>=this.rows||e<0||e>=this.rows)throw new RangeError("Argument out of range");for(var n=new this.constructor[Symbol.species](e-r+1,t.length),i=0;i=this.columns)throw new RangeError(`Column index out of range: ${t[i]}`);n.set(o-r,i,this.get(o,t[i]))}return n}setSubMatrix(t,r,e){y(this,r,r+(t=this.constructor.checkMatrix(t)).rows-1,e,e+t.columns-1);for(var n=0;nt?i[o]=1/i[o]:i[o]=0;return i=this.constructor[Symbol.species].diag(i),n.mmul(i.mmul(e.transposeView()))}clone(){for(var t=new this.constructor[Symbol.species](this.rows,this.columns),r=0;r>","signPropagatingRightShift"],[">>>","rightShift","zeroFillRightShift"]]){var u=o($("\n(function %name%(value) {\n if (typeof value === 'number') return this.%name%S(value);\n return this.%name%M(value);\n})\n",{name:s[1],op:s[0]})),l=o($("\n(function %name%S(value) {\n for (var i = 0; i < this.rows; i++) {\n for (var j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) %op% value);\n }\n }\n return this;\n})\n",{name:`${s[1]}S`,op:s[0]})),d=o($("\n(function %name%M(matrix) {\n matrix = this.constructor.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (var i = 0; i < this.rows; i++) {\n for (var j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) %op% matrix.get(i, j));\n }\n }\n return this;\n})\n",{name:`${s[1]}M`,op:s[0]})),w=o($("\n(function %name%(matrix, value) {\n var newMatrix = new this[Symbol.species](matrix);\n return newMatrix.%name%(value);\n})\n",{name:s[1]}));for(n=1;n0){if(super(t),!(Number.isInteger(r)&&r>0))throw new TypeError("nColumns must be a positive integer");for(e=0;e=0;o--){for(i=0;i=0;e--){for(t=0;ti)return new Array(r.rows+1).fill(0);for(var o=r.addRow(e,[0]),s=0;s0;a--){for(c=0,s=0,u=0;u0&&(o=-o),r[a]=c*o,s-=i*o,e[a-1]=i-o,h=0;hl){0;do{for(1,i=e[l],f=(e[l+1]-i)/(2*r[l]),m=u(f,1),f<0&&(m=-m),e[l]=r[l]/(f+m),e[l+1]=r[l]*(f+m),g=e[l+1],o=i-e[l],s=l+2;s=l;s--)for(d=v,v=p,b=y,i=p*r[s],o=p*f,m=u(f,r[s]),r[s+1]=y*m,y=r[s]/m,f=(p=f/m)*e[s]-y*i,e[s+1]=o+y*(p*i+y*e[s]),h=0;hS*x)}e[l]=e[l]+M,r[l]=0}for(s=0;s=u;a--)e[a]=r[a][u-1]/l,s+=e[a]*e[a];for(o=Math.sqrt(s),e[u]>0&&(o=-o),s-=e[u]*o,e[u]=e[u]-o,h=u;h=u;a--)i+=e[a]*r[a][h];for(i/=s,a=u;a<=c;a++)r[a][h]-=i*e[a]}for(a=0;a<=c;a++){for(i=0,h=c;h>=u;h--)i+=e[h]*r[a][h];for(i/=s,h=u;h<=c;h++)r[a][h]-=i*e[h]}e[u]=l*e[u],r[u][u-1]=l*o}}for(a=0;a=1;u--)if(0!==r[u][u-1]){for(a=u+1;a<=c;a++)e[a]=r[a][u-1];for(h=u;h<=c;h++){for(o=0,a=u;a<=c;a++)o+=e[a]*n[a][h];for(o=o/e[u]/r[u][u-1],a=u;a<=c;a++)n[a][h]+=o*e[a]}}}(o,f,m,s),function(t,r,e,n,i){var o,s,a,h,u,l,c,f,m,g,p,v,d,w,y,b=t-1,M=t-1,x=Number.EPSILON,S=0,E=0,R=0,k=0,z=0,N=0,A=0,V=0;for(o=0;oM)&&(e[o]=i[o][o],r[o]=0),s=Math.max(o-1,0);s=0;){for(h=b;h>0&&(0===(N=Math.abs(i[h-1][h-1])+Math.abs(i[h][h]))&&(N=E),!(Math.abs(i[h][h-1])=0){for(A=R>=0?R+A:R-A,e[b-1]=f+A,e[b]=e[b-1],0!==A&&(e[b]=f-c/A),r[b-1]=0,r[b]=0,f=i[b][b-1],N=Math.abs(f)+Math.abs(A),R=f/N,k=A/N,z=Math.sqrt(R*R+k*k),R/=z,k/=z,s=b-1;s0){for(N=Math.sqrt(N),m=h&&(A=i[u][u],R=((z=f-A)*(N=m-A)-c)/i[u+1][u]+i[u][u+1],k=i[u+1][u+1]-A-z-N,z=i[u+2][u+1],N=Math.abs(R)+Math.abs(k)+Math.abs(z),R/=N,k/=N,z/=N,u!==h)&&!(Math.abs(i[u][u-1])*(Math.abs(k)+Math.abs(z))u+2&&(i[o][o-3]=0);for(a=u;a<=b-1&&(w=a!==b-1,a!==u&&(R=i[a][a-1],k=i[a+1][a-1],z=w?i[a+2][a-1]:0,0!==(f=Math.abs(R)+Math.abs(k)+Math.abs(z))&&(R/=f,k/=f,z/=f)),0!==f);a++)if(N=Math.sqrt(R*R+k*k+z*z),R<0&&(N=-N),0!==N){for(a!==u?i[a][a-1]=-N*f:h!==u&&(i[a][a-1]=-i[a][a-1]),f=(R+=N)/N,m=k/N,A=z/N,k/=R,z/=R,s=a;s=0;b--)if(R=e[b],0===(k=r[b]))for(h=b,i[b][b]=1,o=b-1;o>=0;o--){for(c=i[o][o]-R,z=0,s=h;s<=b;s++)z+=i[o][s]*i[s][b];if(r[o]<0)A=c,N=z;else if(h=o,0===r[o]?i[o][b]=0!==c?-z/c:-z/(x*E):(f=i[o][o+1],m=i[o+1][o],k=(e[o]-R)*(e[o]-R)+r[o]*r[o],l=(f*N-A*z)/k,i[o][b]=l,i[o+1][b]=Math.abs(f)>Math.abs(A)?(-z-c*l)/f:(-N-m*l)/A),l=Math.abs(i[o][b]),x*l*l>1)for(s=o;s<=b;s++)i[s][b]=i[s][b]/l}else if(k<0)for(h=b-1,Math.abs(i[b][b-1])>Math.abs(i[b-1][b])?(i[b-1][b-1]=k/i[b][b-1],i[b-1][b]=-(i[b][b]-R)/i[b][b-1]):(y=$(0,-i[b-1][b],i[b-1][b-1]-R,k),i[b-1][b-1]=y[0],i[b-1][b]=y[1]),i[b][b-1]=0,i[b][b]=1,o=b-2;o>=0;o--){for(g=0,p=0,s=h;s<=b;s++)g+=i[o][s]*i[s][b-1],p+=i[o][s]*i[s][b];if(c=i[o][o]-R,r[o]<0)A=c,z=g,N=p;else if(h=o,0===r[o]?(y=$(-g,-p,c,k),i[o][b-1]=y[0],i[o][b]=y[1]):(f=i[o][o+1],m=i[o+1][o],v=(e[o]-R)*(e[o]-R)+r[o]*r[o]-k*k,d=2*(e[o]-R)*k,0===v&&0===d&&(v=x*E*(Math.abs(c)+Math.abs(k)+Math.abs(f)+Math.abs(m)+Math.abs(A))),y=$(f*z-A*g+k*p,f*N-A*p-k*g,v,d),i[o][b-1]=y[0],i[o][b]=y[1],Math.abs(f)>Math.abs(A)+Math.abs(k)?(i[o+1][b-1]=(-g-c*i[o][b-1]+k*i[o][b])/f,i[o+1][b]=(-p-c*i[o][b]-k*i[o][b-1])/f):(y=$(-z-m*i[o][b-1],-N-m*i[o][b],A,k),i[o+1][b-1]=y[0],i[o+1][b]=y[1])),l=Math.max(Math.abs(i[o][b-1]),Math.abs(i[o][b])),x*l*l>1)for(s=o;s<=b;s++)i[s][b-1]=i[s][b-1]/l,i[s][b]=i[s][b]/l}for(o=0;oM)for(s=o;s=0;s--)for(o=0;o<=M;o++){for(A=0,a=0;a<=Math.min(s,M);a++)A+=n[o][a]*i[a][s];n[o][s]=A}}(o,h,a,s,f)}this.n=o,this.e=h,this.d=a,this.V=s}get realEigenvalues(){return this.d}get imaginaryEigenvalues(){return this.e}get eigenvectorMatrix(){return _.isMatrix(this.V)||(this.V=new _(this.V)),this.V}get diagonalMatrix(){var t,r,e=this.n,n=this.e,i=this.d,o=new _(e,e);for(t=0;t0?o[t][t+1]=n[t]:n[t]<0&&(o[t][t-1]=n[t])}return o}}function $(t,r,e,n){var i,o;return Math.abs(e)>Math.abs(n)?[(t+(i=n/e)*r)/(o=e+i*n),(r-i*t)/o]:[((i=e/n)*t+r)/(o=n+i*e),(i*r-t)/o]}class Q{constructor(t){if(!(t=j.checkMatrix(t)).isSymmetric())throw new Error("Matrix is not symmetric");var r,e,n,i=t,o=i.rows,s=new _(o,o),a=!0;for(e=0;e0,s[e][e]=Math.sqrt(Math.max(u,0)),n=e+1;n=0;o--)for(i=0;i=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};function o(t,e){return Math.floor(e()*t)}function i(t){for(var e=[],r=0;re?t[r]:e;return e},e.max2d=function(t){for(var e=0,r=0;re?t[r][n]:e;return e},e.rejectionSample=function(t,e,r){for(var n=a(t),i=0;i=s[0])return 0;for(var a=0;a=s[0])return 0;s[0]=r,i[0]=n,a[0]=o;for(var h=0,u=0;;){var l=2*h+1,f=l+1,c=t[0][0].length;if(l>=c)break;if(f>=c){if(!(s[l]>r))break;u=l}else if(s[l]>=s[f]){if(!(rr.length;a++)1===o[a]&&n[a]=0?(o[s]=0,Math.floor(r[s])):-1}},function(t,e,r){"use strict";var n,o=this&&this.__createBinding||(Object.create?function(t,e,r,n){void 0===n&&(n=r),Object.defineProperty(t,n,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,n){void 0===n&&(n=r),t[n]=e[r]}),i=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),s=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)"default"!==r&&Object.hasOwnProperty.call(t,r)&&o(e,t,r);return i(e,t),e},a=this&&this.__read||function(t,e){var r="function"==typeof Symbol&&t[Symbol.iterator];if(!r)return t;var n,o,i=r.call(t),s=[];try{for(;(void 0===e||e-- >0)&&!(n=i.next()).done;)s.push(n.value)}catch(t){o={error:t}}finally{try{n&&!n.done&&(r=i.return)&&r.call(i)}finally{if(o)throw o.error}}return s},h=this&&this.__values||function(t){var e="function"==typeof Symbol&&Symbol.iterator,r=e&&t[e],n=0;if(r)return r.call(t);if(t&&"number"==typeof t.length)return{next:function(){return t&&n>=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};Object.defineProperty(e,"__esModule",{value:!0}),e.getCSR=e.normalize=e.eliminateZeros=e.multiplyScalar=e.maximum=e.subtract=e.add=e.pairwiseMultiply=e.identity=e.transpose=e.SparseMatrix=void 0;var u=s(r(0)),l=function(){function t(t,e,r,n){if(this.entries=new Map,this.nRows=0,this.nCols=0,t.length!==e.length||t.length!==r.length)throw new Error("rows, cols and values arrays must all have the same length");this.nRows=n[0],this.nCols=n[1];for(var o=0;oe?t:e}))},e.multiplyScalar=function(t,e){return t.map((function(t){return t*e}))},e.eliminateZeros=function(t){for(var e=new Set,r=t.getValues(),n=t.getRows(),o=t.getCols(),i=0;ie?t[r]:e;return t.map((function(t){return t/e}))},n.l1=function(t){for(var e=0,r=0;r0)&&!(n=i.next()).done;)s.push(n.value)}catch(t){o={error:t}}finally{try{n&&!n.done&&(r=i.return)&&r.call(i)}finally{if(o)throw o.error}}return s},a=this&&this.__spread||function(){for(var t=[],e=0;e=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};Object.defineProperty(e,"__esModule",{value:!0}),e.searchFlatTree=e.makeLeafArray=e.makeForest=e.FlatTree=void 0;var u=i(r(0)),l=function(t,e,r,n){this.hyperplanes=t,this.offsets=e,this.children=r,this.indices=n};function f(t,e,r,n){for(var o=e,i=0;i0?0:1}e.FlatTree=l,e.makeForest=function(t,e,r,n){var o=Math.max(10,e);return u.range(r).map((function(e,r){return function(t,e,r,n){void 0===e&&(e=30);var o=u.range(t.length);return function t(e,r,n,o,i){void 0===n&&(n=30);if(r.length>n){var s=function(t,e,r){var n=t[0].length,o=u.tauRandInt(e.length,r),i=u.tauRandInt(e.length,r);i=(i+=o===i?1:0)%e.length;for(var s=e[o],a=e[i],h=0,l=u.zeros(n),f=0;f0?(p[f]=0,c+=1):(p[f]=1,m+=1)}var d=u.zeros(c),y=u.zeros(m);c=0,m=0;for(f=0;f0){var n=[];try{for(var o=h(t),i=o.next();!i.done;i=o.next()){var s=i.value;n.push.apply(n,a(s.indices))}}catch(t){e={error:t}}finally{try{i&&!i.done&&(r=o.return)&&r.call(o)}finally{if(e)throw e.error}}return n}return[[-1]]},e.searchFlatTree=function(t,e,r){for(var n=0;e.children[n][0]>0;){n=0===f(e.hyperplanes[n],e.offsets[n],t,r)?e.children[n][0]:e.children[n][1]}var o=-1*e.children[n][0];return e.indices[o]}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=r(5);Object.defineProperty(e,"UMAP",{enumerable:!0,get:function(){return n.UMAP}})},function(t,e,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(t,e,r,n){void 0===n&&(n=r),Object.defineProperty(t,n,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,n){void 0===n&&(n=r),t[n]=e[r]}),o=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),i=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)"default"!==r&&Object.hasOwnProperty.call(t,r)&&n(e,t,r);return o(e,t),e},s=this&&this.__awaiter||function(t,e,r,n){return new(r||(r=Promise))((function(o,i){function s(t){try{h(n.next(t))}catch(t){i(t)}}function a(t){try{h(n.throw(t))}catch(t){i(t)}}function h(t){var e;t.done?o(t.value):(e=t.value,e instanceof r?e:new r((function(t){t(e)}))).then(s,a)}h((n=n.apply(t,e||[])).next())}))},a=this&&this.__generator||function(t,e){var r,n,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;s;)try{if(r=1,n&&(o=2&i[0]?n.return:i[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,i[1])).done)return o;switch(n=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,n=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(n=i.next()).done;)s.push(n.value)}catch(t){o={error:t}}finally{try{n&&!n.done&&(r=i.return)&&r.call(i)}finally{if(o)throw o.error}}return s},u=this&&this.__spread||function(){for(var t=[],e=0;e0&&o.set(i,u,l)}var f=c.transpose(o);return c.maximum(o,f)},t.prototype.transform=function(t){var e=this,r=this.X;if(void 0===r||0===r.length)throw new Error("No data has been fit.");var n=Math.floor(this.nNeighbors*this.transformQueueSize);n=Math.min(r.length,n);var o=m.initializeSearch(this.rpForest,r,t,n,this.initFromRandom,this.initFromTree,this.random),i=this.search(r,this.searchGraph,o,t),s=f.deheapSort(i),a=s.indices,h=s.weights;a=a.map((function(t){return t.slice(0,e.nNeighbors)})),h=h.map((function(t){return t.slice(0,e.nNeighbors)}));var u=Math.max(0,this.localConnectivity-1),l=this.smoothKNNDistance(h,this.nNeighbors,u),p=l.sigmas,w=l.rhos,d=this.computeMembershipStrengths(a,h,p,w),y=d.rows,v=d.cols,b=d.vals,M=[t.length,r.length],S=new c.SparseMatrix(y,v,b,M),x=c.normalize(S,"l1"),E=c.getCSR(x),k=t.length,N=R(g.reshape2d(E.indices,k,this.nNeighbors),g.reshape2d(E.values,k,this.nNeighbors),this.embedding),z=this.nEpochs?this.nEpochs/3:S.nRows<=1e4?100:30,_=S.getValues().reduce((function(t,e){return e>t?e:t}),0);S=S.map((function(t){return t<_/z?0:t})),S=c.eliminateZeros(S);var A=this.makeEpochsPerSample(S.getValues(),z),P=S.getRows(),j=S.getCols();return this.assignOptimizationStateParameters({headEmbedding:N,tailEmbedding:this.embedding,head:P,tail:j,currentEpoch:0,nEpochs:z,nVertices:S.getDims()[1],epochsPerSample:A}),this.prepareForOptimizationLoop(),this.optimizeLayout()},t.prototype.processGraphForSupervisedProjection=function(){var t=this.Y,e=this.X;if(t){if(t.length!==e.length)throw new Error("Length of X and y must be equal");if("categorical"===this.targetMetric){var r=this.targetWeight<1?1/(1-this.targetWeight)*2.5:1e12;this.graph=this.categoricalSimplicialSetIntersection(this.graph,t,r)}}},t.prototype.step=function(){var t=this.optimizationState.currentEpoch;return t0}));if(m.length>=r){var p=Math.floor(r),w=r-p;p>0?(s[h]=m[p-1],w>1e-5&&(s[h]+=w*(m[p]-m[p-1]))):s[h]=w*m[0]}else m.length>0&&(s[h]=g.max(m));for(var d=0;d0?Math.exp(-b/f):1}if(Math.abs(y-i)<1e-5)break;y>i?f=(u+(l=f))/2:(u=f,l===1/0?f*=2:f=(u+l)/2)}if(a[h]=f,s[h]>0){var M=g.mean(c);a[h]<.001*M&&(a[h]=.001*M)}else{var S=g.mean(t.map(g.mean));a[h]<.001*S&&(a[h]=.001*S)}}return{sigmas:a,rhos:s}},t.prototype.computeMembershipStrengths=function(t,e,r,n){for(var o=t.length,i=t[0].length,s=g.zeros(o*i),a=g.zeros(o*i),h=g.zeros(o*i),u=0;u0&&(r[n]=e/o[n])})),r},t.prototype.assignOptimizationStateParameters=function(t){Object.assign(this.optimizationState,t)},t.prototype.prepareForOptimizationLoop=function(){var t=this.repulsionStrength,e=this.learningRate,r=this.negativeSampleRate,n=this.optimizationState,o=n.epochsPerSample,i=n.headEmbedding,s=n.tailEmbedding,a=i[0].length,h=i.length===s.length,l=o.map((function(t){return t/r})),f=u(l),c=u(o);this.assignOptimizationStateParameters({epochOfNextSample:c,epochOfNextNegativeSample:f,epochsPerNegativeSample:l,moveOther:h,initialAlpha:e,alpha:e,gamma:t,dim:a})},t.prototype.initializeOptimization=function(){var t=this.embedding,e=this.embedding,r=this.optimizationState,n=r.head,o=r.tail,i=r.epochsPerSample,s=this.getNEpochs(),a=this.graph.nCols,h=S(this.spread,this.minDist),u=h.a,l=h.b;this.assignOptimizationStateParameters({headEmbedding:t,tailEmbedding:e,head:n,tail:o,epochsPerSample:i,a:u,b:l,nEpochs:s,nVertices:a})},t.prototype.optimizeLayoutStep=function(t){for(var e=this.optimizationState,r=e.head,n=e.tail,o=e.headEmbedding,i=e.tailEmbedding,s=e.epochsPerSample,a=e.epochOfNextSample,h=e.epochOfNextNegativeSample,u=e.epochsPerNegativeSample,l=e.moveOther,f=e.initialAlpha,c=e.alpha,m=e.gamma,p=e.a,w=e.b,d=e.dim,y=e.nEpochs,v=e.nVertices,S=0;St)){var x=r[S],E=n[S],R=o[x],k=i[E],N=M(R,k),z=0;N>0&&(z=-2*p*w*Math.pow(N,w-1),z/=p*Math.pow(N,w)+1);for(var _=0;_0)I=2*m*w,I/=(.001+T)*(p*Math.pow(T,w)+1);else if(x===O)continue;for(_=0;_0&&(A=b(I*(R[_]-C[_]),4)),R[_]+=A*c}}h[S]+=P*u[S]}return e.alpha=f*(1-t/y),e.currentEpoch+=1,o},t.prototype.optimizeLayoutAsync=function(t){var e=this;return void 0===t&&(t=function(){return!0}),new Promise((function(r,n){var o=function(){return s(e,void 0,void 0,(function(){var e,i,s,h,u,l;return a(this,(function(a){try{if(e=this.optimizationState,i=e.nEpochs,s=e.currentEpoch,this.embedding=this.optimizeLayoutStep(s),h=this.optimizationState.currentEpoch,u=!1===t(h),l=h===i,u||l)return[2,r(l)];setTimeout((function(){return o()}),0)}catch(t){n(t)}return[2]}))}))};setTimeout((function(){return o()}),0)}))},t.prototype.optimizeLayout=function(t){void 0===t&&(t=function(){return!0});for(var e=!1,r=[];!e;){var n=this.optimizationState,o=n.nEpochs,i=n.currentEpoch;r=this.optimizeLayoutStep(i);var s=this.optimizationState.currentEpoch,a=!1===t(s);e=s===o||a}return r},t.prototype.getNEpochs=function(){var t=this.graph;if(this.nEpochs>0)return this.nEpochs;var e=t.nRows;return e<=2500?500:e<=5e3?400:e<=7500?300:200},t}();function y(t,e){for(var r=0,n=0;ne?e:t<-e?-e:t}function M(t,e){for(var r=0,n=0;n=e?Math.exp(-(r[o]-e)/t):n})),o={x:r,y:n},i={damping:1.5,initialValues:[.5,.5],gradientDifference:.1,maxIterations:100,errorTolerance:.01},s=w.default(o,(function(t){var e=h(t,2),r=e[0],n=e[1];return function(t){return 1/(1+r*Math.pow(t,2*n))}}),i).parameterValues,a=h(s,2);return{a:a[0],b:a[1]}}function x(t,e,r,n){return void 0===r&&(r=1),void 0===n&&(n=5),t.map((function(t,o,i){return-1===e[o]||-1===e[i]?t*Math.exp(-r):e[o]!==e[i]?t*Math.exp(-n):t}))}function E(t){t=c.normalize(t,"max");var e=c.transpose(t),r=c.pairwiseMultiply(e,t);return t=c.add(t,c.subtract(e,r)),c.eliminateZeros(t)}function R(t,e,r){for(var n=g.zeros(t.length).map((function(t){return g.zeros(r[0].length)})),o=0;o=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};Object.defineProperty(e,"__esModule",{value:!0}),e.initializeSearch=e.makeInitializedNNSearch=e.makeInitializations=e.makeNNDescent=void 0;var a=i(r(1)),h=i(r(2)),u=i(r(3)),l=i(r(0));e.makeNNDescent=function(t,e){return function(r,n,o,i,s,h,u,f){void 0===i&&(i=10),void 0===s&&(s=50),void 0===h&&(h=.001),void 0===u&&(u=.5),void 0===f&&(f=!0);for(var c=r.length,m=a.makeHeap(r.length,o),p=0;p1&&void 0!==arguments[1]?arguments[1]:{};if(!u(t))throw new TypeError("input must be an array");if(0===t.length)throw new TypeError("input must not be empty");var r=e.fromIndex,n=void 0===r?0:r,o=e.toIndex,i=void 0===o?t.length:o;if(n<0||n>=t.length||!Number.isInteger(n))throw new Error("fromIndex must be a positive integer smaller than length");if(i<=n||i>t.length||!Number.isInteger(i))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var s=t[n],a=n+1;as&&(s=t[a]);return s};const f=Object.prototype.toString;function c(t){return f.call(t).endsWith("Array]")}var m=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!c(t))throw new TypeError("input must be an array");if(0===t.length)throw new TypeError("input must not be empty");var r=e.fromIndex,n=void 0===r?0:r,o=e.toIndex,i=void 0===o?t.length:o;if(n<0||n>=t.length||!Number.isInteger(n))throw new Error("fromIndex must be a positive integer smaller than length");if(i<=n||i>t.length||!Number.isInteger(i))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var s=t[n],a=n+1;a1&&void 0!==arguments[1]?arguments[1]:{};if(!a(t))throw new TypeError("input must be an array");if(0===t.length)throw new TypeError("input must not be empty");if(void 0!==r.output){if(!a(r.output))throw new TypeError("output option must be an array if specified");e=r.output}else e=new Array(t.length);var n=m(t),o=l(t);if(n===o)throw new RangeError("minimum and maximum input values are equal. Cannot rescale a constant array");var i=r.min,s=void 0===i?r.autoMinMax?n:0:i,h=r.max,u=void 0===h?r.autoMinMax?o:1:h;if(s>=u)throw new RangeError("min option must be smaller than max option");for(var f=(u-s)/(o-n),c=0;cn)throw new RangeError("Row index out of range")}function b(t,e,r){let n=r?t.columns:t.columns-1;if(e<0||e>n)throw new RangeError("Column index out of range")}function M(t,e){if(e.to1DArray&&(e=e.to1DArray()),e.length!==t.columns)throw new RangeError("vector size must be the same as the number of columns");return e}function S(t,e){if(e.to1DArray&&(e=e.to1DArray()),e.length!==t.rows)throw new RangeError("vector size must be the same as the number of rows");return e}function x(t,e){if("object"!=typeof e)throw new TypeError("unexpected type for row indices");if(e.some(e=>e<0||e>=t.rows))throw new RangeError("row indices are out of range");return Array.isArray(e)||(e=Array.from(e)),e}function E(t,e){if("object"!=typeof e)throw new TypeError("unexpected type for column indices");if(e.some(e=>e<0||e>=t.columns))throw new RangeError("column indices are out of range");return Array.isArray(e)||(e=Array.from(e)),e}function R(t,e,r,n,o){if(5!==arguments.length)throw new RangeError("expected 4 arguments");if(N("startRow",e),N("endRow",r),N("startColumn",n),N("endColumn",o),e>r||n>o||e<0||e>=t.rows||r<0||r>=t.rows||n<0||n>=t.columns||o<0||o>=t.columns)throw new RangeError("Submatrix indices are out of range")}function k(t,e=0){let r=[];for(let n=0;n=o)throw new RangeError("min must be smaller than max");let s=o-n,a=new P(t,e);for(let r=0;rr?(o=!0,r=e):(n=!1,o=!0);t++}return n}isReducedEchelonForm(){let t=0,e=0,r=-1,n=!0,o=!1;for(;tr?(o=!0,r=e):(n=!1,o=!0);for(let r=e+1;rt.get(n,r)&&(n=o);if(0===t.get(n,r))r++;else{t.swapRows(e,n);let o=t.get(e,r);for(let n=r;n=0;)if(0===t.maxRow(n))n--;else{let o=0,i=!1;for(;ot&&(t=this.get(e,r));return t}maxIndex(){z(this);let t=this.get(0,0),e=[0,0];for(let r=0;rt&&(t=this.get(r,n),e[0]=r,e[1]=n);return e}min(){if(this.isEmpty())return NaN;let t=this.get(0,0);for(let e=0;ee&&(e=this.get(t,r));return e}maxRowIndex(t){v(this,t),z(this);let e=this.get(t,0),r=[t,0];for(let n=1;ne&&(e=this.get(t,n),r[1]=n);return r}minRow(t){if(v(this,t),this.isEmpty())return NaN;let e=this.get(t,0);for(let r=1;re&&(e=this.get(r,t));return e}maxColumnIndex(t){b(this,t),z(this);let e=this.get(0,t),r=[0,t];for(let n=1;ne&&(e=this.get(n,t),r[0]=n);return r}minColumn(t){if(b(this,t),this.isEmpty())return NaN;let e=this.get(0,t);for(let r=1;r=r)throw new RangeError("min must be smaller than max");let n=new P(this.rows,this.columns);for(let t=0;t0&&p(o,{min:e,max:r,output:o}),n.setRow(t,o)}return n}scaleColumns(t={}){if("object"!=typeof t)throw new TypeError("options must be an object");const{min:e=0,max:r=1}=t;if(!Number.isFinite(e))throw new TypeError("min must be a number");if(!Number.isFinite(r))throw new TypeError("max must be a number");if(e>=r)throw new RangeError("min must be smaller than max");let n=new P(this.rows,this.columns);for(let t=0;tr||e<0||e>=this.columns||r<0||r>=this.columns)throw new RangeError("Argument out of range");let n=new P(t.length,r-e+1);for(let o=0;o=this.rows)throw new RangeError("Row index out of range: "+t[o]);n.set(o,i-e,this.get(t[o],i))}return n}subMatrixColumn(t,e,r){if(void 0===e&&(e=0),void 0===r&&(r=this.rows-1),e>r||e<0||e>=this.rows||r<0||r>=this.rows)throw new RangeError("Argument out of range");let n=new P(r-e+1,t.length);for(let o=0;o=this.columns)throw new RangeError("Column index out of range: "+t[o]);n.set(i-e,o,this.get(i,t[o]))}return n}setSubMatrix(t,e,r){if((t=P.checkMatrix(t)).isEmpty())return this;R(this,e,e+t.rows-1,r,r+t.columns-1);for(let n=0;n=0){if(this.data=[],!(Number.isInteger(e)&&e>=0))throw new TypeError("nColumns must be a positive integer");for(let r=0;r>t);return this},j.prototype.signPropagatingRightShiftM=function(t){if(t=O.checkMatrix(t),this.rows!==t.rows||this.columns!==t.columns)throw new RangeError("Matrices dimensions must be equal");for(let e=0;e>t.get(e,r));return this},j.signPropagatingRightShift=function(t,e){return new O(t).signPropagatingRightShift(e)},j.prototype.rightShift=function(t){return"number"==typeof t?this.rightShiftS(t):this.rightShiftM(t)},j.prototype.rightShiftS=function(t){for(let e=0;e>>t);return this},j.prototype.rightShiftM=function(t){if(t=O.checkMatrix(t),this.rows!==t.rows||this.columns!==t.columns)throw new RangeError("Matrices dimensions must be equal");for(let e=0;e>>t.get(e,r));return this},j.rightShift=function(t,e){return new O(t).rightShift(e)},j.prototype.zeroFillRightShift=j.prototype.rightShift,j.prototype.zeroFillRightShiftS=j.prototype.rightShiftS,j.prototype.zeroFillRightShiftM=j.prototype.rightShiftM,j.zeroFillRightShift=j.rightShift,j.prototype.not=function(){for(let t=0;tMath.abs(h[o])&&(o=e);if(o!==r){for(n=0;n=0;o--){for(n=0;ne?n.set(o,e,t.get(o,e)):o===e?n.set(o,e,1):n.set(o,e,0);return n}get upperTriangularMatrix(){let t=this.LU,e=t.rows,r=t.columns,n=new P(e,r);for(let o=0;oMath.abs(e)?(r=e/t,Math.abs(t)*Math.sqrt(1+r*r)):0!==e?(r=t/e,Math.abs(e)*Math.sqrt(1+r*r)):0}class F{constructor(t){let e,r,n,o,i=(t=C.checkMatrix(t)).clone(),s=t.rows,a=t.columns,h=new Float64Array(a);for(n=0;n=0;i--){for(o=0;o=0;r--){for(t=0;t=0;t--)if(0!==m[t]){for(let e=t+1;e=0;t--){if(t0;){let t,e;for(t=S-2;t>=-1&&-1!==t;t--){const e=Number.MIN_VALUE+R*Math.abs(m[t]+Math.abs(m[t+1]));if(Math.abs(w[t])<=e||Number.isNaN(w[t])){w[t]=0;break}}if(t===S-2)e=4;else{let r;for(r=S-1;r>=t&&r!==t;r--){let e=(r!==S?Math.abs(w[r]):0)+(r!==t+1?Math.abs(w[r-1]):0);if(Math.abs(m[r])<=R*e){m[r]=0;break}}r===t?e=3:r===S-1?e=1:(e=2,t=r)}switch(t++,e){case 1:{let e=w[S-2];w[S-2]=0;for(let r=S-2;r>=t;r--){let o=I(m[r],e),i=m[r]/o,s=e/o;if(m[r]=o,r!==t&&(e=-s*w[r-1],w[r-1]=i*w[r-1]),u)for(let t=0;t=m[t+1]);){let e=m[t];if(m[t]=m[t+1],m[t+1]=e,u&&te&&o.set(i,r,t.get(i,r)/this.s[r]);let i=this.U,s=i.rows,a=i.columns,h=new P(r,s);for(let t=0;tt&&e++;return e}get diagonal(){return Array.from(this.s)}get threshold(){return Number.EPSILON/2*Math.max(this.m,this.n)*this.s[0]}get leftSingularVectors(){return this.U}get rightSingularVectors(){return this.V}get diagonalMatrix(){return P.diag(this.s)}}function D(t,e=!1){return t=C.checkMatrix(t),e?new V(t).inverse():function(t,e,r=!1){return t=C.checkMatrix(t),e=C.checkMatrix(e),r?new V(t).solve(e):t.isSquare()?new T(t).solve(e):new F(t).solve(e)}(t,P.eye(t.rows))}function q(t,e,r,n,o){let i=r*n*n,s=P.eye(e.length,e.length,i);const a=o(e);let h=new Float64Array(t.x.length);for(let e=0;e