Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

ml-matrix

Package Overview
Dependencies
Maintainers
7
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ml-matrix - npm Package Compare versions

Comparing version
6.0.0-5
to
6.0.0-6
+3
src/inspect.browser.js
export function inspectMatrix() {
// noop
}
export function inspectMatrix() {
const indent = ' '.repeat(2);
const indentData = ' '.repeat(4);
return `${this.constructor.name} {
${indent}[
${indentData}${inspectData(this, indentData)}
${indent}]
${indent}rows: ${this.rows}
${indent}columns: ${this.columns}
}`;
}
const maxRows = 15;
const maxColumns = 10;
const maxNumSize = 8;
function inspectData(matrix, indent) {
const { rows, columns } = matrix;
const maxI = Math.min(rows, maxRows);
const maxJ = Math.min(columns, maxColumns);
const result = [];
for (var i = 0; i < maxI; i++) {
let line = [];
for (var j = 0; j < maxJ; j++) {
line.push(formatNumber(matrix.get(i, j)));
}
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${indent}`);
}
function formatNumber(num) {
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.substring(eIndex);
return exponential.substring(0, maxNumSize - e.length) + e;
}
export 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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) + value);
}
}
return this;
};
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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) + matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.add = function add(matrix, value) {
var newMatrix = new Matrix(matrix);
return newMatrix.add(value);
};
AbstractMatrix.prototype.sub = function sub(value) {
if (typeof value === 'number') return this.subS(value);
return this.subM(value);
};
AbstractMatrix.prototype.subS = function subS(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) - value);
}
}
return this;
};
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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) - matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.sub = function sub(matrix, value) {
var 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);
};
AbstractMatrix.prototype.mulS = function mulS(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) * value);
}
}
return this;
};
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');
}
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) * matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.mul = function mul(matrix, value) {
var 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);
};
AbstractMatrix.prototype.divS = function divS(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) / value);
}
}
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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) / matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.div = function div(matrix, value) {
var 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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) % value);
}
}
return this;
};
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');
}
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) % matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.mod = function mod(matrix, value) {
var 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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) & value);
}
}
return this;
};
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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) & matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.and = function and(matrix, value) {
var newMatrix = new Matrix(matrix);
return newMatrix.and(value);
};
AbstractMatrix.prototype.or = function or(value) {
if (typeof value === 'number') return this.orS(value);
return this.orM(value);
};
AbstractMatrix.prototype.orS = function orS(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) | value);
}
}
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 (var i = 0; i < this.rows; i++) {
for (var 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) {
var 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);
};
AbstractMatrix.prototype.xorS = function xorS(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) ^ value);
}
}
return this;
};
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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) ^ matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.xor = function xor(matrix, value) {
var newMatrix = new Matrix(matrix);
return newMatrix.xor(value);
};
AbstractMatrix.prototype.leftShift = function leftShift(value) {
if (typeof value === 'number') return this.leftShiftS(value);
return this.leftShiftM(value);
};
AbstractMatrix.prototype.leftShiftS = function leftShiftS(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) << value);
}
}
return this;
};
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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) << matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.leftShift = function leftShift(matrix, value) {
var newMatrix = new Matrix(matrix);
return newMatrix.leftShift(value);
};
AbstractMatrix.prototype.signPropagatingRightShift = function signPropagatingRightShift(value) {
if (typeof value === 'number') return this.signPropagatingRightShiftS(value);
return this.signPropagatingRightShiftM(value);
};
AbstractMatrix.prototype.signPropagatingRightShiftS = function signPropagatingRightShiftS(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) >> value);
}
}
return this;
};
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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) >> matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.signPropagatingRightShift = function signPropagatingRightShift(matrix, value) {
var newMatrix = new Matrix(matrix);
return newMatrix.signPropagatingRightShift(value);
};
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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) >>> value);
}
}
return this;
};
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');
}
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, this.get(i, j) >>> matrix.get(i, j));
}
}
return this;
};
AbstractMatrix.rightShift = function rightShift(matrix, value) {
var 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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, ~(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.not = function not(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.not();
};
AbstractMatrix.prototype.abs = function abs() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.abs(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.abs = function abs(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.abs();
};
AbstractMatrix.prototype.acos = function acos() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.acos(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.acos = function acos(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.acos();
};
AbstractMatrix.prototype.acosh = function acosh() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.acosh(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.acosh = function acosh(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.acosh();
};
AbstractMatrix.prototype.asin = function asin() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.asin(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.asin = function asin(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.asin();
};
AbstractMatrix.prototype.asinh = function asinh() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.asinh(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.asinh = function asinh(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.asinh();
};
AbstractMatrix.prototype.atan = function atan() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.atan(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.atan = function atan(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.atan();
};
AbstractMatrix.prototype.atanh = function atanh() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.atanh(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.atanh = function atanh(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.atanh();
};
AbstractMatrix.prototype.cbrt = function cbrt() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.cbrt(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.cbrt = function cbrt(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.cbrt();
};
AbstractMatrix.prototype.ceil = function ceil() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.ceil(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.ceil = function ceil(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.ceil();
};
AbstractMatrix.prototype.clz32 = function clz32() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.clz32(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.clz32 = function clz32(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.clz32();
};
AbstractMatrix.prototype.cos = function cos() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.cos(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.cos = function cos(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.cos();
};
AbstractMatrix.prototype.cosh = function cosh() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.cosh(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.cosh = function cosh(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.cosh();
};
AbstractMatrix.prototype.exp = function exp() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.exp(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.exp = function exp(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.exp();
};
AbstractMatrix.prototype.expm1 = function expm1() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.expm1(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.expm1 = function expm1(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.expm1();
};
AbstractMatrix.prototype.floor = function floor() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.floor(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.floor = function floor(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.floor();
};
AbstractMatrix.prototype.fround = function fround() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.fround(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.fround = function fround(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.fround();
};
AbstractMatrix.prototype.log = function log() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.log(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.log = function log(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.log();
};
AbstractMatrix.prototype.log1p = function log1p() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.log1p(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.log1p = function log1p(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.log1p();
};
AbstractMatrix.prototype.log10 = function log10() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.log10(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.log10 = function log10(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.log10();
};
AbstractMatrix.prototype.log2 = function log2() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.log2(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.log2 = function log2(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.log2();
};
AbstractMatrix.prototype.round = function round() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.round(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.round = function round(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.round();
};
AbstractMatrix.prototype.sign = function sign() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.sign(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.sign = function sign(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.sign();
};
AbstractMatrix.prototype.sin = function sin() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.sin(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.sin = function sin(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.sin();
};
AbstractMatrix.prototype.sinh = function sinh() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.sinh(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.sinh = function sinh(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.sinh();
};
AbstractMatrix.prototype.sqrt = function sqrt() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.sqrt(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.sqrt = function sqrt(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.sqrt();
};
AbstractMatrix.prototype.tan = function tan() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.tan(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.tan = function tan(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.tan();
};
AbstractMatrix.prototype.tanh = function tanh() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.tanh(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.tanh = function tanh(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.tanh();
};
AbstractMatrix.prototype.trunc = function trunc() {
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.trunc(this.get(i, j)));
}
}
return this;
};
AbstractMatrix.trunc = function trunc(matrix) {
var newMatrix = new Matrix(matrix);
return newMatrix.trunc();
};
AbstractMatrix.pow = function pow(matrix, arg0) {
var 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 (var i = 0; i < this.rows; i++) {
for (var 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 (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
this.set(i, j, Math.pow(this.get(i, j), matrix.get(i, j)));
}
}
return this;
};
}
+0
-0

@@ -0,0 +0,0 @@ # [5.3.0](https://github.com/mljs/matrix/compare/v5.2.1...v5.3.0) (2019-03-23)

@@ -0,0 +0,0 @@ The MIT License (MIT)

+309
-237
declare module 'ml-matrix' {
type MaybeMatrix = Matrix | number[][];
type Rng = () => number;
type ScalarOrMatrix = number | Matrix;
type MaybeMatrix = AbstractMatrix | number[][];
type ScalarOrMatrix = number | MaybeMatrix;
type MatrixDimension = 'row' | 'column';
export class MatrixColumnView extends Matrix {
constructor(matrix: Matrix, column: number);
export interface IRandomOptions {
random: () => number;
}
export class MatrixColumnSelectionView extends Matrix {
constructor(matrix: Matrix, columnIndices: number[]);
export interface IRandomIntOptions {
min: number;
max: number;
random: () => number;
}
export class MatrixFlipColumnView extends Matrix {
constructor(matrix: Matrix);
export interface IRepeatOptions {
rows?: number;
columns?: number;
}
export class MatrixFlipRowView extends Matrix {
constructor(matrix: Matrix);
export interface IScaleOptions {
min?: number;
max?: number;
}
export class MatrixRowView extends Matrix {
constructor(matrix: Matrix, row: number);
export interface IVarianceOptions {
unbiased?: boolean;
mean?: number;
}
export class MatrixRowSelectionView extends Matrix {
constructor(matrix: Matrix, rowIndices: number[]);
export interface IVarianceByOptions {
unbiased?: boolean;
mean?: number[];
}
export class MatrixSelectionView extends Matrix {
constructor(matrix: Matrix, rowIndices: number[], columnIndices: number[]);
}
export class MatrixSubView extends Matrix {
constructor(
matrix: Matrix,
startRow: number,
endRow: number,
startColumn: number,
endColumn: number
);
}
export class MatrixTransposeView extends BaseView {
constructor(matrix: Matrix);
}
export class Matrix {
export abstract class AbstractMatrix {
readonly size: number;

@@ -45,6 +36,2 @@ readonly rows: number;

constructor(nRows: number, nColumns: number);
constructor(data: number[][]);
constructor(otherMatrix: Matrix);
static from1DArray(

@@ -59,9 +46,16 @@ newRows: number,

static ones(rows: number, columns: number): Matrix;
static rand(rows: number, columns: number, rng?: Rng): Matrix;
static random(rows: number, columns: number, rng?: Rng): Matrix;
static rand(
rows: number,
columns: number,
options?: IRandomOptions
): Matrix;
static random(
rows: number,
columns: number,
options?: IRandomOptions
): Matrix;
static randInt(
rows: number,
columns: number,
maxValue?: number,
rng?: Rng
options?: IRandomIntOptions
): Matrix;

@@ -72,10 +66,14 @@ static eye(rows: number, columns?: number, value?: number): Matrix;

static diagonal(data: number[], rows?: number, columns?: number): Matrix;
static min(matrix1: Matrix, matrix2: Matrix): Matrix;
static max(matrix1: Matrix, matrix2: Matrix): Matrix;
static min(matrix1: MaybeMatrix, matrix2: MaybeMatrix): Matrix;
static max(matrix1: MaybeMatrix, matrix2: MaybeMatrix): Matrix;
static checkMatrix(value: any): Matrix;
static isMatrix(value: any): value is Matrix;
static isMatrix(value: any): value is AbstractMatrix;
apply(callback: Function): this;
set(rowIndex: number, columnIndex: number, value: number): this;
get(rowIndex: number, columnIndex: number): number;
apply(callback: (row: number, column: number) => void): this;
to1DArray(): number[];
to2DArray(): number[][];
toJSON(): number[][];
isRowVector(): boolean;

@@ -88,43 +86,80 @@ isColumnVector(): boolean;

isReducedEchelonForm(): boolean;
set(rowIndex: number, columnIndex: number, value: number): this;
get(rowIndex: number, columnIndex: number): number;
repeat(rowRep: number, colRep: number): Matrix;
repeat(options?: IRepeatOptions): Matrix;
fill(value: number): this;
neg(): Matrix;
negate(): Matrix;
addRow(index: number, array: number[] | Matrix): this;
neg(): this;
negate(): this;
getRow(index: number): number[];
getRowVector(index: number): Matrix;
setRow(index: number, array: number[] | Matrix): Matrix;
swapRows(row1: number, row2: number): Matrix;
addColumn(index: number, array: number[] | Matrix): this;
setRow(index: number, array: number[] | AbstractMatrix): this;
swapRows(row1: number, row2: number): this;
getColumn(index: number): number[];
getColumnVector(index: number): Matrix;
setColumn(index: number, array: number[] | Matrix): Matrix;
swapColumns(column1: number, column2: number): Matrix;
addRowVector(vector: number[] | Matrix): Matrix;
subRowVector(vector: number[] | Matrix): Matrix;
mulRowVector(vector: number[] | Matrix): Matrix;
divRowVector(vector: number[] | Matrix): Matrix;
addColumnVector(vector: number[] | Matrix): Matrix;
subColumnVector(vector: number[] | Matrix): Matrix;
mulColumnVector(vector: number[] | Matrix): Matrix;
divColumnVector(vector: number[] | Matrix): Matrix;
mulRow(index: number, value: number): Matrix;
mulColumn(index: number, value: number): Matrix;
setColumn(index: number, array: number[] | AbstractMatrix): this;
swapColumns(column1: number, column2: number): this;
addRowVector(vector: number[] | AbstractMatrix): this;
subRowVector(vector: number[] | AbstractMatrix): this;
mulRowVector(vector: number[] | AbstractMatrix): this;
divRowVector(vector: number[] | AbstractMatrix): this;
addColumnVector(vector: number[] | AbstractMatrix): this;
subColumnVector(vector: number[] | AbstractMatrix): this;
mulColumnVector(vector: number[] | AbstractMatrix): this;
divColumnVector(vector: number[] | AbstractMatrix): this;
mulRow(index: number, value: number): this;
mulColumn(index: number, value: number): this;
max(): number;
maxIndex(): number[];
maxIndex(): [number, number];
min(): number;
minIndex(): number[];
minIndex(): [number, number];
maxRow(row: number): number;
maxRowIndex(row: number): number[];
maxRowIndex(row: number): [number, number];
minRow(row: number): number;
minRowIndex(row: number): number[];
minRowIndex(row: number): [number, number];
maxColumn(column: number): number;
maxColumnIndex(column: number): number[];
maxColumnIndex(column: number): [number, number];
minColumn(column: number): number;
minColumnIndex(column: number): number[];
minColumnIndex(column: number): [number, number];
diag(): number[];
diagonal(): number[];
norm(type: 'frobenius' | 'max'): number;
cumulativeSum(): this;
dot(vector: AbstractMatrix): number;
mmul(other: MaybeMatrix): Matrix;
strassen2x2(other: MaybeMatrix): Matrix;
strassen3x3(other: MaybeMatrix): Matrix;
mmulStrassen(y: MaybeMatrix): Matrix;
scaleRows(options?: IScaleOptions): Matrix;
scaleColumns(options?: IScaleOptions): Matrix;
flipRows(): this;
flipColumns(): this;
kroneckerProduct(other: MaybeMatrix): Matrix;
tensorProduct(other: MaybeMatrix): Matrix;
transpose(): Matrix;
sortRows(compareFunction?: (a: number, b: number) => number): this;
sortColumns(compareFunction?: (a: number, b: number) => number): this;
subMatrix(
startRow: number,
endRow: number,
startColumn: number,
endColumn: number
): Matrix;
subMatrixRow(
indices: number[],
startColumn?: number,
endColumn?: number
): Matrix;
subMatrixColumn(
indices: number[],
startRow?: number,
endRow?: number
): Matrix;
setSubMatrix(
matrix: MaybeMatrix | number[],
startRow: number,
startColumn: number
): Matrix;
selection(rowIndices: number[], columnIndices: number[]): Matrix;
trace(): number;
clone(): Matrix;
/**

@@ -163,47 +198,11 @@ * Returns the sum of all elements of the matrix.

prod(): number;
norm(type: 'frobenius' | 'max'): number;
cumulativeSum(): this;
dot(vector2: Matrix): number;
mmul(other: Matrix): Matrix;
strassen2x2(other: Matrix): Matrix;
strassen3x3(other: Matrix): Matrix;
mmulStrassen(y: Matrix): Matrix;
scaleRows(min?: number, max?: number): Matrix;
scaleColumns(min?: number, max?: number): Matrix;
reverseRows(): this;
reverseColumns(): this;
kroneckerProduct(other: Matrix): Matrix;
tensorProduct(other: Matrix): Matrix;
transpose(): Matrix;
sortRows(compareFunction: Function): this;
sortColumns(compareFunction: Function): this;
subMatrix(
startRow: number,
endRow: number,
startColumn: number,
endColumn: number
): Matrix;
subMatrixRow(
indices: number[],
startColumn?: number,
endColumn?: number
): Matrix;
subMatrixColumn(
indices: number[],
startRow?: number,
endRow?: number
): Matrix;
setSubMatrix(
matrix: Matrix | number[],
startRow: number,
startColumn: number
): Matrix;
selection(rowIndices: number[], columnIndices: number[]): Matrix;
trace(): number;
clone(): Matrix;
entropy(eps?: number): number;
variance(unbiased?: boolean, means?: number[]): number[];
standardDeviation(unbiased?: boolean, means?: number[]): number[];
variance(options?: IVarianceOptions): number;
variance(by: MatrixDimension, options?: IVarianceByOptions): number[];
standardDeviation(options?: IVarianceOptions): number;
standardDeviation(
by: MatrixDimension,
options?: IVarianceByOptions
): number[];
// From here we document methods dynamically generated from operators

@@ -213,110 +212,203 @@

// inplace
add(value: ScalarOrMatrix): Matrix;
sub(value: ScalarOrMatrix): Matrix;
subtract(value: ScalarOrMatrix): Matrix;
mul(value: ScalarOrMatrix): Matrix;
multiply(value: ScalarOrMatrix): Matrix;
div(value: ScalarOrMatrix): Matrix;
divide(value: ScalarOrMatrix): Matrix;
mod(value: ScalarOrMatrix): Matrix;
modulus(value: ScalarOrMatrix): Matrix;
and(value: ScalarOrMatrix): Matrix;
or(value: ScalarOrMatrix): Matrix;
xor(value: ScalarOrMatrix): Matrix;
leftShift(value: ScalarOrMatrix): Matrix;
signPropagatingRightShift(value: ScalarOrMatrix): Matrix;
rightShift(value: ScalarOrMatrix): Matrix;
zeroFillRightShift(value: ScalarOrMatrix): Matrix;
add(value: ScalarOrMatrix): this;
sub(value: ScalarOrMatrix): this;
subtract(value: ScalarOrMatrix): this;
mul(value: ScalarOrMatrix): this;
multiply(value: ScalarOrMatrix): this;
div(value: ScalarOrMatrix): this;
divide(value: ScalarOrMatrix): this;
mod(value: ScalarOrMatrix): this;
modulus(value: ScalarOrMatrix): this;
and(value: ScalarOrMatrix): this;
or(value: ScalarOrMatrix): this;
xor(value: ScalarOrMatrix): this;
leftShift(value: ScalarOrMatrix): this;
signPropagatingRightShift(value: ScalarOrMatrix): this;
rightShift(value: ScalarOrMatrix): this;
zeroFillRightShift(value: ScalarOrMatrix): this;
// new matrix
static add(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static sub(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static subtract(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static mul(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static multiply(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static div(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static divide(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static mod(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static modulus(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static and(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static or(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static xor(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static leftShift(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static add(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static sub(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static subtract(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static mul(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static multiply(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static div(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static divide(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static mod(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static modulus(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static and(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static or(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static xor(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static leftShift(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static signPropagatingRightShift(
matrix: Matrix,
matrix: MaybeMatrix,
value: ScalarOrMatrix
): Matrix;
static rightShift(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static zeroFillRightShift(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static rightShift(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
static zeroFillRightShift(
matrix: MaybeMatrix,
value: ScalarOrMatrix
): Matrix;
// Functional operators (one arg)
// inplace
not(): Matrix;
abs(): Matrix;
acos(): Matrix;
acosh(): Matrix;
asin(): Matrix;
asinh(): Matrix;
atan(): Matrix;
atanh(): Matrix;
cbrt(): Matrix;
ceil(): Matrix;
clz32(): Matrix;
cos(): Matrix;
cosh(): Matrix;
exp(): Matrix;
expm1(): Matrix;
floor(): Matrix;
fround(): Matrix;
log(): Matrix;
log1p(): Matrix;
log10(): Matrix;
log2(): Matrix;
round(): Matrix;
sign(): Matrix;
sin(): Matrix;
sinh(): Matrix;
sqrt(): Matrix;
tan(): Matrix;
tanh(): Matrix;
trunc(): Matrix;
not(): this;
abs(): this;
acos(): this;
acosh(): this;
asin(): this;
asinh(): this;
atan(): this;
atanh(): this;
cbrt(): this;
ceil(): this;
clz32(): this;
cos(): this;
cosh(): this;
exp(): this;
expm1(): this;
floor(): this;
fround(): this;
log(): this;
log1p(): this;
log10(): this;
log2(): this;
round(): this;
sign(): this;
sin(): this;
sinh(): this;
sqrt(): this;
tan(): this;
tanh(): this;
trunc(): this;
// new matrix
static not(value: Matrix): Matrix;
static abs(value: Matrix): Matrix;
static acos(value: Matrix): Matrix;
static acosh(value: Matrix): Matrix;
static asin(value: Matrix): Matrix;
static asinh(value: Matrix): Matrix;
static atan(value: Matrix): Matrix;
static atanh(value: Matrix): Matrix;
static cbrt(value: Matrix): Matrix;
static ceil(value: Matrix): Matrix;
static clz32(value: Matrix): Matrix;
static cos(value: Matrix): Matrix;
static cosh(value: Matrix): Matrix;
static exp(value: Matrix): Matrix;
static expm1(value: Matrix): Matrix;
static floor(value: Matrix): Matrix;
static fround(value: Matrix): Matrix;
static log(value: Matrix): Matrix;
static log1p(value: Matrix): Matrix;
static log10(value: Matrix): Matrix;
static log2(value: Matrix): Matrix;
static round(value: Matrix): Matrix;
static sign(value: Matrix): Matrix;
static sin(value: Matrix): Matrix;
static sinh(value: Matrix): Matrix;
static sqrt(value: Matrix): Matrix;
static tan(value: Matrix): Matrix;
static tanh(value: Matrix): Matrix;
static trunc(value: Matrix): Matrix;
static not(value: MaybeMatrix): Matrix;
static abs(value: MaybeMatrix): Matrix;
static acos(value: MaybeMatrix): Matrix;
static acosh(value: MaybeMatrix): Matrix;
static asin(value: MaybeMatrix): Matrix;
static asinh(value: MaybeMatrix): Matrix;
static atan(value: MaybeMatrix): Matrix;
static atanh(value: MaybeMatrix): Matrix;
static cbrt(value: MaybeMatrix): Matrix;
static ceil(value: MaybeMatrix): Matrix;
static clz32(value: MaybeMatrix): Matrix;
static cos(value: MaybeMatrix): Matrix;
static cosh(value: MaybeMatrix): Matrix;
static exp(value: MaybeMatrix): Matrix;
static expm1(value: MaybeMatrix): Matrix;
static floor(value: MaybeMatrix): Matrix;
static fround(value: MaybeMatrix): Matrix;
static log(value: MaybeMatrix): Matrix;
static log1p(value: MaybeMatrix): Matrix;
static log10(value: MaybeMatrix): Matrix;
static log2(value: MaybeMatrix): Matrix;
static round(value: MaybeMatrix): Matrix;
static sign(value: MaybeMatrix): Matrix;
static sin(value: MaybeMatrix): Matrix;
static sinh(value: MaybeMatrix): Matrix;
static sqrt(value: MaybeMatrix): Matrix;
static tan(value: MaybeMatrix): Matrix;
static tanh(value: MaybeMatrix): Matrix;
static trunc(value: MaybeMatrix): Matrix;
// Functional operators with one arg
// inplace
pow(value: ScalarOrMatrix): Matrix;
pow(value: ScalarOrMatrix): this;
// new matrix
static pow(matrix: Matrix, value: ScalarOrMatrix): Matrix;
static pow(matrix: MaybeMatrix, value: ScalarOrMatrix): Matrix;
}
export class Matrix extends AbstractMatrix {
constructor(nRows: number, nColumns: number);
constructor(data: number[][]);
constructor(otherMatrix: AbstractMatrix);
}
export default Matrix;
class SingularValueDecomposition {
export class MatrixColumnView extends AbstractMatrix {
constructor(matrix: AbstractMatrix, column: number);
}
export class MatrixColumnSelectionView extends AbstractMatrix {
constructor(matrix: AbstractMatrix, columnIndices: number[]);
}
export class MatrixFlipColumnView extends AbstractMatrix {
constructor(matrix: AbstractMatrix);
}
export class MatrixFlipRowView extends AbstractMatrix {
constructor(matrix: AbstractMatrix);
}
export class MatrixRowView extends AbstractMatrix {
constructor(matrix: AbstractMatrix, row: number);
}
export class MatrixRowSelectionView extends AbstractMatrix {
constructor(matrix: AbstractMatrix, rowIndices: number[]);
}
export class MatrixSelectionView extends AbstractMatrix {
constructor(
matrix: AbstractMatrix,
rowIndices: number[],
columnIndices: number[]
);
}
export class MatrixSubView extends AbstractMatrix {
constructor(
matrix: AbstractMatrix,
startRow: number,
endRow: number,
startColumn: number,
endColumn: number
);
}
export class MatrixTransposeView extends AbstractMatrix {
constructor(matrix: AbstractMatrix);
}
export interface IWrap1DOptions {
rows?: number;
}
export function wrap(
array: number[],
options?: IWrap1DOptions
): WrapperMatrix1D;
export function wrap(twoDAray: number[][]): WrapperMatrix2D;
export class WrapperMatrix1D extends AbstractMatrix {
constructor(data: number[], options?: IWrap1DOptions);
}
export class WrapperMatrix2D extends AbstractMatrix {
constructor(data: number[][]);
}
export function solve(
leftHandSide: MaybeMatrix,
rightHandSide: MaybeMatrix,
useSVD?: boolean
): Matrix;
export function inverse(matrix: MaybeMatrix, useSVD?: boolean): Matrix;
export function determinant(matrix: MaybeMatrix): number;
export interface ILinearDependenciesOptions {
thresholdValue?: number;
thresholdError?: number;
}
export function linearDependencies(
matrix: MaybeMatrix,
options?: ILinearDependenciesOptions
): Matrix;
export function pseudoInverse(
matrix: MaybeMatrix,
threshold?: number
): Matrix;
export interface ISVDOptions {
computeLeftSingularVectors?: boolean;
computeRightSingularVectors?: boolean;
autoTranspose?: boolean;
}
export class SingularValueDecomposition {
constructor(value: MaybeMatrix, options?: ISVDOptions);

@@ -335,10 +427,8 @@ inverse(): Matrix;

}
export interface ISVDOptions {
computeLeftSingularVectors?: boolean;
computeRightSingularVectors?: boolean;
autoTranspose?: boolean;
export { SingularValueDecomposition as SVD };
export interface IEVDOptions {
assumeSymmetric?: boolean;
}
export { SingularValueDecomposition, SingularValueDecomposition as SVD };
class EigenvalueDecomposition {
export class EigenvalueDecomposition {
constructor(value: MaybeMatrix, options?: IEVDOptions);

@@ -350,8 +440,5 @@ readonly diagonalMatrix: Matrix;

}
export interface IEVDOptions {
assumeSymmetric?: boolean;
}
export { EigenvalueDecomposition, EigenvalueDecomposition as EVD };
export { EigenvalueDecomposition as EVD };
class CholeskyDecomposition {
export class CholeskyDecomposition {
constructor(value: MaybeMatrix);

@@ -361,5 +448,5 @@ solve(value: Matrix): Matrix;

}
export { CholeskyDecomposition, CholeskyDecomposition as CHO };
export { CholeskyDecomposition as CHO };
class LuDecomposition {
export class LuDecomposition {
constructor(value: MaybeMatrix);

@@ -373,3 +460,3 @@ isSingular(): boolean;

}
export { LuDecomposition, LuDecomposition as LU };
export { LuDecomposition as LU };

@@ -384,17 +471,2 @@ class QrDecomposition {

export { QrDecomposition, QrDecomposition as QR };
export function solve(
leftHandSide: MaybeMatrix,
rightHandSide: MaybeMatrix,
useSVD?: boolean
): Matrix;
export function inverse(matrix: MaybeMatrix, useSVD?: boolean): Matrix;
export function determinant(matrix: MaybeMatrix): number;
export function pseudoInverse(
matrix: MaybeMatrix,
threshold?: number
): Matrix;
}
{
"name": "ml-matrix",
"version": "6.0.0-5",
"version": "6.0.0-6",
"description": "Matrix manipulation and computation library",

@@ -8,2 +8,3 @@ "main": "matrix.js",

"types": "matrix.d.ts",
"sideEffects": false,
"files": [

@@ -10,0 +11,0 @@ "matrix.d.ts",

@@ -0,0 +0,0 @@ # ml-matrix

@@ -0,0 +0,0 @@ export function hypotenuse(a, b) {

@@ -1,8 +0,7 @@

export { default, default as Matrix } from './matrix';
export { default as AbstractMatrix } from './abstractMatrix';
export { AbstractMatrix, default, default as Matrix } from './matrix';
export * from './views/index';
export { wrap } from './wrap/wrap';
export { default as WrapperMatrix1D } from './wrap/WrapperMatrix1D';
export { default as WrapperMatrix2D } from './wrap/WrapperMatrix2D';
export { default as WrapperMatrix1D } from './wrap/WrapperMatrix1D';

@@ -13,2 +12,3 @@ export { solve, inverse } from './decompositions';

export { pseudoInverse } from './pseudoInverse';
export {

@@ -15,0 +15,0 @@ default as SingularValueDecomposition,

@@ -49,2 +49,3 @@ import Matrix from './matrix';

const { thresholdValue = 10e-10, thresholdError = 10e-10 } = options;
matrix = Matrix.checkMatrix(matrix);

@@ -51,0 +52,0 @@ var n = matrix.rows;

@@ -1,9 +0,1694 @@

import AbstractMatrix from './abstractMatrix';
import rescale from 'ml-array-rescale';
import {
checkRowVector,
checkRowIndex,
checkColumnIndex,
checkColumnVector,
checkRowIndex,
checkRowVector
checkRange,
checkIndices
} from './util';
import {
sumByRow,
sumByColumn,
sumAll,
productByRow,
productByColumn,
productAll,
varianceByRow,
varianceByColumn,
varianceAll
} from './stat';
import { inspectMatrix } from './inspect';
import { installMathOperations } from './mathOperations';
export class AbstractMatrix {
/**
* 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 Matrix(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 Matrix(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 Matrix(newData.length, 1);
for (var i = 0; i < newData.length; i++) {
vector.set(i, 0, newData[i]);
}
return vector;
}
/**
* 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 new Matrix(rows, columns);
}
/**
* 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 new Matrix(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 {object} [options]
* @param {function} [options.random=Math.random] - Random number generator
* @return {Matrix} The new matrix
*/
static rand(rows, columns, options = {}) {
if (typeof options !== 'object') {
throw new TypeError('options must be an object');
}
const { random = Math.random } = options;
var matrix = new Matrix(rows, columns);
for (var i = 0; i < rows; i++) {
for (var j = 0; j < columns; j++) {
matrix.set(i, j, random());
}
}
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 {object} [options]
* @param {number} [options.min=0] - Minimum value
* @param {number} [options.max=1000] - Maximum value
* @param {function} [options.random=Math.random] - Random number generator
* @return {Matrix} The new matrix
*/
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');
var interval = max - min;
var matrix = new Matrix(rows, columns);
for (var i = 0; i < rows; i++) {
for (var j = 0; j < columns; j++) {
var value = min + Math.round(random() * interval);
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 Matrix(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 AbstractMatrix.isMatrix(value) ? value : new Matrix(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');
}
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
callback.call(this, i, j);
}
}
return this;
}
/**
* Returns a new 1D array filled row by row with the matrix values
* @return {Array}
*/
to1DArray() {
var array = [];
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
array.push(this.get(i, j));
}
}
return array;
}
/**
* Returns a 2D array containing a copy of the data
* @return {Array}
*/
to2DArray() {
var copy = [];
for (var i = 0; i < this.rows; i++) {
copy.push([]);
for (var j = 0; j < this.columns; j++) {
copy[i].push(this.get(i, j));
}
}
return copy;
}
toJSON() {
return this.to2DArray();
}
/**
* @return {boolean} true if the matrix has one row
*/
isRowVector() {
return this.rows === 1;
}
/**
* @return {boolean} true if the matrix has one column
*/
isColumnVector() {
return this.columns === 1;
}
/**
* @return {boolean} true if the matrix has one row or one column
*/
isVector() {
return this.rows === 1 || this.columns === 1;
}
/**
* @return {boolean} true if the matrix has the same number of rows and columns
*/
isSquare() {
return this.rows === this.columns;
}
/**
* @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;
}
/**
* @return true if the matrix is in echelon form
*/
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;
}
/**
* @return true if the matrix is in reduced echelon form
*/
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;
}
/**
* Sets a given element of the matrix.
* @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
*/
// eslint-disable-next-line no-unused-vars
set(rowIndex, columnIndex, value) {
throw new Error('set method is unimplemented');
}
/**
* Returns the given element of the matrix.
* @abstract
* @param {number} rowIndex - Index of the row
* @param {number} columnIndex - Index of the column
* @return {number}
*/
// eslint-disable-next-line no-unused-vars
get(rowIndex, columnIndex) {
throw new Error('get method is unimplemented');
}
/**
* Creates a new matrix that is a repetition of the current matrix. New matrix has rows times the number of
* rows of the original matrix, and columns times the number of columns of the original matrix.
* @param {object} [options]
* @param {number} [options.rows=1] - Number of times the rows should be repeated
* @param {number} [options.columns=1] - Number of times the columns should be repeated
* @return {Matrix}
* @example
* var matrix = new Matrix([[1,2]]);
* matrix.repeat({ rows: 2 }); // [[1,2],[1,2]]
*/
repeat(options = {}) {
if (typeof options !== 'object') {
throw new TypeError('options must be an object');
}
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');
}
var matrix = new Matrix(this.rows * rows, this.columns * columns);
for (var i = 0; i < rows; i++) {
for (var j = 0; j < columns; 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;
}
/**
* 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 = [];
for (var i = 0; i < this.columns; i++) {
row.push(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 Matrix.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]);
}
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);
}
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 = [];
for (var i = 0; i < this.rows; i++) {
column.push(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 Matrix.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]);
}
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);
}
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]);
}
}
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]);
}
}
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]);
}
}
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]);
}
}
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]);
}
}
return this;
}
/**
* 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]);
}
}
return this;
}
/**
* 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]);
}
}
return this;
}
/**
* 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]);
}
}
return this;
}
/**
* 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);
}
return this;
}
/**
* 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);
}
return this;
}
/**
* 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);
}
}
}
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;
}
}
}
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);
}
}
}
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;
}
}
}
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;
}
/**
* 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);
}
}
return v;
}
/**
* 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 = [];
for (var i = 0; i < min; i++) {
diag.push(this.get(i, i));
}
return diag;
}
/**
* 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}`);
}
}
/**
* 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);
}
}
return this;
}
/**
* Computes the dot (scalar) product between the matrix and another.
* @param {Matrix} vector2 vector
* @return {number}
*/
dot(vector2) {
if (AbstractMatrix.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 = Matrix.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.'
);
}
var m = this.rows;
var n = this.columns;
var p = other.columns;
var result = new Matrix(m, p);
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);
}
for (var i = 0; i < m; i++) {
var s = 0;
for (k = 0; k < n; k++) {
s += this.get(i, k) * Bcolj[k];
}
result.set(i, j, s);
}
}
return result;
}
strassen2x2(other) {
other = Matrix.checkMatrix(other);
var result = new 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;
}
strassen3x3(other) {
other = Matrix.checkMatrix(other);
var result = new 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;
}
/**
* 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) {
y = Matrix.checkMatrix(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.`
);
}
// 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 = AbstractMatrix.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(
AbstractMatrix.add(a11, a22),
AbstractMatrix.add(b11, b22),
halfRows,
halfCols
);
var m2 = blockMult(AbstractMatrix.add(a21, a22), b11, halfRows, halfCols);
var m3 = blockMult(a11, AbstractMatrix.sub(b12, b22), halfRows, halfCols);
var m4 = blockMult(a22, AbstractMatrix.sub(b21, b11), halfRows, halfCols);
var m5 = blockMult(AbstractMatrix.add(a11, a12), b22, halfRows, halfCols);
var m6 = blockMult(
AbstractMatrix.sub(a21, a11),
AbstractMatrix.add(b11, b12),
halfRows,
halfCols
);
var m7 = blockMult(
AbstractMatrix.sub(a12, a22),
AbstractMatrix.add(b21, b22),
halfRows,
halfCols
);
// Combine intermediate values into the output.
var c11 = AbstractMatrix.add(m1, m4);
c11.sub(m5);
c11.add(m7);
var c12 = AbstractMatrix.add(m3, m5);
var c21 = AbstractMatrix.add(m2, m4);
var c22 = AbstractMatrix.sub(m1, m2);
c22.add(m3);
c22.add(m6);
// Crop output to the desired size (undo dynamic padding).
var resultat = 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);
}
/**
* Returns a row-by-row scaled matrix
* @param {object} [options]
* @param {number} [options.min=0] - Minimum scaled value
* @param {number} [optiens.max=1] - Maximum scaled value
* @return {Matrix} - The scaled matrix
*/
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');
var newMatrix = new Matrix(this.rows, this.columns);
for (var i = 0; i < this.rows; i++) {
const row = this.getRow(i);
rescale(row, { min, max, output: row });
newMatrix.setRow(i, row);
}
return newMatrix;
}
/**
* Returns a new column-by-column scaled matrix
* @param {object} [options]
* @param {number} [options.min=0] - Minimum scaled value
* @param {number} [optiens.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(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');
var newMatrix = new Matrix(this.rows, this.columns);
for (var i = 0; i < this.columns; i++) {
const column = this.getColumn(i);
rescale(column, {
min: min,
max: max,
output: column
});
newMatrix.setColumn(i, column);
}
return newMatrix;
}
flipRows() {
const middle = Math.ceil(this.columns / 2);
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < middle; j++) {
var first = this.get(i, j);
var last = this.get(i, this.columns - 1 - j);
this.set(i, j, last);
this.set(i, this.columns - 1 - j, first);
}
}
return this;
}
flipColumns() {
const middle = Math.ceil(this.rows / 2);
for (var j = 0; j < this.columns; j++) {
for (var i = 0; i < middle; i++) {
var first = this.get(i, j);
var last = this.get(this.rows - 1 - i, j);
this.set(i, j, last);
this.set(this.rows - 1 - i, j, first);
}
}
return this;
}
/**
* 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 = Matrix.checkMatrix(other);
var m = this.rows;
var n = this.columns;
var p = other.rows;
var q = other.columns;
var result = new Matrix(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.set(p * i + k, q * j + l, this.get(i, j) * other.get(k, l));
}
}
}
}
return result;
}
/**
* Transposes the matrix and returns a new one containing the result
* @return {Matrix}
*/
transpose() {
var result = new Matrix(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));
}
}
return result;
}
/**
* Sorts the rows (in place)
* @param {function} [compareFunction] - usual Array.prototype.sort comparison function
* @return {Matrix} this
*/
sortRows(compareFunction = compareNumbers) {
for (var i = 0; i < this.rows; i++) {
this.setRow(i, this.getRow(i).sort(compareFunction));
}
return this;
}
/**
* Sorts the columns (in place)
* @param {function} [compareFunction] - usual Array.prototype.sort comparison function
* @return {Matrix} this
*/
sortColumns(compareFunction = compareNumbers) {
for (var i = 0; i < this.columns; i++) {
this.setColumn(i, this.getColumn(i).sort(compareFunction));
}
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 Matrix(
endRow - startRow + 1,
endColumn - startColumn + 1
);
for (var i = startRow; i <= endRow; i++) {
for (var j = startColumn; j <= endColumn; j++) {
newMatrix.set(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 Matrix(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));
}
}
return newMatrix;
}
/**
* 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');
}
var newMatrix = new Matrix(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]}`);
}
newMatrix.set(j - startRow, i, this.get(j, indices[i]));
}
}
return newMatrix;
}
/**
* 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 = Matrix.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.set(startRow + i, startColumn + j, matrix.get(i, j));
}
}
return this;
}
/**
* Return a new matrix based on a selection of rows and columns
* @param {Array<number>} rowIndices - The row indices to select. Order matters and an index can be more than once.
* @param {Array<number>} 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 Matrix(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.set(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;
}
/**
* Creates an exact and independent copy of the matrix
* @return {Matrix}
*/
clone() {
var newMatrix = new Matrix(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));
}
}
return newMatrix;
}
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}`);
}
}
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}`);
}
}
variance(by, options = {}) {
if (typeof by === 'object') {
options = by;
by = undefined;
}
if (typeof options !== 'object') {
throw new TypeError('options must be an object');
}
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}`);
}
}
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 (var i = 0; i < variance.length; i++) {
variance[i] = Math.sqrt(variance[i]);
}
return variance;
}
}
}
AbstractMatrix.prototype.klass = 'Matrix';
if (typeof Symbol !== 'undefined') {
AbstractMatrix.prototype[
Symbol.for('nodejs.util.inspect.custom')
] = inspectMatrix;
}
function compareNumbers(a, b) {
return a - b;
}
// Synonyms
AbstractMatrix.random = AbstractMatrix.rand;
AbstractMatrix.randomInt = AbstractMatrix.randInt;
AbstractMatrix.diagonal = AbstractMatrix.diag;
AbstractMatrix.prototype.diagonal = AbstractMatrix.prototype.diag;
AbstractMatrix.identity = AbstractMatrix.eye;
AbstractMatrix.prototype.negate = AbstractMatrix.prototype.neg;
AbstractMatrix.prototype.tensorProduct =
AbstractMatrix.prototype.kroneckerProduct;
export default class Matrix extends AbstractMatrix {

@@ -133,1 +1818,3 @@ constructor(nRows, nColumns) {

}
installMathOperations(AbstractMatrix, Matrix);

@@ -1,2 +0,2 @@

import SvDecomposition from './dc/svd';
import SVD from './dc/svd';
import Matrix from './matrix';

@@ -11,3 +11,3 @@

matrix = Matrix.checkMatrix(matrix);
var svdSolution = new SvDecomposition(matrix, { autoTranspose: true });
var svdSolution = new SVD(matrix, { autoTranspose: true });

@@ -26,5 +26,3 @@ var U = svdSolution.leftSingularVectors;

// convert list to diagonal
s = matrix.constructor[Symbol.species].diag(s);
return V.mmul(s.mmul(U.transpose()));
return V.mmul(Matrix.diag(s).mmul(U.transpose()));
}

@@ -62,1 +62,69 @@ import { newArray } from './util';

}
export function varianceByRow(matrix, unbiased, mean) {
const rows = matrix.rows;
const cols = matrix.columns;
const variance = [];
for (var i = 0; i < rows; i++) {
var sum1 = 0;
var sum2 = 0;
var x = 0;
for (var j = 0; j < cols; j++) {
x = matrix.get(j, i) - 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;
}
export function varianceByColumn(matrix, unbiased, mean) {
const rows = matrix.rows;
const cols = matrix.columns;
const variance = [];
for (var j = 0; j < cols; j++) {
var sum1 = 0;
var sum2 = 0;
var x = 0;
for (var 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;
}
export function varianceAll(matrix, unbiased, mean) {
const rows = matrix.rows;
const cols = matrix.columns;
const size = rows * cols;
var sum1 = 0;
var sum2 = 0;
var x = 0;
for (var i = 0; i < rows; i++) {
for (var 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;
}
}

@@ -0,0 +0,0 @@ /**

@@ -1,3 +0,2 @@

import AbstractMatrix from '../abstractMatrix';
import Matrix from '../matrix';
import { AbstractMatrix } from '../matrix';

@@ -11,6 +10,2 @@ export default class BaseView extends AbstractMatrix {

}
static get [Symbol.species]() {
return Matrix;
}
}

@@ -0,0 +0,0 @@ import { checkColumnIndices } from '../util';

@@ -0,0 +0,0 @@ import BaseView from './base';

@@ -0,0 +0,0 @@ import BaseView from './base';

@@ -1,9 +0,9 @@

export { default as MatrixTransposeView } from './transpose';
export { default as MatrixColumnView } from './column';
export { default as MatrixColumnSelectionView } from './columnSelection';
export { default as MatrixFlipColumnView } from './flipColumn';
export { default as MatrixFlipRowView } from './flipRow';
export { default as MatrixRowView } from './row';
export { default as MatrixRowSelectionView } from './rowSelection';
export { default as MatrixSelectionView } from './selection';
export { default as MatrixSubView } from './sub';
export { default as MatrixSelectionView } from './selection';
export { default as MatrixRowSelectionView } from './rowSelection';
export { default as MatrixColumnSelectionView } from './columnSelection';
export { default as MatrixColumnView } from './column';
export { default as MatrixFlipRowView } from './flipRow';
export { default as MatrixFlipColumnView } from './flipColumn';
export { default as MatrixTransposeView } from './transpose';

@@ -0,0 +0,0 @@ import { checkRowIndices } from '../util';

@@ -0,0 +0,0 @@ import { checkIndices } from '../util';

@@ -0,0 +0,0 @@ import { checkRange } from '../util';

@@ -0,0 +0,0 @@ import BaseView from './base';

@@ -0,0 +0,0 @@ import WrapperMatrix1D from './WrapperMatrix1D';

@@ -1,3 +0,2 @@

import AbstractMatrix from '../abstractMatrix';
import Matrix from '../matrix';
import { AbstractMatrix } from '../matrix';

@@ -37,6 +36,2 @@ export default class WrapperMatrix1D extends AbstractMatrix {

}
static get [Symbol.species]() {
return Matrix;
}
}

@@ -1,3 +0,2 @@

import AbstractMatrix from '../abstractMatrix';
import Matrix from '../matrix';
import { AbstractMatrix } from '../matrix';

@@ -24,6 +23,2 @@ export default class WrapperMatrix2D extends AbstractMatrix {

}
static get [Symbol.species]() {
return Matrix;
}
}
import rescale from 'ml-array-rescale';
import {
checkRowVector,
checkRowIndex,
checkColumnIndex,
checkColumnVector,
checkRange,
checkIndices
} from './util';
import {
sumByRow,
sumByColumn,
sumAll,
productByRow,
productByColumn,
productAll
} from './stat';
export default class AbstractMatrix {
static get [Symbol.species]() {
return this;
}
/**
* 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 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 new this(rows, columns);
}
/**
* 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 new this(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 = new this(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 = new this(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 AbstractMatrix.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);
}
}
return this;
}
/**
* 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);
}
}
return array;
}
/**
* 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;
}
toJSON() {
return this.to2DArray();
}
/**
* @return {boolean} true if the matrix has one row
*/
isRowVector() {
return this.rows === 1;
}
/**
* @return {boolean} true if the matrix has one column
*/
isColumnVector() {
return this.columns === 1;
}
/**
* @return {boolean} true if the matrix has one row or one column
*/
isVector() {
return this.rows === 1 || this.columns === 1;
}
/**
* @return {boolean} true if the matrix has the same number of rows and columns
*/
isSquare() {
return this.rows === this.columns;
}
/**
* @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;
}
/**
* @return true if the matrix is in echelon form
*/
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;
}
/**
* @return true if the matrix is in reduced echelon form
*/
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;
}
/**
* 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
*/
// eslint-disable-next-line no-unused-vars
set(rowIndex, columnIndex, value) {
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}
*/
// eslint-disable-next-line no-unused-vars
get(rowIndex, columnIndex) {
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;
}
/**
* 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]);
}
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);
}
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]);
}
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);
}
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]);
}
}
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]);
}
}
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]);
}
}
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]);
}
}
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]);
}
}
return this;
}
/**
* 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]);
}
}
return this;
}
/**
* 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]);
}
}
return this;
}
/**
* 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]);
}
}
return this;
}
/**
* 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);
}
return this;
}
/**
* 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);
}
return this;
}
/**
* 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);
}
}
}
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;
}
}
}
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);
}
}
}
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;
}
}
}
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;
}
/**
* 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);
}
}
return v;
}
/**
* 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;
}
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}`);
}
}
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}`);
}
}
/**
* 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}`);
}
}
/**
* 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);
}
}
return this;
}
/**
* Computes the dot (scalar) product between the matrix and another
* @param {Matrix} vector2 vector
* @return {number}
*/
dot(vector2) {
if (AbstractMatrix.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.'
);
}
var m = this.rows;
var n = this.columns;
var p = other.columns;
var result = new this.constructor[Symbol.species](m, p);
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);
}
for (var i = 0; i < m; i++) {
var s = 0;
for (k = 0; k < n; k++) {
s += this.get(i, k) * Bcolj[k];
}
result.set(i, j, s);
}
}
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);
// 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;
}
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.`
);
}
// 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 = AbstractMatrix.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(
AbstractMatrix.add(a11, a22),
AbstractMatrix.add(b11, b22),
halfRows,
halfCols
);
var m2 = blockMult(AbstractMatrix.add(a21, a22), b11, halfRows, halfCols);
var m3 = blockMult(a11, AbstractMatrix.sub(b12, b22), halfRows, halfCols);
var m4 = blockMult(a22, AbstractMatrix.sub(b21, b11), halfRows, halfCols);
var m5 = blockMult(AbstractMatrix.add(a11, a12), b22, halfRows, halfCols);
var m6 = blockMult(
AbstractMatrix.sub(a21, a11),
AbstractMatrix.add(b11, b12),
halfRows,
halfCols
);
var m7 = blockMult(
AbstractMatrix.sub(a12, a22),
AbstractMatrix.add(b21, b22),
halfRows,
halfCols
);
// Combine intermediate values into the output.
var c11 = AbstractMatrix.add(m1, m4);
c11.sub(m5);
c11.add(m7);
var c12 = AbstractMatrix.add(m3, m5);
var c21 = AbstractMatrix.add(m2, m4);
var c22 = AbstractMatrix.sub(m1, m2);
c22.add(m3);
c22.add(m6);
// Crop output to the desired size (undo dynamic padding).
var resultat = 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);
}
/**
* 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 = new this.constructor(this.rows, this.columns);
for (var i = 0; i < this.rows; i++) {
const row = this.getRow(i);
rescale(row, { min, max, output: row });
newMatrix.setRow(i, row);
}
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 = new this.constructor(this.rows, this.columns);
for (var i = 0; i < this.columns; i++) {
const column = this.getColumn(i);
rescale(column, {
min: min,
max: max,
output: column
});
newMatrix.setColumn(i, column);
}
return newMatrix;
}
reverseRows() {
const middle = Math.ceil(this.columns / 2);
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < middle; j++) {
var first = this.get(i, j);
var last = this.get(i, this.columns - 1 - j);
this.set(i, j, last);
this.set(i, this.columns - 1 - j, first);
}
}
return this;
}
reverseColumns() {
const middle = Math.ceil(this.rows / 2);
for (var j = 0; j < this.columns; j++) {
for (var i = 0; i < middle; i++) {
var first = this.get(i, j);
var last = this.get(this.rows - 1 - i, j);
this.set(i, j, last);
this.set(this.rows - 1 - i, j, first);
}
}
return this;
}
/**
* 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);
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.set(p * i + k, q * j + l, this.get(i, j) * other.get(k, l));
}
}
}
}
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));
}
}
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));
}
return this;
}
/**
* 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));
}
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.set(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));
}
}
return newMatrix;
}
/**
* 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');
}
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]}`);
}
newMatrix.set(j - startRow, i, this.get(j, indices[i]));
}
}
return newMatrix;
}
/**
* 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.set(startRow + i, startColumn + j, matrix.get(i, j));
}
}
return this;
}
/**
* Return a new matrix based on a selection of rows and columns
* @param {Array<number>} rowIndices - The row indices to select. Order matters and an index can be more than once.
* @param {Array<number>} 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.set(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;
}
/**
* 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));
}
}
return newMatrix;
}
entropy(eps = 0) {
var sum = 0;
for (var i = 0; i < this.rows; i++) {
for (var j = 0; j < this.columns; j++) {
sum += this.get(i, j) * Math.log(this.get(i, j) + eps);
}
}
return 0 - sum;
}
variance(unbiased = true, means = this.mean('column')) {
if (typeof unbiased !== 'boolean') {
throw new TypeError('unbiased must be a boolean');
}
if (!Array.isArray(means)) {
throw new TypeError('means must be an array');
}
const rows = this.rows;
const cols = this.columns;
const variance = [];
for (var j = 0; j < cols; j++) {
var sum1 = 0;
var sum2 = 0;
var x = 0;
for (var i = 0; i < rows; i++) {
x = this.get(i, j) - means[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;
}
standardDeviation(unbiased = true, means = this.mean('column')) {
if (typeof unbiased !== 'boolean') {
throw new TypeError('unbiased must be a boolean');
}
if (!Array.isArray(means)) {
throw new TypeError('means must be an array');
}
const variance = this.variance(unbiased, means);
for (var i = 0; i < variance.length; i++) {
variance[i] = Math.sqrt(variance[i]);
}
return variance;
}
}
AbstractMatrix.prototype.klass = 'Matrix';
function compareNumbers(a, b) {
return a - b;
}
/*
Synonyms
*/
AbstractMatrix.random = AbstractMatrix.rand;
AbstractMatrix.diagonal = AbstractMatrix.diag;
AbstractMatrix.prototype.diagonal = AbstractMatrix.prototype.diag;
AbstractMatrix.identity = AbstractMatrix.eye;
AbstractMatrix.prototype.negate = AbstractMatrix.prototype.neg;
AbstractMatrix.prototype.tensorProduct =
AbstractMatrix.prototype.kroneckerProduct;
/*
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);
})
`;
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);
}
}
return this;
})
`;
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');
}
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));
}
}
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)));
}
}
return this;
})
`;
var staticMethod = `
(function %name%(matrix) {
var newMatrix = new this[Symbol.species](matrix);
return newMatrix.%name%();
})
`;
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%));
}
}
return this;
})
`;
var staticMethodWithArgs = `
(function %name%(matrix, %args%) {
var newMatrix = new this[Symbol.species](matrix);
return newMatrix.%name%(%args%);
})
`;
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));
}
}
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');
}
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)));
}
}
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++) {
AbstractMatrix.prototype[operator[i]] = inplaceOp;
AbstractMatrix.prototype[`${operator[i]}S`] = inplaceOpS;
AbstractMatrix.prototype[`${operator[i]}M`] = inplaceOpM;
AbstractMatrix[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++) {
AbstractMatrix.prototype[method[i]] = inplaceMeth;
AbstractMatrix[method[i]] = staticMeth;
}
}
var methodsWithArgs = [['Math.pow', 1, 'pow']];
for (var methodWithArg of methodsWithArgs) {
var args = 'arg0';
for (i = 1; i < methodWithArg[1]; i++) {
args += `, arg${i}`;
}
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++) {
AbstractMatrix.prototype[methodWithArg[i]] = inplaceMethWithArgs;
AbstractMatrix[methodWithArg[i]] = staticMethWithArgs;
}
} 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++) {
AbstractMatrix.prototype[methodWithArg[i]] = inplaceMethod2;
AbstractMatrix.prototype[`${methodWithArg[i]}M`] = inplaceMethodM;
AbstractMatrix.prototype[`${methodWithArg[i]}S`] = inplaceMethodS;
AbstractMatrix[methodWithArg[i]] = staticMethod2;
}
}
}
function fillTemplateFunction(template, values) {
for (var value in values) {
template = template.replace(new RegExp(`%${value}%`, 'g'), values[value]);
}
return template;
}

Sorry, the diff of this file is too big to display