#ifndef STORM_SOLVER_GMMXXLINEAREQUATIONSOLVER_H_ #define STORM_SOLVER_GMMXXLINEAREQUATIONSOLVER_H_ #include #include "src/utility/gmm.h" #include "LinearEquationSolver.h" namespace storm { namespace solver { template class GmmxxLinearEquationSolverSettings { public: // An enumeration specifying the available preconditioners. enum class Preconditioner { Ilu, Diagonal, None }; friend std::ostream& operator<<(std::ostream& out, Preconditioner const& preconditioner) { switch (preconditioner) { case GmmxxLinearEquationSolverSettings::Preconditioner::Ilu: out << "ilu"; break; case GmmxxLinearEquationSolverSettings::Preconditioner::Diagonal: out << "diagonal"; break; case GmmxxLinearEquationSolverSettings::Preconditioner::None: out << "none"; break; } return out; } // An enumeration specifying the available solution methods. enum class SolutionMethod { Bicgstab, Qmr, Gmres, Jacobi }; friend std::ostream& operator<<(std::ostream& out, SolutionMethod const& method) { switch (method) { case GmmxxLinearEquationSolverSettings::SolutionMethod::Bicgstab: out << "BiCGSTAB"; break; case GmmxxLinearEquationSolverSettings::SolutionMethod::Qmr: out << "QMR"; break; case GmmxxLinearEquationSolverSettings::SolutionMethod::Gmres: out << "GMRES"; break; case GmmxxLinearEquationSolverSettings::SolutionMethod::Jacobi: out << "Jacobi"; break; } return out; } GmmxxLinearEquationSolverSettings(); void setSolutionMethod(SolutionMethod const& method); void setPreconditioner(Preconditioner const& preconditioner); void setPrecision(ValueType precision); void setMaximalNumberOfIterations(uint64_t maximalNumberOfIterations); void setRelativeTerminationCriterion(bool value); void setNumberOfIterationsUntilRestart(uint64_t restart); SolutionMethod getSolutionMethod() const; Preconditioner getPreconditioner() const; ValueType getPrecision() const; uint64_t getMaximalNumberOfIterations() const; bool getRelativeTerminationCriterion() const; uint64_t getNumberOfIterationsUntilRestart() const; private: // The method to use for solving linear equation systems. SolutionMethod method; // The required precision for the iterative methods. double precision; // The maximal number of iterations to do before iteration is aborted. uint_fast64_t maximalNumberOfIterations; // The preconditioner to use when solving the linear equation system. Preconditioner preconditioner; // Sets whether the relative or absolute error is to be considered for convergence detection. Note that this // only applies to the Jacobi method for this solver. bool relative; // A restart value that determines when restarted methods shall do so. uint_fast64_t restart; }; /*! * A class that uses the gmm++ library to implement the LinearEquationSolver interface. */ template class GmmxxLinearEquationSolver : public LinearEquationSolver { public: GmmxxLinearEquationSolver(storm::storage::SparseMatrix const& A, GmmxxLinearEquationSolverSettings const& settings = GmmxxLinearEquationSolverSettings()); GmmxxLinearEquationSolver(storm::storage::SparseMatrix&& A, GmmxxLinearEquationSolverSettings const& settings = GmmxxLinearEquationSolverSettings()); virtual void setMatrix(storm::storage::SparseMatrix const& A) override; virtual void setMatrix(storm::storage::SparseMatrix&& A) override; virtual void solveEquations(std::vector& x, std::vector const& b) const override; virtual void multiply(std::vector& x, std::vector const* b, std::vector& result) const override; GmmxxLinearEquationSolverSettings& getSettings(); GmmxxLinearEquationSolverSettings const& getSettings() const; virtual bool allocateAuxMemory(LinearEquationSolverOperation operation) const override; virtual bool deallocateAuxMemory(LinearEquationSolverOperation operation) const override; virtual bool reallocateAuxMemory(LinearEquationSolverOperation operation) const override; virtual bool hasAuxMemory(LinearEquationSolverOperation operation) const override; private: /*! * Solves the linear equation system A*x = b given by the parameters using the Jacobi method. * * @param A The matrix specifying the coefficients of the linear equations. * @param x The solution vector x. The initial values of x represent a guess of the real values to the * solver, but may be set to zero. * @param b The right-hand side of the equation system. * @return The number of iterations needed until convergence if the solver converged and * maximalNumberOfIteration otherwise. * @param multiplyResult If non-null, this memory is used as a scratch memory. If given, the length of this * vector must be equal to the number of rows of A. */ uint_fast64_t solveLinearEquationSystemWithJacobi(storm::storage::SparseMatrix const& A, std::vector& x, std::vector const& b) const; virtual uint64_t getMatrixRowCount() const override; virtual uint64_t getMatrixColumnCount() const override; // If the solver takes posession of the matrix, we store the moved matrix in this member, so it gets deleted // when the solver is destructed. std::unique_ptr> localA; // A pointer to the original sparse matrix given to this solver. If the solver takes posession of the matrix // the pointer refers to localA. storm::storage::SparseMatrix const* A; // The (gmm++) matrix associated with this equation solver. std::unique_ptr> gmmxxMatrix; // The settings used by the solver. GmmxxLinearEquationSolverSettings settings; // Auxiliary storage for the Jacobi method. mutable std::unique_ptr> auxiliaryJacobiMemory; }; template class GmmxxLinearEquationSolverFactory : public LinearEquationSolverFactory { public: virtual std::unique_ptr> create(storm::storage::SparseMatrix const& matrix) const override; virtual std::unique_ptr> create(storm::storage::SparseMatrix&& matrix) const override; GmmxxLinearEquationSolverSettings& getSettings(); GmmxxLinearEquationSolverSettings const& getSettings() const; virtual std::unique_ptr> clone() const override; private: GmmxxLinearEquationSolverSettings settings; }; } // namespace solver } // namespace storm #endif /* STORM_SOLVER_GMMXXLINEAREQUATIONSOLVER_H_ */