public void solve(DMatrixRBlock B, DMatrixRBlock X) { if (B.numRows != QR.numRows) { throw new ArgumentException("Row of B and A do not match"); } X.reshape(QR.numCols, B.numCols); // 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); }
public void invert(DMatrixRBlock A_inv) { DMatrixRBlock T = decomposer.getT(null); if (A_inv.numRows != T.numRows || A_inv.numCols != T.numCols) { throw new ArgumentException("Unexpected number or rows and/or columns"); } // zero the upper triangular portion of A_inv MatrixOps_DDRB.zeroTriangle(true, A_inv); DSubmatrixD1 L = new DSubmatrixD1(T); DSubmatrixD1 B = new DSubmatrixD1(A_inv); // invert L from cholesky decomposition and write the solution into the lower // triangular portion of A_inv // B = inv(L) TriangularSolver_DDRB.invert(blockLength, false, L, B, workspace); // B = L^-T * B // todo could speed up by taking advantage of B being lower triangular // todo take advantage of symmetry TriangularSolver_DDRB.solveL(blockLength, L, B, true); }
virtual public void solve(DMatrixRBlock B, DMatrixRBlock X) { if (B.blockLength != blockLength) { throw new ArgumentException("Unexpected blocklength in B."); } DSubmatrixD1 L = new DSubmatrixD1(decomposer.getT(null)); if (X == null) { //X = B.create<DMatrixRBlock>(L.col1, B.numCols); X = new DMatrixRBlock(L.col1, B.numCols); } else { X.reshape(L.col1, B.numCols, blockLength, false); } // L * L^T*X = B // Solve for Y: L*Y = B TriangularSolver_DDRB.solve(blockLength, false, L, new DSubmatrixD1(B), false); // L^T * X = Y TriangularSolver_DDRB.solve(blockLength, false, L, new DSubmatrixD1(B), true); if (X != null) { // copy the solution from B into X MatrixOps_DDRB.extractAligned(B, X); } }
private bool decomposeUpper() { int blockLength = T.blockLength; subA.set(T); subB.set(T); subC.set(T); for (int i = 0; i < T.numCols; i += blockLength) { int widthA = Math.Min(blockLength, T.numCols - i); //@formatter:off subA.col0 = i; subA.col1 = i + widthA; subA.row0 = subA.col0; subA.row1 = subA.col1; subB.col0 = i + widthA; subB.col1 = T.numCols; subB.row0 = i; subB.row1 = i + widthA; subC.col0 = i + widthA; subC.col1 = T.numCols; subC.row0 = i + widthA; subC.row1 = T.numCols; //@formatter:on // cholesky on inner block A if (!InnerCholesky_DDRB.upper(subA)) { return(false); } // on the last block these operations are not needed. if (widthA == blockLength) { // B = U^-1 B TriangularSolver_DDRB.solveBlock(blockLength, true, subA, subB, true, false); // C = C - B^T * B InnerRankUpdate_DDRB.symmRankNMinus_U(blockLength, subC, subB); } } MatrixOps_DDRB.zeroTriangle(false, T); return(true); }