LHAPDF  6.5.6
KnotArray.h
1 // -*- C++ -*-
2 //
3 // This file is part of LHAPDF
4 // Copyright (C) 2012-2024 The LHAPDF collaboration (see AUTHORS for details)
5 //
6 #pragma once
7 #ifndef LHAPDF_KnotArray_H
8 #define LHAPDF_KnotArray_H
9 
10 #include "LHAPDF/Exceptions.h"
11 #include "LHAPDF/Utils.h"
12 #include <algorithm> // for std::upper_bound, std::find
13 
14 namespace {
15 
16 
17  // Hide some internal functions from outside API view
18 
19  // General function to find the knot below a given value
20  // PERFORMANCE-CRITICAL: This function is very hot. Keep optimized for speed. When upgrading to C++20, add [[unlikely]] to the edge case branch.
21  inline size_t indexbelow(double value, const std::vector<double>& knots) {
22  const size_t n = knots.size();
23  const double* b = knots.data();
24  const double* e = b + n;
25 
26  size_t i = std::upper_bound(b, e, value) - b;
27  if (i >= n) i = n - 1;
28  return i - 1;
29  }
30 
31  int findPidInPids(int pid, const std::vector<int>& pids) {
32  std::vector<int>::const_iterator it = std::find(pids.begin(), pids.end(), pid);
33  if (it == pids.end())
34  return -1;
35  else
36  // save to cast, given small number of pid's
37  return static_cast<int>(std::distance(pids.begin(), it));
38  }
39 
40 
41 }
42 
43 namespace LHAPDF {
44 
45 
49  class KnotArray{
50  public:
51 
53  size_t size() const { return _shape.back(); }
55  size_t numflavs() const { return _shape.back(); }
56 
58  size_t xsize() const { return _shape[0]; }
59 
61  size_t q2size() const { return _shape[1]; }
62 
64  bool empty() const { return _grid.empty(); }
65 
67  inline size_t ixbelow(double x) const { return indexbelow(x, _xs); }
68 
70  inline size_t iq2below(double q2) const { return indexbelow(q2, _q2s); }
71 
73  double xf(int ix, int iq2, int ipid) const {
74  return _grid[ix*_shape[2]*_shape[1] + iq2*_shape[2] + ipid];
75  }
76 
80  const double& coeff(int ix, int iq2, int pid, int in) const {
81  return _coeffs[ix*(_shape[1])*_shape[2]*4 + iq2*_shape[2]*4 + pid*4 + in];
82  }
83 
85  int lookUpPid(size_t id) const { return _lookup[id]; }
86 
88  double xs(size_t id) const { return _xs[id]; }
89 
91  double logxs(size_t id) const { return _logxs[id]; }
92 
94  double q2s(size_t id) const { return _q2s[id]; }
95 
97  double logq2s(size_t id) const { return _logq2s[id]; }
98 
102  size_t shape(size_t id) const { return _shape[id]; }
103 
105  bool inRangeX(double x) const {
106  if (x < _xs.front()) return false;
107  if (x > _xs.back()) return false;
108  return true;
109  }
110 
112  bool inRangeQ2(double q2) const {
113  if (q2 < _q2s.front()) return false;
114  if (q2 > _q2s.back()) return false;
115  return true;
116  }
117 
119  inline int get_pid(int id) const {
120  // hardcoded lookup table for particle ids
121  // -6,...,-1,21/0,1,...,6,22
122  // if id outside of this range, search in list of ids
123  if (-6 <= id && id <= 6) return _lookup[id + 6];
124  else if (id == 21) return _lookup[0 + 6];
125  else if (id == 22) return _lookup[13];
126  else return findPidInPids(id, _pids);
127  }
128 
130  bool has_pid(int id) const {
131  return get_pid(id) != -1;
132  }
133 
135  void initPidLookup();
136 
138  void fillLogKnots();
139 
140 
143 
144  const std::vector<double>& xs() const { return _xs; }
145 
146  const std::vector<double>& logxs() const { return _logxs; }
147 
148  const std::vector<double>& q2s() const { return _q2s; }
149 
150  const std::vector<double>& logq2s() const { return _logq2s; }
151 
153 
154 
157 
158  std::vector<double>& setCoeffs() { return _coeffs; }
159 
160  std::vector<double>& setGrid() { return _grid; }
161 
162  std::vector<double>& setxknots() { return _xs; }
163 
164  std::vector<double>& setq2knots() { return _q2s; }
165 
166  std::vector<size_t>& setShape() { return _shape; }
167 
168  std::vector<int>& setPids() { return _pids; }
169 
171 
172 
173  private:
174 
178  std::vector<size_t> _shape;
179 
181  std::vector<double> _grid;
182 
184  std::vector<double> _coeffs;
185 
187  std::vector<int> _pids;
188  std::vector<int> _lookup;
189 
192  std::vector<double> _xs;
193  std::vector<double> _q2s;
194  std::vector<double> _logxs;
195  std::vector<double> _logq2s;
197 
198  };
199 
200 
202  class AlphaSArray {
203  public:
204 
207 
210 
212  AlphaSArray(const std::vector<double>& q2knots, const std::vector<double>& as)
213  : _q2s(q2knots), _as(as)
214  {
215  _syncq2s();
216  }
217 
219 
220 
223 
225  const std::vector<double>& q2s() const { return _q2s; }
226 
228  const std::vector<double>& logq2s() const { return _logq2s; }
229 
233  size_t iq2below(double q2) const {
234  // Test that Q2 is in the grid range
235  if (q2 < q2s().front()) throw AlphaSError("Q2 value " + to_str(q2) + " is lower than lowest-Q2 grid point at " + to_str(q2s().front()));
236  if (q2 > q2s().back()) throw AlphaSError("Q2 value " + to_str(q2) + " is higher than highest-Q2 grid point at " + to_str(q2s().back()));
238  size_t i = upper_bound(q2s().begin(), q2s().end(), q2) - q2s().begin();
239  if (i == q2s().size()) i -= 1; // can't return the last knot index
240  i -= 1; // have to step back to get the knot <= q2 behaviour
241  return i;
242  }
243 
247  size_t ilogq2below(double logq2) const {
248  // Test that log(Q2) is in the grid range
249  if (logq2 < logq2s().front()) throw GridError("logQ2 value " + to_str(logq2) + " is lower than lowest-logQ2 grid point at " + to_str(logq2s().front()));
250  if (logq2 > logq2s().back()) throw GridError("logQ2 value " + to_str(logq2) + " is higher than highest-logQ2 grid point at " + to_str(logq2s().back()));
252  size_t i = upper_bound(logq2s().begin(), logq2s().end(), logq2) - logq2s().begin();
253  if (i == logq2s().size()) i -= 1; // can't return the last knot index
254  i -= 1; // have to step back to get the knot <= q2 behaviour
255  return i;
256  }
257 
259 
260 
263 
265  const std::vector<double>& alphas() const { return _as; }
266  // /// alpha_s value accessor (non-const)
267  // std::vector<double>& alphas() { return _as; }
268  // /// alpha_s value setter
269  // void setalphas(const valarray& xfs) { _as = as; }
270 
272 
273 
276 
278  double ddlogq_forward(size_t i) const {
279  return (alphas()[i+1] - alphas()[i]) / (logq2s()[i+1] - logq2s()[i]);
280  }
281 
283  double ddlogq_backward(size_t i) const {
284  return (alphas()[i] - alphas()[i-1]) / (logq2s()[i] - logq2s()[i-1]);
285  }
286 
288  double ddlogq_central(size_t i) const {
289  return 0.5 * (ddlogq_forward(i) + ddlogq_backward(i));
290  }
291 
293 
294 
295  private:
296 
298  void _syncq2s() {
299  _logq2s.resize(_q2s.size());
300  for (size_t i = 0; i < _q2s.size(); ++i) _logq2s[i] = log(_q2s[i]);
301  }
302 
304  std::vector<double> _q2s;
306  std::vector<double> _logq2s;
308  std::vector<double> _as;
309 
310  };
311 }
312 #endif
double xf(int ix, int iq2, int ipid) const
Convenient accessor to the grid values.
Definition: KnotArray.h:73
std::vector< int > _pids
Order the PIDs are filled in.
Definition: KnotArray.h:187
int get_pid(int id) const
Definition: KnotArray.h:119
Internal storage class for alpha_s interpolation grids.
Definition: KnotArray.h:202
double logxs(size_t id) const
Set of log10(x) knots.
Definition: KnotArray.h:91
size_t size() const
How many flavours are stored in the grid.
Definition: KnotArray.h:53
std::vector< double > _grid
Grid values.
Definition: KnotArray.h:181
std::vector< double > _q2s
List of Q2 knots.
Definition: KnotArray.h:304
std::vector< double > _logq2s
List of log(Q2) knots.
Definition: KnotArray.h:306
bool inRangeX(double x) const
Check if value within the boundaries of xknots.
Definition: KnotArray.h:105
const std::vector< double > & logq2s() const
log(Q2) knot vector accessor
Definition: KnotArray.h:228
const std::vector< double > & alphas() const
alpha_s value accessor (const)
Definition: KnotArray.h:265
Internal storage class for PDF data point grids.
Definition: KnotArray.h:49
bool empty() const
Is this container empty?
Definition: KnotArray.h:64
Error for general AlphaS computation problems.
Definition: Exceptions.h:94
std::vector< double > _coeffs
Storage for the precomputed polynomial coefficients.
Definition: KnotArray.h:184
double logq2s(size_t id) const
Set of log10(Q2) knots.
Definition: KnotArray.h:97
size_t ixbelow(double x) const
Find the largest grid index below given x, such that xknots[index] < x.
Definition: KnotArray.h:67
double ddlogq_forward(size_t i) const
Forward derivative w.r.t. logQ2.
Definition: KnotArray.h:278
Error for general PDF grid problems.
Definition: Exceptions.h:30
void _syncq2s()
Synchronise the log(Q2) array from the Q2 one.
Definition: KnotArray.h:298
size_t ilogq2below(double logq2) const
Definition: KnotArray.h:247
size_t q2size() const
How many q2 knots are there.
Definition: KnotArray.h:61
size_t shape(size_t id) const
Shape of the interpolation grid.
Definition: KnotArray.h:102
double ddlogq_backward(size_t i) const
Backward derivative w.r.t. logQ2.
Definition: KnotArray.h:283
size_t numflavs() const
How many flavours are stored in the grid.
Definition: KnotArray.h:55
Namespace for all LHAPDF functions and classes.
Definition: AlphaS.h:14
std::string to_str(const T &val)
Make a string representation of val.
Definition: Utils.h:61
const double & coeff(int ix, int iq2, int pid, int in) const
Convenient accessor to the polynomial coefficients.
Definition: KnotArray.h:80
double xs(size_t id) const
Set of x knots.
Definition: KnotArray.h:88
size_t iq2below(double q2) const
Find the largest grid index below given q2, such that q2knots[index] < q2.
Definition: KnotArray.h:70
std::vector< size_t > _shape
Shape of the interpolation grid.
Definition: KnotArray.h:178
size_t iq2below(double q2) const
Definition: KnotArray.h:233
double ddlogq_central(size_t i) const
Central (avg of forward and backward) derivative w.r.t. logQ2.
Definition: KnotArray.h:288
bool inRangeQ2(double q2) const
Check if value within the boundaries of q2knots.
Definition: KnotArray.h:112
bool has_pid(int id) const
Definition: KnotArray.h:130
int lookUpPid(size_t id) const
Accessor to the internal &#39;lookup table&#39; for the pid&#39;s.
Definition: KnotArray.h:85
double q2s(size_t id) const
Set of Q2 knots.
Definition: KnotArray.h:94
size_t xsize() const
How many x knots are there.
Definition: KnotArray.h:58
std::vector< double > _as
List of alpha_s values across the knot array.
Definition: KnotArray.h:308
AlphaSArray()
Default constructor just for std::map insertability.
Definition: KnotArray.h:209
const std::vector< double > & q2s() const
Q2 knot vector accessor.
Definition: KnotArray.h:225
AlphaSArray(const std::vector< double > &q2knots, const std::vector< double > &as)
Constructor from Q2 knot values and alpha_s values.
Definition: KnotArray.h:212