/** * Sanity checks the input or declares a new matrix. Return matrix is an identity matrix. */ public static DMatrixRBlock initializeQ(DMatrixRBlock Q, int numRows, int numCols, int blockLength, bool compact) { int minLength = Math.Min(numRows, numCols); if (compact) { if (Q == null) { Q = new DMatrixRBlock(numRows, minLength, blockLength); MatrixOps_DDRB.setIdentity(Q); } else { if (Q.numRows != numRows || Q.numCols != minLength) { throw new ArgumentException("Unexpected matrix dimension. Found " + Q.numRows + " " + Q.numCols); } else { MatrixOps_DDRB.setIdentity(Q); } } } else { if (Q == null) { Q = new DMatrixRBlock(numRows, numRows, blockLength); MatrixOps_DDRB.setIdentity(Q); } else { if (Q.numRows != numRows || Q.numCols != numRows) { throw new ArgumentException("Unexpected matrix dimension. Found " + Q.numRows + " " + Q.numCols); } else { MatrixOps_DDRB.setIdentity(Q); } } } return(Q); }
public virtual /**/ double quality() { return(SpecializedOps_DDRM.qualityTriangular(decomposer.getQR())); } public virtual void solve(DMatrixRBlock B, DMatrixRBlock X) { if (B.numCols != X.numCols) { throw new ArgumentException("Columns of B and X do not match"); } if (QR.numCols != X.numRows) { throw new ArgumentException("Rows in X do not match the columns in A"); } if (QR.numRows != B.numRows) { throw new ArgumentException("Rows in B do not match the rows in A."); } if (B.blockLength != QR.blockLength || X.blockLength != QR.blockLength) { throw new ArgumentException("All matrices must have the same block length."); } // The system being solved for can be described as: // Q*R*X = B // First apply householder reflectors to B // Y = Q^T*B decomposer.applyQTran(B); // Second solve for Y using the upper triangle matrix R and the just computed Y // X = R^-1 * Y MatrixOps_DDRB.extractAligned(B, X); // extract a block aligned matrix int M = Math.Min(QR.numRows, QR.numCols); TriangularSolver_DDRB.solve(QR.blockLength, true, new DSubmatrixD1(QR, 0, M, 0, M), new DSubmatrixD1(X), false); } /** * Invert by solving for against an identity matrix. * * @param A_inv Where the inverted matrix saved. Modified. */ public virtual void invert(DMatrixRBlock A_inv) { int M = Math.Min(QR.numRows, QR.numCols); if (A_inv.numRows != M || A_inv.numCols != M) { throw new ArgumentException("A_inv must be square an have dimension " + M); } // Solve for A^-1 // Q*R*A^-1 = I // Apply householder reflectors to the identity matrix // y = Q^T*I = Q^T MatrixOps_DDRB.setIdentity(A_inv); decomposer.applyQTran(A_inv); // Solve using upper triangular R matrix // R*A^-1 = y // A^-1 = R^-1*y TriangularSolver_DDRB.solve(QR.blockLength, true, new DSubmatrixD1(QR, 0, M, 0, M), new DSubmatrixD1(A_inv), false); }