Ejemplo n.º 1
0
        public void solve(DMatrixRBlock B, DMatrixRBlock X)
        {
            if (B.numRows != QR.numRows)
            {
                throw new ArgumentException("Row of B and A do not match");
            }

            X.reshape(QR.numCols, B.numCols);

            // The system being solved for can be described as:
            // Q*R*X = B

            // First apply householder reflectors to B
            // Y = Q^T*B
            //decomposer.applyQTran(B);

            // Second solve for Y using the upper triangle matrix R and the just computed Y
            // X = R^-1 * Y
            MatrixOps_DDRB.extractAligned(B, X);

            // extract a block aligned matrix
            int M = Math.Min(QR.numRows, QR.numCols);

            TriangularSolver_DDRB.solve(QR.blockLength, true,
                                        new DSubmatrixD1(QR, 0, M, 0, M), new DSubmatrixD1(X), false);
        }
        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);
        }
        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);
            }
        }
        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);
        }