Пример #1
0
        public static float innerProdRowSymm(int blockLength,
                                             FSubmatrixD1 A,
                                             int rowA,
                                             FSubmatrixD1 B,
                                             int rowB, int zeroOffset)
        {
            int offset = rowA + zeroOffset;

            if (offset + B.col0 >= B.col1)
            {
                return(0);
            }

            if (offset < rowB)
            {
                // take in account the one in 'A'
                float total = B.get(offset, rowB);

                total += VectorOps_FDRB.dot_row_col(blockLength, A, rowA, B, rowB, offset + 1, rowB);
                total += VectorOps_FDRB.dot_row(blockLength, A, rowA, B, rowB, rowB, A.col1 - A.col0);

                return(total);
            }
            else
            {
                // take in account the one in 'A'
                float total = B.get(rowB, offset);

                total += VectorOps_FDRB.dot_row(blockLength, A, rowA, B, rowB, offset + 1, A.col1 - A.col0);

                return(total);
            }
        }
Пример #2
0
        /**
         * <p>
         * Computes the householder vector that is used to create reflector for the column.
         * The results are stored in the original matrix.
         * </p>
         *
         * <p>
         * The householder vector 'u' is computed as follows:<br>
         * <br>
         * u(1) = 1 <br>
         * u(i) = x(i)/(&tau; + x(1))<br>
         * </p>
         *
         * The first element is implicitly assumed to be one and not written.
         *
         * @return If there was any problems or not. true = no problem.
         */
        public static bool computeHouseHolderCol(int blockLength, FSubmatrixD1 Y,
                                                 float[] gamma, int i)
        {
            float max = BlockHouseHolder_FDRB.findMaxCol(blockLength, Y, i);

            if (max == 0.0f)
            {
                return(false);
            }
            else
            {
                // computes tau and normalizes u by max
                float tau = computeTauAndDivideCol(blockLength, Y, i, max);

                // divide u by u_0
                float u_0 = Y.get(i, i) + tau;
                divideElementsCol(blockLength, Y, i, u_0);

                gamma[Y.col0 + i] = u_0 / tau;
                tau *= max;

                // after the reflector is applied the column would be all zeros but be -tau in the first element
                Y.set(i, i, -tau);
            }
            return(true);
        }
Пример #3
0
        /**
         * <p>
         * Computes the householder vector from the specified row
         * </p>
         *
         * <p>
         * The householder vector 'u' is computed as follows:<br>
         * <br>
         * u(1) = 1 <br>
         * u(i) = x(i)/(&tau; + x(1))<br>
         * </p>
         *
         * The first element is implicitly assumed to be one and not written.
         *
         * @return If there was any problems or not. true = no problem.
         */
        public static bool computeHouseHolderRow(int blockLength, FSubmatrixD1 Y,
                                                 float[] gamma, int i)
        {
            float max = BlockHouseHolder_FDRB.findMaxRow(blockLength, Y, i, i + 1);

            if (max == 0.0f)
            {
                return(false);
            }
            else
            {
                // computes tau and normalizes u by max
                float tau = computeTauAndDivideRow(blockLength, Y, i, i + 1, max);

                // divide u by u_0
                float u_0 = Y.get(i, i + 1) + tau;
                VectorOps_FDRB.div_row(blockLength, Y, i, u_0, Y, i, i + 1, Y.col1 - Y.col0);

                gamma[Y.row0 + i] = u_0 / tau;

                // after the reflector is applied the column would be all zeros but be -tau in the first element
                Y.set(i, i + 1, -tau * max);
            }
            return(true);
        }
Пример #4
0
        /**
         * <p>
         * Applies the reflectors that have been computed previously to the specified row.
         * <br>
         * A = A + u*v^T + v*u^T only along the specified row in A.
         * </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 applyReflectorsToRow(int blockLength,
                                                FSubmatrixD1 A,
                                                FSubmatrixD1 V,
                                                int row)
        {
            int height = Math.Min(blockLength, A.row1 - A.row0);

            float[] dataA = A.original.data;
            float[] dataV = V.original.data;

            int indexU, indexV;

            // for each previously computed reflector
            for (int i = 0; i < row; i++)
            {
                int width = Math.Min(blockLength, A.col1 - A.col0);

                indexU = A.original.numCols * A.row0 + height * A.col0 + i * width + row;
                indexV = V.original.numCols * V.row0 + height * V.col0 + i * width + row;

                float u_row = (i + 1 == row) ? 1.0f : dataA[indexU];
                float v_row = dataV[indexV];

                // take in account the leading one
                float before = A.get(i, i + 1);
                A.set(i, i + 1, 1);

                // grab only the relevant row from A = A + u*v^T + v*u^T
                VectorOps_FDRB.add_row(blockLength, A, row, 1, V, i, u_row, A, row, row, A.col1 - A.col0);
                VectorOps_FDRB.add_row(blockLength, A, row, 1, A, i, v_row, A, row, row, A.col1 - A.col0);

                A.set(i, i + 1, before);
            }
        }
Пример #5
0
        private void copyZeros(FSubmatrixD1 subU)
        {
            int N = Math.Min(A.blockLength, subU.col1 - subU.col0);

            for (int i = 0; i < N; i++)
            {
                // save the zeros
                for (int j = 0; j <= i; j++)
                {
                    zerosM.unsafe_set(i, j, subU.get(i, j));
                    subU.set(i, j, 0);
                }
                // save the one
                if (subU.col0 + i + 1 < subU.original.numCols)
                {
                    zerosM.unsafe_set(i, i + 1, subU.get(i, i + 1));
                    subU.set(i, i + 1, 1);
                }
            }
        }
Пример #6
0
        public virtual bool decompose(FMatrixRBlock orig)
        {
            if (orig.numCols != orig.numRows)
            {
                throw new ArgumentException("Input matrix must be square.");
            }

            init(orig);

            FSubmatrixD1 subA = new FSubmatrixD1(A);
            FSubmatrixD1 subV = new FSubmatrixD1(V);
            FSubmatrixD1 subU = new FSubmatrixD1(A);

            int N = orig.numCols;

            for (int i = 0; i < N; i += A.blockLength)
            {
//            Console.WriteLine("-------- triag i "+i);
                int height = Math.Min(A.blockLength, A.numRows - i);

                subA.col0 = subU.col0 = i;
                subA.row0 = subU.row0 = i;

                subU.row1 = subU.row0 + height;

                subV.col0 = i;
                subV.row1 = height;
                subV.original.reshape(subV.row1, subV.col1, false);

                // bidiagonalize the top row
                TridiagonalHelper_FDRB.tridiagUpperRow(A.blockLength, subA, gammas, subV);

                // apply Householder reflectors to the lower portion using block multiplication

                if (subU.row1 < orig.numCols)
                {
                    // take in account the 1 in the last row.  The others are skipped over.
                    float before = subU.get(A.blockLength - 1, A.blockLength);
                    subU.set(A.blockLength - 1, A.blockLength, 1);

                    // A = A + U*V^T + V*U^T
                    multPlusTransA(A.blockLength, subU, subV, subA);
                    multPlusTransA(A.blockLength, subV, subU, subA);

                    subU.set(A.blockLength - 1, A.blockLength, before);
                }
            }

            return(true);
        }
Пример #7
0
        public static void add_row(int blockLength,
                                   FSubmatrixD1 A, int rowA, float alpha,
                                   FSubmatrixD1 B, int rowB, float beta,
                                   FSubmatrixD1 C, int rowC,
                                   int zeroOffset, int end)
        {
            int offset = rowA + zeroOffset;

            if (C.col0 + offset >= C.col1)
            {
                return;
            }
            // handle leading one
            C.set(rowC, offset, alpha + B.get(rowB, offset) * beta);

            VectorOps_FDRB.add_row(blockLength, A, rowA, alpha, B, rowB, beta, C, rowC, offset + 1, end);
        }
Пример #8
0
        /**
         * <p>
         * Final computation for a single row of 'v':<br>
         * <br>
         * v = y -(1/2)&gamma;(y^T*u)*u
         * </p>
         *
         * @param blockLength
         * @param A
         * @param V
         * @param row
         * @param gamma
         */
        public static void computeRowOfV(int blockLength,
                                         FSubmatrixD1 A,
                                         FSubmatrixD1 V,
                                         int row,
                                         float gamma)
        {
            // val=(y^T*u)
            float val = BlockHouseHolder_FDRB.innerProdRow(blockLength, A, row, V, row, 1);

            // take in account the one
            float before = A.get(row, row + 1);

            A.set(row, row + 1, 1);

            // v = y - (1/2)gamma*val * u
            VectorOps_FDRB.add_row(blockLength, V, row, 1, A, row, -0.5f * gamma * val, V, row, row + 1,
                                   A.col1 - A.col0);

            A.set(row, row + 1, before);
        }