15template<
typename SolutionType>
20template<
typename SolutionType>
27template<
typename SolutionType>
32template<
typename SolutionType>
37template<
typename SolutionType>
42template<
typename SolutionType>
47template<
typename SolutionType>
52template<
typename SolutionType>
58 return this->getTerminationCondition().terminateNow(values, guarantee);
61template<
typename SolutionType>
66template<
typename SolutionType>
71template<
typename SolutionType>
76template<
typename SolutionType>
81template<
typename SolutionType>
86template<
typename SolutionType>
91template<
typename SolutionType>
93 if (type == BoundType::Any) {
95 }
else if (type == BoundType::Global) {
96 return static_cast<bool>(lowerBound);
97 }
else if (type == BoundType::Local) {
98 return static_cast<bool>(lowerBounds);
103template<
typename SolutionType>
105 if (type == BoundType::Any) {
107 }
else if (type == BoundType::Global) {
109 }
else if (type == BoundType::Local) {
110 return static_cast<bool>(upperBounds);
115template<
typename SolutionType>
120template<
typename SolutionType>
125template<
typename SolutionType>
131template<
typename SolutionType>
136template<
typename SolutionType>
151template<
typename SolutionType>
155 }
else if (convertLocalBounds) {
158 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"No lower bound available but some was requested.");
159 return SolutionType();
162template<
typename SolutionType>
167template<
typename SolutionType>
182template<
typename SolutionType>
186 }
else if (convertLocalBounds) {
187 return *std::max_element(upperBounds->begin(), upperBounds->end());
189 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"No upper bound available but some was requested.");
190 return SolutionType();
193template<
typename SolutionType>
198template<
typename SolutionType>
203template<
typename SolutionType>
208template<
typename SolutionType>
213template<
typename SolutionType>
218template<
typename SolutionType>
223template<
typename SolutionType>
229template<
typename SolutionType>
245template<
typename SolutionType>
247 return solutionBounds.hasLower();
250template<
typename SolutionType>
252 return solutionBounds.hasUpper();
255template<
typename SolutionType>
257 return solutionBounds.isExact();
260template<
typename SolutionType>
263 return *solutionBounds.lower;
266template<
typename SolutionType>
269 return *solutionBounds.upper;
272template<
typename SolutionType>
274 return solutionBounds;
277template<
typename SolutionType>
280 "Bounds on the solution must have the same size.");
281 solutionBounds = std::move(bounds);
284template<
typename SolutionType>
291template<
typename SolutionType>
293 bool relative)
const {
294 if constexpr (std::is_same_v<SolutionType, storm::RationalFunction>) {
295 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Cannot derive solution bounds from a precision for rational functions.");
299 std::vector<SolutionType>& lower = bounds.
lower.emplace(x.size());
300 std::vector<SolutionType>& upper = bounds.
upper.emplace(x.size());
301 for (uint64_t i = 0; i < x.size(); ++i) {
304 SolutionType
const deviation =
306 lower[i] = x[i] - deviation;
307 upper[i] = x[i] + deviation;
309 this->setSolutionBounds(std::move(bounds));
313template<
typename SolutionType>
315 if constexpr (std::is_same_v<SolutionType, storm::RationalFunction>) {
321 bool const hadBound = solutionBounds.hasLower();
322 std::vector<SolutionType>& bound = hadBound ? *solutionBounds.lower : solutionBounds.lower.emplace(x.size());
323 STORM_LOG_ASSERT(bound.size() == x.size(),
"Computed lower bound does not match the size of the solution.");
324 for (uint64_t i = 0; i < x.size(); ++i) {
329 bool const hadBound = solutionBounds.hasUpper();
330 std::vector<SolutionType>& bound = hadBound ? *solutionBounds.upper : solutionBounds.upper.emplace(x.size());
331 STORM_LOG_ASSERT(bound.size() == x.size(),
"Computed upper bound does not match the size of the solution.");
332 for (uint64_t i = 0; i < x.size(); ++i) {
338 solutionBounds.widenTo(x);
342template<
typename SolutionType>
344 solutionBounds.clear();
347template<
typename SolutionType>
355template<
typename SolutionType>
361 for (
auto& e : lowerBoundsVector) {
367template<
typename SolutionType>
371 upperBoundsVector.assign(upperBoundsVector.size(), this->getUpperBound());
377template<
typename SolutionType>
380 if (!upperBoundsVector) {
383 upperBoundsVector = std::make_unique<std::vector<SolutionType>>(this->
getUpperBounds());
385 upperBoundsVector = std::make_unique<std::vector<SolutionType>>(length, this->
getUpperBound());
392template<
typename SolutionType>
394 return this->progressMeasurement.is_initialized();
397template<
typename SolutionType>
400 return this->progressMeasurement->getShowProgressDelay();
403template<
typename SolutionType>
406 this->progressMeasurement->startNewMeasurement(startingIteration);
410template<
typename SolutionType>
414 this->progressMeasurement->setMaxCount(bound.get());
416 this->progressMeasurement->updateProgress(iteration);
420template<
typename SolutionType>
425 STORM_LOG_TRACE(
"Iterative solver converged after " << iterations.get() <<
" iterations.");
428 STORM_LOG_TRACE(
"Iterative solver terminated early after " << iterations.get() <<
" iterations.");
431 STORM_LOG_WARN(
"Iterative solver did not converge after " << iterations.get() <<
" iterations.");
434 STORM_LOG_WARN(
"Iterative solver was aborted after " << iterations.get() <<
" iterations.");
437 STORM_LOG_THROW(
false, storm::exceptions::InvalidStateException,
"Iterative solver terminated unexpectedly.");
448 STORM_LOG_ASSERT(
false,
"Non-iterative solver should not exceed maximal number of iterations.");
455 STORM_LOG_THROW(
false, storm::exceptions::InvalidStateException,
"Solver terminated unexpectedly.");
460template<
typename SolutionType>
462 uint64_t maximalNumberOfIterations)
const {
464 if (earlyTermination) {
466 }
else if (iterations >= maximalNumberOfIterations) {
475template<
typename SolutionType>
477 uint64_t iterations, uint64_t maximalNumberOfIterations)
const {
479 maximalNumberOfIterations);
bool hasLowerBound(BoundType const &type=BoundType::Any) const
Retrieves whether this solver has a lower bound.
void setSolutionBoundsExact(std::vector< SolutionType > const &x) const
Reports the given solution as an exact one, i.e.
void setRelevantValues(storm::storage::BitVector &&valuesOfInterest)
Sets the relevant values.
void setSolutionBounds(SolutionBounds< SolutionType > bounds) const
Stores sound bounds on the solution that were obtained while solving.
bool hasCustomTerminationCondition() const
Retrieves whether a custom termination condition has been set.
std::unique_ptr< TerminationCondition< SolutionType > > const & getTerminationConditionPointer() const
void showProgressIterative(uint64_t iterations, boost::optional< uint64_t > const &bound=boost::none) const
Shows progress if this solver is asked to do so.
void setTerminationCondition(std::unique_ptr< TerminationCondition< SolutionType > > terminationCondition)
Sets a custom termination condition that is used together with the regular termination condition of t...
void setBounds(SolutionType const &lower, SolutionType const &upper)
Sets bounds for the solution that can potentially be used by the solver.
boost::optional< storm::storage::BitVector > const & getOptionalRelevantValues() const
boost::optional< ValueType > lowerBound
std::vector< SolutionType > const & getSolutionUpperBounds() const
storm::storage::BitVector const & getRelevantValues() const
Retrieves the relevant values (if there are any).
bool hasUpperBound(BoundType const &type=BoundType::Any) const
Retrieves whether this solver has an upper bound.
std::unique_ptr< TerminationCondition< SolutionType > > terminationCondition
bool isShowProgressSet() const
Retrieves whether progress is to be shown.
bool hasExactSolutionBounds() const
Retrieves whether the bounds computed by the last call to this solver coincide.
SolutionType const & getUpperBound() const
Retrieves the upper bound (if there is any).
void setBoundsFromOtherSolver(AbstractEquationSolver< SolutionType > const &other)
void setSolutionBoundsFromPrecision(std::vector< SolutionType > const &x, SolutionType const &precision, bool relative) const
Turns a precision that the solving procedure is known to have achieved into sound bounds on the solut...
SolutionBounds< SolutionType > const & getSolutionBounds() const
Retrieves both bounds at once, either of which may be unset.
std::vector< SolutionType > const & getLowerBounds() const
Retrieves a vector containing the lower bounds (if there are any).
void setShowProgress(bool verbose, uint64_t delay=5)
Configures whether this solver should show progress during iterative solving.
bool hasSolutionLowerBounds() const
Retrieves whether the last call to this solver computed a sound lower resp.
void setUpperBounds(std::vector< SolutionType > const &values)
Sets upper bounds for the solution that can potentially be used by the solver.
SolverStatus updateStatus(SolverStatus status, std::vector< SolutionType > const &x, SolverGuarantee const &guarantee, uint64_t iterations, uint64_t maximalNumberOfIterations) const
Update the status of the solver with respect to convergence, early termination, abortion,...
boost::optional< SolutionType > upperBound
void createUpperBoundsVector(std::vector< SolutionType > &upperBoundsVector) const
void setLowerBound(SolutionType const &value)
Sets a lower bound for the solution that can potentially be used by the solver.
boost::optional< storm::storage::BitVector > relevantValues
void startMeasureProgress(uint64_t startingIteration=0) const
Starts to measure progress.
void resetTerminationCondition()
Removes a previously set custom termination condition.
TerminationCondition< SolutionType > const & getTerminationCondition() const
Retrieves the custom termination condition (if any was set).
SolutionType const & getLowerBound() const
Retrieves the lower bound (if there is any).
bool hasRelevantValues() const
Retrieves whether this solver has particularly relevant values.
void clearRelevantValues()
Removes the values of interest (if there were any).
bool hasSolutionUpperBounds() const
std::vector< SolutionType > const & getUpperBounds() const
Retrieves a vector containing the upper bounds (if there are any).
bool terminateNow(std::vector< SolutionType > const &values, SolverGuarantee const &guarantee) const
Checks whether the solver can terminate wrt.
void clearSolutionBounds() const
Discards any bounds on the solution obtained by a previous call.
void clearBounds()
Removes all specified solution bounds.
boost::optional< std::vector< SolutionType > > upperBounds
void reportStatus(SolverStatus status, boost::optional< uint64_t > const &iterations=boost::none) const
Report the current status of the solver.
void createLowerBoundsVector(std::vector< SolutionType > &lowerBoundsVector) const
uint64_t getShowProgressDelay() const
Retrieves the delay between progress emissions.
void finalizeSolutionBounds(std::vector< SolutionType > const &x) const
Settles the bounds to report once solving is over: the ones handed to this solver beforehand are fold...
boost::optional< std::vector< ValueType > > lowerBounds
void setUpperBound(SolutionType const &value)
Sets an upper bound for the solution that can potentially be used by the solver.
void setLowerBounds(std::vector< SolutionType > const &values)
Sets lower bounds for the solution that can potentially be used by the solver.
std::vector< SolutionType > const & getSolutionLowerBounds() const
Retrieves sound bounds on the solution that the last call to this solver computed.
A bit vector that is internally represented as a vector of 64-bit values.
A class that provides convenience operations to display run times.
#define STORM_LOG_WARN(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
@ MaximalIterationsExceeded
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
ValueType abs(ValueType const &number)
Sound lower and upper bounds on a solution vector.
std::optional< std::vector< ValueType > > lower
bool hasUpper() const
Returns true if the upper bound is set.
bool hasLower() const
Returns true if the lower bound is set.
std::optional< std::vector< ValueType > > upper
void setExact(std::vector< ValueType > const &values)
Sets both bounds to the given values, i.e.