Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
LinearEquationSolver.cpp
Go to the documentation of this file.
3
6
13
15
17
21
22namespace storm {
23namespace solver {
24
25template<typename ValueType>
27 // Intentionally left empty.
28}
29
30template<typename ValueType>
31bool LinearEquationSolver<ValueType>::solveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const {
32 return this->internalSolveEquations(env, x, b);
33}
34
35template<typename ValueType>
39
40template<typename ValueType>
42 if (cachingEnabled && !value) {
43 // caching will be turned off. Hence we clear the cache at this point
44 clearCache();
45 }
46 cachingEnabled = value;
47}
48
49template<typename ValueType>
51 return cachingEnabled;
52}
53
54template<typename ValueType>
56 cachedRowVector.reset();
57}
58
59template<typename ValueType>
60std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env,
61 storm::storage::SparseMatrix<ValueType> const& matrix) const {
62 std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env);
63 solver->setMatrix(matrix);
64 return solver;
65}
66
67template<typename ValueType>
68std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env,
70 std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env);
71 solver->setMatrix(std::move(matrix));
72 return solver;
73}
74
75template<typename ValueType>
77 return this->create(env)->getEquationProblemFormat(env);
78}
79
80template<typename ValueType>
82 return this->create(env)->getRequirements(env);
83}
84
85template<typename ValueType>
89
90template<>
91std::unique_ptr<LinearEquationSolver<storm::RationalNumber>> GeneralLinearEquationSolverFactory<storm::RationalNumber>::create(Environment const& env) const {
92 EquationSolverType type = env.solver().getLinearEquationSolverType();
93
94 // Adjust the solver type if it is not supported by this value type
95 if (type != EquationSolverType::Eigen && type != EquationSolverType::Topological && type != EquationSolverType::Acyclic &&
96 (env.solver().isLinearEquationSolverTypeSetFromDefaultValue() || type == EquationSolverType::Gmmxx)) {
97 STORM_LOG_INFO("Selecting '" + toString(EquationSolverType::Eigen) + "' as the linear equation solver since the previously selected one ("
98 << toString(type) << ") does not support exact computations.");
99 type = EquationSolverType::Eigen;
100 }
101
102 switch (type) {
103 case EquationSolverType::Native:
104 return std::make_unique<NativeLinearEquationSolver<storm::RationalNumber>>();
105 case EquationSolverType::Eigen:
106 return std::make_unique<EigenLinearEquationSolver<storm::RationalNumber>>();
107 case EquationSolverType::Elimination:
108 return std::make_unique<EliminationLinearEquationSolver<storm::RationalNumber>>();
109 case EquationSolverType::Topological:
110 return std::make_unique<TopologicalLinearEquationSolver<storm::RationalNumber>>();
111 case EquationSolverType::Acyclic:
112 return std::make_unique<AcyclicLinearEquationSolver<storm::RationalNumber>>();
113 default:
114 STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type.");
115 return nullptr;
116 }
117}
118
119template<>
120std::unique_ptr<LinearEquationSolver<storm::RationalFunction>> GeneralLinearEquationSolverFactory<storm::RationalFunction>::create(
121 Environment const& env) const {
122 EquationSolverType type = env.solver().getLinearEquationSolverType();
123
124 // Adjust the solver type if it is not supported by this value type
125 if (type == EquationSolverType::Gmmxx || type == EquationSolverType::Native) {
127 STORM_LOG_INFO("Selecting '" + toString(EquationSolverType::Eigen) + "' as the linear equation solver since the previously selected one ("
128 << toString(type) << ") does not support parametric computations.");
129 } else {
130 // Be more verbose if the user set the solver explicitly
131 STORM_LOG_WARN("The selected linear equation solver (" << toString(type) << ") does not support parametric computations. Falling back to "
132 << toString(EquationSolverType::Eigen) << ".");
133 }
134 type = EquationSolverType::Eigen;
135 }
136
137 switch (type) {
138 case EquationSolverType::Eigen:
139 return std::make_unique<EigenLinearEquationSolver<storm::RationalFunction>>();
140 case EquationSolverType::Elimination:
141 return std::make_unique<EliminationLinearEquationSolver<storm::RationalFunction>>();
142 case EquationSolverType::Topological:
143 return std::make_unique<TopologicalLinearEquationSolver<storm::RationalFunction>>();
144 case EquationSolverType::Acyclic:
145 return std::make_unique<AcyclicLinearEquationSolver<storm::RationalFunction>>();
146 default:
147 STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type.");
148 return nullptr;
149 }
150}
151
152template<typename ValueType>
153std::unique_ptr<LinearEquationSolver<ValueType>> GeneralLinearEquationSolverFactory<ValueType>::create(Environment const& env) const {
154 EquationSolverType type = env.solver().getLinearEquationSolverType();
155
156 if constexpr (std::is_same_v<ValueType, storm::Interval>) {
157 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We have not implemented interval-based linear equation solvers");
158 }
159
160 // Adjust the solver type if none was specified and we want sound/exact computations
161 if (env.solver().isForceExact() && type != EquationSolverType::Native && type != EquationSolverType::Eigen && type != EquationSolverType::Elimination &&
162 type != EquationSolverType::Topological && type != EquationSolverType::Acyclic) {
164 type = EquationSolverType::Eigen;
166 "Selecting '" + toString(type) +
167 "' as the linear equation solver to guarantee exact results. If you want to override this, please explicitly specify a different solver.");
168 } else {
169 STORM_LOG_WARN("The selected solver does not yield exact results.");
170 }
171 } else if (env.solver().isForceSoundness() && type != EquationSolverType::Native && type != EquationSolverType::Eigen &&
172 type != EquationSolverType::Elimination && type != EquationSolverType::Topological && type != EquationSolverType::Acyclic) {
174 type = EquationSolverType::Native;
176 "Selecting '" + toString(type) +
177 "' as the linear equation solver to guarantee sound results. If you want to override this, please explicitly specify a different solver.");
178 } else {
179 STORM_LOG_WARN("The selected solver does not yield sound results.");
180 }
181 }
182
183 switch (type) {
184 case EquationSolverType::Gmmxx:
185 return std::make_unique<GmmxxLinearEquationSolver<ValueType>>();
186 case EquationSolverType::Native:
187 return std::make_unique<NativeLinearEquationSolver<ValueType>>();
188 case EquationSolverType::Eigen:
189 return std::make_unique<EigenLinearEquationSolver<ValueType>>();
190 case EquationSolverType::Elimination:
191 return std::make_unique<EliminationLinearEquationSolver<ValueType>>();
192 case EquationSolverType::Topological:
193 return std::make_unique<TopologicalLinearEquationSolver<ValueType>>();
194 case EquationSolverType::Acyclic:
195 return std::make_unique<AcyclicLinearEquationSolver<ValueType>>();
196 default:
197 STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type.");
198 return nullptr;
199 }
200}
201
202template<typename ValueType>
203std::unique_ptr<LinearEquationSolverFactory<ValueType>> GeneralLinearEquationSolverFactory<ValueType>::clone() const {
204 return std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>(*this);
205}
206
207template class LinearEquationSolver<double>;
210
214
218
219} // namespace solver
220} // namespace storm
SolverEnvironment & solver()
storm::solver::EquationSolverType const & getLinearEquationSolverType() const
bool isLinearEquationSolverTypeSetFromDefaultValue() 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 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:29
#define STORM_LOG_WARN(message)
Definition logging.h:30
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
std::string toString(GurobiSolverMethod const &method)
Yields a string representation of the GurobiSolverMethod.
LabParser.cpp.
Definition cli.cpp:18