Cosmoflow
The content on this page was written by AI under human supervision.
Cosmoflow is a Python package for the integrals behind the wavefunction and correlators of a scalar field in an expanding (Friedmann–Robertson–Walker, FRW) or de Sitter universe. You give it a graph of sites and edges: a chain, a ring, a star or a multi-loop polygon. It returns the linear energy denominators of the integrand and the candidate symbol letters built from them, as a JSON file in the input format of Ansatzer. For any one-loop polygon it also constructs the Baikov polynomial of the loop integrand symbolically, and a worked example carries the three-site triangle through to high-precision numbers.
What it does
A wavefunction coefficient is labeled by a graph: sites (vertices), each carrying the total energy $x_v$ of the external legs attached to it, joined by edges (internal lines) with energies $y_e\ge 0$. The singularities of its integrand are linear forms $q_g$, one for each connected subgraph $g$: the sum of the site energies in $g$, plus the energy of every edge leaving $g$, plus $c$ times the energy of every loop edge deleted inside $g$ (both endpoints in $g$, the edge itself left out). The package defaults to $c=2$, the value its documentation argues is the consistent one; $c=1$, printed in one section of the reference paper, can be requested by argument, and at tree level $c$ never enters.
alphabet_graph(nv, edges) enumerates the connected subgraphs of any connected graph, parallel edges allowed, and emits three classes of symbol lettersthe arguments of the logarithms from which a polylogarithmic answer is built; knowing them in advance fixes the space of functions to fit. The first class is the forms $q_g$ themselves, which are also the allowed first entries. The second gives every $q_g$ that contains an edge energy a "folded" partner with the signs of those edge energies flipped (the $X-Y$ letters of the two-site chain belong here). The third is the bare energy $y_e$ of every edge that lies on a cycle. Each letter carries a source note saying which rule produced it, and the output is marked complete: false: it is a candidate list, to be trusted only after it has been compared with the denominators of an independently derived differential equation for the same graph.
For a one-loop polygon with $n_s$ sites the loop momentum enters only through the $n_s$ edge energies, and using them as integration variables brings in the Baikov polynomial $B(y;X)$. It is the Cayley–Menger determinant of the simplex whose base edges are the external invariants $X_{ij}$ and whose remaining edges are the $y_e$, proportional to the simplex's squared volume and quadratic in each $y_e^2$. The integrals of the family are
$$I[N,\tau]=\int_{y_e\ge 0,\;B\ge 0} d^{\,n_s}y\;B(y;X)^{-1/2+\epsilon}\,\frac{N(y)}{q_g^{\,\tau}}\,,$$
with $N$ a polynomial, $q_g$ one of the linear forms and $\epsilon$ a regulator. baikov_B(n_s, ys, Xs) returns $B$ as a sympy polynomial for any $n_s$. For one-loop polygons the letter list can carry a separate block, disc_kallen_baikov, holding the irreducible factors of the discriminant of $B$ in each $z_e=y_e^2$; they are functions of the $X_{ij}$ and $z_e$ rather than of the energies, which is why they are kept apart. The three-site case of $B$ has been checked against independent calculations; two sites and four or more come from the same formula and are meant for structural work.
The worked example, in examples/triangle/, is the one-loop three-site triangle of arXiv:2408.16386. Its integral family has an elliptic sector: nine master integralsa finite set of basis integrals to which all integrals of the family reduce by exact linear relations $e_1,\dots,e_9$ whose differential equation contains an irreducible second-order operator $\mathcal L_2$ solved by complete elliptic integrals. The module oracle.py evaluates them on the kinematic family $X=(a\lambda,\lambda,1)$ by three nested one-dimensional quadratures, at $\epsilon=0$ or small nonzero $\epsilon$. The singular points inside the unbounded integration region are treated analytically: an inner complete elliptic integral plus a smooth remainder, a polar patch around the crossing of two singular lines, and a split at an interior pinch when $X_1\gt X_3$. Each value comes with an estimated count of correct digits from the quadrature refinement, an estimate rather than a proven bound. At $\epsilon=0$ only $e_3,e_5,e_6,e_7$ converge, and $e_3,e_5$ reach only 8 to 10 digits. Expect this evaluator to be slow: at the coarse settings of the self-test's --deep check, $e_6$ takes several minutes and comes out to roughly 7 or 8 digits; 30 digits take far longer. The module maxcut.py gives the triangle's elliptic data directly: the residue period of the sector on the surface $X_1+X_2+X_3+c\,y_{12}=0$ (about a tenth of a second at 100 digits), the two periods $\varpi_0,\varpi_1$ of $\mathcal L_2$ in closed form, and a sympy proof that $\mathcal L_2\varpi_0=0$.
The same example includes the two-site tree chain coefficient $F(X_1,X_2,Y;\epsilon)$ for $-1\lt\epsilon\le 0$ and its first Taylor coefficient in $\epsilon$, each from a one-dimensional integral, as a control with a known closed form. F_twosite_certified repeats the computation at two precisions and two quadrature levels and reports only the digits on which all four runs agree; a call takes hundredths of a second at 50 digits. Inputs must be exact (integers, Fraction objects or strings such as '7/10'); floats are refused with an error, and the region $X_1\gt Y\gt 0$, $X_2\gt 0$ is enforced.
Limits: the site graph must be connected (an assertion stops the call otherwise), and the discriminant block exists only for one-loop polygons (asking for it on any other graph raises ValueError). Numerical evaluation is provided only for the triangle and the two-site chain: eval_master raises NotImplementedError for four or more sites, and the two-site evaluator computes the tree chain, not the master integrals of the one-loop bubble. No $\epsilon$-factorized basis is constructed, and the residue period contains lower-sector contributions, so it is not itself a solution of $\mathcal L_2$.
Examples
Run the self-test. From inside tools/cosmoflow/ (the script locates the package itself, so python3 tools/cosmoflow/selftest.py from the repository root works too):
python3 selftest.py python3 selftest.py --deep
The first command takes about five seconds, prints one PASS or FAIL line per check, writes SELFTEST.json beside the script (or at the path in the environment variable COSMOFLOW_SELFTEST_OUT, if set) and exits 0 only if every check passes. The checks cover the two-site $F$ at $X_1=2$, $X_2=3$, $Y=1$, $\epsilon=-1/4$ against the printed closed form of arXiv:2312.05303 eq. (3.42) and its certified $\epsilon^0$ and $\epsilon^1$ coefficients (40 digits required, about 50 obtained). They also cover the letter count 5 for the two-site chain, the facet counts 10 and 17 for the three- and four-site polygons, and alphabet_graph agreeing letter for letter with alphabet_loop_ngon(3) on the three-site ring (from Python and from the command line) and with alphabet_tree_chain(3) on the three-site chain. The remaining checks are the symbolic proof $\mathcal L_2\varpi_0=0$, the period Wronskian at $a=2$, $\lambda=1/2$, the residue period at two precisions, and the interior pinch points used by the triangle evaluator when $X_1\gt X_3$, compared with the symbolic $B$. With --deep it instead evaluates the triangle master $e_6$ at $a=2$, $\lambda=1/2$, $c=1$, $\epsilon=0$ with coarse settings (several minutes) and compares it with an independently verified value. The digits and time go under deep in SELFTEST.json, and a shortfall against that check's 15-digit, 60-second target is recorded as SKIP rather than as a failure.
Letters of an arbitrary site graph. Run these from tools/, the directory that contains cosmoflow/. Sites are numbered from 0 and a repeated pair is a parallel edge:
python3 -m cosmoflow.alphabet graph --nv 4 --edges 0-1,1-2,2-3,3-0,0-2 --out boxdiag.json python3 -m cosmoflow.alphabet graph --nv 2 --edges 0-1,0-1 --disc python3 -m cosmoflow.alphabet tree 2 python3 -m cosmoflow.alphabet loop 3 --out triangle.json
The first graph is a four-site ring with one diagonal, a two-loop graph; with --out the JSON goes to the file and a one-line summary gives the letter and facet counts (33 facets here). The second is the one-loop bubble, two sites joined by two edges, with --disc attaching the discriminant block. tree n_s and loop n_s are the named special cases, the $n_s$-site chain and the one-loop $n_s$-gon; for the two-site chain the five letters are X1 + Y, X2 + Y, X1 + X2, X1 - Y, X2 - Y, under the names l_EL, l_ER, l_ET, l_FL, l_FR. The JSON has the fields name, graph (sites, edges, loop number, cycle edges), vars, letters, first_entry, sources, c and honesty, plus disc_kallen_baikov when the block is attached. --c C changes the coefficient of deleted loop edges, --sites and --enames rename the site and edge energies, and --no-disc drops the discriminant block from loop. The same call from Python:
from cosmoflow import alphabet_graph alph = alphabet_graph(4, [(0, 1), (1, 2), (2, 3), (3, 0), (0, 2)])
alph['letters'] maps names to expressions in x1..x4 and the edge energies: q_g1 is x1 + y12 + y13 + y41 (site 1 with its three edges cut), fold_g1 is its folded partner x1 - y12 - y13 - y41, names containing del_ mark forms with a deleted loop edge and coefficient 2, and disc_y12 and its relatives are the bare cycle-edge energies. alph['first_entry'] lists the 33 facet forms, alph['graph']['loops'] is 2, and alph['honesty']['complete'] is False.
The triangle and the two-site chain. From tools/:
python3 -m cosmoflow.cosmoflow build 3 python3 -m cosmoflow.cosmoflow maxcut 2 3/10 2
build 3 prints the expanded polynomial $B_3(y;X)$ in the symbols y1..y3, X1..X3 (build n_s accepts any $n_s$). maxcut a lam c [dps] prints a one-line JSON object with the residue period at $(a,\lambda)=(2,3/10)$, $c=2$, to dps digits (default 80). From Python, the same quantities the self-test checks:
from fractions import Fraction from cosmoflow.examples.triangle import oracle, maxcut v = oracle.F_twosite(2, 3, 1, eps=Fraction(-1, 4), dps=50, level=10) r = oracle.F_twosite_certified(2, 3, 1, eps=0, which='F') I = maxcut.period_residue(2, Fraction(3, 10), 2, dps=50) ok = maxcut.prove_L2_varpi0_symbolic()
v is an mpmath number, $F(2,3,1;-1/4)$ at 50 working digits. r is a dictionary with value (a decimal string), certified_digits (how many leading digits agreed across the four runs), level_agree, cross_dps_agree and wall_s; which='F1' gives the $\epsilon^1$ coefficient instead. I is the residue period to 50 digits and ok is True when sympy reduces $\mathcal L_2\varpi_0$ to zero. A triangle master comes from oracle.eval_master(3, key, a, lam, c) with key one of 'e1' to 'e9', which returns (value, digits_est, wall_s); expect minutes, not seconds.
Routines
Command-line entry points
selftest.py [--deep]— the self-test suite; writesSELFTEST.json(or the file named byCOSMOFLOW_SELFTEST_OUT).python3 -m cosmoflow.alphabet graph --nv N --edges u-v,u-v,... [--c C] [--sites ...] [--enames ...] [--disc] [--out FILE]— candidate letters of any connected site graph, as JSON.python3 -m cosmoflow.alphabet tree n_s [--out FILE]andloop n_s [--c C] [--no-disc] [--out FILE]— the same for the $n_s$-site chain and the one-loop $n_s$-gon.python3 -m cosmoflow.cosmoflow build n_s | oracle key a lam c [dps] | maxcut a lam c [dps] | periods a lam— print $B$ for any $n_s$; the other three drive the triangle example (one master integral, the residue period, or $(\varpi_0,\varpi_1,k^2)$, each as one line of JSON).
Letter lists (alphabet.py; also importable as from cosmoflow import ...)
alphabet_graph(nv, edges, c=2, site_names=None, edge_names=None, with_disc=False, name=None)— letters of an arbitrary connected site graph (0-based(u, v)pairs, parallel edges allowed).alphabet_tree_chain(n_s, ...),alphabet_loop_ngon(n_s, c=2, ..., with_disc=True)— the chain and the one-loop polygon, thin wrappers overalphabet_graphwith the conventional variable names.connected_subgraphs(nv, edges)— the connected subgraphs that give the energy denominators.q_of_subgraph(V, E, edges, xs, ye, c=2)— the linear form $q_g$ of one subgraph, returned together with its number of deleted loop edges.parse_edges('0-1,1-2,0-2'),tree_chain_edges(n_s),loop_ngon_edges(n_s)— edge lists from a string, or for the named graphs.disc_kallen_block(n_s, c=2)— irreducible factors of the discriminant of $B$ for the one-loop $n_s$-gon.
Integrand (polytope.py)
baikov_B(n_s, y_list, X_list)— the Cayley–Menger polynomial $B(y;X)$ of the one-loop $n_s$-gon (sympy), with the base invariants ordered $X_{12},X_{13},\dots,X_{n-1,n}$.q_subgraph(spec, y_list, X_list, c=2)— a linear facet form.baikov_B3(y12, y23, y31, X1, X2, X3),q_G12(y12, X1, X2, X3, c=2)— the triangle's $B$ and $X_1+X_2+X_3+c\,y_{12}$.B_z,B_num— the triangle's $B$ in $z_e=y_e^2$, symbolic and mpmath-callable.
Worked example: the triangle and the two-site chain (examples/triangle/; import as from cosmoflow.examples.triangle import oracle, maxcut)
oracle.eval_master(n_s, key, a, lam, c, eps=0, dps=50, Nch=48)— one triangle master (n_s=3,key'e1'..'e9') or the two-site coefficient (n_s=2,key'F','F0'or'F1', kinematic slots read asX1, X2, Y); returns(value, digits, wall_s).oracle.eval_all_triangle(a, lam, eps=0, dps=50, ...)— several triangle masters and both values of $c$ in one pass; returns({(key, c): (value, digits)}, wall_s).oracle.eval_master_lspace(key, a, lam, c, dps=30)— the same master as a three-dimensional loop-momentum integral, an independent cross-check.oracle.F_twosite(X1, X2, Y, eps=0, dps=50, level=10),oracle.F1_twosite(X1, X2, Y, dps=50, level=10)— the two-site chain coefficient at given $\epsilon$ and its $\epsilon^1$ coefficient.oracle.F_twosite_certified(X1, X2, Y, eps=0, ..., which='F')— the same with a certified digit count.oracle.F_twosite_print342(X1, X2, Y, eps, dps)— the printed closed form of arXiv:2312.05303 eq. (3.42), used only as an independent check.oracle.MASTERS,oracle.FINITE_EPS0— the nine masters (numerator, $\tau$, degree) and the subset finite at $\epsilon=0$.maxcut.period_residue(a, lam, cq, dps=80)— residue period of the elliptic sector.maxcut.K2_modulus(a, lam),maxcut.varpi0(a, lam),maxcut.varpi1(a, lam)— the modulus $k^2$ and the periods $K(k^2)$, $K(1-k^2)$ over $\sqrt{1-(a+1)^2\lambda^2}$.maxcut.L2_paper_coeffs(a, lam)— coefficients of the second-order operator $\mathcal L_2$.maxcut.prove_L2_varpi0_symbolic()—Trueif sympy reduces $\mathcal L_2\varpi_0$ to zero identically.
cosmoflow.examples.triangle.maxcut belongs to this example and is unrelated to the separate Maxcut package; import it by its full path.
Used on this site
- Cosmological correlators — used in the first version of that study, for numerical values of the triangle's elliptic-sector master integrals and the closed-form periods of its curve; the materials from that version are listed near the end of the page.
Requirements and source
Python 3 with mpmath and sympy. The self-test is python3 selftest.py inside the package directory (about five seconds; --deep runs the slow triangle check instead). The code lives in tools/cosmoflow/ in BootLoops' bootloops-dev repository (GitHub organization BootLoops-ai), released under the MIT license. An earlier snapshot, with the triangle modules at the top level of the package rather than under examples/triangle/, is posted with the cosmology page's files as cosmoflow-package.tar.gz; the repository version described here supersedes it. The target integrals and $\mathcal L_2$ are from Benincasa, Brunello, Mandal, Mastrolia and Vazão, arXiv:2408.16386; the two-site check uses the closed form printed in arXiv:2312.05303.