/// <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]); } }
public static IMatrix Invert(IMatrix A) { Debug.Assert(A.RowCount == A.ColCount); int n = A.RowCount; double one = 1; List <IVector> AinvCols = new List <IVector>(); for (int i = 0; i < n; ++i) { IVector e_i = new SparseVector(n, A.DefaultValue); e_i[i] = one; IVector AinvCol = Solve(A, e_i); AinvCols.Add(AinvCol); } IMatrix Ainv = MatrixUtils.GetMatrix(AinvCols); return(Ainv); }
/// <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); }
/// <summary> /// Get the eigen values and corresponding eigen vectors for the square matrix A /// </summary> /// <param name="A"></param> /// <param name="eigenValues"></param> /// <param name="eigenVectors"></param> public static List <IVector> FindEigenVectors(IMatrix A, out List <double> eigenValues, int K = 100, double epsilon = 1e-10) { Debug.Assert(A.RowCount == A.ColCount); IMatrix T, U; Factorize(A, out T, out U, K, epsilon); int n = A.RowCount; eigenValues = new List <double>(); for (int i = 0; i < n; ++i) { eigenValues.Add(T[i, i]); } List <IVector> eigenVectors = MatrixUtils.GetColumnVectors(U); return(eigenVectors); }