virtual public void solve(DMatrixRBlock B, DMatrixRBlock X)
        {
            if (B.blockLength != blockLength)
            {
                throw new ArgumentException("Unexpected blocklength in B.");
            }

            DSubmatrixD1 L = new DSubmatrixD1(decomposer.getT(null));

            if (X == null)
            {
                //X = B.create<DMatrixRBlock>(L.col1, B.numCols);
                X = new DMatrixRBlock(L.col1, B.numCols);
            }
            else
            {
                X.reshape(L.col1, B.numCols, blockLength, false);
            }

            //  L * L^T*X = B

            // Solve for Y:  L*Y = B
            TriangularSolver_DDRB.solve(blockLength, false, L, new DSubmatrixD1(B), false);

            // L^T * X = Y
            TriangularSolver_DDRB.solve(blockLength, false, L, new DSubmatrixD1(B), true);

            if (X != null)
            {
                // copy the solution from B into X
                MatrixOps_DDRB.extractAligned(B, X);
            }
        }
        public void invert(DMatrixRBlock A_inv)
        {
            DMatrixRBlock T = decomposer.getT(null);

            if (A_inv.numRows != T.numRows || A_inv.numCols != T.numCols)
            {
                throw new ArgumentException("Unexpected number or rows and/or columns");
            }

            // zero the upper triangular portion of A_inv
            MatrixOps_DDRB.zeroTriangle(true, A_inv);

            DSubmatrixD1 L = new DSubmatrixD1(T);
            DSubmatrixD1 B = new DSubmatrixD1(A_inv);

            // invert L from cholesky decomposition and write the solution into the lower
            // triangular portion of A_inv
            // B = inv(L)
            TriangularSolver_DDRB.invert(blockLength, false, L, B, workspace);

            // B = L^-T * B
            // todo could speed up by taking advantage of B being lower triangular
            // todo take advantage of symmetry
            TriangularSolver_DDRB.solveL(blockLength, L, B, true);
        }
Exemple #3
0
        /**
         * Sanity checks the input or declares a new matrix. Return matrix is an identity matrix.
         */
        public static DMatrixRBlock initializeQ(DMatrixRBlock Q,
                                                int numRows, int numCols, int blockLength,
                                                bool compact)
        {
            int minLength = Math.Min(numRows, numCols);

            if (compact)
            {
                if (Q == null)
                {
                    Q = new DMatrixRBlock(numRows, minLength, blockLength);
                    MatrixOps_DDRB.setIdentity(Q);
                }
                else
                {
                    if (Q.numRows != numRows || Q.numCols != minLength)
                    {
                        throw new ArgumentException("Unexpected matrix dimension. Found " + Q.numRows + " " + Q.numCols);
                    }
                    else
                    {
                        MatrixOps_DDRB.setIdentity(Q);
                    }
                }
            }
            else
            {
                if (Q == null)
                {
                    Q = new DMatrixRBlock(numRows, numRows, blockLength);
                    MatrixOps_DDRB.setIdentity(Q);
                }
                else
                {
                    if (Q.numRows != numRows || Q.numCols != numRows)
                    {
                        throw new ArgumentException("Unexpected matrix dimension. Found " + Q.numRows + " " + Q.numCols);
                    }
                    else
                    {
                        MatrixOps_DDRB.setIdentity(Q);
                    }
                }
            }
            return(Q);
        }
        private bool decomposeUpper()
        {
            int blockLength = T.blockLength;

            subA.set(T);
            subB.set(T);
            subC.set(T);

            for (int i = 0; i < T.numCols; i += blockLength)
            {
                int widthA = Math.Min(blockLength, T.numCols - i);

                //@formatter:off
                subA.col0 = i; subA.col1 = i + widthA;
                subA.row0 = subA.col0; subA.row1 = subA.col1;

                subB.col0 = i + widthA; subB.col1 = T.numCols;
                subB.row0 = i; subB.row1 = i + widthA;

                subC.col0 = i + widthA; subC.col1 = T.numCols;
                subC.row0 = i + widthA; subC.row1 = T.numCols;
                //@formatter:on

                // cholesky on inner block A
                if (!InnerCholesky_DDRB.upper(subA))
                {
                    return(false);
                }

                // on the last block these operations are not needed.
                if (widthA == blockLength)
                {
                    // B = U^-1 B
                    TriangularSolver_DDRB.solveBlock(blockLength, true, subA, subB, true, false);

                    // C = C - B^T * B
                    InnerRankUpdate_DDRB.symmRankNMinus_U(blockLength, subC, subB);
                }
            }

            MatrixOps_DDRB.zeroTriangle(false, T);

            return(true);
        }
Exemple #5
0
        public static void checkShapeMult(int blockLength,
                                          DSubmatrixD1 A, DSubmatrixD1 B,
                                          DSubmatrixD1 C)
        {
            //@formatter:off
            int Arow = A.Rows; int Acol = A.Cols;
            int Brow = B.Rows; int Bcol = B.Cols;
            int Crow = C.Rows; int Ccol = C.Cols;

            //@formatter:on

            if (Arow != Crow)
            {
                throw new SystemException("Mismatch A and C rows");
            }
            if (Bcol != Ccol)
            {
                throw new SystemException("Mismatch B and C columns");
            }
            if (Acol != Brow)
            {
                throw new SystemException("Mismatch A columns and B rows");
            }

            if (!MatrixOps_DDRB.blockAligned(blockLength, A))
            {
                throw new SystemException("Sub-Matrix A is not block aligned");
            }

            if (!MatrixOps_DDRB.blockAligned(blockLength, B))
            {
                throw new SystemException("Sub-Matrix B is not block aligned");
            }

            if (!MatrixOps_DDRB.blockAligned(blockLength, C))
            {
                throw new SystemException("Sub-Matrix C is not block aligned");
            }
        }
Exemple #6
0
        /**
         * <p>
         * Performs a matrix multiplication on {@link DMatrixRBlock} submatrices.<br>
         * <br>
         * 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 mult(int blockLength,
                                DSubmatrixD1 A, DSubmatrixD1 B,
                                DSubmatrixD1 C)
        {
            MatrixOps_DDRB.checkShapeMult(blockLength, A, B, C);

            //CONCURRENT_BELOW EjmlConcurrency.loopFor(A.row0,A.row1,blockLength,i->{
            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;

                        if (k == A.col0)
                        {
                            InnerMultiplication_DDRB.blockMultSet(A.original.data, B.original.data, C.original.data,
                                                                  indexA, indexB, indexC, heightA, widthA, widthB);
                        }
                        else
                        {
                            InnerMultiplication_DDRB.blockMultPlus(A.original.data, B.original.data, C.original.data,
                                                                   indexA, indexB, indexC, heightA, widthA, widthB);
                        }
                    }
                }
            }
            //CONCURRENT_ABOVE });
        }