1+ #include < LHAPDF/PDF.h>
12#include < pineappl_capi.h>
3+
4+ #include < algorithm>
25#include < cstdint>
36#include < cstdlib>
47#include < cassert>
58#include < cstddef>
69#include < string>
7- #include < algorithm>
810#include < vector>
9- #include < random>
1011
11- double FAC0 = 1.65 ;
12+ // NOTE: Uses the scale of the Grid as the starting scale such that we can use an IDENTITY EKO.
13+ double FAC0 = 6456.44 ;
14+
15+ std::vector<std::size_t > unravel_index (std::size_t flat_index, const std::vector<std::size_t >& shape) {
16+ std::size_t ndim = shape.size ();
17+ std::vector<std::size_t > coords (ndim);
18+
19+ for (int i = ndim - 1 ; i >= 0 ; --i) {
20+ coords[i] = flat_index % shape[i];
21+ flat_index /= shape[i];
22+ }
23+
24+ return coords;
25+ }
1226
1327std::vector<double > generate_fake_ekos (
14- double q2,
1528 std::vector<int > pids0,
1629 std::vector<double > x0,
1730 std::vector<int > pids1,
1831 std::vector<double > x1
1932) {
20- std::random_device rd;
21- std::mt19937 gen (rd ());
22- std::uniform_real_distribution<double > distrib (q2 / 1000 , q2 / 100 );
23-
2433 std::size_t flat_len = x0.size () * x1.size () * pids0.size () * pids1.size ();
2534 std::vector<double > ops (flat_len);
2635
36+ std::vector<std::size_t > shape = {pids0.size (), x0.size (), pids1.size (), x1.size ()};
2737 for (std::size_t i = 0 ; i != flat_len; i++) {
28- ops[i] = distrib (gen);
38+ std::vector<std::size_t > coords = unravel_index (i, shape);
39+
40+ double delta_ik = (coords[0 ] == coords[2 ]) ? 1.0 : 0.0 ;
41+ double delta_jl = (coords[1 ] == coords[3 ]) ? 1.0 : 0.0 ;
42+
43+ ops[i] = delta_ik * delta_jl;
2944 }
3045
3146 return ops;
@@ -56,8 +71,8 @@ int main() {
5671
5772 // Get the shape of the evolve info objects
5873 std::vector<std::size_t > evinfo_shape (5 );
59- std::vector<uint8_t > order_mask = {3 , 0 };
60- pineappl_grid_evolve_info_shape (grid, order_mask .data (), evinfo_shape.data ());
74+ std::vector<uint8_t > apply_order = {3 , 0 };
75+ pineappl_grid_evolve_info_shape (grid, apply_order .data (), evinfo_shape.data ());
6176
6277 // Get the values of the evolve info parameters. These contain, for example, the
6378 // information on the `x`-grid and `PID` used to interpolate the Grid.
@@ -67,7 +82,7 @@ int main() {
6782 std::vector<int > pids1 (evinfo_shape[2 ]);
6883 std::vector<double > x1 (evinfo_shape[3 ]);
6984 std::vector<double > ren1 (evinfo_shape[4 ]);
70- pineappl_grid_evolve_info (grid, order_mask .data (), fac1.data (),
85+ pineappl_grid_evolve_info (grid, apply_order .data (), fac1.data (),
7186 frg1.data (), pids1.data (), x1.data (), ren1.data ());
7287
7388 // ------------------ Construct the Operator Info ------------------
@@ -90,9 +105,9 @@ int main() {
90105 // The Evolution Operator is a vector with length `N_conv * N_Q2_slices * Σ product(OP shape)`
91106 std::vector<double > op_slices;
92107 std::size_t flat_len = x1.size () * x1.size () * pids1.size () * pids1.size ();
93- for (std::size_t i = 0 ; i != conv_types.size (); i ++) {
108+ for (std::size_t _i = 0 ; _i != conv_types.size (); _i ++) {
94109 for (std::size_t j = 0 ; j != fac1.size (); j++) {
95- std::vector<double > eko = generate_fake_ekos (fac1[j], pids1, x1, pids1, x1);
110+ std::vector<double > eko = generate_fake_ekos (pids1, x1, pids1, x1);
96111 for (std::size_t k = 0 ; k != flat_len; k++) {
97112 op_slices.push_back (eko[k]);
98113 }
@@ -104,11 +119,72 @@ int main() {
104119 std::vector<double > xi = {1.0 , 1.0 , 1.0 };
105120 std::vector<std::size_t > tensor_shape = {pids1.size (), x1.size (), pids1.size (), x1.size ()};
106121
107- pineappl_fk_table* fktable = pineappl_grid_evolve (grid, opinfo_slices.data (), order_mask.data (),
108- op_slices.data (), x1.data (), x1.data (), pids1.data (), pids1.data (),
122+ pineappl_fk_table* fktable = pineappl_grid_evolve (grid, opinfo_slices.data (),
123+ apply_order.data (), op_slices.data (), x1.data (),
124+ x1.data (), pids1.data (), pids1.data (),
109125 tensor_shape.data (), xi.data (), ren1.data (), alphas_table.data ());
110126
127+ // ------------------ Compare Grid & FK after convolution ------------------
128+ // disable LHAPDF banners to guarantee deterministic output
129+ LHAPDF::setVerbosity (0 );
130+ std::string pdfset = " NNPDF31_nlo_as_0118_luxqed" ;
131+ auto pdf = std::unique_ptr<LHAPDF::PDF>(LHAPDF::mkPDF (pdfset, 0 ));
132+
133+ auto xfx = [](int32_t id, double x, double q2, void * pdf) {
134+ return static_cast <LHAPDF::PDF*> (pdf)->xfxQ2 (id, x, q2);
135+ };
136+ auto alphas = [](double q2, void * pdf) {
137+ return static_cast <LHAPDF::PDF*> (pdf)->alphasQ2 (q2);
138+ };
139+
140+ std::vector<LHAPDF::PDF*> pdfs = {pdf.get (), pdf.get ()};
141+ void ** pdf_states = reinterpret_cast <void **>(pdfs.data ());
142+
143+ // how many bins does this grid have?
144+ std::size_t bins = pineappl_grid_bin_count (grid);
145+
146+ // [ convolve the Grid ]
147+ std::vector<double > mu_scales = { 1.0 , 1.0 , 1.0 };
148+ std::vector<double > dxsec_grid (bins);
149+ pineappl_grid_convolve (grid, xfx, alphas, pdf_states, pdf.get (),
150+ nullptr , nullptr , nullptr , 1 ,
151+ mu_scales.data (), dxsec_grid.data ());
152+
153+ // [ convolve the FK Table ]
154+ std::vector<double > dxsec_fktable (bins);
155+ pineappl_fk_table_convolve (fktable, xfx, pdf_states, nullptr ,
156+ nullptr , dxsec_fktable.data ());
157+
158+ // Print the results
159+ const int idx_width = 6 ;
160+ const int num_width = 15 ;
161+ const int dif_width = 15 ;
162+
163+ // Print headers
164+ std::cout << std::setw (idx_width) << " Bin"
165+ << std::setw (num_width) << " Grid"
166+ << std::setw (num_width) << " FkTable"
167+ << std::setw (dif_width) << " reldiff" << std::endl;
168+
169+ // Print dashed lines
170+ std::cout << std::setw (idx_width) << std::string (idx_width - 2 , ' -' )
171+ << std::setw (num_width) << std::string (num_width - 2 , ' -' )
172+ << std::setw (num_width) << std::string (num_width - 2 , ' -' )
173+ << std::setw (dif_width) << std::string (dif_width - 2 , ' -' ) << std::endl;
174+
175+ // Print the data
176+ std::cout << std::scientific << std::setprecision (6 );
177+ for (size_t i = 0 ; i < dxsec_grid.size (); ++i) {
178+ double reldiff = std::abs (dxsec_grid[i] - dxsec_fktable[i]) / (std::abs (dxsec_grid[i]));
179+ std::cout << std::setw (idx_width) << i
180+ << std::setw (num_width) << dxsec_grid[i]
181+ << std::setw (num_width) << dxsec_fktable[i]
182+ << std::setw (dif_width) << reldiff
183+ << std::endl;
184+ }
185+
111186 pineappl_fktable_write (fktable, " evolved-grid.pineappl.lz4" );
187+
112188 pineappl_grid_delete (grid);
113189 pineappl_fk_table_delete (fktable);
114190}
0 commit comments