update for 2025

This commit is contained in:
quantumjim
2025-09-08 09:59:21 +02:00
parent 6a880e4360
commit 91e3f28eb0
7 changed files with 25 additions and 934 deletions

View File

@@ -1,6 +1,6 @@
# Quantum Computation and Error Correction
This is a [course at the University of Basel](https://vorlesungsverzeichnis.unibas.ch/de/semester-planung?id=286075), given by Dr James Wootton of Moth Quantum.
This is a [course at the University of Basel](https://vorlesungsverzeichnis.unibas.ch/de/semester-planung?id=286075), given by Dr James Wootton, Pierre Fromholz and Daniel Bultrini of Moth Quantum.
## Course Content
@@ -16,21 +16,21 @@ The course will be based on the [Qiskit textbook](https://github.com/NCCR-SPIN/q
The course consists of the following set of lectures. We will aim to do slightly more than one per week. All lectures will be given in person (14:15, [Seminarzimmer 4.1](https://vorlesungsverzeichnis.unibas.ch/ajax/room.cfm?id=8210)), but [video versions](https://www.youtube.com/playlist?list=PLaU1vYImkPDxyqJ6zHAs8W92fYKsfXsV-) of many lectures are available also. For those, links to the pertinent parts of the Qiskit textbook can be found in the video descriptions. **Let me know if any link doesn't work!**
* 10/09: [The Atoms of Computation and What is Quantum](https://youtu.be/myzcjukQUFc)
* 17/09: [Representing Single Qubit States and Gates](https://www.youtube.com/watch?v=GdRt8vO9xY8)
* 24/09: [Multi qubit States and Circuit Identities](https://www.youtube.com/watch?v=pzkeypXaQ-Q)
* 01/10: [Fun with matrices](https://www.youtube.com/watch?v=e7NTozZMRqk)
* 08/10: [Circuits and Universality](https://www.youtube.com/watch?v=E53mfGrV8ek)
* 15/10: [From the Fourier Transform to Shor's Algorithm](https://www.youtube.com/watch?v=WqgNu8ZziPQ)
* 22/10: [Basic Algorithms and Protocols](https://www.youtube.com/watch?v=fNOEVXQKv9M)
* 29/10: [Grover's Algorithm and why we can't yet run it](https://www.youtube.com/watch?v=YfFp3K4cAF4)
* 5/11: [Introduction to QEC 1: The repetition code](https://www.youtube.com/watch?v=AuDfq7j_W7E&list=PLaU1vYImkPDxyqJ6zHAs8W92fYKsfXsV-&index=10)
* 12/11: [Introduction to QEC 2: The surface code](https://www.youtube.com/watch?v=IdZkxX-Qank&list=PLaU1vYImkPDxyqJ6zHAs8W92fYKsfXsV-&index=11) and the [Stabilizer formalism](https://github.com/quantumjim/Quantum-Computation-course-Basel/blob/main/QI_course/9_Stabilizer_Formalism.pdf)
* 19/11: [Classical Coding](extra_resources/Classical%20Coding.pdf) and Decoded Quantum Interferometry (based on [this talk](https://www.youtube.com/watch?v=mA4kdOPOFLM&list=PLgKuh-lKre10gQ2WmHimdr4Bqa3uE8yhX&index=3) and [this blog post](https://dabacon.org/pontiff/2024/10/29/new-quantum-algorithm-dance-dqi-edition/))
* 26/11: Entanglement: [Part 1](QI_course/6_Quantum_Correlations_part_1.pdf) [Part 2](QI_course/7_Quantum_Correlations_part_2.pdf)
* 03/12: ZX Calculus: [Part 1](extra_resources/ZX.pdf) [Part 2](extra_resources/Wootton-QNLP2023.pdf)
* 10/12: Benchmarking: [Part 1](extra_resources/Benchmarking-with-QEC-1.pdf) [Part 2](extra_resources/Benchmarking-with-QEC-2a.pdf) [Part 3](extra_resources/Benchmarking-with-QA.pdf)
* 17/12: Final Project brainstorming (1 hour only)
* 16/09: [The Atoms of Computation and What is Quantum](https://youtu.be/myzcjukQUFc)
* 23/09: [Representing Single Qubit States and Gates](https://www.youtube.com/watch?v=GdRt8vO9xY8)
* 30/09: [Multi qubit States and Circuit Identities](https://www.youtube.com/watch?v=pzkeypXaQ-Q)
* 7/10: [Fun with matrices](https://www.youtube.com/watch?v=e7NTozZMRqk)
* 14/10: [Circuits and Universality](https://www.youtube.com/watch?v=E53mfGrV8ek)
* 21/10: [From the Fourier Transform to Shor's Algorithm](https://www.youtube.com/watch?v=WqgNu8ZziPQ)
* 28/10: [Basic Algorithms and Protocols](https://www.youtube.com/watch?v=fNOEVXQKv9M)
* 4/11: [Grover's Algorithm and why we can't yet run it](https://www.youtube.com/watch?v=YfFp3K4cAF4)
* 11/11: [Introduction to QEC 1: The repetition code](https://www.youtube.com/watch?v=AuDfq7j_W7E&list=PLaU1vYImkPDxyqJ6zHAs8W92fYKsfXsV-&index=10) and [Introduction to QEC 2: The surface code](https://www.youtube.com/watch?v=IdZkxX-Qank&list=PLaU1vYImkPDxyqJ6zHAs8W92fYKsfXsV-&index=11)
* 18/11: TBD
* 25/11: TBD
* 26/11: TBD
* 02/12: TBD
* 9/12: TBD
* 16/12: Final Project brainstorming (1 hour only)
## Extra Topics
@@ -52,26 +52,27 @@ For some lectures there is also some extra content. We'll cover it if there is t
Four sets of take-home exercises set throughout the course. There will be hints sessions at 16:15 on the dates that these are set. Solutions will be presented after the exercises have been graded.
* [Exercise 1](exercises/Exercise1.ipynb): Set 01/10/2024, due 15/10/2024, Anatolii as TA.
* [Exercise 2](exercises/Exercise2.ipynb): Set 15/10/2024, due 29/10/2024, Anatolii as TA.
* [Exercise 3](exercises/Exercise3.ipynb): Set 29/10/2024, due 12/11/2024, Kacper as TA.
* [Exercise 4](exercises/Exercise4.ipynb): Set 12/11/2024, due 26/11/2024, Kacper as TA.
* Exercise 1: Set 01/10/2024, due 15/10/2024, TBD as TA.
* Exercise 2: Set 15/10/2024, due 29/10/2024, TBD as TA.
* Exercise 3: Set 29/10/2024, due 12/11/2024, TBD as TA.
* Exercise 4: Set 12/11/2024, due 26/11/2024, TBD as TA.
**Note: These exercises form 50% of your final grade**
**Note: These exercises form the final grade for the [2 practical credit points](https://vorlesungsverzeichnis.unibas.ch/en/course-directory?id=297199)**
## Final Project
As in previous years, we'll have a final project instead of a standard exam. The main aim of this is for you to demonstrate understanding of the topics in the course. The format is fairly free to allow you to do this in a way that suits you best. Collaboration will be fine. But everyone needs something unique to submit.
**Note: This project forms 50% of your final grade**
**Note: These project forms the final grade for the [4 lecture credit points](https://vorlesungsverzeichnis.unibas.ch/en/course-directory?id=294582)**
### Important dates
You have until 13th January to hand-in your final projects (to me, by email). You are expected to put a similar amount of time and effort in to the final project as you would put into two sets of exercises.
You have until TDB January to hand-in your final projects (to me, by email). You are expected to put a similar amount of time and effort in to the final project as you would put into two sets of exercises.
You have until 20th December to email me and ask for feedback on project ideas, and to give guidelines for what would be expected for them. We will also use the lecture on 17th December as a brainstorming session.
You have until TBD December to email me and ask for feedback on project ideas, and to give guidelines for what would be expected for them. We will also use the lecture on 16th December as a brainstorming session.
### Project ideas

View File

@@ -1,605 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"tags": [
"remove_cell"
]
},
"source": [
"# Exercise Sheet 1: Quantum Logic Gates"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To run this notebook you'll need to [install `qiskit`](https://docs.quantum.ibm.com/guides/install-qiskit), `qiskit-aer` and `qiskit-ibm-runtime`."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from qiskit import QuantumCircuit, transpile\n",
"from qiskit_aer import AerSimulator\n",
"from qiskit.visualization import plot_histogram\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Exercise 1**\n",
"\n",
"See 'Part 1' below, and find the circuits required for the:\n",
"* (a) `XOR` gate;\n",
"* (b) `AND` gate;\n",
"* (c) `NAND` gate;\n",
"* (d) `OR` gate.\n",
"\n",
"## **Exercise 2**\n",
"\n",
"See 'Part 2' below, and find a `layout` for which the AND gate compiles to 6 non-local gates for `ibmqx2`. Note that there is some randomness in the compiling process. So you might need to try a few times."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 style=\"font-size:24px;\">Part 1: Classical logic gates with quantum circuits</h2>\n",
"\n",
"<br>\n",
"\n",
"<h3 style=\"font-size: 20px\">&#128211; NOT gate</h3>\n",
"\n",
"In the following function we use a quantum circuit to do the simplest job in all of computation: apply a NOT gate to a bit."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def NOT(inp):\n",
" \"\"\"An NOT gate.\n",
" \n",
" Parameters:\n",
" inp (str): Input, encoded in qubit 0.\n",
" \n",
" Returns:\n",
" QuantumCircuit: Output NOT circuit.\n",
" str: Output value measured from qubit 0.\n",
" \"\"\"\n",
"\n",
" qc = QuantumCircuit(1, 1) # A quantum circuit with a single qubit and a single classical bit\n",
" qc.reset(0)\n",
" \n",
" # We encode '0' as the qubit state |0⟩, and '1' as |1⟩\n",
" # Since the qubit is initially |0⟩, we don't need to do anything for an input of '0'\n",
" # For an input of '1', we do an x to rotate the |0⟩ to |1⟩\n",
" if inp=='1':\n",
" qc.x(0)\n",
" \n",
" # barrier between input state and gate operation \n",
" qc.barrier()\n",
" \n",
" # Now we've encoded the input, we can do a NOT on it using x\n",
" qc.x(0)\n",
" \n",
" #barrier between gate operation and measurement\n",
" qc.barrier()\n",
" \n",
" # Finally, we extract the |0⟩/|1⟩ output of the qubit and encode it in the bit c[0]\n",
" qc.measure(0,0)\n",
" \n",
" # We'll run the program on a simulator\n",
" backend = AerSimulator()\n",
" # Since the output will be deterministic, we can use just a single shot to get it\n",
" job = backend.run(qc, shots=1, memory=True)\n",
" output = job.result().get_memory()[0]\n",
" \n",
" return qc, output"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's see it in action."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for inp in ['0', '1']:\n",
" qc, out = NOT(inp)\n",
" print('NOT with input',inp,'gives output',out)\n",
" display(qc.draw())\n",
" print('\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This implementation of NOT gate was an example of what you will need to do for a range of other gates below."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3 style=\"font-size: 20px\">&#128211; XOR gate</h3>\n",
"\n",
"Takes two binary strings as input and gives one as output.\n",
"\n",
"The output is '0' when the inputs are equal and '1' otherwise."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def XOR(inp1,inp2):\n",
" \"\"\"An XOR gate.\n",
" \n",
" Parameters:\n",
" inpt1 (str): Input 1, encoded in qubit 0.\n",
" inpt2 (str): Input 2, encoded in qubit 1.\n",
" \n",
" Returns:\n",
" QuantumCircuit: Output XOR circuit.\n",
" str: Output value measured from qubit 1.\n",
" \"\"\"\n",
" \n",
" qc = QuantumCircuit(2, 1) \n",
" qc.reset(range(2))\n",
" \n",
" if inp1=='1':\n",
" qc.x(0)\n",
" if inp2=='1':\n",
" qc.x(1)\n",
" \n",
" # barrier between input state and gate operation \n",
" qc.barrier()\n",
" \n",
" # this is where your program for quantum XOR gate goes\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" # barrier between input state and gate operation \n",
" qc.barrier()\n",
" \n",
" qc.measure(1,0) # output from qubit 1 is measured\n",
" \n",
" #We'll run the program on a simulator\n",
" backend = AerSimulator()\n",
" #Since the output will be deterministic, we can use just a single shot to get it\n",
" job = backend.run(qc, shots=1, memory=True)\n",
" output = job.result().get_memory()[0]\n",
" \n",
" return qc, output"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## Test the function\n",
"for inp1 in ['0', '1']:\n",
" for inp2 in ['0', '1']:\n",
" qc, output = XOR(inp1, inp2)\n",
" print('XOR with inputs',inp1,inp2,'gives output',output)\n",
" display(qc.draw())\n",
" print('\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3 style=\"font-size: 20px\">&#128211; AND gate</h3>\n",
"\n",
"Takes two binary strings as input and gives one as output.\n",
"\n",
"The output is `'1'` only when both the inputs are `'1'`."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def AND(inp1,inp2):\n",
" \"\"\"An AND gate.\n",
" \n",
" Parameters:\n",
" inpt1 (str): Input 1, encoded in qubit 0.\n",
" inpt2 (str): Input 2, encoded in qubit 1.\n",
" \n",
" Returns:\n",
" QuantumCircuit: Output XOR circuit.\n",
" str: Output value measured from qubit 2.\n",
" \"\"\"\n",
" qc = QuantumCircuit(3, 1) \n",
" qc.reset(range(2))\n",
" \n",
" if inp1=='1':\n",
" qc.x(0)\n",
" if inp2=='1':\n",
" qc.x(1)\n",
" \n",
" qc.barrier()\n",
"\n",
" # this is where your program for quantum AND gate goes\n",
"\n",
" \n",
" \n",
" \n",
" \n",
" \n",
"\n",
" qc.barrier()\n",
" qc.measure(2, 0) # output from qubit 2 is measured\n",
" \n",
" # We'll run the program on a simulator\n",
" backend = AerSimulator()\n",
" #Since the output will be deterministic, we can use just a single shot to get it\n",
" job = backend.run(qc, shots=1, memory=True)\n",
" output = job.result().get_memory()[0]\n",
" \n",
" return qc, output"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## Test the function\n",
"for inp1 in ['0', '1']:\n",
" for inp2 in ['0', '1']:\n",
" qc, output = AND(inp1, inp2)\n",
" print('AND with inputs',inp1,inp2,'gives output',output)\n",
" display(qc.draw())\n",
" print('\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3 style=\"font-size: 20px\">&#128211; NAND gate</h3>\n",
"\n",
"Takes two binary strings as input and gives one as output.\n",
"\n",
"The output is `'0'` only when both the inputs are `'1'`."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def NAND(inp1,inp2):\n",
" \"\"\"An NAND gate.\n",
" \n",
" Parameters:\n",
" inpt1 (str): Input 1, encoded in qubit 0.\n",
" inpt2 (str): Input 2, encoded in qubit 1.\n",
" \n",
" Returns:\n",
" QuantumCircuit: Output NAND circuit.\n",
" str: Output value measured from qubit 2.\n",
" \"\"\"\n",
" qc = QuantumCircuit(3, 1) \n",
" qc.reset(range(3))\n",
" \n",
" if inp1=='1':\n",
" qc.x(0)\n",
" if inp2=='1':\n",
" qc.x(1)\n",
" \n",
" qc.barrier()\n",
" \n",
" # this is where your program for quantum NAND gate goes\n",
"\n",
"\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" qc.barrier()\n",
" qc.measure(2, 0) # output from qubit 2 is measured\n",
" \n",
" # We'll run the program on a simulator\n",
" backend = AerSimulator()\n",
" #Since the output will be deterministic, we can use just a single shot to get it\n",
" job = backend.run(qc, shots=1, memory=True)\n",
" output = job.result().get_memory()[0]\n",
" \n",
" return qc, output"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## Test the function\n",
"for inp1 in ['0', '1']:\n",
" for inp2 in ['0', '1']:\n",
" qc, output = NAND(inp1, inp2)\n",
" print('NAND with inputs',inp1,inp2,'gives output',output)\n",
" display(qc.draw())\n",
" print('\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3 style=\"font-size: 20px\">&#128211; OR gate</h3>\n",
"\n",
"Takes two binary strings as input and gives one as output.\n",
"\n",
"The output is '1' if either input is '1'."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"def OR(inp1,inp2):\n",
" \"\"\"An OR gate.\n",
" \n",
" Parameters:\n",
" inpt1 (str): Input 1, encoded in qubit 0.\n",
" inpt2 (str): Input 2, encoded in qubit 1.\n",
" \n",
" Returns:\n",
" QuantumCircuit: Output XOR circuit.\n",
" str: Output value measured from qubit 2.\n",
" \"\"\"\n",
"\n",
" qc = QuantumCircuit(3, 1) \n",
" qc.reset(range(3))\n",
" \n",
" if inp1=='1':\n",
" qc.x(0)\n",
" if inp2=='1':\n",
" qc.x(1)\n",
" \n",
" qc.barrier()\n",
" \n",
" # this is where your program for quantum OR gate goes\n",
"\n",
"\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" qc.barrier()\n",
" qc.measure(2, 0) # output from qubit 2 is measured\n",
" \n",
" # We'll run the program on a simulator\n",
" backend = AerSimulator()\n",
" #Since the output will be deterministic, we can use just a single shot to get it\n",
" job = backend.run(qc, shots=1, memory=True)\n",
" output = job.result().get_memory()[0]\n",
" \n",
" return qc, output"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## Test the function\n",
"for inp1 in ['0', '1']:\n",
" for inp2 in ['0', '1']:\n",
" qc, output = OR(inp1, inp2)\n",
" print('OR with inputs',inp1,inp2,'gives output',output)\n",
" display(qc.draw())\n",
" print('\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 style=\"font-size:24px;\">Part 2: AND gate on Quantum Computer</h2>\n",
"<br>\n",
"\n",
"Real quantum computers are not able to implement arbitary gates directly. Instead, everything needs to be compiled (or 'transpiled') to the set of basic gates that the device can use. This usually consists of a set of single qubit rotations, as well as two qubit gates like `cx`.\n",
"\n",
"There are also limits on which `cx` gates can be used directly: only some pairs of control and target qubits are possible. To implement other `cx` gates, tricks such as using `swap` gates to effectively move information around must be used. The possible pairs of qubits on which `cx` gates can be applied is known as the 'connectivity' of the device.\n",
"\n",
"We'll now look at some examples. To make sure you don't end up in a queue for a busy device, we'll be using mock backends. These are designed to act exactly like real backends."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from qiskit_ibm_runtime.fake_provider import FakeYorktown\n",
"backend = FakeYorktown()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The two system we are using (or at least pretending to) is `ibmqx2` (also known as `ibmq_yorktown`). With this system, it is not possible to peform a `cx` gate between any arbitrary pair of qubits. Instead only the following pairings are allowed (where the qubits are labelled from 0 to 4)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"backend.configuration().coupling_map"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"The following cell has a circuit that applies an `AND` gate that is constructed from single and two qubit gates. However, this circuit assumes full connectivity: that `cx` gates can be applied between any pair of qubits."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"qc_and = QuantumCircuit(3)\n",
"qc_and.ccx(0,1,2)\n",
"print('AND gate')\n",
"display(qc_and.draw())\n",
"print('\\n\\nTranspiled AND gate for hardware with the required connectiviy')\n",
"qc_and.decompose().draw()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This ideal transpilation requires 6 `cx` gates.\n",
"\n",
"There are often optimizations that the transpiler can perform that reduce the overall gate count, and thus total length of the input circuits. Note that the addition of swaps to match the device topology, and optimizations for reducing the length of a circuit are at odds with each other. In what follows we will make use of `initial_layout` that allows us to pick the qubits on a device used for the computation and `optimization_level`, an argument that allows selecting from internal defaults for circuit swap mapping and optimization methods to perform."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Rather than actually running the AND function, let's just look at the transpiled circuits. The following function does this for a given set of inputs."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"# run the cell to define AND gate for real quantum system\n",
"\n",
"def AND(inp1, inp2, backend, layout):\n",
" \n",
" qc = QuantumCircuit(3, 1) \n",
" qc.reset(range(3))\n",
" \n",
" if inp1=='1':\n",
" qc.x(0)\n",
" if inp2=='1':\n",
" qc.x(1)\n",
" \n",
" qc.barrier()\n",
" qc.ccx(0, 1, 2) \n",
" qc.barrier()\n",
" qc.measure(2, 0) \n",
" \n",
" qc_trans = transpile(qc, backend, initial_layout=layout, optimization_level=3)\n",
" \n",
" return qc_trans"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p>&#128211; Assign your choice of layout to the list variable <code>layout</code> in the cell below</p>"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"# Assign your choice of the initial_layout to the variable layout1 as a list \n",
"# For example\n",
"# layout = [0,2,4]\n",
"layout = "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Compile the `AND` gate on `ibmqx2` by running the cell below."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"for input1 in ['0','1']:\n",
" for input2 in ['0','1']:\n",
" qc_trans1 = AND(input1, input2, backend, layout)\n",
" \n",
" print('For input '+input1+input2)\n",
" print('# of nonlocal gates =',qc_trans1.num_nonlocal_gates())"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -1,95 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exercise 2\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Delayed measurement with Clifford only circuits\n",
"\n",
"In general, we can consider quantum circuits with classically-controlled operations: this is when measurements are made throught the circuit, with the outcomes being used to determine what gates are subsequently applied.\n",
"\n",
"Nevertheless, when reasoning about what kind of computations we can do with quantum circuits, it is simplest to consider only circuits of the form represented below.\n",
"\n",
"![](circuit_model.png)\n",
"\n",
"Here all measurements are deferred to the end, and so there are no classically-controlled operations.\n",
"\n",
"Remarkably, this comes with no loss of generality. This is because all classically-controlled operations (with measurement) can be replaced by fully quantum controlled gates (unitary and without measurement). For example\n",
"\n",
"<div>\n",
"<img src=\"delayed.png\" width=\"500\"/>\n",
"</div>\n",
"\n",
"Any circuit with classically-controlled gates can therefore be replaced by an equivalent one with only fully quantum gates and with all measurements deferred to the end. However, the gate set required for the latter will typically need to be more powerful that the set of unitary gates used in the former."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To show this, consider circuits for which classical-control is allowed, but for which the unitary part of all gates must be Clifford. Show that, in general, the equivalent circuit without classically-controlled gates requires non-Clifford gates."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Unitarity of the order-finding operator\n",
"\n",
"For integers $x$, $N$ and $L$ with $x < N \\leq 2^L-1$ and $\\rm { gcd} (x,N) = 1$, consider the following operation,\n",
"\n",
"$$\n",
"U = \\sum_{y=0}^{2^L-1} \\left| \\, f(y) \\, \\right\\rangle \\left\\langle \\,y \\, \\right|,\n",
"$$\n",
"\n",
"Where $f(y) = x \\times y \\,\\,\\, {\\rm mod}\\, N$ for $0 \\leq y <N$ and $f(y)=y$ otherwise. Show that $U$ is unitary."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Eigenstates of the order-finding operator\n",
"\n",
"* (a) Show that the following states are eigenstates of $U$,\n",
"\n",
"$$\n",
"\\left| u_s \\right\\rangle = \\frac{1}{\\sqrt{r}} \\sum_{k=0}^{r-1} \\exp \\left[ \\frac{-2 \\pi i s k}{r} \\right] \\left| x^k \\,\\,\\, {\\rm mod}\\, N \\right\\rangle.\n",
"$$\n",
"\n",
"Here $0 \\leq s \\leq r-1$, where $r$ is the smallest integer such that $x^r = 1 \\,\\,\\, {\\rm mod}\\, N$. Show also that the corresponding eigenvalues are $u_s = \\exp ( {2 \\pi i s}/{r} )$.\n",
"\n",
"* (b) There are also many states with eigenvalue $1$. What are these?\n",
"\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -1,74 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exercise 3\n",
"\n",
"This sheet is about [density matrices](../QI_course/2_The_Qubit.pdf), [the partial trace](../QI_course/3_Quantum_Information.pdf) and [the Schmidt decomposition](../QI_course/6_Quantum_Correlations_part_1.pdf). Take a look at the linked materials to find out more."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1\n",
"\n",
"Given an arbitrary single qubit state $a|0\\rangle +b|1\\rangle$:\n",
"\n",
"(a) Write down the corresponding density matrix.\n",
"\n",
"(b) Write down the density matrix representing the effect of applying an $X$ with probability $q_x$, $Y$ with probability $q_y$, $Z$ with probability $q_z$ (and doing nothing with probability $1-q_x-q_y-q_z$).\n",
"\n",
"(c) Write down the density matrix for representing the effect of replacing the state with $I/2$ with probability $p$.\n",
"\n",
"(d) For what values of $q_x$, $q_y$ and $q_z$ is the effect of (b) equivalent to that of (c)?\n",
"\n",
"## 2\n",
"\n",
"(a) Write down the density matrix of a single qubit which is in state $|0\\rangle$ with probability $2/3$ and $|+\\rangle$ with probability $1/3$.\n",
"\n",
"(b) Find a two qubit state such that one of the reduced density matrices is equal to the density matrix in (a).\n",
"\n",
"(c) Write down a density matrix for a state that is not entangled, but which has the same reduced density matrices as your answer for (b).\n",
"\n",
"## 3\n",
"\n",
"Consider the three qubit state $(|001\\rangle + |010\\rangle)+ |100\\rangle/\\sqrt{3}$.\n",
"\n",
"(a) What is the reduced density matrix for a single qubit in this state?\n",
"\n",
"(b) What is the reduced density matrix for a pair of qubits in this state?\n",
"\n",
"(c) Use the Schmidt decomposition to rewrite the state, with one qubit on one side of the bipartition and two qubits on the other."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -1,136 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "pmm5uV8cQQN6"
},
"source": [
"# Exercise 4"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Shor Code\n",
"\n",
"The Shor (or 9 Qubit) code is a method for quantum error correction based on the classical repetition code. Here we will consider the version where a logical qubit is first stored in three physical qubits using the encoding\n",
"$$\n",
"|+\\rangle_3 = |+++\\rangle, \\,\\,\\, |-\\rangle_3 = |---\\rangle.\n",
"$$\n",
"This protects against errors that try to flip $|+\\rangle_3$ to $|-\\rangle_3$, and vice-versa. But the corresponding errors for the $Z$ basis states\n",
"\n",
"\n",
"$$\n",
"|0\\rangle_3 = \\frac{1}{\\sqrt{2}} (|+++\\rangle+|---\\rangle), \\,\\,\\, |1\\rangle_3 = \\frac{1}{\\sqrt{2}} (|+++\\rangle-|---\\rangle)\n",
"$$\n",
"\n",
"become more likely. To deal with this we take three of these logical qubits and use them (like the original physical qubits) to encode a single logical qubit. This uses the encoding:\n",
"\n",
"$$\n",
"|0\\rangle_9 = |0\\rangle_3 \\otimes |0\\rangle_3 \\otimes |0\\rangle_3, \\,\\,\\, |1\\rangle_9 = |1\\rangle_3 \\otimes |1\\rangle_3 \\otimes |1\\rangle_3.\n",
"$$\n",
"\n",
"The end result is then a code that stores one logical qubit in 9 physical qubits, with stabilizer states\n",
"\n",
"$$\n",
"|0\\rangle_9 = \\left\\lbrack \\frac{1}{\\sqrt{2}} \\left(|+++\\rangle +|---\\rangle \\right) \\right\\rbrack^{\\otimes 3}, \\,\\,\\, |1\\rangle_9 = \\left\\lbrack\\frac{1}{\\sqrt{2}}\\left(|+++\\rangle-|---\\rangle\\right) \\right\\rbrack^{\\otimes 3}\n",
"$$\n",
"\n",
"a) Find operators that act as $X$ and $Z$ on the logical qubit. What are the minimal number of qubits these act on?\n",
"\n",
"b) Suppose $\\sigma_x$ errors occur independently on each qubit with probability $p_x$. What is the probability $P_x$ that a logical $X$ occurs after syndrome measurement and error correction? For simplicity you can determine this only up to lowest order in $p_x$.\n",
"\n",
"c) Similarly, what is the probability $P_z$ of $Z$ errors, given that $\\sigma_z$ errors occur with probability $p_z$? For simplicity you can determine this only up to lowest order in $p_z$."
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "CJyxxSDUQQN9"
},
"source": [
"## 2. Concatenated Shor Code\n",
"\n",
"In order to increase the performance of a code we can use the concept of concatenation. We will now consider this process for the Shor code.\n",
"\n",
"Let us describe physical qubits as level-0 qubits, and suppose we have $n$ of them. We can use these to encode $n/9$ logical qubits, which we call level-1 qubits. These will have lower probabilities for noise than the level-0 qubits, but maybe not as low as we require. We can then use the level-1 qubits as if they were physical qubits, using them to encode $n/9^2$ level-2 qubits. This procedure can then be continued as many times as required, with the level-$(l-1)$ qubits always used as the physical qubits of the Shor codes that encode the level-$l$ qubits.\n",
"\n",
"a) In order to encode a single level-$l$ qubit, for arbitrary $l$, what is the number $n(l)$ of level-0 qubits required?\n",
"\n",
"b) The standard Shor code has distance $d=3$. What is the distance of a level-$l$ concatenated Shor code?\n",
"\n",
"c) We will use $p_x^{(l)}$ to denote the bit flip error probility at level-$l$. The level-0 error rate is that of the phyical qubit errors: $p_x^{(0)}=p_x$. The level-1 error rate is that of the logical qubits of the 9 qubit code: $p_x^{(1)}=P_x$. Use your result from question 1(b) to show that $p_x^{(l-1)}$ and $p_x^{(l)}$ are related by\n",
"$$\n",
"p_x^{(l)} < 27 \\left( p_x^{(l-1)} \\right)^2.\n",
"$$\n",
"\n",
"d) Show that $p_x^{(l)}$ decays exponentially with $n(l)^\\beta$ when $p_x < 1/27$, and find $\\beta$.\n",
"\n",
"This is a proof of the `threshold theorem' for this code and error model. As long as the physical noise rate $p_x$ is below the threshold value of $1/27$ ( and $p_z$ is below its threshold of $1/9$), concatenation of the Shor code can achieve arbitrarily low error rates.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. The Toric Code\n",
"\n",
"The surface code is defined on a plane with rough and smooth boundary conditions.\n",
"But we could instead wrap the $L \\times L$ square lattice around a torus and have periodic\n",
"boundary conditions. Then the code would be translationally invariant, and all $A_s$\n",
"and $B_p$ stabilizers would be four qubit operators.\n",
"\n",
"a) The parameter $L$ counts the number of plaquettes along each direction. Show that\n",
"$n = 2L^2$, where $n$ is the number of qubits.\n",
"\n",
"b) Show that the number of plaquette operators is $L^2$, but that the number of independent plaquette operators is $L^2-1$. Show the same thing for the vertex operators.\n",
"\n",
"c) How many logical qubits, $k$, can be stored in the stabilizer space?\n",
"\n",
"d) Define logical $X$ and $Z$ operators for these logical qubits. Note that these are not\n",
"uniquely defined. However, as with any stabilizer code, you will know that your logical\n",
"operators are a valid choice if they satisfy the following conditions.\n",
"\n",
"1. Logical Pauli operators must commute with all stabilizers.\n",
"2. Logical Pauli operators for the same logical qubit anticommute: $\\{ X_j, Z_j \\} = 0$.\n",
"3. Logical Pauli operators for different logical qubits commute: $\\left[ X_j, Z_j \\right] = 0$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "Exercise_4.ipynb",
"provenance": [],
"version": "0.3.2"
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.4"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB