---
title: "Recompute a Primordial Spectrum and Test the Solver"
description: "Run a small Python reference, check it against exact power-law spectra, recompute five fixed models and compare their tilt and tensor ratio with Planck."
canonical_url: "https://sandboxphysics.com/stories/inflation-perturbations/recompute-a-primordial-spectrum/"
language: "en"
page_type: "story"
alternate_languages:
  zh-CN: "https://sandboxphysics.com/zh/stories/inflation-perturbations/recompute-a-primordial-spectrum/"
last_modified: "2026-11-12"
---

[From quantum ripples to cosmic texture](https://sandboxphysics.com/stories/inflation-perturbations/)

# Recompute a Primordial Spectrum and Test the Solver

Sandbox Physics · 2026-11-12

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.

## Before you begin

The mode-equation chapter. You need Python 3.9 or newer with NumPy and SciPy, and a terminal. No browser or Lab code is used.

## Predict before you run

Write down what you expect. For the $R^2$ plateau with $N_*=55$, the lowest-order formulas give $n_s\approx0.9636$ and $r\approx0.004$. For $\tfrac12m^2\phi^2$ they give $n_s\approx0.9640$ and $r\approx0.144$.

Also predict the size of the step’s effect. A step placed $59$ e-folds before the end should disturb modes about four e-folds larger than the pivot, near $k\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=V_0e^{-\lambda\phi}$, has constant $\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.02$ to $0.3$. The worst power error was $2.0\times10^{-6}$ and the worst Wronskian drift $4.0\times10^{-7}$. The leading slow-roll formula was off by $1.1\times10^{-4}$ at $\epsilon=2\times10^{-4}$ and by $2.6\%$ at $\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 $V_0$ in units of $M_{\mathrm{pl}}^4$, the starting field, $N_*$, the step and a grid of $27$ wavenumbers in $\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^{-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 $n_s=0.96490$, $r=0.00355$; with the default step, the same to four decimal places; quadratic $n_s=0.96338$, $r=0.14403$; shorter reheating, $N_*=46$, $n_s=0.95826$, $r=0.00498$.

The amplitude needs care. The plateau’s $V_0$ was chosen so that $A_s=2.0989\times10^{-9}$, matching Planck’s $\ln(10^{10}A_s)=3.044$. With the same $V_0$ the $N_*=46$ model gives $1.4880\times10^{-9}$. Since $\mathcal{P}_{\mathcal{R}}\propto V_0$ at fixed $N_*$, rescaling $V_0$ by $1.4105$ restores it without changing the tilt or $r$.

```
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 $n_s=0.9649\pm0.0042$ and $\ln(10^{10}A_s)=3.044\pm0.014$; PDG 2025 gives $r<0.036$ at $95\%$ confidence. The plateau sits on the centre of the tilt band. The quadratic model fits the tilt but its $r$ is four times the bound. The $N_*=46$ plateau is $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 $\mathrm{atol}=10^{-30}$. For $N_*=46$ the starting $|\mathcal{R}|$ ranges from about $2\times10^{-29}$ to $10^{-24}$ across the grid in these units, so the tolerance was loose. Over the $27$-point grid the power came out up to $0.55\%$ wrong and the Wronskian drifted by up to $0.88\%$, while the integrator reported success. The plateau at $N_*=55$ stayed below $10^{-4}$. The fix scales the tolerance to each component’s starting size.

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

Pivot choice for $r$. The default step leaves $r$ at $0.05\,\mathrm{Mpc}^{-1}$ unchanged, at $0.00355$, but raises it at $0.002\,\mathrm{Mpc}^{-1}$ from $0.00318$ to $0.00441$. The Lab therefore reports $r$ at $0.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 $\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\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 $V_0$ for the $N_*=46$ model so that $A_s$ matches Planck. What happens to $n_s$ and $r$?

   Read the explanation

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

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

   Read the explanation

   The size of $\mathcal{R}$ in these units depends on where $a=1$ sits, which is arbitrary. For $N_*=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^{-30}$ is no longer small. Tolerances must be relative to each variable’s scale.

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

   Read the explanation

   No. It is below the $10^{-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](https://sandboxphysics.com/labs/inflation-mode-freezing/)

1. With the default preset, the Lab reads a tilt of $0.965$ and a tensor ratio of $3.55\times10^{-3}$. Compare them with your $0.96490$ and $0.00355$.
2. Choose Shorter reheating history. The Lab reads $0.958$ and $4.98\times10^{-3}$. The Lab renormalises $A_s$, so only the amplitude differs from your raw run.
3. Choose Steep slope, strong gravitational waves and confirm $r\approx0.144$.

## Recompute the spectra yourself

[Download the Python reference, benchmarks, inputs and expected outputs](https://sandboxphysics.com/stories/inflation-perturbations/materials/inflation-spectrum-recompute-v1.zip) (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.

[Previous: What the Tilt, Tensors and Squeezed Triangles Measure](https://sandboxphysics.com/stories/inflation-perturbations/what-tilt-tensors-and-squeezed-triangles-measure/) [Next: Reading Planck’s Searches for Inflation Features and Non-Gaussianity](https://sandboxphysics.com/stories/inflation-perturbations/read-feature-and-non-gaussianity-searches/)

## Sources and calculation scope

1. [Planck Collaboration, Planck 2018 results. X. Constraints on inflation, arXiv:1807.06211v2](https://arxiv.org/abs/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)](https://pdg.lbl.gov/2025/reviews/rpp2025-rev-inflation.pdf)

   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](https://arxiv.org/abs/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](https://arxiv.org/abs/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](https://github.com/lesgourg/class_public/blob/c5d93d01990116162b408b789b62ec5669fc4ea4/explanatory.ini)

   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](https://sandboxphysics.com/stories/inflation-perturbations/materials/inflation-spectrum-recompute-v1.zip)

   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

From quantum ripples to cosmic texture · Reading path

### Horizon exit, the mode equation and spectral constraints

1. [Article **How a Quantum Ripple Becomes Cosmic Structure**](https://sandboxphysics.com/stories/inflation-perturbations/how-a-quantum-ripple-becomes-cosmic-structure/)
2. [Article **Why a Stretched Ripple Stops Changing After Horizon Exit**](https://sandboxphysics.com/stories/inflation-perturbations/why-a-stretched-ripple-stops-changing/)
3. [Article **Deriving the Mode Equation Behind a Computed Spectrum**](https://sandboxphysics.com/stories/inflation-perturbations/slow-roll-and-the-mode-equation/)
4. [Article **What the Tilt, Tensors and Squeezed Triangles Measure**](https://sandboxphysics.com/stories/inflation-perturbations/what-tilt-tensors-and-squeezed-triangles-measure/)
5. [You are here **Recompute a Primordial Spectrum and Test the Solver**](https://sandboxphysics.com/stories/inflation-perturbations/recompute-a-primordial-spectrum/)
6. [Article **Reading Planck’s Searches for Inflation Features and Non-Gaussianity**](https://sandboxphysics.com/stories/inflation-perturbations/read-feature-and-non-gaussianity-searches/)
