Chris@102: Chris@102: /////////////////////////////////////////////////////////////////////////////// Chris@102: // Copyright 2013 Nikhar Agrawal Chris@102: // Copyright 2013 Christopher Kormanyos Chris@102: // Copyright 2014 John Maddock Chris@102: // Copyright 2013 Paul Bristow Chris@102: // Distributed under the Boost Chris@102: // Software License, Version 1.0. (See accompanying file Chris@102: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: Chris@102: #ifndef _BOOST_POLYGAMMA_2013_07_30_HPP_ Chris@102: #define _BOOST_POLYGAMMA_2013_07_30_HPP_ Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: namespace boost { namespace math { Chris@102: Chris@102: Chris@102: template Chris@102: inline typename tools::promote_args::type polygamma(const int n, T x, const Policy& pol) Chris@102: { Chris@102: // Chris@102: // Filter off special cases right at the start: Chris@102: // Chris@102: if(n == 0) Chris@102: return boost::math::digamma(x, pol); Chris@102: if(n == 1) Chris@102: return boost::math::trigamma(x, pol); Chris@102: // Chris@102: // We've found some standard library functions to misbehave if any FPU exception flags Chris@102: // are set prior to their call, this code will clear those flags, then reset them Chris@102: // on exit: Chris@102: // Chris@102: BOOST_FPU_EXCEPTION_GUARD Chris@102: // Chris@102: // The type of the result - the common type of T and U after Chris@102: // any integer types have been promoted to double: Chris@102: // Chris@102: typedef typename tools::promote_args::type result_type; Chris@102: // Chris@102: // The type used for the calculation. This may be a wider type than Chris@102: // the result in order to ensure full precision: Chris@102: // Chris@102: typedef typename policies::evaluation::type value_type; Chris@102: // Chris@102: // The type of the policy to forward to the actual implementation. Chris@102: // We disable promotion of float and double as that's [possibly] Chris@102: // happened already in the line above. Also reset to the default Chris@102: // any policies we don't use (reduces code bloat if we're called Chris@102: // multiple times with differing policies we don't actually use). Chris@102: // Also normalise the type, again to reduce code bloat in case we're Chris@102: // called multiple times with functionally identical policies that happen Chris@102: // to be different types. Chris@102: // Chris@102: typedef typename policies::normalise< Chris@102: Policy, Chris@102: policies::promote_float, Chris@102: policies::promote_double, Chris@102: policies::discrete_quantile<>, Chris@102: policies::assert_undefined<> >::type forwarding_policy; Chris@102: // Chris@102: // Whew. Now we can make the actual call to the implementation. Chris@102: // Arguments are explicitly cast to the evaluation type, and the result Chris@102: // passed through checked_narrowing_cast which handles things like overflow Chris@102: // according to the policy passed: Chris@102: // Chris@102: return policies::checked_narrowing_cast( Chris@102: detail::polygamma_imp(n, static_cast(x), forwarding_policy()), Chris@102: "boost::math::polygamma<%1%>(int, %1%)"); Chris@102: } Chris@102: Chris@102: template Chris@102: inline typename tools::promote_args::type polygamma(const int n, T x) Chris@102: { Chris@102: return boost::math::polygamma(n, x, policies::policy<>()); Chris@102: } Chris@102: Chris@102: } } // namespace boost::math Chris@102: Chris@102: #endif // _BOOST_BERNOULLI_2013_05_30_HPP_ Chris@102: