Beispiel #1
0
        /**
         * <p>
         * Performs a matrix inversion operation that does not modify the original
         * and stores the results in another matrix.  The two matrices must have the
         * same dimension.<br>
         * <br>
         * B = A<sup>-1</sup>
         * </p>
         *
         * <p>
         * If the algorithm could not invert the matrix then false is returned.  If it returns true
         * that just means the algorithm finished.  The results could still be bad
         * because the matrix is singular or nearly singular.
         * </p>
         *
         * <p>
         * For medium to large matrices there might be a slight performance boost to using
         * {@link LinearSolverFactory_DSCC} instead.
         * </p>
         *
         * @param A (Input) The matrix that is to be inverted. Not modified.
         * @param inverse (Output) Where the inverse matrix is stored.  Modified.
         * @return true if it could invert the matrix false if it could not.
         */
        public static bool invert(DMatrixSparseCSC A, DMatrixRMaj inverse)
        {
            if (A.numRows != A.numCols)
            {
                throw new ArgumentException("A must be a square matrix");
            }
            if (A.numRows != inverse.numRows || A.numCols != inverse.numCols)
            {
                throw new ArgumentException("A and inverse must have the same shape.");
            }

            LinearSolverSparse <DMatrixSparseCSC, DMatrixRMaj> solver;

            solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE);

            // Ensure that the input isn't modified
            if (solver.modifiesA())
            {
                A = (DMatrixSparseCSC)A.copy();
            }

            DMatrixRMaj I = CommonOps_DDRM.identity(A.numRows);

            // decompose then solve the matrix
            if (!solver.setA(A))
            {
                return(false);
            }

            solver.solve(I, inverse);
            return(true);
        }
Beispiel #2
0
        /**
         * <p>
         * Solves for x in the following equation:<br>
         * <br>
         * A*x = b
         * </p>
         *
         * <p>
         * If the system could not be solved then false is returned.  If it returns true
         * that just means the algorithm finished operating, but the results could still be bad
         * because 'A' is singular or nearly singular.
         * </p>
         *
         * <p>
         * If repeat calls to solve are being made then one should consider using {@link LinearSolverFactory_DSCC}
         * instead.
         * </p>
         *
         * <p>
         * It is ok for 'b' and 'x' to be the same matrix.
         * </p>
         *
         * @param a (Input) A matrix that is m by n. Not modified.
         * @param b (Input) A matrix that is n by k. Not modified.
         * @param x (Output) A matrix that is m by k. Modified.
         *
         * @return true if it could invert the matrix false if it could not.
         */
        public static bool solve(DMatrixSparseCSC a,
                                 DMatrixRMaj b,
                                 DMatrixRMaj x)
        {
            LinearSolverSparse <DMatrixSparseCSC, DMatrixRMaj> solver;

            if (a.numRows > a.numCols)
            {
                solver = LinearSolverFactory_DSCC.qr(FillReducing.NONE); // todo specify a filling that makes sense
            }
            else
            {
                solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE);
            }

            // Ensure that the input isn't modified
            if (solver.modifiesA())
            {
                a = (DMatrixSparseCSC)a.copy();
            }

            if (solver.modifiesB())
            {
                b = (DMatrixRMaj)b.copy();
            }

            // decompose then solve the matrix
            if (!solver.setA(a))
            {
                return(false);
            }

            solver.solve(b, x);
            return(true);
        }