aidoesscience
aidoessciencefindings › Reaction–diffusion scale selection
ValidatingOracle-validated

Reaction–diffusion / Turing scale selection

Does a structureless chemical soup pick a length scale on its own — and is that scale the fastest-growing Turing mode of the linearized dynamics, recoverable from nothing but the raw PDE?

Measured by the lab
11.94815
Known value
11.947825
Relative error
2.75e-5

Units: dimensionless Gray–Scott length units (k_max = 0.5258853 rad/unit; F=0.0866, k=0.0605, Du=0.16, Dv=0.08)

▶ Run this simulationRead how it works

The finding

Reaction–diffusion / Turing scale selection — the emergent length from the raw Gray–Scott PDE: with NOTHING coded but a 5-point Laplacian + the kinetics f = −uv² + F(1−u), g = uv² − (F+k)v (no dispersion relation, no Jacobian, no closed form), a homogeneous state that is ODE-stable (tr J = −0.030) yet destabilized by UNEQUAL diffusion selects the fastest-growing wavelength λ̂ = 11.94815 ± 2.7e-5 vs Turing's λ_c = 2π/k_max = 11.94782 (2.8e-5 rel, 8 seeds) — the whole measured growth curve σ̂(κ) lands on the eigenvalue curve to 1.7e-5, the unstable band is confined to κ ∈ [0.27, 0.81], scaling both diffusivities by s slides λ ∝ √s (log–log slope 0.49981), and the historical rival — EQUAL diffusivities — kills every mode (max σ̂ = −0.019, band power ×3.3e-8): differential diffusion isn't a detail, it IS the mechanism, exactly as Turing 1952 requires

Method

Raw Gray–Scott only. The generator codes ONE thing the module also codes: the 5-point toroidal Laplacian plus the Gray–Scott kinetics, stepped by explicit Euler (f64, h=0.5, dt=0.2, 192² torus). No dispersion relation, no Jacobian, no closed form is in the recovery path: the homogeneous 'blue' steady state is found by finite-difference Newton on (f,g)=0; it is seeded with 1e-8 broadband noise; each Fourier mode (nx,ny) is projected out of the raw v-field at 8 snapshots and its growth rate σ̂ is the LS slope of ln|a| vs t, inverted through the exact Euler map σ = (e^{m·dt}−1)/dt. The selected scale is the vertex of a cubic fit through clean modes (r² ≥ 0.9999) within ±0.07 in κ of the observed argmax — plotted against each mode's exact discrete-Laplacian eigenvalue κ, the von-Neumann-style scorer correction that removes all lattice bias. The scorer alone holds Turing's known λ_c, the eigenvalue curve σ(q), and the band edges. Rival: the SAME machinery with EQUAL diffusivities. 12 gates in scripts/reactdiff-derisk.mjs (~16 s): 7 physics gates plus an honest-module certificate (H–L) that EXECUTES the shipped ReactionDiffusionModule.ts — sha-pinned, type-stripped, lockstepped 1800 calls bit-exact against a statics-built replica; tamper ⇒ exit 1. ?world=reactdiff.

Measurements, controls & cross-checks

Recovered se

2.6500e-5

Worst seed rel error

3.5400e-5

Seeds

8

Steady state

U star
0.4884313
V star
0.3011682
Tr J
-0.030202
Newton residual
0
Ode stability
a 1e-3 well-mixed kick decays 1.4e-3 → 9.3e-14 over t=3000 — the state is stable to spatially-uniform perturbations, so the pattern is diffusion-DRIVEN, not a reaction instability

Dispersion curve

Clean modes
51
Max abs dev from eigenvalue
1.7000e-5
Sigma max
0.0094666635
Note
the measured growth rate of every one of 51 tracked modes lands on the kinetics-Jacobian eigenvalue curve σ(κ) to 1.7e-5 (≈0.18% of σ_max) — the emergent growth IS linear stability, mode by mode, not just at the peak

Instability band

Kappa
  • 0.071530564
  • 0.65908008
Leaks
0
Note
no clean mode with σ̂ > 2e-4 lies outside the predicted band (±3%): the medium amplifies a finite window of scales and damps the rest, the signature of a Turing instability

Diffusive scaling

Scales s
  • 0.5
  • 2
  • 4
Worst ratio dev
0.000448
Loglog slope
0.49981
Note
scaling BOTH diffusivities by s is an exact rescaling of space, so λ̂(s) = λ̂(1)·√s point-by-point (slope ½) — the selected length is set by diffusion against reaction (λ ~ √(D·τ)), not by the grid, the box, or the noise

Rival equal diffusivity

D
0.12
Max sigma
-0.0194
Band power ratio
3.3300e-8
Note
the SAME machinery with Du = Dv (same mean diffusion) collapses Turing's condition to D·tr J > 0, impossible for the ODE-stable state: every mode decays and the band power falls ×3.3e-8 — no band, no peak, no pattern. Differential diffusion is the whole mechanism (Turing's necessity of unequal rates)

Module estimator

Regime
Pearson self-replicating (F=0.0545, k=0.062) — the module's on-screen regime, NOT the linear-Turing point
Lambda cells
13.07
Sd cells
0.24
Cv
0.019
Drift per 3k steps
0.021
Seeds
  • 7
  • 1
  • 2
  • 3
Note
the module's autocorrelation estimator, replicated byte-for-byte on its f32 200×130 grid, gives a seed-independent (CV 1.9%) and quasi-stationary (drift 2.1%/3000 steps) λ — but this is a NONLINEAR coarsening scale in the far-from-equilibrium regime with no closed form, disclosed and NOT scored against Turing's λ_c (the module's own honest framing). The oracle validates the DIFFERENT, cited claim — linear scale selection at the Turing point — which the module does not itself run on screen

Module certificate

Gates
H module-pin · I init-exec · J lockstep-1800 · K dt-twins · L display-closure
Class
frozen-init (hall/conway/fractal lineage) — every mulberry32 draw is in _seedField; the dynamics slice draws nothing
Src sha256
d2d88f3b9851849cc84eb6d3700612fb8a7a775ca742d1aed9bf9655efadc4d4
Rng census
2 Math.random sites, BOTH outside the dynamics and both EXECUTED, not merely scanned: the no-seed constructor fallback (seeded init draws 0, unseeded exactly 1, seed === (draw·0xffffffff)>>>0) and the 'r' re-seed key handler (1 draw + λ-history push + λ reset). 5 rng() sites, all in _seedField: 1 blob-count + 3 per blob + 26,000 noise draws = 26,043 for seed 7 (14 blobs); the live stream sits at exactly 26,043 both before AND after the 1800-call lockstep — the PDE is deterministic f32 arithmetic
Lockstep
1800 calls at fl(1/120), bit-exact every call: accumulator, tick count, λ, population, HUD text, thinInstanceCount, bufferUpdates, bounds; the 26k-float u and v fields compared on every tick, the 416k-float render buffer on every measure. 450 ticks, gap census {4:450} — 4·fl(1/120) ≡ fl(1/30) EXACTLY, so the accumulator returns to a true zero and the cadence never drifts. HUD 360 writes / 14 distinct, final text sha-pinned
Lambda trajectory
all 15 measured λ values Object.is-pinned as exact doubles, including a null at tick 90: the autocorrelation genuinely loses its interior peak while the blob fronts collide, and the HUD honestly displays '—' for that second rather than a stale number
Display closure
CROSS-CODE-PATH IDENTITY — the executed module's on-screen λ at substep 5400 is Object.is-equal to gate 7's independently written moduleLambda instrument (13.027941109516162): two separately authored f32 pipelines land on the same bit pattern, so the screen value IS the disclosed measurement, not a resemblance of it
Display latency
the HUD refreshes on every 5th render (calls 1, 6, …, 1796) while the final measure lands at call 1800, so the last-written HUD lags the state by one measure — ≤5 calls ≈ 42 ms. Measured, not assumed; the gate pins the lagged value (13.1 cells / 2.61 u), which is what a viewer actually sees
Dt twins
the accumulator machinery is LIVE, not vestigial: dt=999 fires the budget-3 cap (3 ticks) and then the overflow reset (acc → 0); dt=0 ticks nothing; dt=fl(1/60) lockstepped 240 calls bit-exact at 120 ticks, census {2:120} (exact halving)
Tampers
sha ⇒ H alone. Science tamper (0.999× the autocatalytic gain in the v update — a pure dynamics edit no init state, HUD constant, or sha can see) ⇒ J diverges at call 4, the FIRST PDE tick, plus K and L; H and I stay green. known_value 11.9478 → 12.5 ⇒ the lambda gate fails at rel 4.4e-2 with the recovery byte-unchanged at 11.94815; all three exit 1

What it reduces to

Turing's diffusion-driven instability (Phil. Trans. R. Soc. B 237, 37, 1952): a homogeneous steady state stable to well-mixed perturbations (tr J < 0, det J > 0) is destabilized by unequal diffusion, and the emerging pattern's scale is the fastest-growing wavenumber k_max = argmax σ(k²) of the linearized dynamics σ(k²) = larger eigenvalue of J − k²·diag(Du,Dv). For Gray–Scott kinetics this gives λ_c = 2π/k_max = 11.9478 length units. Non-circular because the generator is one level MORE primitive than the law: it steps only the raw PDE (Laplacian + kinetics) and finds the steady state by numerical Newton; the Jacobian, the eigenvalue curve σ(q), k_max, the band edges and λ_c live ONLY in the scorer — every one is read off measured per-mode growth rates, never fed into the simulation. The decisive control is the historical one: with EQUAL diffusivities (Turing's counterfactual) the identical machinery kills all modes and forms no pattern — a max-growth sign flip of ~2e-2 that no tuning can undo — because differential diffusion is the mechanism. Opens the reaction–diffusion / morphogenesis family (distinct from the SOC worlds sandpile/baksneppen and the growth worlds kpz/dla: here a length scale, not a scaling exponent, is selected). Honest scope: the on-screen module runs the far-from-equilibrium Pearson regime whose coarsening length has no closed form; this finding validates the linear-Turing scale-selection claim the module's framing points at but does not itself measure — the module_estimator block discloses the gap.

Module systematics

CERTIFIED (gates H–L, 2026-07-27): the module is untouched, and the shipped file itself is now EXECUTED by the oracle rather than described — sha-pinned, mechanically type-stripped, and lockstepped 1800 calls bit-exact against a replica built from its own statics. Three things that were prose before are executed facts now. (1) The on-screen λ is the disclosed measurement: the executed module's λ at substep 5400 is Object.is-equal to gate 7's independently written instrument, 13.027941109516162 — a cross-code-path identity, not a resemblance. (2) The display has a measured latency, not zero: the %5 HUD cadence lags the state by one measure, ≤42 ms, so the number a viewer reads is the tick-420 value (13.1 cells / 2.61 u) while the state holds tick 450 — pinned as such. (3) The instrument's honest gap is pinned too: at tick 90 the autocorrelation genuinely has no interior peak (the blob fronts are still colliding) and the HUD shows '—' rather than a stale λ; that null is one of 15 Object.is-pinned trajectory values. Randomness is fully accounted: 26,043 mulberry32 draws all inside _seedField, the stream frozen at that exact position before AND after the lockstep, and both Math.random sites (no-seed fallback, 'r' re-seed key) executed under counting stubs rather than merely grepped. The remaining gap is scientific, not instrumental: the module runs a DIFFERENT experiment than the oracle validates. On screen it steps the far-from-equilibrium Pearson regime (F=0.0545, k=0.062) and measures a NONLINEAR coarsening wavelength from the activator autocorrelation — which the module already frames honestly as an emergent length with no closed-form value. The oracle instead validates the cited claim the module's framing gestures at: linear Turing scale selection at a genuinely Turing-unstable point (F=0.0866, k=0.0605), recovered from per-mode growth rates. Gate 7 reproduces the module's exact f32 estimator and confirms it is seed-independent (CV 1.9%) and quasi-stationary (drift 2.1%/3k steps) — an honest characterization of the on-screen number (13.07 cells), disclosed as coarsening, not scored against λ_c. The gap is the module's regime, not a bug: closing it fully would mean adding a linear-regime on-screen mode, deferred as a module change out of this run's scope.

Notes

1 retry — first full run was 6/7 with the diffusive-scaling gate at 6.3e-3 (> 2e-3): the cubic fit window was held FIXED in κ while scaling both D maps the dispersion curve to q/s, so a fixed κ-window covers a different fraction of the (rescaled) peak per s and the cubic-truncation bias varied across the sweep. Fixed by scaling the fit half-width as HALF/s (identical window in the rescaled variable q·s) — worst ratio dev dropped to 4.5e-4, slope 0.49981; no tolerance touched, the physics was exact all along (κ-space σ_s(q) = σ_1(sq)). Prototype-first (2 scratchpad scripts) set three design choices before the oracle: (a) noise 1e-8 not 1e-6 — at 1e-6 the difference-wavevector quadratic products of the kinetics measurably contaminate slow-mode growth and bias the curve gate; (b) cubic vertex not quadratic — the σ(κ) peak is skewed, biasing a quadratic vertex −6.6e-3 vs cubic 3e-5 (the blackbody lesson); (c) score in κ-space against the exact discrete-Laplacian eigenvalue, the reaction–diffusion analogue of the waves oracle's von Neumann correction, so the argmax needs no lattice fudge. Tamper self-test: known_value → 12.5 ⇒ lambda gate FAILs (rel 4.4e-2), exit 1, recovered λ̂ unchanged at 11.94815; restored by hand. Scope: only reactdiff-owned files touched (oracle pair + finding + fragment + loop line); no src/ change, gate = build + derisk. — 2026-07-27 REFINER (validated → validated + honest-module): appended gates H–L, append-only (the 7 physics gates are byte-untouched), no module edit, no tolerance change. Prototype-first in the scratchpad discovered every pin by execution and the first full derisk run was 11/12 — the single miss was my own prediction, not the science: I had assumed the HUD quotes the current λ, but the %5 render cadence writes at calls 1, 6, …, 1796 while the last measure lands at call 1800, so the display lags one measure. Fixed by pinning what a viewer actually sees (the tick-420 value) and disclosing the ≤42 ms latency — the module was right, my model of it was wrong. Tampers this run: sha ⇒ H only; science tamper (0.999× the autocatalytic gain in the v update) ⇒ J diverges at call 4 (the first PDE tick) + K + L, with H and I green — the predicted blast radius, because this world's HUD quotes only tamper-invariant constants (F, k, seed) and λ stays null until tick 30, so unlike cooperation's init-frozen display there is nothing for a science tamper to poison at call 1; known_value ⇒ lambda gate only, recovery byte-unchanged.

Confidence & reproduction

Confidence
high
Validation
derisk-pass
Re-run the check
npm run derisk -- reactdiff (scripts/reactdiff-derisk.mjs)
Oracle
scripts/oracles/reactdiff.reference.json

Sources

A. M. Turing, 'The Chemical Basis of Morphogenesis', Phil. Trans. R. Soc. B 237, 37–72 (1952); P. Gray & S. K. Scott, Chem. Eng. Sci. 39, 1087 (1984); J. E. Pearson, 'Complex Patterns in a Simple System', Science 261, 189–192 (1993); J. D. Murray, Mathematical Biology II, ch. 2–3 (3rd ed., 2003) — dispersion relation σ(k²), Turing conditions, k_max (scorer side only).

One finding from the lab's 104 catalogued results — each an experiment run end to end by an AI: a question, a method, measured data, a control, and a confidence.