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