/** * <p> * Performs a tridiagonal decomposition on the upper row only. * </p> * * <p> * For each row 'a' in 'A': * Compute 'u' the householder reflector. * y(:) = A*u * v(i) = y - (1/2)*(y^T*u)*u * a(i+1) = a(i) - u*γ*v^T - v*u^t * </p> * * @param blockLength Size of a block * @param A is the row block being decomposed. Modified. * @param gammas Householder gammas. * @param V Where computed 'v' are stored in a row block. Modified. */ public static void tridiagUpperRow(int blockLength, DSubmatrixD1 A, double[] gammas, DSubmatrixD1 V) { int blockHeight = Math.Min(blockLength, A.row1 - A.row0); if (blockHeight <= 1) { return; } int width = A.col1 - A.col0; int num = Math.Min(width - 1, blockHeight); int applyIndex = Math.Min(width, blockHeight); // step through rows in the block for (int i = 0; i < num; i++) { // compute the new reflector and save it in a row in 'A' BlockHouseHolder_DDRB.computeHouseHolderRow(blockLength, A, gammas, i); double gamma = gammas[A.row0 + i]; // compute y computeY(blockLength, A, V, i, gamma); // compute v from y computeRowOfV(blockLength, A, V, i, gamma); // Apply the reflectors to the next row in 'A' only if (i + 1 < applyIndex) { applyReflectorsToRow(blockLength, A, V, i + 1); } } }
/** * Performs a standard bidiagonal decomposition just on the outer blocks of the provided matrix * * @param blockLength * @param A * @param gammasU */ public static bool bidiagOuterBlocks(int blockLength, DSubmatrixD1 A, double[] gammasU, double[] gammasV) { // Console.WriteLine("---------- Orig"); // A.original.print(); int width = Math.Min(blockLength, A.col1 - A.col0); int height = Math.Min(blockLength, A.row1 - A.row0); int min = Math.Min(width, height); for (int i = 0; i < min; i++) { //--- Apply reflector to the column // compute the householder vector if (!BlockHouseHolder_DDRB.computeHouseHolderCol(blockLength, A, gammasU, i)) { return(false); } // apply to rest of the columns in the column block BlockHouseHolder_DDRB.rank1UpdateMultR_Col(blockLength, A, i, gammasU[A.col0 + i]); // apply to the top row block BlockHouseHolder_DDRB.rank1UpdateMultR_TopRow(blockLength, A, i, gammasU[A.col0 + i]); Console.WriteLine("After column stuff"); A.original.print(); //-- Apply reflector to the row if (!BlockHouseHolder_DDRB.computeHouseHolderRow(blockLength, A, gammasV, i)) { return(false); } // apply to rest of the rows in the row block BlockHouseHolder_DDRB.rank1UpdateMultL_Row(blockLength, A, i, i + 1, gammasV[A.row0 + i]); Console.WriteLine("After update row"); A.original.print(); // apply to the left column block // TODO THIS WON'T WORK!!!!!!!!!!!!! // Needs the whole matrix to have been updated by the left reflector to compute the correct solution // rank1UpdateMultL_LeftCol(blockLength,A,i,i+1,gammasV[A.row0+i]); Console.WriteLine("After row stuff"); A.original.print(); } return(true); }