Feynman-diagram expansion and evaluation in stochastic field theories
Zheng Zhang
Jodrell Bank Centre for Astrophysics, University of Manchester
With support from



ERC grant agreement No. 948764 · RadioForegroundsPlus GA 101135036
Averages over realisations: \(\vev{\varphi_a}\), \(\vev{\varphi_a\varphi_b}\), \(\vev{\varphi_a\varphi_b\varphi_c}\), …
Each \(n\)-point function needs the \((n{+}1)\)-point function: the closure problem from turbulence that the MSR formalism organises.
Worked example I at one point: exact AR(1) drive, Heun steps, as in examples/demo1 · applications: paper, Sec. 1
Drives: same mean and \(\cumulant^{(2)}\). Only the lower one has \(\cumulant^{(3)}, \cumulant^{(4)}, \dots\)
Fields: same variance. Skewness 0.00 and 0.34 (4 000 runs).
Worked example II: the cover's equations, coupling \(\times\,0.2\).
Through the nonlinear dynamics, does the difference reach a two-point function \(\vev{\varphi\varphi}\)? By how much, and through which terms?
Path integral, two propagators, Wick's theorem and Feynman rules.
Write the model in YAML, run it, read the output, change a parameter.
Higher cumulants as vertices, and the answer to the opening question.
A light bundle in a random universe, treated as a stochastic field.
The YAML files, commands and outputs of part 2 are in the tutorial/ folder that accompanies this recording.
A stochastic field equation becomes a field theory with two propagators and a set of vertices.
The driving field is set by its cumulant generating functional:
Gaussian if \(\cumulant^{(n)} = 0\) for all \(n > 2\). Zero mean is assumed.
Goal: ensemble averages, such as \(\xi_{ab} = \vev{\varphi_a(\bm{x},t)\,\varphi_b(\bm{y},t)}\)

Each realisation of \(\eta\) fixes one history \(\varphi\). With Itô time slicing the Jacobian is a constant.
Fourier representation: one response field \(\psi_a\) per component (Martin, Siggia, Rose).
The noise average is its cumulant generating functional at \(J = \psi\).
Paper, Sec. 2.1 · Jacobian: App. D
Linear dynamics and the second cumulant \(\cumulant^{(2)}\). Quadratic in \(\varphi\) and \(\psi\).
Order \(n\) is the number of vertices. Every term is a moment of the Gaussian theory \(S_0\).
Paper, Sec. 2.2 · \(Z_S = 1\): App. D
Solid line, no direction.
Dashed line, arrow from \(\psi\) to \(\varphi\).
Every \(\psi\) must pair with a \(\varphi\).
Paper, Sec. 2.3 · \(\bm{x}, \bm{y}\): space-time points · same structure as the classical limit of the Schwinger–Keldysh formalism, with \(G^{qq} = 0\)
Paper, Sec. 2.4 · worked example I: Sec. 3
Gaussian fields: sum over the \((2n-1)!!\) ways to split \(2n\) fields into pairs.
Of the 105 pairings, 30 are nonzero. They fall into 6 topologies; diagram (b) collects \(\mu = 4\) of them.
| \(\CorrOp(\bm{z};\bm{z}')\) | |
| \(-\ii\,\RespOp(\bm{z};\bm{z}')\), from \(\psi\) to \(\varphi\) | |
| \(-\ii\,F^{(3)}\) and \(\int\!\dd\bm{z}\) over the vertex | |
| external field \(\varphi_a(\bm{x})\) | |
| order \(n\) | \(\dfrac{(-1)^n}{n!}\) and the multiplicity \(\mu\) |
Odd orders vanish: \(3n+2\) fields cannot all be paired when \(n\) is odd.
Diagram (b): \(\displaystyle\int\!\dd\bm{z}_0\,\dd\bm{z}_1\;\RespOp(\bm{x};\bm{z}_0)\,\RespOp(\bm{y};\bm{z}_1)\,\CorrOp(\bm{z}_0;\bm{z}_1)\,\CorrOp(\bm{z}_0;\bm{z}_1)\), with coefficient and coupling sum set by the rules.
Paper, Sec. 2.8 and Sec. 3.2
30 pairings remain, in 6 topologies.
Paper, Secs. 2.5 to 2.7 · counts applied in the order listed
Multinomial expansion of \(\Sint^n\), fresh indices for each vertex copy
Spatial topologies under the three rules, analytic multiplicities \(\mu\)
Canonical forms merge relabelled topologies; coupling sums
NumPy tensors with \((-1)^n/n!\) and \((-\ii)^{n_R}\)
\(\CorrOp\) in closed form or by quadrature; Gauss–Legendre or quasi-Monte Carlo
Input: action \(S_0 + \Sint\), observable, order
Output: \(\xi^{(n)}\) for each order and grid point
sft-wick run config.yaml · part 2System · Expansion · PropagatorsField · Vertex · compute_momentWorked example I of the paper, written as a YAML file and run from the command line.
\(\hl{a}{\varphi_1,\ \varphi_2}\): two components on a line \(x\)
\(\lambda = 0.05,\ \ \sigma_t = 0.3,\ \ \sigma_x = 1\)
Arrays count from 0: index 0 is \(\varphi_1\), index 1 is \(\varphi_2\). So coupling[0][1][1] is \(F^{(3)}_{122}\).
system: field: {name: phi, n_components: 2} linear: {type: diagonal, gamma: [1.0, 1.0]} vertices: - name: F coupling: # bare F; sft-wick adds the MSR factor - [[0.0, 0.0], [0.0, 1.0]] - [[0.0, 0.5], [0.5, 0.0]] noise: kappa2: type: separable_translation temporal: {type: exponential, lam: 0.05, sigma_t: 0.3} spatial: {type: exponential, sigma_x: 1.0}expand: observable: ["phi_a(x)", "phi_b(y)"] orders: [0, 2]⋮sweep: positions_grid: x: [0.0] y: [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0] t_final_grid: [3.0] component_pairs: [[0, 0]] n_samples: 8192 seed: 42output: - {type: table, format: markdown} - {type: table, format: csv, path: results/base/orders.csv} - {type: npz, path: results/base/orders.npz}$ sft-wick validate configs/01_gaussian.yaml[sft-wick] valid: configs/01_gaussian.yaml$ sft-wick run configs/01_gaussian.yaml --dry-run⋮[sft-wick] cost estimate[sft-wick] diagrams: order 0: 1, order 2: 6 (total 7)⋮[sft-wick] C propagator: closed_form:builtin (lazy per-separation table)⋮[sft-wick] ROUGH TOTAL: 2 s serial (factor ~2 uncertainty)⋮$ sft-wick run configs/01_gaussian.yaml⋮[sft-wick] sweep done in 2.1s| x | y | t_final | a | b | order | value |⋮| 0 | 0 | 3 | 0 | 0 | 0 | 0.0114854 || 0 | 0 | 3 | 0 | 0 | 2 | 0.000344013 |⋮
validateReads the file and builds the model. Errors appear before any computation.--dry-runExpands the series and times one evaluation per order: 7 diagrams, a few seconds.runExpansion, propagator table, then the sweep over 13 separations.Each order row is one contribution \(\xi^{(n)}\).
The second-order prediction is the partial sum \(\xi^{(0+2)} = \xi^{(0)} + \xi^{(2)}\).
From results/base/orders.csv: \(\xi^{(2)}/\xi^{(0)} = 3.0\%\) at \(r = 0\) and \(19\%\) at \(r = 3\).
- spatial: {type: exponential, sigma_x: 1.0}+ spatial: {type: exponential, sigma_x: 2.0}⋮- - {type: table, format: csv, path: results/base/orders.csv}- - {type: npz, path: results/base/orders.npz}+ - {type: table, format: csv, path: results/sigma_x_2/orders.csv}+ - {type: npz, path: results/sigma_x_2/orders.npz}$ sft-wick run configs/02_sigma_x_2.yamlA longer noise correlation length gives longer-range field correlations. The variance at a point is unchanged, so the curves start together.
Heun integrator with exact coloured noise, \(10^5\) realisations; Monte Carlo error \(\lesssim 0.6\%\).
Orders 0, 2, 4. Each even order is smaller than the previous by about \(\lambda = 0.05\).
\(\xi^{(0+2+4)}\) stays within about \(1.5\%\) of the simulation. At late times the residual exceeds the shaded band, most clearly for \(\xi_{11}\).
Back to the opening question: shot noise with the same covariance as a Gaussian drive.
Poisson events \((x_k, s_k)\) at rate \(\nu\); pulses \(g(\tau) = \Theta(\tau)\,e^{-\tau/\sigma_t}\) and \(w(x) = e^{-|x|/\sigma_x}\).
\(n \equiv \nu\sigma_t\sigma_x\). Adjusting \(h\) holds the variance \(nh^2/2\) fixed.
One-point PDF of the drive (orange) and the Gaussian of equal variance (dashed). The worked example and the opening slide use \(n = 1\).
With \(n_F\) cubic vertices and one \(\cumulant^{(m)}\), a diagram of \(\vev{\varphi_a\varphi_b}\) exists only if
So \(\cumulant^{(m)}\) first enters at order \(m - 1\): \(\cumulant^{(3)}\) at order 2, the FK class.
Gaussian theory: symmetric under \((\varphi_2, \psi_2) \to (-\varphi_2, -\psi_2)\). Odd cumulants break it, so Gaussian driving gives \(\xi_{12} = 0\) exactly.
| Channel at \(t = 3\) | Order | \(10^{-3}\) |
|---|---|---|
| \(F\cumulant^{(3)}\) | 2 | 2.897 |
| \(F^{3}\cumulant^{(3)}\) | 4 | 0.229 |
| \(F^{3}\cumulant^{(5)}\) | 4 | 0.0027 |
| Simulation | \(3.144 \pm 0.032\) |
Same covariance, different noise: \(\xi_{12}(t{=}3) \approx 3.1\times10^{-3}\) for shot noise, exactly zero for Gaussian driving.
\(\tilde\eta = \eta + \alpha(\eta^2 - \lambda)\): narrow non-local cumulant kernels, evaluated in \(\RespOp\)-contracted form.
One event drives each component with its own amplitude, width and decay.
State-dependent noise, against an exact reference.
Two copies of one non-local vertex, \(m = 5\) and \(m = 2\) vertices, a quartic drift next to a cubic one.
Distinct observation points and times; spatial and rotation-invariant angular kernels.
Time-dependent rates, an oscillator response that changes sign, custom temporal kernels.
Each example compares the package with a reference calculation; see the README in each example folder.
The application that motivated sft-wick: a light bundle propagating through a random universe.
Sachs equations along each ray, with affine parameter \(\lambda\) and sky direction \(\direc\):
\(\theta\): expansion. \(\sigma_+, \sigma_\times\): shear.
\(\Phi_{00}\): Ricci focusing. \(\mathcal{W}_{1,2}\): Weyl shear, the real and imaginary parts of \(\Psi_0\).
The curvature along the rays is a random field set by the matter distribution.
| sft-wick paper | Lensing paper | |
|---|---|---|
| Field | \(\varphi_a(\bm{x}, t)\) | \(\Dsachs_a(\direc, \lambda) = \sachsvec_a - \sachsvec^{(\mathrm{sa})}_a\), with \(\sachsvec = (\theta, \sigma_+, \sigma_\times)\) |
| Coordinates | position \(\bm{x}\), time \(t\) | sky direction \(\direc\), affine parameter \(\lambda\) |
| Driving field | \(\eta_a\) | \(\Dsrc_a = \src_a - \bar{\src}_a\), with \(\src = (\Phi_{00}, \mathcal{W}_1, \mathcal{W}_2)\) |
| Linear term | \(A_{ab}\) | \(-2\,\delta_{ab}\,\theta^{(\mathrm{sa})}(\lambda)\) |
| Cumulants | \(\cumulant^{(2)}, \cumulant^{(3)}, \dots\) | linear \(P(k)\), tree-level bispectrum |
| Observable | \(\vev{\varphi_a\varphi_b}\) | \(\kappa\) and shear correlations: line-of-sight integrals of \(\Dsachs\) |
Each column keeps its paper's notation. In the lensing paper \(\varphi\) is the driving field.
FF, \((n_F, n_K) = (2, 0)\), diagrams #1 to #6
Nonlinear propagation of the bundle. Present for Gaussian curvature too.
FK, \((n_F, n_K) = (1, 1)\), diagrams #7 and #8
The curvature bispectrum enters a two-point function, as \(\cumulant^{(3)}\) entered \(\xi_{12}\) in part 3.
The standard linear result; the lensing paper checks it against PyCCL.
FF / Order-0 \(= 0.3\%\)
FK / Order-0 \(= 1.6\%\)
A finite-cutoff worked example, not a calibrated amplitude for the real Universe. Shaded: 2′ to 12′, the range of small-scale cuts in current cosmic-shear analyses.
A response field gives two propagators, \(\CorrOp\) and \(\RespOp\), and vertices for both the nonlinearity \(F\) and the noise cumulants \(\cumulant^{(m)}\).
Topology-level contraction, coupling sums and numerical integrals. A YAML file and three commands for a first calculation.
Higher noise cumulants reach two-point statistics: \(\xi_{12}\) for shot noise, the FK channel in weak lensing.
$ pip install sft-wickgithub.com/StatFieldTheory/sft-wick · tutorial in tutorial/
Z. Zhang, sft-wick, accepted in Computer Physics Communications
Z. Zhang, P. Bull, C. Clarkson, A. Nicola, arXiv:2606.19472
Thank you



ERC, EU Horizon 2020, grant 948764 · RadioForegroundsPlus, HORIZON-CL4-2023-SPACE-01, GA 101135036
| Symbol | Meaning |
|---|---|
| \(\cumulant^{(m)}\) | driving-field cumulant of rank \(m\) (\(m\) legs); \(\kappa\) is reserved for the lensing convergence |
| order \(n\) | number of vertices (\(F\) or \(\cumulant\)) in a diagram; \(F^{3}\cumulant^{(3)}\) is order 4 |
| \(\xi^{(n)}\), \(\xi^{(0+2)}\) | contribution at order \(n\); partial sum of orders 0 and 2 |
| \(\varphi_1, \varphi_2\) | components as in the paper; YAML arrays use indices 0 and 1 |
| Itô | \(\Theta(0) = 0\); a Stratonovich model must be converted first |
n_samples |
quasi-Monte Carlo points per diagram integral, not stochastic trajectories |
Tree-level bispectrum, \(z_s = 5\), \(\gamma = 0.5'\). Replotted from the frozen corrected products; the PDF figure in the current lensing manuscript shows an earlier value.