SI Code 2a · Parts 1–3

How many iterations does the calibration need?

Four gates decide whether a sampler budget is adequate. Three of them ask whether the chains agree with each other; only one asks whether they found the right answer. The forward grid is now complete across all three models — and the inverse model turns out to need a different question entirely.

Forward grid
81 fits
univariate
400 / 600
EIV multivariate
400 / 800
T0-shift
300 / 900
Inverse (Part 3)
300 / 1000 · M=50

The four gates

A budget passes only if all four hold at once. They are deliberately different in kind — the first three are self-consistency checks that a broken sampler can still pass, and the fourth is the one that catches it.

Split R̂

< 1.01

Compares variance between chains against variance within them. At 1.00 the chains are exploring one common distribution; above 1.01 they are still describing different places.

Catches: warmup too short for the sampler to adapt. Misses: four chains that are all confidently wrong in the same way.

Bulk ESS

≥ 400

How many independent draws the correlated chain is worth. 400 across 4 chains is 100 each — the usual floor for trusting a posterior mean.

Catches: chains that move but crawl. Misses: bias — a stuck sampler can report high ESS for the wrong distribution.

Divergent transitions

= 0

The integrator failing on curvature it cannot resolve. Divergences are not noise: they mark regions the sampler could not enter, so the posterior is biased away from them.

Catches: geometry the step size cannot handle. Any non-zero count invalidates the run regardless of R̂.

Drift vs reference

|z| ≤ 0.1

Distance from a long reference run’s posterior mean, in units of that reference’s SD. The only gate that asks whether this budget reproduces the answer rather than merely agreeing with itself.

Catches: everything above passing on a posterior that is quietly shifted. This is the gate that makes the other three meaningful.

What you are turning, and what you are watching

Two different vocabularies get mixed together in the output. These are the knobs:

iter_warmup
Adaptation, not sampling. Stan uses these iterations to tune step size and the mass matrix, then throws the draws away. This is the setting that determines whether the sampler can navigate the posterior at all.
iter_sampling
Draws kept per chain, after warmup. Buys precision (ESS). Whether it buys anything else depends on the model — see Finding 1, which is narrower than it first appeared.
chains
Independent runs from different starting points. Held at 4 throughout, because R̂ is a between-chain statistic — a budget adequate at 4 chains says nothing about the same budget at 2.
multiplier
iter_sampling / iter_warmup. A convenience for laying the grid out, not a quantity Stan knows about.
M
Calibration draws marginalised per observation in the inverse model only. Not an MCMC setting at all — it sets Monte Carlo error in the likelihood itself (~5.8% at 300, ~4.5% at 500), which no number of iterations reduces.

And these are the calibration parameters being watched. R̂ and ESS are reported per parameter; the gates use the worst one.

t0_crtp
Inflection point of the logistic — the temperature at which Ring Index responds most steeply. °C.
k_crtp
Slope at the inflection. Sets proxy sensitivity, so it propagates directly into reconstructed-temperature uncertainty.
b_crtp
Lower asymptote — the Ring Index floor as temperature falls.
v_crtp
Shape parameter controlling asymmetry of the generalized logistic. Weakly identified by construction, and the slowest to settle in the univariate fit.
sigma_proxyObs_crtp
Process noise only — oceanographic scatter and bioturbation. Analytical measurement error enters separately in quadrature, so this is not a residual SD.
beta_G23_crtp
beta_NO3_crtp
Non-thermal slopes in the parent EIV model, added to the response outside the logistic. Units of Scaled RI.
gamma_G23_crtp
gamma_NO3_crtp
The same predictors in bounded‑T, applied to the inflection point inside the logistic instead. Units of °C. Expected to be the harder geometry, since they trade off directly against t0 — an expectation the grid did not support.

Three models, three budgets

All 81 cells complete, N = 1513 coretop sites, 4 chains, one seed per cell. Each recommendation is the cheapest cell clearing all four gates, measured against the 1000/1000 incumbent.

Recommended budget per model. Speed-up is against that model’s own 1000/1000 run.
modelwarmup / samplingwallvs 1000/1000 max R̂min ESSmax |z|cells passing
univariate400 / 60016.3 s1.92×1.005684280.0328 of 26
EIV multivariate400 / 800140.6 s1.16×1.0097417000.0497 of 26
T0-shift300 / 90079.3 s1.35×1.0091215110.0688 of 26

Bounded‑T is the easiest of the three, not the hardest

It converges at warmup 300 where the parent EIV model needs 400, and it does so in 79 s against the parent’s 141 s. The reasoning for giving it its own grid is unaffected and still stands — a budget does not transfer between models, which is the entire premise of this exercise. Only the guess about which direction the difference would run was wrong.

Superseded: the earlier draft of this page, and the notebook prose it was written from, predicted bounded‑T would set the binding budget because gamma enters inside the logistic and goes near-degenerate with t0. Both have been corrected in the repository rather than quietly deleted — the expectation is why the third grid was run at all.

Finding 1 — warmup binds; whether sampling helps depends on the model

Each cell holds the number of parameters left with R̂ > 1.01. The univariate panel is the one that produced the original headline: read across a row and sampling three times longer barely moves it, read down and crossing warmup 400 collapses it to zero.

The two EIV panels do not behave that way. Both axes matter there, because what is being counted is dominated by 3026 per-site latent variables — and those do respond to more draws.

univariate · ~7 parameters
warmup1.5×2.5×
10078777
20076611
30076766
40030100
50070000
100000
EIV multivariate · ~3040 parameters
warmup1.5×2.5×
10018341317967647392
2007543101022713
300428992053
40017924000
500583000
100000
T0-shift · ~3040 parameters
warmup1.5×2.5×
100193614271064752467
2008993921355323
30021638320
4001079100
500260000
100000

The counts are not comparable across panels — the univariate model has about seven parameters and the EIV models about 3040, so a 7 and a 754 describe very different failures. Within a panel the gradient is the message.

The practical advice survives, with its scope narrowed: if a fit will not converge, raise warmup first. Adding draws to an unadapted chain buys ESS on a posterior that has not settled, which makes a bad answer look more precise. For the EIV models, raising both is what actually clears the latent variables.

Two univariate cells still break the pattern: 500 / 500 reports 7 while its neighbours report 0, and 300 stays bad where 200 / 500 is nearly clean. Each cell is a single seed, so these are almost certainly noise — see the caveats.

Finding 2 — the strict gate works, but it is gating on nuisance parameters

The EIV models add a latent true value per site for both G2/3 and NO3 — 3026 extra parameters, each informed by roughly one observation. They dominate the maximum, and they are not the calibration.

How completely they dominate it is worth stating precisely: across the full grid, the worst-R̂ parameter is a per-site latent in 27 of 27 EIV cells and 27 of 27 bounded‑T cells. Not once, in 54 fits, is the slowest parameter one the calibration actually uses.

Cheapest cell clearing all four gates, under each definition of “max R̂”.
modelgatebudgetwallspeed-up R̂ usedcells passing
EIV multivariateall parameters400 / 800140.6 s1.16×1.009747 of 26
EIV multivariatecalibration only200 / 30063.3 s2.58×1.0052321 of 26
T0-shiftall parameters300 / 90079.3 s1.35×1.009128 of 26
T0-shiftcalibration only200 / 20043.3 s2.46×1.0066122 of 26

A choice to justify, not a bug to fix

Core-gating is roughly 2.2× cheaper than strict gating for both EIV models, and it is defensible: the parameters it drops are per-site nuisance variables that never enter a reconstruction. But it is a choice that has to be argued for in the SI, because the strict gate does work — it is simply paying to converge 3026 variables nobody reads.

Superseded: at 6 of 27 EIV cells this page said “the criterion as written will reject every EIV budget” and called it a false negative requiring a max_rhat_core gate before any EIV recommendation could be quoted. With all 27 cells in, 7 pass the strict gate. The observation about which parameters are slowest was right; the conclusion drawn from it was too strong, because the failing cells were all at low warmup.

The same question, outside the grid

The proxy-convention comparison (Part 2) refits the whole calibration under three crenarchaeol ring conventions at a deliberately generous 1000/1000. Three of those posteriors are flagged as failing — and every one fails on a latent, exactly as the grid predicts.

Posteriors flagged FAIL by the strict gate, re-checked on calibration parameters only.
posteriormax R̂ (all)verdict max R̂ (calibration)slowest calibration parameterfile
univ_priorApprox · SST · thermal only · scaledRI_cren51.01407FAIL1.00417v_crtptx.v026.GHPU.sst.sri05.p0.001.fwd.nc
multiv_priorApprox_eiv · SST · G23 · scaledRI_cren31.01268FAIL1.00060k_crtpgen_logi_fixed_hier_crtp_multiv_priorApprox_eiv_SST_gdgt23ratio_scaledRI_cren3_041626.nc
multiv_priorApprox_eiv · SST · G23+NO3 · scaledRI1.01188FAIL1.00020beta_NO3_crtptx.v026.GHEA.sst.sri.G23-N10.001.fwd.nc
multiv_priorApprox_eiv · SST · G23+NO3 · scaledRI_cren31.01023FAIL1.00001k_crtpgen_logi_fixed_hier_crtp_multiv_priorApprox_eiv_SST_gdgt23ratio_no3_1.0_scaledRI_cren3.nc
multiv_priorApprox_eiv · SST · G23+NO3 · scaledRI_cren31.01023FAIL1.00001k_crtpgen_logi_fixed_hier_crtp_multiv_priorApprox_eiv_SST_gdgt23ratio_no3_1.0_scaledRI_cren3_041626_eiv.nc

The calibration behind the main-text figures carries a headline R̂ of 1.01023 — and a calibration-parameter R̂ of 1.00001. Every parameter that reaches a reconstruction is converged with room to spare.

Part 3 — the inverse model asks a different question

It is tempting to carry the forward budget across to the reconstructions. The Stan source says not to. The forward EIV model is hierarchical with ~3000 correlated latent variables, which is why its warmup binds. The inverse model declares one parameter block:

parameters { vector[N] t_est; }  // the ONLY parameter in this model

The calibration draws arrive as data, not parameters, and the target is a sum of per-sample terms with no coupling between samples. The posterior therefore factorises into N independent one-dimensional posteriors, where a diagonal metric is exact rather than approximate — the easiest geometry HMC ever sees.

So N is a cost knob, not a difficulty knob, and what binds instead is M and saturation: where Ring Index approaches the upper asymptote the likelihood goes flat in temperature and t_est is prior-dominated. Neither is fixed by more iterations. Part 3 sweeps 4 budgets × M ∈ {300, 500} against 200 coretop sites spread over the proxy range rather than sampled at random — the near-saturated warm end is 15.6% of the compilation and 30% of this subset, and it is where the paleo sites live.

Because coretop temperature is known, this half can be scored on accuracy as well as convergence: bias, RMSE, and 68% / 90% interval coverage against measured SST. The sites trained the calibration, so those numbers are a tuning diagnostic and never a validation statistic.

Two defects the first Part 3 run exposed

No inverse run has ever recorded its convergence. The invT path calls sample_from_model, which returned draws without ever summarising the fit — so all 35 cached reconstructions carry no R̂, no ESS, no divergence count. The loss is irreversible after the fact: the fit object goes out of scope, and the draws are reduced to quantiles before saving. Fixed, with tests.

The drift gate was set below the noise floor. Worst-site drift came in at 0.24–0.45 °C and did not fall as the budget rose — 1000/1000 at M=300 drifted further from the reference than 300/1000 at M=500 did. That is Monte Carlo jitter in the single reference realisation, not a budget effect, and a 0.1 °C threshold under it can never be met at any cost. The sweep now runs a seed replicate of the reference configuration and gates on whichever is larger, the threshold or the measured seed-to-seed drift.

Inverse budget sweep over 200 coretop sites, cheapest first. Accuracy is against measured SST and is in-sample.
warmup / samplingMwallmax R̂ min ESSRMSE °Ccov 68drift °C
300 / 10002527 s1.005815714.3190.6350.411
500 / 10002533 s1.006012514.3070.6200.422
300 / 10005047 s1.005613754.3140.6250.337
500 / 10005048 s1.006013684.3130.6300.418
300 / 100010076 s1.007314694.3070.6250.322
500 / 100010081 s1.005913364.3100.6250.301
300 / 1000200128 s1.006515624.3180.6250.301
500 / 1000200134 s1.005314764.3040.6250.315
300 / 1000300171 s1.006114674.3050.6250.296
500 / 1000300189 s1.005114534.3100.6300.259
300 / 1000500277 s1.004815054.3090.6200.296
500 / 1000  replicate500304 s1.005914504.3050.6200.371
500 / 1000500304 s1.007214544.3000.6250.000

Recommended: warmup 300, sampling 1000, M = 50

R̂ = 1.0056 · ESS = 1375 · worst-site drift 0.337 °C against a measured seed-to-seed floor of 0.371 °C. At 47 s that is 6.48× faster than the richest cell swept.

What the manuscript refit uses

Forward 400/1000, inverse 500/1000 with M = 300 (scripts/paper/run_manuscript_refits.py).

The inverse budget is a deliberate choice over the recommender’s output, on three grounds: it clears R̂ < 1.01 and ESS ≥ 400 with room; its accuracy is indistinguishable from every other cell; and it avoids warmup 300, which is the one place the grid genuinely does discriminate — two of its three cells fail R̂. Over 64 reconstructions it costs about three hours rather than six.

Stated plainly because it is a judgement call: the drift gate does not pass this cell, for the reason given above. More seed replicates would either vindicate it or move it on evidence.

RMSE varies by 0.02 °C across a 11.5× spread in cost, and M = 300 is indistinguishable from M = 500. The defensible SI statement is therefore not “we picked this budget” but “the answer does not depend on it”, which is the stronger claim.

Coverage is the open question: 68% intervals contain the measured SST 62%–64% of the time and 90% intervals 86%–86%, stable across every cell, so it is not sampling noise. Some of that is by construction — a constant prior mean, an in-sample set, a subset deliberately weighted toward the hard end — but systematic under-coverage deserves an explanation before it reaches an SI.

Caveats worth stating in the SI

  • One seed per cell in the forward grid. Every number there is a single draw from a noisy process, and the two univariate anomalies are the visible evidence. Part 3 now carries a seed replicate; the forward grid still does not, and a defensible published recommendation wants 3–5 seeds near the threshold.
  • E‑BFMI is not being reported. This cmdstanpy build does not expose it, so the diagnostic returns -1 / UNKNOWN for every run. It is therefore not one of the four gates, and no claim about energy-transition efficiency should be made from this sweep.
  • Iteration counts transfer between machines; seconds do not. Every speed-up here is specific to this 8-core box, running nothing else alongside.
  • Thresholds are conventions, not laws. R̂ < 1.01 and ESS ≥ 400 follow Vehtari et al. (2021); the |z| ≤ 0.1 accuracy bound and the 0.1 °C drift bound are this study’s own choices and should be stated as such.
  • Part 2 reused the SRI03 calibration rather than refitting it. The resume logic found it cached, so the SRI03 column of the proxy comparison comes from the earlier run, not from this sweep.

What happened next

Every item this page listed as pending has now been resolved:

  • The remaining EIV cells finished, including the 1000/4000 reference the drift gate needs.
  • Bounded‑T ran as a third model — and came back easier than the parent, not harder.
  • The EIV gate question was settled empirically rather than by switching the gate: strict gating works, core gating is 2.2× cheaper, and the choice between them is now an SI argument with numbers behind it.
  • A seed repeat was added — to Part 3, where it turned out to be load-bearing rather than a refinement.

Still open: the corrected Part 3 run, the under-coverage question, and a seed-repeat pass on the forward cells nearest the threshold.