{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Track A: The Physics of Encoded Magic States\n", "\n", "**Plan C \u2014 Parallel Tracks**\n", "\n", "This track is pure quantum mechanics. It covers the theory behind magic states, the [[4,2,2]] stabilizer code, and the witness formula. No optimization, no scoring \u2014 just the physics.\n", "\n", "> **Dashboard:** Open `00_dashboard.ipynb` alongside this notebook for interactive exploration." ] }, { "cell_type": "code", "metadata": {}, "source": [ "%matplotlib inline\n", "import warnings\n", "warnings.filterwarnings(\"ignore\")\n", "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from math import pi, sqrt\n", "\n", "from qiskit import QuantumCircuit\n", "from qiskit.quantum_info import Statevector, SparsePauliOp, state_fidelity, Operator\n", "from qiskit.visualization import plot_bloch_multivector\n", "from qiskit_aer import AerSimulator\n", "\n", "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", "from autoresearch_quantum.experiments.encoded_magic_state import build_circuit_bundle\n", "from autoresearch_quantum.models import ExperimentSpec\n", "from autoresearch_quantum.execution.analysis import logical_magic_witness\n", "\n", "print(\"All imports successful.\")" ], "outputs": [], "execution_count": null }, { "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_c_track_a\")\n", "print(\"Learning tracker active.\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 1. Why Magic States Matter\n", "\n", "Quantum error correction can protect information, but it has a fundamental limitation:\n", "\n", "> **The Eastin-Knill Theorem:** No quantum error-correcting code can implement a universal gate set transversally (i.e., by applying independent gates to each physical qubit).\n", "\n", "Clifford gates ($H$, $S$, CNOT) *can* be done transversally on many codes. But Cliffords alone are **classically simulable** (Gottesman-Knill theorem). To get universal quantum computation, you need at least one non-Clifford gate.\n", "\n", "The standard choice is the **T-gate** ($\\pi/8$ rotation):\n", "\n", "$$T = \\begin{pmatrix} 1 & 0 \\\\ 0 & e^{i\\pi/4} \\end{pmatrix}$$\n", "\n", "Instead of applying $T$ directly (which would break error correction), we prepare a special resource state called a **magic state** and consume it via **gate teleportation**." ] }, { "cell_type": "code", "metadata": {}, "source": [ "quiz(tracker, \"q1_eastin_knill\",\n", " question=\"The Eastin-Knill theorem limits fault-tolerant QC. What does it say?\",\n", " options=[\n", " \"No quantum code can detect all errors\",\n", " \"No quantum code has a universal set of transversal gates \\u2014 you need a non-transversal resource like magic states\",\n", " \"Quantum error correction always requires more physical qubits than logical qubits\",\n", " ],\n", " correct=1, section=\"1. Why magic states\", bloom=\"remember\",\n", " explanation=\"Eastin-Knill: you cannot implement a universal gate set transversally in any code. The T-gate is the most common non-transversal resource, supplied via magic states.\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 2. The T-State on the Bloch Sphere\n", "\n", "The magic state for the T-gate is:\n", "\n", "$$|T\\rangle = H \\cdot T|0\\rangle = \\frac{|0\\rangle + e^{i\\pi/4}|1\\rangle}{\\sqrt{2}}$$" ] }, { "cell_type": "code", "metadata": {}, "source": [ "qc = QuantumCircuit(1, name=\"|T>\")\n", "qc.h(0)\n", "qc.p(pi/4, 0)\n", "\n", "t_state = Statevector.from_instruction(qc)\n", "print(\"T-state amplitudes:\")\n", "print(f\" |0>: {t_state[0]:.4f}\")\n", "print(f\" |1>: {t_state[1]:.4f}\")\n", "print(f\" |1> phase: {np.angle(t_state[1]) * 180 / pi:.1f} degrees = pi/4\")\n", "\n", "alpha, beta = t_state[0], t_state[1]\n", "exp_x = 2 * np.real(np.conj(alpha) * beta)\n", "exp_y = 2 * np.imag(np.conj(alpha) * beta)\n", "exp_z = float(np.abs(alpha)**2 - np.abs(beta)**2)\n", "print(f\"\\nBloch coordinates:\")\n", "print(f\" = {exp_x:.4f} (expected: 1/sqrt(2) = {1/sqrt(2):.4f})\")\n", "print(f\" = {exp_y:.4f} (expected: 1/sqrt(2) = {1/sqrt(2):.4f})\")\n", "print(f\" = {exp_z:.4f} (on the equator)\")\n", "\n", "plot_bloch_multivector(t_state)" ], "outputs": [], "execution_count": null }, { "cell_type": "code", "metadata": {}, "source": [ "quiz(tracker, \"q2_tstate_phase\",\n", " question=\"The T-state phase on |1\\u27E9 is:\",\n", " options=[\"\\u03C0/2\", \"\\u03C0/4\", \"\\u03C0/8\"],\n", " correct=1, section=\"2. T-state\", bloom=\"remember\",\n", " explanation=\"\\u03C0/4 = 45\\u00b0. Despite the gate being called T (\\u03C0/8 rotation on the Bloch sphere), the state phase is \\u03C0/4.\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Key Insight:** The T-state sits at $\\theta = \\pi/2$ from the Z-axis and $\\phi = \\pi/4$ azimuthally. Its defining feature: $\\langle X \\rangle = \\langle Y \\rangle = 1/\\sqrt{2}$. No stabilizer state has this property." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 3. Three Equivalent Preparations\n", "\n", "The codebase offers three gate sequences to prepare $|T\\rangle$. All produce the same state up to a global phase." ] }, { "cell_type": "code", "metadata": {}, "source": [ "styles = [\"h_p\", \"ry_rz\", \"u_magic\"]\n", "states = []\n", "\n", "for style in styles:\n", " qc = QuantumCircuit(1)\n", " apply_magic_seed(qc, 0, style)\n", " sv = Statevector.from_instruction(qc)\n", " states.append(sv)\n", " print(f\"{style:8s}: amplitudes = [{sv[0]:.4f}, {sv[1]:.4f}]\")\n", "\n", "print(\"\\nPairwise fidelities (1.0 = identical up to global phase):\")\n", "for i in range(len(styles)):\n", " for j in range(i+1, len(styles)):\n", " fid = state_fidelity(states[i], states[j])\n", " print(f\" {styles[i]} vs {styles[j]}: F = {fid:.10f}\")" ], "outputs": [], "execution_count": null }, { "cell_type": "code", "metadata": {}, "source": [ "quiz(tracker, \"q3_global_phase\",\n", " question=\"Three gate sequences produce states with different amplitudes but fidelity 1.0. Why?\",\n", " options=[\n", " \"Floating-point errors\",\n", " \"Global phase has no physical consequence\",\n", " \"They actually produce different states\",\n", " ],\n", " correct=1, section=\"3. Preparations\", bloom=\"understand\",\n", " explanation=\"A global phase multiplies ALL amplitudes. No measurement can distinguish the states.\")\n", "checkpoint_summary(tracker, \"3. Preparations\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 4. The [[4,2,2]] Code\n", "\n", "The [[4,2,2]] code encodes **2 logical qubits** into **4 physical qubits** with distance **2**.\n", "\n", "The **stabilizer group**:\n", "\n", "$$\\mathcal{S} = \\langle X_0 X_1 X_2 X_3,\\; Z_0 Z_1 Z_2 Z_3 \\rangle$$\n", "\n", "The codespace is the simultaneous $+1$ eigenspace of both generators. Dimension: $2^4 / 2^2 = 4 = 2^2$ (room for 2 logical qubits)." ] }, { "cell_type": "code", "metadata": {}, "source": [ "for name, stab in STABILIZERS.items():\n", " print(f\"{name}: {stab.to_list()}\")\n", " stab_sq = stab @ stab\n", " is_identity = np.allclose(stab_sq.to_matrix(), np.eye(16))\n", " print(f\" Squares to identity: {is_identity}\")\n", "\n", "comm = STABILIZERS[\"z_stabilizer\"] @ STABILIZERS[\"x_stabilizer\"] - STABILIZERS[\"x_stabilizer\"] @ STABILIZERS[\"z_stabilizer\"]\n", "print(f\"\\n[ZZZZ, XXXX] = {np.max(np.abs(comm.to_matrix())):.1e} (should be 0 = they commute)\")" ], "outputs": [], "execution_count": null }, { "cell_type": "code", "metadata": {}, "source": [ "quiz(tracker, \"q4_stabilizer_square\",\n", " question=\"Each stabilizer squares to the identity (S\\u00b2 = I). What does this imply about its eigenvalues?\",\n", " options=[\n", " \"Eigenvalues can be anything\",\n", " \"Eigenvalues are exactly +1 or \\u22121\",\n", " \"Eigenvalues are 0 or 1\",\n", " ],\n", " correct=1, section=\"4. [[4,2,2]] code\", bloom=\"understand\",\n", " explanation=\"If S\\u00b2 = I, then S has eigenvalues \\u00b11. The codespace has eigenvalue +1; error states have \\u22121.\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 5. Logical Operators\n", "\n", "| Logical qubit | $X_L$ | $Z_L$ |\n", "|---|---|---|\n", "| Qubit 0 (magic) | $X_0 X_2$ | $Z_0 Z_2$ |\n", "| Qubit 1 (spectator) | $X_1 X_3$ | $Z_1 Z_2$ |\n", "\n", "For the magic witness we measure: $X_L$, $Y_L = Y_0 Z_1 X_2$, and $Z_{\\text{spectator}} = Z_1 Z_2$." ] }, { "cell_type": "code", "metadata": {}, "source": [ "print(\"Measurement operators for the magic witness:\")\n", "for name, op_dict in MEASUREMENT_OPERATORS.items():\n", " pauli_str = [\"I\"] * 4\n", " for qubit, basis in op_dict.items():\n", " pauli_str[qubit] = basis\n", " label = \"\".join(reversed(pauli_str))\n", " print(f\" {name:15s} = {label} (qubits {dict(op_dict)})\")" ], "outputs": [], "execution_count": null }, { "cell_type": "code", "metadata": {}, "source": [ "quiz(tracker, \"q5_logical_ops\",\n", " question=\"Why does the logical Y operator (Y\\u2080Z\\u2081X\\u2082) involve 3 qubits instead of just 1?\",\n", " options=[\n", " \"It's a bug in the code\",\n", " \"In a quantum code, logical operators act on the encoded information which is spread across multiple physical qubits\",\n", " \"Y is always a 3-qubit operator\",\n", " ],\n", " correct=1, section=\"5. Logical operators\", bloom=\"understand\",\n", " explanation=\"The logical information is distributed across all physical qubits. Logical operators must act on this distributed encoding.\")\n", "checkpoint_summary(tracker, \"5. Logical operators\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 6. The Encoding Circuit" ] }, { "cell_type": "code", "metadata": {}, "source": [ "for style in [\"cx_chain\", \"cz_compiled\"]:\n", " enc = build_encoder(style)\n", " print(f\"\\n{style}:\")\n", " print(enc.draw(\"text\"))" ], "outputs": [], "execution_count": null }, { "cell_type": "code", "metadata": {}, "source": [ "# Full preparation: seed + encoder\n", "prep = build_preparation_circuit(\"h_p\", \"cx_chain\")\n", "prep.draw(\"mpl\", style=\"iqp\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 7. Verifying the Encoded State\n", "\n", "The encoded T-state must satisfy: $\\langle XXXX \\rangle = \\langle ZZZZ \\rangle = +1$ (in codespace) and $\\langle X_L \\rangle = \\langle Y_L \\rangle = 1/\\sqrt{2}$, $\\langle Z_{\\text{spectator}} \\rangle = +1$." ] }, { "cell_type": "code", "metadata": {}, "source": [ "state = encoded_magic_statevector()\n", "\n", "print(\"Stabilizer expectations:\")\n", "for name, stab in STABILIZERS.items():\n", " val = state.expectation_value(stab).real\n", " print(f\" <{name}> = {val:+.6f} (should be +1)\")\n", "\n", "print(\"\\nLogical operator expectations:\")\n", "for name, op_dict in MEASUREMENT_OPERATORS.items():\n", " pauli_str = [\"I\"] * 4\n", " for qubit, basis in op_dict.items():\n", " pauli_str[qubit] = basis\n", " op = SparsePauliOp.from_list([(\"\".join(reversed(pauli_str)), 1.0)])\n", " val = state.expectation_value(op).real\n", " print(f\" <{name}> = {val:+.6f}\")\n", "\n", "print(f\"\\nExpected: = = 1/sqrt(2) = {1/sqrt(2):+.6f}\")" ], "outputs": [], "execution_count": null }, { "cell_type": "code", "metadata": {}, "source": [ "predict_choice(tracker, \"q6_z_error\",\n", " question=\"A single Z error on qubit 0: which stabilizer detects it?\",\n", " options=[\n", " \"ZZZZ (Z commutes with Z, so it detects Z errors)\",\n", " \"XXXX (Z anti-commutes with X, flipping the XXXX eigenvalue)\",\n", " \"Neither \\u2014 Z errors are invisible\",\n", " ],\n", " correct=1, section=\"8. Error detection\", bloom=\"apply\",\n", " explanation=\"Z anti-commutes with X. A Z error on any qubit flips the XXXX eigenvalue from +1 to \\u22121.\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 8. Error Detection\n", "\n", "The [[4,2,2]] code detects any single-qubit error. Let us apply errors and see which stabilizer flags them." ] }, { "cell_type": "code", "metadata": {}, "source": [ "header = f\"{'Error':12s} {'':>8s} {'':>8s} {'Detected by':>15s}\"\n", "print(header)\n", "print(\"=\" * len(header))\n", "\n", "for qubit in range(4):\n", " for error_name, error_gate in [(\"X\", \"x\"), (\"Z\", \"z\"), (\"Y\", \"y\")]:\n", " test_circuit = build_preparation_circuit(\"h_p\", \"cx_chain\")\n", " getattr(test_circuit, error_gate)(qubit)\n", " errored_state = Statevector.from_instruction(test_circuit)\n", "\n", " z_exp = errored_state.expectation_value(STABILIZERS[\"z_stabilizer\"]).real\n", " x_exp = errored_state.expectation_value(STABILIZERS[\"x_stabilizer\"]).real\n", "\n", " detected = []\n", " if abs(z_exp - 1.0) > 0.01: detected.append(\"ZZZZ\")\n", " if abs(x_exp - 1.0) > 0.01: detected.append(\"XXXX\")\n", "\n", " print(f\"{error_name} on q{qubit}: {z_exp:+.1f} {x_exp:+.1f} {', '.join(detected) or '(none)'}\")" ], "outputs": [], "execution_count": null }, { "cell_type": "code", "metadata": {}, "source": [ "order(tracker, \"q7_error_types\",\n", " instruction=\"Sort error types by how many stabilizers they trigger (fewest first):\",\n", " items=[\"X\", \"Z\", \"Y\"],\n", " correct_order=[\"X\", \"Z\", \"Y\"],\n", " section=\"8. Error detection\", bloom=\"analyze\",\n", " explanation=\"X\\u21921 (ZZZZ). Z\\u21921 (XXXX). Y\\u21922 (both). X and Z are tied.\")\n", "checkpoint_summary(tracker, \"8. Error detection\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Key Insight:** X errors flip ZZZZ to $-1$. Z errors flip XXXX to $-1$. Y = iXZ flips both. Every single-qubit error is detected by at least one stabilizer.\n", "\n", "---\n", "## 9. The Magic Witness Formula\n", "\n", "$$W = \\frac{1 + \\frac{\\langle X_L \\rangle + \\langle Y_L \\rangle}{\\sqrt{2}}}{2} \\times \\frac{1 + \\langle Z_{\\text{spectator}} \\rangle}{2}$$\n", "\n", "- Magic factor: checks non-Clifford character of logical qubit 0\n", "- Spectator factor: checks logical qubit 1 is undisturbed\n", "- $W = 1.0$ for perfect encoded T-state" ] }, { "cell_type": "code", "metadata": {}, "source": [ "lx = 1/sqrt(2)\n", "ly = 1/sqrt(2)\n", "sz = 1.0\n", "\n", "magic_factor = (1 + (lx + ly)/sqrt(2)) / 2\n", "spectator_factor = (1 + sz) / 2\n", "W = magic_factor * spectator_factor\n", "\n", "print(f\" = {lx:.4f}, = {ly:.4f}, = {sz:.4f}\")\n", "print(f\"Magic factor: (1 + ({lx:.4f}+{ly:.4f})/sqrt(2)) / 2 = {magic_factor:.4f}\")\n", "print(f\"Spectator factor: (1 + {sz:.4f}) / 2 = {spectator_factor:.4f}\")\n", "print(f\"Witness W = {W:.4f}\")\n", "print(f\"Library: W = {logical_magic_witness(lx, ly, sz):.4f}\")" ], "outputs": [], "execution_count": null }, { "cell_type": "code", "metadata": {}, "source": [ "quiz(tracker, \"q8_ideal_witness\",\n", " question=\"For a perfect T-state, the magic witness W equals:\",\n", " options=[\"0.0\", \"0.5\", \"1/\\u221A2\", \"1.0\"],\n", " correct=3, section=\"9. Witness formula\", bloom=\"apply\",\n", " explanation=\"Ideal values give magic_factor = 1 and spectator_factor = 1. Product = 1.0.\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 10. How the Witness Degrades" ] }, { "cell_type": "code", "metadata": {}, "source": [ "lx_values = np.linspace(-1, 1, 200)\n", "w_vals = [logical_magic_witness(lx, lx, 1.0) for lx in lx_values]\n", "\n", "fig, ax = plt.subplots(figsize=(8, 4))\n", "ax.plot(lx_values, w_vals, \"b-\", linewidth=2)\n", "ax.axvline(x=1/np.sqrt(2), color=\"r\", linestyle=\"--\", label=\"T-state: 1/\u221a2\")\n", "ax.set_xlabel(\" = \")\n", "ax.set_ylabel(\"Witness W\")\n", "ax.set_title(\"Magic Witness vs Logical Operator Expectations\")\n", "ax.legend()\n", "ax.set_xlim(-1, 1)\n", "ax.set_ylim(0, 1.05)\n", "plt.tight_layout()\n", "plt.show()" ], "outputs": [], "execution_count": null }, { "cell_type": "code", "metadata": {}, "source": [ "reflect(tracker, \"q9_witness_sensitivity\",\n", " question=\"The witness curve drops sharply away from the peak. Why is this useful?\",\n", " section=\"10. Witness degradation\", bloom=\"evaluate\",\n", " model_answer=\"A sharp peak means the witness is sensitive to small deviations from the ideal T-state. This sensitivity is what makes it a good diagnostic: even moderate noise produces a noticeable drop.\")\n", "checkpoint_summary(tracker, \"10. Witness degradation\")" ], "outputs": [], "execution_count": null }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Observe:** The witness peaks sharply at $1/\\sqrt{2}$. Any deviation from the ideal T-state expectation values reduces $W$.\n", "\n", "---\n", "## Summary\n", "\n", "| Concept | Key fact |\n", "|---|---|\n", "| **Magic states** | Non-Clifford resource for universal QC |\n", "| **T-state** | $\\langle X \\rangle = \\langle Y \\rangle = 1/\\sqrt{2}$ on the Bloch equator |\n", "| **[[4,2,2]] code** | 4 qubits, 2 logical, distance 2, stabilizers XXXX and ZZZZ |\n", "| **Error detection** | X caught by ZZZZ, Z caught by XXXX, Y caught by both |\n", "| **Magic witness** | $W=1$ certifies genuine encoded T-state |\n", "\n", "> **Next:** Track B covers noise and engineering. Track C covers automated search." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Free Response: Physics Synthesis\n", "\n", "Reflect on the key physics concepts from this track." ] }, { "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", "id": "11221165", "source": "---\n## Navigation \u2014 Plan C\n\n**\u2192 Next: [Track B \u2014 Engineering](track_b_engineering.ipynb)**\n\n*\u2190 [Dashboard](00_dashboard.ipynb) \u00b7 [Start Here](../00_START_HERE.ipynb)*", "metadata": {} } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.14.2" } }, "nbformat": 4, "nbformat_minor": 5 }