mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
Coverage: improve zeta.hpp coverage and tests.
This commit is contained in:
@@ -152,27 +152,29 @@ T zeta_polynomial_series(T s, T sc, Policy const &)
|
||||
//
|
||||
BOOST_MATH_STD_USING
|
||||
int n = itrunc(T(log(boost::math::tools::epsilon<T>()) / -2));
|
||||
T sum = 0;
|
||||
T sum = 0; // LCOV_EXCL_LINE spurious miss as surrounding lines hit.
|
||||
T two_n = ldexp(T(1), n);
|
||||
int ej_sign = 1;
|
||||
int ej_sign = 1; // LCOV_EXCL_LINE spurious miss as surrounding lines hit.
|
||||
for(int j = 0; j < n; ++j)
|
||||
{
|
||||
sum += ej_sign * -two_n / pow(T(j + 1), s);
|
||||
ej_sign = -ej_sign;
|
||||
}
|
||||
T ej_sum = 1;
|
||||
T ej_term = 1;
|
||||
T ej_sum = 1; // LCOV_EXCL_LINE spurious miss as surrounding lines hit.
|
||||
T ej_term = 1; // LCOV_EXCL_LINE spurious miss as surrounding lines hit.
|
||||
for(int j = n; j <= 2 * n - 1; ++j)
|
||||
{
|
||||
sum += ej_sign * (ej_sum - two_n) / pow(T(j + 1), s);
|
||||
ej_sign = -ej_sign;
|
||||
ej_term *= 2 * n - j;
|
||||
ej_term /= j - n + 1;
|
||||
ej_sum += ej_term;
|
||||
ej_sum += ej_term; // LCOV_EXCL_LINE spurious miss as surrounding lines hit.
|
||||
}
|
||||
return -sum / (two_n * (-powm1(T(2), sc)));
|
||||
}
|
||||
|
||||
//
|
||||
// MP only, verified as covered by the full tests:
|
||||
// LCOV_EXCL_START
|
||||
template <class T, class Policy>
|
||||
T zeta_imp_prec(T s, T sc, const Policy& pol, const std::integral_constant<int, 0>&)
|
||||
{
|
||||
@@ -197,6 +199,7 @@ T zeta_imp_prec(T s, T sc, const Policy& pol, const std::integral_constant<int,
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
template <class T, class Policy>
|
||||
inline T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant<int, 53>&)
|
||||
@@ -372,13 +375,9 @@ inline T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant<in
|
||||
result = tools::evaluate_polynomial(P, T(s - 15)) / tools::evaluate_polynomial(Q, T(s - 15));
|
||||
result = 1 + exp(result);
|
||||
}
|
||||
else if(s < 56)
|
||||
{
|
||||
result = 1 + pow(T(2), -s);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 1;
|
||||
result = 1 + pow(T(2), -s);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -566,13 +565,9 @@ T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant<int, 64>&
|
||||
result = tools::evaluate_polynomial(P, T(s - 15)) / tools::evaluate_polynomial(Q, T(s - 15));
|
||||
result = 1 + exp(result);
|
||||
}
|
||||
else if(s < 63)
|
||||
{
|
||||
result = 1 + pow(T(2), -s);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 1;
|
||||
result = 1 + pow(T(2), -s);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -897,13 +892,9 @@ T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant<int, 113>
|
||||
result = tools::evaluate_polynomial(P, T(s - 30)) / tools::evaluate_polynomial(Q, T(s - 30));
|
||||
result = 1 + exp(result);
|
||||
}
|
||||
else if(s < 117)
|
||||
{
|
||||
result = 1 + pow(T(2), -s);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 1;
|
||||
result = 1 + pow(T(2), -s);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -930,11 +921,11 @@ T zeta_imp_odd_integer(int s, const T& sc, const Policy& pol, const std::false_t
|
||||
static BOOST_MATH_THREAD_LOCAL T results[50] = {};
|
||||
static BOOST_MATH_THREAD_LOCAL int digits = tools::digits<T>();
|
||||
// LCOV_EXCL_STOP
|
||||
int current_digits = tools::digits<T>();
|
||||
int current_digits = tools::digits<T>(); // LCOV_EXCL_LINE spurious miss as surrounding lines hit.
|
||||
if(digits != current_digits)
|
||||
{
|
||||
// Oh my precision has changed...
|
||||
is_init = false;
|
||||
is_init = false; // LCOV_EXCL_LINE variable precision MP case only, not included in coverage tests.
|
||||
}
|
||||
if(!is_init)
|
||||
{
|
||||
@@ -943,7 +934,7 @@ T zeta_imp_odd_integer(int s, const T& sc, const Policy& pol, const std::false_t
|
||||
for(unsigned k = 0; k < sizeof(results) / sizeof(results[0]); ++k)
|
||||
{
|
||||
T arg = k * 2 + 3;
|
||||
T c_arg = 1 - arg;
|
||||
T c_arg = 1 - arg; // LCOV_EXCL_LINE spurious miss as surrounding lines hit.
|
||||
results[k] = zeta_polynomial_series(arg, c_arg, pol);
|
||||
}
|
||||
}
|
||||
@@ -957,10 +948,7 @@ T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag)
|
||||
BOOST_MATH_STD_USING
|
||||
static const char* function = "boost::math::zeta<%1%>";
|
||||
if(sc == 0)
|
||||
return policies::raise_pole_error<T>(
|
||||
function,
|
||||
"Evaluation of zeta function at pole %1%",
|
||||
s, pol);
|
||||
return policies::raise_pole_error<T>(function, "Evaluation of zeta function at pole %1%", s, pol);
|
||||
T result;
|
||||
//
|
||||
// Trivial case:
|
||||
@@ -1003,7 +991,7 @@ T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag)
|
||||
#ifndef BOOST_MATH_NO_EXCEPTIONS
|
||||
}
|
||||
catch(const boost::math::rounding_error&){} // Just fall through, s is too large to round
|
||||
catch(const std::overflow_error&){}
|
||||
catch(const std::overflow_error&){} // LCOV_EXCL_LINE We can only get here for "strange" MP types with small exponents and very large digit counts.
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1026,8 +1014,13 @@ T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag)
|
||||
if(result > tools::log_max_value<T>())
|
||||
return sign(mult) * policies::raise_overflow_error<T>(function, nullptr, pol);
|
||||
result = exp(result);
|
||||
//
|
||||
// Whether this if branch can be triggered is very type dependent, we need
|
||||
// result to be just on the verge of overflow when /s/ is very close to a
|
||||
// half integer.
|
||||
//
|
||||
if(tools::max_value<T>() / fabs(mult) < result)
|
||||
return boost::math::sign(mult) * policies::raise_overflow_error<T>(function, nullptr, pol);
|
||||
return boost::math::sign(mult) * policies::raise_overflow_error<T>(function, nullptr, pol); // LCOV_EXCL_LINE
|
||||
result *= mult;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -170,6 +170,11 @@ void test_spots(T, const char* t)
|
||||
BOOST_CHECK_EQUAL(::boost::math::zeta(static_cast<T>(-10007)), std::numeric_limits<T>::infinity());
|
||||
BOOST_CHECK_EQUAL(::boost::math::zeta(static_cast<T>(-10009)), -std::numeric_limits<T>::infinity());
|
||||
}
|
||||
//
|
||||
// Coverage tests:
|
||||
//
|
||||
BOOST_CHECK_THROW(boost::math::zeta(static_cast<T>(1)), std::domain_error);
|
||||
BOOST_CHECK_EQUAL(boost::math::zeta(-boost::math::tools::max_value<T>()), static_cast<T>(0));
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user