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