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
ChebyshevInterpolatingFunction.hh
1
4//
5// This file is part of MARLEY (Model of Argon Reaction Low Energy Yields)
6//
7// MARLEY is free software: you can redistribute it and/or modify it under the
8// terms of version 3 of the GNU General Public License as published by the
9// Free Software Foundation.
10//
11// For the full text of the license please see COPYING or
12// visit http://opensource.org/licenses/GPL-3.0
13//
14// Please respect the MCnet academic usage guidelines. See GUIDELINES
15// or visit https://www.montecarlonet.org/GUIDELINES for details.
16
17#pragma once
18#include <functional>
19#include <vector>
20
21#include "marley/InterpolatingFunction.hh"
22
23namespace marley {
24
25 // Default Chebyshev grid size to use (when not using adaptive sizing)
26 constexpr size_t DEFAULT_N_CHEBYSHEV = 64u;
27
29 class ChebyshevInterpolatingFunction : public InterpolatingFunction {
30
31 public:
32
33 // N = 0 triggers adaptive grid sizing
34 ChebyshevInterpolatingFunction( const std::function<double(double)>& func,
35 double x_min, double x_max, size_t N = 0 );
36
39 inline double evaluate( double x ) const override {
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 }
61
62 // @brief Returns the integral of this function on the interval [x_min_,
63 // x_max_]
64 inline double integral() const { return integral_; };
65
66 inline const std::vector<double>& chebyshev_coeffs() const
67 { return chebyshev_coeffs_; }
68
69 inline const std::vector<double>& Fs() const
70 { return Fs_; }
71
72 inline const std::vector<double>& Xs() const
73 { return Xs_; }
74
75 inline int N() const { return N_; }
76
78
79 inline double x_min() const { return x_min_; }
80 inline double x_max() const { return x_max_; }
81
82 protected:
83
86
88 static constexpr size_t N_MAX_ = 65536u; // 16 adaptive iterations
89
91 size_t N_;
92
94 double integral_;
95
97 std::vector<double> Xs_;
98
100 std::vector<double> Fs_;
101
103 std::vector<double> chebyshev_coeffs_;
104
105 // Helper arrays for discrete cosine transforms calculated using FFTPACK4
106 std::vector<double> wsave_;
107 std::vector<int> ifac_;
108
113 inline double chebyshev_point(size_t j) const {
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 }
120
121 void compute_integral();
122 };
123
124}
double integral_
Approximate integral of the function on [x_min_, x_max_].
static constexpr size_t N_MAX_
Maximum allowed value of the grid size parameter.
size_t N_
Grid size parameter (N + 1 total points)
ChebyshevInterpolatingFunction(const std::function< double(double)> &func, double x_min, double x_max, size_t N=0)
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)
double evaluate(double x) const override
Approximates the represented function using the barycentric formula.
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.
double x_max_
Upper bound of the interpolation range.
double x_min_
Lower bound of the interpolation range.