13template<
typename ValueType,
bool TrivialRowGrouping>
16 : viOperator(viOperator) {
20template<
typename ValueType, OptimizationDirection Dir>
25 void firstRow(std::pair<ValueType, ValueType>&& value, [[maybe_unused]] uint64_t rowGroup, [[maybe_unused]] uint64_t row) {
26 xBest = std::move(value.first);
27 yBest = std::move(value.second);
30 void nextRow(std::pair<ValueType, ValueType>&& value, [[maybe_unused]] uint64_t rowGroup, [[maybe_unused]] uint64_t row) {
31 xBest &= std::move(value.first);
32 yBest &= std::move(value.second);
35 void applyUpdate(ValueType& xCurr, ValueType& yCurr, [[maybe_unused]] uint64_t rowGroup) {
36 xCurr = std::max(xCurr, *xBest);
37 yCurr = std::min(yCurr, *yBest);
56template<
typename ValueType>
57bool checkConvergence(std::pair<std::vector<ValueType>, std::vector<ValueType>>
const& xy, uint64_t& convergenceCheckState,
58 std::function<
void()>
const& getNextConvergenceCheckState,
bool relative, ValueType
const& precision) {
60 for (; convergenceCheckState < xy.first.size(); getNextConvergenceCheckState()) {
61 ValueType
const& l = xy.first[convergenceCheckState];
62 ValueType
const& u = xy.second[convergenceCheckState];
64 if ((u - l) > l * precision) {
68 if ((l - u) < u * precision) {
78 for (; convergenceCheckState < xy.first.size(); getNextConvergenceCheckState()) {
79 if (xy.second[convergenceCheckState] - xy.first[convergenceCheckState] > precision) {
87template<
typename ValueType,
bool TrivialRowGrouping>
88template<OptimizationDirection Dir>
90 std::vector<ValueType>
const& offsets, uint64_t& numIterations,
bool relative,
91 ValueType
const& precision,
93 std::optional<storm::storage::BitVector>
const& relevantValues)
const {
96 uint64_t convergenceCheckState = 0;
97 std::function<void()> getNextConvergenceCheckState;
99 convergenceCheckState = relevantValues->getNextSetIndex(0);
100 getNextConvergenceCheckState = [&convergenceCheckState, &relevantValues]() {
101 convergenceCheckState = relevantValues->getNextSetIndex(++convergenceCheckState);
104 getNextConvergenceCheckState = [&convergenceCheckState]() { ++convergenceCheckState; };
108 viOperator->applyInPlace(xy, offsets, backend);
109 if (
checkConvergence(xy, convergenceCheckState, getNextConvergenceCheckState, relative, precision)) {
111 }
else if (iterationCallback) {
118template<
typename ValueType,
bool TrivialRowGrouping>
120 uint64_t& numIterations,
bool relative, ValueType
const& precision,
121 std::function<
void(std::vector<ValueType>&)>
const& prepareLowerBounds,
122 std::function<
void(std::vector<ValueType>&)>
const& prepareUpperBounds,
123 std::optional<storm::OptimizationDirection>
const& dir,
125 std::optional<storm::storage::BitVector>
const& relevantValues)
const {
127 std::pair<std::vector<ValueType>, std::vector<ValueType>> xy;
128 auto& auxVector = viOperator->allocateAuxiliaryVector(operand.size());
129 xy.first.swap(operand);
130 xy.second.swap(auxVector);
131 prepareLowerBounds(xy.first);
132 prepareUpperBounds(xy.second);
133 auto doublePrec = precision + precision;
134 if constexpr (std::is_same_v<ValueType, double>) {
135 doublePrec -= precision * 1e-6;
138 if (!dir.has_value() ||
maximize(*dir)) {
146 xy.first, xy.second, xy.first, [&two](ValueType
const& a, ValueType
const& b) -> ValueType { return (a + b) / two; });
148 xy.first.swap(operand);
149 xy.second.swap(auxVector);
150 viOperator->freeAuxiliaryVector();
154template<
typename ValueType,
bool TrivialRowGrouping>
156 ValueType
const& precision,
157 std::function<
void(std::vector<ValueType>&)>
const& prepareLowerBounds,
158 std::function<
void(std::vector<ValueType>&)>
const& prepareUpperBounds,
159 std::optional<storm::OptimizationDirection>
const& dir,
161 std::optional<storm::storage::BitVector>
const& relevantValues)
const {
162 uint64_t numIterations = 0;
163 return II(operand, offsets, numIterations, relative, precision, prepareLowerBounds, prepareUpperBounds, dir, iterationCallback, relevantValues);
bool constexpr converged() const
void applyUpdate(ValueType &xCurr, ValueType &yCurr, uint64_t rowGroup)
void nextRow(std::pair< ValueType, ValueType > &&value, uint64_t rowGroup, uint64_t row)
bool constexpr abort() const
void endOfIteration() const
void firstRow(std::pair< ValueType, ValueType > &&value, uint64_t rowGroup, uint64_t row)
Implements interval iteration.
IntervalIterationHelper(std::shared_ptr< ValueIterationOperator< ValueType, TrivialRowGrouping > > viOperator)
SolverStatus II(std::pair< std::vector< ValueType >, std::vector< ValueType > > &xy, std::vector< ValueType > const &offsets, uint64_t &numIterations, bool relative, ValueType const &precision, std::function< SolverStatus(IIData< ValueType > const &)> const &iterationCallback={}, std::optional< storm::storage::BitVector > const &relevantValues={}) const
This class represents the Value Iteration Operator (also known as Bellman operator).
Stores and manages an extremal (maximal or minimal) value.
bool checkConvergence(std::pair< std::vector< ValueType >, std::vector< ValueType > > const &xy, uint64_t &convergenceCheckState, std::function< void()> const &getNextConvergenceCheckState, bool relative, ValueType const &precision)
bool constexpr maximize(OptimizationDirection d)
void applyPointwise(std::vector< InValueType1 > const &firstOperand, std::vector< InValueType2 > const &secondOperand, std::vector< OutValueType > &target, Operation f=Operation())
Applies the given operation pointwise on the two given vectors and writes the result to the third vec...
TargetType convertNumber(SourceType const &number)