From 6eb55c7b8b02c7d710853546f051346b8e927538 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Tue, 29 Mar 2022 17:16:33 +0200 Subject: [PATCH 01/47] move harmonics to a proper subpackage --- src/eko/anomalous_dimensions/__init__.py | 17 +- src/eko/anomalous_dimensions/as2.py | 67 +- src/eko/anomalous_dimensions/as3.py | 6 +- src/eko/anomalous_dimensions/harmonics.py | 305 ------- src/eko/beta.py | 2 +- src/eko/gamma.py | 2 +- src/eko/harmonics/__init__.py | 11 + src/eko/harmonics/constants.py | 25 + .../as3 => harmonics}/f_functions/__init__.py | 0 .../as3 => harmonics}/f_functions/f11.py | 0 .../as3 => harmonics}/f_functions/f13.py | 0 .../as3 => harmonics}/f_functions/f14_f12.py | 0 .../as3 => harmonics}/f_functions/f16.py | 0 .../as3 => harmonics}/f_functions/f17.py | 0 .../as3 => harmonics}/f_functions/f18.py | 0 .../as3 => harmonics}/f_functions/f19.py | 0 .../as3 => harmonics}/f_functions/f20.py | 0 .../as3 => harmonics}/f_functions/f21.py | 0 .../as3 => harmonics}/f_functions/f9.py | 0 .../as3 => harmonics}/g_functions.py | 114 ++- src/eko/harmonics/polygamma.py | 126 +++ src/eko/harmonics/w1.py | 62 ++ src/eko/harmonics/w2.py | 61 ++ src/eko/harmonics/w3.py | 181 ++++ src/eko/harmonics/w4.py | 221 +++++ src/eko/harmonics/w5.py | 426 ++++++++++ src/eko/matching_conditions/as1.py | 4 +- src/eko/matching_conditions/as2.py | 23 +- src/eko/matching_conditions/as3/aqqNS.py | 22 +- .../matching_conditions/as3/s_functions.py | 801 ------------------ .../operator_matrix_element.py | 42 +- 31 files changed, 1267 insertions(+), 1251 deletions(-) delete mode 100644 src/eko/anomalous_dimensions/harmonics.py create mode 100644 src/eko/harmonics/__init__.py create mode 100644 src/eko/harmonics/constants.py rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/__init__.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f11.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f13.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f14_f12.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f16.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f17.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f18.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f19.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f20.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f21.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/f_functions/f9.py (100%) rename src/eko/{matching_conditions/as3 => harmonics}/g_functions.py (70%) create mode 100644 src/eko/harmonics/polygamma.py create mode 100644 src/eko/harmonics/w1.py create mode 100644 src/eko/harmonics/w2.py create mode 100644 src/eko/harmonics/w3.py create mode 100644 src/eko/harmonics/w4.py create mode 100644 src/eko/harmonics/w5.py delete mode 100644 src/eko/matching_conditions/as3/s_functions.py diff --git a/src/eko/anomalous_dimensions/__init__.py b/src/eko/anomalous_dimensions/__init__.py index a02322360..6200c2018 100644 --- a/src/eko/anomalous_dimensions/__init__.py +++ b/src/eko/anomalous_dimensions/__init__.py @@ -20,7 +20,8 @@ import numba as nb import numpy as np -from . import as1, as2, as3, harmonics +from .. import harmonics +from . import as1, as2, as3 @nb.njit(cache=True) @@ -102,7 +103,7 @@ def gamma_ns(order, mode, n, nf): eko.anomalous_dimensions.as3.gamma_nsv : :math:`\gamma_{ns,v}^{(2)}(N)` """ # cache the s-es - sx = np.full(1, harmonics.harmonic_S1(n)) + sx = np.full(1, harmonics.S1(n)) # now combine gamma_ns = np.zeros(order + 1, np.complex_) gamma_ns[0] = as1.gamma_ns(n, sx[0]) @@ -119,8 +120,8 @@ def gamma_ns(order, mode, n, nf): gamma_ns[1] = gamma_ns_1 # NNLO and beyond if order >= 2: - sx = np.append(sx, harmonics.harmonic_S2(n)) - sx = np.append(sx, harmonics.harmonic_S3(n)) + sx = np.append(sx, harmonics.S2(n)) + sx = np.append(sx, harmonics.S3(n)) if mode == 10101: gamma_ns_2 = -as3.gamma_nsp(n, nf, sx) elif mode == 10201: @@ -157,16 +158,16 @@ def gamma_singlet(order, n, nf): eko.anomalous_dimensions.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` """ # cache the s-es - sx = np.full(1, harmonics.harmonic_S1(n)) + sx = np.full(1, harmonics.S1(n)) if order >= 1: - sx = np.append(sx, harmonics.harmonic_S2(n)) - sx = np.append(sx, harmonics.harmonic_S3(n)) + sx = np.append(sx, harmonics.S2(n)) + sx = np.append(sx, harmonics.S3(n)) gamma_s = np.zeros((order + 1, 2, 2), np.complex_) gamma_s[0] = as1.gamma_singlet(n, sx[0], nf) if order >= 1: gamma_s[1] = as2.gamma_singlet(n, nf) if order == 2: - sx = np.append(sx, harmonics.harmonic_S4(n)) + sx = np.append(sx, harmonics.S4(n)) gamma_s[2] = -as3.gamma_singlet(n, nf, sx) return gamma_s diff --git a/src/eko/anomalous_dimensions/as2.py b/src/eko/anomalous_dimensions/as2.py index 07249ef31..6832cb8c8 100644 --- a/src/eko/anomalous_dimensions/as2.py +++ b/src/eko/anomalous_dimensions/as2.py @@ -10,8 +10,8 @@ import numba as nb import numpy as np -from .. import constants -from . import harmonics +from .. import constants, harmonics +from ..harmonics.constants import log2, zeta2, zeta3 @nb.njit(cache=True) @@ -34,19 +34,18 @@ def gamma_nsm(n, nf): |NLO| valence-like non-singlet anomalous dimension :math:`\\gamma_{ns,-}^{(1)}(N)` """ - S1 = harmonics.harmonic_S1(n) - S2 = harmonics.harmonic_S2(n) + # TODO: use harmonics from cache + S1 = harmonics.S1(n) + S2 = harmonics.S2(n) # Here, Sp refers to S' ("s-prime") (german: "s-strich" or in Pegasus language: SSTR) # of :cite:`Gluck:1989ze` and NOT to the Spence function a.k.a. dilogarithm - Sp1m = harmonics.harmonic_S1((n - 1) / 2) - Sp2m = harmonics.harmonic_S2((n - 1) / 2) - Sp3m = harmonics.harmonic_S3((n - 1) / 2) - g3n = harmonics.mellin_g3(n) - zeta2 = harmonics.zeta2 - zeta3 = harmonics.zeta3 + Sp1m = harmonics.S1((n - 1) / 2) + Sp2m = harmonics.S2((n - 1) / 2) + Sp3m = harmonics.S3((n - 1) / 2) + g3n = harmonics.g_functions.mellin_g3(n) # fmt: off - gqq1m_cfca = 16*g3n - (144 + n*(1 + n)*(156 + n*(340 + n*(655 + 51*n*(2 + n)))))/(18.*np.power(n,3)*np.power(1 + n,3)) + (-14.666666666666666 + 8/n - 8/(1 + n))*S2 - (4*Sp2m)/(n + np.power(n,2)) + S1*(29.77777777777778 + 16/np.power(n,2) - 16*S2 + 8*Sp2m) + 2*Sp3m + 10*zeta3 + zeta2*(16*S1 - 16*Sp1m - (16*(1 + n*np.log(2)))/n) # pylint: disable=line-too-long - gqq1m_cfcf = -32*g3n + (24 - n*(-32 + 3*n*(-8 + n*(3 + n)*(3 + np.power(n,2)))))/(2.*np.power(n,3)*np.power(1 + n,3)) + (12 - 8/n + 8/(1 + n))*S2 + S1*(-24/np.power(n,2) - 8/np.power(1 + n,2) + 16*S2 - 16*Sp2m) + (8*Sp2m)/(n + np.power(n,2)) - 4*Sp3m - 20*zeta3 + zeta2*(-32*S1 + 32*Sp1m + 32*(1/n + np.log(2))) # pylint: disable=line-too-long + gqq1m_cfca = 16*g3n - (144 + n*(1 + n)*(156 + n*(340 + n*(655 + 51*n*(2 + n)))))/(18.*np.power(n,3)*np.power(1 + n,3)) + (-14.666666666666666 + 8/n - 8/(1 + n))*S2 - (4*Sp2m)/(n + np.power(n,2)) + S1*(29.77777777777778 + 16/np.power(n,2) - 16*S2 + 8*Sp2m) + 2*Sp3m + 10*zeta3 + zeta2*(16*S1 - 16*Sp1m - (16*(1 + n*log2))/n) # pylint: disable=line-too-long + gqq1m_cfcf = -32*g3n + (24 - n*(-32 + 3*n*(-8 + n*(3 + n)*(3 + np.power(n,2)))))/(2.*np.power(n,3)*np.power(1 + n,3)) + (12 - 8/n + 8/(1 + n))*S2 + S1*(-24/np.power(n,2) - 8/np.power(1 + n,2) + 16*S2 - 16*Sp2m) + (8*Sp2m)/(n + np.power(n,2)) - 4*Sp3m - 20*zeta3 + zeta2*(-32*S1 + 32*Sp1m + 32*(1/n + log2)) # pylint: disable=line-too-long gqq1m_cfnf = (-12 + n*(20 + n*(47 + 3*n*(2 + n))))/(9.*np.power(n,2)*np.power(1 + n,2)) - (40*S1)/9. + (8*S2)/3. # pylint: disable=line-too-long # fmt: on result = constants.CF * ( @@ -77,17 +76,15 @@ def gamma_nsp(n, nf): |NLO| singlet-like non-singlet anomalous dimension :math:`\\gamma_{ns,+}^{(1)}(N)` """ - S1 = harmonics.harmonic_S1(n) - S2 = harmonics.harmonic_S2(n) - Sp1p = harmonics.harmonic_S1(n / 2) - Sp2p = harmonics.harmonic_S2(n / 2) - Sp3p = harmonics.harmonic_S3(n / 2) - g3n = harmonics.mellin_g3(n) - zeta2 = harmonics.zeta2 - zeta3 = harmonics.zeta3 + S1 = harmonics.S1(n) + S2 = harmonics.S2(n) + Sp1p = harmonics.S1(n / 2) + Sp2p = harmonics.S2(n / 2) + Sp3p = harmonics.S3(n / 2) + g3n = harmonics.g_functions.mellin_g3(n) # fmt: off - gqq1p_cfca = -16*g3n + (132 - n*(340 + n*(655 + 51*n*(2 + n))))/(18.*np.power(n,2)*np.power(1 + n,2)) + (-14.666666666666666 + 8/n - 8/(1 + n))*S2 - (4*Sp2p)/(n + np.power(n,2)) + S1*(29.77777777777778 - 16/np.power(n,2) - 16*S2 + 8*Sp2p) + 2*Sp3p + 10*zeta3 + zeta2*(16*S1 - 16*Sp1p + 16*(1/n - np.log(2))) # pylint: disable=line-too-long - gqq1p_cfcf = 32*g3n - (8 + n*(32 + n*(40 + 3*n*(3 + n)*(3 + np.power(n,2)))))/(2.*np.power(n,3)*np.power(1 + n,3)) + (12 - 8/n + 8/(1 + n))*S2 + S1*(40/np.power(n,2) - 8/np.power(1 + n,2) + 16*S2 - 16*Sp2p) + (8*Sp2p)/(n + np.power(n,2)) - 4*Sp3p - 20*zeta3 + zeta2*(-32*S1 + 32*Sp1p + 32*(-(1/n) + np.log(2))) # pylint: disable=line-too-long + gqq1p_cfca = -16*g3n + (132 - n*(340 + n*(655 + 51*n*(2 + n))))/(18.*np.power(n,2)*np.power(1 + n,2)) + (-14.666666666666666 + 8/n - 8/(1 + n))*S2 - (4*Sp2p)/(n + np.power(n,2)) + S1*(29.77777777777778 - 16/np.power(n,2) - 16*S2 + 8*Sp2p) + 2*Sp3p + 10*zeta3 + zeta2*(16*S1 - 16*Sp1p + 16*(1/n - log2)) # pylint: disable=line-too-long + gqq1p_cfcf = 32*g3n - (8 + n*(32 + n*(40 + 3*n*(3 + n)*(3 + np.power(n,2)))))/(2.*np.power(n,3)*np.power(1 + n,3)) + (12 - 8/n + 8/(1 + n))*S2 + S1*(40/np.power(n,2) - 8/np.power(1 + n,2) + 16*S2 - 16*Sp2p) + (8*Sp2p)/(n + np.power(n,2)) - 4*Sp3p - 20*zeta3 + zeta2*(-32*S1 + 32*Sp1p + 32*(-(1/n) + log2)) # pylint: disable=line-too-long gqq1p_cfnf = (-12 + n*(20 + n*(47 + 3*n*(2 + n))))/(9.*np.power(n,2)*np.power(1 + n,2)) - (40*S1)/9. + (8*S2)/3. # pylint: disable=line-too-long # fmt: on result = constants.CF * ( @@ -145,9 +142,9 @@ def gamma_qg(n, nf): |NLO| quark-gluon singlet anomalous dimension :math:`\\gamma_{qg}^{(1)}(N)` """ - S1 = harmonics.harmonic_S1(n) - S2 = harmonics.harmonic_S2(n) - Sp2p = harmonics.harmonic_S2(n / 2) + S1 = harmonics.S1(n) + S2 = harmonics.S2(n) + Sp2p = harmonics.S2(n / 2) # fmt: off gqg1_nfca = (-4*(16 + n*(64 + n*(104 + n*(128 + n*(85 + n*(36 + n*(25 + n*(15 + n*(6 + n))))))))))/((-1 + n)*np.power(n,3)*np.power(1 + n,3)*np.power(2 + n,3)) - (16*(3 + 2*n)*S1)/np.power(2 + 3*n + np.power(n,2),2) + (4*(2 + n + np.power(n,2))*np.power(S1,2))/(n*(2 + 3*n + np.power(n,2))) - (4*(2 + n + np.power(n,2))*S2)/(n*(2 + 3*n + np.power(n,2))) + (4*(2 + n + np.power(n,2))*Sp2p)/(n*(2 + 3*n + np.power(n,2))) # pylint: disable=line-too-long gqg1_nfcf = (-2*(4 + n*(8 + n*(1 + n)*(25 + n*(26 + 5*n*(2 + n))))))/(np.power(n,3)*np.power(1 + n,3)*(2 + n)) + (8*S1)/np.power(n,2) - (4*(2 + n + np.power(n,2))*np.power(S1,2))/(n*(2 + 3*n + np.power(n,2))) + (4*(2 + n + np.power(n,2))*S2)/(n*(2 + 3*n + np.power(n,2))) # pylint: disable=line-too-long @@ -178,9 +175,9 @@ def gamma_gq(n, nf): |NLO| gluon-quark singlet anomalous dimension :math:`\\gamma_{gq}^{(1)}(N)` """ - S1 = harmonics.harmonic_S1(n) - S2 = harmonics.harmonic_S2(n) - Sp2p = harmonics.harmonic_S2(n / 2) + S1 = harmonics.S1(n) + S2 = harmonics.S2(n) + Sp2p = harmonics.S2(n / 2) # fmt: off ggq1_cfcf = (-8 + 2*n*(-12 + n*(-1 + n*(28 + n*(43 + 6*n*(5 + 2*n))))))/((-1 + n)*np.power(n,3)*np.power(1 + n,3)) - (4*(10 + n*(17 + n*(8 + 5*n)))*S1)/((-1 + n)*n*np.power(1 + n,2)) + (4*(2 + n + np.power(n,2))*np.power(S1,2))/(n*(-1 + np.power(n,2))) + (4*(2 + n + np.power(n,2))*S2)/(n*(-1 + np.power(n,2))) # pylint: disable=line-too-long ggq1_cfca = (-4*(144 + n*(432 + n*(-152 + n*(-1304 + n*(-1031 + n*(695 + n*(1678 + n*(1400 + n*(621 + 109*n))))))))))/(9.*np.power(n,3)*np.power(1 + n,3)*np.power(-2 + n + np.power(n,2),2)) + (4*(-12 + n*(-22 + 41*n + 17*np.power(n,3)))*S1)/(3.*np.power(-1 + n,2)*np.power(n,2)*(1 + n)) + ((8 + 4*n + 4*np.power(n,2))*np.power(S1,2))/(n - np.power(n,3)) + ((8 + 4*n + 4*np.power(n,2))*S2)/(n - np.power(n,3)) + (4*(2 + n + np.power(n,2))*Sp2p)/(n*(-1 + np.power(n,2))) # pylint: disable=line-too-long @@ -214,15 +211,13 @@ def gamma_gg(n, nf): |NLO| gluon-gluon singlet anomalous dimension :math:`\\gamma_{gg}^{(1)}(N)` """ - S1 = harmonics.harmonic_S1(n) - Sp1p = harmonics.harmonic_S1(n / 2) - Sp2p = harmonics.harmonic_S2(n / 2) - Sp3p = harmonics.harmonic_S3(n / 2) - g3n = harmonics.mellin_g3(n) - zeta2 = harmonics.zeta2 - zeta3 = harmonics.zeta3 + S1 = harmonics.S1(n) + Sp1p = harmonics.S1(n / 2) + Sp2p = harmonics.S2(n / 2) + Sp3p = harmonics.S3(n / 2) + g3n = harmonics.g_functions.mellin_g3(n) # fmt: off - ggg1_caca = 16*g3n - (2*(576 + n*(1488 + n*(560 + n*(-1248 + n*(-1384 + n*(1663 + n*(4514 + n*(4744 + n*(3030 + n*(1225 + 48*n*(7 + n))))))))))))/(9.*np.power(-1 + n,2)*np.power(n,3)*np.power(1 + n,3)*np.power(2 + n,3)) + S1*(29.77777777777778 + 16/np.power(-1 + n,2) + 16/np.power(1 + n,2) - 16/np.power(2 + n,2) - 8*Sp2p) + (16*(1 + n + np.power(n,2))*Sp2p)/(n*(1 + n)*(-2 + n + np.power(n,2))) - 2*Sp3p - 10*zeta3 + zeta2*(-16*S1 + 16*Sp1p + 16*(-(1/n) + np.log(2))) # pylint: disable=line-too-long + ggg1_caca = 16*g3n - (2*(576 + n*(1488 + n*(560 + n*(-1248 + n*(-1384 + n*(1663 + n*(4514 + n*(4744 + n*(3030 + n*(1225 + 48*n*(7 + n))))))))))))/(9.*np.power(-1 + n,2)*np.power(n,3)*np.power(1 + n,3)*np.power(2 + n,3)) + S1*(29.77777777777778 + 16/np.power(-1 + n,2) + 16/np.power(1 + n,2) - 16/np.power(2 + n,2) - 8*Sp2p) + (16*(1 + n + np.power(n,2))*Sp2p)/(n*(1 + n)*(-2 + n + np.power(n,2))) - 2*Sp3p - 10*zeta3 + zeta2*(-16*S1 + 16*Sp1p + 16*(-(1/n) + log2)) # pylint: disable=line-too-long ggg1_canf = (8*(6 + n*(1 + n)*(28 + n*(1 + n)*(13 + 3*n*(1 + n)))))/(9.*np.power(n,2)*np.power(1 + n,2)*(-2 + n + np.power(n,2))) - (40*S1)/9. # pylint: disable=line-too-long ggg1_cfnf = (2*(-8 + n*(-8 + n*(-10 + n*(-22 + n*(-3 + n*(6 + n*(8 + n*(4 + n)))))))))/(np.power(n,3)*np.power(1 + n,3)*(-2 + n + np.power(n,2))) # pylint: disable=line-too-long # fmt: on diff --git a/src/eko/anomalous_dimensions/as3.py b/src/eko/anomalous_dimensions/as3.py index 1868a7604..4e5f17090 100644 --- a/src/eko/anomalous_dimensions/as3.py +++ b/src/eko/anomalous_dimensions/as3.py @@ -9,11 +9,7 @@ import numba as nb import numpy as np -from . import harmonics - -# Global variables -zeta2 = harmonics.zeta2 -zeta3 = harmonics.zeta3 +from ..harmonics.constants import zeta2, zeta3 @nb.njit(cache=True) diff --git a/src/eko/anomalous_dimensions/harmonics.py b/src/eko/anomalous_dimensions/harmonics.py deleted file mode 100644 index ac50d4e9a..000000000 --- a/src/eko/anomalous_dimensions/harmonics.py +++ /dev/null @@ -1,305 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Implements higher mathematical functions. - -The functions are described in :doc:`Mellin space `. -""" - -import numba as nb -import numpy as np -import scipy.special - -# compute constants only once -zeta2 = scipy.special.zeta(2) -zeta3 = scipy.special.zeta(3) -zeta4 = scipy.special.zeta(4) -zeta5 = scipy.special.zeta(5) - - -@nb.njit(cache=True) -def cern_polygamma(Z, K): # pylint: disable=all - """ - Computes the polygamma functions :math:`\\psi_k(z)`. - - Reimplementation of ``WPSIPG`` (C317) in `CERNlib `_ - :cite:`KOLBIG1972221`. - - Note that the SciPy implementation :data:`scipy.special.digamma` - does not allow for complex inputs. - - Parameters - ---------- - Z : complex - argument of polygamma function - K : int - order of polygamma function - - Returns - ------- - H : complex - k-th polygamma function :math:`\\psi_k(z)` - """ - # fmt: off - DELTA = 5e-13 - R1 = 1 - HF = R1/2 - C1 = np.pi**2 - C2 = 2*np.pi**3 - C3 = 2*np.pi**4 - C4 = 8*np.pi**5 - - # SGN is originally indexed 0:4 -> no shift - SGN = [-1,+1,-1,+1,-1] - # FCT is originally indexed -1:4 -> shift +1 - FCT = [0,1,1,2,6,24] - - # C is originally indexed 1:6 x 0:4 -> swap indices and shift new last -1 - C = nb.typed.List() - C.append([ - 8.33333333333333333e-2, - -8.33333333333333333e-3, - 3.96825396825396825e-3, - -4.16666666666666667e-3, - 7.57575757575757576e-3, - -2.10927960927960928e-2]) - C.append([ - 1.66666666666666667e-1, - -3.33333333333333333e-2, - 2.38095238095238095e-2, - -3.33333333333333333e-2, - 7.57575757575757576e-2, - -2.53113553113553114e-1]) - C.append([ - 5.00000000000000000e-1, - -1.66666666666666667e-1, - 1.66666666666666667e-1, - -3.00000000000000000e-1, - 8.33333333333333333e-1, - -3.29047619047619048e+0]) - C.append([ - 2.00000000000000000e+0, - -1.00000000000000000e+0, - 1.33333333333333333e+0, - -3.00000000000000000e+0, - 1.00000000000000000e+1, - -4.60666666666666667e+1]) - C.append([10., -7., 12., -33., 130., -691.]) - U=Z - X=np.real(U) - A=np.abs(X) - if K < 0 or K > 4: - raise NotImplementedError("Order K has to be in [0:4]") - if np.abs(np.imag(U)) < DELTA and np.abs(X+int(A)) < DELTA: - raise ValueError("Argument Z equals non-positive integer") - K1=K+1 - if X < 0: - U=-U - V=U - H=0 - if A < 15: - H=1/V**K1 - for I in range(1,14-int(A)+1): - V=V+1 - H=H+1/V**K1 - V=V+1 - R=1/V**2 - P=R*C[K][6-1] - for I in range(5,1-1,-1): - P=R*(C[K][I-1]+P) - H=SGN[K]*(FCT[K+1]*H+(V*(FCT[K-1+1]+P)+HF*FCT[K+1])/V**K1) - if K == 0: - H=H+np.log(V) - if X < 0: - V=np.pi*U - X=np.real(V) - Y=np.imag(V) - A=np.sin(X) - B=np.cos(X) - T=np.tanh(Y) - P=complex(B,-A*T)/complex(A,B*T) - if K == 0: - H=H+1/U+np.pi*P - elif K == 1: - H=-H+1/U**2+C1*(P**2+1) - elif K == 2: - H=H+2/U**3+C2*P*(P**2+1) - elif K == 3: - R=P**2 - H=-H+6/U**4+C3*((3*R+4)*R+1) - elif K == 4: - R=P**2 - H=H+24/U**5+C4*P*((3*R+5)*R+2) - return H - # fmt: on - - -@nb.njit(cache=True) -def harmonic_S1(N): - r""" - Computes the harmonic sum :math:`S_1(N)`. - - .. math:: - S_1(N) = \sum\limits_{j=1}^N \frac 1 j = \psi_0(N+1)+\gamma_E - - with :math:`\psi_0(N)` the digamma function and :math:`\gamma_E` the - Euler-Mascheroni constant. - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - S_1 : complex - (simple) Harmonic sum :math:`S_1(N)` - - See Also - -------- - cern_polygamma : :math:`\psi_k(N)` - """ - return cern_polygamma(N + 1.0, 0) + np.euler_gamma - - -@nb.njit(cache=True) -def harmonic_S2(N): - r""" - Computes the harmonic sum :math:`S_2(N)`. - - .. math:: - S_2(N) = \sum\limits_{j=1}^N \frac 1 {j^2} = -\psi_1(N+1)+\zeta(2) - - with :math:`\psi_1(N)` the trigamma function and :math:`\zeta` the - Riemann zeta function. - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - S_2 : complex - Harmonic sum :math:`S_2(N)` - - See Also - -------- - cern_polygamma : :math:`\psi_k(N)` - """ - return -cern_polygamma(N + 1.0, 1) + zeta2 - - -@nb.njit(cache=True) -def harmonic_S3(N): - r""" - Computes the harmonic sum :math:`S_3(N)`. - - .. math:: - S_3(N) = \sum\limits_{j=1}^N \frac 1 {j^3} = \frac 1 2 \psi_2(N+1)+\zeta(3) - - with :math:`\psi_2(N)` the 2nd-polygamma function and :math:`\zeta` the - Riemann zeta function. - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - S_3 : complex - Harmonic sum :math:`S_3(N)` - - See Also - -------- - cern_polygamma : :math:`\psi_k(N)` - """ - return 0.5 * cern_polygamma(N + 1.0, 2) + zeta3 - - -@nb.njit(cache=True) -def harmonic_S4(N): - r""" - Computes the harmonic sum :math:`S_4(N)`. - - .. math:: - S_4(N) = \sum\limits_{j=1}^N \frac 1 {j^4} = - \frac 1 6 \psi_3(N+1)+\zeta(4) - - with :math:`\psi_3(N)` the 3rd-polygamma function and :math:`\zeta` the - Riemann zeta function. - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - S_4 : complex - Harmonic sum :math:`S_4(N)` - - See Also - -------- - cern_polygamma : :math:`\psi_k(N)` - """ - return zeta4 - 1.0 / 6.0 * cern_polygamma(N + 1.0, 3) - - -@nb.njit(cache=True) -def harmonic_S5(N): - r""" - Computes the harmonic sum :math:`S_5(N)`. - - .. math:: - S_5(N) = \sum\limits_{j=1}^N \frac 1 {j^5} = \frac 1 24 \psi_4(N+1)+\zeta(5) - - with :math:`\psi_4(N)` the 4th-polygamma function and :math:`\zeta` the - Riemann zeta function. - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - S_5 : complex - Harmonic sum :math:`S_5(N)` - - See Also - -------- - cern_polygamma : :math:`\psi_k(N)` - """ - return zeta5 + 1.0 / 24.0 * cern_polygamma(N + 1.0, 4) - - -@nb.njit(cache=True) -def mellin_g3(N): - r""" - Computes the Mellin transform of :math:`\text{Li}_2(x)/(1+x)`. - - This function appears in the analytic continuation of the harmonic sum - :math:`S_{-2,1}(N)` which in turn appears in the |NLO| anomalous dimension - (see :ref:`theory/mellin:harmonic sums`). - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - mellin_g3 : complex - approximate Mellin transform :math:`\mathcal{M}[\text{Li}_2(x)/(1+x)](N)` - - Note - ---- - We use the name from :cite:`MuselliPhD`, but not his implementation - rather we use the - Pegasus :cite:`Vogt:2004ns` implementation. - """ - cs = [1.0000e0, -0.9992e0, 0.9851e0, -0.9005e0, 0.6621e0, -0.3174e0, 0.0699e0] - g3 = 0 - for j, c in enumerate(cs): - Nj = N + j - g3 += c * (zeta2 - harmonic_S1(Nj) / Nj) / Nj - return g3 diff --git a/src/eko/beta.py b/src/eko/beta.py index 2254cad86..6a466727d 100644 --- a/src/eko/beta.py +++ b/src/eko/beta.py @@ -8,7 +8,7 @@ import numba as nb from . import constants -from .anomalous_dimensions.harmonics import zeta3 +from .harmonics.constants import zeta3 @nb.njit(cache=True) diff --git a/src/eko/gamma.py b/src/eko/gamma.py index a9379d83d..6e539562c 100644 --- a/src/eko/gamma.py +++ b/src/eko/gamma.py @@ -6,7 +6,7 @@ """ import numba as nb -from .anomalous_dimensions.harmonics import zeta3, zeta4, zeta5 +from .harmonics.constants import zeta3, zeta4, zeta5 @nb.njit(cache=True) diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py new file mode 100644 index 000000000..530aec2b3 --- /dev/null +++ b/src/eko/harmonics/__init__.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +This module contains some harmonics sum. +Defintion are coming from :cite:`MuselliPhD,Bl_mlein_2000,Blumlein:2009ta` +""" + +from .w1 import S1, Sm1 +from .w2 import S2, Sm2 +from .w3 import S3, S21, S2m1, Sm2m1, Sm3, Sm21 +from .w4 import S4, S31, S211, Sm4, Sm22, Sm31, Sm211 +from .w5 import S5, S23, S41, S221, S311, S2111, S2m3, S21m2, Sm5, Sm23, Sm221, Sm2111 diff --git a/src/eko/harmonics/constants.py b/src/eko/harmonics/constants.py new file mode 100644 index 000000000..e11e8b97a --- /dev/null +++ b/src/eko/harmonics/constants.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +""" +Zeta function and other constants. +""" +import numpy as np +from scipy.special import zeta + +zeta2 = zeta(2) +r""":math:`\zeta(2)`""" + +zeta3 = zeta(3) +r""":math:`\zeta(3)`""" + +zeta4 = zeta(4) +r""":math:`\zeta(4)`""" + +zeta5 = zeta(5) +r""":math:`\zeta(5)`""" + + +log2 = np.log(2) +r""":math:`\ln(2)`""" + +li4half = 0.517479 +""":math:`Li_{4}(1/2)`""" diff --git a/src/eko/matching_conditions/as3/f_functions/__init__.py b/src/eko/harmonics/f_functions/__init__.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/__init__.py rename to src/eko/harmonics/f_functions/__init__.py diff --git a/src/eko/matching_conditions/as3/f_functions/f11.py b/src/eko/harmonics/f_functions/f11.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f11.py rename to src/eko/harmonics/f_functions/f11.py diff --git a/src/eko/matching_conditions/as3/f_functions/f13.py b/src/eko/harmonics/f_functions/f13.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f13.py rename to src/eko/harmonics/f_functions/f13.py diff --git a/src/eko/matching_conditions/as3/f_functions/f14_f12.py b/src/eko/harmonics/f_functions/f14_f12.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f14_f12.py rename to src/eko/harmonics/f_functions/f14_f12.py diff --git a/src/eko/matching_conditions/as3/f_functions/f16.py b/src/eko/harmonics/f_functions/f16.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f16.py rename to src/eko/harmonics/f_functions/f16.py diff --git a/src/eko/matching_conditions/as3/f_functions/f17.py b/src/eko/harmonics/f_functions/f17.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f17.py rename to src/eko/harmonics/f_functions/f17.py diff --git a/src/eko/matching_conditions/as3/f_functions/f18.py b/src/eko/harmonics/f_functions/f18.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f18.py rename to src/eko/harmonics/f_functions/f18.py diff --git a/src/eko/matching_conditions/as3/f_functions/f19.py b/src/eko/harmonics/f_functions/f19.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f19.py rename to src/eko/harmonics/f_functions/f19.py diff --git a/src/eko/matching_conditions/as3/f_functions/f20.py b/src/eko/harmonics/f_functions/f20.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f20.py rename to src/eko/harmonics/f_functions/f20.py diff --git a/src/eko/matching_conditions/as3/f_functions/f21.py b/src/eko/harmonics/f_functions/f21.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f21.py rename to src/eko/harmonics/f_functions/f21.py diff --git a/src/eko/matching_conditions/as3/f_functions/f9.py b/src/eko/harmonics/f_functions/f9.py similarity index 100% rename from src/eko/matching_conditions/as3/f_functions/f9.py rename to src/eko/harmonics/f_functions/f9.py diff --git a/src/eko/matching_conditions/as3/g_functions.py b/src/eko/harmonics/g_functions.py similarity index 70% rename from src/eko/matching_conditions/as3/g_functions.py rename to src/eko/harmonics/g_functions.py index aff3b8a9f..c075303ba 100644 --- a/src/eko/matching_conditions/as3/g_functions.py +++ b/src/eko/harmonics/g_functions.py @@ -1,15 +1,14 @@ # -*- coding: utf-8 -*- +""" +Implemtations of some mellin transformations :cite:`MuselliPhD` +appearing in the analytic continuation of harmonics sums of weight = 3,4. +""" import numba as nb import numpy as np -from ...anomalous_dimensions.harmonics import ( - cern_polygamma, - harmonic_S1, - harmonic_S2, - harmonic_S3, - zeta2, - zeta3, -) +from . import w1, w2, w3 +from .constants import log2, zeta2, zeta3 +from .polygamma import cern_polygamma a1 = np.array( [ @@ -63,12 +62,44 @@ p31 = np.array([205.0 / 144.0, -25.0 / 12.0, 23.0 / 24.0, -13.0 / 36.0, 1.0 / 16]) +@nb.njit(cache=True) +def mellin_g3(N): + r""" + Computes the Mellin transform of :math:`\text{Li}_2(x)/(1+x)`. + + This function appears in the analytic continuation of the harmonic sum + :math:`S_{-2,1}(N)` which in turn appears in the |NLO| anomalous dimension + (see :ref:`theory/mellin:harmonic sums`). + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + mellin_g3 : complex + approximate Mellin transform :math:`\mathcal{M}[\text{Li}_2(x)/(1+x)](N)` + + Note + ---- + We use the name from :cite:`MuselliPhD`, but not his implementation - rather we use the + Pegasus :cite:`Vogt:2004ns` implementation. + """ + cs = [1.0000e0, -0.9992e0, 0.9851e0, -0.9005e0, 0.6621e0, -0.3174e0, 0.0699e0] + g3 = 0 + for j, c in enumerate(cs): + Nj = N + j + g3 += c * (zeta2 - w1.S1(Nj) / Nj) / Nj + return g3 + + @nb.njit(cache=True) def mellin_g4(N): r""" Computes the Mellin transform of :math:`\text{Li}_2(-x)/(1+x)`. - Implementation and defition in B.5.25 of :cite:`MuselliPhD` or + Implementation and definition in B.5.25 of :cite:`MuselliPhD` or in eq 61 of :cite:`Bl_mlein_2000`, but none of them is fully correct. @@ -82,11 +113,11 @@ def mellin_g4(N): mellin_g4 : complex Mellin transform :math:`\mathcal{M}[\text{Li}_2(-x)/(1+x)](N)` """ - g4 = -1 / 2 * zeta2 * np.log(2) + g4 = -1 / 2 * zeta2 * log2 for k, ak in enumerate(a1): Nk = N + k + 1 - beta = 1 / 2 * (harmonic_S1((Nk) / 2) - harmonic_S1((Nk - 1) / 2)) - g4 += ak * (N / Nk * zeta2 / 2 + (k + 1) / Nk**2 * (np.log(2) - beta)) + beta = 1 / 2 * (w1.S1((Nk) / 2) - w1.S1((Nk - 1) / 2)) + g4 += ak * (N / Nk * zeta2 / 2 + (k + 1) / Nk**2 * (log2 - beta)) return g4 @@ -95,7 +126,7 @@ def mellin_g5(N): r""" Computes the Mellin transform of :math:`(\text{Li}_2(x)ln(x))/(1+x)`. - Implementation and defition in B.5.26 of :cite:`MuselliPhD` or + Implementation and definition in B.5.26 of :cite:`MuselliPhD` or in eq 62 of :cite:`Bl_mlein_2000`, but none of them is fully correct. Parameters @@ -112,9 +143,7 @@ def mellin_g5(N): for k, ak in enumerate(a1): Nk = N + k + 1 g5 -= ak * ( - (k + 1) - / Nk**2 - * (zeta2 + cern_polygamma(Nk + 1, 1) - 2 * harmonic_S1(Nk) / Nk) + (k + 1) / Nk**2 * (zeta2 + cern_polygamma(Nk + 1, 1) - 2 * w1.S1(Nk) / Nk) ) return g5 @@ -124,7 +153,7 @@ def mellin_g6(N): r""" Computes the Mellin transform of :math:`\text{Li}_3(x)/(1+x)`. - Implementation and defition in B.5.27 of :cite:`MuselliPhD` or + Implementation and definition in B.5.27 of :cite:`MuselliPhD` or in eq 63 of :cite:`Bl_mlein_2000`, but none of them is fully correct. Parameters @@ -139,10 +168,10 @@ def mellin_g6(N): """ - g6 = zeta3 * np.log(2) + g6 = zeta3 * log2 for k, ak in enumerate(a1): Nk = N + k + 1 - g6 -= ak * (N / Nk * zeta3 + (k + 1) / Nk**2 * (zeta2 - harmonic_S1(Nk) / Nk)) + g6 -= ak * (N / Nk * zeta3 + (k + 1) / Nk**2 * (zeta2 - w1.S1(Nk) / Nk)) return g6 @@ -151,7 +180,7 @@ def mellin_g8(N): r""" Computes the Mellin transform of :math:`S_{1,2}(x)/(1+x)`. - Implementation and defition in B.5.29 of :cite:`MuselliPhD` or + Implementation and definition in B.5.29 of :cite:`MuselliPhD` or in eq 65 of :cite:`Bl_mlein_2000`, but none of them is fully correct. Parameters @@ -164,12 +193,11 @@ def mellin_g8(N): mellin_g8 : complex Mellin transform :math:`\mathcal{M}[S_{1,2}(x)/(1+x)](N)` """ - g8 = zeta3 * np.log(2) + g8 = zeta3 * log2 for k, ak in enumerate(a1): Nk = N + k + 1 g8 -= ak * ( - N / Nk * zeta3 - + (k + 1) / Nk**2 * 1 / 2 * (harmonic_S1(Nk) ** 2 + harmonic_S2(Nk)) + N / Nk * zeta3 + (k + 1) / Nk**2 * 1 / 2 * (w1.S1(Nk) ** 2 + w2.S2(Nk)) ) return g8 @@ -179,7 +207,7 @@ def mellin_g18(N, S1, S2): r""" Computes the Mellin transform of :math:`-(\text{Li}_2(x) - \zeta_2)/(1-x)`. - Implementation and defition in eq 124 of :cite:`Bl_mlein_2000` + Implementation and definition in eq 124 of :cite:`Bl_mlein_2000` Note: comparing to :cite:`Bl_mlein_2000`, we believe :cite:`MuselliPhD` was not changing the notations of :math:`P^{(1)}_{2}` to :math:`P^{(1)}_{1}`. @@ -191,9 +219,9 @@ def mellin_g18(N, S1, S2): N : complex Mellin moment S1 : complex - harmonics.harmonic_S1(N) + harmonics.S1(N) S2 : complex - harmonics.harmonic_S2(N) + harmonics.S2(N) Returns ------- mellin_g18 : complex @@ -202,10 +230,10 @@ def mellin_g18(N, S1, S2): g18 = (S1**2 + S2) / (N) - zeta2 * S1 for k, ck in enumerate(c1): Nk = N + k - g18 += ck * (N) / (Nk) * harmonic_S1(Nk) + g18 += ck * (N) / (Nk) * w1.S1(Nk) for k, p11k in enumerate(p11): Nk = N + k - g18 -= p11k * (N) / (Nk) * (harmonic_S1(Nk) ** 2 + harmonic_S2(Nk)) + g18 -= p11k * (N) / (Nk) * (w1.S1(Nk) ** 2 + w2.S2(Nk)) return g18 @@ -214,7 +242,7 @@ def mellin_g19(N, S1): r""" Computes the Mellin transform of :math:`-(\text{Li}_2(-x) + \zeta_2/2)/(1-x)`. - Implementation and defition in B.5.40 of :cite:`MuselliPhD` or in 125 of + Implementation and definition in B.5.40 of :cite:`MuselliPhD` or in 125 of :cite:`Bl_mlein_2000`, but none of them is fully correct. Parameters @@ -222,7 +250,7 @@ def mellin_g19(N, S1): N : complex Mellin moment S1 : complex - harmonics.harmonic_S1(N) + harmonics.S1(N) Returns ------- @@ -232,7 +260,7 @@ def mellin_g19(N, S1): g19 = 1 / 2 * zeta2 * S1 for k, ak in enumerate(a1): Nk = N + k - g19 -= ak / (k + 1) * harmonic_S1(Nk + 1) + g19 -= ak / (k + 1) * w1.S1(Nk + 1) return g19 @@ -241,7 +269,7 @@ def mellin_g21(N, S1, S2, S3): r""" Computes the Mellin transform of :math:`-(S_{1,2}(x) - \zeta_3)/(1-x)`. - Implementation and defition in B.5.42 of :cite:`MuselliPhD` + Implementation and definition in B.5.42 of :cite:`MuselliPhD` Note: comparing to :cite:`Bl_mlein_2000`, we believe :cite:`MuselliPhD` was not changing the notations of :math:`P^{(3)}_{2}` to :math:`P^{(3)}_{1}` @@ -254,11 +282,11 @@ def mellin_g21(N, S1, S2, S3): N : complex Mellin moment S1 : complex - harmonics.harmonic_S1(N) + harmonics.S1(N) S2 : complex - harmonics.harmonic_S2(N) + harmonics.S2(N) S3 : complex - harmonics.harmonic_S3(N) + harmonics.S3(N) Returns ------- @@ -268,20 +296,15 @@ def mellin_g21(N, S1, S2, S3): g21 = -zeta3 * S1 + (S1**3 + 3 * S1 * S2 + 2 * S3) / (2 * N) for k, ck in enumerate(c3): Nk = N + k - g21 += ck * N / Nk * harmonic_S1(Nk) + g21 += ck * N / Nk * w1.S1(Nk) for k in range(0, 5): Nk = N + k g21 += ( N / Nk * ( - p32[k] - * ( - harmonic_S1(Nk) ** 3 - + 3 * harmonic_S1(Nk) * harmonic_S2(Nk) - + 2 * harmonic_S3(Nk) - ) - - p31[k] * (harmonic_S1(Nk) ** 2 + harmonic_S2(Nk)) + p32[k] * (w1.S1(Nk) ** 3 + 3 * w1.S1(Nk) * w2.S2(Nk) + 2 * w3.S3(Nk)) + - p31[k] * (w1.S1(Nk) ** 2 + w2.S2(Nk)) ) ) return g21 @@ -292,7 +315,7 @@ def mellin_g22(N): r""" Computes the Mellin transform of :math:`-(\text{Li}_2(x) ln(x))/(1-x)`. - Implementation and defition in B.5.43 of :cite:`MuselliPhD` + Implementation and definition in B.5.43 of :cite:`MuselliPhD` Note: comparing to :cite:`Bl_mlein_2000`, we believe :cite:`MuselliPhD` was not changing the notations of :math:`P^{(1)}_{2}` to :math:`P^{(1)}_{1}` @@ -316,7 +339,6 @@ def mellin_g22(N): for k, p11k in enumerate(p11): Nk = N + k g22 -= p11k * ( - harmonic_S1(Nk) * cern_polygamma(Nk + 1, 1) - - 1 / 2 * cern_polygamma(Nk + 1, 2) + w1.S1(Nk) * cern_polygamma(Nk + 1, 1) - 1 / 2 * cern_polygamma(Nk + 1, 2) ) return g22 diff --git a/src/eko/harmonics/polygamma.py b/src/eko/harmonics/polygamma.py new file mode 100644 index 000000000..8395365c0 --- /dev/null +++ b/src/eko/harmonics/polygamma.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- +""" +Implements higher mathematical functions. + +The functions are described in :doc:`Mellin space `. +""" + +import numba as nb +import numpy as np + + +@nb.njit(cache=True) +def cern_polygamma(Z, K): # pylint: disable=all + """ + Computes the polygamma functions :math:`\\psi_k(z)`. + + Reimplementation of ``WPSIPG`` (C317) in `CERNlib `_ + :cite:`KOLBIG1972221`. + + Note that the SciPy implementation :data:`scipy.special.digamma` + does not allow for complex inputs. + + Parameters + ---------- + Z : complex + argument of polygamma function + K : int + order of polygamma function + + Returns + ------- + H : complex + k-th polygamma function :math:`\\psi_k(z)` + """ + # fmt: off + DELTA = 5e-13 + R1 = 1 + HF = R1/2 + C1 = np.pi**2 + C2 = 2*np.pi**3 + C3 = 2*np.pi**4 + C4 = 8*np.pi**5 + + # SGN is originally indexed 0:4 -> no shift + SGN = [-1,+1,-1,+1,-1] + # FCT is originally indexed -1:4 -> shift +1 + FCT = [0,1,1,2,6,24] + + # C is originally indexed 1:6 x 0:4 -> swap indices and shift new last -1 + C = nb.typed.List() + C.append([ + 8.33333333333333333e-2, + -8.33333333333333333e-3, + 3.96825396825396825e-3, + -4.16666666666666667e-3, + 7.57575757575757576e-3, + -2.10927960927960928e-2]) + C.append([ + 1.66666666666666667e-1, + -3.33333333333333333e-2, + 2.38095238095238095e-2, + -3.33333333333333333e-2, + 7.57575757575757576e-2, + -2.53113553113553114e-1]) + C.append([ + 5.00000000000000000e-1, + -1.66666666666666667e-1, + 1.66666666666666667e-1, + -3.00000000000000000e-1, + 8.33333333333333333e-1, + -3.29047619047619048e+0]) + C.append([ + 2.00000000000000000e+0, + -1.00000000000000000e+0, + 1.33333333333333333e+0, + -3.00000000000000000e+0, + 1.00000000000000000e+1, + -4.60666666666666667e+1]) + C.append([10., -7., 12., -33., 130., -691.]) + U=Z + X=np.real(U) + A=np.abs(X) + if K < 0 or K > 4: + raise NotImplementedError("Order K has to be in [0:4]") + if np.abs(np.imag(U)) < DELTA and np.abs(X+int(A)) < DELTA: + raise ValueError("Argument Z equals non-positive integer") + K1=K+1 + if X < 0: + U=-U + V=U + H=0 + if A < 15: + H=1/V**K1 + for I in range(1,14-int(A)+1): + V=V+1 + H=H+1/V**K1 + V=V+1 + R=1/V**2 + P=R*C[K][6-1] + for I in range(5,1-1,-1): + P=R*(C[K][I-1]+P) + H=SGN[K]*(FCT[K+1]*H+(V*(FCT[K-1+1]+P)+HF*FCT[K+1])/V**K1) + if K == 0: + H=H+np.log(V) + if X < 0: + V=np.pi*U + X=np.real(V) + Y=np.imag(V) + A=np.sin(X) + B=np.cos(X) + T=np.tanh(Y) + P=complex(B,-A*T)/complex(A,B*T) + if K == 0: + H=H+1/U+np.pi*P + elif K == 1: + H=-H+1/U**2+C1*(P**2+1) + elif K == 2: + H=H+2/U**3+C2*P*(P**2+1) + elif K == 3: + R=P**2 + H=-H+6/U**4+C3*((3*R+4)*R+1) + elif K == 4: + R=P**2 + H=H+24/U**5+C4*P*((3*R+5)*R+2) + return H + # fmt: on diff --git a/src/eko/harmonics/w1.py b/src/eko/harmonics/w1.py new file mode 100644 index 000000000..e929bc7ab --- /dev/null +++ b/src/eko/harmonics/w1.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +""" +Weight 1 harmonics sum. +""" +import numba as nb +import numpy as np + +from .constants import log2 +from .polygamma import cern_polygamma + + +@nb.njit(cache=True) +def S1(N): + r""" + Computes the harmonic sum :math:`S_1(N)`. + + .. math:: + S_1(N) = \sum\limits_{j=1}^N \frac 1 j = \psi_0(N+1)+\gamma_E + + with :math:`\psi_0(N)` the digamma function and :math:`\gamma_E` the + Euler-Mascheroni constant. + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + S_1 : complex + (simple) Harmonic sum :math:`S_1(N)` + + See Also + -------- + eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + """ + return cern_polygamma(N + 1.0, 0) + np.euler_gamma + + +@nb.njit(cache=True) +def Sm1(N): + r""" + Analytic continuation of harmonic sum :math:`S_{-1}(N)`. + + .. math:: + S_{-1}(N) = \sum\limits_{j=1}^N \frac (-1)^j j + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + Sm1 : complex + Harmonic sum :math:`S_{-1}(N)` + + See Also + -------- + eko.anomalous_dimension.w1.S1 : :math:`S_1(N)` + """ + return (-1) ** N / 2 * (S1(N / 2) - S1((N - 1) / 2)) - log2 diff --git a/src/eko/harmonics/w2.py b/src/eko/harmonics/w2.py new file mode 100644 index 000000000..5ab7b8262 --- /dev/null +++ b/src/eko/harmonics/w2.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +""" +Weight 2 harmonics sum. +""" +import numba as nb + +from .constants import zeta2 +from .polygamma import cern_polygamma + + +@nb.njit(cache=True) +def S2(N): + r""" + Computes the harmonic sum :math:`S_2(N)`. + + .. math:: + S_2(N) = \sum\limits_{j=1}^N \frac 1 {j^2} = -\psi_1(N+1)+\zeta(2) + + with :math:`\psi_1(N)` the trigamma function and :math:`\zeta` the + Riemann zeta function. + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + S_2 : complex + Harmonic sum :math:`S_2(N)` + + See Also + -------- + eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + """ + return -cern_polygamma(N + 1.0, 1) + zeta2 + + +@nb.njit(cache=True) +def Sm2(N): + r""" + Analytic continuation of harmonic sum :math:`S_{-2}(N)`. + + .. math:: + S_{-2}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^2 + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + Sm2 : complex + Harmonic sum :math:`S_{-2}(N)` + + See Also + -------- + eko.anomalous_dimension.w2.S2 : :math:`S_2(N)` + """ + return (-1) ** N / 4 * (S2(N / 2) - S2((N - 1) / 2)) - zeta2 / 2 diff --git a/src/eko/harmonics/w3.py b/src/eko/harmonics/w3.py new file mode 100644 index 000000000..442cc11f4 --- /dev/null +++ b/src/eko/harmonics/w3.py @@ -0,0 +1,181 @@ +# -*- coding: utf-8 -*- +""" +Weight 3 harmonics sum. +""" +import numba as nb + +from . import g_functions as gf +from .constants import log2, zeta2, zeta3 +from .polygamma import cern_polygamma + + +@nb.njit(cache=True) +def S3(N): + r""" + Computes the harmonic sum :math:`S_3(N)`. + + .. math:: + S_3(N) = \sum\limits_{j=1}^N \frac 1 {j^3} = \frac 1 2 \psi_2(N+1)+\zeta(3) + + with :math:`\psi_2(N)` the 2nd-polygamma function and :math:`\zeta` the + Riemann zeta function. + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + S_3 : complex + Harmonic sum :math:`S_3(N)` + + See Also + -------- + eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + """ + return 0.5 * cern_polygamma(N + 1.0, 2) + zeta3 + + +@nb.njit(cache=True) +def Sm3(N): + r""" + Analytic continuation of harmonic sum :math:`S_{-3}(N)`. + + .. math:: + S_{-3}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^3 + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + Sm3 : complex + Harmonic sum :math:`S_{-3}(N)` + + See Also + -------- + eko.harmonics.w3.S3 : :math:`S_3(N)` + """ + return (-1) ** N / 8 * (S3(N / 2) - S3((N - 1) / 2)) - 3 / 4 * zeta3 + + +@nb.njit(cache=True) +def S21(N, S1, S2): + r""" + Analytic continuation of harmonic sum :math:`S_{2,1}(N)` + as implemented in eq B.5.77 of :cite:`MuselliPhD` and eq 37 of cite:`Bl_mlein_2000`. + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + + Returns + ------- + S21 : complex + Harmonic sum :math:`S_{2,1}(N)` + + See Also + -------- + eko.harmonics.g_functions.mellin_g18 : :math:`g_18(N)` + """ + return -gf.mellin_g18(N, S1, S2) + 2 * zeta3 + + +@nb.njit(cache=True) +def Sm21(N, Sm1): + r""" + Analytic continuation of harmonic sum :math:`S_{-2,1}(N)` + as implemented in eq B.5.75 of :cite:`MuselliPhD` and eq 22 of cite:`Bl_mlein_2000`. + + Parameters + ---------- + N : complex + Mellin moment + Sm1: complex + Hamrmonic sum :math:`S_{-1}(N)` + + Returns + ------- + Sm21 : complex + Harmonic sum :math:`S_{-2,1}(N)` + + See Also + -------- + eko.harmonics.g_functions : :math:`g_3(N)` + """ + # Note mellin g3 was integrated following x^(N-1) convention. + return ( + -((-1) ** N) * gf.mellin_g3(N + 1) + zeta2 * Sm1 - 5 / 8 * zeta3 + zeta2 * log2 + ) + + +@nb.njit(cache=True) +def S2m1(N, S2, Sm1, Sm2): + r""" + Analytic continuation of harmonic sum :math:`S_{2,-1}(N)` + as implemented in eq B.5.76 of :cite:`MuselliPhD` and eq 23 of cite:`Bl_mlein_2000`. + + Parameters + ---------- + N : complex + Mellin moment + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + Sm1: complex + Hamrmonic sum :math:`S_{-1}(N)` + Sm2: complex + Hamrmonic sum :math:`S_{-2}(N)` + + Returns + ------- + S2m1 : complex + Harmonic sum :math:`S_{2,-1}(N)` + + See Also + -------- + eko.harmonics.g_functions.mellin_g4 : :math:`g_4(N)` + """ + return ( + -((-1) ** N) * gf.mellin_g4(N) + - log2 * (S2 - Sm2) + - 1 / 2 * zeta2 * Sm1 + + 1 / 4 * zeta3 + - 1 / 2 * zeta2 * log2 + ) + + +@nb.njit(cache=True) +def Sm2m1(N, S1, S2, Sm2): + r""" + Analytic continuation of harmonic sum :math:`S_{-2,-1}(N)` + as implemented in eq B.5.74 of :cite:`MuselliPhD` and eq 38 of cite:`Bl_mlein_2000`. + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + Sm2: complex + Hamrmonic sum :math:`S_{-2}(N)` + + Returns + ------- + Sm2m1 : complex + Harmonic sum :math:`S_{-2,-1}(N)` + + See Also + -------- + eko.harmonics.g_functions.mellin_g19 : :math:`g_19(N)` + """ + return -gf.mellin_g19(N, S1) + log2 * (S2 - Sm2) - 5 / 8 * zeta3 diff --git a/src/eko/harmonics/w4.py b/src/eko/harmonics/w4.py new file mode 100644 index 000000000..45a2afff8 --- /dev/null +++ b/src/eko/harmonics/w4.py @@ -0,0 +1,221 @@ +# -*- coding: utf-8 -*- +""" +Weight 4 harmonics sum. +""" +import numba as nb + +from . import g_functions as gf +from .constants import li4half, log2, zeta2, zeta3, zeta4 +from .polygamma import cern_polygamma + + +@nb.njit(cache=True) +def S4(N): + r""" + Computes the harmonic sum :math:`S_4(N)`. + + .. math:: + S_4(N) = \sum\limits_{j=1}^N \frac 1 {j^4} = - \frac 1 6 \psi_3(N+1)+\zeta(4) + + with :math:`\psi_3(N)` the 3rd-polygamma function and :math:`\zeta` the + Riemann zeta function. + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + S_4 : complex + Harmonic sum :math:`S_4(N)` + + See Also + -------- + eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + """ + return zeta4 - 1.0 / 6.0 * cern_polygamma(N + 1.0, 3) + + +@nb.njit(cache=True) +def Sm4(N): + r""" + Analytic continuation of harmonic sum :math:`S_{-4}(N)`. + + .. math:: + S_{-4}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^4 + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + Sm4 : complex + Harmonic sum :math:`S_{-4}(N)` + + See Also + -------- + eko.anomalous_dimension.w4.S4 : :math:`S_4(N)` + """ + return (-1) ** N / 16 * (S4(N / 2) - S4((N - 1) / 2)) - 7 / 8 * zeta4 + + +@nb.njit(cache=True) +def Sm31(N, Sm1, Sm2): + r""" + Analytic continuation of harmonic sum :math:`S_{-3,1}(N)` + as implemented in eq B.5.93 of :cite:`MuselliPhD` and eq 25 of cite:`Bl_mlein_2000`. + + Parameters + ---------- + N : complex + Mellin moment + Sm1: complex + Hamrmonic sum :math:`S_{-1}(N)` + Sm2: complex + Hamrmonic sum :math:`S_{-2}(N)` + + Returns + ------- + Sm31 : complex + Harmonic sum :math:`S_{-3,1}(N)` + + See Also + -------- + eko.harmonics.g_functions.mellin_g6 : :math:`g_6(N)` + """ + return ( + (-1) ** N * gf.mellin_g6(N) + + zeta2 * Sm2 + - zeta3 * Sm1 + - 3 / 5 * zeta2**2 + + 2 * li4half + + 3 / 4 * zeta3 * log2 + - 1 / 2 * zeta2 * log2**2 + + 1 / 12 * log2**4 + ) + + +@nb.njit(cache=True) +def Sm22(N, Sm2, Sm31): + r""" + Analytic continuation of harmonic sum :math:`S_{-2,2}(N)` + as implemented in eq B.5.94 of :cite:`MuselliPhD` and eq 24 of cite:`Bl_mlein_2000`. + + Parameters + ---------- + N : complex + Mellin moment + Sm2: complex + Hamrmonic sum :math:`S_{-2}(N)` + Sm31: complex + Hamrmonic sum :math:`S_{-3,1}(N)` + Returns + ------- + Sm22 : complex + Harmonic sum :math:`S_{-2,2}(N)` + + See Also + -------- + eko.harmonics.g_functions.mellin_g5 : :math:`g_5(N)` + """ + return ( + (-1) ** N * gf.mellin_g5(N) - 2 * Sm31 + 2 * zeta2 * Sm2 + 3 / 40 * zeta2**2 + ) + + +@nb.njit(cache=True) +def Sm211(N, Sm1): + r""" + Analytic continuation of harmonic sum :math:`S_{-2,1,1}(N)` + as implemented in eq B.5.104 of :cite:`MuselliPhD` and eq 27 of cite:`Bl_mlein_2000`. + + Parameters + ---------- + N : complex + Mellin moment + Sm1: complex + Hamrmonic sum :math:`S_{-1}(N)` + + Returns + ------- + Sm31 : complex + Harmonic sum :math:`S_{-2,1,1}(N)` + + See Also + -------- + eko.harmonics.g_functions.mellin_g8 : :math:`g_8(N)` + """ + return ( + -((-1) ** N) * gf.mellin_g8(N) + + zeta3 * Sm1 + - li4half + + 1 / 8 * zeta2**2 + + 1 / 8 * zeta3 * log2 + + 1 / 4 * zeta2 * log2**2 + - 1 / 24 * log2**4 + ) + + +@nb.njit(cache=True) +def S211(N, S1, S2, S3): + r""" + Analytic continuation of harmonic sum :math:`S_{2,1,1}(N)` + as implemented in eq B.5.115 of :cite:`MuselliPhD` and eq 40 of cite:`Bl_mlein_2000`. + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + S3: complex + Hamrmonic sum :math:`S_{3}(N)` + + Returns + ------- + S211 : complex + Harmonic sum :math:`S_{2,1,1}(N)` + + See Also + -------- + eko.harmonics.g_functions.mellin_g21 : :math:`g_21(N)` + """ + return -gf.mellin_g21(N, S1, S2, S3) + 6 / 5 * zeta2**2 + + +@nb.njit(cache=True) +def S31(N, S2, S4): + r""" + Analytic continuation of harmonic sum :math:`S_{3,1}(N)` + as implemented in eq B.5.99 of :cite:`MuselliPhD` and eq 41 of cite:`Bl_mlein_2000`. + + Parameters + ---------- + N : complex + Mellin moment + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + S4: complex + Hamrmonic sum :math:`S_{4}(N)` + + Returns + ------- + S31 : complex + Harmonic sum :math:`S_{3,1}(N)` + + See Also + -------- + eko.harmonics.g_functions.mellin_g22 : :math:`g_22(N)` + """ + return ( + 1 / 2 * gf.mellin_g22(N) + - 1 / 4 * S4 + - 1 / 4 * S2**2 + + zeta2 * S2 + - 3 / 20 * zeta2**2 + ) diff --git a/src/eko/harmonics/w5.py b/src/eko/harmonics/w5.py new file mode 100644 index 000000000..112e5ae57 --- /dev/null +++ b/src/eko/harmonics/w5.py @@ -0,0 +1,426 @@ +# -*- coding: utf-8 -*- +""" +Weight 5 harmonics sum. +""" +import numba as nb + +from . import f_functions as f +from .constants import log2, zeta2, zeta3, zeta4, zeta5 +from .polygamma import cern_polygamma + + +@nb.njit(cache=True) +def S5(N): + r""" + Computes the harmonic sum :math:`S_5(N)`. + + .. math:: + S_5(N) = \sum\limits_{j=1}^N \frac 1 {j^5} = \frac 1 24 \psi_4(N+1)+\zeta(5) + + with :math:`\psi_4(N)` the 4th-polygamma function and :math:`\zeta` the + Riemann zeta function. + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + S_5 : complex + Harmonic sum :math:`S_5(N)` + + See Also + -------- + eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + """ + return zeta5 + 1.0 / 24.0 * cern_polygamma(N + 1.0, 4) + + +@nb.njit(cache=True) +def Sm5(N): + r""" + Analytic continuation of harmonic sum :math:`S_{-5}(N)`. + + .. math:: + S_{-5}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^5 + + Parameters + ---------- + N : complex + Mellin moment + + Returns + ------- + Sm5 : complex + Harmonic sum :math:`S_{-5}(N)` + + See Also + -------- + eko.harmonic.w5.S5 : :math:`S_5(N)` + """ + return (-1) ** N / 32 * (S5(N / 2) - S5((N - 1) / 2)) - 15 / 16 * zeta5 + + +@nb.njit(cache=True) +def S41(N, S1, S2, S3): + r""" + Analytic continuation of harmonic sum :math:`S_{4,1}(N)` + as implemented in eq 9.1 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + S3: complex + Hamrmonic sum :math:`S_{3}(N)` + + Returns + ------- + S41 : complex + Harmonic sum :math:`S_{4,1}(N)` + + See Also + -------- + eko.harmonic.f_functions.F9 : + :math:`\mathcal{M}[(\text{Li}_4(x)/(x-1))_{+}](N)` + """ + return -f.F9(N, S1) + S1 * zeta4 - S2 * zeta3 + S3 * zeta2 + + +@nb.njit(cache=True) +def S311(N, S1, S2): + r""" + Analytic continuation of harmonic sum :math:`S_{3,1,1}(N)` + as implemented in eq 9.21 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + + Returns + ------- + S311 : complex + Harmonic sum :math:`S_{3,1,1}(N)` + + See Also + -------- + eko.harmonic.f_functions.F11 : + :math:`\mathcal{M}[(\text{S}_{2,2}(x)/(x-1))_{+}](N)` + """ + return f.F11(N, S1, S2) + zeta3 * S2 - zeta4 / 4 * S1 + + +@nb.njit(cache=True) +def S221(N, S1, S2, S21): + r""" + Analytic continuation of harmonic sum :math:`S_{2,2,1}(N)` + as implemented in eq 9.23 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + S21: complex + Hamrmonic sum :math:`S_{2,1}(N)` + + Returns + ------- + S221 : complex + Harmonic sum :math:`S_{2,2,1}(N)` + + See Also + -------- + eko.harmonic.f_functions.F11 : + :math:`\mathcal{M}[(\text{S}_{2,2}(x)/(x-1))_{+}](N)` + eko.harmonic.f_functions.F13 : + :math:`\mathcal{M}[(\text{Li}_{2}^2(x)/(x-1))_{+}](N)` + """ + return ( + -2 * f.F11(N, S1, S2) + + 1 / 2 * f.F13(N, S1, S2) + + zeta2 * S21 + - 3 / 10 * zeta2**2 * S1 + ) + + +@nb.njit(cache=True) +def Sm221(N, S1, Sm1, S21, Sm21): + r""" + Analytic continuation of harmonic sum :math:`S_{-2,2,1}(N)` + as implemented in eq 9.25 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + Sm1: complex + Hamrmonic sum :math:`S_{-1}(N)` + S21: complex + Hamrmonic sum :math:`S_{2,1}(N)` + Sm21: complex + Hamrmonic sum :math:`S_{-2,1}(N)` + + Returns + ------- + Sm221 : complex + Harmonic sum :math:`S_{-2,2,1}(N)` + + See Also + -------- + eko.harmonic.f_functions.F14F12 : + :math:`\mathcal{M}[(2 \text{S}_{2,2}(x) - 1/2 \text{Li}_{2}^2(x))/(x+1)](N)` + """ + return ( + (-1) ** (N + 1) * (f.F14F12(N, S1, S21)) + + zeta2 * Sm21 + - 3 / 10 * zeta2**2 * Sm1 + - 0.119102 + + 0.0251709 + ) + + +@nb.njit(cache=True) +def S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1): + r""" + Analytic continuation of harmonic sum :math:`S_{2,1,-2}(N)` + as implemented in eq 9.26 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + Sm1: complex + Hamrmonic sum :math:`S_{-1}(N)` + Sm2: complex + Hamrmonic sum :math:`S_{-2}(N)` + Sm3: complex + Hamrmonic sum :math:`S_{-3}(N)` + S21: complex + Hamrmonic sum :math:`S_{2,1}(N)` + Sm21: complex + Hamrmonic sum :math:`S_{-2,1}(N)` + S2m1: complex + Hamrmonic sum :math:`S_{2,-1}(N)` + + Returns + ------- + S21m2 : complex + Harmonic sum :math:`S_{2,1,-2}(N)` + + See Also + -------- + eko.harmonic.f_functions.F14F12 : + :math:`\mathcal{M}[ + (\text{ln}(x) \text{S}_{1,2}(−x) − \text{Li}_2^2(−x)/2)/(x+1) + ](N)` + """ + return ( + (-1) ** (N) * f.F16(N, S1, Sm1, Sm2, Sm3, Sm21) + - 1 / 2 * zeta2 * (S21 - S2m1) + - (1 / 8 * zeta3 - 1 / 2 * zeta2 * log2) * (S2 - Sm2) + + 1 / 8 * zeta2**2 * Sm1 + + 0.0854806 + ) + + +@nb.njit(cache=True) +def S2111(N, S1, S2, S3): + r""" + Analytic continuation of harmonic sum :math:`S_{2,1,1,1}(N)` + as implemented in eq 9.33 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + S3: complex + Hamrmonic sum :math:`S_{3}(N)` + + Returns + ------- + S2111 : complex + Harmonic sum :math:`S_{2,1,1,1}(N)` + + See Also + -------- + eko.harmonic.f_functions.F17 : + :math:`\mathcal{M}[(\text{S}_{1,3}(x)/(x-1))_{+}](N)` + """ + return -f.F17(N, S1, S2, S3) + zeta4 * S1 + + +@nb.njit(cache=True) +def Sm2111(N, S1, S2, S3, Sm1): + r""" + Analytic continuation of harmonic sum :math:`S_{-2,1,1,1}(N)` + as implemented in eq 9.34 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + S3: complex + Hamrmonic sum :math:`S_{3}(N)` + Sm1: complex + Hamrmonic sum :math:`S_{-1}(N)` + + Returns + ------- + Sm2111 : complex + Harmonic sum :math:`S_{-2,1,1,1}(N)` + + See Also + -------- + eko.harmonic.f_functions.F18 : + :math:`\mathcal{M}[\text{S}_{1,3}(x)/(x+1)](N)` + """ + return ( + (-1) ** (N + 1) * f.F18(N, S1, S2, S3) + + zeta4 * Sm1 + - 0.706186 + + 0.693147 * zeta4 + ) + + +@nb.njit(cache=True) +def S23(N, S1, S2, S3): + r""" + Analytic continuation of harmonic sum :math:`S_{2,3}(N)` + as implemented in eq 9.3 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + S1: complex + Hamrmonic sum :math:`S_{1}(N)` + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + S3: complex + Hamrmonic sum :math:`S_{3}(N)` + + Returns + ------- + S23 : complex + Harmonic sum :math:`S_{2,3}(N)` + + See Also + -------- + eko.harmonic.f_functions.F19 : + :math:`\mathcal{M}[ + (( + \text{ln}(x)[\text{S}_{1,2}(1-x) - \zeta_3] + +3 [\text{S}_{1,3}(1-x) - \zeta_4] + /(x-1))_{+}](N)` + """ + return f.F19(N, S1, S2, S3) + 3 * zeta4 * S1 + + +@nb.njit(cache=True) +def Sm23(N, Sm1, Sm2, Sm3): + r""" + Analytic continuation of harmonic sum :math:`S_{-2,3}(N)` + as implemented in eq 9.4 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + Sm1: complex + Hamrmonic sum :math:`S_{-1}(N)` + Sm2: complex + Hamrmonic sum :math:`S_{-2}(N)` + Sm3: complex + Hamrmonic sum :math:`S_{-3}(N)` + + Returns + ------- + Sm23 : complex + Harmonic sum :math:`S_{-2,3}(N)` + + See Also + -------- + eko.harmonic.f_functions.F19 : + :math:`\mathcal{M}[ + ( + \text{ln}(x)[\text{S}_{1,2}(1-x) - \zeta_3] + +3 [\text{S}_{1,3}(1-x) - \zeta_4] + /(x+1)](N)` + """ + return ( + (-1) ** N * f.F20(N, Sm1, Sm2, Sm3) + + 3 * zeta4 * Sm1 + + 21 / 32 * zeta5 + + 3 * zeta4 * log2 + - 3 / 4 * zeta2 * zeta3 + ) + + +@nb.njit(cache=True) +def S2m3(N, S2, Sm1, Sm2, Sm3): + r""" + Analytic continuation of harmonic sum :math:`S_{2,-3}(N)` + as implemented in eq 9.5 of cite:` Bl_mlein_2009` + + Parameters + ---------- + N : complex + Mellin moment + S2: complex + Hamrmonic sum :math:`S_{2}(N)` + Sm1: complex + Hamrmonic sum :math:`S_{-1}(N)` + Sm2: complex + Hamrmonic sum :math:`S_{-2}(N)` + Sm3: complex + Hamrmonic sum :math:`S_{-3}(N)` + + Returns + ------- + S2m3 : complex + Harmonic sum :math:`S_{2,-3}(N)` + + See Also + -------- + eko.harmonic.f_functions.F19 : + :math:`\mathcal{M}[ + (( + 1/2 \text{ln}^2(x) \text{Li}_2(-x) + -2 \text{ln}(x) \text{Li}_3(-x) + +3 \text{Li}_4(-x) + )/(x-1)](N)` + """ + return ( + (-1) ** (N + 1) * f.F21(N, Sm1, Sm2, Sm3) + + 3 / 4 * zeta3 * (Sm2 - S2) + - 21 / 8 * zeta4 * Sm1 + - 1.32056 + ) diff --git a/src/eko/matching_conditions/as1.py b/src/eko/matching_conditions/as1.py index ee31f565c..f76a3be38 100644 --- a/src/eko/matching_conditions/as1.py +++ b/src/eko/matching_conditions/as1.py @@ -33,8 +33,8 @@ def A_hh(n, sx, L): A_hh : complex |NLO| heavy-heavy |OME| :math:`A_{HH}^{(1)}` """ - S1m = sx[0] - 1 / n # harmonics.harmonic_S1(n - 1) - S2m = sx[1] - 1 / n**2 # harmonics.harmonic_S2(n - 1) + S1m = sx[0] - 1 / n # harmonics.S1(n - 1) + S2m = sx[1] - 1 / n**2 # harmonics.S2(n - 1) ahh_l = (2 + n - 3 * n**2) / (n * (1 + n)) + 4 * S1m ahh = 2 * ( 2 diff --git a/src/eko/matching_conditions/as2.py b/src/eko/matching_conditions/as2.py index 421b40844..deb526344 100644 --- a/src/eko/matching_conditions/as2.py +++ b/src/eko/matching_conditions/as2.py @@ -12,15 +12,11 @@ import numba as nb import numpy as np -from .. import constants -from ..anomalous_dimensions import harmonics +from .. import constants, harmonics +from ..harmonics.constants import log2, zeta2, zeta3 from .as1 import A_gg as A_gg_1 from .as1 import A_hg as A_hg_1 -# Global variables -zeta2 = harmonics.zeta2 -zeta3 = harmonics.zeta3 - @nb.njit(cache=True) def A_qq_ns(n, sx, L): @@ -166,16 +162,17 @@ def A_hg(n, sx, L): S3 = sx[2] S1m = S1 - 1 / n S2m = S2 - 1 / n**2 - Sp2m = harmonics.harmonic_S2((n - 1) / 2) - Sp2p = harmonics.harmonic_S2(n / 2) - Sm1 = -S1 + harmonics.harmonic_S1(n / 2) + Sp2m = harmonics.S2((n - 1) / 2) + Sp2p = harmonics.S2(n / 2) + # TODO: use harmonics from cache + Sm1 = -S1 + harmonics.S1(n / 2) Sm2 = -S2 + 1 / 2 * Sp2p - Sm3 = -S3 + 1 / 4 * harmonics.harmonic_S3(n / 2) + Sm3 = -S3 + 1 / 4 * harmonics.S3(n / 2) Sm21 = ( - -5 / 8 * harmonics.zeta3 - + harmonics.zeta2 * (Sm1 - 1 / n + np.log(2)) + -5 / 8 * zeta3 + + zeta2 * (Sm1 - 1 / n + log2) + S1 / n**2 - + harmonics.mellin_g3(n) + + harmonics.g_functions.mellin_g3(n) ) a_hg_l0 = ( diff --git a/src/eko/matching_conditions/as3/aqqNS.py b/src/eko/matching_conditions/as3/aqqNS.py index fa8079cb8..494fa4015 100644 --- a/src/eko/matching_conditions/as3/aqqNS.py +++ b/src/eko/matching_conditions/as3/aqqNS.py @@ -2,7 +2,7 @@ import numba as nb import numpy as np -from . import s_functions as sf +from ... import harmonics as sf @nb.njit(cache=True) @@ -41,16 +41,16 @@ def A_qqNS(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals Sm1, Sm2, Sm3, Sm4, Sm5 = smx[0], smx[1], smx[2], smx[3], smx[4] S21, S2m1, Sm21 = s3x[0], s3x[1], s3x[2] S31, S211, Sm22, Sm211 = s4x[0], s4x[1], s4x[2], s4x[3] - S41 = sf.harmonic_S41(n, S1, S2, S3) - S311 = sf.harmonic_S311(n, S1, S2) - S221 = sf.harmonic_S221(n, S1, S2, S21) - Sm221 = sf.harmonic_Sm221(n, S1, Sm1, S21, Sm21) - S21m2 = sf.harmonic_S21m2(n, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1) - S2111 = sf.harmonic_S2111(n, S1, S2, S3) - Sm2111 = sf.harmonic_Sm2111(n, S1, S2, S3, Sm1) - S23 = sf.harmonic_S23(n, S1, S2, S3) - Sm23 = sf.harmonic_Sm23(n, Sm1, Sm2, Sm3) - S2m3 = sf.harmonic_S2m3(n, S2, Sm1, Sm2, Sm3) + S41 = sf.S41(n, S1, S2, S3) + S311 = sf.S311(n, S1, S2) + S221 = sf.S221(n, S1, S2, S21) + Sm221 = sf.Sm221(n, S1, Sm1, S21, Sm21) + S21m2 = sf.S21m2(n, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1) + S2111 = sf.S2111(n, S1, S2, S3) + Sm2111 = sf.Sm2111(n, S1, S2, S3, Sm1) + S23 = sf.S23(n, S1, S2, S3) + Sm23 = sf.Sm23(n, Sm1, Sm2, Sm3) + S2m3 = sf.S2m3(n, S2, Sm1, Sm2, Sm3) a_qqNS_l0 = ( 0.3333333333333333 * nf diff --git a/src/eko/matching_conditions/as3/s_functions.py b/src/eko/matching_conditions/as3/s_functions.py deleted file mode 100644 index bf243742c..000000000 --- a/src/eko/matching_conditions/as3/s_functions.py +++ /dev/null @@ -1,801 +0,0 @@ -# -*- coding: utf-8 -*- -""" -This module contains some additional harmonics sum. -Defintion are coming from :cite:`MuselliPhD,Bl_mlein_2000,Blumlein:2009ta` -""" -import numba as nb -import numpy as np - -from eko.anomalous_dimensions import harmonics - -from . import f_functions as f -from . import g_functions as gf - -zeta2 = harmonics.zeta2 -zeta3 = harmonics.zeta3 -zeta4 = harmonics.zeta4 -zeta5 = harmonics.zeta5 - -li4half = 0.517479 -log2 = np.log(2) - - -@nb.njit(cache=True) -def harmonic_Sm1(N): - r""" - Analytic continuation of harmonic sum :math:`S_{-1}(N)`. - - .. math:: - S_{-1}(N) = \sum\limits_{j=1}^N \frac (-1)^j j - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - Sm1 : complex - Harmonic sum :math:`S_{-1}(N)` - - See Also - -------- - eko.anomalous_dimension.harmonics.harmonic_S1 : :math:`S_1(N)` - """ - return (-1) ** N / 2 * ( - harmonics.harmonic_S1(N / 2) - harmonics.harmonic_S1((N - 1) / 2) - ) - log2 - - -@nb.njit(cache=True) -def harmonic_Sm2(N): - r""" - Analytic continuation of harmonic sum :math:`S_{-2}(N)`. - - .. math:: - S_{-2}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^2 - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - Sm2 : complex - Harmonic sum :math:`S_{-2}(N)` - - See Also - -------- - eko.anomalous_dimension.harmonics.harmonic_S2 : :math:`S_2(N)` - """ - return (-1) ** N / 4 * ( - harmonics.harmonic_S2(N / 2) - harmonics.harmonic_S2((N - 1) / 2) - ) - zeta2 / 2 - - -@nb.njit(cache=True) -def harmonic_Sm3(N): - r""" - Analytic continuation of harmonic sum :math:`S_{-3}(N)`. - - .. math:: - S_{-3}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^3 - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - Sm3 : complex - Harmonic sum :math:`S_{-3}(N)` - - See Also - -------- - eko.anomalous_dimension.harmonics.harmonic_S3 : :math:`S_3(N)` - """ - return (-1) ** N / 8 * ( - harmonics.harmonic_S3(N / 2) - harmonics.harmonic_S3((N - 1) / 2) - ) - 3 / 4 * zeta3 - - -@nb.njit(cache=True) -def harmonic_Sm4(N): - r""" - Analytic continuation of harmonic sum :math:`S_{-4}(N)`. - - .. math:: - S_{-4}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^4 - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - Sm4 : complex - Harmonic sum :math:`S_{-4}(N)` - - See Also - -------- - eko.anomalous_dimension.harmonics.harmonic_S4 : :math:`S_4(N)` - """ - return (-1) ** N / 16 * ( - harmonics.harmonic_S4(N / 2) - harmonics.harmonic_S4((N - 1) / 2) - ) - 7 / 8 * zeta4 - - -@nb.njit(cache=True) -def harmonic_Sm5(N): - r""" - Analytic continuation of harmonic sum :math:`S_{-5}(N)`. - - .. math:: - S_{-5}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^5 - - Parameters - ---------- - N : complex - Mellin moment - - Returns - ------- - Sm5 : complex - Harmonic sum :math:`S_{-5}(N)` - - See Also - -------- - eko.anomalous_dimension.harmonics.harmonic_S5 : :math:`S_5(N)` - """ - return (-1) ** N / 32 * ( - harmonics.harmonic_S5(N / 2) - harmonics.harmonic_S5((N - 1) / 2) - ) - 15 / 16 * zeta5 - - -@nb.njit(cache=True) -def harmonic_S21(N, S1, S2): - r""" - Analytic continuation of harmonic sum :math:`S_{2,1}(N)` - as implemented in eq B.5.77 of :cite:`MuselliPhD` and eq 37 of cite:`Bl_mlein_2000`. - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - - Returns - ------- - S21 : complex - Harmonic sum :math:`S_{2,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.g_functions.mellin_g18 : :math:`g_18(N)` - """ - return -gf.mellin_g18(N, S1, S2) + 2 * zeta3 - - -@nb.njit(cache=True) -def harmonic_Sm21(N, Sm1): - r""" - Analytic continuation of harmonic sum :math:`S_{-2,1}(N)` - as implemented in eq B.5.75 of :cite:`MuselliPhD` and eq 22 of cite:`Bl_mlein_2000`. - - Parameters - ---------- - N : complex - Mellin moment - Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` - - Returns - ------- - Sm21 : complex - Harmonic sum :math:`S_{-2,1}(N)` - - See Also - -------- - eko.anomalous_dimension.harmonics.melling_g3 : :math:`g_3(N)` - """ - # Note mellin g3 was integrated following x^(N-1) convention. - return ( - -((-1) ** N) * harmonics.mellin_g3(N + 1) - + zeta2 * Sm1 - - 5 / 8 * zeta3 - + zeta2 * log2 - ) - - -@nb.njit(cache=True) -def harmonic_S2m1(N, S2, Sm1, Sm2): - r""" - Analytic continuation of harmonic sum :math:`S_{2,-1}(N)` - as implemented in eq B.5.76 of :cite:`MuselliPhD` and eq 23 of cite:`Bl_mlein_2000`. - - Parameters - ---------- - N : complex - Mellin moment - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` - Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` - - Returns - ------- - S2m1 : complex - Harmonic sum :math:`S_{2,-1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.g_functions.mellin_g4 : :math:`g_4(N)` - """ - return ( - -((-1) ** N) * gf.mellin_g4(N) - - np.log(2) * (S2 - Sm2) - - 1 / 2 * zeta2 * Sm1 - + 1 / 4 * zeta3 - - 1 / 2 * zeta2 * log2 - ) - - -@nb.njit(cache=True) -def harmonic_Sm31(N, Sm1, Sm2): - r""" - Analytic continuation of harmonic sum :math:`S_{-3,1}(N)` - as implemented in eq B.5.93 of :cite:`MuselliPhD` and eq 25 of cite:`Bl_mlein_2000`. - - Parameters - ---------- - N : complex - Mellin moment - Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` - Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` - - Returns - ------- - Sm31 : complex - Harmonic sum :math:`S_{-3,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.g_functions.mellin_g6 : :math:`g_6(N)` - """ - return ( - (-1) ** N * gf.mellin_g6(N) - + zeta2 * Sm2 - - zeta3 * Sm1 - - 3 / 5 * zeta2**2 - + 2 * li4half - + 3 / 4 * zeta3 * log2 - - 1 / 2 * zeta2 * log2**2 - + 1 / 12 * log2**4 - ) - - -@nb.njit(cache=True) -def harmonic_Sm22(N, Sm31): - r""" - Analytic continuation of harmonic sum :math:`S_{-2,2}(N)` - as implemented in eq B.5.94 of :cite:`MuselliPhD` and eq 24 of cite:`Bl_mlein_2000`. - - Parameters - ---------- - N : complex - Mellin moment - Sm31: complex - Hamrmonic sum :math:`S_{-3,1}(N)` - Returns - ------- - Sm22 : complex - Harmonic sum :math:`S_{-2,2}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.g_functions.mellin_g5 : :math:`g_5(N)` - """ - return ( - (-1) ** N * gf.mellin_g5(N) - - 2 * Sm31 - + 2 * zeta2 * harmonic_Sm2(N) - + 3 / 40 * zeta2**2 - ) - - -@nb.njit(cache=True) -def harmonic_Sm211(N, Sm1): - r""" - Analytic continuation of harmonic sum :math:`S_{-2,1,1}(N)` - as implemented in eq B.5.104 of :cite:`MuselliPhD` and eq 27 of cite:`Bl_mlein_2000`. - - Parameters - ---------- - N : complex - Mellin moment - Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` - - Returns - ------- - Sm31 : complex - Harmonic sum :math:`S_{-2,1,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.g_functions.mellin_g8 : :math:`g_8(N)` - """ - return ( - -((-1) ** N) * gf.mellin_g8(N) - + zeta3 * Sm1 - - li4half - + 1 / 8 * zeta2**2 - + 1 / 8 * zeta3 * log2 - + 1 / 4 * zeta2 * log2**2 - - 1 / 24 * log2**4 - ) - - -@nb.njit(cache=True) -def harmonic_Sm2m1(N, S1, S2, Sm2): - r""" - Analytic continuation of harmonic sum :math:`S_{-2,-1}(N)` - as implemented in eq B.5.74 of :cite:`MuselliPhD` and eq 38 of cite:`Bl_mlein_2000`. - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` - - Returns - ------- - Sm2m1 : complex - Harmonic sum :math:`S_{-2,-1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.g_functions.mellin_g19 : :math:`g_19(N)` - """ - return -gf.mellin_g19(N, S1) + log2 * (S2 - Sm2) - 5 / 8 * zeta3 - - -@nb.njit(cache=True) -def harmonic_S211(N, S1, S2, S3): - r""" - Analytic continuation of harmonic sum :math:`S_{2,1,1}(N)` - as implemented in eq B.5.115 of :cite:`MuselliPhD` and eq 40 of cite:`Bl_mlein_2000`. - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - S3: complex - Hamrmonic sum :math:`S_{3}(N)` - - Returns - ------- - S211 : complex - Harmonic sum :math:`S_{2,1,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.g_functions.mellin_g21 : :math:`g_21(N)` - """ - return -gf.mellin_g21(N, S1, S2, S3) + 6 / 5 * zeta2**2 - - -@nb.njit(cache=True) -def harmonic_S31(N, S2, S4): - r""" - Analytic continuation of harmonic sum :math:`S_{3,1}(N)` - as implemented in eq B.5.99 of :cite:`MuselliPhD` and eq 41 of cite:`Bl_mlein_2000`. - - Parameters - ---------- - N : complex - Mellin moment - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - S4: complex - Hamrmonic sum :math:`S_{4}(N)` - - Returns - ------- - S31 : complex - Harmonic sum :math:`S_{3,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.g_functions.mellin_g22 : :math:`g_22(N)` - """ - return ( - 1 / 2 * gf.mellin_g22(N) - - 1 / 4 * S4 - - 1 / 4 * S2**2 - + zeta2 * S2 - - 3 / 20 * zeta2**2 - ) - - -@nb.njit(cache=True) -def harmonic_S41(N, S1, S2, S3): - r""" - Analytic continuation of harmonic sum :math:`S_{4,1}(N)` - as implemented in eq 9.1 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - S3: complex - Hamrmonic sum :math:`S_{3}(N)` - - Returns - ------- - S41 : complex - Harmonic sum :math:`S_{4,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F9 : - :math:`\mathcal{M}[(\text{Li}_4(x)/(x-1))_{+}](N)` - """ - return -f.F9(N, S1) + S1 * zeta4 - S2 * zeta3 + S3 * zeta2 - - -@nb.njit(cache=True) -def harmonic_S311(N, S1, S2): - r""" - Analytic continuation of harmonic sum :math:`S_{3,1,1}(N)` - as implemented in eq 9.21 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - - Returns - ------- - S311 : complex - Harmonic sum :math:`S_{3,1,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F11 : - :math:`\mathcal{M}[(\text{S}_{2,2}(x)/(x-1))_{+}](N)` - """ - return f.F11(N, S1, S2) + zeta3 * S2 - zeta4 / 4 * S1 - - -@nb.njit(cache=True) -def harmonic_S221(N, S1, S2, S21): - r""" - Analytic continuation of harmonic sum :math:`S_{2,2,1}(N)` - as implemented in eq 9.23 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - S21: complex - Hamrmonic sum :math:`S_{2,1}(N)` - - Returns - ------- - S221 : complex - Harmonic sum :math:`S_{2,2,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F11 : - :math:`\mathcal{M}[(\text{S}_{2,2}(x)/(x-1))_{+}](N)` - eko.matching_conditions.n3lo.f_functions.F13 : - :math:`\mathcal{M}[(\text{Li}_{2}^2(x)/(x-1))_{+}](N)` - """ - return ( - -2 * f.F11(N, S1, S2) - + 1 / 2 * f.F13(N, S1, S2) - + zeta2 * S21 - - 3 / 10 * zeta2**2 * S1 - ) - - -@nb.njit(cache=True) -def harmonic_Sm221(N, S1, Sm1, S21, Sm21): - r""" - Analytic continuation of harmonic sum :math:`S_{-2,2,1}(N)` - as implemented in eq 9.25 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` - S21: complex - Hamrmonic sum :math:`S_{2,1}(N)` - Sm21: complex - Hamrmonic sum :math:`S_{-2,1}(N)` - - Returns - ------- - Sm221 : complex - Harmonic sum :math:`S_{-2,2,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F14F12 : - :math:`\mathcal{M}[(2 \text{S}_{2,2}(x) - 1/2 \text{Li}_{2}^2(x))/(x+1)](N)` - """ - return ( - (-1) ** (N + 1) * (f.F14F12(N, S1, S21)) - + zeta2 * Sm21 - - 3 / 10 * zeta2**2 * Sm1 - - 0.119102 - + 0.0251709 - ) - - -@nb.njit(cache=True) -def harmonic_S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1): - r""" - Analytic continuation of harmonic sum :math:`S_{2,1,-2}(N)` - as implemented in eq 9.26 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` - Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` - Sm3: complex - Hamrmonic sum :math:`S_{-3}(N)` - S21: complex - Hamrmonic sum :math:`S_{2,1}(N)` - Sm21: complex - Hamrmonic sum :math:`S_{-2,1}(N)` - S2m1: complex - Hamrmonic sum :math:`S_{2,-1}(N)` - - Returns - ------- - S21m2 : complex - Harmonic sum :math:`S_{2,1,-2}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F14F12 : - :math:`\mathcal{M}[ - (\text{ln}(x) \text{S}_{1,2}(−x) − \text{Li}_2^2(−x)/2)/(x+1) - ](N)` - """ - return ( - (-1) ** (N) * f.F16(N, S1, Sm1, Sm2, Sm3, Sm21) - - 1 / 2 * zeta2 * (S21 - S2m1) - - (1 / 8 * zeta3 - 1 / 2 * zeta2 * log2) * (S2 - Sm2) - + 1 / 8 * zeta2**2 * Sm1 - + 0.0854806 - ) - - -@nb.njit(cache=True) -def harmonic_S2111(N, S1, S2, S3): - r""" - Analytic continuation of harmonic sum :math:`S_{2,1,1,1}(N)` - as implemented in eq 9.33 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - S3: complex - Hamrmonic sum :math:`S_{3}(N)` - - Returns - ------- - S2111 : complex - Harmonic sum :math:`S_{2,1,1,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F17 : - :math:`\mathcal{M}[(\text{S}_{1,3}(x)/(x-1))_{+}](N)` - """ - return -f.F17(N, S1, S2, S3) + zeta4 * S1 - - -@nb.njit(cache=True) -def harmonic_Sm2111(N, S1, S2, S3, Sm1): - r""" - Analytic continuation of harmonic sum :math:`S_{-2,1,1,1}(N)` - as implemented in eq 9.34 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - S3: complex - Hamrmonic sum :math:`S_{3}(N)` - Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` - - Returns - ------- - Sm2111 : complex - Harmonic sum :math:`S_{-2,1,1,1}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F18 : - :math:`\mathcal{M}[\text{S}_{1,3}(x)/(x+1)](N)` - """ - return ( - (-1) ** (N + 1) * f.F18(N, S1, S2, S3) - + zeta4 * Sm1 - - 0.706186 - + 0.693147 * zeta4 - ) - - -@nb.njit(cache=True) -def harmonic_S23(N, S1, S2, S3): - r""" - Analytic continuation of harmonic sum :math:`S_{2,3}(N)` - as implemented in eq 9.3 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - S1: complex - Hamrmonic sum :math:`S_{1}(N)` - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - S3: complex - Hamrmonic sum :math:`S_{3}(N)` - - Returns - ------- - S23 : complex - Harmonic sum :math:`S_{2,3}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F19 : - :math:`\mathcal{M}[ - (( - \text{ln}(x)[\text{S}_{1,2}(1-x) - \zeta_3] - +3 [\text{S}_{1,3}(1-x) - \zeta_4] - /(x-1))_{+}](N)` - """ - return f.F19(N, S1, S2, S3) + 3 * zeta4 * S1 - - -@nb.njit(cache=True) -def harmonic_Sm23(N, Sm1, Sm2, Sm3): - r""" - Analytic continuation of harmonic sum :math:`S_{-2,3}(N)` - as implemented in eq 9.4 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` - Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` - Sm3: complex - Hamrmonic sum :math:`S_{-3}(N)` - - Returns - ------- - Sm23 : complex - Harmonic sum :math:`S_{-2,3}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F19 : - :math:`\mathcal{M}[ - ( - \text{ln}(x)[\text{S}_{1,2}(1-x) - \zeta_3] - +3 [\text{S}_{1,3}(1-x) - \zeta_4] - /(x+1)](N)` - """ - return ( - (-1) ** N * f.F20(N, Sm1, Sm2, Sm3) - + 3 * zeta4 * Sm1 - + 21 / 32 * zeta5 - + 3 * zeta4 * log2 - - 3 / 4 * zeta2 * zeta3 - ) - - -@nb.njit(cache=True) -def harmonic_S2m3(N, S2, Sm1, Sm2, Sm3): - r""" - Analytic continuation of harmonic sum :math:`S_{2,-3}(N)` - as implemented in eq 9.5 of cite:` Bl_mlein_2009` - - Parameters - ---------- - N : complex - Mellin moment - S2: complex - Hamrmonic sum :math:`S_{2}(N)` - Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` - Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` - Sm3: complex - Hamrmonic sum :math:`S_{-3}(N)` - - Returns - ------- - S2m3 : complex - Harmonic sum :math:`S_{2,-3}(N)` - - See Also - -------- - eko.matching_conditions.n3lo.f_functions.F19 : - :math:`\mathcal{M}[ - (( - 1/2 \text{ln}^2(x) \text{Li}_2(-x) - -2 \text{ln}(x) \text{Li}_3(-x) - +3 \text{Li}_4(-x) - )/(x-1)](N)` - """ - return ( - (-1) ** (N + 1) * f.F21(N, Sm1, Sm2, Sm3) - + 3 / 4 * zeta3 * (Sm2 - S2) - - 21 / 8 * zeta4 * Sm1 - - 1.32056 - ) diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index 2ec0fae4c..c9a97955f 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -11,10 +11,10 @@ import numpy as np from .. import basis_rotation as br +from .. import harmonics from ..anomalous_dimensions import harmonics from ..evolution_operator import Operator, QuadKerBase from . import as1, as2, as3 -from .as3 import s_functions logger = logging.getLogger(__name__) @@ -24,11 +24,11 @@ def get_smx(n): """Get the S-minus cache""" return np.array( [ - s_functions.harmonic_Sm1(n), - s_functions.harmonic_Sm2(n), - s_functions.harmonic_Sm3(n), - s_functions.harmonic_Sm4(n), - s_functions.harmonic_Sm5(n), + harmonics.Sm1(n), + harmonics.Sm2(n), + harmonics.Sm3(n), + harmonics.Sm4(n), + harmonics.Sm5(n), ] ) @@ -38,10 +38,10 @@ def get_s3x(n, sx, smx): """Get the S-w3 cache""" return np.array( [ - s_functions.harmonic_S21(n, sx[0], sx[1]), - s_functions.harmonic_S2m1(n, sx[1], smx[0], smx[1]), - s_functions.harmonic_Sm21(n, smx[0]), - s_functions.harmonic_Sm2m1(n, sx[0], sx[1], smx[1]), + harmonics.S21(n, sx[0], sx[1]), + harmonics.S2m1(n, sx[1], smx[0], smx[1]), + harmonics.Sm21(n, smx[0]), + harmonics.Sm2m1(n, sx[0], sx[1], smx[1]), ] ) @@ -49,14 +49,14 @@ def get_s3x(n, sx, smx): @nb.njit(cache=True) def get_s4x(n, sx, smx): """Get the S-w4 cache""" - Sm31 = s_functions.harmonic_Sm31(n, smx[0], smx[1]) + Sm31 = harmonics.Sm31(n, smx[0], smx[1]) return np.array( [ - s_functions.harmonic_S31(n, sx[1], sx[3]), - s_functions.harmonic_S211(n, sx[0], sx[1], sx[2]), - s_functions.harmonic_Sm22(n, Sm31), - s_functions.harmonic_Sm211(n, smx[0]), - s_functions.harmonic_Sm31(n, smx[0], smx[1]), + harmonics.S31(n, sx[1], sx[3]), + harmonics.S211(n, sx[0], sx[1], sx[2]), + harmonics.Sm22(n, smx[1], Sm31), + harmonics.Sm211(n, smx[0]), + harmonics.Sm31(n, smx[0], smx[1]), ] ) @@ -243,14 +243,12 @@ def quad_ker( # compute the harmonics sx = np.zeros(3, np.complex_) if order >= 1: - sx = np.array( - [harmonics.harmonic_S1(ker_base.n), harmonics.harmonic_S2(ker_base.n)] - ) + sx = np.array([harmonics.S1(ker_base.n), harmonics.S2(ker_base.n)]) if order >= 2: - sx = np.append(sx, harmonics.harmonic_S3(ker_base.n)) + sx = np.append(sx, harmonics.S3(ker_base.n)) if order >= 3: - sx = np.append(sx, harmonics.harmonic_S4(ker_base.n)) - sx = np.append(sx, harmonics.harmonic_S5(ker_base.n)) + sx = np.append(sx, harmonics.S4(ker_base.n)) + sx = np.append(sx, harmonics.S5(ker_base.n)) smx = get_smx(ker_base.n) sx = np.append(sx, smx) sx = np.append(sx, get_s3x(ker_base.n, sx, smx)) From 1611c510017fedfb2e51ce0cce21a35588248961 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Tue, 29 Mar 2022 17:17:20 +0200 Subject: [PATCH 02/47] update tests accordingly --- tests/eko/conftest.py | 10 +- tests/eko/test_ad.py | 2 +- tests/eko/test_ad_lo.py | 10 +- tests/eko/test_ad_nlo.py | 18 +-- tests/eko/test_ad_nnlo.py | 10 +- tests/eko/test_beta.py | 2 +- tests/eko/test_f_functions.py | 107 +++++++++--------- tests/eko/test_g_functions.py | 69 ++++++----- tests/eko/test_matching_nnlo.py | 4 +- tests/eko/test_ome.py | 47 ++++---- ...test_ad_harmonics.py => test_polygamma.py} | 34 +----- tests/eko/test_s_functions.py | 34 ++++-- 12 files changed, 171 insertions(+), 176 deletions(-) rename tests/eko/{test_ad_harmonics.py => test_polygamma.py} (75%) diff --git a/tests/eko/conftest.py b/tests/eko/conftest.py index 68729098b..feb767351 100644 --- a/tests/eko/conftest.py +++ b/tests/eko/conftest.py @@ -11,11 +11,11 @@ def wrapped(N): """Collect the S-cache""" sx = np.array( [ - harmonics.harmonic_S1(N), - harmonics.harmonic_S2(N), - harmonics.harmonic_S3(N), - harmonics.harmonic_S4(N), - harmonics.harmonic_S5(N), + harmonics.S1(N), + harmonics.S2(N), + harmonics.S3(N), + harmonics.S4(N), + harmonics.S5(N), ] ) return sx diff --git a/tests/eko/test_ad.py b/tests/eko/test_ad.py index 2627decd5..45947406f 100644 --- a/tests/eko/test_ad.py +++ b/tests/eko/test_ad.py @@ -13,7 +13,7 @@ def test_eigensystem_gamma_singlet_0_values(): n = 3 - s1 = harmonics.harmonic_S1(n) + s1 = harmonics.S1(n) gamma_S_0 = ad_as1.gamma_singlet(3, s1, NF) res = ad.exp_singlet(gamma_S_0) lambda_p = complex(12.273612971466964, 0) diff --git a/tests/eko/test_ad_lo.py b/tests/eko/test_ad_lo.py index d08e79e32..52779123a 100644 --- a/tests/eko/test_ad_lo.py +++ b/tests/eko/test_ad_lo.py @@ -4,7 +4,7 @@ import eko.anomalous_dimensions.aem1 as ad_aem1 import eko.anomalous_dimensions.as1 as ad_as1 -from eko.anomalous_dimensions import harmonics +from eko import harmonics NF = 5 @@ -12,14 +12,14 @@ def test_number_conservation(): # number N = complex(1.0, 0.0) - s1 = harmonics.harmonic_S1(N) + s1 = harmonics.S1(N) np.testing.assert_almost_equal(ad_as1.gamma_ns(N, s1), 0) def test_quark_momentum_conservation(): # quark momentum N = complex(2.0, 0.0) - s1 = harmonics.harmonic_S1(N) + s1 = harmonics.S1(N) np.testing.assert_almost_equal( ad_as1.gamma_ns(N, s1) + ad_as1.gamma_gq(N), 0, @@ -33,7 +33,7 @@ def test_quark_momentum_conservation(): def test_gluon_momentum_conservation(): # gluon momentum N = complex(2.0, 0.0) - s1 = harmonics.harmonic_S1(N) + s1 = harmonics.S1(N) np.testing.assert_almost_equal( ad_as1.gamma_qg(N, NF) + ad_as1.gamma_gg(N, s1, NF), 0 ) @@ -59,7 +59,7 @@ def test_gamma_gq_0(): def test_gamma_gg_0(): N = complex(0.0, 1.0) - s1 = harmonics.harmonic_S1(N) + s1 = harmonics.S1(N) res = complex(5.195725159621, 10.52008856962) np.testing.assert_almost_equal(ad_as1.gamma_gg(N, s1, NF), res) diff --git a/tests/eko/test_ad_nlo.py b/tests/eko/test_ad_nlo.py index 23a541fae..10abde6de 100644 --- a/tests/eko/test_ad_nlo.py +++ b/tests/eko/test_ad_nlo.py @@ -3,7 +3,7 @@ import numpy as np import eko.anomalous_dimensions.as2 as ad_as2 -import eko.anomalous_dimensions.harmonics as h +import eko.harmonics as h from eko import constants as const NF = 5 @@ -41,8 +41,10 @@ def test_gamma_1(): np.testing.assert_allclose( ad_as2.gamma_nsm(2, NF), ( - (34.0 / 27.0 * (-47.0 + 6 * np.pi**2) - 16.0 * h.zeta3) * const.CF - + (373.0 / 9.0 - 34.0 * np.pi**2 / 9.0 + 8.0 * h.zeta3) * const.CA + (34.0 / 27.0 * (-47.0 + 6 * np.pi**2) - 16.0 * h.constants.zeta3) + * const.CF + + (373.0 / 9.0 - 34.0 * np.pi**2 / 9.0 + 8.0 * h.constants.zeta3) + * const.CA - 64.0 * NF / 27.0 ) * const.CF, @@ -50,8 +52,10 @@ def test_gamma_1(): np.testing.assert_allclose( ad_as2.gamma_nsp(3, NF), ( - (-34487.0 / 432.0 + 86.0 * np.pi**2 / 9.0 - 16.0 * h.zeta3) * const.CF - + (459.0 / 8.0 - 43.0 * np.pi**2 / 9.0 + 8.0 * h.zeta3) * const.CA + (-34487.0 / 432.0 + 86.0 * np.pi**2 / 9.0 - 16.0 * h.constants.zeta3) + * const.CF + + (459.0 / 8.0 - 43.0 * np.pi**2 / 9.0 + 8.0 * h.constants.zeta3) + * const.CA - 415.0 * NF / 108.0 ) * const.CF, @@ -70,7 +74,7 @@ def test_gamma_1(): np.testing.assert_allclose( gS1[1, 1], ( - (-79909.0 / 3375.0 + 194.0 * np.pi**2 / 45.0 - 8.0 * h.zeta3) + (-79909.0 / 3375.0 + 194.0 * np.pi**2 / 45.0 - 8.0 * h.constants.zeta3) * const.CA**2 - 967.0 / 270.0 * const.CA * NF + 541.0 / 216.0 * const.CF * NF @@ -98,7 +102,7 @@ def test_gamma_1(): np.testing.assert_allclose( gS1[1, 1], ( - (-79909.0 / 3375.0 + 194.0 * np.pi**2 / 45.0 - 8.0 * h.zeta3) + (-79909.0 / 3375.0 + 194.0 * np.pi**2 / 45.0 - 8.0 * h.constants.zeta3) * const.CA**2 - 967.0 / 270.0 * const.CA * NF + 541.0 / 216.0 * const.CF * NF diff --git a/tests/eko/test_ad_nnlo.py b/tests/eko/test_ad_nnlo.py index 58381478a..736064be5 100644 --- a/tests/eko/test_ad_nnlo.py +++ b/tests/eko/test_ad_nnlo.py @@ -3,7 +3,7 @@ import numpy as np import eko.anomalous_dimensions.as3 as ad_as3 -from eko.anomalous_dimensions import harmonics +from eko import harmonics NF = 5 @@ -12,10 +12,10 @@ def get_sx(N): """Collect the S-cache""" sx = np.array( [ - harmonics.harmonic_S1(N), - harmonics.harmonic_S2(N), - harmonics.harmonic_S3(N), - harmonics.harmonic_S4(N), + harmonics.S1(N), + harmonics.S2(N), + harmonics.S3(N), + harmonics.S4(N), ] ) return sx diff --git a/tests/eko/test_beta.py b/tests/eko/test_beta.py index b6c61c167..45d9bd37f 100644 --- a/tests/eko/test_beta.py +++ b/tests/eko/test_beta.py @@ -7,7 +7,7 @@ import pytest from eko import beta -from eko.anomalous_dimensions.harmonics import zeta3 +from eko.harmonics.constants import zeta3 def _flav_test(function): diff --git a/tests/eko/test_f_functions.py b/tests/eko/test_f_functions.py index 8485f9bd0..37a0764c2 100644 --- a/tests/eko/test_f_functions.py +++ b/tests/eko/test_f_functions.py @@ -3,13 +3,12 @@ import numpy as np -import eko.matching_conditions.as3.s_functions as sf -from eko.anomalous_dimensions import harmonics +from eko import harmonics -zeta2 = harmonics.zeta2 -zeta3 = harmonics.zeta3 -zeta4 = harmonics.zeta4 -zeta5 = harmonics.zeta5 +zeta2 = harmonics.constants.zeta2 +zeta3 = harmonics.constants.zeta3 +zeta4 = harmonics.constants.zeta4 +zeta5 = harmonics.constants.zeta5 log2 = np.log(2) # reference values coming fom mathematica @@ -58,101 +57,101 @@ # F19, F20,F21 are not present in that paper. def test_F9(): for N, vals in zip(testN, refvals["S41"]): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - S3 = harmonics.harmonic_S3(N) - S41 = sf.harmonic_S41(N, S1, S2, S3) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + S3 = harmonics.S3(N) + S41 = harmonics.S41(N, S1, S2, S3) np.testing.assert_allclose(S41, vals, atol=1e-05) def test_F11(): for N, vals in zip(testN, refvals["S311"]): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - S311 = sf.harmonic_S311(N, S1, S2) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + S311 = harmonics.S311(N, S1, S2) np.testing.assert_allclose(S311, vals, atol=1e-05) def test_F13(): for N, vals in zip(testN, refvals["S221"]): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - S21 = sf.harmonic_S21(N, S1, S2) - S221 = sf.harmonic_S221(N, S1, S2, S21) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + S21 = harmonics.S21(N, S1, S2) + S221 = harmonics.S221(N, S1, S2, S21) np.testing.assert_allclose(S221, vals, atol=1e-05) def test_F12_F14(): # here there is a typo in eq (9.25) of Bl_mlein_2009 for N, vals in zip(testN, refvals["Sm221"]): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - Sm1 = sf.harmonic_Sm1(N) - S21 = sf.harmonic_S21(N, S1, S2) - Sm21 = sf.harmonic_Sm21(N, Sm1) - Sm221 = sf.harmonic_Sm221(N, S1, Sm1, S21, Sm21) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + Sm1 = harmonics.Sm1(N) + S21 = harmonics.S21(N, S1, S2) + Sm21 = harmonics.Sm21(N, Sm1) + Sm221 = harmonics.Sm221(N, S1, Sm1, S21, Sm21) np.testing.assert_allclose(Sm221, vals, atol=1e-05) def test_F16(): for N, vals in zip(testN, refvals["S21m2"]): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - Sm1 = sf.harmonic_Sm1(N) - Sm2 = sf.harmonic_Sm2(N) - Sm3 = sf.harmonic_Sm3(N) - S21 = sf.harmonic_S21(N, S1, S2) - S2m1 = sf.harmonic_S2m1(N, S2, Sm1, Sm2) - Sm21 = sf.harmonic_Sm21(N, Sm1) - S21m2 = sf.harmonic_S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + Sm1 = harmonics.Sm1(N) + Sm2 = harmonics.Sm2(N) + Sm3 = harmonics.Sm3(N) + S21 = harmonics.S21(N, S1, S2) + S2m1 = harmonics.S2m1(N, S2, Sm1, Sm2) + Sm21 = harmonics.Sm21(N, Sm1) + S21m2 = harmonics.S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1) np.testing.assert_allclose(S21m2, vals, atol=1e-04) def test_F17(): for N, vals in zip(testN, refvals["S2111"]): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - S3 = harmonics.harmonic_S3(N) - S2111 = sf.harmonic_S2111(N, S1, S2, S3) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + S3 = harmonics.S3(N) + S2111 = harmonics.S2111(N, S1, S2, S3) np.testing.assert_allclose(S2111, vals, atol=1e-05) def test_F18(): for N, vals in zip(testN, refvals["Sm2111"]): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - S3 = harmonics.harmonic_S3(N) - Sm1 = sf.harmonic_Sm1(N) - Sm2111 = sf.harmonic_Sm2111(N, S1, S2, S3, Sm1) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + S3 = harmonics.S3(N) + Sm1 = harmonics.Sm1(N) + Sm2111 = harmonics.Sm2111(N, S1, S2, S3, Sm1) np.testing.assert_allclose(Sm2111, vals, atol=1e-05) # different parametrization, less accurate def test_F19(): for N, vals in zip(testN, refvals["S23"]): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - S3 = harmonics.harmonic_S3(N) - S23 = sf.harmonic_S23(N, S1, S2, S3) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + S3 = harmonics.S3(N) + S23 = harmonics.S23(N, S1, S2, S3) np.testing.assert_allclose(S23, vals, rtol=2e-03) # different parametrization, less accurate def test_F20(): for N, vals in zip(testN, refvals["Sm23"]): - Sm3 = sf.harmonic_Sm3(N) - Sm2 = sf.harmonic_Sm2(N) - Sm1 = sf.harmonic_Sm1(N) - Sm23 = sf.harmonic_Sm23(N, Sm1, Sm2, Sm3) + Sm3 = harmonics.Sm3(N) + Sm2 = harmonics.Sm2(N) + Sm1 = harmonics.Sm1(N) + Sm23 = harmonics.Sm23(N, Sm1, Sm2, Sm3) np.testing.assert_allclose(Sm23, vals, rtol=1e-03) # different parametrization, less accurate def test_F21(): for N, vals in zip(testN, refvals["S2m3"]): - Sm3 = sf.harmonic_Sm3(N) - Sm2 = sf.harmonic_Sm2(N) - Sm1 = sf.harmonic_Sm1(N) - S2 = harmonics.harmonic_S2(N) - S2m3 = sf.harmonic_S2m3(N, S2, Sm1, Sm2, Sm3) + Sm3 = harmonics.Sm3(N) + Sm2 = harmonics.Sm2(N) + Sm1 = harmonics.Sm1(N) + S2 = harmonics.S2(N) + S2m3 = harmonics.S2m3(N, S2, Sm1, Sm2, Sm3) np.testing.assert_allclose(S2m3, vals, rtol=1e-03) diff --git a/tests/eko/test_g_functions.py b/tests/eko/test_g_functions.py index ce9a4ccff..bb030f401 100644 --- a/tests/eko/test_g_functions.py +++ b/tests/eko/test_g_functions.py @@ -3,51 +3,58 @@ import numpy as np -import eko.matching_conditions.as3.s_functions as sf +import eko.harmonics as sf from eko.anomalous_dimensions import harmonics -zeta3 = harmonics.zeta3 -log2 = np.log(2) +zeta3 = harmonics.constants.zeta3 +log2 = harmonics.constants.log2 testN = [1, 10, 100] - # compare the exact values of some harmonics with Muselli parametrization +def test_g3(): + ns = [1.0, 2.0, 1 + 1j] + # NIntegrate[x^({1, 2, 1 + I} - 1) PolyLog[2, x]/(1 + x), {x, 0, 1}] + mma_ref_values = [0.3888958462, 0.2560382207, 0.3049381491 - 0.1589060625j] + for n, r in zip(ns, mma_ref_values): + np.testing.assert_almost_equal(sf.g_functions.mellin_g3(n), r, decimal=6) + + def test_g4(): refvals = [-1, -1.34359, -1.40286] for N, vals in zip(testN, refvals): - S2 = harmonics.harmonic_S2(N) - Sm1 = sf.harmonic_Sm1(N) - Sm2 = sf.harmonic_Sm2(N) - S2m1 = sf.harmonic_S2m1(N, S2, Sm1, Sm2) + S2 = harmonics.S2(N) + Sm1 = sf.Sm1(N) + Sm2 = sf.Sm2(N) + S2m1 = sf.S2m1(N, S2, Sm1, Sm2) np.testing.assert_allclose(S2m1, vals, atol=1e-05) def test_g6(): refvals = [-1, -0.857976, -0.859245] for N, vals in zip(testN, refvals): - Sm1 = sf.harmonic_Sm1(N) - Sm2 = sf.harmonic_Sm2(N) - Sm31 = sf.harmonic_Sm31(N, Sm1, Sm2) + Sm1 = sf.Sm1(N) + Sm2 = sf.Sm2(N) + Sm31 = sf.Sm31(N, Sm1, Sm2) np.testing.assert_allclose(Sm31, vals, atol=1e-05) def test_g5(): refvals = [-1, -0.777375, -0.784297] for N, vals in zip(testN, refvals): - Sm1 = sf.harmonic_Sm1(N) - Sm2 = sf.harmonic_Sm2(N) - Sm31 = sf.harmonic_Sm31(N, Sm1, Sm2) - Sm22 = sf.harmonic_Sm22(N, Sm31) + Sm1 = sf.Sm1(N) + Sm2 = sf.Sm2(N) + Sm31 = sf.Sm31(N, Sm1, Sm2) + Sm22 = sf.Sm22(N, Sm2, Sm31) np.testing.assert_allclose(Sm22, vals, atol=1e-05) def test_g8(): refvals = [-1, -0.696836, -0.719637] for N, vals in zip(testN, refvals): - Sm1 = sf.harmonic_Sm1(N) - Sm211 = sf.harmonic_Sm211(N, Sm1) + Sm1 = sf.Sm1(N) + Sm211 = sf.Sm211(N, Sm1) np.testing.assert_allclose(Sm211, vals, atol=1e-05) @@ -55,19 +62,19 @@ def test_g18(): testN = [1, 2, 3, 10, 100] refvals = [1, 1.375, 1.5787, 2.0279, 2.34252] for N, vals in zip(testN, refvals): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - S21 = sf.harmonic_S21(N, S1, S2) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + S21 = sf.S21(N, S1, S2) np.testing.assert_allclose(S21, vals, atol=1e-05) def test_g19(): refvals = [1, 0.953673, 0.958928] for N, vals in zip(testN, refvals): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - Sm2 = sf.harmonic_Sm2(N) - Sm2m1 = sf.harmonic_Sm2m1(N, S1, S2, Sm2) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + Sm2 = sf.Sm2(N) + Sm2m1 = sf.Sm2m1(N, S1, S2, Sm2) np.testing.assert_allclose(Sm2m1, vals, atol=1e-05) @@ -75,10 +82,10 @@ def test_g21(): testN = [1, 2, 3, 10, 100] refvals = [1, 1.4375, 1.69985, 2.38081, 3.04323] for N, vals in zip(testN, refvals): - S1 = harmonics.harmonic_S1(N) - S2 = harmonics.harmonic_S2(N) - S3 = harmonics.harmonic_S3(N) - S211 = sf.harmonic_S211(N, S1, S2, S3) + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + S3 = harmonics.S3(N) + S211 = sf.S211(N, S1, S2, S3) np.testing.assert_allclose(S211, vals, atol=1e-05) @@ -86,7 +93,7 @@ def test_g22(): testN = [1, 2, 3, 10, 100] refvals = [1, 1.1875, 1.2554, 1.33724, 1.35262] for N, vals in zip(testN, refvals): - S2 = harmonics.harmonic_S2(N) - S4 = harmonics.harmonic_S4(N) - S31 = sf.harmonic_S31(N, S2, S4) + S2 = harmonics.S2(N) + S4 = harmonics.S4(N) + S31 = sf.S31(N, S2, S4) np.testing.assert_allclose(S31, vals, atol=1e-05) diff --git a/tests/eko/test_matching_nnlo.py b/tests/eko/test_matching_nnlo.py index ce1dcfda0..17bb69d31 100644 --- a/tests/eko/test_matching_nnlo.py +++ b/tests/eko/test_matching_nnlo.py @@ -3,7 +3,7 @@ import numpy as np -from eko.anomalous_dimensions import harmonics +from eko.harmonics import constants from eko.matching_conditions.as2 import A_ns, A_qq_ns, A_singlet @@ -144,7 +144,7 @@ def test_Hg2_pegasus(get_sx): aS2 = A_singlet(N, sx, L) E2 = ( - 2.0 / N * (harmonics.zeta3 - S3 + 1.0 / N * (harmonics.zeta2 - S2 - S1 / N)) + 2.0 / N * (constants.zeta3 - S3 + 1.0 / N * (constants.zeta2 - S2 - S1 / N)) ) a_hg_param = ( diff --git a/tests/eko/test_ome.py b/tests/eko/test_ome.py index dc14e08e0..c3a3b58bb 100644 --- a/tests/eko/test_ome.py +++ b/tests/eko/test_ome.py @@ -5,17 +5,10 @@ import numpy as np from eko import basis_rotation as br +from eko import harmonics as sf from eko import interpolation, mellin -from eko.anomalous_dimensions.harmonics import ( - harmonic_S1, - harmonic_S2, - harmonic_S3, - harmonic_S4, - harmonic_S5, -) from eko.evolution_operator.grid import OperatorGrid from eko.interpolation import InterpolatorDispatcher -from eko.matching_conditions.as3 import s_functions as sf from eko.matching_conditions.operator_matrix_element import ( A_non_singlet, A_singlet, @@ -32,39 +25,39 @@ def test_HarmonicsCache(): N = np.random.rand() + 1.0j * np.random.rand() - Sm1 = sf.harmonic_Sm1(N) - Sm2 = sf.harmonic_Sm2(N) - S1 = harmonic_S1(N) - S2 = harmonic_S2(N) - S3 = harmonic_S3(N) - S4 = harmonic_S4(N) - sx = np.array([S1, S2, S3, S4, harmonic_S5(N)]) + Sm1 = sf.Sm1(N) + Sm2 = sf.Sm2(N) + S1 = sf.S1(N) + S2 = sf.S2(N) + S3 = sf.S3(N) + S4 = sf.S4(N) + sx = np.array([S1, S2, S3, S4, sf.S5(N)]) smx_test = np.array( [ Sm1, Sm2, - sf.harmonic_Sm3(N), - sf.harmonic_Sm4(N), - sf.harmonic_Sm5(N), + sf.Sm3(N), + sf.Sm4(N), + sf.Sm5(N), ] ) np.testing.assert_allclose(get_smx(N), smx_test) s3x_test = np.array( [ - sf.harmonic_S21(N, S1, S2), - sf.harmonic_S2m1(N, S2, Sm1, Sm2), - sf.harmonic_Sm21(N, Sm1), - sf.harmonic_Sm2m1(N, S1, S2, Sm2), + sf.S21(N, S1, S2), + sf.S2m1(N, S2, Sm1, Sm2), + sf.Sm21(N, Sm1), + sf.Sm2m1(N, S1, S2, Sm2), ] ) np.testing.assert_allclose(get_s3x(N, sx, smx_test), s3x_test) - Sm31 = sf.harmonic_Sm31(N, Sm1, Sm2) + Sm31 = sf.Sm31(N, Sm1, Sm2) s4x_test = np.array( [ - sf.harmonic_S31(N, S2, S4), - sf.harmonic_S211(N, S1, S2, S3), - sf.harmonic_Sm22(N, Sm31), - sf.harmonic_Sm211(N, Sm1), + sf.S31(N, S2, S4), + sf.S211(N, S1, S2, S3), + sf.Sm22(N, Sm2, Sm31), + sf.Sm211(N, Sm1), Sm31, ] ) diff --git a/tests/eko/test_ad_harmonics.py b/tests/eko/test_polygamma.py similarity index 75% rename from tests/eko/test_ad_harmonics.py rename to tests/eko/test_polygamma.py index 34ef73401..d0dfa063a 100644 --- a/tests/eko/test_ad_harmonics.py +++ b/tests/eko/test_polygamma.py @@ -2,7 +2,7 @@ import numpy as np import pytest -from eko.anomalous_dimensions import harmonics +from eko import harmonics # until https://github.com/numba/numba/pull/5660 is confirmed # we need to deactivate numba prior running @@ -70,37 +70,11 @@ def test_cern_polygamma(): ] for nk, k in enumerate(ks): for nz, z in enumerate(zs): - me = harmonics.cern_polygamma(z, k) + me = harmonics.polygamma.cern_polygamma(z, k) ref = fortran_ref[nk][nz] np.testing.assert_almost_equal(me, ref) # errors with pytest.raises(NotImplementedError): - _ = harmonics.cern_polygamma(1, 5) + _ = harmonics.polygamma.cern_polygamma(1, 5) with pytest.raises(ValueError): - _ = harmonics.cern_polygamma(0, 0) - - -def test_harmonic_Sx(): - """test harmonic sums S_x on real axis""" - # test on real axis - def sx(n, m): - return np.sum([1 / k**m for k in range(1, n + 1)]) - - ls = [ - harmonics.harmonic_S1, - harmonics.harmonic_S2, - harmonics.harmonic_S3, - harmonics.harmonic_S4, - harmonics.harmonic_S5, - ] - for k in range(1, 5 + 1): - for n in range(1, 4 + 1): - np.testing.assert_almost_equal(ls[k - 1](n), sx(n, k)) - - -def test_melling_g3(): - ns = [1.0, 2.0, 1 + 1j] - # NIntegrate[x^({1, 2, 1 + I} - 1) PolyLog[2, x]/(1 + x), {x, 0, 1}] - mma_ref_values = [0.3888958462, 0.2560382207, 0.3049381491 - 0.1589060625j] - for n, r in zip(ns, mma_ref_values): - np.testing.assert_almost_equal(harmonics.mellin_g3(n), r, decimal=6) + _ = harmonics.polygamma.cern_polygamma(0, 0) diff --git a/tests/eko/test_s_functions.py b/tests/eko/test_s_functions.py index 2358757b6..e42b2ad02 100644 --- a/tests/eko/test_s_functions.py +++ b/tests/eko/test_s_functions.py @@ -3,7 +3,7 @@ import numpy as np -import eko.matching_conditions.as3.s_functions as sf +import eko.harmonics as sf # reference values coming fom mathematica testN = [1, 2, 2 + 2j, 10 + 5j, 100] @@ -43,18 +43,36 @@ def test_Sm21(): for N, vals in zip(testN, refvals["Sm21"]): - Sm1 = sf.harmonic_Sm1(N) - np.testing.assert_allclose(sf.harmonic_Sm21(N, Sm1), vals, atol=1e-06) + Sm1 = sf.Sm1(N) + np.testing.assert_allclose(sf.Sm21(N, Sm1), vals, atol=1e-06) def test_Smx(): for j, N in enumerate(testN): smx = [ - sf.harmonic_Sm1(N), - sf.harmonic_Sm2(N), - sf.harmonic_Sm3(N), - sf.harmonic_Sm4(N), - sf.harmonic_Sm5(N), + sf.Sm1(N), + sf.Sm2(N), + sf.Sm3(N), + sf.Sm4(N), + sf.Sm5(N), ] for i, sm in enumerate(smx): np.testing.assert_allclose(sm, refvals[f"Sm{i+1}"][j], atol=1e-06) + + +def test_Sx(): + """test harmonic sums S_x on real axis""" + # test on real axis + def sx(n, m): + return np.sum([1 / k**m for k in range(1, n + 1)]) + + ls = [ + sf.S1, + sf.S2, + sf.S3, + sf.S4, + sf.S5, + ] + for k in range(1, 5 + 1): + for n in range(1, 4 + 1): + np.testing.assert_almost_equal(ls[k - 1](n), sx(n, k)) From 5533c3ff5ba510545cbbc02a22a6475f75755edb Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Tue, 29 Mar 2022 17:18:01 +0200 Subject: [PATCH 03/47] other minor updates --- benchmarks/eko/benchmark_ad.py | 28 +++++++++++++++------------- doc/source/theory/Mellin.rst | 4 ++-- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/benchmarks/eko/benchmark_ad.py b/benchmarks/eko/benchmark_ad.py index 1087db0e0..7db70149e 100644 --- a/benchmarks/eko/benchmark_ad.py +++ b/benchmarks/eko/benchmark_ad.py @@ -4,7 +4,7 @@ import pytest import eko.anomalous_dimensions.as2 as ad_as2 -import eko.anomalous_dimensions.harmonics as h +import eko.harmonics as h from eko.constants import CA, CF, TR @@ -15,7 +15,7 @@ def benchmark_melling_g3_pegasus(): def check_melling_g3_pegasus(N): - S1 = h.harmonic_S1(N) + S1 = h.S1(N) N1 = N + 1.0 N2 = N + 2.0 N3 = N + 3.0 @@ -28,7 +28,7 @@ def check_melling_g3_pegasus(N): S14 = S13 + 1.0 / N4 S15 = S14 + 1.0 / N5 S16 = S15 + 1.0 / N6 - zeta2 = h.zeta2 + zeta2 = h.constants.zeta2 SPMOM = ( 1.0000 * (zeta2 - S1 / N) / N @@ -39,7 +39,7 @@ def check_melling_g3_pegasus(N): - 0.3174 * (zeta2 - S15 / N5) / N5 + 0.0699 * (zeta2 - S16 / N6) / N6 ) - np.testing.assert_allclose(h.mellin_g3(N), SPMOM) + np.testing.assert_allclose(h.g_functions.mellin_g3(N), SPMOM) @pytest.mark.isolated @@ -52,12 +52,12 @@ def benchmark_gamma_ns_1_pegasus(): def check_gamma_1_pegasus(N, NF): # Test against pegasus implementation - ZETA2 = h.zeta2 - ZETA3 = h.zeta3 + ZETA2 = h.constants.zeta2 + ZETA3 = h.constants.zeta3 # N = np.random.rand(1) + np.random.rand(1) * 1j - S1 = h.harmonic_S1(N) - S2 = h.harmonic_S2(N) + S1 = h.S1(N) + S2 = h.S2(N) N1 = N + 1.0 N2 = N + 2.0 @@ -87,16 +87,18 @@ def check_gamma_1_pegasus(N, NF): ) SLC = -5.0 / 8.0 * ZETA3 SLV = ( - -ZETA2 / 2.0 * (h.cern_polygamma(N1 / 2, 0) - h.cern_polygamma(N / 2, 0)) + -ZETA2 + / 2.0 + * (h.polygamma.cern_polygamma(N1 / 2, 0) - h.polygamma.cern_polygamma(N / 2, 0)) + S1 / NS + SPMOM ) SSCHLM = SLC - SLV - SSTR2M = ZETA2 - h.cern_polygamma(N1 / 2, 1) - SSTR3M = 0.5 * h.cern_polygamma(N1 / 2, 2) + ZETA3 + SSTR2M = ZETA2 - h.polygamma.cern_polygamma(N1 / 2, 1) + SSTR3M = 0.5 * h.polygamma.cern_polygamma(N1 / 2, 2) + ZETA3 SSCHLP = SLC + SLV - SSTR2P = ZETA2 - h.cern_polygamma(N2 / 2, 1) - SSTR3P = 0.5 * h.cern_polygamma(N2 / 2, 2) + ZETA3 + SSTR2P = ZETA2 - h.polygamma.cern_polygamma(N2 / 2, 1) + SSTR3P = 0.5 * h.polygamma.cern_polygamma(N2 / 2, 2) + ZETA3 PNMA = ( 16.0 * S1 * (2.0 * N + 1.0) / (NS * N1S) diff --git a/doc/source/theory/Mellin.rst b/doc/source/theory/Mellin.rst index 2c69e477a..55f1f49e9 100644 --- a/doc/source/theory/Mellin.rst +++ b/doc/source/theory/Mellin.rst @@ -123,7 +123,7 @@ the Mellin inverse. S_m(N) = \sum\limits_{j=1}^N \frac 1 {j^m} = \frac{(-1)^{m-1}}{(m-1)!} \psi_{m-1}(N+1)+c_m \quad \text{with}\, c_m = \left\{\begin{array}{ll} \gamma_E, & m=1\\ \zeta(m), & m>1\end{array} \right. -and where :math:`\psi_k(N)` is the :math:`k`-th polygamma function (implemented as :meth:`~eko.anomalous_dimensions.harmonics.cern_polygamma`) +and where :math:`\psi_k(N)` is the :math:`k`-th polygamma function (implemented as :meth:`~eko.harmonics.polygamma.cern_polygamma`) and :math:`\zeta` the Riemann zeta function (using :func:`scipy.special.zeta`). - for the sums :math:`S_{-m}(N)` and :math:`m > 0` we use :cite:`Gluck:1989ze` @@ -141,4 +141,4 @@ and with -1 elsewise. S_{-2,1}(N) &= - \frac 5 8 \zeta(3) + \zeta(2)\left(S_{-1}(N) - \frac{\eta}{N} + \log(2)\right) + \eta\left(\frac{S_{1}(N)}{N^2} + g_3(N)\right)\\ g_3(N) &= \mathcal M \left[\frac{\text{Li}_2(x)}{1+x}\right](N) -where for :math:`g_3(N)` we use the parametrization of :cite:`Vogt:2004ns` (implemented as :meth:`~eko.anomalous_dimensions.harmonics.mellin_g3`). +where for :math:`g_3(N)` we use the parametrization of :cite:`Vogt:2004ns` (implemented as :meth:`~eko.harmonics.g_functions.mellin_g3`). From fd01b7aa02fb6f697aadeda717cfbde8920807ae Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 11:55:53 +0200 Subject: [PATCH 04/47] first attempt for the harmoncs cache --- src/eko/harmonics/__init__.py | 89 +++++++++++++++++++ src/eko/matching_conditions/as1.py | 4 +- src/eko/matching_conditions/as2.py | 58 ++++++------ .../operator_matrix_element.py | 41 ++++----- tests/eko/test_matching_nlo.py | 15 ++-- tests/eko/test_matching_nnlo.py | 35 ++++---- 6 files changed, 159 insertions(+), 83 deletions(-) diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index 530aec2b3..d73e6a142 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -3,9 +3,98 @@ This module contains some harmonics sum. Defintion are coming from :cite:`MuselliPhD,Bl_mlein_2000,Blumlein:2009ta` """ +import numba as nb +import numpy as np from .w1 import S1, Sm1 from .w2 import S2, Sm2 from .w3 import S3, S21, S2m1, Sm2m1, Sm3, Sm21 from .w4 import S4, S31, S211, Sm4, Sm22, Sm31, Sm211 from .w5 import S5, S23, S41, S221, S311, S2111, S2m3, S21m2, Sm5, Sm23, Sm221, Sm2111 + + +@nb.njit(cache=True) +def base_harmonics_cache(n, max_weight=5, n_max_sums_weight=7): + """ + Get the harmonics sums S basic cache. + Only single index harmonics are computed and stored + in the first (:math:`S_{n}`) or in the last column (:math:`S_{-n}`) + + Parameters + ---------- + n : complex + Mellin moment + max_weight : int + max harmonics weight, max value 5 (default) + Retruns + ------- + h_cache : np.ndarray + list of harmonics sums: + (weights, n_max_sums_weight) + """ + h_cache = np.zeros((max_weight, n_max_sums_weight), np.complex_) + h_cache[:, 0] = get_sx(n, max_weight) + if n_max_sums_weight > 1: + h_cache[:, -1] = get_smx(n, max_weight) + return h_cache + + +@nb.njit(cache=True) +def get_sx(n, max_weight=5): + """ + Get the harmonics sums S cache + + Parameters + ---------- + n : complex + Mellin moment + max_weight : int + max harmonics weight, max value 5 (default) + Retruns + ------- + sx : np.ndarray + list of harmonics sums (:math:`S_{1,..,w}`) + """ + sx = np.zeros(max_weight, np.complex_) + if max_weight >= 1: + sx[0] = S1(n) + if max_weight >= 2: + sx[1] = S2(n) + if max_weight >= 3: + sx[2] = S3(n) + if max_weight >= 4: + sx[3] = S4(n) + if max_weight >= 5: + sx[4] = S5(n) + return sx + + +@nb.njit(cache=True) +def get_smx(n, max_weight=5): + """ + Get the harmonics S-minus cache + + Parameters + ---------- + n : complex + Mellin moment + max_weight : int + max harmonics weight, max value 5 (default) + + Retruns + ------- + smx : np.ndarray + list of harmonics sums (:math:`S_{-1,..,-w}`) + """ + smx = np.zeros(max_weight, np.complex_) + if max_weight >= 1: + smx[0] = Sm1(n) + if max_weight >= 2: + smx[1] = Sm2(n) + if max_weight >= 3: + smx[2] = Sm3(n) + if max_weight >= 4: + smx[3] = Sm4(n) + if max_weight >= 5: + smx[4] = Sm5(n) + return smx diff --git a/src/eko/matching_conditions/as1.py b/src/eko/matching_conditions/as1.py index f76a3be38..e56c22322 100644 --- a/src/eko/matching_conditions/as1.py +++ b/src/eko/matching_conditions/as1.py @@ -24,7 +24,7 @@ def A_hh(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + List of harmonic sums: :math:`S_{1},S_{2}` L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -131,6 +131,8 @@ def A_singlet(n, sx, L): ---------- n : complex Mellin moment + sx : numpy.ndarray + List of harmonic sums L : float :math:`\ln(\mu_F^2 / m_h^2)` diff --git a/src/eko/matching_conditions/as2.py b/src/eko/matching_conditions/as2.py index deb526344..04730f491 100644 --- a/src/eko/matching_conditions/as2.py +++ b/src/eko/matching_conditions/as2.py @@ -12,8 +12,8 @@ import numba as nb import numpy as np -from .. import constants, harmonics -from ..harmonics.constants import log2, zeta2, zeta3 +from .. import constants +from ..harmonics.constants import zeta2, zeta3 from .as1 import A_gg as A_gg_1 from .as1 import A_hg as A_hg_1 @@ -29,7 +29,7 @@ def A_qq_ns(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -74,7 +74,7 @@ def A_qq_ns(n, sx, L): @nb.njit(cache=True) -def A_hq_ps(n, sx, L): +def A_hq_ps(n, S2, L): r""" |NNLO| heavy-light pure-singlet |OME| :math:`A_{Hq}^{PS,(2)}` given in Eq. (B.1) of :cite:`Buza_1998`. @@ -83,8 +83,8 @@ def A_hq_ps(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray - List of harmonic sums + S2 : complex + harmonic sum: :math:`S_{2}` L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -93,7 +93,6 @@ def A_hq_ps(n, sx, L): A_hq_ps : complex |NNLO| heavy-light pure-singlet |OME| :math:`A_{Hq}^{PS,(2)}` """ - S2 = sx[1] F1M = 1.0 / (n - 1.0) * (zeta2 - (S2 - 1.0 / n**2)) F11 = 1.0 / (n + 1.0) * (zeta2 - (S2 + 1.0 / (n + 1.0) ** 2)) @@ -137,7 +136,7 @@ def A_hq_ps(n, sx, L): @nb.njit(cache=True) -def A_hg(n, sx, L): +def A_hg(n, sx, smx, Sm21, L): r""" |NNLO| heavy-gluon |OME| :math:`A_{Hg}^{S,(2)}` given in Eq. (B.3) of :cite:`Buza_1998`. @@ -148,7 +147,11 @@ def A_hg(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + smx : numpy.ndarray + List of harmonic sums: :math:`S_{-1},S_{-2},S_{-3}` + Sm21 : complex + harmonic sum: :math:`S_{-2,1}` L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -162,18 +165,8 @@ def A_hg(n, sx, L): S3 = sx[2] S1m = S1 - 1 / n S2m = S2 - 1 / n**2 - Sp2m = harmonics.S2((n - 1) / 2) - Sp2p = harmonics.S2(n / 2) - # TODO: use harmonics from cache - Sm1 = -S1 + harmonics.S1(n / 2) - Sm2 = -S2 + 1 / 2 * Sp2p - Sm3 = -S3 + 1 / 4 * harmonics.S3(n / 2) - Sm21 = ( - -5 / 8 * zeta3 - + zeta2 * (Sm1 - 1 / n + log2) - + S1 / n**2 - + harmonics.g_functions.mellin_g3(n) - ) + Sm2 = smx[1] + Sm3 = smx[2] a_hg_l0 = ( -( @@ -268,7 +261,7 @@ def A_hg(n, sx, L): * (n + 1) * (n + 2) * (2 + n + n**2) - * (10 * S1m**2 - 9 * Sp2m + 26 * S2m + 9 * Sp2p) + * (10 * S1m**2 + 18 * (-1) ** n * (2 * Sm2 + zeta2) + 26 * S2m) ) ) / (3 * (n * (n + 1) * (n + 2)) ** 3 * (n - 1)) @@ -296,7 +289,7 @@ def A_gq(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + List of harmonic sums: :math:`S_{1},S_{2}` L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -336,7 +329,7 @@ def A_gq(n, sx, L): @nb.njit(cache=True) -def A_gg(n, sx, L): +def A_gg(n, S1, L): r""" |NNLO| gluon-gluon |OME| :math:`A_{gg,H}^{S,(2)} ` given in Eq. (B.7) of :cite:`Buza_1998`. @@ -345,8 +338,8 @@ def A_gg(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray - List of harmonic sums + S1 : complex + harmonic sum :math:`S_{1}` L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -355,7 +348,6 @@ def A_gg(n, sx, L): A_gg : complex |NNLO| gluon-gluon |OME| :math:`A_{gg,H}^{S,(2)}` """ - S1 = sx[0] S1m = S1 - 1 / n # harmonic_S1(n - 1) D1 = -1.0 / n**2 @@ -458,11 +450,11 @@ def A_singlet(n, sx, L, is_msbar=False): A_gq : :math:`A_{gq, H}^{S,(2)}` A_gg : :math:`A_{gg, H}^{S,(2)}` """ - A_hq_2 = A_hq_ps(n, sx, L) - A_qq_2 = A_qq_ns(n, sx, L) - A_hg_2 = A_hg(n, sx, L) - A_gq_2 = A_gq(n, sx, L) - A_gg_2 = A_gg(n, sx, L) + A_hq_2 = A_hq_ps(n, sx[1, 0], L) + A_qq_2 = A_qq_ns(n, sx[:, 0], L) + A_hg_2 = A_hg(n, sx[:, 0], sx[:, -1], sx[2, 1], L) + A_gq_2 = A_gq(n, sx[:-1, 0], L) + A_gg_2 = A_gg(n, sx[0, 0], L) if is_msbar: A_hg_2 -= 2.0 * 4.0 * constants.CF * A_hg_1(n, L=1.0) A_gg_2 -= 2.0 * 4.0 * constants.CF * A_gg_1(L=1.0) @@ -501,4 +493,4 @@ def A_ns(n, sx, L): -------- A_qq_ns : :math:`A_{qq,H}^{NS,(2)}` """ - return np.array([[A_qq_ns(n, sx, L), 0.0], [0 + 0j, 0 + 0j]], np.complex_) + return np.array([[A_qq_ns(n, sx[:, 0], L), 0.0], [0 + 0j, 0 + 0j]], np.complex_) diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index c9a97955f..598085860 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -12,7 +12,6 @@ from .. import basis_rotation as br from .. import harmonics -from ..anomalous_dimensions import harmonics from ..evolution_operator import Operator, QuadKerBase from . import as1, as2, as3 @@ -20,17 +19,21 @@ @nb.njit(cache=True) -def get_smx(n): - """Get the S-minus cache""" - return np.array( - [ - harmonics.Sm1(n), - harmonics.Sm2(n), - harmonics.Sm3(n), - harmonics.Sm4(n), - harmonics.Sm5(n), - ] - ) +def compute_harmonics_cache(n, order): + """Get the harmonics sums cache""" + # max harmonics sum weight for each qcd order + max_weight = {1: 2, 2: 3, 3: 5} + # max number of harmonics sum of a given weight for each qcd order + n_max_sums_weight = {1: 1, 2: 3, 3: 7} + sx = harmonics.base_harmonics_cache(n, max_weight[order], n_max_sums_weight[order]) + if order == 2: + # Add Sm21 to cache + sx[2, 1] = harmonics.Sm21(n, sx[0, -1]) + if order == 3: + # Add weight 3 and 4 to cache + sx[2, 1:] = get_s3x(n, sx[:, 0], sx[:, -1]) + sx[3, 1:] = get_s4x(n, sx[:, 0], sx[:, -1]) + return sx @nb.njit(cache=True) @@ -240,19 +243,7 @@ def quad_ker( if integrand == 0.0: return 0.0 - # compute the harmonics - sx = np.zeros(3, np.complex_) - if order >= 1: - sx = np.array([harmonics.S1(ker_base.n), harmonics.S2(ker_base.n)]) - if order >= 2: - sx = np.append(sx, harmonics.S3(ker_base.n)) - if order >= 3: - sx = np.append(sx, harmonics.S4(ker_base.n)) - sx = np.append(sx, harmonics.S5(ker_base.n)) - smx = get_smx(ker_base.n) - sx = np.append(sx, smx) - sx = np.append(sx, get_s3x(ker_base.n, sx, smx)) - sx = np.append(sx, get_s4x(ker_base.n, sx, smx)) + sx = compute_harmonics_cache(ker_base.n, order) # compute the ome if ker_base.is_singlet: indices = {21: 0, 100: 1, 90: 2} diff --git a/tests/eko/test_matching_nlo.py b/tests/eko/test_matching_nlo.py index 124c6bec8..081f36746 100644 --- a/tests/eko/test_matching_nlo.py +++ b/tests/eko/test_matching_nlo.py @@ -2,14 +2,15 @@ # Test NLO OME import numpy as np +from eko.harmonics import get_sx from eko.matching_conditions.as1 import A_ns, A_singlet -def test_A_1_intrinsic(get_sx): +def test_A_1_intrinsic(): L = 100.0 N = 2 - sx = get_sx(N) + sx = get_sx(N, 2) aS1 = A_singlet(N, sx, L) # heavy quark momentum conservation np.testing.assert_allclose(aS1[0, 2] + aS1[1, 2] + aS1[2, 2], 0.0, atol=1e-10) @@ -18,22 +19,22 @@ def test_A_1_intrinsic(get_sx): np.testing.assert_allclose(aS1[0, 0] + aS1[1, 0] + aS1[2, 0], 0.0) -def test_A_1_shape(get_sx): +def test_A_1_shape(): N = 2 L = 3.0 - sx = get_sx(N) + sx = get_sx(N, 2) aNS1i = A_ns(N, sx, L) aS1i = A_singlet(N, sx, L) assert aNS1i.shape == (2, 2) assert aS1i.shape == (3, 3) - # check intrisic hh is the same + # check intrinsic hh is the same assert aNS1i[1, 1] == aS1i[2, 2] -def test_Blumlein_1(get_sx): +def test_Blumlein_1(): # Test against Blumlein OME implementation :cite:`Bierenbaum:2009mv`. # Only even moments are available in that code. # Note there is a minus sign in the definition of L. @@ -46,7 +47,7 @@ def test_Blumlein_1(get_sx): for n in range(N_vals): N = 2 * n + 2 - sx = get_sx(N) + sx = get_sx(N, 2) for L, ref_gg in ref_val_gg.items(): aS1 = A_singlet(N, sx, L) np.testing.assert_allclose(aS1[0, 0], ref_gg[n], rtol=1e-6) diff --git a/tests/eko/test_matching_nnlo.py b/tests/eko/test_matching_nnlo.py index 17bb69d31..9c38c68f5 100644 --- a/tests/eko/test_matching_nnlo.py +++ b/tests/eko/test_matching_nnlo.py @@ -3,22 +3,23 @@ import numpy as np -from eko.harmonics import constants +from eko.harmonics import constants, get_sx from eko.matching_conditions.as2 import A_ns, A_qq_ns, A_singlet +from eko.matching_conditions.operator_matrix_element import compute_harmonics_cache -def test_A_2(get_sx): +def test_A_2(): logs = [0, 100] for L in logs: N = 1 - sx = get_sx(N) + sx = get_sx(N, 3) aNSqq2 = A_qq_ns(N, sx, L) # quark number conservation np.testing.assert_allclose(aNSqq2, 0.0, atol=2e-11) N = 2 - sx = get_sx(N) + sx = compute_harmonics_cache(N, 2) aS2 = A_singlet(N, sx, L) # gluon momentum conservation @@ -38,7 +39,7 @@ def test_A_2(get_sx): def test_A_2_shape(): N = 2 L = 3 - sx = np.zeros(3, np.complex_) + sx = np.zeros((3, 3), np.complex_) aNS2 = A_ns(N, sx, L) aS2 = A_singlet(N, sx, L) @@ -50,18 +51,18 @@ def test_A_2_shape(): assert aNS2[0].all() == aNS2[1].all() -def test_pegasus_sign(get_sx): +def test_pegasus_sign(): # reference value come from Pegasus code transalted Mathematica ref_val = -21133.9 N = 2 - sx = get_sx(N) + sx = compute_harmonics_cache(N, 2) L = 100.0 aS2 = A_singlet(N, sx, L) np.testing.assert_allclose(aS2[0, 0], ref_val, rtol=4e-5) -def test_Blumlein_2(get_sx): +def test_Blumlein_2(): # Test against Blumlein OME implementation :cite:`Bierenbaum:2009zt`. # For singlet OME only even moments are available in that code. # Note there is a minus sign in the definition of L. @@ -119,7 +120,7 @@ def test_Blumlein_2(get_sx): } for N in range(2, 11): for L, ref_Hg in ref_val_Hg.items(): - sx = get_sx(N) + sx = compute_harmonics_cache(N, 2) aS2 = A_singlet(N, sx, L) if N % 2 == 0: idx = int(N / 2 - 1) @@ -130,17 +131,17 @@ def test_Blumlein_2(get_sx): np.testing.assert_allclose(aS2[1, 1], ref_val_qq[L][N - 2], rtol=4e-6) -def test_Hg2_pegasus(get_sx): +def test_Hg2_pegasus(): # Test against the parametrized expression for A_Hg # coming from Pegasus code # This parametrization is less accurate. L = 0 for N in range(3, 20): - sx = get_sx(N) - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] + sx = compute_harmonics_cache(N, 2) + S1 = sx[0, 0] + S2 = sx[1, 0] + S3 = sx[2, 0] aS2 = A_singlet(N, sx, L) E2 = ( @@ -161,15 +162,15 @@ def test_Hg2_pegasus(get_sx): - 146.8 * E2 ) - np.testing.assert_allclose(aS2[2, 0], a_hg_param, rtol=7e-4) + np.testing.assert_allclose(aS2[2, 0], a_hg_param, rtol=9e-4) -def test_msbar_matching(get_sx): +def test_msbar_matching(): logs = [0, 100] for L in logs: N = 2 - sx = get_sx(N) + sx = compute_harmonics_cache(N, 2) aS2 = A_singlet(N, sx, L, True) # gluon momentum conservation np.testing.assert_allclose(aS2[0, 0] + aS2[1, 0] + aS2[2, 0], 0.0, atol=2e-6) From aeed0189b51fd9e2fc70c7a60d1b271027730c3c Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 14:05:31 +0200 Subject: [PATCH 05/47] restore old signature in ome as1 and as2, delete conftest --- src/eko/matching_conditions/as1.py | 8 ++-- src/eko/matching_conditions/as2.py | 61 +++++++++++++++--------------- tests/eko/conftest.py | 23 ----------- 3 files changed, 33 insertions(+), 59 deletions(-) delete mode 100644 tests/eko/conftest.py diff --git a/src/eko/matching_conditions/as1.py b/src/eko/matching_conditions/as1.py index e56c22322..f327a0bb7 100644 --- a/src/eko/matching_conditions/as1.py +++ b/src/eko/matching_conditions/as1.py @@ -24,7 +24,7 @@ def A_hh(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2}` + List of harmonic sums L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -33,8 +33,8 @@ def A_hh(n, sx, L): A_hh : complex |NLO| heavy-heavy |OME| :math:`A_{HH}^{(1)}` """ - S1m = sx[0] - 1 / n # harmonics.S1(n - 1) - S2m = sx[1] - 1 / n**2 # harmonics.S2(n - 1) + S1m = sx[0, 0] - 1 / n # harmonics.S1(n - 1) + S2m = sx[1, 0] - 1 / n**2 # harmonics.S2(n - 1) ahh_l = (2 + n - 3 * n**2) / (n * (1 + n)) + 4 * S1m ahh = 2 * ( 2 @@ -131,8 +131,6 @@ def A_singlet(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray - List of harmonic sums L : float :math:`\ln(\mu_F^2 / m_h^2)` diff --git a/src/eko/matching_conditions/as2.py b/src/eko/matching_conditions/as2.py index 04730f491..dd11371b6 100644 --- a/src/eko/matching_conditions/as2.py +++ b/src/eko/matching_conditions/as2.py @@ -29,7 +29,7 @@ def A_qq_ns(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + List of harmonic sums L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -38,9 +38,9 @@ def A_qq_ns(n, sx, L): A_qq_ns : complex |NNLO| light-light non-singlet |OME| :math:`A_{qq,H}^{NS,(2)}` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] + S1 = sx[0, 0] + S2 = sx[1, 0] + S3 = sx[2, 0] S1m = S1 - 1 / n # harmonic_S1(n - 1) S2m = S2 - 1 / n**2 # harmonic_S2(n - 1) @@ -74,7 +74,7 @@ def A_qq_ns(n, sx, L): @nb.njit(cache=True) -def A_hq_ps(n, S2, L): +def A_hq_ps(n, sx, L): r""" |NNLO| heavy-light pure-singlet |OME| :math:`A_{Hq}^{PS,(2)}` given in Eq. (B.1) of :cite:`Buza_1998`. @@ -83,8 +83,8 @@ def A_hq_ps(n, S2, L): ---------- n : complex Mellin moment - S2 : complex - harmonic sum: :math:`S_{2}` + sx : numpy.ndarray + List of harmonic sums L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -93,6 +93,7 @@ def A_hq_ps(n, S2, L): A_hq_ps : complex |NNLO| heavy-light pure-singlet |OME| :math:`A_{Hq}^{PS,(2)}` """ + S2 = sx[1, 0] F1M = 1.0 / (n - 1.0) * (zeta2 - (S2 - 1.0 / n**2)) F11 = 1.0 / (n + 1.0) * (zeta2 - (S2 + 1.0 / (n + 1.0) ** 2)) @@ -136,7 +137,7 @@ def A_hq_ps(n, S2, L): @nb.njit(cache=True) -def A_hg(n, sx, smx, Sm21, L): +def A_hg(n, sx, L): r""" |NNLO| heavy-gluon |OME| :math:`A_{Hg}^{S,(2)}` given in Eq. (B.3) of :cite:`Buza_1998`. @@ -147,11 +148,7 @@ def A_hg(n, sx, smx, Sm21, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` - smx : numpy.ndarray - List of harmonic sums: :math:`S_{-1},S_{-2},S_{-3}` - Sm21 : complex - harmonic sum: :math:`S_{-2,1}` + List of harmonic sums L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -160,13 +157,14 @@ def A_hg(n, sx, smx, Sm21, L): A_hg : complex |NNLO| heavy-gluon |OME| :math:`A_{Hg}^{S,(2)}` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] + S1 = sx[0, 0] + S2 = sx[1, 0] + S3 = sx[2, 0] S1m = S1 - 1 / n S2m = S2 - 1 / n**2 - Sm2 = smx[1] - Sm3 = smx[2] + Sm2 = sx[1, -1] + Sm3 = sx[2, -1] + Sm21 = sx[2, 1] a_hg_l0 = ( -( @@ -261,7 +259,7 @@ def A_hg(n, sx, smx, Sm21, L): * (n + 1) * (n + 2) * (2 + n + n**2) - * (10 * S1m**2 + 18 * (-1) ** n * (2 * Sm2 + zeta2) + 26 * S2m) + * (10 * S1m**2 + 18 * (2 * Sm2 + zeta2) + 26 * S2m) ) ) / (3 * (n * (n + 1) * (n + 2)) ** 3 * (n - 1)) @@ -289,7 +287,7 @@ def A_gq(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2}` + List of harmonic sums L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -298,8 +296,8 @@ def A_gq(n, sx, L): A_gq : complex |NNLO| gluon-quark |OME| :math:`A_{gq,H}^{S,(2)}` """ - S1 = sx[0] - S2 = sx[1] + S1 = sx[0, 0] + S2 = sx[1, 0] S1m = S1 - 1 / n # harmonic_S1(n - 1) B2M = ((S1 - 1.0 / n) ** 2 + S2 - 1.0 / n**2) / (n - 1.0) @@ -329,7 +327,7 @@ def A_gq(n, sx, L): @nb.njit(cache=True) -def A_gg(n, S1, L): +def A_gg(n, sx, L): r""" |NNLO| gluon-gluon |OME| :math:`A_{gg,H}^{S,(2)} ` given in Eq. (B.7) of :cite:`Buza_1998`. @@ -338,8 +336,8 @@ def A_gg(n, S1, L): ---------- n : complex Mellin moment - S1 : complex - harmonic sum :math:`S_{1}` + sx : numpy.ndarray + List of harmonic sums L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -348,6 +346,7 @@ def A_gg(n, S1, L): A_gg : complex |NNLO| gluon-gluon |OME| :math:`A_{gg,H}^{S,(2)}` """ + S1 = sx[0, 0] S1m = S1 - 1 / n # harmonic_S1(n - 1) D1 = -1.0 / n**2 @@ -450,11 +449,11 @@ def A_singlet(n, sx, L, is_msbar=False): A_gq : :math:`A_{gq, H}^{S,(2)}` A_gg : :math:`A_{gg, H}^{S,(2)}` """ - A_hq_2 = A_hq_ps(n, sx[1, 0], L) - A_qq_2 = A_qq_ns(n, sx[:, 0], L) - A_hg_2 = A_hg(n, sx[:, 0], sx[:, -1], sx[2, 1], L) - A_gq_2 = A_gq(n, sx[:-1, 0], L) - A_gg_2 = A_gg(n, sx[0, 0], L) + A_hq_2 = A_hq_ps(n, sx, L) + A_qq_2 = A_qq_ns(n, sx, L) + A_hg_2 = A_hg(n, sx, L) + A_gq_2 = A_gq(n, sx, L) + A_gg_2 = A_gg(n, sx, L) if is_msbar: A_hg_2 -= 2.0 * 4.0 * constants.CF * A_hg_1(n, L=1.0) A_gg_2 -= 2.0 * 4.0 * constants.CF * A_gg_1(L=1.0) @@ -493,4 +492,4 @@ def A_ns(n, sx, L): -------- A_qq_ns : :math:`A_{qq,H}^{NS,(2)}` """ - return np.array([[A_qq_ns(n, sx[:, 0], L), 0.0], [0 + 0j, 0 + 0j]], np.complex_) + return np.array([[A_qq_ns(n, sx, L), 0.0], [0 + 0j, 0 + 0j]], np.complex_) diff --git a/tests/eko/conftest.py b/tests/eko/conftest.py deleted file mode 100644 index feb767351..000000000 --- a/tests/eko/conftest.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -import numpy as np -import pytest - -from eko.anomalous_dimensions import harmonics - - -@pytest.fixture -def get_sx(): - def wrapped(N): - """Collect the S-cache""" - sx = np.array( - [ - harmonics.S1(N), - harmonics.S2(N), - harmonics.S3(N), - harmonics.S4(N), - harmonics.S5(N), - ] - ) - return sx - - return wrapped From bcaf20bfd1de9556e7f9f83821974efe221f51e0 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 14:07:36 +0200 Subject: [PATCH 06/47] Move get_s3x and get_s4x to harmonics --- src/eko/harmonics/__init__.py | 68 ++++++++++++++++++- .../operator_matrix_element.py | 32 +-------- tests/eko/test_harmonics.py | 46 +++++++++++++ 3 files changed, 113 insertions(+), 33 deletions(-) create mode 100644 tests/eko/test_harmonics.py diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index d73e6a142..9abedc9f7 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -20,6 +20,8 @@ def base_harmonics_cache(n, max_weight=5, n_max_sums_weight=7): Only single index harmonics are computed and stored in the first (:math:`S_{n}`) or in the last column (:math:`S_{-n}`) + Multi indices harmonics sums can be stored in the middle columns. + Parameters ---------- n : complex @@ -32,7 +34,7 @@ def base_harmonics_cache(n, max_weight=5, n_max_sums_weight=7): list of harmonics sums: (weights, n_max_sums_weight) """ - h_cache = np.zeros((max_weight, n_max_sums_weight), np.complex_) + h_cache = np.zeros((max_weight, n_max_sums_weight), dtype=np.complex_) h_cache[:, 0] = get_sx(n, max_weight) if n_max_sums_weight > 1: h_cache[:, -1] = get_smx(n, max_weight) @@ -55,7 +57,7 @@ def get_sx(n, max_weight=5): sx : np.ndarray list of harmonics sums (:math:`S_{1,..,w}`) """ - sx = np.zeros(max_weight, np.complex_) + sx = np.zeros(max_weight, dtype=np.complex_) if max_weight >= 1: sx[0] = S1(n) if max_weight >= 2: @@ -86,7 +88,7 @@ def get_smx(n, max_weight=5): smx : np.ndarray list of harmonics sums (:math:`S_{-1,..,-w}`) """ - smx = np.zeros(max_weight, np.complex_) + smx = np.zeros(max_weight, dtype=np.complex_) if max_weight >= 1: smx[0] = Sm1(n) if max_weight >= 2: @@ -98,3 +100,63 @@ def get_smx(n, max_weight=5): if max_weight >= 5: smx[4] = Sm5(n) return smx + + +@nb.njit(cache=True) +def get_s3x(n, sx, smx): + """ + Compute the weight 3 multi indices harmonics sums cache + + Parameters + ---------- + n: complex + Mellin moment + sx : list + List of harmonics sums: :math:`S_{1},S_{2}` + smx : list + List of harmonics sums: :math:`S_{-1},S_{-2}` + + Returns + ------- + s3x: np.ndarray + list containing: :math:`S_{2,1},S_{2,-1},S_{-2,1},S_{-2,-1}` + """ + return np.array( + [ + S21(n, sx[0], sx[1]), + S2m1(n, sx[1], smx[0], smx[1]), + Sm21(n, smx[0]), + Sm2m1(n, sx[0], sx[1], smx[1]), + ] + ) + + +@nb.njit(cache=True) +def get_s4x(n, sx, smx): + """ + Compute the weight 4 multi indices harmonics sums cache + + Parameters + ---------- + n: complex + Mellin moment + sx : list + List of harmonics sums: :math:`S_{1},S_{2},S_{3},S_{4}` + smx : list + List of harmonics sums: :math:`S_{-1},S_{-2}` + + Returns + ------- + s4x: np.ndarray + list containing: :math:`S_{3,1},S_{2,1,1},S_{-2,2},S_{-2,1,1},S_{-3,1}` + """ + sm31 = Sm31(n, smx[0], smx[1]) + return np.array( + [ + S31(n, sx[1], sx[3]), + S211(n, sx[0], sx[1], sx[2]), + Sm22(n, smx[1], sm31), + Sm211(n, smx[0]), + Sm31(n, smx[0], smx[1]), + ] + ) diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index 598085860..de5094205 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -31,39 +31,11 @@ def compute_harmonics_cache(n, order): sx[2, 1] = harmonics.Sm21(n, sx[0, -1]) if order == 3: # Add weight 3 and 4 to cache - sx[2, 1:] = get_s3x(n, sx[:, 0], sx[:, -1]) - sx[3, 1:] = get_s4x(n, sx[:, 0], sx[:, -1]) + sx[2, 1:-2] = harmonics.get_s3x(n, sx[:, 0], sx[:, -1]) + sx[3, 1:-1] = harmonics.get_s4x(n, sx[:, 0], sx[:, -1]) return sx -@nb.njit(cache=True) -def get_s3x(n, sx, smx): - """Get the S-w3 cache""" - return np.array( - [ - harmonics.S21(n, sx[0], sx[1]), - harmonics.S2m1(n, sx[1], smx[0], smx[1]), - harmonics.Sm21(n, smx[0]), - harmonics.Sm2m1(n, sx[0], sx[1], smx[1]), - ] - ) - - -@nb.njit(cache=True) -def get_s4x(n, sx, smx): - """Get the S-w4 cache""" - Sm31 = harmonics.Sm31(n, smx[0], smx[1]) - return np.array( - [ - harmonics.S31(n, sx[1], sx[3]), - harmonics.S211(n, sx[0], sx[1], sx[2]), - harmonics.Sm22(n, smx[1], Sm31), - harmonics.Sm211(n, smx[0]), - harmonics.Sm31(n, smx[0], smx[1]), - ] - ) - - @nb.njit(cache=True) def A_singlet(order, n, sx, nf, L, is_msbar): r""" diff --git a/tests/eko/test_harmonics.py b/tests/eko/test_harmonics.py new file mode 100644 index 000000000..081727908 --- /dev/null +++ b/tests/eko/test_harmonics.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Test eko.matching_conditions.OperatorMatrixElement +import numpy as np + +from eko import harmonics as h + + +def test_HarmonicsCache(): + N = np.random.rand() + 1.0j * np.random.rand() + Sm1 = h.Sm1(N) + Sm2 = h.Sm2(N) + S1 = h.S1(N) + S2 = h.S2(N) + S3 = h.S3(N) + S4 = h.S4(N) + sx = np.array([S1, S2, S3, S4, h.S5(N)]) + smx_test = np.array( + [ + Sm1, + Sm2, + h.Sm3(N), + h.Sm4(N), + h.Sm5(N), + ] + ) + np.testing.assert_allclose(h.get_smx(N), smx_test) + s3x_test = np.array( + [ + h.S21(N, S1, S2), + h.S2m1(N, S2, Sm1, Sm2), + h.Sm21(N, Sm1), + h.Sm2m1(N, S1, S2, Sm2), + ] + ) + np.testing.assert_allclose(h.get_s3x(N, sx, smx_test), s3x_test) + Sm31 = h.Sm31(N, Sm1, Sm2) + s4x_test = np.array( + [ + h.S31(N, S2, S4), + h.S211(N, S1, S2, S3), + h.Sm22(N, Sm2, Sm31), + h.Sm211(N, Sm1), + Sm31, + ] + ) + np.testing.assert_allclose(h.get_s4x(N, sx, smx_test), s4x_test) From 174a8e8d216616ff7fe7622192916c22ed7942c4 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 14:09:25 +0200 Subject: [PATCH 07/47] update as3 ome harmincs and tests --- src/eko/matching_conditions/as3/__init__.py | 16 +++---- tests/eko/test_matching_n3lo.py | 16 +++---- tests/eko/test_matching_nlo.py | 8 ++-- tests/eko/test_matching_nnlo.py | 4 +- tests/eko/test_ome.py | 49 +-------------------- 5 files changed, 23 insertions(+), 70 deletions(-) diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/eko/matching_conditions/as3/__init__.py index e8e5c2f66..47d49b26d 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/eko/matching_conditions/as3/__init__.py @@ -68,10 +68,10 @@ def A_singlet(n, sx_all, nf, L): A_S : numpy.ndarray |NNLO| singlet |OME| :math:`A^{S,(3)}(N)` """ - sx = sx_all[:5] - smx = sx_all[5:10] - s3x = sx_all[10:14] - s4x = sx_all[14:] + sx = sx_all[:, 0] + smx = sx_all[:, -1] + s3x = sx_all[2, 1:] + s4x = sx_all[3, 1:] A_hq_3 = A_Hq(n, sx, smx, s3x, s4x, nf, L) A_hg_3 = A_Hg(n, sx, smx, s3x, s4x, nf, L) @@ -128,10 +128,10 @@ def A_ns(n, sx_all, nf, L): -------- A_qqNS_3 : :math:`A_{qq,H}^{NS,(3))}` """ - sx = sx_all[:5] - smx = sx_all[5:10] - s3x = sx_all[10:14] - s4x = sx_all[14:] + sx = sx_all[:, 0] + smx = sx_all[:, -1] + s3x = sx_all[2, 1:] + s4x = sx_all[3, 1:] return np.array( [[A_qqNS(n, sx, smx, s3x, s4x, nf, L), 0.0], [0 + 0j, 0 + 0j]], np.complex_ ) diff --git a/tests/eko/test_matching_n3lo.py b/tests/eko/test_matching_n3lo.py index 562820764..fa9ddd6b6 100644 --- a/tests/eko/test_matching_n3lo.py +++ b/tests/eko/test_matching_n3lo.py @@ -2,12 +2,13 @@ # Test N3LO OME import numpy as np +from eko.harmonics import get_s3x, get_s4x, get_smx, get_sx from eko.matching_conditions import as3 from eko.matching_conditions.as3 import A_ns, A_qqNS, A_singlet -from eko.matching_conditions.operator_matrix_element import get_s3x, get_s4x, get_smx +from eko.matching_conditions.operator_matrix_element import compute_harmonics_cache -def test_A_3(get_sx): +def test_A_3(): logs = [0, 10] nf = 3 @@ -62,7 +63,7 @@ def test_A_3(get_sx): # np.testing.assert_allclose(aS3[0, 1] + aS3[1, 1] + aS3[2, 1], 0.0, atol=1e-11) N = 3 + 2j - sx_all = np.random.rand(19) + 1j * np.random.rand(19) + sx_all = np.random.rand(5, 7) + 1j * np.random.rand(5, 7) aS3 = A_singlet(N, sx_all, nf, L) aNS3 = A_ns(N, sx_all, nf, L) assert aNS3.shape == (2, 2) @@ -72,7 +73,7 @@ def test_A_3(get_sx): np.testing.assert_allclose(aNS3[1, 1], 0) -def test_Blumlein_3(get_sx): +def test_Blumlein_3(): # Test against Blumlein OME implementation :cite:`Bierenbaum:2009mv`. # For singlet OME only even moments are available in that code. # Note there is a minus sign in the definition of L. @@ -145,10 +146,7 @@ def test_Blumlein_3(get_sx): for i, N in enumerate([4.0, 6.0, 10.0, 100.0]): idx = i + 1 for L in [0, 10]: - sx_all = get_sx(N) - sx_all = np.append(sx_all, get_smx(N)) - sx_all = np.append(sx_all, get_s3x(N, get_sx(N), get_smx(N))) - sx_all = np.append(sx_all, get_s4x(N, get_sx(N), get_smx(N))) + sx_all = compute_harmonics_cache(N, 3) aS3 = A_singlet(N, sx_all, nf, L) # here we have a different approximation for AggTF2, @@ -209,7 +207,7 @@ def test_Blumlein_3(get_sx): ) -def test_AHq_asymptotic(get_sx): +def test_AHq_asymptotic(): refs = [ -1.06712, 0.476901, diff --git a/tests/eko/test_matching_nlo.py b/tests/eko/test_matching_nlo.py index 081f36746..d20d2c1bc 100644 --- a/tests/eko/test_matching_nlo.py +++ b/tests/eko/test_matching_nlo.py @@ -2,15 +2,15 @@ # Test NLO OME import numpy as np -from eko.harmonics import get_sx from eko.matching_conditions.as1 import A_ns, A_singlet +from eko.matching_conditions.operator_matrix_element import compute_harmonics_cache def test_A_1_intrinsic(): L = 100.0 N = 2 - sx = get_sx(N, 2) + sx = compute_harmonics_cache(N, 1) aS1 = A_singlet(N, sx, L) # heavy quark momentum conservation np.testing.assert_allclose(aS1[0, 2] + aS1[1, 2] + aS1[2, 2], 0.0, atol=1e-10) @@ -23,7 +23,7 @@ def test_A_1_shape(): N = 2 L = 3.0 - sx = get_sx(N, 2) + sx = compute_harmonics_cache(N, 1) aNS1i = A_ns(N, sx, L) aS1i = A_singlet(N, sx, L) @@ -47,7 +47,7 @@ def test_Blumlein_1(): for n in range(N_vals): N = 2 * n + 2 - sx = get_sx(N, 2) + sx = compute_harmonics_cache(N, 1) for L, ref_gg in ref_val_gg.items(): aS1 = A_singlet(N, sx, L) np.testing.assert_allclose(aS1[0, 0], ref_gg[n], rtol=1e-6) diff --git a/tests/eko/test_matching_nnlo.py b/tests/eko/test_matching_nnlo.py index 9c38c68f5..f17cbc927 100644 --- a/tests/eko/test_matching_nnlo.py +++ b/tests/eko/test_matching_nnlo.py @@ -3,7 +3,7 @@ import numpy as np -from eko.harmonics import constants, get_sx +from eko.harmonics import constants from eko.matching_conditions.as2 import A_ns, A_qq_ns, A_singlet from eko.matching_conditions.operator_matrix_element import compute_harmonics_cache @@ -13,7 +13,7 @@ def test_A_2(): for L in logs: N = 1 - sx = get_sx(N, 3) + sx = compute_harmonics_cache(N, 2) aNSqq2 = A_qq_ns(N, sx, L) # quark number conservation np.testing.assert_allclose(aNSqq2, 0.0, atol=2e-11) diff --git a/tests/eko/test_ome.py b/tests/eko/test_ome.py index c3a3b58bb..e916f4601 100644 --- a/tests/eko/test_ome.py +++ b/tests/eko/test_ome.py @@ -5,7 +5,6 @@ import numpy as np from eko import basis_rotation as br -from eko import harmonics as sf from eko import interpolation, mellin from eko.evolution_operator.grid import OperatorGrid from eko.interpolation import InterpolatorDispatcher @@ -14,62 +13,18 @@ A_singlet, OperatorMatrixElement, build_ome, - get_s3x, - get_s4x, - get_smx, quad_ker, ) from eko.strong_coupling import StrongCoupling from eko.thresholds import ThresholdsAtlas -def test_HarmonicsCache(): - N = np.random.rand() + 1.0j * np.random.rand() - Sm1 = sf.Sm1(N) - Sm2 = sf.Sm2(N) - S1 = sf.S1(N) - S2 = sf.S2(N) - S3 = sf.S3(N) - S4 = sf.S4(N) - sx = np.array([S1, S2, S3, S4, sf.S5(N)]) - smx_test = np.array( - [ - Sm1, - Sm2, - sf.Sm3(N), - sf.Sm4(N), - sf.Sm5(N), - ] - ) - np.testing.assert_allclose(get_smx(N), smx_test) - s3x_test = np.array( - [ - sf.S21(N, S1, S2), - sf.S2m1(N, S2, Sm1, Sm2), - sf.Sm21(N, Sm1), - sf.Sm2m1(N, S1, S2, Sm2), - ] - ) - np.testing.assert_allclose(get_s3x(N, sx, smx_test), s3x_test) - Sm31 = sf.Sm31(N, Sm1, Sm2) - s4x_test = np.array( - [ - sf.S31(N, S2, S4), - sf.S211(N, S1, S2, S3), - sf.Sm22(N, Sm2, Sm31), - sf.Sm211(N, Sm1), - Sm31, - ] - ) - np.testing.assert_allclose(get_s4x(N, sx, smx_test), s4x_test) - - def test_build_ome_as(): # test that if as = 0 ome is and identity N = 2 L = 0.0 a_s = 0.0 - sx = np.random.rand(19) + 1j * np.random.rand(19) + sx = np.random.rand(5, 7) + 1j * np.random.rand(5, 7) nf = 3 is_msbar = False for o in [0, 1, 2, 3]: @@ -96,7 +51,7 @@ def test_build_ome_nlo(): a_s = 20 is_msbar = False - sx = np.array([1, 1, 1], np.complex_) + sx = np.array([[1], [1], [1]], np.complex_) nf = 4 aNSi = A_non_singlet(1, N, sx, nf, L) aSi = A_singlet(1, N, sx, nf, L, is_msbar) From cd4823647e2c57babdca95c3173cf464036fb7f8 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 14:10:55 +0200 Subject: [PATCH 08/47] remove old n3lo names --- src/eko/matching_conditions/as3/__init__.py | 4 ++-- src/eko/matching_conditions/as3/aHg.py | 4 ++-- src/eko/matching_conditions/as3/aHgstfac.py | 2 +- src/eko/matching_conditions/as3/aHq.py | 2 +- src/eko/matching_conditions/as3/agg.py | 4 ++-- src/eko/matching_conditions/as3/aggTF2.py | 2 +- src/eko/matching_conditions/as3/agq.py | 2 +- src/eko/matching_conditions/as3/aqg.py | 2 +- src/eko/matching_conditions/as3/aqqNS.py | 2 +- src/eko/matching_conditions/as3/aqqPS.py | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/eko/matching_conditions/as3/__init__.py index 47d49b26d..bd8387b7c 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/eko/matching_conditions/as3/__init__.py @@ -49,7 +49,7 @@ def A_singlet(n, sx_all, nf, L): \end{array}\right) When using the code, please cite the complete list of references - available at the top of this module :mod:`eko.matching_conditions.n3lo`. + available at the top of this module :mod:`eko.matching_conditions.as3`. Parameters ---------- @@ -105,7 +105,7 @@ def A_ns(n, sx_all, nf, L): \end{array}\right) When using the code, please cite the complete list of references - available at the top of this module :mod:`eko.matching_conditions.n3lo`. + available at the top of this module :mod:`eko.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/aHg.py b/src/eko/matching_conditions/as3/aHg.py index a95bb60c4..609eac33d 100644 --- a/src/eko/matching_conditions/as3/aHg.py +++ b/src/eko/matching_conditions/as3/aHg.py @@ -13,7 +13,7 @@ def A_Hg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals The experssion is presented in :cite:`Bierenbaum:2009mv`. When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.n3lo`. + available in :mod:`eko.matching_conditions.as3`. Parameters ---------- @@ -38,7 +38,7 @@ def A_Hg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals :math:`A_{Hg}^{S,(3)}(N)` See Also -------- - A_Hgstfac: eko.matching_conditions.n3lo.aHgstfac.A_Hgstfac + A_Hgstfac: eko.matching_conditions.as3.aHgstfac.A_Hgstfac Incomplete part of the |OME|. """ S1, S2, S3, S4 = sx[0], sx[1], sx[2], sx[3] diff --git a/src/eko/matching_conditions/as3/aHgstfac.py b/src/eko/matching_conditions/as3/aHgstfac.py index 8c4b2f05b..e605f39d2 100644 --- a/src/eko/matching_conditions/as3/aHgstfac.py +++ b/src/eko/matching_conditions/as3/aHgstfac.py @@ -11,7 +11,7 @@ def A_Hgstfac(n, sx, smx, s3x, s4x, nf): The experssion is presented in cite:`ablinger2017heavy` (eq 3.1). When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.n3lo`. + available in :mod:`eko.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/aHq.py b/src/eko/matching_conditions/as3/aHq.py index 675e4ab53..a3d9d3ee3 100644 --- a/src/eko/matching_conditions/as3/aHq.py +++ b/src/eko/matching_conditions/as3/aHq.py @@ -12,7 +12,7 @@ def A_Hq(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals and :cite:`Blumlein:2017wxd` (eq 3.1). When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.n3lo`. + available in :mod:`eko.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/agg.py b/src/eko/matching_conditions/as3/agg.py index 1f537e0fc..3a0da1e06 100644 --- a/src/eko/matching_conditions/as3/agg.py +++ b/src/eko/matching_conditions/as3/agg.py @@ -13,7 +13,7 @@ def A_gg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals The experssion is presented in :cite:`Bierenbaum:2009mv`. When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.n3lo`. + available in :mod:`eko.matching_conditions.as3`. Parameters ---------- @@ -39,7 +39,7 @@ def A_gg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals See Also -------- - A_ggTF2: eko.matching_conditions.n3lo.aggTF2.A_ggTF2 + A_ggTF2: eko.matching_conditions.as3.aggTF2.A_ggTF2 Incomplete part proportional to :math:`T_{F}^2`. """ S1, S2, S3, S4 = sx[0], sx[1], sx[2], sx[3] diff --git a/src/eko/matching_conditions/as3/aggTF2.py b/src/eko/matching_conditions/as3/aggTF2.py index f2eb5ed75..9528755ad 100644 --- a/src/eko/matching_conditions/as3/aggTF2.py +++ b/src/eko/matching_conditions/as3/aggTF2.py @@ -12,7 +12,7 @@ def A_ggTF2(n, sx, s3x): It contains a binomial factor which is given approximated. When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.n3lo`. + available in :mod:`eko.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/agq.py b/src/eko/matching_conditions/as3/agq.py index d7d668faa..bf4813600 100644 --- a/src/eko/matching_conditions/as3/agq.py +++ b/src/eko/matching_conditions/as3/agq.py @@ -10,7 +10,7 @@ def A_gq(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals The experssion is presented in :cite:`Ablinger_2014` (eq 6.3). When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.n3lo`. + available in :mod:`eko.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/aqg.py b/src/eko/matching_conditions/as3/aqg.py index 577396c08..741906d01 100644 --- a/src/eko/matching_conditions/as3/aqg.py +++ b/src/eko/matching_conditions/as3/aqg.py @@ -10,7 +10,7 @@ def A_qg(n, sx, smx, s3x, s4x, nf, L): The expression is presented in :cite:`Bierenbaum:2009mv`. When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.n3lo`. + available in :mod:`eko.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/aqqNS.py b/src/eko/matching_conditions/as3/aqqNS.py index 494fa4015..97a12da85 100644 --- a/src/eko/matching_conditions/as3/aqqNS.py +++ b/src/eko/matching_conditions/as3/aqqNS.py @@ -13,7 +13,7 @@ def A_qqNS(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals :cite:`Ablinger:2014vwa`. It contains some weight 5 harmonics sums. When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.n3lo`. + available in :mod:`eko.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/aqqPS.py b/src/eko/matching_conditions/as3/aqqPS.py index 7846c0111..9312e3bd9 100644 --- a/src/eko/matching_conditions/as3/aqqPS.py +++ b/src/eko/matching_conditions/as3/aqqPS.py @@ -10,7 +10,7 @@ def A_qqPS(n, sx, nf, L): The expression is presented in :cite:`Bierenbaum:2009mv`. When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.n3lo`. + available in :mod:`eko.matching_conditions.as3`. Parameters ---------- From 18078f9ff7a31751865acd34dca0c581daa12ebd Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 16:57:41 +0200 Subject: [PATCH 09/47] passing S1 and S2 to nlo ad --- src/eko/anomalous_dimensions/__init__.py | 15 +++----- src/eko/anomalous_dimensions/as2.py | 48 +++++++++++++++--------- tests/eko/test_ad_nlo.py | 22 ++++++----- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/eko/anomalous_dimensions/__init__.py b/src/eko/anomalous_dimensions/__init__.py index 6200c2018..3c25e58a7 100644 --- a/src/eko/anomalous_dimensions/__init__.py +++ b/src/eko/anomalous_dimensions/__init__.py @@ -109,18 +109,17 @@ def gamma_ns(order, mode, n, nf): gamma_ns[0] = as1.gamma_ns(n, sx[0]) # NLO and beyond if order >= 1: - # TODO: pass the necessary harmonics to nlo gammas + sx = np.append(sx, harmonics.S2(n)) if mode == 10101: - gamma_ns_1 = as2.gamma_nsp(n, nf) + gamma_ns_1 = as2.gamma_nsp(n, nf, sx) # To fill the full valence vector in NNLO we need to add gamma_ns^1 explicitly here elif mode in [10201, 10200]: - gamma_ns_1 = as2.gamma_nsm(n, nf) + gamma_ns_1 = as2.gamma_nsm(n, nf, sx) else: raise NotImplementedError("Non-singlet sector is not implemented") gamma_ns[1] = gamma_ns_1 # NNLO and beyond if order >= 2: - sx = np.append(sx, harmonics.S2(n)) sx = np.append(sx, harmonics.S3(n)) if mode == 10101: gamma_ns_2 = -as3.gamma_nsp(n, nf, sx) @@ -159,15 +158,13 @@ def gamma_singlet(order, n, nf): """ # cache the s-es sx = np.full(1, harmonics.S1(n)) - if order >= 1: - sx = np.append(sx, harmonics.S2(n)) - sx = np.append(sx, harmonics.S3(n)) - gamma_s = np.zeros((order + 1, 2, 2), np.complex_) gamma_s[0] = as1.gamma_singlet(n, sx[0], nf) if order >= 1: - gamma_s[1] = as2.gamma_singlet(n, nf) + sx = np.append(sx, harmonics.S2(n)) + gamma_s[1] = as2.gamma_singlet(n, nf, sx) if order == 2: + sx = np.append(sx, harmonics.S3(n)) sx = np.append(sx, harmonics.S4(n)) gamma_s[2] = -as3.gamma_singlet(n, nf, sx) return gamma_s diff --git a/src/eko/anomalous_dimensions/as2.py b/src/eko/anomalous_dimensions/as2.py index 6832cb8c8..59c42d626 100644 --- a/src/eko/anomalous_dimensions/as2.py +++ b/src/eko/anomalous_dimensions/as2.py @@ -15,7 +15,7 @@ @nb.njit(cache=True) -def gamma_nsm(n, nf): +def gamma_nsm(n, nf, sx): """ Computes the |NLO| valence-like non-singlet anomalous dimension. @@ -27,6 +27,8 @@ def gamma_nsm(n, nf): Mellin moment nf : int Number of active flavors + sx : numpy.ndarray + List of harmonic sums: :math:`S_{1},S_{2}` Returns ------- @@ -34,9 +36,8 @@ def gamma_nsm(n, nf): |NLO| valence-like non-singlet anomalous dimension :math:`\\gamma_{ns,-}^{(1)}(N)` """ - # TODO: use harmonics from cache - S1 = harmonics.S1(n) - S2 = harmonics.S2(n) + S1 = sx[0] + S2 = sx[1] # Here, Sp refers to S' ("s-prime") (german: "s-strich" or in Pegasus language: SSTR) # of :cite:`Gluck:1989ze` and NOT to the Spence function a.k.a. dilogarithm Sp1m = harmonics.S1((n - 1) / 2) @@ -57,7 +58,7 @@ def gamma_nsm(n, nf): @nb.njit(cache=True) -def gamma_nsp(n, nf): +def gamma_nsp(n, nf, sx): """ Computes the |NLO| singlet-like non-singlet anomalous dimension. @@ -69,6 +70,8 @@ def gamma_nsp(n, nf): Mellin moment nf : int Number of active flavors + sx : numpy.ndarray + List of harmonic sums: :math:`S_{1},S_{2}` Returns ------- @@ -76,8 +79,8 @@ def gamma_nsp(n, nf): |NLO| singlet-like non-singlet anomalous dimension :math:`\\gamma_{ns,+}^{(1)}(N)` """ - S1 = harmonics.S1(n) - S2 = harmonics.S2(n) + S1 = sx[0] + S2 = sx[1] Sp1p = harmonics.S1(n / 2) Sp2p = harmonics.S2(n / 2) Sp3p = harmonics.S3(n / 2) @@ -123,7 +126,7 @@ def gamma_ps(n, nf): @nb.njit(cache=True) -def gamma_qg(n, nf): +def gamma_qg(n, nf, sx): """ Computes the |NLO| quark-gluon singlet anomalous dimension. @@ -135,6 +138,8 @@ def gamma_qg(n, nf): Mellin moment nf : int Number of active flavors + sx : numpy.ndarray + List of harmonic sums: :math:`S_{1},S_{2}` Returns ------- @@ -142,8 +147,8 @@ def gamma_qg(n, nf): |NLO| quark-gluon singlet anomalous dimension :math:`\\gamma_{qg}^{(1)}(N)` """ - S1 = harmonics.S1(n) - S2 = harmonics.S2(n) + S1 = sx[0] + S2 = sx[1] Sp2p = harmonics.S2(n / 2) # fmt: off gqg1_nfca = (-4*(16 + n*(64 + n*(104 + n*(128 + n*(85 + n*(36 + n*(25 + n*(15 + n*(6 + n))))))))))/((-1 + n)*np.power(n,3)*np.power(1 + n,3)*np.power(2 + n,3)) - (16*(3 + 2*n)*S1)/np.power(2 + 3*n + np.power(n,2),2) + (4*(2 + n + np.power(n,2))*np.power(S1,2))/(n*(2 + 3*n + np.power(n,2))) - (4*(2 + n + np.power(n,2))*S2)/(n*(2 + 3*n + np.power(n,2))) + (4*(2 + n + np.power(n,2))*Sp2p)/(n*(2 + 3*n + np.power(n,2))) # pylint: disable=line-too-long @@ -156,7 +161,7 @@ def gamma_qg(n, nf): @nb.njit(cache=True) -def gamma_gq(n, nf): +def gamma_gq(n, nf, sx): """ Computes the |NLO| gluon-quark singlet anomalous dimension. @@ -168,6 +173,8 @@ def gamma_gq(n, nf): Mellin moment nf : int Number of active flavors + sx : numpy.ndarray + List of harmonic sums: :math:`S_{1},S_{2}` Returns ------- @@ -175,8 +182,8 @@ def gamma_gq(n, nf): |NLO| gluon-quark singlet anomalous dimension :math:`\\gamma_{gq}^{(1)}(N)` """ - S1 = harmonics.S1(n) - S2 = harmonics.S2(n) + S1 = sx[0] + S2 = sx[1] Sp2p = harmonics.S2(n / 2) # fmt: off ggq1_cfcf = (-8 + 2*n*(-12 + n*(-1 + n*(28 + n*(43 + 6*n*(5 + 2*n))))))/((-1 + n)*np.power(n,3)*np.power(1 + n,3)) - (4*(10 + n*(17 + n*(8 + 5*n)))*S1)/((-1 + n)*n*np.power(1 + n,2)) + (4*(2 + n + np.power(n,2))*np.power(S1,2))/(n*(-1 + np.power(n,2))) + (4*(2 + n + np.power(n,2))*S2)/(n*(-1 + np.power(n,2))) # pylint: disable=line-too-long @@ -192,7 +199,7 @@ def gamma_gq(n, nf): @nb.njit(cache=True) -def gamma_gg(n, nf): +def gamma_gg(n, nf, sx): """ Computes the |NLO| gluon-gluon singlet anomalous dimension. @@ -204,6 +211,8 @@ def gamma_gg(n, nf): Mellin moment nf : int Number of active flavors + sx : numpy.ndarray + List of harmonic sums: :math:`S_{1},S_{2}` Returns ------- @@ -211,7 +220,7 @@ def gamma_gg(n, nf): |NLO| gluon-gluon singlet anomalous dimension :math:`\\gamma_{gg}^{(1)}(N)` """ - S1 = harmonics.S1(n) + S1 = sx[0] Sp1p = harmonics.S1(n / 2) Sp2p = harmonics.S2(n / 2) Sp3p = harmonics.S3(n / 2) @@ -228,7 +237,7 @@ def gamma_gg(n, nf): @nb.njit(cache=True) -def gamma_singlet(N, nf): +def gamma_singlet(n, nf, sx): r""" Computes the next-leading-order singlet anomalous dimension matrix @@ -242,6 +251,8 @@ def gamma_singlet(N, nf): ---------- N : complex Mellin moment + sx : numpy.ndarray + List of harmonic sums: :math:`S_{1},S_{2}` nf : int Number of active flavors @@ -258,8 +269,9 @@ def gamma_singlet(N, nf): gamma_gq : :math:`\gamma_{gq}^{(1)}` gamma_gg : :math:`\gamma_{gg}^{(1)}` """ - gamma_qq = gamma_nsp(N, nf) + gamma_ps(N, nf) + gamma_qq = gamma_nsp(n, nf, sx) + gamma_ps(n, nf) gamma_S_0 = np.array( - [[gamma_qq, gamma_qg(N, nf)], [gamma_gq(N, nf), gamma_gg(N, nf)]], np.complex_ + [[gamma_qq, gamma_qg(n, nf, sx)], [gamma_gq(n, nf, sx), gamma_gg(n, nf, sx)]], + np.complex_, ) return gamma_S_0 diff --git a/tests/eko/test_ad_nlo.py b/tests/eko/test_ad_nlo.py index 10abde6de..e343d74cb 100644 --- a/tests/eko/test_ad_nlo.py +++ b/tests/eko/test_ad_nlo.py @@ -11,9 +11,11 @@ def test_gamma_1(): # number conservation - np.testing.assert_allclose(ad_as2.gamma_nsm(1, NF), 0.0, atol=2e-6) + sx = h.get_sx(1, 2) + np.testing.assert_allclose(ad_as2.gamma_nsm(1, NF, sx), 0.0, atol=2e-6) - gS1 = ad_as2.gamma_singlet(2, NF) + sx = h.get_sx(2, 2) + gS1 = ad_as2.gamma_singlet(2, NF, sx) # gluon momentum conservation # the CA*NF term seems to be tough to compute, so raise the constraint ... np.testing.assert_allclose(gS1[0, 1] + gS1[1, 1], 0.0, atol=4e-5) @@ -25,7 +27,7 @@ def test_gamma_1(): # reference values are obtained from MMa # Non singlet sector np.testing.assert_allclose( - ad_as2.gamma_nsp(2, NF), + ad_as2.gamma_nsp(2, NF, sx), (-112.0 * const.CF + 376.0 * const.CA - 64.0 * NF) * const.CF / 27.0, ) # singlet sector @@ -39,7 +41,7 @@ def test_gamma_1(): # add additional point at (analytical) continuation point np.testing.assert_allclose( - ad_as2.gamma_nsm(2, NF), + ad_as2.gamma_nsm(2, NF, sx), ( (34.0 / 27.0 * (-47.0 + 6 * np.pi**2) - 16.0 * h.constants.zeta3) * const.CF @@ -49,8 +51,10 @@ def test_gamma_1(): ) * const.CF, ) + sx_3 = h.get_sx(3, 2) + sx_4 = h.get_sx(4, 2) np.testing.assert_allclose( - ad_as2.gamma_nsp(3, NF), + ad_as2.gamma_nsp(3, NF, sx_3), ( (-34487.0 / 432.0 + 86.0 * np.pi**2 / 9.0 - 16.0 * h.constants.zeta3) * const.CF @@ -61,7 +65,7 @@ def test_gamma_1(): * const.CF, ) np.testing.assert_allclose(ad_as2.gamma_ps(3, NF), -1391.0 * const.CF * NF / 5400.0) - gS1 = ad_as2.gamma_singlet(3, NF) + gS1 = ad_as2.gamma_singlet(3, NF, sx_3) np.testing.assert_allclose( gS1[1, 0], ( @@ -81,7 +85,7 @@ def test_gamma_1(): ), rtol=6e-7, ) # gg - gS1 = ad_as2.gamma_singlet(4, NF) + gS1 = ad_as2.gamma_singlet(4, NF, sx_4) np.testing.assert_allclose( gS1[0, 1], (-56317.0 / 18000.0 * const.CF + 16387.0 / 9000.0 * const.CA) * NF ) # qg @@ -89,7 +93,7 @@ def test_gamma_1(): const.update_colors(4) np.testing.assert_allclose(const.CA, 4.0) - gS1 = ad_as2.gamma_singlet(3, NF) + gS1 = ad_as2.gamma_singlet(3, NF, sx_3) np.testing.assert_allclose( gS1[1, 0], ( @@ -109,7 +113,7 @@ def test_gamma_1(): ), rtol=6e-7, ) # gg - gS1 = ad_as2.gamma_singlet(4, NF) + gS1 = ad_as2.gamma_singlet(4, NF, sx_4) np.testing.assert_allclose( gS1[0, 1], (-56317.0 / 18000.0 * const.CF + 16387.0 / 9000.0 * const.CA) * NF ) # qg From fb75e69fece345d1f8a95361fa7139d908f3d047 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 17:01:00 +0200 Subject: [PATCH 10/47] Fix sx doc in as3 --- src/eko/anomalous_dimensions/as3.py | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/eko/anomalous_dimensions/as3.py b/src/eko/anomalous_dimensions/as3.py index 4e5f17090..49fe1cc0f 100644 --- a/src/eko/anomalous_dimensions/as3.py +++ b/src/eko/anomalous_dimensions/as3.py @@ -25,8 +25,8 @@ def gamma_nsm(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + sx : np.ndarray + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` Returns ------- @@ -102,8 +102,8 @@ def gamma_nsp(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + sx : np.ndarray + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` Returns ------- @@ -179,8 +179,8 @@ def gamma_nsv(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + sx : np.ndarray + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` Returns ------- @@ -234,8 +234,8 @@ def gamma_ps(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + sx : np.ndarray + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` Returns ------- @@ -306,8 +306,8 @@ def gamma_qg(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + sx : np.ndarray + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` Returns ------- @@ -380,8 +380,8 @@ def gamma_gq(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + sx : np.ndarray + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` Returns ------- @@ -470,8 +470,8 @@ def gamma_gg(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + sx : np.ndarray + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` Returns ------- @@ -562,8 +562,8 @@ def gamma_singlet(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + sx : np.ndarray + List of harmonic sums: :math:`S_{1},S_{2},S_{3}` Returns From 40e388edfde78b0dc9300eaa2fecea79c95705f5 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 17:22:11 +0200 Subject: [PATCH 11/47] fix docs in ope as1 and as2 --- src/eko/matching_conditions/as1.py | 6 ++++-- src/eko/matching_conditions/as2.py | 14 ++++++------- .../operator_matrix_element.py | 20 ++++++++++++++++--- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/eko/matching_conditions/as1.py b/src/eko/matching_conditions/as1.py index f327a0bb7..930da18d7 100644 --- a/src/eko/matching_conditions/as1.py +++ b/src/eko/matching_conditions/as1.py @@ -24,7 +24,7 @@ def A_hh(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -131,6 +131,8 @@ def A_singlet(n, sx, L): ---------- n : complex Mellin moment + sx : numpy.ndarray + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -173,7 +175,7 @@ def A_ns(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` Returns diff --git a/src/eko/matching_conditions/as2.py b/src/eko/matching_conditions/as2.py index dd11371b6..12360f1b1 100644 --- a/src/eko/matching_conditions/as2.py +++ b/src/eko/matching_conditions/as2.py @@ -29,7 +29,7 @@ def A_qq_ns(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -84,7 +84,7 @@ def A_hq_ps(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -148,7 +148,7 @@ def A_hg(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -287,7 +287,7 @@ def A_gq(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -337,7 +337,7 @@ def A_gg(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -430,7 +430,7 @@ def A_singlet(n, sx, L, is_msbar=False): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` is_msbar: bool @@ -479,7 +479,7 @@ def A_ns(n, sx, L): n : complex Mellin moment sx : numpy.ndarray - List of harmonic sums + harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index de5094205..398486ada 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -20,7 +20,21 @@ @nb.njit(cache=True) def compute_harmonics_cache(n, order): - """Get the harmonics sums cache""" + """ + Get the harmonics sums cache + + Parameters + ---------- + n: complex + Mellin moment + order: int + perturbative order + + Returns + ------- + sx: np.ndarray + harmonic sums cache + """ # max harmonics sum weight for each qcd order max_weight = {1: 2, 2: 3, 3: 5} # max number of harmonics sum of a given weight for each qcd order @@ -48,7 +62,7 @@ def A_singlet(order, n, sx, nf, L, is_msbar): n : complex Mellin variable sx : numpy.ndarray - List of harmonic sums + harmonic sums cache nf: int number of active flavor below threshold L : float @@ -92,7 +106,7 @@ def A_non_singlet(order, n, sx, nf, L): n : complex Mellin variable sx : numpy.ndarray - List of harmonic sums + harmonic sums cache nf: int number of active flavor below threshold L : float From b1d5b634a5c901524c5b3e6e04978a07852f9628 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 17:23:16 +0200 Subject: [PATCH 12/47] fix docs in as1 --- src/eko/anomalous_dimensions/as1.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/eko/anomalous_dimensions/as1.py b/src/eko/anomalous_dimensions/as1.py index 0c94d61d3..a178a3f08 100644 --- a/src/eko/anomalous_dimensions/as1.py +++ b/src/eko/anomalous_dimensions/as1.py @@ -19,7 +19,7 @@ def gamma_ns(N, s1): N : complex Mellin moment s1 : complex - S1(N) + harmonic sum :math:`S_{1}` Returns ------- @@ -89,7 +89,7 @@ def gamma_gg(N, s1, nf): N : complex Mellin moment s1 : complex - S1(N) + harmonic sum :math:`S_{1}` nf : int Number of active flavors @@ -119,7 +119,7 @@ def gamma_singlet(N, s1, nf): N : complex Mellin moment s1 : complex - S1(N) + harmonic sum :math:`S_{1}` nf : int Number of active flavors From 562f3c900959de6f00138987fe8b167f10eda1f2 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 30 Mar 2022 17:33:16 +0200 Subject: [PATCH 13/47] fix harmonics in benchmarks --- benchmarks/eko/benchmark_ad.py | 7 ++++--- benchmarks/lha_paper_bench.py | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/benchmarks/eko/benchmark_ad.py b/benchmarks/eko/benchmark_ad.py index 7db70149e..2aab23f3d 100644 --- a/benchmarks/eko/benchmark_ad.py +++ b/benchmarks/eko/benchmark_ad.py @@ -138,8 +138,9 @@ def check_gamma_1_pegasus(N, NF): P1NSP = CF * ((CF - CA / 2.0) * PNPA + CA * PNSB + TR * NF * PNSC) P1NSM = CF * ((CF - CA / 2.0) * PNMA + CA * PNSB + TR * NF * PNSC) - np.testing.assert_allclose(ad_as2.gamma_nsp(N, NF), -P1NSP) - np.testing.assert_allclose(ad_as2.gamma_nsm(N, NF), -P1NSM) + sx = h.get_sx(N, 2) + np.testing.assert_allclose(ad_as2.gamma_nsp(N, NF, sx), -P1NSP) + np.testing.assert_allclose(ad_as2.gamma_nsm(N, NF, sx), -P1NSM) NS = N * N NT = NS * N @@ -256,7 +257,7 @@ def check_gamma_1_pegasus(N, NF): P1Sgq = (CF * CF * PGQA + CF * CA * PGQB + TR * NF * CF * PGQC) * 4.0 P1Sgg = (CA * CA * PGGA + TR * NF * (CA * PGGB + CF * PGGC)) * 4.0 - gS1 = ad_as2.gamma_singlet(N, NF) + gS1 = ad_as2.gamma_singlet(N, NF, sx) np.testing.assert_allclose(gS1[0, 0], -P1Sqq) np.testing.assert_allclose(gS1[0, 1], -P1Sqg) np.testing.assert_allclose(gS1[1, 0], -P1Sgq) diff --git a/benchmarks/lha_paper_bench.py b/benchmarks/lha_paper_bench.py index b43ec8b2d..27573b721 100644 --- a/benchmarks/lha_paper_bench.py +++ b/benchmarks/lha_paper_bench.py @@ -224,12 +224,12 @@ def benchmark_sv(self, pto): # obj = BenchmarkVFNS() obj = BenchmarkFFNS() - obj.benchmark_plain(0) + # obj.benchmark_plain(0) # obj.benchmark_sv(2) # # VFNS benchmarks with LHA settings - # programs = ["LHA", "pegasus", "apfel"] - # for p in programs: - # obj = BenchmarkRunner(p) - # # obj.benchmark_plain(2) - # obj.benchmark_sv(2) + programs = ["LHA", "pegasus", "apfel"] + for p in programs: + obj = BenchmarkRunner(p) + # obj.benchmark_plain(2) + obj.benchmark_sv(2) From aafb65a57d9216f5cc4ddcfaccda7e8fc8d6f09d Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Thu, 31 Mar 2022 10:12:27 +0200 Subject: [PATCH 14/47] remove get_ --- src/eko/harmonics/__init__.py | 12 ++--- .../operator_matrix_element.py | 4 +- tests/eko/test_ad_nlo.py | 8 +-- tests/eko/test_ad_nnlo.py | 6 +-- tests/eko/test_harmonics.py | 6 +-- tests/eko/test_matching_n3lo.py | 50 +++++++++---------- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index 9abedc9f7..67700ec48 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -35,14 +35,14 @@ def base_harmonics_cache(n, max_weight=5, n_max_sums_weight=7): (weights, n_max_sums_weight) """ h_cache = np.zeros((max_weight, n_max_sums_weight), dtype=np.complex_) - h_cache[:, 0] = get_sx(n, max_weight) + h_cache[:, 0] = sx(n, max_weight) if n_max_sums_weight > 1: - h_cache[:, -1] = get_smx(n, max_weight) + h_cache[:, -1] = smx(n, max_weight) return h_cache @nb.njit(cache=True) -def get_sx(n, max_weight=5): +def sx(n, max_weight=5): """ Get the harmonics sums S cache @@ -72,7 +72,7 @@ def get_sx(n, max_weight=5): @nb.njit(cache=True) -def get_smx(n, max_weight=5): +def smx(n, max_weight=5): """ Get the harmonics S-minus cache @@ -103,7 +103,7 @@ def get_smx(n, max_weight=5): @nb.njit(cache=True) -def get_s3x(n, sx, smx): +def s3x(n, sx, smx): """ Compute the weight 3 multi indices harmonics sums cache @@ -132,7 +132,7 @@ def get_s3x(n, sx, smx): @nb.njit(cache=True) -def get_s4x(n, sx, smx): +def s4x(n, sx, smx): """ Compute the weight 4 multi indices harmonics sums cache diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index 398486ada..295f9def1 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -45,8 +45,8 @@ def compute_harmonics_cache(n, order): sx[2, 1] = harmonics.Sm21(n, sx[0, -1]) if order == 3: # Add weight 3 and 4 to cache - sx[2, 1:-2] = harmonics.get_s3x(n, sx[:, 0], sx[:, -1]) - sx[3, 1:-1] = harmonics.get_s4x(n, sx[:, 0], sx[:, -1]) + sx[2, 1:-2] = harmonics.s3x(n, sx[:, 0], sx[:, -1]) + sx[3, 1:-1] = harmonics.s4x(n, sx[:, 0], sx[:, -1]) return sx diff --git a/tests/eko/test_ad_nlo.py b/tests/eko/test_ad_nlo.py index e343d74cb..c6beae0cd 100644 --- a/tests/eko/test_ad_nlo.py +++ b/tests/eko/test_ad_nlo.py @@ -11,10 +11,10 @@ def test_gamma_1(): # number conservation - sx = h.get_sx(1, 2) + sx = h.sx(1, 2) np.testing.assert_allclose(ad_as2.gamma_nsm(1, NF, sx), 0.0, atol=2e-6) - sx = h.get_sx(2, 2) + sx = h.sx(2, 2) gS1 = ad_as2.gamma_singlet(2, NF, sx) # gluon momentum conservation # the CA*NF term seems to be tough to compute, so raise the constraint ... @@ -51,8 +51,8 @@ def test_gamma_1(): ) * const.CF, ) - sx_3 = h.get_sx(3, 2) - sx_4 = h.get_sx(4, 2) + sx_3 = h.sx(3, 2) + sx_4 = h.sx(4, 2) np.testing.assert_allclose( ad_as2.gamma_nsp(3, NF, sx_3), ( diff --git a/tests/eko/test_ad_nnlo.py b/tests/eko/test_ad_nnlo.py index 736064be5..0eedbfb4e 100644 --- a/tests/eko/test_ad_nnlo.py +++ b/tests/eko/test_ad_nnlo.py @@ -8,7 +8,7 @@ NF = 5 -def get_sx(N): +def sx(N): """Collect the S-cache""" sx = np.array( [ @@ -25,13 +25,13 @@ def get_sx(N): def test_gamma_2(): # number conservation - each is 0 on its own, see :cite:`Moch:2004pa` N = 1 - sx = get_sx(N) + sx = sx(N) np.testing.assert_allclose(ad_as3.gamma_nsv(N, NF, sx), 0.000960586, rtol=3e-7) np.testing.assert_allclose(ad_as3.gamma_nsm(N, NF, sx), -0.000594225, rtol=6e-7) # get singlet sector N = 2 - sx = get_sx(N) + sx = sx(N) gS2 = ad_as3.gamma_singlet(N, NF, sx) # gluon momentum conservation diff --git a/tests/eko/test_harmonics.py b/tests/eko/test_harmonics.py index 081727908..b68d87cad 100644 --- a/tests/eko/test_harmonics.py +++ b/tests/eko/test_harmonics.py @@ -23,7 +23,7 @@ def test_HarmonicsCache(): h.Sm5(N), ] ) - np.testing.assert_allclose(h.get_smx(N), smx_test) + np.testing.assert_allclose(h.smx(N), smx_test) s3x_test = np.array( [ h.S21(N, S1, S2), @@ -32,7 +32,7 @@ def test_HarmonicsCache(): h.Sm2m1(N, S1, S2, Sm2), ] ) - np.testing.assert_allclose(h.get_s3x(N, sx, smx_test), s3x_test) + np.testing.assert_allclose(h.s3x(N, sx, smx_test), s3x_test) Sm31 = h.Sm31(N, Sm1, Sm2) s4x_test = np.array( [ @@ -43,4 +43,4 @@ def test_HarmonicsCache(): Sm31, ] ) - np.testing.assert_allclose(h.get_s4x(N, sx, smx_test), s4x_test) + np.testing.assert_allclose(h.s4x(N, sx, smx_test), s4x_test) diff --git a/tests/eko/test_matching_n3lo.py b/tests/eko/test_matching_n3lo.py index fa9ddd6b6..b6ad0cc3c 100644 --- a/tests/eko/test_matching_n3lo.py +++ b/tests/eko/test_matching_n3lo.py @@ -2,7 +2,7 @@ # Test N3LO OME import numpy as np -from eko.harmonics import get_s3x, get_s4x, get_smx, get_sx +from eko.harmonics import s3x, s4x, smx, sx from eko.matching_conditions import as3 from eko.matching_conditions.as3 import A_ns, A_qqNS, A_singlet from eko.matching_conditions.operator_matrix_element import compute_harmonics_cache @@ -14,10 +14,10 @@ def test_A_3(): for L in logs: N = 1.0 - sx = get_sx(N) - smx = get_smx(N) - s3x = get_s3x(N, sx, smx) - s4x = get_s4x(N, sx, smx) + sx = sx(N) + smx = smx(N) + s3x = s3x(N, sx, smx) + s4x = s4x(N, sx, smx) aNSqq3 = A_qqNS(N, sx, smx, s3x, s4x, nf, L) # quark number conservation # the accuracy of this test depends directly on the precision of the @@ -26,10 +26,10 @@ def test_A_3(): np.testing.assert_allclose(aNSqq3, 0.0, atol=5e-3) N = 2.0 - sx = get_sx(N) - smx = get_smx(N) - s3x = get_s3x(N, sx, smx) - s4x = get_s4x(N, sx, smx) + sx = sx(N) + smx = smx(N) + s3x = s3x(N, sx, smx) + s4x = s4x(N, sx, smx) # reference value comes form Mathematica, gg is not fullycomplete # thus the reference value is not 0.0 # Here the accuracy of this test depends on the approximation of AggTF2 @@ -52,10 +52,10 @@ def test_A_3(): # ) # here you get division by 0 as in Mathematica - # sx_all = get_sx(N) - # sx_all = np.append(sx_all, get_smx(N)) - # sx_all = np.append(sx_all, get_s3x(N, get_sx(N),get_smx(N))) - # sx_all = np.append(sx_all, get_s4x(N, get_sx(N),get_smx(N))) + # sx_all = sx(N) + # sx_all = np.append(sx_all, smx(N)) + # sx_all = np.append(sx_all, s3x(N, sx(N),smx(N))) + # sx_all = np.append(sx_all, s4x(N, sx(N),smx(N))) # aS3 = A_singlet(N, sx_all, nf, L) # gluon momentum conservation # np.testing.assert_allclose(aS3[0, 0] + aS3[1, 0] + aS3[2, 0], 0.0, atol=2e-6) @@ -178,10 +178,10 @@ def test_Blumlein_3(): nf = 3 ref_ggTF_app = [-28.9075, -180.659, -229.537, -281.337, -467.164] for idx, N in enumerate([2.0, 4.0, 6.0, 10.0, 100.0]): - sx = get_sx(N) - smx = get_smx(N) - s3x = get_s3x(N, sx, smx) - s4x = get_s4x(N, sx, smx) + sx = sx(N) + smx = smx(N) + s3x = s3x(N, sx, smx) + s4x = s4x(N, sx, smx) Aggtf2 = as3.aggTF2.A_ggTF2(N, sx, s3x) if N != 100: # Limited in the small N region @@ -198,10 +198,10 @@ def test_Blumlein_3(): # Limited accuracy due to F functions ref_qqNS_odd = [-40.94998646588999, -21.598793547423504, 6.966325573931755] for N, ref in zip([3.0, 15.0, 101.0], ref_qqNS_odd): - sx = get_sx(N) - smx = get_smx(N) - s3x = get_s3x(N, sx, smx) - s4x = get_s4x(N, sx, smx) + sx = sx(N) + smx = smx(N) + s3x = s3x(N, sx, smx) + s4x = s4x(N, sx, smx) np.testing.assert_allclose( as3.aqqNS.A_qqNS(N, sx, smx, s3x, s4x, nf, L=0), ref, rtol=3e-2 ) @@ -251,10 +251,10 @@ def test_AHq_asymptotic(): # Ns = [31.,32.,33.,34.,35.,36.,37.,38.,39.] nf = 3 for N, r in zip(Ns, refs): - sx = get_sx(N) - smx = get_smx(N) - s3x = get_s3x(N, sx, smx) - s4x = get_s4x(N, sx, smx) + sx = sx(N) + smx = smx(N) + s3x = s3x(N, sx, smx) + s4x = s4x(N, sx, smx) np.testing.assert_allclose( as3.aHq.A_Hq(N, sx, smx, s3x, s4x, nf, L=0), r, rtol=1e-5, atol=1e-5 ) From 25c744a727251bcc6669e24a87f69576c54ccef5 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Thu, 31 Mar 2022 10:12:57 +0200 Subject: [PATCH 15/47] use sx in ad init --- src/eko/anomalous_dimensions/__init__.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/eko/anomalous_dimensions/__init__.py b/src/eko/anomalous_dimensions/__init__.py index 3c25e58a7..f1e9edba8 100644 --- a/src/eko/anomalous_dimensions/__init__.py +++ b/src/eko/anomalous_dimensions/__init__.py @@ -103,13 +103,12 @@ def gamma_ns(order, mode, n, nf): eko.anomalous_dimensions.as3.gamma_nsv : :math:`\gamma_{ns,v}^{(2)}(N)` """ # cache the s-es - sx = np.full(1, harmonics.S1(n)) + sx = harmonics.sx(n, max_weight=order + 1) # now combine gamma_ns = np.zeros(order + 1, np.complex_) gamma_ns[0] = as1.gamma_ns(n, sx[0]) # NLO and beyond if order >= 1: - sx = np.append(sx, harmonics.S2(n)) if mode == 10101: gamma_ns_1 = as2.gamma_nsp(n, nf, sx) # To fill the full valence vector in NNLO we need to add gamma_ns^1 explicitly here @@ -120,7 +119,6 @@ def gamma_ns(order, mode, n, nf): gamma_ns[1] = gamma_ns_1 # NNLO and beyond if order >= 2: - sx = np.append(sx, harmonics.S3(n)) if mode == 10101: gamma_ns_2 = -as3.gamma_nsp(n, nf, sx) elif mode == 10201: @@ -157,14 +155,12 @@ def gamma_singlet(order, n, nf): eko.anomalous_dimensions.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` """ # cache the s-es - sx = np.full(1, harmonics.S1(n)) + sx = harmonics.sx(n, max_weight=order + 1) gamma_s = np.zeros((order + 1, 2, 2), np.complex_) gamma_s[0] = as1.gamma_singlet(n, sx[0], nf) if order >= 1: - sx = np.append(sx, harmonics.S2(n)) gamma_s[1] = as2.gamma_singlet(n, nf, sx) if order == 2: - sx = np.append(sx, harmonics.S3(n)) sx = np.append(sx, harmonics.S4(n)) gamma_s[2] = -as3.gamma_singlet(n, nf, sx) return gamma_s From c072ebf9b75a2c37fd0113884c64986b2a4a5368 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Thu, 31 Mar 2022 10:13:30 +0200 Subject: [PATCH 16/47] fix benchmarks --- benchmarks/eko/benchmark_ad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/eko/benchmark_ad.py b/benchmarks/eko/benchmark_ad.py index 2aab23f3d..d29b704f7 100644 --- a/benchmarks/eko/benchmark_ad.py +++ b/benchmarks/eko/benchmark_ad.py @@ -138,7 +138,7 @@ def check_gamma_1_pegasus(N, NF): P1NSP = CF * ((CF - CA / 2.0) * PNPA + CA * PNSB + TR * NF * PNSC) P1NSM = CF * ((CF - CA / 2.0) * PNMA + CA * PNSB + TR * NF * PNSC) - sx = h.get_sx(N, 2) + sx = h.sx(N, 2) np.testing.assert_allclose(ad_as2.gamma_nsp(N, NF, sx), -P1NSP) np.testing.assert_allclose(ad_as2.gamma_nsm(N, NF, sx), -P1NSM) From 1eb8ef295ec8c9aecf81741e30b3821daaf65601 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Thu, 31 Mar 2022 10:55:36 +0200 Subject: [PATCH 17/47] remove old stuff in test ad nnlo --- tests/eko/test_ad_nnlo.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/tests/eko/test_ad_nnlo.py b/tests/eko/test_ad_nnlo.py index 0eedbfb4e..071c9c3bf 100644 --- a/tests/eko/test_ad_nnlo.py +++ b/tests/eko/test_ad_nnlo.py @@ -3,35 +3,22 @@ import numpy as np import eko.anomalous_dimensions.as3 as ad_as3 -from eko import harmonics +from eko import harmonics as h NF = 5 -def sx(N): - """Collect the S-cache""" - sx = np.array( - [ - harmonics.S1(N), - harmonics.S2(N), - harmonics.S3(N), - harmonics.S4(N), - ] - ) - return sx - - # Reference numbers coming from Mathematica def test_gamma_2(): # number conservation - each is 0 on its own, see :cite:`Moch:2004pa` N = 1 - sx = sx(N) + sx = h.sx(N, max_weight=3) np.testing.assert_allclose(ad_as3.gamma_nsv(N, NF, sx), 0.000960586, rtol=3e-7) np.testing.assert_allclose(ad_as3.gamma_nsm(N, NF, sx), -0.000594225, rtol=6e-7) # get singlet sector N = 2 - sx = sx(N) + sx = h.sx(N, max_weight=4) gS2 = ad_as3.gamma_singlet(N, NF, sx) # gluon momentum conservation From d782a61ccc952e394533ccd20e2c81f49eea1f86 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Thu, 31 Mar 2022 10:57:28 +0200 Subject: [PATCH 18/47] start reordering harmonics in ome as3 --- src/eko/matching_conditions/as3/__init__.py | 12 +++-- src/eko/matching_conditions/as3/agg.py | 20 +++------ src/eko/matching_conditions/as3/aggTF2.py | 8 ++-- tests/eko/test_matching_n3lo.py | 50 +++++++++++---------- 4 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/eko/matching_conditions/as3/__init__.py index bd8387b7c..f70becdad 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/eko/matching_conditions/as3/__init__.py @@ -56,8 +56,14 @@ def A_singlet(n, sx_all, nf, L): n : complex Mellin moment sx_all : numpy.ndarray - List of harmonic sums containing: - [S1 ... S5, Sm1 ... Sm5, S21, S2m1, Sm21, Sm2m1, S31, S221, Sm22, Sm211, Sm31] + harmonic sums cache containing: + [ + [S1, 0, 0, 0, 0, 0, Sm1], + [S2, 0, 0, 0, 0, 0, Sm2], + [S3, S21, S2m1, Sm21, Sm2m1, 0, Sm3], + [S4, S31, S221, Sm22, Sm211, Sm31 Sm4], + [S5, 0, 0, 0, 0, 0, Sm5], + ] nf : int number of active flavor below the threshold L : float @@ -76,7 +82,7 @@ def A_singlet(n, sx_all, nf, L): A_hg_3 = A_Hg(n, sx, smx, s3x, s4x, nf, L) A_gq_3 = A_gq(n, sx, smx, s3x, s4x, nf, L) - A_gg_3 = A_gg(n, sx, smx, s3x, s4x, nf, L) + A_gg_3 = A_gg(n, sx_all, nf, L) A_qq_ps_3 = A_qqPS(n, sx, nf, L) A_qq_ns_3 = A_qqNS(n, sx, smx, s3x, s4x, nf, L) diff --git a/src/eko/matching_conditions/as3/agg.py b/src/eko/matching_conditions/as3/agg.py index 3a0da1e06..466c24a15 100644 --- a/src/eko/matching_conditions/as3/agg.py +++ b/src/eko/matching_conditions/as3/agg.py @@ -7,7 +7,7 @@ @nb.njit(cache=True) -def A_gg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals +def A_gg(n, sx, nf, L): # pylint: disable=too-many-locals r""" Computes the |N3LO| singlet |OME| :math:`A_{gg}^{S,(3)}(N)`. The experssion is presented in :cite:`Bierenbaum:2009mv`. @@ -20,13 +20,7 @@ def A_gg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals n : complex Mellin moment sx : numpy.ndarray - list S1 ... S5 - smx : numpy.ndarray - list Sm1 ... Sm5 - s3x : numpy.ndarray - list S21, S2m1, Sm21, Sm2m1 - s4x : numpy.ndarray - list S31, S221, Sm22, Sm211, Sm31 + harmonic sums cache nf : int number of active flavor below the threshold L : float @@ -42,13 +36,13 @@ def A_gg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals A_ggTF2: eko.matching_conditions.as3.aggTF2.A_ggTF2 Incomplete part proportional to :math:`T_{F}^2`. """ - S1, S2, S3, S4 = sx[0], sx[1], sx[2], sx[3] - Sm2, Sm3, Sm4 = smx[1], smx[2], smx[3] - S21, Sm21 = s3x[0], s3x[2] - S31, S211, Sm22, Sm211, Sm31 = s4x[0], s4x[1], s4x[2], s4x[3], s4x[4] + S1, S2, S3, S4 = sx[:4, 0] + Sm2, Sm3, Sm4 = sx[1:4, -1] + S21, Sm21 = sx[2, 1], sx[2, 3] + S31, S211, Sm22, Sm211, Sm31 = sx[3, 1:6] a_gg_l0 = ( -0.35616500834358344 - + A_ggTF2(n, sx, s3x) + + A_ggTF2(n, sx) + 0.75 * ( (-19.945240467240673 * (1.0 + n + np.power(n, 2))) diff --git a/src/eko/matching_conditions/as3/aggTF2.py b/src/eko/matching_conditions/as3/aggTF2.py index 9528755ad..f1d439841 100644 --- a/src/eko/matching_conditions/as3/aggTF2.py +++ b/src/eko/matching_conditions/as3/aggTF2.py @@ -4,7 +4,7 @@ @nb.njit(cache=True) -def A_ggTF2(n, sx, s3x): +def A_ggTF2(n, sx): r""" Computes the approximate incomplete part of :math:`A_{gg}^{S,(3)}(N)` proportional to :math:`T_{F}^2`. @@ -19,7 +19,7 @@ def A_ggTF2(n, sx, s3x): n : complex Mellin moment sx : numpy.ndarray - list S1 ... S5 + harmonic sums cache s3x : numpy.ndarray list S21, S2m1, Sm21, Sm2m1 @@ -28,8 +28,8 @@ def A_ggTF2(n, sx, s3x): A_ggTF2 : complex :math:`A_{gg,T_{F}^2}^{S,(3)}(N)` """ - S1, S2, S3 = sx[0], sx[1], sx[2] - S21 = s3x[0] + S1, S2, S3 = sx[:3, 0] + S21 = sx[2, 1] # here we use an approximation at large N # for binomial(2 * n, n) / np.power(4, n) # faster than the exact result diff --git a/tests/eko/test_matching_n3lo.py b/tests/eko/test_matching_n3lo.py index b6ad0cc3c..aecafd640 100644 --- a/tests/eko/test_matching_n3lo.py +++ b/tests/eko/test_matching_n3lo.py @@ -2,7 +2,7 @@ # Test N3LO OME import numpy as np -from eko.harmonics import s3x, s4x, smx, sx +from eko import harmonics as h from eko.matching_conditions import as3 from eko.matching_conditions.as3 import A_ns, A_qqNS, A_singlet from eko.matching_conditions.operator_matrix_element import compute_harmonics_cache @@ -14,10 +14,10 @@ def test_A_3(): for L in logs: N = 1.0 - sx = sx(N) - smx = smx(N) - s3x = s3x(N, sx, smx) - s4x = s4x(N, sx, smx) + sx = h.sx(N) + smx = h.smx(N) + s3x = h.s3x(N, sx, smx) + s4x = h.s4x(N, sx, smx) aNSqq3 = A_qqNS(N, sx, smx, s3x, s4x, nf, L) # quark number conservation # the accuracy of this test depends directly on the precision of the @@ -26,15 +26,16 @@ def test_A_3(): np.testing.assert_allclose(aNSqq3, 0.0, atol=5e-3) N = 2.0 - sx = sx(N) - smx = smx(N) - s3x = s3x(N, sx, smx) - s4x = s4x(N, sx, smx) + sx_cache = compute_harmonics_cache(N, 3) + sx = h.sx(N) + smx = h.smx(N) + s3x = h.s3x(N, sx, smx) + s4x = h.s4x(N, sx, smx) # reference value comes form Mathematica, gg is not fullycomplete # thus the reference value is not 0.0 # Here the accuracy of this test depends on the approximation of AggTF2 np.testing.assert_allclose( - as3.A_gg(N, sx, smx, s3x, s4x, nf, L) + as3.A_gg(N, sx_cache, nf, L) + as3.A_qg(N, sx, smx, s3x, s4x, nf, L) + as3.A_Hg(N, sx, smx, s3x, s4x, nf, L), 145.148, @@ -178,18 +179,19 @@ def test_Blumlein_3(): nf = 3 ref_ggTF_app = [-28.9075, -180.659, -229.537, -281.337, -467.164] for idx, N in enumerate([2.0, 4.0, 6.0, 10.0, 100.0]): - sx = sx(N) - smx = smx(N) - s3x = s3x(N, sx, smx) - s4x = s4x(N, sx, smx) - Aggtf2 = as3.aggTF2.A_ggTF2(N, sx, s3x) + sx_cache = compute_harmonics_cache(N, 3) + sx = h.sx(N) + smx = h.smx(N) + s3x = h.s3x(N, sx, smx) + s4x = h.s4x(N, sx, smx) + Aggtf2 = as3.aggTF2.A_ggTF2(N, sx_cache) if N != 100: # Limited in the small N region np.testing.assert_allclose(Aggtf2, ref_val_ggTF2[0][idx], rtol=15e-2) np.testing.assert_allclose(Aggtf2, ref_ggTF_app[idx], rtol=2e-4) np.testing.assert_allclose( - as3.agg.A_gg(N, sx, smx, s3x, s4x, nf, L=0) - Aggtf2, + as3.agg.A_gg(N, sx_cache, nf, L=0) - Aggtf2, ref_val_gg[0][idx], rtol=3e-6, ) @@ -198,10 +200,10 @@ def test_Blumlein_3(): # Limited accuracy due to F functions ref_qqNS_odd = [-40.94998646588999, -21.598793547423504, 6.966325573931755] for N, ref in zip([3.0, 15.0, 101.0], ref_qqNS_odd): - sx = sx(N) - smx = smx(N) - s3x = s3x(N, sx, smx) - s4x = s4x(N, sx, smx) + sx = h.sx(N) + smx = h.smx(N) + s3x = h.s3x(N, sx, smx) + s4x = h.s4x(N, sx, smx) np.testing.assert_allclose( as3.aqqNS.A_qqNS(N, sx, smx, s3x, s4x, nf, L=0), ref, rtol=3e-2 ) @@ -251,10 +253,10 @@ def test_AHq_asymptotic(): # Ns = [31.,32.,33.,34.,35.,36.,37.,38.,39.] nf = 3 for N, r in zip(Ns, refs): - sx = sx(N) - smx = smx(N) - s3x = s3x(N, sx, smx) - s4x = s4x(N, sx, smx) + sx = h.sx(N) + smx = h.smx(N) + s3x = h.s3x(N, sx, smx) + s4x = h.s4x(N, sx, smx) np.testing.assert_allclose( as3.aHq.A_Hq(N, sx, smx, s3x, s4x, nf, L=0), r, rtol=1e-5, atol=1e-5 ) From ce590bb0ea3ce6ffd223f2c831c5d39d58ada763 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Thu, 31 Mar 2022 17:16:46 +0200 Subject: [PATCH 19/47] add recursive relation for S sums and propagate cached S1,S2,S3 to g_functions --- benchmarks/eko/benchmark_ad.py | 2 +- src/eko/anomalous_dimensions/as2.py | 6 +- src/eko/harmonics/__init__.py | 12 +-- src/eko/harmonics/g_functions.py | 82 +++++++++++++------ src/eko/harmonics/polygamma.py | 28 +++++++ src/eko/harmonics/w3.py | 27 +++--- src/eko/harmonics/w4.py | 51 +++++++----- src/eko/harmonics/w5.py | 74 ++++++++--------- .../operator_matrix_element.py | 2 +- tests/eko/test_f_functions.py | 4 +- tests/eko/test_g_functions.py | 69 ++++++++-------- tests/eko/test_harmonics.py | 10 +-- tests/eko/test_polygamma.py | 16 ++++ tests/eko/test_s_functions.py | 3 +- 14 files changed, 245 insertions(+), 141 deletions(-) diff --git a/benchmarks/eko/benchmark_ad.py b/benchmarks/eko/benchmark_ad.py index d29b704f7..6ccd12547 100644 --- a/benchmarks/eko/benchmark_ad.py +++ b/benchmarks/eko/benchmark_ad.py @@ -39,7 +39,7 @@ def check_melling_g3_pegasus(N): - 0.3174 * (zeta2 - S15 / N5) / N5 + 0.0699 * (zeta2 - S16 / N6) / N6 ) - np.testing.assert_allclose(h.g_functions.mellin_g3(N), SPMOM) + np.testing.assert_allclose(h.g_functions.mellin_g3(N, S1), SPMOM) @pytest.mark.isolated diff --git a/src/eko/anomalous_dimensions/as2.py b/src/eko/anomalous_dimensions/as2.py index 59c42d626..4dd6088c5 100644 --- a/src/eko/anomalous_dimensions/as2.py +++ b/src/eko/anomalous_dimensions/as2.py @@ -43,7 +43,7 @@ def gamma_nsm(n, nf, sx): Sp1m = harmonics.S1((n - 1) / 2) Sp2m = harmonics.S2((n - 1) / 2) Sp3m = harmonics.S3((n - 1) / 2) - g3n = harmonics.g_functions.mellin_g3(n) + g3n = harmonics.g_functions.mellin_g3(n, S1) # fmt: off gqq1m_cfca = 16*g3n - (144 + n*(1 + n)*(156 + n*(340 + n*(655 + 51*n*(2 + n)))))/(18.*np.power(n,3)*np.power(1 + n,3)) + (-14.666666666666666 + 8/n - 8/(1 + n))*S2 - (4*Sp2m)/(n + np.power(n,2)) + S1*(29.77777777777778 + 16/np.power(n,2) - 16*S2 + 8*Sp2m) + 2*Sp3m + 10*zeta3 + zeta2*(16*S1 - 16*Sp1m - (16*(1 + n*log2))/n) # pylint: disable=line-too-long gqq1m_cfcf = -32*g3n + (24 - n*(-32 + 3*n*(-8 + n*(3 + n)*(3 + np.power(n,2)))))/(2.*np.power(n,3)*np.power(1 + n,3)) + (12 - 8/n + 8/(1 + n))*S2 + S1*(-24/np.power(n,2) - 8/np.power(1 + n,2) + 16*S2 - 16*Sp2m) + (8*Sp2m)/(n + np.power(n,2)) - 4*Sp3m - 20*zeta3 + zeta2*(-32*S1 + 32*Sp1m + 32*(1/n + log2)) # pylint: disable=line-too-long @@ -84,7 +84,7 @@ def gamma_nsp(n, nf, sx): Sp1p = harmonics.S1(n / 2) Sp2p = harmonics.S2(n / 2) Sp3p = harmonics.S3(n / 2) - g3n = harmonics.g_functions.mellin_g3(n) + g3n = harmonics.g_functions.mellin_g3(n, S1) # fmt: off gqq1p_cfca = -16*g3n + (132 - n*(340 + n*(655 + 51*n*(2 + n))))/(18.*np.power(n,2)*np.power(1 + n,2)) + (-14.666666666666666 + 8/n - 8/(1 + n))*S2 - (4*Sp2p)/(n + np.power(n,2)) + S1*(29.77777777777778 - 16/np.power(n,2) - 16*S2 + 8*Sp2p) + 2*Sp3p + 10*zeta3 + zeta2*(16*S1 - 16*Sp1p + 16*(1/n - log2)) # pylint: disable=line-too-long gqq1p_cfcf = 32*g3n - (8 + n*(32 + n*(40 + 3*n*(3 + n)*(3 + np.power(n,2)))))/(2.*np.power(n,3)*np.power(1 + n,3)) + (12 - 8/n + 8/(1 + n))*S2 + S1*(40/np.power(n,2) - 8/np.power(1 + n,2) + 16*S2 - 16*Sp2p) + (8*Sp2p)/(n + np.power(n,2)) - 4*Sp3p - 20*zeta3 + zeta2*(-32*S1 + 32*Sp1p + 32*(-(1/n) + log2)) # pylint: disable=line-too-long @@ -224,7 +224,7 @@ def gamma_gg(n, nf, sx): Sp1p = harmonics.S1(n / 2) Sp2p = harmonics.S2(n / 2) Sp3p = harmonics.S3(n / 2) - g3n = harmonics.g_functions.mellin_g3(n) + g3n = harmonics.g_functions.mellin_g3(n, S1) # fmt: off ggg1_caca = 16*g3n - (2*(576 + n*(1488 + n*(560 + n*(-1248 + n*(-1384 + n*(1663 + n*(4514 + n*(4744 + n*(3030 + n*(1225 + 48*n*(7 + n))))))))))))/(9.*np.power(-1 + n,2)*np.power(n,3)*np.power(1 + n,3)*np.power(2 + n,3)) + S1*(29.77777777777778 + 16/np.power(-1 + n,2) + 16/np.power(1 + n,2) - 16/np.power(2 + n,2) - 8*Sp2p) + (16*(1 + n + np.power(n,2))*Sp2p)/(n*(1 + n)*(-2 + n + np.power(n,2))) - 2*Sp3p - 10*zeta3 + zeta2*(-16*S1 + 16*Sp1p + 16*(-(1/n) + log2)) # pylint: disable=line-too-long ggg1_canf = (8*(6 + n*(1 + n)*(28 + n*(1 + n)*(13 + 3*n*(1 + n)))))/(9.*np.power(n,2)*np.power(1 + n,2)*(-2 + n + np.power(n,2))) - (40*S1)/9. # pylint: disable=line-too-long diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index 67700ec48..4a8e3ac16 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -125,7 +125,7 @@ def s3x(n, sx, smx): [ S21(n, sx[0], sx[1]), S2m1(n, sx[1], smx[0], smx[1]), - Sm21(n, smx[0]), + Sm21(n, sx[0], smx[0]), Sm2m1(n, sx[0], sx[1], smx[1]), ] ) @@ -150,13 +150,13 @@ def s4x(n, sx, smx): s4x: np.ndarray list containing: :math:`S_{3,1},S_{2,1,1},S_{-2,2},S_{-2,1,1},S_{-3,1}` """ - sm31 = Sm31(n, smx[0], smx[1]) + sm31 = Sm31(n, sx[0], smx[0], smx[1]) return np.array( [ - S31(n, sx[1], sx[3]), + S31(n, sx[0], sx[1], sx[3]), S211(n, sx[0], sx[1], sx[2]), - Sm22(n, smx[1], sm31), - Sm211(n, smx[0]), - Sm31(n, smx[0], smx[1]), + Sm22(n, sx[0], smx[1], sm31), + Sm211(n, sx[0], sx[1], smx[0]), + Sm31(n, sx[0], smx[0], smx[1]), ] ) diff --git a/src/eko/harmonics/g_functions.py b/src/eko/harmonics/g_functions.py index c075303ba..fa518ca33 100644 --- a/src/eko/harmonics/g_functions.py +++ b/src/eko/harmonics/g_functions.py @@ -6,9 +6,10 @@ import numba as nb import numpy as np -from . import w1, w2, w3 +from . import w1 from .constants import log2, zeta2, zeta3 from .polygamma import cern_polygamma +from .polygamma import recursive_harmonic_sum as harmonic_sum a1 = np.array( [ @@ -63,7 +64,7 @@ @nb.njit(cache=True) -def mellin_g3(N): +def mellin_g3(N, S1): r""" Computes the Mellin transform of :math:`\text{Li}_2(x)/(1+x)`. @@ -75,6 +76,8 @@ def mellin_g3(N): ---------- N : complex Mellin moment + S1: complex + Harmonic sum :math:`S_{1}(N)` Returns ------- @@ -90,7 +93,7 @@ def mellin_g3(N): g3 = 0 for j, c in enumerate(cs): Nj = N + j - g3 += c * (zeta2 - w1.S1(Nj) / Nj) / Nj + g3 += c * (zeta2 - harmonic_sum(S1, N, j, 1) / Nj) / Nj return g3 @@ -122,7 +125,7 @@ def mellin_g4(N): @nb.njit(cache=True) -def mellin_g5(N): +def mellin_g5(N, S1): r""" Computes the Mellin transform of :math:`(\text{Li}_2(x)ln(x))/(1+x)`. @@ -133,6 +136,8 @@ def mellin_g5(N): ---------- N : complex Mellin moment + S1: complex + Harmonic sum :math:`S_{1}(N)` Returns ------- @@ -143,13 +148,19 @@ def mellin_g5(N): for k, ak in enumerate(a1): Nk = N + k + 1 g5 -= ak * ( - (k + 1) / Nk**2 * (zeta2 + cern_polygamma(Nk + 1, 1) - 2 * w1.S1(Nk) / Nk) + (k + 1) + / Nk**2 + * ( + zeta2 + + cern_polygamma(Nk + 1, 1) + - 2 * harmonic_sum(S1, N, k + 1, 1) / Nk + ) ) return g5 @nb.njit(cache=True) -def mellin_g6(N): +def mellin_g6(N, S1): r""" Computes the Mellin transform of :math:`\text{Li}_3(x)/(1+x)`. @@ -160,6 +171,8 @@ def mellin_g6(N): ---------- N : complex Mellin moment + S1: complex + Harmonic sum :math:`S_{1}(N)` Returns ------- @@ -171,12 +184,15 @@ def mellin_g6(N): g6 = zeta3 * log2 for k, ak in enumerate(a1): Nk = N + k + 1 - g6 -= ak * (N / Nk * zeta3 + (k + 1) / Nk**2 * (zeta2 - w1.S1(Nk) / Nk)) + g6 -= ak * ( + N / Nk * zeta3 + + (k + 1) / Nk**2 * (zeta2 - harmonic_sum(S1, N, k + 1, 1) / Nk) + ) return g6 @nb.njit(cache=True) -def mellin_g8(N): +def mellin_g8(N, S1, S2): r""" Computes the Mellin transform of :math:`S_{1,2}(x)/(1+x)`. @@ -187,6 +203,10 @@ def mellin_g8(N): ---------- N : complex Mellin moment + S1: complex + Harmonic sum :math:`S_{1}(N)` + S2: complex + Harmonic sum :math:`S_{2}(N)` Returns ------- @@ -197,7 +217,12 @@ def mellin_g8(N): for k, ak in enumerate(a1): Nk = N + k + 1 g8 -= ak * ( - N / Nk * zeta3 + (k + 1) / Nk**2 * 1 / 2 * (w1.S1(Nk) ** 2 + w2.S2(Nk)) + N / Nk * zeta3 + + (k + 1) + / Nk**2 + * 1 + / 2 + * (harmonic_sum(S1, N, k + 1, 1) ** 2 + harmonic_sum(S2, N, k + 1, 2)) ) return g8 @@ -219,9 +244,9 @@ def mellin_g18(N, S1, S2): N : complex Mellin moment S1 : complex - harmonics.S1(N) + Harmonic sum :math:`S_{1}(N)` S2 : complex - harmonics.S2(N) + Harmonic sum :math:`S_{2}(N)` Returns ------- mellin_g18 : complex @@ -230,10 +255,15 @@ def mellin_g18(N, S1, S2): g18 = (S1**2 + S2) / (N) - zeta2 * S1 for k, ck in enumerate(c1): Nk = N + k - g18 += ck * (N) / (Nk) * w1.S1(Nk) + g18 += ck * (N) / (Nk) * harmonic_sum(S1, N, k, 1) for k, p11k in enumerate(p11): Nk = N + k - g18 -= p11k * (N) / (Nk) * (w1.S1(Nk) ** 2 + w2.S2(Nk)) + g18 -= ( + p11k + * (N) + / (Nk) + * (harmonic_sum(S1, N, k, 1) ** 2 + harmonic_sum(S2, N, k, 2)) + ) return g18 @@ -250,7 +280,7 @@ def mellin_g19(N, S1): N : complex Mellin moment S1 : complex - harmonics.S1(N) + Harmonic sum :math:`S_{1}(N)` Returns ------- @@ -260,7 +290,7 @@ def mellin_g19(N, S1): g19 = 1 / 2 * zeta2 * S1 for k, ak in enumerate(a1): Nk = N + k - g19 -= ak / (k + 1) * w1.S1(Nk + 1) + g19 -= ak / (k + 1) * harmonic_sum(S1, N, k + 1, 1) return g19 @@ -282,11 +312,11 @@ def mellin_g21(N, S1, S2, S3): N : complex Mellin moment S1 : complex - harmonics.S1(N) + Harmonic sum :math:`S_{1}(N)` S2 : complex - harmonics.S2(N) + Harmonic sum :math:`S_{2}(N)` S3 : complex - harmonics.S3(N) + Harmonic sum :math:`S_{3}(N)` Returns ------- @@ -296,22 +326,25 @@ def mellin_g21(N, S1, S2, S3): g21 = -zeta3 * S1 + (S1**3 + 3 * S1 * S2 + 2 * S3) / (2 * N) for k, ck in enumerate(c3): Nk = N + k - g21 += ck * N / Nk * w1.S1(Nk) + g21 += ck * N / Nk * harmonic_sum(S1, N, k, 1) for k in range(0, 5): Nk = N + k + S1nk = harmonic_sum(S1, N, k, 1) + S2nk = harmonic_sum(S2, N, k, 2) + S3nk = harmonic_sum(S3, N, k, 3) g21 += ( N / Nk * ( - p32[k] * (w1.S1(Nk) ** 3 + 3 * w1.S1(Nk) * w2.S2(Nk) + 2 * w3.S3(Nk)) - - p31[k] * (w1.S1(Nk) ** 2 + w2.S2(Nk)) + p32[k] * (S1nk**3 + 3 * S1nk * S2nk + 2 * S3nk) + - p31[k] * (S1nk**2 + S2nk) ) ) return g21 @nb.njit(cache=True) -def mellin_g22(N): +def mellin_g22(N, S1): r""" Computes the Mellin transform of :math:`-(\text{Li}_2(x) ln(x))/(1-x)`. @@ -326,6 +359,8 @@ def mellin_g22(N): ---------- N : complex Mellin moment + S1 : complex + Harmonic sum :math:`S_{1}(N)` Returns ------- @@ -339,6 +374,7 @@ def mellin_g22(N): for k, p11k in enumerate(p11): Nk = N + k g22 -= p11k * ( - w1.S1(Nk) * cern_polygamma(Nk + 1, 1) - 1 / 2 * cern_polygamma(Nk + 1, 2) + harmonic_sum(S1, N, k, 1) * cern_polygamma(Nk + 1, 1) + - 1 / 2 * cern_polygamma(Nk + 1, 2) ) return g22 diff --git a/src/eko/harmonics/polygamma.py b/src/eko/harmonics/polygamma.py index 8395365c0..b9bc9c78b 100644 --- a/src/eko/harmonics/polygamma.py +++ b/src/eko/harmonics/polygamma.py @@ -124,3 +124,31 @@ def cern_polygamma(Z, K): # pylint: disable=all H=H+24/U**5+C4*P*((3*R+5)*R+2) return H # fmt: on + + +@nb.njit(cache=True) +def recursive_harmonic_sum(base_value, n, iterations, weight): + """ + Compute the harmonic sum :math:`S_{w}(N+i)` stating from the value + S_{w}(N) + + Parameters + ---------- + base_value: complex + starting value :math:`S_{w}(N+i)` + n: complex + starting value + iterations: int + number of iterations + weight: int + harmonic sum weight + + Returns + ------- + sni : complex + :math:`S_{w}(N+i)` + """ + fact = 0 + for i in range(1, iterations + 1): + fact += 1 / (n + i) ** weight + return base_value + fact diff --git a/src/eko/harmonics/w3.py b/src/eko/harmonics/w3.py index 442cc11f4..35c9624e8 100644 --- a/src/eko/harmonics/w3.py +++ b/src/eko/harmonics/w3.py @@ -73,9 +73,9 @@ def S21(N, S1, S2): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` Returns ------- @@ -90,7 +90,7 @@ def S21(N, S1, S2): @nb.njit(cache=True) -def Sm21(N, Sm1): +def Sm21(N, S1, Sm1): r""" Analytic continuation of harmonic sum :math:`S_{-2,1}(N)` as implemented in eq B.5.75 of :cite:`MuselliPhD` and eq 22 of cite:`Bl_mlein_2000`. @@ -99,8 +99,10 @@ def Sm21(N, Sm1): ---------- N : complex Mellin moment + S1: complex + Harmonic sum :math:`S_{1}(N)` Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` + Harmonic sum :math:`S_{-1}(N)` Returns ------- @@ -113,7 +115,10 @@ def Sm21(N, Sm1): """ # Note mellin g3 was integrated following x^(N-1) convention. return ( - -((-1) ** N) * gf.mellin_g3(N + 1) + zeta2 * Sm1 - 5 / 8 * zeta3 + zeta2 * log2 + -((-1) ** N) * gf.mellin_g3(N + 1, S1 + 1 / (N + 1)) + + zeta2 * Sm1 + - 5 / 8 * zeta3 + + zeta2 * log2 ) @@ -128,11 +133,11 @@ def S2m1(N, S2, Sm1, Sm2): N : complex Mellin moment S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` + Harmonic sum :math:`S_{-1}(N)` Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` + Harmonic sum :math:`S_{-2}(N)` Returns ------- @@ -163,11 +168,11 @@ def Sm2m1(N, S1, S2, Sm2): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` + Harmonic sum :math:`S_{-2}(N)` Returns ------- diff --git a/src/eko/harmonics/w4.py b/src/eko/harmonics/w4.py index 45a2afff8..805c2d829 100644 --- a/src/eko/harmonics/w4.py +++ b/src/eko/harmonics/w4.py @@ -63,7 +63,7 @@ def Sm4(N): @nb.njit(cache=True) -def Sm31(N, Sm1, Sm2): +def Sm31(N, S1, Sm1, Sm2): r""" Analytic continuation of harmonic sum :math:`S_{-3,1}(N)` as implemented in eq B.5.93 of :cite:`MuselliPhD` and eq 25 of cite:`Bl_mlein_2000`. @@ -72,10 +72,12 @@ def Sm31(N, Sm1, Sm2): ---------- N : complex Mellin moment + S1: complex + Harmonic sum :math:`S_{1}(N)` Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` + Harmonic sum :math:`S_{-1}(N)` Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` + Harmonic sum :math:`S_{-2}(N)` Returns ------- @@ -87,7 +89,7 @@ def Sm31(N, Sm1, Sm2): eko.harmonics.g_functions.mellin_g6 : :math:`g_6(N)` """ return ( - (-1) ** N * gf.mellin_g6(N) + (-1) ** N * gf.mellin_g6(N, S1) + zeta2 * Sm2 - zeta3 * Sm1 - 3 / 5 * zeta2**2 @@ -99,7 +101,7 @@ def Sm31(N, Sm1, Sm2): @nb.njit(cache=True) -def Sm22(N, Sm2, Sm31): +def Sm22(N, S1, Sm2, Sm31): r""" Analytic continuation of harmonic sum :math:`S_{-2,2}(N)` as implemented in eq B.5.94 of :cite:`MuselliPhD` and eq 24 of cite:`Bl_mlein_2000`. @@ -108,10 +110,12 @@ def Sm22(N, Sm2, Sm31): ---------- N : complex Mellin moment + S1: complex + Harmonic sum :math:`S_{1}(N)` Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` + Harmonic sum :math:`S_{-2}(N)` Sm31: complex - Hamrmonic sum :math:`S_{-3,1}(N)` + Harmonic sum :math:`S_{-3,1}(N)` Returns ------- Sm22 : complex @@ -122,12 +126,15 @@ def Sm22(N, Sm2, Sm31): eko.harmonics.g_functions.mellin_g5 : :math:`g_5(N)` """ return ( - (-1) ** N * gf.mellin_g5(N) - 2 * Sm31 + 2 * zeta2 * Sm2 + 3 / 40 * zeta2**2 + (-1) ** N * gf.mellin_g5(N, S1) + - 2 * Sm31 + + 2 * zeta2 * Sm2 + + 3 / 40 * zeta2**2 ) @nb.njit(cache=True) -def Sm211(N, Sm1): +def Sm211(N, S1, S2, Sm1): r""" Analytic continuation of harmonic sum :math:`S_{-2,1,1}(N)` as implemented in eq B.5.104 of :cite:`MuselliPhD` and eq 27 of cite:`Bl_mlein_2000`. @@ -136,12 +143,16 @@ def Sm211(N, Sm1): ---------- N : complex Mellin moment + S1: complex + Harmonic sum :math:`S_{1}(N)` + S2: complex + Harmonic sum :math:`S_{2}(N)` Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` + Harmonic sum :math:`S_{-1}(N)` Returns ------- - Sm31 : complex + Sm221 : complex Harmonic sum :math:`S_{-2,1,1}(N)` See Also @@ -149,7 +160,7 @@ def Sm211(N, Sm1): eko.harmonics.g_functions.mellin_g8 : :math:`g_8(N)` """ return ( - -((-1) ** N) * gf.mellin_g8(N) + -((-1) ** N) * gf.mellin_g8(N, S1, S2) + zeta3 * Sm1 - li4half + 1 / 8 * zeta2**2 @@ -170,11 +181,11 @@ def S211(N, S1, S2, S3): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` S3: complex - Hamrmonic sum :math:`S_{3}(N)` + Harmonic sum :math:`S_{3}(N)` Returns ------- @@ -189,7 +200,7 @@ def S211(N, S1, S2, S3): @nb.njit(cache=True) -def S31(N, S2, S4): +def S31(N, S1, S2, S4): r""" Analytic continuation of harmonic sum :math:`S_{3,1}(N)` as implemented in eq B.5.99 of :cite:`MuselliPhD` and eq 41 of cite:`Bl_mlein_2000`. @@ -198,10 +209,12 @@ def S31(N, S2, S4): ---------- N : complex Mellin moment + S1: complex + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` S4: complex - Hamrmonic sum :math:`S_{4}(N)` + Harmonic sum :math:`S_{4}(N)` Returns ------- @@ -213,7 +226,7 @@ def S31(N, S2, S4): eko.harmonics.g_functions.mellin_g22 : :math:`g_22(N)` """ return ( - 1 / 2 * gf.mellin_g22(N) + 1 / 2 * gf.mellin_g22(N, S1) - 1 / 4 * S4 - 1 / 4 * S2**2 + zeta2 * S2 diff --git a/src/eko/harmonics/w5.py b/src/eko/harmonics/w5.py index 112e5ae57..bb8cdd5bc 100644 --- a/src/eko/harmonics/w5.py +++ b/src/eko/harmonics/w5.py @@ -73,11 +73,11 @@ def S41(N, S1, S2, S3): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` S3: complex - Hamrmonic sum :math:`S_{3}(N)` + Harmonic sum :math:`S_{3}(N)` Returns ------- @@ -103,9 +103,9 @@ def S311(N, S1, S2): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` Returns ------- @@ -131,11 +131,11 @@ def S221(N, S1, S2, S21): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` S21: complex - Hamrmonic sum :math:`S_{2,1}(N)` + Harmonic sum :math:`S_{2,1}(N)` Returns ------- @@ -168,13 +168,13 @@ def Sm221(N, S1, Sm1, S21, Sm21): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` + Harmonic sum :math:`S_{-1}(N)` S21: complex - Hamrmonic sum :math:`S_{2,1}(N)` + Harmonic sum :math:`S_{2,1}(N)` Sm21: complex - Hamrmonic sum :math:`S_{-2,1}(N)` + Harmonic sum :math:`S_{-2,1}(N)` Returns ------- @@ -206,21 +206,21 @@ def S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` + Harmonic sum :math:`S_{-1}(N)` Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` + Harmonic sum :math:`S_{-2}(N)` Sm3: complex - Hamrmonic sum :math:`S_{-3}(N)` + Harmonic sum :math:`S_{-3}(N)` S21: complex - Hamrmonic sum :math:`S_{2,1}(N)` + Harmonic sum :math:`S_{2,1}(N)` Sm21: complex - Hamrmonic sum :math:`S_{-2,1}(N)` + Harmonic sum :math:`S_{-2,1}(N)` S2m1: complex - Hamrmonic sum :math:`S_{2,-1}(N)` + Harmonic sum :math:`S_{2,-1}(N)` Returns ------- @@ -254,11 +254,11 @@ def S2111(N, S1, S2, S3): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` S3: complex - Hamrmonic sum :math:`S_{3}(N)` + Harmonic sum :math:`S_{3}(N)` Returns ------- @@ -284,13 +284,13 @@ def Sm2111(N, S1, S2, S3, Sm1): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` S3: complex - Hamrmonic sum :math:`S_{3}(N)` + Harmonic sum :math:`S_{3}(N)` Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` + Harmonic sum :math:`S_{-1}(N)` Returns ------- @@ -321,11 +321,11 @@ def S23(N, S1, S2, S3): N : complex Mellin moment S1: complex - Hamrmonic sum :math:`S_{1}(N)` + Harmonic sum :math:`S_{1}(N)` S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` S3: complex - Hamrmonic sum :math:`S_{3}(N)` + Harmonic sum :math:`S_{3}(N)` Returns ------- @@ -355,11 +355,11 @@ def Sm23(N, Sm1, Sm2, Sm3): N : complex Mellin moment Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` + Harmonic sum :math:`S_{-1}(N)` Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` + Harmonic sum :math:`S_{-2}(N)` Sm3: complex - Hamrmonic sum :math:`S_{-3}(N)` + Harmonic sum :math:`S_{-3}(N)` Returns ------- @@ -395,13 +395,13 @@ def S2m3(N, S2, Sm1, Sm2, Sm3): N : complex Mellin moment S2: complex - Hamrmonic sum :math:`S_{2}(N)` + Harmonic sum :math:`S_{2}(N)` Sm1: complex - Hamrmonic sum :math:`S_{-1}(N)` + Harmonic sum :math:`S_{-1}(N)` Sm2: complex - Hamrmonic sum :math:`S_{-2}(N)` + Harmonic sum :math:`S_{-2}(N)` Sm3: complex - Hamrmonic sum :math:`S_{-3}(N)` + Harmonic sum :math:`S_{-3}(N)` Returns ------- diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index 295f9def1..cff00220c 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -42,7 +42,7 @@ def compute_harmonics_cache(n, order): sx = harmonics.base_harmonics_cache(n, max_weight[order], n_max_sums_weight[order]) if order == 2: # Add Sm21 to cache - sx[2, 1] = harmonics.Sm21(n, sx[0, -1]) + sx[2, 1] = harmonics.Sm21(n, sx[0, 0], sx[0, -1]) if order == 3: # Add weight 3 and 4 to cache sx[2, 1:-2] = harmonics.s3x(n, sx[:, 0], sx[:, -1]) diff --git a/tests/eko/test_f_functions.py b/tests/eko/test_f_functions.py index 37a0764c2..047649e95 100644 --- a/tests/eko/test_f_functions.py +++ b/tests/eko/test_f_functions.py @@ -88,7 +88,7 @@ def test_F12_F14(): S2 = harmonics.S2(N) Sm1 = harmonics.Sm1(N) S21 = harmonics.S21(N, S1, S2) - Sm21 = harmonics.Sm21(N, Sm1) + Sm21 = harmonics.Sm21(N, S1, Sm1) Sm221 = harmonics.Sm221(N, S1, Sm1, S21, Sm21) np.testing.assert_allclose(Sm221, vals, atol=1e-05) @@ -102,7 +102,7 @@ def test_F16(): Sm3 = harmonics.Sm3(N) S21 = harmonics.S21(N, S1, S2) S2m1 = harmonics.S2m1(N, S2, Sm1, Sm2) - Sm21 = harmonics.Sm21(N, Sm1) + Sm21 = harmonics.Sm21(N, S1, Sm1) S21m2 = harmonics.S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1) np.testing.assert_allclose(S21m2, vals, atol=1e-04) diff --git a/tests/eko/test_g_functions.py b/tests/eko/test_g_functions.py index bb030f401..79acff2d6 100644 --- a/tests/eko/test_g_functions.py +++ b/tests/eko/test_g_functions.py @@ -3,11 +3,10 @@ import numpy as np -import eko.harmonics as sf -from eko.anomalous_dimensions import harmonics +from eko.anomalous_dimensions import harmonics as h -zeta3 = harmonics.constants.zeta3 -log2 = harmonics.constants.log2 +zeta3 = h.constants.zeta3 +log2 = h.constants.log2 testN = [1, 10, 100] @@ -18,43 +17,48 @@ def test_g3(): # NIntegrate[x^({1, 2, 1 + I} - 1) PolyLog[2, x]/(1 + x), {x, 0, 1}] mma_ref_values = [0.3888958462, 0.2560382207, 0.3049381491 - 0.1589060625j] for n, r in zip(ns, mma_ref_values): - np.testing.assert_almost_equal(sf.g_functions.mellin_g3(n), r, decimal=6) + S1 = h.S1(n) + np.testing.assert_almost_equal(h.g_functions.mellin_g3(n, S1), r, decimal=6) def test_g4(): refvals = [-1, -1.34359, -1.40286] for N, vals in zip(testN, refvals): - S2 = harmonics.S2(N) - Sm1 = sf.Sm1(N) - Sm2 = sf.Sm2(N) - S2m1 = sf.S2m1(N, S2, Sm1, Sm2) + S2 = h.S2(N) + Sm1 = h.Sm1(N) + Sm2 = h.Sm2(N) + S2m1 = h.S2m1(N, S2, Sm1, Sm2) np.testing.assert_allclose(S2m1, vals, atol=1e-05) def test_g6(): refvals = [-1, -0.857976, -0.859245] for N, vals in zip(testN, refvals): - Sm1 = sf.Sm1(N) - Sm2 = sf.Sm2(N) - Sm31 = sf.Sm31(N, Sm1, Sm2) + Sm1 = h.Sm1(N) + Sm2 = h.Sm2(N) + S1 = h.S1(N) + Sm31 = h.Sm31(N, S1, Sm1, Sm2) np.testing.assert_allclose(Sm31, vals, atol=1e-05) def test_g5(): refvals = [-1, -0.777375, -0.784297] for N, vals in zip(testN, refvals): - Sm1 = sf.Sm1(N) - Sm2 = sf.Sm2(N) - Sm31 = sf.Sm31(N, Sm1, Sm2) - Sm22 = sf.Sm22(N, Sm2, Sm31) + Sm1 = h.Sm1(N) + Sm2 = h.Sm2(N) + S1 = h.S1(N) + Sm31 = h.Sm31(N, S1, Sm1, Sm2) + Sm22 = h.Sm22(N, S1, Sm2, Sm31) np.testing.assert_allclose(Sm22, vals, atol=1e-05) def test_g8(): refvals = [-1, -0.696836, -0.719637] for N, vals in zip(testN, refvals): - Sm1 = sf.Sm1(N) - Sm211 = sf.Sm211(N, Sm1) + Sm1 = h.Sm1(N) + S1 = h.S1(N) + S2 = h.S2(N) + Sm211 = h.Sm211(N, S1, S2, Sm1) np.testing.assert_allclose(Sm211, vals, atol=1e-05) @@ -62,19 +66,19 @@ def test_g18(): testN = [1, 2, 3, 10, 100] refvals = [1, 1.375, 1.5787, 2.0279, 2.34252] for N, vals in zip(testN, refvals): - S1 = harmonics.S1(N) - S2 = harmonics.S2(N) - S21 = sf.S21(N, S1, S2) + S1 = h.S1(N) + S2 = h.S2(N) + S21 = h.S21(N, S1, S2) np.testing.assert_allclose(S21, vals, atol=1e-05) def test_g19(): refvals = [1, 0.953673, 0.958928] for N, vals in zip(testN, refvals): - S1 = harmonics.S1(N) - S2 = harmonics.S2(N) - Sm2 = sf.Sm2(N) - Sm2m1 = sf.Sm2m1(N, S1, S2, Sm2) + S1 = h.S1(N) + S2 = h.S2(N) + Sm2 = h.Sm2(N) + Sm2m1 = h.Sm2m1(N, S1, S2, Sm2) np.testing.assert_allclose(Sm2m1, vals, atol=1e-05) @@ -82,10 +86,10 @@ def test_g21(): testN = [1, 2, 3, 10, 100] refvals = [1, 1.4375, 1.69985, 2.38081, 3.04323] for N, vals in zip(testN, refvals): - S1 = harmonics.S1(N) - S2 = harmonics.S2(N) - S3 = harmonics.S3(N) - S211 = sf.S211(N, S1, S2, S3) + S1 = h.S1(N) + S2 = h.S2(N) + S3 = h.S3(N) + S211 = h.S211(N, S1, S2, S3) np.testing.assert_allclose(S211, vals, atol=1e-05) @@ -93,7 +97,8 @@ def test_g22(): testN = [1, 2, 3, 10, 100] refvals = [1, 1.1875, 1.2554, 1.33724, 1.35262] for N, vals in zip(testN, refvals): - S2 = harmonics.S2(N) - S4 = harmonics.S4(N) - S31 = sf.S31(N, S2, S4) + S1 = h.S1(N) + S2 = h.S2(N) + S4 = h.S4(N) + S31 = h.S31(N, S1, S2, S4) np.testing.assert_allclose(S31, vals, atol=1e-05) diff --git a/tests/eko/test_harmonics.py b/tests/eko/test_harmonics.py index b68d87cad..4d60546f4 100644 --- a/tests/eko/test_harmonics.py +++ b/tests/eko/test_harmonics.py @@ -28,18 +28,18 @@ def test_HarmonicsCache(): [ h.S21(N, S1, S2), h.S2m1(N, S2, Sm1, Sm2), - h.Sm21(N, Sm1), + h.Sm21(N, S1, Sm1), h.Sm2m1(N, S1, S2, Sm2), ] ) np.testing.assert_allclose(h.s3x(N, sx, smx_test), s3x_test) - Sm31 = h.Sm31(N, Sm1, Sm2) + Sm31 = h.Sm31(N, S1, Sm1, Sm2) s4x_test = np.array( [ - h.S31(N, S2, S4), + h.S31(N, S1, S2, S4), h.S211(N, S1, S2, S3), - h.Sm22(N, Sm2, Sm31), - h.Sm211(N, Sm1), + h.Sm22(N, S1, Sm2, Sm31), + h.Sm211(N, S1, S2, Sm1), Sm31, ] ) diff --git a/tests/eko/test_polygamma.py b/tests/eko/test_polygamma.py index d0dfa063a..1db9a8fd4 100644 --- a/tests/eko/test_polygamma.py +++ b/tests/eko/test_polygamma.py @@ -78,3 +78,19 @@ def test_cern_polygamma(): _ = harmonics.polygamma.cern_polygamma(1, 5) with pytest.raises(ValueError): _ = harmonics.polygamma.cern_polygamma(0, 0) + + +def test_recursive_harmonic_sum(): + + n = np.random.rand() + iterations = 1 + sx_base = harmonics.sx(n) + sx_test = harmonics.sx(n + iterations) + + sx_final = [] + for w in range(1, 6): + sx_final.append( + harmonics.polygamma.recursive_harmonic_sum(sx_base[w - 1], n, iterations, w) + ) + + np.testing.assert_allclose(sx_final, sx_test) diff --git a/tests/eko/test_s_functions.py b/tests/eko/test_s_functions.py index e42b2ad02..c8ec5ae59 100644 --- a/tests/eko/test_s_functions.py +++ b/tests/eko/test_s_functions.py @@ -44,7 +44,8 @@ def test_Sm21(): for N, vals in zip(testN, refvals["Sm21"]): Sm1 = sf.Sm1(N) - np.testing.assert_allclose(sf.Sm21(N, Sm1), vals, atol=1e-06) + S1 = sf.S1(N) + np.testing.assert_allclose(sf.Sm21(N, S1, Sm1), vals, atol=1e-06) def test_Smx(): From 547cca537ebfde18a7929cb278e950fe309b2d45 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Thu, 31 Mar 2022 17:17:34 +0200 Subject: [PATCH 20/47] remane one test --- tests/eko/{test_harmonics.py => test_harmonics_cache.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/eko/{test_harmonics.py => test_harmonics_cache.py} (100%) diff --git a/tests/eko/test_harmonics.py b/tests/eko/test_harmonics_cache.py similarity index 100% rename from tests/eko/test_harmonics.py rename to tests/eko/test_harmonics_cache.py From 27972aebcac61c26d80f9cb48b82b6d018efb05b Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Thu, 31 Mar 2022 18:06:53 +0200 Subject: [PATCH 21/47] use cached S in cern polygamma --- src/eko/harmonics/__init__.py | 4 ++-- src/eko/harmonics/g_functions.py | 32 +++++++++++++++---------------- src/eko/harmonics/w4.py | 12 ++++++++---- tests/eko/test_g_functions.py | 6 ++++-- tests/eko/test_harmonics_cache.py | 4 ++-- 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index 4a8e3ac16..de1bdf6da 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -153,9 +153,9 @@ def s4x(n, sx, smx): sm31 = Sm31(n, sx[0], smx[0], smx[1]) return np.array( [ - S31(n, sx[0], sx[1], sx[3]), + S31(n, sx[0], sx[1], sx[2], sx[3]), S211(n, sx[0], sx[1], sx[2]), - Sm22(n, sx[0], smx[1], sm31), + Sm22(n, sx[0], sx[1], smx[1], sm31), Sm211(n, sx[0], sx[1], smx[0]), Sm31(n, sx[0], smx[0], smx[1]), ] diff --git a/src/eko/harmonics/g_functions.py b/src/eko/harmonics/g_functions.py index fa518ca33..1f0e0e91b 100644 --- a/src/eko/harmonics/g_functions.py +++ b/src/eko/harmonics/g_functions.py @@ -8,7 +8,6 @@ from . import w1 from .constants import log2, zeta2, zeta3 -from .polygamma import cern_polygamma from .polygamma import recursive_harmonic_sum as harmonic_sum a1 = np.array( @@ -125,7 +124,7 @@ def mellin_g4(N): @nb.njit(cache=True) -def mellin_g5(N, S1): +def mellin_g5(N, S1, S2): r""" Computes the Mellin transform of :math:`(\text{Li}_2(x)ln(x))/(1+x)`. @@ -138,6 +137,8 @@ def mellin_g5(N, S1): Mellin moment S1: complex Harmonic sum :math:`S_{1}(N)` + S2: complex + Harmonic sum :math:`S_{2}(N)` Returns ------- @@ -147,14 +148,11 @@ def mellin_g5(N, S1): g5 = 0.0 for k, ak in enumerate(a1): Nk = N + k + 1 + poly1nk = -harmonic_sum(S2, N, k + 1, 2) + zeta2 g5 -= ak * ( (k + 1) / Nk**2 - * ( - zeta2 - + cern_polygamma(Nk + 1, 1) - - 2 * harmonic_sum(S1, N, k + 1, 1) / Nk - ) + * (zeta2 + poly1nk - 2 * harmonic_sum(S1, N, k + 1, 1) / Nk) ) return g5 @@ -289,7 +287,6 @@ def mellin_g19(N, S1): """ g19 = 1 / 2 * zeta2 * S1 for k, ak in enumerate(a1): - Nk = N + k g19 -= ak / (k + 1) * harmonic_sum(S1, N, k + 1, 1) return g19 @@ -344,7 +341,7 @@ def mellin_g21(N, S1, S2, S3): @nb.njit(cache=True) -def mellin_g22(N, S1): +def mellin_g22(N, S1, S2, S3): r""" Computes the Mellin transform of :math:`-(\text{Li}_2(x) ln(x))/(1-x)`. @@ -361,6 +358,10 @@ def mellin_g22(N, S1): Mellin moment S1 : complex Harmonic sum :math:`S_{1}(N)` + S2 : complex + Harmonic sum :math:`S_{2}(N)` + S3 : complex + Harmonic sum :math:`S_{3}(N)` Returns ------- @@ -369,12 +370,11 @@ def mellin_g22(N, S1): """ g22 = 0.0 for k, ck in enumerate(c1): - Nk = N + k - g22 += ck * cern_polygamma(Nk + 1, 1) + poly1nk = -harmonic_sum(S2, N, k, 2) + zeta2 + g22 += ck * poly1nk for k, p11k in enumerate(p11): - Nk = N + k - g22 -= p11k * ( - harmonic_sum(S1, N, k, 1) * cern_polygamma(Nk + 1, 1) - - 1 / 2 * cern_polygamma(Nk + 1, 2) - ) + S1nk = harmonic_sum(S1, N, k, 1) + poly1nk = -harmonic_sum(S2, N, k, 2) + zeta2 + poly2nk = 2 * harmonic_sum(S3, N, k, 3) + zeta3 + g22 -= p11k * (S1nk * poly1nk - 1 / 2 * poly2nk) return g22 diff --git a/src/eko/harmonics/w4.py b/src/eko/harmonics/w4.py index 805c2d829..9537ca941 100644 --- a/src/eko/harmonics/w4.py +++ b/src/eko/harmonics/w4.py @@ -101,7 +101,7 @@ def Sm31(N, S1, Sm1, Sm2): @nb.njit(cache=True) -def Sm22(N, S1, Sm2, Sm31): +def Sm22(N, S1, S2, Sm2, Sm31): r""" Analytic continuation of harmonic sum :math:`S_{-2,2}(N)` as implemented in eq B.5.94 of :cite:`MuselliPhD` and eq 24 of cite:`Bl_mlein_2000`. @@ -112,6 +112,8 @@ def Sm22(N, S1, Sm2, Sm31): Mellin moment S1: complex Harmonic sum :math:`S_{1}(N)` + S2: complex + Harmonic sum :math:`S_{2}(N)` Sm2: complex Harmonic sum :math:`S_{-2}(N)` Sm31: complex @@ -126,7 +128,7 @@ def Sm22(N, S1, Sm2, Sm31): eko.harmonics.g_functions.mellin_g5 : :math:`g_5(N)` """ return ( - (-1) ** N * gf.mellin_g5(N, S1) + (-1) ** N * gf.mellin_g5(N, S1, S2) - 2 * Sm31 + 2 * zeta2 * Sm2 + 3 / 40 * zeta2**2 @@ -200,7 +202,7 @@ def S211(N, S1, S2, S3): @nb.njit(cache=True) -def S31(N, S1, S2, S4): +def S31(N, S1, S2, S3, S4): r""" Analytic continuation of harmonic sum :math:`S_{3,1}(N)` as implemented in eq B.5.99 of :cite:`MuselliPhD` and eq 41 of cite:`Bl_mlein_2000`. @@ -213,6 +215,8 @@ def S31(N, S1, S2, S4): Harmonic sum :math:`S_{1}(N)` S2: complex Harmonic sum :math:`S_{2}(N)` + S3: complex + Harmonic sum :math:`S_{3}(N)` S4: complex Harmonic sum :math:`S_{4}(N)` @@ -226,7 +230,7 @@ def S31(N, S1, S2, S4): eko.harmonics.g_functions.mellin_g22 : :math:`g_22(N)` """ return ( - 1 / 2 * gf.mellin_g22(N, S1) + 1 / 2 * gf.mellin_g22(N, S1, S2, S3) - 1 / 4 * S4 - 1 / 4 * S2**2 + zeta2 * S2 diff --git a/tests/eko/test_g_functions.py b/tests/eko/test_g_functions.py index 79acff2d6..34d6ce9fd 100644 --- a/tests/eko/test_g_functions.py +++ b/tests/eko/test_g_functions.py @@ -47,8 +47,9 @@ def test_g5(): Sm1 = h.Sm1(N) Sm2 = h.Sm2(N) S1 = h.S1(N) + S2 = h.S2(N) Sm31 = h.Sm31(N, S1, Sm1, Sm2) - Sm22 = h.Sm22(N, S1, Sm2, Sm31) + Sm22 = h.Sm22(N, S1, S2, Sm2, Sm31) np.testing.assert_allclose(Sm22, vals, atol=1e-05) @@ -99,6 +100,7 @@ def test_g22(): for N, vals in zip(testN, refvals): S1 = h.S1(N) S2 = h.S2(N) + S3 = h.S3(N) S4 = h.S4(N) - S31 = h.S31(N, S1, S2, S4) + S31 = h.S31(N, S1, S2, S3, S4) np.testing.assert_allclose(S31, vals, atol=1e-05) diff --git a/tests/eko/test_harmonics_cache.py b/tests/eko/test_harmonics_cache.py index 4d60546f4..7da15cd59 100644 --- a/tests/eko/test_harmonics_cache.py +++ b/tests/eko/test_harmonics_cache.py @@ -36,9 +36,9 @@ def test_HarmonicsCache(): Sm31 = h.Sm31(N, S1, Sm1, Sm2) s4x_test = np.array( [ - h.S31(N, S1, S2, S4), + h.S31(N, S1, S2, S3, S4), h.S211(N, S1, S2, S3), - h.Sm22(N, S1, Sm2, Sm31), + h.Sm22(N, S1, S2, Sm2, Sm31), h.Sm211(N, S1, S2, Sm1), Sm31, ] From 66a36242feb7869c375f7037cd845543af14171e Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Thu, 31 Mar 2022 18:09:34 +0200 Subject: [PATCH 22/47] rename harmonic_sum to s --- src/eko/harmonics/g_functions.py | 48 +++++++++++--------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/eko/harmonics/g_functions.py b/src/eko/harmonics/g_functions.py index 1f0e0e91b..220dc95ed 100644 --- a/src/eko/harmonics/g_functions.py +++ b/src/eko/harmonics/g_functions.py @@ -8,7 +8,7 @@ from . import w1 from .constants import log2, zeta2, zeta3 -from .polygamma import recursive_harmonic_sum as harmonic_sum +from .polygamma import recursive_harmonic_sum as s a1 = np.array( [ @@ -92,7 +92,7 @@ def mellin_g3(N, S1): g3 = 0 for j, c in enumerate(cs): Nj = N + j - g3 += c * (zeta2 - harmonic_sum(S1, N, j, 1) / Nj) / Nj + g3 += c * (zeta2 - s(S1, N, j, 1) / Nj) / Nj return g3 @@ -148,12 +148,8 @@ def mellin_g5(N, S1, S2): g5 = 0.0 for k, ak in enumerate(a1): Nk = N + k + 1 - poly1nk = -harmonic_sum(S2, N, k + 1, 2) + zeta2 - g5 -= ak * ( - (k + 1) - / Nk**2 - * (zeta2 + poly1nk - 2 * harmonic_sum(S1, N, k + 1, 1) / Nk) - ) + poly1nk = -s(S2, N, k + 1, 2) + zeta2 + g5 -= ak * ((k + 1) / Nk**2 * (zeta2 + poly1nk - 2 * s(S1, N, k + 1, 1) / Nk)) return g5 @@ -183,8 +179,7 @@ def mellin_g6(N, S1): for k, ak in enumerate(a1): Nk = N + k + 1 g6 -= ak * ( - N / Nk * zeta3 - + (k + 1) / Nk**2 * (zeta2 - harmonic_sum(S1, N, k + 1, 1) / Nk) + N / Nk * zeta3 + (k + 1) / Nk**2 * (zeta2 - s(S1, N, k + 1, 1) / Nk) ) return g6 @@ -216,11 +211,7 @@ def mellin_g8(N, S1, S2): Nk = N + k + 1 g8 -= ak * ( N / Nk * zeta3 - + (k + 1) - / Nk**2 - * 1 - / 2 - * (harmonic_sum(S1, N, k + 1, 1) ** 2 + harmonic_sum(S2, N, k + 1, 2)) + + (k + 1) / Nk**2 * 1 / 2 * (s(S1, N, k + 1, 1) ** 2 + s(S2, N, k + 1, 2)) ) return g8 @@ -253,15 +244,10 @@ def mellin_g18(N, S1, S2): g18 = (S1**2 + S2) / (N) - zeta2 * S1 for k, ck in enumerate(c1): Nk = N + k - g18 += ck * (N) / (Nk) * harmonic_sum(S1, N, k, 1) + g18 += ck * (N) / (Nk) * s(S1, N, k, 1) for k, p11k in enumerate(p11): Nk = N + k - g18 -= ( - p11k - * (N) - / (Nk) - * (harmonic_sum(S1, N, k, 1) ** 2 + harmonic_sum(S2, N, k, 2)) - ) + g18 -= p11k * (N) / (Nk) * (s(S1, N, k, 1) ** 2 + s(S2, N, k, 2)) return g18 @@ -287,7 +273,7 @@ def mellin_g19(N, S1): """ g19 = 1 / 2 * zeta2 * S1 for k, ak in enumerate(a1): - g19 -= ak / (k + 1) * harmonic_sum(S1, N, k + 1, 1) + g19 -= ak / (k + 1) * s(S1, N, k + 1, 1) return g19 @@ -323,12 +309,12 @@ def mellin_g21(N, S1, S2, S3): g21 = -zeta3 * S1 + (S1**3 + 3 * S1 * S2 + 2 * S3) / (2 * N) for k, ck in enumerate(c3): Nk = N + k - g21 += ck * N / Nk * harmonic_sum(S1, N, k, 1) + g21 += ck * N / Nk * s(S1, N, k, 1) for k in range(0, 5): Nk = N + k - S1nk = harmonic_sum(S1, N, k, 1) - S2nk = harmonic_sum(S2, N, k, 2) - S3nk = harmonic_sum(S3, N, k, 3) + S1nk = s(S1, N, k, 1) + S2nk = s(S2, N, k, 2) + S3nk = s(S3, N, k, 3) g21 += ( N / Nk @@ -370,11 +356,11 @@ def mellin_g22(N, S1, S2, S3): """ g22 = 0.0 for k, ck in enumerate(c1): - poly1nk = -harmonic_sum(S2, N, k, 2) + zeta2 + poly1nk = -s(S2, N, k, 2) + zeta2 g22 += ck * poly1nk for k, p11k in enumerate(p11): - S1nk = harmonic_sum(S1, N, k, 1) - poly1nk = -harmonic_sum(S2, N, k, 2) + zeta2 - poly2nk = 2 * harmonic_sum(S3, N, k, 3) + zeta3 + S1nk = s(S1, N, k, 1) + poly1nk = -s(S2, N, k, 2) + zeta2 + poly2nk = 2 * s(S3, N, k, 3) + zeta3 g22 -= p11k * (S1nk * poly1nk - 1 / 2 * poly2nk) return g22 From b8e55581a0bef15db7f9fa8d72307f110be33e07 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Fri, 1 Apr 2022 15:48:37 +0200 Subject: [PATCH 23/47] remove zeros from harmonic cache --- src/eko/harmonics/__init__.py | 2 ++ src/eko/matching_conditions/as1.py | 4 ++-- src/eko/matching_conditions/as2.py | 23 ++++++++----------- src/eko/matching_conditions/as3/__init__.py | 8 +++---- src/eko/matching_conditions/as3/agg.py | 8 +++---- src/eko/matching_conditions/as3/aggTF2.py | 6 +++-- .../operator_matrix_element.py | 3 ++- tests/eko/test_matching_nnlo.py | 10 ++++---- tests/eko/test_ome.py | 7 +++--- 9 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index de1bdf6da..e1a1ddc1a 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -28,6 +28,8 @@ def base_harmonics_cache(n, max_weight=5, n_max_sums_weight=7): Mellin moment max_weight : int max harmonics weight, max value 5 (default) + n_max_sums_weight : int + max number of harmonics sums for a given weight Retruns ------- h_cache : np.ndarray diff --git a/src/eko/matching_conditions/as1.py b/src/eko/matching_conditions/as1.py index 930da18d7..eba61d778 100644 --- a/src/eko/matching_conditions/as1.py +++ b/src/eko/matching_conditions/as1.py @@ -33,8 +33,8 @@ def A_hh(n, sx, L): A_hh : complex |NLO| heavy-heavy |OME| :math:`A_{HH}^{(1)}` """ - S1m = sx[0, 0] - 1 / n # harmonics.S1(n - 1) - S2m = sx[1, 0] - 1 / n**2 # harmonics.S2(n - 1) + S1m = sx[0][0] - 1 / n # harmonics.S1(n - 1) + S2m = sx[1][0] - 1 / n**2 # harmonics.S2(n - 1) ahh_l = (2 + n - 3 * n**2) / (n * (1 + n)) + 4 * S1m ahh = 2 * ( 2 diff --git a/src/eko/matching_conditions/as2.py b/src/eko/matching_conditions/as2.py index 12360f1b1..ff3628162 100644 --- a/src/eko/matching_conditions/as2.py +++ b/src/eko/matching_conditions/as2.py @@ -38,9 +38,9 @@ def A_qq_ns(n, sx, L): A_qq_ns : complex |NNLO| light-light non-singlet |OME| :math:`A_{qq,H}^{NS,(2)}` """ - S1 = sx[0, 0] - S2 = sx[1, 0] - S3 = sx[2, 0] + S1 = sx[0][0] + S2 = sx[1][0] + S3 = sx[2][0] S1m = S1 - 1 / n # harmonic_S1(n - 1) S2m = S2 - 1 / n**2 # harmonic_S2(n - 1) @@ -93,7 +93,7 @@ def A_hq_ps(n, sx, L): A_hq_ps : complex |NNLO| heavy-light pure-singlet |OME| :math:`A_{Hq}^{PS,(2)}` """ - S2 = sx[1, 0] + S2 = sx[1][0] F1M = 1.0 / (n - 1.0) * (zeta2 - (S2 - 1.0 / n**2)) F11 = 1.0 / (n + 1.0) * (zeta2 - (S2 + 1.0 / (n + 1.0) ** 2)) @@ -157,14 +157,11 @@ def A_hg(n, sx, L): A_hg : complex |NNLO| heavy-gluon |OME| :math:`A_{Hg}^{S,(2)}` """ - S1 = sx[0, 0] - S2 = sx[1, 0] - S3 = sx[2, 0] + S1 = sx[0][0] + S2, Sm2 = sx[1] + S3, Sm21, Sm3 = sx[2] S1m = S1 - 1 / n S2m = S2 - 1 / n**2 - Sm2 = sx[1, -1] - Sm3 = sx[2, -1] - Sm21 = sx[2, 1] a_hg_l0 = ( -( @@ -296,8 +293,8 @@ def A_gq(n, sx, L): A_gq : complex |NNLO| gluon-quark |OME| :math:`A_{gq,H}^{S,(2)}` """ - S1 = sx[0, 0] - S2 = sx[1, 0] + S1 = sx[0][0] + S2 = sx[1][0] S1m = S1 - 1 / n # harmonic_S1(n - 1) B2M = ((S1 - 1.0 / n) ** 2 + S2 - 1.0 / n**2) / (n - 1.0) @@ -346,7 +343,7 @@ def A_gg(n, sx, L): A_gg : complex |NNLO| gluon-gluon |OME| :math:`A_{gg,H}^{S,(2)}` """ - S1 = sx[0, 0] + S1 = sx[0][0] S1m = S1 - 1 / n # harmonic_S1(n - 1) D1 = -1.0 / n**2 diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/eko/matching_conditions/as3/__init__.py index f70becdad..a20f509cb 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/eko/matching_conditions/as3/__init__.py @@ -58,11 +58,11 @@ def A_singlet(n, sx_all, nf, L): sx_all : numpy.ndarray harmonic sums cache containing: [ - [S1, 0, 0, 0, 0, 0, Sm1], - [S2, 0, 0, 0, 0, 0, Sm2], - [S3, S21, S2m1, Sm21, Sm2m1, 0, Sm3], + [S1, Sm1], + [S2, Sm2], + [S3, S21, S2m1, Sm21, Sm2m1, Sm3], [S4, S31, S221, Sm22, Sm211, Sm31 Sm4], - [S5, 0, 0, 0, 0, 0, Sm5], + [S5, Sm5], ] nf : int number of active flavor below the threshold diff --git a/src/eko/matching_conditions/as3/agg.py b/src/eko/matching_conditions/as3/agg.py index 466c24a15..5aa18ef61 100644 --- a/src/eko/matching_conditions/as3/agg.py +++ b/src/eko/matching_conditions/as3/agg.py @@ -36,10 +36,10 @@ def A_gg(n, sx, nf, L): # pylint: disable=too-many-locals A_ggTF2: eko.matching_conditions.as3.aggTF2.A_ggTF2 Incomplete part proportional to :math:`T_{F}^2`. """ - S1, S2, S3, S4 = sx[:4, 0] - Sm2, Sm3, Sm4 = sx[1:4, -1] - S21, Sm21 = sx[2, 1], sx[2, 3] - S31, S211, Sm22, Sm211, Sm31 = sx[3, 1:6] + S1, _ = sx[0] + S2, Sm2 = sx[1] + S3, S21, _, Sm21, _, Sm3 = sx[2] + S4, S31, S211, Sm22, Sm211, Sm31, Sm4 = sx[3] a_gg_l0 = ( -0.35616500834358344 + A_ggTF2(n, sx) diff --git a/src/eko/matching_conditions/as3/aggTF2.py b/src/eko/matching_conditions/as3/aggTF2.py index f1d439841..d39045ff0 100644 --- a/src/eko/matching_conditions/as3/aggTF2.py +++ b/src/eko/matching_conditions/as3/aggTF2.py @@ -28,8 +28,10 @@ def A_ggTF2(n, sx): A_ggTF2 : complex :math:`A_{gg,T_{F}^2}^{S,(3)}(N)` """ - S1, S2, S3 = sx[:3, 0] - S21 = sx[2, 1] + S1 = sx[0][0] + S1 = sx[1][0] + S1 = sx[2][0] + S21 = sx[2][1] # here we use an approximation at large N # for binomial(2 * n, n) / np.power(4, n) # faster than the exact result diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index cff00220c..04f270886 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -47,7 +47,8 @@ def compute_harmonics_cache(n, order): # Add weight 3 and 4 to cache sx[2, 1:-2] = harmonics.s3x(n, sx[:, 0], sx[:, -1]) sx[3, 1:-1] = harmonics.s4x(n, sx[:, 0], sx[:, -1]) - return sx + # return list of list keeping the non zero values + return [[el for el in sx_list if el != 0] for sx_list in sx] @nb.njit(cache=True) diff --git a/tests/eko/test_matching_nnlo.py b/tests/eko/test_matching_nnlo.py index f17cbc927..ce5dee2a4 100644 --- a/tests/eko/test_matching_nnlo.py +++ b/tests/eko/test_matching_nnlo.py @@ -37,9 +37,9 @@ def test_A_2(): def test_A_2_shape(): - N = 2 + N = np.random.rand() L = 3 - sx = np.zeros((3, 3), np.complex_) + sx = compute_harmonics_cache(N, 2) aNS2 = A_ns(N, sx, L) aS2 = A_singlet(N, sx, L) @@ -139,9 +139,9 @@ def test_Hg2_pegasus(): for N in range(3, 20): sx = compute_harmonics_cache(N, 2) - S1 = sx[0, 0] - S2 = sx[1, 0] - S3 = sx[2, 0] + S1 = sx[0][0] + S2 = sx[1][0] + S3 = sx[2][0] aS2 = A_singlet(N, sx, L) E2 = ( diff --git a/tests/eko/test_ome.py b/tests/eko/test_ome.py index e916f4601..6571211c5 100644 --- a/tests/eko/test_ome.py +++ b/tests/eko/test_ome.py @@ -13,6 +13,7 @@ A_singlet, OperatorMatrixElement, build_ome, + compute_harmonics_cache, quad_ker, ) from eko.strong_coupling import StrongCoupling @@ -24,12 +25,12 @@ def test_build_ome_as(): N = 2 L = 0.0 a_s = 0.0 - sx = np.random.rand(5, 7) + 1j * np.random.rand(5, 7) nf = 3 is_msbar = False - for o in [0, 1, 2, 3]: + for o in [1, 2, 3]: if o == 3: N = complex(2.123) + sx = compute_harmonics_cache(np.random.rand(), o) aNS = A_non_singlet(o, N, sx, nf, L) aS = A_singlet(o, N, sx, nf, L, is_msbar) @@ -51,7 +52,7 @@ def test_build_ome_nlo(): a_s = 20 is_msbar = False - sx = np.array([[1], [1], [1]], np.complex_) + sx = [[1], [1], [1]] nf = 4 aNSi = A_non_singlet(1, N, sx, nf, L) aSi = A_singlet(1, N, sx, nf, L, is_msbar) From 9fef339714b745f6fe2352170bf4afef2901266a Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Fri, 1 Apr 2022 16:55:24 +0200 Subject: [PATCH 24/47] update cached harmoincs in ome as3 --- src/eko/matching_conditions/as1.py | 18 ++++-- src/eko/matching_conditions/as2.py | 33 +++++++---- src/eko/matching_conditions/as3/__init__.py | 44 +++++++-------- src/eko/matching_conditions/as3/aHg.py | 22 +++----- src/eko/matching_conditions/as3/aHgstfac.py | 16 +++--- src/eko/matching_conditions/as3/aHq.py | 21 +++---- src/eko/matching_conditions/as3/agg.py | 2 +- src/eko/matching_conditions/as3/aggTF2.py | 8 +-- src/eko/matching_conditions/as3/agq.py | 20 +++---- src/eko/matching_conditions/as3/aqg.py | 20 +++---- src/eko/matching_conditions/as3/aqqNS.py | 21 +++---- src/eko/matching_conditions/as3/aqqPS.py | 9 ++- .../operator_matrix_element.py | 15 +++-- tests/eko/test_matching_n3lo.py | 56 ++++++------------- tests/eko/test_ome.py | 2 +- 15 files changed, 140 insertions(+), 167 deletions(-) diff --git a/src/eko/matching_conditions/as1.py b/src/eko/matching_conditions/as1.py index eba61d778..78a070766 100644 --- a/src/eko/matching_conditions/as1.py +++ b/src/eko/matching_conditions/as1.py @@ -23,7 +23,7 @@ def A_hh(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray + sx : list harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -131,8 +131,12 @@ def A_singlet(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray - harmonic sums cache + sx : list + harmonic sums cache containing: + [ + [S1], + [S2], + ] L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -174,8 +178,12 @@ def A_ns(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray - harmonic sums cache + sx : list + harmonic sums cache containing: + [ + [S1], + [S2], + ] L : float :math:`\ln(\mu_F^2 / m_h^2)` Returns diff --git a/src/eko/matching_conditions/as2.py b/src/eko/matching_conditions/as2.py index ff3628162..593de7acc 100644 --- a/src/eko/matching_conditions/as2.py +++ b/src/eko/matching_conditions/as2.py @@ -28,7 +28,7 @@ def A_qq_ns(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray + sx : list harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -83,7 +83,7 @@ def A_hq_ps(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray + sx : list harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -147,7 +147,7 @@ def A_hg(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray + sx : list harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -159,7 +159,10 @@ def A_hg(n, sx, L): """ S1 = sx[0][0] S2, Sm2 = sx[1] - S3, Sm21, Sm3 = sx[2] + try: + S3, Sm21, Sm3 = sx[2] + except ValueError: + S3, _, _, Sm21, _, Sm3 = sx[2] S1m = S1 - 1 / n S2m = S2 - 1 / n**2 @@ -283,7 +286,7 @@ def A_gq(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray + sx : list harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -333,7 +336,7 @@ def A_gg(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray + sx : list harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -426,8 +429,13 @@ def A_singlet(n, sx, L, is_msbar=False): ---------- n : complex Mellin moment - sx : numpy.ndarray - harmonic sums cache + sx : list + harmonic sums cache containing: + [ + [S1, Sm1], + [S2, Sm2], + [S3, Sm21, Sm3], + ] L : float :math:`\ln(\mu_F^2 / m_h^2)` is_msbar: bool @@ -475,8 +483,13 @@ def A_ns(n, sx, L): ---------- n : complex Mellin moment - sx : numpy.ndarray - harmonic sums cache + sx : list + harmonic sums cache containing: + [ + [S1, Sm1], + [S2, Sm2], + [S3, Sm21, Sm3], + ] L : float :math:`\ln(\mu_F^2 / m_h^2)` diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/eko/matching_conditions/as3/__init__.py index a20f509cb..80f32d365 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/eko/matching_conditions/as3/__init__.py @@ -55,13 +55,13 @@ def A_singlet(n, sx_all, nf, L): ---------- n : complex Mellin moment - sx_all : numpy.ndarray + sx_all : list harmonic sums cache containing: [ [S1, Sm1], [S2, Sm2], - [S3, S21, S2m1, Sm21, Sm2m1, Sm3], - [S4, S31, S221, Sm22, Sm211, Sm31 Sm4], + [S3, S21, S2m1, Sm21, Sm2m1, Sm3], + [S4, S31, S211, Sm22, Sm211, Sm31, Sm4], [S5, Sm5], ] nf : int @@ -74,19 +74,15 @@ def A_singlet(n, sx_all, nf, L): A_S : numpy.ndarray |NNLO| singlet |OME| :math:`A^{S,(3)}(N)` """ - sx = sx_all[:, 0] - smx = sx_all[:, -1] - s3x = sx_all[2, 1:] - s4x = sx_all[3, 1:] - A_hq_3 = A_Hq(n, sx, smx, s3x, s4x, nf, L) - A_hg_3 = A_Hg(n, sx, smx, s3x, s4x, nf, L) - - A_gq_3 = A_gq(n, sx, smx, s3x, s4x, nf, L) + A_hq_3 = A_Hq(n, sx_all, nf, L) + A_hg_3 = A_Hg(n, sx_all, nf, L) + + A_gq_3 = A_gq(n, sx_all, nf, L) A_gg_3 = A_gg(n, sx_all, nf, L) - A_qq_ps_3 = A_qqPS(n, sx, nf, L) - A_qq_ns_3 = A_qqNS(n, sx, smx, s3x, s4x, nf, L) - A_qg_3 = A_qg(n, sx, smx, s3x, s4x, nf, L) + A_qq_ps_3 = A_qqPS(n, sx_all, nf, L) + A_qq_ns_3 = A_qqNS(n, sx_all, nf, L) + A_qg_3 = A_qg(n, sx_all, nf, L) A_S = np.array( [ @@ -117,9 +113,15 @@ def A_ns(n, sx_all, nf, L): ---------- n : complex Mellin moment - sx_all : numpy.ndarray - List of harmonic sums containing: - [S1 ... S5, Sm1 ... Sm5, S21, S2m1, Sm21, Sm2m1, S31, S221, Sm22, Sm211, Sm31] + sx_all : list + harmonic sums cache containing: + [ + [S1, Sm1], + [S2, Sm2], + [S3, S21, S2m1, Sm21, Sm2m1, Sm3], + [S4, S31, S211, Sm22, Sm211, Sm31, Sm4], + [S5, Sm5], + ] nf : int number of active flavor below the threshold L : float @@ -134,10 +136,4 @@ def A_ns(n, sx_all, nf, L): -------- A_qqNS_3 : :math:`A_{qq,H}^{NS,(3))}` """ - sx = sx_all[:, 0] - smx = sx_all[:, -1] - s3x = sx_all[2, 1:] - s4x = sx_all[3, 1:] - return np.array( - [[A_qqNS(n, sx, smx, s3x, s4x, nf, L), 0.0], [0 + 0j, 0 + 0j]], np.complex_ - ) + return np.array([[A_qqNS(n, sx_all, nf, L), 0.0], [0 + 0j, 0 + 0j]], np.complex_) diff --git a/src/eko/matching_conditions/as3/aHg.py b/src/eko/matching_conditions/as3/aHg.py index 609eac33d..af1c76052 100644 --- a/src/eko/matching_conditions/as3/aHg.py +++ b/src/eko/matching_conditions/as3/aHg.py @@ -7,7 +7,7 @@ @nb.njit(cache=True) -def A_Hg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals +def A_Hg(n, sx, nf, L): # pylint: disable=too-many-locals r""" Computes the |N3LO| singlet |OME| :math:`A_{Hg}^{S,(3)}(N)`. The experssion is presented in :cite:`Bierenbaum:2009mv`. @@ -19,14 +19,8 @@ def A_Hg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals ---------- n : complex Mellin moment - sx : numpy.ndarray - list S1 ... S5 - smx : numpy.ndarray - list Sm1 ... Sm5 - s3x : numpy.ndarray - list S21, S2m1, Sm21, Sm2m1 - s4x : numpy.ndarray - list S31, S221, Sm22, Sm211, Sm31 + sx : list + harmonic sums cache nf : int number of active flavor below the threshold L : float @@ -41,12 +35,12 @@ def A_Hg(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals A_Hgstfac: eko.matching_conditions.as3.aHgstfac.A_Hgstfac Incomplete part of the |OME|. """ - S1, S2, S3, S4 = sx[0], sx[1], sx[2], sx[3] - Sm2, Sm3, Sm4 = smx[1], smx[2], smx[3] - S21, Sm21 = s3x[0], s3x[2] - S31, S211, Sm22, Sm211, Sm31 = s4x[0], s4x[1], s4x[2], s4x[3], s4x[4] + S1, _ = sx[0] + S2, Sm2 = sx[1] + S3, S21, _, Sm21, _, Sm3 = sx[2] + S4, S31, S211, Sm22, Sm211, Sm31, Sm4 = sx[3] a_Hg_l0 = ( - A_Hgstfac(n, sx, smx, s3x, s4x, nf) + A_Hgstfac(n, sx, nf) + (1.0684950250307503 * (2.0 + n + np.power(n, 2))) / (n * (1.0 + n) * (2.0 + n)) + 0.3333333333333333 diff --git a/src/eko/matching_conditions/as3/aHgstfac.py b/src/eko/matching_conditions/as3/aHgstfac.py index e605f39d2..eb057262b 100644 --- a/src/eko/matching_conditions/as3/aHgstfac.py +++ b/src/eko/matching_conditions/as3/aHgstfac.py @@ -4,7 +4,7 @@ @nb.njit(cache=True) -def A_Hgstfac(n, sx, smx, s3x, s4x, nf): +def A_Hgstfac(n, sx, nf): r""" Computes the approximate incomplete part of :math:`A_{Hg}^{S,(3)}(N)` proportional to various color factors. @@ -17,19 +17,17 @@ def A_Hgstfac(n, sx, smx, s3x, s4x, nf): ---------- n : complex Mellin moment - sx : numpy.ndarray - list S1 ... S5 - s3x : numpy.ndarray - list S21, S2m1, Sm21, Sm2m1 + sx : list + harmonic sums cache Returns ------- A_ggTF2 : complex """ - S1, S2, S3, S4 = sx[0], sx[1], sx[2], sx[3] - Sm2, Sm3, Sm4 = smx[1], smx[2], smx[3] - S21, Sm21 = s3x[0], s3x[2] - S31, S211, Sm22, Sm211, Sm31 = s4x[0], s4x[1], s4x[2], s4x[3], s4x[4] + S1, _ = sx[0] + S2, Sm2 = sx[1] + S3, S21, _, Sm21, _, Sm3 = sx[2] + S4, S31, S211, Sm22, Sm211, Sm31, Sm4 = sx[3] return ( (-1.0684950250307503 * (2.0 + n + np.power(n, 2))) / (n * (1.0 + n) * (2.0 + n)) + 1.3333333333333333 diff --git a/src/eko/matching_conditions/as3/aHq.py b/src/eko/matching_conditions/as3/aHq.py index a3d9d3ee3..09702bdb2 100644 --- a/src/eko/matching_conditions/as3/aHq.py +++ b/src/eko/matching_conditions/as3/aHq.py @@ -5,7 +5,7 @@ @nb.njit(cache=True) -def A_Hq(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals +def A_Hq(n, sx, nf, L): # pylint: disable=too-many-locals r""" Computes the |N3LO| singlet |OME| :math:`A_{Hq}^{S,(3)}(N)`. The experssion is presented in :cite:`Ablinger_2015` (eq 5.1) @@ -18,14 +18,8 @@ def A_Hq(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals ---------- n : complex Mellin moment - sx : numpy.ndarray - list S1 ... S5 - smx : numpy.ndarray - list Sm1 ... Sm5 - s3x : numpy.ndarray - list S21, S2m1, Sm21, Sm2m1 - s4x : numpy.ndarray - list S31, S221, Sm22, Sm211, Sm31 + sx : list + harmonic sums cache nf : int number of active flavor below the threshold L : float @@ -36,10 +30,11 @@ def A_Hq(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals A_Hq : complex :math:`A_{Hq}^{S,(3)}(N)` """ - S1, S2, S3, S4, S5 = sx[0], sx[1], sx[2], sx[3], sx[4] - Sm2, Sm3, Sm4 = smx[1], smx[2], smx[3] - S21, Sm21 = s3x[0], s3x[2] - S31, S211, Sm22, Sm211, Sm31 = s4x[0], s4x[1], s4x[2], s4x[3], s4x[4] + S1, _ = sx[0] + S2, Sm2 = sx[1] + S3, S21, _, Sm21, _, Sm3 = sx[2] + S4, S31, S211, Sm22, Sm211, Sm31, Sm4 = sx[3] + S5, _ = sx[4] # fit of: # 2^-N * ( H1 + 8.41439832211716) diff --git a/src/eko/matching_conditions/as3/agg.py b/src/eko/matching_conditions/as3/agg.py index 5aa18ef61..862c04f68 100644 --- a/src/eko/matching_conditions/as3/agg.py +++ b/src/eko/matching_conditions/as3/agg.py @@ -19,7 +19,7 @@ def A_gg(n, sx, nf, L): # pylint: disable=too-many-locals ---------- n : complex Mellin moment - sx : numpy.ndarray + sx : list harmonic sums cache nf : int number of active flavor below the threshold diff --git a/src/eko/matching_conditions/as3/aggTF2.py b/src/eko/matching_conditions/as3/aggTF2.py index d39045ff0..707e14443 100644 --- a/src/eko/matching_conditions/as3/aggTF2.py +++ b/src/eko/matching_conditions/as3/aggTF2.py @@ -18,10 +18,8 @@ def A_ggTF2(n, sx): ---------- n : complex Mellin moment - sx : numpy.ndarray + sx : list harmonic sums cache - s3x : numpy.ndarray - list S21, S2m1, Sm21, Sm2m1 Returns ------- @@ -29,8 +27,8 @@ def A_ggTF2(n, sx): :math:`A_{gg,T_{F}^2}^{S,(3)}(N)` """ S1 = sx[0][0] - S1 = sx[1][0] - S1 = sx[2][0] + S2 = sx[1][0] + S3 = sx[2][0] S21 = sx[2][1] # here we use an approximation at large N # for binomial(2 * n, n) / np.power(4, n) diff --git a/src/eko/matching_conditions/as3/agq.py b/src/eko/matching_conditions/as3/agq.py index bf4813600..472389d55 100644 --- a/src/eko/matching_conditions/as3/agq.py +++ b/src/eko/matching_conditions/as3/agq.py @@ -4,7 +4,7 @@ @nb.njit(cache=True) -def A_gq(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals +def A_gq(n, sx, nf, L): # pylint: disable=too-many-locals r""" Computes the |N3LO| singlet |OME| :math:`A_{gq}^{S,(3)}(N)`. The experssion is presented in :cite:`Ablinger_2014` (eq 6.3). @@ -16,14 +16,8 @@ def A_gq(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals ---------- n : complex Mellin moment - sx : numpy.ndarray - list S1 ... S5 - smx : numpy.ndarray - list Sm1 ... Sm5 - s3x : numpy.ndarray - list S21, S2m1, Sm21, Sm2m1 - s4x : numpy.ndarray - list S31, S221, Sm22, Sm211, Sm31 + sx : list + harmonic sums cache nf : int number of active flavor below the threshold L : float @@ -34,10 +28,10 @@ def A_gq(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals A_gq : complex :math:`A_{gq}^{S,(3)}(N)` """ - S1, S2, S3, S4 = sx[0], sx[1], sx[2], sx[3] - Sm1, Sm2, Sm3, Sm4 = smx[0], smx[1], smx[2], smx[3] - S21, S2m1, Sm21, Sm2m1 = s3x[0], s3x[1], s3x[2], s3x[3] - S31, S211, Sm22, Sm211, Sm31 = s4x[0], s4x[1], s4x[2], s4x[3], s4x[4] + S1, Sm1 = sx[0] + S2, Sm2 = sx[1] + S3, S21, S2m1, Sm21, Sm2m1, Sm3 = sx[2] + S4, S31, S211, Sm22, Sm211, Sm31, Sm4 = sx[3] a_gq_l0 = ( 0.3333333333333333 * ( diff --git a/src/eko/matching_conditions/as3/aqg.py b/src/eko/matching_conditions/as3/aqg.py index 741906d01..5f6bd89ac 100644 --- a/src/eko/matching_conditions/as3/aqg.py +++ b/src/eko/matching_conditions/as3/aqg.py @@ -4,7 +4,7 @@ @nb.njit(cache=True) -def A_qg(n, sx, smx, s3x, s4x, nf, L): +def A_qg(n, sx, nf, L): r""" Computes the |N3LO| singlet |OME| :math:`A_{qg}^{S,(3)}(N)`. The expression is presented in :cite:`Bierenbaum:2009mv`. @@ -16,14 +16,8 @@ def A_qg(n, sx, smx, s3x, s4x, nf, L): ---------- n : complex Mellin moment - sx : numpy.ndarray - list S1 ... S5 - smx : numpy.ndarray - list Sm1 ... Sm5 - s3x : numpy.ndarray - list S21, S2m1, Sm21, Sm2m1 - s4x : numpy.ndarray - list S31, S221, Sm22, Sm211, Sm31 + sx : list + harmonic sums cache nf : int number of active flavor below the threshold L : float @@ -34,10 +28,10 @@ def A_qg(n, sx, smx, s3x, s4x, nf, L): A_qg : complex :math:`A_{qg}^{S,(3)}(N)` """ - S1, S2, S3, S4 = sx[0], sx[1], sx[2], sx[3] - Sm2, Sm3, Sm4 = smx[1], smx[2], smx[3] - S21 = s3x[0] - S31, S211 = s4x[0], s4x[1] + S1, _ = sx[0] + S2, Sm2 = sx[1] + S3, S21, _, _, _, Sm3 = sx[2] + S4, S31, S211, _, _, _, Sm4 = sx[3] a_qg_l0 = 0.3333333333333333 * nf * ( ( -8.547960200246003 diff --git a/src/eko/matching_conditions/as3/aqqNS.py b/src/eko/matching_conditions/as3/aqqNS.py index 97a12da85..1f8543426 100644 --- a/src/eko/matching_conditions/as3/aqqNS.py +++ b/src/eko/matching_conditions/as3/aqqNS.py @@ -6,7 +6,7 @@ @nb.njit(cache=True) -def A_qqNS(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals +def A_qqNS(n, sx, nf, L): # pylint: disable=too-many-locals r""" Computes the |N3LO| singlet |OME| :math:`A_{qq}^{NS,(3)}(N)`. The experssion is presented in :cite:`Bierenbaum:2009mv` and @@ -19,14 +19,8 @@ def A_qqNS(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals ---------- n : complex Mellin moment - sx : numpy.ndarray - list S1 ... S5 - smx : numpy.ndarray - list Sm1 ... Sm5 - s3x : numpy.ndarray - list S21, S2m1, Sm21, Sm2m1 - s4x : numpy.ndarray - list S31, S221, Sm22, Sm211, Sm31 + sx : list + harmonic sums cache nf : int number of active flavor below the threshold L : float @@ -37,10 +31,11 @@ def A_qqNS(n, sx, smx, s3x, s4x, nf, L): # pylint: disable=too-many-locals A_qqNS : complex :math:`A_{qq}^{NS,(3)}(N)` """ - S1, S2, S3, S4, S5 = sx[0], sx[1], sx[2], sx[3], sx[4] - Sm1, Sm2, Sm3, Sm4, Sm5 = smx[0], smx[1], smx[2], smx[3], smx[4] - S21, S2m1, Sm21 = s3x[0], s3x[1], s3x[2] - S31, S211, Sm22, Sm211 = s4x[0], s4x[1], s4x[2], s4x[3] + S1, Sm1 = sx[0] + S2, Sm2 = sx[1] + S3, S21, S2m1, Sm21, _, Sm3 = sx[2] + S4, S31, S211, Sm22, Sm211, _, Sm4 = sx[3] + S5, Sm5 = sx[4] S41 = sf.S41(n, S1, S2, S3) S311 = sf.S311(n, S1, S2) S221 = sf.S221(n, S1, S2, S21) diff --git a/src/eko/matching_conditions/as3/aqqPS.py b/src/eko/matching_conditions/as3/aqqPS.py index 9312e3bd9..df845cbf1 100644 --- a/src/eko/matching_conditions/as3/aqqPS.py +++ b/src/eko/matching_conditions/as3/aqqPS.py @@ -16,8 +16,8 @@ def A_qqPS(n, sx, nf, L): ---------- n : complex Mellin moment - sx : numpy.ndarray - list S1 ... S5 + sx : list + harmonic sums cache nf : int number of active flavor below the threshold L : float @@ -28,7 +28,10 @@ def A_qqPS(n, sx, nf, L): A_qqPS : complex :math:`A_{qq}^{PS,(3)}(N)` """ - S1, S2, S3 = sx[0], sx[1], sx[2] + S1 = sx[0][0] + S2 = sx[1][0] + S3 = sx[2][0] + a_qqPS_l0 = ( 0.3333333333333333 * nf diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index 04f270886..82ebe3617 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -32,8 +32,15 @@ def compute_harmonics_cache(n, order): Returns ------- - sx: np.ndarray - harmonic sums cache + sx: list + harmonic sums cache. At |N3LO| it contains: + [ + [S1, Sm1], + [S2, Sm2], + [S3, S21, S2m1, Sm21, Sm2m1, Sm3], + [S4, S31, S211, Sm22, Sm211, Sm31, Sm4], + [S5, Sm5], + ] """ # max harmonics sum weight for each qcd order max_weight = {1: 2, 2: 3, 3: 5} @@ -62,7 +69,7 @@ def A_singlet(order, n, sx, nf, L, is_msbar): perturbative order n : complex Mellin variable - sx : numpy.ndarray + sx : list harmonic sums cache nf: int number of active flavor below threshold @@ -106,7 +113,7 @@ def A_non_singlet(order, n, sx, nf, L): perturbative order n : complex Mellin variable - sx : numpy.ndarray + sx : list harmonic sums cache nf: int number of active flavor below threshold diff --git a/tests/eko/test_matching_n3lo.py b/tests/eko/test_matching_n3lo.py index aecafd640..4c582ec28 100644 --- a/tests/eko/test_matching_n3lo.py +++ b/tests/eko/test_matching_n3lo.py @@ -2,7 +2,6 @@ # Test N3LO OME import numpy as np -from eko import harmonics as h from eko.matching_conditions import as3 from eko.matching_conditions.as3 import A_ns, A_qqNS, A_singlet from eko.matching_conditions.operator_matrix_element import compute_harmonics_cache @@ -14,11 +13,8 @@ def test_A_3(): for L in logs: N = 1.0 - sx = h.sx(N) - smx = h.smx(N) - s3x = h.s3x(N, sx, smx) - s4x = h.s4x(N, sx, smx) - aNSqq3 = A_qqNS(N, sx, smx, s3x, s4x, nf, L) + sx_cache = compute_harmonics_cache(N, 3) + aNSqq3 = A_qqNS(N, sx_cache, nf, L) # quark number conservation # the accuracy of this test depends directly on the precision of the # F functions, thus is dominated by F19,F20,F21 accuracy are the worst ones @@ -27,46 +23,38 @@ def test_A_3(): N = 2.0 sx_cache = compute_harmonics_cache(N, 3) - sx = h.sx(N) - smx = h.smx(N) - s3x = h.s3x(N, sx, smx) - s4x = h.s4x(N, sx, smx) # reference value comes form Mathematica, gg is not fullycomplete # thus the reference value is not 0.0 # Here the accuracy of this test depends on the approximation of AggTF2 np.testing.assert_allclose( as3.A_gg(N, sx_cache, nf, L) - + as3.A_qg(N, sx, smx, s3x, s4x, nf, L) - + as3.A_Hg(N, sx, smx, s3x, s4x, nf, L), + + as3.A_qg(N, sx_cache, nf, L) + + as3.A_Hg(N, sx_cache, nf, L), 145.148, rtol=32e-3, ) # here you get division by 0 as in Mathematica # np.testing.assert_allclose( - # n3lo.A_gq(N, sx, smx, s3x, s4x, nf,L) - # + n3lo.A_qqNS(N, sx, smx, s3x, s4x, nf,L) + # n3lo.A_gq(N, sx_cache, nf,L) + # + n3lo.A_qqNS(N, sx_cache, nf,L) # + n3lo.A_qqPS(N, sx, nf,L) - # + n3lo.A_Hq(N, sx, smx, s3x, s4x, nf,L), + # + n3lo.A_Hq(N, sx_cache, nf,L), # 0.0, # atol=2e-6, # ) # here you get division by 0 as in Mathematica - # sx_all = sx(N) - # sx_all = np.append(sx_all, smx(N)) - # sx_all = np.append(sx_all, s3x(N, sx(N),smx(N))) - # sx_all = np.append(sx_all, s4x(N, sx(N),smx(N))) - # aS3 = A_singlet(N, sx_all, nf, L) + # aS3 = A_singlet(N, sx_cache, nf, L) # gluon momentum conservation # np.testing.assert_allclose(aS3[0, 0] + aS3[1, 0] + aS3[2, 0], 0.0, atol=2e-6) # quark momentum conservation # np.testing.assert_allclose(aS3[0, 1] + aS3[1, 1] + aS3[2, 1], 0.0, atol=1e-11) N = 3 + 2j - sx_all = np.random.rand(5, 7) + 1j * np.random.rand(5, 7) - aS3 = A_singlet(N, sx_all, nf, L) - aNS3 = A_ns(N, sx_all, nf, L) + sx_cache = compute_harmonics_cache(np.random.rand(), 3) + aS3 = A_singlet(N, sx_cache, nf, L) + aNS3 = A_ns(N, sx_cache, nf, L) assert aNS3.shape == (2, 2) assert aS3.shape == (3, 3) @@ -147,8 +135,8 @@ def test_Blumlein_3(): for i, N in enumerate([4.0, 6.0, 10.0, 100.0]): idx = i + 1 for L in [0, 10]: - sx_all = compute_harmonics_cache(N, 3) - aS3 = A_singlet(N, sx_all, nf, L) + sx_cache = compute_harmonics_cache(N, 3) + aS3 = A_singlet(N, sx_cache, nf, L) # here we have a different approximation for AggTF2, # some terms are neglected @@ -180,10 +168,6 @@ def test_Blumlein_3(): ref_ggTF_app = [-28.9075, -180.659, -229.537, -281.337, -467.164] for idx, N in enumerate([2.0, 4.0, 6.0, 10.0, 100.0]): sx_cache = compute_harmonics_cache(N, 3) - sx = h.sx(N) - smx = h.smx(N) - s3x = h.s3x(N, sx, smx) - s4x = h.s4x(N, sx, smx) Aggtf2 = as3.aggTF2.A_ggTF2(N, sx_cache) if N != 100: # Limited in the small N region @@ -200,12 +184,9 @@ def test_Blumlein_3(): # Limited accuracy due to F functions ref_qqNS_odd = [-40.94998646588999, -21.598793547423504, 6.966325573931755] for N, ref in zip([3.0, 15.0, 101.0], ref_qqNS_odd): - sx = h.sx(N) - smx = h.smx(N) - s3x = h.s3x(N, sx, smx) - s4x = h.s4x(N, sx, smx) + sx_cache = compute_harmonics_cache(N, 3) np.testing.assert_allclose( - as3.aqqNS.A_qqNS(N, sx, smx, s3x, s4x, nf, L=0), ref, rtol=3e-2 + as3.aqqNS.A_qqNS(N, sx_cache, nf, L=0), ref, rtol=3e-2 ) @@ -253,10 +234,7 @@ def test_AHq_asymptotic(): # Ns = [31.,32.,33.,34.,35.,36.,37.,38.,39.] nf = 3 for N, r in zip(Ns, refs): - sx = h.sx(N) - smx = h.smx(N) - s3x = h.s3x(N, sx, smx) - s4x = h.s4x(N, sx, smx) + sx_cache = compute_harmonics_cache(N, 3) np.testing.assert_allclose( - as3.aHq.A_Hq(N, sx, smx, s3x, s4x, nf, L=0), r, rtol=1e-5, atol=1e-5 + as3.aHq.A_Hq(N, sx_cache, nf, L=0), r, rtol=1e-5, atol=1e-5 ) diff --git a/tests/eko/test_ome.py b/tests/eko/test_ome.py index 6571211c5..50569dd8e 100644 --- a/tests/eko/test_ome.py +++ b/tests/eko/test_ome.py @@ -30,7 +30,7 @@ def test_build_ome_as(): for o in [1, 2, 3]: if o == 3: N = complex(2.123) - sx = compute_harmonics_cache(np.random.rand(), o) + sx = compute_harmonics_cache(N, o) aNS = A_non_singlet(o, N, sx, nf, L) aS = A_singlet(o, N, sx, nf, L, is_msbar) From 4e86511fb446ed25fec4ddec044b2e377b36f05d Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Fri, 1 Apr 2022 17:25:31 +0200 Subject: [PATCH 25/47] update harmonics docs --- doc/source/theory/Mellin.rst | 34 +++++++++++++------ src/eko/matching_conditions/as1.py | 12 ++----- src/eko/matching_conditions/as2.py | 12 ++----- src/eko/matching_conditions/as3/__init__.py | 28 +++++++-------- .../operator_matrix_element.py | 14 ++++---- 5 files changed, 49 insertions(+), 51 deletions(-) diff --git a/doc/source/theory/Mellin.rst b/doc/source/theory/Mellin.rst index 55f1f49e9..d7fd8562f 100644 --- a/doc/source/theory/Mellin.rst +++ b/doc/source/theory/Mellin.rst @@ -126,19 +126,33 @@ the Mellin inverse. and where :math:`\psi_k(N)` is the :math:`k`-th polygamma function (implemented as :meth:`~eko.harmonics.polygamma.cern_polygamma`) and :math:`\zeta` the Riemann zeta function (using :func:`scipy.special.zeta`). -- for the sums :math:`S_{-m}(N)` and :math:`m > 0` we use :cite:`Gluck:1989ze` +- for the sums :math:`S_{-m}(N)` and :math:`m > 0` we use: .. math :: - S_m'(N) = 2^{m-1}(S_m(N) + S_{-m}(N)) = \frac{1+\eta}{2} S_m(N/2) + \frac{1-\eta}{2}S_m((N-1)/2) + S_{-m}(N) = \frac{\eta}{2} (S_{m}(N / 2) - S_{m}((N - 1) / 2)) - c_{m} -where formally :math:`\eta = (-1)^N` but in all singlet-like quantities it has to be analytically continued with 1 -and with -1 elsewise. + where formally :math:`\eta = (-1)^N` but in all singlet-like quantities it has to be analytically continued with 1 + and with -1 elsewise and :math:`c_{m}= \left [ log(2), 1/2 \zeta_{2}, 3/4 \zeta_{3}, 7/8 \zeta_{4}, 15/16 \zeta_{5} \right]` -- for the sums with greater depth we use the lists provided in :cite:`Gluck:1989ze,MuselliPhD,Blumlein:1998if`. -- For :math:`S_{-2,1}(N)` we use the implementation of :cite:`Gluck:1989ze` (where it is called :math:`\tilde S`): +- for the sums with greater depth we use the definitions provided in :cite:`Gluck:1989ze,MuselliPhD,Blumlein:1998if,Blumlein:2009ta`: -.. math :: - S_{-2,1}(N) &= - \frac 5 8 \zeta(3) + \zeta(2)\left(S_{-1}(N) - \frac{\eta}{N} + \log(2)\right) + \eta\left(\frac{S_{1}(N)}{N^2} + g_3(N)\right)\\ - g_3(N) &= \mathcal M \left[\frac{\text{Li}_2(x)}{1+x}\right](N) +The full list of harmonics sums available in :mod:`eko.harmonics` is: + + - weight 1: :math:`S_{1}, S_{-1}` + - weight 2: :math:`S_{2}, S_{-2}` + - weight 3: :math:`S_{3}, S_{2,1}, S_{2,-1}, S_{-2,1}, S_{-2,-1}, S_{-3}` + - weight 4: + + .. math :: + S_{4}, S_{3,1}, S_{2,1,1}, S_{-2,-2}, S_{-3, 1}, S_{-4} + + these sums relies on the integrals :mod:`eko.harmonics.g_functions` :cite:`MuselliPhD,Blumlein:1998if` + + - weight 5: + + .. math :: + S_{5}, S_{4,1}, S_{3,1,1}, S_{2,3}, S_{2,2,1}, S_{2,1,1,1}, S_{2,1,-2}, S_{2,-3}, S_{-2,3}, S_{-2,2,1}, S_{-2,1,1,1}, S_{-5} + + these sums relies on the integrals :mod:`eko.harmonics.f_functions` :cite:`Blumlein:2009ta` -where for :math:`g_3(N)` we use the parametrization of :cite:`Vogt:2004ns` (implemented as :meth:`~eko.harmonics.g_functions.mellin_g3`). +We have also implemented a recursive computation of simple harmonics (single index), see :func:`eko.harmonics.polygamma.recursive_harmonic_sum` diff --git a/src/eko/matching_conditions/as1.py b/src/eko/matching_conditions/as1.py index 78a070766..cbd9a0baf 100644 --- a/src/eko/matching_conditions/as1.py +++ b/src/eko/matching_conditions/as1.py @@ -132,11 +132,7 @@ def A_singlet(n, sx, L): n : complex Mellin moment sx : list - harmonic sums cache containing: - [ - [S1], - [S2], - ] + harmonic sums cache containing: [[:math:`S_1`][:math:`S_2`]] L : float :math:`\ln(\mu_F^2 / m_h^2)` @@ -179,11 +175,7 @@ def A_ns(n, sx, L): n : complex Mellin moment sx : list - harmonic sums cache containing: - [ - [S1], - [S2], - ] + harmonic sums cache containing: [[:math:`S_1`][:math:`S_2`]] L : float :math:`\ln(\mu_F^2 / m_h^2)` Returns diff --git a/src/eko/matching_conditions/as2.py b/src/eko/matching_conditions/as2.py index 593de7acc..e83d632ea 100644 --- a/src/eko/matching_conditions/as2.py +++ b/src/eko/matching_conditions/as2.py @@ -431,11 +431,7 @@ def A_singlet(n, sx, L, is_msbar=False): Mellin moment sx : list harmonic sums cache containing: - [ - [S1, Sm1], - [S2, Sm2], - [S3, Sm21, Sm3], - ] + [[:math:`S_1,S_{-1}`],[:math:`S_2,S_{-2}`],[:math:`S_3,S_{-2,1},S_{-3}`]] L : float :math:`\ln(\mu_F^2 / m_h^2)` is_msbar: bool @@ -485,11 +481,7 @@ def A_ns(n, sx, L): Mellin moment sx : list harmonic sums cache containing: - [ - [S1, Sm1], - [S2, Sm2], - [S3, Sm21, Sm3], - ] + [[:math:`S_1,S_{-1}`],[:math:`S_2,S_{-2}`],[:math:`S_3,S_{-2,1},S_{-3}`]] L : float :math:`\ln(\mu_F^2 / m_h^2)` diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/eko/matching_conditions/as3/__init__.py index 80f32d365..7863d1971 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/eko/matching_conditions/as3/__init__.py @@ -57,13 +57,13 @@ def A_singlet(n, sx_all, nf, L): Mellin moment sx_all : list harmonic sums cache containing: - [ - [S1, Sm1], - [S2, Sm2], - [S3, S21, S2m1, Sm21, Sm2m1, Sm3], - [S4, S31, S211, Sm22, Sm211, Sm31, Sm4], - [S5, Sm5], - ] + + .. math :: + [[S_1,S_{-1}], + [S_2,S_{-2}], + [S_{3}, S_{2,1}, S_{2,-1}, S_{-2,1}, S_{-2,-1}, S_{-3}], + [S_{4}, S_{3,1}, S_{2,1,1}, S_{-2,-2}, S_{-3, 1}, S_{-4}],] + nf : int number of active flavor below the threshold L : float @@ -115,13 +115,13 @@ def A_ns(n, sx_all, nf, L): Mellin moment sx_all : list harmonic sums cache containing: - [ - [S1, Sm1], - [S2, Sm2], - [S3, S21, S2m1, Sm21, Sm2m1, Sm3], - [S4, S31, S211, Sm22, Sm211, Sm31, Sm4], - [S5, Sm5], - ] + + .. math :: + [[S_1,S_{-1}], + [S_2,S_{-2}], + [S_{3}, S_{2,1}, S_{2,-1}, S_{-2,1}, S_{-2,-1}, S_{-3}], + [S_{4}, S_{3,1}, S_{2,1,1}, S_{-2,-2}, S_{-3, 1}, S_{-4}],] + nf : int number of active flavor below the threshold L : float diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index 82ebe3617..f7c100463 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -34,13 +34,13 @@ def compute_harmonics_cache(n, order): ------- sx: list harmonic sums cache. At |N3LO| it contains: - [ - [S1, Sm1], - [S2, Sm2], - [S3, S21, S2m1, Sm21, Sm2m1, Sm3], - [S4, S31, S211, Sm22, Sm211, Sm31, Sm4], - [S5, Sm5], - ] + + .. math :: + [[S_1,S_{-1}], + [S_2,S_{-2}], + [S_{3}, S_{2,1}, S_{2,-1}, S_{-2,1}, S_{-2,-1}, S_{-3}], + [S_{4}, S_{3,1}, S_{2,1,1}, S_{-2,-2}, S_{-3, 1}, S_{-4}],] + """ # max harmonics sum weight for each qcd order max_weight = {1: 2, 2: 3, 3: 5} From 4cb7767952caaf4ee796c87af1aea26765a5544e Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Fri, 1 Apr 2022 17:46:37 +0200 Subject: [PATCH 26/47] remove try except --- src/eko/matching_conditions/as2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/eko/matching_conditions/as2.py b/src/eko/matching_conditions/as2.py index e83d632ea..a6e18953d 100644 --- a/src/eko/matching_conditions/as2.py +++ b/src/eko/matching_conditions/as2.py @@ -159,9 +159,9 @@ def A_hg(n, sx, L): """ S1 = sx[0][0] S2, Sm2 = sx[1] - try: + if len(sx[2]) == 3: S3, Sm21, Sm3 = sx[2] - except ValueError: + else: S3, _, _, Sm21, _, Sm3 = sx[2] S1m = S1 - 1 / n S2m = S2 - 1 / n**2 From e3606fc564bc6db0c65b4771eec58dc311e504ef Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Mon, 4 Apr 2022 16:19:08 +0200 Subject: [PATCH 27/47] removing not necesarry LO --- src/eko/matching_conditions/operator_matrix_element.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index f7c100463..e60add596 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -90,8 +90,6 @@ def A_singlet(order, n, sx, nf, L, is_msbar): eko.matching_conditions.nlo.A_gh_1 : :math:`A_{gH}^{(1)}(N)` eko.matching_conditions.nnlo.A_singlet_2 : :math:`A_{S,(2)}(N)` """ - if order == 0: - return np.zeros((1, 3, 3), np.complex_) A_s = np.zeros((order, 3, 3), np.complex_) if order >= 1: A_s[0] = as1.A_singlet(n, sx, L) @@ -130,8 +128,6 @@ def A_non_singlet(order, n, sx, nf, L): eko.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` eko.matching_conditions.nnlo.A_ns_2 : :math:`A_{qq,H}^{NS,(2)}` """ - if order == 0: - return np.zeros((1, 2, 2), np.complex_) A_ns = np.zeros((order, 2, 2), np.complex_) if order >= 1: A_ns[0] = as1.A_ns(n, sx, L) From d1a3e8b3b258c6d9c0109062455e8eca39600564 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Mon, 4 Apr 2022 17:44:52 +0200 Subject: [PATCH 28/47] some docs fixes --- doc/source/theory/DGLAP.rst | 2 +- doc/source/theory/Mellin.rst | 36 +++++++++++++++++++++++++---------- src/eko/harmonics/__init__.py | 11 ++++++----- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/doc/source/theory/DGLAP.rst b/doc/source/theory/DGLAP.rst index f7441977c..79d182686 100644 --- a/doc/source/theory/DGLAP.rst +++ b/doc/source/theory/DGLAP.rst @@ -284,7 +284,7 @@ And thus the |NLO| solution: .. math:: \ln \tilde E^{(2)}_{ns}(a_s \leftarrow a_s^0) &= \ln \tilde E^{(1)}_{ns}(a_s \leftarrow a_s^0) + j^{(1,2)'}(a_s,a_s^0)(\gamma^{(1)} - b_1 \gamma^{(0)}) + j^{(2,2)}(a_s,a_s^0)(\gamma^{(2)} - b_2 \gamma^{(0)}) \\ - j^{(1,2)'}(a_s,a_s^0) &= \int\limits_{a_s^0}^{a_s}\!da_s'\,\frac{ \beta_2 a_s'^2}{\beta_0 + \beta_1 a_s' + \beta_2 a_s'^2 ) (\beta_0 + \beta_1 a_s')} + j^{(1,2)'}(a_s,a_s^0) &= \int\limits_{a_s^0}^{a_s}\!da_s'\,\frac{ \beta_2 a_s'^2}{( \beta_0 + \beta_1 a_s' + \beta_2 a_s'^2 ) (\beta_0 + \beta_1 a_s')} In |NNLO| we provide different strategies to define the |EKO|: diff --git a/doc/source/theory/Mellin.rst b/doc/source/theory/Mellin.rst index d7fd8562f..54bafc8c5 100644 --- a/doc/source/theory/Mellin.rst +++ b/doc/source/theory/Mellin.rst @@ -107,40 +107,56 @@ are doing, are proportional to Harmonic Sums ------------- -In the computations of the anomalous dimensions (generalized) harmonic sums +In the computations of the anomalous dimensions and matching conditions, (generalized) harmonic sums :cite:`Ablinger:2013hcp` appear naturally: .. math :: S_{m}(N) &= \sum\limits_{j=1}^N \frac{(\text{sign}(m))^j}{j^{|m|}} \\ S_{m_0,m_1\ldots}(N) &= \sum\limits_{j=1}^N \frac{(\text{sign}(m_0))^j}{j^{|m_0|}} S_{m_1\ldots}(j) +At |N3LO| the anomalous dimensions contains at maximum weight 7 harmonic sums. We then need to find an analytical continuation of these sums into the complex plain to perform the Mellin inverse. - the sums :math:`S_{m}(N)` for :math:`m > 0` do have a straight continuation: -.. math :: + .. math :: S_m(N) = \sum\limits_{j=1}^N \frac 1 {j^m} = \frac{(-1)^{m-1}}{(m-1)!} \psi_{m-1}(N+1)+c_m \quad \text{with}\, c_m = \left\{\begin{array}{ll} \gamma_E, & m=1\\ \zeta(m), & m>1\end{array} \right. -and where :math:`\psi_k(N)` is the :math:`k`-th polygamma function (implemented as :meth:`~eko.harmonics.polygamma.cern_polygamma`) -and :math:`\zeta` the Riemann zeta function (using :func:`scipy.special.zeta`). + where :math:`\psi_k(N)` is the :math:`k`-th polygamma function (implemented as :meth:`~eko.harmonics.polygamma.cern_polygamma`) + and :math:`\zeta` the Riemann zeta function (using :func:`scipy.special.zeta`). - for the sums :math:`S_{-m}(N)` and :math:`m > 0` we use: -.. math :: + .. math :: S_{-m}(N) = \frac{\eta}{2} (S_{m}(N / 2) - S_{m}((N - 1) / 2)) - c_{m} where formally :math:`\eta = (-1)^N` but in all singlet-like quantities it has to be analytically continued with 1 and with -1 elsewise and :math:`c_{m}= \left [ log(2), 1/2 \zeta_{2}, 3/4 \zeta_{3}, 7/8 \zeta_{4}, 15/16 \zeta_{5} \right]` -- for the sums with greater depth we use the definitions provided in :cite:`Gluck:1989ze,MuselliPhD,Blumlein:1998if,Blumlein:2009ta`: +- for the sums with greater depth we use the definitions provided in :cite:`Gluck:1989ze,MuselliPhD,Blumlein:1998if,Blumlein:2009ta`, + which express higher weight sums in terms of simple one :math:`S_{m}, S_{-m}` and some irreducible integrals. + +The complete list of harmonics sums available in :mod:`eko.harmonics` is: + + - weight 1: + + .. math:: + S_{1}, S_{-1} -The full list of harmonics sums available in :mod:`eko.harmonics` is: + - weight 2: + + .. math:: + S_{2}, S_{-2} + + - weight 3: + + .. math:: + S_{3}, S_{2,1}, S_{2,-1}, S_{-2,1}, S_{-2,-1}, S_{-3} + + these sums relies on the integrals :mod:`eko.harmonics.g_functions` :cite:`MuselliPhD,Blumlein:1998if` - - weight 1: :math:`S_{1}, S_{-1}` - - weight 2: :math:`S_{2}, S_{-2}` - - weight 3: :math:`S_{3}, S_{2,1}, S_{2,-1}, S_{-2,1}, S_{-2,-1}, S_{-3}` - weight 4: .. math :: diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index e1a1ddc1a..ca48eb55e 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -30,11 +30,11 @@ def base_harmonics_cache(n, max_weight=5, n_max_sums_weight=7): max harmonics weight, max value 5 (default) n_max_sums_weight : int max number of harmonics sums for a given weight - Retruns + + Returns ------- h_cache : np.ndarray - list of harmonics sums: - (weights, n_max_sums_weight) + list of harmonics sums: (weights, n_max_sums_weight) """ h_cache = np.zeros((max_weight, n_max_sums_weight), dtype=np.complex_) h_cache[:, 0] = sx(n, max_weight) @@ -54,7 +54,8 @@ def sx(n, max_weight=5): Mellin moment max_weight : int max harmonics weight, max value 5 (default) - Retruns + + Returns ------- sx : np.ndarray list of harmonics sums (:math:`S_{1,..,w}`) @@ -85,7 +86,7 @@ def smx(n, max_weight=5): max_weight : int max harmonics weight, max value 5 (default) - Retruns + Returns ------- smx : np.ndarray list of harmonics sums (:math:`S_{-1,..,-w}`) From 143726f639f247d8d6d4738d8189c248bf5147cf Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 4 Apr 2022 18:05:00 +0200 Subject: [PATCH 29/47] Init asv --- benchmarks/.gitignore | 4 ++ benchmarks/asv.conf.json | 91 +++++++++++++++++++++++++++++ benchmarks/performance/__init__.py | 0 benchmarks/performance/harmonics.py | 39 +++++++++++++ pyproject.toml | 6 ++ 5 files changed, 140 insertions(+) create mode 100644 benchmarks/asv.conf.json create mode 100644 benchmarks/performance/__init__.py create mode 100644 benchmarks/performance/harmonics.py diff --git a/benchmarks/.gitignore b/benchmarks/.gitignore index b34cba189..ff7d75b05 100644 --- a/benchmarks/.gitignore +++ b/benchmarks/.gitignore @@ -1,3 +1,7 @@ +# ignore airspeed velocity output +html/ +results/ + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json new file mode 100644 index 000000000..628c6b460 --- /dev/null +++ b/benchmarks/asv.conf.json @@ -0,0 +1,91 @@ +{ + // The version of the config file format. Do not change, unless + // you know what you are doing. + "version": 1, + + // The name of the project being benchmarked + "project": "eko", + + // The project's homepage + "project_url": "https://n3pdf.github.io/eko/", + + // The URL or local path of the source code repository for the + // project being benchmarked + "repo": "..", + + // List of branches to benchmark. If not provided, defaults to "master" + // (for git) or "tip" (for mercurial). + "branches": ["HEAD"], + + // The DVCS being used. If not set, it will be automatically + // determined from "repo" by looking at the protocol in the URL + // (if remote), or by looking for special directories, such as + // ".git" (if local). + "dvcs": "git", + + // The tool to use to create environments. May be "conda", + // "virtualenv" or other value depending on the plugins in use. + // If missing or the empty string, the tool will be automatically + // determined by looking for tools on the PATH environment + // variable. + "environment_type": "virtualenv", + + // the base URL to show a commit for the project. + "show_commit_url": "https://github.com/N3PDF/eko/commit/", + + // The Pythons you'd like to test against. If not provided, defaults + // to the current version of Python used to run `asv`. + "pythons": ["3.8", "3.9", "3.10"], + + // The matrix of dependencies to test. Each key is the name of a + // package (in PyPI) and the values are version numbers. An empty + // list indicates to just test against the default (latest) + //version. + "matrix": { + "poetry": [] + }, + + // The directory (relative to the current directory) that benchmarks are + // stored in. If not provided, defaults to "benchmarks" + "benchmark_dir": "performance", + + // The directory (relative to the current directory) to cache the Python + // environments in. If not provided, defaults to "env" + // "env_dir": "env", + + // The directory (relative to the current directory) that raw benchmark + // results are stored in. If not provided, defaults to "results". + "results_dir": "results", + + // The directory (relative to the current directory) that the html tree + // should be written to. If not provided, defaults to "html". + "html_dir": "html", + + // The number of characters to retain in the commit hashes. + // "hash_length": 8, + + // `asv` will cache wheels of the recent builds in each + // environment, making them faster to install next time. This is + // number of builds to keep, per environment. + "build_cache_size": 8, + + // The commits after which the regression search in `asv publish` + // should start looking for regressions. Dictionary whose keys are + // regexps matching to benchmark names, and values corresponding to + // the commit (exclusive) after which to start looking for + // regressions. The default is to start from the first commit + // with results. If the commit is `null`, regression detection is + // skipped for the matching benchmark. + // + // "regressions_first_commits": { + // "some_benchmark": "352cdf", // Consider regressions only after this commit + // "another_benchmark": null, // Skip regression detection altogether + // } + + + "install_command": ["in-dir={env_dir} python -mpip install {wheel_file}[mark]"], + + "build_command": [ + "PIP_NO_BUILD_ISOLATION=false python -mpip wheel --no-deps -w {build_cache_dir} {build_dir}" + ] +} diff --git a/benchmarks/performance/__init__.py b/benchmarks/performance/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/benchmarks/performance/harmonics.py b/benchmarks/performance/harmonics.py new file mode 100644 index 000000000..922eb316e --- /dev/null +++ b/benchmarks/performance/harmonics.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +import numpy as np + +from eko import anomalous_dimensions as ad +from eko.mellin import Path + +NF = 5 + + +class TimeSuite: + def setup(self): + ts = np.linspace(0.5, 1.0 - 1e-5, 100) + logx = 0.8 + axis_offset = True + self.ns = [] + for t in ts: + self.ns.append(Path(t, logx, axis_offset).n) + + def time_as1_sing(self): + for n in self.ns: + ad.gamma_singlet(0, n, NF) + + def time_as2_sing(self): + for n in self.ns: + ad.gamma_singlet(1, n, NF) + + def time_as3_sing(self): + for n in self.ns: + ad.gamma_singlet(2, n, NF) + + +# class MemorySuite: +# def mem_sf(self): +# return compute_sf() + + +# class PeakMemorySuite: +# def peakmem_sf(self): +# compute_sf() diff --git a/pyproject.toml b/pyproject.toml index 054e83b27..de47e9e2f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,6 +92,12 @@ docs-view = { "shell" = "cd doc; make view" } docs-server = { "shell" = "cd doc; make server" } docs-clean = { "shell" = "cd doc; make clean" } docs-cleanall = { "shell" = "cd doc; make cleanall" } +asv-run = "asv run --config benchmarks/asv.conf.json master..HEAD" +asv-preview = "asv preview --config benchmarks/asv.conf.json" +asv-publish = "asv publish --config benchmarks/asv.conf.json" +asv-show = "asv show --config benchmarks/asv.conf.json" +asv-clean = { "shell" = "rm -rf benchmarks/env benchmarks/html benchmarks/results" } +asv = ["asv-run", "asv-publish", "asv-preview"] [tool.pytest.ini_options] testpaths = ['tests/', 'benchmarks/'] From 4e5c2b1768162bab5c89df328efd8e53b9349821 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 4 Apr 2022 18:20:21 +0200 Subject: [PATCH 30/47] Add asv as dev-dep --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index de47e9e2f..d9ebb4482 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,9 @@ pytest-cov = "^3.0.0" pytest-env = "^0.6.2" a3b2bbc3ced97675ac3a71df45f55ba = "^6.4.0" # = lhapdf # benchmark +asv = "^0.4.2" +virtualenv = "^20.13.2" +# docs Sphinx = "^4.3.2" sphinx-rtd-theme = "^1.0.0" sphinxcontrib-bibtex = "^2.4.1" From 81ad0b589b53e1286f49900acc0953fae75f8665 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 5 Apr 2022 11:27:36 +0200 Subject: [PATCH 31/47] Call ev_op.compute once in parallel --- tests/eko/test_ev_operator.py | 119 +++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 45 deletions(-) diff --git a/tests/eko/test_ev_operator.py b/tests/eko/test_ev_operator.py index ba7cfc807..a085442d3 100644 --- a/tests/eko/test_ev_operator.py +++ b/tests/eko/test_ev_operator.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import copy import os import numpy as np @@ -124,6 +125,44 @@ def test_quad_ker(monkeypatch): np.testing.assert_allclose(res_ns, 0.0) +theory_card = { + "alphas": 0.35, + "PTO": 0, + "ModEv": "TRN", + "fact_to_ren_scale_ratio": 1.0, + "Qref": np.sqrt(2), + "nfref": None, + "Q0": np.sqrt(2), + "nf0": 3, + "FNS": "FFNS", + "NfFF": 3, + "IC": 0, + "IB": 0, + "mc": 1.0, + "mb": 4.75, + "mt": 173.0, + "kcThr": np.inf, + "kbThr": np.inf, + "ktThr": np.inf, + "MaxNfPdf": 6, + "MaxNfAs": 6, + "HQ": "POLE", + "ModSV": None, +} +operators_card = { + "Q2grid": [1, 10], + "interpolation_xgrid": [0.1, 1.0], + "interpolation_polynomial_degree": 1, + "interpolation_is_log": True, + "debug_skip_singlet": False, + "debug_skip_non_singlet": False, + "ev_op_max_order": 1, + "ev_op_iterations": 1, + "backward_inversion": "exact", + "n_integration_cores": 1, +} + + class TestOperator: def test_labels(self): o = Operator( @@ -168,58 +207,28 @@ def test_n_pools(self): ) assert o.n_pools == os.cpu_count() - excluded_cores - def test_compute(self, monkeypatch): - # setup objs - theory_card = { - "alphas": 0.35, - "PTO": 0, - "ModEv": "TRN", - "fact_to_ren_scale_ratio": 1.0, - "Qref": np.sqrt(2), - "nfref": None, - "Q0": np.sqrt(2), - "nf0": 3, - "FNS": "FFNS", - "NfFF": 3, - "IC": 0, - "IB": 0, - "mc": 1.0, - "mb": 4.75, - "mt": 173.0, - "kcThr": np.inf, - "kbThr": np.inf, - "ktThr": np.inf, - "MaxNfPdf": 6, - "MaxNfAs": 6, - "HQ": "POLE", - "ModSV": None, - } - operators_card = { - "Q2grid": [1, 10], - "interpolation_xgrid": [0.1, 1.0], - "interpolation_polynomial_degree": 1, - "interpolation_is_log": True, - "debug_skip_singlet": False, - "debug_skip_non_singlet": False, - "ev_op_max_order": 1, - "ev_op_iterations": 1, - "backward_inversion": "exact", - "n_integration_cores": 1, - } + def test_compute_parallel(self, monkeypatch): + tcard = copy.deepcopy(theory_card) + ocard = copy.deepcopy(operators_card) + ocard["n_integration_cores"] = 2 g = OperatorGrid.from_dict( - theory_card, - operators_card, - ThresholdsAtlas.from_dict(theory_card), - StrongCoupling.from_dict(theory_card), - InterpolatorDispatcher.from_dict(operators_card), + tcard, + ocard, + ThresholdsAtlas.from_dict(tcard), + StrongCoupling.from_dict(tcard), + InterpolatorDispatcher.from_dict(ocard), ) - o = Operator(g.config, g.managers, 3, 2, 10) + # setup objs + o = Operator(g.config, g.managers, 3, 2.0, 10.0) # fake quad monkeypatch.setattr( scipy.integrate, "quad", lambda *args, **kwargs: np.random.rand(2) ) # LO o.compute() + self.check_lo(o) + + def check_lo(self, o): assert (br.non_singlet_pids_map["ns-"], 0) in o.op_members np.testing.assert_allclose( o.op_members[(br.non_singlet_pids_map["ns-"], 0)].value, @@ -229,6 +238,26 @@ def test_compute(self, monkeypatch): o.op_members[(br.non_singlet_pids_map["nsV"], 0)].value, o.op_members[(br.non_singlet_pids_map["ns+"], 0)].value, ) + + def test_compute(self, monkeypatch): + tcard = copy.deepcopy(theory_card) + ocard = copy.deepcopy(operators_card) + g = OperatorGrid.from_dict( + tcard, + ocard, + ThresholdsAtlas.from_dict(tcard), + StrongCoupling.from_dict(tcard), + InterpolatorDispatcher.from_dict(ocard), + ) + # setup objs + o = Operator(g.config, g.managers, 3, 2.0, 10.0) + # fake quad + monkeypatch.setattr( + scipy.integrate, "quad", lambda *args, **kwargs: np.random.rand(2) + ) + # LO + o.compute() + self.check_lo(o) # NLO o.config["order"] = 1 o.compute() @@ -243,7 +272,7 @@ def test_compute(self, monkeypatch): # unity operators for n in range(0, 2 + 1): - o1 = Operator(g.config, g.managers, 3, 2, 2) + o1 = Operator(g.config, g.managers, 3, 2.0, 2.0) o1.config["order"] = n o1.compute() for k in br.non_singlet_labels: From 4aa9cd936f25ab1df02490f267deead35181282a Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 5 Apr 2022 11:43:25 +0200 Subject: [PATCH 32/47] Update Mellin doc --- doc/source/theory/Mellin.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/theory/Mellin.rst b/doc/source/theory/Mellin.rst index 54bafc8c5..fd4a4ab63 100644 --- a/doc/source/theory/Mellin.rst +++ b/doc/source/theory/Mellin.rst @@ -130,10 +130,10 @@ the Mellin inverse. - for the sums :math:`S_{-m}(N)` and :math:`m > 0` we use: .. math :: - S_{-m}(N) = \frac{\eta}{2} (S_{m}(N / 2) - S_{m}((N - 1) / 2)) - c_{m} + S_{-m}(N) = \frac{\eta}{2} (S_{m}(N / 2) - S_{m}((N - 1) / 2)) - d_{m} where formally :math:`\eta = (-1)^N` but in all singlet-like quantities it has to be analytically continued with 1 - and with -1 elsewise and :math:`c_{m}= \left [ log(2), 1/2 \zeta_{2}, 3/4 \zeta_{3}, 7/8 \zeta_{4}, 15/16 \zeta_{5} \right]` + and with -1 elsewise and :math:`d_{m}= \left [ \log(2), 1/2 \zeta_{2}, 3/4 \zeta_{3}, 7/8 \zeta_{4}, 15/16 \zeta_{5}, \ldots \right]` - for the sums with greater depth we use the definitions provided in :cite:`Gluck:1989ze,MuselliPhD,Blumlein:1998if,Blumlein:2009ta`, which express higher weight sums in terms of simple one :math:`S_{m}, S_{-m}` and some irreducible integrals. From 2d5482f6441f16b0b304177fddb7301f1cee4186 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 5 Apr 2022 12:11:42 +0200 Subject: [PATCH 33/47] Update docstrings --- src/eko/harmonics/polygamma.py | 14 +++++++------- src/eko/harmonics/w1.py | 4 ++-- src/eko/harmonics/w2.py | 4 ++-- src/eko/harmonics/w3.py | 12 ++++++------ src/eko/harmonics/w4.py | 4 ++-- src/eko/harmonics/w5.py | 24 ++++++++++++------------ 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/eko/harmonics/polygamma.py b/src/eko/harmonics/polygamma.py index b9bc9c78b..03d877150 100644 --- a/src/eko/harmonics/polygamma.py +++ b/src/eko/harmonics/polygamma.py @@ -129,15 +129,15 @@ def cern_polygamma(Z, K): # pylint: disable=all @nb.njit(cache=True) def recursive_harmonic_sum(base_value, n, iterations, weight): """ - Compute the harmonic sum :math:`S_{w}(N+i)` stating from the value - S_{w}(N) + Compute the harmonic sum :math:`S_{w}(N+k)` stating from the value + :math:`S_{w}(N)` via the recurrence relations. Parameters ---------- base_value: complex - starting value :math:`S_{w}(N+i)` + starting value :math:`S_{w}(N)` n: complex - starting value + starting point iterations: int number of iterations weight: int @@ -146,9 +146,9 @@ def recursive_harmonic_sum(base_value, n, iterations, weight): Returns ------- sni : complex - :math:`S_{w}(N+i)` + :math:`S_{w}(N+k)` """ - fact = 0 + fact = 0.0 for i in range(1, iterations + 1): - fact += 1 / (n + i) ** weight + fact += 1.0 / (n + i) ** weight return base_value + fact diff --git a/src/eko/harmonics/w1.py b/src/eko/harmonics/w1.py index e929bc7ab..d31c003f1 100644 --- a/src/eko/harmonics/w1.py +++ b/src/eko/harmonics/w1.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Weight 1 harmonics sum. +Weight 1 harmonic sums. """ import numba as nb import numpy as np @@ -43,7 +43,7 @@ def Sm1(N): Analytic continuation of harmonic sum :math:`S_{-1}(N)`. .. math:: - S_{-1}(N) = \sum\limits_{j=1}^N \frac (-1)^j j + S_{-1}(N) = \sum\limits_{j=1}^N \frac {(-1)^j} j Parameters ---------- diff --git a/src/eko/harmonics/w2.py b/src/eko/harmonics/w2.py index 5ab7b8262..2f14cb98a 100644 --- a/src/eko/harmonics/w2.py +++ b/src/eko/harmonics/w2.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Weight 2 harmonics sum. +Weight 2 harmonic sums. """ import numba as nb @@ -42,7 +42,7 @@ def Sm2(N): Analytic continuation of harmonic sum :math:`S_{-2}(N)`. .. math:: - S_{-2}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^2 + S_{-2}(N) = \sum\limits_{j=1}^N \frac {(-1)^j}{j^2} Parameters ---------- diff --git a/src/eko/harmonics/w3.py b/src/eko/harmonics/w3.py index 35c9624e8..fdc85e274 100644 --- a/src/eko/harmonics/w3.py +++ b/src/eko/harmonics/w3.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Weight 3 harmonics sum. +Weight 3 harmonic sums. """ import numba as nb @@ -43,7 +43,7 @@ def Sm3(N): Analytic continuation of harmonic sum :math:`S_{-3}(N)`. .. math:: - S_{-3}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^3 + S_{-3}(N) = \sum\limits_{j=1}^N \frac {(-1)^j} {j^3} Parameters ---------- @@ -66,7 +66,7 @@ def Sm3(N): def S21(N, S1, S2): r""" Analytic continuation of harmonic sum :math:`S_{2,1}(N)` - as implemented in eq B.5.77 of :cite:`MuselliPhD` and eq 37 of cite:`Bl_mlein_2000`. + as implemented in eq B.5.77 of :cite:`MuselliPhD` and eq 37 of :cite:`Bl_mlein_2000`. Parameters ---------- @@ -93,7 +93,7 @@ def S21(N, S1, S2): def Sm21(N, S1, Sm1): r""" Analytic continuation of harmonic sum :math:`S_{-2,1}(N)` - as implemented in eq B.5.75 of :cite:`MuselliPhD` and eq 22 of cite:`Bl_mlein_2000`. + as implemented in eq B.5.75 of :cite:`MuselliPhD` and eq 22 of :cite:`Bl_mlein_2000`. Parameters ---------- @@ -126,7 +126,7 @@ def Sm21(N, S1, Sm1): def S2m1(N, S2, Sm1, Sm2): r""" Analytic continuation of harmonic sum :math:`S_{2,-1}(N)` - as implemented in eq B.5.76 of :cite:`MuselliPhD` and eq 23 of cite:`Bl_mlein_2000`. + as implemented in eq B.5.76 of :cite:`MuselliPhD` and eq 23 of :cite:`Bl_mlein_2000`. Parameters ---------- @@ -161,7 +161,7 @@ def S2m1(N, S2, Sm1, Sm2): def Sm2m1(N, S1, S2, Sm2): r""" Analytic continuation of harmonic sum :math:`S_{-2,-1}(N)` - as implemented in eq B.5.74 of :cite:`MuselliPhD` and eq 38 of cite:`Bl_mlein_2000`. + as implemented in eq B.5.74 of :cite:`MuselliPhD` and eq 38 of :cite:`Bl_mlein_2000`. Parameters ---------- diff --git a/src/eko/harmonics/w4.py b/src/eko/harmonics/w4.py index 9537ca941..bfc807a87 100644 --- a/src/eko/harmonics/w4.py +++ b/src/eko/harmonics/w4.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Weight 4 harmonics sum. +Weight 4 harmonic sums. """ import numba as nb @@ -43,7 +43,7 @@ def Sm4(N): Analytic continuation of harmonic sum :math:`S_{-4}(N)`. .. math:: - S_{-4}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^4 + S_{-4}(N) = \sum\limits_{j=1}^N \frac {(-1)^j} {j^4} Parameters ---------- diff --git a/src/eko/harmonics/w5.py b/src/eko/harmonics/w5.py index bb8cdd5bc..816692a27 100644 --- a/src/eko/harmonics/w5.py +++ b/src/eko/harmonics/w5.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Weight 5 harmonics sum. +Weight 5 harmonic sums. """ import numba as nb @@ -43,7 +43,7 @@ def Sm5(N): Analytic continuation of harmonic sum :math:`S_{-5}(N)`. .. math:: - S_{-5}(N) = \sum\limits_{j=1}^N \frac (-1)^j j^5 + S_{-5}(N) = \sum\limits_{j=1}^N \frac {(-1)^j} {j^5} Parameters ---------- @@ -66,7 +66,7 @@ def Sm5(N): def S41(N, S1, S2, S3): r""" Analytic continuation of harmonic sum :math:`S_{4,1}(N)` - as implemented in eq 9.1 of cite:` Bl_mlein_2009` + as implemented in eq 9.1 of :cite:` Bl_mlein_2009` Parameters ---------- @@ -96,7 +96,7 @@ def S41(N, S1, S2, S3): def S311(N, S1, S2): r""" Analytic continuation of harmonic sum :math:`S_{3,1,1}(N)` - as implemented in eq 9.21 of cite:` Bl_mlein_2009` + as implemented in eq 9.21 of :cite:` Bl_mlein_2009` Parameters ---------- @@ -124,7 +124,7 @@ def S311(N, S1, S2): def S221(N, S1, S2, S21): r""" Analytic continuation of harmonic sum :math:`S_{2,2,1}(N)` - as implemented in eq 9.23 of cite:` Bl_mlein_2009` + as implemented in eq 9.23 of :cite:` Bl_mlein_2009` Parameters ---------- @@ -161,7 +161,7 @@ def S221(N, S1, S2, S21): def Sm221(N, S1, Sm1, S21, Sm21): r""" Analytic continuation of harmonic sum :math:`S_{-2,2,1}(N)` - as implemented in eq 9.25 of cite:` Bl_mlein_2009` + as implemented in eq 9.25 of :cite:` Bl_mlein_2009` Parameters ---------- @@ -199,7 +199,7 @@ def Sm221(N, S1, Sm1, S21, Sm21): def S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1): r""" Analytic continuation of harmonic sum :math:`S_{2,1,-2}(N)` - as implemented in eq 9.26 of cite:` Bl_mlein_2009` + as implemented in eq 9.26 of :cite:` Bl_mlein_2009` Parameters ---------- @@ -247,7 +247,7 @@ def S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1): def S2111(N, S1, S2, S3): r""" Analytic continuation of harmonic sum :math:`S_{2,1,1,1}(N)` - as implemented in eq 9.33 of cite:` Bl_mlein_2009` + as implemented in eq 9.33 of :cite:` Bl_mlein_2009` Parameters ---------- @@ -277,7 +277,7 @@ def S2111(N, S1, S2, S3): def Sm2111(N, S1, S2, S3, Sm1): r""" Analytic continuation of harmonic sum :math:`S_{-2,1,1,1}(N)` - as implemented in eq 9.34 of cite:` Bl_mlein_2009` + as implemented in eq 9.34 of :cite:` Bl_mlein_2009` Parameters ---------- @@ -314,7 +314,7 @@ def Sm2111(N, S1, S2, S3, Sm1): def S23(N, S1, S2, S3): r""" Analytic continuation of harmonic sum :math:`S_{2,3}(N)` - as implemented in eq 9.3 of cite:` Bl_mlein_2009` + as implemented in eq 9.3 of :cite:` Bl_mlein_2009` Parameters ---------- @@ -348,7 +348,7 @@ def S23(N, S1, S2, S3): def Sm23(N, Sm1, Sm2, Sm3): r""" Analytic continuation of harmonic sum :math:`S_{-2,3}(N)` - as implemented in eq 9.4 of cite:` Bl_mlein_2009` + as implemented in eq 9.4 of :cite:` Bl_mlein_2009` Parameters ---------- @@ -388,7 +388,7 @@ def Sm23(N, Sm1, Sm2, Sm3): def S2m3(N, S2, Sm1, Sm2, Sm3): r""" Analytic continuation of harmonic sum :math:`S_{2,-3}(N)` - as implemented in eq 9.5 of cite:` Bl_mlein_2009` + as implemented in eq 9.5 of :cite:` Bl_mlein_2009` Parameters ---------- From bb9693cc1928b94851bd570461f9428da8a63587 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 5 Apr 2022 12:12:01 +0200 Subject: [PATCH 34/47] Update lock file --- poetry.lock | 660 ++++++++++++++++++++++++++++------------------------ 1 file changed, 358 insertions(+), 302 deletions(-) diff --git a/poetry.lock b/poetry.lock index fc0504481..adb51b5cd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -24,7 +24,7 @@ python-versions = "*" [[package]] name = "appnope" -version = "0.1.2" +version = "0.1.3" description = "Disable App Nap on macOS >= 10.9" category = "main" optional = true @@ -32,7 +32,7 @@ python-versions = "*" [[package]] name = "astroid" -version = "2.9.3" +version = "2.11.2" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false @@ -41,7 +41,7 @@ python-versions = ">=3.6.2" [package.dependencies] lazy-object-proxy = ">=1.4.0" typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} -wrapt = ">=1.11,<1.14" +wrapt = ">=1.11,<2" [[package]] name = "asttokens" @@ -57,6 +57,20 @@ six = "*" [package.extras] test = ["astroid", "pytest"] +[[package]] +name = "asv" +version = "0.4.2" +description = "Airspeed Velocity: A simple Python history benchmarking tool" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +six = ">=1.4" + +[package.extras] +hg = ["python-hglib (>=1.5)"] + [[package]] name = "atomicwrites" version = "1.4.0" @@ -100,7 +114,7 @@ python-versions = "*" [[package]] name = "banana-hep" -version = "0.6.4" +version = "0.6.5" description = "Benchmark QCD physics" category = "main" optional = true @@ -150,11 +164,11 @@ unicode_backport = ["unicodedata2"] [[package]] name = "click" -version = "8.0.4" +version = "8.1.2" description = "Composable command line interface toolkit" category = "main" optional = true -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -208,6 +222,17 @@ category = "main" optional = true python-versions = ">=3.5" +[[package]] +name = "dill" +version = "0.3.4" +description = "serialize all of python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*" + +[package.extras] +graph = ["objgraph (>=1.7.2)"] + [[package]] name = "distlib" version = "0.3.4" @@ -258,7 +283,7 @@ testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-co [[package]] name = "fonttools" -version = "4.29.1" +version = "4.31.2" description = "Tools to manipulate font files" category = "main" optional = true @@ -290,7 +315,7 @@ docs = ["sphinx"] [[package]] name = "identify" -version = "2.4.11" +version = "2.4.12" description = "File identification library for Python" category = "dev" optional = false @@ -317,7 +342,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "4.11.2" +version = "4.11.3" description = "Read metadata from Python packages" category = "main" optional = false @@ -341,7 +366,7 @@ python-versions = "*" [[package]] name = "ipython" -version = "8.1.1" +version = "8.2.0" description = "IPython: Productive Interactive Computing" category = "main" optional = true @@ -362,7 +387,7 @@ stack-data = "*" traitlets = ">=5" [package.extras] -all = ["black", "Sphinx (>=1.3)", "ipykernel", "nbconvert", "nbformat", "ipywidgets", "notebook", "ipyparallel", "qtconsole", "curio", "matplotlib (!=3.2.0)", "numpy (>=1.19)", "pandas", "pytest", "testpath", "trio", "pytest-asyncio"] +all = ["black", "Sphinx (>=1.3)", "ipykernel", "nbconvert", "nbformat", "ipywidgets", "notebook", "ipyparallel", "qtconsole", "pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "numpy (>=1.19)", "pandas", "trio"] black = ["black"] doc = ["Sphinx (>=1.3)"] kernel = ["ipykernel"] @@ -371,8 +396,8 @@ nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pytest", "pytest-asyncio", "testpath"] -test_extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.19)", "pandas", "pytest", "testpath", "trio"] +test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] +test_extra = ["pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.19)", "pandas", "trio"] [[package]] name = "isort" @@ -405,11 +430,11 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" -version = "3.0.3" +version = "3.1.1" description = "A very fast and expressive template engine." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] MarkupSafe = ">=2.0" @@ -419,7 +444,7 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "kiwisolver" -version = "1.3.2" +version = "1.4.2" description = "A fast implementation of the Cassowary constraint solver" category = "main" optional = true @@ -467,7 +492,7 @@ tests = ["pytest (!=3.3.0)", "psutil", "pytest-cov"] [[package]] name = "markupsafe" -version = "2.1.0" +version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false @@ -505,11 +530,11 @@ traitlets = "*" [[package]] name = "mccabe" -version = "0.6.1" +version = "0.7.0" description = "McCabe checker, plugin for flake8" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "nodeenv" @@ -552,7 +577,7 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pandas" -version = "1.4.1" +version = "1.4.2" description = "Powerful data structures for data analysis, time series, and statistics" category = "main" optional = true @@ -633,12 +658,16 @@ python-versions = "*" [[package]] name = "pillow" -version = "9.0.1" +version = "9.1.0" description = "Python Imaging Library (Fork)" category = "main" optional = true python-versions = ">=3.7" +[package.extras] +docs = ["olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinx-rtd-theme (>=1.0)", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] + [[package]] name = "platformdirs" version = "2.5.1" @@ -665,11 +694,11 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "2.17.0" +version = "2.18.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.7" [package.dependencies] cfgv = ">=2.0.0" @@ -681,7 +710,7 @@ virtualenv = ">=20.0.8" [[package]] name = "prompt-toolkit" -version = "3.0.28" +version = "3.0.29" description = "Library for building powerful interactive command lines in Python" category = "main" optional = true @@ -755,21 +784,25 @@ python-versions = ">=3.5" [[package]] name = "pylint" -version = "2.12.2" +version = "2.13.4" description = "python code static checker" category = "dev" optional = false python-versions = ">=3.6.2" [package.dependencies] -astroid = ">=2.9.0,<2.10" +astroid = ">=2.11.2,<=2.12.0-dev0" colorama = {version = "*", markers = "sys_platform == \"win32\""} +dill = ">=0.2" isort = ">=4.2.5,<6" -mccabe = ">=0.6,<0.7" +mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" -toml = ">=0.9.2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} +[package.extras] +testutil = ["gitpython (>3)"] + [[package]] name = "pyparsing" version = "3.0.7" @@ -857,7 +890,7 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2021.3" +version = "2022.1" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -958,7 +991,7 @@ python-versions = "*" [[package]] name = "sphinx" -version = "4.4.0" +version = "4.5.0" description = "Python documentation generator" category = "main" optional = false @@ -1090,7 +1123,7 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "1.4.32" +version = "1.4.34" description = "Database Abstraction Library" category = "main" optional = true @@ -1103,7 +1136,7 @@ greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platfo aiomysql = ["greenlet (!=0.4.17)", "aiomysql"] aiosqlite = ["typing_extensions (!=3.10.0.1)", "greenlet (!=0.4.17)", "aiosqlite"] asyncio = ["greenlet (!=0.4.17)"] -asyncmy = ["greenlet (!=0.4.17)", "asyncmy (>=0.2.3)"] +asyncmy = ["greenlet (!=0.4.17)", "asyncmy (>=0.2.3,!=0.2.4)"] mariadb_connector = ["mariadb (>=1.0.1)"] mssql = ["pyodbc"] mssql_pymssql = ["pymssql"] @@ -1173,20 +1206,20 @@ python-versions = ">=3.6" [[package]] name = "urllib3" -version = "1.26.8" +version = "1.26.9" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] -brotli = ["brotlipy (>=0.6.0)"] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.13.3" +version = "20.14.0" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -1220,7 +1253,7 @@ python-versions = "*" [[package]] name = "wrapt" -version = "1.13.3" +version = "1.14.0" description = "Module for decorators, wrappers and monkey patching." category = "dev" optional = false @@ -1228,15 +1261,15 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "zipp" -version = "3.7.0" +version = "3.8.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] [extras] box = ["banana-hep", "sqlalchemy", "pandas", "matplotlib"] @@ -1246,7 +1279,7 @@ mark = ["banana-hep", "sqlalchemy", "pandas", "matplotlib"] [metadata] lock-version = "1.1" python-versions = "^3.8,<3.11" -content-hash = "59deb666ca547633026cedb1a6ef346c95da7e29168c026881b42da5cb0ea983" +content-hash = "0e56ea9ff0b071e60f311f1997d5103f4c5537a020ae6b61f86feabca8a7f5e2" [metadata.files] a3b2bbc3ced97675ac3a71df45f55ba = [ @@ -1267,17 +1300,20 @@ appdirs = [ {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] appnope = [ - {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, - {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, + {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, + {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, ] astroid = [ - {file = "astroid-2.9.3-py3-none-any.whl", hash = "sha256:506daabe5edffb7e696ad82483ad0228245a9742ed7d2d8c9cdb31537decf9f6"}, - {file = "astroid-2.9.3.tar.gz", hash = "sha256:1efdf4e867d4d8ba4a9f6cf9ce07cd182c4c41de77f23814feb27ca93ca9d877"}, + {file = "astroid-2.11.2-py3-none-any.whl", hash = "sha256:cc8cc0d2d916c42d0a7c476c57550a4557a083081976bf42a73414322a6411d9"}, + {file = "astroid-2.11.2.tar.gz", hash = "sha256:8d0a30fe6481ce919f56690076eafbb2fb649142a89dc874f1ec0e7a011492d0"}, ] asttokens = [ {file = "asttokens-2.0.5-py2.py3-none-any.whl", hash = "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c"}, {file = "asttokens-2.0.5.tar.gz", hash = "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"}, ] +asv = [ + {file = "asv-0.4.2.tar.gz", hash = "sha256:9134f56b7a2f465420f17b5bb0dee16047a70f01029c996b7ab3f197de2d0779"}, +] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, @@ -1295,8 +1331,8 @@ backcall = [ {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] banana-hep = [ - {file = "banana-hep-0.6.4.tar.gz", hash = "sha256:e642946fad9545e1aec0a8108b0d31deb01b8f0d50411951f323123c4da75c2e"}, - {file = "banana_hep-0.6.4-py3-none-any.whl", hash = "sha256:9e02874b135e900244fe8c007d192844cccb1191eb07ed949c9e229524365b07"}, + {file = "banana-hep-0.6.5.tar.gz", hash = "sha256:748923aae41d5be0e117516698e523935d5f68146b53a8565372c7489137b0f1"}, + {file = "banana_hep-0.6.5-py3-none-any.whl", hash = "sha256:6a8da394b0492cdd11f454a73c81727aff1bc96b206f1ca109cecdd087b980cd"}, ] certifi = [ {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, @@ -1311,8 +1347,8 @@ charset-normalizer = [ {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, ] click = [ - {file = "click-8.0.4-py3-none-any.whl", hash = "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1"}, - {file = "click-8.0.4.tar.gz", hash = "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"}, + {file = "click-8.1.2-py3-none-any.whl", hash = "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e"}, + {file = "click-8.1.2.tar.gz", hash = "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"}, ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, @@ -1373,6 +1409,10 @@ decorator = [ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] +dill = [ + {file = "dill-0.3.4-py2.py3-none-any.whl", hash = "sha256:7e40e4a70304fd9ceab3535d36e58791d9c4a776b38ec7f7ec9afc8d3dca4d4f"}, + {file = "dill-0.3.4.zip", hash = "sha256:9f9734205146b2b353ab3fec9af0070237b6ddae78452af83d2fca84d739e675"}, +] distlib = [ {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"}, {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"}, @@ -1394,8 +1434,8 @@ filelock = [ {file = "filelock-3.6.0.tar.gz", hash = "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85"}, ] fonttools = [ - {file = "fonttools-4.29.1-py3-none-any.whl", hash = "sha256:1933415e0fbdf068815cb1baaa1f159e17830215f7e8624e5731122761627557"}, - {file = "fonttools-4.29.1.zip", hash = "sha256:2b18a172120e32128a80efee04cff487d5d140fe7d817deb648b2eee023a40e4"}, + {file = "fonttools-4.31.2-py3-none-any.whl", hash = "sha256:2df636a3f402ef14593c6811dac0609563b8c374bd7850e76919eb51ea205426"}, + {file = "fonttools-4.31.2.zip", hash = "sha256:236b29aee6b113e8f7bee28779c1230a86ad2aac9a74a31b0aedf57e7dfb62a4"}, ] greenlet = [ {file = "greenlet-1.1.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6"}, @@ -1450,8 +1490,8 @@ greenlet = [ {file = "greenlet-1.1.2.tar.gz", hash = "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a"}, ] identify = [ - {file = "identify-2.4.11-py2.py3-none-any.whl", hash = "sha256:fd906823ed1db23c7a48f9b176a1d71cb8abede1e21ebe614bac7bdd688d9213"}, - {file = "identify-2.4.11.tar.gz", hash = "sha256:2986942d3974c8f2e5019a190523b0b0e2a07cb8e89bf236727fb4b26f27f8fd"}, + {file = "identify-2.4.12-py2.py3-none-any.whl", hash = "sha256:5f06b14366bd1facb88b00540a1de05b69b310cbc2654db3c7e07fa3a4339323"}, + {file = "identify-2.4.12.tar.gz", hash = "sha256:3f3244a559290e7d3deb9e9adc7b33594c1bc85a9dd82e0f1be519bf12a1ec17"}, ] idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, @@ -1462,16 +1502,16 @@ imagesize = [ {file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.11.2-py3-none-any.whl", hash = "sha256:d16e8c1deb60de41b8e8ed21c1a7b947b0bc62fab7e1d470bcdf331cea2e6735"}, - {file = "importlib_metadata-4.11.2.tar.gz", hash = "sha256:b36ffa925fe3139b2f6ff11d6925ffd4fa7bc47870165e3ac260ac7b4f91e6ac"}, + {file = "importlib_metadata-4.11.3-py3-none-any.whl", hash = "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6"}, + {file = "importlib_metadata-4.11.3.tar.gz", hash = "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] ipython = [ - {file = "ipython-8.1.1-py3-none-any.whl", hash = "sha256:6f56bfaeaa3247aa3b9cd3b8cbab3a9c0abf7428392f97b21902d12b2f42a381"}, - {file = "ipython-8.1.1.tar.gz", hash = "sha256:8138762243c9b3a3ffcf70b37151a2a35c23d3a29f9743878c33624f4207be3d"}, + {file = "ipython-8.2.0-py3-none-any.whl", hash = "sha256:1b672bfd7a48d87ab203d9af8727a3b0174a4566b4091e9447c22fb63ea32857"}, + {file = "ipython-8.2.0.tar.gz", hash = "sha256:70e5eb132cac594a34b5f799bd252589009905f05104728aea6a403ec2519dc1"}, ] isort = [ {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, @@ -1482,54 +1522,53 @@ jedi = [ {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, ] jinja2 = [ - {file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"}, - {file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"}, + {file = "Jinja2-3.1.1-py3-none-any.whl", hash = "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119"}, + {file = "Jinja2-3.1.1.tar.gz", hash = "sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9"}, ] kiwisolver = [ - {file = "kiwisolver-1.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1d819553730d3c2724582124aee8a03c846ec4362ded1034c16fb3ef309264e6"}, - {file = "kiwisolver-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d93a1095f83e908fc253f2fb569c2711414c0bfd451cab580466465b235b470"}, - {file = "kiwisolver-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4550a359c5157aaf8507e6820d98682872b9100ce7607f8aa070b4b8af6c298"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2210f28778c7d2ee13f3c2a20a3a22db889e75f4ec13a21072eabb5693801e84"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:82f49c5a79d3839bc8f38cb5f4bfc87e15f04cbafa5fbd12fb32c941cb529cfb"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9661a04ca3c950a8ac8c47f53cbc0b530bce1b52f516a1e87b7736fec24bfff0"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ddb500a2808c100e72c075cbb00bf32e62763c82b6a882d403f01a119e3f402"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72be6ebb4e92520b9726d7146bc9c9b277513a57a38efcf66db0620aec0097e0"}, - {file = "kiwisolver-1.3.2-cp310-cp310-win32.whl", hash = "sha256:83d2c9db5dfc537d0171e32de160461230eb14663299b7e6d18ca6dca21e4977"}, - {file = "kiwisolver-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:cba430db673c29376135e695c6e2501c44c256a81495da849e85d1793ee975ad"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4116ba9a58109ed5e4cb315bdcbff9838f3159d099ba5259c7c7fb77f8537492"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19554bd8d54cf41139f376753af1a644b63c9ca93f8f72009d50a2080f870f77"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a4cf5bbdc861987a7745aed7a536c6405256853c94abc9f3287c3fa401b174"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0007840186bacfaa0aba4466d5890334ea5938e0bb7e28078a0eb0e63b5b59d5"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec2eba188c1906b05b9b49ae55aae4efd8150c61ba450e6721f64620c50b59eb"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3dbb3cea20b4af4f49f84cffaf45dd5f88e8594d18568e0225e6ad9dec0e7967"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-win32.whl", hash = "sha256:5326ddfacbe51abf9469fe668944bc2e399181a2158cb5d45e1d40856b2a0589"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c6572c2dab23c86a14e82c245473d45b4c515314f1f859e92608dcafbd2f19b8"}, - {file = "kiwisolver-1.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b5074fb09429f2b7bc82b6fb4be8645dcbac14e592128beeff5461dcde0af09f"}, - {file = "kiwisolver-1.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:22521219ca739654a296eea6d4367703558fba16f98688bd8ce65abff36eaa84"}, - {file = "kiwisolver-1.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c358721aebd40c243894298f685a19eb0491a5c3e0b923b9f887ef1193ddf829"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ba5a1041480c6e0a8b11a9544d53562abc2d19220bfa14133e0cdd9967e97af"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44e6adf67577dbdfa2d9f06db9fbc5639afefdb5bf2b4dfec25c3a7fbc619536"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d45d1c74f88b9f41062716c727f78f2a59a5476ecbe74956fafb423c5c87a76"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70adc3658138bc77a36ce769f5f183169bc0a2906a4f61f09673f7181255ac9b"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6a5431940f28b6de123de42f0eb47b84a073ee3c3345dc109ad550a3307dd28"}, - {file = "kiwisolver-1.3.2-cp38-cp38-win32.whl", hash = "sha256:ee040a7de8d295dbd261ef2d6d3192f13e2b08ec4a954de34a6fb8ff6422e24c"}, - {file = "kiwisolver-1.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:8dc3d842fa41a33fe83d9f5c66c0cc1f28756530cd89944b63b072281e852031"}, - {file = "kiwisolver-1.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a498bcd005e8a3fedd0022bb30ee0ad92728154a8798b703f394484452550507"}, - {file = "kiwisolver-1.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80efd202108c3a4150e042b269f7c78643420cc232a0a771743bb96b742f838f"}, - {file = "kiwisolver-1.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f8eb7b6716f5b50e9c06207a14172cf2de201e41912ebe732846c02c830455b9"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f441422bb313ab25de7b3dbfd388e790eceb76ce01a18199ec4944b369017009"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:30fa008c172355c7768159983a7270cb23838c4d7db73d6c0f6b60dde0d432c6"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f8f6c8f4f1cff93ca5058d6ec5f0efda922ecb3f4c5fb76181f327decff98b8"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba677bcaff9429fd1bf01648ad0901cea56c0d068df383d5f5856d88221fe75b"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7843b1624d6ccca403a610d1277f7c28ad184c5aa88a1750c1a999754e65b439"}, - {file = "kiwisolver-1.3.2-cp39-cp39-win32.whl", hash = "sha256:e6f5eb2f53fac7d408a45fbcdeda7224b1cfff64919d0f95473420a931347ae9"}, - {file = "kiwisolver-1.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:eedd3b59190885d1ebdf6c5e0ca56828beb1949b4dfe6e5d0256a461429ac386"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:dedc71c8eb9c5096037766390172c34fb86ef048b8e8958b4e484b9e505d66bc"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:bf7eb45d14fc036514c09554bf983f2a72323254912ed0c3c8e697b62c4c158f"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b65bd35f3e06a47b5c30ea99e0c2b88f72c6476eedaf8cfbc8e66adb5479dcf"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25405f88a37c5f5bcba01c6e350086d65e7465fd1caaf986333d2a045045a223"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:bcadb05c3d4794eb9eee1dddf1c24215c92fb7b55a80beae7a60530a91060560"}, - {file = "kiwisolver-1.3.2.tar.gz", hash = "sha256:fc4453705b81d03568d5b808ad8f09c77c47534f6ac2e72e733f9ca4714aa75c"}, + {file = "kiwisolver-1.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e395ece147f0692ca7cdb05a028d31b83b72c369f7b4a2c1798f4b96af1e3d8"}, + {file = "kiwisolver-1.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b7f50a1a25361da3440f07c58cd1d79957c2244209e4f166990e770256b6b0b"}, + {file = "kiwisolver-1.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3c032c41ae4c3a321b43a3650e6ecc7406b99ff3e5279f24c9b310f41bc98479"}, + {file = "kiwisolver-1.4.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1dcade8f6fe12a2bb4efe2cbe22116556e3b6899728d3b2a0d3b367db323eacc"}, + {file = "kiwisolver-1.4.2-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e45e780a74416ef2f173189ef4387e44b5494f45e290bcb1f03735faa6779bf"}, + {file = "kiwisolver-1.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d2bb56309fb75a811d81ed55fbe2208aa77a3a09ff5f546ca95e7bb5fac6eff"}, + {file = "kiwisolver-1.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b2d6c12f2ad5f55104a36a356192cfb680c049fe5e7c1f6620fc37f119cdc2"}, + {file = "kiwisolver-1.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:262c248c60f22c2b547683ad521e8a3db5909c71f679b93876921549107a0c24"}, + {file = "kiwisolver-1.4.2-cp310-cp310-win32.whl", hash = "sha256:1008346a7741620ab9cc6c96e8ad9b46f7a74ce839dbb8805ddf6b119d5fc6c2"}, + {file = "kiwisolver-1.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:6ece2e12e4b57bc5646b354f436416cd2a6f090c1dadcd92b0ca4542190d7190"}, + {file = "kiwisolver-1.4.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b978afdb913ca953cf128d57181da2e8798e8b6153be866ae2a9c446c6162f40"}, + {file = "kiwisolver-1.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f88c4b8e449908eeddb3bbd4242bd4dc2c7a15a7aa44bb33df893203f02dc2d"}, + {file = "kiwisolver-1.4.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e348f1904a4fab4153407f7ccc27e43b2a139752e8acf12e6640ba683093dd96"}, + {file = "kiwisolver-1.4.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c839bf28e45d7ddad4ae8f986928dbf5a6d42ff79760d54ec8ada8fb263e097c"}, + {file = "kiwisolver-1.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8ae5a071185f1a93777c79a9a1e67ac46544d4607f18d07131eece08d415083a"}, + {file = "kiwisolver-1.4.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c222f91a45da9e01a9bc4f760727ae49050f8e8345c4ff6525495f7a164c8973"}, + {file = "kiwisolver-1.4.2-cp37-cp37m-win32.whl", hash = "sha256:a4e8f072db1d6fb7a7cc05a6dbef8442c93001f4bb604f1081d8c2db3ca97159"}, + {file = "kiwisolver-1.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:be9a650890fb60393e60aacb65878c4a38bb334720aa5ecb1c13d0dac54dd73b"}, + {file = "kiwisolver-1.4.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ec2e55bf31b43aabe32089125dca3b46fdfe9f50afbf0756ae11e14c97b80ca"}, + {file = "kiwisolver-1.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d1078ba770d6165abed3d9a1be1f9e79b61515de1dd00d942fa53bba79f01ae"}, + {file = "kiwisolver-1.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cbb5eb4a2ea1ffec26268d49766cafa8f957fe5c1b41ad00733763fae77f9436"}, + {file = "kiwisolver-1.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e6cda72db409eefad6b021e8a4f964965a629f577812afc7860c69df7bdb84a"}, + {file = "kiwisolver-1.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1605c7c38cc6a85212dfd6a641f3905a33412e49f7c003f35f9ac6d71f67720"}, + {file = "kiwisolver-1.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81237957b15469ea9151ec8ca08ce05656090ffabc476a752ef5ad7e2644c526"}, + {file = "kiwisolver-1.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:240009fdf4fa87844f805e23f48995537a8cb8f8c361e35fda6b5ac97fcb906f"}, + {file = "kiwisolver-1.4.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:240c2d51d098395c012ddbcb9bd7b3ba5de412a1d11840698859f51d0e643c4f"}, + {file = "kiwisolver-1.4.2-cp38-cp38-win32.whl", hash = "sha256:8b6086aa6936865962b2cee0e7aaecf01ab6778ce099288354a7229b4d9f1408"}, + {file = "kiwisolver-1.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:0d98dca86f77b851350c250f0149aa5852b36572514d20feeadd3c6b1efe38d0"}, + {file = "kiwisolver-1.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:91eb4916271655dfe3a952249cb37a5c00b6ba68b4417ee15af9ba549b5ba61d"}, + {file = "kiwisolver-1.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa4d97d7d2b2c082e67907c0b8d9f31b85aa5d3ba0d33096b7116f03f8061261"}, + {file = "kiwisolver-1.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:71469b5845b9876b8d3d252e201bef6f47bf7456804d2fbe9a1d6e19e78a1e65"}, + {file = "kiwisolver-1.4.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8ff3033e43e7ca1389ee59fb7ecb8303abb8713c008a1da49b00869e92e3dd7c"}, + {file = "kiwisolver-1.4.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89b57c2984f4464840e4b768affeff6b6809c6150d1166938ade3e22fbe22db8"}, + {file = "kiwisolver-1.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffbdb9a96c536f0405895b5e21ee39ec579cb0ed97bdbd169ae2b55f41d73219"}, + {file = "kiwisolver-1.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a830a03970c462d1a2311c90e05679da56d3bd8e78a4ba9985cb78ef7836c9f"}, + {file = "kiwisolver-1.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f74f2a13af201559e3d32b9ddfc303c94ae63d63d7f4326d06ce6fe67e7a8255"}, + {file = "kiwisolver-1.4.2-cp39-cp39-win32.whl", hash = "sha256:e677cc3626287f343de751e11b1e8a5b915a6ac897e8aecdbc996cd34de753a0"}, + {file = "kiwisolver-1.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b3e251e5c38ac623c5d786adb21477f018712f8c6fa54781bd38aa1c60b60fc2"}, + {file = "kiwisolver-1.4.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0c380bb5ae20d829c1a5473cfcae64267b73aaa4060adc091f6df1743784aae0"}, + {file = "kiwisolver-1.4.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:484f2a5f0307bc944bc79db235f41048bae4106ffa764168a068d88b644b305d"}, + {file = "kiwisolver-1.4.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e8afdf533b613122e4bbaf3c1e42c2a5e9e2d1dd3a0a017749a7658757cb377"}, + {file = "kiwisolver-1.4.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:42f6ef9b640deb6f7d438e0a371aedd8bef6ddfde30683491b2e6f568b4e884e"}, + {file = "kiwisolver-1.4.2.tar.gz", hash = "sha256:7f606d91b8a8816be476513a77fd30abe66227039bd6f8b406c348cb0247dcc9"}, ] latexcodec = [ {file = "latexcodec-2.0.1-py2.py3-none-any.whl", hash = "sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271"}, @@ -1625,46 +1664,46 @@ lz4 = [ {file = "lz4-3.1.10.tar.gz", hash = "sha256:439e575ecfa9ecffcbd63cfed99baefbe422ab9645b1e82278024d8a21d9720b"}, ] markupsafe = [ - {file = "MarkupSafe-2.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3028252424c72b2602a323f70fbf50aa80a5d3aa616ea6add4ba21ae9cc9da4c"}, - {file = "MarkupSafe-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:290b02bab3c9e216da57c1d11d2ba73a9f73a614bbdcc027d299a60cdfabb11a"}, - {file = "MarkupSafe-2.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e104c0c2b4cd765b4e83909cde7ec61a1e313f8a75775897db321450e928cce"}, - {file = "MarkupSafe-2.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24c3be29abb6b34052fd26fc7a8e0a49b1ee9d282e3665e8ad09a0a68faee5b3"}, - {file = "MarkupSafe-2.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204730fd5fe2fe3b1e9ccadb2bd18ba8712b111dcabce185af0b3b5285a7c989"}, - {file = "MarkupSafe-2.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d3b64c65328cb4cd252c94f83e66e3d7acf8891e60ebf588d7b493a55a1dbf26"}, - {file = "MarkupSafe-2.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:96de1932237abe0a13ba68b63e94113678c379dca45afa040a17b6e1ad7ed076"}, - {file = "MarkupSafe-2.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:75bb36f134883fdbe13d8e63b8675f5f12b80bb6627f7714c7d6c5becf22719f"}, - {file = "MarkupSafe-2.1.0-cp310-cp310-win32.whl", hash = "sha256:4056f752015dfa9828dce3140dbadd543b555afb3252507348c493def166d454"}, - {file = "MarkupSafe-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:d4e702eea4a2903441f2735799d217f4ac1b55f7d8ad96ab7d4e25417cb0827c"}, - {file = "MarkupSafe-2.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f0eddfcabd6936558ec020130f932d479930581171368fd728efcfb6ef0dd357"}, - {file = "MarkupSafe-2.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ddea4c352a488b5e1069069f2f501006b1a4362cb906bee9a193ef1245a7a61"}, - {file = "MarkupSafe-2.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09c86c9643cceb1d87ca08cdc30160d1b7ab49a8a21564868921959bd16441b8"}, - {file = "MarkupSafe-2.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0a0abef2ca47b33fb615b491ce31b055ef2430de52c5b3fb19a4042dbc5cadb"}, - {file = "MarkupSafe-2.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:736895a020e31b428b3382a7887bfea96102c529530299f426bf2e636aacec9e"}, - {file = "MarkupSafe-2.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:679cbb78914ab212c49c67ba2c7396dc599a8479de51b9a87b174700abd9ea49"}, - {file = "MarkupSafe-2.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:84ad5e29bf8bab3ad70fd707d3c05524862bddc54dc040982b0dbcff36481de7"}, - {file = "MarkupSafe-2.1.0-cp37-cp37m-win32.whl", hash = "sha256:8da5924cb1f9064589767b0f3fc39d03e3d0fb5aa29e0cb21d43106519bd624a"}, - {file = "MarkupSafe-2.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:454ffc1cbb75227d15667c09f164a0099159da0c1f3d2636aa648f12675491ad"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:142119fb14a1ef6d758912b25c4e803c3ff66920635c44078666fe7cc3f8f759"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b2a5a856019d2833c56a3dcac1b80fe795c95f401818ea963594b345929dffa7"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d1fb9b2eec3c9714dd936860850300b51dbaa37404209c8d4cb66547884b7ed"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62c0285e91414f5c8f621a17b69fc0088394ccdaa961ef469e833dbff64bd5ea"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc3150f85e2dbcf99e65238c842d1cfe69d3e7649b19864c1cc043213d9cd730"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f02cf7221d5cd915d7fa58ab64f7ee6dd0f6cddbb48683debf5d04ae9b1c2cc1"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5653619b3eb5cbd35bfba3c12d575db2a74d15e0e1c08bf1db788069d410ce8"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7d2f5d97fcbd004c03df8d8fe2b973fe2b14e7bfeb2cfa012eaa8759ce9a762f"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-win32.whl", hash = "sha256:3cace1837bc84e63b3fd2dfce37f08f8c18aeb81ef5cf6bb9b51f625cb4e6cd8"}, - {file = "MarkupSafe-2.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:fabbe18087c3d33c5824cb145ffca52eccd053061df1d79d4b66dafa5ad2a5ea"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:023af8c54fe63530545f70dd2a2a7eed18d07a9a77b94e8bf1e2ff7f252db9a3"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d66624f04de4af8bbf1c7f21cc06649c1c69a7f84109179add573ce35e46d448"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c532d5ab79be0199fa2658e24a02fce8542df196e60665dd322409a03db6a52c"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ec74fada3841b8c5f4c4f197bea916025cb9aa3fe5abf7d52b655d042f956"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c653fde75a6e5eb814d2a0a89378f83d1d3f502ab710904ee585c38888816c"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:961eb86e5be7d0973789f30ebcf6caab60b844203f4396ece27310295a6082c7"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:598b65d74615c021423bd45c2bc5e9b59539c875a9bdb7e5f2a6b92dfcfc268d"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:599941da468f2cf22bf90a84f6e2a65524e87be2fce844f96f2dd9a6c9d1e635"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-win32.whl", hash = "sha256:e6f7f3f41faffaea6596da86ecc2389672fa949bd035251eab26dc6697451d05"}, - {file = "MarkupSafe-2.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:b8811d48078d1cf2a6863dafb896e68406c5f513048451cd2ded0473133473c7"}, - {file = "MarkupSafe-2.1.0.tar.gz", hash = "sha256:80beaf63ddfbc64a0452b841d8036ca0611e049650e20afcb882f5d3c266d65f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] matplotlib = [ {file = "matplotlib-3.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:456cc8334f6d1124e8ff856b42d2cc1c84335375a16448189999496549f7182b"}, @@ -1708,8 +1747,8 @@ matplotlib-inline = [ {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"}, ] mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] nodeenv = [ {file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"}, @@ -1779,27 +1818,27 @@ packaging = [ {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] pandas = [ - {file = "pandas-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3dfb32ed50122fe8c5e7f2b8d97387edd742cc78f9ec36f007ee126cd3720907"}, - {file = "pandas-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0259cd11e7e6125aaea3af823b80444f3adad6149ff4c97fef760093598b3e34"}, - {file = "pandas-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96e9ece5759f9b47ae43794b6359bbc54805d76e573b161ae770c1ea59393106"}, - {file = "pandas-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:508c99debccd15790d526ce6b1624b97a5e1e4ca5b871319fb0ebfd46b8f4dad"}, - {file = "pandas-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6a7bbbb7950063bfc942f8794bc3e31697c020a14f1cd8905fc1d28ec674a01"}, - {file = "pandas-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:c614001129b2a5add5e3677c3a213a9e6fd376204cb8d17c04e84ff7dfc02a73"}, - {file = "pandas-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4e1176f45981c8ccc8161bc036916c004ca51037a7ed73f2d2a9857e6dbe654f"}, - {file = "pandas-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bbb15ad79050e8b8d39ec40dd96a30cd09b886a2ae8848d0df1abba4d5502a67"}, - {file = "pandas-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6d6ad1da00c7cc7d8dd1559a6ba59ba3973be6b15722d49738b2be0977eb8a0c"}, - {file = "pandas-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:358b0bc98a5ff067132d23bf7a2242ee95db9ea5b7bbc401cf79205f11502fd3"}, - {file = "pandas-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6105af6533f8b63a43ea9f08a2ede04e8f43e49daef0209ab0d30352bcf08bee"}, - {file = "pandas-1.4.1-cp38-cp38-win32.whl", hash = "sha256:04dd15d9db538470900c851498e532ef28d4e56bfe72c9523acb32042de43dfb"}, - {file = "pandas-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b384516dbb4e6aae30e3464c2e77c563da5980440fbdfbd0968e3942f8f9d70"}, - {file = "pandas-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f02e85e6d832be37d7f16cf6ac8bb26b519ace3e5f3235564a91c7f658ab2a43"}, - {file = "pandas-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0b1a13f647e4209ed7dbb5da3497891d0045da9785327530ab696417ef478f84"}, - {file = "pandas-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:19f7c632436b1b4f84615c3b127bbd7bc603db95e3d4332ed259dc815c9aaa26"}, - {file = "pandas-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ea47ba1d6f359680130bd29af497333be6110de8f4c35b9211eec5a5a9630fa"}, - {file = "pandas-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e5a7a1e0ecaac652326af627a3eca84886da9e667d68286866d4e33f6547caf"}, - {file = "pandas-1.4.1-cp39-cp39-win32.whl", hash = "sha256:1d85d5f6be66dfd6d1d8d13b9535e342a2214260f1852654b19fa4d7b8d1218b"}, - {file = "pandas-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3129a35d9dad1d80c234dd78f8f03141b914395d23f97cf92a366dcd19f8f8bf"}, - {file = "pandas-1.4.1.tar.gz", hash = "sha256:8db93ec98ac7cb5f8ac1420c10f5e3c43533153f253fe7fb6d891cf5aa2b80d2"}, + {file = "pandas-1.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be67c782c4f1b1f24c2f16a157e12c2693fd510f8df18e3287c77f33d124ed07"}, + {file = "pandas-1.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5a206afa84ed20e07603f50d22b5f0db3fb556486d8c2462d8bc364831a4b417"}, + {file = "pandas-1.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0010771bd9223f7afe5f051eb47c4a49534345dfa144f2f5470b27189a4dd3b5"}, + {file = "pandas-1.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3228198333dd13c90b6434ddf61aa6d57deaca98cf7b654f4ad68a2db84f8cfe"}, + {file = "pandas-1.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b79af3a69e5175c6fa7b4e046b21a646c8b74e92c6581a9d825687d92071b51"}, + {file = "pandas-1.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:5586cc95692564b441f4747c47c8a9746792e87b40a4680a2feb7794defb1ce3"}, + {file = "pandas-1.4.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:061609334a8182ab500a90fe66d46f6f387de62d3a9cb9aa7e62e3146c712167"}, + {file = "pandas-1.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b8134651258bce418cb79c71adeff0a44090c98d955f6953168ba16cc285d9f7"}, + {file = "pandas-1.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:df82739e00bb6daf4bba4479a40f38c718b598a84654cbd8bb498fd6b0aa8c16"}, + {file = "pandas-1.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:385c52e85aaa8ea6a4c600a9b2821181a51f8be0aee3af6f2dcb41dafc4fc1d0"}, + {file = "pandas-1.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:295872bf1a09758aba199992c3ecde455f01caf32266d50abc1a073e828a7b9d"}, + {file = "pandas-1.4.2-cp38-cp38-win32.whl", hash = "sha256:95c1e422ced0199cf4a34385ff124b69412c4bc912011ce895582bee620dfcaa"}, + {file = "pandas-1.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:5c54ea4ef3823108cd4ec7fb27ccba4c3a775e0f83e39c5e17f5094cb17748bc"}, + {file = "pandas-1.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c072c7f06b9242c855ed8021ff970c0e8f8b10b35e2640c657d2a541c5950f59"}, + {file = "pandas-1.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f549097993744ff8c41b5e8f2f0d3cbfaabe89b4ae32c8c08ead6cc535b80139"}, + {file = "pandas-1.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff08a14ef21d94cdf18eef7c569d66f2e24e0bc89350bcd7d243dd804e3b5eb2"}, + {file = "pandas-1.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c5bf555b6b0075294b73965adaafb39cf71c312e38c5935c93d78f41c19828a"}, + {file = "pandas-1.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51649ef604a945f781105a6d2ecf88db7da0f4868ac5d45c51cb66081c4d9c73"}, + {file = "pandas-1.4.2-cp39-cp39-win32.whl", hash = "sha256:d0d4f13e4be7ce89d7057a786023c461dd9370040bdb5efa0a7fe76b556867a0"}, + {file = "pandas-1.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:09d8be7dd9e1c4c98224c4dfe8abd60d145d934e9fc1f5f411266308ae683e6a"}, + {file = "pandas-1.4.2.tar.gz", hash = "sha256:92bc1fc585f1463ca827b45535957815b7deb218c549b7c18402c322c7549a12"}, ] parso = [ {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, @@ -1841,41 +1880,44 @@ pickleshare = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] pillow = [ - {file = "Pillow-9.0.1-1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4"}, - {file = "Pillow-9.0.1-1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976"}, - {file = "Pillow-9.0.1-1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc"}, - {file = "Pillow-9.0.1-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd"}, - {file = "Pillow-9.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a"}, - {file = "Pillow-9.0.1-cp310-cp310-win32.whl", hash = "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e"}, - {file = "Pillow-9.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b"}, - {file = "Pillow-9.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030"}, - {file = "Pillow-9.0.1-cp37-cp37m-win32.whl", hash = "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669"}, - {file = "Pillow-9.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092"}, - {file = "Pillow-9.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204"}, - {file = "Pillow-9.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae"}, - {file = "Pillow-9.0.1-cp38-cp38-win32.whl", hash = "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c"}, - {file = "Pillow-9.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00"}, - {file = "Pillow-9.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838"}, - {file = "Pillow-9.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7"}, - {file = "Pillow-9.0.1-cp39-cp39-win32.whl", hash = "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7"}, - {file = "Pillow-9.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e"}, - {file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"}, - {file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"}, + {file = "Pillow-9.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea"}, + {file = "Pillow-9.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652"}, + {file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a"}, + {file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7"}, + {file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e"}, + {file = "Pillow-9.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3"}, + {file = "Pillow-9.1.0-cp310-cp310-win32.whl", hash = "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160"}, + {file = "Pillow-9.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033"}, + {file = "Pillow-9.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c"}, + {file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165"}, + {file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a"}, + {file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2"}, + {file = "Pillow-9.1.0-cp37-cp37m-win32.whl", hash = "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244"}, + {file = "Pillow-9.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef"}, + {file = "Pillow-9.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512"}, + {file = "Pillow-9.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477"}, + {file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b"}, + {file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378"}, + {file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e"}, + {file = "Pillow-9.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5"}, + {file = "Pillow-9.1.0-cp38-cp38-win32.whl", hash = "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a"}, + {file = "Pillow-9.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34"}, + {file = "Pillow-9.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717"}, + {file = "Pillow-9.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581"}, + {file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6"}, + {file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4"}, + {file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331"}, + {file = "Pillow-9.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8"}, + {file = "Pillow-9.1.0-cp39-cp39-win32.whl", hash = "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58"}, + {file = "Pillow-9.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595"}, + {file = "Pillow-9.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481"}, + {file = "Pillow-9.1.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0"}, + {file = "Pillow-9.1.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a"}, + {file = "Pillow-9.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7"}, + {file = "Pillow-9.1.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3"}, + {file = "Pillow-9.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8"}, + {file = "Pillow-9.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458"}, + {file = "Pillow-9.1.0.tar.gz", hash = "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97"}, ] platformdirs = [ {file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"}, @@ -1886,12 +1928,12 @@ pluggy = [ {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] pre-commit = [ - {file = "pre_commit-2.17.0-py2.py3-none-any.whl", hash = "sha256:725fa7459782d7bec5ead072810e47351de01709be838c2ce1726b9591dad616"}, - {file = "pre_commit-2.17.0.tar.gz", hash = "sha256:c1a8040ff15ad3d648c70cc3e55b93e4d2d5b687320955505587fd79bbaed06a"}, + {file = "pre_commit-2.18.1-py2.py3-none-any.whl", hash = "sha256:02226e69564ebca1a070bd1f046af866aa1c318dbc430027c50ab832ed2b73f2"}, + {file = "pre_commit-2.18.1.tar.gz", hash = "sha256:5d445ee1fa8738d506881c5d84f83c62bb5be6b2838e32207433647e8e5ebe10"}, ] prompt-toolkit = [ - {file = "prompt_toolkit-3.0.28-py3-none-any.whl", hash = "sha256:30129d870dcb0b3b6a53efdc9d0a83ea96162ffd28ffe077e94215b233dc670c"}, - {file = "prompt_toolkit-3.0.28.tar.gz", hash = "sha256:9f1cd16b1e86c2968f2519d7fb31dd9d669916f515612c269d14e9ed52b51650"}, + {file = "prompt_toolkit-3.0.29-py3-none-any.whl", hash = "sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752"}, + {file = "prompt_toolkit-3.0.29.tar.gz", hash = "sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"}, ] ptyprocess = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, @@ -1918,8 +1960,8 @@ pygments = [ {file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"}, ] pylint = [ - {file = "pylint-2.12.2-py3-none-any.whl", hash = "sha256:daabda3f7ed9d1c60f52d563b1b854632fd90035bcf01443e234d3dc794e3b74"}, - {file = "pylint-2.12.2.tar.gz", hash = "sha256:9d945a73640e1fec07ee34b42f5669b770c759acd536ec7b16d7e4b87a9c9ff9"}, + {file = "pylint-2.13.4-py3-none-any.whl", hash = "sha256:8672cf7441b81410f5de7defdf56e2d559c956fd0579652f2e0a0a35bea2d546"}, + {file = "pylint-2.13.4.tar.gz", hash = "sha256:7cc6d0c4f61dff440f9ed8b657f4ecd615dcfe35345953eb7b1dc74afe901d7a"}, ] pyparsing = [ {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, @@ -1949,8 +1991,8 @@ python-dateutil = [ {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] pytz = [ - {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, - {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, + {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, + {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, ] pytzdata = [ {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, @@ -2037,8 +2079,8 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] sphinx = [ - {file = "Sphinx-4.4.0-py3-none-any.whl", hash = "sha256:5da895959511473857b6d0200f56865ed62c31e8f82dd338063b84ec022701fe"}, - {file = "Sphinx-4.4.0.tar.gz", hash = "sha256:6caad9786055cb1fa22b4a365c1775816b876f91966481765d7d50e9f0dd35cc"}, + {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, + {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, ] sphinx-rtd-theme = [ {file = "sphinx_rtd_theme-1.0.0-py2.py3-none-any.whl", hash = "sha256:4d35a56f4508cfee4c4fb604373ede6feae2a306731d533f409ef5c3496fdbd8"}, @@ -2073,41 +2115,42 @@ sphinxcontrib-serializinghtml = [ {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] sqlalchemy = [ - {file = "SQLAlchemy-1.4.32-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:4b2bcab3a914715d332ca783e9bda13bc570d8b9ef087563210ba63082c18c16"}, - {file = "SQLAlchemy-1.4.32-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:159c2f69dd6efd28e894f261ffca1100690f28210f34cfcd70b895e0ea7a64f3"}, - {file = "SQLAlchemy-1.4.32-cp27-cp27m-win_amd64.whl", hash = "sha256:d7e483f4791fbda60e23926b098702340504f7684ce7e1fd2c1bf02029288423"}, - {file = "SQLAlchemy-1.4.32-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4aa96e957141006181ca58e792e900ee511085b8dae06c2d08c00f108280fb8a"}, - {file = "SQLAlchemy-1.4.32-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:576684771456d02e24078047c2567025f2011977aa342063468577d94e194b00"}, - {file = "SQLAlchemy-1.4.32-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fff677fa4522dafb5a5e2c0cf909790d5d367326321aeabc0dffc9047cb235bd"}, - {file = "SQLAlchemy-1.4.32-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8679f9aba5ac22e7bce54ccd8a77641d3aea3e2d96e73e4356c887ebf8ff1082"}, - {file = "SQLAlchemy-1.4.32-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7046f7aa2db445daccc8424f50b47a66c4039c9f058246b43796aa818f8b751"}, - {file = "SQLAlchemy-1.4.32-cp310-cp310-win32.whl", hash = "sha256:bedd89c34ab62565d44745212814e4b57ef1c24ad4af9b29c504ce40f0dc6558"}, - {file = "SQLAlchemy-1.4.32-cp310-cp310-win_amd64.whl", hash = "sha256:199dc6d0068753b6a8c0bd3aceb86a3e782df118260ebc1fa981ea31ee054674"}, - {file = "SQLAlchemy-1.4.32-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:8e1e5d96b744a4f91163290b01045430f3f32579e46d87282449e5b14d27d4ac"}, - {file = "SQLAlchemy-1.4.32-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edfcf93fd92e2f9eef640b3a7a40db20fe3c1d7c2c74faa41424c63dead61b76"}, - {file = "SQLAlchemy-1.4.32-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:04164e0063feb7aedd9d073db0fd496edb244be40d46ea1f0d8990815e4b8c34"}, - {file = "SQLAlchemy-1.4.32-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ba59761c19b800bc2e1c9324da04d35ef51e4ee9621ff37534bc2290d258f71"}, - {file = "SQLAlchemy-1.4.32-cp36-cp36m-win32.whl", hash = "sha256:708973b5d9e1e441188124aaf13c121e5b03b6054c2df59b32219175a25aa13e"}, - {file = "SQLAlchemy-1.4.32-cp36-cp36m-win_amd64.whl", hash = "sha256:316270e5867566376e69a0ac738b863d41396e2b63274616817e1d34156dff0e"}, - {file = "SQLAlchemy-1.4.32-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:9a0195af6b9050c9322a97cf07514f66fe511968e623ca87b2df5e3cf6349615"}, - {file = "SQLAlchemy-1.4.32-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7e4a3c0c3c596296b37f8427c467c8e4336dc8d50f8ed38042e8ba79507b2c9"}, - {file = "SQLAlchemy-1.4.32-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bca714d831e5b8860c3ab134c93aec63d1a4f493bed20084f54e3ce9f0a3bf99"}, - {file = "SQLAlchemy-1.4.32-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9a680d9665f88346ed339888781f5236347933906c5a56348abb8261282ec48"}, - {file = "SQLAlchemy-1.4.32-cp37-cp37m-win32.whl", hash = "sha256:9cb5698c896fa72f88e7ef04ef62572faf56809093180771d9be8d9f2e264a13"}, - {file = "SQLAlchemy-1.4.32-cp37-cp37m-win_amd64.whl", hash = "sha256:8b9a395122770a6f08ebfd0321546d7379f43505882c7419d7886856a07caa13"}, - {file = "SQLAlchemy-1.4.32-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:3f88a4ee192142eeed3fe173f673ea6ab1f5a863810a9d85dbf6c67a9bd08f97"}, - {file = "SQLAlchemy-1.4.32-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd93162615870c976dba43963a24bb418b28448fef584f30755990c134a06a55"}, - {file = "SQLAlchemy-1.4.32-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5a2e73508f939175363d8a4be9dcdc84cf16a92578d7fa86e6e4ca0e6b3667b2"}, - {file = "SQLAlchemy-1.4.32-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfec934aac7f9fa95fc82147a4ba5db0a8bdc4ebf1e33b585ab8860beb10232f"}, - {file = "SQLAlchemy-1.4.32-cp38-cp38-win32.whl", hash = "sha256:bb42f9b259c33662c6a9b866012f6908a91731a419e69304e1261ba3ab87b8d1"}, - {file = "SQLAlchemy-1.4.32-cp38-cp38-win_amd64.whl", hash = "sha256:7ff72b3cc9242d1a1c9b84bd945907bf174d74fc2519efe6184d6390a8df478b"}, - {file = "SQLAlchemy-1.4.32-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5dc9801ae9884e822ba942ca493642fb50f049c06b6dbe3178691fce48ceb089"}, - {file = "SQLAlchemy-1.4.32-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4607d2d16330757818c9d6fba322c2e80b4b112ff24295d1343a80b876eb0ed"}, - {file = "SQLAlchemy-1.4.32-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:20e9eba7fd86ef52e0df25bea83b8b518dfdf0bce09b336cfe51671f52aaaa3f"}, - {file = "SQLAlchemy-1.4.32-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:290cbdf19129ae520d4bdce392648c6fcdbee763bc8f750b53a5ab51880cb9c9"}, - {file = "SQLAlchemy-1.4.32-cp39-cp39-win32.whl", hash = "sha256:1bbac3e8293b34c4403d297e21e8f10d2a57756b75cff101dc62186adec725f5"}, - {file = "SQLAlchemy-1.4.32-cp39-cp39-win_amd64.whl", hash = "sha256:b3f1d9b3aa09ab9adc7f8c4b40fc3e081eb903054c9a6f9ae1633fe15ae503b4"}, - {file = "SQLAlchemy-1.4.32.tar.gz", hash = "sha256:6fdd2dc5931daab778c2b65b03df6ae68376e028a3098eb624d0909d999885bc"}, + {file = "SQLAlchemy-1.4.34-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:c025d45318b73c0601cca451532556cbab532b2742839ebb8cb58f9ebf06811e"}, + {file = "SQLAlchemy-1.4.34-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cd5cffd1dd753828f1069f33062f3896e51c990acd957c264f40e051b3e19887"}, + {file = "SQLAlchemy-1.4.34-cp27-cp27m-win32.whl", hash = "sha256:a47bf6b7ca6c28e4f4e262fabcf5be6b907af81be36de77839c9eeda2cdf3bb3"}, + {file = "SQLAlchemy-1.4.34-cp27-cp27m-win_amd64.whl", hash = "sha256:c9218e3519398129e364121e0d89823e6ba2a2b77c28bfc661face0829c41433"}, + {file = "SQLAlchemy-1.4.34-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7ee14a7f9f76d1ef9d5e5b760c9252617c839b87eee04d1ce8325ac66ae155c4"}, + {file = "SQLAlchemy-1.4.34-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:4414ace6e3a5e39523e55a5d9f3b215699b2ead4ff91fca98f1b659b7ab2d92a"}, + {file = "SQLAlchemy-1.4.34-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a6cfd468f54d65324fd3847cfd0148b0610efa6a43e5f5fcc89f455696ae9e7"}, + {file = "SQLAlchemy-1.4.34-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:27a42894a2751e438eaed12fc0dcfe741ff2f66c14760d081222c5adc5460064"}, + {file = "SQLAlchemy-1.4.34-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:671f61c3db4595b0e86cc4b30f675a7c0206d9ce99f041b4f6761c7ddd1e0074"}, + {file = "SQLAlchemy-1.4.34-cp310-cp310-win32.whl", hash = "sha256:3ebb97ed96f4506e2f212e1fcf0ec07a103bb194938627660a5acb4d9feae49c"}, + {file = "SQLAlchemy-1.4.34-cp310-cp310-win_amd64.whl", hash = "sha256:d8efcaa709ea8e7c08c3d3e7639c39b36083f5a995f397f9e6eedf5f5e4e4946"}, + {file = "SQLAlchemy-1.4.34-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:a4fb5c6ee84a6bba4ff6f9f5379f0b3a0ffe9de7ba5a0945659b3da8d519709b"}, + {file = "SQLAlchemy-1.4.34-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07f4dab2deb6d34618a2ccfff3971a85923ad7c3a9a45401818870fc51d3f0cc"}, + {file = "SQLAlchemy-1.4.34-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:67c1c27c48875afc950bee5ee24582794f20b545e64e4f9ca94071a9b514d6ed"}, + {file = "SQLAlchemy-1.4.34-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:954ea8c527c4322afb6885944904714893af81fe9167e421273770991bf08a4a"}, + {file = "SQLAlchemy-1.4.34-cp36-cp36m-win32.whl", hash = "sha256:2a3e4dc7c452ba3c0f3175ad5a8e0ba49c2b0570a8d07272cf50844c8d78e74f"}, + {file = "SQLAlchemy-1.4.34-cp36-cp36m-win_amd64.whl", hash = "sha256:f47996b1810894f766c9ee689607077c6c0e0fd6761e04c12ba13efb56d50c1d"}, + {file = "SQLAlchemy-1.4.34-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:b34bbc683789559f1bc9bb685fc162e0956dbbdfbe2fbd6755a9f5982c113610"}, + {file = "SQLAlchemy-1.4.34-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804cf491437f3e4ce31247ab4b309b181f06ecc97d309b746d10f09439b4eb85"}, + {file = "SQLAlchemy-1.4.34-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f197c66663ed0f9e1178d51141d864688fb244a83f6b17f667d521e482537b2e"}, + {file = "SQLAlchemy-1.4.34-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08aaad905aba8940f27aeb9f1f851bf63f18ef97b0062ca41f64afc4b64e0e8c"}, + {file = "SQLAlchemy-1.4.34-cp37-cp37m-win32.whl", hash = "sha256:345306707bb0e51e7cd6e7573adafbce018894ee5e3b9c31134545f704936db0"}, + {file = "SQLAlchemy-1.4.34-cp37-cp37m-win_amd64.whl", hash = "sha256:50174e173d03209c34e07e7b57cca48d0082ac2390edf927aafc706c111da11e"}, + {file = "SQLAlchemy-1.4.34-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:878c7beaafa365602762c19f638282e1885454fed1aed86f8fae038933c7c671"}, + {file = "SQLAlchemy-1.4.34-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70048a83f0a1ece1fcd7189891c888e20af2c57fbd33eb760d8cece9843b896c"}, + {file = "SQLAlchemy-1.4.34-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:621d3f6c0ba2407bb97e82b649be5ca7d5b6c201dcfb964ce13f517bf1cb6305"}, + {file = "SQLAlchemy-1.4.34-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:045d6a26c262929af0b9cb25441aae675ac04db4ea8bd2446b355617cd6b6b7d"}, + {file = "SQLAlchemy-1.4.34-cp38-cp38-win32.whl", hash = "sha256:e297a5cc625e3f1367a82deedf2d48ee4d2b2bd263b8b8d2efbaaf5608b5229e"}, + {file = "SQLAlchemy-1.4.34-cp38-cp38-win_amd64.whl", hash = "sha256:36f08d94670315ca04c8139bd80b3e02b9dd9cc66fc11bcb96fd10ad51a051ab"}, + {file = "SQLAlchemy-1.4.34-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:40b995d7aeeb6f88a1927ce6692c0f626b59d8effd3e1d597f125e141707b37c"}, + {file = "SQLAlchemy-1.4.34-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb6558ba07409dafa18c793c34292b3265be455904966f0724c10198829477e3"}, + {file = "SQLAlchemy-1.4.34-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e67278ceb63270cdac0a7b89fc3c29a56f7dac9616a7ee48e7ad6b52e3b631e5"}, + {file = "SQLAlchemy-1.4.34-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50107d8183da3fbe5715957aa3954cd9d82aed555c5b4d3fd37fac861af422fa"}, + {file = "SQLAlchemy-1.4.34-cp39-cp39-win32.whl", hash = "sha256:c3ad7f5b61ba014f5045912aea15b03c473bb02b1c07fd92c9d2c794fa183276"}, + {file = "SQLAlchemy-1.4.34-cp39-cp39-win_amd64.whl", hash = "sha256:5e88912bf192e7b5739c446d2276e1cba74cfa6c1c93eea2b2534404f6be1dbd"}, + {file = "SQLAlchemy-1.4.34.tar.gz", hash = "sha256:623bac2d6bdca3f3e61cf1e1c466c5fb9f5cf08735736ee1111187b7a4108891"}, ] stack-data = [ {file = "stack_data-0.2.0-py3-none-any.whl", hash = "sha256:999762f9c3132308789affa03e9271bbbe947bf78311851f4d485d8402ed858e"}, @@ -2130,12 +2173,12 @@ typing-extensions = [ {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, ] urllib3 = [ - {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"}, - {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, + {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, + {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, ] virtualenv = [ - {file = "virtualenv-20.13.3-py2.py3-none-any.whl", hash = "sha256:dd448d1ded9f14d1a4bfa6bfc0c5b96ae3be3f2d6c6c159b23ddcfd701baa021"}, - {file = "virtualenv-20.13.3.tar.gz", hash = "sha256:e9dd1a1359d70137559034c0f5433b34caf504af2dc756367be86a5a32967134"}, + {file = "virtualenv-20.14.0-py2.py3-none-any.whl", hash = "sha256:1e8588f35e8b42c6ec6841a13c5e88239de1e6e4e4cedfd3916b306dc826ec66"}, + {file = "virtualenv-20.14.0.tar.gz", hash = "sha256:8e5b402037287126e81ccde9432b95a8be5b19d36584f64957060a3488c11ca8"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, @@ -2145,59 +2188,72 @@ wmctrl = [ {file = "wmctrl-0.4.tar.gz", hash = "sha256:66cbff72b0ca06a22ec3883ac3a4d7c41078bdae4fb7310f52951769b10e14e0"}, ] wrapt = [ - {file = "wrapt-1.13.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca"}, - {file = "wrapt-1.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44"}, - {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056"}, - {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785"}, - {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096"}, - {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33"}, - {file = "wrapt-1.13.3-cp310-cp310-win32.whl", hash = "sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f"}, - {file = "wrapt-1.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755"}, - {file = "wrapt-1.13.3-cp35-cp35m-win32.whl", hash = "sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851"}, - {file = "wrapt-1.13.3-cp35-cp35m-win_amd64.whl", hash = "sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13"}, - {file = "wrapt-1.13.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918"}, - {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade"}, - {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc"}, - {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf"}, - {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125"}, - {file = "wrapt-1.13.3-cp36-cp36m-win32.whl", hash = "sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36"}, - {file = "wrapt-1.13.3-cp36-cp36m-win_amd64.whl", hash = "sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10"}, - {file = "wrapt-1.13.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068"}, - {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709"}, - {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df"}, - {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2"}, - {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b"}, - {file = "wrapt-1.13.3-cp37-cp37m-win32.whl", hash = "sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829"}, - {file = "wrapt-1.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea"}, - {file = "wrapt-1.13.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9"}, - {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554"}, - {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c"}, - {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b"}, - {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce"}, - {file = "wrapt-1.13.3-cp38-cp38-win32.whl", hash = "sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79"}, - {file = "wrapt-1.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb"}, - {file = "wrapt-1.13.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb"}, - {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32"}, - {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7"}, - {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e"}, - {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640"}, - {file = "wrapt-1.13.3-cp39-cp39-win32.whl", hash = "sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374"}, - {file = "wrapt-1.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb"}, - {file = "wrapt-1.13.3.tar.gz", hash = "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185"}, + {file = "wrapt-1.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:5a9a1889cc01ed2ed5f34574c90745fab1dd06ec2eee663e8ebeefe363e8efd7"}, + {file = "wrapt-1.14.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:9a3ff5fb015f6feb78340143584d9f8a0b91b6293d6b5cf4295b3e95d179b88c"}, + {file = "wrapt-1.14.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4b847029e2d5e11fd536c9ac3136ddc3f54bc9488a75ef7d040a3900406a91eb"}, + {file = "wrapt-1.14.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9a5a544861b21e0e7575b6023adebe7a8c6321127bb1d238eb40d99803a0e8bd"}, + {file = "wrapt-1.14.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:88236b90dda77f0394f878324cfbae05ae6fde8a84d548cfe73a75278d760291"}, + {file = "wrapt-1.14.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f0408e2dbad9e82b4c960274214af533f856a199c9274bd4aff55d4634dedc33"}, + {file = "wrapt-1.14.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9d8c68c4145041b4eeae96239802cfdfd9ef927754a5be3f50505f09f309d8c6"}, + {file = "wrapt-1.14.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:22626dca56fd7f55a0733e604f1027277eb0f4f3d95ff28f15d27ac25a45f71b"}, + {file = "wrapt-1.14.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:65bf3eb34721bf18b5a021a1ad7aa05947a1767d1aa272b725728014475ea7d5"}, + {file = "wrapt-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09d16ae7a13cff43660155383a2372b4aa09109c7127aa3f24c3cf99b891c330"}, + {file = "wrapt-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:debaf04f813ada978d7d16c7dfa16f3c9c2ec9adf4656efdc4defdf841fc2f0c"}, + {file = "wrapt-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:748df39ed634851350efa87690c2237a678ed794fe9ede3f0d79f071ee042561"}, + {file = "wrapt-1.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1807054aa7b61ad8d8103b3b30c9764de2e9d0c0978e9d3fc337e4e74bf25faa"}, + {file = "wrapt-1.14.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:763a73ab377390e2af26042f685a26787c402390f682443727b847e9496e4a2a"}, + {file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8529b07b49b2d89d6917cfa157d3ea1dfb4d319d51e23030664a827fe5fd2131"}, + {file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:68aeefac31c1f73949662ba8affaf9950b9938b712fb9d428fa2a07e40ee57f8"}, + {file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59d7d92cee84a547d91267f0fea381c363121d70fe90b12cd88241bd9b0e1763"}, + {file = "wrapt-1.14.0-cp310-cp310-win32.whl", hash = "sha256:3a88254881e8a8c4784ecc9cb2249ff757fd94b911d5df9a5984961b96113fff"}, + {file = "wrapt-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:9a242871b3d8eecc56d350e5e03ea1854de47b17f040446da0e47dc3e0b9ad4d"}, + {file = "wrapt-1.14.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a65bffd24409454b889af33b6c49d0d9bcd1a219b972fba975ac935f17bdf627"}, + {file = "wrapt-1.14.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9d9fcd06c952efa4b6b95f3d788a819b7f33d11bea377be6b8980c95e7d10775"}, + {file = "wrapt-1.14.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:db6a0ddc1282ceb9032e41853e659c9b638789be38e5b8ad7498caac00231c23"}, + {file = "wrapt-1.14.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:14e7e2c5f5fca67e9a6d5f753d21f138398cad2b1159913ec9e9a67745f09ba3"}, + {file = "wrapt-1.14.0-cp35-cp35m-win32.whl", hash = "sha256:6d9810d4f697d58fd66039ab959e6d37e63ab377008ef1d63904df25956c7db0"}, + {file = "wrapt-1.14.0-cp35-cp35m-win_amd64.whl", hash = "sha256:d808a5a5411982a09fef6b49aac62986274ab050e9d3e9817ad65b2791ed1425"}, + {file = "wrapt-1.14.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b77159d9862374da213f741af0c361720200ab7ad21b9f12556e0eb95912cd48"}, + {file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36a76a7527df8583112b24adc01748cd51a2d14e905b337a6fefa8b96fc708fb"}, + {file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0057b5435a65b933cbf5d859cd4956624df37b8bf0917c71756e4b3d9958b9e"}, + {file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0a4ca02752ced5f37498827e49c414d694ad7cf451ee850e3ff160f2bee9d3"}, + {file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8c6be72eac3c14baa473620e04f74186c5d8f45d80f8f2b4eda6e1d18af808e8"}, + {file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:21b1106bff6ece8cb203ef45b4f5778d7226c941c83aaaa1e1f0f4f32cc148cd"}, + {file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:493da1f8b1bb8a623c16552fb4a1e164c0200447eb83d3f68b44315ead3f9036"}, + {file = "wrapt-1.14.0-cp36-cp36m-win32.whl", hash = "sha256:89ba3d548ee1e6291a20f3c7380c92f71e358ce8b9e48161401e087e0bc740f8"}, + {file = "wrapt-1.14.0-cp36-cp36m-win_amd64.whl", hash = "sha256:729d5e96566f44fccac6c4447ec2332636b4fe273f03da128fff8d5559782b06"}, + {file = "wrapt-1.14.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:891c353e95bb11abb548ca95c8b98050f3620a7378332eb90d6acdef35b401d4"}, + {file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23f96134a3aa24cc50614920cc087e22f87439053d886e474638c68c8d15dc80"}, + {file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6807bcee549a8cb2f38f73f469703a1d8d5d990815c3004f21ddb68a567385ce"}, + {file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6915682f9a9bc4cf2908e83caf5895a685da1fbd20b6d485dafb8e218a338279"}, + {file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f2f3bc7cd9c9fcd39143f11342eb5963317bd54ecc98e3650ca22704b69d9653"}, + {file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3a71dbd792cc7a3d772ef8cd08d3048593f13d6f40a11f3427c000cf0a5b36a0"}, + {file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5a0898a640559dec00f3614ffb11d97a2666ee9a2a6bad1259c9facd01a1d4d9"}, + {file = "wrapt-1.14.0-cp37-cp37m-win32.whl", hash = "sha256:167e4793dc987f77fd476862d32fa404d42b71f6a85d3b38cbce711dba5e6b68"}, + {file = "wrapt-1.14.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d066ffc5ed0be00cd0352c95800a519cf9e4b5dd34a028d301bdc7177c72daf3"}, + {file = "wrapt-1.14.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d9bdfa74d369256e4218000a629978590fd7cb6cf6893251dad13d051090436d"}, + {file = "wrapt-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2498762814dd7dd2a1d0248eda2afbc3dd9c11537bc8200a4b21789b6df6cd38"}, + {file = "wrapt-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f24ca7953f2643d59a9c87d6e272d8adddd4a53bb62b9208f36db408d7aafc7"}, + {file = "wrapt-1.14.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b835b86bd5a1bdbe257d610eecab07bf685b1af2a7563093e0e69180c1d4af1"}, + {file = "wrapt-1.14.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b21650fa6907e523869e0396c5bd591cc326e5c1dd594dcdccac089561cacfb8"}, + {file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:354d9fc6b1e44750e2a67b4b108841f5f5ea08853453ecbf44c81fdc2e0d50bd"}, + {file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1f83e9c21cd5275991076b2ba1cd35418af3504667affb4745b48937e214bafe"}, + {file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:61e1a064906ccba038aa3c4a5a82f6199749efbbb3cef0804ae5c37f550eded0"}, + {file = "wrapt-1.14.0-cp38-cp38-win32.whl", hash = "sha256:28c659878f684365d53cf59dc9a1929ea2eecd7ac65da762be8b1ba193f7e84f"}, + {file = "wrapt-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:b0ed6ad6c9640671689c2dbe6244680fe8b897c08fd1fab2228429b66c518e5e"}, + {file = "wrapt-1.14.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3f7e671fb19734c872566e57ce7fc235fa953d7c181bb4ef138e17d607dc8a1"}, + {file = "wrapt-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87fa943e8bbe40c8c1ba4086971a6fefbf75e9991217c55ed1bcb2f1985bd3d4"}, + {file = "wrapt-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4775a574e9d84e0212f5b18886cace049a42e13e12009bb0491562a48bb2b758"}, + {file = "wrapt-1.14.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d57677238a0c5411c76097b8b93bdebb02eb845814c90f0b01727527a179e4d"}, + {file = "wrapt-1.14.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00108411e0f34c52ce16f81f1d308a571df7784932cc7491d1e94be2ee93374b"}, + {file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d332eecf307fca852d02b63f35a7872de32d5ba8b4ec32da82f45df986b39ff6"}, + {file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:01f799def9b96a8ec1ef6b9c1bbaf2bbc859b87545efbecc4a78faea13d0e3a0"}, + {file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47045ed35481e857918ae78b54891fac0c1d197f22c95778e66302668309336c"}, + {file = "wrapt-1.14.0-cp39-cp39-win32.whl", hash = "sha256:2eca15d6b947cfff51ed76b2d60fd172c6ecd418ddab1c5126032d27f74bc350"}, + {file = "wrapt-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb36fbb48b22985d13a6b496ea5fb9bb2a076fea943831643836c9f6febbcfdc"}, + {file = "wrapt-1.14.0.tar.gz", hash = "sha256:8323a43bd9c91f62bb7d4be74cc9ff10090e7ef820e27bfe8815c57e68261311"}, ] zipp = [ - {file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"}, - {file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"}, + {file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"}, + {file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"}, ] From 44759d0ba93db67d8addf796f251dc5764ed7252 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 5 Apr 2022 12:46:12 +0200 Subject: [PATCH 35/47] Attempt to add more harmonic tests --- ...t_harmonics_cache.py => test_harmonics.py} | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) rename tests/eko/{test_harmonics_cache.py => test_harmonics.py} (64%) diff --git a/tests/eko/test_harmonics_cache.py b/tests/eko/test_harmonics.py similarity index 64% rename from tests/eko/test_harmonics_cache.py rename to tests/eko/test_harmonics.py index 7da15cd59..854c98092 100644 --- a/tests/eko/test_harmonics_cache.py +++ b/tests/eko/test_harmonics.py @@ -1,11 +1,26 @@ # -*- coding: utf-8 -*- -# Test eko.matching_conditions.OperatorMatrixElement import numpy as np from eko import harmonics as h -def test_HarmonicsCache(): +def test_spm1(): + for k in range(1, 5 + 1): + f = np.sum([1.0 / j for j in range(1, k + 1)]) + np.testing.assert_allclose(f, h.w1.S1(k)) + g = np.sum([(-1.0) ** j / j for j in range(1, k + 1)]) + np.testing.assert_allclose(g, h.w1.Sm1(k)) + + +def test_spm2(): + for k in range(1, 5 + 1): + f = np.sum([1.0 / j**2 for j in range(1, k + 1)]) + np.testing.assert_allclose(f, h.w2.S2(k)) + g = np.sum([(-1.0) ** j / j**2 for j in range(1, k + 1)]) + np.testing.assert_allclose(g, h.w2.Sm2(k)) + + +def test_harmonics_cache(): N = np.random.rand() + 1.0j * np.random.rand() Sm1 = h.Sm1(N) Sm2 = h.Sm2(N) From 8c9e7d37848449ae69e5a303f90461789b0390f5 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Tue, 5 Apr 2022 13:50:52 +0200 Subject: [PATCH 36/47] fix w5 docstring --- src/eko/harmonics/w5.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/eko/harmonics/w5.py b/src/eko/harmonics/w5.py index 816692a27..ea727b318 100644 --- a/src/eko/harmonics/w5.py +++ b/src/eko/harmonics/w5.py @@ -66,7 +66,7 @@ def Sm5(N): def S41(N, S1, S2, S3): r""" Analytic continuation of harmonic sum :math:`S_{4,1}(N)` - as implemented in eq 9.1 of :cite:` Bl_mlein_2009` + as implemented in eq 9.1 of :cite:`Blumlein:2009ta` Parameters ---------- @@ -96,7 +96,7 @@ def S41(N, S1, S2, S3): def S311(N, S1, S2): r""" Analytic continuation of harmonic sum :math:`S_{3,1,1}(N)` - as implemented in eq 9.21 of :cite:` Bl_mlein_2009` + as implemented in eq 9.21 of :cite:`Blumlein:2009ta` Parameters ---------- @@ -124,7 +124,7 @@ def S311(N, S1, S2): def S221(N, S1, S2, S21): r""" Analytic continuation of harmonic sum :math:`S_{2,2,1}(N)` - as implemented in eq 9.23 of :cite:` Bl_mlein_2009` + as implemented in eq 9.23 of :cite:`Blumlein:2009ta` Parameters ---------- @@ -161,7 +161,7 @@ def S221(N, S1, S2, S21): def Sm221(N, S1, Sm1, S21, Sm21): r""" Analytic continuation of harmonic sum :math:`S_{-2,2,1}(N)` - as implemented in eq 9.25 of :cite:` Bl_mlein_2009` + as implemented in eq 9.25 of :cite:`Blumlein:2009ta` Parameters ---------- @@ -199,7 +199,7 @@ def Sm221(N, S1, Sm1, S21, Sm21): def S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1): r""" Analytic continuation of harmonic sum :math:`S_{2,1,-2}(N)` - as implemented in eq 9.26 of :cite:` Bl_mlein_2009` + as implemented in eq 9.26 of :cite:`Blumlein:2009ta` Parameters ---------- @@ -247,7 +247,7 @@ def S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1): def S2111(N, S1, S2, S3): r""" Analytic continuation of harmonic sum :math:`S_{2,1,1,1}(N)` - as implemented in eq 9.33 of :cite:` Bl_mlein_2009` + as implemented in eq 9.33 of :cite:`Blumlein:2009ta` Parameters ---------- @@ -277,7 +277,7 @@ def S2111(N, S1, S2, S3): def Sm2111(N, S1, S2, S3, Sm1): r""" Analytic continuation of harmonic sum :math:`S_{-2,1,1,1}(N)` - as implemented in eq 9.34 of :cite:` Bl_mlein_2009` + as implemented in eq 9.34 of :cite:`Blumlein:2009ta` Parameters ---------- @@ -314,7 +314,7 @@ def Sm2111(N, S1, S2, S3, Sm1): def S23(N, S1, S2, S3): r""" Analytic continuation of harmonic sum :math:`S_{2,3}(N)` - as implemented in eq 9.3 of :cite:` Bl_mlein_2009` + as implemented in eq 9.3 of :cite:`Blumlein:2009ta` Parameters ---------- @@ -348,7 +348,7 @@ def S23(N, S1, S2, S3): def Sm23(N, Sm1, Sm2, Sm3): r""" Analytic continuation of harmonic sum :math:`S_{-2,3}(N)` - as implemented in eq 9.4 of :cite:` Bl_mlein_2009` + as implemented in eq 9.4 of :cite:`Blumlein:2009ta` Parameters ---------- @@ -388,7 +388,7 @@ def Sm23(N, Sm1, Sm2, Sm3): def S2m3(N, S2, Sm1, Sm2, Sm3): r""" Analytic continuation of harmonic sum :math:`S_{2,-3}(N)` - as implemented in eq 9.5 of :cite:` Bl_mlein_2009` + as implemented in eq 9.5 of :cite:`Blumlein:2009ta` Parameters ---------- From deee6a2d9de41c85c97d6b2ae615a0bd13fabe9e Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Tue, 5 Apr 2022 17:13:58 +0200 Subject: [PATCH 37/47] Add is_singlet to harmonics sums and remove (-1)**N --- src/eko/harmonics/__init__.py | 56 +++++++++++-------- src/eko/harmonics/w1.py | 12 +++- src/eko/harmonics/w2.py | 11 +++- src/eko/harmonics/w3.py | 27 +++++++-- src/eko/harmonics/w4.py | 38 +++++++++---- src/eko/harmonics/w5.py | 19 +++++-- src/eko/matching_conditions/as3/__init__.py | 6 +- src/eko/matching_conditions/as3/aqqNS.py | 7 ++- .../operator_matrix_element.py | 19 ++++--- 9 files changed, 136 insertions(+), 59 deletions(-) diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index ca48eb55e..d3920ab01 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -14,8 +14,8 @@ @nb.njit(cache=True) -def base_harmonics_cache(n, max_weight=5, n_max_sums_weight=7): - """ +def base_harmonics_cache(n, is_singlet, max_weight=5, n_max_sums_weight=7): + r""" Get the harmonics sums S basic cache. Only single index harmonics are computed and stored in the first (:math:`S_{n}`) or in the last column (:math:`S_{-n}`) @@ -26,6 +26,9 @@ def base_harmonics_cache(n, max_weight=5, n_max_sums_weight=7): ---------- n : complex Mellin moment + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) max_weight : int max harmonics weight, max value 5 (default) n_max_sums_weight : int @@ -39,7 +42,7 @@ def base_harmonics_cache(n, max_weight=5, n_max_sums_weight=7): h_cache = np.zeros((max_weight, n_max_sums_weight), dtype=np.complex_) h_cache[:, 0] = sx(n, max_weight) if n_max_sums_weight > 1: - h_cache[:, -1] = smx(n, max_weight) + h_cache[:, -1] = smx(n, h_cache[:, 0], is_singlet) return h_cache @@ -75,39 +78,42 @@ def sx(n, max_weight=5): @nb.njit(cache=True) -def smx(n, max_weight=5): - """ +def smx(n, sx, is_singlet): + r""" Get the harmonics S-minus cache Parameters ---------- n : complex Mellin moment - max_weight : int - max harmonics weight, max value 5 (default) - + sx : numpy.ndarray + List of harmonics sums: :math:`S_{1},\dots,S_{w}` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- smx : np.ndarray list of harmonics sums (:math:`S_{-1,..,-w}`) """ + max_weight = sx.size smx = np.zeros(max_weight, dtype=np.complex_) if max_weight >= 1: - smx[0] = Sm1(n) + smx[0] = Sm1(n, sx[0], is_singlet) if max_weight >= 2: - smx[1] = Sm2(n) + smx[1] = Sm2(n, sx[1], is_singlet) if max_weight >= 3: - smx[2] = Sm3(n) + smx[2] = Sm3(n, sx[2], is_singlet) if max_weight >= 4: - smx[3] = Sm4(n) + smx[3] = Sm4(n, sx[3], is_singlet) if max_weight >= 5: - smx[4] = Sm5(n) + smx[4] = Sm5(n, sx[4], is_singlet) return smx @nb.njit(cache=True) -def s3x(n, sx, smx): - """ +def s3x(n, sx, smx, is_singlet): + r""" Compute the weight 3 multi indices harmonics sums cache Parameters @@ -118,6 +124,9 @@ def s3x(n, sx, smx): List of harmonics sums: :math:`S_{1},S_{2}` smx : list List of harmonics sums: :math:`S_{-1},S_{-2}` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -127,16 +136,16 @@ def s3x(n, sx, smx): return np.array( [ S21(n, sx[0], sx[1]), - S2m1(n, sx[1], smx[0], smx[1]), - Sm21(n, sx[0], smx[0]), + S2m1(n, sx[1], smx[0], smx[1], is_singlet), + Sm21(n, sx[0], smx[0], is_singlet), Sm2m1(n, sx[0], sx[1], smx[1]), ] ) @nb.njit(cache=True) -def s4x(n, sx, smx): - """ +def s4x(n, sx, smx, is_singlet): + r""" Compute the weight 4 multi indices harmonics sums cache Parameters @@ -147,6 +156,9 @@ def s4x(n, sx, smx): List of harmonics sums: :math:`S_{1},S_{2},S_{3},S_{4}` smx : list List of harmonics sums: :math:`S_{-1},S_{-2}` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -158,8 +170,8 @@ def s4x(n, sx, smx): [ S31(n, sx[0], sx[1], sx[2], sx[3]), S211(n, sx[0], sx[1], sx[2]), - Sm22(n, sx[0], sx[1], smx[1], sm31), - Sm211(n, sx[0], sx[1], smx[0]), - Sm31(n, sx[0], smx[0], smx[1]), + Sm22(n, sx[0], sx[1], smx[1], sm31, is_singlet), + Sm211(n, sx[0], sx[1], smx[0], is_singlet), + Sm31(n, sx[0], smx[0], smx[1], is_singlet), ] ) diff --git a/src/eko/harmonics/w1.py b/src/eko/harmonics/w1.py index d31c003f1..74501eb49 100644 --- a/src/eko/harmonics/w1.py +++ b/src/eko/harmonics/w1.py @@ -38,7 +38,7 @@ def S1(N): @nb.njit(cache=True) -def Sm1(N): +def Sm1(N, S1, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-1}(N)`. @@ -49,7 +49,11 @@ def Sm1(N): ---------- N : complex Mellin moment - + S1: complex + Harmonic sum :math:`S_{1}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- Sm1 : complex @@ -59,4 +63,6 @@ def Sm1(N): -------- eko.anomalous_dimension.w1.S1 : :math:`S_1(N)` """ - return (-1) ** N / 2 * (S1(N / 2) - S1((N - 1) / 2)) - log2 + if is_singlet: + return S1(N / 2) - S1 + return S1((N - 1) / 2) - S1 diff --git a/src/eko/harmonics/w2.py b/src/eko/harmonics/w2.py index 2f14cb98a..aad93892f 100644 --- a/src/eko/harmonics/w2.py +++ b/src/eko/harmonics/w2.py @@ -37,7 +37,7 @@ def S2(N): @nb.njit(cache=True) -def Sm2(N): +def Sm2(N, S2, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-2}(N)`. @@ -48,6 +48,11 @@ def Sm2(N): ---------- N : complex Mellin moment + S2: complex + Harmonic sum :math:`S_{2}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -58,4 +63,6 @@ def Sm2(N): -------- eko.anomalous_dimension.w2.S2 : :math:`S_2(N)` """ - return (-1) ** N / 4 * (S2(N / 2) - S2((N - 1) / 2)) - zeta2 / 2 + if is_singlet: + return S2(N / 2) - 1 / 2 * S2 + return S2((N - 1) / 2) - 1 / 2 * S2 diff --git a/src/eko/harmonics/w3.py b/src/eko/harmonics/w3.py index fdc85e274..c17b3a00e 100644 --- a/src/eko/harmonics/w3.py +++ b/src/eko/harmonics/w3.py @@ -38,7 +38,7 @@ def S3(N): @nb.njit(cache=True) -def Sm3(N): +def Sm3(N, S3, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-3}(N)`. @@ -49,6 +49,11 @@ def Sm3(N): ---------- N : complex Mellin moment + S3: complex + Harmonic sum :math:`S_{3}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -59,7 +64,9 @@ def Sm3(N): -------- eko.harmonics.w3.S3 : :math:`S_3(N)` """ - return (-1) ** N / 8 * (S3(N / 2) - S3((N - 1) / 2)) - 3 / 4 * zeta3 + if is_singlet: + return S3(N / 2) - 1 / 2**2 * S3 + return S3((N - 1) / 2) - 1 / 2**2 * S3 @nb.njit(cache=True) @@ -90,7 +97,7 @@ def S21(N, S1, S2): @nb.njit(cache=True) -def Sm21(N, S1, Sm1): +def Sm21(N, S1, Sm1, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-2,1}(N)` as implemented in eq B.5.75 of :cite:`MuselliPhD` and eq 22 of :cite:`Bl_mlein_2000`. @@ -103,6 +110,9 @@ def Sm21(N, S1, Sm1): Harmonic sum :math:`S_{1}(N)` Sm1: complex Harmonic sum :math:`S_{-1}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -114,8 +124,9 @@ def Sm21(N, S1, Sm1): eko.harmonics.g_functions : :math:`g_3(N)` """ # Note mellin g3 was integrated following x^(N-1) convention. + eta = 1 if is_singlet else -1 return ( - -((-1) ** N) * gf.mellin_g3(N + 1, S1 + 1 / (N + 1)) + -eta * gf.mellin_g3(N + 1, S1 + 1 / (N + 1)) + zeta2 * Sm1 - 5 / 8 * zeta3 + zeta2 * log2 @@ -123,7 +134,7 @@ def Sm21(N, S1, Sm1): @nb.njit(cache=True) -def S2m1(N, S2, Sm1, Sm2): +def S2m1(N, S2, Sm1, Sm2, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{2,-1}(N)` as implemented in eq B.5.76 of :cite:`MuselliPhD` and eq 23 of :cite:`Bl_mlein_2000`. @@ -138,6 +149,9 @@ def S2m1(N, S2, Sm1, Sm2): Harmonic sum :math:`S_{-1}(N)` Sm2: complex Harmonic sum :math:`S_{-2}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -148,8 +162,9 @@ def S2m1(N, S2, Sm1, Sm2): -------- eko.harmonics.g_functions.mellin_g4 : :math:`g_4(N)` """ + eta = 1 if is_singlet else -1 return ( - -((-1) ** N) * gf.mellin_g4(N) + -eta * gf.mellin_g4(N) - log2 * (S2 - Sm2) - 1 / 2 * zeta2 * Sm1 + 1 / 4 * zeta3 diff --git a/src/eko/harmonics/w4.py b/src/eko/harmonics/w4.py index bfc807a87..9d74d9cf9 100644 --- a/src/eko/harmonics/w4.py +++ b/src/eko/harmonics/w4.py @@ -38,7 +38,7 @@ def S4(N): @nb.njit(cache=True) -def Sm4(N): +def Sm4(N, S4, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-4}(N)`. @@ -49,6 +49,11 @@ def Sm4(N): ---------- N : complex Mellin moment + S4: complex + Harmonic sum :math:`S_{4}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -59,11 +64,13 @@ def Sm4(N): -------- eko.anomalous_dimension.w4.S4 : :math:`S_4(N)` """ - return (-1) ** N / 16 * (S4(N / 2) - S4((N - 1) / 2)) - 7 / 8 * zeta4 + if is_singlet: + return S4(N / 2) - 1 / 2**3 * S4 + return S4((N - 1) / 2) - 1 / 2**3 * S4 @nb.njit(cache=True) -def Sm31(N, S1, Sm1, Sm2): +def Sm31(N, S1, Sm1, Sm2, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-3,1}(N)` as implemented in eq B.5.93 of :cite:`MuselliPhD` and eq 25 of cite:`Bl_mlein_2000`. @@ -78,6 +85,9 @@ def Sm31(N, S1, Sm1, Sm2): Harmonic sum :math:`S_{-1}(N)` Sm2: complex Harmonic sum :math:`S_{-2}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -88,8 +98,9 @@ def Sm31(N, S1, Sm1, Sm2): -------- eko.harmonics.g_functions.mellin_g6 : :math:`g_6(N)` """ + eta = 1 if is_singlet else -1 return ( - (-1) ** N * gf.mellin_g6(N, S1) + eta * gf.mellin_g6(N, S1) + zeta2 * Sm2 - zeta3 * Sm1 - 3 / 5 * zeta2**2 @@ -101,7 +112,7 @@ def Sm31(N, S1, Sm1, Sm2): @nb.njit(cache=True) -def Sm22(N, S1, S2, Sm2, Sm31): +def Sm22(N, S1, S2, Sm2, Sm31, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-2,2}(N)` as implemented in eq B.5.94 of :cite:`MuselliPhD` and eq 24 of cite:`Bl_mlein_2000`. @@ -118,6 +129,9 @@ def Sm22(N, S1, S2, Sm2, Sm31): Harmonic sum :math:`S_{-2}(N)` Sm31: complex Harmonic sum :math:`S_{-3,1}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- Sm22 : complex @@ -127,16 +141,14 @@ def Sm22(N, S1, S2, Sm2, Sm31): -------- eko.harmonics.g_functions.mellin_g5 : :math:`g_5(N)` """ + eta = 1 if is_singlet else -1 return ( - (-1) ** N * gf.mellin_g5(N, S1, S2) - - 2 * Sm31 - + 2 * zeta2 * Sm2 - + 3 / 40 * zeta2**2 + eta * gf.mellin_g5(N, S1, S2) - 2 * Sm31 + 2 * zeta2 * Sm2 + 3 / 40 * zeta2**2 ) @nb.njit(cache=True) -def Sm211(N, S1, S2, Sm1): +def Sm211(N, S1, S2, Sm1, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-2,1,1}(N)` as implemented in eq B.5.104 of :cite:`MuselliPhD` and eq 27 of cite:`Bl_mlein_2000`. @@ -151,6 +163,9 @@ def Sm211(N, S1, S2, Sm1): Harmonic sum :math:`S_{2}(N)` Sm1: complex Harmonic sum :math:`S_{-1}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -161,8 +176,9 @@ def Sm211(N, S1, S2, Sm1): -------- eko.harmonics.g_functions.mellin_g8 : :math:`g_8(N)` """ + eta = 1 if is_singlet else -1 return ( - -((-1) ** N) * gf.mellin_g8(N, S1, S2) + -eta * gf.mellin_g8(N, S1, S2) + zeta3 * Sm1 - li4half + 1 / 8 * zeta2**2 diff --git a/src/eko/harmonics/w5.py b/src/eko/harmonics/w5.py index ea727b318..564d28ca0 100644 --- a/src/eko/harmonics/w5.py +++ b/src/eko/harmonics/w5.py @@ -38,7 +38,7 @@ def S5(N): @nb.njit(cache=True) -def Sm5(N): +def Sm5(N, S5, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-5}(N)`. @@ -49,6 +49,11 @@ def Sm5(N): ---------- N : complex Mellin moment + S5: complex + Harmonic sum :math:`S_{5}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -59,7 +64,9 @@ def Sm5(N): -------- eko.harmonic.w5.S5 : :math:`S_5(N)` """ - return (-1) ** N / 32 * (S5(N / 2) - S5((N - 1) / 2)) - 15 / 16 * zeta5 + if is_singlet: + return S5(N / 2) - 1 / 2**4 * S5 + return S5((N - 1) / 2) - 1 / 2**4 * S5 @nb.njit(cache=True) @@ -345,7 +352,7 @@ def S23(N, S1, S2, S3): @nb.njit(cache=True) -def Sm23(N, Sm1, Sm2, Sm3): +def Sm23(N, Sm1, Sm2, Sm3, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-2,3}(N)` as implemented in eq 9.4 of :cite:`Blumlein:2009ta` @@ -360,6 +367,9 @@ def Sm23(N, Sm1, Sm2, Sm3): Harmonic sum :math:`S_{-2}(N)` Sm3: complex Harmonic sum :math:`S_{-3}(N)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -375,8 +385,9 @@ def Sm23(N, Sm1, Sm2, Sm3): +3 [\text{S}_{1,3}(1-x) - \zeta_4] /(x+1)](N)` """ + eta = 1 if is_singlet else -1 return ( - (-1) ** N * f.F20(N, Sm1, Sm2, Sm3) + eta * f.F20(N, Sm1, Sm2, Sm3) + 3 * zeta4 * Sm1 + 21 / 32 * zeta5 + 3 * zeta4 * log2 diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/eko/matching_conditions/as3/__init__.py index 7863d1971..9150141f0 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/eko/matching_conditions/as3/__init__.py @@ -81,7 +81,7 @@ def A_singlet(n, sx_all, nf, L): A_gg_3 = A_gg(n, sx_all, nf, L) A_qq_ps_3 = A_qqPS(n, sx_all, nf, L) - A_qq_ns_3 = A_qqNS(n, sx_all, nf, L) + A_qq_ns_3 = A_qqNS(n, sx_all, nf, L, True) A_qg_3 = A_qg(n, sx_all, nf, L) A_S = np.array( @@ -136,4 +136,6 @@ def A_ns(n, sx_all, nf, L): -------- A_qqNS_3 : :math:`A_{qq,H}^{NS,(3))}` """ - return np.array([[A_qqNS(n, sx_all, nf, L), 0.0], [0 + 0j, 0 + 0j]], np.complex_) + return np.array( + [[A_qqNS(n, sx_all, nf, L, False), 0.0], [0 + 0j, 0 + 0j]], np.complex_ + ) diff --git a/src/eko/matching_conditions/as3/aqqNS.py b/src/eko/matching_conditions/as3/aqqNS.py index 1f8543426..7dedebd38 100644 --- a/src/eko/matching_conditions/as3/aqqNS.py +++ b/src/eko/matching_conditions/as3/aqqNS.py @@ -6,7 +6,7 @@ @nb.njit(cache=True) -def A_qqNS(n, sx, nf, L): # pylint: disable=too-many-locals +def A_qqNS(n, sx, nf, L, is_singlet): # pylint: disable=too-many-locals r""" Computes the |N3LO| singlet |OME| :math:`A_{qq}^{NS,(3)}(N)`. The experssion is presented in :cite:`Bierenbaum:2009mv` and @@ -25,6 +25,9 @@ def A_qqNS(n, sx, nf, L): # pylint: disable=too-many-locals number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -44,7 +47,7 @@ def A_qqNS(n, sx, nf, L): # pylint: disable=too-many-locals S2111 = sf.S2111(n, S1, S2, S3) Sm2111 = sf.Sm2111(n, S1, S2, S3, Sm1) S23 = sf.S23(n, S1, S2, S3) - Sm23 = sf.Sm23(n, Sm1, Sm2, Sm3) + Sm23 = sf.Sm23(n, Sm1, Sm2, Sm3, is_singlet) S2m3 = sf.S2m3(n, S2, Sm1, Sm2, Sm3) a_qqNS_l0 = ( 0.3333333333333333 diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index e60add596..dc6239d79 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -19,8 +19,8 @@ @nb.njit(cache=True) -def compute_harmonics_cache(n, order): - """ +def compute_harmonics_cache(n, order, is_singlet): + r""" Get the harmonics sums cache Parameters @@ -29,6 +29,9 @@ def compute_harmonics_cache(n, order): Mellin moment order: int perturbative order + is_singlet: bool + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -46,14 +49,16 @@ def compute_harmonics_cache(n, order): max_weight = {1: 2, 2: 3, 3: 5} # max number of harmonics sum of a given weight for each qcd order n_max_sums_weight = {1: 1, 2: 3, 3: 7} - sx = harmonics.base_harmonics_cache(n, max_weight[order], n_max_sums_weight[order]) + sx = harmonics.base_harmonics_cache( + n, is_singlet, max_weight[order], n_max_sums_weight[order] + ) if order == 2: # Add Sm21 to cache - sx[2, 1] = harmonics.Sm21(n, sx[0, 0], sx[0, -1]) + sx[2, 1] = harmonics.Sm21(n, sx[0, 0], sx[0, -1], is_singlet) if order == 3: # Add weight 3 and 4 to cache - sx[2, 1:-2] = harmonics.s3x(n, sx[:, 0], sx[:, -1]) - sx[3, 1:-1] = harmonics.s4x(n, sx[:, 0], sx[:, -1]) + sx[2, 1:-2] = harmonics.s3x(n, sx[:, 0], sx[:, -1], is_singlet) + sx[3, 1:-1] = harmonics.s4x(n, sx[:, 0], sx[:, -1], is_singlet) # return list of list keeping the non zero values return [[el for el in sx_list if el != 0] for sx_list in sx] @@ -233,7 +238,7 @@ def quad_ker( if integrand == 0.0: return 0.0 - sx = compute_harmonics_cache(ker_base.n, order) + sx = compute_harmonics_cache(ker_base.n, order, ker_base.is_singlet) # compute the ome if ker_base.is_singlet: indices = {21: 0, 100: 1, 90: 2} From f44a1f66c3d8888c841b831f82a73912f4a5fc16 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Tue, 5 Apr 2022 17:57:00 +0200 Subject: [PATCH 38/47] Adding is_singlet to tests --- src/eko/harmonics/__init__.py | 2 +- src/eko/harmonics/w1.py | 8 +-- src/eko/harmonics/w2.py | 8 +-- src/eko/harmonics/w3.py | 8 +-- src/eko/harmonics/w4.py | 8 +-- src/eko/harmonics/w5.py | 8 +-- tests/eko/test_f_functions.py | 41 +++++++++----- tests/eko/test_g_functions.py | 33 ++++++----- tests/eko/test_harmonics.py | 99 +++++++++++++++++++++++++++------ tests/eko/test_matching_n3lo.py | 20 +++---- tests/eko/test_matching_nlo.py | 6 +- tests/eko/test_matching_nnlo.py | 16 +++--- tests/eko/test_ome.py | 2 +- tests/eko/test_s_functions.py | 79 -------------------------- 14 files changed, 170 insertions(+), 168 deletions(-) delete mode 100644 tests/eko/test_s_functions.py diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index d3920ab01..00eebc8ae 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -165,7 +165,7 @@ def s4x(n, sx, smx, is_singlet): s4x: np.ndarray list containing: :math:`S_{3,1},S_{2,1,1},S_{-2,2},S_{-2,1,1},S_{-3,1}` """ - sm31 = Sm31(n, sx[0], smx[0], smx[1]) + sm31 = Sm31(n, sx[0], smx[0], smx[1], is_singlet) return np.array( [ S31(n, sx[0], sx[1], sx[2], sx[3]), diff --git a/src/eko/harmonics/w1.py b/src/eko/harmonics/w1.py index 74501eb49..55f3558c0 100644 --- a/src/eko/harmonics/w1.py +++ b/src/eko/harmonics/w1.py @@ -38,7 +38,7 @@ def S1(N): @nb.njit(cache=True) -def Sm1(N, S1, is_singlet): +def Sm1(N, hS1, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-1}(N)`. @@ -49,7 +49,7 @@ def Sm1(N, S1, is_singlet): ---------- N : complex Mellin moment - S1: complex + hS1: complex Harmonic sum :math:`S_{1}(N)` is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), @@ -64,5 +64,5 @@ def Sm1(N, S1, is_singlet): eko.anomalous_dimension.w1.S1 : :math:`S_1(N)` """ if is_singlet: - return S1(N / 2) - S1 - return S1((N - 1) / 2) - S1 + return S1(N / 2) - hS1 + return S1((N - 1) / 2) - hS1 diff --git a/src/eko/harmonics/w2.py b/src/eko/harmonics/w2.py index aad93892f..878c14ca0 100644 --- a/src/eko/harmonics/w2.py +++ b/src/eko/harmonics/w2.py @@ -37,7 +37,7 @@ def S2(N): @nb.njit(cache=True) -def Sm2(N, S2, is_singlet): +def Sm2(N, hS2, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-2}(N)`. @@ -48,7 +48,7 @@ def Sm2(N, S2, is_singlet): ---------- N : complex Mellin moment - S2: complex + hS2: complex Harmonic sum :math:`S_{2}(N)` is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), @@ -64,5 +64,5 @@ def Sm2(N, S2, is_singlet): eko.anomalous_dimension.w2.S2 : :math:`S_2(N)` """ if is_singlet: - return S2(N / 2) - 1 / 2 * S2 - return S2((N - 1) / 2) - 1 / 2 * S2 + return 1 / 2 * S2(N / 2) - hS2 + return 1 / 2 * S2((N - 1) / 2) - hS2 diff --git a/src/eko/harmonics/w3.py b/src/eko/harmonics/w3.py index c17b3a00e..8647f2326 100644 --- a/src/eko/harmonics/w3.py +++ b/src/eko/harmonics/w3.py @@ -38,7 +38,7 @@ def S3(N): @nb.njit(cache=True) -def Sm3(N, S3, is_singlet): +def Sm3(N, hS3, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-3}(N)`. @@ -49,7 +49,7 @@ def Sm3(N, S3, is_singlet): ---------- N : complex Mellin moment - S3: complex + hS3: complex Harmonic sum :math:`S_{3}(N)` is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), @@ -65,8 +65,8 @@ def Sm3(N, S3, is_singlet): eko.harmonics.w3.S3 : :math:`S_3(N)` """ if is_singlet: - return S3(N / 2) - 1 / 2**2 * S3 - return S3((N - 1) / 2) - 1 / 2**2 * S3 + return 1 / 2**2 * S3(N / 2) - hS3 + return 1 / 2**2 * S3((N - 1) / 2) - hS3 @nb.njit(cache=True) diff --git a/src/eko/harmonics/w4.py b/src/eko/harmonics/w4.py index 9d74d9cf9..7e4bd7e73 100644 --- a/src/eko/harmonics/w4.py +++ b/src/eko/harmonics/w4.py @@ -38,7 +38,7 @@ def S4(N): @nb.njit(cache=True) -def Sm4(N, S4, is_singlet): +def Sm4(N, hS4, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-4}(N)`. @@ -49,7 +49,7 @@ def Sm4(N, S4, is_singlet): ---------- N : complex Mellin moment - S4: complex + hS4: complex Harmonic sum :math:`S_{4}(N)` is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), @@ -65,8 +65,8 @@ def Sm4(N, S4, is_singlet): eko.anomalous_dimension.w4.S4 : :math:`S_4(N)` """ if is_singlet: - return S4(N / 2) - 1 / 2**3 * S4 - return S4((N - 1) / 2) - 1 / 2**3 * S4 + return 1 / 2**3 * S4(N / 2) - hS4 + return 1 / 2**3 * S4((N - 1) / 2) - hS4 @nb.njit(cache=True) diff --git a/src/eko/harmonics/w5.py b/src/eko/harmonics/w5.py index 564d28ca0..0a275881f 100644 --- a/src/eko/harmonics/w5.py +++ b/src/eko/harmonics/w5.py @@ -38,7 +38,7 @@ def S5(N): @nb.njit(cache=True) -def Sm5(N, S5, is_singlet): +def Sm5(N, hS5, is_singlet): r""" Analytic continuation of harmonic sum :math:`S_{-5}(N)`. @@ -49,7 +49,7 @@ def Sm5(N, S5, is_singlet): ---------- N : complex Mellin moment - S5: complex + hS5: complex Harmonic sum :math:`S_{5}(N)` is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), @@ -65,8 +65,8 @@ def Sm5(N, S5, is_singlet): eko.harmonic.w5.S5 : :math:`S_5(N)` """ if is_singlet: - return S5(N / 2) - 1 / 2**4 * S5 - return S5((N - 1) / 2) - 1 / 2**4 * S5 + return 1 / 2**4 * S5(N / 2) - hS5 + return 1 / 2**4 * S5((N - 1) / 2) - hS5 @nb.njit(cache=True) diff --git a/tests/eko/test_f_functions.py b/tests/eko/test_f_functions.py index 047649e95..269d59a2e 100644 --- a/tests/eko/test_f_functions.py +++ b/tests/eko/test_f_functions.py @@ -84,25 +84,28 @@ def test_F13(): def test_F12_F14(): # here there is a typo in eq (9.25) of Bl_mlein_2009 for N, vals in zip(testN, refvals["Sm221"]): + is_singlet = (-1) ** N == 1 S1 = harmonics.S1(N) S2 = harmonics.S2(N) - Sm1 = harmonics.Sm1(N) + Sm1 = harmonics.Sm1(N, S1, is_singlet) S21 = harmonics.S21(N, S1, S2) - Sm21 = harmonics.Sm21(N, S1, Sm1) + Sm21 = harmonics.Sm21(N, S1, Sm1, is_singlet) Sm221 = harmonics.Sm221(N, S1, Sm1, S21, Sm21) np.testing.assert_allclose(Sm221, vals, atol=1e-05) def test_F16(): for N, vals in zip(testN, refvals["S21m2"]): + is_singlet = (-1) ** N == 1 S1 = harmonics.S1(N) S2 = harmonics.S2(N) - Sm1 = harmonics.Sm1(N) - Sm2 = harmonics.Sm2(N) - Sm3 = harmonics.Sm3(N) + S3 = harmonics.S3(N) + Sm1 = harmonics.Sm1(N, S1, is_singlet) + Sm2 = harmonics.Sm2(N, S2, is_singlet) + Sm3 = harmonics.Sm3(N, S3, is_singlet) S21 = harmonics.S21(N, S1, S2) - S2m1 = harmonics.S2m1(N, S2, Sm1, Sm2) - Sm21 = harmonics.Sm21(N, S1, Sm1) + S2m1 = harmonics.S2m1(N, S2, Sm1, Sm2, is_singlet) + Sm21 = harmonics.Sm21(N, S1, Sm1, is_singlet) S21m2 = harmonics.S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1) np.testing.assert_allclose(S21m2, vals, atol=1e-04) @@ -118,10 +121,11 @@ def test_F17(): def test_F18(): for N, vals in zip(testN, refvals["Sm2111"]): + is_singlet = (-1) ** N == 1 S1 = harmonics.S1(N) S2 = harmonics.S2(N) S3 = harmonics.S3(N) - Sm1 = harmonics.Sm1(N) + Sm1 = harmonics.Sm1(N, S1, is_singlet) Sm2111 = harmonics.Sm2111(N, S1, S2, S3, Sm1) np.testing.assert_allclose(Sm2111, vals, atol=1e-05) @@ -139,19 +143,26 @@ def test_F19(): # different parametrization, less accurate def test_F20(): for N, vals in zip(testN, refvals["Sm23"]): - Sm3 = harmonics.Sm3(N) - Sm2 = harmonics.Sm2(N) - Sm1 = harmonics.Sm1(N) - Sm23 = harmonics.Sm23(N, Sm1, Sm2, Sm3) + is_singlet = (-1) ** N == 1 + S1 = harmonics.S1(N) + S2 = harmonics.S2(N) + S3 = harmonics.S3(N) + Sm3 = harmonics.Sm3(N, S3, is_singlet) + Sm2 = harmonics.Sm2(N, S2, is_singlet) + Sm1 = harmonics.Sm1(N, S1, is_singlet) + Sm23 = harmonics.Sm23(N, Sm1, Sm2, Sm3, is_singlet) np.testing.assert_allclose(Sm23, vals, rtol=1e-03) # different parametrization, less accurate def test_F21(): for N, vals in zip(testN, refvals["S2m3"]): - Sm3 = harmonics.Sm3(N) - Sm2 = harmonics.Sm2(N) - Sm1 = harmonics.Sm1(N) + is_singlet = (-1) ** N == 1 + S1 = harmonics.S1(N) S2 = harmonics.S2(N) + S3 = harmonics.S3(N) + Sm3 = harmonics.Sm3(N, S3, is_singlet) + Sm2 = harmonics.Sm2(N, S2, is_singlet) + Sm1 = harmonics.Sm1(N, S1, is_singlet) S2m3 = harmonics.S2m3(N, S2, Sm1, Sm2, Sm3) np.testing.assert_allclose(S2m3, vals, rtol=1e-03) diff --git a/tests/eko/test_g_functions.py b/tests/eko/test_g_functions.py index 34d6ce9fd..2dc30729f 100644 --- a/tests/eko/test_g_functions.py +++ b/tests/eko/test_g_functions.py @@ -24,42 +24,48 @@ def test_g3(): def test_g4(): refvals = [-1, -1.34359, -1.40286] for N, vals in zip(testN, refvals): + is_singlet = (-1) ** N == 1 + S1 = h.S1(N) S2 = h.S2(N) - Sm1 = h.Sm1(N) - Sm2 = h.Sm2(N) - S2m1 = h.S2m1(N, S2, Sm1, Sm2) + Sm1 = h.Sm1(N, S1, is_singlet) + Sm2 = h.Sm2(N, S2, is_singlet) + S2m1 = h.S2m1(N, S2, Sm1, Sm2, is_singlet) np.testing.assert_allclose(S2m1, vals, atol=1e-05) def test_g6(): refvals = [-1, -0.857976, -0.859245] for N, vals in zip(testN, refvals): - Sm1 = h.Sm1(N) - Sm2 = h.Sm2(N) + is_singlet = (-1) ** N == 1 S1 = h.S1(N) - Sm31 = h.Sm31(N, S1, Sm1, Sm2) + S2 = h.S2(N) + Sm1 = h.Sm1(N, S1, is_singlet) + Sm2 = h.Sm2(N, S2, is_singlet) + Sm31 = h.Sm31(N, S1, Sm1, Sm2, is_singlet) np.testing.assert_allclose(Sm31, vals, atol=1e-05) def test_g5(): refvals = [-1, -0.777375, -0.784297] for N, vals in zip(testN, refvals): - Sm1 = h.Sm1(N) - Sm2 = h.Sm2(N) + is_singlet = (-1) ** N == 1 S1 = h.S1(N) S2 = h.S2(N) - Sm31 = h.Sm31(N, S1, Sm1, Sm2) - Sm22 = h.Sm22(N, S1, S2, Sm2, Sm31) + Sm1 = h.Sm1(N, S1, is_singlet) + Sm2 = h.Sm2(N, S2, is_singlet) + Sm31 = h.Sm31(N, S1, Sm1, Sm2, is_singlet) + Sm22 = h.Sm22(N, S1, S2, Sm2, Sm31, is_singlet) np.testing.assert_allclose(Sm22, vals, atol=1e-05) def test_g8(): refvals = [-1, -0.696836, -0.719637] for N, vals in zip(testN, refvals): - Sm1 = h.Sm1(N) + is_singlet = (-1) ** N == 1 S1 = h.S1(N) S2 = h.S2(N) - Sm211 = h.Sm211(N, S1, S2, Sm1) + Sm1 = h.Sm1(N, S1, is_singlet) + Sm211 = h.Sm211(N, S1, S2, Sm1, is_singlet) np.testing.assert_allclose(Sm211, vals, atol=1e-05) @@ -76,9 +82,10 @@ def test_g18(): def test_g19(): refvals = [1, 0.953673, 0.958928] for N, vals in zip(testN, refvals): + is_singlet = (-1) ** N == 1 S1 = h.S1(N) S2 = h.S2(N) - Sm2 = h.Sm2(N) + Sm2 = h.Sm2(N, S2, is_singlet) Sm2m1 = h.Sm2m1(N, S1, S2, Sm2) np.testing.assert_allclose(Sm2m1, vals, atol=1e-05) diff --git a/tests/eko/test_harmonics.py b/tests/eko/test_harmonics.py index 854c98092..3b565f5ab 100644 --- a/tests/eko/test_harmonics.py +++ b/tests/eko/test_harmonics.py @@ -7,55 +7,118 @@ def test_spm1(): for k in range(1, 5 + 1): f = np.sum([1.0 / j for j in range(1, k + 1)]) - np.testing.assert_allclose(f, h.w1.S1(k)) + S1 = h.w1.S1(k) + np.testing.assert_allclose(f, S1) g = np.sum([(-1.0) ** j / j for j in range(1, k + 1)]) - np.testing.assert_allclose(g, h.w1.Sm1(k)) + np.testing.assert_allclose(g, h.w1.Sm1(k, S1, (-1) ** k == 1)) def test_spm2(): for k in range(1, 5 + 1): f = np.sum([1.0 / j**2 for j in range(1, k + 1)]) - np.testing.assert_allclose(f, h.w2.S2(k)) + S2 = h.w2.S2(k) + np.testing.assert_allclose(f, S2) g = np.sum([(-1.0) ** j / j**2 for j in range(1, k + 1)]) - np.testing.assert_allclose(g, h.w2.Sm2(k)) + np.testing.assert_allclose(g, h.w2.Sm2(k, S2, (-1) ** k == 1)) def test_harmonics_cache(): N = np.random.rand() + 1.0j * np.random.rand() - Sm1 = h.Sm1(N) - Sm2 = h.Sm2(N) + is_singlet = (-1) ** N == 1 S1 = h.S1(N) S2 = h.S2(N) S3 = h.S3(N) S4 = h.S4(N) - sx = np.array([S1, S2, S3, S4, h.S5(N)]) + S5 = h.S5(N) + Sm1 = h.Sm1(N, S1, is_singlet) + Sm2 = h.Sm2(N, S2, is_singlet) + sx = np.array([S1, S2, S3, S4, S5]) smx_test = np.array( [ Sm1, Sm2, - h.Sm3(N), - h.Sm4(N), - h.Sm5(N), + h.Sm3(N, S3, is_singlet), + h.Sm4(N, S4, is_singlet), + h.Sm5(N, S5, is_singlet), ] ) - np.testing.assert_allclose(h.smx(N), smx_test) + np.testing.assert_allclose(h.smx(N, sx, is_singlet), smx_test) s3x_test = np.array( [ h.S21(N, S1, S2), - h.S2m1(N, S2, Sm1, Sm2), - h.Sm21(N, S1, Sm1), + h.S2m1(N, S2, Sm1, Sm2, is_singlet), + h.Sm21(N, S1, Sm1, is_singlet), h.Sm2m1(N, S1, S2, Sm2), ] ) - np.testing.assert_allclose(h.s3x(N, sx, smx_test), s3x_test) - Sm31 = h.Sm31(N, S1, Sm1, Sm2) + np.testing.assert_allclose(h.s3x(N, sx, smx_test, is_singlet), s3x_test) + Sm31 = h.Sm31(N, S1, Sm1, Sm2, is_singlet) s4x_test = np.array( [ h.S31(N, S1, S2, S3, S4), h.S211(N, S1, S2, S3), - h.Sm22(N, S1, S2, Sm2, Sm31), - h.Sm211(N, S1, S2, Sm1), + h.Sm22(N, S1, S2, Sm2, Sm31, is_singlet), + h.Sm211(N, S1, S2, Sm1, is_singlet), Sm31, ] ) - np.testing.assert_allclose(h.s4x(N, sx, smx_test), s4x_test) + np.testing.assert_allclose(h.s4x(N, sx, smx_test, is_singlet), s4x_test) + + +# reference values coming fom mathematica +testN = [1, 2, 2 + 2j, 10 + 5j, 100] +refvals = { + "Sm1": [-1.0, -0.5, -0.692917 - 0.000175788j, -0.693147 - 2.77406e-9j, -0.688172], + "Sm2": [ + -1.0, + -0.75, + -0.822442 - 0.0000853585j, + -0.822467 - 4.29516e-10j, + -0.822418, + ], + "Sm3": [ + -1.0, + -0.875, + -0.901551 - 0.0000255879j, + -0.901543 - 4.61382e-11j, + -0.901542, + ], + "Sm4": [ + -1.0, + -0.9375, + -0.947039 - 4.84597e-6j, + -0.947033 - 3.99567e-12j, + -0.947033, + ], + "Sm5": [-1.0, -0.96875, -0.972122 - 1.13162e-7j, -0.97212 - 2.81097e-13j, -0.97212], + "Sm21": [ + -1.0, + -0.625, + -0.751192 - 0.000147181j, + -0.751286 - 1.17067e-9j, + -0.751029, + ], +} + + +def test_Sm21(): + for N, vals in zip(testN, refvals["Sm21"]): + is_singlet = (-1) ** N == 1 + S1 = h.S1(N) + Sm1 = h.Sm1(N, S1, is_singlet) + np.testing.assert_allclose(h.Sm21(N, S1, Sm1, is_singlet), vals, atol=1e-06) + + +def test_Smx(): + for j, N in enumerate(testN): + is_singlet = (-1) ** N == 1 + sx = h.sx(N) + smx = [ + h.Sm1(N, sx[0], is_singlet), + h.Sm2(N, sx[1], is_singlet), + h.Sm3(N, sx[2], is_singlet), + h.Sm4(N, sx[3], is_singlet), + h.Sm5(N, sx[4], is_singlet), + ] + for i, sm in enumerate(smx): + np.testing.assert_allclose(sm, refvals[f"Sm{i+1}"][j], atol=1e-06) diff --git a/tests/eko/test_matching_n3lo.py b/tests/eko/test_matching_n3lo.py index 4c582ec28..b64654bb6 100644 --- a/tests/eko/test_matching_n3lo.py +++ b/tests/eko/test_matching_n3lo.py @@ -13,8 +13,8 @@ def test_A_3(): for L in logs: N = 1.0 - sx_cache = compute_harmonics_cache(N, 3) - aNSqq3 = A_qqNS(N, sx_cache, nf, L) + sx_cache = compute_harmonics_cache(N, 3, False) + aNSqq3 = A_qqNS(N, sx_cache, nf, L, False) # quark number conservation # the accuracy of this test depends directly on the precision of the # F functions, thus is dominated by F19,F20,F21 accuracy are the worst ones @@ -22,7 +22,7 @@ def test_A_3(): np.testing.assert_allclose(aNSqq3, 0.0, atol=5e-3) N = 2.0 - sx_cache = compute_harmonics_cache(N, 3) + sx_cache = compute_harmonics_cache(N, 3, True) # reference value comes form Mathematica, gg is not fullycomplete # thus the reference value is not 0.0 # Here the accuracy of this test depends on the approximation of AggTF2 @@ -37,7 +37,7 @@ def test_A_3(): # here you get division by 0 as in Mathematica # np.testing.assert_allclose( # n3lo.A_gq(N, sx_cache, nf,L) - # + n3lo.A_qqNS(N, sx_cache, nf,L) + # + n3lo.A_qqNS(N, sx_cache, nf,L, True) # + n3lo.A_qqPS(N, sx, nf,L) # + n3lo.A_Hq(N, sx_cache, nf,L), # 0.0, @@ -52,7 +52,7 @@ def test_A_3(): # np.testing.assert_allclose(aS3[0, 1] + aS3[1, 1] + aS3[2, 1], 0.0, atol=1e-11) N = 3 + 2j - sx_cache = compute_harmonics_cache(np.random.rand(), 3) + sx_cache = compute_harmonics_cache(np.random.rand(), 3, (-1) ** N == 1) aS3 = A_singlet(N, sx_cache, nf, L) aNS3 = A_ns(N, sx_cache, nf, L) assert aNS3.shape == (2, 2) @@ -135,7 +135,7 @@ def test_Blumlein_3(): for i, N in enumerate([4.0, 6.0, 10.0, 100.0]): idx = i + 1 for L in [0, 10]: - sx_cache = compute_harmonics_cache(N, 3) + sx_cache = compute_harmonics_cache(N, 3, True) aS3 = A_singlet(N, sx_cache, nf, L) # here we have a different approximation for AggTF2, @@ -167,7 +167,7 @@ def test_Blumlein_3(): nf = 3 ref_ggTF_app = [-28.9075, -180.659, -229.537, -281.337, -467.164] for idx, N in enumerate([2.0, 4.0, 6.0, 10.0, 100.0]): - sx_cache = compute_harmonics_cache(N, 3) + sx_cache = compute_harmonics_cache(N, 3, True) Aggtf2 = as3.aggTF2.A_ggTF2(N, sx_cache) if N != 100: # Limited in the small N region @@ -184,9 +184,9 @@ def test_Blumlein_3(): # Limited accuracy due to F functions ref_qqNS_odd = [-40.94998646588999, -21.598793547423504, 6.966325573931755] for N, ref in zip([3.0, 15.0, 101.0], ref_qqNS_odd): - sx_cache = compute_harmonics_cache(N, 3) + sx_cache = compute_harmonics_cache(N, 3, False) np.testing.assert_allclose( - as3.aqqNS.A_qqNS(N, sx_cache, nf, L=0), ref, rtol=3e-2 + as3.aqqNS.A_qqNS(N, sx_cache, nf, L=0, is_singlet=False), ref, rtol=3e-2 ) @@ -234,7 +234,7 @@ def test_AHq_asymptotic(): # Ns = [31.,32.,33.,34.,35.,36.,37.,38.,39.] nf = 3 for N, r in zip(Ns, refs): - sx_cache = compute_harmonics_cache(N, 3) + sx_cache = compute_harmonics_cache(N, 3, True) np.testing.assert_allclose( as3.aHq.A_Hq(N, sx_cache, nf, L=0), r, rtol=1e-5, atol=1e-5 ) diff --git a/tests/eko/test_matching_nlo.py b/tests/eko/test_matching_nlo.py index d20d2c1bc..bf99faf3f 100644 --- a/tests/eko/test_matching_nlo.py +++ b/tests/eko/test_matching_nlo.py @@ -10,7 +10,7 @@ def test_A_1_intrinsic(): L = 100.0 N = 2 - sx = compute_harmonics_cache(N, 1) + sx = compute_harmonics_cache(N, 1, True) aS1 = A_singlet(N, sx, L) # heavy quark momentum conservation np.testing.assert_allclose(aS1[0, 2] + aS1[1, 2] + aS1[2, 2], 0.0, atol=1e-10) @@ -23,7 +23,7 @@ def test_A_1_shape(): N = 2 L = 3.0 - sx = compute_harmonics_cache(N, 1) + sx = compute_harmonics_cache(N, 1, (-1) ** N == 1) aNS1i = A_ns(N, sx, L) aS1i = A_singlet(N, sx, L) @@ -47,7 +47,7 @@ def test_Blumlein_1(): for n in range(N_vals): N = 2 * n + 2 - sx = compute_harmonics_cache(N, 1) + sx = compute_harmonics_cache(N, 1, True) for L, ref_gg in ref_val_gg.items(): aS1 = A_singlet(N, sx, L) np.testing.assert_allclose(aS1[0, 0], ref_gg[n], rtol=1e-6) diff --git a/tests/eko/test_matching_nnlo.py b/tests/eko/test_matching_nnlo.py index ce5dee2a4..90e373ae7 100644 --- a/tests/eko/test_matching_nnlo.py +++ b/tests/eko/test_matching_nnlo.py @@ -13,13 +13,13 @@ def test_A_2(): for L in logs: N = 1 - sx = compute_harmonics_cache(N, 2) + sx = compute_harmonics_cache(N, 2, False) aNSqq2 = A_qq_ns(N, sx, L) # quark number conservation np.testing.assert_allclose(aNSqq2, 0.0, atol=2e-11) N = 2 - sx = compute_harmonics_cache(N, 2) + sx = compute_harmonics_cache(N, 2, True) aS2 = A_singlet(N, sx, L) # gluon momentum conservation @@ -39,7 +39,7 @@ def test_A_2(): def test_A_2_shape(): N = np.random.rand() L = 3 - sx = compute_harmonics_cache(N, 2) + sx = compute_harmonics_cache(N, 2, (-1) ** N == 1) aNS2 = A_ns(N, sx, L) aS2 = A_singlet(N, sx, L) @@ -55,7 +55,7 @@ def test_pegasus_sign(): # reference value come from Pegasus code transalted Mathematica ref_val = -21133.9 N = 2 - sx = compute_harmonics_cache(N, 2) + sx = compute_harmonics_cache(N, 2, True) L = 100.0 aS2 = A_singlet(N, sx, L) @@ -120,7 +120,7 @@ def test_Blumlein_2(): } for N in range(2, 11): for L, ref_Hg in ref_val_Hg.items(): - sx = compute_harmonics_cache(N, 2) + sx = compute_harmonics_cache(N, 2, True) aS2 = A_singlet(N, sx, L) if N % 2 == 0: idx = int(N / 2 - 1) @@ -138,7 +138,7 @@ def test_Hg2_pegasus(): L = 0 for N in range(3, 20): - sx = compute_harmonics_cache(N, 2) + sx = compute_harmonics_cache(N, 2, True) S1 = sx[0][0] S2 = sx[1][0] S3 = sx[2][0] @@ -162,7 +162,7 @@ def test_Hg2_pegasus(): - 146.8 * E2 ) - np.testing.assert_allclose(aS2[2, 0], a_hg_param, rtol=9e-4) + np.testing.assert_allclose(aS2[2, 0], a_hg_param, rtol=7e-4) def test_msbar_matching(): @@ -170,7 +170,7 @@ def test_msbar_matching(): for L in logs: N = 2 - sx = compute_harmonics_cache(N, 2) + sx = compute_harmonics_cache(N, 2, True) aS2 = A_singlet(N, sx, L, True) # gluon momentum conservation np.testing.assert_allclose(aS2[0, 0] + aS2[1, 0] + aS2[2, 0], 0.0, atol=2e-6) diff --git a/tests/eko/test_ome.py b/tests/eko/test_ome.py index 50569dd8e..e6282d45c 100644 --- a/tests/eko/test_ome.py +++ b/tests/eko/test_ome.py @@ -30,7 +30,7 @@ def test_build_ome_as(): for o in [1, 2, 3]: if o == 3: N = complex(2.123) - sx = compute_harmonics_cache(N, o) + sx = compute_harmonics_cache(N, o, (-1) ** N == 1) aNS = A_non_singlet(o, N, sx, nf, L) aS = A_singlet(o, N, sx, nf, L, is_msbar) diff --git a/tests/eko/test_s_functions.py b/tests/eko/test_s_functions.py deleted file mode 100644 index c8ec5ae59..000000000 --- a/tests/eko/test_s_functions.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8 -*- -# Test some harmonics - -import numpy as np - -import eko.harmonics as sf - -# reference values coming fom mathematica -testN = [1, 2, 2 + 2j, 10 + 5j, 100] -refvals = { - "Sm1": [-1.0, -0.5, -0.692917 - 0.000175788j, -0.693147 - 2.77406e-9j, -0.688172], - "Sm2": [ - -1.0, - -0.75, - -0.822442 - 0.0000853585j, - -0.822467 - 4.29516e-10j, - -0.822418, - ], - "Sm3": [ - -1.0, - -0.875, - -0.901551 - 0.0000255879j, - -0.901543 - 4.61382e-11j, - -0.901542, - ], - "Sm4": [ - -1.0, - -0.9375, - -0.947039 - 4.84597e-6j, - -0.947033 - 3.99567e-12j, - -0.947033, - ], - "Sm5": [-1.0, -0.96875, -0.972122 - 1.13162e-7j, -0.97212 - 2.81097e-13j, -0.97212], - "Sm21": [ - -1.0, - -0.625, - -0.751192 - 0.000147181j, - -0.751286 - 1.17067e-9j, - -0.751029, - ], -} - - -def test_Sm21(): - for N, vals in zip(testN, refvals["Sm21"]): - Sm1 = sf.Sm1(N) - S1 = sf.S1(N) - np.testing.assert_allclose(sf.Sm21(N, S1, Sm1), vals, atol=1e-06) - - -def test_Smx(): - for j, N in enumerate(testN): - smx = [ - sf.Sm1(N), - sf.Sm2(N), - sf.Sm3(N), - sf.Sm4(N), - sf.Sm5(N), - ] - for i, sm in enumerate(smx): - np.testing.assert_allclose(sm, refvals[f"Sm{i+1}"][j], atol=1e-06) - - -def test_Sx(): - """test harmonic sums S_x on real axis""" - # test on real axis - def sx(n, m): - return np.sum([1 / k**m for k in range(1, n + 1)]) - - ls = [ - sf.S1, - sf.S2, - sf.S3, - sf.S4, - sf.S5, - ] - for k in range(1, 5 + 1): - for n in range(1, 4 + 1): - np.testing.assert_almost_equal(ls[k - 1](n), sx(n, k)) From f76f97c1c1cdef7bc68c3409c5f7a4b80b5218db Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Tue, 5 Apr 2022 23:33:38 +0200 Subject: [PATCH 39/47] Allow for generic complex S minus harmonics --- src/eko/harmonics/polygamma.py | 28 +++++++++++++++++++++++++++ src/eko/harmonics/w1.py | 11 ++++++++--- src/eko/harmonics/w2.py | 11 +++++++++-- src/eko/harmonics/w3.py | 25 +++++++++++++++--------- src/eko/harmonics/w4.py | 31 ++++++++++++++++++------------ src/eko/harmonics/w5.py | 19 ++++++++++++------ tests/eko/test_f_functions.py | 35 +++++++++++++++------------------- tests/eko/test_harmonics.py | 24 +++++++++++------------ 8 files changed, 119 insertions(+), 65 deletions(-) diff --git a/src/eko/harmonics/polygamma.py b/src/eko/harmonics/polygamma.py index 03d877150..9f61240ae 100644 --- a/src/eko/harmonics/polygamma.py +++ b/src/eko/harmonics/polygamma.py @@ -152,3 +152,31 @@ def recursive_harmonic_sum(base_value, n, iterations, weight): for i in range(1, iterations + 1): fact += 1.0 / (n + i) ** weight return base_value + fact + + +@nb.njit(cache=True) +def symmetry_factor(N, is_singlet=None): + """ + Compute the analytical continuation of :math:`(-1)^N` + + Parameters + ---------- + N: complex + Mellin moment + is_singlet: bool, None + True for singlet like quantities + False for non singlet like quantities + None for generic complex N value + + Retruns + ------- + eta: complex + 1 for singlet like quantities, + -1 for non singlet like quantities, + :math:`(-1)^N` elsewise + """ + if is_singlet is None: + return (-1) ** N + if is_singlet: + return 1 + return -1 diff --git a/src/eko/harmonics/w1.py b/src/eko/harmonics/w1.py index 55f3558c0..88afee8d3 100644 --- a/src/eko/harmonics/w1.py +++ b/src/eko/harmonics/w1.py @@ -5,7 +5,6 @@ import numba as nb import numpy as np -from .constants import log2 from .polygamma import cern_polygamma @@ -38,7 +37,7 @@ def S1(N): @nb.njit(cache=True) -def Sm1(N, hS1, is_singlet): +def Sm1(N, hS1, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-1}(N)`. @@ -51,7 +50,7 @@ def Sm1(N, hS1, is_singlet): Mellin moment hS1: complex Harmonic sum :math:`S_{1}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns @@ -63,6 +62,12 @@ def Sm1(N, hS1, is_singlet): -------- eko.anomalous_dimension.w1.S1 : :math:`S_1(N)` """ + if is_singlet is None: + return ( + -((-1) ** N - 1) / 2 * S1((N - 1) / 2) + + ((-1) ** N + 1) / 2 * S1(N / 2) + - hS1 + ) if is_singlet: return S1(N / 2) - hS1 return S1((N - 1) / 2) - hS1 diff --git a/src/eko/harmonics/w2.py b/src/eko/harmonics/w2.py index 878c14ca0..a79fe6d83 100644 --- a/src/eko/harmonics/w2.py +++ b/src/eko/harmonics/w2.py @@ -37,7 +37,7 @@ def S2(N): @nb.njit(cache=True) -def Sm2(N, hS2, is_singlet): +def Sm2(N, hS2, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-2}(N)`. @@ -50,7 +50,7 @@ def Sm2(N, hS2, is_singlet): Mellin moment hS2: complex Harmonic sum :math:`S_{2}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) @@ -63,6 +63,13 @@ def Sm2(N, hS2, is_singlet): -------- eko.anomalous_dimension.w2.S2 : :math:`S_2(N)` """ + if is_singlet is None: + return ( + 1 + / 2 + * (-((-1) ** N - 1) / 2 * S2((N - 1) / 2) + ((-1) ** N + 1) / 2 * S2(N / 2)) + - hS2 + ) if is_singlet: return 1 / 2 * S2(N / 2) - hS2 return 1 / 2 * S2((N - 1) / 2) - hS2 diff --git a/src/eko/harmonics/w3.py b/src/eko/harmonics/w3.py index 8647f2326..0f1689fdd 100644 --- a/src/eko/harmonics/w3.py +++ b/src/eko/harmonics/w3.py @@ -6,7 +6,7 @@ from . import g_functions as gf from .constants import log2, zeta2, zeta3 -from .polygamma import cern_polygamma +from .polygamma import cern_polygamma, symmetry_factor @nb.njit(cache=True) @@ -38,7 +38,7 @@ def S3(N): @nb.njit(cache=True) -def Sm3(N, hS3, is_singlet): +def Sm3(N, hS3, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-3}(N)`. @@ -51,7 +51,7 @@ def Sm3(N, hS3, is_singlet): Mellin moment hS3: complex Harmonic sum :math:`S_{3}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) @@ -64,6 +64,13 @@ def Sm3(N, hS3, is_singlet): -------- eko.harmonics.w3.S3 : :math:`S_3(N)` """ + if is_singlet is None: + return ( + 1 + / 2**2 + * (-((-1) ** N - 1) / 2 * S3((N - 1) / 2) + ((-1) ** N + 1) / 2 * S3(N / 2)) + - hS3 + ) if is_singlet: return 1 / 2**2 * S3(N / 2) - hS3 return 1 / 2**2 * S3((N - 1) / 2) - hS3 @@ -97,7 +104,7 @@ def S21(N, S1, S2): @nb.njit(cache=True) -def Sm21(N, S1, Sm1, is_singlet): +def Sm21(N, S1, Sm1, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-2,1}(N)` as implemented in eq B.5.75 of :cite:`MuselliPhD` and eq 22 of :cite:`Bl_mlein_2000`. @@ -110,7 +117,7 @@ def Sm21(N, S1, Sm1, is_singlet): Harmonic sum :math:`S_{1}(N)` Sm1: complex Harmonic sum :math:`S_{-1}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) @@ -124,7 +131,7 @@ def Sm21(N, S1, Sm1, is_singlet): eko.harmonics.g_functions : :math:`g_3(N)` """ # Note mellin g3 was integrated following x^(N-1) convention. - eta = 1 if is_singlet else -1 + eta = symmetry_factor(N, is_singlet) return ( -eta * gf.mellin_g3(N + 1, S1 + 1 / (N + 1)) + zeta2 * Sm1 @@ -134,7 +141,7 @@ def Sm21(N, S1, Sm1, is_singlet): @nb.njit(cache=True) -def S2m1(N, S2, Sm1, Sm2, is_singlet): +def S2m1(N, S2, Sm1, Sm2, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{2,-1}(N)` as implemented in eq B.5.76 of :cite:`MuselliPhD` and eq 23 of :cite:`Bl_mlein_2000`. @@ -149,7 +156,7 @@ def S2m1(N, S2, Sm1, Sm2, is_singlet): Harmonic sum :math:`S_{-1}(N)` Sm2: complex Harmonic sum :math:`S_{-2}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) @@ -162,7 +169,7 @@ def S2m1(N, S2, Sm1, Sm2, is_singlet): -------- eko.harmonics.g_functions.mellin_g4 : :math:`g_4(N)` """ - eta = 1 if is_singlet else -1 + eta = symmetry_factor(N, is_singlet) return ( -eta * gf.mellin_g4(N) - log2 * (S2 - Sm2) diff --git a/src/eko/harmonics/w4.py b/src/eko/harmonics/w4.py index 7e4bd7e73..48567d3f7 100644 --- a/src/eko/harmonics/w4.py +++ b/src/eko/harmonics/w4.py @@ -6,7 +6,7 @@ from . import g_functions as gf from .constants import li4half, log2, zeta2, zeta3, zeta4 -from .polygamma import cern_polygamma +from .polygamma import cern_polygamma, symmetry_factor @nb.njit(cache=True) @@ -38,7 +38,7 @@ def S4(N): @nb.njit(cache=True) -def Sm4(N, hS4, is_singlet): +def Sm4(N, hS4, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-4}(N)`. @@ -51,7 +51,7 @@ def Sm4(N, hS4, is_singlet): Mellin moment hS4: complex Harmonic sum :math:`S_{4}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) @@ -64,13 +64,20 @@ def Sm4(N, hS4, is_singlet): -------- eko.anomalous_dimension.w4.S4 : :math:`S_4(N)` """ + if is_singlet is None: + return ( + 1 + / 2**3 + * (-((-1) ** N - 1) / 2 * S4((N - 1) / 2) + ((-1) ** N + 1) / 2 * S4(N / 2)) + - hS4 + ) if is_singlet: return 1 / 2**3 * S4(N / 2) - hS4 return 1 / 2**3 * S4((N - 1) / 2) - hS4 @nb.njit(cache=True) -def Sm31(N, S1, Sm1, Sm2, is_singlet): +def Sm31(N, S1, Sm1, Sm2, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-3,1}(N)` as implemented in eq B.5.93 of :cite:`MuselliPhD` and eq 25 of cite:`Bl_mlein_2000`. @@ -85,7 +92,7 @@ def Sm31(N, S1, Sm1, Sm2, is_singlet): Harmonic sum :math:`S_{-1}(N)` Sm2: complex Harmonic sum :math:`S_{-2}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) @@ -98,7 +105,7 @@ def Sm31(N, S1, Sm1, Sm2, is_singlet): -------- eko.harmonics.g_functions.mellin_g6 : :math:`g_6(N)` """ - eta = 1 if is_singlet else -1 + eta = symmetry_factor(N, is_singlet) return ( eta * gf.mellin_g6(N, S1) + zeta2 * Sm2 @@ -112,7 +119,7 @@ def Sm31(N, S1, Sm1, Sm2, is_singlet): @nb.njit(cache=True) -def Sm22(N, S1, S2, Sm2, Sm31, is_singlet): +def Sm22(N, S1, S2, Sm2, Sm31, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-2,2}(N)` as implemented in eq B.5.94 of :cite:`MuselliPhD` and eq 24 of cite:`Bl_mlein_2000`. @@ -129,7 +136,7 @@ def Sm22(N, S1, S2, Sm2, Sm31, is_singlet): Harmonic sum :math:`S_{-2}(N)` Sm31: complex Harmonic sum :math:`S_{-3,1}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns @@ -141,14 +148,14 @@ def Sm22(N, S1, S2, Sm2, Sm31, is_singlet): -------- eko.harmonics.g_functions.mellin_g5 : :math:`g_5(N)` """ - eta = 1 if is_singlet else -1 + eta = symmetry_factor(N, is_singlet) return ( eta * gf.mellin_g5(N, S1, S2) - 2 * Sm31 + 2 * zeta2 * Sm2 + 3 / 40 * zeta2**2 ) @nb.njit(cache=True) -def Sm211(N, S1, S2, Sm1, is_singlet): +def Sm211(N, S1, S2, Sm1, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-2,1,1}(N)` as implemented in eq B.5.104 of :cite:`MuselliPhD` and eq 27 of cite:`Bl_mlein_2000`. @@ -163,7 +170,7 @@ def Sm211(N, S1, S2, Sm1, is_singlet): Harmonic sum :math:`S_{2}(N)` Sm1: complex Harmonic sum :math:`S_{-1}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) @@ -176,7 +183,7 @@ def Sm211(N, S1, S2, Sm1, is_singlet): -------- eko.harmonics.g_functions.mellin_g8 : :math:`g_8(N)` """ - eta = 1 if is_singlet else -1 + eta = symmetry_factor(N, is_singlet) return ( -eta * gf.mellin_g8(N, S1, S2) + zeta3 * Sm1 diff --git a/src/eko/harmonics/w5.py b/src/eko/harmonics/w5.py index 0a275881f..9acc9095f 100644 --- a/src/eko/harmonics/w5.py +++ b/src/eko/harmonics/w5.py @@ -6,7 +6,7 @@ from . import f_functions as f from .constants import log2, zeta2, zeta3, zeta4, zeta5 -from .polygamma import cern_polygamma +from .polygamma import cern_polygamma, symmetry_factor @nb.njit(cache=True) @@ -38,7 +38,7 @@ def S5(N): @nb.njit(cache=True) -def Sm5(N, hS5, is_singlet): +def Sm5(N, hS5, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-5}(N)`. @@ -51,7 +51,7 @@ def Sm5(N, hS5, is_singlet): Mellin moment hS5: complex Harmonic sum :math:`S_{5}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) @@ -64,6 +64,13 @@ def Sm5(N, hS5, is_singlet): -------- eko.harmonic.w5.S5 : :math:`S_5(N)` """ + if is_singlet is None: + return ( + 1 + / 2**4 + * (-((-1) ** N - 1) / 2 * S5((N - 1) / 2) + ((-1) ** N + 1) / 2 * S5(N / 2)) + - hS5 + ) if is_singlet: return 1 / 2**4 * S5(N / 2) - hS5 return 1 / 2**4 * S5((N - 1) / 2) - hS5 @@ -352,7 +359,7 @@ def S23(N, S1, S2, S3): @nb.njit(cache=True) -def Sm23(N, Sm1, Sm2, Sm3, is_singlet): +def Sm23(N, Sm1, Sm2, Sm3, is_singlet=None): r""" Analytic continuation of harmonic sum :math:`S_{-2,3}(N)` as implemented in eq 9.4 of :cite:`Blumlein:2009ta` @@ -367,7 +374,7 @@ def Sm23(N, Sm1, Sm2, Sm3, is_singlet): Harmonic sum :math:`S_{-2}(N)` Sm3: complex Harmonic sum :math:`S_{-3}(N)` - is_singlet: bool + is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) @@ -385,7 +392,7 @@ def Sm23(N, Sm1, Sm2, Sm3, is_singlet): +3 [\text{S}_{1,3}(1-x) - \zeta_4] /(x+1)](N)` """ - eta = 1 if is_singlet else -1 + eta = symmetry_factor(N, is_singlet) return ( eta * f.F20(N, Sm1, Sm2, Sm3) + 3 * zeta4 * Sm1 diff --git a/tests/eko/test_f_functions.py b/tests/eko/test_f_functions.py index 269d59a2e..b7ee8e14c 100644 --- a/tests/eko/test_f_functions.py +++ b/tests/eko/test_f_functions.py @@ -84,28 +84,26 @@ def test_F13(): def test_F12_F14(): # here there is a typo in eq (9.25) of Bl_mlein_2009 for N, vals in zip(testN, refvals["Sm221"]): - is_singlet = (-1) ** N == 1 S1 = harmonics.S1(N) S2 = harmonics.S2(N) - Sm1 = harmonics.Sm1(N, S1, is_singlet) + Sm1 = harmonics.Sm1(N, S1) S21 = harmonics.S21(N, S1, S2) - Sm21 = harmonics.Sm21(N, S1, Sm1, is_singlet) + Sm21 = harmonics.Sm21(N, S1, Sm1) Sm221 = harmonics.Sm221(N, S1, Sm1, S21, Sm21) np.testing.assert_allclose(Sm221, vals, atol=1e-05) def test_F16(): for N, vals in zip(testN, refvals["S21m2"]): - is_singlet = (-1) ** N == 1 S1 = harmonics.S1(N) S2 = harmonics.S2(N) S3 = harmonics.S3(N) - Sm1 = harmonics.Sm1(N, S1, is_singlet) - Sm2 = harmonics.Sm2(N, S2, is_singlet) - Sm3 = harmonics.Sm3(N, S3, is_singlet) + Sm1 = harmonics.Sm1(N, S1) + Sm2 = harmonics.Sm2(N, S2) + Sm3 = harmonics.Sm3(N, S3) S21 = harmonics.S21(N, S1, S2) - S2m1 = harmonics.S2m1(N, S2, Sm1, Sm2, is_singlet) - Sm21 = harmonics.Sm21(N, S1, Sm1, is_singlet) + S2m1 = harmonics.S2m1(N, S2, Sm1, Sm2) + Sm21 = harmonics.Sm21(N, S1, Sm1) S21m2 = harmonics.S21m2(N, S1, S2, Sm1, Sm2, Sm3, S21, Sm21, S2m1) np.testing.assert_allclose(S21m2, vals, atol=1e-04) @@ -121,11 +119,10 @@ def test_F17(): def test_F18(): for N, vals in zip(testN, refvals["Sm2111"]): - is_singlet = (-1) ** N == 1 S1 = harmonics.S1(N) S2 = harmonics.S2(N) S3 = harmonics.S3(N) - Sm1 = harmonics.Sm1(N, S1, is_singlet) + Sm1 = harmonics.Sm1(N, S1) Sm2111 = harmonics.Sm2111(N, S1, S2, S3, Sm1) np.testing.assert_allclose(Sm2111, vals, atol=1e-05) @@ -143,26 +140,24 @@ def test_F19(): # different parametrization, less accurate def test_F20(): for N, vals in zip(testN, refvals["Sm23"]): - is_singlet = (-1) ** N == 1 S1 = harmonics.S1(N) S2 = harmonics.S2(N) S3 = harmonics.S3(N) - Sm3 = harmonics.Sm3(N, S3, is_singlet) - Sm2 = harmonics.Sm2(N, S2, is_singlet) - Sm1 = harmonics.Sm1(N, S1, is_singlet) - Sm23 = harmonics.Sm23(N, Sm1, Sm2, Sm3, is_singlet) + Sm3 = harmonics.Sm3(N, S3) + Sm2 = harmonics.Sm2(N, S2) + Sm1 = harmonics.Sm1(N, S1) + Sm23 = harmonics.Sm23(N, Sm1, Sm2, Sm3) np.testing.assert_allclose(Sm23, vals, rtol=1e-03) # different parametrization, less accurate def test_F21(): for N, vals in zip(testN, refvals["S2m3"]): - is_singlet = (-1) ** N == 1 S1 = harmonics.S1(N) S2 = harmonics.S2(N) S3 = harmonics.S3(N) - Sm3 = harmonics.Sm3(N, S3, is_singlet) - Sm2 = harmonics.Sm2(N, S2, is_singlet) - Sm1 = harmonics.Sm1(N, S1, is_singlet) + Sm3 = harmonics.Sm3(N, S3) + Sm2 = harmonics.Sm2(N, S2) + Sm1 = harmonics.Sm1(N, S1) S2m3 = harmonics.S2m3(N, S2, Sm1, Sm2, Sm3) np.testing.assert_allclose(S2m3, vals, rtol=1e-03) diff --git a/tests/eko/test_harmonics.py b/tests/eko/test_harmonics.py index 3b565f5ab..d8a03f4a4 100644 --- a/tests/eko/test_harmonics.py +++ b/tests/eko/test_harmonics.py @@ -7,19 +7,19 @@ def test_spm1(): for k in range(1, 5 + 1): f = np.sum([1.0 / j for j in range(1, k + 1)]) - S1 = h.w1.S1(k) + S1 = h.S1(k) np.testing.assert_allclose(f, S1) g = np.sum([(-1.0) ** j / j for j in range(1, k + 1)]) - np.testing.assert_allclose(g, h.w1.Sm1(k, S1, (-1) ** k == 1)) + np.testing.assert_allclose(g, h.Sm1(k, S1, (-1) ** k == 1)) def test_spm2(): for k in range(1, 5 + 1): f = np.sum([1.0 / j**2 for j in range(1, k + 1)]) - S2 = h.w2.S2(k) + S2 = h.S2(k) np.testing.assert_allclose(f, S2) g = np.sum([(-1.0) ** j / j**2 for j in range(1, k + 1)]) - np.testing.assert_allclose(g, h.w2.Sm2(k, S2, (-1) ** k == 1)) + np.testing.assert_allclose(g, h.Sm2(k, S2, (-1) ** k == 1)) def test_harmonics_cache(): @@ -103,22 +103,20 @@ def test_harmonics_cache(): def test_Sm21(): for N, vals in zip(testN, refvals["Sm21"]): - is_singlet = (-1) ** N == 1 S1 = h.S1(N) - Sm1 = h.Sm1(N, S1, is_singlet) - np.testing.assert_allclose(h.Sm21(N, S1, Sm1, is_singlet), vals, atol=1e-06) + Sm1 = h.Sm1(N, S1) + np.testing.assert_allclose(h.Sm21(N, S1, Sm1), vals, atol=1e-06) def test_Smx(): for j, N in enumerate(testN): - is_singlet = (-1) ** N == 1 sx = h.sx(N) smx = [ - h.Sm1(N, sx[0], is_singlet), - h.Sm2(N, sx[1], is_singlet), - h.Sm3(N, sx[2], is_singlet), - h.Sm4(N, sx[3], is_singlet), - h.Sm5(N, sx[4], is_singlet), + h.Sm1(N, sx[0]), + h.Sm2(N, sx[1]), + h.Sm3(N, sx[2]), + h.Sm4(N, sx[3]), + h.Sm5(N, sx[4]), ] for i, sm in enumerate(smx): np.testing.assert_allclose(sm, refvals[f"Sm{i+1}"][j], atol=1e-06) From fa9f688918f53195992f72b3c347fdb9f2a01990 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Tue, 5 Apr 2022 23:35:01 +0200 Subject: [PATCH 40/47] remove impossible odd moment test on ahq3 --- tests/eko/test_matching_n3lo.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/eko/test_matching_n3lo.py b/tests/eko/test_matching_n3lo.py index b64654bb6..48bfb8395 100644 --- a/tests/eko/test_matching_n3lo.py +++ b/tests/eko/test_matching_n3lo.py @@ -191,10 +191,14 @@ def test_Blumlein_3(): def test_AHq_asymptotic(): + # Odd moments can't be not tested, since in the + # reference values coming from mathematica, some + # harmonics still contains some (-1)**N factors which + # should be continued with 1, but this is not doable. refs = [ - -1.06712, + # -1.06712, 0.476901, - -0.771605, + # -0.771605, 0.388789, 0.228768, 0.114067, @@ -210,9 +214,9 @@ def test_AHq_asymptotic(): -0.000560666, ] Ns = [ - 11.0, + # 11.0, 12.0, - 13.0, + # 13.0, 14.0, 20.0, 30.0, From 510c741a778a23c80b3dce17c293d6d1cb2e46a2 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 6 Apr 2022 10:28:40 +0200 Subject: [PATCH 41/47] passing correct harmonics to as3.A_qqNS --- src/eko/harmonics/__init__.py | 2 +- src/eko/matching_conditions/as3/__init__.py | 26 ++++++++-------- src/eko/matching_conditions/as3/aqqNS.py | 7 ++--- .../operator_matrix_element.py | 30 ++++++++++++++++--- tests/eko/test_harmonics.py | 4 ++- tests/eko/test_matching_n3lo.py | 26 +++++++++------- tests/eko/test_ome.py | 12 ++++---- 7 files changed, 67 insertions(+), 40 deletions(-) diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index 00eebc8ae..c28802663 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -172,6 +172,6 @@ def s4x(n, sx, smx, is_singlet): S211(n, sx[0], sx[1], sx[2]), Sm22(n, sx[0], sx[1], smx[1], sm31, is_singlet), Sm211(n, sx[0], sx[1], smx[0], is_singlet), - Sm31(n, sx[0], smx[0], smx[1], is_singlet), + sm31, ] ) diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/eko/matching_conditions/as3/__init__.py index 9150141f0..e863cab56 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/eko/matching_conditions/as3/__init__.py @@ -37,7 +37,7 @@ @nb.njit(cache=True) -def A_singlet(n, sx_all, nf, L): +def A_singlet(n, sx_singlet, sx_non_singlet, nf, L): r""" Computes the |N3LO| singlet |OME|. @@ -55,8 +55,8 @@ def A_singlet(n, sx_all, nf, L): ---------- n : complex Mellin moment - sx_all : list - harmonic sums cache containing: + sx_singlet : list + singlet like harmonic sums cache containing: .. math :: [[S_1,S_{-1}], @@ -64,6 +64,8 @@ def A_singlet(n, sx_all, nf, L): [S_{3}, S_{2,1}, S_{2,-1}, S_{-2,1}, S_{-2,-1}, S_{-3}], [S_{4}, S_{3,1}, S_{2,1,1}, S_{-2,-2}, S_{-3, 1}, S_{-4}],] + sx_non_singlet: list + same as sx_singlet but now for non singlet like harmonics nf : int number of active flavor below the threshold L : float @@ -74,15 +76,15 @@ def A_singlet(n, sx_all, nf, L): A_S : numpy.ndarray |NNLO| singlet |OME| :math:`A^{S,(3)}(N)` """ - A_hq_3 = A_Hq(n, sx_all, nf, L) - A_hg_3 = A_Hg(n, sx_all, nf, L) + A_hq_3 = A_Hq(n, sx_singlet, nf, L) + A_hg_3 = A_Hg(n, sx_singlet, nf, L) - A_gq_3 = A_gq(n, sx_all, nf, L) - A_gg_3 = A_gg(n, sx_all, nf, L) + A_gq_3 = A_gq(n, sx_singlet, nf, L) + A_gg_3 = A_gg(n, sx_singlet, nf, L) - A_qq_ps_3 = A_qqPS(n, sx_all, nf, L) - A_qq_ns_3 = A_qqNS(n, sx_all, nf, L, True) - A_qg_3 = A_qg(n, sx_all, nf, L) + A_qq_ps_3 = A_qqPS(n, sx_singlet, nf, L) + A_qq_ns_3 = A_qqNS(n, sx_non_singlet, nf, L) + A_qg_3 = A_qg(n, sx_singlet, nf, L) A_S = np.array( [ @@ -136,6 +138,4 @@ def A_ns(n, sx_all, nf, L): -------- A_qqNS_3 : :math:`A_{qq,H}^{NS,(3))}` """ - return np.array( - [[A_qqNS(n, sx_all, nf, L, False), 0.0], [0 + 0j, 0 + 0j]], np.complex_ - ) + return np.array([[A_qqNS(n, sx_all, nf, L), 0.0], [0 + 0j, 0 + 0j]], np.complex_) diff --git a/src/eko/matching_conditions/as3/aqqNS.py b/src/eko/matching_conditions/as3/aqqNS.py index 7dedebd38..114949bd3 100644 --- a/src/eko/matching_conditions/as3/aqqNS.py +++ b/src/eko/matching_conditions/as3/aqqNS.py @@ -6,7 +6,7 @@ @nb.njit(cache=True) -def A_qqNS(n, sx, nf, L, is_singlet): # pylint: disable=too-many-locals +def A_qqNS(n, sx, nf, L): # pylint: disable=too-many-locals r""" Computes the |N3LO| singlet |OME| :math:`A_{qq}^{NS,(3)}(N)`. The experssion is presented in :cite:`Bierenbaum:2009mv` and @@ -25,9 +25,6 @@ def A_qqNS(n, sx, nf, L, is_singlet): # pylint: disable=too-many-locals number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` - is_singlet: bool - symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -47,7 +44,7 @@ def A_qqNS(n, sx, nf, L, is_singlet): # pylint: disable=too-many-locals S2111 = sf.S2111(n, S1, S2, S3) Sm2111 = sf.Sm2111(n, S1, S2, S3, Sm1) S23 = sf.S23(n, S1, S2, S3) - Sm23 = sf.Sm23(n, Sm1, Sm2, Sm3, is_singlet) + Sm23 = sf.Sm23(n, Sm1, Sm2, Sm3, False) S2m3 = sf.S2m3(n, S2, Sm1, Sm2, Sm3) a_qqNS_l0 = ( 0.3333333333333333 diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index dc6239d79..44dfcd982 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -64,7 +64,7 @@ def compute_harmonics_cache(n, order, is_singlet): @nb.njit(cache=True) -def A_singlet(order, n, sx, nf, L, is_msbar): +def A_singlet(order, n, sx, nf, L, is_msbar, sx_ns=None): r""" Computes the tower of the singlet |OME|. @@ -75,13 +75,15 @@ def A_singlet(order, n, sx, nf, L, is_msbar): n : complex Mellin variable sx : list - harmonic sums cache + singlet like harmonic sums cache nf: int number of active flavor below threshold L : float :math:`log(q^2/m_h^2)` is_msbar: bool add the |MSbar| contribution + sx_ns : list + non singlet like harmonic sums cache Returns ------- @@ -101,7 +103,7 @@ def A_singlet(order, n, sx, nf, L, is_msbar): if order >= 2: A_s[1] = as2.A_singlet(n, sx, L, is_msbar) if order >= 3: - A_s[2] = as3.A_singlet(n, sx, nf, L) + A_s[2] = as3.A_singlet(n, sx, sx_ns, nf, L) return A_s @@ -239,10 +241,30 @@ def quad_ker( return 0.0 sx = compute_harmonics_cache(ker_base.n, order, ker_base.is_singlet) + sx_ns = None + if order == 3 and ( + (backward_method != "" and ker_base.is_singlet) + or (mode0 == 100 and mode0 == 100) + ): + # At N3LO for A_qq singlet or backward you need to compute + # both the singlet and non singlet like harmonics + # avoiding recomputing all of them ... + sx_ns = sx.copy() + smx_ns = harmonics.smx(ker_base.n, np.array([s[0] for s in sx]), False) + for w, sm in enumerate(smx_ns): + sx_ns[w][-1] = sm + sx_ns[2][2] = harmonics.S2m1(ker_base.n, sx[0][1], smx_ns[0], smx_ns[1], False) + sx_ns[2][3] = harmonics.Sm21(ker_base.n, sx[0][0], smx_ns[0], False) + sx_ns[3][5] = harmonics.Sm31(ker_base.n, sx[0][0], smx_ns[0], smx_ns[1], False) + sx_ns[3][4] = harmonics.Sm211(ker_base.n, sx[0][0], sx[0][1], smx_ns[0], False) + sx_ns[3][3] = harmonics.Sm22( + ker_base.n, sx[0][0], sx[0][1], smx_ns[1], sx_ns[3][5], False + ) + # compute the ome if ker_base.is_singlet: indices = {21: 0, 100: 1, 90: 2} - A = A_singlet(order, ker_base.n, sx, nf, L, is_msbar) + A = A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) else: indices = {200: 0, 91: 1} A = A_non_singlet(order, ker_base.n, sx, nf, L) diff --git a/tests/eko/test_harmonics.py b/tests/eko/test_harmonics.py index d8a03f4a4..cce120965 100644 --- a/tests/eko/test_harmonics.py +++ b/tests/eko/test_harmonics.py @@ -23,7 +23,7 @@ def test_spm2(): def test_harmonics_cache(): - N = np.random.rand() + 1.0j * np.random.rand() + N = np.random.randint(100) is_singlet = (-1) ** N == 1 S1 = h.S1(N) S2 = h.S2(N) @@ -66,6 +66,8 @@ def test_harmonics_cache(): # reference values coming fom mathematica +# and are computed doing an inverse mellin +# transformation testN = [1, 2, 2 + 2j, 10 + 5j, 100] refvals = { "Sm1": [-1.0, -0.5, -0.692917 - 0.000175788j, -0.693147 - 2.77406e-9j, -0.688172], diff --git a/tests/eko/test_matching_n3lo.py b/tests/eko/test_matching_n3lo.py index 48bfb8395..26a239997 100644 --- a/tests/eko/test_matching_n3lo.py +++ b/tests/eko/test_matching_n3lo.py @@ -14,7 +14,7 @@ def test_A_3(): for L in logs: N = 1.0 sx_cache = compute_harmonics_cache(N, 3, False) - aNSqq3 = A_qqNS(N, sx_cache, nf, L, False) + aNSqq3 = A_qqNS(N, sx_cache, nf, L) # quark number conservation # the accuracy of this test depends directly on the precision of the # F functions, thus is dominated by F19,F20,F21 accuracy are the worst ones @@ -37,7 +37,7 @@ def test_A_3(): # here you get division by 0 as in Mathematica # np.testing.assert_allclose( # n3lo.A_gq(N, sx_cache, nf,L) - # + n3lo.A_qqNS(N, sx_cache, nf,L, True) + # + n3lo.A_qqNS(N, ns_sx_cache, nf,L) # + n3lo.A_qqPS(N, sx, nf,L) # + n3lo.A_Hq(N, sx_cache, nf,L), # 0.0, @@ -52,14 +52,16 @@ def test_A_3(): # np.testing.assert_allclose(aS3[0, 1] + aS3[1, 1] + aS3[2, 1], 0.0, atol=1e-11) N = 3 + 2j - sx_cache = compute_harmonics_cache(np.random.rand(), 3, (-1) ** N == 1) - aS3 = A_singlet(N, sx_cache, nf, L) - aNS3 = A_ns(N, sx_cache, nf, L) + sx_cache = compute_harmonics_cache(np.random.rand(), 3, True) + ns_sx_cache = compute_harmonics_cache(np.random.rand(), 3, False) + aS3 = A_singlet(N, sx_cache, ns_sx_cache, nf, L) + aNS3 = A_ns(N, ns_sx_cache, nf, L) assert aNS3.shape == (2, 2) assert aS3.shape == (3, 3) np.testing.assert_allclose(aS3[:, 2], np.zeros(3)) np.testing.assert_allclose(aNS3[1, 1], 0) + np.testing.assert_allclose(aNS3[0, 0], as3.A_qqNS(N, ns_sx_cache, nf, L)) def test_Blumlein_3(): @@ -124,8 +126,8 @@ def test_Blumlein_3(): 10: [-74.4038, -1347.17, -1278.72, -1080.31, -291.084], } ref_val_qqNS = { - 0: [-37.0244, -40.1562, -36.0358, -28.3506, 6.83759], - 10: [-7574.85, -14130.3, -17928.6, -22768.0, -45425.9], + 0: [-36.5531, -40.1257, -36.0358, -28.3555, 6.83735], + 10: [-7562.97, -14129.7, -17928.6, -22768.1, -45326.9], } ref_val_qqPS = { 0: [-8.65731, -0.766936, -0.0365199, 0.147675, 0.0155598], @@ -136,7 +138,8 @@ def test_Blumlein_3(): idx = i + 1 for L in [0, 10]: sx_cache = compute_harmonics_cache(N, 3, True) - aS3 = A_singlet(N, sx_cache, nf, L) + ns_sx_cache = compute_harmonics_cache(N, 3, False) + aS3 = A_singlet(N, sx_cache, ns_sx_cache, nf, L) # here we have a different approximation for AggTF2, # some terms are neglected @@ -160,7 +163,7 @@ def test_Blumlein_3(): # as non singlet. The accuracy is worst for large N # due to the approximations of F functions. np.testing.assert_allclose( - aS3[1, 1], ref_val_qqNS[L][idx] + ref_val_qqPS[L][idx], rtol=3e-2 + aS3[1, 1], ref_val_qqNS[L][idx] + ref_val_qqPS[L][idx], rtol=8e-2 ) # Here we test the critical parts @@ -183,10 +186,11 @@ def test_Blumlein_3(): # odd numbers of qqNS # Limited accuracy due to F functions ref_qqNS_odd = [-40.94998646588999, -21.598793547423504, 6.966325573931755] - for N, ref in zip([3.0, 15.0, 101.0], ref_qqNS_odd): + rtols = [4e-4, 3e-3, 21e-2] + for N, ref, rtol in zip([3.0, 15.0, 101.0], ref_qqNS_odd, rtols): sx_cache = compute_harmonics_cache(N, 3, False) np.testing.assert_allclose( - as3.aqqNS.A_qqNS(N, sx_cache, nf, L=0, is_singlet=False), ref, rtol=3e-2 + as3.aqqNS.A_qqNS(N, sx_cache, nf, L=0), ref, rtol=rtol ) diff --git a/tests/eko/test_ome.py b/tests/eko/test_ome.py index e6282d45c..593bed230 100644 --- a/tests/eko/test_ome.py +++ b/tests/eko/test_ome.py @@ -22,17 +22,19 @@ def test_build_ome_as(): # test that if as = 0 ome is and identity - N = 2 + N = complex(2.123) L = 0.0 a_s = 0.0 nf = 3 is_msbar = False for o in [1, 2, 3]: + sx_singlet = compute_harmonics_cache(N, o, True) + sx_ns = sx_singlet if o == 3: - N = complex(2.123) - sx = compute_harmonics_cache(N, o, (-1) ** N == 1) - aNS = A_non_singlet(o, N, sx, nf, L) - aS = A_singlet(o, N, sx, nf, L, is_msbar) + sx_ns = compute_harmonics_cache(N, o, False) + + aNS = A_non_singlet(o, N, sx_ns, nf, L) + aS = A_singlet(o, N, sx_singlet, nf, L, is_msbar, sx_ns) for a in [aNS, aS]: for method in ["", "expanded", "exact"]: From 43197264da24bd2f29acab06696c28819c9f44d1 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 6 Apr 2022 11:19:12 +0200 Subject: [PATCH 42/47] Add S minus test against old definition --- tests/eko/test_harmonics.py | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/eko/test_harmonics.py b/tests/eko/test_harmonics.py index cce120965..46ddbe320 100644 --- a/tests/eko/test_harmonics.py +++ b/tests/eko/test_harmonics.py @@ -122,3 +122,48 @@ def test_Smx(): ] for i, sm in enumerate(smx): np.testing.assert_allclose(sm, refvals[f"Sm{i+1}"][j], atol=1e-06) + + +def test_smx_continuation(): + # test s_{-m} against a different analytic continuation + N = np.random.rand() + 1j * np.random.rand() + sx = h.sx(N) + + def dm(m): + zeta_list = [ + h.constants.zeta2, + h.constants.zeta3, + h.constants.zeta4, + h.constants.zeta5, + ] + if m == 1: + return h.constants.log2 + return (2 ** (m - 1) - 1) / (2 ** (m - 1)) * zeta_list[m - 2] + + def sm_complex(m, N): + return ((-1) ** N) / 2**m * (s(m, N / 2) - s(m, (N - 1) / 2)) - dm(m) + + def s(m, N): + if m == 1: + return h.S1(N) + if m == 2: + return h.S2(N) + if m == 3: + return h.S3(N) + if m == 4: + return h.S4(N) + return h.S5(N) + + def sm(m, N, hs): + if m == 1: + return h.Sm1(N, hs) + if m == 2: + return h.Sm2(N, hs) + if m == 3: + return h.Sm3(N, hs) + if m == 4: + return h.Sm4(N, hs) + return h.Sm5(N, hs) + + for j, hs in enumerate(sx): + np.testing.assert_allclose(sm_complex(j + 1, N), sm(j + 1, N, hs)) From 87065d2177efe534edf2e70e04cfd1a12acf1f0c Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 6 Apr 2022 11:20:09 +0200 Subject: [PATCH 43/47] remove useless minus sign --- src/eko/harmonics/polygamma.py | 2 +- src/eko/harmonics/w1.py | 2 +- src/eko/harmonics/w2.py | 2 +- src/eko/harmonics/w3.py | 2 +- src/eko/harmonics/w4.py | 2 +- src/eko/harmonics/w5.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/eko/harmonics/polygamma.py b/src/eko/harmonics/polygamma.py index 9f61240ae..b729cf952 100644 --- a/src/eko/harmonics/polygamma.py +++ b/src/eko/harmonics/polygamma.py @@ -168,7 +168,7 @@ def symmetry_factor(N, is_singlet=None): False for non singlet like quantities None for generic complex N value - Retruns + Returns ------- eta: complex 1 for singlet like quantities, diff --git a/src/eko/harmonics/w1.py b/src/eko/harmonics/w1.py index 88afee8d3..4e94bba27 100644 --- a/src/eko/harmonics/w1.py +++ b/src/eko/harmonics/w1.py @@ -64,7 +64,7 @@ def Sm1(N, hS1, is_singlet=None): """ if is_singlet is None: return ( - -((-1) ** N - 1) / 2 * S1((N - 1) / 2) + (1 - (-1) ** N) / 2 * S1((N - 1) / 2) + ((-1) ** N + 1) / 2 * S1(N / 2) - hS1 ) diff --git a/src/eko/harmonics/w2.py b/src/eko/harmonics/w2.py index a79fe6d83..c877da155 100644 --- a/src/eko/harmonics/w2.py +++ b/src/eko/harmonics/w2.py @@ -67,7 +67,7 @@ def Sm2(N, hS2, is_singlet=None): return ( 1 / 2 - * (-((-1) ** N - 1) / 2 * S2((N - 1) / 2) + ((-1) ** N + 1) / 2 * S2(N / 2)) + * ((1 - (-1) ** N) / 2 * S2((N - 1) / 2) + ((-1) ** N + 1) / 2 * S2(N / 2)) - hS2 ) if is_singlet: diff --git a/src/eko/harmonics/w3.py b/src/eko/harmonics/w3.py index 0f1689fdd..74e36bd3d 100644 --- a/src/eko/harmonics/w3.py +++ b/src/eko/harmonics/w3.py @@ -68,7 +68,7 @@ def Sm3(N, hS3, is_singlet=None): return ( 1 / 2**2 - * (-((-1) ** N - 1) / 2 * S3((N - 1) / 2) + ((-1) ** N + 1) / 2 * S3(N / 2)) + * ((1 - (-1) ** N) / 2 * S3((N - 1) / 2) + ((-1) ** N + 1) / 2 * S3(N / 2)) - hS3 ) if is_singlet: diff --git a/src/eko/harmonics/w4.py b/src/eko/harmonics/w4.py index 48567d3f7..003aab025 100644 --- a/src/eko/harmonics/w4.py +++ b/src/eko/harmonics/w4.py @@ -68,7 +68,7 @@ def Sm4(N, hS4, is_singlet=None): return ( 1 / 2**3 - * (-((-1) ** N - 1) / 2 * S4((N - 1) / 2) + ((-1) ** N + 1) / 2 * S4(N / 2)) + * ((1 - (-1) ** N) / 2 * S4((N - 1) / 2) + ((-1) ** N + 1) / 2 * S4(N / 2)) - hS4 ) if is_singlet: diff --git a/src/eko/harmonics/w5.py b/src/eko/harmonics/w5.py index 9acc9095f..c8be1194b 100644 --- a/src/eko/harmonics/w5.py +++ b/src/eko/harmonics/w5.py @@ -68,7 +68,7 @@ def Sm5(N, hS5, is_singlet=None): return ( 1 / 2**4 - * (-((-1) ** N - 1) / 2 * S5((N - 1) / 2) + ((-1) ** N + 1) / 2 * S5(N / 2)) + * ((1 - (-1) ** N) / 2 * S5((N - 1) / 2) + ((-1) ** N + 1) / 2 * S5(N / 2)) - hS5 ) if is_singlet: From b06d81332ba92b9bcee62575669a7ea13f735b66 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 6 Apr 2022 11:20:45 +0200 Subject: [PATCH 44/47] expand harmonics docs --- doc/source/theory/Mellin.rst | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/doc/source/theory/Mellin.rst b/doc/source/theory/Mellin.rst index fd4a4ab63..083f3e9a9 100644 --- a/doc/source/theory/Mellin.rst +++ b/doc/source/theory/Mellin.rst @@ -122,21 +122,32 @@ the Mellin inverse. .. math :: S_m(N) = \sum\limits_{j=1}^N \frac 1 {j^m} = \frac{(-1)^{m-1}}{(m-1)!} \psi_{m-1}(N+1)+c_m \quad - \text{with}\, c_m = \left\{\begin{array}{ll} \gamma_E, & m=1\\ \zeta(m), & m>1\end{array} \right. + \text{with},\quad c_m = \left\{\begin{array}{ll} \gamma_E, & m=1\\ \zeta(m), & m>1\end{array} \right. where :math:`\psi_k(N)` is the :math:`k`-th polygamma function (implemented as :meth:`~eko.harmonics.polygamma.cern_polygamma`) and :math:`\zeta` the Riemann zeta function (using :func:`scipy.special.zeta`). -- for the sums :math:`S_{-m}(N)` and :math:`m > 0` we use: +- for the sums :math:`S_{-m}(N)` and m > 0 we use :cite:`Gluck:1989ze`: .. math :: - S_{-m}(N) = \frac{\eta}{2} (S_{m}(N / 2) - S_{m}((N - 1) / 2)) - d_{m} + S_m'(N) = 2^{m-1}(S_m(N) + S_{-m}(N)) = \frac{1+\eta}{2} S_m\left(\frac{N}{2}\right) + \frac{1-\eta}{2} S_m\left(\frac{N-1}{2}\right) + + .. math :: + S_{-m}(N) = \frac{1}{2^{m-1}} \left [ \frac{1+\eta}{2} S_m\left(\frac{N}{2}\right) + \frac{1-\eta}{2}S_m\left(\frac{N-1}{2}\right)\right ] - S_m(N) where formally :math:`\eta = (-1)^N` but in all singlet-like quantities it has to be analytically continued with 1 - and with -1 elsewise and :math:`d_{m}= \left [ \log(2), 1/2 \zeta_{2}, 3/4 \zeta_{3}, 7/8 \zeta_{4}, 15/16 \zeta_{5}, \ldots \right]` + and with -1 elsewise. In case the symmetry condition is not given the formal definition of :math:`\eta` is used. + This relation is equivalent to the standard analytical continuation :cite:`Blumlein:2009ta,MuselliPhD`: + + .. math :: + S_{-m}(N) &= \frac{\eta}{2^m} \left[ S_m\left(\frac{N}{2}\right) - S_m\left(\frac{N-1}{2}\right) \right] - d_{m} \quad + \text{with},\quad d_m = \left\{\begin{array}{ll} \log(2), & m=1\\ \frac{2^{m-1}-1}{2^{m-1}}\zeta(m), & m>1\end{array} \right.\\ + + but it's faster for :math:`\eta = \pm 1`. - for the sums with greater depth we use the definitions provided in :cite:`Gluck:1989ze,MuselliPhD,Blumlein:1998if,Blumlein:2009ta`, which express higher weight sums in terms of simple one :math:`S_{m}, S_{-m}` and some irreducible integrals. + The above prescription on the analytical continuation of :math:`\eta` is applied. The complete list of harmonics sums available in :mod:`eko.harmonics` is: From febe124670315b93ffc3850775c85e9ec81d9e44 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Wed, 6 Apr 2022 15:35:11 +0200 Subject: [PATCH 45/47] suggested fixes in tests --- tests/eko/test_ad_nlo.py | 26 +++++++++++++------------- tests/eko/test_ad_nnlo.py | 12 ++++++------ tests/eko/test_matching_n3lo.py | 22 +++++----------------- 3 files changed, 24 insertions(+), 36 deletions(-) diff --git a/tests/eko/test_ad_nlo.py b/tests/eko/test_ad_nlo.py index c6beae0cd..29ebfefc2 100644 --- a/tests/eko/test_ad_nlo.py +++ b/tests/eko/test_ad_nlo.py @@ -11,11 +11,11 @@ def test_gamma_1(): # number conservation - sx = h.sx(1, 2) - np.testing.assert_allclose(ad_as2.gamma_nsm(1, NF, sx), 0.0, atol=2e-6) + sx_n1 = h.sx(1, 2) + np.testing.assert_allclose(ad_as2.gamma_nsm(1, NF, sx_n1), 0.0, atol=2e-6) - sx = h.sx(2, 2) - gS1 = ad_as2.gamma_singlet(2, NF, sx) + sx_n2 = h.sx(2, 2) + gS1 = ad_as2.gamma_singlet(2, NF, sx_n2) # gluon momentum conservation # the CA*NF term seems to be tough to compute, so raise the constraint ... np.testing.assert_allclose(gS1[0, 1] + gS1[1, 1], 0.0, atol=4e-5) @@ -27,7 +27,7 @@ def test_gamma_1(): # reference values are obtained from MMa # Non singlet sector np.testing.assert_allclose( - ad_as2.gamma_nsp(2, NF, sx), + ad_as2.gamma_nsp(2, NF, sx_n2), (-112.0 * const.CF + 376.0 * const.CA - 64.0 * NF) * const.CF / 27.0, ) # singlet sector @@ -41,7 +41,7 @@ def test_gamma_1(): # add additional point at (analytical) continuation point np.testing.assert_allclose( - ad_as2.gamma_nsm(2, NF, sx), + ad_as2.gamma_nsm(2, NF, sx_n2), ( (34.0 / 27.0 * (-47.0 + 6 * np.pi**2) - 16.0 * h.constants.zeta3) * const.CF @@ -51,10 +51,10 @@ def test_gamma_1(): ) * const.CF, ) - sx_3 = h.sx(3, 2) - sx_4 = h.sx(4, 2) + sx_n3 = h.sx(3, 2) + sx_n4 = h.sx(4, 2) np.testing.assert_allclose( - ad_as2.gamma_nsp(3, NF, sx_3), + ad_as2.gamma_nsp(3, NF, sx_n3), ( (-34487.0 / 432.0 + 86.0 * np.pi**2 / 9.0 - 16.0 * h.constants.zeta3) * const.CF @@ -65,7 +65,7 @@ def test_gamma_1(): * const.CF, ) np.testing.assert_allclose(ad_as2.gamma_ps(3, NF), -1391.0 * const.CF * NF / 5400.0) - gS1 = ad_as2.gamma_singlet(3, NF, sx_3) + gS1 = ad_as2.gamma_singlet(3, NF, sx_n3) np.testing.assert_allclose( gS1[1, 0], ( @@ -85,7 +85,7 @@ def test_gamma_1(): ), rtol=6e-7, ) # gg - gS1 = ad_as2.gamma_singlet(4, NF, sx_4) + gS1 = ad_as2.gamma_singlet(4, NF, sx_n4) np.testing.assert_allclose( gS1[0, 1], (-56317.0 / 18000.0 * const.CF + 16387.0 / 9000.0 * const.CA) * NF ) # qg @@ -93,7 +93,7 @@ def test_gamma_1(): const.update_colors(4) np.testing.assert_allclose(const.CA, 4.0) - gS1 = ad_as2.gamma_singlet(3, NF, sx_3) + gS1 = ad_as2.gamma_singlet(3, NF, sx_n3) np.testing.assert_allclose( gS1[1, 0], ( @@ -113,7 +113,7 @@ def test_gamma_1(): ), rtol=6e-7, ) # gg - gS1 = ad_as2.gamma_singlet(4, NF, sx_4) + gS1 = ad_as2.gamma_singlet(4, NF, sx_n4) np.testing.assert_allclose( gS1[0, 1], (-56317.0 / 18000.0 * const.CF + 16387.0 / 9000.0 * const.CA) * NF ) # qg diff --git a/tests/eko/test_ad_nnlo.py b/tests/eko/test_ad_nnlo.py index 071c9c3bf..8348712fa 100644 --- a/tests/eko/test_ad_nnlo.py +++ b/tests/eko/test_ad_nnlo.py @@ -12,14 +12,14 @@ def test_gamma_2(): # number conservation - each is 0 on its own, see :cite:`Moch:2004pa` N = 1 - sx = h.sx(N, max_weight=3) - np.testing.assert_allclose(ad_as3.gamma_nsv(N, NF, sx), 0.000960586, rtol=3e-7) - np.testing.assert_allclose(ad_as3.gamma_nsm(N, NF, sx), -0.000594225, rtol=6e-7) + sx_n1 = h.sx(N, max_weight=3) + np.testing.assert_allclose(ad_as3.gamma_nsv(N, NF, sx_n1), 0.000960586, rtol=3e-7) + np.testing.assert_allclose(ad_as3.gamma_nsm(N, NF, sx_n1), -0.000594225, rtol=6e-7) # get singlet sector N = 2 - sx = h.sx(N, max_weight=4) - gS2 = ad_as3.gamma_singlet(N, NF, sx) + sx_n2 = h.sx(N, max_weight=4) + gS2 = ad_as3.gamma_singlet(N, NF, sx_n2) # gluon momentum conservation np.testing.assert_allclose(gS2[0, 1] + gS2[1, 1], 0.00388726, rtol=2e-6) @@ -29,4 +29,4 @@ def test_gamma_2(): assert gS2.shape == (2, 2) # test nsv_2 equal to referece value - np.testing.assert_allclose(ad_as3.gamma_nsv(N, NF, sx), -188.325593, rtol=3e-7) + np.testing.assert_allclose(ad_as3.gamma_nsv(N, NF, sx_n2), -188.325593, rtol=3e-7) diff --git a/tests/eko/test_matching_n3lo.py b/tests/eko/test_matching_n3lo.py index 26a239997..393d039dd 100644 --- a/tests/eko/test_matching_n3lo.py +++ b/tests/eko/test_matching_n3lo.py @@ -34,22 +34,10 @@ def test_A_3(): rtol=32e-3, ) - # here you get division by 0 as in Mathematica - # np.testing.assert_allclose( - # n3lo.A_gq(N, sx_cache, nf,L) - # + n3lo.A_qqNS(N, ns_sx_cache, nf,L) - # + n3lo.A_qqPS(N, sx, nf,L) - # + n3lo.A_Hq(N, sx_cache, nf,L), - # 0.0, - # atol=2e-6, - # ) - - # here you get division by 0 as in Mathematica - # aS3 = A_singlet(N, sx_cache, nf, L) - # gluon momentum conservation - # np.testing.assert_allclose(aS3[0, 0] + aS3[1, 0] + aS3[2, 0], 0.0, atol=2e-6) - # quark momentum conservation - # np.testing.assert_allclose(aS3[0, 1] + aS3[1, 1] + aS3[2, 1], 0.0, atol=1e-11) + # here you can't test the quark momentum conservation + # since you get division by 0 as in Mathematica + # due to a factor 1/(N-2) which should cancel when + # doing a proper limit. N = 3 + 2j sx_cache = compute_harmonics_cache(np.random.rand(), 3, True) @@ -186,7 +174,7 @@ def test_Blumlein_3(): # odd numbers of qqNS # Limited accuracy due to F functions ref_qqNS_odd = [-40.94998646588999, -21.598793547423504, 6.966325573931755] - rtols = [4e-4, 3e-3, 21e-2] + rtols = [4e-4, 3e-3, 2.1e-2] for N, ref, rtol in zip([3.0, 15.0, 101.0], ref_qqNS_odd, rtols): sx_cache = compute_harmonics_cache(N, 3, False) np.testing.assert_allclose( From c59aa0f30c0d1331928939b2169c4133b546c601 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 6 Apr 2022 17:40:38 +0200 Subject: [PATCH 46/47] Remove commented code --- benchmarks/performance/harmonics.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/benchmarks/performance/harmonics.py b/benchmarks/performance/harmonics.py index 922eb316e..1d173ba15 100644 --- a/benchmarks/performance/harmonics.py +++ b/benchmarks/performance/harmonics.py @@ -27,13 +27,3 @@ def time_as2_sing(self): def time_as3_sing(self): for n in self.ns: ad.gamma_singlet(2, n, NF) - - -# class MemorySuite: -# def mem_sf(self): -# return compute_sf() - - -# class PeakMemorySuite: -# def peakmem_sf(self): -# compute_sf() From 9606618337c08df4e2118ce3c10be0862b1562c6 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 6 Apr 2022 18:00:24 +0200 Subject: [PATCH 47/47] Unify non-singlet language --- src/eko/evolution_operator/__init__.py | 2 +- src/eko/harmonics/__init__.py | 8 ++++---- src/eko/harmonics/polygamma.py | 4 ++-- src/eko/harmonics/w1.py | 2 +- src/eko/harmonics/w2.py | 2 +- src/eko/harmonics/w3.py | 6 +++--- src/eko/harmonics/w4.py | 8 ++++---- src/eko/harmonics/w5.py | 4 ++-- src/eko/matching_conditions/as3/__init__.py | 2 +- src/eko/matching_conditions/operator_matrix_element.py | 8 ++++---- src/eko/scale_variations/expanded.py | 2 +- tests/eko/test_ad_nlo.py | 2 +- tests/eko/test_matching_n3lo.py | 2 +- tests/eko/test_sv_expanded.py | 2 +- 14 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 0fadfbedc..69087526a 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -367,7 +367,7 @@ def initialize_op_members(self): zero = OpMember(*[np.zeros((self.grid_size, self.grid_size))] * 2) for n in self.full_labels: if n in self.labels: - # non singlet evolution and diagonal op are identities + # non-singlet evolution and diagonal op are identities if n in br.non_singlet_labels or n[0] == n[1]: self.op_members[n] = eye.copy() else: diff --git a/src/eko/harmonics/__init__.py b/src/eko/harmonics/__init__.py index c28802663..087ea60f0 100644 --- a/src/eko/harmonics/__init__.py +++ b/src/eko/harmonics/__init__.py @@ -28,7 +28,7 @@ def base_harmonics_cache(n, is_singlet, max_weight=5, n_max_sums_weight=7): Mellin moment is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) max_weight : int max harmonics weight, max value 5 (default) n_max_sums_weight : int @@ -90,7 +90,7 @@ def smx(n, sx, is_singlet): List of harmonics sums: :math:`S_{1},\dots,S_{w}` is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- smx : np.ndarray @@ -126,7 +126,7 @@ def s3x(n, sx, smx, is_singlet): List of harmonics sums: :math:`S_{-1},S_{-2}` is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -158,7 +158,7 @@ def s4x(n, sx, smx, is_singlet): List of harmonics sums: :math:`S_{-1},S_{-2}` is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- diff --git a/src/eko/harmonics/polygamma.py b/src/eko/harmonics/polygamma.py index b729cf952..b63ce5846 100644 --- a/src/eko/harmonics/polygamma.py +++ b/src/eko/harmonics/polygamma.py @@ -165,14 +165,14 @@ def symmetry_factor(N, is_singlet=None): Mellin moment is_singlet: bool, None True for singlet like quantities - False for non singlet like quantities + False for non-singlet like quantities None for generic complex N value Returns ------- eta: complex 1 for singlet like quantities, - -1 for non singlet like quantities, + -1 for non-singlet like quantities, :math:`(-1)^N` elsewise """ if is_singlet is None: diff --git a/src/eko/harmonics/w1.py b/src/eko/harmonics/w1.py index 4e94bba27..27255d652 100644 --- a/src/eko/harmonics/w1.py +++ b/src/eko/harmonics/w1.py @@ -52,7 +52,7 @@ def Sm1(N, hS1, is_singlet=None): Harmonic sum :math:`S_{1}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- Sm1 : complex diff --git a/src/eko/harmonics/w2.py b/src/eko/harmonics/w2.py index c877da155..9fcd6218d 100644 --- a/src/eko/harmonics/w2.py +++ b/src/eko/harmonics/w2.py @@ -52,7 +52,7 @@ def Sm2(N, hS2, is_singlet=None): Harmonic sum :math:`S_{2}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- diff --git a/src/eko/harmonics/w3.py b/src/eko/harmonics/w3.py index 74e36bd3d..ad12aedb1 100644 --- a/src/eko/harmonics/w3.py +++ b/src/eko/harmonics/w3.py @@ -53,7 +53,7 @@ def Sm3(N, hS3, is_singlet=None): Harmonic sum :math:`S_{3}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -119,7 +119,7 @@ def Sm21(N, S1, Sm1, is_singlet=None): Harmonic sum :math:`S_{-1}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -158,7 +158,7 @@ def S2m1(N, S2, Sm1, Sm2, is_singlet=None): Harmonic sum :math:`S_{-2}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- diff --git a/src/eko/harmonics/w4.py b/src/eko/harmonics/w4.py index 003aab025..2c46266dc 100644 --- a/src/eko/harmonics/w4.py +++ b/src/eko/harmonics/w4.py @@ -53,7 +53,7 @@ def Sm4(N, hS4, is_singlet=None): Harmonic sum :math:`S_{4}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -94,7 +94,7 @@ def Sm31(N, S1, Sm1, Sm2, is_singlet=None): Harmonic sum :math:`S_{-2}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -138,7 +138,7 @@ def Sm22(N, S1, S2, Sm2, Sm31, is_singlet=None): Harmonic sum :math:`S_{-3,1}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- Sm22 : complex @@ -172,7 +172,7 @@ def Sm211(N, S1, S2, Sm1, is_singlet=None): Harmonic sum :math:`S_{-1}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- diff --git a/src/eko/harmonics/w5.py b/src/eko/harmonics/w5.py index c8be1194b..c55a842b2 100644 --- a/src/eko/harmonics/w5.py +++ b/src/eko/harmonics/w5.py @@ -53,7 +53,7 @@ def Sm5(N, hS5, is_singlet=None): Harmonic sum :math:`S_{5}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -376,7 +376,7 @@ def Sm23(N, Sm1, Sm2, Sm3, is_singlet=None): Harmonic sum :math:`S_{-3}(N)` is_singlet: bool, None symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/eko/matching_conditions/as3/__init__.py index e863cab56..0653e64b7 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/eko/matching_conditions/as3/__init__.py @@ -65,7 +65,7 @@ def A_singlet(n, sx_singlet, sx_non_singlet, nf, L): [S_{4}, S_{3,1}, S_{2,1,1}, S_{-2,-2}, S_{-3, 1}, S_{-4}],] sx_non_singlet: list - same as sx_singlet but now for non singlet like harmonics + same as sx_singlet but now for non-singlet like harmonics nf : int number of active flavor below the threshold L : float diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/eko/matching_conditions/operator_matrix_element.py index 44dfcd982..8b6df8784 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/eko/matching_conditions/operator_matrix_element.py @@ -31,7 +31,7 @@ def compute_harmonics_cache(n, order, is_singlet): perturbative order is_singlet: bool symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non singlet like quantities (:math:`\eta=(-1)^N=-1`) + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -83,7 +83,7 @@ def A_singlet(order, n, sx, nf, L, is_msbar, sx_ns=None): is_msbar: bool add the |MSbar| contribution sx_ns : list - non singlet like harmonic sums cache + non-singlet like harmonic sums cache Returns ------- @@ -247,7 +247,7 @@ def quad_ker( or (mode0 == 100 and mode0 == 100) ): # At N3LO for A_qq singlet or backward you need to compute - # both the singlet and non singlet like harmonics + # both the singlet and non-singlet like harmonics # avoiding recomputing all of them ... sx_ns = sx.copy() smx_ns = harmonics.smx(ker_base.n, np.array([s[0] for s in sx]), False) @@ -340,7 +340,7 @@ def labels(self): """ labels = [] - # non singlet labels + # non-singlet labels if self.config["debug_skip_non_singlet"]: logger.warning("%s: skipping non-singlet sector", self.log_label) else: diff --git a/src/eko/scale_variations/expanded.py b/src/eko/scale_variations/expanded.py index a739df5c0..179e511aa 100644 --- a/src/eko/scale_variations/expanded.py +++ b/src/eko/scale_variations/expanded.py @@ -91,7 +91,7 @@ def gamma_3_variation(gamma, L, beta0, beta1, g0e2, g0e3, g1g0): @nb.njit(cache=True) def non_singlet_variation(gamma, a_s, order, nf, L): """ - Scale Variation non singlet dispatcher + Scale Variation non-singlet dispatcher Parameters ---------- diff --git a/tests/eko/test_ad_nlo.py b/tests/eko/test_ad_nlo.py index 29ebfefc2..617b7cd48 100644 --- a/tests/eko/test_ad_nlo.py +++ b/tests/eko/test_ad_nlo.py @@ -25,7 +25,7 @@ def test_gamma_1(): assert gS1.shape == (2, 2) # reference values are obtained from MMa - # Non singlet sector + # non-singlet sector np.testing.assert_allclose( ad_as2.gamma_nsp(2, NF, sx_n2), (-112.0 * const.CF + 376.0 * const.CA - 64.0 * NF) * const.CF / 27.0, diff --git a/tests/eko/test_matching_n3lo.py b/tests/eko/test_matching_n3lo.py index 393d039dd..753d52ebc 100644 --- a/tests/eko/test_matching_n3lo.py +++ b/tests/eko/test_matching_n3lo.py @@ -148,7 +148,7 @@ def test_Blumlein_3(): # here we have a different convention for (-1)^N, # for even values qqNS is analytically continued - # as non singlet. The accuracy is worst for large N + # as non-singlet. The accuracy is worst for large N # due to the approximations of F functions. np.testing.assert_allclose( aS3[1, 1], ref_val_qqNS[L][idx] + ref_val_qqPS[L][idx], rtol=8e-2 diff --git a/tests/eko/test_sv_expanded.py b/tests/eko/test_sv_expanded.py index 592df331b..f0828f6f9 100644 --- a/tests/eko/test_sv_expanded.py +++ b/tests/eko/test_sv_expanded.py @@ -80,7 +80,7 @@ def scheme_diff(g, k, pto, is_singlet): for L in [np.log(0.5), np.log(2)]: for order in [1, 2]: - # Non singlet kernels + # non-singlet kernels gns = gamma_ns(order, br.non_singlet_pids_map["ns+"], n, nf) ker = non_singlet.dispatcher( order, method, gns, a1, a0, nf, ev_op_iterations=1