Skip to main content

Follow the source behind the result.

Search the paper sections, open their original context and follow the checks they actually cite. The knowledge atlas explains the result; this library locates its source.

v86_nstar_reheating.py

verification/v86_nstar_reheating.py

This is a registered verification module. Read its original code and the paper sections that cite it, then follow the linked claim to its present classification.

Read the publication code on this page

The registered Python source is shown as text. Displaying it does not execute the code.

"""v86 -- N_star from scalaron reheating: the external band sharpened to a point [P].

Until now N_star (e-folds at horizon exit) was an EXTERNAL reheating input,
demoted explicitly in origin_theory.tex and registered only as a BAND
N_star in [50, 60] in the frozen registry (predictions_frozen.json).  But TFPT
fixes the scalaron mass from the axioms,

    M_scal = c3^{7/2} Mbar = 3.06e13 GeV          [I] (v28/v36/v80),

and once the scalaron mass is fixed, STANDARD physics (no new TFPT input)
fixes the reheating history of R^2 inflation:

  1. scalaron decay rate into minimally coupled scalars
         Gamma = N_eff * M^3/(48 pi Mbar^2),  N_eff = 4 (SM Higgs doublet)
     (Starobinsky 1980; Vilenkin 1985; Gorbunov & Panin 2010);
  2. reheating at H = Gamma:  rho_reh = 3 Gamma^2 Mbar^2,
         T_reh = (30 rho_reh / (pi^2 g_star))^{1/4},  g_star = 106.75;
  3. the standard pivot-matching equation (w = 0 during scalaron
     oscillations, entropy conservation a^3 s = const afterwards):
         ln k_star = -N_star + (1/3) ln(rho_reh/rho_end) + ln(T0/T_reh)
                     + (1/3) ln(g_{s,0}/g_star) + ln H_star .

Solving self-consistently on the exact Starobinsky potential
V = (3/4) M^2 Mbar^2 (1 - e^{-sqrt(2/3) phi/Mbar})^2:

    T_reh = 9.6e9 GeV,   N_star(k=0.05/Mpc) = 51.44,
    n_s = 1 - 2/N_star = 0.9611,   r = 12/N_star^2 = 0.00454 .

Cross-check: at the older pivot k = 0.002/Mpc the chain gives N_star = 54.7,
reproducing the known literature value (~54) for R^2-inflation reheating.

Robustness (the point of the exercise): N_star depends only LOGARITHMICALLY
on the decay-channel ambiguity -- N_eff from 1 to 100 moves N_star by < 0.8
e-folds, and even instantaneous reheating only allows N_star <= 55.7.  So the
former free band collapses to a point with an O(0.5) theoretical width.

HONEST TYPING AND TENSION (do not oversell):
  * the whole chain is [P] -- standard imported physics (decay channel,
    g_star, w=0 oscillation phase), conditional on M_Starobinsky = M_scal;
    the only compiler input is M_scal;
  * the frozen registry is NOT touched: N_star = 51.4 lies inside the frozen
    band [50, 60], so the freeze discipline holds (v84 still passes);
  * consequence n_s = 0.9611 sits ~1 sigma BELOW Planck 2018 (0.9649 +-
    0.0042) and INCREASES the known DESI-combined tension (~0.9743).  This is
    recorded as an honest, falsifiable sharpening: if precision data settle
    at n_s >= 0.967 the scalaron-reheating chain (not just N_star) is wrong;
  * A_s COHERENCE (the sharper consequence): with M_scal fixed, A_s is also
    predicted, A_s(51.44) = 1.76e-9 = -11.4 sigma vs Planck 2.105(30)e-9.
    The A_s-preferred N_star = 56.2 exceeds even the instantaneous-reheating
    bound 55.6 by 0.6 e-folds (instantaneous gives 2.06e-9 = -1.5 sigma,
    compatible).  So within standard physics the measured A_s REQUIRES
    near-instantaneous reheating, and the slow Higgs-channel point 51.4 is
    A_s-disfavoured.  The [P] point is therefore CONDITIONAL on the decay
    channel; the frozen band [50, 60] remains the prediction surface of
    record.  Nothing here is promoted.
"""
import mpmath as mp
from tfpt_constants import check, summary, reset, c3, Mbar, PI

G_STAR = mp.mpf('106.75')     # SM relativistic dof at T_reh ~ 1e10 GeV
G_S0 = mp.mpf('3.91')         # entropy dof today
T0_GEV = mp.mpf('2.3486e-13')  # 2.7255 K
GEV_PER_INV_MPC = mp.mpf('1.9733e-14') / mp.mpf('3.0857e24')
N_EFF_HIGGS = 4               # real scalar dof of the SM Higgs doublet


def starobinsky():
    """Exact Starobinsky potential data in units Mbar = 1."""
    m2 = (c3**(mp.mpf(7) / 2))**2          # (M/Mbar)^2 = c3^7
    b = mp.sqrt(mp.mpf(2) / 3)
    V = lambda f: mp.mpf(3) / 4 * m2 * (1 - mp.e**(-b * f))**2
    Vp = lambda f: mp.mpf(3) / 4 * m2 * 2 * (1 - mp.e**(-b * f)) * b * mp.e**(-b * f)
    eps = lambda f: mp.mpf(1) / 2 * (Vp(f) / V(f))**2
    f_end = mp.findroot(lambda f: eps(f) - 1, mp.mpf('0.6'))
    return V, Vp, f_end


def nstar_chain(n_eff, kstar_inv_mpc, rho_reh_override=None):
    """Solve the pivot-matching equation self-consistently; returns
    (N_star, T_reh, Gamma)."""
    V, Vp, f_end = starobinsky()
    M = c3**(mp.mpf(7) / 2) * Mbar
    gamma = n_eff * M**3 / (48 * PI * Mbar**2)
    rho_end = mp.mpf(4) / 3 * V(f_end) * Mbar**4
    rho_reh = rho_reh_override if rho_reh_override is not None \
        else 3 * gamma**2 * Mbar**2
    t_reh = (30 * rho_reh / (PI**2 * G_STAR))**mp.mpf('0.25')
    kstar = mp.mpf(kstar_inv_mpc) * GEV_PER_INV_MPC

    def n_of_phi(f):
        return mp.quad(lambda x: V(x) / Vp(x), [f_end, f])

    def phi_of_n(n):
        return mp.findroot(lambda f: n_of_phi(f) - n, mp.mpf('5.0'))

    def mismatch(ns):
        v_st = V(phi_of_n(ns)) * Mbar**4
        h_st = mp.sqrt(v_st / 3) / Mbar
        return (-ns + mp.log(rho_reh / rho_end) / 3 + mp.log(T0_GEV / t_reh)
                + mp.log(G_S0 / G_STAR) / 3 + mp.log(h_st)) - mp.log(kstar)

    return mp.findroot(mismatch, mp.mpf('54')), t_reh, gamma


def run():
    reset()
    mp.mp.dps = 30
    print("v86 N_star from scalaron reheating (band -> point, [P])")

    M = c3**(mp.mpf(7) / 2) * Mbar
    check("compiler input: M_scal = c3^{7/2} Mbar = 3.0600e13 GeV [I]",
          M, mp.mpf('3.0599695e13'), tol=mp.mpf('1e-7'))

    V, Vp, f_end = starobinsky()
    check("end of slow roll: V_end^{1/4} = 5.881e15 GeV",
          (V(f_end))**mp.mpf('0.25') * Mbar, mp.mpf('5.88089e15'),
          tol=mp.mpf('1e-5'))

    # baseline: SM Higgs doublet channel
    ns, t_reh, gamma = nstar_chain(N_EFF_HIGGS, '0.05')
    check("scalaron width Gamma = 4 M^3/(48 pi Mbar^2) = 128.1 GeV [P]",
          gamma, mp.mpf('128.14'), tol=mp.mpf('1e-3'))
    check("reheating temperature T_reh = 9.55e9 GeV [P]",
          t_reh, mp.mpf('9.5505e9'), tol=mp.mpf('1e-3'))
    check("N_star(k=0.05/Mpc) = 51.44 (the former free band, now a point) [P]",
          ns, mp.mpf('51.4406'), tol=mp.mpf('1e-4'))
    check("consequence n_s = 1 - 2/N_star = 0.9611 [P]",
          1 - 2 / ns, mp.mpf('0.961120'), tol=mp.mpf('1e-5'))
    check("consequence r = 12/N_star^2 = 0.00454 [P] (CMB-S4/LiteBIRD target)",
          12 / ns**2, mp.mpf('0.0045352'), tol=mp.mpf('1e-4'))

    # literature cross-check at the older pivot
    ns002, _, _ = nstar_chain(N_EFF_HIGGS, '0.002')
    check("cross-check k=0.002/Mpc: N_star = 54.7 (reproduces the known "
          "R^2-reheating literature value ~54)",
          ns002, mp.mpf('54.6602'), tol=mp.mpf('1e-4'))

    # robustness: only log sensitivity to the decay-channel ambiguity
    ns_lo, _, _ = nstar_chain(1, '0.05')
    ns_hi, _, _ = nstar_chain(100, '0.05')
    check("channel robustness: N_eff 1 -> 100 moves N_star by < 0.8 e-folds "
          "(51.21 .. 51.98)",
          ns_hi - ns_lo < mp.mpf('0.8') and ns_lo > 51 and ns_hi < 52)

    # absolute upper bound: instantaneous reheating
    rho_end = mp.mpf(4) / 3 * V(f_end) * Mbar**4
    ns_inst, _, _ = nstar_chain(N_EFF_HIGGS, '0.05', rho_reh_override=rho_end)
    check("instantaneous-reheating upper bound: N_star <= 55.7",
          ns_inst, mp.mpf('55.6125'), tol=mp.mpf('1e-4'))

    # freeze discipline: the sharpened point lies INSIDE the frozen band;
    # predictions_frozen.json is untouched (v84 remains the lock)
    check("freeze discipline: 50 < N_star = 51.4 < 60 (inside the frozen "
          "registry band; registry NOT modified)",
          mp.mpf(50) < ns < mp.mpf(60))

    # honest tension, recorded not hidden: n_s = 0.9611 is ~1 sigma below
    # Planck 2018 (0.9649 +- 0.0042) and increases the DESI-combined tension
    planck_ns, planck_sig = mp.mpf('0.9649'), mp.mpf('0.0042')
    pull = (planck_ns - (1 - 2 / ns)) / planck_sig
    check("honest tension: n_s pull vs Planck 2018 = +0.90 sigma (recorded; "
          "kill: robust n_s >= 0.967 falsifies the reheating chain)",
          pull, mp.mpf('0.90'), tol=mp.mpf('0.02'))

    # A_s coherence (the sharper consequence -- recorded, not hidden):
    # with M_scal fixed, A_s = N_star^2 c3^7/(24 pi^2) is ALSO predicted.
    planck_As, planck_As_sig = mp.mpf('2.105e-9'), mp.mpf('0.030e-9')
    As = lambda n: n**2 * c3**7 / (24 * PI**2)
    check("A_s coherence: A_s(N_star=51.44) = 1.764e-9 -> -11.4 sigma vs "
          "Planck (the Higgs-channel chain UNDERPREDICTS A_s; recorded)",
          (As(ns) - planck_As) / planck_As_sig, mp.mpf('-11.38'),
          tol=mp.mpf('1e-2'))
    nA = mp.sqrt(planck_As * 24 * PI**2 / c3**7)
    check("A_s-preferred N_star = 56.20 exceeds even the instantaneous-"
          "reheating bound 55.61 by 0.59 e-folds",
          nA, mp.mpf('56.198'), tol=mp.mpf('1e-4'))
    check("instantaneous limit: A_s(55.61) = 2.061e-9 = -1.5 sigma "
          "(compatible) => within standard physics the A_s match REQUIRES "
          "near-instantaneous reheating; the slow Higgs-channel point "
          "N_star=51.4 is A_s-disfavoured. VERDICT: the [P] point is "
          "conditional on the decay channel; the frozen band [50,60] stays "
          "the prediction surface of record",
          (As(ns_inst) - planck_As) / planck_As_sig > mp.mpf('-1.6'))

    # the dichotomy, quantified: at fixed N_star = 51.4 the measured A_s
    # would need M_scal raised by +9.2% -- but M_scal = c3^{7/2} Mbar is
    # [I]-locked (exponent 7 fourfold forced).  So the future discriminator:
    # either a fast preheating mechanism [P] (then N_star -> 55-56 and the
    # c3^7 normalisation stands), or precision cosmology pins slow reheating
    # and the exponent-7 reading fails.  Both outcomes are decisive.
    M_needed = mp.sqrt(planck_As / As(ns))
    check("dichotomy quantified: matching A_s at N_star=51.4 needs "
          "M_scal x 1.092 (+9.2%) -- impossible at locked c3^{7/2} => "
          "either fast preheating [P] or the exponent-7 normalisation "
          "fails (decisive future discriminator)",
          M_needed, mp.mpf('1.0924'), tol=mp.mpf('1e-3'))

    return summary("v86 N_star reheating")


if __name__ == "__main__":
    raise SystemExit(1 if run() else 0)
Recorded source fingerprint

c9c84aff0b6e87e42e4b61c547e5f1eb005c9ca582ae89ebe9062ee8233351f5

Paper sections that cite this module

The module’s catalogue entry retains all 24 section references.

What this source index covers

The public registry includes 116 document views, 6,693 section records and 985 physical LaTeX sources. Active publication documents, research material and archives retain their recorded roles. This is source navigation, not a new semantic review or proof run.