From 275ed5562248b3515d166fbf222e6c2283f248cd Mon Sep 17 00:00:00 2001 From: niccolo Date: Wed, 24 Apr 2024 18:27:40 +0200 Subject: [PATCH] Implement analytic convolution of Pgg0 x Pgg0 --- inc/adani/ApproximateCoefficientFunction.h | 6 +- inc/adani/ExactCoefficientFunction.h | 4 +- inc/adani/SplittingFunction.h | 31 +++- pywrap/pywrap.cc | 12 +- src/ApproximateCoefficientFunction.cc | 16 ++- src/ExactCoefficientFunction.cc | 13 +- src/SplittingFunction.cc | 158 ++++++++++++++++++++- 7 files changed, 208 insertions(+), 32 deletions(-) diff --git a/inc/adani/ApproximateCoefficientFunction.h b/inc/adani/ApproximateCoefficientFunction.h index 93c0bcd..ed71e59 100644 --- a/inc/adani/ApproximateCoefficientFunction.h +++ b/inc/adani/ApproximateCoefficientFunction.h @@ -64,7 +64,7 @@ class AbstractApproximate : public CoefficientFunction { AbstractApproximate( const int &order, const char &kind, const char &channel, const double &abserr = 1e-3, const double &relerr = 1e-3, - const int &dim = 1000, const bool &MCintegral = false, + const int &dim = 1000, const bool &analytical_PggxPgg = true, const bool &MCintegral = false, const int &MCcalls = 25000 ); ~AbstractApproximate(); @@ -91,7 +91,7 @@ class ApproximateCoefficientFunction : public AbstractApproximate { const int &order, const char &kind, const char &channel, const bool &NLL = true, const string &highscale_version = "klmv", const double &abserr = 1e-3, const double &relerr = 1e-3, - const int &dim = 1000, const bool &MCintegral = false, + const int &dim = 1000, const bool &analytical_PggxPgg = true, const bool &MCintegral = false, const int &MCcalls = 25000 ); ~ApproximateCoefficientFunction() override; @@ -124,7 +124,7 @@ class ApproximateCoefficientFunctionKLMV : public AbstractApproximate { const int &order, const char &kind, const char &channel, const string &highscale_version = "klmv", const bool &lowxi = false, const double &abserr = 1e-3, const double &relerr = 1e-3, - const int &dim = 1000, const bool &MCintegral = false, + const int &dim = 1000, const bool &analytical_PggxPgg = true, const bool &MCintegral = false, const int &MCcalls = 25000 ); ~ApproximateCoefficientFunctionKLMV() override; diff --git a/inc/adani/ExactCoefficientFunction.h b/inc/adani/ExactCoefficientFunction.h index d43dd1b..74404bd 100644 --- a/inc/adani/ExactCoefficientFunction.h +++ b/inc/adani/ExactCoefficientFunction.h @@ -41,7 +41,8 @@ class ExactCoefficientFunction : public CoefficientFunction { ExactCoefficientFunction( const int &order, const char &kind, const char &channel, const double &abserr = 1e-3, const double &relerr = 1e-3, - const int &dim = 1000, const bool &MCintegral = false, + const int &dim = 1000, const bool &analytical_PggxPgg = true, + const bool &MCintegral = false, const int &MCcalls = 25000 ); ~ExactCoefficientFunction() override; @@ -84,6 +85,7 @@ class ExactCoefficientFunction : public CoefficientFunction { SplittingFunction *Pgg1_; SplittingFunction *Pqg0_; ConvolutedSplittingFunctions *Pgq0Pqg0_; + ConvolutedSplittingFunctions * Pgg0Pgg0_; Delta *delta_; diff --git a/inc/adani/SplittingFunction.h b/inc/adani/SplittingFunction.h index 8fe3e01..96624d7 100644 --- a/inc/adani/SplittingFunction.h +++ b/inc/adani/SplittingFunction.h @@ -140,7 +140,7 @@ class ConvolutedSplittingFunctions : public AbstractSplittingFunction { const int &order1, const char &entry1, const char &entry2, const int &order2, const char &entry3, const char &entry4 ); - ~ConvolutedSplittingFunctions() override{}; + ~ConvolutedSplittingFunctions() override; // overloading operators ConvolutedSplittingFunctions operator*(const double &rhs) const; @@ -151,12 +151,10 @@ class ConvolutedSplittingFunctions : public AbstractSplittingFunction { // Components of the Convoluted Splitting Function double Regular(double x, int nf) const override; - double Singular(double /*x*/, int /*nf*/) const override { return 0.; }; - double Local(int /*nf*/) const override { return 0.; }; + double Singular(double x, int nf) const override ; + double Local(int nf) const override ; // Integral from 0 to x of the Singular part - double SingularIntegrated(double /*x*/, int /*nf*/) const override { - return 0.; - }; + double SingularIntegrated(double x, int nf) const override ; void SetFunctions(); @@ -177,6 +175,11 @@ class ConvolutedSplittingFunctions : public AbstractSplittingFunction { const char entry4_; double (ConvolutedSplittingFunctions::*reg_)(double, int) const; + double (ConvolutedSplittingFunctions::*sing_)(double, int) const; + double (ConvolutedSplittingFunctions::*sing_int_)(double, int) const; + double (ConvolutedSplittingFunctions::*loc_)(int) const; + + SplittingFunction* Pgg0_ ; //==========================================================================================// // Convolution between the splitting functions Pgg0/Pqq0 @@ -192,6 +195,22 @@ class ConvolutedSplittingFunctions : public AbstractSplittingFunction { double Pgq0_x_Pqg0(double x, int nf) const; + //==========================================================================================// + // Convolution between the splitting functions Pgg0 and Pgg0 + //------------------------------------------------------------------------------------------// + + double Pgg0reg_x_Pgg0reg(double x) const; + double Pgg0reg_x_Pgg0sing(double x) const; + double Pgg0sing_x_Pgg0sing_reg(double x) const; + double Pgg0sing_x_Pgg0sing_sing(double x) const; + double Pgg0sing_x_Pgg0sing_sing_integrated(double x) const; + double Pgg0sing_x_Pgg0sing_loc() const; + + double Pgg0_x_Pgg0_reg(double x, int nf) const; + double Pgg0_x_Pgg0_sing(double x, int nf) const; + double Pgg0_x_Pgg0_sing_integrated(double x, int nf) const; + double Pgg0_x_Pgg0_loc(int nf) const; + //==========================================================================================// // Function needed to return a zero function //------------------------------------------------------------------------------------------// diff --git a/pywrap/pywrap.cc b/pywrap/pywrap.cc index 082064d..07de9ca 100644 --- a/pywrap/pywrap.cc +++ b/pywrap/pywrap.cc @@ -56,11 +56,11 @@ PYBIND11_MODULE(_core, m) { py::init< const int &, const char &, const char &, const bool &, const string &, const double &, const double &, const int &, - const bool &, const int &>(), + const bool &, const bool &, const int &>(), py::arg("order"), py::arg("kind"), py::arg("channel"), py::arg("NLL") = true, py::arg("highscale_version") = "klmv", py::arg("abserr") = 1e-3, py::arg("relerr") = 1e-3, - py::arg("dim") = 1000, py::arg("MCintegral") = false, + py::arg("dim") = 1000, py::arg("analytical_PggxPgg") = true, py::arg("MCintegral") = false, py::arg("MCcalls") = 25000 ) .def( @@ -100,11 +100,11 @@ PYBIND11_MODULE(_core, m) { py::init< const int &, const char &, const char &, const string &, const bool &, const double &, const double &, const int &, - const bool &, const int &>(), + const bool &, const bool &, const int &>(), py::arg("order"), py::arg("kind"), py::arg("channel"), py::arg("highscale_version") = "klmv", py::arg("lowxi") = false, py::arg("abserr") = 1e-3, py::arg("relerr") = 1e-3, - py::arg("dim") = 1000, py::arg("MCintegral") = false, + py::arg("dim") = 1000, py::arg("analytical_PggxPgg") = true, py::arg("MCintegral") = false, py::arg("MCcalls") = 25000 ) .def( @@ -183,10 +183,10 @@ PYBIND11_MODULE(_core, m) { .def( py::init< const int &, const char &, const char &, const double &, - const double &, const int &, const bool &, const int &>(), + const double &, const int &, const bool &, const bool &, const int &>(), py::arg("order"), py::arg("kind"), py::arg("channel"), py::arg("abserr") = 1e-3, py::arg("relerr") = 1e-3, - py::arg("dim") = 1000, py::arg("MCintegral") = false, + py::arg("dim") = 1000, py::arg("analytical_PggxPgg") = true, py::arg("MCintegral") = false, py::arg("MCcalls") = 25000 ) .def( diff --git a/src/ApproximateCoefficientFunction.cc b/src/ApproximateCoefficientFunction.cc index 2310e33..1571751 100644 --- a/src/ApproximateCoefficientFunction.cc +++ b/src/ApproximateCoefficientFunction.cc @@ -19,13 +19,13 @@ using std::vector; AbstractApproximate::AbstractApproximate( const int &order, const char &kind, const char &channel, - const double &abserr, const double &relerr, const int &dim, + const double &abserr, const double &relerr, const int &dim, const bool &analytical_PggxPgg, const bool &MCintegral, const int &MCcalls ) : CoefficientFunction(order, kind, channel) { muterms_ = new ExactCoefficientFunction( - order, kind, channel, abserr, relerr, dim, MCintegral, MCcalls + order, kind, channel, abserr, relerr, dim, analytical_PggxPgg, MCintegral, MCcalls ); } @@ -35,6 +35,10 @@ AbstractApproximate::AbstractApproximate( AbstractApproximate::~AbstractApproximate() { delete muterms_; } +//==========================================================================================// +// AbstractApproximate: central value of the mu-independent terms +//------------------------------------------------------------------------------------------// + double AbstractApproximate::MuIndependentTerms( double x, double m2Q2, int nf ) const { @@ -96,10 +100,10 @@ struct variation_parameters CL_var = { 0.2, 2. }; ApproximateCoefficientFunction::ApproximateCoefficientFunction( const int &order, const char &kind, const char &channel, const bool &NLL, const string &highscale_version, const double &abserr, const double &relerr, - const int &dim, const bool &MCintegral, const int &MCcalls + const int &dim, const bool &analytical_PggxPgg, const bool &MCintegral, const int &MCcalls ) : AbstractApproximate( - order, kind, channel, abserr, relerr, dim, MCintegral, MCcalls + order, kind, channel, abserr, relerr, dim, analytical_PggxPgg, MCintegral, MCcalls ) { threshold_ = new ThresholdCoefficientFunction(order, kind, channel); @@ -262,11 +266,11 @@ struct klmv_params klmv_C2g3B_lowxi = { 0.8, 10.7, 0.055125, 2, 0.3825 }; ApproximateCoefficientFunctionKLMV::ApproximateCoefficientFunctionKLMV( const int &order, const char &kind, const char &channel, const string &highscale_version, const bool &lowxi, const double &abserr, - const double &relerr, const int &dim, const bool &MCintegral, + const double &relerr, const int &dim, const bool &analytical_PggxPgg, const bool &MCintegral, const int &MCcalls ) : AbstractApproximate( - order, kind, channel, abserr, relerr, dim, MCintegral, MCcalls + order, kind, channel, abserr, relerr, dim, analytical_PggxPgg, MCintegral, MCcalls ) { if (GetOrder() == 1) { cout << "Error: KLMV approximation is not implemented at O(as)!" diff --git a/src/ExactCoefficientFunction.cc b/src/ExactCoefficientFunction.cc index 3a6a81e..d9529f7 100644 --- a/src/ExactCoefficientFunction.cc +++ b/src/ExactCoefficientFunction.cc @@ -15,7 +15,7 @@ using std::endl; ExactCoefficientFunction::ExactCoefficientFunction( const int &order, const char &kind, const char &channel, - const double &abserr, const double &relerr, const int &dim, + const double &abserr, const double &relerr, const int &dim, const bool &analytical_PggxPgg, const bool &MCintegral, const int &MCcalls ) : CoefficientFunction(order, kind, channel) { @@ -33,6 +33,7 @@ ExactCoefficientFunction::ExactCoefficientFunction( Pgg1_ = nullptr; Pqg0_ = nullptr; Pgq0Pqg0_ = nullptr; + Pgg0Pgg0_ = nullptr; delta_ = nullptr; @@ -110,9 +111,13 @@ ExactCoefficientFunction::ExactCoefficientFunction( ); convolutions_lmu1_.push_back(new Convolution(gluon_as2_, delta_)); - convolutions_lmu2_.push_back(new DoubleConvolution( - gluon_as1_, Pgg0_, abserr, relerr, dim, MCintegral, MCcalls - )); + if (!analytical_PggxPgg) { + convolutions_lmu2_.push_back(new DoubleConvolution( + gluon_as1_, Pgg0_, abserr, relerr, dim, MCintegral, MCcalls + )); + } else { + convolutions_lmu2_.push_back(new Convolution(gluon_as1_, Pgg0Pgg0_, abserr, relerr, dim)); + } convolutions_lmu2_.push_back( new Convolution(gluon_as1_, Pgq0Pqg0_, abserr, relerr, dim) ); diff --git a/src/SplittingFunction.cc b/src/SplittingFunction.cc index 9257601..394b3e5 100644 --- a/src/SplittingFunction.cc +++ b/src/SplittingFunction.cc @@ -231,9 +231,20 @@ ConvolutedSplittingFunctions::ConvolutedSplittingFunctions( exit(-1); } + if (order1_ == 0 && entry1_ == 'g' && entry2_ == 'g' && order2_ == 0 && entry3_ == 'g' && entry4_ == 'g') { + Pgg0_ = new SplittingFunction(0, 'g', 'g'); + } else { + Pgg0_ = nullptr; + } + SetFunctions(); } +ConvolutedSplittingFunctions::~ConvolutedSplittingFunctions() { + + delete Pgg0_; +} + //==========================================================================================// // ConvolutedSplittingFunctions: regular part //------------------------------------------------------------------------------------------// @@ -242,6 +253,30 @@ double ConvolutedSplittingFunctions::Regular(double x, int nf) const { return GetMultFact() * (this->*reg_)(x, nf); } +//==========================================================================================// +// ConvolutedSplittingFunctions: singular part +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Singular(double x, int nf) const { + return GetMultFact() * (this->*sing_)(x, nf); +} + +//==========================================================================================// +// ConvolutedSplittingFunctions: integral from 0 to x of the singular part +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::SingularIntegrated(double x, int nf) const { + return GetMultFact() * (this->*sing_int_)(x, nf); +} + +//==========================================================================================// +// ConvolutedSplittingFunctions: local part +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Local(int nf) const { + return GetMultFact() * (this->*loc_)(nf); +} + //==========================================================================================// // ConvolutedSplittingFunctions: overload of operator * double //------------------------------------------------------------------------------------------// @@ -291,15 +326,30 @@ void ConvolutedSplittingFunctions::SetFunctions() { if (order1_ == 0 && order2_ == 0) { if (entry1_ == 'g' && entry2_ == 'q' && entry3_ == 'q' - && entry4_ == 'g') + && entry4_ == 'g') { reg_ = &ConvolutedSplittingFunctions::Pgq0_x_Pqg0; - else if (entry1_ == 'g' && entry2_ == 'g' && entry3_ == 'g' - && entry4_ == 'q') + sing_ = &ConvolutedSplittingFunctions::ZeroFunction_x_nf; + sing_int_ = &ConvolutedSplittingFunctions::ZeroFunction_x_nf; + loc_ = &ConvolutedSplittingFunctions::ZeroFunction_nf; + } else if (entry1_ == 'g' && entry2_ == 'g' && entry3_ == 'g' + && entry4_ == 'q') { reg_ = &ConvolutedSplittingFunctions::Pgg0_x_Pgq0; - else if (entry1_ == 'q' && entry2_ == 'q' && entry3_ == 'g' - && entry4_ == 'q') + sing_ = &ConvolutedSplittingFunctions::ZeroFunction_x_nf; + sing_int_ = &ConvolutedSplittingFunctions::ZeroFunction_x_nf; + loc_ = &ConvolutedSplittingFunctions::ZeroFunction_nf; + } else if (entry1_ == 'q' && entry2_ == 'q' && entry3_ == 'g' + && entry4_ == 'q') { reg_ = &ConvolutedSplittingFunctions::Pqq0_x_Pgq0; - else { + sing_ = &ConvolutedSplittingFunctions::ZeroFunction_x_nf; + sing_int_ = &ConvolutedSplittingFunctions::ZeroFunction_x_nf; + loc_ = &ConvolutedSplittingFunctions::ZeroFunction_nf; + } else if (entry1_ == 'g' && entry2_ == 'g' && entry3_ == 'g' + && entry4_ == 'g') { + reg_ = &ConvolutedSplittingFunctions::Pgg0_x_Pgg0_reg; + sing_ = &ConvolutedSplittingFunctions::Pgg0_x_Pgg0_sing; + sing_int_ = &ConvolutedSplittingFunctions::Pgg0_x_Pgg0_sing_integrated; + loc_ = &ConvolutedSplittingFunctions::Pgg0_x_Pgg0_loc; + } else { cout << "Error: P" << entry1_ << entry2_ << order1_ << " x P" << entry3_ << entry4_ << order2_ << " is not implemented!" << endl; @@ -627,3 +677,99 @@ double ConvolutedSplittingFunctions::Pgq0_x_Pqg0(double x, int nf) const { return 4. * CF * nf * (1. + 4. / 3 / x - x - 4. * x * x / 3 + 2. * (1 + x) * log(x)); } + +//==========================================================================================// +// Analytical convolution between the splitting functions Pgq0 and Pqg0 +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0reg_x_Pgg0reg(double x) const { + + return 16 * CA * CA *((-1. + x) * (11. + x * (5. + 2. * x)) - 3. * (1. + x * (4. + x + x * x)) * log(x)) / (3. * x); +} + +//==========================================================================================// +// Analytical convolution between the splitting functions Pgg0reg and Pgg0sing +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0reg_x_Pgg0sing(double x) const { + + return 16. * CA * CA * (0.5 * (1. - 4. * x + 3. * x * x) + (-2. + 1. / x + x - x * x) * log(1. - x) + (2. - x + x * x) * log(x)); +} + +//==========================================================================================// +// Analytical convolution between the splitting functions Pgg0reg and Pgg0sing +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0sing_x_Pgg0sing_reg(double x) const { + + return - 16 * CA * CA * log(x) / (1. - x); +} + +//==========================================================================================// +// Analytical convolution between the splitting functions Pgg0reg and Pgg0sing +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0sing_x_Pgg0sing_sing(double x) const { + + return 16 * CA * CA * 2. * log(1. - x) / (1. - x); +} + +//==========================================================================================// +// Analytical convolution between the splitting functions Pgg0reg and Pgg0sing +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0sing_x_Pgg0sing_sing_integrated(double x) const { + + double L1 = log(1. - x); + return - 16. * CA * CA * L1 * L1 ; +} + +//==========================================================================================// +// Analytical convolution between the splitting functions Pgg0reg and Pgg0sing +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0sing_x_Pgg0sing_loc() const { + + return - 16 * CA * CA * zeta2; +} + +//==========================================================================================// +// Regular part of the analytical convolution between the splitting functions Pgg0 and Pgg0 +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0_x_Pgg0_reg(double x, int nf) const { + + return Pgg0reg_x_Pgg0reg(x) + + 2 * Pgg0reg_x_Pgg0sing(x) + + 2 * Pgg0_ -> Regular(x, nf) * Pgg0_ -> Local(nf) + + Pgg0sing_x_Pgg0sing_reg(x); +} + +//==========================================================================================// +// Regular part of the analytical convolution between the splitting functions Pgg0 and Pgg0 +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0_x_Pgg0_sing(double x, int nf) const { + + return Pgg0sing_x_Pgg0sing_sing(x) + + 2 * Pgg0_ -> Singular(x, nf) * Pgg0_ -> Local(nf); +} + +//==========================================================================================// +// Regular part of the analytical convolution between the splitting functions Pgg0 and Pgg0 +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0_x_Pgg0_sing_integrated(double x, int nf) const { + + return Pgg0sing_x_Pgg0sing_sing_integrated(x) + + 2 * Pgg0_ -> SingularIntegrated(x, nf) * Pgg0_ -> Local(nf); +} + +//==========================================================================================// +// Regular part of the analytical convolution between the splitting functions Pgg0 and Pgg0 +//------------------------------------------------------------------------------------------// + +double ConvolutedSplittingFunctions::Pgg0_x_Pgg0_loc(int nf) const { + + return Pgg0sing_x_Pgg0sing_loc() + Pgg0_ -> Local(nf); +}