diff options
Diffstat (limited to 'boost/math/special_functions/zeta.hpp')
-rw-r--r-- | boost/math/special_functions/zeta.hpp | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/boost/math/special_functions/zeta.hpp b/boost/math/special_functions/zeta.hpp index 011182718e..b176f20176 100644 --- a/boost/math/special_functions/zeta.hpp +++ b/boost/math/special_functions/zeta.hpp @@ -10,6 +10,7 @@ #pragma once #endif +#include <boost/math/special_functions/math_fwd.hpp> #include <boost/math/tools/precision.hpp> #include <boost/math/tools/series.hpp> #include <boost/math/tools/big_constant.hpp> @@ -378,7 +379,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<64>&) BOOST_MATH_BIG_CONSTANT(T, 64, -0.279496685273033761927e-4), }; static const T Q[7] = { - BOOST_MATH_BIG_CONSTANT(T, 64, 1), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), BOOST_MATH_BIG_CONSTANT(T, 64, -0.30425480068225790522), BOOST_MATH_BIG_CONSTANT(T, 64, 0.050052748580371598736), BOOST_MATH_BIG_CONSTANT(T, 64, -0.00519355671064700627862), @@ -406,7 +407,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<64>&) BOOST_MATH_BIG_CONSTANT(T, 64, 0.700867470265983665042e-5), }; static const T Q[7] = { - BOOST_MATH_BIG_CONSTANT(T, 64, 1), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), BOOST_MATH_BIG_CONSTANT(T, 64, 0.259385759149531030085), BOOST_MATH_BIG_CONSTANT(T, 64, 0.0373974962106091316854), BOOST_MATH_BIG_CONSTANT(T, 64, 0.00332735159183332820617), @@ -432,7 +433,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<64>&) BOOST_MATH_BIG_CONSTANT(T, 64, 0.540319769113543934483e-7), }; static const T Q[8] = { - 1, + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), BOOST_MATH_BIG_CONSTANT(T, 64, 0.286577739726542730421), BOOST_MATH_BIG_CONSTANT(T, 64, 0.0447355811517733225843), BOOST_MATH_BIG_CONSTANT(T, 64, 0.00430125107610252363302), @@ -458,7 +459,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<64>&) BOOST_MATH_BIG_CONSTANT(T, 64, -0.252884970740994069582e-5), }; static const T Q[9] = { - 1, + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), BOOST_MATH_BIG_CONSTANT(T, 64, 1.01300131390690459085), BOOST_MATH_BIG_CONSTANT(T, 64, 0.387898115758643503827), BOOST_MATH_BIG_CONSTANT(T, 64, 0.0695071490045701135188), @@ -487,7 +488,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<64>&) BOOST_MATH_BIG_CONSTANT(T, 64, -0.815696314790853893484e-8), }; static const T Q[9] = { - 1, + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), BOOST_MATH_BIG_CONSTANT(T, 64, 0.525765665400123515036), BOOST_MATH_BIG_CONSTANT(T, 64, 0.10852641753657122787), BOOST_MATH_BIG_CONSTANT(T, 64, 0.0115669945375362045249), @@ -516,7 +517,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<64>&) BOOST_MATH_BIG_CONSTANT(T, 64, -0.145392555873022044329e-9), }; static const T Q[10] = { - 1, + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), BOOST_MATH_BIG_CONSTANT(T, 64, 0.205135978585281988052), BOOST_MATH_BIG_CONSTANT(T, 64, 0.0192359357875879453602), BOOST_MATH_BIG_CONSTANT(T, 64, 0.00111496452029715514119), @@ -554,7 +555,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<113>&) // Max error found at long double precision: 7.281332e-31 static const T P[10] = { - BOOST_MATH_BIG_CONSTANT(T, 113, -1), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.0), BOOST_MATH_BIG_CONSTANT(T, 113, -0.0353008629988648122808504280990313668), BOOST_MATH_BIG_CONSTANT(T, 113, 0.0107795651204927743049369868548706909), BOOST_MATH_BIG_CONSTANT(T, 113, 0.000523961870530500751114866884685172975), @@ -566,7 +567,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<113>&) BOOST_MATH_BIG_CONSTANT(T, 113, 0.113103113698388531428914333768142527e-10), }; static const T Q[11] = { - BOOST_MATH_BIG_CONSTANT(T, 113, 1), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), BOOST_MATH_BIG_CONSTANT(T, 113, -0.387483472099602327112637481818565459), BOOST_MATH_BIG_CONSTANT(T, 113, 0.0802265315091063135271497708694776875), BOOST_MATH_BIG_CONSTANT(T, 113, -0.0110727276164171919280036408995078164), @@ -600,7 +601,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<113>&) BOOST_MATH_BIG_CONSTANT(T, 113, -0.835774625259919268768735944711219256e-11), }; static const T Q[11] = { - BOOST_MATH_BIG_CONSTANT(T, 113, 1), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), BOOST_MATH_BIG_CONSTANT(T, 113, 0.316661751179735502065583176348292881), BOOST_MATH_BIG_CONSTANT(T, 113, 0.0540401806533507064453851182728635272), BOOST_MATH_BIG_CONSTANT(T, 113, 0.00598621274107420237785899476374043797), @@ -636,7 +637,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<113>&) BOOST_MATH_BIG_CONSTANT(T, 113, 0.340169592866058506675897646629036044e-12), }; static const T Q[12] = { - BOOST_MATH_BIG_CONSTANT(T, 113, 1), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), BOOST_MATH_BIG_CONSTANT(T, 113, 0.363755247765087100018556983050520554), BOOST_MATH_BIG_CONSTANT(T, 113, 0.0696581979014242539385695131258321598), BOOST_MATH_BIG_CONSTANT(T, 113, 0.00882208914484611029571547753782014817), @@ -675,7 +676,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<113>&) BOOST_MATH_BIG_CONSTANT(T, 113, -0.15090220092460596872172844424267351e-10), }; static const T Q[14] = { - BOOST_MATH_BIG_CONSTANT(T, 113, 1), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), BOOST_MATH_BIG_CONSTANT(T, 113, 1.69490865837142338462982225731926485), BOOST_MATH_BIG_CONSTANT(T, 113, 1.22697696630994080733321401255942464), BOOST_MATH_BIG_CONSTANT(T, 113, 0.495409420862526540074366618006341533), @@ -715,7 +716,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<113>&) BOOST_MATH_BIG_CONSTANT(T, 113, -0.420204769185233365849253969097184005e-12), }; static const T Q[14] = { - BOOST_MATH_BIG_CONSTANT(T, 113, 1), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), BOOST_MATH_BIG_CONSTANT(T, 113, 0.97663511666410096104783358493318814), BOOST_MATH_BIG_CONSTANT(T, 113, 0.40878780231201806504987368939673249), BOOST_MATH_BIG_CONSTANT(T, 113, 0.0963890666609396058945084107597727252), @@ -753,7 +754,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<113>&) BOOST_MATH_BIG_CONSTANT(T, 113, -0.289187187441625868404494665572279364e-15), }; static const T Q[14] = { - BOOST_MATH_BIG_CONSTANT(T, 113, 1), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), BOOST_MATH_BIG_CONSTANT(T, 113, 0.427310044448071818775721584949868806), BOOST_MATH_BIG_CONSTANT(T, 113, 0.074602514873055756201435421385243062), BOOST_MATH_BIG_CONSTANT(T, 113, 0.00688651562174480772901425121653945942), @@ -792,7 +793,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<113>&) BOOST_MATH_BIG_CONSTANT(T, 113, -0.402663128248642002351627980255756363e-16), }; static const T Q[14] = { - BOOST_MATH_BIG_CONSTANT(T, 113, 1), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), BOOST_MATH_BIG_CONSTANT(T, 113, 0.311288325355705609096155335186466508), BOOST_MATH_BIG_CONSTANT(T, 113, 0.0438318468940415543546769437752132748), BOOST_MATH_BIG_CONSTANT(T, 113, 0.00374396349183199548610264222242269536), @@ -831,7 +832,7 @@ T zeta_imp_prec(T s, T sc, const Policy&, const mpl::int_<113>&) BOOST_MATH_BIG_CONSTANT(T, 113, -0.376708747782400769427057630528578187e-19), }; static const T Q[16] = { - BOOST_MATH_BIG_CONSTANT(T, 113, 1), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), BOOST_MATH_BIG_CONSTANT(T, 113, 0.205076752981410805177554569784219717), BOOST_MATH_BIG_CONSTANT(T, 113, 0.0202526722696670378999575738524540269), BOOST_MATH_BIG_CONSTANT(T, 113, 0.001278305290005994980069466658219057), @@ -866,15 +867,16 @@ template <class T, class Policy, class Tag> T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag) { BOOST_MATH_STD_USING - if(s == 1) + static const char* function = "boost::math::zeta<%1%>"; + if(sc == 0) return policies::raise_pole_error<T>( - "boost::math::zeta<%1%>", + function, "Evaluation of zeta function at pole %1%", s, pol); T result; - if(s == 0) + if(fabs(s) < tools::root_epsilon<T>()) { - result = -0.5; + result = -0.5f - constants::log_root_two_pi<T, Policy>() * s; } else if(s < 0) { @@ -883,10 +885,25 @@ T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag) result = 0; else { - result = boost::math::sin_pi(0.5f * sc, pol) - * 2 * pow(2 * constants::pi<T>(), -s) - * boost::math::tgamma(s, pol) - * zeta_imp(s, sc, pol, tag); + if(s > max_factorial<T>::value) + { + T mult = boost::math::sin_pi(0.5f * sc, pol) * 2 * zeta_imp(s, sc, pol, tag); + result = boost::math::lgamma(s, pol); + result -= s * log(2 * constants::pi<T>()); + if(result > tools::log_max_value<T>()) + return sign(mult) * policies::raise_overflow_error<T>(function, 0, pol); + result = exp(result); + if(tools::max_value<T>() / fabs(mult) < result) + return boost::math::sign(mult) * policies::raise_overflow_error<T>(function, 0, pol); + result *= mult; + } + else + { + result = boost::math::sin_pi(0.5f * sc, pol) + * 2 * pow(2 * constants::pi<T>(), -s) + * boost::math::tgamma(s, pol) + * zeta_imp(s, sc, pol, tag); + } } } else |