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) {
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) {
120 std::vector<ValueType>& operand, std::vector<ValueType>
const& offsets, uint64_t& numIterations,
bool relative, ValueType
const& precision,
121 std::function<
void(std::vector<ValueType>&)>
const& prepareLowerBounds, std::function<
void(std::vector<ValueType>&)>
const& prepareUpperBounds,
125 std::pair<std::vector<ValueType>, std::vector<ValueType>> xy;
126 auto& auxVector = viOperator->allocateAuxiliaryVector(operand.size());
127 xy.first.swap(operand);
128 xy.second.swap(auxVector);
129 prepareLowerBounds(xy.first);
130 prepareUpperBounds(xy.second);
131 auto doublePrec = precision + precision;
132 if constexpr (std::is_same_v<ValueType, double>) {
133 doublePrec -= precision * 1e-6;
136 if (!dir.has_value() ||
maximize(*dir)) {
141 if (solutionBounds.has_value()) {
144 solutionBounds->lower = xy.first;
145 solutionBounds->upper = xy.second;
150 xy.first, xy.second, xy.first, [&two](ValueType
const& a, ValueType
const& b) -> ValueType { return (a + b) / two; });
152 xy.first.swap(operand);
153 xy.second.swap(auxVector);
154 viOperator->freeAuxiliaryVector();
160 ValueType
const& precision,
161 std::function<
void(std::vector<ValueType>&)>
const& prepareLowerBounds,
162 std::function<
void(std::vector<ValueType>&)>
const& prepareUpperBounds,
163 std::optional<storm::OptimizationDirection>
const& dir,
165 std::optional<storm::storage::BitVector>
const& relevantValues)
const {
166 uint64_t numIterations = 0;
167 return II(operand, offsets, numIterations, relative, precision, prepareLowerBounds, prepareUpperBounds, dir, iterationCallback, relevantValues);
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
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)
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...