/** * <p> * A = (I + W Y<sup>T</sup>)<sup>T</sup>A<BR> * A = A + Y (W<sup>T</sup>A)<BR> * <br> * where A is a submatrix of the input matrix. * </p> */ protected void updateA(FSubmatrixD1 A) { setW(); A.row0 = Y.row0; A.row1 = Y.row1; A.col0 = Y.col1; A.col1 = Y.original.numCols; WTA.row0 = 0; WTA.col0 = 0; WTA.row1 = W.col1 - W.col0; WTA.col1 = A.col1 - A.col0; WTA.original.reshape(WTA.row1, WTA.col1, false); if (A.col1 > A.col0) { BlockHouseHolder_FDRB.computeW_Column(blockLength, Y, W, temp, gammas, Y.col0); MatrixMult_FDRB.multTransA(blockLength, W, A, WTA); BlockHouseHolder_FDRB.multAdd_zeros(blockLength, Y, WTA, A); } else if (saveW) { BlockHouseHolder_FDRB.computeW_Column(blockLength, Y, W, temp, gammas, Y.col0); } }
/** * <p> * Multiplies the provided matrix by Q<sup>T</sup> using householder reflectors. This is more * efficient that computing Q then applying it to the matrix. * </p> * * <p> * Q = Q*(I - γ W*Y^T)<br> * QR = A ≥ R = Q^T*A = (Q3^T * (Q2^T * (Q1^t * A))) * </p> * * @param B Matrix which Q is applied to. Modified. */ public void applyQTran(FMatrixRBlock B) { int minDimen = Math.Min(dataA.numCols, dataA.numRows); FSubmatrixD1 subB = new FSubmatrixD1(B); W.col0 = W.row0 = 0; Y.row1 = W.row1 = dataA.numRows; WTA.row0 = WTA.col0 = 0; // (Q3^T * (Q2^T * (Q1^t * A))) for (int i = 0; i < minDimen; i += blockLength) { Y.col0 = i; Y.col1 = Math.Min(Y.col0 + blockLength, dataA.numCols); Y.row0 = i; subB.row0 = i; // subB.row1 = B.numRows; // subB.col0 = 0; // subB.col1 = B.numCols; setW(); // W.original.reshape(W.row1,W.col1,false); WTA.row0 = 0; WTA.col0 = 0; WTA.row1 = W.col1 - W.col0; WTA.col1 = subB.col1 - subB.col0; WTA.original.reshape(WTA.row1, WTA.col1, false); // Compute W matrix from reflectors stored in Y if (!saveW) { BlockHouseHolder_FDRB.computeW_Column(blockLength, Y, W, temp, gammas, Y.col0); } // Apply the Qi to Q MatrixMult_FDRB.multTransA(blockLength, W, subB, WTA); BlockHouseHolder_FDRB.multAdd_zeros(blockLength, Y, WTA, subB); } }