Version: SMASH-3.4
tabulation.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2020,2026
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 
8 #ifndef SRC_INCLUDE_SMASH_TABULATION_H_
9 #define SRC_INCLUDE_SMASH_TABULATION_H_
10 
11 #include <algorithm>
12 #include <fstream>
13 #include <functional>
14 #include <map>
15 #include <memory>
16 #include <vector>
17 
18 #include "smash/constants.h"
20 #include "smash/integrate.h"
21 #include "smash/kinematics.h"
22 #include "smash/particletype.h"
23 #include "smash/sha256.h"
24 
25 namespace smash {
26 
27 /**
28  * A class for storing a one-dimensional lookup table of floating-point values.
29  */
30 class Tabulation {
31  public:
32  /**
33  * Construct an empty tabulation object.
34  */
35  Tabulation() : values_({}), x_min_(0.0), x_max_(0.0), inv_dx_(0.0) {}
36 
37  /**
38  * Construct a new tabulation object.
39  *
40  * \param x_min lower bound of tabulation domain
41  * \param range range (x_max-x_min) of tabulation domain
42  * \param num number of intervals (the number of tabulated points is actually
43  * num+1)
44  * \param f one-dimensional function f(x) which is supposed to be tabulated
45  * \return Construct object.
46  * \throws if less than two values are tabulated.
47  */
48  Tabulation(double x_min, double range, size_t num,
49  std::function<double(double)> f);
50 
51  /**
52  * \returns whether the tabulation is empty.
53  */
54  bool is_empty() const { return values_.empty(); }
55 
56  /**
57  * Construct a tabulation object by reading binary data from a stream.
58  *
59  * \param stream Stream containing the binary representation of the
60  * tabulation. \param hash Hash corresponding to the particle properties for
61  * which the tabulation was created. \returns (true, tabulation) if the given
62  * hash matches the one given by the stream, (false, empty) otherwise.
63  */
64  static Tabulation from_file(std::ifstream& stream, sha256::Hash hash);
65 
66  /**
67  * Look up a value from the tabulation (without any interpolation, simply
68  * using the closest tabulated value). If \par x is below the lower tabulation
69  * bound we return 0, if it is above the upper bound we return the tabulated
70  * value at the upper bound.
71  *
72  * \param x Argument to tabulated function.
73  * \return Tabulated value using constant interpolation.
74  */
75  double get_value_step(double x) const;
76 
77  /**
78  * Look up a value from the tabulation using linear interpolation.
79  * If \par x is below the lower bound we return 0.
80  * If x is above the upper bound, then by default we use linear extrapolation
81  * of the two highest tabulated points. Optionally one can also extrapolate
82  * with rightmost value or zero. Linear extrapolation is not an arbitrary
83  * choice, in fact many functions tabulated in SMASH have a linear
84  * asymptotics, e.g. rho(m) functions.
85  *
86  * \param x Argument to tabulated function.
87  * \param extrapolation Extrapolation type that is used for values greater
88  * than the maximum x in the tabulation.
89  *
90  * \return Tabulated value using linear interpolation.
91  * \throw std::invalid_argument if unsupported extrapolation type is
92  * requested.
93  */
94  double get_value_linear(double x, ExtrapolationType extrapolation =
96 
97  /**
98  * Write a binary representation of the tabulation to a stream.
99  *
100  * \param stream Stream to which the binary representation is written.
101  * \param hash Hash corresponding to the particle properties for which the
102  * tabulation was created.
103  */
104  void write(std::ofstream& stream, sha256::Hash hash) const;
105 
106  private:
107  /// vector for storing tabulated values
108  std::vector<double> values_{};
109 
110  /// lower bound for tabulation
111  double x_min_ = smash_NaN<double>;
112 
113  /// upper bound for tabulation
114  double x_max_ = smash_NaN<double>;
115 
116  /// inverse step size 1/dx
117  double inv_dx_ = smash_NaN<double>;
118 
119  /// Linear approximation to interpolate and extrapolate tabulations
120  double linear_approximation_(double x) const {
121  const double index_double = (x - x_min_) * inv_dx_;
122  // here n is the lower index
123  const size_t n =
124  std::min(static_cast<size_t>(index_double), values_.size() - 2);
125  const double r = index_double - n;
126  return values_[n] + (values_[n + 1] - values_[n]) * r;
127  }
128 };
129 
130 /**
131  * Spectral function integrand for GSL integration, with one resonance in the
132  * final state (the second particle is stable).
133  *
134  * The integrand is \f$ A(m) p_{cm}^f \f$, where \f$ m \f$ is the
135  * resonance mass, \f$ A(m) \f$ is the spectral function
136  * and \f$ p_{cm}^f \f$ is the center-of-mass momentum of the final state.
137  *
138  * \param[in] resonance_mass Actual mass of the resonance [GeV].
139  * \param[in] sqrts Center-of-mass Energy, i.e. sqrt of Mandelstam s [GeV].
140  * \param[in] stable_mass Mass of the stable particle in the final state [GeV].
141  * \param[in] type Type of the resonance.
142  * \return Value of the integrand.
143  */
144 inline double spec_func_integrand_1res(double resonance_mass, double sqrts,
145  double stable_mass,
146  const ParticleType& type) {
147  if (sqrts <= stable_mass + resonance_mass) {
148  return 0.;
149  }
150 
151  /* Integrand is the spectral function weighted by the CM momentum of the
152  * final state. */
153  return type.full_spectral_function(resonance_mass) *
154  pCM(sqrts, stable_mass, resonance_mass);
155 }
156 
157 /**
158  * Spectral function integrand for GSL integration, with two resonances in the
159  * final state.
160  *
161  * The integrand is \f$ A_1(m_1) A_2(m_2) p_{cm}^f \f$, where \f$ m_1 \f$ and
162  * \f$ m_2 \f$ are the resonance masses, \f$ A_1 \f$ and \f$ A_2 \f$ are the
163  * spectral functions and \f$ p_{cm}^f \f$ is the center-of-mass momentum of
164  * the final state.
165  *
166  * \param[in] sqrts Center-of-mass energy, i.e. sqrt of Mandelstam s [GeV].
167  * \param[in] res_mass_1 Actual mass of the first resonance [GeV].
168  * \param[in] res_mass_2 Actual mass of the second resonance [GeV].
169  * \param[in] t1 Type of the first resonance.
170  * \param[in] t2 Type of the second resonance.
171  * \return Value of the integrand.
172  */
173 inline double spec_func_integrand_2res(double sqrts, double res_mass_1,
174  double res_mass_2,
175  const ParticleType& t1,
176  const ParticleType& t2) {
177  if (sqrts <= res_mass_1 + res_mass_2) {
178  return 0.;
179  }
180 
181  /* Integrand is the product of the spectral function weighted by the
182  * CM momentum of the final state. */
183  return t1.full_spectral_function(res_mass_1) *
184  t2.full_spectral_function(res_mass_2) *
185  pCM(sqrts, res_mass_1, res_mass_2);
186 }
187 
188 /**
189  * Create a table for the spectral integral of a resonance and a stable
190  * particle.
191  *
192  * \param[inout] integrate Numerical integrator.
193  * \param[in] resonance Type of the resonance particle.
194  * \param[in] stable Type of the stable particle.
195  * \param[in] range Distance between tabulation points [GeV].
196  * \return Tabulation of the given integral.
197  */
199  const ParticleType& resonance,
200  const ParticleType& stable,
201  double range) {
202  const double m_min = resonance.min_mass_kinematic();
203  const double m_stable = stable.mass();
204  return Tabulation(m_min + m_stable, range, 100, [&](double srts) {
205  return integrate(m_min, srts - m_stable, [&](double m) {
206  return spec_func_integrand_1res(m, srts, m_stable, resonance);
207  });
208  });
209 }
210 
211 /**
212  * Create a table for the spectral integral of two resonances.
213  *
214  * \param[inout] integrate2d Numerical integrator.
215  * \param[in] res1 Type of the first resonance particle.
216  * \param[in] res2 Type of the second resonance particle.
217  * \param[in] range Distance between tabulation points [GeV].
218  * \return Tabulation of the given integral.
219  */
221  const ParticleType& res1,
222  const ParticleType& res2,
223  double range) {
224  const double m1_min = res1.min_mass_kinematic();
225  const double m2_min = res2.min_mass_kinematic();
226  return Tabulation(m1_min + m2_min, range, 125, [&](double srts) {
227  const double m1_max = srts - m2_min;
228  const double m2_max = srts - m1_min;
229  return integrate2d(
230  m1_min, m1_max, m2_min, m2_max, [&](double m1, double m2) {
231  return spec_func_integrand_2res(srts, m1, m2, res1, res2);
232  });
233  });
234 }
235 
236 } // namespace smash
237 
238 #endif // SRC_INCLUDE_SMASH_TABULATION_H_
A C++ interface for numerical integration in two dimensions with the Cuba Cuhre integration function.
Definition: integrate.h:219
A C++ interface for numerical integration in one dimension with the GSL CQUAD integration functions.
Definition: integrate.h:106
Particle type contains the static properties of a particle species.
Definition: particletype.h:100
double min_mass_kinematic() const
The minimum mass of the resonance that is kinematically allowed.
double full_spectral_function(double m) const
Full spectral function of the resonance (relativistic Breit-Wigner distribution with mass-dependent ...
double mass() const
Definition: particletype.h:147
A class for storing a one-dimensional lookup table of floating-point values.
Definition: tabulation.h:30
double x_min_
lower bound for tabulation
Definition: tabulation.h:111
double inv_dx_
inverse step size 1/dx
Definition: tabulation.h:117
double x_max_
upper bound for tabulation
Definition: tabulation.h:114
double get_value_linear(double x, ExtrapolationType extrapolation=ExtrapolationType::Linear) const
Look up a value from the tabulation using linear interpolation.
Definition: tabulation.cc:40
std::vector< double > values_
vector for storing tabulated values
Definition: tabulation.h:108
static Tabulation from_file(std::ifstream &stream, sha256::Hash hash)
Construct a tabulation object by reading binary data from a stream.
Definition: tabulation.cc:176
Tabulation()
Construct an empty tabulation object.
Definition: tabulation.h:35
void write(std::ofstream &stream, sha256::Hash hash) const
Write a binary representation of the tabulation to a stream.
Definition: tabulation.cc:168
double linear_approximation_(double x) const
Linear approximation to interpolate and extrapolate tabulations.
Definition: tabulation.h:120
double get_value_step(double x) const
Look up a value from the tabulation (without any interpolation, simply using the closest tabulated va...
Definition: tabulation.cc:27
bool is_empty() const
Definition: tabulation.h:54
Collection of useful constants that are known at compile time.
ExtrapolationType
Allows to specify the desired extrapolation type.
@ Linear
Extrapolate using a linear approach.
constexpr int n
Neutron.
std::array< uint8_t, HASH_SIZE > Hash
A SHA256 hash.
Definition: sha256.h:25
Definition: action.h:24
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
Definition: kinematics.h:79
static Integrator integrate
Definition: decaytype.cc:143
Tabulation spectral_integral_semistable(Integrator &integrate, const ParticleType &resonance, const ParticleType &stable, double range)
Create a table for the spectral integral of a resonance and a stable particle.
Definition: tabulation.h:198
static Integrator2d integrate2d(1E7)
double spec_func_integrand_2res(double sqrts, double res_mass_1, double res_mass_2, const ParticleType &t1, const ParticleType &t2)
Spectral function integrand for GSL integration, with two resonances in the final state.
Definition: tabulation.h:173
Tabulation spectral_integral_unstable(Integrator2d &integrate2d, const ParticleType &res1, const ParticleType &res2, double range)
Create a table for the spectral integral of two resonances.
Definition: tabulation.h:220
double spec_func_integrand_1res(double resonance_mass, double sqrts, double stable_mass, const ParticleType &type)
Spectral function integrand for GSL integration, with one resonance in the final state (the second pa...
Definition: tabulation.h:144