diff --git a/exercises/Exercise3.ipynb b/exercises/Exercise3.ipynb new file mode 100644 index 0000000..1d65454 --- /dev/null +++ b/exercises/Exercise3.ipynb @@ -0,0 +1,116 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Exercise Sheet 3 - Decoding the Repetition Code\n", + "\n", + "*These exercises require you to use a quantum SDK such as Qiskit. If you are having trouble setting up Qiskit or Python locally, you can use [this online service](https://lab.quantum-computing.ibm.com).*\n", + "\n", + "*For information about how many points each question is worth, contact the TA.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1 - Repetition code circuits\n", + "\n", + "*Note: You should not use Qiskit QEC for this exercise.*\n", + "\n", + "(a) Write a function to create Qisit circuits for linear repetition codes, for arbitrary code distance `d`, number of syndrome measurement rounds `T` and for both a stored logical `0` and logical `1`. Remember that, for the final set of syndrome measurememnts, there is no need for the `reset` gate after the final measurement. So leave this out in your circuits.\n", + "\n", + "(b) Transpile these to the backend `FakeSherbrooke` for distances from `d=3` to `d=55` and with `T=1`. This should be done such that the number of two-qubit gates prior to transpilation should be equal to the number of two-qubit gates after transpilation. Note that the native two-qubit gate for Sherbrooke is the `'ecr'` gate. The backend can be obtained with\n", + "\n", + " from qiskit.providers.fake_provider import FakeSherbrooke\n", + " backend = FakeSherbrooke()\n", + "\n", + "\n", + "### 2 - Decoding graphs\n", + "\n", + "*Note: You should not use Qiskit QEC for this exercise.*\n", + "\n", + "In the lecture [Decoding 2: Correcting Errors](https://github.com/quantumjim/qec_lectures/blob/main/lecture-2.ipynb) we saw Qiskit QEC create a decoding graph for a Qiskit QEC repetition code. In this exercise, you will create the same thing for your own repetition code.\n", + "\n", + "(a) Write a function that can process the output of your repetition code, to find syndrome changes and create nodes for your decoding graph. For this you can draw heavy inspiration from [Decoding 1: Running Circuits and Interpreting Outputs](https://github.com/quantumjim/qec_lectures/blob/main/lecture-1.ipynb). To demonstrate your function, apply it to a few example output strings that result in both normal nodes and boundary nodes, and explain why it does what it does.\n", + "\n", + "(b) Using this, insert all possible single Paulis into your circuit to see what nodes result. Using `rustworkx` or `networkx`, create a graph in which edges link nodes that were found to result from the same inserted Paulis. In the end you should create an image such as the following one in [Decoding 2: Correcting Errors](https://github.com/quantumjim/qec_lectures/blob/main/lecture-2.ipynb) (but the numbers don't need to be the same).\n", + "\n", + "![](graph.png)\n", + "\n", + "For an idea of how to insert Paulis into a circuit, see the following example.\n", + "\n", + " from qiskit import QuantumCircuit\n", + "\n", + " # here's a circuit, into which we'll insert a Pauli\n", + " qc = QuantumCircuit(2,2)\n", + " qc.h(0)\n", + " qc.cx(0,1)\n", + " qc.measure([0,1],[0,1])\n", + "\n", + " # first we make a blank circuit\n", + " error_qc = QuantumCircuit()\n", + " for reg in qc.qregs + qc.cregs:\n", + " error_qc.add_register(reg)\n", + "\n", + " # go through all the gates in the circuit\n", + " for gate in qc.data:\n", + " # add them to the new circuit\n", + " error_qc.data.append(gate)\n", + " # if one of them is a cnot\n", + " if gate[0].name == 'cx':\n", + " # find out what the control qubit is\n", + " q = gate[1][0]\n", + " # add an x as an 'error'\n", + " error_qc.x(q)\n", + "\n", + " # the resulting circuit now has an x inserted on the control qubit\n", + " # after every cnot\n", + " error_qc.draw()\n", + "\n", + "\n", + "### 3 - A hexagonal code\n", + "\n", + "Consider a hexagonal lattice with periodic boundary conditions (wrapped around a torus), with a qubit at each vertex. A portion of this lattice is shown in Fig. (a) below, with the qubits in black.\n", + "\n", + "![](lattice.png)\n", + "\n", + "Consider a QEC code in which the stabilizer generators consist of:\n", + "* The $Z \\otimes Z$ operator on every vertical link, as seen in Fig. (b).\n", + "* A plaquette operator $W_p = X \\otimes Y \\otimes Z\\otimes X\\otimes Y \\otimes Z$ defined on the 6 qubits around each hexagon. The qubits from left to right in this tensor product are those numbered from 0 to 5 in Fig. (b).\n", + "\n", + "(a) Show that these stabilizer generators mutually commute.\n", + "\n", + "(b) Find logical $X$ and $Z$ operators for the two stored logical qubits. Show that they have the correct communtation relations.\n", + "\n", + "(c) Repeat (a) and (b), but with for the code in which the $Y \\otimes Y$ operators are the stabilizer generators instead of the $Z \\otimes Z$ operators.\n", + "\n", + "(d) Devise circuits for mmeasuring the $Z \\otimes Z$, $Y \\otimes Y$ and $X \\otimes X$ operators. For these, use the additional grey qubits located on the edges of the lattice, and assume that two-qubit gates exist between these and their neighbouring black qubits.\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "arc-decoder", + "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.6" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}