public virtual DMatrixRBlock getR(DMatrixRBlock R, bool compact) { int min = Math.Min(dataA.numRows, dataA.numCols); if (R == null) { if (compact) { R = new DMatrixRBlock(min, dataA.numCols, blockLength); } else { R = new DMatrixRBlock(dataA.numRows, dataA.numCols, blockLength); } } else { if (compact) { if (R.numCols != dataA.numCols || R.numRows != min) { throw new ArgumentException("Unexpected dimension."); } } else if (R.numCols != dataA.numCols || R.numRows != dataA.numRows) { throw new ArgumentException("Unexpected dimension."); } } MatrixOps_DDRB.zeroTriangle(false, R); MatrixOps_DDRB.copyTriangle(true, dataA, R); return(R); }
public virtual 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"); } if (temp == null || temp.Length < blockLength * blockLength) { temp = new double[blockLength * blockLength]; } // 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, temp); // 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); }
private bool decomposeLower() { 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); subA.col0 = i; subA.col1 = i + widthA; subA.row0 = subA.col0; subA.row1 = subA.col1; subB.col0 = i; subB.col1 = i + widthA; subB.row0 = i + widthA; subB.row1 = T.numRows; subC.col0 = i + widthA; subC.col1 = T.numRows; subC.row0 = i + widthA; subC.row1 = T.numRows; // cholesky on inner block A if (!InnerCholesky_DDRB.lower(subA)) { return(false); } // on the last block these operations are not needed. if (widthA == blockLength) { // B = L^-1 B TriangularSolver_DDRB.solveBlock(blockLength, false, subA, subB, false, true); // C = C - B * B^T InnerRankUpdate_DDRB.symmRankNMinus_L(blockLength, subC, subB); } } MatrixOps_DDRB.zeroTriangle(true, T); return(true); }