#ifndef STORM_SOLVER_NATIVELINEAREQUATIONSOLVER_H_ #define STORM_SOLVER_NATIVELINEAREQUATIONSOLVER_H_ #include #include "storm/solver/LinearEquationSolver.h" #include "storm/solver/SolverSelectionOptions.h" #include "storm/solver/NativeMultiplier.h" #include "storm/solver/SolverStatus.h" #include "storm/solver/helper/SoundValueIterationHelper.h" #include "storm/utility/NumberTraits.h" namespace storm { class Environment; namespace solver { /*! * A class that uses storm's native matrix operations to implement the LinearEquationSolver interface. */ template class NativeLinearEquationSolver : public LinearEquationSolver { public: NativeLinearEquationSolver(); NativeLinearEquationSolver(storm::storage::SparseMatrix const& A); NativeLinearEquationSolver(storm::storage::SparseMatrix&& A); virtual void setMatrix(storm::storage::SparseMatrix const& A) override; virtual void setMatrix(storm::storage::SparseMatrix&& A) override; virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const& env) const override; virtual LinearEquationSolverRequirements getRequirements(Environment const& env) const override; virtual void clearCache() const override; protected: virtual bool internalSolveEquations(storm::Environment const& env, std::vector& x, std::vector const& b) const override; private: struct PowerIterationResult { PowerIterationResult(uint64_t iterations, SolverStatus status) : iterations(iterations), status(status) { // Intentionally left empty. } uint64_t iterations; SolverStatus status; }; template friend class NativeLinearEquationSolver; PowerIterationResult performPowerIteration(Environment const& env, std::vector*& currentX, std::vector*& newX, std::vector const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const; void logIterations(bool converged, bool terminate, uint64_t iterations) const; virtual uint64_t getMatrixRowCount() const override; virtual uint64_t getMatrixColumnCount() const override; NativeLinearEquationSolverMethod getMethod(Environment const& env, bool isExactMode) const; virtual bool solveEquationsSOR(storm::Environment const& env, std::vector& x, std::vector const& b, ValueType const& omega) const; virtual bool solveEquationsJacobi(storm::Environment const& env, std::vector& x, std::vector const& b) const; virtual bool solveEquationsWalkerChae(storm::Environment const& env, std::vector& x, std::vector const& b) const; virtual bool solveEquationsPower(storm::Environment const& env, std::vector& x, std::vector const& b) const; virtual bool solveEquationsSoundValueIteration(storm::Environment const& env, std::vector& x, std::vector const& b) const; virtual bool solveEquationsOptimisticValueIteration(storm::Environment const& env, std::vector& x, std::vector const& b) const; virtual bool solveEquationsIntervalIteration(storm::Environment const& env, std::vector& x, std::vector const& b) const; virtual bool solveEquationsRationalSearch(storm::Environment const& env, std::vector& x, std::vector const& b) const; template bool solveEquationsRationalSearchHelper(storm::Environment const& env, NativeLinearEquationSolver const& impreciseSolver, storm::storage::SparseMatrix const& rationalA, std::vector& rationalX, std::vector const& rationalB, storm::storage::SparseMatrix const& A, std::vector& x, std::vector const& b, std::vector& tmpX) const; template typename std::enable_if::value && !NumberTraits::IsExact, bool>::type solveEquationsRationalSearchHelper(storm::Environment const& env, std::vector& x, std::vector const& b) const; template typename std::enable_if::value && NumberTraits::IsExact, bool>::type solveEquationsRationalSearchHelper(storm::Environment const& env, std::vector& x, std::vector const& b) const; template typename std::enable_if::value, bool>::type solveEquationsRationalSearchHelper(storm::Environment const& env, std::vector& x, std::vector const& b) const; template static bool sharpen(uint64_t precision, storm::storage::SparseMatrix const& A, std::vector const& x, std::vector const& b, std::vector& tmp); static bool isSolution(storm::storage::SparseMatrix const& matrix, std::vector const& values, std::vector const& b); // 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; // An object to dispatch all multiplication operations. mutable std::unique_ptr> multiplier; // cached auxiliary data mutable std::unique_ptr> cachedRowVector2; // A.getRowCount() rows mutable std::unique_ptr> soundValueIterationHelper; struct JacobiDecomposition { JacobiDecomposition(Environment const& env, storm::storage::SparseMatrix const& A); storm::storage::SparseMatrix LUMatrix; std::vector DVector; std::unique_ptr> multiplier; }; mutable std::unique_ptr jacobiDecomposition; struct WalkerChaeData { WalkerChaeData(Environment const& env, storm::storage::SparseMatrix const& originalMatrix, std::vector const& originalB); void computeWalkerChaeMatrix(storm::storage::SparseMatrix const& originalMatrix); void computeNewB(std::vector const& originalB); void precomputeAuxiliaryData(); storm::storage::SparseMatrix matrix; std::vector b; ValueType t; std::unique_ptr> multiplier; // Auxiliary data. std::vector columnSums; std::vector newX; }; mutable std::unique_ptr walkerChaeData; }; template class NativeLinearEquationSolverFactory : public LinearEquationSolverFactory { public: using LinearEquationSolverFactory::create; virtual std::unique_ptr> create(Environment const& env) const override; virtual std::unique_ptr> clone() const override; }; } } #endif /* STORM_SOLVER_NATIVELINEAREQUATIONSOLVER_H_ */