How to use compensated horner evaluation scheme to get better accuracy when evaluating polynomials close to its roots
#include "../src/aerobus.h"
constexpr size_t NB_POINTS = 400;
template<typename P, typename T, bool compensated>
if constexpr (compensated) {
return P::template compensated_eval<T>(x);
} else {
return P::template eval<T>(x);
}
}
template<typename T>
DEVICE T exact_large(
const T& x) {
return pow_scalar<T, 5>(0.75 - x) * pow_scalar<T, 11>(1 - x);
}
template<typename T>
DEVICE T exact_small(
const T& x) {
return pow_scalar<T, 3>(x - 1);
}
template<typename P, typename T, bool compensated>
void run(T left, T right, const char *file_name, T (*exact)(const T&)) {
FILE *f = ::fopen(file_name, "w+");
T step = (right - left) / NB_POINTS;
T x = left;
for (size_t i = 0; i <= NB_POINTS; ++i) {
::fprintf(f, "%e %e %e\n", x, eval<P, T, compensated>(x), exact(x));
x += step;
}
::fclose(f);
}
int main() {
{
typename q64::template inject_constant_t<-1>,
pow_t<
pq64,
pq64::val<
typename q64::template inject_constant_t<-1>,
typename q64::one>, 11>
>;
using FLOAT = double;
run<P, FLOAT, false>(0.68, 1.15, "plots/large_sample_horner.dat", &exact_large);
run<P, FLOAT, true>(0.68, 1.15, "plots/large_sample_comp_horner.dat", &exact_large);
run<P, FLOAT, false>(0.74995, 0.75005, "plots/first_root_horner.dat", &exact_large);
run<P, FLOAT, true>(0.74995, 0.75005, "plots/first_root_comp_horner.dat", &exact_large);
run<P, FLOAT, false>(0.9935, 1.0065, "plots/second_root_horner.dat", &exact_large);
run<P, FLOAT, true>(0.9935, 1.0065, "plots/second_root_comp_horner.dat", &exact_large);
}
{
run<P, double, false>(1-0.00005, 1+0.00005, "plots/double.dat", &exact_small);
run<P, float, true>(1-0.00005, 1+0.00005, "plots/float_comp.dat", &exact_small);
}
}
#define INLINED
Definition aerobus.h:31
#define DEVICE
Definition aerobus.h:37
main namespace for all publicly exposed types or functions
typename X::enclosing_type::template mul_t< X, Y > mul_t
generic multiplication
Definition aerobus.h:2914
typename internal::pow< T, p, n >::type pow_t
p^n (as 'val' type in T)
Definition aerobus.h:3414
typename polynomial< Ring >::template val< typename Ring::template inject_constant_t< xs >... > make_int_polynomial_t
make a polynomial with coefficients in Ring
Definition aerobus.h:3043
32 bits signed integers, seen as a algebraic ring with related operations
Definition aerobus.h:1222
values in i64
Definition aerobus.h:1404
values (seen as types) in polynomial ring
Definition aerobus.h:1837
Definition aerobus.h:1807