MARLEY (Model of Argon Reaction Low Energy Yields)  v1.2.0
A Monte Carlo event generator for tens-of-MeV neutrino interactions
ChebyshevInterpolatingFunction.hh
1 //
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/marley_utils.hh"
22 
23 namespace marley {
24 
25  // Default Chebyshev grid size to use (when not using adaptive sizing)
26  constexpr size_t DEFAULT_N_CHEBYSHEV = 64u;
27 
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 {
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  protected:
80 
83 
85  static constexpr size_t N_MAX_ = 65536u; // 16 adaptive iterations
86 
88  size_t N_;
89 
91  double x_min_;
92 
94  double x_max_;
95 
97  double integral_;
98 
100  std::vector<double> Xs_;
101 
103  std::vector<double> Fs_;
104 
106  std::vector<double> chebyshev_coeffs_;
107 
108  // Helper arrays for discrete cosine transforms calculated using FFTPACK4
109  std::vector<double> wsave_;
110  std::vector<int> ifac_;
111 
116  inline double chebyshev_point(size_t j) const {
117  // jth Chebyshev point (of the second kind) on [-1, 1]
118  double x = std::cos( static_cast<double>(marley_utils::pi * j) / N_ );
119  // Affine transformation to [x_min_, x_max_] (primed basis)
120  double x_prime = (( x_max_ - x_min_ )*x + ( x_max_ + x_min_ )) / 2.;
121  return x_prime;
122  }
123 
124  void compute_integral();
125  };
126 
127 }
Approximate representation of a 1D continuous function.
Definition: ChebyshevInterpolatingFunction.hh:29
double x_min_
Lower edge of the grid.
Definition: ChebyshevInterpolatingFunction.hh:91
double integral_
Approximate integral of the function on [x_min_, x_max_].
Definition: ChebyshevInterpolatingFunction.hh:97
static constexpr size_t N_MAX_
Maximum allowed value of the grid size parameter.
Definition: ChebyshevInterpolatingFunction.hh:85
double x_max_
Upper edge of the grid.
Definition: ChebyshevInterpolatingFunction.hh:94
size_t N_
Grid size parameter (N + 1 total points)
Definition: ChebyshevInterpolatingFunction.hh:88
ChebyshevInterpolatingFunction()
Default constructor used by cdf()
Definition: ChebyshevInterpolatingFunction.hh:82
double chebyshev_point(size_t j) const
For a given N, returns the x position of the jth Chebyshev point (of the second kind)
Definition: ChebyshevInterpolatingFunction.hh:116
double evaluate(double x) const
Approximates the represented function using the barycentric formula.
Definition: ChebyshevInterpolatingFunction.hh:39
std::vector< double > Xs_
Chebyshev points at which the function was evaluated.
Definition: ChebyshevInterpolatingFunction.hh:100
std::vector< double > chebyshev_coeffs_
Coefficients of the Chebyshev expansion of this function.
Definition: ChebyshevInterpolatingFunction.hh:106
std::vector< double > Fs_
Function values at the grid points.
Definition: ChebyshevInterpolatingFunction.hh:103