Skip to content

Commit c4c4592

Browse files
author
Tomáš Kolárik
committed
Implemented templated free function Rational to_rational(simple_continued_fraction)
1 parent 25ab7c5 commit c4c4592

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

include/boost/math/tools/simple_continued_fraction.hpp

+30
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <sstream>
1818
#include <utility>
1919
#include <cstdint>
20+
#include <cassert>
2021

2122
#include <boost/math/tools/is_standalone.hpp>
2223
#ifndef BOOST_MATH_STANDALONE
@@ -214,5 +215,34 @@ inline auto simple_continued_fraction_coefficients(Real x)
214215
return temp.get_data();
215216
}
216217

218+
// Can be used with `boost::rational` from <boost/rational.hpp>
219+
template <typename Rational, typename Real, typename Z = std::int64_t>
220+
inline Rational to_rational(const simple_continued_fraction<Real, Z>& scf)
221+
{
222+
using int_t = typename Rational::int_type;
223+
224+
auto& coefs = scf.partial_denominators();
225+
const size_t size_ = coefs.size();
226+
assert(size_ >= 1);
227+
if (size_ == 1) return static_cast<int_t>(coefs[0]);
228+
229+
// p0 = a0, p1 = a1.a0 + 1, pn = an.pn-1 + pn-2 for 2 <= n
230+
// q0 = 1, q1 = a1, qn = an.qn-1 + qn-2 for 2 <= n
231+
232+
int_t p0 = coefs[0];
233+
int_t p1 = p0*coefs[1] + 1;
234+
int_t q0 = 1;
235+
int_t q1 = coefs[1];
236+
for (size_t i = 2; i < size_; ++i) {
237+
const Z cn = coefs[i];
238+
const int_t pn = cn*p1 + p0;
239+
const int_t qn = cn*q1 + q0;
240+
p0 = std::exchange(p1, pn);
241+
q0 = std::exchange(q1, qn);
242+
}
243+
244+
return {p1, q1};
245+
}
246+
217247
}
218248
#endif

0 commit comments

Comments
 (0)