11storm::RationalNumber
findRational(storm::RationalNumber
const& lowerBound,
bool lowerInclusive, storm::RationalNumber
const& upperBound,
bool upperInclusive) {
13 STORM_LOG_ASSERT(lowerBound < upperBound || (lowerBound == upperBound && lowerInclusive && upperInclusive),
"Invalid interval for rational approximation.");
18 if (upperBound >
zero || (upperBound ==
zero && upperInclusive)) {
22 return -
findRational(-upperBound, upperInclusive, -lowerBound, lowerInclusive);
33 std::vector<Integer> path;
42 path.push_back(std::min(l_i, u_i));
52 path.back() += Integer(1);
58 if (needAdjustLower || needAdjustUpper) {
60 auto const& o_i = needAdjustLower ? u_i : l_i;
61 auto const& o_rem = needAdjustLower ? u_rem : l_rem;
62 auto const& o_den = needAdjustLower ? u_den : l_den;
63 auto const& o_inclusive = needAdjustLower ? upperInclusive : lowerInclusive;
69 bool const currentDirectionIsIncreasing = (path.size() - 1) % 2 == 0;
70 bool const adjustInCurrentDirection = (needAdjustLower && currentDirectionIsIncreasing) || (needAdjustUpper && !currentDirectionIsIncreasing);
74 if (adjustInCurrentDirection) {
75 STORM_LOG_ASSERT(path.back() <= o_i,
"Unexpected case when navigating the Stern-Brocot tree.");
76 if (path.back() + Integer(1) < o_i || (path.back() + Integer(1) == o_i && !
storm::utility::isZero(o_rem))) {
78 path.back() += Integer(1);
82 path.back() += Integer(1);
99 path.back() += Integer(1);
100 }
else if (!o_inclusive) {
102 path.back() += Integer(1);
108 STORM_LOG_ASSERT(o_i == path.back() - Integer(1),
"Unexpected case when navigating the Stern-Brocot tree.");
111 path.back() -= Integer(1);
114 path.emplace_back(2);
118 path.emplace_back(2);
121 path.emplace_back(1);
122 path.emplace_back(2);
129 path.emplace_back(1);
130 path.push_back(o_i3);
133 path.back() += Integer(1);
134 }
else if (!o_inclusive) {
136 path.back() += Integer(1);
145 auto it = path.rbegin();
147 for (++it; it != path.rend(); ++it) {
152 STORM_LOG_ASSERT(result > lowerBound || (lowerInclusive && result == lowerBound),
"Result is below lower bound.");
153 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.