1use ekore::harmonics::cache::Cache;
4use num::Complex;
5use std::ffi::c_void;
6
7pub mod bib;
8pub mod mellin;
9
10struct RawCmplx {
12 re: Vec<f64>,
13 im: Vec<f64>,
14}
15
16fn unravel<const DIM: usize>(res: Vec<[[Complex<f64>; DIM]; DIM]>, order_qcd: usize) -> RawCmplx {
20 let mut target = RawCmplx {
21 re: Vec::<f64>::new(),
22 im: Vec::<f64>::new(),
23 };
24 for obj in res.iter().take(order_qcd) {
25 for col in obj.iter().take(DIM) {
26 for el in col.iter().take(DIM) {
27 target.re.push(el.re);
28 target.im.push(el.im);
29 }
30 }
31 }
32 target
33}
34
35fn unravel_qed<const DIM: usize>(
39 res: Vec<Vec<[[Complex<f64>; DIM]; DIM]>>,
40 order_qcd: usize,
41 order_qed: usize,
42) -> RawCmplx {
43 let mut target = RawCmplx {
44 re: Vec::<f64>::new(),
45 im: Vec::<f64>::new(),
46 };
47 for obj_ in res.iter().take(order_qcd + 1) {
48 for obj in obj_.iter().take(order_qed + 1) {
49 for col in obj.iter().take(DIM) {
50 for el in col.iter().take(DIM) {
51 target.re.push(el.re);
52 target.im.push(el.im);
53 }
54 }
55 }
56 }
57 target
58}
59
60fn unravel_qed_ns(res: Vec<Vec<Complex<f64>>>, order_qcd: usize, order_qed: usize) -> RawCmplx {
64 let mut target = RawCmplx {
65 re: Vec::<f64>::new(),
66 im: Vec::<f64>::new(),
67 };
68 for col in res.iter().take(order_qcd + 1) {
69 for el in col.iter().take(order_qed + 1) {
70 target.re.push(el.re);
71 target.im.push(el.im);
72 }
73 }
74 target
75}
76
77#[no_mangle]
82pub unsafe extern "C" fn rust_quad_ker(u: f64, rargs: *mut c_void) -> f64 {
83 let args = *(rargs as *mut QuadArgs);
84
85 let is_singlet = (100 == args.mode0)
86 || (21 == args.mode0)
87 || (90 == args.mode0)
88 || (22 == args.mode0)
89 || (101 == args.mode0);
90
91 let is_qed_valence = (10200 == args.mode0) || (10204 == args.mode0);
92 let path = mellin::TalbotPath::new(u, args.logx, is_singlet);
94 let jac = path.jac() * path.prefactor();
95 let mut c = Cache::new(path.n());
96 let mut raw = RawCmplx {
97 re: Vec::<f64>::new(),
98 im: Vec::<f64>::new(),
99 };
100
101 if args.is_ome {
102 if is_singlet {
103 raw = unravel(
104 ekore::operator_matrix_elements::unpolarized::spacelike::A_singlet(
105 args.order_qcd,
106 &mut c,
107 args.nf,
108 args.L,
109 ),
110 args.order_qcd,
111 );
112 } else {
113 raw = unravel(
114 ekore::operator_matrix_elements::unpolarized::spacelike::A_non_singlet(
115 args.order_qcd,
116 &mut c,
117 args.nf,
118 args.L,
119 ),
120 args.order_qcd,
121 );
122 }
123 } else if is_singlet {
124 if args.order_qed > 0 {
125 let gamma_singlet_qed =
126 ekore::anomalous_dimensions::unpolarized::spacelike::gamma_singlet_qed;
127 raw = unravel_qed(
128 gamma_singlet_qed(args.order_qcd, args.order_qed, &mut c, args.nf),
129 args.order_qcd,
130 args.order_qed,
131 );
132 } else {
133 let gamma_singlet_qcd = match args.is_polarized {
134 true => ekore::anomalous_dimensions::polarized::spacelike::gamma_singlet_qcd,
135 false => ekore::anomalous_dimensions::unpolarized::spacelike::gamma_singlet_qcd,
136 };
137 raw = unravel(
138 gamma_singlet_qcd(args.order_qcd, &mut c, args.nf),
139 args.order_qcd,
140 );
141 }
142 } else if args.order_qed > 0 {
143 if is_qed_valence {
144 let gamma_valence_qed =
145 ekore::anomalous_dimensions::unpolarized::spacelike::gamma_valence_qed;
146 raw = unravel_qed(
147 gamma_valence_qed(args.order_qcd, args.order_qed, &mut c, args.nf),
148 args.order_qcd,
149 args.order_qed,
150 );
151 } else {
152 let gamma_ns_qed = ekore::anomalous_dimensions::unpolarized::spacelike::gamma_ns_qed;
153 raw = unravel_qed_ns(
154 gamma_ns_qed(args.order_qcd, args.order_qed, args.mode0, &mut c, args.nf),
155 args.order_qcd,
156 args.order_qed,
157 );
158 }
159 } else {
160 let gamma_ns_qcd = match args.is_polarized {
162 true => ekore::anomalous_dimensions::polarized::spacelike::gamma_ns_qcd,
163 false => ekore::anomalous_dimensions::unpolarized::spacelike::gamma_ns_qcd,
164 };
165 let res = gamma_ns_qcd(args.order_qcd, args.mode0, &mut c, args.nf);
166 for el in res.iter().take(args.order_qcd) {
167 raw.re.push(el.re);
168 raw.im.push(el.im);
169 }
170 }
171
172 (args.py)(
174 raw.re.as_ptr(),
175 raw.im.as_ptr(),
176 c.n().re,
177 c.n().im,
178 jac.re,
179 jac.im,
180 args.order_qcd,
181 args.order_qed,
182 is_singlet,
183 args.mode0,
184 args.mode1,
185 args.nf,
186 args.is_log,
187 args.logx,
188 args.areas,
189 args.areas_x,
190 args.areas_y,
191 args.method_num,
192 args.as1,
193 args.as0,
194 args.ev_op_iterations,
195 args.ev_op_max_order_qcd,
196 args.sv_mode_num,
197 args.is_threshold,
198 args.Lsv,
199 args.as_list,
201 args.as_list_len,
202 args.mu2_from,
203 args.mu2_to,
204 args.a_half,
205 args.a_half_x,
206 args.a_half_y,
207 args.alphaem_running,
208 )
209}
210
211type PyQuadKerT = unsafe extern "C" fn(
213 *const f64, *const f64, f64, f64, f64, f64, usize, usize, bool, u16, u16, u8, bool, f64, *const f64, u8, u8, u8, f64, f64, u8, u8, u8, bool, f64, *const f64, u8, f64, f64, *const f64, u8, u8, bool, ) -> f64;
247
248#[allow(non_snake_case)]
250#[repr(C)]
251#[derive(Clone, Copy)]
252pub struct QuadArgs {
253 pub order_qcd: usize,
254 pub order_qed: usize,
255 pub mode0: u16,
256 pub mode1: u16,
257 pub is_polarized: bool,
258 pub is_time_like: bool,
259 pub nf: u8,
260 pub py: PyQuadKerT,
261 pub is_log: bool,
262 pub logx: f64,
263 pub areas: *const f64,
264 pub areas_x: u8,
265 pub areas_y: u8,
266 pub L: f64,
267 pub method_num: u8,
268 pub as1: f64,
269 pub as0: f64,
270 pub ev_op_iterations: u8,
271 pub ev_op_max_order_qcd: u8,
272 pub sv_mode_num: u8,
273 pub is_threshold: bool,
274 pub is_ome: bool,
275 pub Lsv: f64,
276 pub as_list: *const f64,
278 pub as_list_len: u8,
279 pub mu2_from: f64,
280 pub mu2_to: f64,
281 pub a_half: *const f64,
282 pub a_half_x: u8,
283 pub a_half_y: u8,
284 pub alphaem_running: bool,
285}
286
287pub unsafe extern "C" fn my_py(
292 _re_gamma: *const f64,
293 _im_gamma: *const f64,
294 _re_n: f64,
295 _im_n: f64,
296 _re_jac: f64,
297 _im_jac: f64,
298 _order_qcd: usize,
299 _order_qed: usize,
300 _is_singlet: bool,
301 _mode0: u16,
302 _mode1: u16,
303 _nf: u8,
304 _is_log: bool,
305 _logx: f64,
306 _areas: *const f64,
307 _areas_x: u8,
308 _areas_y: u8,
309 _method_num: u8,
310 _as1: f64,
311 _as0: f64,
312 _ev_op_iterations: u8,
313 _ev_op_max_order_qcd: u8,
314 _sv_mode_num: u8,
315 _is_threshold: bool,
316 _lsv: f64,
317 _as_list: *const f64,
318 _as_list_len: u8,
319 _mu2_from: f64,
320 _mu2_to: f64,
321 _a_half: *const f64,
322 _a_half_x: u8,
323 _a_half_y: u8,
324 _alphaem_running: bool,
325) -> f64 {
326 0.
327}
328
329#[no_mangle]
337pub unsafe extern "C" fn empty_args() -> QuadArgs {
338 QuadArgs {
339 order_qcd: 0,
340 order_qed: 0,
341 mode0: 0,
342 mode1: 0,
343 is_polarized: false,
344 is_time_like: false,
345 nf: 0,
346 py: my_py,
347 is_log: true,
348 logx: 0.,
349 areas: [].as_ptr(),
350 areas_x: 0,
351 areas_y: 0,
352 L: 0.,
353 method_num: 0,
354 as1: 0.,
355 as0: 0.,
356 ev_op_iterations: 0,
357 ev_op_max_order_qcd: 0,
358 sv_mode_num: 0,
359 is_threshold: false,
360 is_ome: false,
361 Lsv: 0.,
362 as_list: [].as_ptr(),
363 as_list_len: 0,
364 mu2_from: 0.,
365 mu2_to: 0.,
366 a_half: [].as_ptr(),
367 a_half_x: 0,
368 a_half_y: 0,
369 alphaem_running: false,
370 }
371}