#include #include "storm/solver/LinearEquationSolver.h" #include "storm/solver/SolverSelectionOptions.h" #include "storm/solver/GmmxxLinearEquationSolver.h" #include "storm/solver/NativeLinearEquationSolver.h" #include "storm/solver/EigenLinearEquationSolver.h" #include "storm/solver/EliminationLinearEquationSolver.h" #include "storm/solver/TopologicalLinearEquationSolver.h" #include "storm/utility/vector.h" #include "storm/environment/solver/SolverEnvironment.h" #include "storm/utility/macros.h" #include "storm/exceptions/NotSupportedException.h" #include "storm/exceptions/UnmetRequirementException.h" namespace storm { namespace solver { template LinearEquationSolver::LinearEquationSolver() : cachingEnabled(false) { // Intentionally left empty. } template bool LinearEquationSolver::solveEquations(Environment const& env, std::vector& x, std::vector const& b) const { return this->internalSolveEquations(env, x, b); } template LinearEquationSolverRequirements LinearEquationSolver::getRequirements(Environment const& env) const { return LinearEquationSolverRequirements(); } template void LinearEquationSolver::setCachingEnabled(bool value) const { if(cachingEnabled && !value) { // caching will be turned off. Hence we clear the cache at this point clearCache(); } cachingEnabled = value; } template bool LinearEquationSolver::isCachingEnabled() const { return cachingEnabled; } template void LinearEquationSolver::clearCache() const { cachedRowVector.reset(); } template std::unique_ptr> LinearEquationSolverFactory::create(Environment const& env, storm::storage::SparseMatrix const& matrix) const { std::unique_ptr> solver = this->create(env); solver->setMatrix(matrix); return solver; } template std::unique_ptr> LinearEquationSolverFactory::create(Environment const& env, storm::storage::SparseMatrix&& matrix) const { std::unique_ptr> solver = this->create(env); solver->setMatrix(std::move(matrix)); return solver; } template LinearEquationSolverProblemFormat LinearEquationSolverFactory::getEquationProblemFormat(Environment const& env) const { return this->create(env)->getEquationProblemFormat(env); } template LinearEquationSolverRequirements LinearEquationSolverFactory::getRequirements(Environment const& env) const { return this->create(env)->getRequirements(env); } template GeneralLinearEquationSolverFactory::GeneralLinearEquationSolverFactory() { // Intentionally left empty. } template<> std::unique_ptr> GeneralLinearEquationSolverFactory::create(Environment const& env) const { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if it is not supported by this value type if (type == EquationSolverType::Gmmxx) { type = EquationSolverType::Eigen; STORM_LOG_INFO("Selecting '" + toString(type) + "' as the linear equation solver since the selected one does not support exact computations."); } switch (type) { case EquationSolverType::Native: return std::make_unique>(); case EquationSolverType::Eigen: return std::make_unique>(); case EquationSolverType::Elimination: return std::make_unique>(); case EquationSolverType::Topological: return std::make_unique>(); default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type."); return nullptr; } } template<> std::unique_ptr> GeneralLinearEquationSolverFactory::create(Environment const& env) const { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if it is not supported by this value type if (type == EquationSolverType::Gmmxx || type == EquationSolverType::Native) { type = EquationSolverType::Eigen; STORM_LOG_INFO("Selecting '" + toString(type) + "' as the linear equation solver since the selected one does not support parametric computations."); } switch (type) { case EquationSolverType::Eigen: return std::make_unique>(); case EquationSolverType::Elimination: return std::make_unique>(); case EquationSolverType::Topological: return std::make_unique>(); default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type."); return nullptr; } } template std::unique_ptr> GeneralLinearEquationSolverFactory::create(Environment const& env) const { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if none was specified and we want sound computations if (env.solver().isForceSoundness() && type != EquationSolverType::Native && type != EquationSolverType::Eigen && type != EquationSolverType::Elimination && type != EquationSolverType::Topological) { if (env.solver().isLinearEquationSolverTypeSetFromDefaultValue()) { type = EquationSolverType::Native; STORM_LOG_INFO("Selecting '" + toString(type) + "' as the linear equation solver to guarantee sound results. If you want to override this, please explicitly specify a different solver."); } else { STORM_LOG_WARN("The selected solver does not yield sound results."); } } switch (type) { case EquationSolverType::Gmmxx: return std::make_unique>(); case EquationSolverType::Native: return std::make_unique>(); case EquationSolverType::Eigen: return std::make_unique>(); case EquationSolverType::Elimination: return std::make_unique>(); case EquationSolverType::Topological: return std::make_unique>(); default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type."); return nullptr; } } template std::unique_ptr> GeneralLinearEquationSolverFactory::clone() const { return std::make_unique>(*this); } template class LinearEquationSolver; template class LinearEquationSolverFactory; template class GeneralLinearEquationSolverFactory; template class LinearEquationSolver; template class LinearEquationSolverFactory; template class GeneralLinearEquationSolverFactory; template class LinearEquationSolver; template class LinearEquationSolverFactory; template class GeneralLinearEquationSolverFactory; } }