Skip to main content
Sandbox Physics
From quantum ripples to cosmic texture

Recompute a Primordial Spectrum and Test the Solver

This guide reruns the Lab’s spectra outside the browser. You test the solver against a closed-form answer first, then recompute fixed models, measure the tilt yourself and compare with published constraints. Every number below came from running these files.

Predict before you run

Write down what you expect. For the R2R^2 plateau with N∗=55N_*=55, the lowest-order formulas give ns≈0.9636n_s\approx0.9636 and r≈0.004r\approx0.004. For 12m2ϕ2\tfrac12m^2\phi^2 they give ns≈0.9640n_s\approx0.9640 and r≈0.144r\approx0.144.

Also predict the size of the step’s effect. A step placed 5959 e-folds before the end should disturb modes about four e-folds larger than the pivot, near k≈10−3 Mpc−1k\approx10^{-3}\,\mathrm{Mpc}^{-1}, and leave the pivot alone.

Reading: Planck Collaboration, Planck 2018 results. X. Constraints on inflation, arXiv:1807.06211v2 · Original background and mode calculations with an independent Python reference

Get the files and fix the environment

Download the ZIP below and extract it into a fresh directory. It contains the reference solver, the benchmark script, a comparison script, five input models and their expected outputs. There is no browser Engine in it.

Install the pinned versions in a virtual environment. The expected files were made with Python 3.9.6, NumPy 2.0.2 and SciPy 1.13.1, and every output records the versions that produced it.

python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt

Reading: Original background and mode calculations with an independent Python reference · CLASS explanatory.ini, lesgourg/class_public commit c5d93d01990116162b408b789b62ec5669fc4ea4

Test the solver on an exact answer first

Power-law inflation, V=V0e−λϕV=V_0e^{-\lambda\phi}, has constant ϵ=λ2/2\epsilon=\lambda^2/2, and its scalar and tensor spectra are known in closed form from Stewart and Lyth’s equations 31, 41 and 43. The benchmark compares the numerical spectra with that formula, not with the slow-roll estimate.

Our run covered λ\lambda from 0.020.02 to 0.30.3. The worst power error was 2.0×10−62.0\times10^{-6} and the worst Wronskian drift 4.0×10−74.0\times10^{-7}. The leading slow-roll formula was off by 1.1×10−41.1\times10^{-4} at ϵ=2×10−4\epsilon=2\times10^{-4} and by 2.6%2.6\% at ϵ=0.045\epsilon=0.045. That is why the closed form, not slow roll, is the test.

The script exits with an error if any check fails. Move on once it passes on your machine.

python verify_benchmarks.py my-benchmarks.json

Reading: Stewart & Lyth, A more accurate analytic calculation of the spectrum of cosmological perturbations produced during inflation (1993), gr-qc/9302019v1 · Original background and mode calculations with an independent Python reference

Recompute a fixed model

Each input names the potential, the amplitude V0V_0 in units of Mpl4M_{\mathrm{pl}}^4, the starting field, N∗N_*, the step and a grid of 2727 wavenumbers in Mpc−1\mathrm{Mpc}^{-1}. The step uses the tanh form of Adams, Cresswell and Easther’s equation 1, with its position and width given in field units.

The output holds the background, with total e-folds, pivot field and ϵ\epsilon there, then one row per wavenumber. Each row gives the scalar and tensor power, the slow-roll estimate, the exit time and the field at exit. Each preset takes about one second.

On the same software versions our fresh run matched the expected file exactly. A different SciPy may move the last digits; the comparison script fails above 10−410^{-4}, which is far larger than the solver error and far smaller than any physical effect discussed here.

python recompute_inflation_spectrum.py inputs/step-ripples.json my-step.json
python compare_with_expected.py my-step.json expected/step-ripples.json

Reading: Adams, Cresswell & Easther, Inflationary perturbations from a potential with a step (2001), astro-ph/0102236v2 · Original background and mode calculations with an independent Python reference

Measure the tilt and tensor ratio yourself

Make a three-point input around the pivot and difference the logarithm of the power. The snippet below does it for the plateau.

Our results: plateau ns=0.96490n_s=0.96490, r=0.00355r=0.00355; with the default step, the same to four decimal places; quadratic ns=0.96338n_s=0.96338, r=0.14403r=0.14403; shorter reheating, N∗=46N_*=46, ns=0.95826n_s=0.95826, r=0.00498r=0.00498.

The amplitude needs care. The plateau’s V0V_0 was chosen so that As=2.0989×10−9A_s=2.0989\times10^{-9}, matching Planck’s ln⁡(1010As)=3.044\ln(10^{10}A_s)=3.044. With the same V0V_0 the N∗=46N_*=46 model gives 1.4880×10−91.4880\times10^{-9}. Since PR∝V0\mathcal{P}_{\mathcal{R}}\propto V_0 at fixed N∗N_*, rescaling V0V_0 by 1.41051.4105 restores it without changing the tilt or rr.

import json, math, subprocess
model = json.load(open('inputs/smooth-plateau.json'))
model['kGridMpc'] = [0.049, 0.05, 0.051]
json.dump(model, open('tilt-input.json', 'w'))
subprocess.run(['python', 'recompute_inflation_spectrum.py', 'tilt-input.json', 'tilt-output.json'], check=True)
low, mid, high = json.load(open('tilt-output.json'))['spectrum']
print('n_s =', 1 + math.log(high['scalar'] / low['scalar']) / math.log(0.051 / 0.049))
print('r   =', mid['tensor'] / mid['scalar'])

Reading: Original background and mode calculations with an independent Python reference · Planck Collaboration, Planck 2018 results. X. Constraints on inflation, arXiv:1807.06211v2

Compare with published constraints

Planck 2018 X gives ns=0.9649±0.0042n_s=0.9649\pm0.0042 and ln⁡(1010As)=3.044±0.014\ln(10^{10}A_s)=3.044\pm0.014; PDG 2025 gives r<0.036r<0.036 at 95%95\% confidence. The plateau sits on the centre of the tilt band. The quadratic model fits the tilt but its rr is four times the bound. The N∗=46N_*=46 plateau is 1.6σ1.6\sigma low in tilt.

These are comparisons of primordial parameters, which were themselves fitted assuming a power-law spectrum. A model with a step must instead go through a Boltzmann code and the likelihood. CLASS can accept your own table through its external_Pk option, which is the natural next step; this course stops at the primordial spectrum.

Reading: Planck Collaboration, Planck 2018 results. X. Constraints on inflation, arXiv:1807.06211v2 · Ellis, Vennin & Wands, Review 23: Inflation, Review of Particle Physics (PDG 2025, revised August 2025) · CLASS explanatory.ini, lesgourg/class_public commit c5d93d01990116162b408b789b62ec5669fc4ea4

Failure cases we actually hit

Absolute tolerance. An early version used a fixed atol=10−30\mathrm{atol}=10^{-30}. For N∗=46N_*=46 the starting ∣R∣|\mathcal{R}| ranges from about 2×10−292\times10^{-29} to 10−2410^{-24} across the grid in these units, so the tolerance was loose. Over the 2727-point grid the power came out up to 0.55%0.55\% wrong and the Wronskian drifted by up to 0.88%0.88\%, while the integrator reported success. The plateau at N∗=55N_*=55 stayed below 10−410^{-4}. The fix scales the tolerance to each component’s starting size.

Step position. With the step crossed 5858 e-folds before the end, its ringing reached the pivot and moved the reported tilt. We moved the default step to 5959 e-folds and now check the pivot tilt against the smooth model.

Pivot choice for rr. The default step leaves rr at 0.05 Mpc−10.05\,\mathrm{Mpc}^{-1} unchanged, at 0.003550.00355, but raises it at 0.002 Mpc−10.002\,\mathrm{Mpc}^{-1} from 0.003180.00318 to 0.004410.00441. The Lab therefore reports rr at 0.05 Mpc−10.05\,\mathrm{Mpc}^{-1}.

Reading: Original background and mode calculations with an independent Python reference · Planck Collaboration, Planck 2018 results. X. Constraints on inflation, arXiv:1807.06211v2

What this reproduction does not establish

It is one canonical field in Einstein gravity, with a Bunch–Davies vacuum and no dynamics after ϵ=1\epsilon=1. It produces primordial spectra only; no transfer function or likelihood is applied, so no fit to data is claimed.

Agreement between the Lab’s integrator and this reference, within 2.5×10−42.5\times10^{-4} on all five presets, shows the two codes solve the same equations.

Reading: Original background and mode calculations with an independent Python reference · Ellis, Vennin & Wands, Review 23: Inflation, Review of Particle Physics (PDG 2025, revised August 2025)

Exercises and explained answers

  1. Rescale V0V_0 for the N∗=46N_*=46 model so that AsA_s matches Planck. What happens to nsn_s and rr?

    Read the explanation

    Multiply V0=1.1322×10−10V_0=1.1322\times10^{-10} by 2.0989/1.4880=1.41052.0989/1.4880=1.4105, giving 1.597×10−101.597\times10^{-10}. Both power spectra scale with V0V_0, and changing V0V_0 only rescales HH, leaving the e-fold history unchanged. So ns=0.95826n_s=0.95826 and r=0.00498r=0.00498 stay the same.

  2. Why did the fixed tolerance fail at N∗=46N_*=46 but not at N∗=55N_*=55?

    Read the explanation

    The size of R\mathcal{R} in these units depends on where a=1a=1 sits, which is arbitrary. For N∗=46N_*=46 the pivot starts about nine e-folds later, so the starting mode function is about six orders of magnitude smaller and a fixed 10−3010^{-30} is no longer small. Tolerances must be relative to each variable’s scale.

  3. Your comparison reports 3×10−53\times10^{-5} on a newer SciPy. Should you worry?

    Read the explanation

    No. It is below the 10−410^{-4} gate and comparable to small changes in an adaptive integrator. Check that the benchmark still passes; if it does, the difference is numerical noise.

Try the prediction

Check the Lab against your recomputation

  1. With the default preset, the Lab reads a tilt of 0.9650.965 and a tensor ratio of 3.55×10−33.55\times10^{-3}. Compare them with your 0.964900.96490 and 0.003550.00355.
  2. Choose Shorter reheating history. The Lab reads 0.9580.958 and 4.98×10−34.98\times10^{-3}. The Lab renormalises AsA_s, so only the amplitude differs from your raw run.
  3. Choose Steep slope, strong gravitational waves and confirm r≈0.144r\approx0.144.

Recompute the spectra yourself

Download the Python reference, benchmarks, inputs and expected outputs (23973 B)

NumPy and SciPy integrate the background and every mode from its vacuum state. The expected files were made with Python 3.9.6, NumPy 2.0.2 and SciPy 1.13.1. The ZIP contains no browser Engine and no paper text.

SHA-256 and what the files are

01825a57661f03e95e517178320bf1bd20f1bf050aae74318a37deb51a799a77

The five inputs are the fixed models behind the Lab presets. The expected outputs are our own model calculations, not observations. A fresh extraction reproduced them exactly on the same software versions.

Sources and calculation scope

  1. Planck Collaboration, Planck 2018 results. X. Constraints on inflation, arXiv:1807.06211v2

    Full v2 PDF (2 August 2019) read for Sections 4.2 and 7.1–7.3: equations 47–48, the step template in equations 57–62, Table 11 priors, Table 12 step results and Figure 28. The headline spectral index and amplitude quoted in this course come from its parameter tables.

  2. Ellis, Vennin & Wands, Review 23: Inflation, Review of Particle Physics (PDG 2025, revised August 2025)

    Full review read. Used: Section 23.3.4 equations 23.55–23.57 and its sentence on the ACT combination, Section 23.6 on reheating and the number of e-folds after the pivot exits, and Section 23.7.3.2 equations 23.101–23.103 for the sign convention of the local non-Gaussian amplitude and its single-field squeezed-limit value.

  3. Adams, Cresswell & Easther, Inflationary perturbations from a potential with a step (2001), astro-ph/0102236v2

    Full v2 read. Equation 1 defines the tanh step we use; equations 6–19 set out the mode equation in e-fold time and its initial data. Our code is written independently and puts the step on the Starobinsky plateau and on a quadratic potential, not only on the paper’s quadratic case.

  4. Stewart & Lyth, A more accurate analytic calculation of the spectrum of cosmological perturbations produced during inflation (1993), gr-qc/9302019v1

    Full v1 read, with printed pages 4–6 checked as images. Equations 31, 41 and 43 give the exact power-law-inflation spectra that our solver must reproduce.

  5. CLASS explanatory.ini, lesgourg/class_public commit c5d93d01990116162b408b789b62ec5669fc4ea4

    Primordial-spectrum options read: the pivot wavenumber setting, the inflation_V numerical mode and the external_Pk route for handing CLASS your own table. We did not run CLASS for this course.

  6. Original background and mode calculations with an independent Python reference

    Our own calculations: the Lab integrator and a separate NumPy/SciPy reference agree to better than three parts in ten thousand on all five presets. The ZIP holds the Python reference, closed-form benchmarks, five inputs and expected outputs. No Engine code and no paper text is included.

Keep reading

What this page links to directly

From quantum ripples to cosmic texture · Reading path

Horizon exit, the mode equation and spectral constraints

  1. ArticleHow a Quantum Ripple Becomes Cosmic Structure
  2. ArticleWhy a Stretched Ripple Stops Changing After Horizon Exit
  3. ArticleDeriving the Mode Equation Behind a Computed Spectrum
  4. ArticleWhat the Tilt, Tensors and Squeezed Triangles Measure
  5. You are hereRecompute a Primordial Spectrum and Test the Solver
  6. ArticleReading Planck’s Searches for Inflation Features and Non-Gaussianity
Something broken, confusing, or missing on this page?Tell us
What kind of feedback?

Sent with this page’s address, its Lab ID, the site language and your device type. Please leave out personal details. Feedback is kept for up to 12 months.Privacy policy