Comparing version 1.4.0 to 2.0.0
@@ -0,1 +1,24 @@ | ||
<a name="2.0.0"></a> | ||
# [2.0.0](https://github.com/mljs/matrix/compare/v1.4.0...v2.0.0) (2016-08-04) | ||
### Features | ||
* add column view ([5ff6680](https://github.com/mljs/matrix/commit/5ff6680)) | ||
* add concept of abstract matrix ([cbefc9b](https://github.com/mljs/matrix/commit/cbefc9b)) | ||
* add flipColumn and flipRow views ([55ee4a6](https://github.com/mljs/matrix/commit/55ee4a6)) | ||
* add method subMatrixView ([aa1df18](https://github.com/mljs/matrix/commit/aa1df18)) | ||
* add row view ([a9e99f2](https://github.com/mljs/matrix/commit/a9e99f2)) | ||
* add selection method and selection view ([59aa861](https://github.com/mljs/matrix/commit/59aa861)) | ||
* add transposeView ([fb0a0c9](https://github.com/mljs/matrix/commit/fb0a0c9)) | ||
* make use of Symbol.species to allow creating new matrices in any class ([eaee5de](https://github.com/mljs/matrix/commit/eaee5de)) | ||
### BREAKING CHANGES | ||
* This is a non trivial change and could potentially break existing code. | ||
There is no known backward incompatibility though. | ||
<a name="1.4.0"></a> | ||
@@ -2,0 +25,0 @@ # [1.4.0](https://github.com/mljs/matrix/compare/v1.3.0...v1.4.0) (2016-08-03) |
{ | ||
"name": "ml-matrix", | ||
"version": "1.4.0", | ||
"version": "2.0.0", | ||
"description": "Matrix manipulation and computation library", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
1482
src/matrix.js
'use strict'; | ||
const arrayUtils = require('ml-array-utils'); | ||
require('./symbol-species'); | ||
var abstractMatrix = require('./abstractMatrix'); | ||
var util = require('./util'); | ||
/** | ||
* Real matrix | ||
* @class Matrix | ||
* @param {number|Array|Matrix} nRows - Number of rows of the new matrix, | ||
* 2D array containing the data or Matrix instance to clone | ||
* @param {number} [nColumns] - Number of columns of the new matrix | ||
*/ | ||
class Matrix extends Array { | ||
class Matrix extends abstractMatrix(Array) { | ||
constructor(nRows, nColumns) { | ||
if (arguments.length === 1 && typeof nRows === 'number') { | ||
return new Array(nRows); | ||
} | ||
if (Matrix.isMatrix(nRows)) { | ||
@@ -46,218 +44,12 @@ return nRows.clone(); | ||
// Native array methods should return instances of Array, not Matrix | ||
static get [Symbol.species]() { | ||
return Array; | ||
set(rowIndex, columnIndex, value) { | ||
this[rowIndex][columnIndex] = value; | ||
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 | ||
* @returns {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[row][column] = newData[row * newColumns + column]; | ||
} | ||
} | ||
return newMatrix; | ||
get(rowIndex, columnIndex) { | ||
return this[rowIndex][columnIndex]; | ||
} | ||
/** | ||
* Creates a row vector, a matrix with only one row. | ||
* @param {Array} newData - A 1D array containing data for the vector | ||
* @returns {Matrix} - The new matrix | ||
*/ | ||
static rowVector(newData) { | ||
var vector = new Matrix(1, newData.length); | ||
for (var i = 0; i < newData.length; i++) { | ||
vector[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 | ||
* @returns {Matrix} - The new matrix | ||
*/ | ||
static columnVector(newData) { | ||
var vector = new Matrix(newData.length, 1); | ||
for (var i = 0; i < newData.length; i++) { | ||
vector[i][0] = newData[i]; | ||
} | ||
return vector; | ||
} | ||
/** | ||
* Creates an empty matrix with the given dimensions. Values will be undefined. Same as using new Matrix(rows, columns). | ||
* @param {number} rows - Number of rows | ||
* @param {number} columns - Number of columns | ||
* @returns {Matrix} - The new matrix | ||
*/ | ||
static empty(rows, columns) { | ||
return new Matrix(rows, columns); | ||
} | ||
/** | ||
* Creates a matrix with the given dimensions. Values will be set to zero. | ||
* @param {number} rows - Number of rows | ||
* @param {number} columns - Number of columns | ||
* @returns {Matrix} - The new matrix | ||
*/ | ||
static zeros(rows, columns) { | ||
return Matrix.empty(rows, columns).fill(0); | ||
} | ||
/** | ||
* Creates a matrix with the given dimensions. Values will be set to one. | ||
* @param {number} rows - Number of rows | ||
* @param {number} columns - Number of columns | ||
* @returns {Matrix} - The new matrix | ||
*/ | ||
static ones(rows, columns) { | ||
return Matrix.empty(rows, columns).fill(1); | ||
} | ||
/** | ||
* Creates a matrix with the given dimensions. Values will be randomly set. | ||
* @param {number} rows - Number of rows | ||
* @param {number} columns - Number of columns | ||
* @param {function} [rng] - Random number generator (default: Math.random) | ||
* @returns {Matrix} The new matrix | ||
*/ | ||
static rand(rows, columns, rng) { | ||
if (rng === undefined) rng = Math.random; | ||
var matrix = Matrix.empty(rows, columns); | ||
for (var i = 0; i < rows; i++) { | ||
for (var j = 0; j < columns; j++) { | ||
matrix[i][j] = rng(); | ||
} | ||
} | ||
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] - Number of columns (Default: rows) | ||
* @returns {Matrix} - The new identity matrix | ||
*/ | ||
static eye(rows, columns) { | ||
if (columns === undefined) columns = rows; | ||
var min = Math.min(rows, columns); | ||
var matrix = Matrix.zeros(rows, columns); | ||
for (var i = 0; i < min; i++) { | ||
matrix[i][i] = 1; | ||
} | ||
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) | ||
* @returns {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 = Matrix.zeros(rows, columns); | ||
for (var i = 0; i < min; i++) { | ||
matrix[i][i] = data[i]; | ||
} | ||
return matrix; | ||
} | ||
/** | ||
* Returns a matrix whose elements are the minimum between matrix1 and matrix2 | ||
* @param matrix1 | ||
* @param matrix2 | ||
* @returns {Matrix} | ||
*/ | ||
static min(matrix1, matrix2) { | ||
var rows = matrix1.length; | ||
var columns = matrix1[0].length; | ||
var result = new Matrix(rows, columns); | ||
for (var i = 0; i < rows; i++) { | ||
for (var j = 0; j < columns; j++) { | ||
result[i][j] = Math.min(matrix1[i][j], matrix2[i][j]); | ||
} | ||
} | ||
return result; | ||
} | ||
/** | ||
* Returns a matrix whose elements are the maximum between matrix1 and matrix2 | ||
* @param matrix1 | ||
* @param matrix2 | ||
* @returns {Matrix} | ||
*/ | ||
static max(matrix1, matrix2) { | ||
var rows = matrix1.length; | ||
var columns = matrix1[0].length; | ||
var result = new Matrix(rows, columns); | ||
for (var i = 0; i < rows; i++) { | ||
for (var j = 0; j < columns; j++) { | ||
result[i][j] = Math.max(matrix1[i][j], matrix2[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 | ||
* @returns {Matrix} | ||
*/ | ||
static checkMatrix(value) { | ||
return Matrix.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'); | ||
} | ||
/** | ||
* @property {number} - 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) | ||
* @returns {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; | ||
} | ||
/** | ||
* Creates an exact and independent copy of the matrix | ||
@@ -267,6 +59,6 @@ * @returns {Matrix} | ||
clone() { | ||
var newMatrix = new Matrix(this.rows, this.columns); | ||
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[row][column] = this[row][column]; | ||
newMatrix.set(row, column, this.get(row, column)); | ||
} | ||
@@ -278,170 +70,2 @@ } | ||
/** | ||
* Returns a new 1D array filled row by row with the matrix values | ||
* @returns {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[i][j]; | ||
} | ||
} | ||
return array; | ||
} | ||
/** | ||
* Returns a 2D array containing a copy of the data | ||
* @returns {Array} | ||
*/ | ||
to2DArray() { | ||
var copy = new Array(this.rows); | ||
for (var i = 0; i < this.rows; i++) { | ||
copy[i] = [].concat(this[i]); | ||
} | ||
return copy; | ||
} | ||
/** | ||
* @returns {boolean} true if the matrix has one row | ||
*/ | ||
isRowVector() { | ||
return this.rows === 1; | ||
} | ||
/** | ||
* @returns {boolean} true if the matrix has one column | ||
*/ | ||
isColumnVector() { | ||
return this.columns === 1; | ||
} | ||
/** | ||
* @returns {boolean} true if the matrix has one row or one column | ||
*/ | ||
isVector() { | ||
return (this.rows === 1) || (this.columns === 1); | ||
} | ||
/** | ||
* @returns {boolean} true if the matrix has the same number of rows and columns | ||
*/ | ||
isSquare() { | ||
return this.rows === this.columns; | ||
} | ||
/** | ||
* @returns {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[i][j] !== this[j][i]) { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
/** | ||
* Sets a given element of the matrix. mat.set(3,4,1) is equivalent to mat[3][4]=1 | ||
* @param {number} rowIndex - Index of the row | ||
* @param {number} columnIndex - Index of the column | ||
* @param {number} value - The new value for the element | ||
* @returns {Matrix} this | ||
*/ | ||
set(rowIndex, columnIndex, value) { | ||
this[rowIndex][columnIndex] = value; | ||
return this; | ||
} | ||
/** | ||
* Returns the given element of the matrix. mat.get(3,4) is equivalent to matrix[3][4] | ||
* @param {number} rowIndex - Index of the row | ||
* @param {number} columnIndex - Index of the column | ||
* @returns {number} | ||
*/ | ||
get(rowIndex, columnIndex) { | ||
return this[rowIndex][columnIndex]; | ||
} | ||
/** | ||
* 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 | ||
* @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 Matrix(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 | ||
* @returns {Matrix} this | ||
*/ | ||
fill(value) { | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
this[i][j] = value; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Negates the matrix. All elements will be multiplied by (-1) | ||
* @returns {Matrix} this | ||
*/ | ||
neg() { | ||
return this.mulS(-1); | ||
} | ||
/** | ||
* Returns a new array from the given row index | ||
* @param {number} index - Row index | ||
* @returns {Array} | ||
*/ | ||
getRow(index) { | ||
checkRowIndex(this, index); | ||
return [].concat(this[index]); | ||
} | ||
/** | ||
* Returns a new row vector from the given row index | ||
* @param {number} index - Row index | ||
* @returns {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 | ||
* @returns {Matrix} this | ||
*/ | ||
setRow(index, array) { | ||
checkRowIndex(this, index); | ||
array = checkRowVector(this, array, true); | ||
this[index] = array; | ||
return this; | ||
} | ||
/** | ||
* Removes a row from the given index | ||
@@ -452,3 +76,3 @@ * @param {number} index - Row index | ||
removeRow(index) { | ||
checkRowIndex(this, index); | ||
util.checkRowIndex(this, index); | ||
if (this.rows === 1) | ||
@@ -472,4 +96,4 @@ throw new RangeError('A matrix cannot have less than one row'); | ||
} | ||
checkRowIndex(this, index, true); | ||
array = checkRowVector(this, array, true); | ||
util.checkRowIndex(this, index, true); | ||
array = util.checkRowVector(this, array, true); | ||
this.splice(index, 0, array); | ||
@@ -481,55 +105,2 @@ this.rows += 1; | ||
/** | ||
* Swaps two rows | ||
* @param {number} row1 - First row index | ||
* @param {number} row2 - Second row index | ||
* @returns {Matrix} this | ||
*/ | ||
swapRows(row1, row2) { | ||
checkRowIndex(this, row1); | ||
checkRowIndex(this, row2); | ||
var temp = this[row1]; | ||
this[row1] = this[row2]; | ||
this[row2] = temp; | ||
return this; | ||
} | ||
/** | ||
* Returns a new array from the given column index | ||
* @param {number} index - Column index | ||
* @returns {Array} | ||
*/ | ||
getColumn(index) { | ||
checkColumnIndex(this, index); | ||
var column = new Array(this.rows); | ||
for (var i = 0; i < this.rows; i++) { | ||
column[i] = this[i][index]; | ||
} | ||
return column; | ||
} | ||
/** | ||
* Returns a new column vector from the given column index | ||
* @param {number} index - Column index | ||
* @returns {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 | ||
* @returns {Matrix} this | ||
*/ | ||
setColumn(index, array) { | ||
checkColumnIndex(this, index); | ||
array = checkColumnVector(this, array); | ||
for (var i = 0; i < this.rows; i++) { | ||
this[i][index] = array[i]; | ||
} | ||
return this; | ||
} | ||
/** | ||
* Removes a column from the given index | ||
@@ -540,3 +111,3 @@ * @param {number} index - Column index | ||
removeColumn(index) { | ||
checkColumnIndex(this, index); | ||
util.checkColumnIndex(this, index); | ||
if (this.columns === 1) | ||
@@ -562,4 +133,4 @@ throw new RangeError('A matrix cannot have less than one column'); | ||
} | ||
checkColumnIndex(this, index, true); | ||
array = checkColumnVector(this, array); | ||
util.checkColumnIndex(this, index, true); | ||
array = util.checkColumnVector(this, array); | ||
for (var i = 0; i < this.rows; i++) { | ||
@@ -571,1016 +142,5 @@ this[i].splice(index, 0, array[i]); | ||
} | ||
/** | ||
* Swaps two columns | ||
* @param {number} column1 - First column index | ||
* @param {number} column2 - Second column index | ||
* @returns {Matrix} this | ||
*/ | ||
swapColumns(column1, column2) { | ||
checkColumnIndex(this, column1); | ||
checkColumnIndex(this, column2); | ||
var temp, row; | ||
for (var i = 0; i < this.rows; i++) { | ||
row = this[i]; | ||
temp = row[column1]; | ||
row[column1] = row[column2]; | ||
row[column2] = temp; | ||
} | ||
return this; | ||
} | ||
/** | ||
* Adds the values of a vector to each row | ||
* @param {Array|Matrix} vector - Array or vector | ||
* @returns {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[i][j] += vector[j]; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Subtracts the values of a vector from each row | ||
* @param {Array|Matrix} vector - Array or vector | ||
* @returns {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[i][j] -= vector[j]; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Multiplies the values of a vector with each row | ||
* @param {Array|Matrix} vector - Array or vector | ||
* @returns {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[i][j] *= vector[j]; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Divides the values of each row by those of a vector | ||
* @param {Array|Matrix} vector - Array or vector | ||
* @returns {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[i][j] /= vector[j]; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Adds the values of a vector to each column | ||
* @param {Array|Matrix} vector - Array or vector | ||
* @returns {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[i][j] += vector[i]; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Subtracts the values of a vector from each column | ||
* @param {Array|Matrix} vector - Array or vector | ||
* @returns {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[i][j] -= vector[i]; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Multiplies the values of a vector with each column | ||
* @param {Array|Matrix} vector - Array or vector | ||
* @returns {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[i][j] *= vector[i]; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Divides the values of each column by those of a vector | ||
* @param {Array|Matrix} vector - Array or vector | ||
* @returns {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[i][j] /= vector[i]; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Multiplies the values of a row with a scalar | ||
* @param {number} index - Row index | ||
* @param {number} value | ||
* @returns {Matrix} this | ||
*/ | ||
mulRow(index, value) { | ||
checkRowIndex(this, index); | ||
for (var i = 0; i < this.columns; i++) { | ||
this[index][i] *= value; | ||
} | ||
return this; | ||
} | ||
/** | ||
* Multiplies the values of a column with a scalar | ||
* @param {number} index - Column index | ||
* @param {number} value | ||
* @returns {Matrix} this | ||
*/ | ||
mulColumn(index, value) { | ||
checkColumnIndex(this, index); | ||
for (var i = 0; i < this.rows; i++) { | ||
this[i][index] *= value; | ||
} | ||
} | ||
/** | ||
* Returns the maximum value of the matrix | ||
* @returns {number} | ||
*/ | ||
max() { | ||
var v = this[0][0]; | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
if (this[i][j] > v) { | ||
v = this[i][j]; | ||
} | ||
} | ||
} | ||
return v; | ||
} | ||
/** | ||
* Returns the index of the maximum value | ||
* @returns {Array} | ||
*/ | ||
maxIndex() { | ||
var v = this[0][0]; | ||
var idx = [0, 0]; | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
if (this[i][j] > v) { | ||
v = this[i][j]; | ||
idx[0] = i; | ||
idx[1] = j; | ||
} | ||
} | ||
} | ||
return idx; | ||
} | ||
/** | ||
* Returns the minimum value of the matrix | ||
* @returns {number} | ||
*/ | ||
min() { | ||
var v = this[0][0]; | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
if (this[i][j] < v) { | ||
v = this[i][j]; | ||
} | ||
} | ||
} | ||
return v; | ||
} | ||
/** | ||
* Returns the index of the minimum value | ||
* @returns {Array} | ||
*/ | ||
minIndex() { | ||
var v = this[0][0]; | ||
var idx = [0, 0]; | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
if (this[i][j] < v) { | ||
v = this[i][j]; | ||
idx[0] = i; | ||
idx[1] = j; | ||
} | ||
} | ||
} | ||
return idx; | ||
} | ||
/** | ||
* Returns the maximum value of one row | ||
* @param {number} row - Row index | ||
* @returns {number} | ||
*/ | ||
maxRow(row) { | ||
checkRowIndex(this, row); | ||
var v = this[row][0]; | ||
for (var i = 1; i < this.columns; i++) { | ||
if (this[row][i] > v) { | ||
v = this[row][i]; | ||
} | ||
} | ||
return v; | ||
} | ||
/** | ||
* Returns the index of the maximum value of one row | ||
* @param {number} row - Row index | ||
* @returns {Array} | ||
*/ | ||
maxRowIndex(row) { | ||
checkRowIndex(this, row); | ||
var v = this[row][0]; | ||
var idx = [row, 0]; | ||
for (var i = 1; i < this.columns; i++) { | ||
if (this[row][i] > v) { | ||
v = this[row][i]; | ||
idx[1] = i; | ||
} | ||
} | ||
return idx; | ||
} | ||
/** | ||
* Returns the minimum value of one row | ||
* @param {number} row - Row index | ||
* @returns {number} | ||
*/ | ||
minRow(row) { | ||
checkRowIndex(this, row); | ||
var v = this[row][0]; | ||
for (var i = 1; i < this.columns; i++) { | ||
if (this[row][i] < v) { | ||
v = this[row][i]; | ||
} | ||
} | ||
return v; | ||
} | ||
/** | ||
* Returns the index of the maximum value of one row | ||
* @param {number} row - Row index | ||
* @returns {Array} | ||
*/ | ||
minRowIndex(row) { | ||
checkRowIndex(this, row); | ||
var v = this[row][0]; | ||
var idx = [row, 0]; | ||
for (var i = 1; i < this.columns; i++) { | ||
if (this[row][i] < v) { | ||
v = this[row][i]; | ||
idx[1] = i; | ||
} | ||
} | ||
return idx; | ||
} | ||
/** | ||
* Returns the maximum value of one column | ||
* @param {number} column - Column index | ||
* @returns {number} | ||
*/ | ||
maxColumn(column) { | ||
checkColumnIndex(this, column); | ||
var v = this[0][column]; | ||
for (var i = 1; i < this.rows; i++) { | ||
if (this[i][column] > v) { | ||
v = this[i][column]; | ||
} | ||
} | ||
return v; | ||
} | ||
/** | ||
* Returns the index of the maximum value of one column | ||
* @param {number} column - Column index | ||
* @returns {Array} | ||
*/ | ||
maxColumnIndex(column) { | ||
checkColumnIndex(this, column); | ||
var v = this[0][column]; | ||
var idx = [0, column]; | ||
for (var i = 1; i < this.rows; i++) { | ||
if (this[i][column] > v) { | ||
v = this[i][column]; | ||
idx[0] = i; | ||
} | ||
} | ||
return idx; | ||
} | ||
/** | ||
* Returns the minimum value of one column | ||
* @param {number} column - Column index | ||
* @returns {number} | ||
*/ | ||
minColumn(column) { | ||
checkColumnIndex(this, column); | ||
var v = this[0][column]; | ||
for (var i = 1; i < this.rows; i++) { | ||
if (this[i][column] < v) { | ||
v = this[i][column]; | ||
} | ||
} | ||
return v; | ||
} | ||
/** | ||
* Returns the index of the minimum value of one column | ||
* @param {number} column - Column index | ||
* @returns {Array} | ||
*/ | ||
minColumnIndex(column) { | ||
checkColumnIndex(this, column); | ||
var v = this[0][column]; | ||
var idx = [0, column]; | ||
for (var i = 1; i < this.rows; i++) { | ||
if (this[i][column] < v) { | ||
v = this[i][column]; | ||
idx[0] = i; | ||
} | ||
} | ||
return idx; | ||
} | ||
/** | ||
* Returns an array containing the diagonal values of the matrix | ||
* @returns {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[i][i]; | ||
} | ||
return diag; | ||
} | ||
/** | ||
* Returns the sum of all elements of the matrix | ||
* @returns {number} | ||
*/ | ||
sum() { | ||
var v = 0; | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
v += this[i][j]; | ||
} | ||
} | ||
return v; | ||
} | ||
/** | ||
* Returns the mean of all elements of the matrix | ||
* @returns {number} | ||
*/ | ||
mean() { | ||
return this.sum() / this.size; | ||
} | ||
/** | ||
* Returns the product of all elements of the matrix | ||
* @returns {number} | ||
*/ | ||
prod() { | ||
var prod = 1; | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
prod *= this[i][j]; | ||
} | ||
} | ||
return prod; | ||
} | ||
/** | ||
* Computes the cumulative sum of the matrix elements (in place, row by row) | ||
* @returns {Matrix} this | ||
*/ | ||
cumulativeSum() { | ||
var sum = 0; | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
sum += this[i][j]; | ||
this[i][j] = sum; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Computes the dot (scalar) product between the matrix and another | ||
* @param {Matrix} vector2 vector | ||
* @returns {number} | ||
*/ | ||
dot(vector2) { | ||
if (Matrix.isMatrix(vector2)) vector2 = vector2.to1DArray(); | ||
var vector1 = this.to1DArray(); | ||
if (vector1.length !== vector2.length) { | ||
throw new RangeError('vectors do not have the same size'); | ||
} | ||
var dot = 0; | ||
for (var i = 0; i < vector1.length; i++) { | ||
dot += vector1[i] * vector2[i]; | ||
} | ||
return dot; | ||
} | ||
/** | ||
* Returns the matrix product between this and other | ||
* @param {Matrix} other | ||
* @returns {Matrix} | ||
*/ | ||
mmul(other) { | ||
other = Matrix.checkMatrix(other); | ||
if (this.columns !== other.rows) | ||
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[k][j]; | ||
for (var i = 0; i < m; i++) { | ||
var Arowi = this[i]; | ||
var s = 0; | ||
for (k = 0; k < n; k++) | ||
s += Arowi[k] * Bcolj[k]; | ||
result[i][j] = s; | ||
} | ||
} | ||
return result; | ||
} | ||
/** | ||
* Returns a row-by-row scaled matrix | ||
* @param {Number} [min=0] - Minimum scaled value | ||
* @param {Number} [max=1] - Maximum scaled value | ||
* @returns {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 = Matrix.empty(this.rows, this.columns); | ||
for (var i = 0; i < this.rows; i++) { | ||
var scaled = arrayUtils.scale(this.getRow(i), {min, max}); | ||
newMatrix.setRow(i, scaled); | ||
} | ||
return newMatrix; | ||
} | ||
/** | ||
* Returns a new column-by-column scaled matrix | ||
* @param {Number} [min=0] - Minimum scaled value | ||
* @param {Number} [max=1] - Maximum scaled value | ||
* @returns {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 = Matrix.empty(this.rows, this.columns); | ||
for (var i = 0; i < this.columns; i++) { | ||
var scaled = arrayUtils.scale(this.getColumn(i), { | ||
min: min, | ||
max: max | ||
}); | ||
newMatrix.setColumn(i, scaled); | ||
} | ||
return newMatrix; | ||
} | ||
/** | ||
* 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[p * i + k][q * j + l] = this[i][j] * other[k][l]; | ||
} | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
/** | ||
* Transposes the matrix and returns a new one containing the result | ||
* @returns {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[j][i] = this[i][j]; | ||
} | ||
} | ||
return result; | ||
} | ||
/** | ||
* Sorts the rows (in place) | ||
* @param {function} compareFunction - usual Array.prototype.sort comparison function | ||
* @returns {Matrix} this | ||
*/ | ||
sortRows(compareFunction) { | ||
if (compareFunction === undefined) compareFunction = compareNumbers; | ||
for (var i = 0; i < this.rows; i++) { | ||
this[i].sort(compareFunction); | ||
} | ||
return this; | ||
} | ||
/** | ||
* Sorts the columns (in place) | ||
* @param {function} compareFunction - usual Array.prototype.sort comparison function | ||
* @returns {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 | ||
* @returns {Matrix} | ||
*/ | ||
subMatrix(startRow, endRow, startColumn, endColumn) { | ||
if ((startRow > endRow) || (startColumn > endColumn) || (startRow < 0) || (startRow >= this.rows) || (endRow < 0) || (endRow >= this.rows) || (startColumn < 0) || (startColumn >= this.columns) || (endColumn < 0) || (endColumn >= this.columns)) { | ||
throw new RangeError('Argument out of range'); | ||
} | ||
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[i - startRow][j - startColumn] = this[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 | ||
* @returns {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[i][j - startColumn] = this[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 | ||
* @returns {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[j - startRow][i] = this[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 startRow - The index of the first row to set | ||
* @param startColumn - The index of the first column to set | ||
* @returns {Matrix} | ||
*/ | ||
setSubMatrix(matrix, startRow, startColumn) { | ||
matrix = Matrix.checkMatrix(matrix); | ||
var endRow = startRow + matrix.rows - 1; | ||
var endColumn = startColumn + matrix.columns - 1; | ||
if ((startRow > endRow) || (startColumn > endColumn) || (startRow < 0) || (startRow >= this.rows) || (endRow < 0) || (endRow >= this.rows) || (startColumn < 0) || (startColumn >= this.columns) || (endColumn < 0) || (endColumn >= this.columns)) { | ||
throw new RangeError('Argument out of range'); | ||
} | ||
for (var i = 0; i < matrix.rows; i++) { | ||
for (var j = 0; j < matrix.columns; j++) { | ||
this[startRow + i][startColumn + j] = matrix[i][j]; | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* Returns the trace of the matrix (sum of the diagonal elements) | ||
* @returns {number} | ||
*/ | ||
trace() { | ||
var min = Math.min(this.rows, this.columns); | ||
var trace = 0; | ||
for (var i = 0; i < min; i++) { | ||
trace += this[i][i]; | ||
} | ||
return trace; | ||
} | ||
} | ||
Matrix.prototype.klass = 'Matrix'; | ||
module.exports = Matrix; | ||
/** | ||
* @private | ||
* Check that a row index is not out of bounds | ||
* @param {Matrix} matrix | ||
* @param {number} index | ||
* @param {boolean} [outer] | ||
*/ | ||
function checkRowIndex(matrix, index, outer) { | ||
var max = outer ? matrix.rows : matrix.rows - 1; | ||
if (index < 0 || index > max) | ||
throw new RangeError('Row index out of range'); | ||
} | ||
/** | ||
* @private | ||
* Check that the provided vector is an array with the right length | ||
* @param {Matrix} matrix | ||
* @param {Array|Matrix} vector | ||
* @param {boolean} copy | ||
* @returns {Array} | ||
* @throws {RangeError} | ||
*/ | ||
function checkRowVector(matrix, vector, copy) { | ||
if (Matrix.isMatrix(vector)) { | ||
vector = vector.to1DArray(); | ||
} else if (copy) { | ||
vector = [].concat(vector); | ||
} | ||
if (vector.length !== matrix.columns) | ||
throw new RangeError('vector size must be the same as the number of columns'); | ||
return vector; | ||
} | ||
/** | ||
* @private | ||
* Check that the provided vector is an array with the right length | ||
* @param {Matrix} matrix | ||
* @param {Array|Matrix} vector | ||
* @param {boolean} copy | ||
* @returns {Array} | ||
* @throws {RangeError} | ||
*/ | ||
function checkColumnVector(matrix, vector, copy) { | ||
if (Matrix.isMatrix(vector)) { | ||
vector = vector.to1DArray(); | ||
} else if (copy) { | ||
vector = [].concat(vector); | ||
} | ||
if (vector.length !== matrix.rows) | ||
throw new RangeError('vector size must be the same as the number of rows'); | ||
return vector; | ||
} | ||
/** | ||
* @private | ||
* Check that a column index is not out of bounds | ||
* @param {Matrix} matrix | ||
* @param {number} index | ||
* @param {boolean} [outer] | ||
*/ | ||
function checkColumnIndex(matrix, index, outer) { | ||
var max = outer ? matrix.columns : matrix.columns - 1; | ||
if (index < 0 || index > max) | ||
throw new RangeError('Column index out of range'); | ||
} | ||
/** | ||
* @private | ||
* Check that two matrices have the same dimensions | ||
* @param {Matrix} matrix | ||
* @param {Matrix} otherMatrix | ||
*/ | ||
function checkDimensions(matrix, otherMatrix) { | ||
if (matrix.rows !== otherMatrix.length || | ||
matrix.columns !== otherMatrix[0].length) { | ||
throw new RangeError('Matrices dimensions must be equal'); | ||
} | ||
} | ||
function compareNumbers(a, b) { | ||
return a - b; | ||
} | ||
/* | ||
Synonyms | ||
*/ | ||
Matrix.random = Matrix.rand; | ||
Matrix.diagonal = Matrix.diag; | ||
Matrix.prototype.diagonal = Matrix.prototype.diag; | ||
Matrix.identity = Matrix.eye; | ||
Matrix.prototype.negate = Matrix.prototype.neg; | ||
Matrix.prototype.tensorProduct = Matrix.prototype.kroneckerProduct; | ||
/* | ||
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[i][j] = this[i][j] %op% value; | ||
} | ||
} | ||
return this; | ||
}) | ||
`; | ||
var inplaceOperatorMatrix = ` | ||
(function %name%M(matrix) { | ||
checkDimensions(this, matrix); | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
this[i][j] = this[i][j] %op% matrix[i][j]; | ||
} | ||
} | ||
return this; | ||
}) | ||
`; | ||
var staticOperator = ` | ||
(function %name%(matrix, value) { | ||
var newMatrix = new Matrix(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[i][j] = %method%(this[i][j]); | ||
} | ||
} | ||
return this; | ||
}) | ||
`; | ||
var staticMethod = ` | ||
(function %name%(matrix) { | ||
var newMatrix = new Matrix(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[i][j] = %method%(this[i][j], %args%); | ||
} | ||
} | ||
return this; | ||
}) | ||
`; | ||
var staticMethodWithArgs = ` | ||
(function %name%(matrix, %args%) { | ||
var newMatrix = new Matrix(matrix); | ||
return newMatrix.%name%(%args%); | ||
}) | ||
`; | ||
var inplaceMethodWithOneArgScalar = ` | ||
(function %name%S(%args%) { | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
this[i][j] = %method%(this[i][j], %args%); | ||
} | ||
} | ||
return this; | ||
}) | ||
`; | ||
var inplaceMethodWithOneArgMatrix = ` | ||
(function %name%M(%args%) { | ||
checkDimensions(this, %args%); | ||
for (var i = 0; i < this.rows; i++) { | ||
for (var j = 0; j < this.columns; j++) { | ||
this[i][j] = %method%(this[i][j], %args%[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'] | ||
]; | ||
for (var operator of operators) { | ||
var inplaceOp = eval(fillTemplateFunction(inplaceOperator, {name: operator[1], op: operator[0]})); | ||
var inplaceOpS = eval(fillTemplateFunction(inplaceOperatorScalar, {name: operator[1] + 'S', op: operator[0]})); | ||
var inplaceOpM = eval(fillTemplateFunction(inplaceOperatorMatrix, {name: operator[1] + 'M', op: operator[0]})); | ||
var staticOp = eval(fillTemplateFunction(staticOperator, {name: operator[1]})); | ||
for (var i = 1; i < operator.length; i++) { | ||
Matrix.prototype[operator[i]] = inplaceOp; | ||
Matrix.prototype[operator[i] + 'S'] = inplaceOpS; | ||
Matrix.prototype[operator[i] + 'M'] = inplaceOpM; | ||
Matrix[operator[i]] = staticOp; | ||
} | ||
} | ||
var methods = [ | ||
['~', 'not'] | ||
]; | ||
[ | ||
'abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cbrt', 'ceil', | ||
'clz32', 'cos', 'cosh', 'exp', 'expm1', 'floor', 'fround', 'log', 'log1p', | ||
'log10', 'log2', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc' | ||
].forEach(function (mathMethod) { | ||
methods.push(['Math.' + mathMethod, mathMethod]); | ||
}); | ||
for (var method of methods) { | ||
var inplaceMeth = eval(fillTemplateFunction(inplaceMethod, {name: method[1], method: method[0]})); | ||
var staticMeth = eval(fillTemplateFunction(staticMethod, {name: method[1]})); | ||
for (var i = 1; i < method.length; i++) { | ||
Matrix.prototype[method[i]] = inplaceMeth; | ||
Matrix[method[i]] = staticMeth; | ||
} | ||
} | ||
var methodsWithArgs = [ | ||
['Math.pow', 1, 'pow'] | ||
]; | ||
for (var methodWithArg of methodsWithArgs) { | ||
var args = 'arg0'; | ||
for (var i = 1; i < methodWithArg[1]; i++) { | ||
args += `, arg${i}`; | ||
} | ||
if (methodWithArg[1] !== 1) { | ||
var inplaceMethWithArgs = eval(fillTemplateFunction(inplaceMethodWithArgs, { | ||
name: methodWithArg[2], | ||
method: methodWithArg[0], | ||
args: args | ||
})); | ||
var staticMethWithArgs = eval(fillTemplateFunction(staticMethodWithArgs, {name: methodWithArg[2], args: args})); | ||
for (var i = 2; i < methodWithArg.length; i++) { | ||
Matrix.prototype[methodWithArg[i]] = inplaceMethWithArgs; | ||
Matrix[methodWithArg[i]] = staticMethWithArgs; | ||
} | ||
} else { | ||
var tmplVar = { | ||
name: methodWithArg[2], | ||
args: args, | ||
method: methodWithArg[0] | ||
}; | ||
console.log(tmplVar); | ||
let inplaceMethod = eval(fillTemplateFunction(inplaceMethodWithOneArg, tmplVar)); | ||
let inplaceMethodS = eval(fillTemplateFunction(inplaceMethodWithOneArgScalar, tmplVar)); | ||
let inplaceMethodM = eval(fillTemplateFunction(inplaceMethodWithOneArgMatrix, tmplVar)); | ||
console.log(fillTemplateFunction(staticMethodWithOneArg, tmplVar)); | ||
let staticMethod = eval(fillTemplateFunction(staticMethodWithOneArg, tmplVar)); | ||
for (var i = 2; i < methodWithArg.length; i++) { | ||
Matrix.prototype[methodWithArg[i]] = inplaceMethod; | ||
Matrix.prototype[methodWithArg[i] + 'M'] = inplaceMethodM; | ||
Matrix.prototype[methodWithArg[i] + 'S'] = inplaceMethodS; | ||
Matrix[methodWithArg[i]] = staticMethod; | ||
} | ||
} | ||
} | ||
function fillTemplateFunction(template, values) { | ||
for (var i in values) { | ||
template = template.replace(new RegExp('%' + i + '%', 'g'), values[i]); | ||
} | ||
return template; | ||
} | ||
Matrix.abstractMatrix = abstractMatrix; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
118223
24
3308