From c14b43e27734a890baaa5af0a3d2bcbbb02d429f Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 11 Jan 2023 12:50:42 +0100 Subject: [PATCH 01/30] Split math of status quo --- benchmarks/eko/benchmark_ad.py | 4 +-- benchmarks/eko/benchmark_evol_to_unity.py | 2 +- benchmarks/performance/harmonics.py | 2 +- doc/source/overview/features.rst | 4 +-- doc/source/theory/Mellin.rst | 12 +++---- src/eko/beta.py | 2 +- src/eko/evolution_operator/__init__.py | 2 +- src/eko/evolution_operator/grid.py | 5 +-- src/eko/gamma.py | 2 +- src/eko/kernels/singlet.py | 2 +- .../anomalous_dimensions/__init__.py | 34 +++++++++---------- .../anomalous_dimensions/aem1.py | 2 +- .../anomalous_dimensions/aem2.py | 2 +- .../anomalous_dimensions/as1.py | 2 +- .../anomalous_dimensions/as1aem1.py | 3 +- .../anomalous_dimensions/as2.py | 3 +- .../anomalous_dimensions/as3.py | 0 .../anomalous_dimensions/as4/__init__.py | 0 .../anomalous_dimensions/as4/ggg.py | 0 .../anomalous_dimensions/as4/ggq.py | 0 .../anomalous_dimensions/as4/gnsm.py | 2 +- .../anomalous_dimensions/as4/gnsp.py | 0 .../anomalous_dimensions/as4/gnsv.py | 0 .../anomalous_dimensions/as4/gps.py | 0 .../anomalous_dimensions/as4/gqg.py | 0 src/{eko => ekore}/harmonics/__init__.py | 0 src/{eko => ekore}/harmonics/constants.py | 0 .../harmonics/f_functions/__init__.py | 0 .../harmonics/f_functions/f11.py | 0 .../harmonics/f_functions/f13.py | 0 .../harmonics/f_functions/f14_f12.py | 0 .../harmonics/f_functions/f16.py | 0 .../harmonics/f_functions/f17.py | 0 .../harmonics/f_functions/f18.py | 0 .../harmonics/f_functions/f19.py | 0 .../harmonics/f_functions/f20.py | 0 .../harmonics/f_functions/f21.py | 0 .../harmonics/f_functions/f9.py | 0 src/{eko => ekore}/harmonics/g_functions.py | 0 src/{eko => ekore}/harmonics/log_functions.py | 0 src/{eko => ekore}/harmonics/polygamma.py | 0 src/{eko => ekore}/harmonics/w1.py | 2 +- src/{eko => ekore}/harmonics/w2.py | 2 +- src/{eko => ekore}/harmonics/w3.py | 12 +++---- src/{eko => ekore}/harmonics/w4.py | 12 +++---- src/{eko => ekore}/harmonics/w5.py | 2 +- .../matching_conditions/__init__.py | 4 +-- src/{eko => ekore}/matching_conditions/as1.py | 2 +- src/{eko => ekore}/matching_conditions/as2.py | 2 +- .../matching_conditions/as3/__init__.py | 4 +-- .../matching_conditions/as3/aHg.py | 4 +-- .../matching_conditions/as3/aHgstfac.py | 2 +- .../matching_conditions/as3/aHq.py | 2 +- .../matching_conditions/as3/agg.py | 4 +-- .../matching_conditions/as3/aggTF2.py | 2 +- .../matching_conditions/as3/agq.py | 2 +- .../matching_conditions/as3/aqg.py | 2 +- .../matching_conditions/as3/aqqNS.py | 2 +- .../matching_conditions/as3/aqqPS.py | 2 +- .../operator_matrix_element.py | 16 ++++----- tests/eko/evolution_operator/test_init.py | 2 +- tests/eko/evolution_operator/test_physical.py | 2 +- tests/eko/kernels/test_ns.py | 2 +- tests/eko/kernels/test_s.py | 2 +- tests/eko/scale_variations/test_expanded.py | 2 +- tests/eko/test_beta.py | 2 +- .../anomalous_dimensions/__init__.py | 0 .../anomalous_dimensions/test_aem1.py | 2 +- .../anomalous_dimensions/test_aem2.py | 4 +-- .../anomalous_dimensions/test_as1.py | 6 ++-- .../anomalous_dimensions/test_as1aem1.py | 4 +-- .../anomalous_dimensions/test_as2.py | 4 +-- .../anomalous_dimensions/test_as3.py | 4 +-- .../anomalous_dimensions/test_as4.py | 4 +-- .../anomalous_dimensions/test_init.py | 6 ++-- tests/{eko => ekore}/harmonics/__init__.py | 0 .../harmonics/test_f_functions.py | 4 +-- .../harmonics/test_g_functions.py | 2 +- tests/{eko => ekore}/harmonics/test_init.py | 2 +- .../harmonics/test_log_functions.py | 2 +- .../harmonics/test_polygamma.py | 2 +- .../matching_conditions/__init__.py | 0 .../matching_conditions/test_init.py | 2 +- .../matching_conditions/test_n3lo.py | 6 ++-- .../matching_conditions/test_nlo.py | 4 +-- .../matching_conditions/test_nnlo.py | 4 +-- .../matching_conditions/test_ome.py | 10 +++--- 87 files changed, 126 insertions(+), 123 deletions(-) rename src/{eko => ekore}/anomalous_dimensions/__init__.py (81%) rename src/{eko => ekore}/anomalous_dimensions/aem1.py (98%) rename src/{eko => ekore}/anomalous_dimensions/aem2.py (99%) rename src/{eko => ekore}/anomalous_dimensions/as1.py (99%) rename src/{eko => ekore}/anomalous_dimensions/as1aem1.py (99%) rename src/{eko => ekore}/anomalous_dimensions/as2.py (99%) rename src/{eko => ekore}/anomalous_dimensions/as3.py (100%) rename src/{eko => ekore}/anomalous_dimensions/as4/__init__.py (100%) rename src/{eko => ekore}/anomalous_dimensions/as4/ggg.py (100%) rename src/{eko => ekore}/anomalous_dimensions/as4/ggq.py (100%) rename src/{eko => ekore}/anomalous_dimensions/as4/gnsm.py (99%) rename src/{eko => ekore}/anomalous_dimensions/as4/gnsp.py (100%) rename src/{eko => ekore}/anomalous_dimensions/as4/gnsv.py (100%) rename src/{eko => ekore}/anomalous_dimensions/as4/gps.py (100%) rename src/{eko => ekore}/anomalous_dimensions/as4/gqg.py (100%) rename src/{eko => ekore}/harmonics/__init__.py (100%) rename src/{eko => ekore}/harmonics/constants.py (100%) rename src/{eko => ekore}/harmonics/f_functions/__init__.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f11.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f13.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f14_f12.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f16.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f17.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f18.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f19.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f20.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f21.py (100%) rename src/{eko => ekore}/harmonics/f_functions/f9.py (100%) rename src/{eko => ekore}/harmonics/g_functions.py (100%) rename src/{eko => ekore}/harmonics/log_functions.py (100%) rename src/{eko => ekore}/harmonics/polygamma.py (100%) rename src/{eko => ekore}/harmonics/w1.py (95%) rename src/{eko => ekore}/harmonics/w2.py (95%) rename src/{eko => ekore}/harmonics/w3.py (93%) rename src/{eko => ekore}/harmonics/w4.py (94%) rename src/{eko => ekore}/harmonics/w5.py (99%) rename src/{eko => ekore}/matching_conditions/__init__.py (98%) rename src/{eko => ekore}/matching_conditions/as1.py (99%) rename src/{eko => ekore}/matching_conditions/as2.py (99%) rename src/{eko => ekore}/matching_conditions/as3/__init__.py (97%) rename src/{eko => ekore}/matching_conditions/as3/aHg.py (99%) rename src/{eko => ekore}/matching_conditions/as3/aHgstfac.py (99%) rename src/{eko => ekore}/matching_conditions/as3/aHq.py (99%) rename src/{eko => ekore}/matching_conditions/as3/agg.py (99%) rename src/{eko => ekore}/matching_conditions/as3/aggTF2.py (99%) rename src/{eko => ekore}/matching_conditions/as3/agq.py (99%) rename src/{eko => ekore}/matching_conditions/as3/aqg.py (99%) rename src/{eko => ekore}/matching_conditions/as3/aqqNS.py (99%) rename src/{eko => ekore}/matching_conditions/as3/aqqPS.py (99%) rename src/{eko => ekore}/matching_conditions/operator_matrix_element.py (95%) rename tests/{eko => ekore}/anomalous_dimensions/__init__.py (100%) rename tests/{eko => ekore}/anomalous_dimensions/test_aem1.py (93%) rename tests/{eko => ekore}/anomalous_dimensions/test_aem2.py (94%) rename tests/{eko => ekore}/anomalous_dimensions/test_as1.py (90%) rename tests/{eko => ekore}/anomalous_dimensions/test_as1aem1.py (95%) rename tests/{eko => ekore}/anomalous_dimensions/test_as2.py (98%) rename tests/{eko => ekore}/anomalous_dimensions/test_as3.py (91%) rename tests/{eko => ekore}/anomalous_dimensions/test_as4.py (98%) rename tests/{eko => ekore}/anomalous_dimensions/test_init.py (95%) rename tests/{eko => ekore}/harmonics/__init__.py (100%) rename tests/{eko => ekore}/harmonics/test_f_functions.py (98%) rename tests/{eko => ekore}/harmonics/test_g_functions.py (98%) rename tests/{eko => ekore}/harmonics/test_init.py (99%) rename tests/{eko => ekore}/harmonics/test_log_functions.py (97%) rename tests/{eko => ekore}/harmonics/test_polygamma.py (99%) rename tests/{eko => ekore}/matching_conditions/__init__.py (100%) rename tests/{eko => ekore}/matching_conditions/test_init.py (98%) rename tests/{eko => ekore}/matching_conditions/test_n3lo.py (98%) rename tests/{eko => ekore}/matching_conditions/test_nlo.py (93%) rename tests/{eko => ekore}/matching_conditions/test_nnlo.py (97%) rename tests/{eko => ekore}/matching_conditions/test_ome.py (97%) diff --git a/benchmarks/eko/benchmark_ad.py b/benchmarks/eko/benchmark_ad.py index cb5c07e66..d7f1baa39 100644 --- a/benchmarks/eko/benchmark_ad.py +++ b/benchmarks/eko/benchmark_ad.py @@ -2,8 +2,8 @@ import numpy as np import pytest -import eko.anomalous_dimensions.as2 as ad_as2 -import eko.harmonics as h +import ekore.anomalous_dimensions.as2 as ad_as2 +import ekore.harmonics as h from eko.constants import CA, CF, TR diff --git a/benchmarks/eko/benchmark_evol_to_unity.py b/benchmarks/eko/benchmark_evol_to_unity.py index 6baf6bfa8..978d11c62 100644 --- a/benchmarks/eko/benchmark_evol_to_unity.py +++ b/benchmarks/eko/benchmark_evol_to_unity.py @@ -11,7 +11,7 @@ from eko.io.runcards import OperatorCard, TheoryCard from eko.runner.legacy import Runner -# from eko.matching_conditions.operator_matrix_element import OperatorMatrixElement +# from ekore.matching_conditions.operator_matrix_element import OperatorMatrixElement def update_cards(theory: TheoryCard, operator: OperatorCard): diff --git a/benchmarks/performance/harmonics.py b/benchmarks/performance/harmonics.py index f803bcda0..e794aafde 100644 --- a/benchmarks/performance/harmonics.py +++ b/benchmarks/performance/harmonics.py @@ -1,6 +1,6 @@ import numpy as np -from eko import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad from eko.mellin import Path NF = 5 diff --git a/doc/source/overview/features.rst b/doc/source/overview/features.rst index 719bc5d61..3edf80aff 100644 --- a/doc/source/overview/features.rst +++ b/doc/source/overview/features.rst @@ -1,8 +1,8 @@ Features ======== -- perturbation orders: :mod:`LO ` + :mod:`NLO ` - + :mod:`NNLO ` +- perturbation orders: :mod:`LO ` + :mod:`NLO ` + + :mod:`NNLO ` - evolution in an (almost) arbitrary sequence of |FNS| (:class:`~eko.thresholds.ThresholdsAtlas`) - :ref:`theory/pQCD:scale variations` - different :doc:`solutions ` of |DGLAP| differential equation diff --git a/doc/source/theory/Mellin.rst b/doc/source/theory/Mellin.rst index 083f3e9a9..2c160902f 100644 --- a/doc/source/theory/Mellin.rst +++ b/doc/source/theory/Mellin.rst @@ -124,7 +124,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},\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`) + where :math:`\psi_k(N)` is the :math:`k`-th polygamma function (implemented as :meth:`~ekore.harmonics.polygamma.cern_polygamma`) and :math:`\zeta` the Riemann zeta function (using :func:`scipy.special.zeta`). - for the sums :math:`S_{-m}(N)` and m > 0 we use :cite:`Gluck:1989ze`: @@ -149,7 +149,7 @@ the Mellin inverse. 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: +The complete list of harmonics sums available in :mod:`ekore.harmonics` is: - weight 1: @@ -166,20 +166,20 @@ The complete list of harmonics sums available in :mod:`eko.harmonics` is: .. 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` + these sums relies on the integrals :mod:`ekore.harmonics.g_functions` :cite:`MuselliPhD,Blumlein:1998if` - 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` + these sums relies on the integrals :mod:`ekore.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` + these sums relies on the integrals :mod:`ekore.harmonics.f_functions` :cite:`Blumlein:2009ta` -We have also implemented a recursive computation of simple harmonics (single index), see :func:`eko.harmonics.polygamma.recursive_harmonic_sum` +We have also implemented a recursive computation of simple harmonics (single index), see :func:`ekore.harmonics.polygamma.recursive_harmonic_sum` diff --git a/src/eko/beta.py b/src/eko/beta.py index f83d013bb..92212bf58 100644 --- a/src/eko/beta.py +++ b/src/eko/beta.py @@ -7,7 +7,7 @@ import numba as nb from . import constants -from .harmonics.constants import zeta3 +from ekore.harmonics.constants import zeta3 @nb.njit(cache=True) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 323b117b4..544fde4cc 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -13,7 +13,7 @@ import numpy as np from scipy import integrate -from .. import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad from .. import basis_rotation as br from .. import interpolation, mellin from .. import scale_variations as sv diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index 1b55a2072..82e50fe9a 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -11,10 +11,11 @@ import numpy as np import numpy.typing as npt -from .. import matching_conditions, member +from ekore import matching_conditions +from .. import member from .. import scale_variations as sv from ..io.runcards import Configs, Debug -from ..matching_conditions.operator_matrix_element import OperatorMatrixElement +from ekore.matching_conditions.operator_matrix_element import OperatorMatrixElement from ..thresholds import flavor_shift, is_downward_path from . import Operator, flavors, physical diff --git a/src/eko/gamma.py b/src/eko/gamma.py index cd4e9aa3e..b2c4a857b 100644 --- a/src/eko/gamma.py +++ b/src/eko/gamma.py @@ -5,7 +5,7 @@ """ import numba as nb -from .harmonics.constants import zeta3, zeta4, zeta5 +from ekore.harmonics.constants import zeta3, zeta4, zeta5 @nb.njit(cache=True) diff --git a/src/eko/kernels/singlet.py b/src/eko/kernels/singlet.py index ab3d4dfc8..2bab5d35c 100644 --- a/src/eko/kernels/singlet.py +++ b/src/eko/kernels/singlet.py @@ -3,7 +3,7 @@ import numba as nb import numpy as np -from .. import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad from .. import beta from . import as4_evolution_integrals as as4_ei from . import evolution_integrals as ei diff --git a/src/eko/anomalous_dimensions/__init__.py b/src/ekore/anomalous_dimensions/__init__.py similarity index 81% rename from src/eko/anomalous_dimensions/__init__.py rename to src/ekore/anomalous_dimensions/__init__.py index c3a3f8c78..69c9865d7 100644 --- a/src/eko/anomalous_dimensions/__init__.py +++ b/src/ekore/anomalous_dimensions/__init__.py @@ -19,7 +19,7 @@ import numba as nb import numpy as np -from .. import basis_rotation as br +from eko import basis_rotation as br from .. import harmonics from . import aem1, aem2, as1, as1aem1, as2, as3, as4 @@ -53,9 +53,9 @@ def exp_singlet(gamma_S): See Also -------- - eko.anomalous_dimensions.as1.gamma_singlet : :math:`\gamma_{S}^{(0)}(N)` - eko.anomalous_dimensions.as2.gamma_singlet : :math:`\gamma_{S}^{(1)}(N)` - eko.anomalous_dimensions.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` + ekore.anomalous_dimensions.as1.gamma_singlet : :math:`\gamma_{S}^{(0)}(N)` + ekore.anomalous_dimensions.as2.gamma_singlet : :math:`\gamma_{S}^{(1)}(N)` + ekore.anomalous_dimensions.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` """ # compute eigenvalues det = np.sqrt( @@ -94,15 +94,15 @@ def gamma_ns(order, mode, n, nf): See Also -------- - eko.anomalous_dimensions.as1.gamma_ns : :math:`\gamma_{ns}^{(0)}(N)` - eko.anomalous_dimensions.as2.gamma_nsp : :math:`\gamma_{ns,+}^{(1)}(N)` - eko.anomalous_dimensions.as2.gamma_nsm : :math:`\gamma_{ns,-}^{(1)}(N)` - eko.anomalous_dimensions.as3.gamma_nsp : :math:`\gamma_{ns,+}^{(2)}(N)` - eko.anomalous_dimensions.as3.gamma_nsm : :math:`\gamma_{ns,-}^{(2)}(N)` - eko.anomalous_dimensions.as3.gamma_nsv : :math:`\gamma_{ns,v}^{(2)}(N)` - eko.anomalous_dimensions.as4.gamma_nsp : :math:`\gamma_{ns,+}^{(3)}(N)` - eko.anomalous_dimensions.as4.gamma_nsm : :math:`\gamma_{ns,-}^{(3)}(N)` - eko.anomalous_dimensions.as4.gamma_nsv : :math:`\gamma_{ns,v}^{(3)}(N)` + ekore.anomalous_dimensions.as1.gamma_ns : :math:`\gamma_{ns}^{(0)}(N)` + ekore.anomalous_dimensions.as2.gamma_nsp : :math:`\gamma_{ns,+}^{(1)}(N)` + ekore.anomalous_dimensions.as2.gamma_nsm : :math:`\gamma_{ns,-}^{(1)}(N)` + ekore.anomalous_dimensions.as3.gamma_nsp : :math:`\gamma_{ns,+}^{(2)}(N)` + ekore.anomalous_dimensions.as3.gamma_nsm : :math:`\gamma_{ns,-}^{(2)}(N)` + ekore.anomalous_dimensions.as3.gamma_nsv : :math:`\gamma_{ns,v}^{(2)}(N)` + ekore.anomalous_dimensions.as4.gamma_nsp : :math:`\gamma_{ns,+}^{(3)}(N)` + ekore.anomalous_dimensions.as4.gamma_nsm : :math:`\gamma_{ns,-}^{(3)}(N)` + ekore.anomalous_dimensions.as4.gamma_nsv : :math:`\gamma_{ns,v}^{(3)}(N)` """ # cache the s-es @@ -172,10 +172,10 @@ def gamma_singlet(order, n, nf): See Also -------- - eko.anomalous_dimensions.as1.gamma_singlet : :math:`\gamma_{S}^{(0)}(N)` - eko.anomalous_dimensions.as2.gamma_singlet : :math:`\gamma_{S}^{(1)}(N)` - eko.anomalous_dimensions.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` - eko.anomalous_dimensions.as4.gamma_singlet : :math:`\gamma_{S}^{(3)}(N)` + ekore.anomalous_dimensions.as1.gamma_singlet : :math:`\gamma_{S}^{(0)}(N)` + ekore.anomalous_dimensions.as2.gamma_singlet : :math:`\gamma_{S}^{(1)}(N)` + ekore.anomalous_dimensions.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` + ekore.anomalous_dimensions.as4.gamma_singlet : :math:`\gamma_{S}^{(3)}(N)` """ # cache the s-es diff --git a/src/eko/anomalous_dimensions/aem1.py b/src/ekore/anomalous_dimensions/aem1.py similarity index 98% rename from src/eko/anomalous_dimensions/aem1.py rename to src/ekore/anomalous_dimensions/aem1.py index f272439cb..d26683969 100644 --- a/src/eko/anomalous_dimensions/aem1.py +++ b/src/ekore/anomalous_dimensions/aem1.py @@ -4,7 +4,7 @@ import numba as nb -from .. import constants +from eko import constants from . import as1 diff --git a/src/eko/anomalous_dimensions/aem2.py b/src/ekore/anomalous_dimensions/aem2.py similarity index 99% rename from src/eko/anomalous_dimensions/aem2.py rename to src/ekore/anomalous_dimensions/aem2.py index d2a4940d6..83f40e456 100644 --- a/src/eko/anomalous_dimensions/aem2.py +++ b/src/ekore/anomalous_dimensions/aem2.py @@ -4,7 +4,7 @@ import numba as nb -from .. import constants +from eko import constants from . import as1aem1 diff --git a/src/eko/anomalous_dimensions/as1.py b/src/ekore/anomalous_dimensions/as1.py similarity index 99% rename from src/eko/anomalous_dimensions/as1.py rename to src/ekore/anomalous_dimensions/as1.py index b4e5fd133..28afb3a00 100644 --- a/src/eko/anomalous_dimensions/as1.py +++ b/src/ekore/anomalous_dimensions/as1.py @@ -3,7 +3,7 @@ import numba as nb import numpy as np -from .. import constants +from eko import constants @nb.njit(cache=True) diff --git a/src/eko/anomalous_dimensions/as1aem1.py b/src/ekore/anomalous_dimensions/as1aem1.py similarity index 99% rename from src/eko/anomalous_dimensions/as1aem1.py rename to src/ekore/anomalous_dimensions/as1aem1.py index 85eb25ffa..d2b7ebebc 100644 --- a/src/eko/anomalous_dimensions/as1aem1.py +++ b/src/ekore/anomalous_dimensions/as1aem1.py @@ -4,7 +4,8 @@ import numba as nb -from .. import constants, harmonics +from eko import constants +from .. import harmonics from ..harmonics.constants import zeta2, zeta3 diff --git a/src/eko/anomalous_dimensions/as2.py b/src/ekore/anomalous_dimensions/as2.py similarity index 99% rename from src/eko/anomalous_dimensions/as2.py rename to src/ekore/anomalous_dimensions/as2.py index 03945a495..e51034a5b 100644 --- a/src/eko/anomalous_dimensions/as2.py +++ b/src/ekore/anomalous_dimensions/as2.py @@ -9,7 +9,8 @@ import numba as nb import numpy as np -from .. import constants, harmonics +from eko import constants +from .. import harmonics from ..harmonics.constants import log2, zeta2, zeta3 diff --git a/src/eko/anomalous_dimensions/as3.py b/src/ekore/anomalous_dimensions/as3.py similarity index 100% rename from src/eko/anomalous_dimensions/as3.py rename to src/ekore/anomalous_dimensions/as3.py diff --git a/src/eko/anomalous_dimensions/as4/__init__.py b/src/ekore/anomalous_dimensions/as4/__init__.py similarity index 100% rename from src/eko/anomalous_dimensions/as4/__init__.py rename to src/ekore/anomalous_dimensions/as4/__init__.py diff --git a/src/eko/anomalous_dimensions/as4/ggg.py b/src/ekore/anomalous_dimensions/as4/ggg.py similarity index 100% rename from src/eko/anomalous_dimensions/as4/ggg.py rename to src/ekore/anomalous_dimensions/as4/ggg.py diff --git a/src/eko/anomalous_dimensions/as4/ggq.py b/src/ekore/anomalous_dimensions/as4/ggq.py similarity index 100% rename from src/eko/anomalous_dimensions/as4/ggq.py rename to src/ekore/anomalous_dimensions/as4/ggq.py diff --git a/src/eko/anomalous_dimensions/as4/gnsm.py b/src/ekore/anomalous_dimensions/as4/gnsm.py similarity index 99% rename from src/eko/anomalous_dimensions/as4/gnsm.py rename to src/ekore/anomalous_dimensions/as4/gnsm.py index 691aede24..ae50c68ba 100644 --- a/src/eko/anomalous_dimensions/as4/gnsm.py +++ b/src/ekore/anomalous_dimensions/as4/gnsm.py @@ -3,7 +3,7 @@ """ import numba as nb -from ...constants import CF +from eko.constants import CF from ...harmonics.constants import zeta3 from ...harmonics.log_functions import lm11m1, lm12m1, lm13m1 diff --git a/src/eko/anomalous_dimensions/as4/gnsp.py b/src/ekore/anomalous_dimensions/as4/gnsp.py similarity index 100% rename from src/eko/anomalous_dimensions/as4/gnsp.py rename to src/ekore/anomalous_dimensions/as4/gnsp.py diff --git a/src/eko/anomalous_dimensions/as4/gnsv.py b/src/ekore/anomalous_dimensions/as4/gnsv.py similarity index 100% rename from src/eko/anomalous_dimensions/as4/gnsv.py rename to src/ekore/anomalous_dimensions/as4/gnsv.py diff --git a/src/eko/anomalous_dimensions/as4/gps.py b/src/ekore/anomalous_dimensions/as4/gps.py similarity index 100% rename from src/eko/anomalous_dimensions/as4/gps.py rename to src/ekore/anomalous_dimensions/as4/gps.py diff --git a/src/eko/anomalous_dimensions/as4/gqg.py b/src/ekore/anomalous_dimensions/as4/gqg.py similarity index 100% rename from src/eko/anomalous_dimensions/as4/gqg.py rename to src/ekore/anomalous_dimensions/as4/gqg.py diff --git a/src/eko/harmonics/__init__.py b/src/ekore/harmonics/__init__.py similarity index 100% rename from src/eko/harmonics/__init__.py rename to src/ekore/harmonics/__init__.py diff --git a/src/eko/harmonics/constants.py b/src/ekore/harmonics/constants.py similarity index 100% rename from src/eko/harmonics/constants.py rename to src/ekore/harmonics/constants.py diff --git a/src/eko/harmonics/f_functions/__init__.py b/src/ekore/harmonics/f_functions/__init__.py similarity index 100% rename from src/eko/harmonics/f_functions/__init__.py rename to src/ekore/harmonics/f_functions/__init__.py diff --git a/src/eko/harmonics/f_functions/f11.py b/src/ekore/harmonics/f_functions/f11.py similarity index 100% rename from src/eko/harmonics/f_functions/f11.py rename to src/ekore/harmonics/f_functions/f11.py diff --git a/src/eko/harmonics/f_functions/f13.py b/src/ekore/harmonics/f_functions/f13.py similarity index 100% rename from src/eko/harmonics/f_functions/f13.py rename to src/ekore/harmonics/f_functions/f13.py diff --git a/src/eko/harmonics/f_functions/f14_f12.py b/src/ekore/harmonics/f_functions/f14_f12.py similarity index 100% rename from src/eko/harmonics/f_functions/f14_f12.py rename to src/ekore/harmonics/f_functions/f14_f12.py diff --git a/src/eko/harmonics/f_functions/f16.py b/src/ekore/harmonics/f_functions/f16.py similarity index 100% rename from src/eko/harmonics/f_functions/f16.py rename to src/ekore/harmonics/f_functions/f16.py diff --git a/src/eko/harmonics/f_functions/f17.py b/src/ekore/harmonics/f_functions/f17.py similarity index 100% rename from src/eko/harmonics/f_functions/f17.py rename to src/ekore/harmonics/f_functions/f17.py diff --git a/src/eko/harmonics/f_functions/f18.py b/src/ekore/harmonics/f_functions/f18.py similarity index 100% rename from src/eko/harmonics/f_functions/f18.py rename to src/ekore/harmonics/f_functions/f18.py diff --git a/src/eko/harmonics/f_functions/f19.py b/src/ekore/harmonics/f_functions/f19.py similarity index 100% rename from src/eko/harmonics/f_functions/f19.py rename to src/ekore/harmonics/f_functions/f19.py diff --git a/src/eko/harmonics/f_functions/f20.py b/src/ekore/harmonics/f_functions/f20.py similarity index 100% rename from src/eko/harmonics/f_functions/f20.py rename to src/ekore/harmonics/f_functions/f20.py diff --git a/src/eko/harmonics/f_functions/f21.py b/src/ekore/harmonics/f_functions/f21.py similarity index 100% rename from src/eko/harmonics/f_functions/f21.py rename to src/ekore/harmonics/f_functions/f21.py diff --git a/src/eko/harmonics/f_functions/f9.py b/src/ekore/harmonics/f_functions/f9.py similarity index 100% rename from src/eko/harmonics/f_functions/f9.py rename to src/ekore/harmonics/f_functions/f9.py diff --git a/src/eko/harmonics/g_functions.py b/src/ekore/harmonics/g_functions.py similarity index 100% rename from src/eko/harmonics/g_functions.py rename to src/ekore/harmonics/g_functions.py diff --git a/src/eko/harmonics/log_functions.py b/src/ekore/harmonics/log_functions.py similarity index 100% rename from src/eko/harmonics/log_functions.py rename to src/ekore/harmonics/log_functions.py diff --git a/src/eko/harmonics/polygamma.py b/src/ekore/harmonics/polygamma.py similarity index 100% rename from src/eko/harmonics/polygamma.py rename to src/ekore/harmonics/polygamma.py diff --git a/src/eko/harmonics/w1.py b/src/ekore/harmonics/w1.py similarity index 95% rename from src/eko/harmonics/w1.py rename to src/ekore/harmonics/w1.py index 5d4e5b27c..10f7cc3d4 100644 --- a/src/eko/harmonics/w1.py +++ b/src/ekore/harmonics/w1.py @@ -28,7 +28,7 @@ def S1(N): See Also -------- - eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + ekore.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` """ return cern_polygamma(N + 1.0, 0) + np.euler_gamma diff --git a/src/eko/harmonics/w2.py b/src/ekore/harmonics/w2.py similarity index 95% rename from src/eko/harmonics/w2.py rename to src/ekore/harmonics/w2.py index 9e978f0d4..69c0029eb 100644 --- a/src/eko/harmonics/w2.py +++ b/src/ekore/harmonics/w2.py @@ -28,7 +28,7 @@ def S2(N): See Also -------- - eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + ekore.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` """ return -cern_polygamma(N + 1.0, 1) + zeta2 diff --git a/src/eko/harmonics/w3.py b/src/ekore/harmonics/w3.py similarity index 93% rename from src/eko/harmonics/w3.py rename to src/ekore/harmonics/w3.py index 49e3d5a7e..dcd52428c 100644 --- a/src/eko/harmonics/w3.py +++ b/src/ekore/harmonics/w3.py @@ -29,7 +29,7 @@ def S3(N): See Also -------- - eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + ekore.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` """ return 0.5 * cern_polygamma(N + 1.0, 2) + zeta3 @@ -59,7 +59,7 @@ def Sm3(N, hS3, is_singlet=None): See Also -------- - eko.harmonics.w3.S3 : :math:`S_3(N)` + ekore.harmonics.w3.S3 : :math:`S_3(N)` """ if is_singlet is None: @@ -97,7 +97,7 @@ def S21(N, S1, S2): See Also -------- - eko.harmonics.g_functions.mellin_g18 : :math:`g_18(N)` + ekore.harmonics.g_functions.mellin_g18 : :math:`g_18(N)` """ return -gf.mellin_g18(N, S1, S2) + 2 * zeta3 @@ -129,7 +129,7 @@ def Sm21(N, S1, Sm1, is_singlet=None): See Also -------- - eko.harmonics.g_functions : :math:`g_3(N)` + ekore.harmonics.g_functions : :math:`g_3(N)` """ # Note mellin g3 was integrated following x^(N-1) convention. @@ -170,7 +170,7 @@ def S2m1(N, S2, Sm1, Sm2, is_singlet=None): See Also -------- - eko.harmonics.g_functions.mellin_g4 : :math:`g_4(N)` + ekore.harmonics.g_functions.mellin_g4 : :math:`g_4(N)` """ eta = symmetry_factor(N, is_singlet) @@ -208,7 +208,7 @@ def Sm2m1(N, S1, S2, Sm2): See Also -------- - eko.harmonics.g_functions.mellin_g19 : :math:`g_19(N)` + ekore.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/ekore/harmonics/w4.py similarity index 94% rename from src/eko/harmonics/w4.py rename to src/ekore/harmonics/w4.py index 270e79311..855602ec7 100644 --- a/src/eko/harmonics/w4.py +++ b/src/ekore/harmonics/w4.py @@ -29,7 +29,7 @@ def S4(N): See Also -------- - eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + ekore.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` """ return zeta4 - 1.0 / 6.0 * cern_polygamma(N + 1.0, 3) @@ -102,7 +102,7 @@ def Sm31(N, S1, Sm1, Sm2, is_singlet=None): See Also -------- - eko.harmonics.g_functions.mellin_g6 : :math:`g_6(N)` + ekore.harmonics.g_functions.mellin_g6 : :math:`g_6(N)` """ eta = symmetry_factor(N, is_singlet) @@ -148,7 +148,7 @@ def Sm22(N, S1, S2, Sm2, Sm31, is_singlet=None): See Also -------- - eko.harmonics.g_functions.mellin_g5 : :math:`g_5(N)` + ekore.harmonics.g_functions.mellin_g5 : :math:`g_5(N)` """ eta = symmetry_factor(N, is_singlet) @@ -185,7 +185,7 @@ def Sm211(N, S1, S2, Sm1, is_singlet=None): See Also -------- - eko.harmonics.g_functions.mellin_g8 : :math:`g_8(N)` + ekore.harmonics.g_functions.mellin_g8 : :math:`g_8(N)` """ eta = symmetry_factor(N, is_singlet) @@ -225,7 +225,7 @@ def S211(N, S1, S2, S3): See Also -------- - eko.harmonics.g_functions.mellin_g21 : :math:`g_21(N)` + ekore.harmonics.g_functions.mellin_g21 : :math:`g_21(N)` """ return -gf.mellin_g21(N, S1, S2, S3) + 6 / 5 * zeta2**2 @@ -258,7 +258,7 @@ def S31(N, S1, S2, S3, S4): See Also -------- - eko.harmonics.g_functions.mellin_g22 : :math:`g_22(N)` + ekore.harmonics.g_functions.mellin_g22 : :math:`g_22(N)` """ return ( diff --git a/src/eko/harmonics/w5.py b/src/ekore/harmonics/w5.py similarity index 99% rename from src/eko/harmonics/w5.py rename to src/ekore/harmonics/w5.py index d6a3f91d9..b75f9eebf 100644 --- a/src/eko/harmonics/w5.py +++ b/src/ekore/harmonics/w5.py @@ -29,7 +29,7 @@ def S5(N): See Also -------- - eko.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` + ekore.harmonics.polygamma.cern_polygamma : :math:`\psi_k(N)` """ return zeta5 + 1.0 / 24.0 * cern_polygamma(N + 1.0, 4) diff --git a/src/eko/matching_conditions/__init__.py b/src/ekore/matching_conditions/__init__.py similarity index 98% rename from src/eko/matching_conditions/__init__.py rename to src/ekore/matching_conditions/__init__.py index 32b8cd036..f2eaed8e0 100644 --- a/src/eko/matching_conditions/__init__.py +++ b/src/ekore/matching_conditions/__init__.py @@ -2,8 +2,8 @@ This module defines the matching conditions for the |VFNS| evolution. """ -from .. import basis_rotation as br -from .. import member +from eko import basis_rotation as br +from eko import member class MatchingCondition(member.OperatorBase): diff --git a/src/eko/matching_conditions/as1.py b/src/ekore/matching_conditions/as1.py similarity index 99% rename from src/eko/matching_conditions/as1.py rename to src/ekore/matching_conditions/as1.py index cc74550ca..c373f8091 100644 --- a/src/eko/matching_conditions/as1.py +++ b/src/ekore/matching_conditions/as1.py @@ -9,7 +9,7 @@ import numba as nb import numpy as np -from ..constants import CF +from eko.constants import CF @nb.njit(cache=True) diff --git a/src/eko/matching_conditions/as2.py b/src/ekore/matching_conditions/as2.py similarity index 99% rename from src/eko/matching_conditions/as2.py rename to src/ekore/matching_conditions/as2.py index 7a86d8050..242f1fa5f 100644 --- a/src/eko/matching_conditions/as2.py +++ b/src/ekore/matching_conditions/as2.py @@ -11,7 +11,7 @@ import numba as nb import numpy as np -from .. import constants +from eko 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 diff --git a/src/eko/matching_conditions/as3/__init__.py b/src/ekore/matching_conditions/as3/__init__.py similarity index 97% rename from src/eko/matching_conditions/as3/__init__.py rename to src/ekore/matching_conditions/as3/__init__.py index b414369a5..06feccd38 100644 --- a/src/eko/matching_conditions/as3/__init__.py +++ b/src/ekore/matching_conditions/as3/__init__.py @@ -80,7 +80,7 @@ def A_singlet(n, sx_singlet, sx_non_singlet, 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.as3`. + available at the top of this module :mod:`ekore.matching_conditions.as3`. Parameters ---------- @@ -140,7 +140,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.as3`. + at the top of this module :mod:`ekore.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/aHg.py b/src/ekore/matching_conditions/as3/aHg.py similarity index 99% rename from src/eko/matching_conditions/as3/aHg.py rename to src/ekore/matching_conditions/as3/aHg.py index b756ab584..c676ce558 100644 --- a/src/eko/matching_conditions/as3/aHg.py +++ b/src/ekore/matching_conditions/as3/aHg.py @@ -11,7 +11,7 @@ def A_Hg(n, sx, nf, L): # pylint: disable=too-many-locals 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.as3`. + available in :mod:`ekore.matching_conditions.as3`. Parameters ---------- @@ -31,7 +31,7 @@ def A_Hg(n, sx, nf, L): # pylint: disable=too-many-locals See Also -------- - A_Hgstfac: eko.matching_conditions.as3.aHgstfac.A_Hgstfac + A_Hgstfac: ekore.matching_conditions.as3.aHgstfac.A_Hgstfac Incomplete part of the |OME|. """ diff --git a/src/eko/matching_conditions/as3/aHgstfac.py b/src/ekore/matching_conditions/as3/aHgstfac.py similarity index 99% rename from src/eko/matching_conditions/as3/aHgstfac.py rename to src/ekore/matching_conditions/as3/aHgstfac.py index 863c46536..4eed1890a 100644 --- a/src/eko/matching_conditions/as3/aHgstfac.py +++ b/src/ekore/matching_conditions/as3/aHgstfac.py @@ -10,7 +10,7 @@ def A_Hgstfac(n, sx, nf): The expression is presented in :cite:`Blumlein:2017wxd` (eq 3.1). When using the code, please cite the complete list of references - available in :mod:`eko.matching_conditions.as3`. + available in :mod:`ekore.matching_conditions.as3`. The expression contains some unknown parts which are set to 0. However we have included a shift to impose the gluon diff --git a/src/eko/matching_conditions/as3/aHq.py b/src/ekore/matching_conditions/as3/aHq.py similarity index 99% rename from src/eko/matching_conditions/as3/aHq.py rename to src/ekore/matching_conditions/as3/aHq.py index 18a0bb61c..6ea2968ec 100644 --- a/src/eko/matching_conditions/as3/aHq.py +++ b/src/ekore/matching_conditions/as3/aHq.py @@ -10,7 +10,7 @@ def A_Hq(n, sx, 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.as3`. + available in :mod:`ekore.matching_conditions.as3`. The part proportional to :math:`n_f^0` includes non trivial weight-5 harmonics and has been parametrized in Mellin space. diff --git a/src/eko/matching_conditions/as3/agg.py b/src/ekore/matching_conditions/as3/agg.py similarity index 99% rename from src/eko/matching_conditions/as3/agg.py rename to src/ekore/matching_conditions/as3/agg.py index 79debe7c3..b4783d83e 100644 --- a/src/eko/matching_conditions/as3/agg.py +++ b/src/ekore/matching_conditions/as3/agg.py @@ -11,7 +11,7 @@ def A_gg(n, sx, nf, L): # pylint: disable=too-many-locals 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.as3`. + available in :mod:`ekore.matching_conditions.as3`. Parameters ---------- @@ -31,7 +31,7 @@ def A_gg(n, sx, nf, L): # pylint: disable=too-many-locals See Also -------- - A_ggTF2: eko.matching_conditions.as3.aggTF2.A_ggTF2 + A_ggTF2: ekore.matching_conditions.as3.aggTF2.A_ggTF2 Incomplete part proportional to :math:`T_{F}^2`. """ diff --git a/src/eko/matching_conditions/as3/aggTF2.py b/src/ekore/matching_conditions/as3/aggTF2.py similarity index 99% rename from src/eko/matching_conditions/as3/aggTF2.py rename to src/ekore/matching_conditions/as3/aggTF2.py index 5e337c5f0..299006dc6 100644 --- a/src/eko/matching_conditions/as3/aggTF2.py +++ b/src/ekore/matching_conditions/as3/aggTF2.py @@ -10,7 +10,7 @@ def A_ggTF2(n, sx): 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.as3`. + available in :mod:`ekore.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/agq.py b/src/ekore/matching_conditions/as3/agq.py similarity index 99% rename from src/eko/matching_conditions/as3/agq.py rename to src/ekore/matching_conditions/as3/agq.py index 1d874021d..906e08e52 100644 --- a/src/eko/matching_conditions/as3/agq.py +++ b/src/ekore/matching_conditions/as3/agq.py @@ -8,7 +8,7 @@ def A_gq(n, sx, nf, L): # pylint: disable=too-many-locals The expression 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.as3`. + available in :mod:`ekore.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/aqg.py b/src/ekore/matching_conditions/as3/aqg.py similarity index 99% rename from src/eko/matching_conditions/as3/aqg.py rename to src/ekore/matching_conditions/as3/aqg.py index 33a059eb9..3c2cc36e4 100644 --- a/src/eko/matching_conditions/as3/aqg.py +++ b/src/ekore/matching_conditions/as3/aqg.py @@ -8,7 +8,7 @@ def A_qg(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.as3`. + available in :mod:`ekore.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/as3/aqqNS.py b/src/ekore/matching_conditions/as3/aqqNS.py similarity index 99% rename from src/eko/matching_conditions/as3/aqqNS.py rename to src/ekore/matching_conditions/as3/aqqNS.py index fdbf9114e..40be9ed69 100644 --- a/src/eko/matching_conditions/as3/aqqNS.py +++ b/src/ekore/matching_conditions/as3/aqqNS.py @@ -9,7 +9,7 @@ def A_qqNS(n, sx, nf, L): :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.as3`. + available in :mod:`ekore.matching_conditions.as3`. Note the part proportional to nf^0 includes weight = 5 harmonics and has been parametrized in Mellin space. diff --git a/src/eko/matching_conditions/as3/aqqPS.py b/src/ekore/matching_conditions/as3/aqqPS.py similarity index 99% rename from src/eko/matching_conditions/as3/aqqPS.py rename to src/ekore/matching_conditions/as3/aqqPS.py index a0f20af1c..ee8f136cd 100644 --- a/src/eko/matching_conditions/as3/aqqPS.py +++ b/src/ekore/matching_conditions/as3/aqqPS.py @@ -8,7 +8,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.as3`. + available in :mod:`ekore.matching_conditions.as3`. Parameters ---------- diff --git a/src/eko/matching_conditions/operator_matrix_element.py b/src/ekore/matching_conditions/operator_matrix_element.py similarity index 95% rename from src/eko/matching_conditions/operator_matrix_element.py rename to src/ekore/matching_conditions/operator_matrix_element.py index a8ad60109..c19cc2991 100644 --- a/src/eko/matching_conditions/operator_matrix_element.py +++ b/src/ekore/matching_conditions/operator_matrix_element.py @@ -9,9 +9,9 @@ import numba as nb import numpy as np -from .. import basis_rotation as br +from eko import basis_rotation as br from .. import harmonics -from ..evolution_operator import Operator, QuadKerBase +from eko.evolution_operator import Operator, QuadKerBase from . import as1, as2, as3 logger = logging.getLogger(__name__) @@ -46,10 +46,10 @@ def A_singlet(matching_order, n, sx, nf, L, is_msbar, sx_ns=None): See Also -------- - eko.matching_conditions.nlo.A_singlet_1 : :math:`A^{S,(1)}(N)` - eko.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` - eko.matching_conditions.nlo.A_gh_1 : :math:`A_{gH}^{(1)}(N)` - eko.matching_conditions.nnlo.A_singlet_2 : :math:`A_{S,(2)}(N)` + ekore.matching_conditions.nlo.A_singlet_1 : :math:`A^{S,(1)}(N)` + ekore.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` + ekore.matching_conditions.nlo.A_gh_1 : :math:`A_{gH}^{(1)}(N)` + ekore.matching_conditions.nnlo.A_singlet_2 : :math:`A_{S,(2)}(N)` """ A_s = np.zeros((matching_order[0], 3, 3), np.complex_) if matching_order[0] >= 1: @@ -86,8 +86,8 @@ def A_non_singlet(matching_order, n, sx, nf, L): See Also -------- - 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)}` + ekore.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` + ekore.matching_conditions.nnlo.A_ns_2 : :math:`A_{qq,H}^{NS,(2)}` """ A_ns = np.zeros((matching_order[0], 2, 2), np.complex_) if matching_order[0] >= 1: diff --git a/tests/eko/evolution_operator/test_init.py b/tests/eko/evolution_operator/test_init.py index dc8ddbd8e..d94ad542c 100644 --- a/tests/eko/evolution_operator/test_init.py +++ b/tests/eko/evolution_operator/test_init.py @@ -4,7 +4,7 @@ import scipy.integrate import eko.runner.legacy -from eko import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad from eko import basis_rotation as br from eko import interpolation, mellin from eko.evolution_operator import Operator, quad_ker diff --git a/tests/eko/evolution_operator/test_physical.py b/tests/eko/evolution_operator/test_physical.py index a02591d44..d28602aa6 100644 --- a/tests/eko/evolution_operator/test_physical.py +++ b/tests/eko/evolution_operator/test_physical.py @@ -4,7 +4,7 @@ from eko import basis_rotation as br from eko import member from eko.evolution_operator.physical import PhysicalOperator -from eko.matching_conditions import MatchingCondition +from ekore.matching_conditions import MatchingCondition def mkOM(shape): diff --git a/tests/eko/kernels/test_ns.py b/tests/eko/kernels/test_ns.py index 17d4964b8..350122948 100644 --- a/tests/eko/kernels/test_ns.py +++ b/tests/eko/kernels/test_ns.py @@ -3,7 +3,7 @@ import numpy as np import pytest -from eko import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad from eko import beta from eko.kernels import non_singlet as ns diff --git a/tests/eko/kernels/test_s.py b/tests/eko/kernels/test_s.py index ec4d93293..618699e84 100644 --- a/tests/eko/kernels/test_s.py +++ b/tests/eko/kernels/test_s.py @@ -3,7 +3,7 @@ import numpy as np import pytest -from eko import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad from eko.kernels import singlet as s methods = [ diff --git a/tests/eko/scale_variations/test_expanded.py b/tests/eko/scale_variations/test_expanded.py index bce253f9c..01eb80d08 100644 --- a/tests/eko/scale_variations/test_expanded.py +++ b/tests/eko/scale_variations/test_expanded.py @@ -1,7 +1,7 @@ import numpy as np from eko import basis_rotation as br -from eko.anomalous_dimensions import gamma_ns, gamma_singlet +from ekore.anomalous_dimensions import gamma_ns, gamma_singlet from eko.beta import beta_qcd_as2 from eko.kernels import non_singlet, singlet from eko.scale_variations import Modes, expanded, exponentiated diff --git a/tests/eko/test_beta.py b/tests/eko/test_beta.py index 4e2eb814e..fb089bb62 100644 --- a/tests/eko/test_beta.py +++ b/tests/eko/test_beta.py @@ -6,7 +6,7 @@ import pytest from eko import beta -from eko.harmonics.constants import zeta3 +from ekore.harmonics.constants import zeta3 def _flav_test(function): diff --git a/tests/eko/anomalous_dimensions/__init__.py b/tests/ekore/anomalous_dimensions/__init__.py similarity index 100% rename from tests/eko/anomalous_dimensions/__init__.py rename to tests/ekore/anomalous_dimensions/__init__.py diff --git a/tests/eko/anomalous_dimensions/test_aem1.py b/tests/ekore/anomalous_dimensions/test_aem1.py similarity index 93% rename from tests/eko/anomalous_dimensions/test_aem1.py rename to tests/ekore/anomalous_dimensions/test_aem1.py index 70ee30cc5..671cce1cf 100644 --- a/tests/eko/anomalous_dimensions/test_aem1.py +++ b/tests/ekore/anomalous_dimensions/test_aem1.py @@ -1,7 +1,7 @@ # Test LO splitting functions import numpy as np -from eko import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad def test_number_conservation(): diff --git a/tests/eko/anomalous_dimensions/test_aem2.py b/tests/ekore/anomalous_dimensions/test_aem2.py similarity index 94% rename from tests/eko/anomalous_dimensions/test_aem2.py rename to tests/ekore/anomalous_dimensions/test_aem2.py index aadbbfc2f..a124add68 100644 --- a/tests/eko/anomalous_dimensions/test_aem2.py +++ b/tests/ekore/anomalous_dimensions/test_aem2.py @@ -1,9 +1,9 @@ # Test O(as1aem1) splitting functions import numpy as np -from eko import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad from eko import constants -from eko import harmonics as h +from ekore import harmonics as h def test_number_conservation(): diff --git a/tests/eko/anomalous_dimensions/test_as1.py b/tests/ekore/anomalous_dimensions/test_as1.py similarity index 90% rename from tests/eko/anomalous_dimensions/test_as1.py rename to tests/ekore/anomalous_dimensions/test_as1.py index 14fd3d004..5f7f5671b 100644 --- a/tests/eko/anomalous_dimensions/test_as1.py +++ b/tests/ekore/anomalous_dimensions/test_as1.py @@ -1,9 +1,9 @@ # Test LO splitting functions import numpy as np -import eko.anomalous_dimensions.aem1 as ad_aem1 -import eko.anomalous_dimensions.as1 as ad_as1 -from eko import harmonics +import ekore.anomalous_dimensions.aem1 as ad_aem1 +import ekore.anomalous_dimensions.as1 as ad_as1 +from ekore import harmonics NF = 5 diff --git a/tests/eko/anomalous_dimensions/test_as1aem1.py b/tests/ekore/anomalous_dimensions/test_as1aem1.py similarity index 95% rename from tests/eko/anomalous_dimensions/test_as1aem1.py rename to tests/ekore/anomalous_dimensions/test_as1aem1.py index 988bb11f1..c1cd55f82 100644 --- a/tests/eko/anomalous_dimensions/test_as1aem1.py +++ b/tests/ekore/anomalous_dimensions/test_as1aem1.py @@ -2,9 +2,9 @@ import numpy as np import pytest -from eko import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad from eko import constants -from eko import harmonics as h +from ekore import harmonics as h def test_number_conservation(): diff --git a/tests/eko/anomalous_dimensions/test_as2.py b/tests/ekore/anomalous_dimensions/test_as2.py similarity index 98% rename from tests/eko/anomalous_dimensions/test_as2.py rename to tests/ekore/anomalous_dimensions/test_as2.py index 01d7f2f28..d49a6852f 100644 --- a/tests/eko/anomalous_dimensions/test_as2.py +++ b/tests/ekore/anomalous_dimensions/test_as2.py @@ -1,8 +1,8 @@ # Test NLO anomalous dims import numpy as np -import eko.anomalous_dimensions.as2 as ad_as2 -import eko.harmonics as h +import ekore.anomalous_dimensions.as2 as ad_as2 +import ekore.harmonics as h from eko import constants as const NF = 5 diff --git a/tests/eko/anomalous_dimensions/test_as3.py b/tests/ekore/anomalous_dimensions/test_as3.py similarity index 91% rename from tests/eko/anomalous_dimensions/test_as3.py rename to tests/ekore/anomalous_dimensions/test_as3.py index e0830c4a2..2b01fe2a9 100644 --- a/tests/eko/anomalous_dimensions/test_as3.py +++ b/tests/ekore/anomalous_dimensions/test_as3.py @@ -1,8 +1,8 @@ # Test NNLO anomalous dimensions import numpy as np -import eko.anomalous_dimensions.as3 as ad_as3 -from eko import harmonics as h +import ekore.anomalous_dimensions.as3 as ad_as3 +from ekore import harmonics as h NF = 5 diff --git a/tests/eko/anomalous_dimensions/test_as4.py b/tests/ekore/anomalous_dimensions/test_as4.py similarity index 98% rename from tests/eko/anomalous_dimensions/test_as4.py rename to tests/ekore/anomalous_dimensions/test_as4.py index 95c02f180..2a64df44c 100644 --- a/tests/eko/anomalous_dimensions/test_as4.py +++ b/tests/ekore/anomalous_dimensions/test_as4.py @@ -1,7 +1,7 @@ # Test N3LO anomalous dimensions import numpy as np -from eko.anomalous_dimensions.as4 import ( +from ekore.anomalous_dimensions.as4 import ( gamma_singlet, ggg, ggq, @@ -12,7 +12,7 @@ gqg, ) from eko.constants import CA, CF -from eko.harmonics import compute_cache +from ekore.harmonics import compute_cache NF = 5 diff --git a/tests/eko/anomalous_dimensions/test_init.py b/tests/ekore/anomalous_dimensions/test_init.py similarity index 95% rename from tests/eko/anomalous_dimensions/test_init.py rename to tests/ekore/anomalous_dimensions/test_init.py index a080cdd1b..72ecbf99f 100644 --- a/tests/eko/anomalous_dimensions/test_init.py +++ b/tests/ekore/anomalous_dimensions/test_init.py @@ -4,10 +4,10 @@ import numpy as np from numpy.testing import assert_allclose, assert_almost_equal, assert_raises -from eko import anomalous_dimensions as ad +from ekore import anomalous_dimensions as ad from eko import basis_rotation as br -from eko.anomalous_dimensions import as1 as ad_as1 -from eko.anomalous_dimensions import harmonics +from ekore.anomalous_dimensions import as1 as ad_as1 +from ekore.anomalous_dimensions import harmonics NF = 5 diff --git a/tests/eko/harmonics/__init__.py b/tests/ekore/harmonics/__init__.py similarity index 100% rename from tests/eko/harmonics/__init__.py rename to tests/ekore/harmonics/__init__.py diff --git a/tests/eko/harmonics/test_f_functions.py b/tests/ekore/harmonics/test_f_functions.py similarity index 98% rename from tests/eko/harmonics/test_f_functions.py rename to tests/ekore/harmonics/test_f_functions.py index 943dd7131..89136a9a6 100644 --- a/tests/eko/harmonics/test_f_functions.py +++ b/tests/ekore/harmonics/test_f_functions.py @@ -2,8 +2,8 @@ import numpy as np -from eko import harmonics -from eko.harmonics import w5 +from ekore import harmonics +from ekore.harmonics import w5 zeta2 = harmonics.constants.zeta2 zeta3 = harmonics.constants.zeta3 diff --git a/tests/eko/harmonics/test_g_functions.py b/tests/ekore/harmonics/test_g_functions.py similarity index 98% rename from tests/eko/harmonics/test_g_functions.py rename to tests/ekore/harmonics/test_g_functions.py index 4dc1e758f..dff9964f6 100644 --- a/tests/eko/harmonics/test_g_functions.py +++ b/tests/ekore/harmonics/test_g_functions.py @@ -2,7 +2,7 @@ import numpy as np -from eko.anomalous_dimensions import harmonics as h +from ekore.anomalous_dimensions import harmonics as h zeta3 = h.constants.zeta3 log2 = h.constants.log2 diff --git a/tests/eko/harmonics/test_init.py b/tests/ekore/harmonics/test_init.py similarity index 99% rename from tests/eko/harmonics/test_init.py rename to tests/ekore/harmonics/test_init.py index fbaa4cea4..dc4e39637 100644 --- a/tests/eko/harmonics/test_init.py +++ b/tests/ekore/harmonics/test_init.py @@ -1,6 +1,6 @@ import numpy as np -from eko import harmonics as h +from ekore import harmonics as h def test_spm1(): diff --git a/tests/eko/harmonics/test_log_functions.py b/tests/ekore/harmonics/test_log_functions.py similarity index 97% rename from tests/eko/harmonics/test_log_functions.py rename to tests/ekore/harmonics/test_log_functions.py index e53f13c11..2f3ad4e90 100644 --- a/tests/eko/harmonics/test_log_functions.py +++ b/tests/ekore/harmonics/test_log_functions.py @@ -1,7 +1,7 @@ import numpy as np from scipy.integrate import quad -from eko import harmonics as h +from ekore import harmonics as h def test_lm1pm1(): diff --git a/tests/eko/harmonics/test_polygamma.py b/tests/ekore/harmonics/test_polygamma.py similarity index 99% rename from tests/eko/harmonics/test_polygamma.py rename to tests/ekore/harmonics/test_polygamma.py index a790d3828..7ea4389dd 100644 --- a/tests/eko/harmonics/test_polygamma.py +++ b/tests/ekore/harmonics/test_polygamma.py @@ -1,7 +1,7 @@ import numpy as np import pytest -from eko import harmonics +from ekore import harmonics # until https://github.com/numba/numba/pull/5660 is confirmed # we need to deactivate numba prior running diff --git a/tests/eko/matching_conditions/__init__.py b/tests/ekore/matching_conditions/__init__.py similarity index 100% rename from tests/eko/matching_conditions/__init__.py rename to tests/ekore/matching_conditions/__init__.py diff --git a/tests/eko/matching_conditions/test_init.py b/tests/ekore/matching_conditions/test_init.py similarity index 98% rename from tests/eko/matching_conditions/test_init.py rename to tests/ekore/matching_conditions/test_init.py index ab93c3487..e0378a515 100644 --- a/tests/eko/matching_conditions/test_init.py +++ b/tests/ekore/matching_conditions/test_init.py @@ -3,7 +3,7 @@ from eko import basis_rotation as br from eko import member -from eko.matching_conditions import MatchingCondition +from ekore.matching_conditions import MatchingCondition def mkOM(shape): diff --git a/tests/eko/matching_conditions/test_n3lo.py b/tests/ekore/matching_conditions/test_n3lo.py similarity index 98% rename from tests/eko/matching_conditions/test_n3lo.py rename to tests/ekore/matching_conditions/test_n3lo.py index 377e1b606..56d0b8df9 100644 --- a/tests/eko/matching_conditions/test_n3lo.py +++ b/tests/ekore/matching_conditions/test_n3lo.py @@ -1,9 +1,9 @@ # Test N3LO OME import numpy as np -from eko.harmonics import compute_cache -from eko.matching_conditions import as3 -from eko.matching_conditions.as3 import A_ns, A_qqNS, A_singlet +from ekore.harmonics import compute_cache +from ekore.matching_conditions import as3 +from ekore.matching_conditions.as3 import A_ns, A_qqNS, A_singlet def test_A_3(): diff --git a/tests/eko/matching_conditions/test_nlo.py b/tests/ekore/matching_conditions/test_nlo.py similarity index 93% rename from tests/eko/matching_conditions/test_nlo.py rename to tests/ekore/matching_conditions/test_nlo.py index b7f03cc82..cc5700b30 100644 --- a/tests/eko/matching_conditions/test_nlo.py +++ b/tests/ekore/matching_conditions/test_nlo.py @@ -1,8 +1,8 @@ # Test NLO OME import numpy as np -from eko.harmonics import compute_cache -from eko.matching_conditions.as1 import A_ns, A_singlet +from ekore.harmonics import compute_cache +from ekore.matching_conditions.as1 import A_ns, A_singlet def test_A_1_intrinsic(): diff --git a/tests/eko/matching_conditions/test_nnlo.py b/tests/ekore/matching_conditions/test_nnlo.py similarity index 97% rename from tests/eko/matching_conditions/test_nnlo.py rename to tests/ekore/matching_conditions/test_nnlo.py index aea957e95..98aeddcbe 100644 --- a/tests/eko/matching_conditions/test_nnlo.py +++ b/tests/ekore/matching_conditions/test_nnlo.py @@ -2,8 +2,8 @@ import numpy as np -from eko.harmonics import compute_cache, constants -from eko.matching_conditions.as2 import A_ns, A_qq_ns, A_singlet +from ekore.harmonics import compute_cache, constants +from ekore.matching_conditions.as2 import A_ns, A_qq_ns, A_singlet def test_A_2(): diff --git a/tests/eko/matching_conditions/test_ome.py b/tests/ekore/matching_conditions/test_ome.py similarity index 97% rename from tests/eko/matching_conditions/test_ome.py rename to tests/ekore/matching_conditions/test_ome.py index 2df26a03f..aeb67ddec 100644 --- a/tests/eko/matching_conditions/test_ome.py +++ b/tests/ekore/matching_conditions/test_ome.py @@ -1,14 +1,14 @@ -# Test eko.matching_conditions.OperatorMatrixElement +# Test ekore.matching_conditions.OperatorMatrixElement import pathlib import numpy as np from eko import basis_rotation as br from eko import interpolation, mellin -from eko.harmonics import compute_cache +from ekore.harmonics import compute_cache from eko.io.runcards import OperatorCard, TheoryCard from eko.io.types import InversionMethod -from eko.matching_conditions.operator_matrix_element import ( +from ekore.matching_conditions.operator_matrix_element import ( A_non_singlet, A_singlet, OperatorMatrixElement, @@ -88,12 +88,12 @@ def test_quad_ker(monkeypatch): monkeypatch.setattr(interpolation, "evaluate_Nx", lambda *args: 1) zeros = np.zeros((2, 2)) monkeypatch.setattr( - "eko.matching_conditions.operator_matrix_element.A_non_singlet", + "ekore.matching_conditions.operator_matrix_element.A_non_singlet", lambda *args: np.array([zeros, zeros, zeros]), ) zeros = np.zeros((3, 3)) monkeypatch.setattr( - "eko.matching_conditions.operator_matrix_element.A_singlet", + "ekore.matching_conditions.operator_matrix_element.A_singlet", lambda *args: np.array([zeros, zeros, zeros]), ) for is_log in [True, False]: From 85c2da69f10dc561c4dd3f25e9394296f8b601b9 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 12 Jan 2023 12:53:29 +0100 Subject: [PATCH 02/30] Move ads to new layout --- benchmarks/eko/benchmark_ad.py | 2 +- benchmarks/performance/harmonics.py | 2 +- src/eko/evolution_operator/__init__.py | 2 +- src/ekore/anomalous_dimensions/__init__.py | 144 ---------------- .../unpolarized/__init.py | 0 .../unpolarized/space_like/__init__.py | 156 ++++++++++++++++++ .../{ => unpolarized/space_like}/aem1.py | 0 .../{ => unpolarized/space_like}/aem2.py | 0 .../{ => unpolarized/space_like}/as1.py | 0 .../{ => unpolarized/space_like}/as1aem1.py | 4 +- .../{ => unpolarized/space_like}/as2.py | 4 +- .../{ => unpolarized/space_like}/as3.py | 2 +- .../space_like}/as4/__init__.py | 0 .../{ => unpolarized/space_like}/as4/ggg.py | 2 +- .../{ => unpolarized/space_like}/as4/ggq.py | 2 +- .../{ => unpolarized/space_like}/as4/gnsm.py | 4 +- .../{ => unpolarized/space_like}/as4/gnsp.py | 2 +- .../{ => unpolarized/space_like}/as4/gnsv.py | 0 .../{ => unpolarized/space_like}/as4/gps.py | 0 .../{ => unpolarized/space_like}/as4/gqg.py | 2 +- tests/eko/evolution_operator/test_init.py | 2 +- tests/eko/kernels/test_ns.py | 2 +- tests/eko/scale_variations/test_expanded.py | 2 +- .../unpolarized/__init__.py | 0 .../unpolarized/space_like/__init__.py | 0 .../{ => unpolarized/space_like}/test_aem1.py | 13 +- .../{ => unpolarized/space_like}/test_aem2.py | 2 +- .../{ => unpolarized/space_like}/test_as1.py | 3 +- .../space_like}/test_as1aem1.py | 2 +- .../{ => unpolarized/space_like}/test_as2.py | 2 +- .../{ => unpolarized/space_like}/test_as3.py | 2 +- .../{ => unpolarized/space_like}/test_as4.py | 2 +- .../{ => unpolarized/space_like}/test_init.py | 21 +-- tests/ekore/harmonics/test_g_functions.py | 2 +- 34 files changed, 198 insertions(+), 185 deletions(-) create mode 100644 src/ekore/anomalous_dimensions/unpolarized/__init.py create mode 100644 src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/aem1.py (100%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/aem2.py (100%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as1.py (100%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as1aem1.py (99%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as2.py (99%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as3.py (99%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as4/__init__.py (100%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as4/ggg.py (99%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as4/ggq.py (98%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as4/gnsm.py (98%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as4/gnsp.py (98%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as4/gnsv.py (100%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as4/gps.py (100%) rename src/ekore/anomalous_dimensions/{ => unpolarized/space_like}/as4/gqg.py (99%) create mode 100644 tests/ekore/anomalous_dimensions/unpolarized/__init__.py create mode 100644 tests/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py rename tests/ekore/anomalous_dimensions/{ => unpolarized/space_like}/test_aem1.py (57%) rename tests/ekore/anomalous_dimensions/{ => unpolarized/space_like}/test_aem2.py (95%) rename tests/ekore/anomalous_dimensions/{ => unpolarized/space_like}/test_as1.py (92%) rename tests/ekore/anomalous_dimensions/{ => unpolarized/space_like}/test_as1aem1.py (96%) rename tests/ekore/anomalous_dimensions/{ => unpolarized/space_like}/test_as2.py (98%) rename tests/ekore/anomalous_dimensions/{ => unpolarized/space_like}/test_as3.py (93%) rename tests/ekore/anomalous_dimensions/{ => unpolarized/space_like}/test_as4.py (99%) rename tests/ekore/anomalous_dimensions/{ => unpolarized/space_like}/test_init.py (75%) diff --git a/benchmarks/eko/benchmark_ad.py b/benchmarks/eko/benchmark_ad.py index d7f1baa39..08919150e 100644 --- a/benchmarks/eko/benchmark_ad.py +++ b/benchmarks/eko/benchmark_ad.py @@ -2,7 +2,7 @@ import numpy as np import pytest -import ekore.anomalous_dimensions.as2 as ad_as2 +import ekore.anomalous_dimensions.unpolarized.space_like.as2 as ad_as2 import ekore.harmonics as h from eko.constants import CA, CF, TR diff --git a/benchmarks/performance/harmonics.py b/benchmarks/performance/harmonics.py index e794aafde..c0b7c4a95 100644 --- a/benchmarks/performance/harmonics.py +++ b/benchmarks/performance/harmonics.py @@ -1,6 +1,6 @@ import numpy as np -from ekore import anomalous_dimensions as ad +import ekore.anomalous_dimensions.unpolarized.space_like as ad from eko.mellin import Path NF = 5 diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 544fde4cc..2b047083f 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -13,7 +13,7 @@ import numpy as np from scipy import integrate -from ekore import anomalous_dimensions as ad +import ekore.anomalous_dimensions.unpolarized.space_like as ad from .. import basis_rotation as br from .. import interpolation, mellin from .. import scale_variations as sv diff --git a/src/ekore/anomalous_dimensions/__init__.py b/src/ekore/anomalous_dimensions/__init__.py index 69c9865d7..47a877c03 100644 --- a/src/ekore/anomalous_dimensions/__init__.py +++ b/src/ekore/anomalous_dimensions/__init__.py @@ -19,10 +19,6 @@ import numba as nb import numpy as np -from eko import basis_rotation as br -from .. import harmonics -from . import aem1, aem2, as1, as1aem1, as2, as3, as4 - @nb.njit(cache=True) def exp_singlet(gamma_S): @@ -50,12 +46,6 @@ def exp_singlet(gamma_S): e_m : numpy.ndarray projector for the negative eigenvalue of the singlet anomalous dimension matrix :math:`\gamma_{S}(N)` - - See Also - -------- - ekore.anomalous_dimensions.as1.gamma_singlet : :math:`\gamma_{S}^{(0)}(N)` - ekore.anomalous_dimensions.as2.gamma_singlet : :math:`\gamma_{S}^{(1)}(N)` - ekore.anomalous_dimensions.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` """ # compute eigenvalues det = np.sqrt( @@ -70,137 +60,3 @@ def exp_singlet(gamma_S): e_m = -c * (gamma_S - lambda_p * identity) exp = e_m * np.exp(lambda_m) + e_p * np.exp(lambda_p) return exp, lambda_p, lambda_m, e_p, e_m - - -@nb.njit(cache=True) -def gamma_ns(order, mode, n, nf): - r"""Computes the tower of the non-singlet anomalous dimensions - - Parameters - ---------- - order : tuple(int,int) - perturbative orders - mode : 10201 | 10101 | 10200 - sector identifier - n : complex - Mellin variable - nf : int - Number of active flavors - - Returns - ------- - numpy.ndarray - non-singlet anomalous dimensions - - See Also - -------- - ekore.anomalous_dimensions.as1.gamma_ns : :math:`\gamma_{ns}^{(0)}(N)` - ekore.anomalous_dimensions.as2.gamma_nsp : :math:`\gamma_{ns,+}^{(1)}(N)` - ekore.anomalous_dimensions.as2.gamma_nsm : :math:`\gamma_{ns,-}^{(1)}(N)` - ekore.anomalous_dimensions.as3.gamma_nsp : :math:`\gamma_{ns,+}^{(2)}(N)` - ekore.anomalous_dimensions.as3.gamma_nsm : :math:`\gamma_{ns,-}^{(2)}(N)` - ekore.anomalous_dimensions.as3.gamma_nsv : :math:`\gamma_{ns,v}^{(2)}(N)` - ekore.anomalous_dimensions.as4.gamma_nsp : :math:`\gamma_{ns,+}^{(3)}(N)` - ekore.anomalous_dimensions.as4.gamma_nsm : :math:`\gamma_{ns,-}^{(3)}(N)` - ekore.anomalous_dimensions.as4.gamma_nsv : :math:`\gamma_{ns,v}^{(3)}(N)` - - """ - # cache the s-es - if order[0] >= 4: - full_sx_cache = harmonics.compute_cache(n, 5, is_singlet=False) - sx = np.array( - [ - full_sx_cache[0][0], - full_sx_cache[1][0], - full_sx_cache[2][0], - full_sx_cache[3][0], - ] - ) - else: - sx = harmonics.sx(n, max_weight=order[0] + 1) - # now combine - gamma_ns = np.zeros(order[0], np.complex_) - gamma_ns[0] = as1.gamma_ns(n, sx[0]) - # NLO and beyond - if order[0] >= 2: - 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 - elif mode in [10201, 10200]: - 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[0] >= 3: - if mode == 10101: - gamma_ns_2 = as3.gamma_nsp(n, nf, sx) - elif mode == 10201: - gamma_ns_2 = as3.gamma_nsm(n, nf, sx) - elif mode == 10200: - gamma_ns_2 = as3.gamma_nsv(n, nf, sx) - gamma_ns[2] = gamma_ns_2 - # N3LO - if order[0] >= 4: - if mode == 10101: - gamma_ns_3 = as4.gamma_nsp(n, nf, full_sx_cache) - elif mode == 10201: - gamma_ns_3 = as4.gamma_nsm(n, nf, full_sx_cache) - elif mode == 10200: - gamma_ns_3 = as4.gamma_nsv(n, nf, full_sx_cache) - gamma_ns[3] = gamma_ns_3 - return gamma_ns - - -@nb.njit(cache=True) -def gamma_singlet(order, n, nf): - r"""Computes the tower of the singlet anomalous dimensions matrices - - Parameters - ---------- - order : tuple(int,int) - perturbative orders - n : complex - Mellin variable - nf : int - Number of active flavors - - Returns - ------- - numpy.ndarray - singlet anomalous dimensions matrices - - See Also - -------- - ekore.anomalous_dimensions.as1.gamma_singlet : :math:`\gamma_{S}^{(0)}(N)` - ekore.anomalous_dimensions.as2.gamma_singlet : :math:`\gamma_{S}^{(1)}(N)` - ekore.anomalous_dimensions.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` - ekore.anomalous_dimensions.as4.gamma_singlet : :math:`\gamma_{S}^{(3)}(N)` - - """ - # cache the s-es - if order[0] >= 4: - full_sx_cache = harmonics.compute_cache(n, 5, is_singlet=False) - sx = np.array( - [ - full_sx_cache[0][0], - full_sx_cache[1][0], - full_sx_cache[2][0], - full_sx_cache[3][0], - ] - ) - elif order[0] >= 3: - # here we need only S1,S2,S3,S4 - sx = harmonics.sx(n, max_weight=order[0] + 1) - else: - sx = harmonics.sx(n, max_weight=order[0]) - - gamma_s = np.zeros((order[0], 2, 2), np.complex_) - gamma_s[0] = as1.gamma_singlet(n, sx[0], nf) - if order[0] >= 2: - gamma_s[1] = as2.gamma_singlet(n, nf, sx) - if order[0] >= 3: - gamma_s[2] = as3.gamma_singlet(n, nf, sx) - if order[0] >= 4: - gamma_s[3] = as4.gamma_singlet(n, nf, full_sx_cache) - return gamma_s diff --git a/src/ekore/anomalous_dimensions/unpolarized/__init.py b/src/ekore/anomalous_dimensions/unpolarized/__init.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py new file mode 100644 index 000000000..134596498 --- /dev/null +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py @@ -0,0 +1,156 @@ +r""" +This module contains the Altarelli-Parisi splitting kernels. + +Normalization is given by + +.. math:: + \mathbf{P}(x) = \sum\limits_{j=0} a_s^{j+1} \mathbf P^{(j)}(x) + +with :math:`a_s = \frac{\alpha_S(\mu^2)}{4\pi}`. +The 3-loop references for the non-singlet :cite:`Moch:2004pa` +and singlet :cite:`Vogt:2004mw` case contain also the lower +order results. The results are also determined in Mellin space in +terms of the anomalous dimensions (note the additional sign!) + +.. math:: + \gamma(N) = - \mathcal{M}[\mathbf{P}(x)](N) +""" + +import numba as nb +import numpy as np + +from .... import harmonics +from . import as1, as2, as3, as4, aem1, aem2 + +@nb.njit(cache=True) +def gamma_ns(order, mode, n, nf): + r"""Computes the tower of the non-singlet anomalous dimensions + + Parameters + ---------- + order : tuple(int,int) + perturbative orders + mode : 10201 | 10101 | 10200 + sector identifier + n : complex + Mellin variable + nf : int + Number of active flavors + + Returns + ------- + numpy.ndarray + non-singlet anomalous dimensions + + See Also + -------- + ekore.anomalous_dimensions.unpolarized.space_like.as1.gamma_ns : :math:`\gamma_{ns}^{(0)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as2.gamma_nsp : :math:`\gamma_{ns,+}^{(1)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as2.gamma_nsm : :math:`\gamma_{ns,-}^{(1)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as3.gamma_nsp : :math:`\gamma_{ns,+}^{(2)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as3.gamma_nsm : :math:`\gamma_{ns,-}^{(2)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as3.gamma_nsv : :math:`\gamma_{ns,v}^{(2)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as4.gamma_nsp : :math:`\gamma_{ns,+}^{(3)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as4.gamma_nsm : :math:`\gamma_{ns,-}^{(3)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as4.gamma_nsv : :math:`\gamma_{ns,v}^{(3)}(N)` + + """ + # cache the s-es + if order[0] >= 4: + full_sx_cache = harmonics.compute_cache(n, 5, is_singlet=False) + sx = np.array( + [ + full_sx_cache[0][0], + full_sx_cache[1][0], + full_sx_cache[2][0], + full_sx_cache[3][0], + ] + ) + else: + sx = harmonics.sx(n, max_weight=order[0] + 1) + # now combine + gamma_ns = np.zeros(order[0], np.complex_) + gamma_ns[0] = as1.gamma_ns(n, sx[0]) + # NLO and beyond + if order[0] >= 2: + 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 + elif mode in [10201, 10200]: + 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[0] >= 3: + if mode == 10101: + gamma_ns_2 = as3.gamma_nsp(n, nf, sx) + elif mode == 10201: + gamma_ns_2 = as3.gamma_nsm(n, nf, sx) + elif mode == 10200: + gamma_ns_2 = as3.gamma_nsv(n, nf, sx) + gamma_ns[2] = gamma_ns_2 + # N3LO + if order[0] >= 4: + if mode == 10101: + gamma_ns_3 = as4.gamma_nsp(n, nf, full_sx_cache) + elif mode == 10201: + gamma_ns_3 = as4.gamma_nsm(n, nf, full_sx_cache) + elif mode == 10200: + gamma_ns_3 = as4.gamma_nsv(n, nf, full_sx_cache) + gamma_ns[3] = gamma_ns_3 + return gamma_ns + + +@nb.njit(cache=True) +def gamma_singlet(order, n, nf): + r"""Computes the tower of the singlet anomalous dimensions matrices + + Parameters + ---------- + order : tuple(int,int) + perturbative orders + n : complex + Mellin variable + nf : int + Number of active flavors + + Returns + ------- + numpy.ndarray + singlet anomalous dimensions matrices + + See Also + -------- + ekore.anomalous_dimensions.unpolarized.space_like.as1.gamma_singlet : :math:`\gamma_{S}^{(0)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as2.gamma_singlet : :math:`\gamma_{S}^{(1)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` + ekore.anomalous_dimensions.unpolarized.space_like.as4.gamma_singlet : :math:`\gamma_{S}^{(3)}(N)` + + """ + # cache the s-es + if order[0] >= 4: + full_sx_cache = harmonics.compute_cache(n, 5, is_singlet=False) + sx = np.array( + [ + full_sx_cache[0][0], + full_sx_cache[1][0], + full_sx_cache[2][0], + full_sx_cache[3][0], + ] + ) + elif order[0] >= 3: + # here we need only S1,S2,S3,S4 + sx = harmonics.sx(n, max_weight=order[0] + 1) + else: + sx = harmonics.sx(n, max_weight=order[0]) + + gamma_s = np.zeros((order[0], 2, 2), np.complex_) + gamma_s[0] = as1.gamma_singlet(n, sx[0], nf) + if order[0] >= 2: + gamma_s[1] = as2.gamma_singlet(n, nf, sx) + if order[0] >= 3: + gamma_s[2] = as3.gamma_singlet(n, nf, sx) + if order[0] >= 4: + gamma_s[3] = as4.gamma_singlet(n, nf, full_sx_cache) + return gamma_s diff --git a/src/ekore/anomalous_dimensions/aem1.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/aem1.py similarity index 100% rename from src/ekore/anomalous_dimensions/aem1.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/aem1.py diff --git a/src/ekore/anomalous_dimensions/aem2.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/aem2.py similarity index 100% rename from src/ekore/anomalous_dimensions/aem2.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/aem2.py diff --git a/src/ekore/anomalous_dimensions/as1.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py similarity index 100% rename from src/ekore/anomalous_dimensions/as1.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py diff --git a/src/ekore/anomalous_dimensions/as1aem1.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py similarity index 99% rename from src/ekore/anomalous_dimensions/as1aem1.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py index d2b7ebebc..e16133a05 100644 --- a/src/ekore/anomalous_dimensions/as1aem1.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py @@ -5,8 +5,8 @@ import numba as nb from eko import constants -from .. import harmonics -from ..harmonics.constants import zeta2, zeta3 +from .... import harmonics +from ....harmonics.constants import zeta2, zeta3 @nb.njit(cache=True) diff --git a/src/ekore/anomalous_dimensions/as2.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py similarity index 99% rename from src/ekore/anomalous_dimensions/as2.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py index e51034a5b..8691a54b2 100644 --- a/src/ekore/anomalous_dimensions/as2.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py @@ -10,8 +10,8 @@ import numpy as np from eko import constants -from .. import harmonics -from ..harmonics.constants import log2, zeta2, zeta3 +from .... import harmonics +from ....harmonics.constants import log2, zeta2, zeta3 @nb.njit(cache=True) diff --git a/src/ekore/anomalous_dimensions/as3.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py similarity index 99% rename from src/ekore/anomalous_dimensions/as3.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py index d1b8171a1..a2387bd08 100644 --- a/src/ekore/anomalous_dimensions/as3.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py @@ -8,7 +8,7 @@ import numba as nb import numpy as np -from ..harmonics.constants import zeta2, zeta3 +from ....harmonics.constants import zeta2, zeta3 @nb.njit(cache=True) diff --git a/src/ekore/anomalous_dimensions/as4/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py similarity index 100% rename from src/ekore/anomalous_dimensions/as4/__init__.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py diff --git a/src/ekore/anomalous_dimensions/as4/ggg.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggg.py similarity index 99% rename from src/ekore/anomalous_dimensions/as4/ggg.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggg.py index 8570bb3c6..c627b474f 100644 --- a/src/ekore/anomalous_dimensions/as4/ggg.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggg.py @@ -3,7 +3,7 @@ import numba as nb import numpy as np -from ...harmonics.log_functions import lm11 +from .....harmonics.log_functions import lm11 @nb.njit(cache=True) diff --git a/src/ekore/anomalous_dimensions/as4/ggq.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py similarity index 98% rename from src/ekore/anomalous_dimensions/as4/ggq.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py index eb7d96bc1..4752328dc 100644 --- a/src/ekore/anomalous_dimensions/as4/ggq.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py @@ -3,7 +3,7 @@ import numba as nb import numpy as np -from ...harmonics.log_functions import lm13, lm13m1, lm14, lm15 +from .....harmonics.log_functions import lm13, lm13m1, lm14, lm15 @nb.njit(cache=True) diff --git a/src/ekore/anomalous_dimensions/as4/gnsm.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py similarity index 98% rename from src/ekore/anomalous_dimensions/as4/gnsm.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py index ae50c68ba..336d5b568 100644 --- a/src/ekore/anomalous_dimensions/as4/gnsm.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py @@ -4,8 +4,8 @@ import numba as nb from eko.constants import CF -from ...harmonics.constants import zeta3 -from ...harmonics.log_functions import lm11m1, lm12m1, lm13m1 +from .....harmonics.constants import zeta3 +from .....harmonics.log_functions import lm11m1, lm12m1, lm13m1 @nb.njit(cache=True) diff --git a/src/ekore/anomalous_dimensions/as4/gnsp.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py similarity index 98% rename from src/ekore/anomalous_dimensions/as4/gnsp.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py index 1f96efc16..9f5be5c4d 100644 --- a/src/ekore/anomalous_dimensions/as4/gnsp.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py @@ -3,7 +3,7 @@ """ import numba as nb -from ...harmonics.log_functions import lm11m1, lm12m1, lm13m1 +from .....harmonics.log_functions import lm11m1, lm12m1, lm13m1 from .gnsm import gamma_ns_nf3 diff --git a/src/ekore/anomalous_dimensions/as4/gnsv.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py similarity index 100% rename from src/ekore/anomalous_dimensions/as4/gnsv.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py diff --git a/src/ekore/anomalous_dimensions/as4/gps.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gps.py similarity index 100% rename from src/ekore/anomalous_dimensions/as4/gps.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gps.py diff --git a/src/ekore/anomalous_dimensions/as4/gqg.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gqg.py similarity index 99% rename from src/ekore/anomalous_dimensions/as4/gqg.py rename to src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gqg.py index f23cfef01..7f146eebc 100644 --- a/src/ekore/anomalous_dimensions/as4/gqg.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gqg.py @@ -3,7 +3,7 @@ import numba as nb import numpy as np -from ...harmonics.log_functions import lm13, lm13m1, lm14, lm15 +from .....harmonics.log_functions import lm13, lm13m1, lm14, lm15 @nb.njit(cache=True) diff --git a/tests/eko/evolution_operator/test_init.py b/tests/eko/evolution_operator/test_init.py index d94ad542c..a801f5c56 100644 --- a/tests/eko/evolution_operator/test_init.py +++ b/tests/eko/evolution_operator/test_init.py @@ -4,7 +4,7 @@ import scipy.integrate import eko.runner.legacy -from ekore import anomalous_dimensions as ad +import ekore.anomalous_dimensions.unpolarized.space_like as ad from eko import basis_rotation as br from eko import interpolation, mellin from eko.evolution_operator import Operator, quad_ker diff --git a/tests/eko/kernels/test_ns.py b/tests/eko/kernels/test_ns.py index 350122948..9e89492aa 100644 --- a/tests/eko/kernels/test_ns.py +++ b/tests/eko/kernels/test_ns.py @@ -3,7 +3,7 @@ import numpy as np import pytest -from ekore import anomalous_dimensions as ad +import ekore.anomalous_dimensions.unpolarized.space_like as ad from eko import beta from eko.kernels import non_singlet as ns diff --git a/tests/eko/scale_variations/test_expanded.py b/tests/eko/scale_variations/test_expanded.py index 01eb80d08..7c3f37ee3 100644 --- a/tests/eko/scale_variations/test_expanded.py +++ b/tests/eko/scale_variations/test_expanded.py @@ -1,7 +1,7 @@ import numpy as np from eko import basis_rotation as br -from ekore.anomalous_dimensions import gamma_ns, gamma_singlet +from ekore.anomalous_dimensions.unpolarized.space_like import gamma_ns, gamma_singlet from eko.beta import beta_qcd_as2 from eko.kernels import non_singlet, singlet from eko.scale_variations import Modes, expanded, exponentiated diff --git a/tests/ekore/anomalous_dimensions/unpolarized/__init__.py b/tests/ekore/anomalous_dimensions/unpolarized/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/ekore/anomalous_dimensions/test_aem1.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_aem1.py similarity index 57% rename from tests/ekore/anomalous_dimensions/test_aem1.py rename to tests/ekore/anomalous_dimensions/unpolarized/space_like/test_aem1.py index 671cce1cf..0cf4d26e1 100644 --- a/tests/ekore/anomalous_dimensions/test_aem1.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_aem1.py @@ -1,22 +1,23 @@ # Test LO splitting functions import numpy as np -from ekore import anomalous_dimensions as ad +import ekore.harmonics as h +import ekore.anomalous_dimensions.unpolarized.space_like as ad_us def test_number_conservation(): # number N = complex(1.0, 0.0) - s1 = ad.harmonics.S1(N) - np.testing.assert_almost_equal(ad.aem1.gamma_ns(N, s1), 0) + s1 = h.S1(N) + np.testing.assert_almost_equal(ad_us.aem1.gamma_ns(N, s1), 0) def test_quark_momentum_conservation(): # quark momentum N = complex(2.0, 0.0) - s1 = ad.harmonics.S1(N) + s1 = h.S1(N) np.testing.assert_almost_equal( - ad.aem1.gamma_ns(N, s1) + ad.aem1.gamma_phq(N), + ad_us.aem1.gamma_ns(N, s1) + ad_us.aem1.gamma_phq(N), 0, ) @@ -26,5 +27,5 @@ def test_photon_momentum_conservation(): N = complex(2.0, 0.0) for NF in range(2, 6 + 1): np.testing.assert_almost_equal( - ad.aem1.gamma_qph(N, NF) + ad.aem1.gamma_phph(NF), 0 + ad_us.aem1.gamma_qph(N, NF) + ad_us.aem1.gamma_phph(NF), 0 ) diff --git a/tests/ekore/anomalous_dimensions/test_aem2.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_aem2.py similarity index 95% rename from tests/ekore/anomalous_dimensions/test_aem2.py rename to tests/ekore/anomalous_dimensions/unpolarized/space_like/test_aem2.py index a124add68..0a1ddabde 100644 --- a/tests/ekore/anomalous_dimensions/test_aem2.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_aem2.py @@ -1,7 +1,7 @@ # Test O(as1aem1) splitting functions import numpy as np -from ekore import anomalous_dimensions as ad +import ekore.anomalous_dimensions.unpolarized.space_like as ad from eko import constants from ekore import harmonics as h diff --git a/tests/ekore/anomalous_dimensions/test_as1.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as1.py similarity index 92% rename from tests/ekore/anomalous_dimensions/test_as1.py rename to tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as1.py index 5f7f5671b..23cd67d50 100644 --- a/tests/ekore/anomalous_dimensions/test_as1.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as1.py @@ -1,8 +1,7 @@ # Test LO splitting functions import numpy as np -import ekore.anomalous_dimensions.aem1 as ad_aem1 -import ekore.anomalous_dimensions.as1 as ad_as1 +import ekore.anomalous_dimensions.unpolarized.space_like.as1 as ad_as1 from ekore import harmonics NF = 5 diff --git a/tests/ekore/anomalous_dimensions/test_as1aem1.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as1aem1.py similarity index 96% rename from tests/ekore/anomalous_dimensions/test_as1aem1.py rename to tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as1aem1.py index c1cd55f82..ce77d4f3a 100644 --- a/tests/ekore/anomalous_dimensions/test_as1aem1.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as1aem1.py @@ -2,7 +2,7 @@ import numpy as np import pytest -from ekore import anomalous_dimensions as ad +import ekore.anomalous_dimensions.unpolarized.space_like as ad from eko import constants from ekore import harmonics as h diff --git a/tests/ekore/anomalous_dimensions/test_as2.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as2.py similarity index 98% rename from tests/ekore/anomalous_dimensions/test_as2.py rename to tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as2.py index d49a6852f..a118e0a9a 100644 --- a/tests/ekore/anomalous_dimensions/test_as2.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as2.py @@ -1,7 +1,7 @@ # Test NLO anomalous dims import numpy as np -import ekore.anomalous_dimensions.as2 as ad_as2 +import ekore.anomalous_dimensions.unpolarized.space_like.as2 as ad_as2 import ekore.harmonics as h from eko import constants as const diff --git a/tests/ekore/anomalous_dimensions/test_as3.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as3.py similarity index 93% rename from tests/ekore/anomalous_dimensions/test_as3.py rename to tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as3.py index 2b01fe2a9..7db2b7c64 100644 --- a/tests/ekore/anomalous_dimensions/test_as3.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as3.py @@ -1,7 +1,7 @@ # Test NNLO anomalous dimensions import numpy as np -import ekore.anomalous_dimensions.as3 as ad_as3 +import ekore.anomalous_dimensions.unpolarized.space_like.as3 as ad_as3 from ekore import harmonics as h NF = 5 diff --git a/tests/ekore/anomalous_dimensions/test_as4.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py similarity index 99% rename from tests/ekore/anomalous_dimensions/test_as4.py rename to tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py index 2a64df44c..38935ec00 100644 --- a/tests/ekore/anomalous_dimensions/test_as4.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py @@ -1,7 +1,7 @@ # Test N3LO anomalous dimensions import numpy as np -from ekore.anomalous_dimensions.as4 import ( +from ekore.anomalous_dimensions.unpolarized.space_like.as4 import ( gamma_singlet, ggg, ggq, diff --git a/tests/ekore/anomalous_dimensions/test_init.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_init.py similarity index 75% rename from tests/ekore/anomalous_dimensions/test_init.py rename to tests/ekore/anomalous_dimensions/unpolarized/space_like/test_init.py index 72ecbf99f..f36efec04 100644 --- a/tests/ekore/anomalous_dimensions/test_init.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_init.py @@ -6,8 +6,9 @@ from ekore import anomalous_dimensions as ad from eko import basis_rotation as br -from ekore.anomalous_dimensions import as1 as ad_as1 -from ekore.anomalous_dimensions import harmonics +import ekore.anomalous_dimensions.unpolarized.space_like as ad_us +from ekore.anomalous_dimensions.unpolarized.space_like import as1 as ad_as1 +from ekore import harmonics NF = 5 @@ -41,7 +42,7 @@ def test_eigensystem_gamma_singlet_projectors_EV(): # NNLO and N3LO too big numbers, # ignore Runtime Warnings warnings.simplefilter("ignore", RuntimeWarning) - for gamma_S in ad.gamma_singlet(o, N, nf): + for gamma_S in ad_us.gamma_singlet(o, N, nf): _exp, l_p, l_m, e_p, e_m = ad.exp_singlet(gamma_S) # projectors behave as P_a . P_b = delta_ab P_a assert_allclose(np.dot(e_p, e_p), e_p) @@ -56,40 +57,40 @@ def test_gamma_ns(): nf = 3 # LO assert_almost_equal( - ad.gamma_ns((3, 0), br.non_singlet_pids_map["ns+"], 1, nf)[0], 0.0 + ad_us.gamma_ns((3, 0), br.non_singlet_pids_map["ns+"], 1, nf)[0], 0.0 ) # NLO assert_allclose( - ad.gamma_ns((2, 0), br.non_singlet_pids_map["ns-"], 1, nf), + ad_us.gamma_ns((2, 0), br.non_singlet_pids_map["ns-"], 1, nf), np.zeros(2), atol=2e-6, ) # NNLO assert_allclose( - ad.gamma_ns((3, 0), br.non_singlet_pids_map["ns-"], 1, nf), + ad_us.gamma_ns((3, 0), br.non_singlet_pids_map["ns-"], 1, nf), np.zeros(3), atol=2e-4, ) assert_allclose( - ad.gamma_ns((3, 0), br.non_singlet_pids_map["nsV"], 1, nf), + ad_us.gamma_ns((3, 0), br.non_singlet_pids_map["nsV"], 1, nf), np.zeros(3), atol=8e-4, ) # N3LO assert_allclose( - ad.gamma_ns((4, 0), br.non_singlet_pids_map["ns-"], 1, nf), + ad_us.gamma_ns((4, 0), br.non_singlet_pids_map["ns-"], 1, nf), np.zeros(4), atol=2e-4, ) # N3LO valence has a spurious pole, need to add a small shift assert_allclose( - ad.gamma_ns((4, 0), br.non_singlet_pids_map["nsV"], 1 + 1e-6, nf), + ad_us.gamma_ns((4, 0), br.non_singlet_pids_map["nsV"], 1 + 1e-6, nf), np.zeros(4), atol=5e-4, ) assert_raises( AssertionError, assert_allclose, - ad.gamma_ns((4, 0), br.non_singlet_pids_map["ns+"], 1, nf), + ad_us.gamma_ns((4, 0), br.non_singlet_pids_map["ns+"], 1, nf), np.zeros(4), ) diff --git a/tests/ekore/harmonics/test_g_functions.py b/tests/ekore/harmonics/test_g_functions.py index dff9964f6..b6a895e6e 100644 --- a/tests/ekore/harmonics/test_g_functions.py +++ b/tests/ekore/harmonics/test_g_functions.py @@ -2,7 +2,7 @@ import numpy as np -from ekore.anomalous_dimensions import harmonics as h +from ekore import harmonics as h zeta3 = h.constants.zeta3 log2 = h.constants.log2 From 10d22407acb328835e1eb20b34b0e83687625698 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 12 Jan 2023 12:54:46 +0100 Subject: [PATCH 03/30] Add pytest coverage --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index f290ce339..79889abbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -133,6 +133,7 @@ python_functions = ['test_*', 'benchmark_*'] addopts = [ '--cov=eko', '--cov=ekobox', + '--cov=ekore', '--cov-report=html', '--cov-report=xml', '--strict-markers', From 8fd54364a0d73064dc0f4c44edeff4f1e5bf3881 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Mon, 16 Jan 2023 15:00:18 +0100 Subject: [PATCH 04/30] fix init name --- .../anomalous_dimensions/unpolarized/{__init.py => __init__.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/ekore/anomalous_dimensions/unpolarized/{__init.py => __init__.py} (100%) diff --git a/src/ekore/anomalous_dimensions/unpolarized/__init.py b/src/ekore/anomalous_dimensions/unpolarized/__init__.py similarity index 100% rename from src/ekore/anomalous_dimensions/unpolarized/__init.py rename to src/ekore/anomalous_dimensions/unpolarized/__init__.py From 4678da77be4f5d32a4e85ff8783cac1bf79ceebc Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 16 Jan 2023 18:25:52 +0100 Subject: [PATCH 05/30] Start reshuffling OME --- src/eko/evolution_operator/grid.py | 9 +- .../evolution_operator/matching_condition.py} | 4 +- .../operator_matrix_element.py | 97 ++----------------- .../ekore}/__init__.py | 0 .../operator_matrix_elements/__init__.py | 97 +++++++++++++++++++ .../as1.py | 0 .../as2.py | 1 + .../as3/__init__.py | 0 .../as3/aHg.py | 0 .../as3/aHgstfac.py | 0 .../as3/aHq.py | 0 .../as3/agg.py | 0 .../as3/aggTF2.py | 0 .../as3/agq.py | 0 .../as3/aqg.py | 0 .../as3/aqqNS.py | 0 .../as3/aqqPS.py | 0 .../test_matchin_condition.py} | 2 +- .../evolution_operator}/test_ome.py | 15 ++- tests/eko/evolution_operator/test_physical.py | 2 +- .../operator_matrix_elements/__init__.py | 0 .../test_n3lo.py | 4 +- .../test_nlo.py | 2 +- .../test_nnlo.py | 2 +- 24 files changed, 125 insertions(+), 110 deletions(-) rename src/{ekore/matching_conditions/__init__.py => eko/evolution_operator/matching_condition.py} (98%) rename src/{ekore/matching_conditions => eko/evolution_operator}/operator_matrix_element.py (77%) rename {tests/ekore/matching_conditions => src/ekore}/__init__.py (100%) create mode 100644 src/ekore/operator_matrix_elements/__init__.py rename src/ekore/{matching_conditions => operator_matrix_elements}/as1.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as2.py (99%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/__init__.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/aHg.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/aHgstfac.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/aHq.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/agg.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/aggTF2.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/agq.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/aqg.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/aqqNS.py (100%) rename src/ekore/{matching_conditions => operator_matrix_elements}/as3/aqqPS.py (100%) rename tests/{ekore/matching_conditions/test_init.py => eko/evolution_operator/test_matchin_condition.py} (98%) rename tests/{ekore/matching_conditions => eko/evolution_operator}/test_ome.py (98%) create mode 100644 tests/ekore/operator_matrix_elements/__init__.py rename tests/ekore/{matching_conditions => operator_matrix_elements}/test_n3lo.py (98%) rename tests/ekore/{matching_conditions => operator_matrix_elements}/test_nlo.py (95%) rename tests/ekore/{matching_conditions => operator_matrix_elements}/test_nnlo.py (98%) diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index 82e50fe9a..f357899d1 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -11,13 +11,12 @@ import numpy as np import numpy.typing as npt -from ekore import matching_conditions from .. import member from .. import scale_variations as sv from ..io.runcards import Configs, Debug -from ekore.matching_conditions.operator_matrix_element import OperatorMatrixElement from ..thresholds import flavor_shift, is_downward_path -from . import Operator, flavors, physical +from . import Operator, flavors, matching_condition, physical +from .operator_matrix_element import OperatorMatrixElement logger = logging.getLogger(__name__) @@ -245,7 +244,7 @@ def generate(self, q2): # join with the basis rotation, since matching requires c+ (or likewise) if is_downward: - matching = matching_conditions.MatchingCondition.split_ad_to_evol_map( + matching = matching_condition.MatchingCondition.split_ad_to_evol_map( self._matching_operators[op.q2_to], op.nf - 1, op.q2_to, @@ -256,7 +255,7 @@ def generate(self, q2): ) final_op = final_op @ matching @ invrot @ phys_op else: - matching = matching_conditions.MatchingCondition.split_ad_to_evol_map( + matching = matching_condition.MatchingCondition.split_ad_to_evol_map( self._matching_operators[op.q2_to], op.nf, op.q2_to, diff --git a/src/ekore/matching_conditions/__init__.py b/src/eko/evolution_operator/matching_condition.py similarity index 98% rename from src/ekore/matching_conditions/__init__.py rename to src/eko/evolution_operator/matching_condition.py index f2eaed8e0..32b8cd036 100644 --- a/src/ekore/matching_conditions/__init__.py +++ b/src/eko/evolution_operator/matching_condition.py @@ -2,8 +2,8 @@ This module defines the matching conditions for the |VFNS| evolution. """ -from eko import basis_rotation as br -from eko import member +from .. import basis_rotation as br +from .. import member class MatchingCondition(member.OperatorBase): diff --git a/src/ekore/matching_conditions/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py similarity index 77% rename from src/ekore/matching_conditions/operator_matrix_element.py rename to src/eko/evolution_operator/operator_matrix_element.py index c19cc2991..652e7dbdc 100644 --- a/src/ekore/matching_conditions/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -9,94 +9,13 @@ import numba as nb import numpy as np -from eko import basis_rotation as br -from .. import harmonics -from eko.evolution_operator import Operator, QuadKerBase -from . import as1, as2, as3 +from ekore import harmonics +from ekore import operator_matrix_elements as ome -logger = logging.getLogger(__name__) - - -@nb.njit(cache=True) -def A_singlet(matching_order, n, sx, nf, L, is_msbar, sx_ns=None): - r""" - Computes the tower of the singlet |OME|. - - Parameters - ---------- - matching_order : tuple(int,int) - perturbative matching_order - n : complex - Mellin variable - sx : list - singlet like harmonic sums cache - nf: int - number of active flavor below threshold - L : float - :math:``\ln(\mu_F^2 / m_h^2)`` - is_msbar: bool - add the |MSbar| contribution - sx_ns : list - non-singlet like harmonic sums cache - - Returns - ------- - A_singlet : numpy.ndarray - singlet |OME| - - See Also - -------- - ekore.matching_conditions.nlo.A_singlet_1 : :math:`A^{S,(1)}(N)` - ekore.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` - ekore.matching_conditions.nlo.A_gh_1 : :math:`A_{gH}^{(1)}(N)` - ekore.matching_conditions.nnlo.A_singlet_2 : :math:`A_{S,(2)}(N)` - """ - A_s = np.zeros((matching_order[0], 3, 3), np.complex_) - if matching_order[0] >= 1: - A_s[0] = as1.A_singlet(n, sx, L) - if matching_order[0] >= 2: - A_s[1] = as2.A_singlet(n, sx, L, is_msbar) - if matching_order[0] >= 3: - A_s[2] = as3.A_singlet(n, sx, sx_ns, nf, L) - return A_s +from .. import basis_rotation as br +from . import Operator, QuadKerBase - -@nb.njit(cache=True) -def A_non_singlet(matching_order, n, sx, nf, L): - r""" - Computes the tower of the non-singlet |OME| - - Parameters - ---------- - matching_order : tuple(int,int) - perturbative matching_order - n : complex - Mellin variable - sx : list - harmonic sums cache - nf: int - number of active flavor below threshold - L : float - :math:``\ln(\mu_F^2 / m_h^2)`` - - Returns - ------- - A_non_singlet : numpy.ndarray - non-singlet |OME| - - See Also - -------- - ekore.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` - ekore.matching_conditions.nnlo.A_ns_2 : :math:`A_{qq,H}^{NS,(2)}` - """ - A_ns = np.zeros((matching_order[0], 2, 2), np.complex_) - if matching_order[0] >= 1: - A_ns[0] = as1.A_ns(n, sx, L) - if matching_order[0] >= 2: - A_ns[1] = as2.A_ns(n, sx, L) - if matching_order[0] >= 3: - A_ns[2] = as3.A_ns(n, sx, nf, L) - return A_ns +logger = logging.getLogger(__name__) @nb.njit(cache=True) @@ -155,7 +74,7 @@ def build_ome(A, matching_order, a_s, backward_method): def quad_ker( u, order, mode0, mode1, is_log, logx, areas, a_s, nf, L, backward_method, is_msbar ): - """ + r""" Raw kernel inside quad Parameters @@ -220,10 +139,10 @@ def quad_ker( # 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, sx_ns) + A = ome.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) + A = ome.A_non_singlet(order, ker_base.n, sx, nf, L) # build the expansion in alpha_s depending on the strategy ker = build_ome(A, order, a_s, backward_method) diff --git a/tests/ekore/matching_conditions/__init__.py b/src/ekore/__init__.py similarity index 100% rename from tests/ekore/matching_conditions/__init__.py rename to src/ekore/__init__.py diff --git a/src/ekore/operator_matrix_elements/__init__.py b/src/ekore/operator_matrix_elements/__init__.py new file mode 100644 index 000000000..074079ba9 --- /dev/null +++ b/src/ekore/operator_matrix_elements/__init__.py @@ -0,0 +1,97 @@ +""" +This module defines the |OME| for the non-trivial matching conditions in the +|VFNS| evolution. +""" + +import functools +import logging + +import numba as nb +import numpy as np + +from .. import harmonics +from . import as1, as2, as3 + +logger = logging.getLogger(__name__) + + +@nb.njit(cache=True) +def A_singlet(matching_order, n, sx, nf, L, is_msbar, sx_ns=None): + r""" + Computes the tower of the singlet |OME|. + + Parameters + ---------- + matching_order : tuple(int,int) + perturbative matching_order + n : complex + Mellin variable + sx : list + singlet like harmonic sums cache + nf: int + number of active flavor below threshold + L : float + :math:``\ln(\mu_F^2 / m_h^2)`` + is_msbar: bool + add the |MSbar| contribution + sx_ns : list + non-singlet like harmonic sums cache + + Returns + ------- + A_singlet : numpy.ndarray + singlet |OME| + + See Also + -------- + ekore.matching_conditions.nlo.A_singlet_1 : :math:`A^{S,(1)}(N)` + ekore.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` + ekore.matching_conditions.nlo.A_gh_1 : :math:`A_{gH}^{(1)}(N)` + ekore.matching_conditions.nnlo.A_singlet_2 : :math:`A_{S,(2)}(N)` + """ + A_s = np.zeros((matching_order[0], 3, 3), np.complex_) + if matching_order[0] >= 1: + A_s[0] = as1.A_singlet(n, sx, L) + if matching_order[0] >= 2: + A_s[1] = as2.A_singlet(n, sx, L, is_msbar) + if matching_order[0] >= 3: + A_s[2] = as3.A_singlet(n, sx, sx_ns, nf, L) + return A_s + + +@nb.njit(cache=True) +def A_non_singlet(matching_order, n, sx, nf, L): + r""" + Computes the tower of the non-singlet |OME| + + Parameters + ---------- + matching_order : tuple(int,int) + perturbative matching_order + n : complex + Mellin variable + sx : list + harmonic sums cache + nf: int + number of active flavor below threshold + L : float + :math:``\ln(\mu_F^2 / m_h^2)`` + + Returns + ------- + A_non_singlet : numpy.ndarray + non-singlet |OME| + + See Also + -------- + ekore.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` + ekore.matching_conditions.nnlo.A_ns_2 : :math:`A_{qq,H}^{NS,(2)}` + """ + A_ns = np.zeros((matching_order[0], 2, 2), np.complex_) + if matching_order[0] >= 1: + A_ns[0] = as1.A_ns(n, sx, L) + if matching_order[0] >= 2: + A_ns[1] = as2.A_ns(n, sx, L) + if matching_order[0] >= 3: + A_ns[2] = as3.A_ns(n, sx, nf, L) + return A_ns diff --git a/src/ekore/matching_conditions/as1.py b/src/ekore/operator_matrix_elements/as1.py similarity index 100% rename from src/ekore/matching_conditions/as1.py rename to src/ekore/operator_matrix_elements/as1.py diff --git a/src/ekore/matching_conditions/as2.py b/src/ekore/operator_matrix_elements/as2.py similarity index 99% rename from src/ekore/matching_conditions/as2.py rename to src/ekore/operator_matrix_elements/as2.py index 242f1fa5f..c496abfc3 100644 --- a/src/ekore/matching_conditions/as2.py +++ b/src/ekore/operator_matrix_elements/as2.py @@ -12,6 +12,7 @@ import numpy as np from eko 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 diff --git a/src/ekore/matching_conditions/as3/__init__.py b/src/ekore/operator_matrix_elements/as3/__init__.py similarity index 100% rename from src/ekore/matching_conditions/as3/__init__.py rename to src/ekore/operator_matrix_elements/as3/__init__.py diff --git a/src/ekore/matching_conditions/as3/aHg.py b/src/ekore/operator_matrix_elements/as3/aHg.py similarity index 100% rename from src/ekore/matching_conditions/as3/aHg.py rename to src/ekore/operator_matrix_elements/as3/aHg.py diff --git a/src/ekore/matching_conditions/as3/aHgstfac.py b/src/ekore/operator_matrix_elements/as3/aHgstfac.py similarity index 100% rename from src/ekore/matching_conditions/as3/aHgstfac.py rename to src/ekore/operator_matrix_elements/as3/aHgstfac.py diff --git a/src/ekore/matching_conditions/as3/aHq.py b/src/ekore/operator_matrix_elements/as3/aHq.py similarity index 100% rename from src/ekore/matching_conditions/as3/aHq.py rename to src/ekore/operator_matrix_elements/as3/aHq.py diff --git a/src/ekore/matching_conditions/as3/agg.py b/src/ekore/operator_matrix_elements/as3/agg.py similarity index 100% rename from src/ekore/matching_conditions/as3/agg.py rename to src/ekore/operator_matrix_elements/as3/agg.py diff --git a/src/ekore/matching_conditions/as3/aggTF2.py b/src/ekore/operator_matrix_elements/as3/aggTF2.py similarity index 100% rename from src/ekore/matching_conditions/as3/aggTF2.py rename to src/ekore/operator_matrix_elements/as3/aggTF2.py diff --git a/src/ekore/matching_conditions/as3/agq.py b/src/ekore/operator_matrix_elements/as3/agq.py similarity index 100% rename from src/ekore/matching_conditions/as3/agq.py rename to src/ekore/operator_matrix_elements/as3/agq.py diff --git a/src/ekore/matching_conditions/as3/aqg.py b/src/ekore/operator_matrix_elements/as3/aqg.py similarity index 100% rename from src/ekore/matching_conditions/as3/aqg.py rename to src/ekore/operator_matrix_elements/as3/aqg.py diff --git a/src/ekore/matching_conditions/as3/aqqNS.py b/src/ekore/operator_matrix_elements/as3/aqqNS.py similarity index 100% rename from src/ekore/matching_conditions/as3/aqqNS.py rename to src/ekore/operator_matrix_elements/as3/aqqNS.py diff --git a/src/ekore/matching_conditions/as3/aqqPS.py b/src/ekore/operator_matrix_elements/as3/aqqPS.py similarity index 100% rename from src/ekore/matching_conditions/as3/aqqPS.py rename to src/ekore/operator_matrix_elements/as3/aqqPS.py diff --git a/tests/ekore/matching_conditions/test_init.py b/tests/eko/evolution_operator/test_matchin_condition.py similarity index 98% rename from tests/ekore/matching_conditions/test_init.py rename to tests/eko/evolution_operator/test_matchin_condition.py index e0378a515..cf6ddd0f5 100644 --- a/tests/ekore/matching_conditions/test_init.py +++ b/tests/eko/evolution_operator/test_matchin_condition.py @@ -3,7 +3,7 @@ from eko import basis_rotation as br from eko import member -from ekore.matching_conditions import MatchingCondition +from eko.evolution_operator.matching_condition import MatchingCondition def mkOM(shape): diff --git a/tests/ekore/matching_conditions/test_ome.py b/tests/eko/evolution_operator/test_ome.py similarity index 98% rename from tests/ekore/matching_conditions/test_ome.py rename to tests/eko/evolution_operator/test_ome.py index aeb67ddec..8ae19e699 100644 --- a/tests/ekore/matching_conditions/test_ome.py +++ b/tests/eko/evolution_operator/test_ome.py @@ -5,17 +5,16 @@ from eko import basis_rotation as br from eko import interpolation, mellin -from ekore.harmonics import compute_cache -from eko.io.runcards import OperatorCard, TheoryCard -from eko.io.types import InversionMethod -from ekore.matching_conditions.operator_matrix_element import ( - A_non_singlet, - A_singlet, +from eko.evolution_operator.operator_matrix_element import ( OperatorMatrixElement, build_ome, quad_ker, ) +from eko.io.runcards import OperatorCard, TheoryCard +from eko.io.types import InversionMethod from eko.runner import legacy +from ekore.harmonics import compute_cache +from ekore.operator_matrix_elements import A_non_singlet, A_singlet max_weight_dict = {1: 2, 2: 3, 3: 5} @@ -88,12 +87,12 @@ def test_quad_ker(monkeypatch): monkeypatch.setattr(interpolation, "evaluate_Nx", lambda *args: 1) zeros = np.zeros((2, 2)) monkeypatch.setattr( - "ekore.matching_conditions.operator_matrix_element.A_non_singlet", + "ekore.operator_matrix_elements.A_non_singlet", lambda *args: np.array([zeros, zeros, zeros]), ) zeros = np.zeros((3, 3)) monkeypatch.setattr( - "ekore.matching_conditions.operator_matrix_element.A_singlet", + "ekore.operator_matrix_elements.A_singlet", lambda *args: np.array([zeros, zeros, zeros]), ) for is_log in [True, False]: diff --git a/tests/eko/evolution_operator/test_physical.py b/tests/eko/evolution_operator/test_physical.py index d28602aa6..a194f0502 100644 --- a/tests/eko/evolution_operator/test_physical.py +++ b/tests/eko/evolution_operator/test_physical.py @@ -3,8 +3,8 @@ from eko import basis_rotation as br from eko import member +from eko.evolution_operator.matching_condition import MatchingCondition from eko.evolution_operator.physical import PhysicalOperator -from ekore.matching_conditions import MatchingCondition def mkOM(shape): diff --git a/tests/ekore/operator_matrix_elements/__init__.py b/tests/ekore/operator_matrix_elements/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/ekore/matching_conditions/test_n3lo.py b/tests/ekore/operator_matrix_elements/test_n3lo.py similarity index 98% rename from tests/ekore/matching_conditions/test_n3lo.py rename to tests/ekore/operator_matrix_elements/test_n3lo.py index 56d0b8df9..dbbb190b1 100644 --- a/tests/ekore/matching_conditions/test_n3lo.py +++ b/tests/ekore/operator_matrix_elements/test_n3lo.py @@ -2,8 +2,8 @@ import numpy as np from ekore.harmonics import compute_cache -from ekore.matching_conditions import as3 -from ekore.matching_conditions.as3 import A_ns, A_qqNS, A_singlet +from ekore.operator_matrix_elements import as3 +from ekore.operator_matrix_elements.as3 import A_ns, A_qqNS, A_singlet def test_A_3(): diff --git a/tests/ekore/matching_conditions/test_nlo.py b/tests/ekore/operator_matrix_elements/test_nlo.py similarity index 95% rename from tests/ekore/matching_conditions/test_nlo.py rename to tests/ekore/operator_matrix_elements/test_nlo.py index cc5700b30..2fdbd76dc 100644 --- a/tests/ekore/matching_conditions/test_nlo.py +++ b/tests/ekore/operator_matrix_elements/test_nlo.py @@ -2,7 +2,7 @@ import numpy as np from ekore.harmonics import compute_cache -from ekore.matching_conditions.as1 import A_ns, A_singlet +from ekore.operator_matrix_elements.as1 import A_ns, A_singlet def test_A_1_intrinsic(): diff --git a/tests/ekore/matching_conditions/test_nnlo.py b/tests/ekore/operator_matrix_elements/test_nnlo.py similarity index 98% rename from tests/ekore/matching_conditions/test_nnlo.py rename to tests/ekore/operator_matrix_elements/test_nnlo.py index 98aeddcbe..2572b2cbf 100644 --- a/tests/ekore/matching_conditions/test_nnlo.py +++ b/tests/ekore/operator_matrix_elements/test_nnlo.py @@ -3,7 +3,7 @@ import numpy as np from ekore.harmonics import compute_cache, constants -from ekore.matching_conditions.as2 import A_ns, A_qq_ns, A_singlet +from ekore.operator_matrix_elements.as2 import A_ns, A_qq_ns, A_singlet def test_A_2(): From 694a239ee94e69c700ccd681132fab510933d813 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 16 Jan 2023 18:29:51 +0100 Subject: [PATCH 06/30] Move ad benchmark --- benchmarks/{eko => ekore}/benchmark_ad.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename benchmarks/{eko => ekore}/benchmark_ad.py (100%) diff --git a/benchmarks/eko/benchmark_ad.py b/benchmarks/ekore/benchmark_ad.py similarity index 100% rename from benchmarks/eko/benchmark_ad.py rename to benchmarks/ekore/benchmark_ad.py From ec04696f971d0776773ad7d8131b28bd61ffd58c Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 17 Jan 2023 17:04:11 +0100 Subject: [PATCH 07/30] Move OME --- src/eko/evolution_operator/operator_matrix_element.py | 6 +++--- src/ekore/operator_matrix_elements/unpolarized/__init__.py | 0 .../{ => unpolarized/space_like}/__init__.py | 6 ------ .../{ => unpolarized/space_like}/as1.py | 0 .../{ => unpolarized/space_like}/as2.py | 2 +- .../{ => unpolarized/space_like}/as3/__init__.py | 0 .../{ => unpolarized/space_like}/as3/aHg.py | 0 .../{ => unpolarized/space_like}/as3/aHgstfac.py | 0 .../{ => unpolarized/space_like}/as3/aHq.py | 0 .../{ => unpolarized/space_like}/as3/agg.py | 0 .../{ => unpolarized/space_like}/as3/aggTF2.py | 0 .../{ => unpolarized/space_like}/as3/agq.py | 0 .../{ => unpolarized/space_like}/as3/aqg.py | 0 .../{ => unpolarized/space_like}/as3/aqqNS.py | 0 .../{ => unpolarized/space_like}/as3/aqqPS.py | 0 tests/eko/evolution_operator/test_ome.py | 6 +++--- .../ekore/operator_matrix_elements/unpolarized/__init__.py | 0 .../unpolarized/space_like/__init__.py | 0 .../{ => unpolarized/space_like}/test_n3lo.py | 4 ++-- .../{ => unpolarized/space_like}/test_nlo.py | 2 +- .../{ => unpolarized/space_like}/test_nnlo.py | 2 +- 21 files changed, 11 insertions(+), 17 deletions(-) create mode 100644 src/ekore/operator_matrix_elements/unpolarized/__init__.py rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/__init__.py (96%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as1.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as2.py (99%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/__init__.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/aHg.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/aHgstfac.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/aHq.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/agg.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/aggTF2.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/agq.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/aqg.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/aqqNS.py (100%) rename src/ekore/operator_matrix_elements/{ => unpolarized/space_like}/as3/aqqPS.py (100%) create mode 100644 tests/ekore/operator_matrix_elements/unpolarized/__init__.py create mode 100644 tests/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py rename tests/ekore/operator_matrix_elements/{ => unpolarized/space_like}/test_n3lo.py (97%) rename tests/ekore/operator_matrix_elements/{ => unpolarized/space_like}/test_nlo.py (94%) rename tests/ekore/operator_matrix_elements/{ => unpolarized/space_like}/test_nnlo.py (98%) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 652e7dbdc..6d8bfb8bb 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -10,7 +10,7 @@ import numpy as np from ekore import harmonics -from ekore import operator_matrix_elements as ome +import ekore.operator_matrix_elements.unpolarized.space_like as ome_us from .. import basis_rotation as br from . import Operator, QuadKerBase @@ -139,10 +139,10 @@ def quad_ker( # compute the ome if ker_base.is_singlet: indices = {21: 0, 100: 1, 90: 2} - A = ome.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) + A = ome_us.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) else: indices = {200: 0, 91: 1} - A = ome.A_non_singlet(order, ker_base.n, sx, nf, L) + A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) # build the expansion in alpha_s depending on the strategy ker = build_ome(A, order, a_s, backward_method) diff --git a/src/ekore/operator_matrix_elements/unpolarized/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/ekore/operator_matrix_elements/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py similarity index 96% rename from src/ekore/operator_matrix_elements/__init__.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py index 074079ba9..a1d2f8ec6 100644 --- a/src/ekore/operator_matrix_elements/__init__.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py @@ -3,17 +3,11 @@ |VFNS| evolution. """ -import functools -import logging - import numba as nb import numpy as np -from .. import harmonics from . import as1, as2, as3 -logger = logging.getLogger(__name__) - @nb.njit(cache=True) def A_singlet(matching_order, n, sx, nf, L, is_msbar, sx_ns=None): diff --git a/src/ekore/operator_matrix_elements/as1.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py similarity index 100% rename from src/ekore/operator_matrix_elements/as1.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py diff --git a/src/ekore/operator_matrix_elements/as2.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py similarity index 99% rename from src/ekore/operator_matrix_elements/as2.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py index c496abfc3..2197fbfd9 100644 --- a/src/ekore/operator_matrix_elements/as2.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py @@ -13,7 +13,7 @@ from eko import constants -from ..harmonics.constants import zeta2, zeta3 +from ....harmonics.constants import zeta2, zeta3 from .as1 import A_gg as A_gg_1 from .as1 import A_hg as A_hg_1 diff --git a/src/ekore/operator_matrix_elements/as3/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/__init__.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py diff --git a/src/ekore/operator_matrix_elements/as3/aHg.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/aHg.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py diff --git a/src/ekore/operator_matrix_elements/as3/aHgstfac.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHgstfac.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/aHgstfac.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHgstfac.py diff --git a/src/ekore/operator_matrix_elements/as3/aHq.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/aHq.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py diff --git a/src/ekore/operator_matrix_elements/as3/agg.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/agg.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py diff --git a/src/ekore/operator_matrix_elements/as3/aggTF2.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aggTF2.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/aggTF2.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aggTF2.py diff --git a/src/ekore/operator_matrix_elements/as3/agq.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/agq.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py diff --git a/src/ekore/operator_matrix_elements/as3/aqg.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/aqg.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py diff --git a/src/ekore/operator_matrix_elements/as3/aqqNS.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/aqqNS.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py diff --git a/src/ekore/operator_matrix_elements/as3/aqqPS.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py similarity index 100% rename from src/ekore/operator_matrix_elements/as3/aqqPS.py rename to src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py diff --git a/tests/eko/evolution_operator/test_ome.py b/tests/eko/evolution_operator/test_ome.py index 8ae19e699..64824b85d 100644 --- a/tests/eko/evolution_operator/test_ome.py +++ b/tests/eko/evolution_operator/test_ome.py @@ -14,7 +14,7 @@ from eko.io.types import InversionMethod from eko.runner import legacy from ekore.harmonics import compute_cache -from ekore.operator_matrix_elements import A_non_singlet, A_singlet +from ekore.operator_matrix_elements.unpolarized.space_like import A_non_singlet, A_singlet max_weight_dict = {1: 2, 2: 3, 3: 5} @@ -87,12 +87,12 @@ def test_quad_ker(monkeypatch): monkeypatch.setattr(interpolation, "evaluate_Nx", lambda *args: 1) zeros = np.zeros((2, 2)) monkeypatch.setattr( - "ekore.operator_matrix_elements.A_non_singlet", + "ekore.operator_matrix_elements.unpolarized.space_like.A_non_singlet", lambda *args: np.array([zeros, zeros, zeros]), ) zeros = np.zeros((3, 3)) monkeypatch.setattr( - "ekore.operator_matrix_elements.A_singlet", + "ekore.operator_matrix_elements.unpolarized.space_like.A_singlet", lambda *args: np.array([zeros, zeros, zeros]), ) for is_log in [True, False]: diff --git a/tests/ekore/operator_matrix_elements/unpolarized/__init__.py b/tests/ekore/operator_matrix_elements/unpolarized/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py b/tests/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/ekore/operator_matrix_elements/test_n3lo.py b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_n3lo.py similarity index 97% rename from tests/ekore/operator_matrix_elements/test_n3lo.py rename to tests/ekore/operator_matrix_elements/unpolarized/space_like/test_n3lo.py index dbbb190b1..eed992f3d 100644 --- a/tests/ekore/operator_matrix_elements/test_n3lo.py +++ b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_n3lo.py @@ -2,8 +2,8 @@ import numpy as np from ekore.harmonics import compute_cache -from ekore.operator_matrix_elements import as3 -from ekore.operator_matrix_elements.as3 import A_ns, A_qqNS, A_singlet +from ekore.operator_matrix_elements.unpolarized.space_like import as3 +from ekore.operator_matrix_elements.unpolarized.space_like.as3 import A_ns, A_qqNS, A_singlet def test_A_3(): diff --git a/tests/ekore/operator_matrix_elements/test_nlo.py b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nlo.py similarity index 94% rename from tests/ekore/operator_matrix_elements/test_nlo.py rename to tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nlo.py index 2fdbd76dc..953d797c7 100644 --- a/tests/ekore/operator_matrix_elements/test_nlo.py +++ b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nlo.py @@ -2,7 +2,7 @@ import numpy as np from ekore.harmonics import compute_cache -from ekore.operator_matrix_elements.as1 import A_ns, A_singlet +from ekore.operator_matrix_elements.unpolarized.space_like.as1 import A_ns, A_singlet def test_A_1_intrinsic(): diff --git a/tests/ekore/operator_matrix_elements/test_nnlo.py b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nnlo.py similarity index 98% rename from tests/ekore/operator_matrix_elements/test_nnlo.py rename to tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nnlo.py index 2572b2cbf..648568d1c 100644 --- a/tests/ekore/operator_matrix_elements/test_nnlo.py +++ b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nnlo.py @@ -3,7 +3,7 @@ import numpy as np from ekore.harmonics import compute_cache, constants -from ekore.operator_matrix_elements.as2 import A_ns, A_qq_ns, A_singlet +from ekore.operator_matrix_elements.unpolarized.space_like.as2 import A_ns, A_qq_ns, A_singlet def test_A_2(): From febd41515bf048dcce56fc9d7d898012f281e8ee Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 17 Jan 2023 17:10:57 +0100 Subject: [PATCH 08/30] Add missing init file --- src/ekore/operator_matrix_elements/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/ekore/operator_matrix_elements/__init__.py diff --git a/src/ekore/operator_matrix_elements/__init__.py b/src/ekore/operator_matrix_elements/__init__.py new file mode 100644 index 000000000..e69de29bb From bb6af22675ab83c28f79aa1d9853dd9a63ffb375 Mon Sep 17 00:00:00 2001 From: giacomomagni Date: Mon, 16 Jan 2023 14:36:10 +0100 Subject: [PATCH 09/30] propagate polarized and time-like from op card to op.__init__ --- src/eko/evolution_operator/__init__.py | 38 +++++++++++++++++-- src/eko/evolution_operator/grid.py | 2 + src/eko/io/runcards.py | 5 +++ src/ekobox/cards.py | 2 + src/ekomark/data/db.py | 2 + src/ekomark/data/operators.py | 2 + src/ekomark/navigator/navigator.py | 2 + .../polarized/__init__.py | 0 .../polarized/space_like/__init__.py | 21 ++++++++++ .../polarized/time_like/__init__.py | 21 ++++++++++ .../unpolarized/space_like/__init__.py | 6 +-- .../unpolarized/time_like/__init__.py | 21 ++++++++++ tests/eko/evolution_operator/test_init.py | 12 ++++++ 13 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 src/ekore/anomalous_dimensions/polarized/__init__.py create mode 100644 src/ekore/anomalous_dimensions/polarized/space_like/__init__.py create mode 100644 src/ekore/anomalous_dimensions/polarized/time_like/__init__.py create mode 100644 src/ekore/anomalous_dimensions/unpolarized/time_like/__init__.py diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 2b047083f..5e90ddbfc 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -13,7 +13,11 @@ import numpy as np from scipy import integrate -import ekore.anomalous_dimensions.unpolarized.space_like as ad +import ekore.anomalous_dimensions.polarized.space_like as ad_ps +import ekore.anomalous_dimensions.polarized.time_like as ad_pt +import ekore.anomalous_dimensions.unpolarized.space_like as ad_us +import ekore.anomalous_dimensions.unpolarized.time_like as ad_ut + from .. import basis_rotation as br from .. import interpolation, mellin from .. import scale_variations as sv @@ -130,6 +134,8 @@ def quad_ker( ev_op_max_order, sv_mode, is_threshold, + is_polarized, + is_time_like, ): """Raw evolution kernel inside quad. @@ -168,7 +174,11 @@ def quad_ker( sv_mode: int, `enum.IntEnum` scale variation mode, see `eko.scale_variations.Modes` is_threshold : boolean - is this an itermediate threshold operator? + is this an intermediate threshold operator? + is_polarized : boolean + is polarized evolution ? + is_time_like : boolean + is time-like evolution ? Returns ------- @@ -182,7 +192,16 @@ def quad_ker( # compute the actual evolution kernel if ker_base.is_singlet: - gamma_singlet = ad.gamma_singlet(order, ker_base.n, nf) + if is_polarized: + if is_time_like: + gamma_singlet = ad_pt.gamma_singlet(order, ker_base.n, nf) + else: + gamma_singlet = ad_ps.gamma_singlet(order, ker_base.n, nf) + else: + if is_time_like: + gamma_singlet = ad_ut.gamma_singlet(order, ker_base.n, nf) + else: + gamma_singlet = ad_us.gamma_singlet(order, ker_base.n, nf) # scale var exponentiated is directly applied on gamma if sv_mode == sv.Modes.exponentiated: gamma_singlet = sv.exponentiated.gamma_variation( @@ -205,7 +224,16 @@ def quad_ker( ) @ np.ascontiguousarray(ker) ker = select_singlet_element(ker, mode0, mode1) else: - gamma_ns = ad.gamma_ns(order, mode0, ker_base.n, nf) + if is_polarized: + if is_time_like: + gamma_ns = ad_pt.gamma_ns(order, mode0, ker_base.n, nf) + else: + gamma_ns = ad_ps.gamma_ns(order, mode0, ker_base.n, nf) + else: + if is_time_like: + gamma_ns = ad_ut.gamma_ns(order, mode0, ker_base.n, nf) + else: + gamma_ns = ad_us.gamma_ns(order, mode0, ker_base.n, nf) if sv_mode == sv.Modes.exponentiated: gamma_ns = sv.exponentiated.gamma_variation(gamma_ns, order, nf, L) ker = ns.dispatcher( @@ -382,6 +410,8 @@ def quad_ker(self, label, logx, areas): ev_op_max_order=tuple(self.config["ev_op_max_order"]), sv_mode=self.sv_mode, is_threshold=self.is_threshold, + is_polarized=self.config["polarized"], + is_time_like=self.config["time_like"], ) def initialize_op_members(self): diff --git a/src/eko/evolution_operator/grid.py b/src/eko/evolution_operator/grid.py index f357899d1..270d434a8 100644 --- a/src/eko/evolution_operator/grid.py +++ b/src/eko/evolution_operator/grid.py @@ -89,6 +89,8 @@ def __init__( config["n_integration_cores"] = configs.n_integration_cores config["debug_skip_singlet"] = debug.skip_singlet config["debug_skip_non_singlet"] = debug.skip_non_singlet + config["polarized"] = configs.polarized + config["time_like"] = configs.time_like if method not in [ "iterate-exact", diff --git a/src/eko/io/runcards.py b/src/eko/io/runcards.py index 414cb87be..941078f8f 100644 --- a/src/eko/io/runcards.py +++ b/src/eko/io/runcards.py @@ -88,6 +88,10 @@ class Configs(DictLike): r"""Whether to use polynomials in :math:`\log(x)`. If `false`, polynomials are in :math:`x`. """ + polarized: bool + """If `true` do polarized evolution.""" + time_like: bool + """If `true` do time-like evolution.""" scvar_method: Optional[ScaleVariationsMethod] """""" inversion_method: Optional[InversionMethod] @@ -326,6 +330,7 @@ def new_operator(self): "interpolation_is_log", "ev_op_iterations", "n_integration_cores", + "polarized", ): new["configs"][k] = old[k] max_order = old["ev_op_max_order"] diff --git a/src/ekobox/cards.py b/src/ekobox/cards.py index 52569909b..231dc7266 100644 --- a/src/ekobox/cards.py +++ b/src/ekobox/cards.py @@ -38,6 +38,8 @@ scvar_method=None, inversion_method=None, n_integration_cores=0, + polarized=False, + time_like=False, ), debug=dict( skip_singlet=False, diff --git a/src/ekomark/data/db.py b/src/ekomark/data/db.py index 782dbef30..a9fe0fd9f 100644 --- a/src/ekomark/data/db.py +++ b/src/ekomark/data/db.py @@ -22,3 +22,5 @@ class Operator(Base): # pylint: disable=too-few-public-methods ev_op_iterations = Column(Integer) Q2grid = Column(Text) backward_inversion = Column(Text) + polarized = Column(Boolean) + time_like = Column(Boolean) diff --git a/src/ekomark/data/operators.py b/src/ekomark/data/operators.py index 4a161c0fd..bf19cb465 100644 --- a/src/ekomark/data/operators.py +++ b/src/ekomark/data/operators.py @@ -22,6 +22,8 @@ targetgrid=None, inputpids=None, targetpids=None, + polarized=False, + time_like=False, ).items() ) ) diff --git a/src/ekomark/navigator/navigator.py b/src/ekomark/navigator/navigator.py index 48148de16..137ecca64 100644 --- a/src/ekomark/navigator/navigator.py +++ b/src/ekomark/navigator/navigator.py @@ -81,6 +81,8 @@ def fill_operators(self, op, obj): obj["iters"] = op["ev_op_iterations"] obj["skip_ns"] = op["debug_skip_non_singlet"] obj["skip_s"] = op["debug_skip_singlet"] + obj["pol"] = op["polarized"] + obj["time"] = op["time_like"] def fill_cache(self, cac, obj): """ diff --git a/src/ekore/anomalous_dimensions/polarized/__init__.py b/src/ekore/anomalous_dimensions/polarized/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/ekore/anomalous_dimensions/polarized/space_like/__init__.py b/src/ekore/anomalous_dimensions/polarized/space_like/__init__.py new file mode 100644 index 000000000..1b64ab235 --- /dev/null +++ b/src/ekore/anomalous_dimensions/polarized/space_like/__init__.py @@ -0,0 +1,21 @@ +r"""The polarized, space-like Altarelli-Parisi splitting kernels. + +Normalization is given by + +.. math:: + \mathbf{P}(x) = \sum\limits_{j=0} a_s^{j+1} \mathbf P^{(j)}(x) + +with :math:`a_s = \frac{\alpha_S(\mu^2)}{4\pi}`. +""" + +import numba as nb + + +@nb.njit(cache=True) +def gamma_ns(_order, _mode, _n, _nf): + raise NotImplementedError("Polarised, space-like is not yet implemented") + + +@nb.njit(cache=True) +def gamma_singlet(_order, _n, _nf): + raise NotImplementedError("Polarised, space-like is not yet implemented") diff --git a/src/ekore/anomalous_dimensions/polarized/time_like/__init__.py b/src/ekore/anomalous_dimensions/polarized/time_like/__init__.py new file mode 100644 index 000000000..74aa85770 --- /dev/null +++ b/src/ekore/anomalous_dimensions/polarized/time_like/__init__.py @@ -0,0 +1,21 @@ +r"""The polarized, time-like Altarelli-Parisi splitting kernels. + +Normalization is given by + +.. math:: + \mathbf{P}(x) = \sum\limits_{j=0} a_s^{j+1} \mathbf P^{(j)}(x) + +with :math:`a_s = \frac{\alpha_S(\mu^2)}{4\pi}`. +""" + +import numba as nb + + +@nb.njit(cache=True) +def gamma_ns(_order, _mode, _n, _nf): + raise NotImplementedError("Polarised, time-like is not yet implemented") + + +@nb.njit(cache=True) +def gamma_singlet(_order, _n, _nf): + raise NotImplementedError("Polarised, time-like is not yet implemented") diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py index 134596498..dc4ad9dbf 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py @@ -1,5 +1,4 @@ -r""" -This module contains the Altarelli-Parisi splitting kernels. +r"""The unpolarized, space-like Altarelli-Parisi splitting kernels. Normalization is given by @@ -20,7 +19,8 @@ import numpy as np from .... import harmonics -from . import as1, as2, as3, as4, aem1, aem2 +from . import aem1, aem2, as1, as2, as3, as4 + @nb.njit(cache=True) def gamma_ns(order, mode, n, nf): diff --git a/src/ekore/anomalous_dimensions/unpolarized/time_like/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/time_like/__init__.py new file mode 100644 index 000000000..7d353c93e --- /dev/null +++ b/src/ekore/anomalous_dimensions/unpolarized/time_like/__init__.py @@ -0,0 +1,21 @@ +r"""The unpolarized, time-like Altarelli-Parisi splitting kernels. + +Normalization is given by + +.. math:: + \mathbf{P}(x) = \sum\limits_{j=0} a_s^{j+1} \mathbf P^{(j)}(x) + +with :math:`a_s = \frac{\alpha_S(\mu^2)}{4\pi}`. +""" + +import numba as nb + + +@nb.njit(cache=True) +def gamma_ns(_order, _mode, _n, _nf): + raise NotImplementedError("Polarised is not yet implemented") + + +@nb.njit(cache=True) +def gamma_singlet(_order, _n, _nf): + raise NotImplementedError("Polarised is not yet implemented") diff --git a/tests/eko/evolution_operator/test_init.py b/tests/eko/evolution_operator/test_init.py index a801f5c56..e7c883a05 100644 --- a/tests/eko/evolution_operator/test_init.py +++ b/tests/eko/evolution_operator/test_init.py @@ -44,6 +44,8 @@ def test_quad_ker(monkeypatch): ev_op_max_order=(0, 0), sv_mode=1, is_threshold=False, + is_polarized=False, + is_time_like=False, ) np.testing.assert_allclose(res_ns, 0.0) res_s = quad_ker( @@ -64,6 +66,8 @@ def test_quad_ker(monkeypatch): ev_op_max_order=(0, 0), sv_mode=1, is_threshold=False, + is_polarized=False, + is_time_like=False, ) np.testing.assert_allclose(res_s, 1.0) res_s = quad_ker( @@ -84,6 +88,8 @@ def test_quad_ker(monkeypatch): ev_op_max_order=(0, 0), sv_mode=1, is_threshold=False, + is_polarized=False, + is_time_like=False, ) np.testing.assert_allclose(res_s, 0.0) for label in [(br.non_singlet_pids_map["ns+"], 0), (100, 100)]: @@ -106,6 +112,8 @@ def test_quad_ker(monkeypatch): ev_op_max_order=(1, 0), sv_mode=sv, is_threshold=False, + is_polarized=False, + is_time_like=False, ) np.testing.assert_allclose(res_sv, 1.0) @@ -128,6 +136,8 @@ def test_quad_ker(monkeypatch): ev_op_max_order=(0, 0), sv_mode=1, is_threshold=False, + is_polarized=False, + is_time_like=False, ) np.testing.assert_allclose(res_ns, 0.0) @@ -342,6 +352,8 @@ def quad_ker_pegasus( 10, 0, False, + False, + False, ), epsabs=1e-12, epsrel=1e-5, From 3db8696cebcaf2ea8210d33fcb309e8b035cb0ce Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 17 Jan 2023 18:10:38 +0100 Subject: [PATCH 10/30] Add switch for OME --- .../operator_matrix_element.py | 141 +++++++++++------- .../polarized/__init__.py | 0 .../polarized/space_like/__init__.py | 13 ++ .../polarized/time_like/__init__.py | 13 ++ .../unpolarized/time_like/__init__.py | 13 ++ tests/eko/evolution_operator/test_ome.py | 17 ++- 6 files changed, 143 insertions(+), 54 deletions(-) create mode 100644 src/ekore/operator_matrix_elements/polarized/__init__.py create mode 100644 src/ekore/operator_matrix_elements/polarized/space_like/__init__.py create mode 100644 src/ekore/operator_matrix_elements/polarized/time_like/__init__.py create mode 100644 src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 6d8bfb8bb..e8012f6a4 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -1,7 +1,4 @@ -""" -This module defines the |OME| for the non-trivial matching conditions in the -|VFNS| evolution. -""" +"""The |OME| for the non-trivial matching conditions in the |VFNS| evolution.""" import functools import logging @@ -9,8 +6,11 @@ import numba as nb import numpy as np -from ekore import harmonics +import ekore.operator_matrix_elements.polarized.space_like as ome_ps +import ekore.operator_matrix_elements.polarized.time_like as ome_pt import ekore.operator_matrix_elements.unpolarized.space_like as ome_us +import ekore.operator_matrix_elements.unpolarized.time_like as ome_ut +from ekore import harmonics from .. import basis_rotation as br from . import Operator, QuadKerBase @@ -20,24 +20,23 @@ @nb.njit(cache=True) def build_ome(A, matching_order, a_s, backward_method): - r""" - Construct the matching expansion in :math:`a_s` with the appropriate method. + r"""Construct the matching expansion in :math:`a_s` with the appropriate method. Parameters ---------- - A : numpy.ndarray - list of |OME| - matching_order : tuple(int,int) - perturbation matching order - a_s : float - strong coupling, needed only for the exact inverse - backward_method : ["exact", "expanded" or ""] - empty or method for inverting the matching condition (exact or expanded) + A : numpy.ndarray + list of |OME| + matching_order : tuple(int,int) + perturbation matching order + a_s : float + strong coupling, needed only for the exact inverse + backward_method : ["exact", "expanded" or ""] + empty or method for inverting the matching condition (exact or expanded) Returns ------- - ome : numpy.ndarray - matching operator matrix + ome : numpy.ndarray + matching operator matrix """ # to get the inverse one can use this FORM snippet # Symbol a; @@ -72,41 +71,58 @@ def build_ome(A, matching_order, a_s, backward_method): @nb.njit(cache=True) def quad_ker( - u, order, mode0, mode1, is_log, logx, areas, a_s, nf, L, backward_method, is_msbar + u, + order, + mode0, + mode1, + is_log, + logx, + areas, + a_s, + nf, + L, + backward_method, + is_msbar, + is_polarized, + is_time_like, ): - r""" - Raw kernel inside quad + r"""Raw kernel inside quad. Parameters ---------- - u : float - quad argument - order : tuple(int,int) - perturbation matching order - mode0 : int - pid for first element in the singlet sector - mode1 : int - pid for second element in the singlet sector - is_log : boolean - logarithmic interpolation - logx : float - Mellin inversion point - areas : tuple - basis function configuration - a_s : float - strong coupling, needed only for the exact inverse - nf: int - number of active flavor below threshold - L : float - :math:``\ln(\mu_F^2 / m_h^2)`` - backward_method : ["exact", "expanded" or ""] - empty or method for inverting the matching condition (exact or expanded) - is_msbar: bool - add the |MSbar| contribution + u : float + quad argument + order : tuple(int,int) + perturbation matching order + mode0 : int + pid for first element in the singlet sector + mode1 : int + pid for second element in the singlet sector + is_log : boolean + logarithmic interpolation + logx : float + Mellin inversion point + areas : tuple + basis function configuration + a_s : float + strong coupling, needed only for the exact inverse + nf: int + number of active flavor below threshold + L : float + :math:``\ln(\mu_F^2 / m_h^2)`` + backward_method : ["exact", "expanded" or ""] + empty or method for inverting the matching condition (exact or expanded) + is_msbar: bool + add the |MSbar| contribution + is_polarized : boolean + is polarized evolution ? + is_time_like : boolean + is time-like evolution ? + Returns ------- - ker : float - evaluated integration kernel + ker : float + evaluated integration kernel """ ker_base = QuadKerBase(u, is_log, logx, mode0) integrand = ker_base.integrand(areas) @@ -139,10 +155,28 @@ def quad_ker( # compute the ome if ker_base.is_singlet: indices = {21: 0, 100: 1, 90: 2} - A = ome_us.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) + if is_polarized: + if is_time_like: + A = ome_pt.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) + else: + A = ome_ps.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) + else: + if is_time_like: + A = ome_ut.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) + else: + A = ome_us.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) else: indices = {200: 0, 91: 1} - A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) + if is_polarized: + if is_time_like: + A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) + else: + A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) + else: + if is_time_like: + A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) + else: + A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) # build the expansion in alpha_s depending on the strategy ker = build_ome(A, order, a_s, backward_method) @@ -206,14 +240,13 @@ def __init__(self, config, managers, nf, q2, is_backward, L, is_msbar): @property def labels(self): - """Computes the necessary sector labels to compute. + """Necessary sector labels to compute. Returns ------- list(str) sector labels """ - labels = [] # non-singlet labels if self.config["debug_skip_non_singlet"]: @@ -247,7 +280,7 @@ def labels(self): return labels def quad_ker(self, label, logx, areas): - """Partially initialized integrand function. + """Return partially initialized integrand function. Parameters ---------- @@ -276,11 +309,13 @@ def quad_ker(self, label, logx, areas): L=self.L, backward_method=self.backward_method, is_msbar=self.is_msbar, + is_polarized=self.config["polarized"], + is_time_like=self.config["time_like"], ) @property def a_s(self): - """Returns the computed values for :math:`a_s`. + """Compute values for :math:`a_s`. Note that here you need to use :math:`a_s^{n_f+1}` """ @@ -288,7 +323,7 @@ def a_s(self): return sc.a_s(self.mur2_shift(self.q2_from), self.q2_from, nf_to=self.nf + 1) def compute(self): - """Compute the actual operators (i.e. run the integrations)""" + """Compute the actual operators (i.e. run the integrations).""" self.initialize_op_members() # At LO you don't need anything else diff --git a/src/ekore/operator_matrix_elements/polarized/__init__.py b/src/ekore/operator_matrix_elements/polarized/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py b/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py new file mode 100644 index 000000000..2dab4db48 --- /dev/null +++ b/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py @@ -0,0 +1,13 @@ +r"""The polarized, space-like |OME|.""" + +import numba as nb + + +@nb.njit(cache=True) +def A_non_singlet(_matching_order, _n, _sx, _nf, _L): + raise NotImplementedError("Polarised, space-like is not yet implemented") + + +@nb.njit(cache=True) +def A_non_singlet(_order, _n, _sx, _nf, _L): + raise NotImplementedError("Polarised, space-like is not yet implemented") diff --git a/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py b/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py new file mode 100644 index 000000000..c5232eff3 --- /dev/null +++ b/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py @@ -0,0 +1,13 @@ +r"""The polarized, time-like |OME|.""" + +import numba as nb + + +@nb.njit(cache=True) +def A_non_singlet(_matching_order, _n, _sx, _nf, _L): + raise NotImplementedError("Polarised, time-like is not yet implemented") + + +@nb.njit(cache=True) +def A_non_singlet(_order, _n, _sx, _nf, _L): + raise NotImplementedError("Polarised, time-like is not yet implemented") diff --git a/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py new file mode 100644 index 000000000..2d3107dce --- /dev/null +++ b/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py @@ -0,0 +1,13 @@ +r"""The polarized, time-like |OME|.""" + +import numba as nb + + +@nb.njit(cache=True) +def A_non_singlet(_matching_order, _n, _sx, _nf, _L): + raise NotImplementedError("Time-like is not yet implemented") + + +@nb.njit(cache=True) +def A_non_singlet(_order, _n, _sx, _nf, _L): + raise NotImplementedError("Time-like is not yet implemented") diff --git a/tests/eko/evolution_operator/test_ome.py b/tests/eko/evolution_operator/test_ome.py index 64824b85d..0d33d071d 100644 --- a/tests/eko/evolution_operator/test_ome.py +++ b/tests/eko/evolution_operator/test_ome.py @@ -14,7 +14,10 @@ from eko.io.types import InversionMethod from eko.runner import legacy from ekore.harmonics import compute_cache -from ekore.operator_matrix_elements.unpolarized.space_like import A_non_singlet, A_singlet +from ekore.operator_matrix_elements.unpolarized.space_like import ( + A_non_singlet, + A_singlet, +) max_weight_dict = {1: 2, 2: 3, 3: 5} @@ -109,6 +112,8 @@ def test_quad_ker(monkeypatch): nf=3, L=0.0, is_msbar=False, + is_polarized=False, + is_time_like=False, ) np.testing.assert_allclose(res_ns, 1.0) res_s = quad_ker( @@ -124,6 +129,8 @@ def test_quad_ker(monkeypatch): nf=3, L=0.0, is_msbar=False, + is_polarized=False, + is_time_like=False, ) np.testing.assert_allclose(res_s, 1.0) res_s = quad_ker( @@ -139,6 +146,8 @@ def test_quad_ker(monkeypatch): nf=3, L=0.0, is_msbar=False, + is_polarized=False, + is_time_like=False, ) np.testing.assert_allclose(res_s, 0.0) @@ -158,6 +167,8 @@ def test_quad_ker(monkeypatch): nf=3, L=0.0, is_msbar=False, + is_polarized=False, + is_time_like=False, ) if label[-1] == label[-2]: np.testing.assert_allclose(res_ns, 1.0) @@ -191,6 +202,8 @@ def test_quad_ker(monkeypatch): nf=3, L=0.0, is_msbar=False, + is_polarized=False, + is_time_like=False, ) if label[-1] == label[-2]: np.testing.assert_allclose(res_ns, 1.0) @@ -211,6 +224,8 @@ def test_quad_ker(monkeypatch): nf=3, L=0.0, is_msbar=False, + is_polarized=False, + is_time_like=False, ) np.testing.assert_allclose(res_ns, 0.0) From 7a74ddbfdfff5b485de3aec20d7f1fbcd33b6c29 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 17 Jan 2023 18:15:57 +0100 Subject: [PATCH 11/30] Fix function names --- .../operator_matrix_elements/polarized/space_like/__init__.py | 2 +- .../operator_matrix_elements/polarized/time_like/__init__.py | 2 +- .../operator_matrix_elements/unpolarized/time_like/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py b/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py index 2dab4db48..5d5f771f7 100644 --- a/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py +++ b/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py @@ -9,5 +9,5 @@ def A_non_singlet(_matching_order, _n, _sx, _nf, _L): @nb.njit(cache=True) -def A_non_singlet(_order, _n, _sx, _nf, _L): +def A_singlet(_matching_order, _n, _sx, _nf, _L, _is_msbar, _sx_ns=None): raise NotImplementedError("Polarised, space-like is not yet implemented") diff --git a/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py b/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py index c5232eff3..81b9f3de8 100644 --- a/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py +++ b/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py @@ -9,5 +9,5 @@ def A_non_singlet(_matching_order, _n, _sx, _nf, _L): @nb.njit(cache=True) -def A_non_singlet(_order, _n, _sx, _nf, _L): +def A_singlet(_matching_order, _n, _sx, _nf, _L, _is_msbar, _sx_ns=None): raise NotImplementedError("Polarised, time-like is not yet implemented") diff --git a/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py index 2d3107dce..53c68e8d6 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py +++ b/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py @@ -9,5 +9,5 @@ def A_non_singlet(_matching_order, _n, _sx, _nf, _L): @nb.njit(cache=True) -def A_non_singlet(_order, _n, _sx, _nf, _L): +def A_singlet(_matching_order, _n, _sx, _nf, _L, _is_msbar, _sx_ns=None): raise NotImplementedError("Time-like is not yet implemented") From 112608934a46bde7d5541a113784bdf3e0f0f0f7 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 26 Jan 2023 16:26:40 +0100 Subject: [PATCH 12/30] Fix runcard translation --- src/eko/io/runcards.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/eko/io/runcards.py b/src/eko/io/runcards.py index 941078f8f..4b41ea1f9 100644 --- a/src/eko/io/runcards.py +++ b/src/eko/io/runcards.py @@ -331,6 +331,7 @@ def new_operator(self): "ev_op_iterations", "n_integration_cores", "polarized", + "time_like", ): new["configs"][k] = old[k] max_order = old["ev_op_max_order"] From 9226ccc3feb8a900e3fe97b649bb97aa2ad77aa3 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Thu, 26 Jan 2023 16:56:10 +0100 Subject: [PATCH 13/30] Init cache at LO --- .../unpolarized/space_like/__init__.py | 8 ++- .../unpolarized/space_like/as1.py | 21 ++++--- src/ekore/harmonics/cache.py | 56 +++++++++++++++++++ 3 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 src/ekore/harmonics/cache.py diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py index dc4ad9dbf..e070835ec 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py @@ -19,6 +19,7 @@ import numpy as np from .... import harmonics +from ....harmonics import cache as c from . import aem1, aem2, as1, as2, as3, as4 @@ -70,7 +71,9 @@ def gamma_ns(order, mode, n, nf): sx = harmonics.sx(n, max_weight=order[0] + 1) # now combine gamma_ns = np.zeros(order[0], np.complex_) - gamma_ns[0] = as1.gamma_ns(n, sx[0]) + + cache = c.reset() + gamma_ns[0] = as1.gamma_ns(n, cache) # NLO and beyond if order[0] >= 2: if mode == 10101: @@ -145,8 +148,9 @@ def gamma_singlet(order, n, nf): else: sx = harmonics.sx(n, max_weight=order[0]) + cache = c.reset() gamma_s = np.zeros((order[0], 2, 2), np.complex_) - gamma_s[0] = as1.gamma_singlet(n, sx[0], nf) + gamma_s[0] = as1.gamma_singlet(n, nf, cache) if order[0] >= 2: gamma_s[1] = as2.gamma_singlet(n, nf, sx) if order[0] >= 3: diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py index 28afb3a00..cdcc0afcc 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py @@ -5,9 +5,11 @@ from eko import constants +from ....harmonics import cache as c + @nb.njit(cache=True) -def gamma_ns(N, s1): +def gamma_ns(N, cache): """ Computes the leading-order non-singlet anomalous dimension. @@ -17,15 +19,13 @@ def gamma_ns(N, s1): ---------- N : complex Mellin moment - s1 : complex - harmonic sum :math:`S_{1}` Returns ------- gamma_ns : complex Leading-order non-singlet anomalous dimension :math:`\\gamma_{ns}^{(0)}(N)` """ - gamma = -(3.0 - 4.0 * s1 + 2.0 / N / (N + 1.0)) + gamma = -(3.0 - 4.0 * c.get(c.S1, cache, N) + 2.0 / N / (N + 1.0)) result = constants.CF * gamma return result @@ -77,7 +77,7 @@ def gamma_gq(N): @nb.njit(cache=True) -def gamma_gg(N, s1, nf): +def gamma_gg(N, nf, cache): """ Computes the leading-order gluon-gluon anomalous dimension @@ -87,8 +87,6 @@ def gamma_gg(N, s1, nf): ---------- N : complex Mellin moment - s1 : complex - harmonic sum :math:`S_{1}` nf : int Number of active flavors @@ -97,13 +95,13 @@ def gamma_gg(N, s1, nf): gamma_gg : complex Leading-order gluon-gluon anomalous dimension :math:`\\gamma_{gg}^{(0)}(N)` """ - gamma = s1 - 1.0 / N / (N - 1.0) - 1.0 / (N + 1.0) / (N + 2.0) + gamma = c.get(c.S1, cache, N) - 1.0 / N / (N - 1.0) - 1.0 / (N + 1.0) / (N + 2.0) result = constants.CA * (4.0 * gamma - 11.0 / 3.0) + 4.0 / 3.0 * constants.TR * nf return result @nb.njit(cache=True) -def gamma_singlet(N, s1, nf): +def gamma_singlet(N, nf, cache): r""" Computes the leading-order singlet anomalous dimension matrix @@ -134,8 +132,9 @@ def gamma_singlet(N, s1, nf): gamma_gq : :math:`\gamma_{gq}^{(0)}` gamma_gg : :math:`\gamma_{gg}^{(0)}` """ - gamma_qq = gamma_ns(N, s1) + gamma_qq = gamma_ns(N, cache) gamma_S_0 = np.array( - [[gamma_qq, gamma_qg(N, nf)], [gamma_gq(N), gamma_gg(N, s1, nf)]], np.complex_ + [[gamma_qq, gamma_qg(N, nf)], [gamma_gq(N), gamma_gg(N, nf, cache)]], + np.complex_, ) return gamma_S_0 diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py new file mode 100644 index 000000000..81491b9a8 --- /dev/null +++ b/src/ekore/harmonics/cache.py @@ -0,0 +1,56 @@ +"""Caching (complicated) harmonic sums across :mod:`ekore`.""" +import numba as nb +import numpy as np +import numpy.typing as npt + +from . import w1, w2 + +# here a register of all possible functions +S1 = 0 # = S_1(N) +S2 = 1 +# this could also be S1h = S1(N/2) +# the only requirement is that they are insubsequent order +# and reset knows the maximum size (to fit them all) + +# this is a plain list holding the values +@nb.njit(cache=True) +def reset(): + """Return the cache placeholder array.""" + return np.full(2, np.nan, np.complex_) + + +@nb.njit(cache=True) +def get(key: int, cache: npt.ArrayLike, n: complex) -> complex: + """Retrieve a element of the cache. + + Parameters + ---------- + key : + harmonic sum key + cache : + cache list holding all elements + n : + complex evaluation point + + Returns + ------- + complex : + requested harmonic sum evaluated at n + + """ + # Maybe improve error + if key < 0 or key > len(cache): + raise RuntimeError + # load the thing + s = cache[key] + # found? i.e. not NaN? + if not np.isnan(s): + return s + # compute it now ... + if key == S1: + s = w1.S1(n) + elif key == S2: + s = w2.S2(n) + # store and return + cache[key] = s + return s From 45b95a5345c8702d36e0d4c9615a3b22f5706b8c Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Fri, 27 Jan 2023 10:51:14 +0100 Subject: [PATCH 14/30] Update src/ekore/harmonics/cache.py Co-authored-by: Giacomo Magni <39065935+giacomomagni@users.noreply.github.com> --- src/ekore/harmonics/cache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index 81491b9a8..84d811929 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -21,7 +21,7 @@ def reset(): @nb.njit(cache=True) def get(key: int, cache: npt.ArrayLike, n: complex) -> complex: - """Retrieve a element of the cache. + """Retrieve an element of the cache. Parameters ---------- From 764d876fdbd702638f35e7593e066432b6876be8 Mon Sep 17 00:00:00 2001 From: t7phy Date: Mon, 30 Jan 2023 22:19:00 +0100 Subject: [PATCH 15/30] added all harmonic sums that are currently implemented to new cache, and added harmonic constants to eko.constants module --- src/eko/constants.py | 19 ++++++++ src/ekore/harmonics/cache.py | 71 ++++++++++++++++++++++++++-- src/ekore/harmonics/g_functions.py | 2 +- src/ekore/harmonics/log_functions.py | 2 +- src/ekore/harmonics/w2.py | 2 +- src/ekore/harmonics/w3.py | 2 +- src/ekore/harmonics/w4.py | 2 +- src/ekore/harmonics/w5.py | 2 +- 8 files changed, 92 insertions(+), 10 deletions(-) diff --git a/src/eko/constants.py b/src/eko/constants.py index b5cfb54f7..3eb57aa1b 100644 --- a/src/eko/constants.py +++ b/src/eko/constants.py @@ -1,6 +1,8 @@ """This files sets the physical constants.""" import numba as nb +import numpy as np +from scipy.special import zeta NC = 3 """The number of colors.""" @@ -29,6 +31,23 @@ ed2 = 1.0 / 9 """Down quarks charge squared.""" +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)`""" def update_colors(nc): """Updates the number of colors to :math:`NC = nc`. diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index 84d811929..b49bcc454 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -3,11 +3,29 @@ import numpy as np import numpy.typing as npt -from . import w1, w2 +from . import w1, w2, w3, w4, w5 # here a register of all possible functions S1 = 0 # = S_1(N) S2 = 1 +S3 = 2 +S4 = 3 +S5 = 4 +Sm1 = 5 +Sm2 = 6 +Sm3 = 7 +Sm4 = 8 +Sm5 = 9 +S21 = 10 +S2m1 = 11 +Sm21 = 12 +Sm2m1 = 13 +S31 = 14 +Sm31 = 15 +Sm22 = 16 +S211 = 17 +Sm211 = 18 + # this could also be S1h = S1(N/2) # the only requirement is that they are insubsequent order # and reset knows the maximum size (to fit them all) @@ -16,11 +34,11 @@ @nb.njit(cache=True) def reset(): """Return the cache placeholder array.""" - return np.full(2, np.nan, np.complex_) + return np.full(19, np.nan, np.complex_) @nb.njit(cache=True) -def get(key: int, cache: npt.ArrayLike, n: complex) -> complex: +def get(key: int, cache: npt.ArrayLike, n: complex, is_singlet: bool) -> complex: """Retrieve an element of the cache. Parameters @@ -31,6 +49,9 @@ def get(key: int, cache: npt.ArrayLike, n: complex) -> complex: cache list holding all elements n : complex evaluation point + is_singlet : + symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), + False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) Returns ------- @@ -51,6 +72,48 @@ def get(key: int, cache: npt.ArrayLike, n: complex) -> complex: s = w1.S1(n) elif key == S2: s = w2.S2(n) + elif key == S3: + s = w3.S3(n) + elif key == S4: + s = w4.S4(n) + elif key == S5: + s = w5.S5(n) + elif key == Sm1: + s = w1.Sm1(n, get(S1, cache, n), is_singlet) + elif key == Sm2: + s = w2.Sm2(n, get(S2, cache, n), is_singlet) + elif key == Sm3: + s = w3.Sm3(n, get(S3, cache, n), is_singlet) + elif key == Sm4: + s = w4.Sm4(n, get(S4, cache, n), is_singlet) + elif key == Sm5: + s = w5.Sm5(n, get(S5, cache, n), is_singlet) + elif key == S21: + s = w3.S21(n, get(S1, cache, n), get(S2, cache, n)) + elif key == S2m1: + s = w3.S2m1(n, get(S2, cache, n), get(Sm1, cache, n), + get(Sm2, cache, n), is_singlet) + elif key == Sm21: + s = w3.Sm21(n, get(S1, cache, n), get(Sm1, cache, n), + is_singlet) + elif key == Sm2m1: + s = w3.Sm2m1(n, get(S1, cache, n), get(S2, cache, n), + get(Sm2, cache, n)) + elif key == S31: + s = w4.S31(n, get(S1, cache, n), get(S2, cache, n), + get(S3, cache, n), get(S4, cache, n)) + elif key == Sm31: + s = w4.Sm31(n, get(S1, cache, n), get(Sm1, cache, n), + get(Sm2, cache, n), is_singlet) + elif key == Sm22: + s = w4.Sm22(n, get(S1, cache, n), get(S2, cache, n), + get(Sm2, cache, n), get(Sm31, cache, n), is_singlet) + elif key == S211: + s = w4.S211(n, get(S1, cache, n), get(S2, cache, n), + get(S3, cache, n)) + elif key == Sm211: + s = Sm211(n, get(S1, cache, n), get(S2, cache, n), + get(Sm1, cache, n), is_singlet) # store and return cache[key] = s - return s + return s \ No newline at end of file diff --git a/src/ekore/harmonics/g_functions.py b/src/ekore/harmonics/g_functions.py index dc7073175..dea674ae4 100644 --- a/src/ekore/harmonics/g_functions.py +++ b/src/ekore/harmonics/g_functions.py @@ -6,7 +6,7 @@ import numpy as np from . import w1 -from .constants import log2, zeta2, zeta3 +from eko.constants import log2, zeta2, zeta3 from .polygamma import recursive_harmonic_sum as s a1 = np.array( diff --git a/src/ekore/harmonics/log_functions.py b/src/ekore/harmonics/log_functions.py index 8cf1bf857..6d321063b 100644 --- a/src/ekore/harmonics/log_functions.py +++ b/src/ekore/harmonics/log_functions.py @@ -8,7 +8,7 @@ """ import numba as nb -from .constants import zeta3 +from eko.constants import zeta3 @nb.njit(cache=True) diff --git a/src/ekore/harmonics/w2.py b/src/ekore/harmonics/w2.py index 69c0029eb..249b26757 100644 --- a/src/ekore/harmonics/w2.py +++ b/src/ekore/harmonics/w2.py @@ -2,7 +2,7 @@ import numba as nb -from .constants import zeta2 +from eko.constants import zeta2 from .polygamma import cern_polygamma diff --git a/src/ekore/harmonics/w3.py b/src/ekore/harmonics/w3.py index dcd52428c..a09f906d1 100644 --- a/src/ekore/harmonics/w3.py +++ b/src/ekore/harmonics/w3.py @@ -3,7 +3,7 @@ import numba as nb from . import g_functions as gf -from .constants import log2, zeta2, zeta3 +from eko.constants import log2, zeta2, zeta3 from .polygamma import cern_polygamma, symmetry_factor diff --git a/src/ekore/harmonics/w4.py b/src/ekore/harmonics/w4.py index 855602ec7..55b9b25bb 100644 --- a/src/ekore/harmonics/w4.py +++ b/src/ekore/harmonics/w4.py @@ -3,7 +3,7 @@ import numba as nb from . import g_functions as gf -from .constants import li4half, log2, zeta2, zeta3, zeta4 +from eko.constants import li4half, log2, zeta2, zeta3, zeta4 from .polygamma import cern_polygamma, symmetry_factor diff --git a/src/ekore/harmonics/w5.py b/src/ekore/harmonics/w5.py index b75f9eebf..c9da46c3d 100644 --- a/src/ekore/harmonics/w5.py +++ b/src/ekore/harmonics/w5.py @@ -3,7 +3,7 @@ import numba as nb from . import f_functions as f -from .constants import log2, zeta2, zeta3, zeta4, zeta5 +from eko.constants import log2, zeta2, zeta3, zeta4, zeta5 from .polygamma import cern_polygamma, symmetry_factor From d2fd5357e88c6ba22d45eb79c81536f8ec5a68ad Mon Sep 17 00:00:00 2001 From: t7phy Date: Mon, 30 Jan 2023 22:34:39 +0100 Subject: [PATCH 16/30] with pre-commit --- src/ekore/harmonics/cache.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index b49bcc454..7f0264d55 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -38,7 +38,8 @@ def reset(): @nb.njit(cache=True) -def get(key: int, cache: npt.ArrayLike, n: complex, is_singlet: bool) -> complex: +def get(key: int, cache: npt.ArrayLike, + n: complex, is_singlet: bool) -> complex: """Retrieve an element of the cache. Parameters @@ -50,8 +51,10 @@ def get(key: int, cache: npt.ArrayLike, n: complex, is_singlet: bool) -> complex n : complex evaluation point is_singlet : - symmetry factor: True for singlet like quantities (:math:`\eta=(-1)^N = 1`), - False for non-singlet like quantities (:math:`\eta=(-1)^N=-1`) + symmetry factor: True for singlet like quantities + (:math:`\eta=(-1)^N = 1`), + False for non-singlet like quantities + (:math:`\eta=(-1)^N=-1`) Returns ------- From 3d766ba4514714b141efe795451ac1d009ca008d Mon Sep 17 00:00:00 2001 From: t7phy Date: Mon, 30 Jan 2023 23:12:31 +0100 Subject: [PATCH 17/30] change imports to use eko.constants --- .../anomalous_dimensions/unpolarized/space_like/as1aem1.py | 2 +- src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py | 2 +- src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py | 4 ++-- .../anomalous_dimensions/unpolarized/space_like/as4/gnsm.py | 3 +-- src/ekore/harmonics/g_functions.py | 2 +- src/ekore/harmonics/log_functions.py | 1 - src/ekore/harmonics/w3.py | 2 +- src/ekore/harmonics/w4.py | 2 +- src/ekore/harmonics/w5.py | 2 +- .../operator_matrix_elements/unpolarized/space_like/as2.py | 2 +- 10 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py index e16133a05..cc131e980 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py @@ -5,8 +5,8 @@ import numba as nb from eko import constants +from eko.constants import zeta2, zeta3 from .... import harmonics -from ....harmonics.constants import zeta2, zeta3 @nb.njit(cache=True) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py index 8691a54b2..eb34db624 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py @@ -10,8 +10,8 @@ import numpy as np from eko import constants +from eko.constants import log2, zeta2, zeta3 from .... import harmonics -from ....harmonics.constants import log2, zeta2, zeta3 @nb.njit(cache=True) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py index a2387bd08..8cc858c7b 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py @@ -5,11 +5,11 @@ Note that the QCD colour factors have been hard-wired in the parametrizations. """ +from eko.constants import zeta2, zeta3 + import numba as nb import numpy as np -from ....harmonics.constants import zeta2, zeta3 - @nb.njit(cache=True) def gamma_nsm(n, nf, sx): diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py index 336d5b568..1fa3e3172 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py @@ -3,8 +3,7 @@ """ import numba as nb -from eko.constants import CF -from .....harmonics.constants import zeta3 +from eko.constants import CF, zeta3 from .....harmonics.log_functions import lm11m1, lm12m1, lm13m1 diff --git a/src/ekore/harmonics/g_functions.py b/src/ekore/harmonics/g_functions.py index dea674ae4..523828202 100644 --- a/src/ekore/harmonics/g_functions.py +++ b/src/ekore/harmonics/g_functions.py @@ -5,8 +5,8 @@ import numba as nb import numpy as np -from . import w1 from eko.constants import log2, zeta2, zeta3 +from . import w1 from .polygamma import recursive_harmonic_sum as s a1 = np.array( diff --git a/src/ekore/harmonics/log_functions.py b/src/ekore/harmonics/log_functions.py index 6d321063b..62a563ccf 100644 --- a/src/ekore/harmonics/log_functions.py +++ b/src/ekore/harmonics/log_functions.py @@ -10,7 +10,6 @@ from eko.constants import zeta3 - @nb.njit(cache=True) def lm11m1(n, S1): r"""Mellin transform of :math:`(1-x)\ln(1-x)`. diff --git a/src/ekore/harmonics/w3.py b/src/ekore/harmonics/w3.py index a09f906d1..531c17716 100644 --- a/src/ekore/harmonics/w3.py +++ b/src/ekore/harmonics/w3.py @@ -2,8 +2,8 @@ import numba as nb -from . import g_functions as gf from eko.constants import log2, zeta2, zeta3 +from . import g_functions as gf from .polygamma import cern_polygamma, symmetry_factor diff --git a/src/ekore/harmonics/w4.py b/src/ekore/harmonics/w4.py index 55b9b25bb..840ed4c70 100644 --- a/src/ekore/harmonics/w4.py +++ b/src/ekore/harmonics/w4.py @@ -2,8 +2,8 @@ import numba as nb -from . import g_functions as gf from eko.constants import li4half, log2, zeta2, zeta3, zeta4 +from . import g_functions as gf from .polygamma import cern_polygamma, symmetry_factor diff --git a/src/ekore/harmonics/w5.py b/src/ekore/harmonics/w5.py index c9da46c3d..5c88eb15d 100644 --- a/src/ekore/harmonics/w5.py +++ b/src/ekore/harmonics/w5.py @@ -2,8 +2,8 @@ import numba as nb -from . import f_functions as f from eko.constants import log2, zeta2, zeta3, zeta4, zeta5 +from . import f_functions as f from .polygamma import cern_polygamma, symmetry_factor diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py index 2197fbfd9..3549bd324 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py @@ -12,8 +12,8 @@ import numpy as np from eko import constants +from eko.constants import zeta2, zeta3 -from ....harmonics.constants import zeta2, zeta3 from .as1 import A_gg as A_gg_1 from .as1 import A_hg as A_hg_1 From 26f1ddb4f5cdbe5a62e1b5d45ca55b0aa29d253b Mon Sep 17 00:00:00 2001 From: t7phy Date: Tue, 31 Jan 2023 11:57:01 +0100 Subject: [PATCH 18/30] added fractional harmonic sums and g functions to cache --- src/ekore/harmonics/cache.py | 39 +++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index 7f0264d55..fc800f8ad 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -4,6 +4,7 @@ import numpy.typing as npt from . import w1, w2, w3, w4, w5 +from .g_functions import mellin_g3 # here a register of all possible functions S1 = 0 # = S_1(N) @@ -25,6 +26,18 @@ Sm22 = 16 S211 = 17 Sm211 = 18 +S1h = 19 +S2h = 20 +S3h = 21 +S1mh = 22 +S2mh = 23 +S3mh = 24 +S1ph = 25 +S2ph = 26 +S3ph = 27 +g3 = 28 +S1p2 = 29 +g3p2 = 30 # this could also be S1h = S1(N/2) # the only requirement is that they are insubsequent order @@ -34,7 +47,7 @@ @nb.njit(cache=True) def reset(): """Return the cache placeholder array.""" - return np.full(19, np.nan, np.complex_) + return np.full(31, np.nan, np.complex_) @nb.njit(cache=True) @@ -117,6 +130,30 @@ def get(key: int, cache: npt.ArrayLike, elif key == Sm211: s = Sm211(n, get(S1, cache, n), get(S2, cache, n), get(Sm1, cache, n), is_singlet) + elif key == S1h: + s = w1.S1(n/2) + elif key == S2h: + s = w2.S2(n/2) + elif key == S3h: + s = w3.S3(n/2) + elif key == S1mh: + s = w1.S1((n-1)/2) + elif key == S2mh: + s = w2.S2((n-1)/2) + elif key == S3mh: + s = w3.s3((n-1)/2) + elif key == S1ph: + s = w1.S1((n+1)/2) + elif key == S2ph: + s = w2.S2((n+1)/2) + elif key == S3ph: + s = w3.S3((n+1)/2) + elif key == g3: + s = mellin_g3(n, get(S1, cache, n)) + elif key == S1p2: + s = w1.S1(n+2) + elif key == g3p2: + s = mellin_g3(n+2, get(S1p2, cache, n)) # store and return cache[key] = s return s \ No newline at end of file From 611f3bbc79a59dc6120816975917232f53ab0c88 Mon Sep 17 00:00:00 2001 From: t7phy Date: Wed, 1 Feb 2023 01:37:16 +0100 Subject: [PATCH 19/30] harmonic sums Smx using cache --- src/ekore/harmonics/cache.py | 57 +++++++++++++++++++++----------- src/ekore/harmonics/constants.py | 22 ------------ src/ekore/harmonics/w1.py | 11 +++--- src/ekore/harmonics/w2.py | 10 +++--- src/ekore/harmonics/w3.py | 10 +++--- src/ekore/harmonics/w4.py | 10 +++--- src/ekore/harmonics/w5.py | 10 +++--- 7 files changed, 68 insertions(+), 62 deletions(-) delete mode 100644 src/ekore/harmonics/constants.py diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index fc800f8ad..3d3d4f68b 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -2,6 +2,7 @@ import numba as nb import numpy as np import numpy.typing as npt +import polygamma from . import w1, w2, w3, w4, w5 from .g_functions import mellin_g3 @@ -29,15 +30,21 @@ S1h = 19 S2h = 20 S3h = 21 -S1mh = 22 -S2mh = 23 -S3mh = 24 -S1ph = 25 -S2ph = 26 -S3ph = 27 -g3 = 28 -S1p2 = 29 -g3p2 = 30 +S4h = 22 +S5h = 23 +S1mh = 24 +S2mh = 25 +S3mh = 26 +S4mh = 27 +S5mh = 28 +S1ph = 29 +S2ph = 30 +S3ph = 31 +S4ph = 32 +S5ph = 33 +g3 = 34 +S1p2 = 35 +g3p2 = 36 # this could also be S1h = S1(N/2) # the only requirement is that they are insubsequent order @@ -47,7 +54,7 @@ @nb.njit(cache=True) def reset(): """Return the cache placeholder array.""" - return np.full(31, np.nan, np.complex_) + return np.full(37, np.nan, np.complex_) @nb.njit(cache=True) @@ -95,15 +102,15 @@ def get(key: int, cache: npt.ArrayLike, elif key == S5: s = w5.S5(n) elif key == Sm1: - s = w1.Sm1(n, get(S1, cache, n), is_singlet) + s = w1.Sm1(n, get(S1, cache, n), cache, is_singlet) elif key == Sm2: - s = w2.Sm2(n, get(S2, cache, n), is_singlet) + s = w2.Sm2(n, get(S2, cache, n), cache, is_singlet) elif key == Sm3: - s = w3.Sm3(n, get(S3, cache, n), is_singlet) + s = w3.Sm3(n, get(S3, cache, n), cache, is_singlet) elif key == Sm4: - s = w4.Sm4(n, get(S4, cache, n), is_singlet) + s = w4.Sm4(n, get(S4, cache, n), cache, is_singlet) elif key == Sm5: - s = w5.Sm5(n, get(S5, cache, n), is_singlet) + s = w5.Sm5(n, get(S5, cache, n), cache, is_singlet) elif key == S21: s = w3.S21(n, get(S1, cache, n), get(S2, cache, n)) elif key == S2m1: @@ -136,22 +143,34 @@ def get(key: int, cache: npt.ArrayLike, s = w2.S2(n/2) elif key == S3h: s = w3.S3(n/2) + elif key == S4h: + s = w4.S4(n/2) + elif key == S5h: + s = w5.S5(n/2) elif key == S1mh: s = w1.S1((n-1)/2) elif key == S2mh: s = w2.S2((n-1)/2) elif key == S3mh: s = w3.s3((n-1)/2) + elif key == S4mh: + s = w4.S4((n-1)/2) + elif key == S5mh: + s = w5.s5((n-1)/2) elif key == S1ph: - s = w1.S1((n+1)/2) + s = polygamma.recursive_harmonic_sum(get(S1mh, cache, n), n, 1, 1) elif key == S2ph: - s = w2.S2((n+1)/2) + s = polygamma.recursive_harmonic_sum(get(S2mh, cache, n), n, 1, 2) elif key == S3ph: - s = w3.S3((n+1)/2) + s = polygamma.recursive_harmonic_sum(get(S3mh, cache, n), n, 1, 3) + elif key == S4ph: + s = polygamma.recursive_harmonic_sum(get(S4mh, cache, n), n, 1, 4) + elif key == S5ph: + s = polygamma.recursive_harmonic_sum(get(S5mh, cache, n), n, 1, 5) elif key == g3: s = mellin_g3(n, get(S1, cache, n)) elif key == S1p2: - s = w1.S1(n+2) + s = polygamma.recursive_harmonic_sum(get(S1, cache, n), n, 2, 1) elif key == g3p2: s = mellin_g3(n+2, get(S1p2, cache, n)) # store and return diff --git a/src/ekore/harmonics/constants.py b/src/ekore/harmonics/constants.py deleted file mode 100644 index df64544dd..000000000 --- a/src/ekore/harmonics/constants.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Zeta function values 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/ekore/harmonics/w1.py b/src/ekore/harmonics/w1.py index 10f7cc3d4..aced47bd5 100644 --- a/src/ekore/harmonics/w1.py +++ b/src/ekore/harmonics/w1.py @@ -3,6 +3,7 @@ import numba as nb import numpy as np +from . import cache as c from .polygamma import cern_polygamma @@ -34,7 +35,7 @@ def S1(N): @nb.njit(cache=True) -def Sm1(N, hS1, is_singlet=None): +def Sm1(N, hS1, cache, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-1}(N)`. .. math:: @@ -60,10 +61,10 @@ def Sm1(N, hS1, is_singlet=None): """ if is_singlet is None: return ( - (1 - (-1) ** N) / 2 * S1((N - 1) / 2) - + ((-1) ** N + 1) / 2 * S1(N / 2) + (1 - (-1) ** N) / 2 * c.get(c.S1mh, cache, N, is_singlet) + + ((-1) ** N + 1) / 2 * c.get(c.S1h, cache, N, is_singlet) - hS1 ) if is_singlet: - return S1(N / 2) - hS1 - return S1((N - 1) / 2) - hS1 + return c.get(c.S1h, cache, N, is_singlet) - hS1 + return c.get(c.S1mh, cache, N, is_singlet) - hS1 diff --git a/src/ekore/harmonics/w2.py b/src/ekore/harmonics/w2.py index 249b26757..9537ae146 100644 --- a/src/ekore/harmonics/w2.py +++ b/src/ekore/harmonics/w2.py @@ -3,6 +3,7 @@ import numba as nb from eko.constants import zeta2 +from . import cache as c from .polygamma import cern_polygamma @@ -34,7 +35,7 @@ def S2(N): @nb.njit(cache=True) -def Sm2(N, hS2, is_singlet=None): +def Sm2(N, hS2, cache, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-2}(N)`. .. math:: @@ -64,9 +65,10 @@ def Sm2(N, hS2, is_singlet=None): return ( 1 / 2 - * ((1 - (-1) ** N) / 2 * S2((N - 1) / 2) + ((-1) ** N + 1) / 2 * S2(N / 2)) + * ((1 - (-1) ** N) / 2 * c.get(c.S2mh, cache, N, is_singlet) + + ((-1) ** N + 1) / 2 * c.get(c.S2h, cache, N, is_singlet)) - hS2 ) if is_singlet: - return 1 / 2 * S2(N / 2) - hS2 - return 1 / 2 * S2((N - 1) / 2) - hS2 + return 1 / 2 * c.get(c.S2h, cache, N, is_singlet) - hS2 + return 1 / 2 * c.get(c.S2mh, cache, N, is_singlet) - hS2 diff --git a/src/ekore/harmonics/w3.py b/src/ekore/harmonics/w3.py index 531c17716..44aa224e0 100644 --- a/src/ekore/harmonics/w3.py +++ b/src/ekore/harmonics/w3.py @@ -3,6 +3,7 @@ import numba as nb from eko.constants import log2, zeta2, zeta3 +from . import cache as c from . import g_functions as gf from .polygamma import cern_polygamma, symmetry_factor @@ -36,7 +37,7 @@ def S3(N): @nb.njit(cache=True) -def Sm3(N, hS3, is_singlet=None): +def Sm3(N, hS3, cache, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-3}(N)`. .. math:: @@ -66,12 +67,13 @@ def Sm3(N, hS3, is_singlet=None): return ( 1 / 2**2 - * ((1 - (-1) ** N) / 2 * S3((N - 1) / 2) + ((-1) ** N + 1) / 2 * S3(N / 2)) + * ((1 - (-1) ** N) / 2 * c.get(c.S3mh, cache, N, is_singlet) + + ((-1) ** N + 1) / 2 * c.get(c.S3h, cache, N, is_singlet)) - hS3 ) if is_singlet: - return 1 / 2**2 * S3(N / 2) - hS3 - return 1 / 2**2 * S3((N - 1) / 2) - hS3 + return 1 / 2**2 * c.get(c.S3h, cache, N, is_singlet) - hS3 + return 1 / 2**2 * c.get(c.S3mh, cache, N, is_singlet) - hS3 @nb.njit(cache=True) diff --git a/src/ekore/harmonics/w4.py b/src/ekore/harmonics/w4.py index 840ed4c70..75b2e5868 100644 --- a/src/ekore/harmonics/w4.py +++ b/src/ekore/harmonics/w4.py @@ -3,6 +3,7 @@ import numba as nb from eko.constants import li4half, log2, zeta2, zeta3, zeta4 +from . import cache as c from . import g_functions as gf from .polygamma import cern_polygamma, symmetry_factor @@ -36,7 +37,7 @@ def S4(N): @nb.njit(cache=True) -def Sm4(N, hS4, is_singlet=None): +def Sm4(N, hS4, cache, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-4}(N)`. .. math:: @@ -66,12 +67,13 @@ def Sm4(N, hS4, is_singlet=None): return ( 1 / 2**3 - * ((1 - (-1) ** N) / 2 * S4((N - 1) / 2) + ((-1) ** N + 1) / 2 * S4(N / 2)) + * ((1 - (-1) ** N) / 2 * c.get(c.S4mh, cache, N, is_singlet) + + ((-1) ** N + 1) / 2 * c.get(c.S4h, cache, N, is_singlet)) - hS4 ) if is_singlet: - return 1 / 2**3 * S4(N / 2) - hS4 - return 1 / 2**3 * S4((N - 1) / 2) - hS4 + return 1 / 2**3 * c.get(c.S4h, cache, N, is_singlet) - hS4 + return 1 / 2**3 * c.get(c.S4mh, cache, N, is_singlet) - hS4 @nb.njit(cache=True) diff --git a/src/ekore/harmonics/w5.py b/src/ekore/harmonics/w5.py index 5c88eb15d..40ff3f74d 100644 --- a/src/ekore/harmonics/w5.py +++ b/src/ekore/harmonics/w5.py @@ -3,6 +3,7 @@ import numba as nb from eko.constants import log2, zeta2, zeta3, zeta4, zeta5 +from . import cache as c from . import f_functions as f from .polygamma import cern_polygamma, symmetry_factor @@ -36,7 +37,7 @@ def S5(N): @nb.njit(cache=True) -def Sm5(N, hS5, is_singlet=None): +def Sm5(N, hS5, cache, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-5}(N)`. .. math:: @@ -66,12 +67,13 @@ def Sm5(N, hS5, is_singlet=None): return ( 1 / 2**4 - * ((1 - (-1) ** N) / 2 * S5((N - 1) / 2) + ((-1) ** N + 1) / 2 * S5(N / 2)) + * ((1 - (-1) ** N) / 2 * c.get(c.S5mh, cache, N, is_singlet) + + ((-1) ** N + 1) / 2 * c.get(c.S5h, cache, N, is_singlet)) - hS5 ) if is_singlet: - return 1 / 2**4 * S5(N / 2) - hS5 - return 1 / 2**4 * S5((N - 1) / 2) - hS5 + return 1 / 2**4 * c.get(c.S5h, cache, N, is_singlet) - hS5 + return 1 / 2**4 * c.get(c.S5mh, cache, N, is_singlet) - hS5 @nb.njit(cache=True) From e88edf9739541861e0343bb78fb11421ecd3a931 Mon Sep 17 00:00:00 2001 From: t7phy Date: Wed, 1 Feb 2023 12:48:50 +0100 Subject: [PATCH 20/30] removal of recursive imports while preserving use of already computed cache --- src/ekore/harmonics/cache.py | 15 ++++++++++----- src/ekore/harmonics/w1.py | 11 +++++------ src/ekore/harmonics/w2.py | 11 +++++------ src/ekore/harmonics/w3.py | 11 +++++------ src/ekore/harmonics/w4.py | 10 +++++----- src/ekore/harmonics/w5.py | 11 +++++------ 6 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index 3d3d4f68b..d8c66637b 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -102,15 +102,20 @@ def get(key: int, cache: npt.ArrayLike, elif key == S5: s = w5.S5(n) elif key == Sm1: - s = w1.Sm1(n, get(S1, cache, n), cache, is_singlet) + s = w1.Sm1(n, get(S1, cache, n), get(S1mh, cache, n), + get(S1h, cache, n), is_singlet) elif key == Sm2: - s = w2.Sm2(n, get(S2, cache, n), cache, is_singlet) + s = w2.Sm2(n, get(S2, cache, n), get(S2mh, cache, n), + get(S2h, cache, n), is_singlet) elif key == Sm3: - s = w3.Sm3(n, get(S3, cache, n), cache, is_singlet) + s = w3.Sm3(n, get(S3, cache, n), get(S3mh, cache, n), + get(S3h, cache, n), is_singlet) elif key == Sm4: - s = w4.Sm4(n, get(S4, cache, n), cache, is_singlet) + s = w4.Sm4(n, get(S4, cache, n), get(S4mh, cache, n), + get(S4h, cache, n), is_singlet) elif key == Sm5: - s = w5.Sm5(n, get(S5, cache, n), cache, is_singlet) + s = w5.Sm5(n, get(S5, cache, n), get(S5mh, cache, n), + get(S5h, cache, n), is_singlet) elif key == S21: s = w3.S21(n, get(S1, cache, n), get(S2, cache, n)) elif key == S2m1: diff --git a/src/ekore/harmonics/w1.py b/src/ekore/harmonics/w1.py index aced47bd5..5d5914e51 100644 --- a/src/ekore/harmonics/w1.py +++ b/src/ekore/harmonics/w1.py @@ -3,7 +3,6 @@ import numba as nb import numpy as np -from . import cache as c from .polygamma import cern_polygamma @@ -35,7 +34,7 @@ def S1(N): @nb.njit(cache=True) -def Sm1(N, hS1, cache, is_singlet=None): +def Sm1(N, hS1, hS1mh, hS1h, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-1}(N)`. .. math:: @@ -61,10 +60,10 @@ def Sm1(N, hS1, cache, is_singlet=None): """ if is_singlet is None: return ( - (1 - (-1) ** N) / 2 * c.get(c.S1mh, cache, N, is_singlet) - + ((-1) ** N + 1) / 2 * c.get(c.S1h, cache, N, is_singlet) + (1 - (-1) ** N) / 2 * hS1mh + + ((-1) ** N + 1) / 2 * hS1h - hS1 ) if is_singlet: - return c.get(c.S1h, cache, N, is_singlet) - hS1 - return c.get(c.S1mh, cache, N, is_singlet) - hS1 + return hS1h - hS1 + return hS1mh - hS1 diff --git a/src/ekore/harmonics/w2.py b/src/ekore/harmonics/w2.py index 9537ae146..d0561a3c0 100644 --- a/src/ekore/harmonics/w2.py +++ b/src/ekore/harmonics/w2.py @@ -3,7 +3,6 @@ import numba as nb from eko.constants import zeta2 -from . import cache as c from .polygamma import cern_polygamma @@ -35,7 +34,7 @@ def S2(N): @nb.njit(cache=True) -def Sm2(N, hS2, cache, is_singlet=None): +def Sm2(N, hS2, hS2mh, hS2h, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-2}(N)`. .. math:: @@ -65,10 +64,10 @@ def Sm2(N, hS2, cache, is_singlet=None): return ( 1 / 2 - * ((1 - (-1) ** N) / 2 * c.get(c.S2mh, cache, N, is_singlet) - + ((-1) ** N + 1) / 2 * c.get(c.S2h, cache, N, is_singlet)) + * ((1 - (-1) ** N) / 2 * hS2mh + + ((-1) ** N + 1) / 2 * hS2h) - hS2 ) if is_singlet: - return 1 / 2 * c.get(c.S2h, cache, N, is_singlet) - hS2 - return 1 / 2 * c.get(c.S2mh, cache, N, is_singlet) - hS2 + return 1 / 2 * hS2h - hS2 + return 1 / 2 * hS2mh - hS2 diff --git a/src/ekore/harmonics/w3.py b/src/ekore/harmonics/w3.py index 44aa224e0..a63944bb1 100644 --- a/src/ekore/harmonics/w3.py +++ b/src/ekore/harmonics/w3.py @@ -3,7 +3,6 @@ import numba as nb from eko.constants import log2, zeta2, zeta3 -from . import cache as c from . import g_functions as gf from .polygamma import cern_polygamma, symmetry_factor @@ -37,7 +36,7 @@ def S3(N): @nb.njit(cache=True) -def Sm3(N, hS3, cache, is_singlet=None): +def Sm3(N, hS3, hS3mh, hS3h, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-3}(N)`. .. math:: @@ -67,13 +66,13 @@ def Sm3(N, hS3, cache, is_singlet=None): return ( 1 / 2**2 - * ((1 - (-1) ** N) / 2 * c.get(c.S3mh, cache, N, is_singlet) - + ((-1) ** N + 1) / 2 * c.get(c.S3h, cache, N, is_singlet)) + * ((1 - (-1) ** N) / 2 * hS3mh + + ((-1) ** N + 1) / 2 * hS3h) - hS3 ) if is_singlet: - return 1 / 2**2 * c.get(c.S3h, cache, N, is_singlet) - hS3 - return 1 / 2**2 * c.get(c.S3mh, cache, N, is_singlet) - hS3 + return 1 / 2**2 * hS3h - hS3 + return 1 / 2**2 * hS3mh - hS3 @nb.njit(cache=True) diff --git a/src/ekore/harmonics/w4.py b/src/ekore/harmonics/w4.py index 75b2e5868..1eca1708f 100644 --- a/src/ekore/harmonics/w4.py +++ b/src/ekore/harmonics/w4.py @@ -37,7 +37,7 @@ def S4(N): @nb.njit(cache=True) -def Sm4(N, hS4, cache, is_singlet=None): +def Sm4(N, hS4, hS4mh, hS4h, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-4}(N)`. .. math:: @@ -67,13 +67,13 @@ def Sm4(N, hS4, cache, is_singlet=None): return ( 1 / 2**3 - * ((1 - (-1) ** N) / 2 * c.get(c.S4mh, cache, N, is_singlet) - + ((-1) ** N + 1) / 2 * c.get(c.S4h, cache, N, is_singlet)) + * ((1 - (-1) ** N) / 2 * hS4mh + + ((-1) ** N + 1) / 2 * hS4h) - hS4 ) if is_singlet: - return 1 / 2**3 * c.get(c.S4h, cache, N, is_singlet) - hS4 - return 1 / 2**3 * c.get(c.S4mh, cache, N, is_singlet) - hS4 + return 1 / 2**3 * hS4h - hS4 + return 1 / 2**3 * hS4mh - hS4 @nb.njit(cache=True) diff --git a/src/ekore/harmonics/w5.py b/src/ekore/harmonics/w5.py index 40ff3f74d..01cd40267 100644 --- a/src/ekore/harmonics/w5.py +++ b/src/ekore/harmonics/w5.py @@ -3,7 +3,6 @@ import numba as nb from eko.constants import log2, zeta2, zeta3, zeta4, zeta5 -from . import cache as c from . import f_functions as f from .polygamma import cern_polygamma, symmetry_factor @@ -37,7 +36,7 @@ def S5(N): @nb.njit(cache=True) -def Sm5(N, hS5, cache, is_singlet=None): +def Sm5(N, hS5, hS5mh, hS5h, is_singlet=None): r"""Analytic continuation of harmonic sum :math:`S_{-5}(N)`. .. math:: @@ -67,13 +66,13 @@ def Sm5(N, hS5, cache, is_singlet=None): return ( 1 / 2**4 - * ((1 - (-1) ** N) / 2 * c.get(c.S5mh, cache, N, is_singlet) - + ((-1) ** N + 1) / 2 * c.get(c.S5h, cache, N, is_singlet)) + * ((1 - (-1) ** N) / 2 * hS5mh + + ((-1) ** N + 1) / 2 * hS5h) - hS5 ) if is_singlet: - return 1 / 2**4 * c.get(c.S5h, cache, N, is_singlet) - hS5 - return 1 / 2**4 * c.get(c.S5mh, cache, N, is_singlet) - hS5 + return 1 / 2**4 * hS5h - hS5 + return 1 / 2**4 * hS5mh - hS5 @nb.njit(cache=True) From 0168fa1906b063c7d0f2c0a071e9dd13043e7151 Mon Sep 17 00:00:00 2001 From: t7phy Date: Mon, 6 Feb 2023 02:31:33 +0100 Subject: [PATCH 21/30] g3p1 and g3p2 added to cache --- src/ekore/harmonics/cache.py | 13 ++++---- src/ekore/harmonics/g_functions.py | 48 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index d8c66637b..9ac87366c 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -5,7 +5,7 @@ import polygamma from . import w1, w2, w3, w4, w5 -from .g_functions import mellin_g3 +from .g_functions import mellin_g3, mellin_g3p1, mellin_g3p2 # here a register of all possible functions S1 = 0 # = S_1(N) @@ -44,7 +44,8 @@ S5ph = 33 g3 = 34 S1p2 = 35 -g3p2 = 36 +g3p1 = 36 +g3p2 = 37 # this could also be S1h = S1(N/2) # the only requirement is that they are insubsequent order @@ -54,7 +55,7 @@ @nb.njit(cache=True) def reset(): """Return the cache placeholder array.""" - return np.full(37, np.nan, np.complex_) + return np.full(38, np.nan, np.complex_) @nb.njit(cache=True) @@ -176,8 +177,10 @@ def get(key: int, cache: npt.ArrayLike, s = mellin_g3(n, get(S1, cache, n)) elif key == S1p2: s = polygamma.recursive_harmonic_sum(get(S1, cache, n), n, 2, 1) + elif key == g3p1: + s = mellin_g3p1(n, get(S1, cache, n), get(g3, cache, n)) elif key == g3p2: - s = mellin_g3(n+2, get(S1p2, cache, n)) + s = mellin_g3p2(n, get(S1, cache, n), get(g3, cache, n)) # store and return cache[key] = s - return s \ No newline at end of file + return s diff --git a/src/ekore/harmonics/g_functions.py b/src/ekore/harmonics/g_functions.py index 523828202..0561d299b 100644 --- a/src/ekore/harmonics/g_functions.py +++ b/src/ekore/harmonics/g_functions.py @@ -95,6 +95,54 @@ def mellin_g3(N, S1): return g3 +@nb.njit(cache=True) +def mellin_g3p1(N, s1, g3): + """ + Computes :math:`g_{3}(N+1)` + + Parameters + ---------- + N : complex + Mellin moment + s1 : complex + Harmonic sum :math:`S_{1}(N)` + mellin_g3 : complex + :math:`g_{3}(N)` + + Returns + ------- + mellin_g3p1 : complex + :math:`g_{3}(N+1)` + + """ + g3p1 = - s1/np.power(N, 2) - g3 + zeta2/N + return g3p1 + +@nb.njit(cache=True) +def mellin_g3p2(N, s1, g3): + """ + Computes :math:`g_{3}(N+2)` + + Parameters + ---------- + N : complex + Mellin moment + s1 : complex + Harmonic sum :math:`S_{1}(N)` + mellin_g3 : complex + :math:`g_{3}(N)` + + Returns + ------- + mellin_g3p2 : complex + :math:`g_{3}(N+2)` + + """ + g3p2 = (s1/np.power(N, 2) + g3 - zeta2/N + zeta2/(N + 1) + - s1/np.power(N + 1, 2) - 1/np.power(N + 1, 3)) + return g3p2 + + @nb.njit(cache=True) def mellin_g4(N): r""" From 65fee8afd2f3205e5aa3a6a7bd0cef7f7ac1dbdf Mon Sep 17 00:00:00 2001 From: t7phy Date: Thu, 9 Feb 2023 03:12:50 +0100 Subject: [PATCH 22/30] sm21 and pylint error fixes for cache file --- src/eko/beta.py | 2 +- src/eko/gamma.py | 2 +- src/ekore/harmonics/cache.py | 65 +++++++++++++++--------------------- src/ekore/harmonics/w3.py | 4 +-- 4 files changed, 30 insertions(+), 43 deletions(-) diff --git a/src/eko/beta.py b/src/eko/beta.py index 92212bf58..3e60b01da 100644 --- a/src/eko/beta.py +++ b/src/eko/beta.py @@ -7,7 +7,7 @@ import numba as nb from . import constants -from ekore.harmonics.constants import zeta3 +from eko.constants import zeta3 @nb.njit(cache=True) diff --git a/src/eko/gamma.py b/src/eko/gamma.py index b2c4a857b..6e67d2845 100644 --- a/src/eko/gamma.py +++ b/src/eko/gamma.py @@ -5,7 +5,7 @@ """ import numba as nb -from ekore.harmonics.constants import zeta3, zeta4, zeta5 +from eko.constants import zeta3, zeta4, zeta5 @nb.njit(cache=True) diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index 9ac87366c..5f1287223 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -2,10 +2,10 @@ import numba as nb import numpy as np import numpy.typing as npt -import polygamma from . import w1, w2, w3, w4, w5 from .g_functions import mellin_g3, mellin_g3p1, mellin_g3p2 +from .polygamma import recursive_harmonic_sum # here a register of all possible functions S1 = 0 # = S_1(N) @@ -103,46 +103,33 @@ def get(key: int, cache: npt.ArrayLike, elif key == S5: s = w5.S5(n) elif key == Sm1: - s = w1.Sm1(n, get(S1, cache, n), get(S1mh, cache, n), - get(S1h, cache, n), is_singlet) + s = w1.Sm1(n, get(S1, cache, n, is_singlet), get(S1mh, cache, n, is_singlet), get(S1h, cache, n), is_singlet) elif key == Sm2: - s = w2.Sm2(n, get(S2, cache, n), get(S2mh, cache, n), - get(S2h, cache, n), is_singlet) + s = w2.Sm2(n, get(S2, cache, n, is_singlet), get(S2mh, cache, n, is_singlet), get(S2h, cache, n, is_singlet), is_singlet) elif key == Sm3: - s = w3.Sm3(n, get(S3, cache, n), get(S3mh, cache, n), - get(S3h, cache, n), is_singlet) + s = w3.Sm3(n, get(S3, cache, n, is_singlet), get(S3mh, cache, n, is_singlet), get(S3h, cache, n, is_singlet), is_singlet) elif key == Sm4: - s = w4.Sm4(n, get(S4, cache, n), get(S4mh, cache, n), - get(S4h, cache, n), is_singlet) + s = w4.Sm4(n, get(S4, cache, n, is_singlet), get(S4mh, cache, n, is_singlet), get(S4h, cache, n, is_singlet), is_singlet) elif key == Sm5: - s = w5.Sm5(n, get(S5, cache, n), get(S5mh, cache, n), - get(S5h, cache, n), is_singlet) + s = w5.Sm5(n, get(S5, cache, n, is_singlet), get(S5mh, cache, n, is_singlet), get(S5h, cache, n, is_singlet), is_singlet) elif key == S21: - s = w3.S21(n, get(S1, cache, n), get(S2, cache, n)) + s = w3.S21(n, get(S1, cache, n, is_singlet), get(S2, cache, n, is_singlet)) elif key == S2m1: - s = w3.S2m1(n, get(S2, cache, n), get(Sm1, cache, n), - get(Sm2, cache, n), is_singlet) + s = w3.S2m1(n, get(S2, cache, n, is_singlet), get(Sm1, cache, n, is_singlet), get(Sm2, cache, n, is_singlet), is_singlet) elif key == Sm21: - s = w3.Sm21(n, get(S1, cache, n), get(Sm1, cache, n), - is_singlet) + s = w3.Sm21(n, get(S1, cache, n, is_singlet), get(Sm1, cache, n, is_singlet), get(g3p1, cache, n, is_singlet), is_singlet) elif key == Sm2m1: - s = w3.Sm2m1(n, get(S1, cache, n), get(S2, cache, n), - get(Sm2, cache, n)) + s = w3.Sm2m1(n, get(S1, cache, n, is_singlet), get(S2, cache, n, is_singlet), get(Sm2, cache, n, is_singlet)) elif key == S31: - s = w4.S31(n, get(S1, cache, n), get(S2, cache, n), - get(S3, cache, n), get(S4, cache, n)) + s = w4.S31(n, get(S1, cache, n, is_singlet), get(S2, cache, n, is_singlet), get(S3, cache, n, is_singlet), get(S4, cache, n, is_singlet)) elif key == Sm31: - s = w4.Sm31(n, get(S1, cache, n), get(Sm1, cache, n), - get(Sm2, cache, n), is_singlet) + s = w4.Sm31(n, get(S1, cache, n, is_singlet), get(Sm1, cache, n, is_singlet), get(Sm2, cache, n, is_singlet), is_singlet) elif key == Sm22: - s = w4.Sm22(n, get(S1, cache, n), get(S2, cache, n), - get(Sm2, cache, n), get(Sm31, cache, n), is_singlet) + s = w4.Sm22(n, get(S1, cache, n, is_singlet), get(S2, cache, n, is_singlet), get(Sm2, cache, n, is_singlet), get(Sm31, cache, n, is_singlet), is_singlet) elif key == S211: - s = w4.S211(n, get(S1, cache, n), get(S2, cache, n), - get(S3, cache, n)) + s = w4.S211(n, get(S1, cache, n, is_singlet), get(S2, cache, n, is_singlet), get(S3, cache, n, is_singlet)) elif key == Sm211: - s = Sm211(n, get(S1, cache, n), get(S2, cache, n), - get(Sm1, cache, n), is_singlet) + s = w4.Sm211(n, get(S1, cache, n, is_singlet), get(S2, cache, n, is_singlet), get(Sm1, cache, n, is_singlet), is_singlet) elif key == S1h: s = w1.S1(n/2) elif key == S2h: @@ -158,29 +145,29 @@ def get(key: int, cache: npt.ArrayLike, elif key == S2mh: s = w2.S2((n-1)/2) elif key == S3mh: - s = w3.s3((n-1)/2) + s = w3.S3((n-1)/2) elif key == S4mh: s = w4.S4((n-1)/2) elif key == S5mh: - s = w5.s5((n-1)/2) + s = w5.S5((n-1)/2) elif key == S1ph: - s = polygamma.recursive_harmonic_sum(get(S1mh, cache, n), n, 1, 1) + s = recursive_harmonic_sum(get(S1mh, cache, n, is_singlet), n, 1, 1) elif key == S2ph: - s = polygamma.recursive_harmonic_sum(get(S2mh, cache, n), n, 1, 2) + s = recursive_harmonic_sum(get(S2mh, cache, n, is_singlet), n, 1, 2) elif key == S3ph: - s = polygamma.recursive_harmonic_sum(get(S3mh, cache, n), n, 1, 3) + s = recursive_harmonic_sum(get(S3mh, cache, n, is_singlet), n, 1, 3) elif key == S4ph: - s = polygamma.recursive_harmonic_sum(get(S4mh, cache, n), n, 1, 4) + s = recursive_harmonic_sum(get(S4mh, cache, n, is_singlet), n, 1, 4) elif key == S5ph: - s = polygamma.recursive_harmonic_sum(get(S5mh, cache, n), n, 1, 5) + s = recursive_harmonic_sum(get(S5mh, cache, n, is_singlet), n, 1, 5) elif key == g3: - s = mellin_g3(n, get(S1, cache, n)) + s = mellin_g3(n, get(S1, cache, n, is_singlet)) elif key == S1p2: - s = polygamma.recursive_harmonic_sum(get(S1, cache, n), n, 2, 1) + s = recursive_harmonic_sum(get(S1, cache, n, is_singlet), n, 2, 1) elif key == g3p1: - s = mellin_g3p1(n, get(S1, cache, n), get(g3, cache, n)) + s = mellin_g3p1(n, get(S1, cache, n, is_singlet), get(g3, cache, n, is_singlet)) elif key == g3p2: - s = mellin_g3p2(n, get(S1, cache, n), get(g3, cache, n)) + s = mellin_g3p2(n, get(S1, cache, n, is_singlet), get(g3, cache, n, is_singlet)) # store and return cache[key] = s return s diff --git a/src/ekore/harmonics/w3.py b/src/ekore/harmonics/w3.py index a63944bb1..789ff7a9d 100644 --- a/src/ekore/harmonics/w3.py +++ b/src/ekore/harmonics/w3.py @@ -105,7 +105,7 @@ def S21(N, S1, S2): @nb.njit(cache=True) -def Sm21(N, S1, Sm1, is_singlet=None): +def Sm21(N, S1, Sm1, g3p1, 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 @@ -136,7 +136,7 @@ def Sm21(N, S1, Sm1, is_singlet=None): # Note mellin g3 was integrated following x^(N-1) convention. eta = symmetry_factor(N, is_singlet) return ( - -eta * gf.mellin_g3(N + 1, S1 + 1 / (N + 1)) + -eta * g3p1 + zeta2 * Sm1 - 5 / 8 * zeta3 + zeta2 * log2 From 0d2c8d2cf55161199dfe446b5d3824e460dfb332 Mon Sep 17 00:00:00 2001 From: t7phy Date: Thu, 9 Feb 2023 03:18:03 +0100 Subject: [PATCH 23/30] additional cache error fixes --- src/ekore/harmonics/cache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ekore/harmonics/cache.py b/src/ekore/harmonics/cache.py index 5f1287223..845e14ebc 100644 --- a/src/ekore/harmonics/cache.py +++ b/src/ekore/harmonics/cache.py @@ -103,7 +103,7 @@ def get(key: int, cache: npt.ArrayLike, elif key == S5: s = w5.S5(n) elif key == Sm1: - s = w1.Sm1(n, get(S1, cache, n, is_singlet), get(S1mh, cache, n, is_singlet), get(S1h, cache, n), is_singlet) + s = w1.Sm1(n, get(S1, cache, n, is_singlet), get(S1mh, cache, n, is_singlet), get(S1h, cache, n, is_singlet), is_singlet) elif key == Sm2: s = w2.Sm2(n, get(S2, cache, n, is_singlet), get(S2mh, cache, n, is_singlet), get(S2h, cache, n, is_singlet), is_singlet) elif key == Sm3: From 0cf143d9c8e8e56bdea7d80b80e890e2b7b8f439 Mon Sep 17 00:00:00 2001 From: t7phy Date: Thu, 9 Feb 2023 14:57:32 +0100 Subject: [PATCH 24/30] merge master in harmonic-sums-cache --- src/eko/beta.py | 3 +++ src/eko/evolution_operator/__init__.py | 2 ++ .../anomalous_dimensions/unpolarized/space_like/__init__.py | 2 ++ .../anomalous_dimensions/unpolarized/space_like/as1aem1.py | 1 + src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py | 1 + src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py | 4 ++-- .../anomalous_dimensions/unpolarized/space_like/as4/gnsm.py | 3 +++ tests/eko/scale_variations/test_expanded.py | 3 +++ 8 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/eko/beta.py b/src/eko/beta.py index 9b6a8a2c2..df296d00b 100644 --- a/src/eko/beta.py +++ b/src/eko/beta.py @@ -7,10 +7,13 @@ import numba as nb from . import constants + <<<<<<< HEAD from eko.constants import zeta3 + ======= from ekore.harmonics.constants import zeta3 + >>>>>>> master diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index 67a126e87..a259f9cb2 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -14,8 +14,10 @@ from scipy import integrate import ekore.anomalous_dimensions.polarized.space_like as ad_ps + <<<<<<< HEAD import ekore.anomalous_dimensions.polarized.time_like as ad_pt + ======= >>>>>>> master import ekore.anomalous_dimensions.unpolarized.space_like as ad_us diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py index c312cc60d..06ab9f855 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py @@ -19,8 +19,10 @@ import numpy as np from .... import harmonics + <<<<<<< HEAD:src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py from ....harmonics import cache as c + ======= >>>>>>> master:src/eko/anomalous_dimensions/__init__.py from . import aem1, aem2, as1, as2, as3, as4 diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py index cc131e980..ca1302dea 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py @@ -6,6 +6,7 @@ from eko import constants from eko.constants import zeta2, zeta3 + from .... import harmonics diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py index eb34db624..81e520d4a 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py @@ -11,6 +11,7 @@ from eko import constants from eko.constants import log2, zeta2, zeta3 + from .... import harmonics diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py index 8cc858c7b..86449adcb 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py @@ -5,11 +5,11 @@ Note that the QCD colour factors have been hard-wired in the parametrizations. """ -from eko.constants import zeta2, zeta3 - import numba as nb import numpy as np +from eko.constants import zeta2, zeta3 + @nb.njit(cache=True) def gamma_nsm(n, nf, sx): diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py index 9307b7f92..83d7b4b78 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py @@ -5,9 +5,12 @@ <<<<<<< HEAD:src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py from eko.constants import CF, zeta3 + ======= from eko.constants import CF + from .....harmonics.constants import zeta3 + >>>>>>> master:src/eko/anomalous_dimensions/as4/gnsm.py from .....harmonics.log_functions import lm11m1, lm12m1, lm13m1 diff --git a/tests/eko/scale_variations/test_expanded.py b/tests/eko/scale_variations/test_expanded.py index 927d0d2b0..77d207124 100644 --- a/tests/eko/scale_variations/test_expanded.py +++ b/tests/eko/scale_variations/test_expanded.py @@ -2,10 +2,13 @@ from eko import basis_rotation as br from ekore.anomalous_dimensions.unpolarized.space_like import gamma_ns, gamma_singlet + <<<<<<< HEAD from eko.beta import beta_qcd_as2 + ======= from eko.beta import beta_qcd_as2, beta_qcd_as3 + >>>>>>> master from eko.kernels import non_singlet, singlet from eko.scale_variations import Modes, expanded, exponentiated From 5de8a74d1929cad3d33897a08b017e4fdc710c15 Mon Sep 17 00:00:00 2001 From: t7phy Date: Thu, 9 Feb 2023 17:23:12 +0100 Subject: [PATCH 25/30] resolve merge conflicts --- doc/source/overview/features.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/source/overview/features.rst b/doc/source/overview/features.rst index 1c825a64c..d566c40e9 100644 --- a/doc/source/overview/features.rst +++ b/doc/source/overview/features.rst @@ -1,12 +1,7 @@ Features ======== -<<<<<<< HEAD -- perturbation orders: :mod:`LO ` + :mod:`NLO ` - + :mod:`NNLO ` -======= - perturbation orders of anomalous dimensions: :math:`\alpha_s,\alpha_{em},\alpha_s\alpha_{em},\alpha_s^2,\alpha_s^3` ->>>>>>> master - evolution in an (almost) arbitrary sequence of |FNS| (:class:`~eko.thresholds.ThresholdsAtlas`) - :ref:`theory/pQCD:scale variations` - different :doc:`solutions ` of |DGLAP| differential equation From 07eec292a5e38b0f6fe5bf146cf4c85fb391704a Mon Sep 17 00:00:00 2001 From: t7phy Date: Thu, 9 Feb 2023 22:18:19 +0100 Subject: [PATCH 26/30] resolve merge conflicts --- src/eko/beta.py | 8 +- src/eko/evolution_operator/__init__.py | 10 -- .../operator_matrix_element.py | 129 ++++++++---------- .../unpolarized/space_like/__init__.py | 5 - .../unpolarized/space_like/as1.py | 6 +- .../unpolarized/space_like/as4/gnsm.py | 7 - 6 files changed, 63 insertions(+), 102 deletions(-) diff --git a/src/eko/beta.py b/src/eko/beta.py index df296d00b..72c8cc272 100644 --- a/src/eko/beta.py +++ b/src/eko/beta.py @@ -6,15 +6,9 @@ import numba as nb -from . import constants - -<<<<<<< HEAD from eko.constants import zeta3 -======= -from ekore.harmonics.constants import zeta3 - ->>>>>>> master +from . import constants @nb.njit(cache=True) diff --git a/src/eko/evolution_operator/__init__.py b/src/eko/evolution_operator/__init__.py index a259f9cb2..ee17b9cd6 100644 --- a/src/eko/evolution_operator/__init__.py +++ b/src/eko/evolution_operator/__init__.py @@ -14,12 +14,6 @@ from scipy import integrate import ekore.anomalous_dimensions.polarized.space_like as ad_ps - -<<<<<<< HEAD -import ekore.anomalous_dimensions.polarized.time_like as ad_pt - -======= ->>>>>>> master import ekore.anomalous_dimensions.unpolarized.space_like as ad_us import ekore.anomalous_dimensions.unpolarized.time_like as ad_ut @@ -228,11 +222,7 @@ def quad_ker( else: if is_polarized: if is_time_like: -<<<<<<< HEAD - gamma_ns = ad_pt.gamma_ns(order, mode0, ker_base.n, nf) -======= raise NotImplementedError("Polarized, time-like is not implemented") ->>>>>>> master else: gamma_ns = ad_ps.gamma_ns(order, mode0, ker_base.n, nf) else: diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index d987973ca..a20307658 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -21,25 +21,25 @@ def build_ome(A, matching_order, a_s, backward_method): r"""Construct the matching expansion in :math:`a_s` with the appropriate method. - Parameters - ---------- - A : numpy.ndarray - list of |OME| - matching_order : tuple(int,int) - perturbation matching order - a_s : float - strong coupling, needed only for the exact inverse - backward_method : ["exact", "expanded" or ""] - empty or method for inverting the matching condition (exact or expanded) - - Returns - ------- - ome : numpy.ndarray - matching operator matrix -<<<<<<< HEAD:src/eko/evolution_operator/operator_matrix_element.py -======= - ->>>>>>> master:src/eko/matching_conditions/operator_matrix_element.py + Parameters + ---------- + A : numpy.ndarray + list of |OME| + matching_order : tuple(int,int) + perturbation matching order + a_s : float + strong coupling, needed only for the exact inverse + backward_method : ["exact", "expanded" or ""] + empty or method for inverting the matching condition (exact or expanded) + + Returns + ------- + ome : numpy.ndarray + matching operator matrix + <<<<<<< HEAD:src/eko/evolution_operator/operator_matrix_element.py + ======= + + >>>>>>> master:src/eko/matching_conditions/operator_matrix_element.py """ # to get the inverse one can use this FORM snippet # Symbol a; @@ -91,45 +91,45 @@ def quad_ker( ): r"""Raw kernel inside quad. - Parameters - ---------- - u : float - quad argument - order : tuple(int,int) - perturbation matching order - mode0 : int - pid for first element in the singlet sector - mode1 : int - pid for second element in the singlet sector - is_log : boolean - logarithmic interpolation - logx : float - Mellin inversion point - areas : tuple - basis function configuration - a_s : float - strong coupling, needed only for the exact inverse - nf: int - number of active flavor below threshold - L : float - :math:``\ln(\mu_F^2 / m_h^2)`` - backward_method : ["exact", "expanded" or ""] - empty or method for inverting the matching condition (exact or expanded) - is_msbar: bool - add the |MSbar| contribution - is_polarized : boolean - is polarized evolution ? - is_time_like : boolean - is time-like evolution ? - - Returns - ------- - ker : float - evaluated integration kernel -<<<<<<< HEAD:src/eko/evolution_operator/operator_matrix_element.py -======= - ->>>>>>> master:src/eko/matching_conditions/operator_matrix_element.py + Parameters + ---------- + u : float + quad argument + order : tuple(int,int) + perturbation matching order + mode0 : int + pid for first element in the singlet sector + mode1 : int + pid for second element in the singlet sector + is_log : boolean + logarithmic interpolation + logx : float + Mellin inversion point + areas : tuple + basis function configuration + a_s : float + strong coupling, needed only for the exact inverse + nf: int + number of active flavor below threshold + L : float + :math:``\ln(\mu_F^2 / m_h^2)`` + backward_method : ["exact", "expanded" or ""] + empty or method for inverting the matching condition (exact or expanded) + is_msbar: bool + add the |MSbar| contribution + is_polarized : boolean + is polarized evolution ? + is_time_like : boolean + is time-like evolution ? + + Returns + ------- + ker : float + evaluated integration kernel + <<<<<<< HEAD:src/eko/evolution_operator/operator_matrix_element.py + ======= + + >>>>>>> master:src/eko/matching_conditions/operator_matrix_element.py """ ker_base = QuadKerBase(u, is_log, logx, mode0) integrand = ker_base.integrand(areas) @@ -164,11 +164,7 @@ def quad_ker( indices = {21: 0, 100: 1, 90: 2} if is_polarized: if is_time_like: -<<<<<<< HEAD:src/eko/evolution_operator/operator_matrix_element.py - A = ome_pt.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) -======= raise NotImplementedError("Polarized, time-like is not implemented") ->>>>>>> master:src/eko/matching_conditions/operator_matrix_element.py else: A = ome_ps.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) else: @@ -180,21 +176,12 @@ def quad_ker( indices = {200: 0, 91: 1} if is_polarized: if is_time_like: -<<<<<<< HEAD:src/eko/evolution_operator/operator_matrix_element.py - A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) - else: - A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) - else: - if is_time_like: - A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) -======= raise NotImplementedError("Polarized, time-like is not implemented") else: A = ome_ps.A_non_singlet(order, ker_base.n, sx, nf, L) else: if is_time_like: A = ome_ut.A_non_singlet(order, ker_base.n, sx, nf, L) ->>>>>>> master:src/eko/matching_conditions/operator_matrix_element.py else: A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py index 06ab9f855..e070835ec 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py @@ -19,12 +19,7 @@ import numpy as np from .... import harmonics - -<<<<<<< HEAD:src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py from ....harmonics import cache as c - -======= ->>>>>>> master:src/eko/anomalous_dimensions/__init__.py from . import aem1, aem2, as1, as2, as3, as4 diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py index cdcc0afcc..ad83127de 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1.py @@ -25,7 +25,7 @@ def gamma_ns(N, cache): gamma_ns : complex Leading-order non-singlet anomalous dimension :math:`\\gamma_{ns}^{(0)}(N)` """ - gamma = -(3.0 - 4.0 * c.get(c.S1, cache, N) + 2.0 / N / (N + 1.0)) + gamma = -(3.0 - 4.0 * c.get(c.S1, cache, N, False) + 2.0 / N / (N + 1.0)) result = constants.CF * gamma return result @@ -95,7 +95,9 @@ def gamma_gg(N, nf, cache): gamma_gg : complex Leading-order gluon-gluon anomalous dimension :math:`\\gamma_{gg}^{(0)}(N)` """ - gamma = c.get(c.S1, cache, N) - 1.0 / N / (N - 1.0) - 1.0 / (N + 1.0) / (N + 2.0) + gamma = ( + c.get(c.S1, cache, N, True) - 1.0 / N / (N - 1.0) - 1.0 / (N + 1.0) / (N + 2.0) + ) result = constants.CA * (4.0 * gamma - 11.0 / 3.0) + 4.0 / 3.0 * constants.TR * nf return result diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py index 83d7b4b78..3d6f16c32 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py @@ -3,15 +3,8 @@ """ import numba as nb -<<<<<<< HEAD:src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py from eko.constants import CF, zeta3 -======= -from eko.constants import CF - -from .....harmonics.constants import zeta3 - ->>>>>>> master:src/eko/anomalous_dimensions/as4/gnsm.py from .....harmonics.log_functions import lm11m1, lm12m1, lm13m1 From 12fbe7a701e3f1b1e3f4c100138433651b8b4bcf Mon Sep 17 00:00:00 2001 From: t7phy Date: Fri, 10 Feb 2023 01:32:46 +0100 Subject: [PATCH 27/30] complete implementation of new harmonic sums cachefor spacelike case --- .../unpolarized/space_like/__init__.py | 72 ++--------- .../unpolarized/space_like/aem1.py | 9 +- .../unpolarized/space_like/aem2.py | 117 ++++++++++------- .../unpolarized/space_like/as1aem1.py | 113 ++++++++-------- .../unpolarized/space_like/as2.py | 103 ++++++++------- .../unpolarized/space_like/as3.py | 121 ++++++++++-------- .../unpolarized/space_like/as4/__init__.py | 16 ++- .../unpolarized/space_like/as4/ggg.py | 64 +++++---- .../unpolarized/space_like/as4/ggq.py | 84 ++++++------ .../unpolarized/space_like/as4/gnsm.py | 81 +++++++----- .../unpolarized/space_like/as4/gnsp.py | 65 ++++++---- .../unpolarized/space_like/as4/gnsv.py | 53 +++++--- .../unpolarized/space_like/as4/gps.py | 51 +++++--- .../unpolarized/space_like/as4/gqg.py | 73 ++++++----- .../unpolarized/space_like/__init__.py | 37 ++---- .../unpolarized/space_like/as1.py | 36 ++++-- .../unpolarized/space_like/as2.py | 99 ++++++++------ .../unpolarized/space_like/as3/__init__.py | 50 +++----- .../unpolarized/space_like/as3/aHg.py | 29 +++-- .../unpolarized/space_like/as3/aHgstfac.py | 28 +++- .../unpolarized/space_like/as3/aHq.py | 30 +++-- .../unpolarized/space_like/as3/agg.py | 29 +++-- .../unpolarized/space_like/as3/aggTF2.py | 22 ++-- .../unpolarized/space_like/as3/agq.py | 31 ++++- .../unpolarized/space_like/as3/aqg.py | 24 +++- .../unpolarized/space_like/as3/aqqNS.py | 25 +++- .../unpolarized/space_like/as3/aqqPS.py | 16 ++- 27 files changed, 854 insertions(+), 624 deletions(-) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py index e070835ec..7e8bd0bb3 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/__init__.py @@ -43,33 +43,8 @@ def gamma_ns(order, mode, n, nf): numpy.ndarray non-singlet anomalous dimensions - See Also - -------- - ekore.anomalous_dimensions.unpolarized.space_like.as1.gamma_ns : :math:`\gamma_{ns}^{(0)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as2.gamma_nsp : :math:`\gamma_{ns,+}^{(1)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as2.gamma_nsm : :math:`\gamma_{ns,-}^{(1)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as3.gamma_nsp : :math:`\gamma_{ns,+}^{(2)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as3.gamma_nsm : :math:`\gamma_{ns,-}^{(2)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as3.gamma_nsv : :math:`\gamma_{ns,v}^{(2)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as4.gamma_nsp : :math:`\gamma_{ns,+}^{(3)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as4.gamma_nsm : :math:`\gamma_{ns,-}^{(3)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as4.gamma_nsv : :math:`\gamma_{ns,v}^{(3)}(N)` - """ - # cache the s-es - if order[0] >= 4: - full_sx_cache = harmonics.compute_cache(n, 5, is_singlet=False) - sx = np.array( - [ - full_sx_cache[0][0], - full_sx_cache[1][0], - full_sx_cache[2][0], - full_sx_cache[3][0], - ] - ) - else: - sx = harmonics.sx(n, max_weight=order[0] + 1) - # now combine + gamma_ns = np.zeros(order[0], np.complex_) cache = c.reset() @@ -77,30 +52,30 @@ def gamma_ns(order, mode, n, nf): # NLO and beyond if order[0] >= 2: if mode == 10101: - gamma_ns_1 = as2.gamma_nsp(n, nf, sx) + gamma_ns_1 = as2.gamma_nsp(n, nf, cache, False) # 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, sx) + gamma_ns_1 = as2.gamma_nsm(n, nf, cache, False) else: raise NotImplementedError("Non-singlet sector is not implemented") gamma_ns[1] = gamma_ns_1 # NNLO and beyond if order[0] >= 3: if mode == 10101: - gamma_ns_2 = as3.gamma_nsp(n, nf, sx) + gamma_ns_2 = as3.gamma_nsp(n, nf, cache, False) elif mode == 10201: - gamma_ns_2 = as3.gamma_nsm(n, nf, sx) + gamma_ns_2 = as3.gamma_nsm(n, nf, cache, False) elif mode == 10200: - gamma_ns_2 = as3.gamma_nsv(n, nf, sx) + gamma_ns_2 = as3.gamma_nsv(n, nf, cache, False) gamma_ns[2] = gamma_ns_2 # N3LO if order[0] >= 4: if mode == 10101: - gamma_ns_3 = as4.gamma_nsp(n, nf, full_sx_cache) + gamma_ns_3 = as4.gamma_nsp(n, nf, cache, False) elif mode == 10201: - gamma_ns_3 = as4.gamma_nsm(n, nf, full_sx_cache) + gamma_ns_3 = as4.gamma_nsm(n, nf, cache, False) elif mode == 10200: - gamma_ns_3 = as4.gamma_nsv(n, nf, full_sx_cache) + gamma_ns_3 = as4.gamma_nsv(n, nf, cache, False) gamma_ns[3] = gamma_ns_3 return gamma_ns @@ -123,38 +98,15 @@ def gamma_singlet(order, n, nf): numpy.ndarray singlet anomalous dimensions matrices - See Also - -------- - ekore.anomalous_dimensions.unpolarized.space_like.as1.gamma_singlet : :math:`\gamma_{S}^{(0)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as2.gamma_singlet : :math:`\gamma_{S}^{(1)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as3.gamma_singlet : :math:`\gamma_{S}^{(2)}(N)` - ekore.anomalous_dimensions.unpolarized.space_like.as4.gamma_singlet : :math:`\gamma_{S}^{(3)}(N)` - """ - # cache the s-es - if order[0] >= 4: - full_sx_cache = harmonics.compute_cache(n, 5, is_singlet=False) - sx = np.array( - [ - full_sx_cache[0][0], - full_sx_cache[1][0], - full_sx_cache[2][0], - full_sx_cache[3][0], - ] - ) - elif order[0] >= 3: - # here we need only S1,S2,S3,S4 - sx = harmonics.sx(n, max_weight=order[0] + 1) - else: - sx = harmonics.sx(n, max_weight=order[0]) cache = c.reset() gamma_s = np.zeros((order[0], 2, 2), np.complex_) gamma_s[0] = as1.gamma_singlet(n, nf, cache) if order[0] >= 2: - gamma_s[1] = as2.gamma_singlet(n, nf, sx) + gamma_s[1] = as2.gamma_singlet(n, nf, cache, True) if order[0] >= 3: - gamma_s[2] = as3.gamma_singlet(n, nf, sx) + gamma_s[2] = as3.gamma_singlet(n, nf, cache, True) if order[0] >= 4: - gamma_s[3] = as4.gamma_singlet(n, nf, full_sx_cache) + gamma_s[3] = as4.gamma_singlet(n, nf, cache, True) return gamma_s diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/aem1.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/aem1.py index d26683969..79c2a0163 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/aem1.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/aem1.py @@ -5,6 +5,7 @@ import numba as nb from eko import constants + from . import as1 @@ -75,7 +76,7 @@ def gamma_phph(nf): @nb.njit(cache=True) -def gamma_ns(N, s1): +def gamma_ns(N, cache): """ Computes the leading-order non-singlet QED anomalous dimension. @@ -85,12 +86,12 @@ def gamma_ns(N, s1): ---------- N : complex Mellin moment - s1 : complex - S1(N) + cache : numpy.ndarray + Harmonic sum cache Returns ------- gamma_ns : complex Leading-order non-singlet QED anomalous dimension :math:`\\gamma_{ns}^{(0)}(N)` """ - return as1.gamma_ns(N, s1) / constants.CF + return as1.gamma_ns(N, cache) / constants.CF diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/aem2.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/aem2.py index 83f40e456..5e5613022 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/aem2.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/aem2.py @@ -5,6 +5,8 @@ import numba as nb from eko import constants + +from ....harmonics import cache as c from . import as1aem1 @@ -35,7 +37,7 @@ def gamma_phph(N, nf): @nb.njit(cache=True) -def gamma_uph(N, nf, sx): +def gamma_uph(N, nf, cache, is_singlet): """Computes the O(aem2) quark-photon anomalous dimension for up quarks. Implements Eq. (55) of :cite:`deFlorian:2016gvk` for q=u. @@ -46,8 +48,10 @@ def gamma_uph(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -55,11 +59,11 @@ def gamma_uph(N, nf, sx): O(aem2) quark-photon anomalous dimension :math:`\\gamma_{u \\gamma}^{(0,2)}(N)` """ - return constants.eu2 * as1aem1.gamma_qph(N, nf, sx) / constants.CF + return constants.eu2 * as1aem1.gamma_qph(N, nf, cache, is_singlet) / constants.CF @nb.njit(cache=True) -def gamma_dph(N, nf, sx): +def gamma_dph(N, nf, cache, is_singlet): """Computes the O(aem2) quark-photon anomalous dimension for down quarks. Implements Eq. (55) of :cite:`deFlorian:2016gvk` for q=d. @@ -70,8 +74,10 @@ def gamma_dph(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -79,11 +85,11 @@ def gamma_dph(N, nf, sx): O(aem2) quark-photon anomalous dimension :math:`\\gamma_{d \\gamma}^{(0,2)}(N)` """ - return constants.ed2 * as1aem1.gamma_qph(N, nf, sx) / constants.CF + return constants.ed2 * as1aem1.gamma_qph(N, nf, cache, is_singlet) / constants.CF @nb.njit(cache=True) -def gamma_phu(N, nf, sx): +def gamma_phu(N, nf, cache, is_singlet): """Computes the O(aem2) photon-quark anomalous dimension for up quarks. Implements Eq. (56) of :cite:`deFlorian:2016gvk` for q=u. @@ -94,8 +100,10 @@ def gamma_phu(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -105,18 +113,21 @@ def gamma_phu(N, nf, sx): """ nu = constants.uplike_flavors(nf) nd = nf - nu - S1 = sx[0] + S1 = c.get(c.S1, cache, N, is_singlet) tmp = (-16 * (-16 - 27 * N - 13 * N**2 - 8 * N**3)) / ( 9.0 * (-1 + N) * N * (1 + N) ** 2 ) - 16 * (2 + 3 * N + 2 * N**2 + N**3) / ( 3.0 * (-1 + N) * N * (1 + N) ** 2 ) * S1 eSigma2 = constants.NC * (nu * constants.eu2 + nd * constants.ed2) - return constants.eu2 * as1aem1.gamma_phq(N, sx) / constants.CF + eSigma2 * tmp + return ( + constants.eu2 * as1aem1.gamma_phq(N, cache, is_singlet) / constants.CF + + eSigma2 * tmp + ) @nb.njit(cache=True) -def gamma_phd(N, nf, sx): +def gamma_phd(N, nf, cache, is_singlet): """Computes the O(aem2) photon-quark anomalous dimension for down quarks. Implements Eq. (56) of :cite:`deFlorian:2016gvk` for q=d. @@ -127,8 +138,10 @@ def gamma_phd(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -138,18 +151,21 @@ def gamma_phd(N, nf, sx): """ nu = constants.uplike_flavors(nf) nd = nf - nu - S1 = sx[0] + S1 = c.get(c.S1, cache, N, is_singlet) tmp = (-16 * (-16 - 27 * N - 13 * N**2 - 8 * N**3)) / ( 9.0 * (-1 + N) * N * (1 + N) ** 2 ) - 16 * (2 + 3 * N + 2 * N**2 + N**3) / ( 3.0 * (-1 + N) * N * (1 + N) ** 2 ) * S1 eSigma2 = constants.NC * (nu * constants.eu2 + nd * constants.ed2) - return constants.ed2 * as1aem1.gamma_phq(N, sx) / constants.CF + eSigma2 * tmp + return ( + constants.ed2 * as1aem1.gamma_phq(N, cache, is_singlet) / constants.CF + + eSigma2 * tmp + ) @nb.njit(cache=True) -def gamma_nspu(N, nf, sx): +def gamma_nspu(N, nf, cache, is_singlet): """Computes the O(aem2) singlet-like non-singlet anomalous dimension for up quarks. Implements sum of Eqs. (57-58) of :cite:`deFlorian:2016gvk` for q=u. @@ -160,9 +176,10 @@ def gamma_nspu(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums - + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- gamma_nspu : complex @@ -170,8 +187,8 @@ def gamma_nspu(N, nf, sx): :math:`\\gamma_{ns,+,u}^{(0,2)}(N)` """ - S1 = sx[0] - S2 = sx[1] + S1 = c.get(c.S1, cache, N, is_singlet) + S2 = c.get(c.S2, cache, N, is_singlet) nu = constants.uplike_flavors(nf) nd = nf - nu eSigma2 = constants.NC * (nu * constants.eu2 + nd * constants.ed2) @@ -182,11 +199,13 @@ def gamma_nspu(N, nf, sx): - 80 / 9 * S1 + 16 / 3 * S2 ) * eSigma2 - return constants.eu2 * as1aem1.gamma_nsp(N, sx) / constants.CF / 2 + tmp + return ( + constants.eu2 * as1aem1.gamma_nsp(N, cache, is_singlet) / constants.CF / 2 + tmp + ) @nb.njit(cache=True) -def gamma_nspd(N, nf, sx): +def gamma_nspd(N, nf, cache, is_singlet): """Computes the O(aem2) singlet-like non-singlet anomalous dimension for down quarks. Implements sum of Eqs. (57-58) of :cite:`deFlorian:2016gvk` for q=d. @@ -197,8 +216,10 @@ def gamma_nspd(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -207,8 +228,8 @@ def gamma_nspd(N, nf, sx): :math:`\\gamma_{ns,+,d}^{(0,2)}(N)` """ - S1 = sx[0] - S2 = sx[1] + S1 = c.get(c.S1, cache, N, is_singlet) + S2 = c.get(c.S2, cache, N, is_singlet) nu = constants.uplike_flavors(nf) nd = nf - nu eSigma2 = constants.NC * (nu * constants.eu2 + nd * constants.ed2) @@ -219,11 +240,13 @@ def gamma_nspd(N, nf, sx): - 80 / 9 * S1 + 16 / 3 * S2 ) * eSigma2 - return constants.ed2 * as1aem1.gamma_nsp(N, sx) / constants.CF / 2 + tmp + return ( + constants.ed2 * as1aem1.gamma_nsp(N, cache, is_singlet) / constants.CF / 2 + tmp + ) @nb.njit(cache=True) -def gamma_nsmu(N, nf, sx): +def gamma_nsmu(N, nf, cache, is_singlet): """Computes the O(aem2) valence-like non-singlet anomalous dimension for up quarks. Implements difference between Eqs. (57-58) of :cite:`deFlorian:2016gvk` for q=u. @@ -234,8 +257,10 @@ def gamma_nsmu(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -244,8 +269,8 @@ def gamma_nsmu(N, nf, sx): :math:`\\gamma_{ns,-,u}^{(0,2)}(N)` """ - S1 = sx[0] - S2 = sx[1] + S1 = c.get(c.S1, cache, N, is_singlet) + S2 = c.get(c.S2, cache, N, is_singlet) nu = constants.uplike_flavors(nf) nd = nf - nu eSigma2 = constants.NC * (nu * constants.eu2 + nd * constants.ed2) @@ -256,11 +281,13 @@ def gamma_nsmu(N, nf, sx): - 80 / 9 * S1 + 16 / 3 * S2 ) * eSigma2 - return constants.eu2 * as1aem1.gamma_nsm(N, sx) / constants.CF / 2 + tmp + return ( + constants.eu2 * as1aem1.gamma_nsm(N, cache, is_singlet) / constants.CF / 2 + tmp + ) @nb.njit(cache=True) -def gamma_nsmd(N, nf, sx): +def gamma_nsmd(N, nf, cache, is_singlet): """Computes the O(aem2) valence-like non-singlet anomalous dimension for down quarks. Implements difference between Eqs. (57-58) of :cite:`deFlorian:2016gvk` for q=d. @@ -271,8 +298,10 @@ def gamma_nsmd(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -281,8 +310,8 @@ def gamma_nsmd(N, nf, sx): :math:`\\gamma_{ns,-,d}^{(0,2)}(N)` """ - S1 = sx[0] - S2 = sx[1] + S1 = c.get(c.S1, cache, N, is_singlet) + S2 = c.get(c.S2, cache, N, is_singlet) nu = constants.uplike_flavors(nf) nd = nf - nu eSigma2 = constants.NC * (nu * constants.eu2 + nd * constants.ed2) @@ -293,7 +322,9 @@ def gamma_nsmd(N, nf, sx): - 80 / 9 * S1 + 16 / 3 * S2 ) * eSigma2 - return constants.ed2 * as1aem1.gamma_nsm(N, sx) / constants.CF / 2 + tmp + return ( + constants.ed2 * as1aem1.gamma_nsm(N, cache, is_singlet) / constants.CF / 2 + tmp + ) @nb.njit(cache=True) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py index ca1302dea..4c0db5b10 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as1aem1.py @@ -7,11 +7,11 @@ from eko import constants from eko.constants import zeta2, zeta3 -from .... import harmonics +from ....harmonics import cache as c @nb.njit(cache=True) -def gamma_phq(N, sx): +def gamma_phq(N, cache, is_singlet): """Computes the O(as1aem1) photon-quark anomalous dimension Implements Eq. (36) of :cite:`deFlorian:2015ujt`. @@ -20,8 +20,10 @@ def gamma_phq(N, sx): ---------- N : complex Mellin moment - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -29,8 +31,8 @@ def gamma_phq(N, sx): O(as1aem1) photon-quark anomalous dimension :math:`\\gamma_{\\gamma q}^{(1,1)}(N)` """ - S1 = sx[0] - S2 = sx[1] + S1 = c.get(c.S1, cache, N, is_singlet) + S2 = c.get(c.S2, cache, N, is_singlet) tmp_const = ( 2 * (-4 - 12 * N - N**2 + 28 * N**3 + 43 * N**4 + 30 * N**5 + 12 * N**6) @@ -48,7 +50,7 @@ def gamma_phq(N, sx): @nb.njit(cache=True) -def gamma_qph(N, nf, sx): +def gamma_qph(N, nf, cache, is_singlet): """Computes the O(as1aem1) quark-photon anomalous dimension Implements Eq. (26) of :cite:`deFlorian:2015ujt`. @@ -59,8 +61,10 @@ def gamma_qph(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -68,8 +72,8 @@ def gamma_qph(N, nf, sx): O(as1aem1) quark-photon anomalous dimension :math:`\\gamma_{q \\gamma}^{(1,1)}(N)` """ - S1 = sx[0] - S2 = sx[1] + S1 = c.get(c.S1, cache, N, is_singlet) + S2 = c.get(c.S2, cache, N, is_singlet) tmp_const = ( -2 * ( @@ -141,7 +145,7 @@ def gamma_phg(N): @nb.njit(cache=True) -def gamma_qg(N, nf, sx): +def gamma_qg(N, nf, cache, is_singlet): """Computes the O(as1aem1) quark-gluon singlet anomalous dimension. Implements Eq. (29) of :cite:`deFlorian:2015ujt`. @@ -152,8 +156,10 @@ def gamma_qg(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -162,11 +168,13 @@ def gamma_qg(N, nf, sx): :math:`\\gamma_{qg}^{(1,1)}(N)` """ - return constants.TR / constants.CF / constants.CA * gamma_qph(N, nf, sx) + return ( + constants.TR / constants.CF / constants.CA * gamma_qph(N, nf, cache, is_singlet) + ) @nb.njit(cache=True) -def gamma_gq(N, sx): +def gamma_gq(N, cache, is_singlet): """Computes the O(as1aem1) gluon-quark singlet anomalous dimension. Implements Eq. (35) of :cite:`deFlorian:2015ujt`. @@ -175,8 +183,10 @@ def gamma_gq(N, sx): ---------- N : complex Mellin moment - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -185,7 +195,7 @@ def gamma_gq(N, sx): :math:`\\gamma_{gq}^{(1,1)}(N)` """ - return gamma_phq(N, sx) + return gamma_phq(N, cache, is_singlet) @nb.njit(cache=True) @@ -231,7 +241,7 @@ def gamma_gg(): @nb.njit(cache=True) -def gamma_nsp(N, sx): +def gamma_nsp(N, cache, is_singlet): """Computes the O(as1aem1) singlet-like non-singlet anomalous dimension. Implements sum of Eqs. (33-34) of :cite:`deFlorian:2015ujt`. @@ -240,8 +250,10 @@ def gamma_nsp(N, sx): ---------- N : complex Mellin moment - sx : np array - List of harmonic sums + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -250,18 +262,18 @@ def gamma_nsp(N, sx): :math:`\\gamma_{ns,+}^{(1)}(N)` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] - S1h = harmonics.S1(N / 2) - S2h = harmonics.S2(N / 2) - S3h = harmonics.S3(N / 2) - S1p1h = harmonics.S1((N + 1.0) / 2) - S2p1h = harmonics.S2((N + 1) / 2) - S3p1h = harmonics.S3((N + 1) / 2) - g3N = harmonics.g_functions.mellin_g3(N, S1) - S1p2 = harmonics.polygamma.recursive_harmonic_sum(S1, N, 2, 1) - g3Np2 = harmonics.g_functions.mellin_g3(N + 2, S1p2) + S1 = c.get(c.S1, cache, N, is_singlet) + S2 = c.get(c.S2, cache, N, is_singlet) + S3 = c.get(c.S3, cache, N, is_singlet) + S1h = c.get(c.S1h, cache, N, is_singlet) + S2h = c.get(c.S2h, cache, N, is_singlet) + S3h = c.get(c.S3h, cache, N, is_singlet) + S1p1h = c.get(c.S1ph, cache, N, is_singlet) + S2p1h = c.get(c.S2ph, cache, N, is_singlet) + S3p1h = c.get(c.S3ph, cache, N, is_singlet) + g3N = c.get(c.g3, cache, N, is_singlet) + S1p2 = c.get(c.S1p2, cache, N, is_singlet) + g3Np2 = c.get(c.g3p2, cache, N, is_singlet) result = ( +32 * zeta2 * S1h - 32 * zeta2 * S1p1h @@ -294,7 +306,7 @@ def gamma_nsp(N, sx): @nb.njit(cache=True) -def gamma_nsm(N, sx): +def gamma_nsm(N, cache, is_singlet): """Computes the O(as1aem1) valence-like non-singlet anomalous dimension. Implements difference between Eqs. (33-34) of :cite:`deFlorian:2015ujt`. @@ -303,9 +315,10 @@ def gamma_nsm(N, sx): ---------- N : complex Mellin moment - sx : np array - List of harmonic sums - + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- gamma_nsm : complex @@ -313,18 +326,18 @@ def gamma_nsm(N, sx): :math:`\\gamma_{ns,-}^{(1,1)}(N)` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] - S1h = harmonics.S1(N / 2) - S2h = harmonics.S2(N / 2) - S3h = harmonics.S3(N / 2) - S1p1h = harmonics.S1((N + 1.0) / 2) - S2p1h = harmonics.S2((N + 1) / 2) - S3p1h = harmonics.S3((N + 1) / 2) - g3N = harmonics.g_functions.mellin_g3(N, S1) - S1p2 = harmonics.polygamma.recursive_harmonic_sum(S1, N, 2, 1) - g3Np2 = harmonics.g_functions.mellin_g3(N + 2, S1p2) + S1 = c.get(c.S1, cache, N, is_singlet) + S2 = c.get(c.S2, cache, N, is_singlet) + S3 = c.get(c.S3, cache, N, is_singlet) + S1h = c.get(c.S1h, cache, N, is_singlet) + S2h = c.get(c.S2h, cache, N, is_singlet) + S3h = c.get(c.S3h, cache, N, is_singlet) + S1p1h = c.get(c.S1ph, cache, N, is_singlet) + S2p1h = c.get(c.S2ph, cache, N, is_singlet) + S3p1h = c.get(c.S3ph, cache, N, is_singlet) + g3N = c.get(c.g3, cache, N, is_singlet) + S1p2 = c.get(c.S1p2, cache, N, is_singlet) + g3Np2 = c.get(c.g3p2, cache, N, is_singlet) result = ( -32.0 * zeta2 * S1h diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py index 81e520d4a..88adc7eb4 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as2.py @@ -12,11 +12,11 @@ from eko import constants from eko.constants import log2, zeta2, zeta3 -from .... import harmonics +from ....harmonics import cache as c @nb.njit(cache=True) -def gamma_nsm(n, nf, sx): +def gamma_nsm(n, nf, cache, is_singlet): """ Computes the |NLO| valence-like non-singlet anomalous dimension. @@ -28,8 +28,10 @@ def gamma_nsm(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -37,14 +39,14 @@ def gamma_nsm(n, nf, sx): |NLO| valence-like non-singlet anomalous dimension :math:`\\gamma_{ns,-}^{(1)}(N)` """ - S1 = sx[0] - S2 = sx[1] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) # 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) - Sp2m = harmonics.S2((n - 1) / 2) - Sp3m = harmonics.S3((n - 1) / 2) - g3n = harmonics.g_functions.mellin_g3(n, S1) + Sp1m = c.get(c.S1mh, cache, n, is_singlet) + Sp2m = c.get(c.S2mh, cache, n, is_singlet) + Sp3m = c.get(c.S3mh, cache, n, is_singlet) + g3n = c.get(c.g3, cache, n, is_singlet) # 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 @@ -59,7 +61,7 @@ def gamma_nsm(n, nf, sx): @nb.njit(cache=True) -def gamma_nsp(n, nf, sx): +def gamma_nsp(n, nf, cache, is_singlet): """ Computes the |NLO| singlet-like non-singlet anomalous dimension. @@ -71,8 +73,10 @@ def gamma_nsp(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -80,12 +84,12 @@ def gamma_nsp(n, nf, sx): |NLO| singlet-like non-singlet anomalous dimension :math:`\\gamma_{ns,+}^{(1)}(N)` """ - S1 = sx[0] - S2 = sx[1] - Sp1p = harmonics.S1(n / 2) - Sp2p = harmonics.S2(n / 2) - Sp3p = harmonics.S3(n / 2) - g3n = harmonics.g_functions.mellin_g3(n, S1) + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sp1p = c.get(c.S1h, cache, n, is_singlet) + Sp2p = c.get(c.S2h, cache, n, is_singlet) + Sp3p = c.get(c.S3h, cache, n, is_singlet) + g3n = c.get(c.g3, cache, n, is_singlet) # 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 @@ -127,7 +131,7 @@ def gamma_ps(n, nf): @nb.njit(cache=True) -def gamma_qg(n, nf, sx): +def gamma_qg(n, nf, cache, is_singlet): """ Computes the |NLO| quark-gluon singlet anomalous dimension. @@ -139,8 +143,10 @@ def gamma_qg(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -148,9 +154,9 @@ def gamma_qg(n, nf, sx): |NLO| quark-gluon singlet anomalous dimension :math:`\\gamma_{qg}^{(1)}(N)` """ - S1 = sx[0] - S2 = sx[1] - Sp2p = harmonics.S2(n / 2) + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sp2p = c.get(c.S2h, cache, n, is_singlet) # 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 @@ -162,7 +168,7 @@ def gamma_qg(n, nf, sx): @nb.njit(cache=True) -def gamma_gq(n, nf, sx): +def gamma_gq(n, nf, cache, is_singlet): """ Computes the |NLO| gluon-quark singlet anomalous dimension. @@ -174,8 +180,10 @@ def gamma_gq(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -183,9 +191,9 @@ def gamma_gq(n, nf, sx): |NLO| gluon-quark singlet anomalous dimension :math:`\\gamma_{gq}^{(1)}(N)` """ - S1 = sx[0] - S2 = sx[1] - Sp2p = harmonics.S2(n / 2) + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sp2p = c.get(c.S2h, cache, n, is_singlet) # 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 @@ -200,7 +208,7 @@ def gamma_gq(n, nf, sx): @nb.njit(cache=True) -def gamma_gg(n, nf, sx): +def gamma_gg(n, nf, cache, is_singlet): """ Computes the |NLO| gluon-gluon singlet anomalous dimension. @@ -212,8 +220,10 @@ def gamma_gg(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -221,11 +231,11 @@ def gamma_gg(n, nf, sx): |NLO| gluon-gluon singlet anomalous dimension :math:`\\gamma_{gg}^{(1)}(N)` """ - S1 = sx[0] - Sp1p = harmonics.S1(n / 2) - Sp2p = harmonics.S2(n / 2) - Sp3p = harmonics.S3(n / 2) - g3n = harmonics.g_functions.mellin_g3(n, S1) + S1 = c.get(c.S1, cache, n, is_singlet) + Sp1p = c.get(c.S1h, cache, n, is_singlet) + Sp2p = c.get(c.S2h, cache, n, is_singlet) + Sp3p = c.get(c.S3h, cache, n, is_singlet) + g3n = c.get(c.g3, cache, n, is_singlet) # 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 @@ -238,7 +248,7 @@ def gamma_gg(n, nf, sx): @nb.njit(cache=True) -def gamma_singlet(n, nf, sx): +def gamma_singlet(n, nf, cache, is_singlet): r""" Computes the next-leading-order singlet anomalous dimension matrix @@ -252,10 +262,12 @@ def gamma_singlet(n, nf, sx): ---------- N : complex Mellin moment - sx : numpy.ndarray - List of harmonic sums: :math:`S_{1},S_{2}` nf : int Number of active flavors + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -270,9 +282,12 @@ def gamma_singlet(n, nf, sx): gamma_gq : :math:`\gamma_{gq}^{(1)}` gamma_gg : :math:`\gamma_{gg}^{(1)}` """ - gamma_qq = gamma_nsp(n, nf, sx) + gamma_ps(n, nf) + gamma_qq = gamma_nsp(n, nf, cache, is_singlet) + gamma_ps(n, nf) gamma_S_0 = np.array( - [[gamma_qq, gamma_qg(n, nf, sx)], [gamma_gq(n, nf, sx), gamma_gg(n, nf, sx)]], + [ + [gamma_qq, gamma_qg(n, nf, cache, is_singlet)], + [gamma_gq(n, nf, cache, is_singlet), gamma_gg(n, nf, cache, is_singlet)], + ], np.complex_, ) return gamma_S_0 diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py index 86449adcb..e0ef10e35 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as3.py @@ -10,9 +10,11 @@ from eko.constants import zeta2, zeta3 +from ....harmonics import cache as c + @nb.njit(cache=True) -def gamma_nsm(n, nf, sx): +def gamma_nsm(n, nf, cache, is_singlet): """ Computes the |NNLO| valence-like non-singlet anomalous dimension. @@ -24,8 +26,10 @@ def gamma_nsm(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -33,9 +37,9 @@ def gamma_nsm(n, nf, sx): |NNLO| valence-like non-singlet anomalous dimension :math:`\\gamma_{ns,-}^{(2)}(N)` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) E1 = S1 / n**2 + (S2 - zeta2) / n E2 = 2.0 * (-S1 / n**3 + (zeta2 - S2) / n**2 - (S3 - zeta3) / n) @@ -89,7 +93,7 @@ def gamma_nsm(n, nf, sx): @nb.njit(cache=True) -def gamma_nsp(n, nf, sx): +def gamma_nsp(n, nf, cache, is_singlet): """ Computes the |NNLO| singlet-like non-singlet anomalous dimension. @@ -101,8 +105,10 @@ def gamma_nsp(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -110,9 +116,9 @@ def gamma_nsp(n, nf, sx): |NNLO| singlet-like non-singlet anomalous dimension :math:`\\gamma_{ns,+}^{(2)}(N)` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) E1 = S1 / n**2 + (S2 - zeta2) / n E2 = 2.0 * (-S1 / n**3 + (zeta2 - S2) / n**2 - (S3 - zeta3) / n) @@ -166,7 +172,7 @@ def gamma_nsp(n, nf, sx): @nb.njit(cache=True) -def gamma_nsv(n, nf, sx): +def gamma_nsv(n, nf, cache, is_singlet): """ Computes the |NNLO| valence non-singlet anomalous dimension. @@ -178,8 +184,10 @@ def gamma_nsv(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -187,9 +195,9 @@ def gamma_nsv(n, nf, sx): |NNLO| valence non-singlet anomalous dimension :math:`\\gamma_{ns,v}^{(2)}(N)` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) E1 = S1 / n**2 + (S2 - zeta2) / n E2 = 2.0 * (-S1 / n**3 + (zeta2 - S2) / n**2 - (S3 - zeta3) / n) @@ -216,12 +224,12 @@ def gamma_nsv(n, nf, sx): + 46.18 * E2 ) - result = gamma_nsm(n, nf, sx) + nf * ps2 + result = gamma_nsm(n, nf, cache, is_singlet) + nf * ps2 return result @nb.njit(cache=True) -def gamma_ps(n, nf, sx): +def gamma_ps(n, nf, cache, is_singlet): """ Computes the |NNLO| pure-singlet quark-quark anomalous dimension. @@ -233,8 +241,10 @@ def gamma_ps(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -242,9 +252,9 @@ def gamma_ps(n, nf, sx): |NNLO| pure-singlet quark-quark anomalous dimension :math:`\\gamma_{ps}^{(2)}(N)` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) E1 = S1 / n**2 + (S2 - zeta2) / n E11 = (S1 + 1.0 / (n + 1.0)) / (n + 1.0) ** 2 + ( @@ -293,7 +303,7 @@ def gamma_ps(n, nf, sx): @nb.njit(cache=True) -def gamma_qg(n, nf, sx): +def gamma_qg(n, nf, cache, is_singlet): """ Computes the |NNLO| quark-gluon singlet anomalous dimension. @@ -305,8 +315,10 @@ def gamma_qg(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -314,10 +326,10 @@ def gamma_qg(n, nf, sx): |NNLO| quark-gluon singlet anomalous dimension :math:`\\gamma_{qg}^{(2)}(N)` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] - S4 = sx[3] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) E1 = S1 / n**2 + (S2 - zeta2) / n E2 = 2.0 * (-S1 / n**3 + (zeta2 - S2) / n**2 - (S3 - zeta3) / n) @@ -367,7 +379,7 @@ def gamma_qg(n, nf, sx): @nb.njit(cache=True) -def gamma_gq(n, nf, sx): +def gamma_gq(n, nf, cache, is_singlet): """ Computes the |NNLO| gluon-quark singlet anomalous dimension. @@ -379,8 +391,10 @@ def gamma_gq(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -388,10 +402,10 @@ def gamma_gq(n, nf, sx): |NNLO| gluon-quark singlet anomalous dimension :math:`\\gamma_{gq}^{(2)}(N)` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] - S4 = sx[3] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) E1 = S1 / n**2 + (S2 - zeta2) / n E2 = 2.0 * (-S1 / n**3 + (zeta2 - S2) / n**2 - (S3 - zeta3) / n) @@ -457,7 +471,7 @@ def gamma_gq(n, nf, sx): @nb.njit(cache=True) -def gamma_gg(n, nf, sx): +def gamma_gg(n, nf, cache, is_singlet): """ Computes the |NNLO| gluon-gluon singlet anomalous dimension. @@ -469,8 +483,10 @@ def gamma_gg(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : np.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -478,9 +494,9 @@ def gamma_gg(n, nf, sx): |NNLO| gluon-gluon singlet anomalous dimension :math:`\\gamma_{gg}^{(2)}(N)` """ - S1 = sx[0] - S2 = sx[1] - S3 = sx[2] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) E1 = S1 / n**2 + (S2 - zeta2) / n E11 = (S1 + 1.0 / (n + 1.0)) / (n + 1.0) ** 2 + ( @@ -545,7 +561,7 @@ def gamma_gg(n, nf, sx): @nb.njit(cache=True) -def gamma_singlet(N, nf, sx): +def gamma_singlet(N, nf, cache, is_singlet): r""" Computes the |NNLO| singlet anomalous dimension matrix @@ -561,8 +577,10 @@ def gamma_singlet(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : np.ndarray - List of harmonic sums: :math:`S_{1},S_{2},S_{3}` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns @@ -579,9 +597,12 @@ def gamma_singlet(N, nf, sx): gamma_gq : :math:`\gamma_{gq}^{(2)}` gamma_gg : :math:`\gamma_{gg}^{(2)}` """ - gamma_qq = gamma_nsp(N, nf, sx) + gamma_ps(N, nf, sx) + gamma_qq = gamma_nsp(N, nf, cache, is_singlet) + gamma_ps(N, nf, cache, is_singlet) gamma_S_0 = np.array( - [[gamma_qq, gamma_qg(N, nf, sx)], [gamma_gq(N, nf, sx), gamma_gg(N, nf, sx)]], + [ + [gamma_qq, gamma_qg(N, nf, cache, is_singlet)], + [gamma_gq(N, nf, cache, is_singlet), gamma_gg(N, nf, cache, is_singlet)], + ], np.complex_, ) return gamma_S_0 diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py index e6860191e..fa67a1486 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/__init__.py @@ -16,7 +16,7 @@ @nb.njit(cache=True) -def gamma_singlet(N, nf, sx): +def gamma_singlet(N, nf, cache, is_singlet): r"""Computes the |N3LO| singlet anomalous dimension matrix .. math:: @@ -31,9 +31,10 @@ def gamma_singlet(N, nf, sx): Mellin moment nf : int Number of active flavors - sx : list - harmonic sums cache - + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- numpy.ndarray @@ -49,9 +50,12 @@ def gamma_singlet(N, nf, sx): gamma_gg : :math:`\gamma_{gg}^{(3)}` """ - gamma_qq = gamma_nsp(N, nf, sx) + gamma_ps(N, nf, sx) + gamma_qq = gamma_nsp(N, nf, cache, is_singlet) + gamma_ps(N, nf, cache, is_singlet) gamma_S_0 = np.array( - [[gamma_qq, gamma_qg(N, nf, sx)], [gamma_gq(N, nf, sx), gamma_gg(N, nf, sx)]], + [ + [gamma_qq, gamma_qg(N, nf, cache, is_singlet)], + [gamma_gq(N, nf, cache, is_singlet), gamma_gg(N, nf, cache, is_singlet)], + ], np.complex_, ) return gamma_S_0 diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggg.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggg.py index c627b474f..66d5b6159 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggg.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggg.py @@ -3,11 +3,12 @@ import numba as nb import numpy as np +from .....harmonics import cache as c from .....harmonics.log_functions import lm11 @nb.njit(cache=True) -def gamma_gg_nf3(n, sx): +def gamma_gg_nf3(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^3` of :math:`\gamma_{gg}^{(3)}`, the expression is copied exact from Eq. 3.14 of :cite:`Davies:2016jie`. @@ -15,18 +16,20 @@ def gamma_gg_nf3(n, sx): ---------- n : complex Mellin moment - sx : list - harmonic sums cache - + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- complex |N3LO| non-singlet anomalous dimension :math:`\gamma_{gg}^{(3)}|_{nf^3}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3, S21, _, _, _, _ = sx[2] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S21 = c.get(c.S21, cache, n, is_singlet) return 3.0 * ( -0.0205761316872428 + 2.599239604033225 / (-1.0 + n) @@ -137,23 +140,24 @@ def gamma_gg_nf3(n, sx): @nb.njit(cache=True) -def gamma_gg_nf1(n, sx): +def gamma_gg_nf1(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^1` of :math:`\gamma_{gg}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache - + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- complex |N3LO| non-singlet anomalous dimension :math:`\gamma_{gg}^{(3)}|_{nf^1}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) return ( 18371.82290926215 + 1992.766087237516 / np.power(-1.0 + n, 3) @@ -168,15 +172,17 @@ def gamma_gg_nf1(n, sx): @nb.njit(cache=True) -def gamma_gg_nf2(n, sx): +def gamma_gg_nf2(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^2` of :math:`\gamma_{gg}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -184,7 +190,7 @@ def gamma_gg_nf2(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{gg}^{(3)}|_{nf^2}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) return ( -436.18166675733164 + 18.346203400819753 / np.power(-1.0 + n, 2) @@ -198,15 +204,17 @@ def gamma_gg_nf2(n, sx): @nb.njit(cache=True) -def gamma_gg_nf0(n, sx): +def gamma_gg_nf0(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^0` of :math:`\gamma_{gg}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -214,7 +222,7 @@ def gamma_gg_nf0(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{gg}^{(3)}|_{nf^0}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) return ( -61782.868048046716 - 49851.703887834694 / np.power(-1.0 + n, 4) @@ -230,7 +238,7 @@ def gamma_gg_nf0(n, sx): @nb.njit(cache=True) -def gamma_gg(n, nf, sx): +def gamma_gg(n, nf, cache, is_singlet): r"""Computes the |N3LO| gluon-gluon singlet anomalous dimension. Parameters @@ -239,8 +247,10 @@ def gamma_gg(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -257,8 +267,8 @@ def gamma_gg(n, nf, sx): """ return ( - gamma_gg_nf0(n, sx) - + nf * gamma_gg_nf1(n, sx) - + nf**2 * gamma_gg_nf2(n, sx) - + nf**3 * gamma_gg_nf3(n, sx) + gamma_gg_nf0(n, cache, is_singlet) + + nf * gamma_gg_nf1(n, cache, is_singlet) + + nf**2 * gamma_gg_nf2(n, cache, is_singlet) + + nf**3 * gamma_gg_nf3(n, cache, is_singlet) ) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py index 4752328dc..83e976234 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/ggq.py @@ -3,11 +3,12 @@ import numba as nb import numpy as np +from .....harmonics import cache as c from .....harmonics.log_functions import lm13, lm13m1, lm14, lm15 @nb.njit(cache=True) -def gamma_gq_nf3(n, sx): +def gamma_gq_nf3(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^3` of :math:`\gamma_{gq}^{(3)}`, the expression is copied exact from Eq. 3.13 of :cite:`Davies:2016jie`. @@ -15,18 +16,19 @@ def gamma_gq_nf3(n, sx): ---------- n : complex Mellin moment - sx : list - harmonic sums cache - + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- complex |N3LO| non-singlet anomalous dimension :math:`\gamma_{gq}^{(3)}|_{nf^3}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) return 1.3333333333333333 * ( -11.39728026699467 / (-1.0 + n) + 11.39728026699467 / n @@ -52,15 +54,17 @@ def gamma_gq_nf3(n, sx): @nb.njit(cache=True) -def gamma_gq_nf0(n, sx): +def gamma_gq_nf0(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^0` of :math:`\gamma_{gq}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -68,11 +72,11 @@ def gamma_gq_nf0(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{gq}^{(3)}|_{nf^0}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] - S4 = sx[3][0] - S5 = sx[4][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S5 = c.get(c.S5, cache, n, is_singlet) return ( -22156.31283903764 / np.power(-1.0 + n, 4) + 63019.91215580799 / np.power(-1.0 + n, 3) @@ -88,15 +92,17 @@ def gamma_gq_nf0(n, sx): @nb.njit(cache=True) -def gamma_gq_nf1(n, sx): +def gamma_gq_nf1(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^1` of :math:`\gamma_{gq}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -104,11 +110,11 @@ def gamma_gq_nf1(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{gq}^{(3)}|_{nf^1}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] - S4 = sx[3][0] - S5 = sx[4][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S5 = c.get(c.S5, cache, n, is_singlet) return ( -4989.9438192798825 / np.power(-1.0 + n, 3) + 9496.873384515262 / np.power(-1.0 + n, 2) @@ -123,15 +129,17 @@ def gamma_gq_nf1(n, sx): @nb.njit(cache=True) -def gamma_gq_nf2(n, sx): +def gamma_gq_nf2(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^2` of :math:`\gamma_{gq}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -139,10 +147,10 @@ def gamma_gq_nf2(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{gq}^{(3)}|_{nf^2}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] - S4 = sx[3][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) return ( -215.9801828033175 / np.power(-1.0 + n, 2) - 18.066114610010438 / (-1.0 + n) @@ -154,7 +162,7 @@ def gamma_gq_nf2(n, sx): @nb.njit(cache=True) -def gamma_gq(n, nf, sx): +def gamma_gq(n, nf, cache, is_singlet): r"""Computes the |N3LO| gluon-quark singlet anomalous dimension. Parameters @@ -163,8 +171,10 @@ def gamma_gq(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -181,8 +191,8 @@ def gamma_gq(n, nf, sx): """ return ( - gamma_gq_nf0(n, sx) - + nf * gamma_gq_nf1(n, sx) - + nf**2 * gamma_gq_nf2(n, sx) - + nf**3 * gamma_gq_nf3(n, sx) + gamma_gq_nf0(n, cache, is_singlet) + + nf * gamma_gq_nf1(n, cache, is_singlet) + + nf**2 * gamma_gq_nf2(n, cache, is_singlet) + + nf**3 * gamma_gq_nf3(n, cache, is_singlet) ) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py index 3d6f16c32..5371a3c11 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsm.py @@ -5,11 +5,12 @@ from eko.constants import CF, zeta3 +from .....harmonics import cache as c from .....harmonics.log_functions import lm11m1, lm12m1, lm13m1 @nb.njit(cache=True) -def gamma_ns_nf3(n, sx): +def gamma_ns_nf3(n, cache, is_singlet): """Implements the common part proportional to :math:`nf^3`, of :math:`\\gamma_{ns,+}^{(3)},\\gamma_{ns,-}^{(3)},\\gamma_{ns,v}^{(3)}`. The expression is copied exact from Eq. 3.6. of :cite:`Davies:2016jie`. @@ -18,8 +19,10 @@ def gamma_ns_nf3(n, sx): ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -27,10 +30,10 @@ def gamma_ns_nf3(n, sx): |N3LO| non-singlet anomalous dimension :math:`\\gamma_{ns}^{(3)}|_{nf^3}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] - S4 = sx[3][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) eta = 1 / n * 1 / (n + 1) g_ns_nf3 = CF * ( -32 / 27 * zeta3 * eta @@ -52,15 +55,17 @@ def gamma_ns_nf3(n, sx): @nb.njit(cache=True) -def gamma_nsm_nf2(n, sx): +def gamma_nsm_nf2(n, cache, is_singlet): """Implements the parametrized valence-like non-singlet part proportional to :math:`nf^2`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -69,10 +74,12 @@ def gamma_nsm_nf2(n, sx): :math:`\\gamma_{ns,-}^{(3)}|_{nf^2}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) Lm11m1 = lm11m1(n, S1) - Lm12m1 = lm12m1(n, S1, sx[1][0]) - Lm13m1 = lm13m1(n, S1, sx[1][0], sx[2][0]) + Lm12m1 = lm12m1(n, S1, S2) + Lm13m1 = lm13m1(n, S1, S2, S3) return ( -193.85692903712987 - 18.962962962962962 / n**5 @@ -93,15 +100,17 @@ def gamma_nsm_nf2(n, sx): @nb.njit(cache=True) -def gamma_nsm_nf1(n, sx): +def gamma_nsm_nf1(n, cache, is_singlet): """Implements the parametrized valence-like non-singlet part proportional to :math:`nf^1`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -110,10 +119,12 @@ def gamma_nsm_nf1(n, sx): :math:`\\gamma_{ns,-}^{(3)}|_{nf^1}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) Lm11m1 = lm11m1(n, S1) - Lm12m1 = lm12m1(n, S1, sx[1][0]) - Lm13m1 = lm13m1(n, S1, sx[1][0], sx[2][0]) + Lm12m1 = lm12m1(n, S1, S2) + Lm13m1 = lm13m1(n, S1, S2, S3) return ( 5549.7951398549685 - 126.41975308641975 / n**6 @@ -135,15 +146,17 @@ def gamma_nsm_nf1(n, sx): @nb.njit(cache=True) -def gamma_nsm_nf0(n, sx): +def gamma_nsm_nf0(n, cache, is_singlet): """Implements the parametrized valence-like non-singlet part proportional to :math:`nf^0`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -151,10 +164,12 @@ def gamma_nsm_nf0(n, sx): |N3LO| valence-like non-singlet anomalous dimension :math:`\\gamma_{ns,-}^{(3)}|_{nf^0}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) Lm11m1 = lm11m1(n, S1) - Lm12m1 = lm12m1(n, S1, sx[1][0]) - Lm13m1 = lm13m1(n, S1, sx[1][0], sx[2][0]) + Lm12m1 = lm12m1(n, S1, S2) + Lm13m1 = lm13m1(n, S1, S2, S3) return ( -23383.08164724965 - 252.8395061728395 / n**7 @@ -177,7 +192,7 @@ def gamma_nsm_nf0(n, sx): @nb.njit(cache=True) -def gamma_nsm(n, nf, sx): +def gamma_nsm(n, nf, cache, is_singlet): """Computes the |N3LO| valence-like non-singlet anomalous dimension. Parameters @@ -186,8 +201,10 @@ def gamma_nsm(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -204,8 +221,8 @@ def gamma_nsm(n, nf, sx): """ return ( - gamma_nsm_nf0(n, sx) - + nf * gamma_nsm_nf1(n, sx) - + nf**2 * gamma_nsm_nf2(n, sx) - + nf**3 * gamma_ns_nf3(n, sx) + gamma_nsm_nf0(n, cache, is_singlet) + + nf * gamma_nsm_nf1(n, cache, is_singlet) + + nf**2 * gamma_nsm_nf2(n, cache, is_singlet) + + nf**3 * gamma_ns_nf3(n, cache, is_singlet) ) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py index 9f5be5c4d..84b4e78a1 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsp.py @@ -3,20 +3,23 @@ """ import numba as nb +from .....harmonics import cache as c from .....harmonics.log_functions import lm11m1, lm12m1, lm13m1 from .gnsm import gamma_ns_nf3 @nb.njit(cache=True) -def gamma_nsp_nf2(n, sx): +def gamma_nsp_nf2(n, cache, is_singlet): """Implements the parametrized singlet-like non-singlet part proportional to :math:`nf^2`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -24,10 +27,12 @@ def gamma_nsp_nf2(n, sx): |N3LO| singlet-like non-singlet anomalous dimension :math:`\\gamma_{ns,+}^{(3)}|_{nf^2}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) Lm11m1 = lm11m1(n, S1) - Lm12m1 = lm12m1(n, S1, sx[1][0]) - Lm13m1 = lm13m1(n, S1, sx[1][0], sx[2][0]) + Lm12m1 = lm12m1(n, S1, S2) + Lm13m1 = lm13m1(n, S1, S2, S3) return ( -193.85479604848626 - 18.962962962962962 / n**5 @@ -48,15 +53,17 @@ def gamma_nsp_nf2(n, sx): @nb.njit(cache=True) -def gamma_nsp_nf1(n, sx): +def gamma_nsp_nf1(n, cache, is_singlet): """Implements the parametrized singlet-like non-singlet part proportional to :math:`nf^1`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -64,10 +71,12 @@ def gamma_nsp_nf1(n, sx): |N3LO| singlet-like non-singlet anomalous dimension :math:`\\gamma_{ns,+}^{(3)}|_{nf^1}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) Lm11m1 = lm11m1(n, S1) - Lm12m1 = lm12m1(n, S1, sx[1][0]) - Lm13m1 = lm13m1(n, S1, sx[1][0], sx[2][0]) + Lm12m1 = lm12m1(n, S1, S2) + Lm13m1 = lm13m1(n, S1, S2, S3) return ( 5550.063827367692 - 126.41975308641975 / n**6 @@ -89,15 +98,17 @@ def gamma_nsp_nf1(n, sx): @nb.njit(cache=True) -def gamma_nsp_nf0(n, sx): +def gamma_nsp_nf0(n, cache, is_singlet): """Implements the parametrized singlet-like non-singlet part proportional to :math:`nf^0`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -105,10 +116,12 @@ def gamma_nsp_nf0(n, sx): |N3LO| singlet-like non-singlet anomalous dimension :math:`\\gamma_{ns,+}^{(3)}|_{nf^0}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) Lm11m1 = lm11m1(n, S1) - Lm12m1 = lm12m1(n, S1, sx[1][0]) - Lm13m1 = lm13m1(n, S1, sx[1][0], sx[2][0]) + Lm12m1 = lm12m1(n, S1, S2) + Lm13m1 = lm13m1(n, S1, S2, S3) return ( -23391.854890259732 - 252.8395061728395 / n**7 @@ -131,7 +144,7 @@ def gamma_nsp_nf0(n, sx): @nb.njit(cache=True) -def gamma_nsp(n, nf, sx): +def gamma_nsp(n, nf, cache, is_singlet): """Computes the |N3LO| singlet-like non-singlet anomalous dimension. Parameters @@ -140,8 +153,10 @@ def gamma_nsp(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -158,8 +173,8 @@ def gamma_nsp(n, nf, sx): """ return ( - gamma_nsp_nf0(n, sx) - + nf * gamma_nsp_nf1(n, sx) - + nf**2 * gamma_nsp_nf2(n, sx) - + nf**3 * gamma_ns_nf3(n, sx) + gamma_nsp_nf0(n, cache, is_singlet) + + nf * gamma_nsp_nf1(n, cache, is_singlet) + + nf**2 * gamma_nsp_nf2(n, cache, is_singlet) + + nf**3 * gamma_ns_nf3(n, cache, is_singlet) ) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py index 5d831590f..99a57c4a2 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gnsv.py @@ -3,11 +3,12 @@ """ import numba as nb +from .....harmonics import cache as c from .gnsm import gamma_nsm @nb.njit(cache=True) -def gamma_nss_nf2(n, sx): +def gamma_nss_nf2(n, cache, is_singlet): """Implements the sea non-singlet part proportional to :math:`nf^2` as in Eq. 3.5 of :cite:`Davies:2016jie`. @@ -15,8 +16,10 @@ def gamma_nss_nf2(n, sx): ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -24,10 +27,18 @@ def gamma_nss_nf2(n, sx): |N3LO| sea non-singlet anomalous dimension :math:`\\gamma_{ns,s}^{(3)}|_{nf^2}` """ - S1, _ = sx[0] - S2, Sm2 = sx[1] - S3, _, _, Sm21, _, Sm3 = sx[2] - S4, S31, _, Sm22, Sm211, Sm31, Sm4 = sx[3] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + Sm21 = c.get(c.Sm21, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S31 = c.get(c.S31, cache, n, is_singlet) + Sm22 = c.get(c.Sm22, cache, n, is_singlet) + Sm211 = c.get(c.Sm211, cache, n, is_singlet) + Sm31 = c.get(c.Sm31, cache, n, is_singlet) + Sm4 = c.get(c.Sm4, cache, n, is_singlet) return ( 160 / 27 @@ -163,7 +174,7 @@ def gamma_nss_nf2(n, sx): @nb.njit(cache=True) -def gamma_nss_nf1(n, sx): +def gamma_nss_nf1(n, cache, is_singlet): """Implements the sea non-singlet part proportional to :math:`nf^1`. The expression is the average of the Mellin transform of Eq. 4.19, 4.20 of :cite:`Moch:2017uml` @@ -172,8 +183,10 @@ def gamma_nss_nf1(n, sx): ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -181,9 +194,9 @@ def gamma_nss_nf1(n, sx): |N3LO| sea non-singlet anomalous dimension :math:`\\gamma_{ns,s}^{(3)}|_{nf^1}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) return ( 3803.04 / n**6 - 3560.16 / n**5 @@ -218,7 +231,7 @@ def gamma_nss_nf1(n, sx): @nb.njit(cache=True) -def gamma_nsv(n, nf, sx): +def gamma_nsv(n, nf, cache, is_singlet): """Computes the |N3LO| valence non-singlet anomalous dimension. Parameters @@ -227,8 +240,10 @@ def gamma_nsv(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -244,7 +259,7 @@ def gamma_nsv(n, nf, sx): """ return ( - gamma_nsm(n, nf, sx) - + nf * gamma_nss_nf1(n, sx) - + nf**2 * gamma_nss_nf2(n, sx) + gamma_nsm(n, nf, cache, is_singlet) + + nf * gamma_nss_nf1(n, cache, is_singlet) + + nf**2 * gamma_nss_nf2(n, cache, is_singlet) ) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gps.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gps.py index a563a693c..bf777ab21 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gps.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gps.py @@ -3,9 +3,11 @@ import numba as nb import numpy as np +from .....harmonics import cache as c + @nb.njit(cache=True) -def gamma_ps_nf3(n, sx): +def gamma_ps_nf3(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^3` of :math:`\gamma_{ps}^{(3)}`, the expression is copied exact from Eq. 3.10 of :cite:`Davies:2016jie`. @@ -13,8 +15,10 @@ def gamma_ps_nf3(n, sx): ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -22,9 +26,9 @@ def gamma_ps_nf3(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{ps}^{(3)}|_{nf^3}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) return 1.3333333333333333 * ( 16.305796943701882 / (-1.0 + n) + 3.5555555555555554 / np.power(n, 5) @@ -77,23 +81,24 @@ def gamma_ps_nf3(n, sx): @nb.njit(cache=True) -def gamma_ps_nf1(n, sx): +def gamma_ps_nf1(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^1` of :math:`\gamma_{ps}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache - + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- complex |N3LO| non-singlet anomalous dimension :math:`\gamma_{ps}^{(3)}|_{nf^1}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) return ( -10185.956311680911 * (1 / (-1.0 + n) - 1.0 / n) - 3498.454512979491 / np.power(-1.0 + n, 3) @@ -107,15 +112,17 @@ def gamma_ps_nf1(n, sx): @nb.njit(cache=True) -def gamma_ps_nf2(n, sx): +def gamma_ps_nf2(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^2` of :math:`\gamma_{ps}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -123,7 +130,7 @@ def gamma_ps_nf2(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{ps}^{(3)}|_{nf^2}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) return ( -547.9815124741111 * (1 / (-1.0 + n) - 1.0 / n) + 383.72024118761027 / np.power(-1.0 + n, 2) @@ -136,7 +143,7 @@ def gamma_ps_nf2(n, sx): @nb.njit(cache=True) -def gamma_ps(n, nf, sx): +def gamma_ps(n, nf, cache, is_singlet): r"""Computes the |N3LO| pure singlet quark-quark anomalous dimension. Parameters @@ -145,8 +152,10 @@ def gamma_ps(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -162,7 +171,7 @@ def gamma_ps(n, nf, sx): """ return ( - +nf * gamma_ps_nf1(n, sx) - + nf**2 * gamma_ps_nf2(n, sx) - + nf**3 * gamma_ps_nf3(n, sx) + +nf * gamma_ps_nf1(n, cache, is_singlet) + + nf**2 * gamma_ps_nf2(n, cache, is_singlet) + + nf**3 * gamma_ps_nf3(n, cache, is_singlet) ) diff --git a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gqg.py b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gqg.py index 7f146eebc..8add77e47 100644 --- a/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gqg.py +++ b/src/ekore/anomalous_dimensions/unpolarized/space_like/as4/gqg.py @@ -3,11 +3,12 @@ import numba as nb import numpy as np +from .....harmonics import cache as c from .....harmonics.log_functions import lm13, lm13m1, lm14, lm15 @nb.njit(cache=True) -def gamma_qg_nf3(n, sx): +def gamma_qg_nf3(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^3` of :math:`\gamma_{qg}^{(3)}`, the expression is copied exact from Eq. 3.12 of :cite:`Davies:2016jie`. @@ -15,8 +16,10 @@ def gamma_qg_nf3(n, sx): ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -24,10 +27,16 @@ def gamma_qg_nf3(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{qg}^{(3)}|_{nf^3}` """ - S1 = sx[0][0] - S2, Sm2 = sx[1] - S3, S21, _, _, _, Sm3 = sx[2] - S4, S31, S211, _, _, _, Sm4 = sx[3] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S21 = c.get(c.S21, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S31 = c.get(c.S31, cache, n, is_singlet) + S211 = c.get(c.S211, cache, n, is_singlet) + Sm4 = c.get(c.Sm4, cache, n, is_singlet) return 1.3333333333333333 * ( 44.56685134331718 / (-1.0 + n) - 82.37037037037037 / np.power(n, 5) @@ -329,15 +338,17 @@ def gamma_qg_nf3(n, sx): @nb.njit(cache=True) -def gamma_qg_nf1(n, sx): +def gamma_qg_nf1(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^1` of :math:`\gamma_{qg}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -345,11 +356,11 @@ def gamma_qg_nf1(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{qg}^{(3)}|_{nf^1}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] - S4 = sx[3][0] - S5 = sx[4][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S5 = c.get(c.S5, cache, n, is_singlet) return ( -7871.5226542038545 / np.power(-1.0 + n, 3) + 13490.08729769531 / np.power(-1.0 + n, 2) @@ -365,15 +376,17 @@ def gamma_qg_nf1(n, sx): @nb.njit(cache=True) -def gamma_qg_nf2(n, sx): +def gamma_qg_nf2(n, cache, is_singlet): r"""Implements the part proportional to :math:`nf^2` of :math:`\gamma_{qg}^{(3)}`. Parameters ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -381,11 +394,11 @@ def gamma_qg_nf2(n, sx): |N3LO| non-singlet anomalous dimension :math:`\gamma_{qg}^{(3)}|_{nf^2}` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] - S4 = sx[3][0] - S5 = sx[4][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S5 = c.get(c.S5, cache, n, is_singlet) return ( 237.02932710506118 / np.power(-1.0 + n, 2) + 447.1862550338544 / (-1.0 + n) @@ -400,7 +413,7 @@ def gamma_qg_nf2(n, sx): @nb.njit(cache=True) -def gamma_qg(n, nf, sx): +def gamma_qg(n, nf, cache, is_singlet): r"""Computes the |N3LO| quark-gluon singlet anomalous dimension. Parameters @@ -409,8 +422,10 @@ def gamma_qg(n, nf, sx): Mellin moment nf : int Number of active flavors - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -426,7 +441,7 @@ def gamma_qg(n, nf, sx): """ return ( - +nf * gamma_qg_nf1(n, sx) - + nf**2 * gamma_qg_nf2(n, sx) - + nf**3 * gamma_qg_nf3(n, sx) + +nf * gamma_qg_nf1(n, cache, is_singlet) + + nf**2 * gamma_qg_nf2(n, cache, is_singlet) + + nf**3 * gamma_qg_nf3(n, cache, is_singlet) ) diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py index a1d2f8ec6..8e1f519fc 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/__init__.py @@ -6,11 +6,12 @@ import numba as nb import numpy as np +from ....harmonics import cache as c from . import as1, as2, as3 @nb.njit(cache=True) -def A_singlet(matching_order, n, sx, nf, L, is_msbar, sx_ns=None): +def A_singlet(matching_order, n, nf, L, is_msbar): r""" Computes the tower of the singlet |OME|. @@ -20,41 +21,33 @@ def A_singlet(matching_order, n, sx, nf, L, is_msbar, sx_ns=None): perturbative matching_order n : complex Mellin variable - sx : list - singlet like harmonic sums cache nf: int number of active flavor below threshold L : float :math:``\ln(\mu_F^2 / m_h^2)`` is_msbar: bool add the |MSbar| contribution - sx_ns : list - non-singlet like harmonic sums cache Returns ------- A_singlet : numpy.ndarray singlet |OME| - See Also - -------- - ekore.matching_conditions.nlo.A_singlet_1 : :math:`A^{S,(1)}(N)` - ekore.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` - ekore.matching_conditions.nlo.A_gh_1 : :math:`A_{gH}^{(1)}(N)` - ekore.matching_conditions.nnlo.A_singlet_2 : :math:`A_{S,(2)}(N)` """ A_s = np.zeros((matching_order[0], 3, 3), np.complex_) + + cache = c.reset() if matching_order[0] >= 1: - A_s[0] = as1.A_singlet(n, sx, L) + A_s[0] = as1.A_singlet(n, L, cache, True) if matching_order[0] >= 2: - A_s[1] = as2.A_singlet(n, sx, L, is_msbar) + A_s[1] = as2.A_singlet(n, L, cache, True, is_msbar) if matching_order[0] >= 3: - A_s[2] = as3.A_singlet(n, sx, sx_ns, nf, L) + A_s[2] = as3.A_singlet(n, nf, L, cache) return A_s @nb.njit(cache=True) -def A_non_singlet(matching_order, n, sx, nf, L): +def A_non_singlet(matching_order, n, nf, L): r""" Computes the tower of the non-singlet |OME| @@ -64,8 +57,6 @@ def A_non_singlet(matching_order, n, sx, nf, L): perturbative matching_order n : complex Mellin variable - sx : list - harmonic sums cache nf: int number of active flavor below threshold L : float @@ -76,16 +67,14 @@ def A_non_singlet(matching_order, n, sx, nf, L): A_non_singlet : numpy.ndarray non-singlet |OME| - See Also - -------- - ekore.matching_conditions.nlo.A_hh_1 : :math:`A_{HH}^{(1)}(N)` - ekore.matching_conditions.nnlo.A_ns_2 : :math:`A_{qq,H}^{NS,(2)}` """ A_ns = np.zeros((matching_order[0], 2, 2), np.complex_) + + cache = c.reset() if matching_order[0] >= 1: - A_ns[0] = as1.A_ns(n, sx, L) + A_ns[0] = as1.A_ns(n, L, cache, False) if matching_order[0] >= 2: - A_ns[1] = as2.A_ns(n, sx, L) + A_ns[1] = as2.A_ns(n, L, cache, False) if matching_order[0] >= 3: - A_ns[2] = as3.A_ns(n, sx, nf, L) + A_ns[2] = as3.A_ns(n, nf, L, cache, False) return A_ns diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py index c373f8091..41fea4c8b 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as1.py @@ -11,9 +11,11 @@ from eko.constants import CF +from ....harmonics import cache as c + @nb.njit(cache=True) -def A_hh(n, sx, L): +def A_hh(n, L, cache, is_singlet): r""" |NLO| heavy-heavy |OME| :math:`A_{HH}^{(1)}` defined as the mellin transform of :math:`K_{hh}` given in Eq. (20a) of :cite:`Ball_2016`. @@ -22,18 +24,20 @@ def A_hh(n, sx, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- 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 = c.get(c.S1, cache, n, is_singlet) - 1 / n # harmonics.S1(n - 1) + S2m = c.get(c.S2, cache, n, is_singlet) - 1 / n**2 # harmonics.S2(n - 1) ahh_l = (2 + n - 3 * n**2) / (n * (1 + n)) + 4 * S1m ahh = 2 * ( 2 @@ -115,7 +119,7 @@ def A_gg(L): @nb.njit(cache=True) -def A_singlet(n, sx, L): +def A_singlet(n, L, cache, is_singlet): r""" Computes the |NLO| singlet |OME|. @@ -130,10 +134,12 @@ def A_singlet(n, sx, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache containing: [[:math:`S_1`][:math:`S_2`]] L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -151,7 +157,7 @@ def A_singlet(n, sx, L): [ [A_gg(L), 0.0, A_gh(n, L)], [0 + 0j, 0 + 0j, 0 + 0j], - [A_hg(n, L), 0.0, A_hh(n, sx, L)], + [A_hg(n, L), 0.0, A_hh(n, L, cache, is_singlet)], ], np.complex_, ) @@ -159,7 +165,7 @@ def A_singlet(n, sx, L): @nb.njit(cache=True) -def A_ns(n, sx, L): +def A_ns(n, L, cache, is_singlet): r""" Computes the |NLO| non-singlet |OME| with intrinsic contributions. @@ -173,10 +179,12 @@ def A_ns(n, sx, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache containing: [[:math:`S_1`][:math:`S_2`]] L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- A_NS : numpy.ndarray @@ -186,4 +194,6 @@ def A_ns(n, sx, L): -------- A_hh : :math:`A_{HH}^{(1)}` """ - return np.array([[0 + 0j, 0 + 0j], [0 + 0j, A_hh(n, sx, L)]], np.complex_) + return np.array( + [[0 + 0j, 0 + 0j], [0 + 0j, A_hh(n, L, cache, is_singlet)]], np.complex_ + ) diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py index 3549bd324..bb3dcdb75 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as2.py @@ -14,12 +14,13 @@ from eko import constants from eko.constants import zeta2, zeta3 +from ....harmonics import cache as c from .as1 import A_gg as A_gg_1 from .as1 import A_hg as A_hg_1 @nb.njit(cache=True) -def A_qq_ns(n, sx, L): +def A_qq_ns(n, L, cache, is_singlet): r""" |NNLO| light-light non-singlet |OME| :math:`A_{qq,H}^{NS,(2)}` given in Eq. (B.4) of :cite:`Buza_1998`. @@ -28,19 +29,21 @@ def A_qq_ns(n, sx, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- 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 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) S1m = S1 - 1 / n # harmonic_S1(n - 1) S2m = S2 - 1 / n**2 # harmonic_S2(n - 1) @@ -74,7 +77,7 @@ def A_qq_ns(n, sx, L): @nb.njit(cache=True) -def A_hq_ps(n, sx, L): +def A_hq_ps(n, L, cache, is_singlet): r""" |NNLO| heavy-light pure-singlet |OME| :math:`A_{Hq}^{PS,(2)}` given in Eq. (B.1) of :cite:`Buza_1998`. @@ -83,17 +86,19 @@ def A_hq_ps(n, sx, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- A_hq_ps : complex |NNLO| heavy-light pure-singlet |OME| :math:`A_{Hq}^{PS,(2)}` """ - S2 = sx[1][0] + S2 = c.get(c.S2, cache, n, is_singlet) 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 +142,7 @@ def A_hq_ps(n, sx, L): @nb.njit(cache=True) -def A_hg(n, sx, L): +def A_hg(n, L, cache, is_singlet): r""" |NNLO| heavy-gluon |OME| :math:`A_{Hg}^{S,(2)}` given in Eq. (B.3) of :cite:`Buza_1998`. @@ -147,22 +152,24 @@ def A_hg(n, sx, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- A_hg : complex |NNLO| heavy-gluon |OME| :math:`A_{Hg}^{S,(2)}` """ - S1 = sx[0][0] - S2, Sm2 = sx[1] - if len(sx[2]) == 3: - S3, Sm21, Sm3 = sx[2] - else: - S3, _, _, Sm21, _, Sm3 = sx[2] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + Sm21 = c.get(c.Sm21, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) S1m = S1 - 1 / n S2m = S2 - 1 / n**2 @@ -277,7 +284,7 @@ def A_hg(n, sx, L): @nb.njit(cache=True) -def A_gq(n, sx, L): +def A_gq(n, L, cache, is_singlet): r""" |NNLO| gluon-quark |OME| :math:`A_{gq,H}^{S,(2)}` given in Eq. (B.5) of :cite:`Buza_1998`. @@ -286,18 +293,20 @@ def A_gq(n, sx, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- A_gq : complex |NNLO| gluon-quark |OME| :math:`A_{gq,H}^{S,(2)}` """ - S1 = sx[0][0] - S2 = sx[1][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) S1m = S1 - 1 / n # harmonic_S1(n - 1) B2M = ((S1 - 1.0 / n) ** 2 + S2 - 1.0 / n**2) / (n - 1.0) @@ -327,7 +336,7 @@ def A_gq(n, sx, L): @nb.njit(cache=True) -def A_gg(n, sx, L): +def A_gg(n, L, cache, is_singlet): r""" |NNLO| gluon-gluon |OME| :math:`A_{gg,H}^{S,(2)} ` given in Eq. (B.7) of :cite:`Buza_1998`. @@ -336,17 +345,19 @@ def A_gg(n, sx, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- A_gg : complex |NNLO| gluon-gluon |OME| :math:`A_{gg,H}^{S,(2)}` """ - S1 = sx[0][0] + S1 = c.get(c.S1, cache, n, is_singlet) S1m = S1 - 1 / n # harmonic_S1(n - 1) D1 = -1.0 / n**2 @@ -414,7 +425,7 @@ def A_gg(n, sx, L): @nb.njit(cache=True) -def A_singlet(n, sx, L, is_msbar=False): +def A_singlet(n, L, cache, is_singlet, is_msbar=False): r""" Computes the |NNLO| singlet |OME|. @@ -429,11 +440,12 @@ def A_singlet(n, sx, L, is_msbar=False): ---------- n : complex Mellin moment - sx : list - harmonic sums cache containing: - [[: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)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise is_msbar: bool add the |MSbar| contribution @@ -450,11 +462,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, L, cache, is_singlet) + A_qq_2 = A_qq_ns(n, L, cache, is_singlet) + A_hg_2 = A_hg(n, L, cache, is_singlet) + A_gq_2 = A_gq(n, L, cache, is_singlet) + A_gg_2 = A_gg(n, L, cache, is_singlet) 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) @@ -465,7 +477,7 @@ def A_singlet(n, sx, L, is_msbar=False): @nb.njit(cache=True) -def A_ns(n, sx, L): +def A_ns(n, L, cache, is_singlet): r""" Computes the |NNLO| non-singlet |OME|. @@ -479,11 +491,12 @@ def A_ns(n, sx, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache containing: - [[: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)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -494,4 +507,6 @@ 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, L, cache, is_singlet), 0.0], [0 + 0j, 0 + 0j]], np.complex_ + ) diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py index 06feccd38..da92e0e34 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/__init__.py @@ -69,7 +69,7 @@ @nb.njit(cache=True) -def A_singlet(n, sx_singlet, sx_non_singlet, nf, L): +def A_singlet(n, nf, L, cache): r"""Computes the |N3LO| singlet |OME|. .. math:: @@ -86,21 +86,13 @@ def A_singlet(n, sx_singlet, sx_non_singlet, nf, L): ---------- n : complex Mellin moment - sx_singlet : list - singlet like harmonic sums cache containing: - - .. 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}],] - - 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 :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + Returns ------- @@ -108,15 +100,15 @@ def A_singlet(n, sx_singlet, sx_non_singlet, nf, L): |NNLO| singlet |OME| :math:`A^{S,(3)}(N)` """ - A_hq_3 = A_Hq(n, sx_singlet, nf, L) - A_hg_3 = A_Hg(n, sx_singlet, nf, L) + A_hq_3 = A_Hq(n, nf, L, cache, True) + A_hg_3 = A_Hg(n, nf, L, cache, True) - A_gq_3 = A_gq(n, sx_singlet, nf, L) - A_gg_3 = A_gg(n, sx_singlet, nf, L) + A_gq_3 = A_gq(n, nf, L, cache, True) + A_gg_3 = A_gg(n, nf, L, cache, True) - 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_qq_ps_3 = A_qqPS(n, nf, L, cache, True) + A_qq_ns_3 = A_qqNS(n, nf, L, cache, False) + A_qg_3 = A_qg(n, nf, L, cache, True) A_S = np.array( [ @@ -130,7 +122,7 @@ def A_singlet(n, sx_singlet, sx_non_singlet, nf, L): @nb.njit(cache=True) -def A_ns(n, sx_all, nf, L): +def A_ns(n, nf, L, cache, is_singlet): r"""Computes the |N3LO| non-singlet |OME|. .. math:: @@ -146,20 +138,14 @@ def A_ns(n, sx_all, nf, L): ---------- n : complex Mellin moment - sx_all : list - harmonic sums cache containing: - - .. 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}],], - [S_{5}, S_{-5}] - nf : int number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -171,4 +157,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, nf, L, cache, is_singlet), 0.0], [0 + 0j, 0 + 0j]], np.complex_ + ) diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py index c676ce558..be45b3be3 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHg.py @@ -2,11 +2,12 @@ import numba as nb import numpy as np +from .....harmonics import cache as c from .aHgstfac import A_Hgstfac @nb.njit(cache=True) -def A_Hg(n, sx, nf, L): # pylint: disable=too-many-locals +def A_Hg(n, nf, L, cache, is_singlet): # pylint: disable=too-many-locals r"""Computes the |N3LO| singlet |OME| :math:`A_{Hg}^{S,(3)}(N)`. The expression is presented in :cite:`Bierenbaum:2009mv`. @@ -17,12 +18,14 @@ def A_Hg(n, sx, nf, L): # pylint: disable=too-many-locals ---------- n : complex Mellin moment - sx : list - harmonic sums cache nf : int number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -35,12 +38,22 @@ def A_Hg(n, sx, nf, L): # pylint: disable=too-many-locals Incomplete part of the |OME|. """ - S1, _ = sx[0] - S2, Sm2 = sx[1] - S3, S21, _, Sm21, _, Sm3 = sx[2] - S4, S31, S211, Sm22, Sm211, Sm31, Sm4 = sx[3] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S21 = c.get(c.S21, cache, n, is_singlet) + Sm21 = c.get(c.Sm21, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S31 = c.get(c.S31, cache, n, is_singlet) + S211 = c.get(c.S211, cache, n, is_singlet) + Sm22 = c.get(c.Sm22, cache, n, is_singlet) + Sm211 = c.get(c.Sm211, cache, n, is_singlet) + Sm31 = c.get(c.Sm31, cache, n, is_singlet) + Sm4 = c.get(c.Sm4, cache, n, is_singlet) a_Hg_l0 = ( - A_Hgstfac(n, sx, nf) + A_Hgstfac(n, nf, cache, is_singlet) + (1.0684950250307503 * (2.0 + n + np.power(n, 2))) / (n * (1.0 + n) * (2.0 + n)) + 0.3333333333333333 diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHgstfac.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHgstfac.py index 4eed1890a..fb135fb25 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHgstfac.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHgstfac.py @@ -2,9 +2,11 @@ import numba as nb import numpy as np +from .....harmonics import cache as c + @nb.njit(cache=True) -def A_Hgstfac(n, sx, nf): +def A_Hgstfac(n, nf, cache, is_singlet): r"""Computes the approximate incomplete part of :math:`A_{Hg}^{S,(3)}(N)` proportional to :math:`T_{F}`. The expression is presented in :cite:`Blumlein:2017wxd` (eq 3.1). @@ -23,18 +25,30 @@ def A_Hgstfac(n, sx, nf): ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- complex """ - S1, _ = sx[0] - S2, Sm2 = sx[1] - S3, S21, _, Sm21, _, Sm3 = sx[2] - S4, S31, S211, Sm22, Sm211, Sm31, Sm4 = sx[3] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S21 = c.get(c.S21, cache, n, is_singlet) + Sm21 = c.get(c.Sm21, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S31 = c.get(c.S31, cache, n, is_singlet) + S211 = c.get(c.S211, cache, n, is_singlet) + Sm22 = c.get(c.Sm22, cache, n, is_singlet) + Sm211 = c.get(c.Sm211, cache, n, is_singlet) + Sm31 = c.get(c.Sm31, cache, n, is_singlet) + Sm4 = c.get(c.Sm4, cache, n, is_singlet) momentum_conservation_shift = ( -136.47358087568801 / n**3 * nf - 375.88217393160176 / n**2 ) diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py index 6ea2968ec..a52fdfaa9 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aHq.py @@ -2,9 +2,11 @@ import numba as nb import numpy as np +from .....harmonics import cache as c + @nb.njit(cache=True) -def A_Hq(n, sx, nf, L): # pylint: disable=too-many-locals +def A_Hq(n, nf, L, cache, is_singlet): # pylint: disable=too-many-locals r"""Computes the |N3LO| singlet |OME| :math:`A_{Hq}^{S,(3)}(N)`. The expression is presented in :cite:`Ablinger_2015` (eq 5.1) and :cite:`Blumlein:2017wxd` (eq 3.1). @@ -22,12 +24,14 @@ def A_Hq(n, sx, nf, L): # pylint: disable=too-many-locals ---------- n : complex Mellin moment - sx : list - harmonic sums cache nf : int number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -35,11 +39,21 @@ def A_Hq(n, sx, nf, L): # pylint: disable=too-many-locals :math:`A_{Hq}^{S,(3)}(N)` """ - 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] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S21 = c.get(c.S21, cache, n, is_singlet) + Sm21 = c.get(c.Sm21, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S31 = c.get(c.S31, cache, n, is_singlet) + S211 = c.get(c.S211, cache, n, is_singlet) + Sm22 = c.get(c.Sm22, cache, n, is_singlet) + Sm211 = c.get(c.Sm211, cache, n, is_singlet) + Sm31 = c.get(c.Sm31, cache, n, is_singlet) + Sm4 = c.get(c.Sm4, cache, n, is_singlet) + S5 = c.get(c.S5, cache, n, is_singlet) # fit of: # 2^-N * ( H1 + 8.41439832211716) diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py index b4783d83e..ee2e43798 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agg.py @@ -2,11 +2,12 @@ import numba as nb import numpy as np +from .....harmonics import cache as c from .aggTF2 import A_ggTF2 @nb.njit(cache=True) -def A_gg(n, sx, nf, L): # pylint: disable=too-many-locals +def A_gg(n, nf, L, cache, is_singlet): # pylint: disable=too-many-locals r"""Computes the |N3LO| singlet |OME| :math:`A_{gg}^{S,(3)}(N)`. The expression is presented in :cite:`Bierenbaum:2009mv`. @@ -17,12 +18,14 @@ def A_gg(n, sx, nf, L): # pylint: disable=too-many-locals ---------- n : complex Mellin moment - sx : list - harmonic sums cache nf : int number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -35,13 +38,23 @@ def A_gg(n, sx, nf, L): # pylint: disable=too-many-locals Incomplete part proportional to :math:`T_{F}^2`. """ - S1, _ = sx[0] - S2, Sm2 = sx[1] - S3, S21, _, Sm21, _, Sm3 = sx[2] - S4, S31, S211, Sm22, Sm211, Sm31, Sm4 = sx[3] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S21 = c.get(c.S21, cache, n, is_singlet) + Sm21 = c.get(c.Sm21, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S31 = c.get(c.S31, cache, n, is_singlet) + S211 = c.get(c.S211, cache, n, is_singlet) + Sm22 = c.get(c.Sm22, cache, n, is_singlet) + Sm211 = c.get(c.Sm211, cache, n, is_singlet) + Sm31 = c.get(c.Sm31, cache, n, is_singlet) + Sm4 = c.get(c.Sm4, cache, n, is_singlet) a_gg_l0 = ( -0.35616500834358344 - + A_ggTF2(n, sx) + + A_ggTF2(n, cache, is_singlet) + 0.75 * ( (-19.945240467240673 * (1.0 + n + np.power(n, 2))) diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aggTF2.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aggTF2.py index 299006dc6..a3856dbb6 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aggTF2.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aggTF2.py @@ -1,9 +1,11 @@ import numba as nb import numpy as np +from .....harmonics import cache as c + @nb.njit(cache=True) -def A_ggTF2(n, sx): +def A_ggTF2(n, cache, is_singlet): r"""Computes the approximate incomplete part of :math:`A_{gg}^{S,(3)}(N)` proportional to :math:`T_{F}^2`. The expression is presented in :cite:`Ablinger:2014uka` (eq 4.2). @@ -16,8 +18,10 @@ def A_ggTF2(n, sx): ---------- n : complex Mellin moment - sx : list - harmonic sums cache + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -25,12 +29,12 @@ def A_ggTF2(n, sx): :math:`A_{gg,T_{F}^2}^{S,(3)}(N)` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] - S4 = sx[3][0] - S5 = sx[4][0] - S21 = sx[2][1] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S5 = c.get(c.S5, cache, n, is_singlet) + S21 = c.get(c.S21, cache, n, is_singlet) # Parametrization of: # 4^(1-n) Binomial[2 n,n] ( # -7 Zeta[3]+ Sum[(4^x(x!)^2(S[1,x] x-1))/((2x)! x^3),{x,1,n}] diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py index 906e08e52..791a9dcb8 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/agq.py @@ -1,9 +1,11 @@ import numba as nb import numpy as np +from .....harmonics import cache as c + @nb.njit(cache=True) -def A_gq(n, sx, nf, L): # pylint: disable=too-many-locals +def A_gq(n, nf, L, cache, is_singlet): # pylint: disable=too-many-locals r"""Computes the |N3LO| singlet |OME| :math:`A_{gq}^{S,(3)}(N)`. The expression is presented in :cite:`Ablinger_2014` (eq 6.3). @@ -14,12 +16,14 @@ def A_gq(n, sx, nf, L): # pylint: disable=too-many-locals ---------- n : complex Mellin moment - sx : list - harmonic sums cache nf : int number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -27,10 +31,23 @@ def A_gq(n, sx, nf, L): # pylint: disable=too-many-locals :math:`A_{gq}^{S,(3)}(N)` """ - 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] + S1 = c.get(c.S1, cache, n, is_singlet) + Sm1 = c.get(c.Sm1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S21 = c.get(c.S21, cache, n, is_singlet) + S2m1 = c.get(c.S2m1, cache, n, is_singlet) + Sm21 = c.get(c.Sm21, cache, n, is_singlet) + Sm2m1 = c.get(c.Sm2m1, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S31 = c.get(c.S31, cache, n, is_singlet) + S211 = c.get(c.S211, cache, n, is_singlet) + Sm22 = c.get(c.Sm22, cache, n, is_singlet) + Sm211 = c.get(c.Sm211, cache, n, is_singlet) + Sm31 = c.get(c.Sm31, cache, n, is_singlet) + Sm4 = c.get(c.Sm4, cache, n, is_singlet) a_gq_l0 = ( 0.3333333333333333 * ( diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py index 3c2cc36e4..b510fae85 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqg.py @@ -1,9 +1,11 @@ import numba as nb import numpy as np +from .....harmonics import cache as c + @nb.njit(cache=True) -def A_qg(n, sx, nf, L): +def A_qg(n, nf, L, cache, is_singlet): r"""Computes the |N3LO| singlet |OME| :math:`A_{qg}^{S,(3)}(N)`. The expression is presented in :cite:`Bierenbaum:2009mv`. @@ -14,12 +16,14 @@ def A_qg(n, sx, nf, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache nf : int number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -27,10 +31,16 @@ def A_qg(n, sx, nf, L): :math:`A_{qg}^{S,(3)}(N)` """ - S1, _ = sx[0] - S2, Sm2 = sx[1] - S3, S21, _, _, _, Sm3 = sx[2] - S4, S31, S211, _, _, _, Sm4 = sx[3] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + S21 = c.get(c.S21, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S31 = c.get(c.S31, cache, n, is_singlet) + S211 = c.get(c.S211, cache, n, is_singlet) + Sm4 = c.get(c.Sm4, cache, n, is_singlet) a_qg_l0 = 0.3333333333333333 * nf * ( ( -8.547960200246003 diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py index 40be9ed69..7246c1b7f 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqNS.py @@ -1,9 +1,11 @@ import numba as nb import numpy as np +from .....harmonics import cache as c + @nb.njit(cache=True) -def A_qqNS(n, sx, nf, L): +def A_qqNS(n, nf, L, cache, is_singlet): r"""Computes the |N3LO| singlet |OME| :math:`A_{qq}^{NS,(3)}(N)`. The expression is presented in :cite:`Bierenbaum:2009mv` and :cite:`Ablinger:2014vwa`. It contains some weight 5 harmonics sums. @@ -21,12 +23,14 @@ def A_qqNS(n, sx, nf, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache nf : int number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -34,10 +38,17 @@ def A_qqNS(n, sx, nf, L): :math:`A_{qq}^{NS,(3)}(N)` """ - S1, _ = sx[0] - S2, Sm2 = sx[1] - S3, _, _, Sm21, _, Sm3 = sx[2] - S4, S31, _, Sm22, Sm211, _, Sm4 = sx[3] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + Sm2 = c.get(c.Sm2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) + Sm21 = c.get(c.Sm21, cache, n, is_singlet) + Sm3 = c.get(c.Sm3, cache, n, is_singlet) + S4 = c.get(c.S4, cache, n, is_singlet) + S31 = c.get(c.S31, cache, n, is_singlet) + Sm22 = c.get(c.Sm22, cache, n, is_singlet) + Sm211 = c.get(c.Sm211, cache, n, is_singlet) + Sm4 = c.get(c.Sm4, cache, n, is_singlet) a_qqNS_l0_nf1 = ( 0.3333333333333333 * nf diff --git a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py index ee8f136cd..2fd442f84 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py +++ b/src/ekore/operator_matrix_elements/unpolarized/space_like/as3/aqqPS.py @@ -1,9 +1,11 @@ import numba as nb import numpy as np +from .....harmonics import cache as c + @nb.njit(cache=True) -def A_qqPS(n, sx, nf, L): +def A_qqPS(n, nf, L, cache, is_singlet): r"""Computes the |N3LO| singlet |OME| :math:`A_{qq}^{PS,(3)}(N)`. The expression is presented in :cite:`Bierenbaum:2009mv`. @@ -14,12 +16,14 @@ def A_qqPS(n, sx, nf, L): ---------- n : complex Mellin moment - sx : list - harmonic sums cache nf : int number of active flavor below the threshold L : float :math:`\ln(\mu_F^2 / m_h^2)` + cache : numpy.ndarray + Harmonic sum cache + is_singlet : boolean + True for singlet, False for non-singlet, None otherwise Returns ------- @@ -27,9 +31,9 @@ def A_qqPS(n, sx, nf, L): :math:`A_{qq}^{PS,(3)}(N)` """ - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] + S1 = c.get(c.S1, cache, n, is_singlet) + S2 = c.get(c.S2, cache, n, is_singlet) + S3 = c.get(c.S3, cache, n, is_singlet) a_qqPS_l0 = ( 0.3333333333333333 From 1f4e9b5fccd488e923d05b5e82694a18f692a1f2 Mon Sep 17 00:00:00 2001 From: t7phy Date: Fri, 10 Feb 2023 01:37:31 +0100 Subject: [PATCH 28/30] some error fixes --- .../operator_matrix_element.py | 12 +- src/ekore/harmonics/__init__.py | 207 ------------------ 2 files changed, 6 insertions(+), 213 deletions(-) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index a20307658..0cdc0dde6 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -166,24 +166,24 @@ def quad_ker( if is_time_like: raise NotImplementedError("Polarized, time-like is not implemented") else: - A = ome_ps.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) + A = ome_ps.A_singlet(order, ker_base.n, nf, L, is_msbar) else: if is_time_like: - A = ome_ut.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) + A = ome_ut.A_singlet(order, ker_base.n, nf, L, is_msbar) else: - A = ome_us.A_singlet(order, ker_base.n, sx, nf, L, is_msbar, sx_ns) + A = ome_us.A_singlet(order, ker_base.n, nf, L, is_msbar) else: indices = {200: 0, 91: 1} if is_polarized: if is_time_like: raise NotImplementedError("Polarized, time-like is not implemented") else: - A = ome_ps.A_non_singlet(order, ker_base.n, sx, nf, L) + A = ome_ps.A_non_singlet(order, ker_base.n, nf, L) else: if is_time_like: - A = ome_ut.A_non_singlet(order, ker_base.n, sx, nf, L) + A = ome_ut.A_non_singlet(order, ker_base.n, nf, L) else: - A = ome_us.A_non_singlet(order, ker_base.n, sx, nf, L) + A = ome_us.A_non_singlet(order, ker_base.n, nf, L) # build the expansion in alpha_s depending on the strategy ker = build_ome(A, order, a_s, backward_method) diff --git a/src/ekore/harmonics/__init__.py b/src/ekore/harmonics/__init__.py index 919ca559b..4f245dff9 100644 --- a/src/ekore/harmonics/__init__.py +++ b/src/ekore/harmonics/__init__.py @@ -10,210 +10,3 @@ from .w3 import S3, S21, S2m1, Sm2m1, Sm3, Sm21 from .w4 import S4, S31, S211, Sm4, Sm22, Sm31, Sm211 from .w5 import S5, Sm5 - - -@nb.njit(cache=True) -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}`). - - Multi indices harmonics sums can be stored in the middle columns. - - Parameters - ---------- - 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 - max number of harmonics sums for a given weight - - Returns - ------- - np.ndarray - 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) - if n_max_sums_weight > 1: - h_cache[:, -1] = smx(n, h_cache[:, 0], is_singlet) - return h_cache - - -@nb.njit(cache=True) -def 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) - - Returns - ------- - np.ndarray - list of harmonics sums (:math:`S_{1,..,w}`) - - """ - sx = np.zeros(max_weight, dtype=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 smx(n, sx, is_singlet): - r"""Get the harmonics S-minus cache. - - Parameters - ---------- - n : complex - Mellin moment - 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 - ------- - 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, sx[0], is_singlet) - if max_weight >= 2: - smx[1] = Sm2(n, sx[1], is_singlet) - if max_weight >= 3: - smx[2] = Sm3(n, sx[2], is_singlet) - if max_weight >= 4: - smx[3] = Sm4(n, sx[3], is_singlet) - if max_weight >= 5: - smx[4] = Sm5(n, sx[4], is_singlet) - return smx - - -@nb.njit(cache=True) -def s3x(n, sx, smx, is_singlet): - r"""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}` - 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 - ------- - 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], 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, is_singlet): - r"""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}` - 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 - ------- - 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], is_singlet) - return np.array( - [ - 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, is_singlet), - Sm211(n, sx[0], sx[1], smx[0], is_singlet), - sm31, - ] - ) - - -@nb.njit(cache=True) -def compute_cache(n, max_weight, is_singlet): - r"""Get the harmonics sums cache. - - Parameters - ---------- - n : complex - Mellin moment - max_weight : int - maximum weight to compute [2,3,4,5] - 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 - ------- - list - harmonic sums cache. At |N3LO| it contains: - - .. 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}],] - [S_{5}, S_{-5}] - - """ - # max number of harmonics sum of a given weight for a given max weight. - n_max_sums_weight = {2: 1, 3: 3, 4: 7, 5: 7} - sx = base_harmonics_cache(n, is_singlet, max_weight, n_max_sums_weight[max_weight]) - if max_weight == 3: - # Add Sm21 to cache - sx[2, 1] = Sm21(n, sx[0, 0], sx[0, -1], is_singlet) - elif max_weight >= 4: - # Add weight 3 and 4 to cache - sx[2, 1:-2] = s3x(n, sx[:, 0], sx[:, -1], is_singlet) - sx[3, 1:-1] = 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] From 1e3adf9ae26f72459748a6974e8009523142b063 Mon Sep 17 00:00:00 2001 From: t7phy Date: Fri, 10 Feb 2023 01:52:14 +0100 Subject: [PATCH 29/30] new cache consistency fixes --- .../operator_matrix_element.py | 22 +------------------ .../polarized/space_like/__init__.py | 4 ++-- .../polarized/time_like/__init__.py | 4 ++-- .../unpolarized/time_like/__init__.py | 4 ++-- 4 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/eko/evolution_operator/operator_matrix_element.py b/src/eko/evolution_operator/operator_matrix_element.py index 0cdc0dde6..ef4df8a62 100644 --- a/src/eko/evolution_operator/operator_matrix_element.py +++ b/src/eko/evolution_operator/operator_matrix_element.py @@ -137,27 +137,7 @@ def quad_ker( return 0.0 max_weight_dict = {1: 2, 2: 3, 3: 5} - sx = harmonics.compute_cache( - ker_base.n, max_weight_dict[order[0]], ker_base.is_singlet - ) - sx_ns = sx.copy() - if order[0] == 3 and ( - (backward_method != "" and ker_base.is_singlet) - or (mode0 == 100 and mode1 == 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 ... - 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: diff --git a/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py b/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py index 5d5f771f7..0d961d2b9 100644 --- a/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py +++ b/src/ekore/operator_matrix_elements/polarized/space_like/__init__.py @@ -4,10 +4,10 @@ @nb.njit(cache=True) -def A_non_singlet(_matching_order, _n, _sx, _nf, _L): +def A_non_singlet(_matching_order, _n, _nf, _L): raise NotImplementedError("Polarised, space-like is not yet implemented") @nb.njit(cache=True) -def A_singlet(_matching_order, _n, _sx, _nf, _L, _is_msbar, _sx_ns=None): +def A_singlet(_matching_order, _n, _nf, _L, _is_msbar): raise NotImplementedError("Polarised, space-like is not yet implemented") diff --git a/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py b/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py index 81b9f3de8..5573f69b0 100644 --- a/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py +++ b/src/ekore/operator_matrix_elements/polarized/time_like/__init__.py @@ -4,10 +4,10 @@ @nb.njit(cache=True) -def A_non_singlet(_matching_order, _n, _sx, _nf, _L): +def A_non_singlet(_matching_order, _n, _nf, _L): raise NotImplementedError("Polarised, time-like is not yet implemented") @nb.njit(cache=True) -def A_singlet(_matching_order, _n, _sx, _nf, _L, _is_msbar, _sx_ns=None): +def A_singlet(_matching_order, _n, _nf, _L, _is_msbar): raise NotImplementedError("Polarised, time-like is not yet implemented") diff --git a/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py b/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py index 53c68e8d6..f8d5417bc 100644 --- a/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py +++ b/src/ekore/operator_matrix_elements/unpolarized/time_like/__init__.py @@ -4,10 +4,10 @@ @nb.njit(cache=True) -def A_non_singlet(_matching_order, _n, _sx, _nf, _L): +def A_non_singlet(_matching_order, _n, _nf, _L): raise NotImplementedError("Time-like is not yet implemented") @nb.njit(cache=True) -def A_singlet(_matching_order, _n, _sx, _nf, _L, _is_msbar, _sx_ns=None): +def A_singlet(_matching_order, _n, _nf, _L, _is_msbar): raise NotImplementedError("Time-like is not yet implemented") From 483107c8e39b859cff4b00629a18c66c1dbd708f Mon Sep 17 00:00:00 2001 From: t7phy Date: Fri, 10 Feb 2023 02:48:14 +0100 Subject: [PATCH 30/30] fixed some tests to work with new cache --- src/ekore/harmonics/__init__.py | 154 ++++++++++++++++++ tests/eko/evolution_operator/test_ome.py | 15 +- tests/eko/scale_variations/test_expanded.py | 5 - tests/eko/test_beta.py | 2 +- .../unpolarized/space_like/test_as4.py | 84 +++++----- tests/ekore/harmonics/test_f_functions.py | 105 ++++++------ tests/ekore/harmonics/test_g_functions.py | 2 - .../unpolarized/space_like/test_n3lo.py | 52 +++--- .../unpolarized/space_like/test_nlo.py | 16 +- .../unpolarized/space_like/test_nnlo.py | 40 ++--- 10 files changed, 312 insertions(+), 163 deletions(-) diff --git a/src/ekore/harmonics/__init__.py b/src/ekore/harmonics/__init__.py index 4f245dff9..b99ae4dea 100644 --- a/src/ekore/harmonics/__init__.py +++ b/src/ekore/harmonics/__init__.py @@ -10,3 +10,157 @@ from .w3 import S3, S21, S2m1, Sm2m1, Sm3, Sm21 from .w4 import S4, S31, S211, Sm4, Sm22, Sm31, Sm211 from .w5 import S5, Sm5 + +@nb.njit(cache=True) +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}`). + Multi indices harmonics sums can be stored in the middle columns. + Parameters + ---------- + 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 + max number of harmonics sums for a given weight + Returns + ------- + np.ndarray + 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) +# if n_max_sums_weight > 1: +# h_cache[:, -1] = smx(n, h_cache[:, 0], is_singlet) + return h_cache + + +@nb.njit(cache=True) +def 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) + Returns + ------- + np.ndarray + list of harmonics sums (:math:`S_{1,..,w}`) + """ + sx = np.zeros(max_weight, dtype=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 s3x(n, sx, smx, is_singlet): + r"""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}` + 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 + ------- + 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], 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, is_singlet): + r"""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}` + 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 + ------- + 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], is_singlet) + return np.array( + [ + 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, is_singlet), + Sm211(n, sx[0], sx[1], smx[0], is_singlet), + sm31, + ] + ) + + +@nb.njit(cache=True) +def compute_cache(n, max_weight, is_singlet): + r"""Get the harmonics sums cache. + Parameters + ---------- + n : complex + Mellin moment + max_weight : int + maximum weight to compute [2,3,4,5] + 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 + ------- + list + harmonic sums cache. At |N3LO| it contains: + .. 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}],] + [S_{5}, S_{-5}] + """ + # max number of harmonics sum of a given weight for a given max weight. + n_max_sums_weight = {2: 1, 3: 3, 4: 7, 5: 7} + sx = base_harmonics_cache(n, is_singlet, max_weight, n_max_sums_weight[max_weight]) + if max_weight == 3: + # Add Sm21 to cache + sx[2, 1] = Sm21(n, sx[0, 0], sx[0, -1], is_singlet) + elif max_weight >= 4: + # Add weight 3 and 4 to cache + sx[2, 1:-2] = s3x(n, sx[:, 0], sx[:, -1], is_singlet) + sx[3, 1:-1] = 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] \ No newline at end of file diff --git a/tests/eko/evolution_operator/test_ome.py b/tests/eko/evolution_operator/test_ome.py index d6f3267f1..08c96b52b 100644 --- a/tests/eko/evolution_operator/test_ome.py +++ b/tests/eko/evolution_operator/test_ome.py @@ -14,7 +14,6 @@ from eko.io.runcards import OperatorCard, TheoryCard from eko.io.types import InversionMethod from eko.runner import legacy -from ekore.harmonics import compute_cache from ekore.operator_matrix_elements.unpolarized.space_like import ( A_non_singlet, A_singlet, @@ -31,13 +30,9 @@ def test_build_ome_as(): nf = 3 is_msbar = False for o in [1, 2, 3]: - sx_singlet = compute_cache(N, max_weight_dict[o], True) - sx_ns = sx_singlet - if o == 3: - sx_ns = compute_cache(N, max_weight_dict[o], False) - - aNS = A_non_singlet((o, 0), N, sx_ns, nf, L) - aS = A_singlet((o, 0), N, sx_singlet, nf, L, is_msbar, sx_ns) + + aNS = A_non_singlet((o, 0), N, nf, L) + aS = A_singlet((o, 0), N, nf, L, is_msbar) for a in [aNS, aS]: for method in ["", "expanded", "exact"]: @@ -58,8 +53,8 @@ def test_build_ome_nlo(): is_msbar = False sx = [[1], [1], [1]] nf = 4 - aNSi = A_non_singlet((1, 0), N, sx, nf, L) - aSi = A_singlet((1, 0), N, sx, nf, L, is_msbar) + aNSi = A_non_singlet((1, 0), N, nf, L) + aSi = A_singlet((1, 0), N, nf, L, is_msbar) for a in [aNSi, aSi]: for method in ["", "expanded", "exact"]: dim = len(a[0]) diff --git a/tests/eko/scale_variations/test_expanded.py b/tests/eko/scale_variations/test_expanded.py index 77d207124..6a2744ff3 100644 --- a/tests/eko/scale_variations/test_expanded.py +++ b/tests/eko/scale_variations/test_expanded.py @@ -3,13 +3,8 @@ from eko import basis_rotation as br from ekore.anomalous_dimensions.unpolarized.space_like import gamma_ns, gamma_singlet -<<<<<<< HEAD -from eko.beta import beta_qcd_as2 - -======= from eko.beta import beta_qcd_as2, beta_qcd_as3 ->>>>>>> master from eko.kernels import non_singlet, singlet from eko.scale_variations import Modes, expanded, exponentiated diff --git a/tests/eko/test_beta.py b/tests/eko/test_beta.py index fb089bb62..4621336de 100644 --- a/tests/eko/test_beta.py +++ b/tests/eko/test_beta.py @@ -6,7 +6,7 @@ import pytest from eko import beta -from ekore.harmonics.constants import zeta3 +from eko.constants import zeta3 def _flav_test(function): diff --git a/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py index 38935ec00..54d74b949 100644 --- a/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py +++ b/tests/ekore/anomalous_dimensions/unpolarized/space_like/test_as4.py @@ -12,14 +12,16 @@ gqg, ) from eko.constants import CA, CF -from ekore.harmonics import compute_cache + +from ekore.harmonics import cache as c NF = 5 def test_quark_number_conservation(): N = 1 - sx_cache = compute_cache(N, 5, False) + + cache = c.reset() # (ns,s) # the exact expression (nf^2 part) has an nonphysical pole at N=1, @@ -29,90 +31,90 @@ def test_quark_number_conservation(): # np.testing.assert_allclose(gamma_nsv(N, NF, sx_cache), 0, rtol=3e-7) # nf^1 part - np.testing.assert_allclose(gnsv.gamma_nss_nf1(N, sx_cache), 0.000400625, atol=2e-6) + np.testing.assert_allclose(gnsv.gamma_nss_nf1(N, cache, None), 0.000400625, atol=2e-6) # (ns,-) # nf^3 part - np.testing.assert_allclose(gnsp.gamma_ns_nf3(N, sx_cache), 0, atol=3e-15) + np.testing.assert_allclose(gnsp.gamma_ns_nf3(N, cache, None), 0, atol=3e-15) # nf^2 part - np.testing.assert_allclose(gnsm.gamma_nsm_nf2(N, sx_cache), 0, atol=3e-13) + np.testing.assert_allclose(gnsm.gamma_nsm_nf2(N, cache, None), 0, atol=3e-13) # nf^1 part - np.testing.assert_allclose(gnsm.gamma_nsm_nf1(N, sx_cache), 0, atol=2e-11) + np.testing.assert_allclose(gnsm.gamma_nsm_nf1(N, cache, None), 0, atol=2e-11) # nf^0 part - np.testing.assert_allclose(gnsm.gamma_nsm_nf0(N, sx_cache), 0, atol=2e-10) + np.testing.assert_allclose(gnsm.gamma_nsm_nf0(N, cache, None), 0, atol=2e-10) # total - np.testing.assert_allclose(gnsm.gamma_nsm(N, NF, sx_cache), 0, atol=1e-10) + np.testing.assert_allclose(gnsm.gamma_nsm(N, NF, cache, None), 0, atol=1e-10) def test_momentum_conservation(): N = 2 - sx_cache = compute_cache(N, 5, True) + cache = c.reset() # nf^3 part np.testing.assert_allclose( - gnsp.gamma_ns_nf3(N, sx_cache) - + gps.gamma_ps_nf3(N, sx_cache) - + ggq.gamma_gq_nf3(N, sx_cache), + gnsp.gamma_ns_nf3(N, cache, None) + + gps.gamma_ps_nf3(N, cache, None) + + ggq.gamma_gq_nf3(N, cache, None), 0, atol=3e-15, ) np.testing.assert_allclose( - ggg.gamma_gg_nf3(N, sx_cache) + gqg.gamma_qg_nf3(N, sx_cache), 0, atol=2e-7 + ggg.gamma_gg_nf3(N, cache, None) + gqg.gamma_qg_nf3(N, cache, None), 0, atol=2e-7 ) # nf^3 part np.testing.assert_allclose( - gnsp.gamma_ns_nf3(N, sx_cache) - + gps.gamma_ps_nf3(N, sx_cache) - + ggq.gamma_gq_nf3(N, sx_cache), + gnsp.gamma_ns_nf3(N, cache, None) + + gps.gamma_ps_nf3(N, cache, None) + + ggq.gamma_gq_nf3(N, cache, None), 0, atol=3e-15, ) np.testing.assert_allclose( - ggg.gamma_gg_nf3(N, sx_cache) + gqg.gamma_qg_nf3(N, sx_cache), 0, atol=2e-7 + ggg.gamma_gg_nf3(N, cache, None) + gqg.gamma_qg_nf3(N, cache, None), 0, atol=2e-7 ) # nf^2 part np.testing.assert_allclose( - gnsp.gamma_nsp_nf2(N, sx_cache) - + gps.gamma_ps_nf2(N, sx_cache) - + ggq.gamma_gq_nf2(N, sx_cache), + gnsp.gamma_nsp_nf2(N, cache, None) + + gps.gamma_ps_nf2(N, cache, None) + + ggq.gamma_gq_nf2(N, cache, None), 0, atol=3e-13, ) np.testing.assert_allclose( - ggg.gamma_gg_nf2(N, sx_cache) + gqg.gamma_qg_nf2(N, sx_cache), + ggg.gamma_gg_nf2(N, cache, None) + gqg.gamma_qg_nf2(N, cache, None), 0, atol=4e-13, ) # nf^1 part np.testing.assert_allclose( - gnsp.gamma_nsp_nf1(N, sx_cache) - + gps.gamma_ps_nf1(N, sx_cache) - + ggq.gamma_gq_nf1(N, sx_cache), + gnsp.gamma_nsp_nf1(N, cache, None) + + gps.gamma_ps_nf1(N, cache, None) + + ggq.gamma_gq_nf1(N, cache, None), 0, ) np.testing.assert_allclose( - ggg.gamma_gg_nf1(N, sx_cache) + gqg.gamma_qg_nf1(N, sx_cache), + ggg.gamma_gg_nf1(N, cache, None) + gqg.gamma_qg_nf1(N, cache, None), 0, atol=5e-11, ) # nf^0 part np.testing.assert_allclose( - gnsp.gamma_nsp_nf0(N, sx_cache) + ggq.gamma_gq_nf0(N, sx_cache), + gnsp.gamma_nsp_nf0(N, cache, None) + ggq.gamma_gq_nf0(N, cache, None), 0, atol=3e-11, ) np.testing.assert_allclose( - ggg.gamma_gg_nf0(N, sx_cache), + ggg.gamma_gg_nf0(N, cache, None), 0, atol=4e-11, ) # total - g_singlet = gamma_singlet(N, NF, sx_cache) + g_singlet = gamma_singlet(N, NF, cache, None) np.testing.assert_allclose( g_singlet[0, 0] + g_singlet[1, 0], 0, @@ -148,18 +150,18 @@ def test_non_singlet_reference_moments(): 2.90857799, ] for N in [3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0]: - sx_cache = compute_cache(N, 5, False) + cache = c.reset() idx = int((N - 3) / 2) if N != 17: np.testing.assert_allclose( - gnsm.gamma_nsm(N, NF, sx_cache), nsm_nf4_refs[idx] + gnsm.gamma_nsm(N, NF, cache, None), nsm_nf4_refs[idx] ) np.testing.assert_allclose( - gnsv.gamma_nsv(N, NF, sx_cache), nss_nf4_refs[idx] + nsm_nf4_refs[idx] + gnsv.gamma_nsv(N, NF, cache, None), nss_nf4_refs[idx] + nsm_nf4_refs[idx] ) gamma_nss = ( - gnsv.gamma_nss_nf1(N, sx_cache) * NF - + gnsv.gamma_nss_nf2(N, sx_cache) * NF**2 + gnsv.gamma_nss_nf1(N, cache, None) * NF + + gnsv.gamma_nss_nf2(N, cache, None) * NF**2 ) np.testing.assert_allclose(gamma_nss, nss_nf4_refs[idx], atol=4e-4) @@ -177,9 +179,9 @@ def test_singlet_reference_moments(): 8119.044600816003, ] for N in [2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0]: - sx_cache = compute_cache(N, 5, True) + cache = c.reset() np.testing.assert_allclose( - gnsp.gamma_nsp(N, NF, sx_cache), nsp_nf4_refs[int((N - 2) / 2)] + gnsp.gamma_nsp(N, NF, cache, None), nsp_nf4_refs[int((N - 2) / 2)] ) @@ -249,15 +251,15 @@ def deltaB3(n, sx): diff = [] ref_vals = [] for N in range(10, 51): - sx_cache = compute_cache(N, 5, not bool(N % 2)) - diff.append(gnsp.gamma_nsp_nf2(N, sx_cache) - gnsm.gamma_nsm_nf2(N, sx_cache)) - ref_vals.append(deltaB3(N, sx_cache)) + cache = c.reset() + diff.append(gnsp.gamma_nsp_nf2(N, cache, None) - gnsm.gamma_nsm_nf2(N, cache, None)) + ref_vals.append(deltaB3(N, cache, None)) np.testing.assert_allclose(diff, ref_vals, atol=5e-4) diff = [] ref_vals = [] for N in range(4, 10): - sx_cache = compute_cache(N, 5, not bool(N % 2)) - diff.append(gnsp.gamma_nsp_nf2(N, sx_cache) - gnsm.gamma_nsm_nf2(N, sx_cache)) - ref_vals.append(deltaB3(N, sx_cache)) + cache = c.reset() + diff.append(gnsp.gamma_nsp_nf2(N, cache, None) - gnsm.gamma_nsm_nf2(N, cache, None)) + ref_vals.append(deltaB3(N, cache, None)) np.testing.assert_allclose(diff, ref_vals, atol=2e-2) diff --git a/tests/ekore/harmonics/test_f_functions.py b/tests/ekore/harmonics/test_f_functions.py index 89136a9a6..adaeeed91 100644 --- a/tests/ekore/harmonics/test_f_functions.py +++ b/tests/ekore/harmonics/test_f_functions.py @@ -2,13 +2,10 @@ import numpy as np -from ekore import harmonics +from eko.constants import zeta2, zeta3, zeta4, zeta5 from ekore.harmonics import w5 +from ekore.harmonics import cache as c -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: @@ -60,26 +57,29 @@ # F19, F20,F21 are not present in that paper. def test_F9(): for N, vals in zip(testN, refvals["S41"]): - S1 = harmonics.S1(N) - S2 = harmonics.S2(N) - S3 = harmonics.S3(N) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + S3 = c.get(c.S3, cache, N, None) S41 = w5.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.S1(N) - S2 = harmonics.S2(N) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) S311 = w5.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.S1(N) - S2 = harmonics.S2(N) - S21 = harmonics.S21(N, S1, S2) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + S21 = c.get(c.S21, cache, N, None) S221 = w5.S221(N, S1, S2, S21) np.testing.assert_allclose(S221, vals, atol=1e-05) @@ -87,45 +87,49 @@ 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"]): - S1 = harmonics.S1(N) - S2 = harmonics.S2(N) - Sm1 = harmonics.Sm1(N, S1) - S21 = harmonics.S21(N, S1, S2) - Sm21 = harmonics.Sm21(N, S1, Sm1) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + Sm1 = c.get(c.Sm1, cache, N, None) + S21 = c.get(c.S21, cache, N, None) + Sm21 = c.get(c.Sm21, cache, N, None) Sm221 = w5.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.S1(N) - S2 = harmonics.S2(N) - S3 = harmonics.S3(N) - 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) - Sm21 = harmonics.Sm21(N, S1, Sm1) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + S3 = c.get(c.S3, cache, N, None) + Sm1 = c.get(c.Sm1, cache, N, None) + Sm2 = c.get(c.Sm2, cache, N, None) + Sm3 = c.get(c.Sm3, cache, N, None) + S21 = c.get(c.S21, cache, N, None) + S2m1 = c.get(c.S2m1, cache, N, None) + Sm21 = c.get(c.Sm21, cache, N, None) S21m2 = w5.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.S1(N) - S2 = harmonics.S2(N) - S3 = harmonics.S3(N) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + S3 = c.get(c.S3, cache, N, None) S2111 = w5.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.S1(N) - S2 = harmonics.S2(N) - S3 = harmonics.S3(N) - Sm1 = harmonics.Sm1(N, S1) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + S3 = c.get(c.S3, cache, N, None) + Sm1 = c.get(c.Sm1, cache, N, None) Sm2111 = w5.Sm2111(N, S1, S2, S3, Sm1) np.testing.assert_allclose(Sm2111, vals, atol=1e-05) @@ -133,9 +137,10 @@ def test_F18(): # different parametrization, less accurate def test_F19(): for N, vals in zip(testN, refvals["S23"]): - S1 = harmonics.S1(N) - S2 = harmonics.S2(N) - S3 = harmonics.S3(N) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + S3 = c.get(c.S3, cache, N, None) S23 = w5.S23(N, S1, S2, S3) np.testing.assert_allclose(S23, vals, rtol=2e-03) @@ -143,12 +148,13 @@ def test_F19(): # different parametrization, less accurate def test_F20(): for N, vals in zip(testN, refvals["Sm23"]): - S1 = harmonics.S1(N) - S2 = harmonics.S2(N) - S3 = harmonics.S3(N) - Sm3 = harmonics.Sm3(N, S3) - Sm2 = harmonics.Sm2(N, S2) - Sm1 = harmonics.Sm1(N, S1) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + S3 = c.get(c.S3, cache, N, None) + Sm3 = c.get(c.Sm3, cache, N, None) + Sm2 = c.get(c.Sm2, cache, N, None) + Sm1 = c.get(c.Sm1, cache, N, None) Sm23 = w5.Sm23(N, Sm1, Sm2, Sm3) np.testing.assert_allclose(Sm23, vals, rtol=1e-03) @@ -156,11 +162,12 @@ def test_F20(): # different parametrization, less accurate def test_F21(): for N, vals in zip(testN, refvals["S2m3"]): - S1 = harmonics.S1(N) - S2 = harmonics.S2(N) - S3 = harmonics.S3(N) - Sm3 = harmonics.Sm3(N, S3) - Sm2 = harmonics.Sm2(N, S2) - Sm1 = harmonics.Sm1(N, S1) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + S3 = c.get(c.S3, cache, N, None) + Sm3 = c.get(c.Sm3, cache, N, None) + Sm2 = c.get(c.Sm2, cache, N, None) + Sm1 = c.get(c.Sm1, cache, N, None) S2m3 = w5.S2m3(N, S2, Sm1, Sm2, Sm3) np.testing.assert_allclose(S2m3, vals, rtol=1e-03) diff --git a/tests/ekore/harmonics/test_g_functions.py b/tests/ekore/harmonics/test_g_functions.py index b6a895e6e..3d1851ab5 100644 --- a/tests/ekore/harmonics/test_g_functions.py +++ b/tests/ekore/harmonics/test_g_functions.py @@ -4,8 +4,6 @@ from ekore import harmonics as h -zeta3 = h.constants.zeta3 -log2 = h.constants.log2 # Reference values comes form Mathematica, and are diff --git a/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_n3lo.py b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_n3lo.py index eed992f3d..2408f6ec5 100644 --- a/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_n3lo.py +++ b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_n3lo.py @@ -1,9 +1,9 @@ # Test N3LO OME import numpy as np -from ekore.harmonics import compute_cache from ekore.operator_matrix_elements.unpolarized.space_like import as3 from ekore.operator_matrix_elements.unpolarized.space_like.as3 import A_ns, A_qqNS, A_singlet +from ekore.harmonics import cache as c def test_A_3(): @@ -12,15 +12,15 @@ def test_A_3(): for L in logs: N = 1.0 - sx_cache = compute_cache(N, 5, False) - aNSqq3 = A_qqNS(N, sx_cache, nf, L) + cache = c.reset() + aNSqq3 = A_qqNS(N, nf, L, cache, None) # quark number conservation # the accuracy of this test depends directly on the precision of the # fitted part of aNSqq3 np.testing.assert_allclose(aNSqq3, 0.0, atol=5e-5) N = 2.0 - sx_cache = compute_cache(N, 5, True) + cache = c.reset() # reference value comes form Mathematica, Hg is not fully complete # thus the reference value is not 0.0 but 145.14813631128334. # Here we have imposed a small shift in A_Hgstfac such that @@ -28,9 +28,9 @@ def test_A_3(): # The accuracy of this test depends on the approximation of AggTF2. atol = 2e-4 if L == 0 else 2e-3 np.testing.assert_allclose( - as3.A_gg(N, sx_cache, nf, L) - + as3.A_qg(N, sx_cache, nf, L) - + as3.A_Hg(N, sx_cache, nf, L), + as3.A_gg(N, nf, L, cache, None) + + as3.A_qg(N, nf, L, cache, None) + + as3.A_Hg(N, nf, L, cache, None), 0, atol=atol, ) @@ -45,27 +45,26 @@ def test_A_3(): eps = 1e-6 atol = 2e-5 N = 2.0 + eps - sx_cache = compute_cache(N, 5, True) + cache = c.reset() np.testing.assert_allclose( - as3.A_gq(N, sx_cache, nf, L) - + as3.A_qqNS(N, sx_cache, nf, L) - + as3.A_qqPS(N, sx_cache, nf, L) - + as3.A_Hq(N, sx_cache, nf, L), + as3.A_gq(N, nf, L, cache, None) + + as3.A_qqNS(N, nf, L, cache, None) + + as3.A_qqPS(N, nf, L, cache, None) + + as3.A_Hq(N, nf, L, cache, None), 0, atol=atol, ) N = 3 + 2j - sx_cache = compute_cache(np.random.rand(), 5, True) - ns_sx_cache = compute_cache(np.random.rand(), 5, False) - aS3 = A_singlet(N, sx_cache, ns_sx_cache, nf, L) - aNS3 = A_ns(N, ns_sx_cache, nf, L) + cache = c.reset() + aS3 = A_singlet(N, nf, L, cache) + aNS3 = A_ns(N, nf, L, cache, None) 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)) + np.testing.assert_allclose(aNS3[0, 0], as3.A_qqNS(N, nf, L, cache, None)) def test_Blumlein_3(): @@ -151,9 +150,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_cache = compute_cache(N, 5, True) - ns_sx_cache = compute_cache(N, 5, False) - aS3 = A_singlet(N, sx_cache, ns_sx_cache, nf, L) + cache = c.reset() + aS3 = A_singlet(N, nf, L, cache) np.testing.assert_allclose( aS3[0, 0], ref_val_gg[L][idx] + ref_val_ggTF2[L][idx], rtol=3e-6 @@ -179,11 +177,11 @@ def test_Blumlein_3(): # Here we test the critical parts for idx, N in enumerate([2.0, 4.0, 6.0, 10.0, 100.0]): - sx_cache = compute_cache(N, 5, True) - Aggtf2 = as3.aggTF2.A_ggTF2(N, sx_cache) + cache = c.reset() + Aggtf2 = as3.aggTF2.A_ggTF2(N, cache, None) np.testing.assert_allclose(Aggtf2, ref_val_ggTF2[0][idx], rtol=3e-6) np.testing.assert_allclose( - as3.agg.A_gg(N, sx_cache, nf, L=0) - Aggtf2, + as3.agg.A_gg(N, nf, 0, cache, None) - Aggtf2, ref_val_gg[0][idx], rtol=3e-6, ) @@ -191,9 +189,9 @@ def test_Blumlein_3(): # odd numbers of qqNS 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_cache(N, 5, False) + cache = c.reset() np.testing.assert_allclose( - as3.aqqNS.A_qqNS(N, sx_cache, nf, L=0), ref, rtol=1e-4 + as3.aqqNS.A_qqNS(N, nf, 0, cache, None), ref, rtol=1e-4 ) @@ -245,7 +243,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_cache(N, 5, True) + cache = c.reset() np.testing.assert_allclose( - as3.aHq.A_Hq(N, sx_cache, nf, L=0), r, rtol=7e-6, atol=1e-5 + as3.aHq.A_Hq(N, nf, 0, cache, None), r, rtol=7e-6, atol=1e-5 ) diff --git a/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nlo.py b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nlo.py index 953d797c7..66daa4f88 100644 --- a/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nlo.py +++ b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nlo.py @@ -1,16 +1,16 @@ # Test NLO OME import numpy as np -from ekore.harmonics import compute_cache from ekore.operator_matrix_elements.unpolarized.space_like.as1 import A_ns, A_singlet +from ekore.harmonics import cache as c def test_A_1_intrinsic(): + cache = c.reset() L = 100.0 N = 2 - sx = compute_cache(N, 2, True) - aS1 = A_singlet(N, sx, L) + aS1 = A_singlet(N, L, cache, None) # heavy quark momentum conservation np.testing.assert_allclose(aS1[0, 2] + aS1[1, 2] + aS1[2, 2], 0.0, atol=1e-10) @@ -20,11 +20,11 @@ def test_A_1_intrinsic(): def test_A_1_shape(): + cache = c.reset() N = 2 L = 3.0 - sx = compute_cache(N, 2, (-1) ** N == 1) - aNS1i = A_ns(N, sx, L) - aS1i = A_singlet(N, sx, L) + aNS1i = A_ns(N, L, cache, None) + aS1i = A_singlet(N, L, cache, None) assert aNS1i.shape == (2, 2) assert aS1i.shape == (3, 3) @@ -46,8 +46,8 @@ def test_Blumlein_1(): for n in range(N_vals): N = 2 * n + 2 - sx = compute_cache(N, 2, True) + cache = c.reset() for L, ref_gg in ref_val_gg.items(): - aS1 = A_singlet(N, sx, L) + aS1 = A_singlet(N, L, cache, None) np.testing.assert_allclose(aS1[0, 0], ref_gg[n], rtol=1e-6) np.testing.assert_allclose(aS1[2, 0], ref_val_Hg[L][n], rtol=3e-6) diff --git a/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nnlo.py b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nnlo.py index 648568d1c..46ffab46f 100644 --- a/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nnlo.py +++ b/tests/ekore/operator_matrix_elements/unpolarized/space_like/test_nnlo.py @@ -2,8 +2,9 @@ import numpy as np -from ekore.harmonics import compute_cache, constants +from eko import constants from ekore.operator_matrix_elements.unpolarized.space_like.as2 import A_ns, A_qq_ns, A_singlet +from ekore.harmonics import cache as c def test_A_2(): @@ -11,21 +12,20 @@ def test_A_2(): for L in logs: N = 1 - sx = compute_cache(N, 3, False) - aNSqq2 = A_qq_ns(N, sx, L) + cache = c.reset() + aNSqq2 = A_qq_ns(N, L, cache, None) # quark number conservation np.testing.assert_allclose(aNSqq2, 0.0, atol=2e-11) N = 2 - sx = compute_cache(N, 3, True) - aS2 = A_singlet(N, sx, L) + aS2 = A_singlet(N, L, cache, None) # gluon momentum conservation np.testing.assert_allclose(aS2[0, 0] + aS2[1, 0] + aS2[2, 0], 0.0, atol=2e-6) # quark momentum conservation np.testing.assert_allclose(aS2[0, 1] + aS2[1, 1] + aS2[2, 1], 0.0, atol=1e-11) - aNS2 = A_ns(N, sx, L) + aNS2 = A_ns(N, L, cache, False) assert aNS2.shape == (2, 2) assert aS2.shape == (3, 3) @@ -37,9 +37,9 @@ def test_A_2(): def test_A_2_shape(): N = np.random.rand() L = 3 - sx = compute_cache(N, 3, (-1) ** N == 1) - aNS2 = A_ns(N, sx, L) - aS2 = A_singlet(N, sx, L) + cache = c.reset() + aNS2 = A_ns(N, L, cache, False) + aS2 = A_singlet(N, L, cache, None) assert aNS2.shape == (2, 2) assert aS2.shape == (3, 3) @@ -53,9 +53,9 @@ def test_pegasus_sign(): # reference value come from Pegasus code transalted Mathematica ref_val = -21133.9 N = 2 - sx = compute_cache(N, 3, True) L = 100.0 - aS2 = A_singlet(N, sx, L) + cache = c.reset() + aS2 = A_singlet(N, L, cache, None) np.testing.assert_allclose(aS2[0, 0], ref_val, rtol=4e-5) @@ -117,9 +117,9 @@ def test_Blumlein_2(): ], } for N in range(2, 11): + cache = c.reset() for L, ref_Hg in ref_val_Hg.items(): - sx = compute_cache(N, 3, True) - aS2 = A_singlet(N, sx, L) + aS2 = A_singlet(N, L, cache, None) if N % 2 == 0: idx = int(N / 2 - 1) np.testing.assert_allclose(aS2[0, 0], ref_val_gg[L][idx], rtol=2e-6) @@ -136,11 +136,11 @@ def test_Hg2_pegasus(): L = 0 for N in range(3, 20): - sx = compute_cache(N, 3, True) - S1 = sx[0][0] - S2 = sx[1][0] - S3 = sx[2][0] - aS2 = A_singlet(N, sx, L) + cache = c.reset() + S1 = c.get(c.S1, cache, N, None) + S2 = c.get(c.S2, cache, N, None) + S3 = c.get(c.S3, cache, N, None) + aS2 = A_singlet(N, L, cache, None) E2 = ( 2.0 / N * (constants.zeta3 - S3 + 1.0 / N * (constants.zeta2 - S2 - S1 / N)) @@ -168,7 +168,7 @@ def test_msbar_matching(): for L in logs: N = 2 - sx = compute_cache(N, 3, True) - aS2 = A_singlet(N, sx, L, True) + cache = c.reset() + aS2 = A_singlet(N, L, cache, None, True) # gluon momentum conservation np.testing.assert_allclose(aS2[0, 0] + aS2[1, 0] + aS2[2, 0], 0.0, atol=2e-6)