PentagonFunctions-cpp (external)

The content on this page was written by AI under human supervision.

PentagonFunctions-cpp (upstream name PentagonFunctions++) is public C++ software by D. Chicherin, V. Sotnikov and S. Zoia that evaluates pentagon functions numerically. Given a kinematic point and a list of functions, it returns their complex values in double, quadruple or octuple precision. BootLoops builds it from the released source without changes and uses it as an independent reference evaluator. A two-loop five-point quantity computed with BootLoops' own tools must reproduce this library's value at a test point before it is accepted. It never supplies input to a BootLoops fit or derivation.

What it does

Two-loop scattering amplitudes for five particles (all massless, or four massless and one massive) can be written as rational coefficients times a fixed, finite set of special functions, the pentagon functionsthe transcendental functions of weight 1 to 4 in which every two-loop five-point master integral for these kinematics can be expressed. The library evaluates those functions at a given point. Three sets can be enabled at build time: fully massless kinematics (m0), one external mass in a 2→3 production channel (m1, planar and non-planar), and one external mass in a 1→4 decay channel (m1_decay).

The input point is the list of adjacent two-particle Mandelstam invariants$s_{ij}=(p_i+p_j)^2$ for neighboring external momenta; five numbers for massless kinematics, six for the one-mass sets, where the first entry is the squared mass $p_1^2$, each divided by the squared dimensional-regularization scale so that they are dimensionless and, ideally, of order one. A function is addressed by its weight and one or two labels; the output is one complex number per function. Weights 1 and 2 are computed from closed expressions in logarithms and dilogarithms, weights 3 and 4 by a one-dimensional numerical integration whose default tolerance is no larger than the rounding error of the number type.

Number types are double and, in a build with the high-precision option, qd's dd_real (about 32 digits) and qd_real (about 64 digits). Results are numerical values at working precision, without a proven error bound. At the test suite's one-mass reference point, BootLoops compared eight functions of weights 1 to 4 with the 70-digit values stored there and found agreement to 13–17 digits in double, 29–31 in dd_real and 60–65 in qd_real. Expect roughly that from each type.

The library has limits. Functions are evaluated only in the physical scattering region defined in the papers and take Mandelstam invariants only, so sign changes of parity-odd functions under parity or odd permutations are left to the user. The parity-odd normalization differs between the planar and the full one-mass papers; do not mix the two in one calculation. The library is not a general polylogarithm evaluator: it computes the sets it contains and nothing else.

Examples

Build with extended precision and run the library's tests. The build uses meson and ninja (both installable with pip); for extended precision install qd first and make it visible through PKG_CONFIG_PATH and LD_LIBRARY_PATH. Following the README:

meson setup build -D prefix=$HOME/local -D high-precision=true
cd build
ninja install
ninja test

ninja install compiles the enabled sets (over ten minutes with all three, per the README; drop one with, for example, -D m1_decay_set=disabled) and installs the headers, the shared library, PentagonFunctions.pc and a Mathematica package under the prefix. ninja test runs the library's test programs (test_w12, test_m1_w12, test_m1_full, test_m1_decay and so on, plus _HP/_VHP variants in a high-precision build), each comparing fresh evaluations with reference values in tests/targets_*.hpp and reporting pass or fail.

Evaluate massless pentagon functions in double precision. The upstream program examples/example_simple.cpp, built automatically as build/examples/example_simple, shows the whole interface. Its central lines (omissions marked // ...):

    using namespace PentagonFunctions;
    // ...
    using T = double;
    // ...
    constexpr KinType KT = KinType::m0;
    // ...
    std::vector<FunID<KT>> needed_functions = {
        {1,1,1}, {1,3,1}, {1,2,10},
        {2,1,3}, {2,2,1},
        {3,3}, {3,17}, {3,111},
        {4,17}, {4,122}, {4,436}, {4,466}, {4,472},
    };
    // ...
    std::vector<FunctionObjectType<T,KT>> function_evaluators;
    // ...
    for (auto f : needed_functions) {
        function_evaluators.push_back(f.get_evaluator<T>()); 
        std::cout << f << "\n";
    }
    // ...
    constexpr size_t n_vars = Kin<T,KT>::Nvis;

    std::array<T,n_vars> sij = {
            169.00000000000000000000000000000000000000000000000000000000000024,
            -127.03554269209390121978365556633554285695735563298040778575769793,
            33.796369695873051618118516726995190978444086393722898206354653227, 
            34.135578250263955969284362230088631173450982210677708512608176643,
            -112.93867208272743252147419350392861691229747936905042006487121976,
    };
    // ...
    Kin<T,KT> k(sij);
    // ...
    for (size_t i = 0; i < function_evaluators.size(); ++i) {
        auto ri = function_evaluators.at(i)(k);
        std::cout << needed_functions.at(i) << " = " << ri << "\n";
    }

A FunID<KinType> names one function by its indices and get_evaluator<T>() returns a callable object for number type T; building the evaluators is the slow step and happens once. Kin<T,KinType> holds the point (Nvis is 5 here), and calling an evaluator on it returns a std::complex<T>, printed after the function's label. dd_real or qd_real in place of double gives extended precision (on x86, bracket the evaluations with qd's fpu_fix_start/fpu_fix_end). KinType::m1 selects the one-mass set, with six invariants per point and two indices for weight-1 and weight-2 functions; the file includes a commented one-mass point to try.

Compile your own program against an installed copy. Linking has two pitfalls. PentagonFunctions.pc lists Li2++ (the dilogarithm library) and qd only as private dependencies, so a dynamic link naming PentagonFunctions alone fails with undefined Li2pp:: symbols; name all three packages. The installed libraries carry no run-time search path, so LD_LIBRARY_PATH must cover both the install's library directory and qd's. With $PF the install prefix, $QD the qd prefix and myprog.cpp your source file (it can #include "FunctionID.h" directly, since --cflags supplies that directory), BootLoops compiles and runs such a program with:

export PKG_CONFIG_PATH=$PF/lib/x86_64-linux-gnu/pkgconfig:$PF/lib/pkgconfig:$QD/lib/pkgconfig
g++ -O2 -std=c++17 myprog.cpp -o myprog \
    $(pkg-config --cflags --libs PentagonFunctions Li2++ qd)
export LD_LIBRARY_PATH=$(pkg-config --variable=libdir PentagonFunctions):$QD/lib:$LD_LIBRARY_PATH
./myprog

Routines

BootLoops adds no code of its own around PentagonFunctions-cpp and carries no patch; it is called from short C++ programs written against the library's documented interface. The library's own entry points such a program uses:

The library also installs a Mathematica package (PentagonFunctions.m), and a separate Python interface by G. De Laurentis can be installed with pip as pentagon-functions. BootLoops calls the C++ interface.

Requirements and source

A C++17 compiler (the README recommends g++; Apple Clang is not expected to work), meson 0.58 or newer, ninja, and the qd library for extended precision; Li2++ is fetched automatically as a meson subproject. One build pitfall: src/PhaseSpaceGen.cpp includes the qd headers unconditionally, so a high-precision=false build on a machine without qd fails to compile. BootLoops builds version 4.0 with high-precision=true against a local qd 2.3.24, which avoids the problem without touching the source. Self-tests: ninja test from the build directory.

The library is not part of BootLoops' bootloops-dev repository (GitHub organization BootLoops-ai), which is released under the MIT license and does not bundle it. The repository's external-software catalog lists it as obtained from upstream and used unmodified; it keeps its own license, the GNU GPLv3. Source: gitlab.com/pentagon-functions/PentagonFunctions-cpp. Cite the defining papers when using it: massless functions, Chicherin and Sotnikov, arXiv:2009.07803; one-mass planar functions, Chicherin, Sotnikov and Zoia, arXiv:2110.10111. The full one-mass set is defined in Abreu, Chicherin, Ita, Page, Sotnikov, Tschernow and Zoia, arXiv:2306.15431, and the decay-channel set in arXiv:2602.18185.

← back to the tools index