QuantumLearning/notebooks/algorithms/module_01_deutsch_family/studio.ipynb

285 lines
12 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Deutsch Family and Oracle Thinking Studio\n"
],
"id": "bc4280d6"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- COURSE_NAV_TOP -->\n",
"## Mainline Navigation\n",
"\n",
"Step 30 of 59. Follow the mainline in order and do not skip ahead.\n",
"\n",
"Previous notebook: [Deutsch Family and Oracle Thinking Problems](problems.ipynb)\n",
"\n",
"Next notebook: [Bernstein-Vazirani and Structured Oracles Lecture](../module_02_bernstein_vazirani/lecture.ipynb)\n",
"\n",
"Rule: finish this notebook top-to-bottom before you open the next one.\n"
],
"id": "f02981e0"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The studio turns the family into a design object. You are no longer only reading the mechanism. You are curating variants, defending what changed, and writing the kind of notes another engineer could actually review.\n"
],
"id": "c7b1b4c2"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Design Brief\n",
"\n",
"\n",
" Produce a small oracle-design mini-portfolio. Include at least one minimal Deutsch case, one Deutsch-Jozsa case, and one deliberate ablation. For each, state the promise class, the reporting contract, and the causal reason the observed verdict should follow.\n"
],
"id": "2230ea42"
},
{
"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": "50c7b992"
},
{
"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": "6d5918b3"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Studio Prompt 1: Curate A Minimal Family\n",
"\n",
"\n",
" Build a tiny family of promise-case circuits and make the family resemblance explicit. The goal is not volume. The goal is a clean taxonomy.\n"
],
"id": "45971ba6"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"editable_code = '\\nfrom qiskit import QuantumCircuit\\n\\ndef deutsch_oracle(kind: str) -> QuantumCircuit:\\n oracle = QuantumCircuit(2, name=f\"oracle_{kind}\")\\n if kind == \"balanced\":\\n oracle.cx(0, 1)\\n elif kind == \"constant_one\":\\n oracle.x(1)\\n elif kind != \"constant_zero\":\\n raise ValueError(\"kind must be constant_zero, constant_one, or balanced\")\\n return oracle\\n\\ncircuit = QuantumCircuit(2, 1)\\n# [1] Query wire in superposition, ancilla in |->\\ncircuit.h(0)\\ncircuit.x(1)\\ncircuit.h(1)\\n# [2] Oracle encodes the promise class\\ncircuit.compose(deutsch_oracle(\"balanced\"), inplace=True)\\n# [3] Final Hadamard turns phase into a measurable distinction\\ncircuit.h(0)\\n# [4] Only the decision wire needs to be reported\\ncircuit.measure(0, 0)\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Studio 1: Minimal Deutsch Family',\n",
" instructions='Turn one balanced and two constant variants into a cleanly explained family. Keep the oracle contract explicit in code comments or naming.',\n",
" shots=256,\n",
")\n"
],
"id": "0638afc3"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Studio Prompt 2: Scale Without Losing The Story\n",
"\n",
"\n",
" Extend the same explanatory discipline to the Deutsch-Jozsa case. If the larger circuit makes your narrative weaker, simplify until the narrative becomes sharp again.\n"
],
"id": "ed679595"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"editable_code = '\\nfrom qiskit import QuantumCircuit\\n\\ndef deutsch_jozsa_oracle(kind: str = \"balanced\") -> QuantumCircuit:\\n oracle = QuantumCircuit(3, name=f\"dj_{kind}\")\\n if kind == \"balanced\":\\n oracle.cx(0, 2)\\n oracle.cx(1, 2)\\n elif kind == \"constant_one\":\\n oracle.x(2)\\n elif kind != \"constant_zero\":\\n raise ValueError(\"kind must be constant_zero, constant_one, or balanced\")\\n return oracle\\n\\ncircuit = QuantumCircuit(3, 2)\\n# Put both query wires into superposition.\\ncircuit.h([0, 1])\\n# Prepare the ancilla in |->\\ncircuit.x(2)\\ncircuit.h(2)\\n# Query the oracle contract.\\ncircuit.compose(deutsch_jozsa_oracle(\"balanced\"), inplace=True)\\n# Interference reveals whether the promise is constant or balanced.\\ncircuit.h([0, 1])\\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='Studio 2: Deutsch-Jozsa Family',\n",
" instructions='Create at least one balanced and one constant case and write down the invariant mechanism they share.',\n",
" shots=256,\n",
")\n"
],
"id": "02fb5bf6"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Studio Prompt 3: Ablation As Evidence\n",
"\n",
"\n",
" Include one broken variant on purpose. A good studio notebook does not only show what works. It shows what fails and why, because that is how your causal understanding becomes reviewable.\n"
],
"id": "32f47135"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"editable_code = '\\nfrom qiskit import QuantumCircuit\\n\\ndef balanced_oracle() -> QuantumCircuit:\\n oracle = QuantumCircuit(2, name=\"balanced\")\\n oracle.cx(0, 1)\\n return oracle\\n\\ncircuit = QuantumCircuit(2, 1)\\n# Toggle these preparation choices to see phase kickback disappear.\\ncircuit.h(0)\\ncircuit.x(1)\\ncircuit.h(1)\\ncircuit.compose(balanced_oracle(), inplace=True)\\ncircuit.h(0)\\ncircuit.measure(0, 0)\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Studio 3: Broken Variant And Diagnosis',\n",
" instructions='Break one preparation or interference step deliberately. Then write a diagnosis that names the missing mechanism.',\n",
" shots=256,\n",
")\n"
],
"id": "d2a36d84"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"quiz_block([{'prompt': 'What makes a good studio outcome in this module?', 'options': ['A small family of oracle-based circuits with a defensible explanation of what changed and what stayed invariant', 'A single copied textbook circuit with no notes', 'The most gates you can fit onto two qubits'], 'correct_index': 0, 'explanation': 'Studio work is about deliberate variation and justification.'}, {'prompt': 'Why is deliberate ablation useful in a design studio?', 'options': ['It identifies which circuit regions actually carry the mechanism and which are accidental', 'It makes the code shorter by default', 'It avoids the need for measurements'], 'correct_index': 0, 'explanation': 'Ablation is a disciplined way to test causal understanding.'}], heading='Studio Design Check')\n"
],
"id": "06d564e5"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Studio Debrief\n",
"\n",
"\n",
" A mature outcome in this studio is not a giant notebook. It is a compact family of circuits whose common logic is easy to explain and whose differences are intentional. If you can produce that here, the later algorithm modules have something disciplined to build on.\n"
],
"id": "43aebb8d"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Studio Standard\n",
"\n",
"A strong studio notebook is compact, explicit, and reviewable. It does not hide behind volume. It makes clear what family of circuits was explored, what invariant mechanism survived across the variants, what evidence justified the final recommendation, and what tradeoffs remained open. If your notebook cannot answer those questions yet, keep refining it. That refinement is the studio.\n"
],
"id": "9f714dc0"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What A Finished Studio Should Feel Like\n",
"\n",
"The finished notebook should feel like a small engineering artifact rather than a scrapbook. A reviewer should be able to open it, understand the task, inspect the candidate circuits, see the evidence, and understand why one recommendation won. If that standard is met on these small modules, later capstone work becomes much more realistic.\n"
],
"id": "8fb3c3ff"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('Which family resemblance between Deutsch and Deutsch-Jozsa feels strongest to you now, and why?')\n"
],
"id": "9473099b"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('What was the most useful deliberate failure you introduced in the studio, and what did it reveal?')\n"
],
"id": "ed88c351"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('Write one paragraph defending your preferred oracle helper style for this family.')\n"
],
"id": "140fffc1"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('State one review criterion you would carry from this module into later algorithm notebooks.')\n"
],
"id": "d74e2641"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- COURSE_NAV_BOTTOM -->\n",
"## What To Open Next\n",
"\n",
"Next notebook: [Bernstein-Vazirani and Structured Oracles Lecture](../module_02_bernstein_vazirani/lecture.ipynb)\n",
"\n",
"When you finish this notebook, open the next notebook shown above. Stay on the guarded mainline route.\n"
],
"id": "f87f3f82"
}
],
"metadata": {
"kernelspec": {
"display_name": "QuantumLearning (.venv)",
"language": "python",
"name": "quantum-learning"
},
"language_info": {
"name": "python",
"version": "3.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}