1 // (C) Copyright John Maddock 2005-2006.
2 // Use, modification and distribution are subject to the
3 // Boost Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_MATH_TOOLS_FRACTION_INCLUDED
7 #define BOOST_MATH_TOOLS_FRACTION_INCLUDED
13 #include <boost/config/no_tr1/cmath.hpp>
14 #include <boost/cstdint.hpp>
15 #include <boost/type_traits/integral_constant.hpp>
16 #include <boost/mpl/if.hpp>
17 #include <boost/math/tools/precision.hpp>
19 namespace boost{ namespace math{ namespace tools{
25 struct is_pair : public boost::false_type{};
27 template <class T, class U>
28 struct is_pair<std::pair<T,U> > : public boost::true_type{};
31 struct fraction_traits_simple
33 typedef typename Gen::result_type result_type;
34 typedef typename Gen::result_type value_type;
36 static result_type a(const value_type& v)
40 static result_type b(const value_type& v)
47 struct fraction_traits_pair
49 typedef typename Gen::result_type value_type;
50 typedef typename value_type::first_type result_type;
52 static result_type a(const value_type& v)
56 static result_type b(const value_type& v)
63 struct fraction_traits
64 : public boost::mpl::if_c<
65 is_pair<typename Gen::result_type>::value,
66 fraction_traits_pair<Gen>,
67 fraction_traits_simple<Gen> >::type
74 // continued_fraction_b
85 // Note that the first a0 returned by generator Gen is disarded.
87 template <class Gen, class U>
88 inline typename detail::fraction_traits<Gen>::result_type continued_fraction_b(Gen& g, const U& factor, boost::uintmax_t& max_terms)
90 BOOST_MATH_STD_USING // ADL of std names
92 typedef detail::fraction_traits<Gen> traits;
93 typedef typename traits::result_type result_type;
94 typedef typename traits::value_type value_type;
96 result_type tiny = tools::min_value<result_type>();
100 result_type f, C, D, delta;
107 boost::uintmax_t counter(max_terms);
111 D = traits::b(v) + traits::a(v) * D;
114 C = traits::b(v) + traits::a(v) / C;
120 }while((fabs(delta - 1) > factor) && --counter);
122 max_terms = max_terms - counter;
127 template <class Gen, class U>
128 inline typename detail::fraction_traits<Gen>::result_type continued_fraction_b(Gen& g, const U& factor)
130 boost::uintmax_t max_terms = (std::numeric_limits<boost::uintmax_t>::max)();
131 return continued_fraction_b(g, factor, max_terms);
135 inline typename detail::fraction_traits<Gen>::result_type continued_fraction_b(Gen& g, int bits)
137 BOOST_MATH_STD_USING // ADL of std names
139 typedef detail::fraction_traits<Gen> traits;
140 typedef typename traits::result_type result_type;
142 result_type factor = ldexp(1.0f, 1 - bits); // 1 / pow(result_type(2), bits);
143 boost::uintmax_t max_terms = (std::numeric_limits<boost::uintmax_t>::max)();
144 return continued_fraction_b(g, factor, max_terms);
148 inline typename detail::fraction_traits<Gen>::result_type continued_fraction_b(Gen& g, int bits, boost::uintmax_t& max_terms)
150 BOOST_MATH_STD_USING // ADL of std names
152 typedef detail::fraction_traits<Gen> traits;
153 typedef typename traits::result_type result_type;
155 result_type factor = ldexp(1.0f, 1 - bits); // 1 / pow(result_type(2), bits);
156 return continued_fraction_b(g, factor, max_terms);
160 // continued_fraction_a
171 // Note that the first a1 and b1 returned by generator Gen are both used.
173 template <class Gen, class U>
174 inline typename detail::fraction_traits<Gen>::result_type continued_fraction_a(Gen& g, const U& factor, boost::uintmax_t& max_terms)
176 BOOST_MATH_STD_USING // ADL of std names
178 typedef detail::fraction_traits<Gen> traits;
179 typedef typename traits::result_type result_type;
180 typedef typename traits::value_type value_type;
182 result_type tiny = tools::min_value<result_type>();
186 result_type f, C, D, delta, a0;
194 boost::uintmax_t counter(max_terms);
198 D = traits::b(v) + traits::a(v) * D;
201 C = traits::b(v) + traits::a(v) / C;
207 }while((fabs(delta - 1) > factor) && --counter);
209 max_terms = max_terms - counter;
214 template <class Gen, class U>
215 inline typename detail::fraction_traits<Gen>::result_type continued_fraction_a(Gen& g, const U& factor)
217 boost::uintmax_t max_iter = (std::numeric_limits<boost::uintmax_t>::max)();
218 return continued_fraction_a(g, factor, max_iter);
222 inline typename detail::fraction_traits<Gen>::result_type continued_fraction_a(Gen& g, int bits)
224 BOOST_MATH_STD_USING // ADL of std names
226 typedef detail::fraction_traits<Gen> traits;
227 typedef typename traits::result_type result_type;
229 result_type factor = ldexp(1.0f, 1-bits); // 1 / pow(result_type(2), bits);
230 boost::uintmax_t max_iter = (std::numeric_limits<boost::uintmax_t>::max)();
232 return continued_fraction_a(g, factor, max_iter);
236 inline typename detail::fraction_traits<Gen>::result_type continued_fraction_a(Gen& g, int bits, boost::uintmax_t& max_terms)
238 BOOST_MATH_STD_USING // ADL of std names
240 typedef detail::fraction_traits<Gen> traits;
241 typedef typename traits::result_type result_type;
243 result_type factor = ldexp(1.0f, 1-bits); // 1 / pow(result_type(2), bits);
244 return continued_fraction_a(g, factor, max_terms);
251 #endif // BOOST_MATH_TOOLS_FRACTION_INCLUDED