QuantumLearning/notebooks/algorithms/module_02_bernstein_vazirani/studio.ipynb

255 lines
11 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Bernstein-Vazirani and Structured Oracles Studio\n"
],
"id": "0a56bc97"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The studio asks you to produce a small but serious hidden-string toolkit. This is the point where the module should start resembling real design work rather than lecture replay.\n"
],
"id": "38d8fdb5"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Design Brief\n",
"\n",
"\n",
" Build a compact notebook that recovers several secrets, defends a stable reporting convention, and compares at least two builder styles for auditability. Your aim is not maximal code. Your aim is a reliable family artifact.\n"
],
"id": "b0693398"
},
{
"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": "3e7046de"
},
{
"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": "319d85e5"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Studio Prompt 1: Secret-Recovery Library\n",
"\n",
"\n",
" Build a secret-recovery helper that you would actually trust next week. The test is whether another reader can tell which secret bits induce which oracle interactions.\n"
],
"id": "073019dc"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"editable_code = '\\nfrom qiskit import QuantumCircuit\\n\\ndef bv_oracle(secret: str = \"101\") -> QuantumCircuit:\\n oracle = QuantumCircuit(4, name=f\"bv_{secret}\")\\n ancilla = 3\\n for index, bit in enumerate(reversed(secret)):\\n if bit == \"1\":\\n oracle.cx(index, ancilla)\\n return oracle\\n\\ncircuit = QuantumCircuit(4, 3)\\n# [1] Prepare the query register and phase-sensitive ancilla.\\ncircuit.h([0, 1, 2])\\ncircuit.x(3)\\ncircuit.h(3)\\n# [2] Query the structured oracle.\\ncircuit.compose(bv_oracle(\"101\"), inplace=True)\\n# [3] Decode the hidden pattern.\\ncircuit.h([0, 1, 2])\\n# [4] Measure only the recovered string.\\ncircuit.measure([0, 1, 2], [0, 1, 2])\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Studio 1: Secret-Recovery Library',\n",
" instructions='Generalize the builder across several secrets while keeping the oracle mapping readable.',\n",
" shots=256,\n",
")\n"
],
"id": "54b81862"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Studio Prompt 2: Reporting Convention Memo\n",
"\n",
"\n",
" Freeze one reporting convention and state it explicitly. Good notebooks do not hide bit order in implicit habits.\n"
],
"id": "1349e254"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"editable_code = '\\nfrom qiskit import QuantumCircuit\\n\\ndef bv_oracle(secret: str = \"110\") -> QuantumCircuit:\\n oracle = QuantumCircuit(4, name=f\"bv_{secret}\")\\n ancilla = 3\\n for index, bit in enumerate(reversed(secret)):\\n if bit == \"1\":\\n oracle.cx(index, ancilla)\\n return oracle\\n\\ncircuit = QuantumCircuit(4, 3)\\ncircuit.h([0, 1, 2])\\ncircuit.x(3)\\ncircuit.h(3)\\ncircuit.compose(bv_oracle(\"110\"), inplace=True)\\ncircuit.h([0, 1, 2])\\n# Change the measurement order only if you can explain the reporting contract.\\ncircuit.measure([0, 1, 2], [0, 1, 2])\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Studio 2: Reporting Convention',\n",
" instructions='Choose a measurement mapping and write the convention clearly enough that another engineer would not misread the output.',\n",
" shots=256,\n",
")\n"
],
"id": "2c4056d0"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Studio Prompt 3: Compare Two Builder Styles\n",
"\n",
"\n",
" Compare a lean and a more structured candidate. The point is not that one style is always correct. The point is to learn how to justify the tradeoff in review language.\n"
],
"id": "a8db9955"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"editable_code = '\\nfrom qiskit import QuantumCircuit\\n\\ndef bv_candidate(secret: str = \"011\", add_barriers: bool = False) -> QuantumCircuit:\\n circuit = QuantumCircuit(4, 3)\\n circuit.h([0, 1, 2])\\n circuit.x(3)\\n circuit.h(3)\\n if add_barriers:\\n circuit.barrier()\\n for index, bit in enumerate(reversed(secret)):\\n if bit == \"1\":\\n circuit.cx(index, 3)\\n if add_barriers:\\n circuit.barrier()\\n circuit.h([0, 1, 2])\\n circuit.measure([0, 1, 2], [0, 1, 2])\\n return circuit\\n\\ncircuit = bv_candidate(secret=\"011\", add_barriers=True)\\n'\n",
"editable_circuit_lab(\n",
" initial_code=editable_code,\n",
" context={\"QuantumCircuit\": QuantumCircuit, \"simulate_counts\": simulate_counts},\n",
" title='Studio 3: Builder Comparison',\n",
" instructions='Adjust helper structure, barriers, or naming, then defend which version is easier to audit and maintain.',\n",
" shots=256,\n",
")\n"
],
"id": "e6b6ad1e"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"quiz_block([{'prompt': 'What is the best studio target for this module?', 'options': ['A small secret-recovery library where the oracle contract and reporting order are both reviewable', 'The shortest possible BV code cell', 'A notebook that uses only barriers and screenshots'], 'correct_index': 0, 'explanation': 'Studio work should promote reusable, auditable design rather than compression alone.'}, {'prompt': 'Why is it useful to compare two secrets of different Hamming weights?', 'options': [\"It shows how the oracle body's density changes while the global motif stays stable\", 'It changes the number of required classical bits', 'It removes the need for a final Hadamard layer'], 'correct_index': 0, 'explanation': 'Different secret densities stress the same design pattern in different ways.'}], heading='Studio Design Check')\n"
],
"id": "9faa6c8e"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Studio Debrief\n",
"\n",
"\n",
" A good studio notebook in this module makes hidden structure feel ordinary and reviewable. If the secret still feels like a mysterious label rather than implemented structure, keep refining the builders and the prose until the structure is obvious.\n"
],
"id": "bc899047"
},
{
"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": "cb73a53e"
},
{
"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": "ae01c89c"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('What secret family did you use in the studio, and why was it a good stress test for your builder?')\n"
],
"id": "bcbce5c0"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('Which reporting convention did you choose, and how did you defend it?')\n"
],
"id": "14edf186"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('What is the strongest review sentence you wrote in this studio?')\n"
],
"id": "30f8dbb4"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"reflection_box('Name one habit from the Deutsch family that carried forward unchanged into BV.')\n"
],
"id": "500d46fa"
}
],
"metadata": {
"kernelspec": {
"display_name": "QuantumLearning (.venv)",
"language": "python",
"name": "quantum-learning"
},
"language_info": {
"name": "python",
"version": "3.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}