Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:41

0001 //  (C) Copyright John Maddock 2006.
0002 //  Use, modification and distribution are subject to the
0003 //  Boost Software License, Version 1.0. (See accompanying file
0004 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_MATH_TOOLS_RATIONAL_HPP
0007 #define BOOST_MATH_TOOLS_RATIONAL_HPP
0008 
0009 #ifdef _MSC_VER
0010 #pragma once
0011 #endif
0012 
0013 #include <array>
0014 #include <boost/math/tools/config.hpp>
0015 #include <boost/math/tools/assert.hpp>
0016 
0017 #if BOOST_MATH_POLY_METHOD == 1
0018 #  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/polynomial_horner1_, BOOST_MATH_MAX_POLY_ORDER).hpp>
0019 #  include BOOST_HEADER()
0020 #  undef BOOST_HEADER
0021 #elif BOOST_MATH_POLY_METHOD == 2
0022 #  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/polynomial_horner2_, BOOST_MATH_MAX_POLY_ORDER).hpp>
0023 #  include BOOST_HEADER()
0024 #  undef BOOST_HEADER
0025 #elif BOOST_MATH_POLY_METHOD == 3
0026 #  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/polynomial_horner3_, BOOST_MATH_MAX_POLY_ORDER).hpp>
0027 #  include BOOST_HEADER()
0028 #  undef BOOST_HEADER
0029 #endif
0030 #if BOOST_MATH_RATIONAL_METHOD == 1
0031 #  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/rational_horner1_, BOOST_MATH_MAX_POLY_ORDER).hpp>
0032 #  include BOOST_HEADER()
0033 #  undef BOOST_HEADER
0034 #elif BOOST_MATH_RATIONAL_METHOD == 2
0035 #  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/rational_horner2_, BOOST_MATH_MAX_POLY_ORDER).hpp>
0036 #  include BOOST_HEADER()
0037 #  undef BOOST_HEADER
0038 #elif BOOST_MATH_RATIONAL_METHOD == 3
0039 #  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/rational_horner3_, BOOST_MATH_MAX_POLY_ORDER).hpp>
0040 #  include BOOST_HEADER()
0041 #  undef BOOST_HEADER
0042 #endif
0043 
0044 #if 0
0045 //
0046 // This just allows dependency trackers to find the headers
0047 // used in the above PP-magic.
0048 //
0049 #include <boost/math/tools/detail/polynomial_horner1_2.hpp>
0050 #include <boost/math/tools/detail/polynomial_horner1_3.hpp>
0051 #include <boost/math/tools/detail/polynomial_horner1_4.hpp>
0052 #include <boost/math/tools/detail/polynomial_horner1_5.hpp>
0053 #include <boost/math/tools/detail/polynomial_horner1_6.hpp>
0054 #include <boost/math/tools/detail/polynomial_horner1_7.hpp>
0055 #include <boost/math/tools/detail/polynomial_horner1_8.hpp>
0056 #include <boost/math/tools/detail/polynomial_horner1_9.hpp>
0057 #include <boost/math/tools/detail/polynomial_horner1_10.hpp>
0058 #include <boost/math/tools/detail/polynomial_horner1_11.hpp>
0059 #include <boost/math/tools/detail/polynomial_horner1_12.hpp>
0060 #include <boost/math/tools/detail/polynomial_horner1_13.hpp>
0061 #include <boost/math/tools/detail/polynomial_horner1_14.hpp>
0062 #include <boost/math/tools/detail/polynomial_horner1_15.hpp>
0063 #include <boost/math/tools/detail/polynomial_horner1_16.hpp>
0064 #include <boost/math/tools/detail/polynomial_horner1_17.hpp>
0065 #include <boost/math/tools/detail/polynomial_horner1_18.hpp>
0066 #include <boost/math/tools/detail/polynomial_horner1_19.hpp>
0067 #include <boost/math/tools/detail/polynomial_horner1_20.hpp>
0068 #include <boost/math/tools/detail/polynomial_horner2_2.hpp>
0069 #include <boost/math/tools/detail/polynomial_horner2_3.hpp>
0070 #include <boost/math/tools/detail/polynomial_horner2_4.hpp>
0071 #include <boost/math/tools/detail/polynomial_horner2_5.hpp>
0072 #include <boost/math/tools/detail/polynomial_horner2_6.hpp>
0073 #include <boost/math/tools/detail/polynomial_horner2_7.hpp>
0074 #include <boost/math/tools/detail/polynomial_horner2_8.hpp>
0075 #include <boost/math/tools/detail/polynomial_horner2_9.hpp>
0076 #include <boost/math/tools/detail/polynomial_horner2_10.hpp>
0077 #include <boost/math/tools/detail/polynomial_horner2_11.hpp>
0078 #include <boost/math/tools/detail/polynomial_horner2_12.hpp>
0079 #include <boost/math/tools/detail/polynomial_horner2_13.hpp>
0080 #include <boost/math/tools/detail/polynomial_horner2_14.hpp>
0081 #include <boost/math/tools/detail/polynomial_horner2_15.hpp>
0082 #include <boost/math/tools/detail/polynomial_horner2_16.hpp>
0083 #include <boost/math/tools/detail/polynomial_horner2_17.hpp>
0084 #include <boost/math/tools/detail/polynomial_horner2_18.hpp>
0085 #include <boost/math/tools/detail/polynomial_horner2_19.hpp>
0086 #include <boost/math/tools/detail/polynomial_horner2_20.hpp>
0087 #include <boost/math/tools/detail/polynomial_horner3_2.hpp>
0088 #include <boost/math/tools/detail/polynomial_horner3_3.hpp>
0089 #include <boost/math/tools/detail/polynomial_horner3_4.hpp>
0090 #include <boost/math/tools/detail/polynomial_horner3_5.hpp>
0091 #include <boost/math/tools/detail/polynomial_horner3_6.hpp>
0092 #include <boost/math/tools/detail/polynomial_horner3_7.hpp>
0093 #include <boost/math/tools/detail/polynomial_horner3_8.hpp>
0094 #include <boost/math/tools/detail/polynomial_horner3_9.hpp>
0095 #include <boost/math/tools/detail/polynomial_horner3_10.hpp>
0096 #include <boost/math/tools/detail/polynomial_horner3_11.hpp>
0097 #include <boost/math/tools/detail/polynomial_horner3_12.hpp>
0098 #include <boost/math/tools/detail/polynomial_horner3_13.hpp>
0099 #include <boost/math/tools/detail/polynomial_horner3_14.hpp>
0100 #include <boost/math/tools/detail/polynomial_horner3_15.hpp>
0101 #include <boost/math/tools/detail/polynomial_horner3_16.hpp>
0102 #include <boost/math/tools/detail/polynomial_horner3_17.hpp>
0103 #include <boost/math/tools/detail/polynomial_horner3_18.hpp>
0104 #include <boost/math/tools/detail/polynomial_horner3_19.hpp>
0105 #include <boost/math/tools/detail/polynomial_horner3_20.hpp>
0106 #include <boost/math/tools/detail/rational_horner1_2.hpp>
0107 #include <boost/math/tools/detail/rational_horner1_3.hpp>
0108 #include <boost/math/tools/detail/rational_horner1_4.hpp>
0109 #include <boost/math/tools/detail/rational_horner1_5.hpp>
0110 #include <boost/math/tools/detail/rational_horner1_6.hpp>
0111 #include <boost/math/tools/detail/rational_horner1_7.hpp>
0112 #include <boost/math/tools/detail/rational_horner1_8.hpp>
0113 #include <boost/math/tools/detail/rational_horner1_9.hpp>
0114 #include <boost/math/tools/detail/rational_horner1_10.hpp>
0115 #include <boost/math/tools/detail/rational_horner1_11.hpp>
0116 #include <boost/math/tools/detail/rational_horner1_12.hpp>
0117 #include <boost/math/tools/detail/rational_horner1_13.hpp>
0118 #include <boost/math/tools/detail/rational_horner1_14.hpp>
0119 #include <boost/math/tools/detail/rational_horner1_15.hpp>
0120 #include <boost/math/tools/detail/rational_horner1_16.hpp>
0121 #include <boost/math/tools/detail/rational_horner1_17.hpp>
0122 #include <boost/math/tools/detail/rational_horner1_18.hpp>
0123 #include <boost/math/tools/detail/rational_horner1_19.hpp>
0124 #include <boost/math/tools/detail/rational_horner1_20.hpp>
0125 #include <boost/math/tools/detail/rational_horner2_2.hpp>
0126 #include <boost/math/tools/detail/rational_horner2_3.hpp>
0127 #include <boost/math/tools/detail/rational_horner2_4.hpp>
0128 #include <boost/math/tools/detail/rational_horner2_5.hpp>
0129 #include <boost/math/tools/detail/rational_horner2_6.hpp>
0130 #include <boost/math/tools/detail/rational_horner2_7.hpp>
0131 #include <boost/math/tools/detail/rational_horner2_8.hpp>
0132 #include <boost/math/tools/detail/rational_horner2_9.hpp>
0133 #include <boost/math/tools/detail/rational_horner2_10.hpp>
0134 #include <boost/math/tools/detail/rational_horner2_11.hpp>
0135 #include <boost/math/tools/detail/rational_horner2_12.hpp>
0136 #include <boost/math/tools/detail/rational_horner2_13.hpp>
0137 #include <boost/math/tools/detail/rational_horner2_14.hpp>
0138 #include <boost/math/tools/detail/rational_horner2_15.hpp>
0139 #include <boost/math/tools/detail/rational_horner2_16.hpp>
0140 #include <boost/math/tools/detail/rational_horner2_17.hpp>
0141 #include <boost/math/tools/detail/rational_horner2_18.hpp>
0142 #include <boost/math/tools/detail/rational_horner2_19.hpp>
0143 #include <boost/math/tools/detail/rational_horner2_20.hpp>
0144 #include <boost/math/tools/detail/rational_horner3_2.hpp>
0145 #include <boost/math/tools/detail/rational_horner3_3.hpp>
0146 #include <boost/math/tools/detail/rational_horner3_4.hpp>
0147 #include <boost/math/tools/detail/rational_horner3_5.hpp>
0148 #include <boost/math/tools/detail/rational_horner3_6.hpp>
0149 #include <boost/math/tools/detail/rational_horner3_7.hpp>
0150 #include <boost/math/tools/detail/rational_horner3_8.hpp>
0151 #include <boost/math/tools/detail/rational_horner3_9.hpp>
0152 #include <boost/math/tools/detail/rational_horner3_10.hpp>
0153 #include <boost/math/tools/detail/rational_horner3_11.hpp>
0154 #include <boost/math/tools/detail/rational_horner3_12.hpp>
0155 #include <boost/math/tools/detail/rational_horner3_13.hpp>
0156 #include <boost/math/tools/detail/rational_horner3_14.hpp>
0157 #include <boost/math/tools/detail/rational_horner3_15.hpp>
0158 #include <boost/math/tools/detail/rational_horner3_16.hpp>
0159 #include <boost/math/tools/detail/rational_horner3_17.hpp>
0160 #include <boost/math/tools/detail/rational_horner3_18.hpp>
0161 #include <boost/math/tools/detail/rational_horner3_19.hpp>
0162 #include <boost/math/tools/detail/rational_horner3_20.hpp>
0163 #endif
0164 
0165 namespace boost{ namespace math{ namespace tools{
0166 
0167 //
0168 // Forward declaration to keep two phase lookup happy:
0169 //
0170 template <class T, class U>
0171 U evaluate_polynomial(const T* poly, U const& z, std::size_t count) BOOST_MATH_NOEXCEPT(U);
0172 
0173 namespace detail{
0174 
0175 template <class T, class V, class Tag>
0176 inline V evaluate_polynomial_c_imp(const T* a, const V& val, const Tag*) BOOST_MATH_NOEXCEPT(V)
0177 {
0178    return evaluate_polynomial(a, val, Tag::value);
0179 }
0180 
0181 } // namespace detail
0182 
0183 //
0184 // Polynomial evaluation with runtime size.
0185 // This requires a for-loop which may be more expensive than
0186 // the loop expanded versions above:
0187 //
0188 template <class T, class U>
0189 inline U evaluate_polynomial(const T* poly, U const& z, std::size_t count) BOOST_MATH_NOEXCEPT(U)
0190 {
0191    BOOST_MATH_ASSERT(count > 0);
0192    U sum = static_cast<U>(poly[count - 1]);
0193    for(int i = static_cast<int>(count) - 2; i >= 0; --i)
0194    {
0195       sum *= z;
0196       sum += static_cast<U>(poly[i]);
0197    }
0198    return sum;
0199 }
0200 //
0201 // Compile time sized polynomials, just inline forwarders to the
0202 // implementations above:
0203 //
0204 template <std::size_t N, class T, class V>
0205 inline V evaluate_polynomial(const T(&a)[N], const V& val) BOOST_MATH_NOEXCEPT(V)
0206 {
0207    typedef std::integral_constant<int, N> tag_type;
0208    return detail::evaluate_polynomial_c_imp(static_cast<const T*>(a), val, static_cast<tag_type const*>(nullptr));
0209 }
0210 
0211 template <std::size_t N, class T, class V>
0212 inline V evaluate_polynomial(const std::array<T,N>& a, const V& val) BOOST_MATH_NOEXCEPT(V)
0213 {
0214    typedef std::integral_constant<int, N> tag_type;
0215    return detail::evaluate_polynomial_c_imp(static_cast<const T*>(a.data()), val, static_cast<tag_type const*>(nullptr));
0216 }
0217 //
0218 // Even polynomials are trivial: just square the argument!
0219 //
0220 template <class T, class U>
0221 inline U evaluate_even_polynomial(const T* poly, U z, std::size_t count) BOOST_MATH_NOEXCEPT(U)
0222 {
0223    return evaluate_polynomial(poly, U(z*z), count);
0224 }
0225 
0226 template <std::size_t N, class T, class V>
0227 inline V evaluate_even_polynomial(const T(&a)[N], const V& z) BOOST_MATH_NOEXCEPT(V)
0228 {
0229    return evaluate_polynomial(a, V(z*z));
0230 }
0231 
0232 template <std::size_t N, class T, class V>
0233 inline V evaluate_even_polynomial(const std::array<T,N>& a, const V& z) BOOST_MATH_NOEXCEPT(V)
0234 {
0235    return evaluate_polynomial(a, V(z*z));
0236 }
0237 //
0238 // Odd polynomials come next:
0239 //
0240 template <class T, class U>
0241 inline U evaluate_odd_polynomial(const T* poly, U z, std::size_t count) BOOST_MATH_NOEXCEPT(U)
0242 {
0243    return poly[0] + z * evaluate_polynomial(poly+1, U(z*z), count-1);
0244 }
0245 
0246 template <std::size_t N, class T, class V>
0247 inline V evaluate_odd_polynomial(const T(&a)[N], const V& z) BOOST_MATH_NOEXCEPT(V)
0248 {
0249    typedef std::integral_constant<int, N-1> tag_type;
0250    return a[0] + z * detail::evaluate_polynomial_c_imp(static_cast<const T*>(a) + 1, V(z*z), static_cast<tag_type const*>(nullptr));
0251 }
0252 
0253 template <std::size_t N, class T, class V>
0254 inline V evaluate_odd_polynomial(const std::array<T,N>& a, const V& z) BOOST_MATH_NOEXCEPT(V)
0255 {
0256    typedef std::integral_constant<int, N-1> tag_type;
0257    return a[0] + z * detail::evaluate_polynomial_c_imp(static_cast<const T*>(a.data()) + 1, V(z*z), static_cast<tag_type const*>(nullptr));
0258 }
0259 
0260 template <class T, class U, class V>
0261 V evaluate_rational(const T* num, const U* denom, const V& z_, std::size_t count) BOOST_MATH_NOEXCEPT(V);
0262 
0263 namespace detail{
0264 
0265 template <class T, class U, class V, class Tag>
0266 inline V evaluate_rational_c_imp(const T* num, const U* denom, const V& z, const Tag*) BOOST_MATH_NOEXCEPT(V)
0267 {
0268    return boost::math::tools::evaluate_rational(num, denom, z, Tag::value);
0269 }
0270 
0271 }
0272 //
0273 // Rational functions: numerator and denominator must be
0274 // equal in size.  These always have a for-loop and so may be less
0275 // efficient than evaluating a pair of polynomials. However, there
0276 // are some tricks we can use to prevent overflow that might otherwise
0277 // occur in polynomial evaluation, if z is large.  This is important
0278 // in our Lanczos code for example.
0279 //
0280 template <class T, class U, class V>
0281 V evaluate_rational(const T* num, const U* denom, const V& z_, std::size_t count) BOOST_MATH_NOEXCEPT(V)
0282 {
0283    V z(z_);
0284    V s1, s2;
0285    if(z <= 1)
0286    {
0287       s1 = static_cast<V>(num[count-1]);
0288       s2 = static_cast<V>(denom[count-1]);
0289       for(int i = (int)count - 2; i >= 0; --i)
0290       {
0291          s1 *= z;
0292          s2 *= z;
0293          s1 += num[i];
0294          s2 += denom[i];
0295       }
0296    }
0297    else
0298    {
0299       z = 1 / z;
0300       s1 = static_cast<V>(num[0]);
0301       s2 = static_cast<V>(denom[0]);
0302       for(unsigned i = 1; i < count; ++i)
0303       {
0304          s1 *= z;
0305          s2 *= z;
0306          s1 += num[i];
0307          s2 += denom[i];
0308       }
0309    }
0310    return s1 / s2;
0311 }
0312 
0313 template <std::size_t N, class T, class U, class V>
0314 inline V evaluate_rational(const T(&a)[N], const U(&b)[N], const V& z) BOOST_MATH_NOEXCEPT(V)
0315 {
0316    return detail::evaluate_rational_c_imp(a, b, z, static_cast<const std::integral_constant<int, N>*>(nullptr));
0317 }
0318 
0319 template <std::size_t N, class T, class U, class V>
0320 inline V evaluate_rational(const std::array<T,N>& a, const std::array<U,N>& b, const V& z) BOOST_MATH_NOEXCEPT(V)
0321 {
0322    return detail::evaluate_rational_c_imp(a.data(), b.data(), z, static_cast<std::integral_constant<int, N>*>(nullptr));
0323 }
0324 
0325 } // namespace tools
0326 } // namespace math
0327 } // namespace boost
0328 
0329 #endif // BOOST_MATH_TOOLS_RATIONAL_HPP
0330 
0331 
0332 
0333