MARLEY (Model of Argon Reaction Low Energy Yields) v2.0.0
A Monte Carlo event generator for tens-of-MeV neutrino interactions
Loading...
Searching...
No Matches
marley::ChebyshevInterpolatingFunction Class Reference

Approximates a 1D function using Chebyshev points. More...

#include <ChebyshevInterpolatingFunction.hh>

Inheritance diagram for marley::ChebyshevInterpolatingFunction:
marley::InterpolatingFunction

Public Member Functions

 ChebyshevInterpolatingFunction (const std::function< double(double)> &func, double x_min, double x_max, size_t N=0)
 
ChebyshevInterpolatingFunction cdf () const
 
const std::vector< double > & chebyshev_coeffs () const
 
double evaluate (double x) const override
 Approximates the represented function using the barycentric formula.
 
const std::vector< double > & Fs () const
 
double integral () const
 
int N () const
 
double x_max () const
 
double x_min () const
 
const std::vector< double > & Xs () const
 
- Public Member Functions inherited from marley::InterpolatingFunction
 InterpolatingFunction (double x_min, double x_max)
 

Protected Member Functions

 ChebyshevInterpolatingFunction ()
 Default constructor used by cdf()
 
double chebyshev_point (size_t j) const
 For a given N, returns the x position of the jth Chebyshev point (of the second kind)
 
void compute_integral ()
 
- Protected Member Functions inherited from marley::InterpolatingFunction
 InterpolatingFunction ()
 Allows construction by derived classes without immediately defining the bounds of the interpolation range.
 

Protected Attributes

std::vector< double > chebyshev_coeffs_
 Coefficients of the Chebyshev expansion of this function.
 
std::vector< double > Fs_
 Function values at the grid points.
 
std::vector< int > ifac_
 
double integral_
 Approximate integral of the function on [x_min_, x_max_].
 
size_t N_
 Grid size parameter (N + 1 total points)
 
std::vector< double > wsave_
 
std::vector< double > Xs_
 Chebyshev points at which the function was evaluated.
 
- Protected Attributes inherited from marley::InterpolatingFunction
double x_max_
 Upper bound of the interpolation range.
 
double x_min_
 Lower bound of the interpolation range.
 

Static Protected Attributes

static constexpr size_t N_MAX_ = 65536u
 Maximum allowed value of the grid size parameter.
 

Detailed Description

Approximates a 1D function using Chebyshev points.

Definition at line 29 of file ChebyshevInterpolatingFunction.hh.

Constructor & Destructor Documentation

◆ ChebyshevInterpolatingFunction() [1/2]

marley::ChebyshevInterpolatingFunction::ChebyshevInterpolatingFunction ( const std::function< double(double)> & func,
double x_min,
double x_max,
size_t N = 0 )
Todo
PRINT WARNING MESSAGE

Definition at line 34 of file ChebyshevInterpolatingFunction.cc.

37 : marley::InterpolatingFunction( x_min, x_max )
38{
39 bool ok;
40
41 if ( N != 0 ) {
42 ok = true;
43 N_ = N;
44 }
45 else {
46 ok = false;
47 N_ = 1;
48 }
49
50 // Adaptively find a good grid size
51 // @todo add more explanation
52 do {
53
54 if ( !ok ) N_ *= 2;
55
56 //std::cout << "N = " << N_ << '\n';
57
58 // @todo optimize this
59 Xs_.clear();
60 Fs_.clear();
61
62 for ( size_t j = 0; j <= N_; ++j ) {
63 double x = chebyshev_point( j );
64 double f = func(x);
65 Xs_.push_back( x );
66 Fs_.push_back( f );
67 }
68
70 wsave_ = std::vector<double>(3*Fs_.size() + 15, 0.);
71 ifac_ = std::vector<int>(Fs_.size() / 2, 0);
72
73 int my_size = Fs_.size();
74 costi( &my_size, wsave_.data(), ifac_.data() );
75 cost( &my_size, chebyshev_coeffs_.data(), wsave_.data(), ifac_.data() );
76
77 double biggest_coeff = *std::max_element(chebyshev_coeffs_.cbegin(),
78 chebyshev_coeffs_.cend(), [](double left, double right) -> double
79 { return std::abs(left) < std::abs(right); });
80
81 double upper_limit = 2. * std::abs( biggest_coeff ) * MY_EPSILON;
82
83 double last_coeff_mag = std::abs( chebyshev_coeffs_.back() );
84 double next_to_last_coeff_mag = std::abs(
85 chebyshev_coeffs_.at( chebyshev_coeffs_.size() - 2 ));
86 if ( last_coeff_mag < upper_limit && next_to_last_coeff_mag < upper_limit )
87 {
88 ok = true;
89 }
90
91 if ( N_ >= N_MAX_ ) {
93 ok = true;
94 }
95
96 } while ( !ok );
97
98 // Normalize the Chebyshev coefficients by dividing by N
99 for (double& d : chebyshev_coeffs_) d /= N_;
100
101 compute_integral();
102}
static constexpr size_t N_MAX_
Maximum allowed value of the grid size parameter.
size_t N_
Grid size parameter (N + 1 total points)
double chebyshev_point(size_t j) const
For a given N, returns the x position of the jth Chebyshev point (of the second kind)
std::vector< double > Xs_
Chebyshev points at which the function was evaluated.
std::vector< double > chebyshev_coeffs_
Coefficients of the Chebyshev expansion of this function.
std::vector< double > Fs_
Function values at the grid points.

References chebyshev_coeffs_, chebyshev_point(), Fs_, N_, N_MAX_, and Xs_.

◆ ChebyshevInterpolatingFunction() [2/2]

marley::ChebyshevInterpolatingFunction::ChebyshevInterpolatingFunction ( )
inlineprotected

Default constructor used by cdf()

Definition at line 85 of file ChebyshevInterpolatingFunction.hh.

85{};

Member Function Documentation

◆ cdf()

marley::ChebyshevInterpolatingFunction marley::ChebyshevInterpolatingFunction::cdf ( ) const

Definition at line 122 of file ChebyshevInterpolatingFunction.cc.

123{
124 marley::ChebyshevInterpolatingFunction result;
125 result.N_ = this->N_ + 1;
126 result.x_min_ = this->x_min_;
127 result.x_max_ = this->x_max_;
128
129 double beta_0 = this->chebyshev_coeffs_.at(0);
130 beta_0 += -0.5 * this->chebyshev_coeffs_.at(1);
131 for ( size_t j = 2; j <= this->N_; ++j ) {
132 beta_0 += 2.*this->chebyshev_coeffs_.at(j)
133 * std::pow(-1.0, j + 1) / (j*j - 1.0);
134 }
135
136 result.chebyshev_coeffs_.push_back( beta_0 );
137 for ( size_t k = 1; k < this->N_; ++k ) {
138 double ak_minus_one = this->chebyshev_coeffs_.at( k - 1 );
139 double ak_plus_one = this->chebyshev_coeffs_.at( k + 1 );
140 result.chebyshev_coeffs_.push_back(
141 (ak_minus_one - ak_plus_one) / (2 * k) );
142 }
143 result.chebyshev_coeffs_.push_back( this->chebyshev_coeffs_.at( N_ - 1 )
144 / (2 * N_) );
145 result.chebyshev_coeffs_.push_back( this->chebyshev_coeffs_.at( N_ )
146 / (2 * (N_ + 1)) );
147
148 for (double& d : result.chebyshev_coeffs_) d *= (x_max_ - x_min_) / 2.;
149
150 result.compute_integral();
151
152 for ( size_t j = 0; j <= result.N_; ++j ) {
153 double x = result.chebyshev_point( j );
154 result.Xs_.push_back( x );
155 }
156
157 result.wsave_ = std::vector<double>(
158 3*result.chebyshev_coeffs_.size() + 15, 0.);
159 result.ifac_ = std::vector<int>(result.chebyshev_coeffs_.size() / 2, 0);
160
161 int my_size = result.chebyshev_coeffs_.size();
162 result.Fs_ = result.chebyshev_coeffs_;
163 costi( &my_size, result.wsave_.data(), result.ifac_.data() );
164 cost( &my_size, result.Fs_.data(), result.wsave_.data(), result.ifac_.data() );
165 for (double& d : result.Fs_) d *= 0.5;
166
167 return result;
168}
double x_max_
Upper bound of the interpolation range.
double x_min_
Lower bound of the interpolation range.

◆ chebyshev_coeffs()

const std::vector< double > & marley::ChebyshevInterpolatingFunction::chebyshev_coeffs ( ) const
inline

Definition at line 66 of file ChebyshevInterpolatingFunction.hh.

67 { return chebyshev_coeffs_; }

◆ chebyshev_point()

double marley::ChebyshevInterpolatingFunction::chebyshev_point ( size_t j) const
inlineprotected

For a given N, returns the x position of the jth Chebyshev point (of the second kind)

Todo
If needed for speed, consider caching the std::cos evaluations used here

Definition at line 113 of file ChebyshevInterpolatingFunction.hh.

113 {
114 // jth Chebyshev point (of the second kind) on [-1, 1]
115 double x = std::cos( static_cast<double>(marley_utils::pi * j) / N_ );
116 // Affine transformation to [x_min_, x_max_] (primed basis)
117 double x_prime = (( x_max_ - x_min_ )*x + ( x_max_ + x_min_ )) / 2.;
118 return x_prime;
119 }

References N_, marley::InterpolatingFunction::x_max_, and marley::InterpolatingFunction::x_min_.

Referenced by ChebyshevInterpolatingFunction().

◆ compute_integral()

void marley::ChebyshevInterpolatingFunction::compute_integral ( )
protected

Definition at line 104 of file ChebyshevInterpolatingFunction.cc.

104 {
105 // Compute the integral over [x_min_, x_max_] via Clenshaw-Curtis
106 // quadrature
107 integral_ = 0.;
108 for (size_t k = 0; k <= N_; k += 2) {
109 // Only even Chebyshev polynomials contribute to this integral
110 double term = chebyshev_coeffs_.at( k ) * 2.0 / ( 1. - std::pow(k, 2) );
111 if ( k == 0 || k == N_ ) term /= 2.;
112 integral_ += term;
113 }
114
115 // Extra factor to account for integration over [x_min_, x_max_] instead
116 // of the standard interval [-1, 1] for the Chebyshev polynomials
117 integral_ *= (x_max_ - x_min_) / 2.;
118}
double integral_
Approximate integral of the function on [x_min_, x_max_].

◆ evaluate()

double marley::ChebyshevInterpolatingFunction::evaluate ( double x) const
inlineoverridevirtual

Approximates the represented function using the barycentric formula.

Implements marley::InterpolatingFunction.

Definition at line 39 of file ChebyshevInterpolatingFunction.hh.

39 {
40 double numer = 0.;
41 double denom = 0.;
42 double w_j = -1.;
43 for ( size_t j = 0; j <= N_; ++j ) {
44 w_j = -w_j; // w_j = (-1)^(j)
45 double x_j = Xs_.at( j );
46 double f_j = Fs_.at( j );
47 // If the requested x value is exactly equal to one
48 // of the grid points where we previously evaluated the
49 // function, then just return that
50 if ( x_j == x ) return f_j;
51
52 double temp = w_j / ( x - x_j );
53 if ( j == 0 || j == N_ ) temp /= 2.;
54 denom += temp;
55 numer += temp * f_j;
56 }
57
58 double px = numer / denom;
59 return px;
60 }

References Fs_, N_, and Xs_.

◆ Fs()

const std::vector< double > & marley::ChebyshevInterpolatingFunction::Fs ( ) const
inline

Definition at line 69 of file ChebyshevInterpolatingFunction.hh.

70 { return Fs_; }

◆ integral()

double marley::ChebyshevInterpolatingFunction::integral ( ) const
inline

Definition at line 64 of file ChebyshevInterpolatingFunction.hh.

64{ return integral_; };

◆ N()

int marley::ChebyshevInterpolatingFunction::N ( ) const
inline

Definition at line 75 of file ChebyshevInterpolatingFunction.hh.

75{ return N_; }

◆ x_max()

double marley::ChebyshevInterpolatingFunction::x_max ( ) const
inline

Definition at line 80 of file ChebyshevInterpolatingFunction.hh.

80{ return x_max_; }

◆ x_min()

double marley::ChebyshevInterpolatingFunction::x_min ( ) const
inline

Definition at line 79 of file ChebyshevInterpolatingFunction.hh.

79{ return x_min_; }

◆ Xs()

const std::vector< double > & marley::ChebyshevInterpolatingFunction::Xs ( ) const
inline

Definition at line 72 of file ChebyshevInterpolatingFunction.hh.

73 { return Xs_; }

Member Data Documentation

◆ chebyshev_coeffs_

std::vector<double> marley::ChebyshevInterpolatingFunction::chebyshev_coeffs_
protected

Coefficients of the Chebyshev expansion of this function.

Definition at line 103 of file ChebyshevInterpolatingFunction.hh.

Referenced by ChebyshevInterpolatingFunction().

◆ Fs_

std::vector<double> marley::ChebyshevInterpolatingFunction::Fs_
protected

Function values at the grid points.

Definition at line 100 of file ChebyshevInterpolatingFunction.hh.

Referenced by ChebyshevInterpolatingFunction(), and evaluate().

◆ ifac_

std::vector<int> marley::ChebyshevInterpolatingFunction::ifac_
protected

Definition at line 107 of file ChebyshevInterpolatingFunction.hh.

◆ integral_

double marley::ChebyshevInterpolatingFunction::integral_
protected

Approximate integral of the function on [x_min_, x_max_].

Definition at line 94 of file ChebyshevInterpolatingFunction.hh.

◆ N_

size_t marley::ChebyshevInterpolatingFunction::N_
protected

Grid size parameter (N + 1 total points)

Definition at line 91 of file ChebyshevInterpolatingFunction.hh.

Referenced by ChebyshevInterpolatingFunction(), chebyshev_point(), and evaluate().

◆ N_MAX_

size_t marley::ChebyshevInterpolatingFunction::N_MAX_ = 65536u
staticconstexprprotected

Maximum allowed value of the grid size parameter.

Definition at line 88 of file ChebyshevInterpolatingFunction.hh.

Referenced by ChebyshevInterpolatingFunction().

◆ wsave_

std::vector<double> marley::ChebyshevInterpolatingFunction::wsave_
protected

Definition at line 106 of file ChebyshevInterpolatingFunction.hh.

◆ Xs_

std::vector<double> marley::ChebyshevInterpolatingFunction::Xs_
protected

Chebyshev points at which the function was evaluated.

Definition at line 97 of file ChebyshevInterpolatingFunction.hh.

Referenced by ChebyshevInterpolatingFunction(), and evaluate().


The documentation for this class was generated from the following files: