# research/period-doubling — the math behind *Period-Doubling, Played*

Supports the instrument **`/instruments/period-doubling/`** (ledger P10 #4) — a
rhythm machine on the logistic map `x → r·x·(1−x)`, where the period of the
rhythm you hear *is* the period of the orbit.

## What's here

- **`verify.mjs`** — proves, in the **same double precision the browser runs**,
  every fact the instrument promises:
  - **A. The period is real.** At named parameters the orbit settles to a cycle of
    the stated length (period 1 at r=2.8, 2 at 3.2, 4 at 3.5, 8 at 3.55, chaos at
    3.9), and the **period-3 window** holds a genuine 3-cycle just above
    `r = 1 + 2√2 = 3.8284271…` — the ¾ waltz that erupts out of chaos.
  - **B. The cascade & Feigenbaum's δ.** The superstable cascade `R_0..R_6`
    (`f^{2ⁿ}(½)=½`) is located by sign-change bisection; `R₀ = 2` and `R₁ = 1+√5`
    come out exact, and the gap ratios `(Rₙ−Rₙ₋₁)/(Rₙ₊₁−Rₙ)` converge:
    `4.7089 → 4.6808 → 4.6630 → 4.6684 → 4.6690`, agreeing with the independent
    **50-digit** value in `research/feigenbaum/delta_of_p.json`
    (`δ = 4.66920160910299…`) to **2.5×10⁻⁴**. The onset landmarks `b₁ = 3` and
    `b₂ = 1+√6` (period 2→4) are exact closed forms.
  - **C. The chaos meter is real.** The **Lyapunov exponent**
    `λ = ⟨ln|r(1−2x)|⟩` is negative in the periodic windows (the rhythm locks)
    and positive in the chaotic bands (it never repeats) — λ is the rigorous
    definition of chaos, and is what the page's meter shows. At `r = 4`,
    `λ = ln 2` exactly (seeded off the dyadic ½, which is a pre-image of 0 there).

  Run: `node verify.mjs` (prints checks, non-zero exit on failure) ·
  `node verify.mjs emit` (writes `embed.js`).

- **`embed.js`** — the verified **reference** constants the page displays as
  ground truth (the closed-form landmarks `3`, `1+√6`, `r∞`, `1+2√2`, and the
  50-digit δ). Everything else — the bifurcation diagram, the live period, the
  live δ cascade, λ — the page recomputes in the browser, house-style.

- **`verify-page.mjs`** — loads the built page in a real (headless) browser and
  checks the UI + the math driving the audio (the same `detectPeriod` /
  `lyapunov` / `liveDelta` the scheduler reads, exposed on `window.__pd`):
  **25 checks**, desktop + mobile, no JS errors, no overflow. Audio can't be
  heard headless, so the *sound's source* (period, pitch frequencies, downbeat
  meter) is what's asserted, not the waveform.

  Run: `npm run build && node verify-page.mjs`.

## The honesty bar (audio)

The **sound is the object**: every beat is the next iterate of `r·x·(1−x)`, run
live; the period you hear is the period the math has; the louder downbeat marks a
true cycle boundary. The **free choices** — the pentatonic pitch map, the tempo,
the root, the marimba-ish timbre — are applied *identically at every r*, so they
change the tune but never the period. Near a fork the orbit settles slowly
(critical slowing-down), so the live readout there honestly reads "settling /
chaos" rather than faking a clean number.

## Sources

R. M. May, *Nature* 261 (1976) 459–467 (the logistic map as a population model) ·
M. J. Feigenbaum, *J. Stat. Phys.* 19 (1978) 25–52 (δ, universality) ·
O. E. Lanford III, *Bull. AMS* 6 (1982) 427–434 (computer-assisted proof) ·
P. Cvitanović, *Universality in Chaos* (1989) · OEIS **A006890** (δ). The δ
cross-check reuses `research/feigenbaum/` (50-digit mpmath).
