QuantumLearning/notebooks/algorithms/module_04_grover/lab.ipynb

827 lines
37 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #2563eb; background:#dbeafe; color:#1e3a8a; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>META READING</strong> · Difficulty 1/10 · Notebook-level rule, objective, or usage guidance.\n",
"</div>\n",
"\n",
"# Grover and Amplitude Amplification Lab\n"
],
"id": "6071e650"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #2563eb; background:#dbeafe; color:#1e3a8a; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>META READING</strong> · Difficulty 1/10 · Official walkthrough guardrail.\n",
"</div>\n",
"\n",
"<!-- COURSE_NAV_TOP -->\n",
"## Mainline Navigation\n",
"\n",
"Step 40 of 59. Follow the official walkthrough in order.\n",
"\n",
"Previous notebook: [Grover and Amplitude Amplification Lecture](lecture.ipynb)\n",
"\n",
"Next notebook: [Grover and Amplitude Amplification Problems](problems.ipynb)\n",
"\n",
"Rule: complete the mandatory cells in this notebook before you open the next one.\n"
],
"id": "13d110d1"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #2563eb; background:#dbeafe; color:#1e3a8a; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>META READING</strong> · Difficulty 1/10 · Notebook-level rule, objective, or usage guidance.\n",
"</div>\n",
"\n",
"The lab emphasizes target variation, iteration comparison, and oracle readability. The small search space is a feature, not a limitation, because it lets you see the mechanism before later reality bands complicate it.\n"
],
"id": "53811385"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #2563eb; background:#dbeafe; color:#1e3a8a; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>META READING</strong> · Difficulty 1/10 · Notebook-level rule, objective, or usage guidance.\n",
"</div>\n",
"\n",
"## Lab Protocol\n",
"\n",
"\n",
" When you edit the target, inspect the oracle wrappers. When you edit the iteration count, predict whether you are improving or overshooting the amplification. When you edit the helper shape, ask whether the semantic role of each block stayed visible.\n"
],
"id": "e283b5ca"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "setup"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #6b7280; background:#e5e7eb; color:#111827; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY SETUP</strong> · Difficulty 1/10 · Environment, import, or helper cell required by the notebook.\n",
"</div>\n"
],
"id": "d3172a31"
},
{
"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": "8ad03118"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "26b3f76d"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from math import pi\n",
"\n",
"from quantum_learning import (\n",
" counts_to_probabilities,\n",
" draw_circuit,\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": "3cc4775a"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #2563eb; background:#dbeafe; color:#1e3a8a; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>META READING</strong> · Difficulty 1/10 · Notebook-level rule, objective, or usage guidance.\n",
"</div>\n",
"\n",
"## Lab 1: Target Changes\n",
"\n",
"\n",
" Start by moving the marked state around the two-qubit search space. The question is not only whether the peak moves. The question is whether the target-marking logic remains readable enough that you can audit it.\n"
],
"id": "6127b66f"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "85f3642b"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"step_reference_table([{'marker': '[1]', 'code_focus': 'Prepare the search register in a uniform superposition.', 'diagram_effect': 'The circuit opens with a clean equal-weight state over all candidates.', 'why_it_matters': 'Amplitude amplification starts from a fair baseline, not from a pre-biased guess.'}, {'marker': '[2]', 'code_focus': 'Implement the oracle as a phase-marking operation on the chosen target.', 'diagram_effect': 'The middle block identifies the marked state without directly measuring it.', 'why_it_matters': 'Grover oracles mark by phase, not by classical tagging.'}, {'marker': '[3]', 'code_focus': 'Apply the diffuser as a reflection about the mean amplitude.', 'diagram_effect': 'The circuit mirrors the oracle block with a deliberate inversion pattern.', 'why_it_matters': 'The diffuser is the engineering heart of amplitude amplification.'}, {'marker': '[4]', 'code_focus': 'Choose the iteration count as a design decision, then measure.', 'diagram_effect': 'The right edge of the circuit closes the amplification loop with a concrete reporting contract.', 'why_it_matters': 'Over-iteration is a real design failure, not a harmless extra pass.'}])\n"
],
"id": "af162c91"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "12a4181c"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"editable_code = '\\nfrom qiskit import QuantumCircuit\\n\\ndef grover_oracle(target: str = \"11\") -> QuantumCircuit:\\n oracle = QuantumCircuit(2, name=f\"oracle_{target}\")\\n if target[0] == \"0\":\\n oracle.x(1)\\n if target[1] == \"0\":\\n oracle.x(0)\\n oracle.cz(0, 1)\\n if target[1] == \"0\":\\n oracle.x(0)\\n if target[0] == \"0\":\\n oracle.x(1)\\n return oracle\\n\\ndef diffuser() -> QuantumCircuit:\\n circuit = QuantumCircuit(2, name=\"diffuser\")\\n circuit.h([0, 1])\\n circuit.x([0, 1])\\n circuit.cz(0, 1)\\n circuit.x([0, 1])\\n circuit.h([0, 1])\\n return circuit\\n\\ncircuit = QuantumCircuit(2, 2)\\n# [1] Uniform search state\\ncircuit.h([0, 1])\\n# [2] Mark the target by phase\\ncircuit.compose(grover_oracle(\"11\"), inplace=True)\\n# [3] Reflect about the mean\\ncircuit.compose(diffuser(), inplace=True)\\n# [4] Report the amplified candidate\\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 1: Target Changes',\n",
" instructions='Change the target string and verify that the X-wrapper logic marks the state you intended before you trust the counts.',\n",
" shots=256,\n",
")\n"
],
"id": "06bd385a"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "d9ccd8f7"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def run(target: str) -> dict[str, int]:\n",
" circuit = QuantumCircuit(2, 2)\n",
" circuit.h([0, 1])\n",
" if target[0] == \"0\":\n",
" circuit.x(1)\n",
" if target[1] == \"0\":\n",
" circuit.x(0)\n",
" circuit.cz(0, 1)\n",
" if target[1] == \"0\":\n",
" circuit.x(0)\n",
" if target[0] == \"0\":\n",
" circuit.x(1)\n",
" circuit.h([0, 1])\n",
" circuit.x([0, 1])\n",
" circuit.cz(0, 1)\n",
" circuit.x([0, 1])\n",
" circuit.h([0, 1])\n",
" circuit.measure([0, 1], [0, 1])\n",
" return simulate_counts(circuit, shots=256)\n",
"\n",
"{target: run(target) for target in [\"00\", \"01\", \"10\", \"11\"]}\n"
],
"id": "fbe4851b"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "test"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY TEST</strong> · Difficulty 2/10 · Official walkthrough multiple-choice test.\n",
"</div>\n"
],
"id": "63b41ca3"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"quiz_block([{'prompt': 'If you change the Grover target from 11 to 01, what should stay invariant?', 'options': ['The overall oracle-plus-diffuser pattern', 'The exact same X wrappers around the oracle', 'The measured winning bitstring'], 'correct_index': 0, 'explanation': 'The motif is stable even though the marking details change.'}, {'prompt': 'What is the right way to inspect a target-change edit?', 'options': ['Check whether the oracle wrappers match the new target and whether the counts peak moved accordingly', 'Only inspect circuit depth', 'Only inspect the diffuser block'], 'correct_index': 0, 'explanation': 'The target lives in the oracle mapping and the resulting readout distribution.'}], heading='Lab Checkpoint A')\n"
],
"id": "267adcfc"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "cb0164f8"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"reflection_box('What did the one-versus-two iteration comparison teach you about the geometric story of Grover?')\n"
],
"id": "ef7d9ebc"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY READING</strong> · Difficulty 2/10 · Official walkthrough reading cell.\n",
"</div>\n",
"\n",
"## Lab 2: Iteration Comparison\n",
"\n",
"\n",
" Next compare one and two iterations explicitly. This is where the rotation language should stop feeling decorative and start feeling predictive.\n"
],
"id": "b0d3c697"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "b8c10e42"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"editable_code = '\\nfrom qiskit import QuantumCircuit\\n\\ndef grover_oracle(target: str = \"10\") -> QuantumCircuit:\\n oracle = QuantumCircuit(2, name=f\"oracle_{target}\")\\n if target[0] == \"0\":\\n oracle.x(1)\\n if target[1] == \"0\":\\n oracle.x(0)\\n oracle.cz(0, 1)\\n if target[1] == \"0\":\\n oracle.x(0)\\n if target[0] == \"0\":\\n oracle.x(1)\\n return oracle\\n\\ndef diffuser() -> QuantumCircuit:\\n circuit = QuantumCircuit(2, name=\"diffuser\")\\n circuit.h([0, 1])\\n circuit.x([0, 1])\\n circuit.cz(0, 1)\\n circuit.x([0, 1])\\n circuit.h([0, 1])\\n return circuit\\n\\ndef grover_circuit(target: str = \"10\", iterations: int = 2) -> QuantumCircuit:\\n circuit = QuantumCircuit(2, 2)\\n circuit.h([0, 1])\\n for _ in range(iterations):\\n circuit.compose(grover_oracle(target), inplace=True)\\n circuit.compose(diffuser(), inplace=True)\\n circuit.measure([0, 1], [0, 1])\\n return circuit\\n\\ncircuit = grover_circuit(target=\"10\", iterations=2)\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Lab 2: Iteration Comparison',\n",
" instructions='Vary the iteration count and explain whether the target amplitude should still be moving toward or past the intended peak.',\n",
" shots=256,\n",
")\n"
],
"id": "6e0b6287"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "2814ef64"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def grover_counts(iterations: int) -> dict[str, int]:\n",
" circuit = QuantumCircuit(2, 2)\n",
" circuit.h([0, 1])\n",
" for _ in range(iterations):\n",
" circuit.cz(0, 1)\n",
" circuit.h([0, 1])\n",
" circuit.x([0, 1])\n",
" circuit.cz(0, 1)\n",
" circuit.x([0, 1])\n",
" circuit.h([0, 1])\n",
" circuit.measure([0, 1], [0, 1])\n",
" return simulate_counts(circuit, shots=256)\n",
"\n",
"{iterations: grover_counts(iterations) for iterations in [0, 1, 2]}\n"
],
"id": "fdcedb9e"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY READING</strong> · Difficulty 2/10 · Official walkthrough reading cell.\n",
"</div>\n",
"\n",
"## Lab 3: Oracle Readability\n",
"\n",
"\n",
" Finally, refactor the oracle helper itself. Keep the behavior fixed while changing how obvious the target-marking logic is. This is where the module becomes explicitly about maintainable design.\n"
],
"id": "51dca227"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "0293d25f"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"editable_code = '\\nfrom qiskit import QuantumCircuit\\n\\ndef grover_oracle(target: str = \"10\") -> QuantumCircuit:\\n oracle = QuantumCircuit(2, name=f\"oracle_{target}\")\\n if target[0] == \"0\":\\n oracle.x(1)\\n if target[1] == \"0\":\\n oracle.x(0)\\n oracle.cz(0, 1)\\n if target[1] == \"0\":\\n oracle.x(0)\\n if target[0] == \"0\":\\n oracle.x(1)\\n return oracle\\n\\ndef diffuser() -> QuantumCircuit:\\n circuit = QuantumCircuit(2, name=\"diffuser\")\\n circuit.h([0, 1])\\n circuit.x([0, 1])\\n circuit.cz(0, 1)\\n circuit.x([0, 1])\\n circuit.h([0, 1])\\n return circuit\\n\\ndef grover_circuit(target: str = \"10\", iterations: int = 2) -> QuantumCircuit:\\n circuit = QuantumCircuit(2, 2)\\n circuit.h([0, 1])\\n for _ in range(iterations):\\n circuit.compose(grover_oracle(target), inplace=True)\\n circuit.compose(diffuser(), inplace=True)\\n circuit.measure([0, 1], [0, 1])\\n return circuit\\n\\ncircuit = grover_circuit(target=\"10\", iterations=2)\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Lab 3: Oracle Readability',\n",
" instructions='Refactor the target-marking helper and decide whether the new version is easier or harder to review across target changes.',\n",
" shots=256,\n",
")\n"
],
"id": "dd340edc"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "b084f968"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"one_iteration = QuantumCircuit(2, 2)\n",
"one_iteration.h([0, 1])\n",
"one_iteration.cz(0, 1)\n",
"one_iteration.h([0, 1])\n",
"one_iteration.x([0, 1])\n",
"one_iteration.cz(0, 1)\n",
"one_iteration.x([0, 1])\n",
"one_iteration.h([0, 1])\n",
"one_iteration.measure([0, 1], [0, 1])\n",
"\n",
"two_iterations = QuantumCircuit(2, 2)\n",
"two_iterations.h([0, 1])\n",
"for _ in range(2):\n",
" two_iterations.cz(0, 1)\n",
" two_iterations.h([0, 1])\n",
" two_iterations.x([0, 1])\n",
" two_iterations.cz(0, 1)\n",
" two_iterations.x([0, 1])\n",
" two_iterations.h([0, 1])\n",
"two_iterations.measure([0, 1], [0, 1])\n",
"\n",
"{\n",
" \"one_iteration\": simulate_counts(one_iteration, shots=256),\n",
" \"two_iterations\": simulate_counts(two_iterations, shots=256),\n",
"}\n"
],
"id": "99d81c43"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "test"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY TEST</strong> · Difficulty 2/10 · Official walkthrough multiple-choice test.\n",
"</div>\n"
],
"id": "9b519db1"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"quiz_block([{'prompt': 'What does two iterations on a 2-qubit Grover problem often illustrate?', 'options': ['Over-rotation or unnecessary extra work relative to the one-iteration optimum', 'Guaranteed improvement over one iteration', 'Automatic error mitigation'], 'correct_index': 0, 'explanation': 'A small search space makes the iteration-choice tradeoff easy to see.'}, {'prompt': 'Why compare separate oracle implementations for different targets?', 'options': ['To see whether the target-selection code stays readable and reviewable as the marking logic changes', 'Because only one target is physically valid', 'Because the diffuser depends on the target string'], 'correct_index': 0, 'explanation': 'Readable target handling matters for maintainable search code.'}], heading='Lab Checkpoint B')\n"
],
"id": "277d1d75"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY READING</strong> · Difficulty 2/10 · Official walkthrough reading cell.\n",
"</div>\n",
"\n",
"## Lab Debrief\n",
"\n",
"\n",
" The key lab outcome is that Grover should no longer feel like a single memorized diagram. It should feel like a modular routine with independent moving parts: target selection, diffusion, and iteration choice. Once those parts become independently discussable, the routine becomes something you can engineer rather than merely admire.\n"
],
"id": "a746be21"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY READING</strong> · Difficulty 2/10 · Official walkthrough reading cell.\n",
"</div>\n",
"\n",
"## Why The Lab Is Slower Than A Tutorial\n",
"\n",
"These exercises are intentionally slower than ordinary click-through tutorials because the purpose is different. A tutorial can reward motion. A professional lab has to reward discrimination. You are being asked to notice which edit changed the semantic burden of the circuit, which edit only changed presentation, and which edit damaged the reporting contract even though the diagram still looked familiar. That is harder work, but it is the right work for someone trying to become a designer rather than a consumer of notebooks.\n"
],
"id": "39744ce8"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY READING</strong> · Difficulty 2/10 · Official walkthrough reading cell.\n",
"</div>\n",
"\n",
"## Prediction Ledger\n",
"\n",
"If the lab begins to feel messy, return to the prediction ledger idea. Before each edit, write down what should remain invariant, what should move, and which evidence will decide the question. That tiny discipline is what keeps experiments from collapsing into aimless button pushing. It also mirrors how real engineering work scales. Good engineers do not only make changes. They keep track of what they expected the change to prove.\n"
],
"id": "6f2bab6b"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "db56ed9f"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"reflection_box('Write a short review note about one oracle helper that would be too opaque for serious use.')\n"
],
"id": "d7c8836c"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "mandatory",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #15803d; background:#dcfce7; color:#14532d; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>MANDATORY EXERCISE</strong> · Difficulty 2/10 · Official walkthrough runnable or written exercise.\n",
"</div>\n"
],
"id": "1a46c83a"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"reflection_box('Write one additional prediction habit you want to carry into later modules.')\n"
],
"id": "f3b6ec95"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #2563eb; background:#dbeafe; color:#1e3a8a; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>META READING</strong> · Difficulty 1/10 · Official walkthrough guardrail.\n",
"</div>\n",
"\n",
"<!-- COURSE_NAV_BOTTOM -->\n",
"## What To Open Next\n",
"\n",
"Next notebook: [Grover and Amplitude Amplification Problems](problems.ipynb)\n",
"\n",
"Official walkthrough rule: once every mandatory cell above is complete, open the next notebook. Anything below this cell is facultative.\n"
],
"id": "f039ba86"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "facultative_zone",
"ql_track": "meta",
"ql_role": "reading",
"ql_difficulty": 1,
"ql_note": "Optional-zone boundary. The official walkthrough is already complete above."
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #2563eb; background:#dbeafe; color:#1e3a8a; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>META READING</strong> · Difficulty 1/10 · Optional-zone boundary. The official walkthrough is already complete above.\n",
"</div>\n",
"\n",
"<!-- QL_OPTIONAL_ZONE -->\n",
"## Facultative Extension Zone\n",
"\n",
"You have already completed the mandatory walkthrough for **Grover and Amplitude Amplification Lab**. Everything below is optional. Use it only if you want deeper consolidation or extra transfer work.\n"
],
"id": "61f51636"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "facultative",
"ql_track": "facultative",
"ql_role": "reading",
"ql_difficulty": 4,
"ql_note": "Optional extension reading."
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #ea580c; background:#ffedd5; color:#9a3412; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>FACULTATIVE READING</strong> · Difficulty 4/10 · Optional extension reading.\n",
"</div>\n",
"\n",
"## Facultative Extension Reading\n",
"\n",
"In **Grover and Amplitude Amplification Lab**, the mandatory labs already gave you the official practice loop. This optional cell is for deeper experimentation discipline: decide one variable you would perturb next, one quantity you would track, and one false conclusion you want to avoid.\n"
],
"id": "186a4978"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "facultative",
"ql_role": "test"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #ea580c; background:#ffedd5; color:#9a3412; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>FACULTATIVE TEST</strong> · Difficulty 5/10 · Optional multiple-choice extension.\n",
"</div>\n"
],
"id": "83c53a07"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"ql_injected": "facultative",
"ql_track": "facultative",
"ql_role": "test",
"ql_difficulty": 5,
"ql_note": "Optional multiple-choice extension.",
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"quiz_block([{'prompt': 'In an optional lab variant, what should you change first?', 'options': ['One design variable you can explain', 'As many gates as possible to make the result surprising', 'The notebook order itself'], 'correct_index': 0, 'explanation': 'Optional exploration is still strongest when the perturbation is controlled.'}, {'prompt': 'What makes an optional lab note useful?', 'options': ['It records what changed, what stayed fixed, and what evidence moved', 'It only reports that the circuit still ran', 'It avoids writing predictions to save time'], 'correct_index': 0, 'explanation': 'The extension is about deeper evidence discipline.'}], heading='Facultative Extension Test')\n"
],
"id": "9a166d01"
},
{
"cell_type": "markdown",
"metadata": {
"ql_injected": "badge",
"ql_track": "facultative",
"ql_role": "exercise"
},
"source": [
"<!-- QL_BADGE -->\n",
"<div style=\"padding:0.55rem 0.8rem; border-left:6px solid #ea580c; background:#ffedd5; color:#9a3412; border-radius:0.35rem; font-family:Helvetica, Arial, sans-serif; margin:0.15rem 0 0.85rem 0;\">\n",
"<strong>FACULTATIVE EXERCISE</strong> · Difficulty 6/10 · Optional written exercise.\n",
"</div>\n"
],
"id": "34c04780"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"ql_injected": "facultative",
"ql_track": "facultative",
"ql_role": "exercise",
"ql_difficulty": 6,
"ql_note": "Optional written exercise.",
"jupyter": {
"source_hidden": true
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"reflection_box('Describe one optional circuit variation you would run after Grover and Amplitude Amplification Lab, what you would predict before running it, and what evidence would make you abandon the prediction.')\n"
],
"id": "3bad3619"
}
],
"metadata": {
"kernelspec": {
"display_name": "QuantumLearning (.venv)",
"language": "python",
"name": "quantum-learning"
},
"language_info": {
"name": "python",
"version": "3.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}