7 #ifndef LHAPDF_KnotArray_H
8 #define LHAPDF_KnotArray_H
10 #include "LHAPDF/Exceptions.h"
11 #include "LHAPDF/Utils.h"
19 size_t indexbelow(
double value,
const std::vector<
double>& knots) {
20 size_t i = upper_bound(knots.begin(), knots.end(), value) - knots.begin();
21 if (i == knots.size()) i -= 1;
27 int findPidInPids(
int pid,
const std::vector<
int>& pids) {
28 std::vector<
int>::const_iterator it = std::find(pids.begin(), pids.end(), pid);
33 return static_cast<
int>(std::distance(pids.begin(), it));
59 bool empty()
const {
return _grid.empty(); }
68 double xf(
int ix,
int iq2,
int ipid)
const {
69 return _grid[ix*_shape[2]*_shape[1] + iq2*_shape[2] + ipid];
73 const double&
coeff(
int ix,
int iq2,
int pid,
int in)
const {
74 return _coeffs[ix*(_shape[1])*_shape[2]*4 + iq2*_shape[2]*4 + pid*4 + in];
78 int lookUpPid(size_t id)
const {
return _lookup[id]; }
80 double xs(size_t id)
const {
return _xs[id]; }
82 double logxs(size_t id)
const {
return _logxs[id]; }
84 double q2s(size_t id)
const {
return _q2s[id]; }
86 double logq2s(size_t id)
const {
return _logq2s[id]; }
88 size_t shape(size_t id)
const {
return _shape[id]; }
92 if (x < _xs.front())
return false;
93 if (x > _xs.back())
return false;
99 if (q2 < _q2s.front())
return false;
100 if (q2 > _q2s.back())
return false;
104 inline int get_pid(
int id)
const {
108 if (-6 <= id && id <= 6)
return _lookup[id + 6];
109 else if (id == 21)
return _lookup[0 + 6];
110 else if (id == 22)
return _lookup[13];
111 else return findPidInPids(id, _pids);
114 bool has_pid(
int id)
const {
115 return get_pid(id) != -1;
118 void initPidLookup();
125 const std::vector<
double>& logxs()
const {
return _logxs; }
127 const std::vector<
double>& q2s()
const {
return _q2s; }
129 const std::vector<
double>& logq2s()
const {
return _logq2s; }
134 std::vector<
double>& setGrid() {
return _grid; }
136 std::vector<
double>& setxknots() {
return _xs; }
138 std::vector<
double>& setq2knots() {
return _q2s; }
140 std::vector<size_t>& setShape(){
return _shape; }
142 std::vector<
int>& setPids() {
return _pids; }
146 std::vector<size_t> _shape;
149 std::vector<
double> _grid;
152 std::vector<
double> _coeffs;
155 std::vector<
int> _pids;
156 std::vector<
int> _lookup;
159 std::vector<
double> _xs;
160 std::vector<
double> _q2s;
161 std::vector<
double> _logxs;
162 std::vector<
double> _logq2s;
178 AlphaSArray(
const std::vector<
double>& q2knots,
const std::vector<
double>& as)
201 if (q2 < q2s().front())
throw AlphaSError(
"Q2 value " + to_str(q2) +
" is lower than lowest-Q2 grid point at " + to_str(q2s().front()));
202 if (q2 > q2s().back())
throw AlphaSError(
"Q2 value " + to_str(q2) +
" is higher than highest-Q2 grid point at " + to_str(q2s().back()));
204 size_t i = upper_bound(q2s().begin(), q2s().end(), q2) - q2s().begin();
205 if (i == q2s().size()) i -= 1;
215 if (logq2 < logq2s().front())
throw GridError(
"logQ2 value " + to_str(logq2) +
" is lower than lowest-logQ2 grid point at " + to_str(logq2s().front()));
216 if (logq2 > logq2s().back())
throw GridError(
"logQ2 value " + to_str(logq2) +
" is higher than highest-logQ2 grid point at " + to_str(logq2s().back()));
218 size_t i = upper_bound(logq2s().begin(), logq2s().end(), logq2) - logq2s().begin();
219 if (i == logq2s().size()) i -= 1;
245 return (alphas()[i+1] - alphas()[i]) / (logq2s()[i+1] - logq2s()[i]);
250 return (alphas()[i] - alphas()[i-1]) / (logq2s()[i] - logq2s()[i-1]);
255 return 0.5 * (ddlogq_forward(i) + ddlogq_backward(i));
265 _logq2s.resize(_q2s.size());
266 for (size_t i = 0; i < _q2s.size(); ++i) _logq2s[i] = log(_q2s[i]);