Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions examples/qec_repetition_code.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d35108d9",
"metadata": {},
"source": [
"# Quantum Error Correction with the 3-Qubit Repetition Code\n",
"\n",
"In this example we will use a 3 qubit repetition code to detect and correct single Pauli X bit flip errors using pairwise parity checks. See https://en.wikipedia.org/wiki/Repetition_code for more info."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a1194bb4",
"metadata": {},
"outputs": [],
"source": [
"from guppylang import guppy\n",
"from guppylang.std.array import array\n",
"from guppylang.std.qsystem.random import RNG\n",
"from guppylang.std.qsystem.utils import get_current_shot\n",
"from guppylang.std.quantum import cx, discard_array, h, measure_array, qubit, x"
]
},
{
"cell_type": "markdown",
"id": "5eaccf74",
"metadata": {},
"source": [
"We will first create our data and ancilla qubits and then create some quantum information to be protected and encode information from q[0] by repetition, i.e. |0> -> |000>, |1> -> |111>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a73ca726",
"metadata": {},
"outputs": [],
"source": [
"# Data / physical qubits\n",
"q = array(qubit() for _ in range(3))\n",
"# Ancilla qubits used for parity checks\n",
"anc = array(qubit() for _ in range(2))\n",
"\n",
"# Create some quantum information to be protected\n",
"h(q[0])\n",
"\n",
"# Encode information from q[0] by repetition, i.e. |0> -> |000>, |1> -> |111>\n",
"cx(q[0], q[1])\n",
"cx(q[0], q[2])"
]
},
{
"cell_type": "markdown",
"id": "2d2ca8b7",
"metadata": {},
"source": [
"We will then seed guppy's random number generator using the current shot number and artificially induce a single x bit flip error in our program."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1d9b5586",
"metadata": {},
"outputs": [],
"source": [
"@guppy\n",
"def flip_random_bit(q: array[qubit, 3], rng: RNG) -> None:\n",
" # Each qubit has a 1/4 chance to be hit by the flip, 1/4 chance nothing happens\n",
" r = rng.random_int_bounded(4)\n",
" if r < 3:\n",
" x(q[r])\n",
" output(\"Flipped qubit\", r)\n",
"\n",
"# Randomly induce a bit-flip on one qubit to simulate an error.\n",
"rng = RNG(get_current_shot())\n",
"flip_random_bit(q, rng)"
]
},
{
"cell_type": "markdown",
"id": "19f0833a",
"metadata": {},
"source": [
"We then extract our syndrome from the ancilla qubits to check for disagreements between neighboring qubits. This can be used to determine which qubit disagrees with the majority and was therefore flipped due to an error thus allowing us to correct it."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6b046364",
"metadata": {},
"outputs": [],
"source": [
"# Perform minimum required parity checks between q[0]q[1] pair and q[1]q[2] pair\n",
"for i in range(2):\n",
" cx(q[i], anc[i])\n",
" cx(q[i+1], anc[i])\n",
"\n",
"s = measure_array(anc)\n",
"# q[0]q[1] disagree, q[1]q[2] agree -> q[0] is bad\n",
"if s[0] and not s[1]:\n",
" correct_qubit = 0\n",
" \n",
"# q[0]q[1] disagree, q[1]q[2] disagree -> q[1] is bad\n",
"elif s[0] and s[1]:\n",
" correct_qubit = 1\n",
"\n",
"# q[0]q[1] agree, q[1]q[2] disagree -> q[2] is bad\n",
"elif not s[0] and s[1]:\n",
" correct_qubit = 2\n",
"\n",
"# q[0]q[1] agree, q[1]q[2] agree, no corrections necessary\n",
"else:\n",
" correct_qubit = 3\n",
"\n",
"if correct_qubit < 3:\n",
" x(q[correct_qubit])\n",
" output(\"Corrected qubit\", correct_qubit)\n",
"\n",
"discard_array(q)\n",
"rng.discard()"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading