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
44Bou-Rabee's reference MATLAB implementation**, used as provided (paper
45arXiv:2506.18746). It's the orbit-based formulation: sample momentum, grow the
46orbit by doubling forward/backward, refine the leapfrog step within each step so
47the energy variation ≤ `δ`, terminate on a U-turn, and pick a draw from the
48orbit by its `log_softmax` weights. We added only `logsumexp`/`log_softmax`
49(standard helpers it calls) and a third output `O` on `walnuts` for the movie.
50`walnuts` takes the density as **function handles** (`@log_density`,
51`@grad_log_density`), which dispatch on the global `WTARGET` — keep the algorithm
52files target-agnostic. The verbatim originals + paper are in `missing_files/`
53(git-ignored).
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 54
55## Performance
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 57WALNUTS here uses **function-handle args, 2-D cell arrays, and recursion**, so it
58runs in the numbl **interpreter** (it does not JS-JIT). It's still fine —
59~1–5 ms/transition on these 2-D targets — but heavier than a flat loop, so keep
60`N` modest (`SAMPLE_CHOICES` tops out at 3000; the demo uses 1000 + 200 burn-in).
61Don't add a `%!numbl:assert_jit` guard; it would (correctly) fail.
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 62
63## Key files
65| File | Purpose |
66|------|---------|
67| `app/src/App.tsx` | Reads data, hosts the info panel |
68| `app/src/render/DensityView.tsx` | Canvas: density heatmap + sample scatter |
69| `app/src/bridge.ts` | `onData` / `onHostEvent` / `sendToMATLAB` (generic) |
cccc996Use Nawaf Bou-Rabee's reference WALNUTS implementationJeremy Magland 70| `helpers/walnuts.m` + building blocks | Nawaf's reference WALNUTS sampler |
71| `helpers/log_density.m` / `grad_log_density.m` | 2D targets (banana/gaussian/correlated/donut), dispatched on global `WTARGET` |
72| `walnuts_sampler.m` | Loops `walnuts(...)`, builds the density grid, opens the figure, handles events |
727e2e4Interactive WALNUTS sampling of a 2D banana targetJeremy Magland 73| `walnuts_demo.m` | Driver: addpath + seed + call the sampler |
75## Local iteration
77```
78cd app && npm install && npm run build # → app/dist/index.html
79cd ..
80npx tsx $NUMBL/src/cli.ts run walnuts_demo.m --plot # quick loop
81# or preview the GitHub Pages bundle:
82( cd $NUMBL && npm run build:site-viewer ) # one-time
83npx tsx $NUMBL/src/cli.ts build-site . --out _site --base /
84( cd _site && python3 -m http.server 8080 )
85```
87`$NUMBL` is a local clone of flatironinstitute/numbl. The real target is GitHub
88Pages, where the deploy builds numbl from `main`.