上次我们研究了如何提高 Whittaker-Shannon 插值的准确性,其中用户 njuffa 证明了明智地使用sin_pi
可以大大提高计算的准确性
现在我正在努力准确评估
我用于评估此导数的代码在这里,为简洁起见,相关部分在这里介绍:
Real prime(Real t) const {
using boost::math::constants::pi;
using std::isfinite;
using std::floor;
Real x = (t - m_t0)/m_h;
// The integer branch is not a problem:
if (ceil(x) == x) {
Real s = 0;
long j = static_cast<long>(x);
long n = m_y.size();
for (long i = 0; i < n; ++i)
{
if (j - i != 0)
{
s += m_y[i]/(j-i);
}
// else derivative of sinc at zero is zero.
}
if (j & 1) {
s /= -m_h;
} else {
s /= m_h;
}
return s;
}
Real z = x;
auto it = m_y.begin();
Real cospix = boost::math::cos_pi(x);
Real sinpix = boost::math::sin_pi(x);
Real s = 0;
auto end = m_y.end();
while(it != end)
{
s += (*it++)*(pi<Real>()*z*cospix - sinpix)/(z*z);
z -= 1;
}
return s/(pi<Real>()*m_h);
}
我希望实现大约 10 个 ULP 的错误,但这会产生大约 1000 个 ULP 的错误,这是比特预算的相当大的一部分。我相信错误的来源来自该(pi<Real>()*z*cospix - sinpix)/(z*z)
术语,但我无法重新排列它以获得更好的准确性。
有没有办法让这个更准确?