Aerobus v1.2
Loading...
Searching...
No Matches
examples/compensated_horner.cpp

How to use compensated horner evaluation scheme to get better accuracy when evaluating polynomials close to its roots

See also
publication
// run with ./generate_comp_horner.sh in this directory
// that will compile and run this sample and plot all the generated data
#include "../src/aerobus.h"
using namespace aerobus; // NOLINT
constexpr size_t NB_POINTS = 400;
template<typename P, typename T, bool compensated>
DEVICE INLINED T eval(const T& x) {
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() {
{
// (0.75 - x)^5 * (1 - x)^11
using P = mul_t<
typename q64::template inject_constant_t<-1>,
q64::val<i64::val<3>, i64::val<4>>>, 5>,
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);
}
{
// (x - 1) ^ 3
using P = make_int_polynomial_t<i32, 1, -3, 3, -1>;
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