The problem
In order to compute the singlet operators eko needs four elements: S_qq, S_qg, S_gq, S_gg (in get_ker(k, l) only the k, l element is provided).
These elements will depend on the anomalous dimensions, but in order to compute each of them all the 4 anomalous dimensions should be evaluated, cf. get_gamma_singlet_0, called by get_Eigensystem_gamma_singlet_0.
But since the eigenvalue decomposition has to be performed N by N (Mellin) is not possible to integrate before the 4 anomalous dimensions and then rotate to the operators, but the single evaluation for a specific N will involve the decomposition, and so the calculation of all of the 4 anomalous dimensions.
What is happening so is that for a given N the anomalous dimensions are evaluated every time for each of the 4 integration of S_qq, S_qg, S_gq, S_gg, and in the integration process evaluating the integrand will take most of the time (almost the total amount, we believe).
A significant improvement would be integrate simultaneously the four elements, indeed when the singlet-gluon sector is relevant (in fact: always) all of the four elements are needed, and in this way all of the four elements produced by get_Eigensystem_gamma_singlet_0 are used, instead of taking one and discarding 3 every time.
Considering also the time required for the non-singlet calculation this will lead to a speed up naïvely estimated by a factor of 3.4=(4*4+1)/(4+1), independently of the complexity of the kernel (LO, NLO, NNLO, ... with whatever method used).
Naïve meaning
If not any other error is present at least this estimate is rough mainly because of the different complexity of the integration of the different elements.
Indeed if any relevant cancellation will smooth some of the elements the convergence will be much faster than for the other elements, because less evaluation are needed.
However in the worst case there is no gain and no loss in performance, since the time is spent mostly in integrating the most complex element, but all the evaluation done are already done by the current implementation, and in this way the other 3 entries will be used to improve the precision of the simplest elements.
Useless solution
scipy.integrate subpackage has a function called scipy.integrate.quad_vec, but it is currently implemented in python (while scipy.integrate.quad currently used is a binding for QUADPACK fortran implementation).
Since the latter is compiled switching to quad_vec it is likely to have no performance benefit.
Proposed solutions
- drop
scipy.integrate.quad and fall back to a sum
- this will reduce the speed up, but it is quick to implement and benchmark
- implement
scipy.integrate.quad_vec in a C/Fortran compiled module of eko
- this will get the theoretical speed up, but we will increase the complexity of package management (so we will loose in development time)
- implement
scipy.integrate.quad_vec in a numba compiled function, inside eko
- in principle can obtain the same speed of the former, but it will be easier to manage and distribute
- implement
scipy.integrate.quad_vec in C/Fortran and pull request into scipy
- slower development for the function itself (not familiar environment, external people slighlty involved), optimal solution for not polluting
eko and keeping the delegation to an external utility
The problem
In order to compute the singlet operators
ekoneeds four elements:S_qq,S_qg,S_gq,S_gg(inget_ker(k, l)only thek, lelement is provided).These elements will depend on the anomalous dimensions, but in order to compute each of them all the 4 anomalous dimensions should be evaluated, cf.
get_gamma_singlet_0, called byget_Eigensystem_gamma_singlet_0.But since the eigenvalue decomposition has to be performed
NbyN(Mellin) is not possible to integrate before the 4 anomalous dimensions and then rotate to the operators, but the single evaluation for a specificNwill involve the decomposition, and so the calculation of all of the 4 anomalous dimensions.What is happening so is that for a given
Nthe anomalous dimensions are evaluated every time for each of the 4 integration ofS_qq,S_qg,S_gq,S_gg, and in the integration process evaluating the integrand will take most of the time (almost the total amount, we believe).A significant improvement would be integrate simultaneously the four elements, indeed when the singlet-gluon sector is relevant (in fact: always) all of the four elements are needed, and in this way all of the four elements produced by
get_Eigensystem_gamma_singlet_0are used, instead of taking one and discarding 3 every time.Considering also the time required for the non-singlet calculation this will lead to a speed up naïvely estimated by a factor of 3.4=(4*4+1)/(4+1), independently of the complexity of the kernel (LO, NLO, NNLO, ... with whatever method used).
Useless solution
scipy.integratesubpackage has a function calledscipy.integrate.quad_vec, but it is currently implemented in python (whilescipy.integrate.quadcurrently used is a binding for QUADPACK fortran implementation).Since the latter is compiled switching to
quad_vecit is likely to have no performance benefit.Proposed solutions
scipy.integrate.quadand fall back to a sumscipy.integrate.quad_vecin a C/Fortran compiled module ofekoscipy.integrate.quad_vecin anumbacompiled function, insideekoscipy.integrate.quad_vecin C/Fortran and pull request intoscipyekoand keeping the delegation to an external utility