Gyselalib++
 
Loading...
Searching...
No Matches
polynomial_evaluator.hpp
1#pragma once
2#include <algorithm>
3#include <array>
4#include <cmath>
5#include <random>
6
7#include <ddc/ddc.hpp>
8
9#include <sll/math_tools.hpp>
10
11#include "ddc_aliases.hpp"
12
17{
21 template <class Grid1D, std::size_t Degree>
23 {
24 public:
26 using Dim = Grid1D;
27
28 private:
29 std::array<double, Degree + 1> m_coeffs;
30 int const m_degree;
31 double const m_xN;
32
33 public:
40 template <class IdxRange>
41 Evaluator(IdxRange idx_range)
42 : m_degree(Degree)
43 , m_xN(std::max(std::abs(rmin(idx_range)), std::abs(rmax(idx_range))))
44 {
45 for (int i(0); i < m_degree + 1; ++i) {
46 m_coeffs[i] = double(rand() % 100) / 100.0;
47 }
48 }
49
55 double operator()(double const x) const noexcept
56 {
57 return eval(x, 0);
58 }
59
64 void operator()(ddc::ChunkSpan<double, ddc::DiscreteDomain<Grid1D>> chunk) const
65 {
66 auto const& idx_range = chunk.idx_range();
67
68 for (ddc::DiscreteElement<Grid1D> const i : idx_range) {
69 chunk(i) = eval(ddc::coordinate(i), 0);
70 }
71 }
72
79 double deriv(double const x, int const derivative) const noexcept
80 {
81 return eval(x, derivative);
82 }
83
89 void deriv(ddc::ChunkSpan<double, ddc::DiscreteDomain<Grid1D>> chunk, int const derivative)
90 const
91 {
92 auto const& idx_range = chunk.idx_range();
93
94 for (ddc::DiscreteElement<Grid1D> const i : idx_range) {
95 chunk(i) = eval(ddc::coordinate(i), derivative);
96 }
97 }
98
104 double max_norm(int diff = 0) const
105 {
106 return std::abs(deriv(m_xN, diff));
107 }
108
109 private:
110 double eval(double const x, int const derivative) const
111 {
112 double result(0.0);
113 int start = derivative < 0 ? 0 : derivative;
114 for (int i(start); i < m_degree + 1; ++i) {
115 double v = double(falling_factorial(i, derivative)) * std::pow(x, i - derivative);
116 result += m_coeffs[i] * v;
117 }
118 return result;
119 }
120
121 double falling_factorial(int i, int d) const
122 {
123 double c = 1.0;
124 if (d >= 0) {
125 for (int k(0); k < d; ++k) {
126 c *= (i - k);
127 }
128 } else {
129 for (int k(-1); k > d - 1; --k) {
130 c /= (i - k);
131 }
132 }
133 return c;
134 }
135 };
136};
An analytical evaluator to be used for exact comparisons in tests.
Definition polynomial_evaluator.hpp:23
void operator()(ddc::ChunkSpan< double, ddc::DiscreteDomain< Grid1D > > chunk) const
Evaluate the equation at the positions on which chunk is defined.
Definition polynomial_evaluator.hpp:64
Grid1D Dim
The grid dimension.
Definition polynomial_evaluator.hpp:26
double operator()(double const x) const noexcept
Evaluate the equation at x.
Definition polynomial_evaluator.hpp:55
void deriv(ddc::ChunkSpan< double, ddc::DiscreteDomain< Grid1D > > chunk, int const derivative) const
Evaluate the derivative of the equation at the positions on which chunk is defined.
Definition polynomial_evaluator.hpp:89
double deriv(double const x, int const derivative) const noexcept
Evaluate the derivative of the equation at x.
Definition polynomial_evaluator.hpp:79
Evaluator(IdxRange idx_range)
A constructor taking the range over which the evaluator will be applied.
Definition polynomial_evaluator.hpp:41
double max_norm(int diff=0) const
The maximum norm of this equation.
Definition polynomial_evaluator.hpp:104
A wrapper around a polynomial Evaluator that can be used in tests.
Definition polynomial_evaluator.hpp:17