Frobenius

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

The frobenius_boundary package works out how the solutions of a Feynman-integral differential equation behave at infinite mass when that behavior is a sum of non-integer powers rather than an ordinary series. It reads an integration-by-parts reduction table and a list of master integrals. It returns the exact polynomial differential equation, the power-law exponents at infinity, a decision on which of them the physical solution can contain, and the series and matrix needed to fix the constants that remain. The purpose is to cut down the number of unknown boundary constants before any expensive numerical evaluation. The same directory also holds two arithmetic companions, asdminer and deform_transport, which study the Frobenius map of a differential operator modulo a prime; they are described at the end of the next section.

What it does

A family of Feynman integrals reduces to a finite set of master integralsa basis of independent integrals to which every integral of the family reduces through integration-by-parts identities $M_k(x)$ obeying a system of linear differential equations in a kinematic variable $x$, here a squared mass. Solving the system numerically means carrying a known solution from one point to another, and $x\to\infty$ is a convenient start because the integrals usually have a simple large-mass expansion there. On a maximal cutthe version of the integral with every propagator put on its mass shell; it obeys the homogeneous part of the same differential equation that can fail: the naive large-mass value vanishes and the solution is not analytic at infinity. It is instead a combination of Frobenius branches, solutions of the form $x^{\lambda}$ times a series in $1/x$, one per allowed exponent $\lambda$, each with its own free constant.

The package builds the exact polynomial system $D(x)\,dM/dx = G(x)\,M$ from a per-point Kira reduction table (kira2math format, every kinematic quantity other than $x$ already numeric) at fixed rational dimension $d = 4-2\varepsilon$. It expands $x\,G/D$ at infinity and forms a residue matrix $D_1$ whose eigenvalues are the exponents. Repeating this at several values of $\varepsilon$ (two at least; four is the tested pattern), it fits each exponent as $\lambda = a + b\,\varepsilon$ with rational $a, b$ and sorts the families. Rational-linear in $\varepsilon$ survives. Complex or irrational is excluded, because the physical large-mass expansion contains only powers $x^{p+q\varepsilon}$ with rational $p, q$. Integer and $\varepsilon$-independent is excluded only when kill_integer_eps_indep is true, which asserts that a vacuum-integral reduction shows those terms vanish for your family (it defaults to true in the Python functions, so pass False unless you have that check; the example configuration sets it to false). Other rational $\varepsilon$-independent exponents are only flagged for review. The package then builds the $1/x$ series of each surviving branch and evaluates them at a large starting value Mstart, giving an $N\times J$ matrix $\Phi$ whose columns span the space the physical solution lives in. The surviving constants $c$ are fixed afterward, outside this package, by a small linear solve $R\,\Phi\,c = O$ against a few independently known numbers.

Resonances (exponents differing by integers) are handled by a minimum-norm solve that sets log_branch_required if a logarithmic term would be needed. A non-Fuchsian system (a nilpotent block $D_0$ ahead of $D_1$ that is not fitting noise) is handled by an exact shear reduction, after which the driver classifies the reduced residue's eigenvalues and records the frame in classification_frame. The equation, $D_1$ and the exponents are exact to the stated precision, and the driver checks that $\mathrm{tr}\,D_1$ is exactly rational-linear in $\varepsilon$, which catches a mis-built equation. The rational $(a,b)$ of survivors come from numerical fits that agree to about $10^{-26}$ across the $\varepsilon$ values, with no symbolic derivation behind them, and the output labels them that way. Excluding $\varepsilon$-incommensurate branches relies on the completeness of the expansion by regionsthe standard technique that writes a Feynman integral's large-mass asymptotics as a sum over momentum regions, each contributing definite powers of the large scale, so keep more matching conditions than surviving constants in the downstream solve and confirm the extra ones hold.

Do not use the package for a Frobenius expansion around a finite singular point (that is frobenius and frob_scalar in Wayfinder), or when the solution is analytic at infinity, where ordinary large-mass values suffice. Reading a single boundary constant off the Picard–Fuchs operator reduced modulo primes (the $p$-adic Frobenius trace) is done elsewhere on this site, with GeoTriage and Lockpick.

The two companions work with that second sense of the name, the Frobenius map of a differential operator reduced modulo a prime $p$. asdminer takes an exact integer or rational series $a(n)$, a prime $p$ and a weight $k$, and solves the three-term Atkin–Swinnerton-Dyer congruences $a(np) - \gamma_p\,a(n) + p^{k-1}\,a(n/p) \equiv 0 \pmod{p^s}$ for a single $\gamma_p$. For each prime it reports one of four outcomes: a single $\gamma_p$ fits every congruence (listed with the integer candidates the Weil bounds allow), the congruences disagree (the offending ones are named), they are underdetermined, or $p$ divides a denominator and nothing can be read. A classification step then separates the trivial unit-root value, which every series shows at a degenerate point of a family and which is not evidence of modularity, from a genuinely modular $\gamma_p$. deform_transport carries the full Frobenius matrix of an operator along a one-parameter deformation and returns the complete local factor at $p$: an integer characteristic polynomial, checked against the functional equation and the Weil bounds and required to agree under two independent truncations. It costs far more than the congruence miner, so run asdminer first.

Examples

Run the pipeline from a configuration file. Copy frobenius_boundary/config_example.json, point kira_targets_m at your kira2math table and masters at your preferred-masters list, set var, mass_slots, n_loops, eps_list, dps, branch_n_terms and Mstart, then from tools/frobenius-boundary/:

python3 -m frobenius_boundary.cli config.json

The driver runs the $\varepsilon$ values in parallel (ncpu), writes <out_dir>/SPECTRUM_<tag>.json and, when branch_n_terms is nonzero, <out_dir>/BRANCHES_<tag>.json, and prints a [cli] wrote ... line for each. The spectrum file holds the per-$\varepsilon$ degrees, fit error and eigenvalues, the classified families (groups, each with a, b, mult, class and Jordan data), the trace check, and the counts n_free_constants, n_killed, n_flagged. The branches file holds each branch's series coefficients and resonance report and, if Mstart was set, Phi.

Classify a hand-built spectrum. From tools/wayfinder/tests/test_boundary_branches.py, which needs no data files; bb is Wayfinder's boundary_branches module, which forwards each call unchanged to frobenius_boundary.core:

eps_list = ["1/101", "1/103", "1/107", "1/109"]
with mp.workdps(60):
    EVs = []
    for e in eps_list:
        _dd_rat, _dd, ev = bb.eps_to_d(e)
        EVs.append([1 - 2 * ev, mp.mpf(1) / 2 + ev / 2, mp.mpf(3)])
    fams, groups = bb.classify(EVs, eps_list, kill_integer_eps_indep=True)
with mp.workdps(60):
    ex = bb.exclude_strata(groups)
assert ex["n_free_constants"] == 2, ex["n_free_constants"]
assert ex["n_killed"] == 1

Three exponents are given at four values of $\varepsilon$: $1-2\varepsilon$, $\tfrac12+\tfrac12\varepsilon$ and the constant $3$. classify returns one group per family; the first two carry class RATIONAL_LINEAR__SURVIVES_pinch and the integer one INT_EPS_INDEP__KILLED_vacuum_theorem, because kill_integer_eps_indep=True was passed. exclude_strata then counts two free constants and one excluded branch. The calls sit inside mp.workdps(60) because several entry points take their precision from the ambient mpmath setting.

Run the acceptance test.

cd tools/frobenius-boundary && python3 -m frobenius_boundary.selftest

The test reads the configuration named by FROB_CONFIG (default config_example.json). If the table it names does not exist, it stops with exit code 3 and a message naming the missing kira_targets_m path; a fresh clone does exactly that, because the reference reduction table is not distributed. With a table in place it runs the full driver and prints a [PASS] or [FAIL] line per check: polynomial degrees, fit error, exponent counts, the shear reduction, the surviving, flagged and excluded families, the trace rules, branch residuals and the column rank of Phi. The expected values in those checks are the reference family's, so a different table exercises the whole pipeline but reports FAIL on the comparisons. The run ends with SELFTEST PASS or the list of failures, writes SELFTEST_VERDICT.json, and takes roughly 15 to 25 minutes.

The two companions have their own quick self-tests, which run on a fresh clone from the same directory:

python3 asdminer/run_control.py
python3 deform_transport/battery/run_battery_deform.py --stages S0,S1

The first needs gp (PARI/GP) on the PATH and takes a few seconds. It mines series whose congruences are proven theorems (point counts of two elliptic curves, Hecke eigenvalues of a weight-4 form, the Apéry numbers), confirms that a deliberately corrupted series and a structureless one are rejected, prints VERDICT: and control_pass = True, and writes asdminer/work/ASD_CONTROL.json. The second needs python-flint and gmpy2: stage S0 rebuilds the order-6 operator used as the rank-6 control, stage S1 transports the rank-2 Legendre family at $p=23$ and $p=29$, where the answer is a known theorem, and the run prints a BATTERY VERDICT: line beginning FAST-TIER-GREEN. The full run, --stages S0,S1,S2,S3,S4, takes hours, and S4 needs the FROB_L6_OPERATOR file described under Routines.

Routines

Command-line entry points (run from tools/frobenius-boundary/)

Pipeline functions (all in frobenius_boundary.core; the first six are also importable from the package itself)

Arithmetic companions (run from tools/frobenius-boundary/; outputs go to asdminer/work/ and deform_transport/work/ or deform_transport/battery/work/)

Related routine in a sibling package

Requirements and source

Python 3 with mpmath, sympy, gmpy2 and numpy. The code is tools/frobenius-boundary/ in BootLoops' bootloops-dev repository (GitHub organization BootLoops-ai), released under the MIT license; Wayfinder's boundary_branches module wraps the same functions. The acceptance test is python3 -m frobenius_boundary.selftest from that directory, with FROB_CONFIG pointing at a filled-in copy of config_example.json; it needs a per-point reduction table made with Kira and stops with exit code 3 until one is configured. The companions sit in the same directory: asdminer/ uses only the Python standard library, plus gp from PARI/GP on the PATH for its self-test python3 asdminer/run_control.py; deform_transport/ needs python-flint and gmpy2 (numpy and scipy only inside one control) and its quick self-test is python3 deform_transport/battery/run_battery_deform.py --stages S0,S1. The order-6 operator file some of their scripts read (FROB_L6_OPERATOR) is not distributed.

← back to the tools index