/** * <p> * Computes the 'y' vector and stores the result in 'v'<br> * <br> * y = -γ(A + U*V^T + V*U^T)u * </p> * * @param blockLength * @param A Contains the reflectors and the row being updated. * @param V Contains previously computed 'v' vectors. * @param row The row of 'A' that is to be updated. */ public static void computeY(int blockLength, FSubmatrixD1 A, FSubmatrixD1 V, int row, float gamma) { // Elements in 'y' before 'row' are known to be zero and the element at 'row' // is not used. Thus only elements after row and after are computed. // y = A*u multA_u(blockLength, A, V, row); for (int i = 0; i < row; i++) { // y = y + u_i*v_i^t*u + v_i*u_i^t*u // v_i^t*u float dot_v_u = BlockHouseHolder_FDRB.innerProdRow(blockLength, A, row, V, i, 1); // u_i^t*u float dot_u_u = BlockHouseHolder_FDRB.innerProdRow(blockLength, A, row, A, i, 1); // y = y + u_i*(v_i^t*u) // the ones in these 'u' are skipped over since the next submatrix of A // is only updated VectorOps_FDRB.add_row(blockLength, V, row, 1, A, i, dot_v_u, V, row, row + 1, A.col1 - A.col0); // y = y + v_i*(u_i^t*u) // the 1 in U is taken account above VectorOps_FDRB.add_row(blockLength, V, row, 1, V, i, dot_u_u, V, row, row + 1, A.col1 - A.col0); } // y = -gamma*y VectorOps_FDRB.scale_row(blockLength, V, row, -gamma, V, row, row + 1, V.col1 - V.col0); }
/** * Scales the elements in the specified row starting at element colStart by 'val'.<br> * W = val*Y * * Takes in account zeros and leading one automatically. * * @param zeroOffset How far off the diagonal is the first element in the vector. */ public static void scale_row(int blockLength, FSubmatrixD1 Y, FSubmatrixD1 W, int row, int zeroOffset, float val) { int offset = row + zeroOffset; if (offset >= W.col1 - W.col0) { return; } // handle the one W.set(row, offset, val); // scale rest of the vector VectorOps_FDRB.scale_row(blockLength, Y, row, val, W, row, offset + 1, Y.col1 - Y.col0); }