update boost
This commit is contained in:
@@ -6,9 +6,11 @@
|
||||
#ifndef BOOST_MATH_TOOLS_CONDITION_NUMBERS_HPP
|
||||
#define BOOST_MATH_TOOLS_CONDITION_NUMBERS_HPP
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <boost/math/differentiation/finite_difference.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
|
||||
namespace boost::math::tools {
|
||||
namespace boost { namespace math { namespace tools {
|
||||
|
||||
template<class Real, bool kahan=true>
|
||||
class summation_condition_number {
|
||||
@@ -26,7 +28,7 @@ public:
|
||||
using std::abs;
|
||||
// No need to Kahan the l1 calc; it's well conditioned:
|
||||
m_l1 += abs(x);
|
||||
if constexpr(kahan)
|
||||
BOOST_IF_CONSTEXPR (kahan)
|
||||
{
|
||||
Real y = x - m_c;
|
||||
Real t = m_sum + y;
|
||||
@@ -49,7 +51,7 @@ public:
|
||||
// but is this sensible? More important is it useful?
|
||||
// In addition, it might change the condition number.
|
||||
|
||||
[[nodiscard]] Real operator()() const
|
||||
Real operator()() const
|
||||
{
|
||||
using std::abs;
|
||||
if (m_sum == Real(0) && m_l1 != Real(0))
|
||||
@@ -59,7 +61,7 @@ public:
|
||||
return m_l1/abs(m_sum);
|
||||
}
|
||||
|
||||
[[nodiscard]] Real sum() const
|
||||
Real sum() const
|
||||
{
|
||||
// Higham, 1993, "The Accuracy of Floating Point Summation":
|
||||
// "In [17] and [18], Kahan describes a variation of compensated summation in which the final sum is also corrected
|
||||
@@ -67,7 +69,7 @@ public:
|
||||
return m_sum + m_c;
|
||||
}
|
||||
|
||||
[[nodiscard]] Real l1_norm() const
|
||||
Real l1_norm() const
|
||||
{
|
||||
return m_l1;
|
||||
}
|
||||
@@ -79,7 +81,7 @@ private:
|
||||
};
|
||||
|
||||
template<class F, class Real>
|
||||
auto evaluation_condition_number(F const & f, Real const & x)
|
||||
Real evaluation_condition_number(F const & f, Real const & x)
|
||||
{
|
||||
using std::abs;
|
||||
using std::isnan;
|
||||
@@ -93,15 +95,18 @@ auto evaluation_condition_number(F const & f, Real const & x)
|
||||
}
|
||||
bool caught_exception = false;
|
||||
Real fp;
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
fp = finite_difference_derivative(f, x);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
caught_exception = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (isnan(fp) || caught_exception)
|
||||
{
|
||||
// Check if the right derivative exists:
|
||||
@@ -135,5 +140,5 @@ auto evaluation_condition_number(F const & f, Real const & x)
|
||||
return abs(x*fp/fx);
|
||||
}
|
||||
|
||||
}
|
||||
}}} // Namespaces
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user