10storm::RationalNumber
findRational(storm::RationalNumber
const& lowerBound,
bool lowerInclusive, storm::RationalNumber
const& upperBound,
bool upperInclusive) {
12 STORM_LOG_ASSERT(lowerBound < upperBound || (lowerBound == upperBound && lowerInclusive && upperInclusive),
"Invalid interval for rational approximation.");
17 if (upperBound >
zero || (upperBound ==
zero && upperInclusive)) {
21 return -
findRational(-upperBound, upperInclusive, -lowerBound, lowerInclusive);
32 std::vector<Integer> path;
41 path.push_back(std::min(l_i, u_i));
51 path.back() += Integer(1);
57 if (needAdjustLower || needAdjustUpper) {
59 auto const& o_i = needAdjustLower ? u_i : l_i;
60 auto const& o_rem = needAdjustLower ? u_rem : l_rem;
61 auto const& o_den = needAdjustLower ? u_den : l_den;
62 auto const& o_inclusive = needAdjustLower ? upperInclusive : lowerInclusive;
68 bool const currentDirectionIsIncreasing = (path.size() - 1) % 2 == 0;
69 bool const adjustInCurrentDirection = (needAdjustLower && currentDirectionIsIncreasing) || (needAdjustUpper && !currentDirectionIsIncreasing);
73 if (adjustInCurrentDirection) {
74 STORM_LOG_ASSERT(path.back() <= o_i,
"Unexpected case when navigating the Stern-Brocot tree.");
75 if (path.back() + Integer(1) < o_i || (path.back() + Integer(1) == o_i && !
storm::utility::isZero(o_rem))) {
77 path.back() += Integer(1);
81 path.back() += Integer(1);
98 path.back() += Integer(1);
99 }
else if (!o_inclusive) {
101 path.back() += Integer(1);
107 STORM_LOG_ASSERT(o_i == path.back() - Integer(1),
"Unexpected case when navigating the Stern-Brocot tree.");
110 path.back() -= Integer(1);
113 path.emplace_back(2);
117 path.emplace_back(2);
120 path.emplace_back(1);
121 path.emplace_back(2);
128 path.emplace_back(1);
129 path.push_back(o_i3);
132 path.back() += Integer(1);
133 }
else if (!o_inclusive) {
135 path.back() += Integer(1);
144 auto it = path.rbegin();
146 for (++it; it != path.rend(); ++it) {
151 STORM_LOG_ASSERT(result > lowerBound || (lowerInclusive && result == lowerBound),
"Result is below lower bound.");
152 STORM_LOG_ASSERT(result < upperBound || (upperInclusive && result == upperBound),
"Result is above upper bound.");
storm::RationalNumber findRational(storm::RationalNumber const &lowerBound, bool lowerInclusive, storm::RationalNumber const &upperBound, bool upperInclusive)
Finds the "simplest" rational number in the given interval, where "simplest" means having the smalles...
std::pair< IntegerType, IntegerType > divide(IntegerType const ÷nd, IntegerType const &divisor)
(Integer-)Divides the dividend by the divisor and returns the result plus the remainder.