-
Notifications
You must be signed in to change notification settings - Fork 14
Hypercube plot
hypercube_plot(output, n_pbits=None, labels=None) (p_kit.visualization) plots a p-circuit's {-1,+1}^n_pbits state space from a sampled +/-1 trajectory (e.g. all_m from Solver.solve(), or a sequence of return_final=True states).
Above MAX_EXACT_DIMS (12) p-bits, 2^n_pbits vertices can no longer be enumerated — a 128-p-bit reservoir has 2^128 ≈ 3.4e38 states, more than atoms in the observable universe. Below that threshold you get the exact vertex/edge graph instead; this page covers the large-n fallback, which is a 2-or-3-panel statistical view.
A naive approach — PCA-project the trajectory to 3D, color by time — tends to look like a structureless tangle even when the underlying trajectory has strong, real structure. Two reasons:
- A "6% of variance" number is meaningless without a baseline. In a 128-dimensional space, pure noise still puts a few percent of variance in the top 3 components just from finite-sample effects. Whether 6% is "basically nothing" or "an enormous excess" depends entirely on what noise looks like at that sample size — you can't tell from the raw number.
- The most informative label usually isn't time. A raw scatter colored by step index shows when each state occurred, not why it looks the way it does. If some other variable actually organizes the space (e.g. "which token drove this state"), coloring by time will hide it completely.
The three panels below are designed to answer "is there structure, and what organizes it" directly, instead of asking you to eyeball a point cloud.
What it plots: C(dt) = ⟨m(t)·m(t+dt)⟩ / n_pbits — the average overlap between a state and itself dt samples later, against a dashed baseline computed by shuffling the trajectory (i.e. what "fully decorrelated" looks like for this data).
How to read it:
-
C(0) = 1by definition (a state always matches itself). - How fast the curve drops to the baseline is the system's relaxation/mixing time — how many steps of "memory" it has.
- A curve that stays elevated well above baseline for a long lag range means the dynamics have real short/medium-term memory. A curve that collapses to baseline in 1–2 steps means the state is nearly refreshed every step — any longer-range modeling has to come from an explicit memory mechanism (e.g. concatenating several past states), not from the raw dynamics itself.
- This is the discrete analogue of a diffusion/mean-squared-displacement curve: mean Hamming distance at lag
dtisn_pbits * (1 - C(dt)) / 2.
What it plots: blue bars are the real trajectory's explained-variance ratio per principal component; orange bars are the same computation on a null model — each p-bit's own time series independently shuffled (preserves each p-bit's bias/marginal, destroys all correlation). The title reports the top-3 excess in standard deviations above the null.
How to read it:
- Compare bar heights to judge how much variance is concentrated in a few directions vs. spread out.
- Compare the excess in std devs, not the raw percentages, to judge whether structure exists at all. The null's error bars are usually tiny, so even a modest-looking height difference can be tens of standard deviations — an unambiguous signal — while raw percentages alone can't tell you that.
- Many elevated components (not just the top 2–3) means the structure is real but diffuse — spread across many directions rather than collapsed onto a low-dimensional manifold. That's normal for a large, fixed, sparse random reservoir: nothing trains it to organize its own state space, only the readout on top of it is trained.
What it plots: the trajectory projected onto its top-3 PCA directions, colored by a label you supply — one label per sample (e.g. the token/character id driving that step). Only drawn when labels is passed. The title reports a separability ratio: between-group variance divided by within-group variance (higher = groups form tighter, more separated clusters; compare against the ratio for randomly shuffled labels to judge significance — near 0 either way means no separation).
How to read it:
- Visible, separated clusters + a separability ratio well above the shuffled-label baseline means that label is a real organizing variable for this space.
- If you don't have a natural per-step label, try the variable that's causally closest to what drives each state (e.g. "what input was applied this step"), not just any auxiliary label — a coarse or indirect grouping (e.g. a category derived from the next output rather than the current input) can dilute a real signal into noise.
Running this on a 128-p-bit sparse reservoir language model reading real text gives:
| panel | finding |
|---|---|
| relaxation |
C(1) ≈ 0.24, decays to baseline by dt ≈ 5, flat after — very short memory (~1–2 characters) |
| PCA vs. noise | top-3 excess ~50 std devs above noise — real structure, spread across many components |
| labeled (by driving character id) | separability ratio ~0.5–0.6 vs. ~0.02 for shuffled labels — strong clustering by current input character |
Put together: the reservoir briefly and strongly encodes "which character just arrived," relaxes back to near-baseline within a handful of steps, and any longer-range modeling downstream has to come from explicitly stacking several such snapshots — not from the reservoir dynamics holding a trace on its own.
| symptom | likely meaning |
|---|---|
| relaxation curve drops to baseline almost immediately | little/no temporal memory in the raw dynamics |
| relaxation curve stays elevated for many lags | real short/medium-term memory |
| PCA bars barely above noise, small std-dev excess | little exploitable low-dimensional structure |
| PCA bars clearly above noise across many components | real but diffuse structure — don't expect a clean 2–3D picture |
| labeled panel shows tight clusters, high separability ratio | that label is a genuine organizing variable |
| labeled panel looks the same as unlabeled, low separability ratio | try a different / more causally direct label before concluding "no structure" |