/// <summary> /// The vector space is represented by V = { x | x = \alpha_1 * u_1 + \alpha_2 * u_2 + ... + \alpha_r * u_r } /// {u_1, u_2, ..., u_r} is the spanning set of V /// </summary> /// <param name="spanning_set"></param> public VectorSpace(IEnumerable <IVector> spanning_set) { List <IVector> vlist = Orthogonalization.Orthogonalize(spanning_set); mOrthogonalBasis = VectorUtils.RemoveZeroVectors(vlist); mOrthoNormalBasis = VectorUtils.Normalize(mOrthogonalBasis); }
/// <summary> /// Return the orthogonal basis of the null space of A /// </summary> /// <param name="A">the matrix</param> /// <returns>The orthogonal basis of the null space of A</returns> public static List <IVector> FindNullSpace(IMatrix A) { int n = A.ColCount; List <IVector> standardBasis = new List <IVector>(); double one = 1; for (int i = 0; i < n; ++i) { int col = A.ColKeys[i]; IVector e_i = new SparseVector(n, A.DefaultValue); e_i[col] = one; standardBasis.Add(e_i); } // return the orthogonal basis for V, which is the null space of A, using orthogonal complement List <IVector> wlist = Orthogonalization.Orthogonalize(A.NonEmptyRows, standardBasis); return(VectorUtils.RemoveZeroVectors(wlist)); }
/// <summary> /// Decompose A = QR /// </summary> /// <param name="A">A m x n matrix, m >= n</param> /// <param name="Q">A m x n orthogonal matrix, this is a column orthonormal matrix and has a property that Q.transpose * Q = I as the column vectors in Q are orthogonal normal vectors </param> /// <param name="R">A n x n matrix, which is upper triangular matrix if A is invertiable</param> public static void Factorize(IMatrix A, out IMatrix Q, out IMatrix R) { List <IVector> Rcols; List <IVector> Acols = MatrixUtils.GetColumnVectors(A); List <IVector> vstarlist = Orthogonalization.Orthogonalize(Acols, out Rcols); List <double> norms; List <IVector> qlist = VectorUtils.Normalize(vstarlist, out norms); Q = MatrixUtils.GetMatrix(qlist, A.DefaultValue); R = MatrixUtils.GetMatrix(Rcols, A.DefaultValue); foreach (int r in R.RowKeys) { R[r] = R[r].Multiply(norms[r]); } }
/// <summary> /// Another way to obtain the orthogonal basis for the null space of A by using the orthogonalization of A's columns /// </summary> /// <param name="A"></param> /// <returns></returns> public static List <IVector> FindNullSpace2(IMatrix A) { List <IVector> R = null; int n = A.ColCount; int rowCount = A.RowCount; // column vectors of A List <IVector> Acols = MatrixUtils.GetColumnVectors(A); List <IVector> vstarlist = Orthogonalization.Orthogonalize(Acols, out R); // T is a matrix with columns given by vectors in R // T is an upper triangle // A = (matrix with columns vstarlist) * T IMatrix T = MatrixUtils.GetMatrix(R, A.DefaultValue); IMatrix T_inverse = T.Transpose(); //T inverse is its transpose // let: A = (vstarlist * T) // then: A * T.inverse = (vstarlist * T) * T.inverse = vstarlist * (T * T.inverse) = vstarlist * I = vstarlist // now: if vstarlist[i] is zero vector then A * T.inverse[i] = 0 // therefore conclude 1: T.inverse[i] is in null space if vstarlist[i] is zero vector, furthermore {T.inverse[i]} are independent (since T is invertible) // // by: nullity(A) + rank(A) = n & count({ non-zero vstarlist[i] }) = rank(A) // therefore conclude 2: nullity(A) = n - rank(A) = n - count({ non-zero vstarlist[i] }) = count({ zero vstarlist[i] }) // // by conclusion 1 and 2 // we have null(A) = Span({ T.inverse[i] | i is such that vstarlist[i] is zero vector}) List <IVector> result = new List <IVector>(); List <IVector> Ticols = MatrixUtils.GetColumnVectors(T_inverse); for (int c = 0; c < vstarlist.Count; ++c) { if (vstarlist[c].IsEmpty) { result.Add(Ticols[c]); } } return(result); }