Example #1
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);
        }
        public virtual /**/ double quality()
        {
            return(SpecializedOps_DDRM.qualityTriangular(decomposer.getQR()));
        }

        public virtual void solve(DMatrixRBlock B, DMatrixRBlock X)
        {
            if (B.numCols != X.numCols)
            {
                throw new ArgumentException("Columns of B and X do not match");
            }
            if (QR.numCols != X.numRows)
            {
                throw new ArgumentException("Rows in X do not match the columns in A");
            }
            if (QR.numRows != B.numRows)
            {
                throw new ArgumentException("Rows in B do not match the rows in A.");
            }
            if (B.blockLength != QR.blockLength || X.blockLength != QR.blockLength)
            {
                throw new ArgumentException("All matrices must have the same block length.");
            }

            // 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);
        }

        /**
         * Invert by solving for against an identity matrix.
         *
         * @param A_inv Where the inverted matrix saved. Modified.
         */
        public virtual void invert(DMatrixRBlock A_inv)
        {
            int M = Math.Min(QR.numRows, QR.numCols);

            if (A_inv.numRows != M || A_inv.numCols != M)
            {
                throw new ArgumentException("A_inv must be square an have dimension " + M);
            }


            // Solve for A^-1
            // Q*R*A^-1 = I

            // Apply householder reflectors to the identity matrix
            // y = Q^T*I = Q^T
            MatrixOps_DDRB.setIdentity(A_inv);
            decomposer.applyQTran(A_inv);

            // Solve using upper triangular R matrix
            // R*A^-1 = y
            // A^-1 = R^-1*y
            TriangularSolver_DDRB.solve(QR.blockLength, true,
                                        new DSubmatrixD1(QR, 0, M, 0, M), new DSubmatrixD1(A_inv), false);
        }