QuantumLearning/notebooks/foundations/module_03_gates_and_measurement/lab.ipynb

292 lines
13 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Gates and Measurement Lab\n",
"\n",
"This lab turns protocol language into concrete manipulation. The main question is not whether the circuit executes. The main question is whether you can change preparation, basis, or reporting one at a time and still keep the explanation stable.\n"
],
"id": "4f89a231"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Lab Protocol\n",
"\n",
"Use the same lab cycle as before: predict, edit one thing, render, inspect, and revise. The only difference here is that you should now classify the edit even more explicitly. Did you change the prepared state, the measurement basis, or the classical reporting layer? If you cannot answer that, the edit was not conceptually controlled enough.\n"
],
"id": "63c86802"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pathlib import Path\n",
"import sys\n",
"\n",
"project_root = Path.cwd().resolve()\n",
"while not (project_root / \"pyproject.toml\").exists():\n",
" if project_root.parent == project_root:\n",
" raise RuntimeError(\"Could not locate the project root from this notebook.\")\n",
" project_root = project_root.parent\n",
"\n",
"src_path = project_root / \"src\"\n",
"if str(src_path) not in sys.path:\n",
" sys.path.insert(0, str(src_path))\n"
],
"id": "a84bcf22"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from quantum_learning import (\n",
" counts_to_probabilities,\n",
" editable_circuit_lab,\n",
" plot_counts,\n",
" plot_probabilities,\n",
" quiz_block,\n",
" reflection_box,\n",
" simulate_counts,\n",
" statevector_probabilities,\n",
" step_reference_table,\n",
")\n",
"from qiskit import QuantumCircuit\n",
"from qiskit.quantum_info import Statevector\n"
],
"id": "96b9c26f"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Lab 1: Small Gate Compositions\n",
"\n",
"Start with a one-qubit circuit. Move `X`, `H`, and `Z` around and explain why the final counts change or fail to change. The purpose is to stop treating gate names as slogans and start treating them as transformations in sequence.\n"
],
"id": "52ccfd63"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"editable_code = '\\ncircuit = QuantumCircuit(1, 1)\\n# [1] Try changing the preparation gate sequence.\\ncircuit.x(0)\\ncircuit.h(0)\\n# [2] Optionally add Z or another H before measurement.\\n# circuit.z(0)\\n# circuit.h(0)\\n# [3] Measure the result.\\ncircuit.measure(0, 0)\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Lab 1: Small Gate Composition',\n",
" instructions='Reorder or add one gate at a time and explain whether the change altered preparation, phase, or the measurement question.',\n",
" shots=256,\n",
")\n"
],
"id": "cc601f31"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"low_shot = QuantumCircuit(1, 1)\n",
"low_shot.h(0)\n",
"low_shot.measure(0, 0)\n",
"\n",
"counts_64 = simulate_counts(low_shot, shots=64)\n",
"counts_4096 = simulate_counts(low_shot, shots=4096)\n",
"{\n",
" \"64_shots\": counts_64,\n",
" \"4096_shots\": counts_4096,\n",
"}\n"
],
"id": "24906bb8"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The first lab makes a simple but essential point: the meaning of a gate sequence is not the sum of independent gate slogans. Order matters. Context matters. A `Z` in the middle of a sequence can be invisible in one immediate view and decisive in a later one.\n"
],
"id": "6ad837ec"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"quiz_block([{'prompt': 'What is the best reason to compare counts across different shot budgets?', 'options': ['To separate stable probability claims from normal sampling fluctuation', 'To reduce circuit depth', 'To change the prepared state'], 'correct_index': 0, 'explanation': 'Shot scaling teaches you how much statistical noise to expect from the same circuit.'}, {'prompt': 'What does swapping classical bit targets test?', 'options': ['Whether your explanation tracks the reporting layer instead of only the quantum layer', 'Whether CNOT still works', 'Whether the backend supports measurement'], 'correct_index': 0, 'explanation': 'Good reasoning follows the evidence all the way into the bitstring labels.'}], heading='Measurement Lab Checkpoint A')\n"
],
"id": "6551598f"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('Which one-qubit edit best exposed the difference between changing preparation and changing the final question?')\n"
],
"id": "972e2163"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Lab 2: Basis Rotation On A Two-Qubit Circuit\n",
"\n",
"Return to the Bell-style preparation and vary the final Hadamard placement. Ask the stronger question every time: what did this edit change in the protocol, and what evidence would support that claim?\n"
],
"id": "b87858ab"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"step_reference_table([{'marker': '[1]', 'code_focus': 'Prepare a Bell-style correlated state with `H` and `CX`.', 'diagram_effect': 'The first two operations create a structured two-wire object rather than two independent qubits.', 'why_it_matters': 'Measurement interpretation depends on what was prepared before the final question is asked.'}, {'marker': '[2]', 'code_focus': 'Rotate one qubit with `H` immediately before measurement.', 'diagram_effect': 'The final question changes on that wire without erasing the rest of the preparation story.', 'why_it_matters': 'Basis changes are part of the experiment design, not cosmetic extras.'}, {'marker': '[3]', 'code_focus': 'Measure into explicitly chosen classical bits.', 'diagram_effect': 'The circuit commits to a specific readout question and a specific reporting layout.', 'why_it_matters': 'Classical wiring is part of the evidence trail and can itself become a source of confusion.'}])\n"
],
"id": "3fe842ef"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"editable_code = '\\ncircuit = QuantumCircuit(2, 2)\\n# [1] Prepare the correlated state.\\ncircuit.h(0)\\ncircuit.cx(0, 1)\\n# [2] Change the basis of the first measurement question.\\ncircuit.h(0)\\n# [3] Measure both qubits into the matching classical bits.\\ncircuit.measure([0, 1], [0, 1])\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Lab 2: Bell Basis Rotation',\n",
" instructions='Move or delete the final Hadamard and explain whether your edit changed preparation or only the final measurement question.',\n",
" shots=256,\n",
")\n"
],
"id": "b7d1eeee"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"bell_z = QuantumCircuit(2, 2)\n",
"bell_z.h(0)\n",
"bell_z.cx(0, 1)\n",
"bell_z.measure([0, 1], [0, 1])\n",
"\n",
"bell_x_probe = QuantumCircuit(2, 2)\n",
"bell_x_probe.h(0)\n",
"bell_x_probe.cx(0, 1)\n",
"bell_x_probe.h(0)\n",
"bell_x_probe.measure([0, 1], [0, 1])\n",
"\n",
"{\n",
" \"z_basis_counts\": simulate_counts(bell_z, shots=512),\n",
" \"probe_counts\": simulate_counts(bell_x_probe, shots=512),\n",
"}\n"
],
"id": "0ce075f6"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Lab 3: Reporting Layer Sanity Check\n",
"\n",
"The last lab isolates classical wiring. Swapping the target classical bits should not be explained as a change in quantum preparation. It is a reporting change. That sounds obvious when written plainly, but many learners still misread the resulting bitstrings unless the notebook forces the distinction.\n"
],
"id": "9b9438df"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"editable_code = '\\ncircuit = QuantumCircuit(2, 2)\\n# [1] Prepare a Bell-style state.\\ncircuit.h(0)\\ncircuit.cx(0, 1)\\n# [2] Try swapping the classical wiring.\\ncircuit.measure([0, 1], [1, 0])\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Lab 3: Classical Wiring Check',\n",
" instructions='Switch between direct and swapped classical mappings and explain how the evidence labels change even if the quantum preparation story does not.',\n",
" shots=256,\n",
")\n"
],
"id": "7fc13277"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This exercise is professionally important because many debugging mistakes come from the reporting layer, not from the state preparation layer. A world-class lecture series should train that suspicion early rather than treating it as an advanced nuisance.\n"
],
"id": "c4bc5363"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Lab Debrief\n",
"\n",
"These three labs together teach a simple review pattern. First ask whether the preparation changed. If not, ask whether the measurement basis changed. If not, ask whether only the reporting layer changed. That sequence is powerful because it narrows explanation quickly. It also stops you from inventing dramatic quantum stories for what may only be a bookkeeping issue.\n",
"\n",
"The debrief is worth reading carefully because many learners still default to a single undifferentiated sentence such as \u201cthe circuit output changed.\u201d That sentence contains almost no engineering value. A stronger sentence might be: \u201cThe prepared Bell-style state stayed the same, but the added Hadamard changed the first qubit's measurement basis, so the empirical correlation pattern now answers a different question.\u201d That is the level of explanation this lab is trying to normalize.\n"
],
"id": "c20e3d2e"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"quiz_block([{'prompt': 'If a final Hadamard changes the counts drastically, what is the first serious question to ask?', 'options': ['Did I change the measurement basis rather than merely add decoration?', 'Did the notebook theme corrupt the circuit?', 'Did the number of qubits change automatically?'], 'correct_index': 0, 'explanation': 'The basis question is the right first interpretation, not panic.'}, {'prompt': 'Why keep counts and probabilities conceptually separate in the same notebook?', 'options': ['Because one is sampled evidence and the other is an idealized expectation derived from the model', 'Because they should never be compared', 'Because counts are only for advanced users'], 'correct_index': 0, 'explanation': 'Serious measurement reasoning compares the ideal story with sampled evidence carefully.'}], heading='Measurement Lab Checkpoint B')\n"
],
"id": "70a4176d"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('Write a short explanation of how you would distinguish a basis mistake from a classical-wiring mistake in a notebook review.')\n"
],
"id": "aebe7688"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('What does shot noise change in your interpretation, and what does it not change?')\n"
],
"id": "e0354f4e"
}
],
"metadata": {
"kernelspec": {
"display_name": "QuantumLearning (.venv)",
"language": "python",
"name": "quantum-learning"
},
"language_info": {
"name": "python",
"version": "3.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}