3Tips for future agents. Patterned after the sibling `hitandrun-interactive`
4project (same numbl + uihtml two-way bridge, 2D canvas figure).
6## Architecture
8- `app/` — React single-file widget (`npm run build` → `app/dist/index.html`).
9- `*.m` at root — `walnuts_demo.m` (driver) and `walnuts_sampler.m` (figure plumbing).
10- `helpers/` — `walnuts.m` (the sampler) and the target `log_density.m` / `grad_log_density.m`, put on the path by the driver via `addpath('helpers')`.
11- `numbl-project.json` — project metadata; `entry` is the landing page.
13`addpath('helpers')` must be the **first statement** in the driver (numbl
14resolves the search path before running, and addpath can't live inside a
15function file). Run `walnuts_demo.m`, not the sampler directly.
17## Data flow (uihtml bridge)
19- **MATLAB → figure:** `uihtml(..., 'Data', struct)` / `sendEventToHTMLSource(src, name, data)`.
20- **Figure → MATLAB:** `sendToMATLAB(name, value)` (see `app/src/bridge.ts`), received via `HTMLEventReceivedFcn`.
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 22The script sends the density grid + samples once, then handles three requests
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 23(`walnuts_sampler.m` `on_event`):
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 25- `resample` `{n, h, delta, target}` → fresh chain → `samples` event.
26- `setTarget` `{target, …}` → new target → full `data` event (density + samples).
27- `movie` `{h, delta, target}` → record a few transitions' orbits → `movie` event.
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 28
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 29The figure's controls (target dropdown, samples / step `h` / energy-tol `δ`
30sliders, Resample) drive `resample`/`setTarget`; the **▶ Movie** button drives
31`movie` and animates the returned orbits (`App.tsx` + `DensityView.tsx`).
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 32
33### Trajectory recording
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 35`walnuts.m` exposes the orbit it built as a third output `O` (a cell of
36`{theta, rho}` states) — purely for the movie; it doesn't affect the algorithm.
37`record_movie` (in `walnuts_sampler.m`) runs a few transitions, pulls each
38orbit's positions, and packs `px/py/seg` + the start and selected draw.
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 39
40## The algorithm
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 42`helpers/walnuts.m` and its building blocks (`extend_orbit_forward/backward`,
43`micro`, `leapfrog`, `u_turn`/`sub_u_turn`, `p_micro`/`pmf_p_micro`) are **Nawaf
38237c7Cite published JMLR version of the WALNUTS paperJeremy Magland 44Bou-Rabee's reference MATLAB implementation**, used as provided (paper: JMLR
4527(113):1–64, 2026, https://jmlr.org/papers/v27/25-1452.html; preprint
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 46arXiv:2506.18746). It's the orbit-based formulation: sample momentum, grow the
47orbit by doubling forward/backward, refine the leapfrog step within each step so
48the energy variation ≤ `δ`, terminate on a U-turn, and pick a draw from the
49orbit by its `log_softmax` weights. We added only `logsumexp`/`log_softmax`
50(standard helpers it calls) and a third output `O` on `walnuts` for the movie.
51`walnuts` takes the density as **function handles** (`@log_density`,
52`@grad_log_density`), which dispatch on the global `WTARGET` — keep the algorithm
53files target-agnostic. The verbatim originals + paper are in `missing_files/`
54(git-ignored).
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 55
56## Performance
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 58WALNUTS here uses **function-handle args, 2-D cell arrays, and recursion**, so it
59runs in the numbl **interpreter** (it does not JS-JIT). It's still fine —
60~1–5 ms/transition on these 2-D targets — but heavier than a flat loop, so keep
61`N` modest (`SAMPLE_CHOICES` tops out at 3000; the demo uses 1000 + 200 burn-in).
62Don't add a `%!numbl:assert_jit` guard; it would (correctly) fail.
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 63
64## Key files
66| File | Purpose |
67|------|---------|
68| `app/src/App.tsx` | Reads data, hosts the info panel |
69| `app/src/render/DensityView.tsx` | Canvas: density heatmap + sample scatter |
70| `app/src/bridge.ts` | `onData` / `onHostEvent` / `sendToMATLAB` (generic) |
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 71| `helpers/walnuts.m` + building blocks | Nawaf's reference WALNUTS sampler |
72| `helpers/log_density.m` / `grad_log_density.m` | 2D targets (banana/gaussian/correlated/donut), dispatched on global `WTARGET` |
73| `walnuts_sampler.m` | Loops `walnuts(...)`, builds the density grid, opens the figure, handles events |
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 74| `walnuts_demo.m` | Driver: addpath + seed + call the sampler |
76## Local iteration
78```
79cd app && npm install && npm run build # → app/dist/index.html
80cd ..
81npx tsx $NUMBL/src/cli.ts run walnuts_demo.m --plot # quick loop
82# or preview the GitHub Pages bundle:
83( cd $NUMBL && npm run build:site-viewer ) # one-time
84npx tsx $NUMBL/src/cli.ts build-site . --out _site --base /
85( cd _site && python3 -m http.server 8080 )
86```
88`$NUMBL` is a local clone of flatironinstitute/numbl. The real target is GitHub
89Pages, where the deploy builds numbl from `main`.