autoresearch-quantum/notebooks/plan_b/spiral_notebook.ipynb

2018 lines
382 KiB
Text
Raw Normal View History

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Spiral Notebook: Three Passes Through Quantum Autoresearch\n",
"\n",
"We are going to run an automated quantum experiment optimizer. **First time through, you just watch.** Second time, you will understand what you are watching. Third time, you will drive.\n",
"\n",
"Each pass covers the *entire* system at increasing depth -- like zooming into a fractal where each pass reveals structure that was invisible before."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# Pass 1: The 5-Minute Demo\n",
"\n",
"You do not need to understand anything yet. The goal is: **run the machine, see it work, get curious.**"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"import tempfile\n",
"import json\n",
"from dataclasses import asdict\n",
"\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from autoresearch_quantum.config import load_rung_config\n",
"from autoresearch_quantum.ratchet.runner import AutoresearchHarness\n",
"from autoresearch_quantum.persistence.store import ResearchStore"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"from autoresearch_quantum.teaching import LearningTracker\n",
"from autoresearch_quantum.teaching.assess import quiz, predict_choice, reflect, order, checkpoint_summary\n",
"tracker = LearningTracker(\"plan_b_spiral\")\n",
"print(\"Learning tracker active.\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.1 Load the Experiment Configuration\n",
"\n",
"We load a pre-built configuration for rung 1. Don't worry about what the fields mean yet -- just notice it has a **name** and an **objective**."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Name: [[4,2,2]] Encoded Magic-State Preparation\n",
"Objective: Maximize acceptance-weighted encoded magic quality for [[4,2,2]] T-state preparation on a backend-aware cheap tier.\n"
]
}
],
"source": [
"rung1_config = load_rung_config(\"../../configs/rungs/rung1.yaml\")\n",
"print(f\"Name: {rung1_config.name}\")\n",
"print(f\"Objective: {rung1_config.objective}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.2 Run a Single Ratchet Step\n",
"\n",
"This runs the entire optimization loop once: evaluate the incumbent, generate challengers, compare, pick a winner."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"step_index\": 1,\n",
" \"rung\": 1,\n",
" \"incumbent_before_id\": \"r1-incumbent-4343a2eac0\",\n",
" \"challengers_tested\": [\n",
" \"r1-challenger-2bc9c87de9\",\n",
" \"r1-challenger-6a036b7f5f\",\n",
" \"r1-challenger-3b16c89d93\",\n",
" \"r1-challenger-7b5e8bbe50\",\n",
" \"r1-challenger-581df4774d\",\n",
" \"r1-challenger-6f76d2ff9b\",\n",
" \"r1-challenger-0006429bd3\",\n",
" \"r1-challenger-610e9daff6\"\n",
" ],\n",
" \"promoted_challengers\": [\n",
" \"r1-challenger-581df4774d\",\n",
" \"r1-challenger-7b5e8bbe50\"\n",
" ],\n",
" \"winner_id\": \"r1-challenger-581df4774d\",\n",
" \"winning_margin\": 0.027819483580358982,\n",
" \"cheap_tier_justification\": \"Promoted challengers beat the incumbent on cheap-tier score by at least 0.0020.\",\n",
" \"expensive_tier_result\": \"Hardware tier disabled.\",\n",
" \"distilled_lesson\": \"verification: both -> z_only, ancilla_strategy: dedicated_pair -> reused_single became the new incumbent on cheap-tier score. It improved final score by +0.0278; 2 challengers were strong enough to justify promotion.\",\n",
" \"created_at\": \"2026-04-05T17:30:33.643541+00:00\"\n",
"}\n"
]
}
],
"source": [
"store_dir = tempfile.mkdtemp()\n",
"store = ResearchStore(store_dir)\n",
"harness = AutoresearchHarness(store)\n",
"\n",
"step = harness.run_ratchet_step(rung1_config)\n",
"print(json.dumps(asdict(step), indent=2, default=str))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.3 Key Numbers at a Glance"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Winner: r1-challenger-581df4774d\n",
"Winning margin: +0.027819\n",
"Challengers tested: 8\n",
"Promoted: 2\n",
"\n",
"Lesson: verification: both -> z_only, ancilla_strategy: dedicated_pair -> reused_single became the new incumbent on cheap-tier score. It improved final score by +0.0278; 2 challengers were strong enough to justify promotion.\n"
]
}
],
"source": [
"print(f\"Winner: {step.winner_id}\")\n",
"print(f\"Winning margin: {step.winning_margin:+.6f}\")\n",
"print(f\"Challengers tested: {len(step.challengers_tested)}\")\n",
"print(f\"Promoted: {len(step.promoted_challengers)}\")\n",
"print(f\"\\nLesson: {step.distilled_lesson}\")"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"quiz(tracker, \"p1_q1_what_is_score\",\n",
" question=\"The winning margin tells you how much the winner improved. What does a margin of 0.0 mean?\",\n",
" options=[\n",
" \"The experiment failed\",\n",
" \"No challenger beat the incumbent \\u2014 the incumbent stayed\",\n",
" \"All challengers tied exactly\",\n",
" ],\n",
" correct=1, section=\"Pass 1: Demo\", bloom=\"remember\",\n",
" explanation=\"Margin 0.0 means the incumbent was not replaced. The ratchet guarantee: never worse.\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.4 Run a Full Rung\n",
"\n",
"A rung runs multiple ratchet steps (up to the `step_budget`), with a patience mechanism that stops early if no improvement is found. At the end, it produces a **lesson** -- a structured summary of what the ratchet learned."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Steps completed: 3\n",
"Step budget: 3\n",
"Patience: 2\n"
]
}
],
"source": [
"# Fresh store for the full rung\n",
"store_rung = ResearchStore(tempfile.mkdtemp())\n",
"harness_rung = AutoresearchHarness(store_rung)\n",
"\n",
"steps, lesson, feedback = harness_rung.run_rung(rung1_config)\n",
"print(f\"Steps completed: {len(steps)}\")\n",
"print(f\"Step budget: {rung1_config.step_budget}\")\n",
"print(f\"Patience: {rung1_config.patience}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.5 The Lesson Narrative\n",
"\n",
"This is a human-readable summary of what the ratchet discovered."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/markdown": [
"# Rung 1: [[4,2,2]] Encoded Magic-State Preparation\n",
"\n",
"Objective: Maximize acceptance-weighted encoded magic quality for [[4,2,2]] T-state preparation on a backend-aware cheap tier.\n",
"\n",
"## What Helped\n",
"- verification=z_only improved mean score by +0.0074 over 17 runs.\n",
"- optimization_level=3 improved mean score by +0.0068 over 8 runs.\n",
"- ancilla_strategy=reused_single improved mean score by +0.0037 over 9 runs.\n",
"\n",
"## What Hurt\n",
"- verification=both hurt mean score by -0.0157 over 8 runs.\n",
"- optimization_level=1 hurt mean score by -0.0092 over 4 runs.\n",
"- ancilla_strategy=dedicated_pair hurt mean score by -0.0021 over 16 runs.\n",
"\n",
"## Invariants\n",
"- Top-ranked experiments consistently kept encoder_style=cx_chain.\n",
"- Top-ranked experiments consistently kept verification=z_only.\n",
"- Top-ranked experiments consistently kept optimization_level=3.\n",
"\n",
"## Hardware-Specific Effects\n",
"- No hardware-specific divergence was observed in this rung.\n",
"\n",
"## Next Tests\n",
"- Probe remaining verification values: ['x_only'].\n",
"\n",
"## Promote Forward\n",
"- seed_style: h_p -> u_magic, verification: both -> z_only, ancilla_strategy: dedicated_pair -> reused_single became the new incumbent on cheap-tier score. It improved final score by +0.0268; 2 challengers were strong enough to justify promotion.\n",
"- seed_style: u_magic -> h_p, ancilla_strategy: reused_single -> dedicated_pair, optimization_level: 2 -> 3 became the new incumbent on cheap-tier score. It improved final score by +0.0025; 1 challengers were strong enough to justify promotion.\n",
"- seed_style: h_p -> ry_rz became the new incumbent on cheap-tier score. It improved final score by +0.0046; 1 challengers were strong enough to justify promotion.\n",
"\n",
"## Discard\n",
"- verification=both hurt mean score by -0.0157 over 8 runs.\n",
"- optimization_level=1 hurt mean score by -0.0092 over 4 runs.\n",
"- ancilla_strategy=dedicated_pair hurt mean score by -0.0021 over 16 runs."
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from IPython.display import Markdown, display\n",
"display(Markdown(lesson.narrative))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.6 Score Landscape\n",
"\n",
"Let's see how all the experiments the ratchet tried compare to each other."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAHqCAYAAADVi/1VAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAgvtJREFUeJzt3QncTPX///+XJUSiKCJFUdbsRIsWhfSJFFIhSfUppZSK7CqpCFFSaSUi+ahkSVGWyJa0SEWUbClr9vO/Pd//35nvXJfLfjnnzFyP++02XHPmzMxr3ud9lnnNe8nkeZ5nAAAAAAAAQIAyB/lmAAAAAAAAgJCUAgAAAAAAQOBISgEAAAAAACBwJKUAAAAAAAAQOJJSAAAAAAAACBxJKQAAAAAAAASOpBQAAAAAAAACR1IKAAAAAAAAgSMpBQAAAAAAgMCRlAIAIECZMmWy7t27x+6/8cYbbtmKFSuSejvcdtttVrRo0bDDwDFSPVV9Vb09GL9ez5s3L5QynzZtmnv/MWPGWEaTkT87ACDxkJQCACCdvPjii+7LYPXq1dO9TJXI0msf6LZmzZp0f8+MZvv27a6c9aU+Pc2YMcPq1atnhQsXthw5cthZZ51l//nPf2zEiBHp+j4Zkcqwf//+oSfp/FvmzJnt1FNPddt79uzZx3QsOVTiL0izZs1y+8Y///wTdigAgCSTNewAAABIFsOHD3etgebOnWs///yzFS9ePN3f46WXXrKTTjppv+V58+a1KHvllVds3759FvWkVI8ePdzfl112Wbq85ujRo61p06ZWoUIFa9eunZ1yyim2fPly++KLL1yZ3HzzzenyPhk5KbVkyRJ74IEHQo2jWbNmds0119jevXvtp59+ckmlyy+/3L7++msrV67cEb+enp8/f37XwjAqSSntG4on6scaAEBiISkFAEA6UKJBX9zGjh1rd911l0tQdevWLd3L9sYbb3RfVhPFtm3bLFeuXHbCCSdYRqTWJaVLl7avvvrKsmXLluKxdevWBRaH53m2Y8cOO/HEEwN7z4ykUqVKduutt8buX3LJJa61lJLISjABAIC00X0PAIB0oCSUWsHUr1/fJY50PwwtW7Z0XcR++OGHFMvr1Knj4lu9enWKMX/UYkdJtHz58tnJJ59sLVq0sL///nu/1/3kk0/cF20lmHLnzu0+53fffZdiHbWiUCuuX375xbUa0Xq33HJLmmNK+d2ennvuORs8eLCdc845ljNnTrv66qtt1apVLonSq1cvO/PMM10ipUGDBrZx48ZjiuuPP/6whg0bur9PO+00e/jhh13LFj8eLRO1CPG7Y/njf6l7ZKtWrVw82bNntzPOOMPFdKixwFQWVatW3S8hJaeffnqK+2pJNmDAANeyRttQ8dStWzfFuEx79uxx5XLuuee6OFSmnTp1sp07d6Z4LS2/9tprbdKkSValShVXhi+//LJ7TF2w1LKoSJEi7jXUoq9Pnz77tWTTeiq7PHnyuNYxqltH2n1Lrc8OVr/0mkqy7t69e7/nqi6cf/75B3xttWb7+OOP7bfffottr9TjlukzPfnkk267qUyvvPJK14oxtTlz5riy1mdVPaxVq5bNnDnTjpbqpL/9473++ut2xRVXuG2vslfCUomrePoMqsPTp0+Pfa74lnvaBg8++KBbT6+hz6Zy3bBhw3H57NoHOnTo4P4uVqxYLKZkHwcPABAMWkoBAJAOlIRq1KiRSz6oK4++aKrrjhIS6SmtxEzWrFljXWqU1Pjss8/cl32NaZMlSxaXjJg8ebK9/fbbVqhQoRTPbdu2rXuuvnguXbrUxa0v+f5gyaLn6fWU2FLyQokGrXfxxRfbwoULUyQClDTRenpMCSd9yT1Uue3atcvuu+8+99meeeYZa9KkifvirhgeffRR90X6hRdecEmkYcOGxZ57JHEp+aT1NN6X4vr000+tb9++Lrnz3//+1yWA9Fz9ff3117ttKRdccIH7/4YbbnCJAsWp11UrpylTptjKlSsPOoD72WefbVOnTrXff//dJQcOpnXr1i5ZqBY2d9xxhyvLL7/80rWyUmJJtPzNN990ic+HHnrIJRR69+7tkpAffPBBitfT9lRdVFKoTZs2LsGjMlLSQQk6Ldf4Vmrh17FjR/vzzz9j4zMpKaikm8bDuvvuu61UqVLu9VXeR+JQ9at58+b21ltvueSZkmg+JQFVjw/W2vDxxx+3TZs2ubJ9/vnn3bLUXVuffvppN86T6o7WVf1SolTl5tP7qMwrV67s3k/r+8kjlX+1atXsSPkJGyWC4+nzlylTxq677jq333744Yd2zz33uATSvffe69bRNlA902fRZ5QCBQq4/7du3eoSXtret99+u2uhpWTU+PHjXTnEt6JMr8+ufUFdEt99911Xzv57+ElcAACOiQcAAI7JvHnzPJ1Sp0yZ4u7v27fPO/PMM7127drtt67W69atW+z+66+/7pYtX778oO+h52i9tG7nn39+inUnTZrklj/xxBPer7/+6p100klew4YNU6zjv2/lypW9Xbt2xZY/88wzbvn//vc/d3/Lli1e3rx5vTZt2qR4/po1a7w8efKkWN6yZUv33Mcee2y/+PXY2WefHbuvz6t1TzvtNO+ff/6JLe/YsaNbXr58eW/37t2x5c2aNfOyZcvm7dix46jj6tmzZ4p1K1as6D6/b/369fttH/n777/d8meffdY7Uq+99pp7rmK//PLLvS5dunhffvmlt3fv3hTrffbZZ269+++/f7/XUH2SRYsWuXXuuOOOFI8//PDDbrlew6ey1rKJEyemWLdXr15erly5vJ9++inFcm2zLFmyeCtXrnT3x40b556v+uDbs2ePd8kll7jlqj8Hc7j1S+WgfaVp06Ypnt+vXz8vU6ZMrv4eTP369VPUK9/nn3/u3qdUqVLezp07Y8sHDBjgln/77bexsi1RooRXp06dWDnL9u3bvWLFinlXXXXVQd/fr8c9evRw9Uf1T9u3atWqbvno0aNTrK/XTU3vfc4556RYVqZMGa9WrVr7rdu1a1f3umPHjt3vMT/+4/HZVfcP5zgFAMCRovseAADHSK191JJBAxuLWoBocOuRI0fGuoell/fff9+10Im/qWVD6m5PagXTs2dP18pBXXf8rlup3XnnnSnGe1JLIbXgmDBhgruv11d3IbW4UYsM/6YWWGp19Pnnn+/3mnqNw9W4cWPXbcjnz1yo8XkUR/xytahSC5+jjUstfuKpxcmvv/56yBjV9U0t4NS6J62ujQej1iwTJ0503a/U6khd7/S+JUqUcC2U4rer6k1aLYP8Fmv+Nmnfvn2Kx9ViStSVLZ66Wql1WOqB1/X+asETX261a9d2dVXdOf33UvnHb0uVrVrwHIlD1S+1zFHrHbX02bJlS4p9qmbNmu4zHAt1uYzvOul3q/O3+6JFi2zZsmVuwPm//vorVh4aC03d3VQehzNAv7abWg4VLFgw1pJJLfHUoi1e/Jhear2k91LLNcWj+4eielK+fHnXmu9A9STozw4AwLGg+x4AAMdAX+SVfFJCSoOd+5QY0ZdSdd1Skii9XHrppYc10Lm6qP3vf/9zXzw1Q1nq8Yt8So7EU5chjZfkdz/Sl1ZRd560aJygeEo4HKqbWjx1H4vnJ6g03lFay/2k0JHG5Y/RFE+JmcNJMmncHnUPVPJHyccLL7zQdTXTOD5KQhyKEkO6qevc/PnzbdSoUTZkyBD3Gj/++KPbNhp7SF0rTz311AO+jrq9KYmTelZHxaAucno8XloJHZXb4sWLD9j1yh98Xa+lepC6O9zBxng6mvolKkeVr7oH6m9181M5qYyOVer65XenS12PDtYtUcmi1N3w0kq+KcGqweTVJW7gwIFpJqQ1VpMSWOpaq/qQ+n3iE7RpUT1RV9IofXYAAI4FSSkAAI6BvoBqLB4lpnRLTS0+0jMpdbg0ppKfYPj2229di6Kj4beU0PhNaSVg4lsz+QkcJU4Ol1rfHMny/78H5JHHdaDXO1waGPw///mPjRs3zo1/1KVLFzeWk7Z/xYoVD+s1NL6WWqvopsSiBlTXQO1HOk5T6hY
"text/plain": [
"<Figure size 1200x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"The ratchet found the best settings automatically.\n"
]
}
],
"source": [
"experiments = store_rung.list_experiments(rung1_config.rung)\n",
"incumbent_id = store_rung.load_incumbent_id(rung1_config.rung)\n",
"\n",
"exp_ids = [e[\"experiment_id\"][:16] for e in experiments]\n",
"scores = [e[\"final_score\"] for e in experiments]\n",
"colors = [\"#2ecc71\" if e[\"experiment_id\"] == incumbent_id else \"#3498db\" for e in experiments]\n",
"\n",
"plt.figure(figsize=(12, 5))\n",
"bars = plt.bar(range(len(scores)), scores, color=colors)\n",
"plt.xticks(range(len(scores)), exp_ids, rotation=60, ha=\"right\", fontsize=7)\n",
"plt.ylabel(\"Score\")\n",
"plt.title(\"All Experiments Scored by the Ratchet\")\n",
"plt.legend(\n",
" handles=[\n",
" plt.Rectangle((0,0),1,1, color=\"#2ecc71\", label=\"Incumbent (winner)\"),\n",
" plt.Rectangle((0,0),1,1, color=\"#3498db\", label=\"Challengers\"),\n",
" ],\n",
" loc=\"upper right\"\n",
")\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"print(\"The ratchet found the best settings automatically.\")"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"predict_choice(tracker, \"p1_q2_score_spread\",\n",
" question=\"Looking at the score landscape: is there a large spread between the best and worst experiments?\",\n",
" options=[\n",
" \"No \\u2014 all experiments score roughly the same\",\n",
" \"Yes \\u2014 there is significant variation, meaning parameter choice matters a lot\",\n",
" \"Impossible to tell from a bar chart\",\n",
" ],\n",
" correct=1, section=\"Pass 1: Demo\", bloom=\"understand\",\n",
" explanation=\"Parameter choice strongly affects the score. This is why optimization matters.\")\n",
"\n",
"checkpoint_summary(tracker, \"Pass 1: Demo\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Questions You Should Have Right Now\n",
"\n",
"- What is a \"score\"?\n",
"- What are \"challengers\"?\n",
"- What is this circuit actually *doing*?\n",
"- What do \"verification\", \"postselection\", and \"witness\" mean?\n",
"- How does the ratchet decide one experiment is better than another?\n",
"\n",
"**Good -- Pass 2 answers all of these.**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# Pass 2: Opening the Black Box\n",
"\n",
"Now we rewind and build understanding from the ground up, but always connecting back to what we saw in Pass 1."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.1 The Quantum State: The Magic T-State\n",
"\n",
"A **magic state** is a specific quantum state needed for universal fault-tolerant quantum computation. The T-state is:\n",
"\n",
"$$|T\\rangle = \\frac{|0\\rangle + e^{i\\pi/4}|1\\rangle}{\\sqrt{2}}$$\n",
"\n",
"This state is \"magic\" because it cannot be created by the cheap Clifford gates alone. If you can prepare it reliably, you unlock the full power of quantum computing. The whole point of this project is to prepare this state *inside an error-detecting code*."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"T-state amplitudes: [0.70710678+0.j 0.5 +0.5j]\n",
"Expected: [1/sqrt(2), e^(i*pi/4)/sqrt(2)] = [0.7071, 0.5000+0.5000j]\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAbYAAAHGCAYAAAAYK66xAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs/XmMHNl23ovurCrWSLI4z/NMNntgz2TP57SObOtJug/2hd8D/AzIAyAbetfyIAu2Yct/+B/bsnR9bcPyFWRbsOFnG9eDZEtXOkd9Tnef7mbPbDa7Oc9zkUVWsUbWlPnwW7lXcGdURGREZGRWVjEWkF3sqszIGPbe315rfetbhVKpVDK55ZZbbrnltkCsZa5PILfccsstt9yytBzYcsstt9xyW1CWA1tuueWWW24LynJgyy233HLLbUFZDmy55ZZbbrktKMuBLbfccssttwVlObDllltuueW2oCwHttxyyy233BaU5cCWW2655ZbbgrIc2HLLLWO7fPmyKRQK5quvvgp9z7vvvivvGRwczO9/brllbDmw5ZbbHNiRI0fMrVu3TG9vr/z/v/23/9YsW7Ys1mcBxWeffdZ0dHSYXbt2yWdzyy23R5YDW265zYG1t7ebdevWideWxC5dumR+6qd+yrz11lviEf7iL/6i+Qt/4S+YP/zDP6zbueaW23yzHNhyy82x0dFR82f/7J81ixcvNuvXrzf/5J/8E/Pmm28KgKgBRv/9v//3ivuGt+X3nE6fPi2eWWdnpzl48KB57733AkOR/Pvnfu7nzIMHD+R3vP7+3//7gc/lN37jN8z27dvlvPbv329+4Rd+wfypP/WnzK//+q/nzzG33KzlwJZbbo790i/9kgDQ7/zO75jvf//7Ajpffvll6mP99b/+182xY8fM4cOHzU//9E+be/fuzXof4Pe//+//u1m6dKmEJ3n9jb/xNwKPefToUfP2229X/O4nf/In5fe55ZZb2XJgyy03ayMjI+a3fuu3zK/+6q+a7373u+bJJ580v/3bv22mp6dT3SO8qT/5J/+keFb/8l/+S8mncfygsCR/w1MjPMkLjzHIbt++bdauXVvxO/5/aGjIjI+P588yt9xyYMstt0d24cIFMzk5aV566SXvdytWrDB79+5NdZvw0tTa2trM888/b06dOpXf8txyq7PlHltuuSU0PCt/f96pqamG3Ee8ub6+vorf8f+EMbu6uhpyDrnl1uyWA1tuuVnbuXOnWbRokfnkk0+8ezIwMGDOnj1bcY9Wr14teTC1c+fOmbGxsVn38eOPP/b+TTjziy++kLBkkBGOnJmZieUFvvPOOxW/+8EPflDhHeaW2+NubXN9Arnl1ixGXuvP//k/L6SPlStXmjVr1pi/83f+jmlpqdz/fec73zH//J//cwETwOiXf/mXBRD99i/+xb8wu3fvFjCDtQhI/rk/9+cCv3vbtm2S4wO0nn76adPd3S0vv/38z/+8fPff/Jt/U471wx/+0Pzn//yfze/93u9leCdyy22eWym33HLzbHh4uPRn/syfKXV3d5fWrl1b+kf/6B+V3njjjdJf+St/xXvPjRs3St/73vdKPT09pd27d5d+//d/v9Tb21v6N//m38jfL126RJyy9B/+w38ovfjii6X29vbSgQMHSj/84Q+9Y/zoRz+S9wwMDHi/+/mf//nSypUr5fe/8iu/EvpU+Owzzzwjx92xY4f3vbnlllvZCvxnrsE1t9ya2ahje+aZZ4SSn1tuuTW/5Tm23HLLLbfcFpTlwJZbbrnlltuCsjwUmVtuueWW24Ky3GPLLbfccsttQVkObLnllltuuS0oy4Ett9xyyy23BWU5sOWWW2655bagLAe23HLLLbfcFpTlwJZbbk1m//pf/2tpUppbbrmlsxzYcsttDgwdSfQh6a5Nm5xPP/3U+xsizP/qX/2r/LnklltKy4Ett9waJMul9p/+038yf+2v/TXzK7/yK9KdG9FjumDfuXNH/v6zP/uz5nd/93fz55JbbiktB7bccmuw/dqv/Zr5i3/xL5qf+7mfMwcOHDC/8Ru/IUr+hCAxunfTY+2bb77Jn01uuaWwHNhyy62BRodu+rK9/fbbjyZhS4v8/9GjR+X/Ozo6zPe+973ca8stt5SWA1tuuTXQ+vv7pYfb2rVrK37P/9++fdv7/zwcmVtu6S0Httxya0L7E3/iTwihBCDMLbfcklkObLnl1kBbtWqVaW1tlRyaa/z/unXrvP+/dOmSWbZsmbxyyy23ZJYDW265NdDa29vNc889Z9555x3vd8ViUf7/8OHD3u9gReK1tbW15c8nt9wSWg5sueXWYIPq/5u/+Zvmt3/7t82pU6fMX/pLf8mMjo4KS9IFNvJsueWWW3LLt4O55dZg+9N/+k+bu3fvmr/39/6eEEaeeeYZ8wd/8AceoYQw5JkzZ8wf+2N/LH82ueWWwvJGo7nl1mT2T//pPzW///u/b/7wD/9wrk8lt9zmpeWhyNxyazIjDPkzP/Mzc30aueU2by332HLLLbfccltQlntsueWWW265LSjLgS233HLLLbcFZTmw5ZZbbrnltqAsB7bccsstt9wWlOXAlltuueWW24KyHNhyyy233HJbUJYrj+SWWxNbqVQyU1NT8m90I+ndlltuuUVbDmy55VZHQ+DYlEqmWCrJ/5eKRQErXvx+plg0Bdts1BQKpuC8sAdDQ2ZiYuLRhG1rMytWrMjFkXPLLcLyAu3ccothNActTk+bqelpU5yaMsWZGQ+4+DcvQIqfHngBajGP7Tc+PzwyYianpsrA19pqSk6HgJUrVphWPLjWVnkZC46tixaZttZW09bRkYNfbo+t5cCWW27WAKnpyUkzMz1tpqemzMzUlPycmpwMBSkBG/XAUpof2PygtmTxYgEzzm/wwQPx/ro6O013d7f8PfS7W1pM26JFAoCL2tvl1d7RYRYBfu3t+XPPbcFaDmy5PT6gBWBNT5uJhw/NFOE9GyYU0LJeVoURQrQ/3ePwPvHU7E8+7/4/IUUFOz6px3VDkAqIRftvAEpDkA8nJuTFvxd3dwsQaWgSkB0dH68AvJZCQby1gvNT3y/nbL/70W8eeXd8vlQoyDEBwLXr1pmurq76Pozccquz5Tm23BYc0QIPSEGM/58YGzOTExPiffGq8L4c8BHQsaDkgoP8VBBzPic/nO92/z+2cWx7XAW98fFxAbzuzk55i5JHXJvgOoeHBfjc61DwKrS0CODpz+mZGTM2Pm7GxsbMw/FxMz42ZsZGR83w6Kh5+PBhxf1o7egwvUuXmt4VK8yq1avltXLlSsntdXR0JL3C3HJruOUeW27z3gAcGnXywhuTEKINKZIX8zwih1GoIKgvJXGod+N5aRbsFlnvptXms1od0HC9pIKClftv9cbs/1f8VEKJ/a7xhw/N6NiYHLN3yRIPaDmvggUvgJuQJP9eunixvEc8RsfrxOO7efOmud/fb8bwUAF0+11cS3dXl4QyeS1evFhe5OZ4rwd6w8NyTzkWQDtTKpnOnh6zbt068/Lhw2bHjh0VnmFuuTWL5cCW27w1FvjhBw/M4MCAmbThRQ3HYeqZeV5VBJlDQoIW0NQzE1KIekKAmGUlkt/qIAQYQb1XMI3jwel5uTm0xT09ptN6R3oMF0IGh4bEI+3p7pbzkftRKpnbt25Jo9LbfX1mUWurWbNunenp6ZH3dHZ3yzG5RwB5lPGeVsKVra1yn9kw4EkCeLdu3zb9AwNm5erV5uUjR8yTTz2VA1xuTWU5sOU272xsZMQM3b9vHjx4UPbMYCLCFly0yPNe3LzYrAW7tXXWS8J2xphp6/W4IIK3g9cC7V6OyntLJfHgOjs7zaK2tprATYFNQoXkulpazLLeXjlXN7zomnp2fDcEkcuXL5vLly7JOa5Yvtxs377dbNy0KZgZibeKN1ssCsAJ49P+FGZnBOgB5nh2g4OD5sL586a/v98s7e01Tx06JAC3eOlSj6WZW25zZTmw5db0xkI7SXhsZERCa6MjI2bK5tEAGfI+7b4FXBZgFv22Ns/zEADzeVkllwBS/kXkeUxMTgrIkbP
"text/plain": [
"<Figure size 480x480 with 1 Axes>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAbYAAAHGCAYAAAAYK66xAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs/XmMHNl23ovurCrWSLI4z/NMNntgz2TP57SObOtJug/2hd8D/AzIAyAbetfyIAu2Yct/+B/bsnR9bcPyFWRbsOFnG9eDZEtXOkd9Tnef7mbPbDa7Oc9zkUVWsUbWlPnwW7lXcGdURGREZGRWVjEWkF3sqszIGPbe315rfetbhVKpVDK55ZZbbrnltkCsZa5PILfccsstt9yytBzYcsstt9xyW1CWA1tuueWWW24LynJgyy233HLLbUFZDmy55ZZbbrktKMuBLbfccssttwVlObDllltuueW2oCwHttxyyy233BaU5cCWW2655ZbbgrIc2HLLLWO7fPmyKRQK5quvvgp9z7vvvivvGRwczO9/brllbDmw5ZbbHNiRI0fMrVu3TG9vr/z/v/23/9YsW7Ys1mcBxWeffdZ0dHSYXbt2yWdzyy23R5YDW265zYG1t7ebdevWideWxC5dumR+6qd+yrz11lviEf7iL/6i+Qt/4S+YP/zDP6zbueaW23yzHNhyy82x0dFR82f/7J81ixcvNuvXrzf/5J/8E/Pmm28KgKgBRv/9v//3ivuGt+X3nE6fPi2eWWdnpzl48KB57733AkOR/Pvnfu7nzIMHD+R3vP7+3//7gc/lN37jN8z27dvlvPbv329+4Rd+wfypP/WnzK//+q/nzzG33KzlwJZbbo790i/9kgDQ7/zO75jvf//7Ajpffvll6mP99b/+182xY8fM4cOHzU//9E+be/fuzXof4Pe//+//u1m6dKmEJ3n9jb/xNwKPefToUfP2229X/O4nf/In5fe55ZZb2XJgyy03ayMjI+a3fuu3zK/+6q+a7373u+bJJ580v/3bv22mp6dT3SO8qT/5J/+keFb/8l/+S8mncfygsCR/w1MjPMkLjzHIbt++bdauXVvxO/5/aGjIjI+P588yt9xyYMstt0d24cIFMzk5aV566SXvdytWrDB79+5NdZvw0tTa2trM888/b06dOpXf8txyq7PlHltuuSU0PCt/f96pqamG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
"text/plain": [
"<Figure size 480x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from qiskit import QuantumCircuit\n",
"from qiskit.quantum_info import Statevector\n",
"from qiskit.visualization import plot_bloch_multivector\n",
"from math import pi, sqrt\n",
"\n",
"# Build |T> on a single qubit\n",
"qc_t = QuantumCircuit(1)\n",
"qc_t.h(0)\n",
"qc_t.p(pi/4, 0)\n",
"\n",
"t_state = Statevector.from_instruction(qc_t)\n",
"print(\"T-state amplitudes:\", t_state.data)\n",
"print(f\"Expected: [1/sqrt(2), e^(i*pi/4)/sqrt(2)] = [{1/sqrt(2):.4f}, {np.exp(1j*pi/4)/sqrt(2):.4f}]\")\n",
"\n",
"plot_bloch_multivector(t_state)"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"quiz(tracker, \"p2_q1_tstate\",\n",
" question=\"The T-state amplitude on |1\\u27E9 has a specific phase. What is it?\",\n",
" options=[\"\\u03C0/2 (90\\u00b0)\", \"\\u03C0/4 (45\\u00b0)\", \"\\u03C0/8 (22.5\\u00b0)\"],\n",
" correct=1, section=\"Pass 2: Concepts\", bloom=\"remember\",\n",
" explanation=\"The phase is \\u03C0/4 = 45\\u00b0. The gate is called T (for \\u03C0/8) because of Bloch sphere conventions.\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Key Insight:** The T-state sits at a specific angle on the Bloch sphere (latitude $\\pi/4$ from the equator in the X-Y plane). Its special position is what makes it \"magic\" -- it lies outside the stabilizer polytope."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.2 The Encoding: [[4,2,2]] Error-Detecting Code\n",
"\n",
"The [[4,2,2]] code uses **4 physical qubits** to encode **2 logical qubits**, with a code distance of 2 (can detect 1 error). We place our magic state on logical qubit 0 and the spectator state $|+\\rangle$ on logical qubit 1.\n",
"\n",
"The `build_preparation_circuit()` function creates this encoded state."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Circuit qubits: 4\n",
"Circuit depth: 7\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 705.552x367.889 with 1 Axes>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 705.552x367.889 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from autoresearch_quantum.codes.four_two_two import (\n",
" build_preparation_circuit, build_encoder, apply_magic_seed,\n",
" encoded_magic_statevector, STABILIZERS, MEASUREMENT_OPERATORS, DATA_QUBITS,\n",
")\n",
"\n",
"prep = build_preparation_circuit(seed_style=\"h_p\", encoder_style=\"cx_chain\")\n",
"print(f\"Circuit qubits: {prep.num_qubits}\")\n",
"print(f\"Circuit depth: {prep.depth()}\")\n",
"prep.draw(output=\"mpl\", style=\"iqp\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Key Insight:** The first gate (H + P on qubit 0) prepares the raw T-state. The remaining CNOT gates \"spread\" it across all 4 qubits so that single errors become detectable."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.3 Stabilizer Check: Verifying the Codeword\n",
"\n",
"The [[4,2,2]] code has two stabilizers: $XXXX$ and $ZZZZ$. A valid codeword must be a $+1$ eigenstate of both.\n",
"\n",
"$$\\langle XXXX \\rangle = +1 \\quad \\text{and} \\quad \\langle ZZZZ \\rangle = +1$$"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<z_stabilizer> = +1.000000\n",
"<x_stabilizer> = +1.000000\n",
"\n",
"Both are +1 -- the state is a valid codeword!\n"
]
}
],
"source": [
"from qiskit.quantum_info import SparsePauliOp\n",
"\n",
"encoded_state = encoded_magic_statevector()\n",
"\n",
"for name, op in STABILIZERS.items():\n",
" expectation = encoded_state.expectation_value(op)\n",
" print(f\"<{name}> = {expectation.real:+.6f}\")\n",
"\n",
"print(\"\\nBoth are +1 -- the state is a valid codeword!\")"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"quiz(tracker, \"p2_q2_stabilizer\",\n",
" question=\"Both stabilizer expectations are +1. What does this confirm?\",\n",
" options=[\n",
" \"The state has high energy\",\n",
" \"The state is in the [[4,2,2]] codespace \\u2014 no errors detected\",\n",
" \"All qubits are in |0\\u27E9\",\n",
" ],\n",
" correct=1, section=\"Pass 2: Concepts\", bloom=\"understand\",\n",
" explanation=\"Stabilizer eigenvalue +1 is the codespace condition. Any single-qubit error would flip at least one to \\u22121.\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Key Insight:** Stabilizer eigenvalues act as error flags. If an error flips one from +1 to -1, we *detect* it (though with distance 2, we cannot correct it -- we can only discard the shot)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.4 What a \"Shot\" Looks Like\n",
"\n",
"When we run the circuit on a (simulated) quantum computer, each execution is called a \"shot\". The result is a bitstring that encodes both **syndrome bits** (stabilizer measurement outcomes) and **data bits** (the actual qubit readout)."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Registers: ['syndrome', 'readout']\n",
"Syndrome labels: ['z_stabilizer', 'x_stabilizer']\n",
"\n",
"First 8 raw shots (syndrome + readout):\n",
" Shot 0: syndrome=1010, readout=00\n",
" Shot 1: syndrome=0000, readout=00\n",
" Shot 2: syndrome=1111, readout=00\n",
" Shot 3: syndrome=0101, readout=00\n",
" Shot 4: syndrome=1010, readout=00\n",
" Shot 5: syndrome=0000, readout=00\n",
" Shot 6: syndrome=1111, readout=00\n",
" Shot 7: syndrome=1111, readout=00\n"
]
}
],
"source": [
"from autoresearch_quantum.experiments.encoded_magic_state import build_circuit_bundle\n",
"from autoresearch_quantum.models import ExperimentSpec\n",
"from qiskit_aer import AerSimulator\n",
"\n",
"spec_demo = ExperimentSpec(\n",
" rung=1,\n",
" seed_style=\"h_p\",\n",
" encoder_style=\"cx_chain\",\n",
" verification=\"both\",\n",
" postselection=\"all_measured\",\n",
" ancilla_strategy=\"dedicated_pair\",\n",
" shots=256,\n",
" repeats=1,\n",
")\n",
"\n",
"bundle = build_circuit_bundle(spec_demo)\n",
"acceptance_circuit = bundle.acceptance\n",
"\n",
"print(f\"Registers: {[creg.name for creg in acceptance_circuit.cregs]}\")\n",
"print(f\"Syndrome labels: {acceptance_circuit.metadata.get('syndrome_labels', [])}\")\n",
"print()\n",
"\n",
"# Run on ideal simulator with memory=True to get individual shots\n",
"sim = AerSimulator()\n",
"result = sim.run(acceptance_circuit, shots=16, memory=True).result()\n",
"memory = result.get_memory(acceptance_circuit)\n",
"\n",
"print(\"First 8 raw shots (syndrome + readout):\")\n",
"for i, shot in enumerate(memory[:8]):\n",
" parts = shot.split(\" \")\n",
" print(f\" Shot {i}: syndrome={parts[0]}, readout={parts[1]}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The syndrome register has 2 bits: one for $ZZZZ$ and one for $XXXX$. On an ideal simulator, syndrome is always `00` (no errors detected). The readout register has 4 bits -- the measured data qubits.\n",
"\n",
"> **Key Insight:** Each shot gives us a syndrome (error flag) and a data readout. We use the syndrome to decide whether to keep or discard the shot."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.5 Postselection: Keeping Only Good Shots\n",
"\n",
"**Postselection** means discarding shots where the syndrome indicates an error was detected. If syndrome = `00`, both stabilizers measured $+1$ and we keep the shot."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total shots: 256\n",
"Accepted shots: 256\n",
"Acceptance rate: 1.0000\n",
"\n",
"Syndrome distribution: {'00': 256}\n",
"\n",
"(On an ideal simulator, acceptance rate should be 1.0 -- no errors!)\n"
]
}
],
"source": [
"from autoresearch_quantum.execution.analysis import (\n",
" local_memory_records, summarize_context, logical_magic_witness, stability_score\n",
")\n",
"\n",
"# Run with more shots for statistics\n",
"result_256 = sim.run(acceptance_circuit, shots=256, memory=True).result()\n",
"memory_256 = result_256.get_memory(acceptance_circuit)\n",
"\n",
"creg_names = [creg.name for creg in acceptance_circuit.cregs]\n",
"records = local_memory_records(memory_256, creg_names)\n",
"\n",
"syndrome_labels = list(acceptance_circuit.metadata.get(\"syndrome_labels\", []))\n",
"summary = summarize_context(\n",
" records,\n",
" syndrome_labels=syndrome_labels,\n",
" postselection=\"all_measured\",\n",
" operator=None,\n",
")\n",
"\n",
"print(f\"Total shots: {summary['total_shots']}\")\n",
"print(f\"Accepted shots: {summary['accepted_shots']}\")\n",
"print(f\"Acceptance rate: {summary['acceptance_rate']:.4f}\")\n",
"print(f\"\\nSyndrome distribution: {summary['syndrome_counts']}\")\n",
"print(\"\\n(On an ideal simulator, acceptance rate should be 1.0 -- no errors!)\")"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"quiz(tracker, \"p2_q3_postselection\",\n",
" question=\"Postselection improves quality by discarding error-flagged shots. What is the cost?\",\n",
" options=[\n",
" \"It makes the circuit deeper\",\n",
" \"You lose shots \\u2014 fewer usable data points\",\n",
" \"It introduces new types of errors\",\n",
" ],\n",
" correct=1, section=\"Pass 2: Concepts\", bloom=\"understand\",\n",
" explanation=\"Postselection trades quantity for quality. Fewer usable shots means worse statistics or more total shots needed.\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.6 Adding Noise: What Happens on Real Hardware\n",
"\n",
"Real quantum processors have gate errors, readout errors, and decoherence. We simulate this using a noise model extracted from IBM's `fake_brisbane` backend."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Noisy acceptance rate: 0.7656\n",
"Ideal acceptance rate: 1.0000\n",
"\n",
"Noise dropped acceptance by 0.2344\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1400x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from autoresearch_quantum.execution.backends import resolve_backend\n",
"from autoresearch_quantum.execution.transpile import transpile_circuits\n",
"from qiskit_aer.noise import NoiseModel\n",
"from qiskit.visualization import plot_histogram\n",
"\n",
"backend = resolve_backend(\"fake_brisbane\")\n",
"noise_model = NoiseModel.from_backend(backend)\n",
"\n",
"noisy_sim = AerSimulator(\n",
" noise_model=noise_model,\n",
" basis_gates=noise_model.basis_gates,\n",
")\n",
"\n",
"# Transpile for the backend\n",
"transpiled_acceptance = transpile_circuits([acceptance_circuit], spec_demo, backend)[0]\n",
"\n",
"result_noisy = noisy_sim.run(transpiled_acceptance, shots=512, memory=True).result()\n",
"memory_noisy = result_noisy.get_memory(transpiled_acceptance)\n",
"\n",
"records_noisy = local_memory_records(memory_noisy, [creg.name for creg in transpiled_acceptance.cregs])\n",
"summary_noisy = summarize_context(\n",
" records_noisy,\n",
" syndrome_labels=syndrome_labels,\n",
" postselection=\"all_measured\",\n",
" operator=None,\n",
")\n",
"\n",
"print(f\"Noisy acceptance rate: {summary_noisy['acceptance_rate']:.4f}\")\n",
"print(f\"Ideal acceptance rate: {summary['acceptance_rate']:.4f}\")\n",
"print(f\"\\nNoise dropped acceptance by {summary['acceptance_rate'] - summary_noisy['acceptance_rate']:.4f}\")\n",
"\n",
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 4))\n",
"ax1.bar(summary[\"syndrome_counts\"].keys(), summary[\"syndrome_counts\"].values(), color=\"#2ecc71\")\n",
"ax1.set_title(\"Ideal: Syndrome Distribution\")\n",
"ax1.set_xlabel(\"Syndrome\")\n",
"ax1.set_ylabel(\"Counts\")\n",
"\n",
"ax2.bar(summary_noisy[\"syndrome_counts\"].keys(), summary_noisy[\"syndrome_counts\"].values(), color=\"#e74c3c\")\n",
"ax2.set_title(\"Noisy: Syndrome Distribution\")\n",
"ax2.set_xlabel(\"Syndrome\")\n",
"ax2.set_ylabel(\"Counts\")\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Key Insight:** Noise causes some shots to fail the stabilizer check (syndrome != `00`). The error-detecting code is working -- it flags corrupted shots so we can discard them. But this comes at a cost: lower acceptance rate means we need more shots."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.7 The Witness Formula: Measuring Magic\n",
"\n",
"How do we know our encoded state is actually the *right* magic state and not just any codeword? We measure three logical operators and combine them into a **witness** value.\n",
"\n",
"The logical operators for the [[4,2,2]] code are:\n",
"- $X_L = X_0 X_2$ (logical X on the magic qubit)\n",
"- $Y_L = Y_0 Z_1 X_2$ (logical Y on the magic qubit)\n",
"- $Z_{\\text{spectator}} = Z_1 Z_2$ (logical Z on the spectator qubit)\n",
"\n",
"The witness formula is:\n",
"\n",
"$$\\text{witness} = \\underbrace{\\frac{1 + \\frac{\\langle X_L \\rangle + \\langle Y_L \\rangle}{\\sqrt{2}}}{2}}_{\\text{magic quality}} \\times \\underbrace{\\frac{1 + \\langle Z_{\\text{spectator}} \\rangle}{2}}_{\\text{spectator alignment}}$$"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"< logical_x> = +0.5071 (acceptance: 0.5469)\n",
"< logical_y> = +0.3569 (acceptance: 0.6621)\n",
"< spectator_z> = +0.0000 (acceptance: 0.5312)\n",
"\n",
"--- Witness Computation ---\n",
" (X_L + Y_L) / sqrt(2) = (0.5071 + 0.3569) / 1.4142 = 0.6110\n",
" Magic quality = (1 + 0.6110) / 2 = 0.8055\n",
" Spectator align = (1 + 0.0000) / 2 = 0.5000\n",
" Witness = 0.8055 x 0.5000 = 0.4027\n",
" Library check: 0.4027\n"
]
}
],
"source": [
"# Measure each logical operator on the noisy simulator\n",
"witness_circuits = bundle.witness_circuits\n",
"transpiled_witnesses = {}\n",
"for name, circ in witness_circuits.items():\n",
" transpiled_witnesses[name] = transpile_circuits([circ], spec_demo, backend)[0]\n",
"\n",
"expectations = {}\n",
"for name, circ in transpiled_witnesses.items():\n",
" result_w = noisy_sim.run(circ, shots=512, memory=True).result()\n",
" mem_w = result_w.get_memory(circ)\n",
" recs_w = local_memory_records(mem_w, [creg.name for creg in circ.cregs])\n",
" summary_w = summarize_context(\n",
" recs_w,\n",
" syndrome_labels=syndrome_labels,\n",
" postselection=\"all_measured\",\n",
" operator=MEASUREMENT_OPERATORS.get(name),\n",
" )\n",
" expectations[name] = summary_w[\"expectation\"]\n",
" print(f\"<{name:>14}> = {summary_w['expectation']:+.4f} (acceptance: {summary_w['acceptance_rate']:.4f})\")\n",
"\n",
"# Build up the witness step by step\n",
"lx = expectations[\"logical_x\"]\n",
"ly = expectations[\"logical_y\"]\n",
"sz = expectations[\"spectator_z\"]\n",
"\n",
"magic_quality = (1.0 + (lx + ly) / sqrt(2)) / 2.0\n",
"spectator_alignment = (1.0 + sz) / 2.0\n",
"witness_value = magic_quality * spectator_alignment\n",
"\n",
"# Also compute via the library function\n",
"witness_lib = logical_magic_witness(lx, ly, sz)\n",
"\n",
"print(f\"\\n--- Witness Computation ---\")\n",
"print(f\" (X_L + Y_L) / sqrt(2) = ({lx:.4f} + {ly:.4f}) / {sqrt(2):.4f} = {(lx + ly)/sqrt(2):.4f}\")\n",
"print(f\" Magic quality = (1 + {(lx+ly)/sqrt(2):.4f}) / 2 = {magic_quality:.4f}\")\n",
"print(f\" Spectator align = (1 + {sz:.4f}) / 2 = {spectator_alignment:.4f}\")\n",
"print(f\" Witness = {magic_quality:.4f} x {spectator_alignment:.4f} = {witness_value:.4f}\")\n",
"print(f\" Library check: {witness_lib:.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Connection to Pass 1:** This witness value is the `logical_magic_witness` field in the evaluation metrics. It is the core measure of **quality** -- the thing the ratchet was trying to maximize."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.8 Cost: Why Circuit Complexity Matters\n",
"\n",
"Longer circuits accumulate more errors. The cost function penalizes experiments with many two-qubit gates, deep circuits, and large shot counts."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" logical_x: depth= 83, two-qubit gates= 30, size=192\n",
" logical_y: depth= 93, two-qubit gates= 30, size=184\n",
" spectator_z: depth=108, two-qubit gates= 32, size=209\n",
"\n",
"Cost formula from rung1 config:\n",
" cost = 1.0 + 0.08*two_q + 0.01*depth + 0.0002*shots + 0.015*runtime + 0.3*queue\n"
]
}
],
"source": [
"from autoresearch_quantum.execution.transpile import count_two_qubit_gates, circuit_metadata\n",
"\n",
"for name, circ in transpiled_witnesses.items():\n",
" tqg = count_two_qubit_gates(circ)\n",
" d = circ.depth()\n",
" meta = circuit_metadata(circ, spec_demo)\n",
" print(f\"{name:>14}: depth={d:3d}, two-qubit gates={tqg:3d}, size={meta['size']}\")\n",
"\n",
"# Show the cost formula\n",
"print(f\"\\nCost formula from rung1 config:\")\n",
"cw = rung1_config.score.cost_weights\n",
"print(f\" cost = {rung1_config.score.base_cost} + {cw.two_qubit_count}*two_q + {cw.depth}*depth + {cw.shot_count}*shots + {cw.runtime_estimate}*runtime + {cw.queue_cost_proxy}*queue\")"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"predict_choice(tracker, \"p2_q4_cost_quality\",\n",
" question=\"More complex circuits might give better quality but higher cost. What does the score formula do with this tension?\",\n",
" options=[\n",
" \"Ignores cost entirely \\u2014 only quality matters\",\n",
" \"Divides quality by cost, so you need quality to outweigh the cost\",\n",
" \"Picks the cheapest circuit regardless of quality\",\n",
" ],\n",
" correct=1, section=\"Pass 2: Scoring\", bloom=\"apply\",\n",
" explanation=\"score = quality \\u00d7 acceptance / cost. A circuit that is 2x better but 3x more expensive scores worse.\")\n",
"\n",
"checkpoint_summary(tracker, \"Pass 2: Scoring\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Key Insight:** There is a tension between quality and cost. More complex circuits might give better error detection, but they also introduce more errors. The scoring function balances this tradeoff."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.9 The Score: Putting It All Together\n",
"\n",
"The final score combines **quality** (witness, fidelity, stability, etc.), **acceptance rate** (fraction of shots that pass postselection), and **cost** (circuit complexity):\n",
"\n",
"$$\\text{score} = \\frac{\\text{quality} \\times \\text{acceptance\\_rate}}{\\text{cost}}$$\n",
"\n",
"where quality is a weighted sum of individual metrics."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Quality: 0.730531\n",
"Acceptance rate: 0.765625\n",
"Cost: 9.542400\n",
"Score: 0.058613\n",
"\n",
"Score = 0.7305 * 0.7656 / 9.5424 = 0.058613\n"
]
}
],
"source": [
"from autoresearch_quantum.scoring.score import score_metrics, weighted_acceptance_cost\n",
"from autoresearch_quantum.models import EvaluationMetrics\n",
"\n",
"# Build metrics from our manual measurements\n",
"manual_metrics = EvaluationMetrics(\n",
" ideal_encoded_fidelity=1.0, # perfect on ideal sim\n",
" noisy_encoded_fidelity=0.85, # placeholder\n",
" logical_magic_witness=witness_lib,\n",
" acceptance_rate=summary_noisy[\"acceptance_rate\"],\n",
" codespace_rate=summary_noisy[\"acceptance_rate\"],\n",
" spectator_logical_z=sz,\n",
" logical_x=lx,\n",
" logical_y=ly,\n",
" stability_score=1.0,\n",
" two_qubit_count=sum(count_two_qubit_gates(c) for c in transpiled_witnesses.values()),\n",
" depth=max(c.depth() for c in transpiled_witnesses.values()),\n",
" shot_count=512,\n",
")\n",
"\n",
"score, quality, cost = score_metrics(manual_metrics, \"cheap\", rung1_config.score)\n",
"\n",
"print(f\"Quality: {quality:.6f}\")\n",
"print(f\"Acceptance rate: {summary_noisy['acceptance_rate']:.6f}\")\n",
"print(f\"Cost: {cost:.6f}\")\n",
"print(f\"Score: {score:.6f}\")\n",
"print(f\"\\nScore = {quality:.4f} * {summary_noisy['acceptance_rate']:.4f} / {cost:.4f} = {score:.6f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Connection to Pass 1:** This is exactly the score number you saw in the bar chart. Every bar in that chart was computed using this formula."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.10 What Are Challengers?\n",
"\n",
"The ratchet starts with an **incumbent** (the current best experiment settings). It then generates **challengers** by mutating one or more parameters. Each challenger is evaluated and compared to the incumbent."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Incumbent settings:\n",
" seed_style: h_p\n",
" encoder_style: cx_chain\n",
" verification: both\n",
" postselection: all_measured\n",
" ancilla_strategy: dedicated_pair\n",
" optimization_level:2\n",
"\n",
"Generated 8 challengers:\n",
" # Mutation \n",
"-------------------------------------------------------\n",
" 1 seed_style: h_p -> ry_rz\n",
" 2 seed_style: h_p -> u_magic\n",
" 3 encoder_style: cx_chain -> cz_compiled\n",
" 4 verification: both -> z_only\n",
" 5 verification: both -> x_only\n",
" 6 postselection: all_measured -> z_only\n",
" 7 postselection: all_measured -> none\n",
" 8 ancilla_strategy: dedicated_pair -> reused_single\n"
]
}
],
"source": [
"from autoresearch_quantum.search.challengers import generate_neighbor_challengers, mutation_summary\n",
"\n",
"incumbent_spec = rung1_config.bootstrap_incumbent\n",
"print(\"Incumbent settings:\")\n",
"print(f\" seed_style: {incumbent_spec.seed_style}\")\n",
"print(f\" encoder_style: {incumbent_spec.encoder_style}\")\n",
"print(f\" verification: {incumbent_spec.verification}\")\n",
"print(f\" postselection: {incumbent_spec.postselection}\")\n",
"print(f\" ancilla_strategy: {incumbent_spec.ancilla_strategy}\")\n",
"print(f\" optimization_level:{incumbent_spec.optimization_level}\")\n",
"\n",
"# Generate challengers\n",
"challengers = generate_neighbor_challengers(incumbent_spec, rung1_config.search_space)\n",
"\n",
"print(f\"\\nGenerated {len(challengers)} challengers:\")\n",
"print(f\"{'#':>3} {'Mutation':50s}\")\n",
"print(\"-\" * 55)\n",
"for i, ch in enumerate(challengers):\n",
" print(f\"{i+1:3d} {ch.mutation_note}\")"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"quiz(tracker, \"p2_q5_neighbors\",\n",
" question=\"Each NeighborWalk challenger differs from the incumbent in how many parameters?\",\n",
" options=[\"0\", \"1\", \"2\", \"All of them\"],\n",
" correct=1, section=\"Pass 2: Ratchet\", bloom=\"apply\",\n",
" explanation=\"NeighborWalk changes exactly one parameter at a time. This is systematic but cannot find parameter interactions.\")\n",
"\n",
"checkpoint_summary(tracker, \"Pass 2: Ratchet\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Each challenger differs from the incumbent in exactly one parameter (this is the `NeighborWalk` strategy). The ratchet also uses `RandomCombo` to mutate multiple parameters at once."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Setting Score Quality Accept\n",
"--------------------------------------------------------------------------------\n",
"INCUMBENT 0.035552 0.851271 1.0000\n",
"seed_style: h_p -> ry_rz 0.035362 0.854142 1.0000\n",
"seed_style: h_p -> u_magic 0.036333 0.853074 1.0000\n",
"encoder_style: cx_chain -> cz_compiled 0.035371 0.841448 1.0000\n",
"verification: both -> z_only 0.069126 0.855724 1.0000\n"
]
}
],
"source": [
"# Evaluate a few challengers and compare\n",
"from autoresearch_quantum.execution.local import LocalCheapExecutor\n",
"\n",
"executor = LocalCheapExecutor()\n",
"\n",
"print(f\"{'Setting':45s} {'Score':>10s} {'Quality':>10s} {'Accept':>10s}\")\n",
"print(\"-\" * 80)\n",
"\n",
"# Evaluate incumbent\n",
"inc_result = executor.evaluate(incumbent_spec, rung1_config)\n",
"print(f\"{'INCUMBENT':45s} {inc_result.score:10.6f} {inc_result.quality_estimate:10.6f} {inc_result.metrics.acceptance_rate:10.4f}\")\n",
"\n",
"# Evaluate first 4 challengers\n",
"for ch in challengers[:4]:\n",
" ch_result = executor.evaluate(ch.spec, rung1_config)\n",
" label = ch.mutation_note[:45]\n",
" print(f\"{label:45s} {ch_result.score:10.6f} {ch_result.quality_estimate:10.6f} {ch_result.metrics.acceptance_rate:10.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Connection to Pass 1:** In Pass 1, the ratchet did this automatically -- generated challengers, evaluated all of them, and picked the best."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.11 Promotion and Winner Selection\n",
"\n",
"Not every challenger becomes the new incumbent. The ratchet uses a **cheap margin** to filter: a challenger must beat the incumbent's score by at least this threshold.\n",
"\n",
"$$\\text{challenger\\_score} > \\text{incumbent\\_score} + \\text{cheap\\_margin}$$\n",
"\n",
"Only the top-K challengers that clear this bar get \"promoted\". The best one among promoted challengers (and the incumbent) becomes the new incumbent."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Cheap margin: 0.002\n",
"Promote top-K: 2\n",
"\n",
"Incumbent score: 0.035552\n",
"Threshold: 0.037552\n",
"\n",
"For a challenger to be promoted, it must score above 0.037552\n"
]
}
],
"source": [
"cheap_margin = rung1_config.tier_policy.cheap_margin\n",
"promote_top_k = rung1_config.tier_policy.promote_top_k\n",
"\n",
"print(f\"Cheap margin: {cheap_margin}\")\n",
"print(f\"Promote top-K: {promote_top_k}\")\n",
"print(f\"\\nIncumbent score: {inc_result.score:.6f}\")\n",
"print(f\"Threshold: {inc_result.score + cheap_margin:.6f}\")\n",
"print(f\"\\nFor a challenger to be promoted, it must score above {inc_result.score + cheap_margin:.6f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.12 Re-Running the Ratchet Step (With Understanding)\n",
"\n",
"Let's run the same ratchet step from Pass 1, but now we understand every decision."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Incumbent ID: r1-incumbent-4343a2eac0\n",
"Incumbent score: 0.035164\n",
" witness: 0.5105\n",
" accept: 1.0000\n",
" cost: 24.2192\n",
"\n",
"--- Running challengers ---\n",
"\n",
" ID Score Margin Promoted? Mutation\n",
"-----------------------------------------------------------------------------------------------\n",
"r1-challenger-49ab8874a8 0.068216 +0.033052 YES combo: postselection: all_measured -> z_\n",
"r1-challenger-b8c950b594 0.053963 +0.018798 YES combo: encoder_style: cx_chain -> cz_com\n",
"r1-challenger-a39c019eb7 0.048566 +0.013402 YES combo: verification: both -> z_only, opt\n",
"r1-challenger-6a036b7f5f 0.036716 +0.001551 no neighbor: seed_style: h_p -> u_magic\n",
"r1-challenger-045a4145b4 0.036413 +0.001249 no combo: postselection: all_measured -> z_\n",
"r1-challenger-49ccceae73 0.035814 +0.000650 no combo: encoder_style: cx_chain -> cz_com\n",
"r1-challenger-2bc9c87de9 0.035086 -0.000078 no neighbor: seed_style: h_p -> ry_rz\n",
"r1-challenger-3b16c89d93 0.034822 -0.000342 no neighbor: encoder_style: cx_chain -> cz_\n"
]
}
],
"source": [
"# Fresh store\n",
"store_p2 = ResearchStore(tempfile.mkdtemp())\n",
"harness_p2 = AutoresearchHarness(store_p2)\n",
"\n",
"# Ensure incumbent\n",
"incumbent_record = harness_p2.ensure_incumbent(rung1_config)\n",
"print(f\"Incumbent ID: {incumbent_record.experiment_id}\")\n",
"print(f\"Incumbent score: {incumbent_record.cheap_result.score:.6f}\")\n",
"print(f\" witness: {incumbent_record.cheap_result.metrics.logical_magic_witness:.4f}\")\n",
"print(f\" accept: {incumbent_record.cheap_result.metrics.acceptance_rate:.4f}\")\n",
"print(f\" cost: {incumbent_record.cheap_result.metrics.total_cost:.4f}\")\n",
"\n",
"# Run challenger set\n",
"print(\"\\n--- Running challengers ---\")\n",
"challenger_records = harness_p2.run_challenger_set(rung1_config)\n",
"\n",
"print(f\"\\n{'ID':>24s} {'Score':>10s} {'Margin':>10s} {'Promoted?':>10s} Mutation\")\n",
"print(\"-\" * 95)\n",
"for rec in sorted(challenger_records, key=lambda r: r.cheap_result.score, reverse=True):\n",
" margin = rec.cheap_result.score - incumbent_record.cheap_result.score\n",
" promoted = \"YES\" if margin > cheap_margin else \"no\"\n",
" print(f\"{rec.experiment_id[:24]:>24s} {rec.cheap_result.score:10.6f} {margin:+10.6f} {promoted:>10s} {rec.mutation_note[:40]}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Connection to Pass 1:** You are now seeing the same optimization process from Pass 1, but with full visibility into the scores, margins, and promotion decisions."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.13 The Lesson Revisited\n",
"\n",
"Let's re-read the lesson from our Pass 1 rung. Now every term should make sense."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'Markdown' is not defined",
"output_type": "error",
"traceback": [
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
"\u001b[31mNameError\u001b[39m Traceback (most recent call last)",
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[19]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m display(Markdown(lesson.narrative))\n\u001b[32m 2\u001b[39m \n\u001b[32m 3\u001b[39m print(\u001b[33m\"\\n--- Now you know what each term means ---\"\u001b[39m)\n\u001b[32m 4\u001b[39m print(\u001b[33m\"- 'verification=both' means measuring both XXXX and ZZZZ stabilizers\"\u001b[39m)\n",
"\u001b[31mNameError\u001b[39m: name 'Markdown' is not defined"
]
}
],
"source": [
"display(Markdown(lesson.narrative))\n",
"\n",
"print(\"\\n--- Now you know what each term means ---\")\n",
"print(\"- 'verification=both' means measuring both XXXX and ZZZZ stabilizers\")\n",
"print(\"- 'logical witness' is the magic_quality x spectator_alignment formula\")\n",
"print(\"- 'acceptance rate' is the fraction of shots where syndrome=00\")\n",
"print(\"- 'score' = quality * acceptance / cost\")\n",
"print(\"- 'mean score improved by +X' means a challenger beat the incumbent\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# Pass 3: Making It Your Own\n",
"\n",
"You have seen the system run (Pass 1) and understood every component (Pass 2). Now you will **drive** -- modify parameters, compare scoring functions, and run multi-step optimizations."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.1 Change the Search Space\n",
"\n",
"What if we restrict the search to only a few dimensions? Or expand it? Let's modify the rung config and see how the challengers change."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from dataclasses import replace\n",
"from autoresearch_quantum.models import SearchSpaceConfig\n",
"\n",
"# Create a search space that only explores verification and postselection\n",
"narrow_space = SearchSpaceConfig(\n",
" dimensions={\n",
" \"verification\": [\"both\", \"z_only\", \"x_only\"],\n",
" \"postselection\": [\"all_measured\", \"z_only\", \"none\"],\n",
" },\n",
" max_challengers_per_step=6,\n",
")\n",
"\n",
"narrow_config = replace(rung1_config, search_space=narrow_space, step_budget=2, patience=2)\n",
"\n",
"# Run a ratchet step with this narrower search\n",
"store_narrow = ResearchStore(tempfile.mkdtemp())\n",
"harness_narrow = AutoresearchHarness(store_narrow)\n",
"step_narrow = harness_narrow.run_ratchet_step(narrow_config)\n",
"\n",
"print(f\"Challengers tested: {len(step_narrow.challengers_tested)}\")\n",
"print(f\"Winner: {step_narrow.winner_id}\")\n",
"print(f\"Margin: {step_narrow.winning_margin:+.6f}\")\n",
"print(f\"Lesson: {step_narrow.distilled_lesson}\")\n",
"\n",
"# Show which experiments were tried\n",
"exps_narrow = store_narrow.list_experiments(1)\n",
"for e in exps_narrow:\n",
" role = e[\"role\"]\n",
" v = e[\"spec\"][\"verification\"]\n",
" p = e[\"spec\"][\"postselection\"]\n",
" s = e[\"final_score\"]\n",
" print(f\" {role:12s} verification={v:12s} postselection={p:14s} score={s:.6f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.2 Compare Scoring Functions\n",
"\n",
"The system supports multiple scoring functions. `weighted_acceptance_cost` balances quality and cost traditionally. `factory_throughput` optimizes for accepted magic states per unit cost, penalizing circuit complexity more heavily."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from autoresearch_quantum.scoring.score import weighted_acceptance_cost, factory_throughput_score\n",
"from autoresearch_quantum.models import ScoreConfig\n",
"\n",
"# Evaluate the same set of specs with both scoring functions\n",
"test_specs = [\n",
" rung1_config.bootstrap_incumbent,\n",
" rung1_config.bootstrap_incumbent.with_updates(verification=\"z_only\"),\n",
" rung1_config.bootstrap_incumbent.with_updates(verification=\"x_only\"),\n",
" rung1_config.bootstrap_incumbent.with_updates(postselection=\"none\"),\n",
" rung1_config.bootstrap_incumbent.with_updates(encoder_style=\"cz_compiled\"),\n",
"]\n",
"\n",
"labels = [\"baseline\", \"z_only_verif\", \"x_only_verif\", \"no_postsel\", \"cz_compiled\"]\n",
"\n",
"wac_scores = []\n",
"ft_scores = []\n",
"\n",
"factory_score_config = replace(rung1_config.score, name=\"factory_throughput\")\n",
"\n",
"for spec_test in test_specs:\n",
" result_test = executor.evaluate(spec_test, rung1_config)\n",
" metrics = result_test.metrics\n",
" \n",
" s_wac, _, _ = weighted_acceptance_cost(metrics, \"cheap\", rung1_config.score)\n",
" # Need fresh metrics for factory scoring since it modifies metrics.extra\n",
" result_test2 = executor.evaluate(spec_test, rung1_config)\n",
" s_ft, _, _ = factory_throughput_score(result_test2.metrics, \"cheap\", factory_score_config)\n",
" \n",
" wac_scores.append(s_wac)\n",
" ft_scores.append(s_ft)\n",
"\n",
"x = np.arange(len(labels))\n",
"width = 0.35\n",
"\n",
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))\n",
"\n",
"ax1.bar(x, wac_scores, width, color=\"#3498db\", label=\"weighted_acceptance_cost\")\n",
"ax1.set_xticks(x)\n",
"ax1.set_xticklabels(labels, rotation=30, ha=\"right\")\n",
"ax1.set_ylabel(\"Score\")\n",
"ax1.set_title(\"weighted_acceptance_cost\")\n",
"\n",
"ax2.bar(x, ft_scores, width, color=\"#e67e22\", label=\"factory_throughput\")\n",
"ax2.set_xticks(x)\n",
"ax2.set_xticklabels(labels, rotation=30, ha=\"right\")\n",
"ax2.set_ylabel(\"Score\")\n",
"ax2.set_title(\"factory_throughput\")\n",
"\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"# Show ranking differences\n",
"wac_rank = np.argsort(wac_scores)[::-1]\n",
"ft_rank = np.argsort(ft_scores)[::-1]\n",
"print(\"Ranking by weighted_acceptance_cost:\", [labels[i] for i in wac_rank])\n",
"print(\"Ranking by factory_throughput: \", [labels[i] for i in ft_rank])"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"reflect(tracker, \"p3_q1_scoring_choice\",\n",
" question=\"You see that different scoring functions rank experiments differently. When would you choose factory throughput over WAC?\",\n",
" section=\"Pass 3: Scoring\", bloom=\"evaluate\",\n",
" model_answer=\"Factory throughput penalizes cost more heavily. Use it when you are producing many T-states in a pipeline and throughput matters more than per-state quality.\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Key Insight:** Different scoring functions can re-order the rankings. The factory throughput scorer penalizes circuit complexity more heavily, which can favor simpler circuits even if their raw quality is slightly lower."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.3 Run a Full Multi-Step Rung and Visualize the Trajectory\n",
"\n",
"Let's run a full rung with `step_budget=3` and watch the score evolve over steps. The patience mechanism will stop early if the ratchet stalls."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"store_multi = ResearchStore(tempfile.mkdtemp())\n",
"harness_multi = AutoresearchHarness(store_multi)\n",
"\n",
"config_multi = replace(rung1_config, step_budget=3, patience=2)\n",
"steps_multi, lesson_multi, feedback_multi = harness_multi.run_rung(config_multi)\n",
"\n",
"# Extract trajectory\n",
"step_indices = [s.step_index for s in steps_multi]\n",
"winning_margins = [s.winning_margin for s in steps_multi]\n",
"winner_ids = [s.winner_id[:16] for s in steps_multi]\n",
"\n",
"# Get incumbent score at each step by loading experiment\n",
"incumbent_scores = []\n",
"for s in steps_multi:\n",
" exp_data = store_multi.load_experiment(1, s.winner_id)\n",
" incumbent_scores.append(exp_data[\"final_score\"])\n",
"\n",
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))\n",
"\n",
"ax1.plot(step_indices, incumbent_scores, \"o-\", color=\"#2ecc71\", linewidth=2, markersize=8)\n",
"ax1.set_xlabel(\"Step\")\n",
"ax1.set_ylabel(\"Winner Score\")\n",
"ax1.set_title(\"Score Trajectory Over Ratchet Steps\")\n",
"ax1.grid(True, alpha=0.3)\n",
"\n",
"colors_margin = [\"#2ecc71\" if m > 0 else \"#e74c3c\" for m in winning_margins]\n",
"ax2.bar(step_indices, winning_margins, color=colors_margin)\n",
"ax2.axhline(y=0, color=\"black\", linewidth=0.5)\n",
"ax2.set_xlabel(\"Step\")\n",
"ax2.set_ylabel(\"Winning Margin\")\n",
"ax2.set_title(\"Margin Over Previous Incumbent\")\n",
"ax2.grid(True, alpha=0.3)\n",
"\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"print(f\"Steps completed: {len(steps_multi)} / {config_multi.step_budget}\")\n",
"for s in steps_multi:\n",
" print(f\" Step {s.step_index}: margin={s.winning_margin:+.6f} challengers={len(s.challengers_tested)} promoted={len(s.promoted_challengers)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### &#9997; Code Challenge\n",
"\n",
"Write code to compute the **cumulative best score** at each step of the multi-step rung.\n",
"That is, for each step, track the highest score seen so far."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.4 Visualize the Exploration Path\n",
"\n",
"For each step, what parameter changed and by how much did the score shift?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Collect step-by-step exploration data\n",
"ratchet_steps_data = store_multi.list_ratchet_steps(1)\n",
"\n",
"print(f\"{'Step':>5s} {'Winner':>20s} {'Margin':>10s} {'Lesson (first 80 chars)'}\")\n",
"print(\"-\" * 120)\n",
"for step_data in ratchet_steps_data:\n",
" print(\n",
" f\"{step_data['step_index']:5d} \"\n",
" f\"{step_data['winner_id'][:20]:>20s} \"\n",
" f\"{step_data['winning_margin']:+10.6f} \"\n",
" f\"{step_data['distilled_lesson'][:80]}\"\n",
" )\n",
"\n",
"# Show all experiments as a parameter heatmap\n",
"all_exps = store_multi.list_experiments(1)\n",
"dimensions = list(rung1_config.search_space.dimensions.keys())\n",
"\n",
"print(f\"\\n{'ID':>20s} {'Score':>10s} {'Role':>12s}\", end=\"\")\n",
"for d in dimensions[:4]:\n",
" print(f\" {d:>18s}\", end=\"\")\n",
"print()\n",
"print(\"-\" * 110)\n",
"for e in sorted(all_exps, key=lambda x: x[\"final_score\"], reverse=True)[:10]:\n",
" print(f\"{e['experiment_id'][:20]:>20s} {e['final_score']:10.6f} {e['role']:>12s}\", end=\"\")\n",
" for d in dimensions[:4]:\n",
" print(f\" {str(e['spec'].get(d, ''))[:18]:>18s}\", end=\"\")\n",
" print()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.5 Search Strategies Head-to-Head\n",
"\n",
"The system uses three search strategies:\n",
"- **NeighborWalk**: Change one parameter at a time (systematic)\n",
"- **RandomCombo**: Change 1-3 parameters at once (exploratory)\n",
"- **LessonGuided**: Use rules from previous rungs to bias the search (adaptive)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from autoresearch_quantum.search.strategies import NeighborWalk, RandomCombo, LessonGuided\n",
"\n",
"incumbent_for_test = rung1_config.bootstrap_incumbent\n",
"space_for_test = rung1_config.search_space\n",
"\n",
"nw = NeighborWalk()\n",
"rc = RandomCombo(num_candidates=8)\n",
"\n",
"nw_challengers = nw.generate(incumbent_for_test, space_for_test, set())\n",
"rc_challengers = rc.generate(incumbent_for_test, space_for_test, set())\n",
"\n",
"print(f\"NeighborWalk generated {len(nw_challengers)} challengers\")\n",
"print(f\"RandomCombo generated {len(rc_challengers)} challengers\")\n",
"\n",
"# Count mutations per dimension for each strategy\n",
"def count_dimensions(challengers):\n",
" dim_counts = {}\n",
" for ch in challengers:\n",
" for dim in dimensions:\n",
" if dim in ch.mutation_note:\n",
" dim_counts[dim] = dim_counts.get(dim, 0) + 1\n",
" return dim_counts\n",
"\n",
"nw_dims = count_dimensions(nw_challengers)\n",
"rc_dims = count_dimensions(rc_challengers)\n",
"\n",
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))\n",
"\n",
"if nw_dims:\n",
" ax1.barh(list(nw_dims.keys()), list(nw_dims.values()), color=\"#3498db\")\n",
" ax1.set_title(\"NeighborWalk: Mutations per Dimension\")\n",
" ax1.set_xlabel(\"Count\")\n",
"\n",
"if rc_dims:\n",
" ax2.barh(list(rc_dims.keys()), list(rc_dims.values()), color=\"#e67e22\")\n",
" ax2.set_title(\"RandomCombo: Mutations per Dimension\")\n",
" ax2.set_xlabel(\"Count\")\n",
"\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"# Show multi-dimensional mutations from RandomCombo\n",
"print(\"\\nRandomCombo mutations (note multi-dimensional changes):\")\n",
"for ch in rc_challengers[:6]:\n",
" print(f\" {ch.mutation_note}\")"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"order(tracker, \"p3_q2_strategy_comparison\",\n",
" instruction=\"Rank strategies by ability to find multi-parameter interactions (worst to best):\",\n",
" items=[\"NeighborWalk\", \"RandomCombo\", \"LessonGuided\"],\n",
" correct_order=[\"NeighborWalk\", \"LessonGuided\", \"RandomCombo\"],\n",
" section=\"Pass 3: Strategies\", bloom=\"analyze\",\n",
" explanation=\"NeighborWalk: 1 axis only. LessonGuided: focused by rules. RandomCombo: multiple axes, can find synergies.\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.6 Lesson-Guided Search\n",
"\n",
"The `LessonGuided` strategy uses rules extracted from previous rungs. Let's create synthetic rules to see how they bias the search."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from autoresearch_quantum.models import SearchRule, LessonFeedback\n",
"\n",
"# Create synthetic rules: prefer z_only verification, avoid x_only\n",
"synthetic_rules = [\n",
" SearchRule(\n",
" dimension=\"verification\",\n",
" action=\"prefer\",\n",
" value=\"z_only\",\n",
" confidence=0.8,\n",
" reason=\"synthetic: z_only performed best in testing\",\n",
" ),\n",
" SearchRule(\n",
" dimension=\"verification\",\n",
" action=\"avoid\",\n",
" value=\"x_only\",\n",
" confidence=0.7,\n",
" reason=\"synthetic: x_only consistently underperformed\",\n",
" ),\n",
" SearchRule(\n",
" dimension=\"encoder_style\",\n",
" action=\"prefer\",\n",
" value=\"cx_chain\",\n",
" confidence=0.6,\n",
" reason=\"synthetic: cx_chain has fewer two-qubit gates after transpilation\",\n",
" ),\n",
"]\n",
"\n",
"synthetic_feedback = LessonFeedback(\n",
" rung=0,\n",
" rules=synthetic_rules,\n",
" narrowed_dimensions={},\n",
" best_spec_fields={},\n",
")\n",
"\n",
"lg = LessonGuided(num_candidates=8)\n",
"lg_challengers = lg.generate(\n",
" incumbent_for_test, space_for_test, set(), lessons=[synthetic_feedback]\n",
")\n",
"\n",
"print(f\"LessonGuided generated {len(lg_challengers)} challengers:\")\n",
"for ch in lg_challengers:\n",
" print(f\" {ch.mutation_note}\")\n",
"\n",
"# Check: does it avoid x_only?\n",
"has_x_only = any(\"x_only\" in ch.mutation_note for ch in lg_challengers)\n",
"has_z_only = any(\"z_only\" in ch.mutation_note for ch in lg_challengers)\n",
"print(f\"\\nContains x_only mutations: {has_x_only} (should be rare/absent)\")\n",
"print(f\"Contains z_only mutations: {has_z_only} (should be common)\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### &#9997; Code Challenge\n",
"\n",
"Create a search rule that **avoids** the `\"none\"` postselection setting\n",
"with high confidence, and add it to the `synthetic_rules` list."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Key Insight:** Lesson-guided search closes the feedback loop. What the ratchet learns in one rung can guide exploration in the next, avoiding settings that already proved poor and focusing on promising regions."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.7 Cross-Rung Propagation\n",
"\n",
"The full `run_ratchet()` method runs multiple rungs in sequence. The winner from rung 1 bootstraps rung 2, and lessons accumulate across rungs."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"rung2_config = load_rung_config(\"../../configs/rungs/rung2.yaml\")\n",
"\n",
"# Use smaller budgets for speed\n",
"config_r1 = replace(rung1_config, step_budget=2, patience=2)\n",
"config_r2 = replace(rung2_config, step_budget=2, patience=2)\n",
"\n",
"store_cross = ResearchStore(tempfile.mkdtemp())\n",
"harness_cross = AutoresearchHarness(store_cross)\n",
"\n",
"print(\"Running cross-rung ratchet (rung1 -> rung2)...\")\n",
"results = harness_cross.run_ratchet([config_r1, config_r2])\n",
"\n",
"for lesson_obj, fb in results:\n",
" print(f\"\\n{'='*60}\")\n",
" print(f\"Rung {lesson_obj.rung}: {lesson_obj.name}\")\n",
" print(f\" What helped: {lesson_obj.what_helped[:2]}\")\n",
" print(f\" What hurt: {lesson_obj.what_hurt[:2]}\")\n",
" print(f\" Rules learned: {len(fb.rules)}\")\n",
" if fb.best_spec_fields:\n",
" print(f\" Best spec seed: {fb.best_spec_fields.get('seed_style', '?')}\")\n",
" print(f\" Best spec verif: {fb.best_spec_fields.get('verification', '?')}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.8 Transfer Evaluation\n",
"\n",
"How well does a winning spec perform across different backend noise profiles? The `TransferEvaluator` tests a single spec on multiple backends and reports the pessimistic (minimum) score."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from autoresearch_quantum.execution.transfer import TransferEvaluator\n",
"\n",
"# Get the rung1 winner\n",
"winner_id = store_cross.load_incumbent_id(1)\n",
"winner_data = store_cross.load_experiment(1, winner_id)\n",
"winner_spec = ExperimentSpec(**{\n",
" k: tuple(v) if k == \"initial_layout\" and isinstance(v, list) else v\n",
" for k, v in winner_data[\"spec\"].items()\n",
"})\n",
"\n",
"# Evaluate on a single additional backend\n",
"transfer_eval = TransferEvaluator()\n",
"report = transfer_eval.evaluate_across_backends(\n",
" winner_spec,\n",
" backends=[\"fake_brisbane\", \"fake_kyoto\"],\n",
" rung_config=config_r1,\n",
")\n",
"\n",
"print(f\"Transfer Evaluation Report\")\n",
"print(f\"{'='*50}\")\n",
"print(f\"Spec fingerprint: {winner_spec.fingerprint()}\")\n",
"print(f\"\\nPer-backend scores:\")\n",
"for bk, sc in report.per_backend_scores.items():\n",
" print(f\" {bk:20s}: {sc:.6f}\")\n",
"print(f\"\\nMean score: {report.mean_score:.6f}\")\n",
"print(f\"Min score: {report.min_score:.6f}\")\n",
"print(f\"Max score: {report.max_score:.6f}\")\n",
"print(f\"Std score: {report.std_score:.6f}\")\n",
"print(f\"Transfer score: {report.transfer_score:.6f} (pessimistic = min)\")"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"quiz(tracker, \"p3_q3_transfer\",\n",
" question=\"A spec scores 0.8 on fake_brisbane but 0.3 on a different backend. What does this tell you?\",\n",
" options=[\n",
" \"The spec is bad\",\n",
" \"The spec is overfitted to fake_brisbane's specific noise profile\",\n",
" \"The other backend is broken\",\n",
" ],\n",
" correct=1, section=\"Pass 3: Transfer\", bloom=\"evaluate\",\n",
" explanation=\"A large score drop on transfer means the settings were tuned to one backend's quirks rather than being generally good.\")\n",
"\n",
"checkpoint_summary(tracker, \"Pass 3: Transfer\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Key Insight:** A spec that scores well on one backend may score poorly on another. The transfer score (minimum across backends) prevents overfitting to a single noise profile. This is crucial for real quantum computing where hardware changes day to day."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3.9 Your Own Experiment\n",
"\n",
"Here is a template for you to create and evaluate your own experiment. Modify the spec fields, run it, and see how your design compares to the ratchet's winner."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# === YOUR EXPERIMENT ===\n",
"# Modify these parameters and re-run the cell!\n",
"\n",
"my_spec = ExperimentSpec(\n",
" rung=1,\n",
" seed_style=\"ry_rz\", # Try: \"h_p\", \"ry_rz\", \"u_magic\"\n",
" encoder_style=\"cx_chain\", # Try: \"cx_chain\", \"cz_compiled\"\n",
" verification=\"both\", # Try: \"both\", \"z_only\", \"x_only\"\n",
" postselection=\"all_measured\", # Try: \"all_measured\", \"z_only\", \"none\"\n",
" ancilla_strategy=\"dedicated_pair\", # Try: \"dedicated_pair\", \"reused_single\"\n",
" optimization_level=2, # Try: 1, 2, 3\n",
" layout_method=\"sabre\",\n",
" routing_method=\"sabre\",\n",
" target_backend=\"fake_brisbane\",\n",
" noise_backend=\"fake_brisbane\",\n",
" shots=256,\n",
" repeats=1,\n",
")\n",
"\n",
"my_result = executor.evaluate(my_spec, rung1_config)\n",
"\n",
"print(f\"Your Experiment Results\")\n",
"print(f\"{'='*50}\")\n",
"print(f\"Score: {my_result.score:.6f}\")\n",
"print(f\"Quality: {my_result.quality_estimate:.6f}\")\n",
"print(f\"Acceptance rate: {my_result.metrics.acceptance_rate:.4f}\")\n",
"print(f\"Magic witness: {my_result.metrics.logical_magic_witness:.4f}\")\n",
"print(f\"Spectator Z: {my_result.metrics.spectator_logical_z:.4f}\")\n",
"print(f\"Two-qubit gates: {my_result.metrics.two_qubit_count}\")\n",
"print(f\"Depth: {my_result.metrics.depth}\")\n",
"print(f\"Total cost: {my_result.metrics.total_cost:.4f}\")\n",
"print(f\"Failure mode: {my_result.metrics.dominant_failure_mode}\")\n",
"\n",
"# Compare to the ratchet winner\n",
"print(f\"\\nRatchet winner score: {winner_data['final_score']:.6f}\")\n",
"delta = my_result.score - winner_data['final_score']\n",
"print(f\"Your delta: {delta:+.6f} {'(you win!)' if delta > 0 else '(ratchet wins)'}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### &#9997; Code Challenge\n",
"\n",
"Modify the experiment spec above, evaluate it, and check whether your custom spec\n",
"beats the rung1 default incumbent score. Set `my_spec_beats_default` to `True` if it does."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Summary\n",
"\n",
"You have now seen the same system three times.\n",
"\n",
"**The first time was magic** -- you pushed a button and an optimizer ran, producing scores, winners, and a lesson narrative. You had no idea what any of it meant.\n",
"\n",
"**The second time was science** -- you built the T-state from scratch, understood stabilizers, measured the witness, computed the score by hand, and saw how challengers compete. Every number from Pass 1 had a concrete physical meaning.\n",
"\n",
"**The third time was engineering** -- you modified the search space, compared scoring functions, ran multi-rung optimizations, tested transfer across backends, and designed your own experiment.\n",
"\n",
"This is the spiral: each pass through the same material reveals structure that was invisible before. The ratchet itself works the same way -- each step builds on what came before, ratcheting toward better and better quantum experiments."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"## Final Assessment"
]
},
{
"cell_type": "code",
"metadata": {},
"source": [
"tracker.dashboard()\n",
"path = tracker.save()\n",
"print(f\"\\nProgress saved to: {path}\")"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"## You've completed Plan B!\n",
"\n",
"Want to explore the same material from a different angle? Try another plan:\n",
"- [Plan A \u2014 Sequential](../plan_a/01_encoded_magic_state.ipynb) (step-by-step, three notebooks)\n",
"- [Plan C \u2014 Parallel Tracks](../plan_c/00_dashboard.ipynb) (self-directed deep dives)\n",
"- [Plan D \u2014 Hypothesis-Driven](../plan_d/experiment_1_protection.ipynb) (experimental method)\n",
"\n",
"*\u2190 Back to [Start Here](../00_START_HERE.ipynb)*"
],
"id": "nav-footer-spiral"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.14.2"
}
},
"nbformat": 4,
"nbformat_minor": 4
}