Membound

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

Membound computes soft-region ($\omega\to0$) boundary constants for worldline and post-Minkowskian-type expansions, in which a loop integral restricted to vanishing radiation frequency reduces to a two- or three-dimensional frequency-space integral over causal frequency factors and modified Bessel kernels. You describe such an integral in a short JSON file and run python3 -m membound --spec core.json; the package returns the first three coefficients of its expansion in the dimensional-regularization parameter $\epsilon$, printed and optionally written as a JSON record. The worked example included with the package is the gravitational-memory sector of black-hole scattering at fifth post-Minkowskian order, where a check script reproduces the published constant $c_M=1$.

What it does

Integrals in these expansions usually come from differential equations in the kinematic variables, which need starting values at a special point. In the soft region (for black-hole scattering the "memory" region, where exchanged gravitons are real radiation with zero net frequency) that point is the static limit. There the integrals collapse to integrals over $n=2$ or $3$ frequencies and a "coupler" frequency equal to their sum, $\omega_{n+1}=\omega_1+\dots+\omega_n$:

$$J(\epsilon)=\frac{1}{(2\pi)^{n}}\int d^{n}\omega\;\prod_{i}\big(0^+-i s_i\omega_i\big)^{p_i-q_i\epsilon}\;\prod_{j}|\omega_j|^{-\epsilon}K_\epsilon(|\omega_j|)\;\prod_{l}\omega_l^{n_l}.$$

Here $\epsilon=(4-d)/2$ with $d$ the spacetime dimension, $K_\epsilon$ is the modified Bessel function, $p_i$ and $n_l$ are integers, and $s_i=\pm1$ selects the retarded or advanced $i0^+$ prescriptionthe rule for passing the pole of a propagator in frequency space: retarded, advanced, or Feynman of a factor. Membound calls such an integral a core and returns the moments $J^{(0)},J^{(1)},J^{(2)}$ of $J(\epsilon)=J^{(0)}+J^{(1)}\epsilon+J^{(2)}\epsilon^2+O(\epsilon^3)$, measure included, together with the layer index $k=\sum_i q_i+(\text{number of Bessel lines})$: the power in the small-frequency behavior $|\omega|^{-k\epsilon}$ under which a family of cores assembles into a boundary vector.

The integrand is expanded in $\epsilon$ to second order before integrating, since a fixed-$\epsilon$ evaluation of these cores loses most of its digits to cancellations between pole orders. Each frequency factor splits into a leading part $(-i)^{p}\omega^{p}$ and an order-$\epsilon$ logarithm $\log|\omega|+i\varphi(\operatorname{sign}\omega)$ whose phase is set by the factor's flag. The frequency space is cut into sign sectors (six for two frequencies; fourteen pieces of the eight sign octants for three), each sector's weight at each order is derived from the factor list, and sectors with equal integrands are merged. Each remaining sector is integrated with mpmath's tanh-sinh quadraturea change of variables that clusters sample points at the ends of each panel, so endpoint singularities such as $\log|\omega|$ or $K_0$ at $\omega=0$ cost little accuracy on panel breakpoints along every magnitude axis. The independent quadratures run in parallel worker processes.

The result is a numerical estimate without a proven error bound. --dps (working digits), --maxdegree (quadrature depth per axis) and --panels (put a breakpoint near every scale of the integrand) control the accuracy, and the cost grows steeply with the first two. A core of your own has no independent value to compare with, so its output record carries digits: null until you repeat the run at higher settings and difference the two. The integrand must decay at large $|\omega|$ along every independent direction; the package does not test this, and a non-decaying integrand returns a finite wrong number rather than an error. The odd projection ("proj": "im") is accepted but has not been validated against any known value.

A flag changes only a factor's order-$\epsilon$ phase; the leading factor always keeps the retarded form. "ret" on every factor is the retarded assignment and is exact; "adv" on every factor is exact too and gives the same integrals, because $\omega_i\to-\omega_i$ maps one into the other; mixing the two between factors misses an overall sign and is not supported. "fey" puts the constant Feynman phase $-\pi/2$ on top of the retarded leading factor, so a "fey" run is a diagnostic of how sensitive an assembled constant is to the phase layer. It is not the Feynman propagator prescription, which changes the whole power to $(0^+-i|\omega|)^{p-q\epsilon}$ and with it the leading factors; that assignment is outside what the package computes.

The worked example is the planar memory sector of black-hole scattering at fifth order in Newton's constant and second order in the mass ratio, at the static point. Its two cores I1M and I3M (two frequencies, layer $k=7$), multiplied by exact $\Gamma$-function series, give the published integrals $I_1^{(M)}$ and $I_3^{(M)}$; $I_2^{(M)}$ follows from an integration-by-parts identity, and $c_M=-\tfrac{6}{5}(8\pi)^4\,I_2^{(M)}\big|_{\epsilon^{-2}}$. Four checks measure the accuracy: the zeroth moment of I1M equals $1/30$, the $\epsilon^{-1}$ coefficient of $I_1^{(M)}$ equals $1/(15(8\pi)^4)$, the $\epsilon^{-4}$ and $\epsilon^{-3}$ terms of $I_2^{(M)}$ cancel, and $c_M=1$. At --dps 30 --maxdegree 6, roughly a quarter of an hour on twelve processes, $c_M$ comes out to about 25 digits and the pole to about 28; this quadrature route does not go further. With "fey" on both memory factors the poles still cancel and $c_M$ moves from 1 to exactly $1/5$. That is not the value with Feynman propagators, for which the leading cores change and the $\epsilon^{-4}$ pole of $I_2^{(M)}$ does not cancel. The example's registry also names the crossed-planar (PX2) memory sector and the non-planar (NP) family, which needs three-frequency cores ("n_freq": 3, supported by the engine); no cores or constants are provided for them, and an absent entry should not be read as zero.

Examples

Compute a core from a JSON spec. We want the moments of the small two-frequency core included as examples/core_example.json, $J(\epsilon)=(2\pi)^{-2}\int d\omega_1\,d\omega_2\,(0^+-i\omega_3)^{2-\epsilon}\prod_{i=1}^{3}|\omega_i|^{-\epsilon}K_\epsilon(|\omega_i|)$ with $\omega_3=\omega_1+\omega_2$, whose zeroth moment is exactly $-1/15$. Without the file's free-text _comment key, the spec is

{
 "name": "w3sq_K123",
 "n_freq": 2,
 "ret": [[3, 2, 1, "ret"]],
 "klines": [1, 2, 3],
 "poly": {},
 "proj": "re"
}

Each ret entry is [index, p, q, flag] for one factor $(0^+-is\,\omega_{\text{index}})^{p-q\epsilon}$ with flag one of "ret", "adv", "fey"; klines lists the frequencies carrying $|\omega|^{-\epsilon}K_\epsilon(|\omega|)$; poly maps an index to an extra integer power; n_freq is 2 or 3, and index n_freq+1 (here 3) is the coupler. Indices outside 1..n_freq+1 and unknown keys are refused with a message. From the directory that contains membound/ (tools/ in the repository):

python3 -m membound --spec membound/examples/core_example.json --dps 9 --maxdegree 3 --panels 0,2,inf

The run prints the core's name, n_freq, layer index (4 here), projection and settings, one progress line per quadrature (--quiet suppresses these), then J^(0), J^(1), J^(2), the assembled J(eps) = ... + O(eps^3) and the elapsed time. At these settings it finishes in seconds and J^(0) agrees with $-1/15$ to eight or more digits. Add --order-max 0 to compute only the leading moment while sizing a run, --jobs 1 to run serially, and --json-out out.json to write a membound.core_moments.v1 record (spec, layer_k, moments as decimal strings, settings, and digits: null until you have differenced two runs).

Reproduce $c_M=1$ through the whole pipeline. We want the published memory constant back at 11 digits: both cores of the worked example, the prefactors, the integration-by-parts step and the four checks. From the same directory:

python3 membound/gate_cM.py --dps 11 --maxdegree 4 --jobs 12

The script prints one line per quadrature (core, $\epsilon$ order, sector multiplicity, value, seconds), then the six moments and the assembled Laurent series of $I_1^{(M)}$, $I_3^{(M)}$ and $I_2^{(M)}$. One CHECK line per test gives the digits of agreement (or, for the cancellation tests, the relative size of the term) beside the demand, dps minus 5. It ends with $c_M$, the integer relation PSLQ finds between $c_M$ and 1 ([1, -1] means $c_M=1$), elapsed time, peak memory, and PASS or FAIL; the exit status is 0 or 1. At these settings expect a couple of minutes on twelve processes, well under a gigabyte of memory, and agreement to roughly ten digits. Before a longer run add --micro to the intended command (for a 30-digit run, --dps 30 --maxdegree 6 --micro): the script then integrates only the most expensive piece and multiplies its time by the number of distinct quadratures a full run needs, an upper estimate of the total. --json-out FILE also writes the boundary-vector record (membound.boundary_vector.v1): the three integrals under their layer $k=7$, each with $\epsilon$-series coefficients as decimal strings, how it was obtained, and the digits confirmed against an independent value (null if none).

Routines

Command line (from the directory containing membound/; the two scripts also run from inside the package)

Core engine, membound.core

Parallel runs and spec loading, membound.farm and membound.cli

Worked-example registry, membound.spec

Series and assembly, membound.laurent and membound.assemble

Used on this site

Requirements and source

Python 3 with mpmath; parallel runs use the standard library's process pool. No install step: work from the directory that contains membound/ (tools/ in the repository), or run the scripts inside the package directly (each puts that directory on the import path). Self-tests: python3 selftest.py from inside tools/membound/, about twenty seconds (--full adds the $c_M$ reproduction and takes minutes); exit status 0 on pass. Source: tools/membound/ in BootLoops' bootloops-dev repository (GitHub organization BootLoops-ai), released under the MIT license. The memory-region integrals, their $\Gamma$-function prefactors, the integration-by-parts identity and the value $c_M=1$ are from Driesse, Jakobsen, Mogull, Nega, Plefka, Sauer and Usovitsch, arXiv:2601.16256, and its supplement. Number recognition beyond the built-in PSLQ test is meant to go through Lockpick.

← back to the tools index