new Subspace( generators [, hints ] )

Class representing a Subspace.

Description

A subspace of R^n is a collection of vectors V satisfying:

  • The zero vector is contained in V.
  • The sum of two vectors V is also in V.
  • All scalar multiples of a vector in V is also in V.

Subspaces often arise as a span of some number of vectors, or as the null space of a matrix. Any subspace can be expressed as a span, which is the same as the column space of a matrix. This class represents a subspace as the column space of the matrix Subspace#basis.

This constructor takes a spanning set for the Subspace. (To produce a null space, use Matrix#nullSpace). It constructs a basis from a maximal linearly independent subset of the generators.

Parameters
Name Type Attributes Default Description
generators Array.<Vector> | Matrix

A spanning set for the subspace. If it is a matrix, use the columns of the matrix as the spanning set.

hints Object <optional>
{}

Precomputed properties of the subspace.

Name Type Attributes Default Description
n integer <optional>
generators.m

The dimension of the ambient R^n. Only necessary to provide if generators is empty.

isBasis boolean <optional>
false

The generators are linearly independent.

isON boolean <optional>
false

The generators are orthonormal.

ε number <optional>
1e-10

Use this value in Matrix#colBasis when computing a basis.

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 V = new Subspace(A);
			V.toString(1);
			  // "Subspace of R^4 of dimension 3 with basis
			  //  [ 0.0] [-3.0] [ 4.0]
			  //  [-1.0] [-2.0] [ 3.0]
			  //  [-2.0] [-3.0] [ 3.0]
			  //  [ 1.0] [ 4.0] [-9.0]"
Throws

Will throw an error if the generators do not all have the same length, or if it can't determine the ambient space R^n.

Details

Members


n :integer

The dimension of the ambient R^n.

Description

All vectors in this subspace have n entries.

Examples

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

basis :Matrix

The columns of this matrix form a basis for this subspace.

Description

A nonzero subspace has infinitely many bases. This is the basis created in the constructor from the passed generators.

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 V = new Subspace(A);
			V.basis.toString(1);
			  // "[ 0.0 -3.0  4.0]
			  //  [-1.0 -2.0  3.0]
			  //  [-2.0 -3.0  3.0]
			  //  [ 1.0  4.0 -9.0]"
Details

dim :integer

The dimension of the subspace.

Description

The dimension of a subspace is by definition the number of vectors in any basis of the subspace. Hence this is an alias for this.basis.n.

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 V = new Subspace(A);
			V.dim;  // 3
Details
integer

Methods


<static> Rn( n ) → {Subspace}

The subspace R^n.

Description

This creates the subspace of R^n with basis equal to the nxn identity matrix.

Parameters
Name Type Description
n integer

The dimension of the space.

Returns

The subspace R^n.

Examples

			Subspace.Rn(3).toString();  // "The full subspace R^3"
Details

<static> zero( n ) → {Subspace}

The zero subspace of R^n.

Description

This creates the subspace of R^n with no generators.

Parameters
Name Type Description
n integer

The ambient dimension.

Returns

The subspace {0}.

Examples

			Subspace.zero(3).toString();  // "The zero subspace of R^3"
Details

toString( [ precision ] ) → {string}

Return a string representation of the subspace.

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

The number of decimal places to include.

Returns

A string representation of the subspace.

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 V = new Subspace(A);
			V.toString(1);
			  // "Subspace of R^4 of dimension 3 with basis
			  //  [ 0.0] [-3.0] [ 4.0]
			  //  [-1.0] [-2.0] [ 3.0]
			  //  [-2.0] [-3.0] [ 3.0]
			  //  [ 1.0] [ 4.0] [-9.0]"
Details

isMaximal() → {boolean}

Test whether the subspace is all of R^n.

Description

The only n-dimensional subspace of R^n is R^n itself, so this is a shortcut for this.dim === this.n.

Returns

True if this subspace is equal to R^n.

Examples

			Subspace.Rn(3).isMaximal();  // true

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

isZero() → {boolean}

Test whether the subspace only contains the zero vector.

Description

The only zero-dimensional subspace of R^n is {0}, so this is a shortcut for this.dim === 0.

Returns

True if this subspace is equal to {0}.

Examples

			Subspace.zero(3).isZero();  // true

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

add( other [, ε ] ) → {Subspace}

Return the sum of two subspaces.

Description

The sum is the subspace generated by the bases of this and other. It is the smallest subspace containing both this and other.

Parameters
Name Type Attributes Default Description
other Subspace

The subspace to add.

ε number <optional>
1e-10

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

Returns

The sum of this and other.

Examples

			let V = new Subspace([[ 0, -1, -2, 1], [-3, -2, -3,  4]]);
			let W = new Subspace([[-6, -1,  0, 5], [ 4,  3,  3, -9]]);
			V.add(W).toString(1);
			  // "Subspace of R^4 of dimension 3 spanned by
			  //  [ 0.0] [-3.0] [ 4.0]
			  //  [-1.0] [-2.0] [ 3.0]
			  //  [-2.0] [-3.0] [ 3.0]
			  //  [ 1.0] [ 4.0] [-9.0]"
Throws

Will throw an error of this.n != other.n.

Details

intersect( other [, ε ] ) → {Subspace}

Take the intersection of two subspaces.

Description

This is the subspace consisting of all vectors contained both in this and in other. It is computed by taking the orthogonal complement of the sum of the orthogonal complements.

Parameters
Name Type Attributes Default Description
other Subspace

The subspace to intersect.

ε number <optional>
1e-10

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

Returns

The largest subspace contained in this and other.

Examples

			let V = new Subspace([[ 0, -1, -2, 1], [-3, -2, -3,  4]]);
			let W = new Subspace([[-6, -1,  0, 5], [ 4,  3,  3, -9]]);
			V.intersect(W).toString();
			  // "Subspace of R^4 of dimension 1 spanned by
			  //  [ 1.0000]
			  //  [ 0.1667]
			  //  [ 0.0000]
			  //  [-0.8333]"
Throws

Will throw and error of this.n != other.n.

Details

projectionMatrix( [ ε ] ) → {Matrix}

Compute the projection matrix onto this.

Description

The projection matrix is the nxn matrix P such that Pv is the projection of v onto this subspace. This method computes P using the formula A(A^TA)^(-1)A^T, where A is the matrix this.basis, unless an orthonormal basis has been computed, in which case it returns QQ^T, where the columns of Q form an orthonormal basis.

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 nxn matrix for projection onto this.

Examples

			let V = new Subspace(Matrix.create([ 0, -3, -6,  4,  9],
			                                   [-1, -2, -1,  3,  1],
			                                   [-2, -3,  0,  3, -1],
			                                   [ 1,  4,  5, -9, -7]));
			let P = V.projectionMatrix();
			P.toString();
			  // "[1.0000  0.0000  0.0000  0.0000]
			  //  [0.0000  0.1667  0.3333 -0.1667]
			  //  [0.0000  0.3333  0.8667  0.0667]
			  //  [0.0000 -0.1667  0.0667  0.9667]"
			P.mult(P).equals(P, 1e-10);      // true
			P.colSpace().equals(V);          // true
			P.nullSpace().equals(V.perp());  // true

project( v [, ε ] ) → {Vector}

Compute the orthogonal projection of a vector onto this.

Description

The orthogonal projection v1 of v is the closest vector to v in the subspace. It is defined by the property that v-v1 is orthogonal to V.

If the projection matrix P has been cached, v1 is computed as Pv. Otherwise v1 is computed using basis.projectColSpace(). If you want to compute many orthogonal projections, run this.projectionMatrix() first.

Parameters
Name Type Attributes Default Description
v Vector

The vector to project.

ε number <optional>
1e-10

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

Returns

The orthogonal projection.

Examples

			let V = new Subspace(Matrix.create([ 0, -3, -6,  4,  9],
			                                   [-1, -2, -1,  3,  1],
			                                   [-2, -3,  0,  3, -1],
			                                   [ 1,  4,  5, -9, -7]));
			
			let u = Vector.create(1, 2, 3, 4);
			let u1 = V.project(u);
			u1.toString();                 // "[1.0000 0.6667 3.5333 3.7333]"
			V.contains(u1);                // true
			V.isOrthogonalTo(u.sub(u1));   // true
			
			let v = Vector.create(0, -1, -2, 1); // in V
			V.project(v).toString(0);      // "[0 -1 -2 1]"
			
			let w = Vector.create(0, 5, -2, 1); // in Vperp
			V.project(w).toString(0);      // "[0 0 0 0]"
Throws

Throws an error if v.length != this.n.


orthoDecomp( v [, ε ] ) → {Array.<Vector>}

Compute the orthogonal decomposition of a vector with respect to this.

Description

This returns the unique pair of vectors [v1, v2] such that v1 is in this, v2 is orthogonal to this, and v1 + v2 = v. The vector v1 is the orthogonal projection of v, and v2 is just v-v1.

Parameters
Name Type Attributes Default Description
v Vector

The vector to decompose.

ε number <optional>
1e-10

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

Returns

Returns [v1, v2] as described above.

Examples

			let V = new Subspace(Matrix.create([ 0, -3, -6,  4,  9],
			                                   [-1, -2, -1,  3,  1],
			                                   [-2, -3,  0,  3, -1],
			                                   [ 1,  4,  5, -9, -7]));
			
			let u = Vector.create(1, 2, 3, 4);
			let [u1, u2] = V.orthoDecomp(u);
			u1.toString();                 // "[1.0000 0.6667 3.5333 3.7333]"
			u2.toString();                 // "[0.0000 1.3333 -0.5333 0.2667]"
			u1.clone().add(u2).equals(u);  // true
			V.contains(u1);                // true
			V.isOrthogonalTo(u2);          // true
			
			let v = Vector.create(0, -1, -2, 1); // in V
			let [v1, v2] = V.orthoDecomp(v);
			v1.toString(0);                // "[0 -1 -2 1]"
			v2.toString(0);                // "[0 0 0 0]"
			
			let w = Vector.create(0, 5, -2, 1); // in Vperp
			let [w1, w2] = V.orthoDecomp(w);
			w1.toString(0);                // "[0 0 0 0]"
			w2.toString(0);                // "[0 5 -2 1]"
Throws

Throws an error if v.length != this.n.


complement( v [, ε ] ) → {Vector}

This is an alias for this.orthoDecomp(v, ε)[1].

Description

The complement v2 of v with respect to this is the shortest vector from this to v. It is defined by the property that v-v2 is the orthogonal projection of v onto this. Equivalently, v2 is the orthogonal projection of v onto the orthogonal complement.

Parameters
Name Type Attributes Default Description
v Vector

The vector to project.

ε number <optional>
1e-10

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

Returns

The orthogonal projection onto the orthogonal complement.

Examples

			let V = new Subspace(Matrix.create([ 0, -3, -6,  4,  9],
			                                   [-1, -2, -1,  3,  1],
			                                   [-2, -3,  0,  3, -1],
			                                   [ 1,  4,  5, -9, -7]));
			
			let u = Vector.create(1, 2, 3, 4);
			let u2 = V.complement(u);
			u2.toString();                 // "[0.0000 1.3333 -0.5333 0.2667]"
			V.isOrthogonalTo(u2);          // true
			V.contains(u2.sub(u));         // true
			
			let v = Vector.create(0, -1, -2, 1); // in V
			let v2 = V.complement(v);
			v2.toString(0);                // "[0 0 0 0]"
			
			let w = Vector.create(0, 5, -2, 1); // in Vperp
			let w2 = V.complement(w);
			w2.toString(0);                // "[0 5 -2 1]"
Throws

Throws an error if v.length != this.n.


distanceTo( v [, ε ] ) → {number}

Compute the distance of v from this.

Description

This is an alias for this.complement(v, ε).size.

Parameters
Name Type Attributes Default Description
v Vector

The vector to measure.

ε number <optional>
1e-10

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

Returns

The distance to this.

Throws

Throws an error if v.length != this.n.

Details

contains( v [, ε ] ) → {boolean}

Test if this subspace contains a vector.

Description

To say that this contains v means that v is a linear combination of the basis vectors.

If v.size <= ε then this method returns true. Otherwise this method measures the distance from v.normalize() to this, and returns true if the distance is at most ε.

Parameters
Name Type Attributes Default Description
v Vector

The vector to test.

ε number <optional>
1e-10

Vectors shorter than this value are taken to be zero. Also used for pivoting if no projection matrix has been cached.

Returns

True if the distance from v to this is at most ε.

Examples

			let V = new Subspace(Matrix.create([ 0, -3, -6,  4,  9],
			                                   [-1, -2, -1,  3,  1],
			                                   [-2, -3,  0,  3, -1],
			                                   [ 1,  4,  5, -9, -7]));
			let v = Vector.create(-9, -4, -5, 10);  // Sum of the first three columns
			V.contains(v);    // true
			let w = Vector.create(-9, -4, -5, 9);
			V.contains(w);    // false
			V.distanceTo(w);  // 0.1825  (approximately)
Throws

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


isOrthogonalTo( v [, ε ] ) → {boolean}

Test if a vector is orthogonal to this.

Description

To say that v is orthogonal to this means that the dot product of v with the basis vectors is equal to zero.

If v.size <= ε then this method returns true. Otherwise this method measures the size of the projection of v.normalize() onto this, and returns true if the size is at most ε. This is (mathematically if not numerically) equivalent to this.perp().contains(v, ε).

Parameters
Name Type Attributes Default Description
v Vector

The vector to test.

ε number <optional>
1e-10

Vectors shorter than this value are taken to be zero. Also used for pivoting if no projection matrix has been cached.

Returns

True if the distance from v to the orthogonal complement of this is at most ε.

Examples

			let V = new Subspace(Matrix.create([ 0, -3, -6,  4,  9],
			                                   [-1, -2, -1,  3,  1],
			                                   [-2, -3,  0,  3, -1],
			                                   [ 1,  4,  5, -9, -7]));
			
			let v = Vector.create(0, 5, -2, 1);
			V.isOrthogonalTo(v);                  // true
			V.basis.transpose.apply(v).isZero();  // true
			let w = Vector.create(0, 5, -2, 2);
			V.isOrthogonalTo(w);                  // false
			V.project(w).size;                    // 0.9831  (approximately)
Throws

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


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

Test if this subspace is contained in another subspace.

Description

This subspace V is contained in another subspace W when all of the basis vectors of V are contained in W.

Parameters
Name Type Attributes Default Description
other Subspace

The subspace to test.

ε number <optional>
1e-10

Parameter passed to Subspace#contains.

Returns

True if this is contained in other.

Examples

			let V = new Subspace([[ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]]);
			let W = new Subspace([[ 1,  0, -3,  0,  5],
			                      [ 0,  0,  0,  1,  0]]);
			W.isSubspaceOf(V);       // true
			W.perp().isSubspaceOf(V);  // false
Throws

Will throw an error if this.n != other.n.


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

Test if this Subspace is equal to other.

Description

Two subspaces are equal if and only if they have the same dimension and one contains the other.

Parameters
Name Type Attributes Default Description
other Subspace

The subspace to compare.

ε number <optional>
1e-10

Parameter passed to Subspace#contains.

Returns

True if the subspaces are equal.

Examples

			let V = new Subspace([[ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]]);
			let W = new Subspace([[-1, -5, -7,  7, 10],
			                      [-3, -5, -1,  6,  0],
			                      [-1,  1,  5, -6, -8]]);
			let U = new Subspace([[ 1,  0,  0,  0,  0],
			                      [ 0,  1,  0,  0,  0],
			                      [ 0,  0,  1,  0,  0]]);
			V.equals(W);  // true
			V.equals(U);  // false
Throws

Will throw an error if this.n != other.n.


perp( [ ε ] ) → {Subspace}

Return the orthogonal complement of this.

Description

The orthogonal complement of a subspace V is the set of all vectors w such that w is orthogonal to every vector in V. Its dimension is n minus the dimension of V.

If V is the column space of a matrix A, then its orthogonal complement is the left null space 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 orthogonal complement.

Examples

			let V = new Subspace([[ 0, -3, -6,  4,  9],
			                      [-1, -2, -1,  3,  1],
			                      [-2, -3,  0,  3, -1],
			                      [ 1,  4,  5, -9, -7]]);
			V.toString(1);
			  // "Subspace of R^5 of dimension 3 with basis
			  //  [ 0.0] [-1.0] [-2.0]
			  //  [-3.0] [-2.0] [-3.0]
			  //  [-6.0] [-1.0] [ 0.0]
			  //  [ 4.0] [ 3.0] [ 3.0]
			  //  [ 9.0] [ 1.0] [-1.0]"
			V.perp().toString(1);
			  // "Subspace of R^5 of dimension 2 with basis
			  //  [ 0.0] [ 1.0]
			  //  [-0.2] [-0.6]
			  //  [ 1.0] [ 0.0]
			  //  [ 0.0] [-0.0]
			  //  [ 0.6] [-0.2]"
			Array.from(V.perp().basis.cols()).every(col => V.isOrthogonalTo(col));
			  // true

ONbasis( [ ε ] ) → {Matrix}

Compute an orthonormal basis for the subspace.

Description

This is a shortcut for this.basis.QR(ε).Q.

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

Vectors shorter than this value are taken to be zero.

Returns

A matrix whose columns form an orthonormal basis for the Subspace.

Examples

			let V = new Subspace([[ 3,  1, -1,  3],
			                      [-5,  1,  5, -7],
			                      [ 1,  1, -2,  8]]);
			let Q = V.ONbasis();
			Q.toString();
			  // "[ 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.colSpace().equals(V);  // true
			Q.transpose.mult(Q).toString(1);
			  // "[1.0 0.0 0.0]
			  //  [0.0 1.0 0.0]
			  //  [0.0 0.0 1.0]"
Details