new Matrix()

Class representing a matrix.

Description

A matrix is a 2-dimensional array of numbers. The first dimension indexes the row, written horizontally; the second indexes the column.

The rows of a Matrix are Vector instances. All rows must have the same length.

Use the static method Matrix.create instead of the constructor.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).toString(0);
			  // "[1 2]
			  //  [3 4]
			  //  [5 6]"
Details

Array

Members


m :integer

The number of rows of the matrix.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).m;  // 3
Details
integer

n :integer

The number of columns of the matrix.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).n;  // 2
Details
integer

transpose :Matrix

The transpose Matrix.

Description

The rows of the transpose are the columns of the matrix.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).transpose.toString(0);
			  // "[1 3 5]
			  //  [2 4 6]"
Details

normal :Matrix

The normal matrix A^TA.

Description

The normal matrix is a symmetric matrix with the same null space. It is used in least-squares computations.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).normal.toString(0);
			  // "[35 44]
			  //  [44 56]"
Details

trace :number

The sum of the diagonal entries of the matrix.

Examples

			Matrix.create([1, 2],
			              [3, 4],
			              [5, 6]).trace;  // 1 + 4
Details
number

charpoly :Polynomial

The characteristic polynomial of the matrix.

Description

The characteristic polynomial of an nxn matrix A is the determinant of (A - λI_n), where λ is an indeterminate. This is a polynomial of degree n and leading coefficient (-1)^n:

(-1)^n λ^n + c1 λ^(n-1) + c2 λ^(n-2) + ... + c(n-1) λ + cn

This only makes sense for square matrices. Throws an error if the matrix is not square.

This method implements the Fadeev–LeVerrier algorithm. This is not the most efficient algorithm: it runs in approximately O(n^4) time. However, it has the advantage that it computes the adjugate matrix at the same time.

Examples

			Matrix.create([1, 6,4],
			              [2,-1,3],
			              [5, 0,1]).charpoly.toString(0);  // "-x^3 + x^2 + 33 x + 97"
Throws

Will throw an error if the matrix is not square.

Details

adjugate :Matrix

The adjugate matrix of the matrix.

Description

The adjugate matrix of A is the matrix B whose (i, j) entry is the (j, i) cofactor of A. It has the property that

AB = BA = det(A) I

In particular, if A is invertible then B = det(A) A^(-1).

This method uses the Fadeev–LeVerrier algorithm, which computes the characteristic polynomial at the same time. It runs in about O(n^4) time, which is much better than computing n^2 determinants.

This only makes sense for square matrices. Throws an error if the matrix is not square.

Examples

			let A = Matrix.create([1, 6,4],
			                      [2,-1,3],
			                      [5, 0,1]);
			let B = A.adjugate;
			B.toString(0);
			  // "[-1  -6  22]
			  //  [13 -19   5]
			  //  [ 5  30 -13]"
			A.mult(B).toString(0);
			  // "[97  0  0]
			  //  [ 0 97  0]
			  //  [ 0  0 97]"
			B.mult(A).toString(0);
			  // "[97  0  0]
			  //  [ 0 97  0]
			  //  [ 0  0 97]"
			A.det();  // 97
Throws

Will throw an error if the matrix is not square.

Details

Methods


<static> create( ...rows ) → {Matrix}

Create a Matrix.

Description

The arguments are Vector instances or Arrays of numbers, used as the rows of the matrix. All rows must have the same length.

Parameters
Name Type Attributes Description
rows Array.<number> | Vector <repeatable>

The rows of the matrix. Arrays will be promoted to Vector instances. All rows must have the same length.

Returns

The new matrix.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).toString(0);
			  // "[1 2]
			  //  [3 4]
			  //  [5 6]"
Throws

Will throw an error if the rows do not have the same length.

Details

<static> identity( n [, λ ] ) → {Matrix}

Create an nxn identity Matrix.

Description

This is the square matrix with ones on the diagonal and zeros elsewhere.

Parameters
Name Type Attributes Default Description
n integer

The resulting Matrix will have this many rows and columns.

λ number <optional>
1

The diagonal entries will be equal to λ.

Returns

The nxn (scaled) identity matrix.

Examples

			Matrix.identity(3).toString(0);
			  // "[1 0 0]
			  //  [0 1 0]
			  //  [0 0 1]"
Details

<static> zero( m [, n ] ) → {Matrix}

Create an mxn zero Matrix.

Parameters
Name Type Attributes Default Description
m integer

The resulting Matrix will have this many rows.

n integer <optional>
m

The resulting Matrix will have this many columns.

Returns

The mxn zero matrix.

Examples

			Matrix.zero(2, 3).toString(0);
			  // "[0 0 0]
			  //  [0 0 0]"
Details

<static> constant( c, m [, n ] ) → {Matrix}

Create an mxn constant Matrix.

Parameters
Name Type Attributes Default Description
c number

All entries of the resulting Matrix will be equal to this.

m integer

The resulting Matrix will have this many rows.

n integer <optional>
m

The resulting Matrix will have this many columns.

Returns

The mxn zero matrix.

Examples

			Matrix.constant(1, 2, 3).toString(0);
			  // "[1 1 1]
			  //  [1 1 1]"
Details

<static> diagonal( entries [, m [, n ] ] ) → {Matrix}

Create a diagonal matrix with specified diagonal entries.

Description

A diagonal matrix has nonzero entries only along the main diagonal. This method creates a dxd diagonal matrix with diagonal entries equal to entries, where d = entries.length. If m is specified, then it creates an mxd matrix, and if m and n are both specified, then it creates an mxn matrix.

Parameters
Name Type Attributes Default Description
entries Array.<number>

The diagonal entries of the resulting Matrix.

m integer <optional>
entries.length

The resulting Matrix will have this many rows.

n integer <optional>
entries.length

The resulting Matrix will have this many columns.

Returns

The mxn diagonal matrix with entries along the main diagonal.

Examples

			Matrix.diagonal([1, 2, 3]).toString(0);
			 // "[1 0 0]
			 //  [0 2 0]
			 //  [0 0 3]"
			Matrix.diagonal([1, 2, 3], 4).toString(0);
			 // "[1 0 0]
			 //  [0 2 0]
			 //  [0 0 3]
			 //  [0 0 0]"
			Matrix.diagonal([1, 2, 3], 3, 4).toString(0);
			 // "[1 0 0 0]
			 //  [0 2 0 0]
			 //  [0 0 3 0]"
Details

<static> permutation( vals ) → {Matrix}

Create a permutation Matrix.

Description

This is the square matrix whose ith row is the vals[i]th unit coordinate vector Vector.e(vals[i], n).

Parameters
Name Type Description
vals Array.<number>

If n numbers are given, these should be a permutation of the set {0,1,...,n-1}.

Returns

The permutation matrix M with the property that the ith entry of M.apply(v) is the vals[i]th entry of v.

Examples

			Matrix.permutation([1, 0]).toString(0);
			  // "[0 1]
			  //  [1 0]"

			Matrix.permutation([2, 0, 1]).toString(0);
			  // "[0 0 1]
			  //  [1 0 0]
			  //  [0 1 0]"
Details

invalidate() → {undefined}

Invalidate cached computations.

Description

Call this after modifying any matrix entries.

Returns
Details

hint( hints ) → {undefined}

Hint precomputed or known properties of the matrix.

Description

This is provided so that the methods in this class can select the best algorithm depending on special properties of the matrix.

Parameters
Name Type Description
hints Object

Hinted properties.

Name Type Description
isSymmetric boolean

Whether the matrix is symmetric.

isUpperTri boolean

Whether the matrix is upper-triangular.

isUpperUni boolean

Whether the matrix is upper-unitriangular.

isLowerTri boolean

Whether the matrix is lower-triangular.

isLowerUni boolean

Whether the matrix is lower-unitriangular.

isEchelon boolean

Whether the matrix is in row-echelon form.

hasONCols boolean

Whether the matrix has orthonormal columns.

eigenvalues Array.<Root>

The eigenvalues of the matrix.

Returns
Details

insertSubmatrix( i, j, M ) → {Matrix}

Insert a submatrix into the matrix at position (i,j).

Description

This overwrites the entries of this with the relevant entries of M.

Parameters
Name Type Description
i integer

The row to insert.

j integer

The column to insert.

M Matrix

The submatrix.

Returns

this, after modification.

Examples

			Matrix.zero(4, 5).insertSubmatrix(
			    1, 2, Matrix.create([1, 1],
			                        [1, 1])).toString(0);
			  // "[0 0 0 0 0]
			  //  [0 0 1 1 0]
			  //  [0 0 1 1 0]
			  //  [0 0 0 0 0]"
Details

equals( other [, ε ] ) → {boolean}

Test if this matrix is equal to other.

Description

Two matrices are equal if they have the same dimensions, and all entries are equal.

Parameters
Name Type Attributes Default Description
other Matrix

The matrix to compare.

ε number <optional>
0

Entries will test as equal if they are within ε of each other. This is provided in order to account for rounding errors.

Returns

True if the matrices are equal.

Examples

			let A = Matrix.zero(2, 3);
			let B = Matrix.create([0, 0,  0.01],
			                      [0, 0, -0.01]);
			A.equals(B);                 // false
			A.equals(B, 0.05);           // true
			A.equals(Matrix.zero(3, 2)); // false
Details

clone() → {Matrix}

Create a new Matrix with the same entries.

Returns

The new matrix.

Details

toString( [ precision ] ) → {string}

Return a string representation of the matrix.

Parameters
Name Type Attributes Default Description
precision integer <optional>
4

The number of decimal places to include.

Returns

A string representation of the matrix.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).toString(1);
			  // "[1.0 2.0]
			  //  [3.0 4.0]
			  //  [5.0 6.0]"
Details

toLaTeX( [ precision [, opts ] ] ) → {string}

Return a LaTeX representation of the matrix.

Parameters
Name Type Attributes Default Description
precision integer <optional>
4

The number of decimal places to include.

opts Object <optional>
{}

Options.

Name Type Attributes Default Description
env string <optional>
"bmatrix"

The matrix environment to use.

Returns

A string representation of the vector.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).toLaTeX(1);
			  // "\begin{bmatrix} 1.0 & 2.0 \\ 3.0 & 4.0 \\ 5.0 & 6.0 \end{bmatrix}"
Details

row( i ) → {Vector}

Return the ith row.

Parameters
Name Type Description
i integer

The row to return.

Returns

The ith row of this.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).row(1).toString(0);  // "[3 4]"
Details

rows() → {Iterable.<Vector>}

Return an iterable over the rows.

Returns

An iterable over the rows.

Examples

			let A = Matrix.create([1, 2], [3, 4], [5, 6]);
			Array.from(A.rows(), row => row.toString(0));
			  // ["[1 2]", "[3 4]", "[5 6]"]
Details

col( j ) → {Vector}

Return the jth column.

Parameters
Name Type Description
j integer

The column to return.

Returns

The jth column of this.

Examples

			Matrix.create([1, 2], [3, 4], [5, 6]).col(1).toString(0);  // "[2 4 6]"
Details

<generator> cols() → {Iterable.<Vector>}

Return an iterable over the columns.

Returns

An iterable over the columns.

Examples

			let A = Matrix.create([1, 2], [3, 4], [5, 6]);
			Array.from(A.cols(), col => col.toString(0));
			  // ["[1 3 5]", "[2 4 6]"]
Details

<generator> diag() → {Iterable.<number>}

Return an iterable over the diagonal entriese.

Returns

An iterable over the diagonal entries.

Examples

			let A = Matrix.create([1, 2], [3, 4], [5, 6]);
			Array.from(A.diag());  // [1, 4]
Details

minor( i, j ) → {Matrix}

Return the (i, j) minor of the matrix.

Description

The (i, j) minor of a matrix is the matrix obtained by deleting the ith row and the jth column.

Parameters
Name Type Description
i integer

The row to delete.

j integer

The column to delete.

Returns

The (i, j) minor.

Examples

			let A = Matrix.create([1, 2, 3],
			                      [4, 5, 6],
			                      [7, 8, 9]);
			A.minor(0, 1).toString(0);
			 // "[4 6]
			 //  [7 9]"
Details

cofactor( i, j ) → {number}

Return the (i, j) cofactor of the matrix.

Description

The (i, j) cofactor of a matrix is (-1)^(i+j) times the determinant of the (i, j) minor. This only makes sense for square matrices.

Parameters
Name Type Description
i integer

The row.

j integer

The column.

Returns

The (i, j) cofactor.

Examples

			let A = Matrix.create([1, 2, 3],
			                      [4, 5, 6],
			                      [7, 8, 9]);
			A.cofactor(0, 1);  // 6
Throws

Will throw an error if the matrix is not square.


leadingEntries( [ ε ] ) → {Array.<Pivot>}

A list of leading entries of each row.

Description

Zero rows do not have a leading entry, and are not included.

Parameters
Name Type Attributes Default Description
ε number <optional>
0

Entries smaller than this value are taken to be zero.

Returns

List of the leading entries of each row.

Examples

			Matrix.create([0, 0, 0],
			              [0, 1, 2],
			              [0, 0, 0],
			              [0, 0, 2]).leadingEntries();  // [[1, 1], [3, 2]]
Details

isSquare() → {boolean}

Test whether the matrix is square.

Description

A square matrix has the same number of rows as columns.

Returns

True if the matrix is square.

Examples

			Matrix.create([1, 2], [3, 4]).isSquare();          // true
			Matrix.create([1, 2], [3, 4], [5, 6]).isSquare();  // false
Details

isZero( [ ε ] ) → {boolean}

Test whether the matrix is zero.

Description

All entries of the zero matrix are equal to zero.

Parameters
Name Type Attributes Default Description
ε number <optional>
0

Entries smaller than this value are assumed to be zero.

Returns

True if the matrix is zero.

Examples

			Matrix.create([0, 0], [0, 0]).isZero();        // true
			Matrix.create([0, 0], [0, 0.01]).isZero();     // false
			Matrix.create([0, 0], [0, 0.01]).isZero(0.02); // true
Details

isUpperTri( [ ε ] ) → {boolean}

Test whether the matrix is upper-triangular.

Description

A matrix is upper-triangular if all entries below the main diagonal are equal to zero. Equivalently, this.transpose is lower-triangular.

Parameters
Name Type Attributes Default Description
ε number <optional>
0

Entries smaller than this value are assumed to be zero.

Returns

True if the matrix is upper-triangular.

Examples

			Matrix.create([1, 1, 1],
			              [0, 1, 1],
			              [0, 0, 2]).isUpperTri(); // true
			Matrix.create([3, 1],
			              [0, 1],
			              [0, 0]).isUpperTri();    // true
			Matrix.create([1, 1, 1],
			              [0, 1, 1],
			              [0, 2, 1]).isUpperTri(); // false
Details

isUpperUni( [ ε ] ) → {boolean}

Test whether the matrix is upper-unitriangular.

Description

An upper-unitriangular matrix is an upper-triangular matrix with ones on the diagonal. Equivalently, this.transpose is lower-unitriangular.

Parameters
Name Type Attributes Default Description
ε number <optional>
0

Entries smaller than this value are assumed to be zero.

Returns

True if the matrix is upper-unipotent.

Examples

			Matrix.create([1, 2, 1],
			              [0, 1, 1],
			              [0, 0, 1]).isUpperUni(); // true
			Matrix.create([1, 3],
			              [0, 1],
			              [0, 0]).isUpperUni();    // true
			Matrix.create([1, 1, 1],
			              [0, 1, 1],
			              [0, 2, 1]).isUpperUni(); // false
			Matrix.create([1, 1, 1],
			              [0, 1, 1],
			              [0, 0, 2]).isUpperUni(); // false
Details

isLowerTri( [ ε ] ) → {boolean}

Test whether the matrix is lower-triangular.

Description

A matrix is lower-triangular if all entries above the main diagonal are equal to zero. Equivalently, this.transpose is upper-triangular.

Parameters
Name Type Attributes Default Description
ε number <optional>
0

Entries smaller than this value are assumed to be zero.

Returns

True if the matrix is lower-triangular.

Examples

			Matrix.create([1, 0, 0],
			              [1, 1, 0],
			              [1, 1, 2]).isLowerTri(); // true
			Matrix.create([3, 0],
			              [1, 1],
			              [2, 2]).isLowerTri();    // true
			Matrix.create([1, 0, 0],
			              [1, 1, 2],
			              [1, 1, 1]).isLowerTri(); // false
Details

isLowerUni( [ ε ] ) → {boolean}

Test whether the matrix is lower-unitriangular.

Description

A lower-unitriangular matrix is a lower-triangular matrix with ones on the diagonal. Equivalently, this.transpose is upper-unitriangular.

Parameters
Name Type Attributes Default Description
ε number <optional>
0

Entries smaller than this value are assumed to be zero.

Returns

True if the matrix is lower-unipotent.

Examples

			Matrix.create([1, 0, 0],
			              [2, 1, 0],
			              [1, 1, 1]).isLowerUni(); // true
			Matrix.create([1, 0],
			              [2, 1],
			              [3, 3]).isLowerUni();    // true
			Matrix.create([1, 0, 0],
			              [1, 1, 2],
			              [1, 1, 1]).isLowerUni(); // false
			Matrix.create([1, 0, 0],
			              [1, 1, 0],
			              [1, 1, 2]).isLowerUni(); // false
Details

isDiagonal( [ ε ] ) → {boolean}

Test whether the matrix is diagonal.

Description

A matrix is diagonal if the only nonzero entries of the matrix are on the diagonal. Equivalently, the matrix is both upper- and lower-triangular.

Parameters
Name Type Attributes Default Description
ε number <optional>
0

Entries smaller than this value are assumed to be zero.

Returns

True if the matrix is diagonal.

Examples

			Matrix.create([1, 0, 0],
			              [0, 2, 0],
			              [0, 0, 3]).isDiagonal(); // true
			Matrix.create([1, 0],
			              [0, 1],
			              [0, 0]).isDiagonal();    // true
			Matrix.create([0, 0, 0],
			              [0, 0, 0],
			              [0, 0, 0]).isDiagonal(); // true
			Matrix.create([1, 0, 0],
			              [0, 1, 2],
			              [0, 0, 1]).isDiagonal(); // false
Details

isEchelon( [ ε ] ) → {boolean}

Test whether the matrix is in row-echelon form.

Description

A matrix is in row-echelon form if the first nonzero entry of each row is to the right of the first nonzero entry of the previous row, which implies that all entries below a pivot are zero and all zero rows are at the bottom.

Parameters
Name Type Attributes Default Description
ε number <optional>
0

Entries smaller than this value are assumed to be zero.

Returns

True if the matrix is in row echelon form.

Examples

			Matrix.create([1,  0,  2],
			              [0,  1, -1]).isEchelon();         // true
			Matrix.create([0, 1, 8, 0]).isEchelon();        // true
			Matrix.create([1, 17,  0],
			              [0,  0,  1]).isEchelon();         // true
			Matrix.zero(2, 3).isEchelon();                  // true
			Matrix.create([2, 1],
			              [0, 1]).isEchelon();              // true
			Matrix.create([2,  7, 1, 4],
			              [0,  0, 2, 1],
			              [0,  0, 0, 3]).isEchelon();       // true
			Matrix.create([1, 17, 0],
			              [0,  1, 1]).isEchelon();          // true
			Matrix.create([2,  1, 3],
			              [0,  0, 0]).isEchelon();          // true
			Matrix.create([2,  7, 1, 4],
			              [0,  0, 2, 1],
			              [0,  0, 1, 3]).isEchelon();       // false
			Matrix.create([0, 17, 0],
			              [0,  2, 1]).isEchelon();          // false
			Matrix.create([2,  1],
			              [2,  1]).isEchelon();             // false
			Matrix.create([0,1,0,0]).transpose.isEchelon(); // false
Details

isRREF( [ ε ] ) → {boolean}

Test whether the matrix is in reduced row-echelon form.

Description

A matrix is in reduced row-echelon form if it is in row-echelon form, and in addition, all pivots are equal to one, and all entries above a pivot are equal to zero.

Parameters
Name Type Attributes Default Description
ε number <optional>
0

Entries smaller than this value are assumed to be zero.

Returns

True if the matrix is in reduced row-echelon form.

Examples

			Matrix.create([1,  0,  2],
			              [0,  1, -1]).isRREF();         // true
			Matrix.create([0, 1, 8, 0]).isRREF();        // true
			Matrix.create([1, 17,  0],
			              [0,  0,  1]).isRREF();         // true
			Matrix.zero(2, 3).isRREF();                  // true
			Matrix.create([2, 1],
			              [0, 1]).isRREF();              // false
			Matrix.create([2,  7, 1, 4],
			              [0,  0, 2, 1],
			              [0,  0, 0, 3]).isRREF();       // false
			Matrix.create([1, 17, 0],
			              [0,  1, 1]).isRREF();          // false
			Matrix.create([2,  1, 3],
			              [0,  0, 0]).isRREF();          // false
			Matrix.create([2,  7, 1, 4],
			              [0,  0, 2, 1],
			              [0,  0, 1, 3]).isRREF();       // false
			Matrix.create([0, 17, 0],
			              [0,  2, 1]).isRREF();          // false
			Matrix.create([2,  1],
			              [2,  1]).isRREF();             // false
			Matrix.create([0,1,0,0]).transpose.isRREF(); // false
Details

isFullRowRank( [ ε ] ) → {boolean}

Test whether the matrix has full row rank.

Description

A matrix has full row rank if the following equivalent conditions hold:

  • There is a pivot in every row.
  • The number of pivots equals m.
  • The column space has dimension m.
  • The matrix equation Ax=b has a solution for every choice of b.

Running this method involves computing the rank if it has not been computed already, unless m > n, in which case the matrix cannot have full row rank.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting and projecting.

Returns

True if the matrix has full row rank.

Examples

			Matrix.create([2,  7, 1, 4],
			              [0,  0, 2, 1],
			              [0,  0, 0, 3]).isFullRowRank();  // true
			Matrix.create([2,  7, 1, 4],
			              [0,  0, 2, 1],
			              [0,  0, 0, 0]).isFullRowRank();  // false
Details

isFullColRank( [ ε ] ) → {boolean}

Test whether the matrix has full column rank.

Description

A matrix has full column rank if the following equivalent conditions hold:

  • There is a pivot in every column.
  • The number of pivots equals n.
  • The null space is zero.
  • The matrix equation Ax=b has at most one solution for every choice of b.

Running this method involves computing the rank if it has not been computed already, unless m < n, in which case the matrix cannot have full column rank.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting and projecting.

Returns

True if the matrix has full column rank.

Examples

			Matrix.create([2,  7, 1],
			              [0,  1, 2],
			              [0,  0, 7]).isFullColRank();  // true
			Matrix.create([2,  7, 1],
			              [0,  0, 2],
			              [0,  0, 0]).isFullColRank();  // false
Details

isInvertible( [ ε ] ) → {boolean}

Test whether the matrix is invertible.

Description

A matrix is invertible if the following equivalent conditions hold:

  • The matrix is square and has the maximum number of pivots.
  • The matrix has full row rank and full column rank.
  • There is another matrix (namely, the inverse) such that the product with this on both sides is equal to the identity.
  • The number zero is not an eigenvalue of this.
  • The determinant of this is nonzero.

Running this method involves computing the rank if it has not been computed already.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting and projecting.

Returns

True if the matrix is invertible.

Examples

			Matrix.create([2,  7, 1],
			              [0,  1, 2],
			              [0,  0, 7]).isInvertible();     // true
			Matrix.create([2,  7, 1],
			              [0,  0, 2],
			              [0,  0, 0]).isInvertible();     // false
			Matrix.create([2,  7, 1, 4],
			              [0,  0, 2, 1],
			              [0,  0, 0, 3]).isInvertible();  // false
Details

isSingular( [ ε ] ) → {boolean}

Alias for !this.isInvertible().

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting and projecting.

Returns

True if the matrix is not invertible.


hasONCols( [ ε ] ) → {boolean}

Test if the matrix is has orthonormal columns.

Description

This means that A^TA is the identity matrix.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Numbers smaller than this value are taken to be zero.

Returns

True if the matrix has orthonormal columns.

Examples

			Matrix.create([1, 0],
			              [0, 1],
			              [0, 0]).hasONCols(); // true
Details

isOrthogonal( [ ε ] ) → {boolean}

Test if the matrix is orthogonal.

Description

A matrix is orthogonal if it is square and has orthonormal columns. Equivalently A is square and A^TA is the identity matrix.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Numbers smaller than this value are taken to be zero.

Returns

True if the matrix is orthogonal.

Examples

			Matrix.create([ 3/5, 4/5],
			              [-4/5, 3/5]).isOrthogonal();   // true
			Matrix.create([ 3/5, 1],
			              [-4/5, 0]).isOrthogonal();     // false
			Matrix.create([ 3, 4],
			              [-4, 3]).isOrthogonal();       // false
			Matrix.create([1, 0],
			              [0, 1],
			              [0, 0]).isOrthogonal();        // false
Details

isSymmetric( [ ε ] ) → {boolean}

Test if the matrix is symmetric.

Description

A matrix is symmetric if it is equal to its transpose. This method is a shortcut for this.equals(this.transpose, ε).

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries will test as equal if they are within ε of each other.

Returns

True if the matrix is symmetric.

Examples

			Matrix.create([1, 2, 3],
			              [2, 4, 5],
			              [3, 5, 6]).isSymmetric();  // true
			Matrix.create([1, 2, 3],
			              [4, 5, 6],
			              [7, 8, 9]).isSymmetric();  // false
			Matrix.create([1, 2, 3],
			              [2, 4, 5]).isSymmetric();  // false
Details

isPosDef( [ ε ] ) → {boolean}

Test if a symmetric matrix is positive-definite.

Description

A symmetric matrix is positive-definite if and only if x^T A x > 0 whenever x is a nonzero vector. Equivalently, all eigenvalues of A are positive, or all diagonal entries of D in the LDLT decomposition are positive.

This method works by computing the LDLT decomposition.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries are considered to be zero if they are smaller than this.

Returns

True if the matrix is positive-definite.

Examples

			let A = Matrix.create([3, 2, 3],
			                      [2, 7, 4],
			                      [3, 4, 8]);
			A.isPosDef();  // true

			let A = Matrix.create([1, 2, 3],
			                      [2, 5, 4],
			                      [3, 4, 2]);
			A.isPosDef();  // false
			// Here is a witness to the indefiniteness of A:
			let v = Vector.create(-7, 2, 1);
			v.dot(A.apply(v));  // -11
Throws

Will throw an error if the matrix is not symmetric.

Details

isDiagonalizable( [ ε ] ) → {boolean}

Test if the matrix is diagonalizable.

Description

A matrix is diagonalizable if it is square and there exists an invertible matrix C such that CAC^(-1) is diagonal. Equivalently, the matrix admits n linearly independent eigenvectors (the columns of C).

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Rounding factor.

Returns

True if the matrix is diagonalizable.

Examples

			Matrix.create([11/13, 22/39,  2/39],
			              [-4/13, 83/39,  4/39],
			              [-1/13, 11/39, 40/39]).isDiagonalizable();  // true
			Matrix.create([    1,   1/2,     0],
			              [-4/13, 83/39,  4/39],
			              [ 5/13,  7/78, 34/39]).isDiagonalizable();  // false
Throws

Will throw an error if the matrix is not square.


add( other [, factor ] ) → {Matrix}

Add a Matrix in-place.

Description

This modifies the matrix in-place by adding the entries of other.

Parameters
Name Type Attributes Default Description
other Matrix

The matrix to add.

factor number <optional>
1

Add factor times other instead of just adding other.

Returns

this

Examples

			let A = Matrix.create([1, 2], [3, 4]);
			let B = Matrix.create([2, 1], [4, 3]);
			A.add(B);
			A.toString(0);
			  // "[3 3]
			  //  [7 7]"
Throws

Will throw an error if the matrices have different sizes.

Details

sub( other ) → {Matrix}

Subtract a Matrix in-place.

Description

This modifies the matrix in-place by subtracting the entries of other.

Parameters
Name Type Description
other Matrix

The matrix to subtract.

Returns

this

Examples

			let A = Matrix.create([1, 2], [3, 4]);
			let B = Matrix.create([2, 1], [4, 3]);
			A.sub(B);
			A.toString(0);
			  // "[-1 1]
			  //  [-1 1]"
Throws

Will throw an error if the matrices have different sizes.

Details

scale( c ) → {Matrix}

Scale a Matrix in-place.

Description

This modifies the matrix in-place by multiplying all entries by c.

Parameters
Name Type Description
c number

The number to multiply.

Returns

this

Examples

			let A = Matrix.create([1, 2], [3, 4]);
			A.scale(2);
			A.toString(0);
			  // "[2 4]
			  //  [6 8]"
Details

mult( other ) → {Matrix}

Multiply by another matrix.

Description

This creates a new matrix equal to the product of this and other. The (i, j) entry of the product is the dot product of the ith row of this and the jth column of other. This only makes sense when the number of rows of other equals the number of columns of this.

This method runs in about O(n^3) time for an nxn matrix. Amazingly, this is known not to be optimal: see sub-cubic algorithms on Wikipedia.

Parameters
Name Type Description
other Matrix

The matrix to multiply.

Returns

The matrix product.

Examples

			let A = Matrix.create([1, 2], [3, 4], [5, 6]);
			let B = Matrix.create([1, 2, 3], [4, 5, 6]);
			A.mult(B).toString(0);
			  // "[ 9 12 15]
			  //  [19 26 33]
			  //  [29 40 51]"
Throws

Will throw an error if the matrices have incompatible dimensions.

Details

apply( v ) → {Vector}

Multiply a matrix times a vector.

Description

This creates a new vector equal to the product of this and v. The ith entry of the product is the dot product of the ith row of this with v. This only makes sense when the number of entries of v equals the number of columns of this.

This is an optimized special case of Matrix#mult.

Parameters
Name Type Description
v Vector | Array.<number>

The vector to multiply. An array of numbers is promoted to a vector.

Returns

The matrix-vector product.

Examples

			let A = Matrix.create([1, 2, 3], [4, 5, 6]);
			B.apply(Vector.create(1, -1, 1)).toString(0); // "[2 5]"
Throws

Will throw an error if the matrix and vector have incompatible dimensions.

Details

inverse( [ ε ] ) → {Matrix}

Compute the inverse matrix.

Description

The inverse matrix is the unique matrix A^(-1) such that A A^(-1) and A^(-1) A are both the identity matrix.

This only makes sense for square matrices. Throws an error if the matrix is not square or is not invertible.

This method runs Gauss–Jordan elimination, keeping track of the row operations involved to produce the inverse matrix. It runs in about O(n^3) time, which is not optimal.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The inverse matrix.

Examples

			let A = Matrix.create([0,  1, 2],
			                      [1,  0, 3],
			                      [4, -3, 8]);
			let Ainv = A.inverse();
			Ainv.toString(1);
			  // "[-4.5  7.0 -1.5]
			  //  [-2.0  4.0 -1.0]
			  //  [ 1.5 -2.0  0.5]"
			Ainv.mult(A).toString(1);
			  // "[1.0 0.0 0.0]
			  //  [0.0 1.0 0.0]
			  //  [0.0 0.0 1.0]"
			A.mult(Ainv).toString(1);
			  // "[1.0 0.0 0.0]
			  //  [0.0 1.0 0.0]
			  //  [0.0 0.0 1.0]"
Throws

Will throw an error if the matrix is not square or not invertible.

Details

rowScale( i, c [, start ] ) → {Matrix}

Scale a row by a constant.

Description

This modifies the matrix in-place by multiplying all entries of row i by the scalar c. This is one of the three fundamental row operations.

Parameters
Name Type Attributes Default Description
i integer

The row to scale.

c number

The scaling factor.

start integer <optional>
0

Only scale the entries start...this.n. Provided for optimizations when the entries before start are known to be zero.

Returns

this

Examples

			let A = Matrix.create([1, 2, 3],
			                      [4, 5, 6],
			                      [7, 8, 9]);
			A.rowScale(1, 2);
			A.toString(0);
			  // "[1  2  3]
			  //  [8 10 12]
			  //  [7  8  9]"
Details

rowReplace( i1, i2, c [, start ] ) → {Matrix}

Add a constant times one row to another row.

Description

This modifies the matrix in-place by adding row i2 times the scalar c to row i1. This is one of the three fundamental row operations.

Parameters
Name Type Attributes Default Description
i1 integer

The row to replace.

i2 integer

The row to add.

c number

The scaling factor.

start integer <optional>
0

Only add the entries start...this.n. Provided for optimizations when the entries before start are known to be zero.

Returns

this

Examples

			let A = Matrix.create([1, 2, 3],
			                      [4, 5, 6],
			                      [7, 8, 9]);
			A.rowReplace(1, 2, -1);
			A.toString(0);
			  // "[ 1  2  3]
			  //  [-3 -3 -3]
			  //  [ 7  8  9]"
Details

rowSwap( i1, i2 ) → {Matrix}

Swap two rows.

Description

This exchanges rows i1 and i2. This is one of the three fundamental row operations.

Parameters
Name Type Description
i1 integer

The first row.

i2 integer

The second row.

Returns

this

Examples

			let A = Matrix.create([1, 2, 3],
			                      [4, 5, 6],
			                      [7, 8, 9]);
			A.rowSwap(0, 1);
			A.toString(0);
			  // "[4 5 6]
			  //  [1 2 3]
			  //  [7 8 9]"
Details

PLU( [ ε ] ) → {PLUData}

Compute a PA = LU factorization.

Description

This computes an mxm permutation matrix P, an mxm lower-triangular matrix L with ones on the diagonal, and a matrix U in row echelon form, such that PA = LU. Along the way, it computes the sign of the permutation P, the pivot positions of the matrix, and an invertible mxm matrix E such that EA = U. (The matrix E is the product of the elementary matrices corresponding to the row operations performed on A).

This is the core method that implements Gaussian elimination. It uses maximal partial pivoting for numerical stability. This algorithm requires about 2n^3/3 operations for an nxn matrix, which seems to be standard.

The permutation matrix P is returned as a list of n numbers defining the permutation. Use Matrix.permutation to turn it into a matrix.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The PA=LU factorization, along with other data computed at the same time.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let {P, L, U, E, pivots} = A.PLU();
			P;  // [2, 0, 3, 1]
			// let PM = Matrix.permutation(P);
			PM.toString(0);
			  // "[0 0 1 0]
			  //  [1 0 0 0]
			  //  [0 0 0 1]
			  //  [0 1 0 0]"
			L.toString();
			  // "[ 1.0000  0.0000  0.0000 0.0000]
			  //  [ 0.0000  1.0000  0.0000 0.0000]
			  //  [-0.5000 -0.8333  1.0000 0.0000]
			  //  [ 0.5000  0.1667 -0.2000 1.0000]"
			L.isLowerUni();  // true
			U.toString();
			  // "[-2.0000 -3.0000  0.0000  3.0000 -1.0000]
			  //  [ 0.0000 -3.0000 -6.0000  4.0000  9.0000]
			  //  [ 0.0000  0.0000  0.0000 -4.1667  0.0000]
			  //  [ 0.0000  0.0000  0.0000  0.0000  0.0000]"
			U.isEchelon();  // true
			U.leadingEntries();  // [[0, 0], [1, 1], [2, 3]], the same as pivots
			E.mult(A).toString();
			  // "[-2.0000 -3.0000  0.0000  3.0000 -1.0000]
			  //  [ 0.0000 -3.0000 -6.0000  4.0000  9.0000]
			  //  [ 0.0000  0.0000  0.0000 -4.1667  0.0000]
			  //  [ 0.0000  0.0000  0.0000  0.0000  0.0000]"
			PM.mult(A).toString(2);
			  // "[-2.00 -3.00  0.00  3.00 -1.00]
			  //  [ 0.00 -3.00 -6.00  4.00  9.00]
			  //  [ 1.00  4.00  5.00 -9.00 -7.00]
			  //  [-1.00 -2.00 -1.00  3.00  1.00]"
			L.mult(U).toString(2);
			  // "[-2.00 -3.00  0.00  3.00 -1.00]
			  //  [ 0.00 -3.00 -6.00  4.00  9.00]
			  //  [ 1.00  4.00  5.00 -9.00 -7.00]
			  //  [-1.00 -2.00 -1.00  3.00  1.00]"

pivots( [ ε ] ) → {Array.<Pivot>}

Compute the pivot positions of the matrix.

Description

The pivot positions are the leading entries of a row-echelon form of the matrix.

This is a shortcut for this.PLU(ε).pivots.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The pivot positions.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			A.PLU().U.toString();
			  // "[-2.0000 -3.0000  0.0000  3.0000 -1.0000]
			  //  [ 0.0000 -3.0000 -6.0000  4.0000  9.0000]
			  //  [ 0.0000  0.0000  0.0000 -4.1667  0.0000]
			  //  [ 0.0000  0.0000  0.0000  0.0000  0.0000]"
			A.pivots();  // [[0, 0], [1, 1], [2, 3]]

rank( [ ε ] ) → {integer}

Compute the rank of the matrix.

Description

The rank of the matrix is the dimension of the column space. It is equal to the number of pivots.

The rank is computed in Matrix#PLU and Matrix#QR, and is cached. If the rank has not been computed yet, then this.pivots(ε).length is returned.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The rank of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			A.PLU().U.toString();
			  // "[-2.0000 -3.0000  0.0000  3.0000 -1.0000]
			  //  [ 0.0000 -3.0000 -6.0000  4.0000  9.0000]
			  //  [ 0.0000  0.0000  0.0000 -4.1667  0.0000]
			  //  [ 0.0000  0.0000  0.0000  0.0000  0.0000]"
			A.pivots();  // [[0, 0], [1, 1], [2, 3]]
			A.rank();    // 3

nullity( [ ε ] ) → {integer}

Compute the nullity of the matrix.

Description

The nullity of a matrix is the dimension of its null space. This is equal to the number of free variables, which is the number of columns without pivots.

According to the Rank-Nullity Theorem, the rank plus the nullity equals n, the number of columns. Therefore, this method simply returns this.n - this.rank(ε).

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The nullity of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			A.nullity(); // 2
			A.rank();    // 3
Details

det( [ ε ] ) → {number}

Compute the matrix determinant.

Description

The determinant is computed as a side-effect of Matrix#PLU: the determinant of A equals the determinant of P times the determinant of U. Since P is a permutation matrix and U is upper-triangular, both quantities are easy to compute.

The PLU decomposition does not use exact arithmetic: pivots smaller than ε are considered to be zero. Also, computing the echelon form may involve dividing by large pivots. Therefore, this.det() may fail to be an integer even when this has all integer entries. On the other hand, the constant coefficient of the characteristic polynomial is also equal to the determinant, is computed using exact arithmetic (but in O(n^4) time), and will always produce an integer determinant for matrices with integer entries.

This only makes sense for square matrices. Throws an error if the matrix is not square.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The matrix determinant.

Examples

			Matrix.create([1, 6,4],
			              [2,-1,3],
			              [5, 0,1]).det();  // 97

			let A = Matrix.create([3, 4],
			                      [5, 6]);
			A.det();             // -2.0000000000000018
			A.charpoly.eval(0);  // -2
Throws

Will throw an error if the matrix is not square.

Details

rref( [ ε ] ) → {Matrix}

Compute the reduced row-echelon form of the matrix.

Description

The reduced row-echelon form of the matrix is obtained from a row-echelon form by scaling so all pivots are equal to 1, and performing row replacements so that all entries above a pivot are equal to zero. This is called Gauss–Jordan elimination.

This method runs this.PLU(ε) to first compute the row-echelon form U. Running rref() after PLU() takes about 50% more time.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The reduced row-echelon form of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let R = A.rref();
			R.toString(1);
			  // "[1.0 0.0 -3.0 0.0  5.0]
			  //  [0.0 1.0  2.0 0.0 -3.0]
			  //  [0.0 0.0  0.0 1.0  0.0]
			  //  [0.0 0.0  0.0 0.0  0.0]"
			R.isRREF();  // true

rowOps( [ ε ] ) → {Matrix}

Return the row operations used in Gauss–Jordan elimination.

Description

This returns an invertible mxm matrix E such that EA is the reduced row-echelon form of A. This matrix is the product of the elementary matrices corresponding to the row operations performed on A to reduce it to reduced row-echelon form. It is computed as a side effect of running this.rref(ε).

If A is invertible then E is the inverse of A.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The matrix recording the row operations.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let E = A.rowOps();
			E.toString(2);
			  // "[ 0.60 0.00 -0.44  0.12]
			  //  [-0.60 0.00 -0.16 -0.32]
			  //  [-0.20 0.00 -0.12 -0.24]
			  //  [ 0.00 1.00 -0.40  0.20]"
			E.mult(A).toString(1);
			  // "[1.0 0.0 -3.0 0.0  5.0]
			  //  [0.0 1.0  2.0 0.0 -3.0]
			  //  [0.0 0.0  0.0 1.0  0.0]
			  //  [0.0 0.0  0.0 0.0  0.0]"
			A.rref().toString(1);
			  // "[1.0 0.0 -3.0 0.0  5.0]
			  //  [0.0 1.0  2.0 0.0 -3.0]
			  //  [0.0 0.0  0.0 1.0  0.0]
			  //  [0.0 0.0  0.0 0.0  0.0]"
Details

solve( b [, ε ] ) → {Vector}

Find some solution x of the equation Ax=b.

Description

This method tries to find the most efficient algorithm based on properties of the matrix:

  • If the matrix is in echelon form, solve using reverse-substitution. This requires about m(m+1)/2 operations.
  • If the matrix is lower-unitriangular, solve using forward-substitution. This requires about m(m+1)/2 operations.
  • If the matrix is symmetric, try an LDLT decomposition. If it exists, solve using forward- and reverse-substitution. This requires about m(m+1) operations once the LDLT decomposition has been computed.
  • If the matrix has no special properties, compute a PLU decomposition and then solve using forward- and reverse-substitution. This requires about m(m+1) operations once the PA=LU decomposition has been computed.
Parameters
Name Type Attributes Default Description
b Vector

The right-hand side of the equation Ax=b.

ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

Returns a solution x, or null if no solution exists.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let b = Vector.create(-3, 7, 10, -15);
			let x = A.solve(b);
			x.toString(0);           // "[-8 5 0 3 0]"
			A.apply(x).toString(0);  // "[-3 7 10 15]"
			let b1 = Vector.create(0, 1, 0, 0);
			A.solve(b1);             // null
Throws

Will throw an error if b.length != this.m.


solveShortest( b [, ε ] ) → {Vector}

Find the shortest solution x of the equation Ax=b.

Description

This is obtained by finding some solution using Matrix#solve, then projecting onto the row space using Matrix#projectRowSpace.

This takes about twice as long as Matrix#solve once PA=LU decompositions for this and this.transpose.normal have been computed.

Parameters
Name Type Attributes Default Description
b Vector

The right-hand side of the equation Ax=b.

ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

Returns the shortest solution x, or null if no solution exists.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let b = Vector.create(-3, 7, 10, -15);
			let x = A.solveShortest(b);
			x.toString();            // "[-0.1429 0.1429 0.7143 3.0000 -1.1429]"
			A.apply(x).toString(0);  // "[-3 7 10 15]"
			// No other solution `x` has smaller size
			x.size.toFixed(4);       // "9.8995"
			let b1 = Vector.create(0, 1, 0, 0);
			A.solveShortest(b1);     // null
Throws

Will throw an error if b.length != this.m.


solveLeastSquares( b [, ε ] ) → {Vector}

Find some least-squares solution x of the equation Ax=b.

Description

A least-squares solution is a vector x such that Ax is as close to b as possible. Equivalently, it is a vector x such that Ax-b is orthogonal to the columns of A. This method finds one such solution; the others are obtained by adding vectors in the null space.

A least-squares solution is obtained by solving the normal equation A^TAx = A^Tb, which is always consistent. This takes about O(n^2) time once a PA=LU decomposition of this.normal has been computed.

If Ax=b is consistent, then a least-squares solution is the same as an actual solution of the equation Ax=b.

Parameters
Name Type Attributes Default Description
b Vector

The right-hand side of the equation Ax=b.

ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

A least-squares solution.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let b = Vector.create(0, 1, 0, 0);
			let x = A.solveLeastSquares(b);
			x.toString();           // "[-0.1667 0.0000 0.0000 0.0000 0.0000]"
			A.apply(x).toString();  // "[0.0000 0.1667 0.3333 -0.1667]"
			let Axmb = A.apply(x).sub(b);
			// No other value of `x` makes `Axmb` shorter than this.
			Axmb.size.toFixed(4);  // "0.9129"
			// Axmb is orthogonal to the columns of A
			A.transpose.apply(Axmb).isZero(1e-10);  // true
			
			// If `Ax=b` is consistent, then a least-squares solution is an ordinary
			// solution.
			let b1 = Vector.create(-3, 7, 10, -15);
			let x1 = A.solveLeastSquares(b1);
			x1.toString(0); // "[-8 5 0 3 0]"
			let x2 = A.solve(b1);
			x2.toString(0); // "[-8 5 0 3 0]"
Throws

Will throw an error if b.length != this.m.

Details

solveLeastSquaresShortest( b [, ε ] ) → {Vector}

Find the shortest least-squares solution x to the equation Ax=b.

Description

This is obtained by finding some solution using Matrix#solveLeastSquares, then projecting onto the row space using Matrix#projectRowSpace. It takes about twice as long as Matrix#solve once PA=LU decompositions for this and this.transpose.normal have been computed.

If the pseudo-inverse A^+ has been computed, then this method multiplies by A^+. If you need to run this method many times, compute A^+ first.

Parameters
Name Type Attributes Default Description
b Vector

The right-hand side of the equation.

ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The shortest least-squares solution.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let b = Vector.create(0, 1, 0, 0);
			let x = A.solveLeastSquaresShortest(b);
			x.toString();           // "[-0.0476 -0.0714 0.0000 0.0000 -0.0238]"
			A.apply(x).toString();  // "[0.0000 0.1667 0.3333 -0.1667]"
			// No other least-squares solution `x` has smaller size
			x.size.toFixed(4);      // "0.0891"
Throws

Will throw an error if b.length != this.m.


pseudoInverse( [ ε ] ) → {Matrix}

Compute the pseudo-inverse matrix.

Description

The pseudo-inverse A^+ of a matrix A has the following geometric description: if v is a vector in R^m, then A^+v is obtained by projecting onto Col(A) to obtain a vector v1, then solving Ax=v1 to obtain a solution x, then projecting x onto the row space of A. The resulting vector is simply the shortest least-squares solution of Ax=v: that is, A^+v = A.solveLeastSquaresShortest(v). Hence to compute the columns of A^+, one has to find the shortest least-squares solutions of Ax=ei for i=1,...,m (the unit coordinate vectors).

This method runs Matrix#solveLeastSquaresShortest for each of the m unit coordinate vectors in R^m. In practice, the pseudo-inverse is usually computed by finding the singular value decomposition A = U Σ V^T; then A^+ = U Σ^+ V^T, where Σ^+ is the same as Σ with the nonzero entries inverted. Since this matrix library does not include a high-quality SVD algorithm, this method is implemented in the naïve way.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The pseudo-inverse matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let Ap = A.pseudoInverse();
			Ap.toString();
			  // "[-0.0857 -0.0476 -0.1752 -0.1124]
			  //  [-0.1714 -0.0714 -0.2743 -0.1914]
			  //  [-0.0857  0.0000 -0.0229 -0.0457]
			  //  [-0.2000  0.0000 -0.1200 -0.2400]
			  //  [ 0.0857 -0.0238 -0.0533  0.0124]"
			A.mult(Ap).equals(A.colSpace().projectionMatrix(), 1e-10);  // true
			Ap.mult(A).equals(A.rowSpace().projectionMatrix(), 1e-10);  // true

projectColSpace( b [, ε ] ) → {Vector}

Project a vector onto the column space of the matrix.

Description

If x is a least-squares solution of Ax=b, then Ax is by definition the projection of b onto the column space of A. Therefore, this method is a shortcut for this.apply(this.solveLeastSquares(b, ε)).

Parameters
Name Type Attributes Default Description
b Vector

A vector of length m.

ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The projection of b onto the column space.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let b = Vector.create(0, 1, 0, 0);
			let x = A.projectColSpace(b);
			x.toString();  // "[0.0000 0.1667 0.3333 -0.1667]"
			// b-x is orthogonal to the columns of A
			A.transpose.apply(b.sub(x)).isZero(1e-10);  // true
Throws

Will throw an error if b.length != this.m.


projectRowSpace( b [, ε ] ) → {Vector}

Project a vector onto the row space of the matrix.

Description

This is an alias for this.transpose.projectColSpace(b, ε).

Parameters
Name Type Attributes Default Description
b Vector

A vector of length n.

ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The projection of b onto the row space.

Throws

Will throw an error if b.length != this.n.


nullBasis( [ ε ] ) → {Array.<Vector>}

Return a basis for the null space of the matrix.

Description

The null space is the subspace of R^n consisting of solutions of the matrix equation Ax=0. This method computes a basis for the null space by finding the parametric vector form of the general solution of Ax=0 using the reduced row echelon form of the matrix. These are all vectors of length n.

If the null space is zero (i.e., the matrix has full column rank), then the empty list is returned.

This method takes negligible time once the reduced row-echelon form has been computed.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

A basis for the null space of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let R = A.rref();
			R.toString(0);
			  // "[1 0 -3 0  5]
			  //  [0 1  2 0 -3]
			  //  [0 0  0 1  0]
			  //  [0 0  0 0  0]"
			A.nullBasis().map(vec => vec.toString(0));
			  // ["[3 -2 1 0 0]", "[-5 3 0 0 1]"]
			A.isFullColRank();  // false

			let A = Matrix.create([1, 0],
			                      [0, 1],
			                      [0, 0]);
			A.nullBasis();      // []
			A.isFullColRank();  // true

nullSpace( [ ε ] ) → {Subspace}

Return the null space of the matrix.

Description

This is essentially a shortcut for new Subspace(this.nullBasis(ε)).

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The null space of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			A.nullBasis().map(vec => vec.toString(0));
			  // ["[3 -2 1 0 0]", "[-5 3 0 0 1]"]
			A.nullSpace().toString(0);
			  // "Subspace of R^5 of dimension 2 with basis
			  //  [ 3] [-5]
			  //  [-2] [ 3]
			  //  [ 1] [ 0]
			  //  [ 0] [ 0]
			  //  [ 0] [ 1]"

			let A = Matrix.create([1, 0],
			                      [0, 1],
			                      [0, 0]);
			A.nullBasis(); // []
			A.nullSpace().toString();  // "The zero subspace of R^2"
Details

colBasis( [ ε ] ) → {Array.<Vector>}

Return a basis for the column space of the matrix.

Description

The column space of a matrix is the subspace of R^m consisting of all linear combinations of the columns. This is the same as the set of all vectors of the form Ax for x in R^n.

This method computes a basis for the column space by finding the pivots and returning the pivot columns. These are all vectors of length m.

This method takes negligible time once a PA=LU decomposition has been computed.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

A basis for the column space of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			A.pivots();  // [[0, 0], [1, 1], [2, 3]]
			A.colBasis().map(vec => vec.toString(0));
			  // ["[0 -1 -2 1]", "[-3 -2 -3 4]", "[4 3 3 -9]"]
Details

colSpace( [ ε ] ) → {Subspace}

Return the column space of the matrix.

Description

This is essentially a shortcut for new Subspace(Array.from(this.cols())).

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The column space of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			A.colBasis().map(vec => vec.toString(0));
			  // ["[0 -1 -2 1]", "[-3 -2 -3 4]", "[4 3 3 -9]"]
			A.colSpace().toString(0);
			  // "Subspace of R^4 of dimension 3 with basis
			  //  [ 0] [-3] [ 4]
			  //  [-1] [-2] [ 3]
			  //  [-2] [-3] [ 3]
			  //  [ 1] [ 4] [-9]"
Details

rowBasis( [ ε ] ) → {Array.<Vector>}

Return a basis for the row space of the matrix.

Description

The row space of a matrix is the subspace of R^n consisting of all linear combinations of the rows. This is the same as the column space of the transpose.

This method computes a basis for the row space by returning the nonzero rows of a row echelon-form of the matrix. These are all vectors of length n.

This method takes negligible time once a PA=LU decomposition has been computed.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

A basis for the row space of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			A.PLU().U.toString();
			  // "[-2.0000 -3.0000  0.0000  3.0000 -1.0000]
			  //  [ 0.0000 -3.0000 -6.0000  4.0000  9.0000]
			  //  [ 0.0000  0.0000  0.0000 -4.1667  0.0000]
			  //  [ 0.0000  0.0000  0.0000  0.0000  0.0000]"
			A.rowBasis().map(vec => vec.toString());
			  // ["[-2.0000 -3.0000 0.0000 3.0000 -1.0000]",
			  //  "[0.0000 -3.0000 -6.0000 4.0000 9.0000]",
			  //  "[0.0000 0.0000 0.0000 -4.1667 0.0000]"]
Details

rowSpace( [ ε ] ) → {Subspace}

Return the row space of the matrix.

Description

This is essentially a shortcut for new Subspace(Array.from(this.rows())), except that the returned subspace will come equipped with the cached output of this.rowBasis() if it has been computed.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The row space of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			// Note that the Subspace computed a basis by finding the pivots of the
			// matrix whose columns are the generators it was provided.
			A.rowSpace().toString(0);
			  // "Subspace of R^5 of dimension 3 with basis
			  //  [ 0] [ 1] [-2]
			  //  [-3] [-2] [-3]
			  //  [-6] [-1] [ 0]
			  //  [ 4] [ 3] [ 3]
			  //  [ 9] [ 1] [-1]"

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			// Precompute a basis of the row space
			A.rowBasis();
			A.rowSpace().toString();
			  // "Subspace of R^5 of dimension 3 with basis
			  //  [-2.0000] [ 0.0000] [ 0.0000]
			  //  [-3.0000] [-3.0000] [ 0.0000]
			  //  [ 0.0000] [-6.0000] [ 0.0000]
			  //  [ 3.0000] [ 4.0000] [-4.1667]
			  //  [-1.0000] [ 9.0000] [ 0.0000]"
Details

leftNullBasis( [ ε ] ) → {Array.<Vector>}

Return a basis for the left null space of the matrix.

Description

The left null space of a matrix is the null space of the transpose. This is a subspace of R^m.

This method computes a basis for the left null space by returning the last m-r rows of L^(-1) P, where P and L come from the PA = LU decomposition and r is the rank. These are all vectors of length m.

This method takes negligible time once a PA=LU decomposition has been computed.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

A basis for the left null space of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			A.PLU().E.toString();
			  // "[0.0000 0.0000  1.0000 0.0000]
			  //  [1.0000 0.0000  0.0000 0.0000]
			  //  [0.8333 0.0000  0.5000 1.0000]
			  //  [0.0000 1.0000 -0.4000 0.2000]"
			A.rank();  // 3
			A.leftNullBasis().map(vec => vec.toString());
			  // ["[0.0000 1.0000 -0.4000 0.2000]"]
Details

leftNullSpace( [ ε ] ) → {Subspace}

Return the left null space of the matrix.

Description

This is essentially a shortcut for new Subspace(this.leftNullBasis(ε)).

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting.

Returns

The left null space of the matrix.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			A.leftNullBasis().map(vec => vec.toString());
			  // ["[0.0000 1.0000 -0.4000 0.2000]"]
			A.leftNullSpace().toString(1);
			  // "Subspace of R^4 of dimension 1 with basis
			  //  [ 0.0]
			  //  [ 1.0]
			  //  [-0.4]
			  //  [ 0.2]"
Details

QR( [ ε ] ) → {QRData}

Compute a QR decomposition.

Description

This computes a matrix Q and an upper-triangular matrix R such that A = QR. If A has full column rank then Q has orthonormal columns and R is invertible, and the decomposition is unique. Otherwise Q may have zero columns and R may have zero rows. In any case the nonzero columns of Q form an orthonormal basis for the column space of A.

This method implements the modified Gram–Schmidt algorithm, which is a simple tweak of the usual Gram–Schmidt algorithm with better numerical properties. It runs in about O(n^3) time for an nxn matrix. (The Householder algorithm is faster and is the one generally used in practice.)

As a side-effect, this method also computes the rank of the matrix.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Vectors smaller than this value are taken to be zero.

Returns

The QR factorization of the matrix.

Examples

			let A = Matrix.create([ 3, -5,  1],
			                      [ 1,  1,  1],
			                      [-1,  5, -2],
			                      [ 3, -7,  8]);
			let {Q, R} = A.QR();
			Q.toSring();
			  // "[ 0.6708  0.2236 -0.6708]
			  //  [ 0.2236  0.6708  0.2236]
			  //  [-0.2236  0.6708  0.2236]
			  //  [ 0.6708 -0.2236  0.6708]"
			// Q has orthogonal columns
			Q.transpose.mult(Q).toString(1);
			  // "[1.0 0.0 0.0]
			  //  [0.0 1.0 0.0]
			  //  [0.0 0.0 1.0]"
			Q.colSpace().equals(A.colSpace());  // true
			R.toString();
			  // "[4.4721 -8.9443  6.7082]
			  //  [0.0000  4.4721 -2.2361]
			  //  [0.0000  0.0000  4.4721]"
			R.isUpperTri();                     // true
			Q.mult(R).toString(1);
			  // "[ 3.0 -5.0  1.0]
			  //  [ 1.0  1.0  1.0]
			  //  [-1.0  5.0 -2.0]
			  //  [ 3.0 -7.0  8.0]"

			// This matrix has rank 3
			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let {Q, R, LD} = A.QR();
			Q.toString();
			  // "[ 0.0000 -0.8018 0.0000 -0.5976 0.0000]
			  //  [-0.4082  0.0000 0.0000  0.0000 0.0000]
			  //  [-0.8165  0.2673 0.0000 -0.3586 0.0000]
			  //  [ 0.4082  0.5345 0.0000 -0.7171 0.0000]"
			// Columns 3 and 5 are zero: that means the third column was in the span
			// of the first 2, and the fifth was in the span of the first 4.
			LD;  // [2, 4]
			// The nonzero columns form an orthonormal basis of the column space of A.
			Q.colSpace().equals(A.colSpace());  // true
			R.toString();
			  // "[2.4495 4.8990 2.4495 -7.3485  -2.4495]
			  //  [0.0000 3.7417 7.4833 -7.2161 -11.2250]
			  //  [0.0000 0.0000 0.0000  0.0000   0.0000]
			  //  [0.0000 0.0000 0.0000  2.9881   0.0000]
			  //  [0.0000 0.0000 0.0000  0.0000   0.0000]"
			Q.mult(R).toString(1);
			  // "[ 0.0 -3.0 -6.0  4.0  9.0]
			  //  [-1.0 -2.0 -1.0  3.0  1.0]
			  //  [-2.0 -3.0  0.0  3.0 -1.0]
			  //  [ 1.0  4.0  5.0 -9.0 -7.0]"

eigenvalues( [ ε ] ) → {Array.<Root>}

Compute the (real and complex) eigenvalues of the matrix.

Description

The eigenvalues are the numbers λ such that there exists a nonzero vector v with Av = λv. They are the roots of the characteristic polynomial.

This method factors the characteristic polynomial and returns the roots. This is not how eigenvalues are generally computed in practice.

Factorization of polynomials is only implemented in degrees at most 4; for matrices larger than 4x4, compute the eigenvalues some other way and use Matrix#hint.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Rounding factor to determine multiplicities, as in Polynomial#factor.

Returns

The eigenvalues with algebraic multiplicity. They are returned in the order specified in Polynomial#factor.

Examples

			Matrix.create([1, 1], [1, 1]).eigenvalues();  // [[0, 1], [2, 1]]
			Matrix.create([1, 1], [0, 1]).eigenvalues();  // [[1, 2]]
			Matrix.create([1, 1], [-1,1]).eigenvalues();
			  // [[new Complex(1, 1), 1], [new Complex(1, -1), 1]]
Throws

Will throw an error if the matrix is not square, or if it is larger than 4x4 and the eigenvalues have not been hinted.


eigenspace( λ [, ε ] ) → {Subspace|Array.<Array.<Vector>>}

Compute the λ-eigenspace of the matrix.

Description

The λ-eigenspace is the null space of A - λI.

This method works for any size matrix if you know an eigenvalue. For complex eigenvalues, it returns a basis for the eigenspace represented as an Array of pairs of vectors [v_r, v_i], where v_r + i v_i is the eigenvector.

Parameters
Name Type Attributes Default Description
λ number

The eigenvalue.

ε number <optional>
1e-10

Entries smaller than this value are taken to be zero for the purposes of pivoting and rounding.

Returns

The eigenspace.

Examples

			let A = Matrix.create([1, 1], [1, 1]);
			A.eigenspace(0).toString(1);
			  // "Subspace of R^2 of dimension 1 with basis
			  //  [-1.0]
			  //  [ 1.0]"
			A.eigenspace(2).toString(1);
			  // "Subspace of R^2 of dimension 1 with basis
			  //  [1.0]
			  //  [1.0]"

			let A = Matrix.create([2, 0], [0, 2]);
			A.eigenspace(2).toString();  // "The full subspace R^2"

			let A = Matrix.create([1, 1], [0, 1]);
			A.eigenspace(1).toString(1);
			  // "Subspace of R^2 of dimension 1 with basis
			  //  [1.0]
			  //  [0.0]"

			let A = Matrix.create([24, -53/2], [20, -22]);
			// The (1+i)-eigenspace is spanned by (1.15 + 0.05i, 1).
			A.eigenspace(new Complex(1, 1));
			  // [Vector.create(1.15, 1), Vector.create(0.05, 0)]
			A.eigenspace(new Complex(1, -1));
			  // [Vector.create(1.15, 1), Vector.create(-0.05, 0)]
Throws

Will throw an error if the matrix is not square, or if λ is not an eigenvalue of the matrix.

Details

diagonalize( [ opts ] ) → {Diagonalization}

Diagonalize the matrix.

Description

For usual diagonalization (opts.block is falsy), it returns an invertible matrix C and a diagonal matrix D such that A = CDC^(-1). This is possible exactly when A has n linearly independent real eigenvectors, which form the columns of C; the eigenvalues are the diagonal entries of D.

For block diagonalization (opts.block is truthy), it returns an invertible matrix C and a matrix D with diagonal blocks consisting of numbers and rotation-scaling matrices, such that A = CDC^(-1). This is possible exactly when A has n linearly independent (real and complex) eigenvectors. If all eigenvalues are real, then diagonalization is the same as block diagonalization.

If opts.ortho is truthy, compute orthonormal eigenbases for all real eigenvalues. Then if (and only if) A is symmetric, the matrix C will be orthogonal, thus resulting in an orthogonal decomposition A = CDC^T.

This is only implemented for matrices up to 4x4, unless the eigenvalues have been hinted.

Parameters
Name Type Attributes Default Description
opts Object <optional>
{}

Options.

Name Type Attributes Default Description
block boolean <optional>
false

Perform block diagonalization.

ortho boolean <optional>
false

Use orthonormal bases for real eigenspaces.

ε number <optional>
1e-10

Rounding factor.

Returns

The diagonalization, or null if the matrix is not (block) diagonalizable.

Examples

			let A = Matrix.create([11/13, 22/39,  2/39],
			                      [-4/13, 83/39,  4/39],
			                      [-1/13, 11/39, 40/39]);
			A.eigenvalues();  // [[1, 2], [2, 1]]  (approximately)
			let {C, D} = A.diagonalize();
			D.toString(1);
			  // "[1.0 0.0 0.0]
			  //  [0.0 1.0 0.0]
			  //  [0.0 0.0 2.0]"
			C.toString();
			  // "[3.6667 0.3333 2.0000]
			  //  [1.0000 0.0000 4.0000]
			  //  [0.0000 1.0000 1.0000]"
			C.mult(D).mult(C.inverse()).scale(39).toString(1);
			  // "[ 33.0 22.0  2.0]
			  //  [-12.0 83.0  4.0]
			  //  [ -3.0 11.0 40.0]"

			let A = Matrix.create([    1,   1/2,     0],
			                      [-4/13, 83/39,  4/39],
			                      [ 5/13,  7/78, 34/39]);
			A.eigenvalues();  // [[1, 2], [2, 1]]  (approximately)
			A.diagonalize();  // null

			let A = Matrix.create([33/29, -23/29,   9/29],
			                      [22/29,  33/29, -23/29],
			                      [19/29,  14/29,  50/29]);
			A.eigenvalues();
			  // [[new Complex(1, 1), 1], [new Complex(1, -1), 1], [2, 1]]
			  // (approximately)
			A.diagonalize();  // null
			let {C, D} = A.diagonalize({block: true});
			D.toString(1);
			  // "[ 1.0 1.0 0.0]
			  //  [-1.0 1.0 0.0]
			  //  [ 0.0 0.0 2.0]"
			C.toString();
			  // "[-1.4000 0.2000  0.6667]
			  //  [ 0.4000 1.8000 -0.3333]
			  //  [ 1.0000 0.0000  1.0000]"
			C.mult(D).mult(C.inverse()).scale(29).toString(1);
			  // "[33.0 -23.0   9.0]
			  //  [22.0  33.0 -23.0]
			  //  [19.0  14.0  50.0]"

			let A = Matrix.create([-1,  5,  4],
			                      [ 5, -2,  3],
			                      [ 4,  3, -9]);
			A.isSymmetric();  // true
			let {C, D} = A.diagonalize({ortho: true});
			C.toString();
			  // "[-0.3105  0.6337 0.7085]
			  //  [-0.1442 -0.7681 0.6239]
			  //  [ 0.9396  0.0916 0.3299]"
			C.isOrthogonal();  // true
			C.mult(D).mult(C.transpose).equals(A, 1e-10);  // true
Throws

Will throw an error if the matrix is not square or if the matrix is larger than 4x4 and the eigenvalues have not been hinted.


SVD( [ ε ] ) → {SVDData}

Singular Value decomposition.

Description

This computes an orthogonal mxm matrix U, an orthogonal nxn matrix V, and a diagonal mxn matrix Σ, such that A = U Σ V^T. The nonzero diagonal entries of Σ are the singular values of the matrix, in descending order. The first r = rank(A) columns of V form an orthonormal basis for the row space of A, and the last n-r columns form an orthonormal basis for the null space. The first r columns of U form an orthonormal basis for the column space of A, and the last m-r columns form an orthonormal basis for the left null space. If vi is the ith column of V, with i <= r, then Avi = σi ui, where σi is the ith singular value and ui is the ith column of U.

Only the nonzero diagonal entries of the matrix Σ are returned. Use Matrix.diagonal to turn it into a matrix, as in Matrix.diagonal(Σ, m, n).

This method will fail if min(m, n) > 4, as the eigenvalue computations have not been implemented for matrices larger that 4x4. This method implements the naïve schoolbook algorithm for computing the SVD, which is not numerically accurate and is rarely used in practice.

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Rounding factor used when computing eigenvalues and eigenvectors of the normal matrix.

Returns

The singular value decomposition.

Examples

			let A = Matrix.create([ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]);
			let {U, V, Σ} = A.SVD();
			U.toString();
			  // "[-0.6428  0.5630 0.5194 -0.0000]
			  //  [-0.1951 -0.3367 0.1235  0.9129]
			  //  [-0.1224 -0.6974 0.6045 -0.3651]
			  //  [ 0.7306  0.2887 0.5912  0.1826]"
			U.isOrthogonal();  // true
			V.toString();
			  // "[ 0.0660  0.3409 -0.4064  0.0000  0.8452]
			  //  [ 0.3162  0.3765 -0.6874 -0.1690 -0.5071]
			  //  [ 0.4344 -0.2697 -0.1557  0.8452  0.0000]
			  //  [-0.5694 -0.5819 -0.5806  0.0000 -0.0000]
			  //  [-0.6186  0.5750  0.0304  0.5071 -0.1690]"
			V.isOrthogonal();  // true
			// The number of singular values is the rank.
			Σ;  //  [17.73589205992891, 5.925426481232183, 1.824130985994107]
			U.mult(Matrix.diagonal(Σ, 4, 5)).mult(V.transpose).equals(A, 1e-10);  // true
			let vi = Array.from(V.cols());
			new Subspace(vi.slice(0, 3)).equals(A.rowSpace());    // true
			new Subspace(vi.slice(3)).equals(A.nullSpace());      // true
			let ui = Array.from(U.cols());
			new Subspace(ui.slice(0, 3)).equals(A.colSpace());    // true
			new Subspace(ui.slice(3)).equals(A.leftNullSpace());  // true
Throws

Will throw an error if the min(m, n) > 4, or if the eigenvalue / eigenspace computations otherwise fail numerically.

Details

LDLT( [ ε ] ) → {LDLTData}

Compute the LDLT decomposition of a symmetric matrix.

Description

For a symmetric matrix A, this computes a lower-unitriangular matrix L and a diagonal matrix D with nonzero entries such that A = L D L^T, if possible. This should be seen as a variant of Gaussian elimination that takes advantage of the symmetry of A. It uses about n^3/3 operations, which is about twice as fast as Gaussian elimination.

The LDLT decomposition exists for symmetric, positive-definite matrices (e.g. the normal matrix of a matrix with full column rank). It exists for some indefinite matrices, and does not exist for singular matrices.

Only the diagonal entries of the matrix D are returned. Use Matrix.diagonal to turn it into a matrix, as in Matrix.diagonal(D).

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this are considered to be zero.

Returns

The LDLT decomposition, or null if it does not exist.

Examples

			let A = Matrix.create([3, 2, 3],
			                      [2, 7, 4],
			                      [3, 4, 8]);
			A.isPosDef();  // true
			let {L, D} = A.LDLT();
			L.toString();
			  // "[1.0000 0.0000 0.0000]
			  //  [0.6667 1.0000 0.0000]
			  //  [1.0000 0.3529 1.0000]"
			let DM = Matrix.diagonal(D);
			DM.toString();
			  // "[3.0000 0.0000 0.0000]
			  //  [0.0000 5.6667 0.0000]
			  //  [0.0000 0.0000 4.2941]"
			L.mult(DM).mult(L.transpose).toString();
			  // "[3.0000 2.0000 3.0000]
			  //  [2.0000 7.0000 4.0000]
			  //  [3.0000 4.0000 8.0000]"

			let A = Matrix.create([1, 2, 3],
			                      [2, 5, 4],
			                      [3, 4, 2]);
			A.isPosDef();  // false
			// Not positive-definite, but the LDLT decomposition still exists
			let {L, D} = A.LDLT();
			L.toString(0);
			  // "[1  0 0]
			  //  [2  1 0]
			  //  [3 -2 1]"
			let DM = Matrix.diagonal(D);
			DM.toString(0);
			  // "[1 0   0]
			  //  [0 1   0]
			  //  [0 0 -11]"
			L.mult(DM).mult(L.transpose).equals(A);  // true

			let A = Matrix.create([ 27, -27,  18],
			                      [-27,  45,  12],
			                      [ 18,  12,  62]);
			A.isSingular();  // true
			A.LDLT();        // null
Throws

Will throw an error if the matrix is not symmetric.

Details

cholesky( [ ε ] ) → {Matrix}

Compute the Cholesky decomposition of a positive-definite symmetric matrix.

Description

For a positive-definite symmetric matrix A, this computes a lower-triangular matrix L with positive diagonal entries such that A = L L^T. These matrices are obtained from an LDLT decomposition by multiplying the columns of L by the square roots of the corresponding entries of D:

A = L D L^T = (L D^(1/2)) (L D^(1/2))^T

Parameters
Name Type Attributes Default Description
ε number <optional>
1e-10

Entries smaller than this are considered to be zero.

Returns

The matrix L such that A = L L^T, or null if the matrix is not positive-definite.

Examples

			let A = Matrix.create([3, 2, 3],
			                      [2, 7, 4],
			                      [3, 4, 8]);
			A.isPosDef();  // true
			let L = A.cholesky();
			L.toString();
			  // "[1.7321 0.0000 0.0000]
			  //  [1.1547 2.3805 0.0000]
			  //  [1.7321 0.8402 2.0722]"
			L.mult(L.transpose).equals(A, 1e-10);  // true

			let A = Matrix.create([1, 2, 3],
			                      [2, 5, 4],
			                      [3, 4, 2]);
			A.isPosDef();  // false
			A.cholesky();  // null
Throws

Will throw an error if the matrix is not symmetric.

Details