/**
         * <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*&gamma;*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);
                }
            }
        }
Example #2
0
        /**
         * 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);
        }