20template<
typename ValueType>
22 std::optional<std::vector<ValueType>>
lower;
23 std::optional<std::vector<ValueType>>
upper;
29 return lower.has_value();
36 return upper.has_value();
49 bool encloses(std::vector<ValueType>
const& values)
const {
50 auto const isBoundedBy = [&values](std::optional<std::vector<ValueType>>
const& bound,
bool fromBelow) {
51 if (!bound.has_value()) {
54 if (bound->size() != values.size()) {
57 for (uint64_t i = 0; i < values.size(); ++i) {
58 if (fromBelow ? (*bound)[i] > values[i] : (*bound)[i] < values[i]) {
64 return isBoundedBy(
lower,
true) && isBoundedBy(
upper,
false);
77 bool isWithinPrecision(std::vector<ValueType>
const& values, ValueType
const& precision,
bool relative)
const {
81 STORM_LOG_THROW(
lower->size() == values.size() &&
upper->size() == values.size(), storm::exceptions::InvalidArgumentException,
82 "The given values do not match the size of the bounds.");
84 for (uint64_t i = 0; i < values.size(); ++i) {
85 ValueType
const& low = (*lower)[i];
86 ValueType
const& up = (*upper)[i];
87 ValueType allowed = precision;
94 if (!(values[i] - low <= allowed) || !(up - values[i] <= allowed)) {
104 void setExact(std::vector<ValueType>
const& values) {
115 std::ranges::transform(*
lower,
lower->begin(), oneMinus);
118 std::ranges::transform(*
upper,
upper->begin(), oneMinus);
127 template<
typename Function>
143 void widenTo(std::vector<ValueType>
const& values) {
145 std::ranges::transform(*
lower, values,
lower->begin(), [](ValueType
const& bound, ValueType
const& value) { return std::min(bound, value); });
148 std::ranges::transform(*
upper, values,
upper->begin(), [](ValueType
const& bound, ValueType
const& value) { return std::max(bound, value); });
156 lower = std::nullopt;
157 upper = std::nullopt;
#define STORM_LOG_THROW(cond, exception, message)
ValueType abs(ValueType const &number)
Sound lower and upper bounds on a solution vector.
bool hasAny() const
Returns true if at least one of the bounds is set.
std::optional< std::vector< ValueType > > lower
bool hasUpper() const
Returns true if the upper bound is set.
auto transform(Function const &function) const
Applies the given function to whichever of the bounds are set, e.g.
bool hasLower() const
Returns true if the lower bound is set.
std::optional< std::vector< ValueType > > upper
void widenTo(std::vector< ValueType > const &values)
Widens whichever bounds are set until they enclose the given values.
void invertProbabilityBounds()
Turns bounds on a probability p into bounds on 1-p, i.e.
void clear()
Clears both bounds.
bool isWithinPrecision(std::vector< ValueType > const &values, ValueType const &precision, bool relative) const
Returns true if both bounds are set and neither is further from its value than the given precision al...
bool encloses(std::vector< ValueType > const &values) const
Returns true if every one of the given values lies within the bounds that are set.
bool isExact() const
Returns true if both bounds are set and coincide.
void setExact(std::vector< ValueType > const &values)
Sets both bounds to the given values, i.e.