#pragma once #include "storm/solver/SymbolicLinearEquationSolver.h" #include "storm/solver/SolverStatus.h" #include "storm/utility/NumberTraits.h" namespace storm { namespace solver { template class SymbolicNativeLinearEquationSolverSettings { public: enum class SolutionMethod { Jacobi, Power, RationalSearch }; SymbolicNativeLinearEquationSolverSettings(); void setPrecision(ValueType precision); void setMaximalNumberOfIterations(uint64_t maximalNumberOfIterations); void setRelativeTerminationCriterion(bool value); void setSolutionMethod(SolutionMethod const& method); ValueType getPrecision() const; uint64_t getMaximalNumberOfIterations() const; bool getRelativeTerminationCriterion() const; SolutionMethod getSolutionMethod() const; private: // The selected solution method. SolutionMethod method; // The required precision for the iterative methods. ValueType precision; // The maximal number of iterations to do before iteration is aborted. uint_fast64_t maximalNumberOfIterations; // 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; }; /*! * An interface that represents an abstract symbolic linear equation solver. In addition to solving a system of * linear equations, the functionality to repeatedly multiply a matrix with a given vector is provided. */ template class SymbolicNativeLinearEquationSolver : public SymbolicLinearEquationSolver { public: /*! * Constructs a symbolic linear equation solver. * * @param settings The settings to use. */ SymbolicNativeLinearEquationSolver(SymbolicNativeLinearEquationSolverSettings const& settings = SymbolicNativeLinearEquationSolverSettings()); /*! * Constructs a symbolic linear equation solver with the given meta variable sets and pairs. * * @param A The matrix defining the coefficients of the linear equation system. * @param diagonal An ADD characterizing the elements on the diagonal of the matrix. * @param allRows A BDD characterizing all rows of the equation system. * @param rowMetaVariables The meta variables used to encode the rows of the matrix. * @param columnMetaVariables The meta variables used to encode the columns of the matrix. * @param rowColumnMetaVariablePairs The pairs of row meta variables and the corresponding column meta * variables. * @param settings The settings to use. */ SymbolicNativeLinearEquationSolver(storm::dd::Add const& A, storm::dd::Bdd const& allRows, std::set const& rowMetaVariables, std::set const& columnMetaVariables, std::vector> const& rowColumnMetaVariablePairs, SymbolicNativeLinearEquationSolverSettings const& settings = SymbolicNativeLinearEquationSolverSettings()); /*! * Constructs a symbolic linear equation solver with the given meta variable sets and pairs. * * @param diagonal An ADD characterizing the elements on the diagonal of the matrix. * @param allRows A BDD characterizing all rows of the equation system. * @param rowMetaVariables The meta variables used to encode the rows of the matrix. * @param columnMetaVariables The meta variables used to encode the columns of the matrix. * @param rowColumnMetaVariablePairs The pairs of row meta variables and the corresponding column meta * variables. * @param settings The settings to use. */ SymbolicNativeLinearEquationSolver(storm::dd::Bdd const& allRows, std::set const& rowMetaVariables, std::set const& columnMetaVariables, std::vector> const& rowColumnMetaVariablePairs, SymbolicNativeLinearEquationSolverSettings const& settings = SymbolicNativeLinearEquationSolverSettings()); /*! * Solves the equation system A*x = b. The matrix A is required to be square and have a unique solution. * The solution of the set of linear equations will be written to the vector x. Note that the matrix A has * to be given upon construction time of the solver object. * * @param x The initial guess for the solution vector. Its length must be equal to the number of rows of A. * @param b The right-hand side of the equation system. Its length must be equal to the number of rows of A. * @return The solution of the equation system. */ virtual storm::dd::Add solveEquations(storm::dd::Add const& x, storm::dd::Add const& b) const override; virtual LinearEquationSolverProblemFormat getEquationProblemFormat() const override; virtual LinearEquationSolverRequirements getRequirements() const override; SymbolicNativeLinearEquationSolverSettings const& getSettings() const; private: storm::dd::Add solveEquationsJacobi(storm::dd::Add const& x, storm::dd::Add const& b) const; storm::dd::Add solveEquationsPower(storm::dd::Add const& x, storm::dd::Add const& b) const; storm::dd::Add solveEquationsRationalSearch(storm::dd::Add const& x, storm::dd::Add const& b) const; /*! * Determines whether the given vector x satisfies x = Ax + b. */ bool isSolutionFixedPoint(storm::dd::Add const& x, storm::dd::Add const& b) const; template static storm::dd::Add sharpen(uint64_t precision, SymbolicNativeLinearEquationSolver const& rationalSolver, storm::dd::Add const& x, storm::dd::Add const& rationalB, bool& isSolution); template storm::dd::Add solveEquationsRationalSearchHelper(SymbolicNativeLinearEquationSolver const& rationalSolver, SymbolicNativeLinearEquationSolver const& impreciseSolver, storm::dd::Add const& rationalB, storm::dd::Add const& x, storm::dd::Add const& b) const; template typename std::enable_if::value && storm::NumberTraits::IsExact, storm::dd::Add>::type solveEquationsRationalSearchHelper(storm::dd::Add const& x, storm::dd::Add const& b) const; template typename std::enable_if::value && !storm::NumberTraits::IsExact, storm::dd::Add>::type solveEquationsRationalSearchHelper(storm::dd::Add const& x, storm::dd::Add const& b) const; template typename std::enable_if::value, storm::dd::Add>::type solveEquationsRationalSearchHelper(storm::dd::Add const& x, storm::dd::Add const& b) const; template friend class SymbolicNativeLinearEquationSolver; struct PowerIterationResult { PowerIterationResult(SolverStatus status, uint64_t iterations, storm::dd::Add const& values) : status(status), iterations(iterations), values(values) { // Intentionally left empty. } SolverStatus status; uint64_t iterations; storm::dd::Add values; }; PowerIterationResult performPowerIteration(storm::dd::Add const& x, storm::dd::Add const& b, ValueType const& precision, bool relativeTerminationCriterion, uint64_t maximalIterations) const; // The settings to use. SymbolicNativeLinearEquationSolverSettings settings; }; template class SymbolicNativeLinearEquationSolverFactory : SymbolicLinearEquationSolverFactory { public: using SymbolicLinearEquationSolverFactory::create; virtual std::unique_ptr> create() const override; SymbolicNativeLinearEquationSolverSettings& getSettings(); SymbolicNativeLinearEquationSolverSettings const& getSettings() const; private: SymbolicNativeLinearEquationSolverSettings settings; }; } // namespace solver } // namespace storm