/// <summary> /// Given we want to find x such as A * x = b /// 1. Decompose A = L * U, where L is the lower triangular and U is the upper triangular /// 2. We have L * U * x = b, which can be rewritten as L * y = b, where U * x = y /// 3. Solve y for L * y = b using forward substitution /// 4. Solve x for U * x = y using backward substitution /// </summary> /// <param name="A"></param> /// <param name="b"></param> /// <returns></returns> public static IVector Solve(IMatrix A, IVector b) { IMatrix L; Cholesky.Factorize(A, out L); IMatrix U = L.Transpose(); // upper triangular matrix IVector y = ForwardSubstitution.Solve(L, b); IVector x = BackwardSubstitution.Solve(U, y); return(x); }
/// <summary> /// Solve x for Ax = b, where A is a invertible matrix /// /// The method works as follows: /// 1. QR factorization A = Q * R /// 2. Let: c = Q.transpose * b, we have R * x = c, where R is a triangular matrix if A is n x n /// 3. Solve x using backward substitution /// </summary> /// <param name="A">An m x n matrix with linearly independent columns, where m >= n</param> /// <param name="b">An m x 1 column vector </param> /// <returns>An n x 1 column vector, x, such that Ax = b when m = n and Ax ~ b when m > n </returns> public static IVector Solve(IMatrix A, IVector b) { // Q is a m x m matrix, R is a m x n matrix // Q = [Q1 Q2] Q1 is a m x n matrix, Q2 is a m x (m-n) matrix // R = [R1; 0] R1 is a n x n upper triangular matrix matrix // A = Q * R = Q1 * R1 IMatrix Q, R; QR.Factorize(A, out Q, out R); IVector c = Q.Transpose().Multiply(b); IVector x = BackwardSubstitution.Solve(R, c); return(x); }
/// <summary> /// This is used for data fitting / regression /// A is a m x n matrix, where m >= n /// b is a m x 1 column vector /// The method solves for x, which is a n x 1 column vectors such that A * x is closest to b /// /// The method works as follows: /// 1. Let C = A.transpose * A, we have A.transpose * A * x = C * x = A.transpose * b /// 2. Decompose C : C = L * L.transpose = L * U, we have L * U * x = A.transpose * b /// 3. Let z = U * x, we have L * z = A.transpose * b /// 4. Solve z using forward substitution /// 5. Solve x from U * x = z using backward substitution /// </summary> /// <param name="A"></param> /// <param name="b"></param> /// <returns></returns> public static IVector SolveLeastSquare(IMatrix A, IVector b) { IMatrix At = A.Transpose(); IMatrix C = At.Multiply(A); //C is a n x n matrix IVector d = At.Multiply(b); IMatrix L; Cholesky.Factorize(C, out L); IMatrix U = L.Transpose(); IVector z = ForwardSubstitution.Solve(L, d); IVector x = BackwardSubstitution.Solve(U, z); return(x); }
/// <summary> /// This is used for data fitting / regression /// A is a m x n matrix, where m >= n /// b is a m x 1 column vector /// The method solves for x, which is a n x 1 column vectors such that A * x is closest to b /// /// The method works as follows: /// 1. Let C = A.transpose * A, we have A.transpose * A * x = C * x = A.transpose * b /// 2. Decompose C : C = Q * R, we have Q * R * x = A.transpose * b /// 3. Multiply both side by Q.transpose = Q.inverse, we have Q.transpose * Q * R * x = Q.transpose * A.transpose * b /// 4. Since Q.tranpose * Q = I, we have R * x = Q.transpose * A.transpose * b /// 5. Solve x from R * x = Q.transpose * A.transpose * b using backward substitution /// </summary> /// <param name="A"></param> /// <param name="b"></param> /// <returns></returns> public static IVector SolveLeastSquare(IMatrix A, IVector b) { IMatrix At = A.Transpose(); IMatrix C = At.Multiply(A); //C is a n x n matrix IMatrix Q, R; QR.Factorize(C, out Q, out R); IMatrix Qt = Q.Transpose(); IVector d = Qt.Multiply(At).Multiply(b); IVector x = BackwardSubstitution.Solve(R, d); return(x); }