From 176284667f9a422da3b7767e57e314babe0d3a74 Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 16 Oct 2024 15:29:56 +0200 Subject: [PATCH 01/32] start implementation of aem1 --- .../unpolarized/spacelike.rs | 1 + .../unpolarized/spacelike/aem1.rs | 62 +++++++++++++++++++ crates/ekore/src/constants.rs | 29 +++++++++ 3 files changed, 92 insertions(+) create mode 100644 crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs index dec73bf04..3ac896f93 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs @@ -4,6 +4,7 @@ use crate::constants::{PID_NSM, PID_NSP, PID_NSV}; use crate::harmonics::cache::Cache; use num::complex::Complex; use num::Zero; +pub mod aem1; pub mod as1; pub mod as2; pub mod as3; diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs new file mode 100644 index 000000000..3a2b728fd --- /dev/null +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs @@ -0,0 +1,62 @@ +//! |LO| |QED|. +use num::complex::Complex; + +use crate::constants::{ed2, eu2, uplike_flavors, CF, NC, TR}; +use crate::harmonics::cache::Cache; + +use crate::anomalous_dimensions::unpolarized::spacelike::as1; + +/// Compute the leading-order photon-quark anomalous dimension. +/// +/// Implements Eq. (2.5) of +pub fn gamma_phq(c: &mut Cache, nf: u8) -> Complex { + as1::gamma_gq(c, nf) / CF +} + +/// Compute the leading-order quark-photon anomalous dimension. +/// +/// Implements Eq. (2.5) of +pub fn gamma_qph(c: &mut Cache, nf: u8) -> Complex { + as1::gamma_qg(c, nf) / TR * (NC as f64) +} + +/// Compute the leading-order photon-photon anomalous dimension. +/// +/// Implements Eq. (2.5) of +pub fn gamma_phph(_c: &mut Cache, nf: u8) -> Complex { + let nu = uplike_flavors(nf); + let nd = nf - nu; + (4.0 / 3.0 * (NC as f64) * ((nu as f64) * eu2 + (nd as f64) * ed2)).into() +} + +/// Compute the leading-order non-singlet QED anomalous dimension +/// +/// Implements Eq. (2.5) of +pub fn gamma_ns(c: &mut Cache, nf: u8) -> Complex { + as1::gamma_ns(c, nf) / CF +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{assert_approx_eq_cmplx, cmplx}; + use num::complex::Complex; + use num::Zero; + const NF: u8 = 5; + + #[test] + fn number_conservation() { + const N: Complex = cmplx!(1., 0.); + let mut c = Cache::new(N); + let me = gamma_ns(&mut c, NF); + assert_approx_eq_cmplx!(f64, me, Complex::zero(), epsilon = 1e-12); + } + + #[test] + fn quark_momentum_conservation() { + const N: Complex = cmplx!(2., 0.); + let mut c = Cache::new(N); + let me = gamma_ns(&mut c, NF) + gamma_phq(&mut c, NF); + assert_approx_eq_cmplx!(f64, me, Complex::zero(), epsilon = 1e-12); + } +} diff --git a/crates/ekore/src/constants.rs b/crates/ekore/src/constants.rs index 8cb90eb1f..377cb1f77 100644 --- a/crates/ekore/src/constants.rs +++ b/crates/ekore/src/constants.rs @@ -1,4 +1,5 @@ //! Global constants. +use std::unimplemented; /// The number of colors. /// @@ -20,6 +21,16 @@ pub const CA: f64 = NC as f64; /// Defaults to $C_F = \frac{N_C^2-1}{2N_C} = 4/3$. pub const CF: f64 = ((NC * NC - 1) as f64) / ((2 * NC) as f64); +/// Up quark charge square. +/// +/// Defaults to $e_u^2 = 4./9$ +pub const eu2: f64 = 4. / 9.; + +/// Down quark charge square. +/// +/// Defaults to $e_d^2 = 1./9$ +pub const ed2: f64 = 1. / 9.; + /// Riemann zeta function at z = 2. /// /// $\zeta(2) = \pi^2 / 6$. @@ -41,3 +52,21 @@ pub const PID_NSM: u16 = 10201; /// non-singlet all-valence |PID|. pub const PID_NSV: u16 = 10200; + +/// compute the number of up flavors +pub fn uplike_flavors(nf: u8) -> u8 { + if nf > 6 { + unimplemented!("Selected nf is not implemented") + } + nf / 2 +} + +pub fn charge_combinations(nf: u8) -> Vec { + let nu = uplike_flavors(nf) as f64; + let nd = (nf as f64) - nu; + let e2avg = (nu * eu2 + nd * ed2) / (nf as f64); + let vue2m = nu / (nf as f64) * (eu2 - ed2); + let vde2m = nd / (nf as f64) * (eu2 - ed2); + let e2delta = vde2m - vue2m + e2avg; + vec![e2avg, vue2m, vde2m, e2delta] +} From 61220f8a3340a7274d81fdc314b729fbf9634f80 Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 21 Oct 2024 11:26:08 +0200 Subject: [PATCH 02/32] complete aem1.py --- .../unpolarized/spacelike/aem1.rs | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs index 3a2b728fd..91427622c 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs @@ -1,7 +1,8 @@ //! |LO| |QED|. use num::complex::Complex; +use num::Zero; -use crate::constants::{ed2, eu2, uplike_flavors, CF, NC, TR}; +use crate::constants::{charge_combinations, ed2, eu2, uplike_flavors, CF, NC, TR}; use crate::harmonics::cache::Cache; use crate::anomalous_dimensions::unpolarized::spacelike::as1; @@ -36,6 +37,64 @@ pub fn gamma_ns(c: &mut Cache, nf: u8) -> Complex { as1::gamma_ns(c, nf) / CF } +/// Compute the leading-order singlet QED anomalous dimension matrix +/// +/// Implements Eq. (2.5) of +pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { + let cc = charge_combinations(nf); + let e2avg = cc[0]; + let vue2m = cc[1]; + let vde2m = cc[2]; + let e2delta = cc[3]; + + let gamma_ph_q = gamma_phq(c, nf); + let gamma_q_ph = gamma_qph(c, nf); + let gamma_nonsinglet = gamma_ns(c, nf); + + [ + [ + Complex::::zero(), + Complex::::zero(), + Complex::::zero(), + Complex::::zero(), + ], + [ + Complex::::zero(), + gamma_phph(c, nf), + e2avg * gamma_ph_q, + vue2m * gamma_ph_q, + ], + [ + Complex::::zero(), + e2avg * gamma_q_ph, + e2avg * gamma_nonsinglet, + vue2m * gamma_nonsinglet, + ], + [ + Complex::::zero(), + vde2m * gamma_q_ph, + vde2m * gamma_nonsinglet, + e2delta * gamma_nonsinglet, + ], + ] +} + +/// Compute the leading-order valence QED anomalous dimension matrix +/// +/// Implements Eq. (2.5) of +pub fn gamma_valence(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { + let cc = charge_combinations(nf); + let e2avg = cc[0]; + let vue2m = cc[1]; + let vde2m = cc[2]; + let e2delta = cc[3]; + + [ + [e2avg * gamma_ns(c, nf), vue2m * gamma_ns(c, nf)], + [vde2m * gamma_ns(c, nf), e2delta * gamma_ns(c, nf)], + ] +} + #[cfg(test)] mod tests { use super::*; From a40908b8a11b91a6a938868b81f159ff41a8844a Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 21 Oct 2024 11:35:08 +0200 Subject: [PATCH 03/32] unit tests --- .../unpolarized/spacelike/aem1.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs index 91427622c..68e30694c 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs @@ -118,4 +118,21 @@ mod tests { let me = gamma_ns(&mut c, NF) + gamma_phq(&mut c, NF); assert_approx_eq_cmplx!(f64, me, Complex::zero(), epsilon = 1e-12); } + + #[test] + fn photon_momentum_conservation() { + const N: Complex = cmplx!(2., 0.); + let mut c = Cache::new(N); + + for nf in 2..7 { + let nu = uplike_flavors(nf); + let nd = nf - nu; + assert_approx_eq_cmplx!( + f64, + eu2 * gamma_qph(&mut c, nu) + ed2 * gamma_qph(&mut c, nd) + gamma_phph(&mut c, nf), + cmplx!(0., 0.), + epsilon = 2e-6 + ); + } + } } From f0edfae5134c029689c98a40fa0131a5e7a2dd11 Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 21 Oct 2024 15:21:20 +0200 Subject: [PATCH 04/32] add struct for charge combinations --- .../unpolarized/spacelike/aem1.rs | 28 +++++++------------ crates/ekore/src/constants.rs | 17 +++++++++-- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs index 68e30694c..8d8d97af1 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs @@ -42,10 +42,6 @@ pub fn gamma_ns(c: &mut Cache, nf: u8) -> Complex { /// Implements Eq. (2.5) of pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { let cc = charge_combinations(nf); - let e2avg = cc[0]; - let vue2m = cc[1]; - let vde2m = cc[2]; - let e2delta = cc[3]; let gamma_ph_q = gamma_phq(c, nf); let gamma_q_ph = gamma_qph(c, nf); @@ -61,20 +57,20 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { [ Complex::::zero(), gamma_phph(c, nf), - e2avg * gamma_ph_q, - vue2m * gamma_ph_q, + cc.e2avg * gamma_ph_q, + cc.vue2m * gamma_ph_q, ], [ Complex::::zero(), - e2avg * gamma_q_ph, - e2avg * gamma_nonsinglet, - vue2m * gamma_nonsinglet, + cc.e2avg * gamma_q_ph, + cc.e2avg * gamma_nonsinglet, + cc.vue2m * gamma_nonsinglet, ], [ Complex::::zero(), - vde2m * gamma_q_ph, - vde2m * gamma_nonsinglet, - e2delta * gamma_nonsinglet, + cc.vde2m * gamma_q_ph, + cc.vde2m * gamma_nonsinglet, + cc.e2delta * gamma_nonsinglet, ], ] } @@ -84,14 +80,10 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { /// Implements Eq. (2.5) of pub fn gamma_valence(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { let cc = charge_combinations(nf); - let e2avg = cc[0]; - let vue2m = cc[1]; - let vde2m = cc[2]; - let e2delta = cc[3]; [ - [e2avg * gamma_ns(c, nf), vue2m * gamma_ns(c, nf)], - [vde2m * gamma_ns(c, nf), e2delta * gamma_ns(c, nf)], + [cc.e2avg * gamma_ns(c, nf), cc.vue2m * gamma_ns(c, nf)], + [cc.vde2m * gamma_ns(c, nf), cc.e2delta * gamma_ns(c, nf)], ] } diff --git a/crates/ekore/src/constants.rs b/crates/ekore/src/constants.rs index 377cb1f77..725b28c8b 100644 --- a/crates/ekore/src/constants.rs +++ b/crates/ekore/src/constants.rs @@ -61,12 +61,25 @@ pub fn uplike_flavors(nf: u8) -> u8 { nf / 2 } -pub fn charge_combinations(nf: u8) -> Vec { +pub struct ChargeCombinations { + pub e2avg: f64, + pub vue2m: f64, + pub vde2m: f64, + pub e2delta: f64, +} + +pub fn charge_combinations(nf: u8) -> ChargeCombinations { let nu = uplike_flavors(nf) as f64; let nd = (nf as f64) - nu; let e2avg = (nu * eu2 + nd * ed2) / (nf as f64); let vue2m = nu / (nf as f64) * (eu2 - ed2); let vde2m = nd / (nf as f64) * (eu2 - ed2); let e2delta = vde2m - vue2m + e2avg; - vec![e2avg, vue2m, vde2m, e2delta] + + ChargeCombinations { + e2avg, + vue2m, + vde2m, + e2delta, + } } From a8d72c02ea5b723e02030c09e2266ebebe517b82 Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 23 Oct 2024 15:58:53 +0200 Subject: [PATCH 05/32] some work on gamma_ns_qed --- .../unpolarized/spacelike.rs | 27 ++++++++++++++++++- crates/ekore/src/constants.rs | 9 +++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs index 3ac896f93..7ff05f431 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs @@ -1,6 +1,8 @@ //! The unpolarized, space-like anomalous dimensions at various couplings power. -use crate::constants::{PID_NSM, PID_NSP, PID_NSV}; +use crate::constants::{ + ed2, eu2, PID_NSM, PID_NSM_ED2, PID_NSM_EU2, PID_NSP, PID_NSP_ED2, PID_NSP_EU2, PID_NSV, +}; use crate::harmonics::cache::Cache; use num::complex::Complex; use num::Zero; @@ -56,3 +58,26 @@ pub fn gamma_singlet_qcd(order_qcd: usize, c: &mut Cache, nf: u8) -> Vec<[[Compl } gamma_S } + +/// Compute the tower of the QED non-singlet anomalous dimensions. +pub fn gamma_ns_qed( + order_qcd: usize, + order_qed: usize, + mode: u16, + c: &mut Cache, + nf: u8, +) -> Vec>> { + let row = vec![Complex::::zero(); order_qcd + 1]; + let mut gamma_ns = vec![row; order_qed + 1]; + gamma_ns[1][0] = as1::gamma_ns(c, nf); + gamma_ns[0][1] = choose_ns_as_aem1(mode, c, nf); + gamma_ns +} + +pub fn choose_ns_as_aem1(mode: u16, c: &mut Cache, nf: u8) -> Complex { + match mode { + PID_NSP_EU2 | PID_NSM_EU2 => eu2 * aem1::gamma_ns(c, nf), + PID_NSP_ED2 | PID_NSM_ED2 => ed2 * aem1::gamma_ns(c, nf), + _ => panic!("Unkown non-singlet sector element"), + } +} diff --git a/crates/ekore/src/constants.rs b/crates/ekore/src/constants.rs index 725b28c8b..7dd00d088 100644 --- a/crates/ekore/src/constants.rs +++ b/crates/ekore/src/constants.rs @@ -53,6 +53,15 @@ pub const PID_NSM: u16 = 10201; /// non-singlet all-valence |PID|. pub const PID_NSV: u16 = 10200; +/// QED |PID|. Need to give sensible names +pub const PID_NSP_EU2: u16 = 10102; + +pub const PID_NSP_ED2: u16 = 10103; + +pub const PID_NSM_EU2: u16 = 10202; + +pub const PID_NSM_ED2: u16 = 10203; + /// compute the number of up flavors pub fn uplike_flavors(nf: u8) -> u8 { if nf > 6 { From e8a3a8bcf8fe7af9d8115c8c9e705d373d6c83af Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 23 Oct 2024 16:22:24 +0200 Subject: [PATCH 06/32] start as1aem1.rs --- .../unpolarized/spacelike.rs | 1 + .../unpolarized/spacelike/as1aem1.rs | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs index 7ff05f431..7a5fc13e8 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs @@ -8,6 +8,7 @@ use num::complex::Complex; use num::Zero; pub mod aem1; pub mod as1; +pub mod as1aem1; pub mod as2; pub mod as3; diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs new file mode 100644 index 000000000..2c9bef29e --- /dev/null +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -0,0 +1,37 @@ +//! The $O(a_s^1a_{em}^1)$ Altarelli-Parisi splitting kernels. +use num::complex::Complex; + +use crate::constants::CF; +use crate::harmonics::cache::{Cache, K}; + +/// Compute the $O(a_s^1a_{em}^1)$ photon-quark anomalous dimension. +/// +/// Implements Eq. (36) of +pub fn gamma_phq(c: &mut Cache, _nf: u8) -> Complex { + let N = c.n(); + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + + #[rustfmt::skip] + let tmp_const = + 2.0 + * ( + -4.0 + - 12.0 * N + - N.powu(2) + + 28.0 * N.powu(3) + + 43.0 * N.powu(4) + + 30.0 * N.powu(5) + + 12.0 * N.powu(6) + ) / ((-1.0 + N) * N.powu(3) * (1.0 + N).powu(3)); + + #[rustfmt::skip] + let tmp_S1 = -4.0 + * (10.0 + 27.0 * N + 25.0 * N.powu(2) + 13.0 * N.powu(3) + 5.0 * N.powu(4)) + / ((-1.0 + N) * N * (1.0 + N).powu(3)); + + let tmp_S12 = 4.0 * (2.0 + N + N.powu(2)) / ((-1.0 + N) * N * (1.0 + N)); + let tmp_S2 = 4.0 * (2.0 + N + N.powu(2)) / ((-1.0 + N) * N * (1.0 + N)); + + CF * (tmp_const + tmp_S1 * S1 + tmp_S12 * S1.powu(2) + tmp_S2 * S2) +} From 136dbe8d32cf80ab222f1a3e2d3fcc5eaff8d2ed Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 23 Oct 2024 16:33:38 +0200 Subject: [PATCH 07/32] gamma_qph as1aem1 --- .../unpolarized/spacelike/as1aem1.rs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs index 2c9bef29e..429d8094e 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -1,7 +1,7 @@ //! The $O(a_s^1a_{em}^1)$ Altarelli-Parisi splitting kernels. use num::complex::Complex; -use crate::constants::CF; +use crate::constants::{CA, CF}; use crate::harmonics::cache::{Cache, K}; /// Compute the $O(a_s^1a_{em}^1)$ photon-quark anomalous dimension. @@ -35,3 +35,28 @@ pub fn gamma_phq(c: &mut Cache, _nf: u8) -> Complex { CF * (tmp_const + tmp_S1 * S1 + tmp_S12 * S1.powu(2) + tmp_S2 * S2) } + +/// Compute the $O(a_s^1a_{em}^1)$ quark-photon anomalous dimension. +/// +/// Implements Eq. (26) of +pub fn gamma_qph(c: &mut Cache, nf: u8) -> Complex { + let N = c.n(); + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + + let tmp_const = -2.0 + * (4.0 + + 8.0 * N + + 25.0 * N.powu(2) + + 51.0 * N.powu(3) + + 36.0 * N.powu(4) + + 15.0 * N.powu(5) + + 5.0 * N.powu(6)) + / (N.powu(3) * (1.0 + N).powu(3) * (2.0 + N)); + + let tmp_S1 = 8.0 / N.powu(2); + let tmp_S12 = -4.0 * (2.0 + N + N.powu(2)) / (N * (1.0 + N) * (2.0 + N)); + let tmp_S2 = 4.0 * (2.0 + N + N.powu(2)) / (N * (1.0 + N) * (2.0 + N)); + + 2.0 * (nf as f64) * CA * CF * (tmp_const + tmp_S1 * S1 + tmp_S12 * S1.powu(2) + tmp_S2 * S2) +} From ce11227a32ecba72bfddbdeef0c3e91863291b35 Mon Sep 17 00:00:00 2001 From: tgiani Date: Fri, 25 Oct 2024 12:07:35 +0200 Subject: [PATCH 08/32] some work on as1aem1 --- .../unpolarized/spacelike/as1aem1.rs | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs index 429d8094e..6a77690aa 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -1,7 +1,8 @@ //! The $O(a_s^1a_{em}^1)$ Altarelli-Parisi splitting kernels. +use crate::cmplx; use num::complex::Complex; -use crate::constants::{CA, CF}; +use crate::constants::{ed2, eu2, uplike_flavors, CA, CF, NC, TR}; use crate::harmonics::cache::{Cache, K}; /// Compute the $O(a_s^1a_{em}^1)$ photon-quark anomalous dimension. @@ -60,3 +61,50 @@ pub fn gamma_qph(c: &mut Cache, nf: u8) -> Complex { 2.0 * (nf as f64) * CA * CF * (tmp_const + tmp_S1 * S1 + tmp_S12 * S1.powu(2) + tmp_S2 * S2) } + +/// Compute the $O(a_s^1a_{em}^1)$ gluon-photon anomalous dimension. +/// +/// Implements Eq. (27) of +pub fn gamma_gph(c: &mut Cache, _nf: u8) -> Complex { + let N = c.n(); + CF * CA + * (8.0 * (-4.0 + N * (-4.0 + N * (-5.0 + N * (-10.0 + N + 2.0 * N.powu(2) * (2.0 + N)))))) + / (N.powu(3) * (1.0 + N).powu(3) * (-2.0 + N + N.powu(2))) +} + +/// Compute the $O(a_s^1a_{em}^1)$ photon-gluon anomalous dimension. +/// +/// Implements Eq. (30) of +pub fn gamma_phg(c: &mut Cache, nf: u8) -> Complex { + TR / CF / CA * (NC as f64) * gamma_gph(c, nf) +} + +/// Compute the $O(a_s^1a_{em}^1)$ quark-gluon singlet anomalous dimension. +/// +/// Implements Eq. (29) of +pub fn gamma_qg(c: &mut Cache, nf: u8) -> Complex { + TR / CF / CA * (NC as f64) * gamma_qph(c, nf) +} + +/// Compute the $O(a_s^1a_{em}^1)$ gluon-quark singlet anomalous dimension. +/// +/// Implements Eq. (35) of +pub fn gamma_gq(c: &mut Cache, nf: u8) -> Complex { + gamma_phq(c, nf) +} + +/// Compute the $O(a_s^1a_{em}^1)$ photon-photon singlet anomalous dimension. +/// +/// Implements Eq. (28) of +pub fn gamma_phph(_c: &mut Cache, nf: u8) -> Complex { + let nu = uplike_flavors(nf); + let nd = nf - nu; + cmplx!(4.0 * CF * CA * ((nu as f64) * eu2 + (nd as f64) * ed2), 0.) +} + +/// Compute the $O(a_s^1a_{em}^1)$ gluon-gluon singlet anomalous dimension. +/// +/// Implements Eq. (31) of +pub fn gamma_gg(_c: &mut Cache, _nf: u8) -> Complex { + cmplx!(4.0 * TR * (NC as f64), 0.) +} From 659fe3112f4e840569b927369905a16c4dcb4961 Mon Sep 17 00:00:00 2001 From: tgiani Date: Fri, 25 Oct 2024 14:01:41 +0200 Subject: [PATCH 09/32] addingv recursive harmonics to cache --- crates/ekore/src/harmonics/cache.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/ekore/src/harmonics/cache.rs b/crates/ekore/src/harmonics/cache.rs index da0f4800b..f8dfd487c 100644 --- a/crates/ekore/src/harmonics/cache.rs +++ b/crates/ekore/src/harmonics/cache.rs @@ -46,6 +46,10 @@ pub enum K { Sm21e, /// $S_{-2,1}(N)$ odd moments Sm21o, + /// recursive harmonics + S1ph, + S2ph, + S3ph, } /// Hold all cached values. @@ -98,6 +102,9 @@ impl Cache { K::Sm3o => w3::Sm3o(self.get(K::S3), self.get(K::S3mh)), K::Sm21e => w3::Sm21e(self.n, self.get(K::S1), self.get(K::Sm1e)), K::Sm21o => w3::Sm21o(self.n, self.get(K::S1), self.get(K::Sm1o)), + K::S1ph => recursive_harmonic_sum(self.get(K::S1mh), (self.n - 1.) / 2., 1, 1), + K::S2ph => recursive_harmonic_sum(self.get(K::S2mh), (self.n - 1.) / 2., 1, 2), + K::S3ph => recursive_harmonic_sum(self.get(K::S3mh), (self.n - 1.) / 2., 1, 3), }; // insert self.m.insert(k, val); From 4007f0dedd5e09869d0cfd449209d6d2d0097be8 Mon Sep 17 00:00:00 2001 From: tgiani Date: Fri, 25 Oct 2024 14:24:11 +0200 Subject: [PATCH 10/32] S1p2 and G3p2. Check that this is correct --- crates/ekore/src/harmonics/cache.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/ekore/src/harmonics/cache.rs b/crates/ekore/src/harmonics/cache.rs index f8dfd487c..a9dc6ad25 100644 --- a/crates/ekore/src/harmonics/cache.rs +++ b/crates/ekore/src/harmonics/cache.rs @@ -50,6 +50,8 @@ pub enum K { S1ph, S2ph, S3ph, + S1p2, + G3p2, } /// Hold all cached values. @@ -94,6 +96,7 @@ impl Cache { K::S2mh => w2::S2((self.n - 1.) / 2.), K::S3mh => w3::S3((self.n - 1.) / 2.), K::G3 => g_functions::g3(self.n, self.get(K::S1)), + K::G3p2 => g_functions::g3(self.n + 2., self.get(K::S1p2)), K::Sm1e => w1::Sm1e(self.get(K::S1), self.get(K::S1h)), K::Sm1o => w1::Sm1o(self.get(K::S1), self.get(K::S1mh)), K::Sm2e => w2::Sm2e(self.get(K::S2), self.get(K::S2h)), @@ -105,6 +108,7 @@ impl Cache { K::S1ph => recursive_harmonic_sum(self.get(K::S1mh), (self.n - 1.) / 2., 1, 1), K::S2ph => recursive_harmonic_sum(self.get(K::S2mh), (self.n - 1.) / 2., 1, 2), K::S3ph => recursive_harmonic_sum(self.get(K::S3mh), (self.n - 1.) / 2., 1, 3), + K::S1p2 => recursive_harmonic_sum(self.get(K::S1), self.n, 2, 1), }; // insert self.m.insert(k, val); From 7c160f1d9da7018a331d718b2bb68ac6a83bfa41 Mon Sep 17 00:00:00 2001 From: tgiani Date: Fri, 25 Oct 2024 14:29:58 +0200 Subject: [PATCH 11/32] gamma_nsp --- .../unpolarized/spacelike/as1aem1.rs | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs index 6a77690aa..2eedf14ec 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -2,7 +2,7 @@ use crate::cmplx; use num::complex::Complex; -use crate::constants::{ed2, eu2, uplike_flavors, CA, CF, NC, TR}; +use crate::constants::{ed2, eu2, uplike_flavors, CA, CF, NC, TR, ZETA2, ZETA3}; use crate::harmonics::cache::{Cache, K}; /// Compute the $O(a_s^1a_{em}^1)$ photon-quark anomalous dimension. @@ -45,6 +45,7 @@ pub fn gamma_qph(c: &mut Cache, nf: u8) -> Complex { let S1 = c.get(K::S1); let S2 = c.get(K::S2); + #[rustfmt::skip] let tmp_const = -2.0 * (4.0 + 8.0 * N @@ -108,3 +109,34 @@ pub fn gamma_phph(_c: &mut Cache, nf: u8) -> Complex { pub fn gamma_gg(_c: &mut Cache, _nf: u8) -> Complex { cmplx!(4.0 * TR * (NC as f64), 0.) } + +/// Compute the $O(a_s^1a_{em}^1)$ singlet-like non singlet anomalous dimension. +/// +/// Implements Eqs. (33-34) of +pub fn gamma_nsp(c: &mut Cache, _nf: u8) -> Complex { + let N = c.n(); + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let S3 = c.get(K::S3); + let S1h = c.get(K::S1h); + let S2h = c.get(K::S2h); + let S3h = c.get(K::S3h); + let S1p1h = c.get(K::S1ph); + let S2p1h = c.get(K::S2ph); + let S3p1h = c.get(K::S3ph); + let g3N = c.get(K::G3); + let g3Np2 = c.get(K::G3p2); + + #[rustfmt::skip] + let result = 32.0 * ZETA2 * S1h - 32.0 * ZETA2 * S1p1h + + 8.0 / (N + N.powu(2)) * S2h + - 4.0 * S3h + (24.0 + 16.0 / (N + N.powu(2))) * S2 + - 32.0 * S3 - 8.0 / (N + N.powu(2)) * S2p1h + + S1 * (16.0 * (3.0 / N.powu(2) - 3.0 / (1.0 + N).powu(2) + 2.0 * ZETA2) - 16.0 * S2h + - 32.0 * S2 + 16.0 * S2p1h ) + + (-8.0 + N * (-32.0 + N * ( -8.0 - 3.0 * N * (3.0 + N) * (3.0 + N.powu(2)) - 48.0 * (1.0 + N).powu(2) * ZETA2))) + / (N.powu(3) * (1.0 + N).powu(3)) + + 32.0 * (g3N + g3Np2) + 4.0 * S3p1h - 16.0 * ZETA3; + + CF * result +} From 37a65e8b066502729e2af48621da83caa8c6f5c3 Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 11 Nov 2024 15:53:22 +0100 Subject: [PATCH 12/32] rewrite ChargeCombination struct --- .../unpolarized/spacelike/aem1.rs | 26 +++++----- .../unpolarized/spacelike/as1aem1.rs | 51 +++++++++++++++++++ crates/ekore/src/constants.rs | 41 ++++++++------- 3 files changed, 88 insertions(+), 30 deletions(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs index 8d8d97af1..bc70ed97f 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs @@ -2,7 +2,7 @@ use num::complex::Complex; use num::Zero; -use crate::constants::{charge_combinations, ed2, eu2, uplike_flavors, CF, NC, TR}; +use crate::constants::{ed2, eu2, uplike_flavors, ChargeCombinations, CF, NC, TR}; use crate::harmonics::cache::Cache; use crate::anomalous_dimensions::unpolarized::spacelike::as1; @@ -41,7 +41,7 @@ pub fn gamma_ns(c: &mut Cache, nf: u8) -> Complex { /// /// Implements Eq. (2.5) of pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { - let cc = charge_combinations(nf); + let cc = ChargeCombinations { nf }; let gamma_ph_q = gamma_phq(c, nf); let gamma_q_ph = gamma_qph(c, nf); @@ -57,20 +57,20 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { [ Complex::::zero(), gamma_phph(c, nf), - cc.e2avg * gamma_ph_q, - cc.vue2m * gamma_ph_q, + cc.e2avg() * gamma_ph_q, + cc.vue2m() * gamma_ph_q, ], [ Complex::::zero(), - cc.e2avg * gamma_q_ph, - cc.e2avg * gamma_nonsinglet, - cc.vue2m * gamma_nonsinglet, + cc.e2avg() * gamma_q_ph, + cc.e2avg() * gamma_nonsinglet, + cc.vue2m() * gamma_nonsinglet, ], [ Complex::::zero(), - cc.vde2m * gamma_q_ph, - cc.vde2m * gamma_nonsinglet, - cc.e2delta * gamma_nonsinglet, + cc.vde2m() * gamma_q_ph, + cc.vde2m() * gamma_nonsinglet, + cc.e2delta() * gamma_nonsinglet, ], ] } @@ -79,11 +79,11 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { /// /// Implements Eq. (2.5) of pub fn gamma_valence(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { - let cc = charge_combinations(nf); + let cc = ChargeCombinations { nf }; [ - [cc.e2avg * gamma_ns(c, nf), cc.vue2m * gamma_ns(c, nf)], - [cc.vde2m * gamma_ns(c, nf), cc.e2delta * gamma_ns(c, nf)], + [cc.e2avg() * gamma_ns(c, nf), cc.vue2m() * gamma_ns(c, nf)], + [cc.vde2m() * gamma_ns(c, nf), cc.e2delta() * gamma_ns(c, nf)], ] } diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs index 2eedf14ec..917ea45a7 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -124,6 +124,7 @@ pub fn gamma_nsp(c: &mut Cache, _nf: u8) -> Complex { let S1p1h = c.get(K::S1ph); let S2p1h = c.get(K::S2ph); let S3p1h = c.get(K::S3ph); + let g3N = c.get(K::G3); let g3Np2 = c.get(K::G3p2); @@ -140,3 +141,53 @@ pub fn gamma_nsp(c: &mut Cache, _nf: u8) -> Complex { CF * result } + +/// Compute the $O(a_s^1a_{em}^1)$ valence-like non singlet anomalous dimension. +/// +/// Implements Eqs. (33-34) of +pub fn gamma_nsm(c: &mut Cache, _nf: u8) -> Complex { + let N = c.n(); + let S1 = c.get(K::S1); + let S2 = c.get(K::S2); + let S3 = c.get(K::S3); + let S1h = c.get(K::S1h); + let S2h = c.get(K::S2h); + let S3h = c.get(K::S3h); + let S1p1h = c.get(K::S1ph); + let S2p1h = c.get(K::S2ph); + let S3p1h = c.get(K::S3ph); + let g3N = c.get(K::G3); + let g3Np2 = c.get(K::G3p2); + + #[rustfmt::skip] + let result = + -32.0 * ZETA2 * S1h + - 8.0 / (N + N.powu(2)) * S2h + + (24.0 + 16.0 / (N + N.powu(2))) * S2 + + 8.0 / (N + N.powu(2)) * S2p1h + + S1 + * ( + 16.0 * (-1.0 / N.powu(2) + 1.0 / (1.0 + N).powu(2) + 2.0 * ZETA2) + + 16.0 * S2h + - 32.0 * S2 + - 16.0 * S2p1h + ) + + ( + 72.0 + + N + * ( + 96.0 + - 3.0 * N * (8.0 + 3.0 * N * (3.0 + N) * (3.0 + N.powu(2))) + + 48.0 * N * (1.0 + N).powu(2) * ZETA2 + ) + ) + / (3.0 * N.powu(3) * (1.0 + N).powu(3)) + - 32.0 * (g3N + g3Np2) + + 32.0 * ZETA2 * S1p1h + + 4.0 * S3h + - 32.0 * S3 + - 4.0 * S3p1h + - 16.0 * ZETA3; + + CF * result +} diff --git a/crates/ekore/src/constants.rs b/crates/ekore/src/constants.rs index 7dd00d088..80c3bc807 100644 --- a/crates/ekore/src/constants.rs +++ b/crates/ekore/src/constants.rs @@ -71,24 +71,31 @@ pub fn uplike_flavors(nf: u8) -> u8 { } pub struct ChargeCombinations { - pub e2avg: f64, - pub vue2m: f64, - pub vde2m: f64, - pub e2delta: f64, + pub nf: u8, } -pub fn charge_combinations(nf: u8) -> ChargeCombinations { - let nu = uplike_flavors(nf) as f64; - let nd = (nf as f64) - nu; - let e2avg = (nu * eu2 + nd * ed2) / (nf as f64); - let vue2m = nu / (nf as f64) * (eu2 - ed2); - let vde2m = nd / (nf as f64) * (eu2 - ed2); - let e2delta = vde2m - vue2m + e2avg; - - ChargeCombinations { - e2avg, - vue2m, - vde2m, - e2delta, +impl ChargeCombinations { + pub fn nu(&self) -> u8 { + uplike_flavors(self.nf) + } + + pub fn nd(&self) -> u8 { + self.nf - self.nu() + } + + pub fn e2avg(&self) -> f64 { + (self.nu() as f64 * eu2 + self.nd() as f64 * ed2) / (self.nf as f64) + } + + pub fn vue2m(&self) -> f64 { + self.nu() as f64 / (self.nf as f64) * (eu2 - ed2) + } + + pub fn vde2m(&self) -> f64 { + self.nd() as f64 / (self.nf as f64) * (eu2 - ed2) + } + + pub fn e2delta(&self) -> f64 { + self.vde2m() - self.vue2m() + self.e2avg() } } From fc5de81d706fd282db40508f6e5324418c240c39 Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 11 Nov 2024 16:14:21 +0100 Subject: [PATCH 13/32] missing entries in as1aem1 --- .../unpolarized/spacelike/as1aem1.rs | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs index 917ea45a7..19f598466 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -2,7 +2,9 @@ use crate::cmplx; use num::complex::Complex; -use crate::constants::{ed2, eu2, uplike_flavors, CA, CF, NC, TR, ZETA2, ZETA3}; +use crate::constants::{ + ed2, eu2, uplike_flavors, ChargeCombinations, CA, CF, NC, TR, ZETA2, ZETA3, +}; use crate::harmonics::cache::{Cache, K}; /// Compute the $O(a_s^1a_{em}^1)$ photon-quark anomalous dimension. @@ -191,3 +193,52 @@ pub fn gamma_nsm(c: &mut Cache, _nf: u8) -> Complex { CF * result } + +/// Compute the $O(a_s^1a_{em}^1)$ singlet sector. +pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { + let cc = ChargeCombinations { nf }; + // let e2avg = cc.e2avg(); + // let vue2m = cc.vue2m(); + // let vde2m = cc.vde2m(); + // let e2delta = cc.e2delta(); + let e2_tot = nf as f64 * cc.e2avg(); + + [ + [ + e2_tot * gamma_gg(c, nf), + e2_tot * gamma_gph(c, nf), + cc.e2avg() * gamma_gq(c, nf), + cc.vue2m() * gamma_gq(c, nf), + ], + [ + e2_tot * gamma_phg(c, nf), + gamma_phph(c, nf), + cc.e2avg() * gamma_phq(c, nf), + cc.vue2m() * gamma_phq(c, nf), + ], + [ + cc.e2avg() * gamma_qg(c, nf), + cc.e2avg() * gamma_qph(c, nf), + cc.e2avg() * gamma_nsp(c, nf), + cc.vue2m() * gamma_nsp(c, nf), + ], + [ + cc.vde2m() * gamma_qg(c, nf), + cc.vde2m() * gamma_qph(c, nf), + cc.vde2m() * gamma_nsp(c, nf), + cc.e2delta() * gamma_nsp(c, nf), + ], + ] +} + +/// Compute the $O(a_s^1a_{em}^1)$ valence sector. +pub fn gamma_valence(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { + let cc = ChargeCombinations { nf }; + [ + [cc.e2avg() * gamma_nsm(c, nf), cc.vue2m() * gamma_nsm(c, nf)], + [ + cc.vde2m() * gamma_nsm(c, nf) * gamma_nsm(c, nf), + cc.e2delta() * gamma_nsm(c, nf), + ], + ] +} From 2a911b1b22ca45b33f698700649d4f0a38073db8 Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 11 Nov 2024 16:38:29 +0100 Subject: [PATCH 14/32] adding tests --- .../unpolarized/spacelike/as1aem1.rs | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs index 19f598466..b96ed3680 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -242,3 +242,68 @@ pub fn gamma_valence(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { ], ] } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{assert_approx_eq_cmplx, cmplx}; + use num::complex::Complex; + use num::Zero; + const NF: u8 = 5; + + #[test] + fn number_conservation() { + const N: Complex = cmplx!(1., 0.); + let mut c = Cache::new(N); + let me = gamma_nsm(&mut c, NF); + assert_approx_eq_cmplx!(f64, me, Complex::zero(), epsilon = 1e-4); + } + + #[test] + fn gluon_momentum_conservation() { + const N: Complex = cmplx!(2., 0.); + let mut c = Cache::new(N); + + for nf in 2..7 { + let nu = uplike_flavors(nf); + let nd = nf - nu; + assert_approx_eq_cmplx!( + f64, + eu2 * gamma_qg(&mut c, nu) + + ed2 * gamma_qg(&mut c, nd) + + (nu as f64 * eu2 + nd as f64 * ed2) * gamma_phg(&mut c, nf) + + (nu as f64 * eu2 + nd as f64 * ed2) * gamma_gg(&mut c, nf), + cmplx!(0., 0.), + epsilon = 1e-14 + ); + } + } + + #[test] + fn photon_momentum_conservation() { + const N: Complex = cmplx!(2., 0.); + let mut c = Cache::new(N); + + for nf in 2..7 { + let nu = uplike_flavors(nf); + let nd = nf - nu; + assert_approx_eq_cmplx!( + f64, + eu2 * gamma_qph(&mut c, nu) + + ed2 * gamma_qph(&mut c, nd) + + gamma_phph(&mut c, nf) + + (nu as f64 * eu2 + nd as f64 * ed2) * gamma_gph(&mut c, nf), + cmplx!(0., 0.), + epsilon = 1e-14 + ); + } + } + + #[test] + fn quark_momentum_conservation() { + const N: Complex = cmplx!(2., 0.); + let mut c = Cache::new(N); + let me = gamma_nsp(&mut c, NF) + gamma_gq(&mut c, NF) + gamma_phq(&mut c, NF); + assert_approx_eq_cmplx!(f64, me, Complex::zero(), epsilon = 1e-4); + } +} From bad124ac40aca464729d962e05ef4bb4e6553adb Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 20 Nov 2024 11:10:25 +0100 Subject: [PATCH 15/32] some work on spacelike.rs and recasting from list to vec --- .../unpolarized/spacelike.rs | 39 +++++++++++++++++++ .../unpolarized/spacelike/aem1.rs | 4 +- .../unpolarized/spacelike/as1.rs | 32 +++++++++++++++ .../unpolarized/spacelike/as1aem1.rs | 4 +- 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs index 7a5fc13e8..f41e52266 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs @@ -72,6 +72,7 @@ pub fn gamma_ns_qed( let mut gamma_ns = vec![row; order_qed + 1]; gamma_ns[1][0] = as1::gamma_ns(c, nf); gamma_ns[0][1] = choose_ns_as_aem1(mode, c, nf); + gamma_ns[1][1] = choose_ns_as_as1aem1(mode, c, nf); gamma_ns } @@ -82,3 +83,41 @@ pub fn choose_ns_as_aem1(mode: u16, c: &mut Cache, nf: u8) -> Complex { _ => panic!("Unkown non-singlet sector element"), } } + +pub fn choose_ns_as_as1aem1(mode: u16, c: &mut Cache, nf: u8) -> Complex { + match mode { + PID_NSP_EU2 => eu2 * as1aem1::gamma_nsp(c, nf), + PID_NSP_ED2 => ed2 * as1aem1::gamma_nsp(c, nf), + PID_NSM_EU2 => eu2 * as1aem1::gamma_nsm(c, nf), + PID_NSM_ED2 => ed2 * as1aem1::gamma_nsm(c, nf), + _ => panic!("Unkown non-singlet sector element"), + } +} + +pub fn gamma_singlet_qed( + order_qcd: usize, + order_qed: usize, + mode: u16, + c: &mut Cache, + nf: u8, +) -> Vec; 4]>>> { + let mut row = vec![ + vec![ + [ + Complex::::zero(), + Complex::::zero(), + Complex::::zero(), + Complex::::zero() + ]; + 4 + ]; + order_qcd + 1 + ]; + + let mut gamma_s = vec![row; order_qed + 1]; + + gamma_s[1][0] = as1::gamma_singlet_qed(c, nf); + gamma_s[0][1] = aem1::gamma_singlet(c, nf); + gamma_s[1][1] = as1aem1::gamma_singlet(c, nf); + gamma_s +} diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs index bc70ed97f..7791d9552 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs @@ -40,14 +40,14 @@ pub fn gamma_ns(c: &mut Cache, nf: u8) -> Complex { /// Compute the leading-order singlet QED anomalous dimension matrix /// /// Implements Eq. (2.5) of -pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { +pub fn gamma_singlet(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { let cc = ChargeCombinations { nf }; let gamma_ph_q = gamma_phq(c, nf); let gamma_q_ph = gamma_qph(c, nf); let gamma_nonsinglet = gamma_ns(c, nf); - [ + vec![ [ Complex::::zero(), Complex::::zero(), diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs index 6d25e1c51..dad16e819 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs @@ -1,6 +1,7 @@ //! |LO| |QCD|. use num::complex::Complex; +use num::Zero; use crate::constants::{CA, CF, TR}; use crate::harmonics::cache::{Cache, K}; @@ -52,6 +53,37 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { ] } +/// Compute the leading-order singlet anomalous dimension matrix +/// for the unified evolution basis. +pub fn gamma_singlet_qed(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { + vec![ + [ + gamma_gg(c, nf), + Complex::::zero(), + gamma_gq(c, nf), + Complex::::zero(), + ], + [ + Complex::::zero(), + Complex::::zero(), + Complex::::zero(), + Complex::::zero(), + ], + [ + gamma_qg(c, nf), + Complex::::zero(), + gamma_ns(c, nf), + Complex::::zero(), + ], + [ + Complex::::zero(), + Complex::::zero(), + Complex::::zero(), + gamma_ns(c, nf), + ], + ] +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs index b96ed3680..a9ae80770 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -195,7 +195,7 @@ pub fn gamma_nsm(c: &mut Cache, _nf: u8) -> Complex { } /// Compute the $O(a_s^1a_{em}^1)$ singlet sector. -pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { +pub fn gamma_singlet(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { let cc = ChargeCombinations { nf }; // let e2avg = cc.e2avg(); // let vue2m = cc.vue2m(); @@ -203,7 +203,7 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { // let e2delta = cc.e2delta(); let e2_tot = nf as f64 * cc.e2avg(); - [ + vec![ [ e2_tot * gamma_gg(c, nf), e2_tot * gamma_gph(c, nf), From d50e9c735f248189486e2990e1f8726df3a482ee Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 20 Nov 2024 15:13:56 +0100 Subject: [PATCH 16/32] valence qed --- .../unpolarized/spacelike.rs | 20 +++++++++++++++++-- .../unpolarized/spacelike/aem1.rs | 4 ++-- .../unpolarized/spacelike/as1.rs | 9 +++++++++ .../unpolarized/spacelike/as1aem1.rs | 8 ++------ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs index f41e52266..e7f94273f 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs @@ -94,14 +94,14 @@ pub fn choose_ns_as_as1aem1(mode: u16, c: &mut Cache, nf: u8) -> Complex { } } +/// Compute the grid of the QED singlet anomalous dimensions matrices pub fn gamma_singlet_qed( order_qcd: usize, order_qed: usize, - mode: u16, c: &mut Cache, nf: u8, ) -> Vec; 4]>>> { - let mut row = vec![ + let row = vec![ vec![ [ Complex::::zero(), @@ -121,3 +121,19 @@ pub fn gamma_singlet_qed( gamma_s[1][1] = as1aem1::gamma_singlet(c, nf); gamma_s } + +/// Compute the grid of the QED valence anomalous dimensions matrices +pub fn gamma_valence_qed( + order_qcd: usize, + order_qed: usize, + c: &mut Cache, + nf: u8, +) -> Vec; 2]>>> { + let row = vec![vec![[Complex::::zero(), Complex::::zero(),]; 2]; order_qcd + 1]; + + let mut gamma_v = vec![row; order_qed + 1]; + gamma_v[1][0] = as1::gamma_valence_qed(c, nf); + gamma_v[0][1] = aem1::gamma_valence(c, nf); + gamma_v[1][1] = as1aem1::gamma_valence(c, nf); + gamma_v +} diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs index 7791d9552..ded4825d7 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs @@ -78,10 +78,10 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { /// Compute the leading-order valence QED anomalous dimension matrix /// /// Implements Eq. (2.5) of -pub fn gamma_valence(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { +pub fn gamma_valence(c: &mut Cache, nf: u8) -> Vec<[Complex; 2]> { let cc = ChargeCombinations { nf }; - [ + vec![ [cc.e2avg() * gamma_ns(c, nf), cc.vue2m() * gamma_ns(c, nf)], [cc.vde2m() * gamma_ns(c, nf), cc.e2delta() * gamma_ns(c, nf)], ] diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs index dad16e819..8075804de 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs @@ -84,6 +84,15 @@ pub fn gamma_singlet_qed(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { ] } +/// Compute the leading-order valence anomalous dimension matrix +/// for the unified evolution basis. +pub fn gamma_valence_qed(c: &mut Cache, nf: u8) -> Vec<[Complex; 2]> { + vec![ + [gamma_ns(c, nf), Complex::::zero()], + [Complex::::zero(), gamma_ns(c, nf)], + ] +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs index a9ae80770..a7ee20db9 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -197,10 +197,6 @@ pub fn gamma_nsm(c: &mut Cache, _nf: u8) -> Complex { /// Compute the $O(a_s^1a_{em}^1)$ singlet sector. pub fn gamma_singlet(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { let cc = ChargeCombinations { nf }; - // let e2avg = cc.e2avg(); - // let vue2m = cc.vue2m(); - // let vde2m = cc.vde2m(); - // let e2delta = cc.e2delta(); let e2_tot = nf as f64 * cc.e2avg(); vec![ @@ -232,9 +228,9 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { } /// Compute the $O(a_s^1a_{em}^1)$ valence sector. -pub fn gamma_valence(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { +pub fn gamma_valence(c: &mut Cache, nf: u8) -> Vec<[Complex; 2]> { let cc = ChargeCombinations { nf }; - [ + vec![ [cc.e2avg() * gamma_nsm(c, nf), cc.vue2m() * gamma_nsm(c, nf)], [ cc.vde2m() * gamma_nsm(c, nf) * gamma_nsm(c, nf), From b0f6722f7281f2c682140ff81969a177c3996529 Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 20 Nov 2024 16:21:02 +0100 Subject: [PATCH 17/32] some unit tests --- .../unpolarized/spacelike.rs | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs index e7f94273f..5d50ca6b5 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs @@ -137,3 +137,94 @@ pub fn gamma_valence_qed( gamma_v[1][1] = as1aem1::gamma_valence(c, nf); gamma_v } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{assert_approx_eq_cmplx, cmplx}; + use num::complex::Complex; + use num::Zero; + + #[test] + fn gamma_ns() { + const NF: u8 = 3; + const N: Complex = cmplx!(1., 0.); + let mut c = Cache::new(N); + assert_approx_eq_cmplx!( + f64, + gamma_ns_qcd(3, PID_NSP, &mut c, NF)[0], + cmplx!(0., 0.), + epsilon = 1e-14 + ); + + for i in [0, 1] { + assert_approx_eq_cmplx!( + f64, + gamma_ns_qcd(2, PID_NSM, &mut c, NF)[i], + cmplx!(0., 0.), + epsilon = 2e-6 + ); + } + + for i in 0..3 { + assert_approx_eq_cmplx!( + f64, + gamma_ns_qcd(3, PID_NSM, &mut c, NF)[i], + cmplx!(0., 0.), + epsilon = 2e-4 + ); + } + + for i in 0..3 { + assert_approx_eq_cmplx!( + f64, + gamma_ns_qcd(3, PID_NSV, &mut c, NF)[i], + cmplx!(0., 0.), + epsilon = 8e-4 + ); + } + } + + #[test] + fn test_gamma_ns_qed() { + const NF: u8 = 3; + const N: Complex = cmplx!(1., 0.); + let mut c = Cache::new(N); + + for i in [0, 1] { + for j in [0, 1] { + assert_approx_eq_cmplx!( + f64, + gamma_ns_qed(1, 1, PID_NSM_EU2, &mut c, NF)[i][j], + cmplx!(0., 0.), + epsilon = 1e-5 + ); + } + } + + for i in [0, 1] { + for j in [0, 1] { + assert_approx_eq_cmplx!( + f64, + gamma_ns_qed(1, 1, PID_NSM_ED2, &mut c, NF)[i][j], + cmplx!(0., 0.), + epsilon = 1e-5 + ); + } + } + + assert_approx_eq_cmplx!( + f64, + gamma_ns_qed(1, 1, PID_NSP_EU2, &mut c, NF)[0][1], + cmplx!(0., 0.), + epsilon = 1e-5 + ); + + assert_approx_eq_cmplx!( + f64, + gamma_ns_qed(1, 1, PID_NSP_ED2, &mut c, NF)[0][1], + cmplx!(0., 0.), + epsilon = 1e-5 + ); + } +} From e4c621b4dbdeea576bdc77c510d76f342aa318ba Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 20 Nov 2024 17:25:44 +0100 Subject: [PATCH 18/32] use Vec<> only when dimension is not known, else use normal list --- .../unpolarized/spacelike.rs | 22 ++++++++----------- .../unpolarized/spacelike/aem1.rs | 8 +++---- .../unpolarized/spacelike/as1.rs | 8 +++---- .../unpolarized/spacelike/as1aem1.rs | 8 +++---- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs index 5d50ca6b5..810e004a9 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs @@ -94,23 +94,19 @@ pub fn choose_ns_as_as1aem1(mode: u16, c: &mut Cache, nf: u8) -> Complex { } } -/// Compute the grid of the QED singlet anomalous dimensions matrices pub fn gamma_singlet_qed( order_qcd: usize, order_qed: usize, c: &mut Cache, nf: u8, -) -> Vec; 4]>>> { +) -> Vec; 4]; 4]>> { let row = vec![ - vec![ - [ - Complex::::zero(), - Complex::::zero(), - Complex::::zero(), - Complex::::zero() - ]; - 4 - ]; + [[ + Complex::::zero(), + Complex::::zero(), + Complex::::zero(), + Complex::::zero() + ]; 4]; order_qcd + 1 ]; @@ -128,8 +124,8 @@ pub fn gamma_valence_qed( order_qed: usize, c: &mut Cache, nf: u8, -) -> Vec; 2]>>> { - let row = vec![vec![[Complex::::zero(), Complex::::zero(),]; 2]; order_qcd + 1]; +) -> Vec; 2]; 2]>> { + let row = vec![[[Complex::::zero(), Complex::::zero(),]; 2]; order_qcd + 1]; let mut gamma_v = vec![row; order_qed + 1]; gamma_v[1][0] = as1::gamma_valence_qed(c, nf); diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs index ded4825d7..bc70ed97f 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/aem1.rs @@ -40,14 +40,14 @@ pub fn gamma_ns(c: &mut Cache, nf: u8) -> Complex { /// Compute the leading-order singlet QED anomalous dimension matrix /// /// Implements Eq. (2.5) of -pub fn gamma_singlet(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { +pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { let cc = ChargeCombinations { nf }; let gamma_ph_q = gamma_phq(c, nf); let gamma_q_ph = gamma_qph(c, nf); let gamma_nonsinglet = gamma_ns(c, nf); - vec![ + [ [ Complex::::zero(), Complex::::zero(), @@ -78,10 +78,10 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { /// Compute the leading-order valence QED anomalous dimension matrix /// /// Implements Eq. (2.5) of -pub fn gamma_valence(c: &mut Cache, nf: u8) -> Vec<[Complex; 2]> { +pub fn gamma_valence(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { let cc = ChargeCombinations { nf }; - vec![ + [ [cc.e2avg() * gamma_ns(c, nf), cc.vue2m() * gamma_ns(c, nf)], [cc.vde2m() * gamma_ns(c, nf), cc.e2delta() * gamma_ns(c, nf)], ] diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs index 8075804de..bd2c67045 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1.rs @@ -55,8 +55,8 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { /// Compute the leading-order singlet anomalous dimension matrix /// for the unified evolution basis. -pub fn gamma_singlet_qed(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { - vec![ +pub fn gamma_singlet_qed(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { + [ [ gamma_gg(c, nf), Complex::::zero(), @@ -86,8 +86,8 @@ pub fn gamma_singlet_qed(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { /// Compute the leading-order valence anomalous dimension matrix /// for the unified evolution basis. -pub fn gamma_valence_qed(c: &mut Cache, nf: u8) -> Vec<[Complex; 2]> { - vec![ +pub fn gamma_valence_qed(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { + [ [gamma_ns(c, nf), Complex::::zero()], [Complex::::zero(), gamma_ns(c, nf)], ] diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs index a7ee20db9..546acca85 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike/as1aem1.rs @@ -195,11 +195,11 @@ pub fn gamma_nsm(c: &mut Cache, _nf: u8) -> Complex { } /// Compute the $O(a_s^1a_{em}^1)$ singlet sector. -pub fn gamma_singlet(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { +pub fn gamma_singlet(c: &mut Cache, nf: u8) -> [[Complex; 4]; 4] { let cc = ChargeCombinations { nf }; let e2_tot = nf as f64 * cc.e2avg(); - vec![ + [ [ e2_tot * gamma_gg(c, nf), e2_tot * gamma_gph(c, nf), @@ -228,9 +228,9 @@ pub fn gamma_singlet(c: &mut Cache, nf: u8) -> Vec<[Complex; 4]> { } /// Compute the $O(a_s^1a_{em}^1)$ valence sector. -pub fn gamma_valence(c: &mut Cache, nf: u8) -> Vec<[Complex; 2]> { +pub fn gamma_valence(c: &mut Cache, nf: u8) -> [[Complex; 2]; 2] { let cc = ChargeCombinations { nf }; - vec![ + [ [cc.e2avg() * gamma_nsm(c, nf), cc.vue2m() * gamma_nsm(c, nf)], [ cc.vde2m() * gamma_nsm(c, nf) * gamma_nsm(c, nf), From 81ece22721a2d051646706da31b055e0fddd906b Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 20 Nov 2024 17:36:28 +0100 Subject: [PATCH 19/32] fix notation row/columns --- .../anomalous_dimensions/unpolarized/spacelike.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs index 810e004a9..38479b89f 100644 --- a/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs +++ b/crates/ekore/src/anomalous_dimensions/unpolarized/spacelike.rs @@ -68,8 +68,8 @@ pub fn gamma_ns_qed( c: &mut Cache, nf: u8, ) -> Vec>> { - let row = vec![Complex::::zero(); order_qcd + 1]; - let mut gamma_ns = vec![row; order_qed + 1]; + let col = vec![Complex::::zero(); order_qcd + 1]; + let mut gamma_ns = vec![col; order_qed + 1]; gamma_ns[1][0] = as1::gamma_ns(c, nf); gamma_ns[0][1] = choose_ns_as_aem1(mode, c, nf); gamma_ns[1][1] = choose_ns_as_as1aem1(mode, c, nf); @@ -100,7 +100,7 @@ pub fn gamma_singlet_qed( c: &mut Cache, nf: u8, ) -> Vec; 4]; 4]>> { - let row = vec![ + let col = vec![ [[ Complex::::zero(), Complex::::zero(), @@ -110,7 +110,7 @@ pub fn gamma_singlet_qed( order_qcd + 1 ]; - let mut gamma_s = vec![row; order_qed + 1]; + let mut gamma_s = vec![col; order_qed + 1]; gamma_s[1][0] = as1::gamma_singlet_qed(c, nf); gamma_s[0][1] = aem1::gamma_singlet(c, nf); @@ -125,9 +125,9 @@ pub fn gamma_valence_qed( c: &mut Cache, nf: u8, ) -> Vec; 2]; 2]>> { - let row = vec![[[Complex::::zero(), Complex::::zero(),]; 2]; order_qcd + 1]; + let col = vec![[[Complex::::zero(), Complex::::zero(),]; 2]; order_qcd + 1]; - let mut gamma_v = vec![row; order_qed + 1]; + let mut gamma_v = vec![col; order_qed + 1]; gamma_v[1][0] = as1::gamma_valence_qed(c, nf); gamma_v[0][1] = aem1::gamma_valence(c, nf); gamma_v[1][1] = as1aem1::gamma_valence(c, nf); From 0def93893a5c8631b287ddbf50e4a7f8ae3a5dd8 Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 20 Nov 2024 17:43:55 +0100 Subject: [PATCH 20/32] add unravel functions for qed case. To be checked --- crates/eko/src/lib.rs | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index a6c5fa9ae..f8c7cb1d8 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -14,6 +14,7 @@ struct RawCmplx { } /// Map tensors to c-ordered list +/// (res is a vector with dim order_qcd filled with DIMxDIM matrices) fn unravel(res: Vec<[[Complex; DIM]; DIM]>, order_qcd: usize) -> RawCmplx { let mut target = RawCmplx { re: Vec::::new(), @@ -30,6 +31,50 @@ fn unravel(res: Vec<[[Complex; DIM]; DIM]>, order_qcd: us target } +/// Map tensors to c-ordered list in the QED singlet and valence case +/// (res is a matrix with dim order_qcd x order_qed filled with DIMxDIM matrices) +fn unravel_qed_singlet( + res: Vec; DIM]; DIM]>>, + order_qcd: usize, + order_qed: usize, +) -> RawCmplx { + let mut target = RawCmplx { + re: Vec::::new(), + im: Vec::::new(), + }; + for obj_ in res.iter().take(order_qcd) { + for obj in obj_.iter().take(order_qed) { + for col in obj.iter().take(DIM) { + for el in col.iter().take(DIM) { + target.re.push(el.re); + target.im.push(el.im); + } + } + } + } + target +} + +/// Map tensors to c-ordered list in the QED singlet and valence case +/// (res is a matrix with dim order_qcd x order_qed filled with complex numbers) +fn unravel_qed_ns( + res: Vec>>, + order_qcd: usize, + order_qed: usize, +) -> RawCmplx { + let mut target = RawCmplx { + re: Vec::::new(), + im: Vec::::new(), + }; + for col in res.iter().take(order_qcd) { + for el in col.iter().take(order_qed) { + target.re.push(el.re); + target.im.push(el.im); + } + } + target +} + /// QCD intergration kernel inside quad. /// /// # Safety From 9b58455df37c253ad15c8928a02cb5bc4d2d7d3e Mon Sep 17 00:00:00 2001 From: tgiani Date: Thu, 21 Nov 2024 11:33:44 +0100 Subject: [PATCH 21/32] modifying rust_quad_ker_qcd, PyQuadKerQCDT and QuadQCDargs to include qed case --- crates/eko/src/lib.rs | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index f8c7cb1d8..3e383ce92 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -57,11 +57,7 @@ fn unravel_qed_singlet( /// Map tensors to c-ordered list in the QED singlet and valence case /// (res is a matrix with dim order_qcd x order_qed filled with complex numbers) -fn unravel_qed_ns( - res: Vec>>, - order_qcd: usize, - order_qed: usize, -) -> RawCmplx { +fn unravel_qed_ns(res: Vec>>, order_qcd: usize, order_qed: usize) -> RawCmplx { let mut target = RawCmplx { re: Vec::::new(), im: Vec::::new(), @@ -115,13 +111,30 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { ); } } else if is_singlet { - let gamma_singlet_qcd = match args.is_polarized { - true => ekore::anomalous_dimensions::polarized::spacelike::gamma_singlet_qcd, - false => ekore::anomalous_dimensions::unpolarized::spacelike::gamma_singlet_qcd, - }; - raw = unravel( - gamma_singlet_qcd(args.order_qcd, &mut c, args.nf), + if args.is_qed { + let gamma_singlet_qed = + ekore::anomalous_dimensions::unpolarized::spacelike::gamma_singlet_qed; + raw = unravel_qed_singlet( + gamma_singlet_qed(args.order_qcd, args.order_qed, &mut c, args.nf), + args.order_qcd, + args.order_qed, + ); + } else { + let gamma_singlet_qcd = match args.is_polarized { + true => ekore::anomalous_dimensions::polarized::spacelike::gamma_singlet_qcd, + false => ekore::anomalous_dimensions::unpolarized::spacelike::gamma_singlet_qcd, + }; + raw = unravel( + gamma_singlet_qcd(args.order_qcd, &mut c, args.nf), + args.order_qcd, + ); + } + } else if args.is_qed { + let gamma_ns_qed = ekore::anomalous_dimensions::unpolarized::spacelike::gamma_ns_qed; + raw = unravel_qed_ns( + gamma_ns_qed(args.order_qcd, args.order_qed, args.mode0, &mut c, args.nf), args.order_qcd, + args.order_qed, ); } else { // we can not do 1D @@ -145,6 +158,7 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { jac.re, jac.im, args.order_qcd, + args.order_qed, is_singlet, args.mode0, args.mode1, @@ -175,6 +189,7 @@ type PyQuadKerQCDT = unsafe extern "C" fn( f64, f64, usize, + usize, bool, u16, u16, @@ -201,6 +216,7 @@ type PyQuadKerQCDT = unsafe extern "C" fn( #[derive(Clone, Copy)] pub struct QuadQCDargs { pub order_qcd: usize, + pub order_qed: usize, pub mode0: u16, pub mode1: u16, pub is_polarized: bool, @@ -221,6 +237,7 @@ pub struct QuadQCDargs { pub sv_mode_num: u8, pub is_threshold: bool, pub is_ome: bool, + pub is_qed: bool, pub Lsv: f64, } @@ -236,6 +253,7 @@ pub unsafe extern "C" fn my_py( _re_jac: f64, _im_jac: f64, _order_qcd: usize, + _order_qed: usize, _is_singlet: bool, _mode0: u16, _mode1: u16, @@ -269,6 +287,7 @@ pub unsafe extern "C" fn my_py( pub unsafe extern "C" fn empty_qcd_args() -> QuadQCDargs { QuadQCDargs { order_qcd: 0, + order_qed: 0, mode0: 0, mode1: 0, is_polarized: false, @@ -289,6 +308,7 @@ pub unsafe extern "C" fn empty_qcd_args() -> QuadQCDargs { sv_mode_num: 0, is_threshold: false, is_ome: false, + is_qed: false, Lsv: 0., } } From 588496ada1b781f6a7c5a2e29ee7b7c68c64053d Mon Sep 17 00:00:00 2001 From: tgiani Date: Thu, 21 Nov 2024 12:11:03 +0100 Subject: [PATCH 22/32] add qed valence option in rust_quad_ker_qcd --- crates/eko/src/lib.rs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index 3e383ce92..c241fb759 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -33,7 +33,7 @@ fn unravel(res: Vec<[[Complex; DIM]; DIM]>, order_qcd: us /// Map tensors to c-ordered list in the QED singlet and valence case /// (res is a matrix with dim order_qcd x order_qed filled with DIMxDIM matrices) -fn unravel_qed_singlet( +fn unravel_qed( res: Vec; DIM]; DIM]>>, order_qcd: usize, order_qed: usize, @@ -55,7 +55,7 @@ fn unravel_qed_singlet( target } -/// Map tensors to c-ordered list in the QED singlet and valence case +/// Map tensors to c-ordered list in the QED non-singlet case /// (res is a matrix with dim order_qcd x order_qed filled with complex numbers) fn unravel_qed_ns(res: Vec>>, order_qcd: usize, order_qed: usize) -> RawCmplx { let mut target = RawCmplx { @@ -79,6 +79,7 @@ fn unravel_qed_ns(res: Vec>>, order_qcd: usize, order_qed: usiz pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { let args = *(rargs as *mut QuadQCDargs); let is_singlet = (100 == args.mode0) || (21 == args.mode0) || (90 == args.mode0); + let is_qed_valence = (10200 == args.mode0) || (10204 == args.mode0); // prepare Mellin stuff let path = mellin::TalbotPath::new(u, args.logx, is_singlet); let jac = path.jac() * path.prefactor(); @@ -114,7 +115,7 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { if args.is_qed { let gamma_singlet_qed = ekore::anomalous_dimensions::unpolarized::spacelike::gamma_singlet_qed; - raw = unravel_qed_singlet( + raw = unravel_qed( gamma_singlet_qed(args.order_qcd, args.order_qed, &mut c, args.nf), args.order_qcd, args.order_qed, @@ -130,12 +131,22 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { ); } } else if args.is_qed { - let gamma_ns_qed = ekore::anomalous_dimensions::unpolarized::spacelike::gamma_ns_qed; - raw = unravel_qed_ns( - gamma_ns_qed(args.order_qcd, args.order_qed, args.mode0, &mut c, args.nf), - args.order_qcd, - args.order_qed, - ); + if is_qed_valence { + let gamma_valence_qed = + ekore::anomalous_dimensions::unpolarized::spacelike::gamma_valence_qed; + raw = unravel_qed( + gamma_valence_qed(args.order_qcd, args.order_qed, &mut c, args.nf), + args.order_qcd, + args.order_qed, + ); + } else { + let gamma_ns_qed = ekore::anomalous_dimensions::unpolarized::spacelike::gamma_ns_qed; + raw = unravel_qed_ns( + gamma_ns_qed(args.order_qcd, args.order_qed, args.mode0, &mut c, args.nf), + args.order_qcd, + args.order_qed, + ); + } } else { // we can not do 1D let gamma_ns_qcd = match args.is_polarized { From 3452243a1d05acdc1307f35dc84446256da40f82 Mon Sep 17 00:00:00 2001 From: tgiani Date: Thu, 21 Nov 2024 14:29:44 +0100 Subject: [PATCH 23/32] remove useless flag is_qed --- crates/eko/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index c241fb759..040a12c69 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -112,7 +112,7 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { ); } } else if is_singlet { - if args.is_qed { + if args.order_qed > 0 { let gamma_singlet_qed = ekore::anomalous_dimensions::unpolarized::spacelike::gamma_singlet_qed; raw = unravel_qed( @@ -130,7 +130,7 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { args.order_qcd, ); } - } else if args.is_qed { + } else if args.order_qed > 0 { if is_qed_valence { let gamma_valence_qed = ekore::anomalous_dimensions::unpolarized::spacelike::gamma_valence_qed; @@ -248,7 +248,6 @@ pub struct QuadQCDargs { pub sv_mode_num: u8, pub is_threshold: bool, pub is_ome: bool, - pub is_qed: bool, pub Lsv: f64, } @@ -319,7 +318,6 @@ pub unsafe extern "C" fn empty_qcd_args() -> QuadQCDargs { sv_mode_num: 0, is_threshold: false, is_ome: false, - is_qed: false, Lsv: 0., } } From 9335b97ed0901020ddd7c409d3d618383888058f Mon Sep 17 00:00:00 2001 From: tgiani Date: Thu, 21 Nov 2024 15:42:56 +0100 Subject: [PATCH 24/32] extend QuadQCDargs to include arguments for c_quad_ker_qed --- crates/eko/src/lib.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index 040a12c69..d6f0153ec 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -188,6 +188,12 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { args.sv_mode_num, args.is_threshold, args.Lsv, + // additional QED params + args.as_list, + args.mu2_from, + args.mu2_to, + args.a_half, + args.alphaem_running, ) } @@ -219,6 +225,11 @@ type PyQuadKerQCDT = unsafe extern "C" fn( u8, bool, f64, + *const f64, + f64, + f64, + f64, + bool, ) -> f64; /// Additional integration parameters @@ -249,6 +260,12 @@ pub struct QuadQCDargs { pub is_threshold: bool, pub is_ome: bool, pub Lsv: f64, + // additional param required for QED + pub as_list: *const f64, + pub mu2_from: f64, + pub mu2_to: f64, + pub a_half: f64, + pub alphaem_running: bool, } /// Empty placeholder function for python callback. @@ -282,6 +299,11 @@ pub unsafe extern "C" fn my_py( _sv_mode_num: u8, _is_threshold: bool, _lsv: f64, + _as_list: *const f64, + _mu2_from: f64, + _mu2_to: f64, + _a_half: f64, + _alphaem_running: bool, ) -> f64 { 0. } @@ -319,5 +341,10 @@ pub unsafe extern "C" fn empty_qcd_args() -> QuadQCDargs { is_threshold: false, is_ome: false, Lsv: 0., + as_list: [].as_ptr(), + mu2_from: 0., + mu2_to: 0., + a_half: 0., + alphaem_running: false, } } From 3390acaa22e07db638c513e5159b3b8181fedfa0 Mon Sep 17 00:00:00 2001 From: tgiani Date: Thu, 28 Nov 2024 16:35:23 +0100 Subject: [PATCH 25/32] setting up input vectors for cb_quad_ker_qed --- .pre-commit-config.yaml | 2 +- crates/eko/src/lib.rs | 23 ++- src/eko/evolution_operator/quad_ker.py | 241 +++++++++++++++++++------ 3 files changed, 205 insertions(+), 61 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 11ee1e506..8b88dfbb8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,7 +30,7 @@ repos: # Run the formatter. - id: ruff-format - repo: https://github.com/PyCQA/docformatter - rev: v1.7.5 + rev: "master" hooks: - id: docformatter additional_dependencies: [tomli] diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index d6f0153ec..b25520fba 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -190,9 +190,12 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { args.Lsv, // additional QED params args.as_list, + args.as_list_len, args.mu2_from, args.mu2_to, args.a_half, + args.a_half_x, + args.a_half_y, args.alphaem_running, ) } @@ -226,9 +229,12 @@ type PyQuadKerQCDT = unsafe extern "C" fn( bool, f64, *const f64, + u8, f64, f64, - f64, + *const f64, + u8, + u8, bool, ) -> f64; @@ -262,9 +268,12 @@ pub struct QuadQCDargs { pub Lsv: f64, // additional param required for QED pub as_list: *const f64, + pub as_list_len: u8, pub mu2_from: f64, pub mu2_to: f64, - pub a_half: f64, + pub a_half: *const f64, + pub a_half_x: u8, + pub a_half_y: u8, pub alphaem_running: bool, } @@ -300,9 +309,12 @@ pub unsafe extern "C" fn my_py( _is_threshold: bool, _lsv: f64, _as_list: *const f64, + _as_list_len: u8, _mu2_from: f64, _mu2_to: f64, - _a_half: f64, + _a_half: *const f64, + _a_half_x: u8, + _a_half_y: u8, _alphaem_running: bool, ) -> f64 { 0. @@ -342,9 +354,12 @@ pub unsafe extern "C" fn empty_qcd_args() -> QuadQCDargs { is_ome: false, Lsv: 0., as_list: [].as_ptr(), + as_list_len: 0, mu2_from: 0., mu2_to: 0., - a_half: 0., + a_half: [].as_ptr(), + a_half_x: 0, + a_half_y: 0, alphaem_running: false, } } diff --git a/src/eko/evolution_operator/quad_ker.py b/src/eko/evolution_operator/quad_ker.py index 087f6bbb7..0ce15d587 100644 --- a/src/eko/evolution_operator/quad_ker.py +++ b/src/eko/evolution_operator/quad_ker.py @@ -47,6 +47,7 @@ def select_singlet_element(ker, mode0, mode1): nb.types.double, # re_jac nb.types.double, # im_jac nb.types.uintc, # order_qcd + nb.types.uintc, # order_qed nb.types.bool_, # is_singlet nb.types.uintc, # mode0 nb.types.uintc, # mode1 @@ -65,6 +66,14 @@ def select_singlet_element(ker, mode0, mode1): nb.types.uintc, # sv_mode_num nb.types.bool_, # is_threshold nb.types.double, # Lsv + nb.types.CPointer(nb.types.double), # as_list + nb.types.uintc, # as_list_len + nb.types.double, # mu2_from + nb.types.double, # mu2_to + nb.types.CPointer(nb.types.double), # a_half + nb.types.uintc, # a_half_x + nb.types.uintc, # a_half_y + nb.types.bool_, # alphaem_running ) @@ -81,6 +90,7 @@ def cb_quad_ker_qcd( re_jac, im_jac, order_qcd, + _order_qed, is_singlet, mode0, mode1, @@ -99,6 +109,14 @@ def cb_quad_ker_qcd( sv_mode, is_threshold, Lsv, + _as_list, + _as_list_len, + _mu2_from, + _mu2_to, + _a_half, + _a_half_x, + _a_half_y, + _alphaem_running, ): """C Callback inside integration kernel.""" # recover complex variables @@ -225,6 +243,7 @@ def cb_quad_ker_ome( re_jac, im_jac, order_qcd, + _order_qed, is_singlet, mode0, mode1, @@ -243,6 +262,14 @@ def cb_quad_ker_ome( sv_mode, _is_threshold, Lsv, + _as_list, + _as_list_len, + _mu2_from, + _mu2_to, + _a_half, + _a_half_x, + _a_half_y, + _alphaem_running, ): """C Callback inside integration kernel.""" # recover complex variables @@ -280,68 +307,170 @@ def cb_quad_ker_ome( return np.real(res) -# from ..kernels import singlet_qed as qed_s -# from ..kernels import non_singlet_qed as qed_ns -# from ..kernels import valence_qed as qed_v +@nb.njit(cache=True) +def select_QEDsinglet_element(ker, mode0, mode1): + """Select element of the QEDsinglet matrix. -# @nb.njit(cache=True) -# def select_QEDsinglet_element(ker, mode0, mode1): -# """Select element of the QEDsinglet matrix. + Parameters + ---------- + ker : numpy.ndarray + QEDsinglet integration kernel + mode0 : int + id for first sector element + mode1 : int + id for second sector element + Returns + ------- + ker : complex + QEDsinglet integration kernel element + """ + if mode0 == 21: + index1 = 0 + elif mode0 == 22: + index1 = 1 + elif mode0 == 100: + index1 = 2 + else: + index1 = 3 + if mode1 == 21: + index2 = 0 + elif mode1 == 22: + index2 = 1 + elif mode1 == 100: + index2 = 2 + else: + index2 = 3 + return ker[index1, index2] -# Parameters -# ---------- -# ker : numpy.ndarray -# QEDsinglet integration kernel -# mode0 : int -# id for first sector element -# mode1 : int -# id for second sector element -# Returns -# ------- -# ker : complex -# QEDsinglet integration kernel element -# """ -# if mode0 == 21: -# index1 = 0 -# elif mode0 == 22: -# index1 = 1 -# elif mode0 == 100: -# index1 = 2 -# else: -# index1 = 3 -# if mode1 == 21: -# index2 = 0 -# elif mode1 == 22: -# index2 = 1 -# elif mode1 == 100: -# index2 = 2 -# else: -# index2 = 3 -# return ker[index1, index2] +@nb.njit(cache=True) +def select_QEDvalence_element(ker, mode0, mode1): + """Select element of the QEDvalence matrix. -# @nb.njit(cache=True) -# def select_QEDvalence_element(ker, mode0, mode1): -# """ -# Select element of the QEDvalence matrix. + Parameters + ---------- + ker : numpy.ndarray + QEDvalence integration kernel + mode0 : int + id for first sector element + mode1 : int + id for second sector element + Returns + ------- + ker : complex + QEDvalence integration kernel element + """ + index1 = 0 if mode0 == 10200 else 1 + index2 = 0 if mode1 == 10200 else 1 + return ker[index1, index2] + + +# @nb.cfunc( +# CB_SIGNATURE, +# cache=True, +# nopython=True, +# ) +# def cb_quad_ker_qed( +# re_gamma_raw, +# im_gamma_raw, +# re_n, +# im_n, +# re_jac, +# im_jac, +# order_qcd, +# order_qed, +# is_singlet, +# mode0, +# mode1, +# nf, +# is_log, +# logx, +# areas_raw, +# areas_x, +# areas_y, +# _L, +# ev_method, +# as1, +# as0, +# ev_op_iterations, +# ev_op_max_order_qcd, +# sv_mode, +# is_threshold, +# Lsv, +# as_list, +# as_list_len, +# mu2_from, +# mu2_to, +# a_half, +# a_half_x, +# a_half_y, +# alphaem_running, +# ): +# """C Callback inside integration kernel.""" +# recover complex variables +# n = re_n + im_n * 1j +# jac = re_jac + im_jac * 1j +# compute basis functions +# areas = nb.carray(areas_raw, (areas_x, areas_y)) +# pj = interpolation.evaluate_grid(n, is_log, logx, areas) +# order = (order_qcd, order_qed) +# ev_op_max_order = (ev_op_max_order_qcd, order_qed) +# is_valence = (mode0 == 10200) or (mode0 == 10204) + +# if is_singlet: +# reconstruct singlet matrices +# re_gamma_singlet = nb.carray(re_gamma_raw, (order_qcd, order_qed, 4, 4)) +# im_gamma_singlet = nb.carray(im_gamma_raw, (order_qcd, order_qed, 4, 4)) +# gamma_singlet = re_gamma_singlet + im_gamma_singlet * 1j + +# scale var exponentiated is directly applied on gamma +# if sv_mode == sv.Modes.exponentiated: +# gamma_singlet = sv.exponentiated.gamma_variation_qed( +# gamma_singlet, order, nf, L, alphaem_running +# ) -# Parameters -# ---------- -# ker : numpy.ndarray -# QEDvalence integration kernel -# mode0 : int -# id for first sector element -# mode1 : int -# id for second sector element -# Returns -# ------- -# ker : complex -# QEDvalence integration kernel element -# """ -# index1 = 0 if mode0 == 10200 else 1 -# index2 = 0 if mode1 == 10200 else 1 -# return ker[index1, index2] +# ker = qed_s.dispatcher( +# order, +# method, +# gamma_s, +# as_list, ### +# a_half, ### +# nf, +# ev_op_iterations, +# ev_op_max_order, +# ) +# if sv_mode == sv.Modes.expanded and not is_threshold: +# ker = np.ascontiguousarray( +# sv.expanded.singlet_variation_qed( +# gamma_s, as_list[-1], a_half[-1][1], alphaem_running, order, nf, L +# ) +# ) @ np.ascontiguousarray(ker) +# ker = select_QEDsinglet_element(ker, mode0, mode1) +# elif is_valence: + +# else: +# construct non-singlet matrices +# re_gamma_ns = nb.carray(re_gamma_raw, order_qcd) +# im_gamma_ns = nb.carray(im_gamma_raw, order_qcd) +# gamma_ns = re_gamma_ns + im_gamma_ns * 1j +# if sv_mode == sv.Modes.exponentiated: +# gamma_ns = sv_exponentiated.gamma_variation(gamma_ns, order, nf, Lsv) +# construct eko +# ker = ns.dispatcher( +# order, +# ev_method, +# gamma_ns, +# as1, +# as0, +# nf, +# ev_op_iterations, +# ) +# if sv_mode == sv.Modes.expanded and not is_threshold: +# ker = sv_expanded.non_singlet_variation(gamma_ns, as1, order, nf, Lsv) * ker +# recombine everything +# res = ker * pj * jac +# return np.real(res) # @nb.njit(cache=True) # def quad_ker_qed( From 6a3af197636f2cfebeb2ddbe3374da848d2b4b44 Mon Sep 17 00:00:00 2001 From: tgiani Date: Tue, 3 Dec 2024 17:16:22 +0100 Subject: [PATCH 26/32] cb_quad_ker_qed --- src/eko/evolution_operator/quad_ker.py | 413 ++++++++++--------------- 1 file changed, 162 insertions(+), 251 deletions(-) diff --git a/src/eko/evolution_operator/quad_ker.py b/src/eko/evolution_operator/quad_ker.py index 0ce15d587..aaedb7374 100644 --- a/src/eko/evolution_operator/quad_ker.py +++ b/src/eko/evolution_operator/quad_ker.py @@ -9,7 +9,11 @@ from .. import scale_variations as sv from ..io.types import InversionMethod from ..kernels import non_singlet as ns +from ..kernels import non_singlet_qed as qed_ns from ..kernels import singlet as s +from ..kernels import singlet_qed as qed_s +from ..kernels import valence_qed as qed_v +from ..matchings import lepton_number from ..scale_variations import expanded as sv_expanded from ..scale_variations import exponentiated as sv_exponentiated @@ -365,254 +369,161 @@ def select_QEDvalence_element(ker, mode0, mode1): return ker[index1, index2] -# @nb.cfunc( -# CB_SIGNATURE, -# cache=True, -# nopython=True, -# ) -# def cb_quad_ker_qed( -# re_gamma_raw, -# im_gamma_raw, -# re_n, -# im_n, -# re_jac, -# im_jac, -# order_qcd, -# order_qed, -# is_singlet, -# mode0, -# mode1, -# nf, -# is_log, -# logx, -# areas_raw, -# areas_x, -# areas_y, -# _L, -# ev_method, -# as1, -# as0, -# ev_op_iterations, -# ev_op_max_order_qcd, -# sv_mode, -# is_threshold, -# Lsv, -# as_list, -# as_list_len, -# mu2_from, -# mu2_to, -# a_half, -# a_half_x, -# a_half_y, -# alphaem_running, -# ): -# """C Callback inside integration kernel.""" -# recover complex variables -# n = re_n + im_n * 1j -# jac = re_jac + im_jac * 1j -# compute basis functions -# areas = nb.carray(areas_raw, (areas_x, areas_y)) -# pj = interpolation.evaluate_grid(n, is_log, logx, areas) -# order = (order_qcd, order_qed) -# ev_op_max_order = (ev_op_max_order_qcd, order_qed) -# is_valence = (mode0 == 10200) or (mode0 == 10204) - -# if is_singlet: -# reconstruct singlet matrices -# re_gamma_singlet = nb.carray(re_gamma_raw, (order_qcd, order_qed, 4, 4)) -# im_gamma_singlet = nb.carray(im_gamma_raw, (order_qcd, order_qed, 4, 4)) -# gamma_singlet = re_gamma_singlet + im_gamma_singlet * 1j - -# scale var exponentiated is directly applied on gamma -# if sv_mode == sv.Modes.exponentiated: -# gamma_singlet = sv.exponentiated.gamma_variation_qed( -# gamma_singlet, order, nf, L, alphaem_running -# ) - -# ker = qed_s.dispatcher( -# order, -# method, -# gamma_s, -# as_list, ### -# a_half, ### -# nf, -# ev_op_iterations, -# ev_op_max_order, -# ) -# if sv_mode == sv.Modes.expanded and not is_threshold: -# ker = np.ascontiguousarray( -# sv.expanded.singlet_variation_qed( -# gamma_s, as_list[-1], a_half[-1][1], alphaem_running, order, nf, L -# ) -# ) @ np.ascontiguousarray(ker) -# ker = select_QEDsinglet_element(ker, mode0, mode1) - -# elif is_valence: - -# else: -# construct non-singlet matrices -# re_gamma_ns = nb.carray(re_gamma_raw, order_qcd) -# im_gamma_ns = nb.carray(im_gamma_raw, order_qcd) -# gamma_ns = re_gamma_ns + im_gamma_ns * 1j -# if sv_mode == sv.Modes.exponentiated: -# gamma_ns = sv_exponentiated.gamma_variation(gamma_ns, order, nf, Lsv) -# construct eko -# ker = ns.dispatcher( -# order, -# ev_method, -# gamma_ns, -# as1, -# as0, -# nf, -# ev_op_iterations, -# ) -# if sv_mode == sv.Modes.expanded and not is_threshold: -# ker = sv_expanded.non_singlet_variation(gamma_ns, as1, order, nf, Lsv) * ker -# recombine everything -# res = ker * pj * jac -# return np.real(res) - -# @nb.njit(cache=True) -# def quad_ker_qed( -# ker_base, -# order, -# mode0, -# mode1, -# method, -# as_list, -# mu2_from, -# mu2_to, -# a_half, -# alphaem_running, -# nf, -# L, -# ev_op_iterations, -# ev_op_max_order, -# sv_mode, -# is_threshold, -# ): -# """Raw evolution kernel inside quad. - -# Parameters -# ---------- -# ker_base : QuadKerBase -# quad argument -# order : int -# perturbation order -# mode0: int -# pid for first sector element -# mode1 : int -# pid for second sector element -# method : str -# method -# as1 : float -# target coupling value -# as0 : float -# initial coupling value -# mu2_from : float -# initial value of mu2 -# mu2_from : float -# final value of mu2 -# aem_list : list -# list of electromagnetic coupling values -# alphaem_running : bool -# whether alphaem is running or not -# nf : int -# number of active flavors -# L : float -# logarithm of the squared ratio of factorization and renormalization scale -# ev_op_iterations : int -# number of evolution steps -# ev_op_max_order : int -# perturbative expansion order of U -# sv_mode: int, `enum.IntEnum` -# scale variation mode, see `eko.scale_variations.Modes` -# is_threshold : boolean -# is this an itermediate threshold operator? - -# Returns -# ------- -# float -# evaluated integration kernel -# """ -# # compute the actual evolution kernel for QEDxQCD -# if ker_base.is_QEDsinglet: -# gamma_s = ad_us.gamma_singlet_qed(order, ker_base.n, nf) -# # scale var exponentiated is directly applied on gamma -# if sv_mode == sv.Modes.exponentiated: -# gamma_s = sv.exponentiated.gamma_variation_qed( -# gamma_s, order, nf, L, alphaem_running -# ) -# ker = qed_s.dispatcher( -# order, -# method, -# gamma_s, -# as_list, -# a_half, -# nf, -# ev_op_iterations, -# ev_op_max_order, -# ) -# # scale var expanded is applied on the kernel -# # TODO : in this way a_half[-1][1] is the aem value computed in -# # the middle point of the last step. Instead we want aem computed in mu2_final. -# # However the distance between the two is very small and affects only the running aem -# if sv_mode == sv.Modes.expanded and not is_threshold: -# ker = np.ascontiguousarray( -# sv.expanded.singlet_variation_qed( -# gamma_s, as_list[-1], a_half[-1][1], alphaem_running, order, nf, L -# ) -# ) @ np.ascontiguousarray(ker) -# ker = select_QEDsinglet_element(ker, mode0, mode1) -# elif ker_base.is_QEDvalence: -# gamma_v = ad_us.gamma_valence_qed(order, ker_base.n, nf) -# # scale var exponentiated is directly applied on gamma -# if sv_mode == sv.Modes.exponentiated: -# gamma_v = sv.exponentiated.gamma_variation_qed( -# gamma_v, order, nf, L, alphaem_running -# ) -# ker = qed_v.dispatcher( -# order, -# method, -# gamma_v, -# as_list, -# a_half, -# nf, -# ev_op_iterations, -# ev_op_max_order, -# ) -# # scale var expanded is applied on the kernel -# if sv_mode == sv.Modes.expanded and not is_threshold: -# ker = np.ascontiguousarray( -# sv.expanded.valence_variation_qed( -# gamma_v, as_list[-1], a_half[-1][1], alphaem_running, order, nf, L -# ) -# ) @ np.ascontiguousarray(ker) -# ker = select_QEDvalence_element(ker, mode0, mode1) -# else: -# gamma_ns = ad_us.gamma_ns_qed(order, mode0, ker_base.n, nf) -# # scale var exponentiated is directly applied on gamma -# if sv_mode == sv.Modes.exponentiated: -# gamma_ns = sv.exponentiated.gamma_variation_qed( -# gamma_ns, order, nf, L, alphaem_running -# ) -# ker = qed_ns.dispatcher( -# order, -# method, -# gamma_ns, -# as_list, -# a_half[:, 1], -# alphaem_running, -# nf, -# ev_op_iterations, -# mu2_from, -# mu2_to, -# ) -# if sv_mode == sv.Modes.expanded and not is_threshold: -# ker = ( -# sv.expanded.non_singlet_variation_qed( -# gamma_ns, as_list[-1], a_half[-1][1], alphaem_running, order, nf, L -# ) -# * ker -# ) -# return ker +@nb.cfunc( + CB_SIGNATURE, + cache=True, + nopython=True, +) +def cb_quad_ker_qed( + re_gamma_raw, + im_gamma_raw, + re_n, + im_n, + re_jac, + im_jac, + order_qcd, + order_qed, + is_singlet, + mode0, + mode1, + nf, + is_log, + logx, + areas_raw, + areas_x, + areas_y, + L, + ev_method, + as1, + as0, + ev_op_iterations, + ev_op_max_order_qcd, + sv_mode, + is_threshold, + Lsv, + as_list_raw, + as_list_len, + mu2_from, + mu2_to, + a_half_raw, + a_half_x, + a_half_y, + alphaem_running, +): + """C Callback inside integration kernel.""" + # recover complex variables + n = re_n + im_n * 1j + jac = re_jac + im_jac * 1j + # compute basis functions + areas = nb.carray(areas_raw, (areas_x, areas_y)) + pj = interpolation.evaluate_grid(n, is_log, logx, areas) + order = (order_qcd, order_qed) + ev_op_max_order = (ev_op_max_order_qcd, order_qed) + is_valence = (mode0 == 10200) or (mode0 == 10204) + + as_list = nb.carray(as_list_raw, as_list_len) + a_half = nb.carray(a_half_raw, (a_half_x, a_half_y)) + + if is_singlet: + # reconstruct singlet matrices + re_gamma_singlet = nb.carray(re_gamma_raw, (order_qcd, order_qed, 4, 4)) + im_gamma_singlet = nb.carray(im_gamma_raw, (order_qcd, order_qed, 4, 4)) + gamma_singlet = re_gamma_singlet + im_gamma_singlet * 1j + + # scale var exponentiated is directly applied on gamma + if sv_mode == sv.Modes.exponentiated: + gamma_singlet = sv.exponentiated.gamma_variation_qed( + gamma_singlet, order, nf, lepton_number(mu2_to), L, alphaem_running + ) + + ker = qed_s.dispatcher( + order, + ev_method, + gamma_singlet, + as_list, + a_half, + nf, + ev_op_iterations, + ev_op_max_order, + ) + if sv_mode == sv.Modes.expanded and not is_threshold: + ker = np.ascontiguousarray( + sv.expanded.singlet_variation_qed( + gamma_singlet, + as_list[-1], + a_half[-1][1], + alphaem_running, + order, + nf, + L, + ) + ) @ np.ascontiguousarray(ker) + ker = select_QEDsinglet_element(ker, mode0, mode1) + + elif is_valence: + # reconstruct valence matrices + re_gamma_valence = nb.carray(re_gamma_raw, (order_qcd, order_qed, 2, 2)) + im_gamma_valence = nb.carray(im_gamma_raw, (order_qcd, order_qed, 2, 2)) + gamma_valence = re_gamma_valence + im_gamma_valence * 1j + + if sv_mode == sv.Modes.exponentiated: + gamma_valence = sv.exponentiated.gamma_variation_qed( + gamma_valence, order, nf, lepton_number(mu2_to), L, alphaem_running + ) + ker = qed_v.dispatcher( + order, + ev_method, + gamma_valence, + as_list, + a_half, + nf, + ev_op_iterations, + ev_op_max_order, + ) + # scale var expanded is applied on the kernel + if sv_mode == sv.Modes.expanded and not is_threshold: + ker = np.ascontiguousarray( + sv.expanded.valence_variation_qed( + gamma_valence, + as_list[-1], + a_half[-1][1], + alphaem_running, + order, + nf, + L, + ) + ) @ np.ascontiguousarray(ker) + ker = select_QEDvalence_element(ker, mode0, mode1) + + else: + # construct non-singlet matrices + re_gamma_ns = nb.carray(re_gamma_raw, (order_qcd, order_qed)) + im_gamma_ns = nb.carray(im_gamma_raw, (order_qcd, order_qed)) + gamma_ns = re_gamma_ns + im_gamma_ns * 1j + if sv_mode == sv.Modes.exponentiated: + gamma_ns = sv_exponentiated.gamma_variation_qed( + gamma_ns, order, nf, lepton_number(mu2_to), L, alphaem_running + ) + # construct eko + ker = qed_ns.dispatcher( + order, + ev_method, + gamma_ns, + as_list, + a_half[:, 1], + alphaem_running, + nf, + ev_op_iterations, + mu2_from, + mu2_to, + ) + if sv_mode == sv.Modes.expanded and not is_threshold: + ker = ( + sv_expanded.non_singlet_variation_qed( + gamma_ns, as_list[-1], a_half[-1][1], alphaem_running, order, nf, L + ) + * ker + ) + # recombine everything + res = ker * pj * jac + return np.real(res) From f0a727dd55c645cfad176ab5f63c0f92414e32b8 Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 9 Dec 2024 13:52:07 +0100 Subject: [PATCH 27/32] fix modes for singlet QED and use == in if statements --- crates/eko/src/lib.rs | 2 +- src/eko/kernels/non_singlet.py | 2 +- src/eko/kernels/singlet.py | 8 ++++---- src/eko/kernels/singlet_qed.py | 2 +- src/eko/kernels/valence_qed.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index b25520fba..f8aac3047 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -78,7 +78,7 @@ fn unravel_qed_ns(res: Vec>>, order_qcd: usize, order_qed: usiz #[no_mangle] pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { let args = *(rargs as *mut QuadQCDargs); - let is_singlet = (100 == args.mode0) || (21 == args.mode0) || (90 == args.mode0); + let is_singlet = (100 == args.mode0) || (21 == args.mode0) || (90 == args.mode0)|| (22 == args.mode0) || (101 == args.mode0); let is_qed_valence = (10200 == args.mode0) || (10204 == args.mode0); // prepare Mellin stuff let path = mellin::TalbotPath::new(u, args.logx, is_singlet); diff --git a/src/eko/kernels/non_singlet.py b/src/eko/kernels/non_singlet.py index 1d25d5845..0e8352dda 100644 --- a/src/eko/kernels/non_singlet.py +++ b/src/eko/kernels/non_singlet.py @@ -375,7 +375,7 @@ def dispatcher(order, method, gamma_ns, a1, a0, nf, ev_op_iterations): # pylint return eko_ordered_truncated( gamma_ns, a1, a0, betalist, order, ev_op_iterations ) - if method is EvoMethods.TRUNCATED: + if method == EvoMethods.TRUNCATED: return eko_truncated(gamma_ns, a1, a0, betalist, order, ev_op_iterations) # NLO diff --git a/src/eko/kernels/singlet.py b/src/eko/kernels/singlet.py index 96f02a972..2ce7bce21 100644 --- a/src/eko/kernels/singlet.py +++ b/src/eko/kernels/singlet.py @@ -613,7 +613,7 @@ def dispatcher( # pylint: disable=too-many-return-statements # Common method for NLO and NNLO if method in [EvoMethods.ITERATE_EXACT, EvoMethods.ITERATE_EXPANDED]: return eko_iterate(gamma_singlet, a1, a0, betalist, order, ev_op_iterations) - if method is EvoMethods.PERTURBATIVE_EXACT: + if method == EvoMethods.PERTURBATIVE_EXACT: return eko_perturbative( gamma_singlet, a1, @@ -624,7 +624,7 @@ def dispatcher( # pylint: disable=too-many-return-statements ev_op_max_order, True, ) - if method is EvoMethods.PERTURBATIVE_EXPANDED: + if method == EvoMethods.PERTURBATIVE_EXPANDED: return eko_perturbative( gamma_singlet, a1, @@ -638,13 +638,13 @@ def dispatcher( # pylint: disable=too-many-return-statements if method in [EvoMethods.TRUNCATED, EvoMethods.ORDERED_TRUNCATED]: return eko_truncated(gamma_singlet, a1, a0, betalist, order, ev_op_iterations) # These methods are scattered for nlo and nnlo - if method is EvoMethods.DECOMPOSE_EXACT: + if method == EvoMethods.DECOMPOSE_EXACT: if order[0] == 2: return nlo_decompose_exact(gamma_singlet, a1, a0, betalist) if order[0] == 3: return nnlo_decompose_exact(gamma_singlet, a1, a0, betalist) return n3lo_decompose_exact(gamma_singlet, a1, a0, nf) - if method is EvoMethods.DECOMPOSE_EXPANDED: + if method == EvoMethods.DECOMPOSE_EXPANDED: if order[0] == 2: return nlo_decompose_expanded(gamma_singlet, a1, a0, betalist) if order[0] == 3: diff --git a/src/eko/kernels/singlet_qed.py b/src/eko/kernels/singlet_qed.py index d63a2f1ac..0a5716df8 100644 --- a/src/eko/kernels/singlet_qed.py +++ b/src/eko/kernels/singlet_qed.py @@ -97,7 +97,7 @@ def dispatcher( e_s : numpy.ndarray singlet EKO """ - if method is EvoMethods.ITERATE_EXACT: + if method == EvoMethods.ITERATE_EXACT: return eko_iterate( gamma_singlet, as_list, a_half, nf, order, ev_op_iterations, 4 ) diff --git a/src/eko/kernels/valence_qed.py b/src/eko/kernels/valence_qed.py index 8b83e1917..b5da158b4 100644 --- a/src/eko/kernels/valence_qed.py +++ b/src/eko/kernels/valence_qed.py @@ -45,7 +45,7 @@ def dispatcher( e_v : numpy.ndarray singlet EKO """ - if method is EvoMethods.ITERATE_EXACT: + if method == EvoMethods.ITERATE_EXACT: return eko_iterate( gamma_valence, as_list, a_half, nf, order, ev_op_iterations, 2 ) From 398c89aa9db530d35bcccbf9b01a60fb3b9662e0 Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 9 Dec 2024 14:21:09 +0100 Subject: [PATCH 28/32] small fix --- crates/eko/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index f8aac3047..44fbc14fb 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -78,6 +78,7 @@ fn unravel_qed_ns(res: Vec>>, order_qcd: usize, order_qed: usiz #[no_mangle] pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { let args = *(rargs as *mut QuadQCDargs); + let is_singlet = (100 == args.mode0) || (21 == args.mode0) || (90 == args.mode0)|| (22 == args.mode0) || (101 == args.mode0); let is_qed_valence = (10200 == args.mode0) || (10204 == args.mode0); // prepare Mellin stuff From ea44cee7a0b962e492161b44d8f62ff3a43e0e75 Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 9 Dec 2024 14:22:43 +0100 Subject: [PATCH 29/32] cargo fmt --- crates/eko/src/lib.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index 44fbc14fb..3aa6d1df8 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -78,8 +78,12 @@ fn unravel_qed_ns(res: Vec>>, order_qcd: usize, order_qed: usiz #[no_mangle] pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { let args = *(rargs as *mut QuadQCDargs); - - let is_singlet = (100 == args.mode0) || (21 == args.mode0) || (90 == args.mode0)|| (22 == args.mode0) || (101 == args.mode0); + + let is_singlet = (100 == args.mode0) + || (21 == args.mode0) + || (90 == args.mode0) + || (22 == args.mode0) + || (101 == args.mode0); let is_qed_valence = (10200 == args.mode0) || (10204 == args.mode0); // prepare Mellin stuff let path = mellin::TalbotPath::new(u, args.logx, is_singlet); From 57213266a7e4fda5279454fce5d0476c7bccc9d5 Mon Sep 17 00:00:00 2001 From: tgiani Date: Mon, 9 Dec 2024 14:30:51 +0100 Subject: [PATCH 30/32] forgot pre-commit --- crates/eko/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/eko/src/lib.rs b/crates/eko/src/lib.rs index 3aa6d1df8..ea42fb1e9 100644 --- a/crates/eko/src/lib.rs +++ b/crates/eko/src/lib.rs @@ -84,6 +84,7 @@ pub unsafe extern "C" fn rust_quad_ker_qcd(u: f64, rargs: *mut c_void) -> f64 { || (90 == args.mode0) || (22 == args.mode0) || (101 == args.mode0); + let is_qed_valence = (10200 == args.mode0) || (10204 == args.mode0); // prepare Mellin stuff let path = mellin::TalbotPath::new(u, args.logx, is_singlet); From 83af8361d52bc37832c8078fba3d52af5859f13a Mon Sep 17 00:00:00 2001 From: tgiani Date: Wed, 11 Dec 2024 11:52:26 +0100 Subject: [PATCH 31/32] updating patch file --- src/eko/evolution_operator/__init__.py.patch | 41 ++++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py.patch b/src/eko/evolution_operator/__init__.py.patch index a4951e687..41ddb9f9d 100644 --- a/src/eko/evolution_operator/__init__.py.patch +++ b/src/eko/evolution_operator/__init__.py.patch @@ -1,5 +1,5 @@ diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py -index bd1b19d6..f543f7bc 100644 +index bd1b19d6..de87651c 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -3,16 +3,16 @@ r"""Contains the central operator classes. @@ -21,11 +21,12 @@ index bd1b19d6..f543f7bc 100644 import ekore.anomalous_dimensions.polarized.space_like as ad_ps import ekore.anomalous_dimensions.unpolarized.space_like as ad_us -@@ -32,91 +32,10 @@ from ..matchings import Segment, lepton_number +@@ -32,91 +32,11 @@ from ..matchings import Segment, lepton_number from ..member import OpMember from ..scale_variations import expanded as sv_expanded from ..scale_variations import exponentiated as sv_exponentiated +from .quad_ker import cb_quad_ker_qcd ++from .quad_ker import cb_quad_ker_qed logger = logging.getLogger(__name__) @@ -114,7 +115,7 @@ index bd1b19d6..f543f7bc 100644 spec = [ ("is_singlet", nb.boolean), ("is_QEDsinglet", nb.boolean), -@@ -188,421 +107,6 @@ class QuadKerBase: +@@ -188,422 +108,6 @@ class QuadKerBase: return self.path.prefactor * pj * self.path.jac @@ -533,9 +534,10 @@ index bd1b19d6..f543f7bc 100644 - ) - return ker - - +- OpMembers = Dict[OperatorLabel, OpMember] """Map of all operators.""" + @@ -792,49 +296,6 @@ class Operator(sv.ScaleVariationModeMixin): """Return the evolution method.""" return ev_method(EvolutionMethod(self.config["method"])) @@ -586,7 +588,7 @@ index bd1b19d6..f543f7bc 100644 def initialize_op_members(self): """Init all operators with the identity or zeros.""" eye = OpMember( -@@ -857,10 +318,14 @@ class Operator(sv.ScaleVariationModeMixin): +@@ -857,10 +318,17 @@ class Operator(sv.ScaleVariationModeMixin): else: self.op_members[n] = zero.copy() @@ -598,14 +600,17 @@ index bd1b19d6..f543f7bc 100644 + """Adjust integration config.""" + cfg.as1 = self.as_list[1] + cfg.as0 = self.as_list[0] -+ cfg.py = ekors.ffi.cast("void *", cb_quad_ker_qcd.address) ++ if self.order[1] == 0: ++ cfg.py = ekors.ffi.cast("void *", cb_quad_ker_qcd.address) ++ else: ++ cfg.py = ekors.ffi.cast("void *", cb_quad_ker_qed.address) + cfg.method_num = self.ev_method + + def run_op_integration(self, log_grid): """Run the integration for each grid point. Parameters -@@ -875,18 +339,53 @@ class Operator(sv.ScaleVariationModeMixin): +@@ -875,18 +343,75 @@ class Operator(sv.ScaleVariationModeMixin): """ column = [] k, logx = log_grid @@ -615,6 +620,7 @@ index bd1b19d6..f543f7bc 100644 + # start preparing C arguments + cfg = ekors.lib.empty_qcd_args() + cfg.order_qcd = self.order[0] ++ cfg.order_qed = self.order[1] + cfg.is_polarized = self.config["polarized"] + cfg.is_time_like = self.config["time_like"] + cfg.nf = self.nf @@ -625,6 +631,27 @@ index bd1b19d6..f543f7bc 100644 + cfg.ev_op_max_order_qcd = self.config["ev_op_max_order"][0] + cfg.sv_mode_num = self.sv_mode + cfg.is_threshold = self.is_threshold ++ cfg.mu2_from = self.q2_from ++ cfg.mu2_to = self.q2_to ++ cfg.alphaem_running=self.alphaem_running ++ ++ # prepare as_list for c ++ as_list_len = self.as_list.shape[0] ++ as_list_ffi = ekors.ffi.new(f"double[{as_list_len}]", self.as_list.tolist()) ++ cfg.as_list = as_list_ffi ++ cfg.as_list_len = as_list_len ++ ++ # prepare a_half for c ++ a_half_x = self.a_half_list.shape[0] ++ a_half_y = self.a_half_list.shape[1] ++ a_half_len = a_half_x * a_half_y ++ a_half_ffi = ekors.ffi.new( ++ f"double[{a_half_len}]", self.a_half_list.flatten().tolist() ++ ) ++ cfg.a_half = a_half_ffi ++ cfg.a_half_x = a_half_x ++ cfg.a_half_y = a_half_y ++ + self.update_cfg(cfg) + # iterate basis functions From 1af5cbf4739f3de81785a44e47fec322c3aa92d5 Mon Sep 17 00:00:00 2001 From: tgiani <33056186+tgiani@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:55:01 +0100 Subject: [PATCH 32/32] Update crates/ekore/src/constants.rs Co-authored-by: Felix Hekhorn --- crates/ekore/src/constants.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ekore/src/constants.rs b/crates/ekore/src/constants.rs index 80c3bc807..61cc0d9e0 100644 --- a/crates/ekore/src/constants.rs +++ b/crates/ekore/src/constants.rs @@ -76,7 +76,7 @@ pub struct ChargeCombinations { impl ChargeCombinations { pub fn nu(&self) -> u8 { - uplike_flavors(self.nf) + self.nf / 2 } pub fn nd(&self) -> u8 {