Surd
The content on this page was written by AI under human supervision.
Surd integrates a three-fold parametric integral with a rational integrand exactly, on a one-parameter family of kinematics labeled by $t$, and returns a closed form in $t$. The closed form is a finite sum of hyperlogarithmsiterated integrals $G(a_1,\dots,a_n;z)=\int_0^z \frac{dx}{x-a_1}\,G(a_2,\dots,a_n;x)$, the functions produced by integrating rational functions one variable at a time; logarithms and polylogarithms are special cases of weight at most three whose arguments may be algebraic in $t$ (roots of quadratic and cubic polynomials included), with exact rational-function coefficients. It also evaluates the closed form to a requested precision and answers structure questions about it, such as which polynomials in $t$ appear as logarithmic singularities and how the function behaves near their roots. BootLoops wrote it for the leading-order collinear four-point energy correlator, and its drivers are organized around that integral.
The name is the point of the tool. A surd is the old word for an irreducible root such as $\sqrt{2}$ or $\sqrt[3]{5}$. Exact integration one variable at a time normally requires every denominator to split into factors linear in the next variable; when the last variable instead appears under square or cube roots, the standard hyperlogarithm programs stop or drop those pieces. Surd carries such radical letters exactly through the final integration, which is what it was written for.
What it does
Feynman-parameter integrals with rational integrands are often computed one variable at a time. Each step gives hyperlogarithms again as long as the denominators stay linear in the next variable; an integral with that property throughout is linearly reducibleevery intermediate denominator factors into polynomials of degree one in the next integration variable, so each step is again a partial-fraction problem, and public programs such as HyperInt and HyperFLINT (see the SubTropica page) handle it. Many integrals fail only at the last step, where the remaining variable sits inside irreducible quadratic or cubic polynomials. The answer is still a hyperlogarithm, but some of its lettersthe arguments $a$ of the logarithmic forms $d\log a$ from which a polylogarithmic function is built; the full set, the alphabet, fixes where the function can have branch points are roots of those polynomials, and the standard programs stop or lose those pieces.
Surd handles that case with one symbolic parameter. The first two integrations are exact polynomial arithmetic over the Gaussian rationals $\mathbb{Q}(i)$ in the integration variables and $t$. Denominators are kept as exponent vectors over a table of irreducible polynomials rather than multiplied out. The third integration is done at function level: the roots of the last-variable polynomials are adjoined as exact algebraic quantities over $\mathbb{Q}(i)(t)$ and partial fractions are taken in that extension. Each output term is a coefficient in $\mathbb{Q}(i)(t)$ times powers of roots times hyperlogarithms whose arguments are rational points or roots; an argument lying exactly on the positive real integration path is taken as "argument $-\,i0$". No fit, tolerance or integer-relation search enters the construction.
The unit of work is a group of integrand terms sharing a denominator structure, with an elimination order for which the first two integrations are linear. The order, and the table of polynomials allowed in denominators at each step, come from a linear-reducibility run and are given as input. Surd does not search for them, and it stops with an error if a denominator factor outside the table ever appears. Each group leaves exact checkpoints and a JSON record under the directory named by COLLINEAR_HYPERLOG_WORK, and assemble.py sums groups into one .json.gz file per function in the format documented in README_FORMAT.txt. Every group is compared twice with independent numerics that share no code with the integrator: the stage-2 intermediate against a residue-plus-Arb-quadrature evaluation, and the stage-3 closed form against a two-chart Arb evaluation, each to at least 30 digits. These comparisons support the result at that level; they are not a proof.
Limits. One symbolic parameter and exactly three integrations, the first two linear. Evaluation is on the principal sheet, so the package can bound the exponent of a possible singularity at a root of $P(t)$ but cannot extract the coefficient of a singularity on another sheet. The symbol test treats square-root letters only. The drivers address integrands by the names of the energy-correlator problem (--channel, --sigma, --pair); a different integral needs its own constructor on the pattern of slice_common.build_group. On that problem a group took up to about 37 minutes and 0.85 GiB on one thread; groups are independent and run in parallel.
Examples
Run the smoke test. It copies the scripts and three small input files into a fresh directory and runs one group through both stages and both comparisons.
bash PROMOTION/smoke_test.sh [TARGET]
TARGET is a fresh scratch directory outside the source tree (default $TMPDIR/collinear_hyperlog_smoke.<stamp>); a target inside the tree is refused. The script prints the agreeing digits of the two comparisons, the closed-form values at $t=1/2$ and $4/5$ beside frozen reference strings, and finally [smoke] RESULT: PASS. Expect 3 to 4 minutes and about 0.15 GB.
Integrate one group by hand, then many. COLLINEAR_HYPERLOG_WORK must point at a scratch directory, otherwise outputs are written next to the scripts.
export COLLINEAR_HYPERLOG_WORK=/path/to/scratch cd slice/scripts python3 slice_run.py --channel q_qbpqpgq --sigma 1234 --pair 34 python3 slice_gate12.py --tag q_qbpqpgq_s1234_p34_g2 python3 stage3.py --tag q_qbpqpgq_s1234_p34_g2 --t 1/2,4/5
The first command does the two linear integrations and writes ckpt/<tag>/stage1.pkl, stage2.pkl and the record SLICE_S12_<tag>.json; a finished group is skipped on rerun unless --force is given. The second writes SLICE_G12_<tag>.json with the minimum agreeing digits of the stage-2 comparison and a pass flag. The third does the function-level integration and writes the exact stage3.pkl and SLICE_S3_<tag>.json with the closed-form values at the listed $t$ beside the reference values; --reuse re-evaluates an existing pickle and --no-po skips the comparison. The package includes the cell inputs for this one channel only; the other channels of the built-in problem read external term lists from the directory named by COLLINEAR_HYPERLOG_TERMS and stop with a clear error if it is unset. For many groups, list one channel sigma pair per line and run the worker, which does the three steps per line, skips finished groups and logs under $COLLINEAR_HYPERLOG_WORK/logs/:
COLLINEAR_HYPERLOG_WORK=<scratch dir> slice/scripts/s13_worker.sh LIST NAME [t-list]
Evaluate a result file. With COLLINEAR_HYPERLOG_DATA naming a directory whose out/ holds files written by assemble.py (no assembled files come with the package):
python3 evaluate.py --file quark --t 3/5 [--dps 60] [--digits 30]
The JSON report carries value, digits_est, the attempts and a mode. The exact value is real, so the imaginary part of the numerical sum is the error monitor; if the estimate falls short of --digits the working precision is raised and the evaluation repeated. Expect roughly the working precision minus 10 digits, fewer near values of $t$ where single terms blow up while the sum stays finite. At a rational $t$ where the representation divides by zero although the function is analytic (as here), mode reads symmetric limit (delta=...): the mean of the values at $t\pm\delta$ is returned with its error. From Python the call is assemble.evaluate_file(path, t, dps).
Routines
Integration drivers (slice/scripts/)
slice_run.py— stages 1–2 (the two linear integrations) for one group, resume-safe.slice_gate12.py— stage-2 intermediate against the independent residue-route evaluation.stage3.py— stage 3 with algebraic letters, evaluation, comparison with the per-group reference value.s13_worker.sh— the three steps for every line of a list file; variantss13n_worker.sh(n4channel),s1_worker.sh(stops after the stage-2 comparison),run_s12.sh(stages 1–2, one group).assemble.py— sums groups into per-channel and per-jet files, collecting identical terms exactly (needsslice_classes.pyoutput);assemble.evaluate_file(path, t, dps)evaluates a file.evaluate.py— guarded evaluator with precision escalation and the symmetric limit;repr_singular.pylists the $t$ values where that is needed.
Reference values and comparisons
slice_oracle.py— independent 30-digit values per channel at rational $t$ by two integration routes, checkpointed;run_oracle.shlaunches it detached;slice_po.pyis the per-group version.file_gate.py,final_gate.py— assembled files, and channel and jet sums, against every available reference value and the $t\to1/t$ symmetry.s4_control.py,cmsyz_slice.py— the built-in problem's $\mathcal{N}=4$ result against the published closed form restricted to the same family of shapes (the ratio must be one constant at every $t$).gate/scripts/onefold_arb.py— Arb integrator for the last integration of a numeric-kinematics one-variable object;fibre_residueis the residue-route evaluator.gate/scripts/oracle.py,oracle_cells.py— 30-digit evaluator of the collinear four-point correlator at a rational complex shape, andbuild_cells(channel, gauge), the exact cell integrands with symbolic kinematics.
Structure of the result (slice/scripts/)
letters.py— rational and algebraic letters per function, discriminants factored over $\mathbb{Q}[t]$.symtest.py— per weight and discriminant class, whether the square-root letters survive in the symbol (SURVIVES/CANCELS), by lattice reduction at--tstarconfirmed at--tstar2;symtest_e6.shruns the standard point pairs.valtest.py— whether $\log P(t)$ is a letter, per weight and symbol slot.tstar_local.py,near_root.py— behavior near the real roots of each class on the physical sheet: odd part under a root swap, pole order, two-sided values at $t_\ast\pm h$.landau_family.py,n4_alphabet.py— which denominator polynomials generate each algebraic letter; a function's prime support against an external alphabet file.gate/scripts/symbol_letters3.py— weight-3 symbol from a numeric-kinematics object with exact number-field coefficients, cubic letters included;nf_cert.pysupplies its PARI certificates.
Engine modules (importable)
symbolic/scripts/fibr.pyEngine,alphabet.pyAlphabet,OffAlphabet— fibration integrator over $(0,\infty)$ on a fixed letter table;slice/scripts/fibr_gi.pyandalphabet_gi.py(GIAlphabet) are the same over $\mathbb{Q}(i)$ with a self-extending table.k3field.pyGT,KF,TRing;fib3.pyFibrator;int3.pyIntegrator— stage 3: arithmetic in $\mathbb{Q}(i)(t)$ and its extensions, rewriting into the basis $G_0(v;x)$, exact integration with algebraic partial fractions.hpath.pyHPath,gate/scripts/hlog_eval.pyGEvalAlg,ZipEvalAlg— numerical hyperlogarithms with algebraic letters on or off the integration path.gate/scripts/kfield.pyKField,residue_exact— exact arithmetic and residues in $\mathbb{Q}[t]/(f)$.slice_common.pybuild_group,d_of_t,order_for— the group constructor and kinematic map to copy for a new integral.slice_prov.pywrite_receipt,log_pid— write-once JSON run records with checksums of scripts and inputs.
Tests
PROMOTION/smoke_test.sh,PROMOTION/tests/run_tests.py;k3field.py,int3.py,hpath.py,hlog_eval.pyandkfield.pyeach run a self-test when executed directly;fib3.pydoes too but needs a finished group's stage-2 checkpoint (--tag).
Used on this site
- The four-point energy correlator — computed the leading-order collinear correlator in closed form on the one-parameter family of dipole shapes for quark jets, gluon jets and $\mathcal{N}=4$ super Yang–Mills, and compared the letters of the three functions.
Requirements and source
Python 3 with python-flint, sympy and mpmath; cypari2 (PARI) only for nf_cert.py. The hyperlogarithm evaluator imports zip_num from the SubTropica package (tools/subtropica/scripts/fibrate/), which must be present. Everything is single-threaded and fits in an 8 GB memory cap. Set COLLINEAR_HYPERLOG_WORK to a scratch directory before running anything, and COLLINEAR_HYPERLOG_DATA to the directory holding assembled out/*.json.gz files for the structure tools and tests.
Self-tests: bash PROMOTION/smoke_test.sh [TARGET]. The regression suite python3 PROMOTION/tests/run_tests.py --data <dir> [--only a,b,c,d2,e] [--quick] [--dps 60] needs the assembled result files, which are not part of the package. Tests b and d2 take about 8 minutes together and all five about an hour and 2.1 GiB; exit code 0 means every selected test passed.
The code is tools/surd/ (version 1.0) in BootLoops' bootloops-dev repository (GitHub organization BootLoops-ai), released under the MIT license (manual MANUAL.md, output format README_FORMAT.txt). The method is Brown's hyperlogarithm fibration and linear-reducibility criterion (arXiv:0804.1660) as implemented for rational alphabets in Panzer's HyperInt (arXiv:1403.3385); the regularization conventions follow HyperFLINT.