Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
LinearEquationSolver.cpp
Go to the documentation of this file.
2
16
17namespace storm {
18namespace solver {
19
20template<typename ValueType>
22 // Intentionally left empty.
23}
24
25template<typename ValueType>
26bool LinearEquationSolver<ValueType>::solveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const {
27 // A reused solver must not report bounds that a previous call computed.
28 this->clearSolutionBounds();
29 bool const result = this->internalSolveEquations(env, x, b);
30 if (result) {
32 }
33 return result;
34}
35
36template<typename ValueType>
40
41template<typename ValueType>
43 if (cachingEnabled && !value) {
44 // caching will be turned off. Hence we clear the cache at this point
45 clearCache();
46 }
47 cachingEnabled = value;
48}
49
50template<typename ValueType>
52 return cachingEnabled;
53}
54
55template<typename ValueType>
59
60template<typename ValueType>
61std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env,
62 storm::storage::SparseMatrix<ValueType> const& matrix) const {
63 std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env);
64 solver->setMatrix(matrix);
65 return solver;
66}
67
68template<typename ValueType>
69std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env,
71 std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env);
72 solver->setMatrix(std::move(matrix));
73 return solver;
74}
75
76template<typename ValueType>
78 return this->create(env)->getEquationProblemFormat(env);
79}
80
81template<typename ValueType>
83 return this->create(env)->getRequirements(env);
84}
85
86template<typename ValueType>
90
91template<>
92std::unique_ptr<LinearEquationSolver<storm::RationalNumber>> GeneralLinearEquationSolverFactory<storm::RationalNumber>::create(Environment const& env) const {
93 EquationSolverType type = env.solver().getLinearEquationSolverType();
94
95 // Adjust the solver type if it is not supported by this value type
96 if (type != EquationSolverType::Eigen && type != EquationSolverType::Topological && type != EquationSolverType::Acyclic &&
97 (env.solver().isLinearEquationSolverTypeSetFromDefaultValue() || type == EquationSolverType::Gmmxx)) {
98 STORM_LOG_INFO("Selecting '" + toString(EquationSolverType::Eigen) + "' as the linear equation solver since the previously selected one ("
99 << toString(type) << ") does not support exact computations.");
100 type = EquationSolverType::Eigen;
101 }
102
103 std::unique_ptr<LinearEquationSolver<storm::RationalNumber>> result;
104 switch (type) {
105 case EquationSolverType::Native:
106 result = std::make_unique<NativeLinearEquationSolver<storm::RationalNumber>>();
107 break;
108 case EquationSolverType::Eigen:
109 result = std::make_unique<EigenLinearEquationSolver<storm::RationalNumber>>();
110 break;
111 case EquationSolverType::Elimination:
112 result = std::make_unique<EliminationLinearEquationSolver<storm::RationalNumber>>();
113 break;
114 case EquationSolverType::Topological:
115 result = std::make_unique<TopologicalLinearEquationSolver<storm::RationalNumber>>();
116 break;
117 case EquationSolverType::Acyclic:
118 result = std::make_unique<AcyclicLinearEquationSolver<storm::RationalNumber>>();
119 break;
120 default:
121 STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type.");
122 return nullptr;
123 }
124 result->setShowProgress(env.solver().isVerboseSet(), env.solver().getShowProgressDelay());
125 return result;
126}
127
128template<>
129std::unique_ptr<LinearEquationSolver<storm::RationalFunction>> GeneralLinearEquationSolverFactory<storm::RationalFunction>::create(
130 Environment const& env) const {
131 EquationSolverType type = env.solver().getLinearEquationSolverType();
132
133 // Adjust the solver type if it is not supported by this value type
134 if (type == EquationSolverType::Gmmxx || type == EquationSolverType::Native) {
136 STORM_LOG_INFO("Selecting '" + toString(EquationSolverType::Eigen) + "' as the linear equation solver since the previously selected one ("
137 << toString(type) << ") does not support parametric computations.");
138 } else {
139 // Be more verbose if the user set the solver explicitly
140 STORM_LOG_WARN("The selected linear equation solver (" << toString(type) << ") does not support parametric computations. Falling back to "
141 << toString(EquationSolverType::Eigen) << ".");
142 }
143 type = EquationSolverType::Eigen;
144 }
145
146 std::unique_ptr<LinearEquationSolver<storm::RationalFunction>> result;
147 switch (type) {
148 case EquationSolverType::Eigen:
149 result = std::make_unique<EigenLinearEquationSolver<storm::RationalFunction>>();
150 break;
151 case EquationSolverType::Elimination:
152 result = std::make_unique<EliminationLinearEquationSolver<storm::RationalFunction>>();
153 break;
154 case EquationSolverType::Topological:
155 result = std::make_unique<TopologicalLinearEquationSolver<storm::RationalFunction>>();
156 break;
157 case EquationSolverType::Acyclic:
158 result = std::make_unique<AcyclicLinearEquationSolver<storm::RationalFunction>>();
159 break;
160 default:
161 STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type.");
162 return nullptr;
163 }
164 result->setShowProgress(env.solver().isVerboseSet(), env.solver().getShowProgressDelay());
165 return result;
166}
167
168template<typename ValueType>
169std::unique_ptr<LinearEquationSolver<ValueType>> GeneralLinearEquationSolverFactory<ValueType>::create(Environment const& env) const {
170 EquationSolverType type = env.solver().getLinearEquationSolverType();
171
172 if constexpr (storm::IsIntervalType<ValueType>) {
173 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We have not implemented interval-based linear equation solvers.");
174 }
175
176 // Adjust the solver type if none was specified and we want sound/exact computations
177 if (env.solver().isForceExact() && type != EquationSolverType::Native && type != EquationSolverType::Eigen && type != EquationSolverType::Elimination &&
178 type != EquationSolverType::Topological && type != EquationSolverType::Acyclic) {
180 type = EquationSolverType::Eigen;
182 "Selecting '" + toString(type) +
183 "' as the linear equation solver to guarantee exact results. If you want to override this, please explicitly specify a different solver.");
184 } else {
185 STORM_LOG_WARN("The selected solver does not yield exact results.");
186 }
187 } else if (env.solver().isForceSoundness() && type != EquationSolverType::Native && type != EquationSolverType::Eigen &&
188 type != EquationSolverType::Elimination && type != EquationSolverType::Topological && type != EquationSolverType::Acyclic) {
190 type = EquationSolverType::Native;
192 "Selecting '" + toString(type) +
193 "' as the linear equation solver to guarantee sound results. If you want to override this, please explicitly specify a different solver.");
194 } else {
195 STORM_LOG_WARN("The selected solver does not yield sound results.");
196 }
197 }
198
199 std::unique_ptr<LinearEquationSolver<ValueType>> result;
200 switch (type) {
201 case EquationSolverType::Gmmxx:
202 result = std::make_unique<GmmxxLinearEquationSolver<ValueType>>();
203 break;
204 case EquationSolverType::Native:
205 result = std::make_unique<NativeLinearEquationSolver<ValueType>>();
206 break;
207 case EquationSolverType::Eigen:
208 result = std::make_unique<EigenLinearEquationSolver<ValueType>>();
209 break;
210 case EquationSolverType::Elimination:
211 result = std::make_unique<EliminationLinearEquationSolver<ValueType>>();
212 break;
213 case EquationSolverType::Topological:
214 result = std::make_unique<TopologicalLinearEquationSolver<ValueType>>();
215 break;
216 case EquationSolverType::Acyclic:
217 result = std::make_unique<AcyclicLinearEquationSolver<ValueType>>();
218 break;
219 default:
220 STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type.");
221 return nullptr;
222 }
223 result->setShowProgress(env.solver().isVerboseSet(), env.solver().getShowProgressDelay());
224 return result;
225}
226
227template<typename ValueType>
228std::unique_ptr<LinearEquationSolverFactory<ValueType>> GeneralLinearEquationSolverFactory<ValueType>::clone() const {
229 return std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>(*this);
230}
231
232template class LinearEquationSolver<double>;
235
239
243
244} // namespace solver
245} // namespace storm
SolverEnvironment & solver()
storm::solver::EquationSolverType const & getLinearEquationSolverType() const
bool isLinearEquationSolverTypeSetFromDefaultValue() const
uint64_t getShowProgressDelay() const
void finalizeSolutionBounds(std::vector< ValueType > const &x) const
virtual std::unique_ptr< LinearEquationSolver< ValueType > > create(Environment const &env) const override
Creates an equation solver with the current settings, but without a matrix.
virtual std::unique_ptr< LinearEquationSolverFactory< ValueType > > clone() const override
Creates a copy of this factory.
std::unique_ptr< LinearEquationSolver< ValueType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix) const
Creates a new linear equation solver instance with the given matrix.
LinearEquationSolverRequirements getRequirements(Environment const &env) const
Retrieves the requirements of the solver if it was created with the current settings.
virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const &env) const
Retrieves the problem format that the solver expects if it was created with the current settings.
An interface that represents an abstract linear equation solver.
void setCachingEnabled(bool value) const
Sets whether some of the generated data during solver calls should be cached.
bool solveEquations(Environment const &env, std::vector< ValueType > &x, std::vector< ValueType > const &b) const
If the solver expects the equation system format, it solves Ax = b.
bool isCachingEnabled() const
Retrieves whether some of the generated data during solver calls should be cached.
virtual bool internalSolveEquations(Environment const &env, std::vector< ValueType > &x, std::vector< ValueType > const &b) const =0
std::unique_ptr< std::vector< ValueType > > cachedRowVector
virtual LinearEquationSolverRequirements getRequirements(Environment const &env) const
Retrieves the requirements of the solver under the current settings.
A class that holds a possibly non-square matrix in the compressed row storage format.
#define STORM_LOG_INFO(message)
Definition logging.h:34
#define STORM_LOG_WARN(message)
Definition logging.h:35
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
std::string toString(GurobiSolverMethod const &method)
Yields a string representation of the GurobiSolverMethod.
constexpr bool IsIntervalType
Helper to check if a type is an interval.