Skip to content

Commit 15ac505

Browse files
committed
update
1 parent de828cf commit 15ac505

40 files changed

Lines changed: 4408 additions & 0 deletions
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"permissions": { "allow": ["Skill"] },
3+
"settingSources": ["user", "project"]
4+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
name: notebook-builder
3+
description: >
4+
How to assemble, execute, and validate the project Jupyter notebook
5+
programmatically (with nbformat), so the notebook stays reproducible and is
6+
built the same way every time. Use this skill WHENEVER the task is to create,
7+
extend, rebuild, re-run, or check a notebook in this repo (e.g.
8+
ResolutionRefPairing.ipynb), add a section/chapter, regenerate its figures, or
9+
verify it executes without errors. Always build notebooks with the scripts
10+
here rather than editing JSON by hand or pasting large code blobs.
11+
---
12+
13+
# Notebook builder
14+
15+
Notebooks are BUILD ARTIFACTS. The source of truth for physics is
16+
`src/pairinglib`; notebook code cells should `import pairinglib as pl` and call
17+
the library, not re-define it. This keeps the tested library and the narrative
18+
in sync.
19+
20+
## Workflow (always in this order)
21+
1. **Plan the cells.** A cell is either a markdown narrative cell or a code cell.
22+
Group: intro -> model -> coarse VQE -> prolongation -> refinement ->
23+
four-particle analysis -> rodeo -> summary. Read the `pairing-model` and
24+
`vqe-circuits` skills first for conventions and the API.
25+
2. **Assemble** with `scripts/build_notebook.py` (uses nbformat; never hand-edit
26+
the .ipynb JSON). It takes an ordered list of (kind, source) cells.
27+
3. **Execute** with `scripts/execute_notebook.py` (jupyter nbconvert --execute,
28+
timeout generous: the HEA k=3 optimisation alone is ~60 s).
29+
4. **Check** with `scripts/check_notebook.py`: asserts zero error outputs, a
30+
minimum figure count, and that the benchmark anchor numbers
31+
(FCI/CCD/UCCSD at k=2,3; refined overlaps; rodeo acceptance->p) appear in the
32+
outputs. Treat a failing check as a build failure.
33+
34+
## Rules
35+
- Keep markdown prose first-person-plural and paper-like (this notebook is the
36+
source for the article). One concept per code cell; a figure-producing cell
37+
ends in `plt.show()`.
38+
- Numbers quoted in markdown must come from a cell that actually computed them.
39+
- Do not use `localStorage`/browser APIs; this is a Python kernel notebook.
40+
- After any change, re-run execute + check before declaring done.
41+
42+
## Common entry points
43+
- "add a section X to the notebook" -> append cells, execute, check.
44+
- "rebuild the notebook from scratch" -> run the full builder, execute, check.
45+
- "the notebook errors" -> execute, read the first error output, fix the cell or
46+
the library, repeat.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env python3
2+
"""Assemble a notebook from an ordered cell list. Import and call build().
3+
Cells: list of ("md"|"code", source_string). Never hand-edit .ipynb JSON."""
4+
import sys, nbformat as nbf
5+
6+
def build(cells, out_path):
7+
nb = nbf.v4.new_notebook()
8+
nb["cells"] = [nbf.v4.new_markdown_cell(s) if k == "md"
9+
else nbf.v4.new_code_cell(s) for k, s in cells]
10+
nb["metadata"]["kernelspec"] = {"display_name": "Python 3",
11+
"language": "python", "name": "python3"}
12+
nbf.write(nb, out_path)
13+
print(f"wrote {out_path} ({len(nb['cells'])} cells)")
14+
15+
if __name__ == "__main__":
16+
print("import build() from this module; pass cells=[('md'|'code', src), ...]")
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env python3
2+
"""Validate an executed notebook: no errors, >= min figures, anchor numbers present.
3+
Usage: check_notebook.py NB [min_figs]"""
4+
import sys, json
5+
nb = json.load(open(sys.argv[1])); min_figs = int(sys.argv[2]) if len(sys.argv) > 2 else 6
6+
errs, figs, text = [], 0, []
7+
for i, c in enumerate(nb["cells"]):
8+
if c["cell_type"] != "code": continue
9+
for o in c.get("outputs", []):
10+
if o.get("output_type") == "error": errs.append((i, o.get("ename")))
11+
if o.get("output_type") == "display_data" and "image/png" in o.get("data", {}): figs += 1
12+
if "text" in o: text.append("".join(o["text"]))
13+
blob = "\n".join(text)
14+
anchors = ["0.794697", "0.635548", "acceptance"] # FCI(k=3), FCI(k=4), rodeo
15+
missing = [a for a in anchors if a not in blob]
16+
ok = not errs and figs >= min_figs and not missing
17+
print(f"errors={errs or 'none'} figures={figs} (min {min_figs}) missing_anchors={missing or 'none'}")
18+
print("CHECK PASSED" if ok else "CHECK FAILED")
19+
sys.exit(0 if ok else 1)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env python3
2+
"""Execute a notebook in place. Usage: execute_notebook.py NB [timeout_s]."""
3+
import sys, subprocess
4+
nb = sys.argv[1]; timeout = sys.argv[2] if len(sys.argv) > 2 else "1200"
5+
cmd = ["python3", "-m", "jupyter", "nbconvert", "--to", "notebook",
6+
"--execute", "--inplace", f"--ExecutePreprocessor.timeout={timeout}", nb]
7+
sys.exit(subprocess.call(cmd))
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
name: pairing-model
3+
description: >
4+
Physics conventions and the validated Python API for the constant-pairing
5+
Hamiltonian (nuclear/condensed-matter pairing model). Use this skill WHENEVER
6+
the task touches the pairing model, seniority-zero spectra, the
7+
delta/g Hamiltonian, Jordan-Wigner encoding of pairs, Hartree-Fock pairing
8+
energies, FCI/CCD/UCCSD benchmarks for pairing, or the `pairinglib` package.
9+
Consult it before writing any pairing physics so the conventions (level
10+
index, qubit ordering, sign of g, benchmark numbers) stay consistent across
11+
the notebook, the library, and the paper.
12+
---
13+
14+
# Pairing model: conventions and API
15+
16+
This project studies the constant-pairing Hamiltonian as a controlled testbed
17+
for the resolution-refinement + rodeo eigenstate-preparation pipeline. Always
18+
use the conventions below; they are baked into `src/pairinglib` and the paper.
19+
20+
## Hamiltonian and conventions (do not deviate)
21+
- `H = delta * sum_p p * sum_sigma n_{p,sigma} - (g/2) * sum_{p,q} a+_{p up} a+_{p dn} a_{q dn} a_{q up}`
22+
- `delta = 1` throughout. Level `p` (0-indexed) has single-particle energy `delta*p`.
23+
- Qubit index `= 2*p + sigma`, with `sigma = 0` (up), `1` (down); a `k`-level
24+
problem uses `2k` qubits. Big-endian: qubit `j` carries bit `(n-1-j)`.
25+
- The force conserves seniority, so the `N`-paired ground state lies entirely in
26+
the seniority-zero subspace; the full `N`-sector FCI equals the seniority-0 result.
27+
- Hartree-Fock fills the lowest `N/2` levels; `E_HF(N=4, g) = 2 - g`.
28+
- "Basis refinement" means increasing `k` at FIXED `N` (the basis/qubit count
29+
grows; the particle number does not).
30+
31+
## Validated benchmark numbers (N=4, g=1) — use as regression anchors
32+
| k | qubits | FCI | CCD | UCCSD |
33+
|---|--------|-----------|-----------|-----------|
34+
| 2 | 4 | 1.000000 | 1.000000 | 1.000000 |
35+
| 3 | 6 | 0.794697 | 0.794697 | 0.794697 |
36+
| 4 | 8 | 0.635548 | 0.630443 | 0.636987 |
37+
| 8 | 16 | 0.145559 | 0.097263 | 0.157856 |
38+
UCCSD is variational (>= FCI); CCD over-binds (< FCI). Singles vanish (seniority).
39+
40+
## Library API (import from `pairinglib`)
41+
See `references/library-api.md` for full signatures. Do NOT redefine these in
42+
notebooks or scripts — import them, so there is a single tested source of truth.
43+
44+
## Common pitfalls
45+
- `np.eye(2, dtype=complex)` — the 2nd positional arg of `np.eye` is the column
46+
count, not the dtype.
47+
- Never shadow stdlib modules with file names (e.g. a file called `re.py`).
48+
- The dense JW pair-interaction operator `W = sum_{p,q} A+_p A_q` is already
49+
Hermitian; use `H = H_kin - (g/2) W` (do not add `W + W.dag`, that double counts).
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# pairinglib API reference
2+
3+
## hamiltonian.py
4+
- `build_sector(k, N) -> (nq, states, index)` — fixed-N Fock sector (bitstring list + lookup).
5+
- `H_pairing_sparse(k, g, N, states, index, delta=1.0) -> csr_matrix` — sparse N-sector H.
6+
- `fci_ground(H) -> float` — lowest eigenvalue (exact).
7+
- `E_HF(N, g, delta=1.0) -> float` — Hartree-Fock energy.
8+
- `build_H_full(k, g, delta=1.0) -> ndarray` — dense H over the full 2^(2k) space (HEA/gate-UCCSD).
9+
10+
## ccd.py
11+
- `run_ccd(k, g, N, delta=1.0, ...) -> (E, iters)` — coupled-cluster doubles.
12+
13+
## uccsd.py (operator-level / statevector)
14+
- `uccsd_pool(k, N) -> (singles, doubles)`
15+
- `setup_uccsd(k, N, delta=1.0) -> dict(nq, states, index, ...)`
16+
- `uccsd_vqe(setup, H, n_trotter=1, ...) -> (E, x, energy_fn, grad_fn)`
17+
18+
## gates.py
19+
- `apply_1q(psi, U, q, n)`, `apply_cnot(psi, c, t, n)`, `Ry(th)`, `Rz(th)`, `Rx(th)`
20+
- `pauli_exp(psi, phi, pauli, n)` — exp(-i phi/2 P) via basis change + CNOT ladder + Rz.
21+
22+
## gate_uccsd.py (gate-level circuits)
23+
- `make_single(i, a, n)`, `make_double(i, j, a, b, n)` — Pauli terms of an excitation.
24+
- `apply_exc_circuit(psi, theta, terms, n)`
25+
- `gate_uccsd_setup(k, N) -> dict(nq, terms, gens, hf, P, ncnot, nrot)`
26+
- `gate_uccsd_vqe(k, N, g, setup) -> (E, nit)`
27+
- `gate_uccsd_state(k, N, g) -> (E, statevector)`
28+
29+
## refine.py
30+
- `prolong_matrix(k_low, k_high, N) -> ndarray` — gate-free basis embedding.
31+
- `refine_state(N, k_high, T, k_low=2, M=160, mu_buf=0.6, g=1.0) -> (psi, H_high)`
32+
- `refine_NK(N, k_high, Ts, ...) -> dict(ov, en, Eh, El, gap, ov0, E0)`
33+
34+
## rodeo.py
35+
- `rodeo_post0(v, U, t, E) -> (state, prob)` — post-selected one-cycle filter.
36+
- `rodeo_cycle_ancilla(v, U, t, E)` — explicit ancilla circuit (same map).
37+
- `rodeo_sweep(v0, H, ts, E) -> (state, cumulative_acceptance)`
38+
- `rodeo_allzero_prob(v0, H, ts, E) -> float` — for energy scans.
39+
- `rodeo_track(v0, H, ts, E, target) -> (fidelity_array, acceptance_array)`
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
name: physics-paper
3+
description: >
4+
How to build the LaTeX scientific article from the notebook: extract the
5+
notebook figures, write/maintain the paper in the project's article style, and
6+
compile to PDF. Use this skill WHENEVER the task is to create, edit, or compile
7+
the paper (eigenq_pairing.tex), pull figures out of the notebook into
8+
paper/figs, update the author list or bibliography, or turn notebook results
9+
into article prose. Follow `references/article-conventions.md` for the house
10+
style (article class, authblk author block, figure/caption rules).
11+
---
12+
13+
# Physics paper builder
14+
15+
The article is generated FROM the executed notebook: figures are extracted, and
16+
every quantitative claim must trace back to a notebook output. Do not invent
17+
numbers.
18+
19+
## Workflow
20+
1. **Extract figures** from the executed notebook into `paper/figs/`:
21+
`python scripts/extract_figures.py notebooks/ResolutionRefPairing.ipynb paper/figs`
22+
It writes `fig1.png ...` in cell order and prints a cell->figure map; choose
23+
which to include and reference them with `\includegraphics{figs/figN.png}`.
24+
2. **Write / update** `paper/eigenq_pairing.tex` following
25+
`references/article-conventions.md` (and reuse `assets/article-template.tex`
26+
as the starting skeleton for a new paper).
27+
3. **Compile**: `bash scripts/build_paper.sh paper/eigenq_pairing.tex` (runs
28+
pdflatex twice to resolve references; fails loudly on LaTeX errors or
29+
undefined citations/references).
30+
31+
## House rules
32+
- Author list in ALPHABETICAL order by surname, with `authblk` affiliation
33+
superscripts. The canonical list lives in the README / application; keep it in sync.
34+
- Standard `article` class (RevTeX is not assumed installed). Packages known to
35+
be available: amsmath, amssymb, graphicx, booktabs, authblk, physics, braket,
36+
hyperref, lmodern, geometry.
37+
- Wide notebook figures (~13:5) go full `\linewidth`, one per `figure`.
38+
- Equations and quoted results must match the notebook and the rodeo reference
39+
(see the vqe-circuits skill); cite Choi 2021 / Qian 2024 for the rodeo and
40+
Bogner 2026 (PLB 875) for resolution refinement.
41+
- Keep Sections within the journal page budget if one is specified.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
\documentclass[11pt]{article}
2+
\usepackage[utf8]{inputenc}\usepackage[T1]{fontenc}\usepackage{lmodern}
3+
\usepackage[a4paper,margin=1in]{geometry}
4+
\usepackage{amsmath,amssymb,physics,graphicx,booktabs,authblk}
5+
\usepackage[colorlinks=true]{hyperref}
6+
\title{\bfseries TITLE}
7+
\author[1]{Author One}\author[2]{Author Two}
8+
\affil[1]{Affiliation 1}\affil[2]{Affiliation 2}
9+
\date{\today}
10+
\begin{document}\maketitle
11+
\begin{abstract}\noindent ABSTRACT\end{abstract}
12+
\section{Introduction}
13+
\bibliographystyle{plain}
14+
\begin{thebibliography}{99}
15+
\end{thebibliography}
16+
\end{document}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Article conventions
2+
3+
## Class & preamble
4+
- `\documentclass[11pt]{article}` + `geometry` (a4, 1in margins).
5+
- Author block via `authblk`: `\author[n]{First Last}` + `\affil[n]{...}`.
6+
- Math: `amsmath, amssymb, physics` (\ket,\bra,\expval,\abs) and/or `braket`.
7+
- `booktabs` for tables, `hyperref` (colorlinks) for links, `lmodern` font.
8+
9+
## Structure (this paper)
10+
1. Introduction (eigenstate-prep bottleneck; VQE/adiabatic/QPE+rodeo limits; the
11+
hybrid idea; pairing model as testbed).
12+
2. The pairing model and its qubit encoding.
13+
3. The hybrid pipeline (coarse UCCSD-VQE; prolongation; resolution refinement;
14+
rodeo algorithm with Eqs. 1-2 and the convergence criterion).
15+
4. Results (UCCSD vs FCI/CCD + scaling; refinement overlap & energy; rodeo scan
16+
+ convergence).
17+
5. Discussion & outlook (hardware/Trotter/Magne; applications).
18+
19+
## Authors (alphabetical by surname) — keep in sync with the application
20+
Bogner (FRIB/MSU), Glittum (Oslo), Hergert (FRIB/MSU), Hjorth-Jensen (Oslo),
21+
Lange (Oslo), LaRose (MSU), Lee (FRIB/MSU), Massel (USN/Oslo).
22+
23+
## Figure captions
24+
Self-contained, describe axes and the takeaway. Reference exact numbers
25+
(e.g. peak at E=0.6352 vs exact 0.635548) only if a notebook cell printed them.

0 commit comments

Comments
 (0)