Example #1
0
        /**
         * <p>
         * Performs a matrix multiplication on {@link DMatrixRBlock} submatrices.<br>
         * <br>
         * c = c + a * b <br>
         * <br>
         * </p>
         *
         * <p>
         * It is assumed that all submatrices start at the beginning of a block and end at the end of a block.
         * </p>
         *
         * @param blockLength Size of the blocks in the submatrix.
         * @param A A submatrix.  Not modified.
         * @param B A submatrix.  Not modified.
         * @param C Result of the operation.  Modified,
         */
        public static void multPlus(int blockLength, DSubmatrixD1 A, DSubmatrixD1 B, DSubmatrixD1 C)
        {
//        checkInput( blockLength,A,B,C);

            for (int i = A.row0; i < A.row1; i += blockLength)
            {
                int heightA = Math.Min(blockLength, A.row1 - i);

                for (int j = B.col0; j < B.col1; j += blockLength)
                {
                    int widthB = Math.Min(blockLength, B.col1 - j);

                    int indexC = (i - A.row0 + C.row0) * C.original.numCols + (j - B.col0 + C.col0) * heightA;

                    for (int k = A.col0; k < A.col1; k += blockLength)
                    {
                        int widthA = Math.Min(blockLength, A.col1 - k);

                        int indexA = i * A.original.numCols + k * heightA;
                        int indexB = (k - A.col0 + B.row0) * B.original.numCols + j * widthA;

                        InnerMultiplication_DDRB.blockMultPlus(A.original.data, B.original.data, C.original.data,
                                                               indexA, indexB, indexC, heightA, widthA, widthB);
                    }
                }
            }
        }
Example #2
0
        /**
         * <p>
         * Performs a matrix multiplication with a transpose on {@link DMatrixRBlock} submatrices.<br>
         * <br>
         * c = a * b <sup>T</sup> <br>
         * <br>
         * </p>
         *
         * <p>
         * It is assumed that all submatrices start at the beginning of a block and end at the end of a block.
         * </p>
         *
         * @param blockLength Length of the blocks in the submatrix.
         * @param A A submatrix.  Not modified.
         * @param B A submatrix.  Not modified.
         * @param C Result of the operation.  Modified,
         */
        public static void multTransB(int blockLength, DSubmatrixD1 A, DSubmatrixD1 B, DSubmatrixD1 C)
        {
            for (int i = A.row0; i < A.row1; i += blockLength)
            {
                int heightA = Math.Min(blockLength, A.row1 - i);

                for (int j = B.row0; j < B.row1; j += blockLength)
                {
                    int widthC = Math.Min(blockLength, B.row1 - j);

                    int indexC = (i - A.row0 + C.row0) * C.original.numCols + (j - B.row0 + C.col0) * heightA;

                    for (int k = A.col0; k < A.col1; k += blockLength)
                    {
                        int widthA = Math.Min(blockLength, A.col1 - k);

                        int indexA = i * A.original.numCols + k * heightA;
                        int indexB = j * B.original.numCols + (k - A.col0 + B.col0) * widthC;

                        if (k == A.col0)
                        {
                            InnerMultiplication_DDRB.blockMultSetTransB(A.original.data, B.original.data, C.original.data,
                                                                        indexA, indexB, indexC, heightA, widthA, widthC);
                        }
                        else
                        {
                            InnerMultiplication_DDRB.blockMultPlusTransB(A.original.data, B.original.data, C.original.data,
                                                                         indexA, indexB, indexC, heightA, widthA, widthC);
                        }
                    }
                }
            }
        }
Example #3
0
        /**
         * Inverts an upper or lower triangular block submatrix.
         *
         * @param blockLength
         * @param upper Is it upper or lower triangular.
         * @param T Triangular matrix that is to be inverted.  Overwritten with solution.  Modified.
         * @param temp Work space variable that is size blockLength*blockLength.
         */
        public static void invert(int blockLength,
                                  bool upper,
                                  DSubmatrixD1 T,
                                  double[] temp)
        {
            if (upper)
            {
                throw new ArgumentException("Upper triangular matrices not supported yet");
            }

            if (temp.Length < blockLength * blockLength)
            {
                throw new ArgumentException("Temp must be at least blockLength*blockLength long.");
            }

            int M = T.row1 - T.row0;

            double[] dataT   = T.original.data;
            int      offsetT = T.row0 * T.original.numCols + M * T.col0;

            for (int i = 0; i < M; i += blockLength)
            {
                int heightT = Math.Min(T.row1 - (i + T.row0), blockLength);

                int indexII = offsetT + T.original.numCols * (i + T.row0) + heightT * (i + T.col0);

                for (int j = 0; j < i; j += blockLength)
                {
                    int widthX = Math.Min(T.col1 - (j + T.col0), blockLength);

                    for (int w = 0; w < temp.Length; w++)
                    {
                        temp[w] = 0;
                    }

                    for (int k = j; k < i; k += blockLength)
                    {
                        int widthT = Math.Min(T.col1 - (k + T.col0), blockLength);

                        int indL = offsetT + T.original.numCols * (i + T.row0) + heightT * (k + T.col0);
                        int indX = offsetT + T.original.numCols * (k + T.row0) + widthT * (j + T.col0);

                        InnerMultiplication_DDRB.blockMultMinus(dataT, dataT, temp, indL, indX, 0, heightT, widthT, widthX);
                    }

                    int indexX = offsetT + T.original.numCols * (i + T.row0) + heightT * (j + T.col0);

                    InnerTriangularSolver_DDRB.solveL(dataT, temp, heightT, widthX, heightT, indexII, 0);
                    Array.Copy(temp, 0, dataT, indexX, widthX * heightT);
                }
                InnerTriangularSolver_DDRB.invertLower(dataT, heightT, indexII);
            }
        }
        /**
         * <p>
         * Performs:<br>
         * <br>
         * A = A + &alpha; B <sup>T</sup>B
         * </p>
         *
         * @param blockLength Size of the block in the block matrix.
         * @param alpha scaling factor for right hand side.
         * @param A Block aligned submatrix.
         * @param B Block aligned submatrix.
         */
        public static void rankNUpdate(int blockLength, double alpha,
                                       DSubmatrixD1 A, DSubmatrixD1 B)
        {
            int heightB = B.row1 - B.row0;

            if (heightB > blockLength)
            {
                throw new ArgumentException("Height of B cannot be greater than the block length");
            }

            int N = B.col1 - B.col0;

            if (A.col1 - A.col0 != N)
            {
                throw new ArgumentException("A does not have the expected number of columns based on B's width");
            }
            if (A.row1 - A.row0 != N)
            {
                throw new ArgumentException("A does not have the expected number of rows based on B's width");
            }

            for (int i = B.col0; i < B.col1; i += blockLength)
            {
                int indexB_i = B.row0 * B.original.numCols + i * heightB;
                int widthB_i = Math.Min(blockLength, B.col1 - i);

                int rowA    = i - B.col0 + A.row0;
                int heightA = Math.Min(blockLength, A.row1 - rowA);

                for (int j = B.col0; j < B.col1; j += blockLength)
                {
                    int widthB_j = Math.Min(blockLength, B.col1 - j);

                    int indexA   = rowA * A.original.numCols + (j - B.col0 + A.col0) * heightA;
                    int indexB_j = B.row0 * B.original.numCols + j * heightB;

                    InnerMultiplication_DDRB.blockMultPlusTransA(alpha,
                                                                 B.original.data, B.original.data, A.original.data,
                                                                 indexB_i, indexB_j, indexA, heightB, widthB_i, widthB_j);
                }
            }
        }