├── Code ├── lab1.ipynb ├── lab2.ipynb ├── lab3.ipynb ├── lab4.ipynb └── lab5.ipynb ├── Images ├── Completion.png ├── Lab1.png ├── Lab2.png ├── Lab3.png ├── Lab4.png └── Lab5.png ├── LICENSE └── README.md /Code/lab3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Lab 3: Iterative phase estimation\n", 8 | "\n", 9 | "The quantum phase estimation (QPE) algorithm is one of the most important and famous quantum algorithms. It is a key subroutine of Shor's factoring algorithm, as well as algorithms for quantum simulation. The textbook version of the algorithm uses a number of auxiliary qubits which scales with the desired precision, leading to circuits that are challenging to execute on today's noisy devices with limited qubit number and connectivity.\n", 10 | "\n", 11 | "Iterative phase estimation (IPE) is a variant of QPE which requires only one auxiliary qubit. In IPE, the auxiliary qubit is repeatedly measured, with the measurement results used to guide future quantum operations. Until the introduction of dynamic circuits, such classical feed-forward was impossible to execute on IBM's quantum hardware.\n", 12 | "\n", 13 | "In this lab, we will use the recently introduced dynamic circuits capabilities to implement IPE." 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "## Background\n", 21 | "\n", 22 | "Like any phase estimation algorithm, IPE is designed to solve the following problem:\n", 23 | "\n", 24 | "**Problem statement:** Given a unitary matrix $U$ and an eigenstate $|\\Psi\\rangle$ of $U$ with an unknown eigenvalue $e^{i 2\\pi \\varphi}$, estimate the value of $\\varphi$.\n", 25 | "\n", 26 | "A few important details need to be clarified in this problem statement, namely, how $U$ and $|\\Psi\\rangle$ are specified. We assume that $U$ is given as a quantum circuit implementing $U$, and in fact, we assume we have the ability to efficiently implement the operations *controlled*-$U^{2^t}$ for positive integers $t$.\n", 27 | "This is the same assumption used in the original QPE algorithm.\n", 28 | "The eigenstate is also given as a quantum circuit: we assume we have the ability to efficiently prepare $|\\Psi\\rangle$.\n", 29 | "\n", 30 | "Let's first assume for simplicity that $\\varphi$ can have an exact binary expansion, that is, it can be written as\n", 31 | "$$\n", 32 | "\\varphi = \\varphi_1/2 + \\varphi_2/4 + \\cdots + \\varphi_m/2^m = 0.\\varphi_1 \\varphi_2 \\cdots \\varphi_m\n", 33 | "$$\n", 34 | "where in the final equality we are using \"decimal\" point notation in base 2.\n", 35 | "For simplicity, suppose $U$ is a unitary operator acting on one qubit (everything we say here also applies to the case where $U$ acts on multiple qubits). Since IPE requires an auxiliary qubit, we need a system of two qubits, $q_0$ and $q_1$, where $q_0$ is the auxiliary qubit and $q_1$ represents the physical system on which $U$ operates.\n", 36 | "\n", 37 | "Now, suppose that we initialize $q_0$ in the state $|+\\rangle = \\frac{|0\\rangle + |1\\rangle}{\\sqrt{2}}$ and $q_1$ in the state $|\\Psi \\rangle$.\n", 38 | "What happens if we apply the *controlled*-$U^{2^t}$ gate, with $q_0$ being the control and $q_1$ being the target?\n", 39 | "Since $|\\Psi \\rangle$ is an eigenstate of $U$ with eigenvalue $e^{i 2\\pi \\varphi}$, we have\n", 40 | "$$\n", 41 | "\\begin{align}\n", 42 | "|+\\rangle |\\Psi \\rangle &= \\left(\\frac{|0\\rangle + |1\\rangle}{\\sqrt{2}}\\right) |\\Psi \\rangle \\\\\n", 43 | "&= \\frac{|0\\rangle |\\Psi \\rangle + |1\\rangle |\\Psi \\rangle}{\\sqrt{2}} \\\\\n", 44 | "&\\xrightarrow{\\text{controlled-}U^{2^t}} \\frac{|0\\rangle |\\Psi \\rangle + e^{i 2 \\pi 2^{t} \\varphi} |1\\rangle |\\Psi \\rangle}{\\sqrt{2}} \\\\\n", 45 | "&= \\left(\\frac{|0\\rangle + e^{i 2 \\pi 2^{t} \\varphi} |1\\rangle}{\\sqrt{2}}\\right) |\\Psi \\rangle.\n", 46 | "\\end{align}\n", 47 | "$$\n", 48 | "That is, the state of the system qubit remains unchanged, while a phase of $e^{i 2 \\pi 2^{t} \\varphi}$ has been \"kicked back\" into the state of the auxiliary qubit.\n", 49 | "\n", 50 | "Now, note that\n", 51 | "$$\n", 52 | "e^{i 2 \\pi 2^{t} \\varphi} = e^{i 2 \\pi 2^{t} (0.\\varphi_1 \\varphi_2 \\cdots \\varphi_m)}\n", 53 | "= e^{i 2 \\pi (\\varphi_1 \\cdots \\varphi_t . \\varphi_{t + 1} \\cdots \\varphi_m)}\n", 54 | "= e^{i 2 \\pi (0. \\varphi_{t + 1} \\cdots \\varphi_m)},\n", 55 | "$$\n", 56 | "where in the last equality, the whole number part of the \"decimal\" representation of the phase has disappeared because $e^{i 2\\pi n} = 1$ for any integer $n$.\n", 57 | "For example:\n", 58 | "- for $t=0$, the phase would be $e^{i 2 \\pi 2^{0} \\varphi} = e^{i 2 \\pi \\varphi} = e^{i 2 \\pi 0.\\varphi_1 \\varphi_2 ... \\varphi_m}$\n", 59 | "- for $t=1$, the phase would be $e^{i 2 \\pi 2^{1} \\varphi}= e^{i 2 \\pi \\varphi_1} e^{i 2 \\pi 0.\\varphi_2 \\varphi_3 ... \\varphi_m} = e^{i 2 \\pi 0.\\varphi_2 \\varphi_3 ... \\varphi_m}$\n", 60 | "- for $t=2$, the phase would be $e^{i 2 \\pi 2^{2} \\varphi} = e^{i 2 \\pi 0.\\varphi_3 \\varphi_4 ... \\varphi_m}$\n", 61 | "- for $t=m-1$, the phase would be $e^{i 2 \\pi 2^{m-1} \\varphi} = e^{i 2 \\pi 0.\\varphi_m}$.\n", 62 | "\n", 63 | "In the last case where $t = m - 1$, the phase is $e^{i 2 \\pi 0.\\varphi_m}$, which is equal to $1$ if $\\varphi_m = 0$ and $-1$ if $\\varphi_m = 1$.\n", 64 | "In the first case, the auxiliary qubit $q_0$ would be in the state $|+\\rangle = \\frac{|0\\rangle + |1\\rangle}{\\sqrt{2}}$, and in the second case it would be\n", 65 | "in the state $|-\\rangle = \\frac{|0\\rangle - |1\\rangle}{\\sqrt{2}}$. Therefore, measuring the qubit in the Pauli $X$ basis would distinguish these cases with a 100\\% success rate.\n", 66 | "This is done by performing a Hadamard gate on the qubit before measuring it. In the first case we would measure 0 and in the second case we would measure 1;\n", 67 | "in other words, the measured bit would be equal to $\\varphi_m$.\n", 68 | "\n", 69 | "### The algorithm\n", 70 | "\n", 71 | "In the first step of the IPE algorithm, we directly measure the least significant bit of the phase $\\varphi$, $\\varphi_m$, by initializing the 2-qubit registers as described above ( $q_0 \\rightarrow |+\\rangle$ and $q_1 \\rightarrow |\\Psi \\rangle$ ), performing a *controlled*-$U^{2^{m-1}}$ operation, and measuring $q_0$ in the Pauli $X$ basis.\n", 72 | "\n", 73 | "in the second step, we initialize the systems in the same way and apply a *controlled*-$U^{2^{m-2}}$ operation. The relative phase in $q_0$ after these operations is now $e^{i 2 \\pi 0.\\varphi_{m-1}\\varphi_{m}}= e^{i 2 \\pi 0.\\varphi_{m-1}} e^{i 2 \\pi \\varphi_m/4}$. \n", 74 | "To extract the phase bit $\\varphi_{m-1}$, first perform a phase correction by rotating around the $Z$-axis by an angle $-2 \\pi \\varphi_m/4=-\\pi \\varphi_m/2$, which results in the state of $q_0$ to be $|0\\rangle + e^{i 2 \\pi 0.\\varphi_{m-1}} | 1 \\rangle$. Perform a measurement on $q_0$ in the Pauli $X$ basis to obtain the phase bit $\\varphi_{m-1}$. \n", 75 | "\n", 76 | "Therefore, the $k$-th step of the IPE, getting $\\varphi_{m-k+1}$, consists of the register initialization ($q_0$ in $|+\\rangle$, $q_1$ in $|\\Psi\\rangle$), the application of a *controlled*-$U^{2^{m-k}}$, a rotation around $Z$ of angle $\\omega_k = -2 \\pi 0.0\\varphi_{m-k+2} ... \\varphi_m$, and a measurement of $q_0$ in the Pauli $X$ basis: a Hadamard transform to $q_0$, and a measurement of $q_0$ in the computational basis. Note that $q_1$ remains in the state $|\\Psi\\rangle$ throughout the algorithm." 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "## Implementation\n", 84 | "\n", 85 | "In this lab, we will perform IPE on the single-qubit $S$-gate. The $S$ gate is given by the matrix\n", 86 | "\n", 87 | "$$ S =\n", 88 | "\\begin{pmatrix}\n", 89 | "1 & 0\\\\\n", 90 | "0 & e^{i\\pi / 2}\n", 91 | "\\end{pmatrix}$$\n", 92 | "\n", 93 | "We will use the eigenstate $|\\Psi\\rangle = |1\\rangle$, which has eigenvalue $e^{i\\pi / 2}= e^{i2\\pi \\cdot 1/4}$. So we have $\\varphi = 1/4 = 0.01 = 0.\\varphi_1 \\varphi_2$. Since $\\varphi$ can be represented exactly with 2 bits, our quantum circuit implementation will use a classical register with two bits to store the result.\n", 94 | "\n", 95 | "The controlled-$S$ gate can be implemented using the controlled phase gate, available in Qiskit as `CPhaseGate`, which can also be applied by calling the `cp` method of a `QuantumCircuit`. The controlled phase gate is parameterized by an angle $\\theta$ and has the matrix\n", 96 | "$$\n", 97 | " \\text{CPhase}(\\theta) =\n", 98 | " \\begin{pmatrix}\n", 99 | " 1 & 0 & 0 & 0 \\\\\n", 100 | " 0 & 1 & 0 & 0 \\\\\n", 101 | " 0 & 0 & 1 & 0 \\\\\n", 102 | " 0 & 0 & 0 & e^{i\\theta}\n", 103 | " \\end{pmatrix}\n", 104 | "$$" 105 | ] 106 | }, 107 | { 108 | "cell_type": "markdown", 109 | "metadata": {}, 110 | "source": [ 111 | "\n", 112 | "### Step 1\n", 113 | "\n", 114 | "In the first step of the algorithm, we measure the least significant bit of $\\varphi$.\n", 115 | "\n", 116 | "#### Exercise 1\n", 117 | "\n", 118 | "Obtain the least significant bit of $\\varphi$ by performing the following steps:\n", 119 | "1. Initialize the qubits:\n", 120 | " - Apply a Hadamard on the auxiliary qubit.\n", 121 | " - Apply an X gate on the system qubit to put it in the $|1\\rangle$ state.\n", 122 | "2. Apply a *controlled*-$S^{2}$ gate by applying a `CPhaseGate` with the appropriate angle.\n", 123 | "3. Measure the auxiliary qubit in the $X$ basis:\n", 124 | " - Apply a Hadamard gate on the auxiliary qubit.\n", 125 | " - Measure it in the computational basis.\n", 126 | "\n", 127 | "The resulting circuit should look something like this:\n", 128 | "\n", 129 | "![step1-circuit](resources/step1-circuit.png)" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 4, 135 | "metadata": {}, 136 | "outputs": [ 137 | { 138 | "data": { 139 | "image/png": "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c/iNANw+Iov28XF+rsgzdGLzB5MmTaq9S/KPf/wjw4cPr1134sQJVq5cycyZM936PpOX3lzH2fJzbtfmdDopr6zZPjoyglA3zqKLSI0LFy8SHhbm7zLqiW0TxX9N/0mzt1OIA7t372bQoEGEhoayd+9e0tLSPNr//Jffoqy8wqN9ikhwiWsTw9xfTGv2dhrSAe+99x4AY8eO9XiAQ81vWHdpFC7SOribE0oEID+/5oRhVlaWV/p35yPSJRs+3sE/dh2ge5dO/Pze8TqhKSJ1KMSpOakJcNVVV3mlf3fnxH88Ci85dZoFr/zJ06WJSIBwd05cIQ7ExdWcpfbWd5WcLT/X4jnxyqrzwHnPFCQiQUMhDvTr149169axY8cOr/TvzlyX5sJFWhd358R1dQqwd+9errvuOsLCwsjLy6Nv377+Lklz4SLSJLrZBxgwYACTJ0/m4sWLjBkzhk8++aTO+hMnTrBgwQIqKnxzmaDuzhSRptJI/AdlZWVMmDCBrVu3AtC1a1e6dOlCcXExRUVFuFwuSktLiY+P93otGoWLSFNpJP6DuLg4PvroI1auXMmwYcOorKxk3759WK1WbrvtNlauXElsbKxPamkTE0VkRLhG4SJyRRqJB6iq8xeICA9TiIvIZSnERUQMpukUERGDKcRFRAymEBcRMZhCXETEYApxERGDKcRFRAymEBcRMZhCXETEYApxERGDKcRFRAymEBcRMZhCXETEYApxERGDKcRFRAymEBcRMZhCXETEYApxERGDKcRFRAymEBcRMZhCXETEYApxERGDKcRFRAymEBcRMZhCXETEYApxERGDKcRFRAymEBcRMZhCXETEYApxERGDKcRFRAymEBcRMZhCXETEYApxERGDKcRFRAymEBcRMZhCXETEYApxERGDKcRFRAymEBcRMdj/B602hCvzsim3AAAAAElFTkSuQmCC\n", 140 | "text/plain": [ 141 | "
" 142 | ] 143 | }, 144 | "execution_count": 4, 145 | "metadata": {}, 146 | "output_type": "execute_result" 147 | } 148 | ], 149 | "source": [ 150 | "from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister\n", 151 | "import numpy as np\n", 152 | "\n", 153 | "\n", 154 | "def step_1_circuit(qr: QuantumRegister, cr: ClassicalRegister) -> QuantumCircuit:\n", 155 | " # qr is a quantum register with 2 qubits\n", 156 | " # cr is a classical register with 2 bits\n", 157 | "\n", 158 | " qc = QuantumCircuit(qr, cr)\n", 159 | "\n", 160 | " ####### your code goes here #######\n", 161 | " # Step 1: Initialize the qubits\n", 162 | " qc.h(qr[0]) # Apply a Hadamard gate on the auxiliary qubit (qubit 0)\n", 163 | " qc.x(qr[1]) # Apply an X gate on the system qubit (qubit 1) to put it in the |1⟩ state\n", 164 | "\n", 165 | " # Step 2: Apply the controlled-S^2 gate\n", 166 | " qc.cp(np.pi, qr[0], qr[1]) # Apply a CPhaseGate with angle 2π/4 (corresponding to the S^2 gate)\n", 167 | " \n", 168 | " # Step 3: MEasure the Auxiliary qubit in the X basis\n", 169 | " qc.h(qr[0]) # Apply a Hadamard gate on the auxiliary qubit\n", 170 | " qc.measure(qr[0], cr[0]) # # Measure the auxiliary qubit and store the result in the first classical bit\n", 171 | "\n", 172 | " return qc\n", 173 | "\n", 174 | "\n", 175 | "qr = QuantumRegister(2, \"q\")\n", 176 | "cr = ClassicalRegister(2, \"c\")\n", 177 | "qc = QuantumCircuit(qr, cr)\n", 178 | "qc = step_1_circuit(qr, cr)\n", 179 | "qc.draw(\"mpl\")" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 5, 185 | "metadata": {}, 186 | "outputs": [ 187 | { 188 | "name": "stdout", 189 | "output_type": "stream", 190 | "text": [ 191 | "Submitting your answer. Please wait...\n", 192 | "Congratulations 🎉! Your answer is correct and has been submitted.\n" 193 | ] 194 | } 195 | ], 196 | "source": [ 197 | "# Submit your circuit\n", 198 | "\n", 199 | "from qc_grader.challenges.spring_2023 import grade_ex3a\n", 200 | "\n", 201 | "grade_ex3a(qc)" 202 | ] 203 | }, 204 | { 205 | "cell_type": "markdown", 206 | "metadata": {}, 207 | "source": [ 208 | "### Step 2\n", 209 | "\n", 210 | "In the first step, we measured the least significant bit $\\varphi_2$. In the second (and final) step, we extract the next bit $\\varphi_1$, which will involve applying a phase correction to cancel out the phase contribution from $\\varphi_2$. The phase correction depends on the value of the classical register holding $\\varphi_2$. We need dynamic circuits to perform this classical feedback! The phase correction can be applied using `PhaseGate` or by directly calling the `p` method of a QuantumCircuit.\n", 211 | "\n", 212 | "#### Exercise 2\n", 213 | "\n", 214 | "In this exercise, we begin with the circuit from Step 1, which you should have constructed in Exercise 1.\n", 215 | "\n", 216 | "Obtain the next bit of $\\varphi$ by performing the following steps:\n", 217 | "1. Reset and re-initialize the auxiliary qubit.\n", 218 | "2. Apply the controlled unitary gate.\n", 219 | "3. Measure the auxiliary qubit in the $X$ basis.\n", 220 | "\n", 221 | "The resulting circuit should look something like this:\n", 222 | "\n", 223 | "![step1-circuit](resources/step2-circuit.png)" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 14, 229 | "metadata": {}, 230 | "outputs": [ 231 | { 232 | "data": { 233 | "image/png": "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\n", 234 | "text/plain": [ 235 | "
" 236 | ] 237 | }, 238 | "execution_count": 14, 239 | "metadata": {}, 240 | "output_type": "execute_result" 241 | } 242 | ], 243 | "source": [ 244 | "def step_2_circuit(qr: QuantumRegister, cr: ClassicalRegister) -> QuantumCircuit:\n", 245 | " # qr is a quantum register with 2 qubits\n", 246 | " # cr is a classical register with 2 bits\n", 247 | "\n", 248 | " # begin with the circuit from Step 1\n", 249 | " qc = step_1_circuit(qr, cr)\n", 250 | "\n", 251 | " ####### your code goes here #######\n", 252 | " # Step 1: Reset and re-initialize the auxiliary qubit\n", 253 | " qc.reset(qr[0]) # Reset the auxiliary qubit to |0⟩ state\n", 254 | " qc.h(qr[0]) # Apply a Hadamard gate on the auxiliary qubit\n", 255 | "\n", 256 | " # Step 2: Apply the controlled unitary gate\n", 257 | " # The phase correction depends on the value of the classical register holding 𝜑2\n", 258 | " with qc.if_test((cr[0],1)):\n", 259 | " qc.p(-np.pi/2, qr[0]) # Apply a phase gate with angle -π/2 conditioned on cr[0] being 1\n", 260 | " \n", 261 | " qc.cp(np.pi/2,qr[0],qr[1])\n", 262 | "\n", 263 | " # Step 3: Measure the auxiliary qubit in the X basis\n", 264 | " qc.h(qr[0]) # Apply a Hadamard gate on the auxiliary qubit\n", 265 | " qc.measure(qr[0], cr[1]) # Measure the auxiliary qubit and store the result in the second classical bit\n", 266 | "\n", 267 | " return qc\n", 268 | "\n", 269 | "\n", 270 | "qr = QuantumRegister(2, \"q\")\n", 271 | "cr = ClassicalRegister(2, \"c\")\n", 272 | "qc = QuantumCircuit(qr, cr)\n", 273 | "qc = step_2_circuit(qr, cr)\n", 274 | "qc.draw(\"mpl\")" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 15, 280 | "metadata": {}, 281 | "outputs": [ 282 | { 283 | "name": "stdout", 284 | "output_type": "stream", 285 | "text": [ 286 | "Submitting your answer. Please wait...\n", 287 | "Congratulations 🎉! Your answer is correct and has been submitted.\n" 288 | ] 289 | } 290 | ], 291 | "source": [ 292 | "# Submit your circuit\n", 293 | "\n", 294 | "from qc_grader.challenges.spring_2023 import grade_ex3b\n", 295 | "\n", 296 | "grade_ex3b(qc)" 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "metadata": {}, 302 | "source": [ 303 | "## Run on simulator\n", 304 | "\n", 305 | "Now that we have the complete circuit, let's first run it on a local simulator." 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 16, 311 | "metadata": {}, 312 | "outputs": [ 313 | { 314 | "data": { 315 | "text/plain": [ 316 | "{'01': 1000}" 317 | ] 318 | }, 319 | "execution_count": 16, 320 | "metadata": {}, 321 | "output_type": "execute_result" 322 | } 323 | ], 324 | "source": [ 325 | "from qiskit_aer import AerSimulator\n", 326 | "\n", 327 | "sim = AerSimulator()\n", 328 | "job = sim.run(qc, shots=1000)\n", 329 | "result = job.result()\n", 330 | "counts = result.get_counts()\n", 331 | "counts" 332 | ] 333 | }, 334 | { 335 | "cell_type": "markdown", 336 | "metadata": {}, 337 | "source": [ 338 | "If your circuit is correct, you should have gotten the bitstring `01` with 100% probability. This value corresponds to the phase written in binary as $\\varphi = 0.01 = 1/4$. Indeed, this is the correct phase!" 339 | ] 340 | }, 341 | { 342 | "cell_type": "markdown", 343 | "metadata": {}, 344 | "source": [ 345 | "### Exercise 3\n", 346 | "\n", 347 | "Construct an IPE circuit to estimate the phase of the T gate, whose matrix is given by\n", 348 | "\n", 349 | "$$ T =\n", 350 | "\\begin{pmatrix}\n", 351 | "1 & 0\\\\\n", 352 | "0 & e^{i\\pi / 4}\n", 353 | "\\end{pmatrix}$$\n", 354 | "\n", 355 | "How many bits are needed to represent the phase in this case?" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 20, 361 | "metadata": {}, 362 | "outputs": [ 363 | { 364 | "data": { 365 | "image/png": "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\n", 366 | "text/plain": [ 367 | "
" 368 | ] 369 | }, 370 | "execution_count": 20, 371 | "metadata": {}, 372 | "output_type": "execute_result" 373 | } 374 | ], 375 | "source": [ 376 | "from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister\n", 377 | "import numpy as np\n", 378 | "\n", 379 | "\n", 380 | "def t_gate_ipe_circuit(qr: QuantumRegister, cr: ClassicalRegister) -> QuantumCircuit:\n", 381 | " # qr is a quantum register with 2 qubits\n", 382 | " # cr is a classical register with 3 bits\n", 383 | "\n", 384 | " qc = QuantumCircuit(qr, cr)\n", 385 | " m = 3 #number of bits\n", 386 | " ####### your code goes here #######\n", 387 | " qc.h(qr[0])\n", 388 | " qc.x(qr[1])\n", 389 | " \n", 390 | " \n", 391 | " # for _ in range (2 ** (m-1)):\n", 392 | " # qc.cp(np.pi/4,qr[0],qr[1])\n", 393 | " \n", 394 | " qc.cp(np.pi,qr[0],qr[1])\n", 395 | " \n", 396 | " qc.h(qr[0])\n", 397 | " qc.measure(qr[0],cr[0])\n", 398 | " \n", 399 | " qc.reset(qr[0])\n", 400 | " qc.h(qr[0])\n", 401 | " \n", 402 | " #phase correction\n", 403 | " with qc.if_test((cr[0],1)):\n", 404 | " qc.p(-np.pi/2,qr[0])\n", 405 | " \n", 406 | " # for _ in range (2 ** (m-2)):\n", 407 | " # qc.cp(np.pi/4,qr[0],qr[1])\n", 408 | " \n", 409 | " qc.cp(np.pi/2,qr[0],qr[1])\n", 410 | " \n", 411 | " qc.h(qr[0])\n", 412 | " qc.measure(qr[0],cr[1])\n", 413 | " \n", 414 | " qc.reset(qr[0])\n", 415 | " qc.h(qr[0])\n", 416 | " \n", 417 | " #phase correction\n", 418 | " with qc.if_test((cr[0],1)):\n", 419 | " qc.p(-np.pi/4,qr[0])\n", 420 | " \n", 421 | " with qc.if_test((cr[1],1)):\n", 422 | " qc.p(-np.pi/2,qr[0])\n", 423 | " \n", 424 | " # for _ in range (2 ** (m-3)):\n", 425 | " # qc.cp(np.pi/4,qr[0],qr[1])\n", 426 | " \n", 427 | " qc.cp(np.pi/4,qr[0],qr[1])\n", 428 | " \n", 429 | " qc.h(qr[0])\n", 430 | " qc.measure(qr[0],cr[2])\n", 431 | " \n", 432 | " return qc\n", 433 | "\n", 434 | "\n", 435 | "qr = QuantumRegister(2, \"q\")\n", 436 | "cr = ClassicalRegister(3, \"c\")\n", 437 | "qc = QuantumCircuit(qr, cr)\n", 438 | "qc = t_gate_ipe_circuit(qr, cr)\n", 439 | "qc.draw(\"mpl\")" 440 | ] 441 | }, 442 | { 443 | "cell_type": "code", 444 | "execution_count": 21, 445 | "metadata": {}, 446 | "outputs": [ 447 | { 448 | "data": { 449 | "text/plain": [ 450 | "{'001': 1000}" 451 | ] 452 | }, 453 | "execution_count": 21, 454 | "metadata": {}, 455 | "output_type": "execute_result" 456 | } 457 | ], 458 | "source": [ 459 | "from qiskit_aer import AerSimulator\n", 460 | "\n", 461 | "sim = AerSimulator()\n", 462 | "job = sim.run(qc, shots=1000)\n", 463 | "result = job.result()\n", 464 | "counts = result.get_counts()\n", 465 | "counts" 466 | ] 467 | }, 468 | { 469 | "cell_type": "code", 470 | "execution_count": 22, 471 | "metadata": {}, 472 | "outputs": [ 473 | { 474 | "name": "stdout", 475 | "output_type": "stream", 476 | "text": [ 477 | "Submitting your answer. Please wait...\n", 478 | "Congratulations 🎉! Your answer is correct and has been submitted.\n" 479 | ] 480 | } 481 | ], 482 | "source": [ 483 | "# Submit your circuit\n", 484 | "\n", 485 | "from qc_grader.challenges.spring_2023 import grade_ex3c\n", 486 | "\n", 487 | "grade_ex3c(qc)" 488 | ] 489 | }, 490 | { 491 | "cell_type": "markdown", 492 | "metadata": {}, 493 | "source": [ 494 | "### When the phase does not have an exact binary expansion\n", 495 | "\n", 496 | "Let's consider the case when the phase does not have an exact binary expansion, for example, $\\varphi = 1/3$.\n", 497 | "In this case, the single-qubit gate has the unitary\n", 498 | "\n", 499 | "$$ U =\n", 500 | "\\begin{pmatrix}\n", 501 | "1 & 0\\\\\n", 502 | "0 & e^{i2\\pi / 3}\n", 503 | "\\end{pmatrix}\n", 504 | "$$\n", 505 | "\n", 506 | "The angle $\\varphi = 1/3$ does not have an exact finite binary expansion. In contrast, it has the infinite binary expansion\n", 507 | "\n", 508 | "$$\n", 509 | "1/3 = 0.010101\\ldots\n", 510 | "$$\n", 511 | "\n", 512 | "In practice we work with a fixed number of bits of precision, so our goal is to obtain the closest value that can be represented with those bits. In the following example, we will use two bits of precision. In this case, the closest value is $0.01 = 1/4$. Because this value does not represent the exact phase, there is some probability that we will obtain a different, less precise result.\n", 513 | "\n", 514 | "In the following code cells, we construct and simulate an IPE circuit to measure the phase of this gate." 515 | ] 516 | }, 517 | { 518 | "cell_type": "code", 519 | "execution_count": 23, 520 | "metadata": {}, 521 | "outputs": [ 522 | { 523 | "data": { 524 | "image/png": "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\n", 525 | "text/plain": [ 526 | "
" 527 | ] 528 | }, 529 | "execution_count": 23, 530 | "metadata": {}, 531 | "output_type": "execute_result" 532 | } 533 | ], 534 | "source": [ 535 | "from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister\n", 536 | "import numpy as np\n", 537 | "\n", 538 | "\n", 539 | "def u_circuit(qr: QuantumRegister, cr: ClassicalRegister) -> QuantumCircuit:\n", 540 | " # qr is a quantum register with 2 qubits\n", 541 | " # cr is a classical register with 2 bits\n", 542 | "\n", 543 | " qc = QuantumCircuit(qr, cr)\n", 544 | "\n", 545 | " # Initialization\n", 546 | " q0, q1 = qr\n", 547 | " qc.h(q0)\n", 548 | " qc.x(q1)\n", 549 | "\n", 550 | " # Apply control-U operator as many times as needed to get the least significant phase bit\n", 551 | " u_angle = np.pi / 3\n", 552 | " k = 1\n", 553 | " cphase_angle = u_angle * 2**k\n", 554 | " qc.cp(cphase_angle, q0, q1)\n", 555 | "\n", 556 | " # Measure the auxiliary qubit in x-basis into the first classical bit\n", 557 | " qc.h(q0)\n", 558 | " c0, c1 = cr\n", 559 | " qc.measure(q0, c0)\n", 560 | "\n", 561 | " # Reset and re-initialize the auxiliary qubit\n", 562 | " qc.reset(q0)\n", 563 | " qc.h(q0)\n", 564 | "\n", 565 | " # Apply phase correction conditioned on the first classical bit\n", 566 | " with qc.if_test((c0, 1)):\n", 567 | " qc.p(-np.pi / 2, q0)\n", 568 | "\n", 569 | " # Apply control-U operator as many times as needed to get the next phase bit\n", 570 | " k = 0\n", 571 | " cphase_angle = u_angle * 2**k\n", 572 | " qc.cp(cphase_angle, q0, q1)\n", 573 | "\n", 574 | " # Measure the auxiliary qubit in x-basis into the second classical bit\n", 575 | " qc.h(q0)\n", 576 | " qc.measure(q0, c1)\n", 577 | "\n", 578 | " return qc\n", 579 | "\n", 580 | "\n", 581 | "qr = QuantumRegister(2, \"q\")\n", 582 | "cr = ClassicalRegister(2, \"c\")\n", 583 | "qc = QuantumCircuit(qr, cr)\n", 584 | "qc = u_circuit(qr, cr)\n", 585 | "qc.draw(\"mpl\")" 586 | ] 587 | }, 588 | { 589 | "cell_type": "code", 590 | "execution_count": 24, 591 | "metadata": {}, 592 | "outputs": [ 593 | { 594 | "name": "stdout", 595 | "output_type": "stream", 596 | "text": [ 597 | "{'11': 43, '01': 720, '10': 56, '00': 181}\n", 598 | "Success probability: 0.72\n" 599 | ] 600 | } 601 | ], 602 | "source": [ 603 | "from qiskit_aer import AerSimulator\n", 604 | "\n", 605 | "sim = AerSimulator()\n", 606 | "job = sim.run(qc, shots=1000)\n", 607 | "result = job.result()\n", 608 | "counts = result.get_counts()\n", 609 | "print(counts)\n", 610 | "success_probability = counts[\"01\"] / counts.shots()\n", 611 | "print(f\"Success probability: {success_probability}\")" 612 | ] 613 | }, 614 | { 615 | "cell_type": "markdown", 616 | "metadata": {}, 617 | "source": [ 618 | "As you can see, this time, we are not guaranteed to obtain the desired result. A natural question to ask is: How can we boost the success probability?\n", 619 | "\n", 620 | "One way that the algorithm fails is that the first measured bit is incorrect. In this case, the phase correction applied before measuring the second bit is also incorrect, causing the rest of the bits to be likely incorrect as well. A simple way to mitigate this problem is to repeat the measurement of the first few bits several times and take a majority vote to increase the likelihood that we measure the bit correctly. Implementing this procedure within a single circuit requires performing arithmetic on the measured outcomes. Due to a temporary limitation in Qiskit, it is currently not possible to perform arithmetic on measured bits and condition future circuit operations on the results. So, here we will measure each bit using separate circuits.\n", 621 | "\n", 622 | "The following code cells construct and simulate an IPE circuit for measuring just the first bit of the phase." 623 | ] 624 | }, 625 | { 626 | "cell_type": "code", 627 | "execution_count": 25, 628 | "metadata": {}, 629 | "outputs": [ 630 | { 631 | "data": { 632 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbIAAADuCAYAAABcSIIkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAcg0lEQVR4nO3deXRU9f3/8eedrCQkshNIICE10LCGVcA1NFB2sIrKotbij5/tD8VCiRb1qKdWilKwVPmBX+CnoGIUKCJLPShQ+VJEtgBli1CCTJJBI2FJQoBk5vdHZL6mCZIZJpl8Jq/HORy493OX98DcvPjc+7n3Wi6Xy4WIiIihbP4uQERE5EYoyERExGgKMhERMZqCTEREjKYgExERoynIRETEaAoyERExmoJMRESMpiATERGjKchERMRoCjIRETGagkxERIymIBMREaMpyERExGgKMhERMZqCTEREjKYgExERoynIRETEaAoyERExmoJMRESMpiATERGjKchERMRoCjIRETGagkxERIymIBMREaMpyERExGgKMhERMZqCTEREjKYgExERoynIRETEaAoyERExmoJMRESMpiATERGjKchERMRoCjIRETGagkxERIymIBMREaMF+7sAqczlgstl/q7CM6FBYFn+rkICiWnHga+PAZfLRXFxse82WAsiIiKw/PCDQEFWB10ug6cy/F2FZ2bdD2H6NokPmXYc+PoYKC4upmHDhr7bYC0oLCwkMjKy1verU4siImI0BZmIiBhNQSYiIkZTkImIiNEUZCIiYjQFmYiIGE1BJiIiRlOQiYiI0RRkIiJiNAWZiIgYTUEmIlIPWJZFq1atSExMJCEhgSZNmni0fkhICL///e8JCwuroQq9p6fjiYgEqB49evDAAw/Qu3dvunfvzk033VShPScnh927d7N9+3aWLl1Kbm5uldsJCQnhww8/ZNSoUdx6663cc889XLp0qTY+QrWoRyYiEkAsy2L8+PF88cUX7N69m+nTp3PXXXdVCjGA2NhYRo4cycyZMzl58iQffvgh/fr1q7DMD0MMIDU1lc6dO9fKZ6mugA+y/Px80tPTufnmmwkPD6dNmzZMmTKFoqIiJk6ciGVZvP766/4uUwKYywVnc+DwRti3GvZ9BFlboOg7f1cmgaZdu3Zs2rSJd955h1tuuaVC26lTp1i7di3vvvsu7733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\n", 633 | "text/plain": [ 634 | "
" 635 | ] 636 | }, 637 | "execution_count": 25, 638 | "metadata": {}, 639 | "output_type": "execute_result" 640 | } 641 | ], 642 | "source": [ 643 | "from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister\n", 644 | "import numpy as np\n", 645 | "\n", 646 | "\n", 647 | "def u_circuit(qr: QuantumRegister, cr: ClassicalRegister) -> QuantumCircuit:\n", 648 | " # qr is a quantum register with 2 qubits\n", 649 | " # cr is a classical register with 1 bits\n", 650 | "\n", 651 | " qc = QuantumCircuit(qr, cr)\n", 652 | "\n", 653 | " # Initialization\n", 654 | " q0, q1 = qr\n", 655 | " qc.h(q0)\n", 656 | " qc.x(q1)\n", 657 | "\n", 658 | " # Apply control-U operator as many times as needed to get the least significant phase bit\n", 659 | " u_angle = np.pi / 3\n", 660 | " k = 1\n", 661 | " cphase_angle = u_angle * 2**k\n", 662 | " qc.cp(cphase_angle, q0, q1)\n", 663 | "\n", 664 | " # Measure the auxiliary qubit in x-basis\n", 665 | " qc.h(q0)\n", 666 | " (c0,) = cr\n", 667 | " qc.measure(q0, c0)\n", 668 | "\n", 669 | " return qc\n", 670 | "\n", 671 | "\n", 672 | "qr = QuantumRegister(2, \"q\")\n", 673 | "cr = ClassicalRegister(1, \"c\")\n", 674 | "qc = QuantumCircuit(qr, cr)\n", 675 | "qc = u_circuit(qr, cr)\n", 676 | "qc.draw(\"mpl\")" 677 | ] 678 | }, 679 | { 680 | "cell_type": "code", 681 | "execution_count": 26, 682 | "metadata": {}, 683 | "outputs": [ 684 | { 685 | "name": "stdout", 686 | "output_type": "stream", 687 | "text": [ 688 | "{'0': 2, '1': 13}\n" 689 | ] 690 | } 691 | ], 692 | "source": [ 693 | "job = sim.run(qc, shots=15)\n", 694 | "result = job.result()\n", 695 | "counts = result.get_counts()\n", 696 | "print(counts)" 697 | ] 698 | }, 699 | { 700 | "cell_type": "markdown", 701 | "metadata": {}, 702 | "source": [ 703 | "Hopefully, the correct bit was measured more often than not.\n", 704 | "\n", 705 | "### Exercise 4\n", 706 | "\n", 707 | "Examine the counts dictionary from the output of the last code cell. What is the correct value for the first bit? Was it measured more often than not? If not, rerun the last code cell until it is. Then, write some code in the code cell below that sets the variable `step1_bit` equal to the value of the bit that was measured the majority of the time." 708 | ] 709 | }, 710 | { 711 | "cell_type": "code", 712 | "execution_count": 28, 713 | "metadata": {}, 714 | "outputs": [ 715 | { 716 | "name": "stdout", 717 | "output_type": "stream", 718 | "text": [ 719 | "1\n" 720 | ] 721 | } 722 | ], 723 | "source": [ 724 | "step1_bit: int\n", 725 | "\n", 726 | "####### your code goes here #######\n", 727 | "if(counts['0']>counts['1']):\n", 728 | " step1_bit = 0\n", 729 | "else:\n", 730 | " step1_bit = 1\n", 731 | "\n", 732 | "print(step1_bit)" 733 | ] 734 | }, 735 | { 736 | "cell_type": "code", 737 | "execution_count": 29, 738 | "metadata": {}, 739 | "outputs": [ 740 | { 741 | "name": "stdout", 742 | "output_type": "stream", 743 | "text": [ 744 | "Submitting your answer. Please wait...\n", 745 | "Congratulations 🎉! Your answer is correct and has been submitted.\n" 746 | ] 747 | } 748 | ], 749 | "source": [ 750 | "# Submit your result\n", 751 | "\n", 752 | "from qc_grader.challenges.spring_2023 import grade_ex3d\n", 753 | "\n", 754 | "grade_ex3d(step1_bit)" 755 | ] 756 | }, 757 | { 758 | "cell_type": "markdown", 759 | "metadata": {}, 760 | "source": [ 761 | "### Exercise 5\n", 762 | "\n", 763 | "Now construct the circuit to measure the second bit of the phase. Replace the first stage of the circuit with one which simply sets the auxiliary bit to the value we measured above, so that we always measure the correct value for the first bit of the phase." 764 | ] 765 | }, 766 | { 767 | "cell_type": "code", 768 | "execution_count": 30, 769 | "metadata": {}, 770 | "outputs": [ 771 | { 772 | "data": { 773 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvQAAAEvCAYAAAAqzVVnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA2EUlEQVR4nO3dd3wUdf7H8fdm05uhhwABQm8JGIpAAEFBpQaUYqEcihWBE8F2HlxRxIaCnIKeJ3qKeICgiId6hCLSSygBQguQJoQWkhBCsvv7Iz9WYhJIwm42s3k9Hw8eMDPf+e5nAsy+97vfmTFZrVarAAAAABiSm7MLAAAAAFB2BHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBgBHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBgBHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBgBHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBgBHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABubu7AJQmNVqVZYlz9lllIqvm1kmk8lu/VmtVmVlZdmtv/Lg6+trt59BZT9+SbJapRwD/TfwNEt2PPybZrVKlivOrsJ43Dwq1t8jKi+jnQMl+58HeS8sOQJ9BZRlyVOV1T86u4xSOdert/zM9vvnlJWVJX9/f7v1Vx4yMjLk5+dnl74q+/FL+W9kzy2yW3cON3O45FWBzqiWK1LMbGdXYTw9J0hmT2dXARjvHCjZ/zzIe2HJMeUGAAAAMDACPQAAAGBgBHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBgBHqghNzc+O8CAEBlVlGzgLuzCwAcyWQyqWnTpoqMjFSjRo3k5eWl3NxcnTt3Tjt37tTOnTt18eLFG/bTu3dvvf322+rbt69OnjxZDpUDAAB7MJlMaty4sSIjI9W4cWN5e3srLy9P58+f186dO7Vjxw6lp6ffsJ+oqCjNmzdPAwYM0NGjR8uh8pIj0MMl3XbbbXryyScVHR2tgICA67bduXOn5s+fr3//+9/KyMgotL13795avny5fHx8FBMTo6ioKKWmpjqqdAAAYAeRkZF68sknde+99+qWW265btvdu3frww8/1KefflpkuI+KitL3338vf39/rVmzRl27dq1QA3wV83sDO0pLS9PUqVNtn8jq1auniRMnKjMzUw8//LBMJpPee+89Z5cJO4mKitL27du1ceNGjRw58oZhXpLatWun999/X0lJSfrb3/4mT09P27Zrw7wkxcbGKi0tzWH136yYmBjFxMSUef/HHntMeXl5Cg4OtmNVAJDPapGuXJJycySr1dnVwFV16NBBmzZt0rZt2zR27NgbhnlJCg8P15w5c5ScnKzXX3/d9r4vFQzzkrRnzx6dOnXKYfWXhUuP0O/atUv33HOPUlNT5efnp5YtWyo5OVmzZ8/WkSNHdPbsWUlS27ZtnVuoA+V9/IksX34l8zOT5HZ3nwLbrFar8qY8L+v+/XJ/b7ZMDRs4p0g78PHx0auvvqoJEyYUmN929uxZrVmzRtu3b9fevXuVkZEhs9ms0NBQRUZGqnPnzra//8DAQP3pT3/S4MGDNWbMGFWpUqVAmF+6dKmGDx+u3NxcZxziTTGZTJo4caIee+wxNWjQQKdPn9ZXX32lP//5z8rKyrK1++abb/SPf/xDAwYM0IcffujEiu0jMW6NlrzaU1H3v6HIfs8W2ebdh0xq0LafBj27opyrcy6LxaKvf35X322ap9RzCQryq6HuEcM0+q6/ysfTz9nlwYVYrdKFZClxl/TrwfxQL0le/lKd8PxfXv5OLdGlVabzoJeXl6ZPn64pU6bIbDbb1p8/f15r167Vtm3btGfPHl28eFFms1l169ZVZGSkOnXqpPbt20uS/Pz8NGXKFA0aNEhjx46VyWQqEOZXrlypIUOG6PLly045xuK4bKBPS0vTgAEDlJqaqsmTJ2vatGm20drXX39dzz33nNzd3WUymRQeHu7kah3HbeSDsmzarLx5H8oUeatMNarbtlmWLpN19x65jR1j6DBfs2ZNrVq1qsAHs507d+qdd97RV199pezs7CL3++c//ylJioiI0JNPPqkxY8bI09NTrVq10qZNm5SXl2cbrTdymJekWbNmaeLEiVq6dKneeusttWjRQhMmTFC7du105513yvr/Q2UpKSnatm2boqOjXSLQo3jvf/tHLft5trq2Hqz7ekzWiV/3a9nPs3UkaadmPvpThb3wC8aSd0Xa+510+nDhbZczpKO/SMc2Sc17S3XalH99cB1Vq1bVypUr1alTJ9u6PXv26N1339XChQsLDF5d61//+pckqVWrVnriiSf08MMPy9vbW02bNtW6deuUk5Mjb29vSRU3zEsuPOVmwoQJSkxM1Pjx4/Xmm28WmHoxdepURUREKDc3Vw0aNFBgYKATK3Usk4eH3KdMlrKzlff2O7b11pOJsnzyqUzNm8lt6L3OK/Am1ahRQ2vXrrWF+UuXLumZZ55R+/bt9emnnxYb5q8VGxurxx57TLfeequ2bdsmSTKbzS4T5lu2bKmnn35aS5Ys0b333quPPvpIkydP1jPPPKNevXppxIgRBdovW7ZMvXr1kp8fo7SuKiF1n5ZvmKOo1kM0ffRS9e00To8PfFuPD3hbu47EaE3sl84uES7AkifFfl10mL+W1SLtXyUl7S6fuuB6goKCtHr1aluYz8nJ0Ysvvqh27drpn//8Z7Fh/lr79u3T+PHjFRERoV9++UVS/h1tjBDmJRcN9Pv379eiRYtUvXp1zZgxo8g2kZGRkvJHZ6917NgxDRw4UAEBAapSpYpGjRqlM2fOOLxmRzI1aSy3EcNk3b5Dlu++lzUvT3mvvylZrTJPmSzTNV9LGYm7u7tWrFih5s2bS5JOnDihyMhIzZo1SxaLpdT97du3Ty+//HKB4G61WjV//nzDhnlJuv/+++Xm5qZ33nmnwPoPP/xQmZmZeuihhwqsX758uby9vXX33XeXY5UoTzG7FspqtWpIt0kF1vftNE7eHr76ace/nVMYXMqJbdLZEyVvf+BH6dIFx9UD1+Tm5qZly5bZ8lxKSoo6duyoGTNmKC8vr9T9xcfH64UXXlBOTk6B9f/85z8rbJiXXDTQL1y4UBaLRQ8++KBtztPvXZ0XfW2gv3jxonr27KnExEQtXLhQ8+fP1/r169W/f/8yBcSKxO3B+6WwMOV9+JEscz+Q9WC83MaMkqleXWeXVmbPP/+8OnbsKEk6efKkunfvrv3795e5v969e2vp0qVyd/9tJprJZNL8+fMN/S1Ohw4dlJeXpy1bthRYf/nyZe3atUsdOnQosD4uLk6HDh1SdHR0OVbpWLk5Wbp0Ma3IX5XRwZNb5WZyU7PQjgXWe3p4KyykreJPbnVSZXAVVkv+nPlS7WNllN6RXPU8OHHiRPXo0UOSlJqaqu7duys2NrbM/UVFRem7774rcIMMSZo7d66qVq16U7U6kkvOoV+9erUkqWfPnsW2SUxMlFQw0M+fP19JSUlat26dQkNDJUl169ZVly5d9M033xg64Jjc3eU+5RnlPj1JlhXfydS6ldyGRDu7rDJr06aNXn75ZUlSbm6uhgwZouPHj5e5v9/fzWbp0qUKCgpSr169FBoaqjfffFOPPvqoXWovbyEhIUpLSys02iBJSUlJ6tq1qzw8PHTlyhXb+uXLl2vs2LEym81lGuGoaDYtmaZNS6Y5u4wK40x6sgL9qsvT3avQtuq31FHc8V90JTdHHu6eRewN3NiZBCn7xo/4KCRptxTWVeISDvtzxfNgkyZN9Morr0jKv9B/6NChOnz4BnO8ruP3d7NZuXKlLBaL+vfvr+DgYM2ZM0cPPvigXWq3N5cM9FeDXf369Yvcnpubqw0bNkgqGOhXrFihqKgoW5iXpM6dOyssLEzffvttmQN9+/btS3XfcqunpzRvbple67r8/CQPDyk3V6YO7WWy4xmzaZOmMhURGMvqRt+ITJ8+3fbpeebMmba572VRVJgfPny46tSpoz179iggIEDjxo3Ta6+9dt0HSTRp0sRuFxLa8xshX1/fYr8mvHqNga+vry5c+O277uXLl+vZZ59V9+7dS3wbTHsevySZPXw0+O+H7NJX656PqkmnoUVu+/q13nZ5jaZNmijvyiW79GUPnu4+mj++6J/f5ZwseRQR5vP3y58vevlKVqUM9E2aNlFObsX5ezSqeyIf1/Bufyr1flcuSa2bt1V6lrFHje3BnudAyZjnwRu9F7788su29+7Zs2fr559/LvNrFRXmhwwZoipVqmjfvn2qWrWqHnjgAc2YMUN79+4ttp+beS8MDg4uc55xyUCfmZkpKf8CyaIsWrRIaWlpCggIUMOGDW3r4+LiNHRo4X/srVq1UlxcXJnrSU1NVVJSUsl38PaSR5lfrWhWq1V5b82Scq9IofVk+eJLufXoLlNIbbv0n5ySLGWXz9yyOnXqaNCgQfmvm5ysv/71r2Xuq7gwn5ubq+PHj+vVV1+1XYfx+OOPa+rUqcX2lZKSUuY6HCkrK0s1a9YsctvVi31+f8HQ1VF5cymur7D38bt7+dqtr6DgJgptfafd+itKckqyci/f+MKr8uLtUfzPz8vTV5cyir6Hck5u/oc8r+vs78pSkpOVfaXi/D0aVVbzG9+QoDhnTp/TqfOleM90UfY8B0qudx6sXr26hg0bJkk6c+aMXnrppTL3VVyYv3z5slJTUzV9+nTNnj1bkvTEE0/oqaeeKrYvZ2UBlwz0wcHBOnfunHbs2KHOnTsX2JaSkqIpU6ZIyn+IgMlksm07d+6cgoKCCvVXtWpVHTx48KbqKQ2rp6dOl/nVimZZ9o2ssbvl9ofRcut8m3Kfelp5b82S+c2ZBX4GZRVSO8TuI/TF/acYN26cLWjOnz+/yKkkJXG9MH/VRx99pOnTp8vLy0tjx47Vyy+/XOxod+3ate06Qm+vk0JycrJatmwpT0/PQj+rOnXq6PTp0wWm20hSdHS0zp8/rzVr1pT4dex5/FL+6JSRhNQOqXAj9MWpFhiiE7/GKSf3cqFpN2kXknSLX/VKOTovSbVDQhihtwM3j7LdSMBitcg/yEsefnXsXJHxGO0cKNn/PHi998I//OEP8vLKP399/PHHJbqTTVGuF+avWrBggV599VX5+/tr5MiReu6554p8srx0c++FN/NQR5cM9Hfeeaf279+vmTNnqnfv3mratKkkaevWrRo5cqTtSZ/l9UCp0n59kpmXqyqrf7Tb61uTkmT5+BOZmjWV27D7ZDKb5fbQg7L8a4Esy76RefCgm36N+EPx8jPb759TZmZmsRc033XXXbY/l/Ve6SUJ81L+8wyWLl2q+++/X9WqVVNkZKTtdla/d+jQIbvd6vF6x19aW7du1V133aWOHTsW+DrSy8tLbdu21bp16wrtM2jQIK1cubJUd/ex5/FL0uVc6blFduvO4eIPHZJXBTqj5uVIMbOL3tasXgdtj/9BB09sUZuwbrb1OVeydTR5l9qEdS+nKiueQ/GHZK6cn2Xs6nKG9PP83x4iVVI1wtx05Fi8Y4oyGKOdAyX7nwdLmgXmz59fpv5LEuYlKT09XV9++aUeeeQRBQQEqHPnzvrxx6Jzmr3fC0vKJS87mTp1qqpVq6aTJ0+qVatWatOmjZo0aaKOHTsqLCxMvXr1klT4lpVVqlTR+fPnC/V39uzZCn1l8/VYLRblvfG2ZLHIPOUZ2y0q3YbdJ1PTJrJ8/ImsyRVzqkhR3N3dbX9vhw4dUnJycqn7KGmYv2rt2rW2P1+93amRLFq0SBaLRZMmTSqwfty4cfLz89Pnn39eYH3z5s3VrFkzLV++vByrRHm6PWK4TCaTlq5/p8D6lZs/VPaVLPVqVzEv+oJxePlLNRqXfr+6be1eClzUrbfeKin/W+iyXAhb0jB/VUXPAi4Z6OvWrav169erX79+8vb2VkJCgqpWrap58+bpu+++U3x8/qf/3wf6Fi1aFDlXPi4uTi1atCiX2u3NsniprHH75Tb6IZmuudjXZDbL/OwzkiVPeW/Nsj0ptKJr0aKFLYhv37691PuXNsz//nUq4n/iG9m7d6/mzp2re++9V0uWLNHDDz+sN998U2+//bbWrFmjL774okD7QYMG6fLly/r++++dVDEcrWHtNhrY5Sn9vHeppi8YopWbP9IH307WB98+o/CwHurV7gFnlwgX0LCz5FaK0dqgulL1hjduBzRs2FBVqlSRVLYsUNow//vXad++falf09Eq0BfE9tWiRQutWLGi0PqMjAwlJCTIzc1NrVu3LrCtf//+evHFF5WYmKi6dfPvz75582YdOXJEb7zxRrnUbU/WEydkWfCZTC2ay+3eIYW2mxrUt/vUG0cLCQmx/fnqB7OSKkuYl1Tg+onate1zEXF5mzRpkhISEvToo4+qX79+SktL05w5c/TnP/+50Ie5QYMGKSYmRhcvluGeczCMJwa+o1pVGmjl5vnasv87BfpVV3TXpzX6rr/a9VoIVF4BNaSIQVLscslyg9l7AbXy25r4p4cSuJksUJYw//vXqYhZwGQ1ytCsnWzevFm33XabmjVrpgMHDhTYlp6erjZt2qh69er6y1/+ouzsbE2dOlU1atTQxo0by+1Nzt5z6MvDuV69y2UOfePGjTVixAh5e3tr9erVtmcO3EhgYKASEhJsn+hLGual/Du9vPLKK8rOztahQ4cKTVG5KiMjw+lz6K/eYvJ6z2C4nlq1aik5OVlPPfWUPvjgg1Lta8/jl4w3f3TmcBlmDj2K13OCmENvZ+m/Ssc2SqePSPpd4vDwlkLa5I/mV9LrsItltHOgZP/zYHHvhaGhoRo5cqR8fHz0888/67///W+J+vPx8dGxY8dUq1YtSSUP81fNmDFDly9fVkJCgj755JMi29j7vbCkKtDbT/nYs2ePpMLTbaT80Ld69WpNnDhRI0aMkLu7u/r3769Zs2YxYlVBHD58WH//+99LvV96erruv/9+LVu2TCtXrixxmJfyb+H4/PPPl/o1jWjgwIGSxPx5AHYTWEuKiJay06Vf46VDa37bFvWYZLb3fZrh8k6cOGF7oFRpXLp0ScOHD9d3332ntWvXlirMS9ILL7xQ6tcsLwT632nUqFGRU3VgfKtWrVJUVJRiY2NLdfeWyuTjjz/WggULynwrUAAojnegVL+9dGit8kfqTYR5lL+1a9eqW7duiouLK1WYr+gI9KhUynLxTGWSl5dne6gUAACuaOfOnc4uwe4qXaAv6ZxrwIjKOnceAAAYFxPDAQAAAAMj0AMAAAAGRqAHAAAADIxADwAAABgYgR4AAAAwMAI9AAAAYGAEegAAAMDACPQAAACAgRHoAQAAAAMj0AMAAAAGRqAHAAAADMzd2QWgMF83s8716u3sMkrF181s3/58fZWRkWG3/t6Y96XSM7MU6OerKY+NKLRsD76+vnbp52pf9jz+8mDP45ckT7M0c7hdu3QoT/v+FwBQyRntHCjZ/zxY2bNAaRDoKyCTySQ/c+X+qzGZTPLz87Nbf55e3vK8kidPL2/5+fkVWq5o7H38RmQySV6V+78BgEqMcyBZoDSYcgMAAAAYGIEeAABUOA0aNFCzZs3Utm1btWzZUnPnzi227dChQ7Vx48YS9bt48WI98cQTkqQ+ffooPDxcbdu2Vbdu3bRz505bu27duunYsWM3dxBAOankX+YAAICKatGiRWrbtq2OHz+u8PBwdevWTeHh4QXabNmyRWfPnlXnzp1L1OfXX3+tUaNGSZK++uorBQUF2daPGTNGsbGxkqTJkydr2rRp+vTTT+13QICDMEIPAAAqtPr166tZs2aKj48vtG3evHl64IEHJEnnz59X3bp1Va1aNbVt21YtWrSQl5eXHnnkEUnSlStXtGHDBvXq1UuSbGFeki5cuCCTyWRb7tevn77//ntduHDBgUcG2AeBHgAAVGh79uzRgQMHFBERUWjbmjVr1KlTJ0n5Af2BBx7QpEmTtGvXLr3zzju67bbb9NFHH0mSYmJi1KVLF3l4eNj2HzVqlOrVq6eXX35Zn332mW29h4eH2rRpo/Xr1zv46ICbx5QbAABQIQ0fPlw+Pj7y9fXVxx9/rCZNmhRqk5iYqFq1atmWd+3apQkTJkiStm/frnbt2tm2LVu2TIMHDy6w/9UpNQsWLNBzzz2nlStX2rYFBwcrMTHRrscEOAKBHgAAVEhX59Bfj6+vr7Kzs23Lu3btsoX47du3a+DAgZIkq9WqVatW6fXXXy+yn9GjR+vxxx/XmTNnVK1aNUlSdna2fHx87HAkgGMx5QYAABhWeHi4Dh48KElKSkqSyWRSnTp1JEm7d+9WmzZtJOVfPNuiRQv5+/tLyp9vn5ycbOtn2bJlqlatmqpWrWpbt3///iKn+QAVDYEeAAAY1n333adVq1ZJknbu3Flgik1QUJD+8Y9/SMq/i010dLRt24ULFxQdHa02bdooIiJC7733nlasWGG7MDYhIUF5eXkEehgCU24AAECFk5CQUKJ2f/jDH9SlSxdNnz5d/fv3V//+/W3btm7davvzt99+q5iYGNty/fr1tWXLlmL7/eCDDzR16tQCd74BKipG6AEAgGH5+/tr1qxZN3wI1L59+1SzZs0S9xsSEqKxY8febHlAuWCEHgAAGNodd9xh9z6v3ikHMAJG6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBg3LayArJaJcsVZ1dROm4eEs/eAAAAKH8E+grIckWKme3sKkqn5wTJ7OnsKgAAACofptwAAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBgBHoAAADAwAj0LmTy+7dr8vu3l3n/bzd+oD5T3XQmPcV+RQEAAMChCPSw6dxyoCRpU9y3Tq4EAAAAJUWgh031W0LUtG57bdi3zNmlAAAAoIQI9CigS6to7Tq8WpcuZzi7FAAAAJQAgb4SePLd9hr7Rgvb8l8/vU9D/lzVtjzn6/HqPcWkjEvn1aXVIF3JvaytB//rjFIBAABQSgR6F5eXl6vjqfvUKKStbd3hpJ0KC4mwLR9J3qXgKg3k7xOkBsGtFFK9sX7Zu6z8iwUAAECpVYpAn5aWpqlTp6px48by9vZWvXr1NHHiRGVmZurhhx+WyWTSe++95+wyHeLk6YPKyc22BfrM7HSlnjtmW7ZarTqWsluN6rSz7dOl5SBtObBSeXm5TqgYgBFk52Rp7rIJeuCVUN011ayHXm3gkNf59Ifp6j3FpNSzCQ7pHwBcgbuzC3C0Xbt26Z577lFqaqr8/PzUsmVLJScna/bs2Tpy5IjOnj0rSWrbtq1zC3WQI8m7JMkW4I8mx8pqtdqWU84cVdbliwVG8Lu0GqTF697S7mPr1K5xr/ItGECFE3tkjZ79oKce7feGht7+rCRpUcxMLdswR0N7PKuGtcPl6xXg5CpRkVmt0tkT0q8HJFmvrpQunZd8gpxXF+AqXDrQp6WlacCAAUpNTdXkyZM1bdo0BQTkv+m8/vrreu655+Tu7i6TyaTw8HAnV+sYR5NjJUmN/z+wXw34jUPaFVi+NtC7uZklSRZLXrnUCMB4dhz6UQ2D2+jR/m84uxRUcKcOSYfXSVnnCm/b8JFUPUxq3lvy5jMhUGYuPeVmwoQJSkxM1Pjx4/Xmm2/awrwkTZ06VREREcrNzVWDBg0UGBjoxEod50hKrKoGBKtKQK385eRd8nD3UmitFrbtktT4mik3v+xdJj/vWxTR6PZyrxeAMZy9mKoA36o3bohKLTFW2r286DB/VdpRaevn128D4PpcdoR+//79WrRokapXr64ZM2YU2SYyMlKxsbGKiPjtAtHExES99tpr2rJli2JjY5WTkyOr1Vrk/kaQdDpe1QJDbMtHknepfq2Wcjd7SJK2HvheNYLqqWZQPVubX+KWq2PzvrY2AHDVqq2f6M2v/iBJSj17TL2nmCRJI3tP06g+00vcT+LpQ/r3T3/VzkM/KT3rjKoFhqh7+FCN7DNdPp5+1903PeusPv/pb9q47xulpSfJ29NPwVUa6Pa2IzTs9ikF2q7ZtUjLNszR0ZRYWSx5ahjcRkNvn6Lu4feV7sBRamePSwd+KlnbyxnSrqVSp9GS2WWTCeA4LjtCv3DhQlksFj344IPy9/cvso2Pj48kFQj0hw8f1pIlSxQcHKwOHTqUS62OlGfJVXrWGVmtVuXl5Srh19/ueLPt4A+KT9ymO9o9aGt//Nf9Sjwdry6tBjmpYgAVWXhYdz034jPd4ldd9Wo213MjPtNzIz5TVOshJe4jPnG7nprdXnuOrlO/2x7T04PnqlOL/lr282w9P7+3cvOuXHf/v302VMs3vKeOLfpqfPQcjew9Tc3qdVTskTUF2v3rv3/SK5+PkK9XgMbc9Tc93Pc1eXn6/v/+c8ty+CiFhC36bb58CWSdk04ddFg5gEtz2c/Bq1evliT17Nmz2DaJiYmSCgb67t27KyUlRZI0ffp0bdiwwYFVOl5Eo576acdnenfJ42rX5E5dyb0sf+8gLV77tj776S+qW6OpRvR6wdZ+477l8jB7qkPze5xYNYCKqna1MNWuFqZPVv1JVfxr6c7Ih0rdx1tfjVW1gNp6b8JW+V4zcbpd4zv0l0+H6H87PtddHcYUuW/mpQvadXi1BnR+QuOj5xT7GocSd+iL/72iEb1e0MP3vGpbPzhqgqZ9Eq2Pv39BvSNHFXh92E/m2fwR+tJK3CXVbmX3cgCX57Ij9MeP559J6tevX+T23NxcW1i/NtC7ubnWj+TxgW8rsmkffbd5vv7+72GSpCXrZ+lf/31JvSNH6d2nfpGf92/XD/yyb7kiGvUssA4A7OVYyh4dTdmtnu0e0JW8y7qQmWb71bphlLw9/bQ9/odi9/f08JGHu5cOnNh83VtZ/m/n5zKZTOoTObrAa1zITFPnlgOVdfmi4o5vdMARQpLOJJRtvwsp0pVsu5YCVAouO0KfmZkpSbp06VKR2xctWqS0tDQFBASoYcOGDq2lffv2Sk1NLXF7T3cfzR9/yC6vfYtfdb02bpWS045oztdPafuhH/TaIz+odcMoeXp4F2h7Nj1VB05u1tPRpf8quknTJsrJLfpnXREM/sMk+fkHKiU1RXXr1i20DLgae55H7OnEqf2SpE9/mKZPf5hWZJtzGb8Wu7+Hu6eeGPiO3l8+USNnNFT9Wi3VtnEvdWkVrVub3FHgdaxWq8a+0bzYvop6nYp+LjOKgR0nakiXKTduWIQOt96mtPREO1cEVPwsEBwcrG3btpVpX5cN9MHBwTp37px27Nihzp07F9iWkpKiKVPyTzTh4eEymUwOrSU1NVVJSUklbu/t4Wv3GkKqN1JuXo5qVw3TrU3vLLLNxrhvJEmdyzB/PiU5WdlXsm6qRkey5OXZfk9KSiq0DLgaR5xH7OHqTQbu6z5ZHZrdXWQbf98q1+1jQOfH1aXVIG3e/512H12r9bsXa/mG93R7xHC99NCXV19IJpNJrzz8vcwmc5H91A8uPLejop/LjOLUmZQy73vs+GGlZ52xYzVAPlfOAi4b6O+8807t379fM2fOVO/evdW0aVNJ0tatWzVy5EilpaVJKp8HSgUHB5eqvae7j0PqOJISq7aNir+m4O4OY9W7/Wh5unuVuu/aISEVelTLzWy2/V6nTp1Cy4CrcdR55GbVqd5EUv7zLoobXCiJaoG11bfTI+rb6RHlWfI0c+FIxexaqPt6TFazeh1Up3oTbT34X9UMClX9/79Nb0lU9HOZUZy5dExS/ge40gyanTqfoMAqPgqownkZ9lfRs0Bp8+K1XDbQT506VV988YVOnjypVq1aqXnz5srOztbhw4d1zz33qEGDBlq1alWB+fOOUtqvT/JypJjZ9q3h9PlEXcw6W+ABUr9nNrvLXMZ/EofiD8nsWcbiysGrcz9XekamagfXVmJiYqFlwNU44jxiD43rtFOD4NZasekD9b/tMdWuFlZge15erjIvpyuwmHvcZ+fkj557e/72DYTZzayw2uGK2bVQ6Vn5T/++M3Kklm2Yo399/6JeHrVYZreCo/TnLv5qez7HtSr6ucworFZp0wIpM61034B3GdhAJ/9+0kFVobJz5SzgsoG+bt26Wr9+vaZMmaK1a9cqISFBLVu21Lx58zRu3Dg1atRIksol0JeXt55YU+y2GkF19eMbxr2fPgDXYDKZ9NyIzzR1Xi89+na47u4wVvVrtdLlK1lKSjusDXuXauw9M4q9y03i6XhN/qCHurYarIbBreXvW0Unft2vFRvfV3DVhmrTsJskqVm9DhrVe7o+/XG6Hp/VVt3Dh6paYIjOpqfoUNJ2bTmwUt+/llOOR165mExSaKS0f1XJ9zF7SiGtHVcT4MpcNtBLUosWLbRixYpC6zMyMpSQkCA3Nze1bs3ZAwDKU+M6bfX+H3dq4eoZ2hj3jVZs+kA+XgEKrtJAfdqPUbtrLm79vZpB9XR3h7HadThGv+xbpiu5l1X9ljq6p9M4De/5XIGR+5F9pqlpvfb6+ufZ+nr9O8rOyVSQf001CG6tJwdVwK8vXExIa+lCspS858ZtTW5S+EDJs2Je+gFUeC4d6Iuzb98+Wa1WNW3aVL6+hc8eixcvliTFxcUVWG7QoIHat29ffoUCQAUQ0ej2Qt/w/fvFhJvqs1aV+pp07wc3bDeqz/QCT6AN9KumJwbOKvHrdGrRT51a9CtLibhJJpPUoo/k6SMd3yZZLUW38/STWveTqoaWb32AK6mUgX7PnvzhguKm2wwdOrTI5dGjR+uTTz5xaG0AALgKk0lq3F2qFykl7ZZ+PShdyZJMZsmvilQnQqrRWHIr+kZEAEqIQF+Eq7dVM4LeU0xqENxaj/SdqU4t+irx9CG9sSj/QSp+3rdoyvBP1KCIW7Nda+6yCdoY941+PXdc70/aqcZ12tq2PftBTx1NjtVDvf+sId0mOfZgABhW5qULunzl+neHcXf3LPZiV7g2Lz8prHP+LwD2R6B3AbOeXC9/nyBJ0rtLHlPfTo/qrg5jtG73Yr2xaIzmTtx63f27hd+nYbdP1R//EVVo25uPx+j1L8c4oGoArmTu8on6cfuC67YJD+tx3Yv3AQBlUykD/erVq51dgkOcyzil+MRtem1c/mPTu7W5V+99PV5JaYdVp3rjYvcLD+teXiUCcFHDe07Vnbc+dN02N3pgFACgbCploHdVp8+fVNXA2jKb8/9aTSaTalYJ1anzJ64b6AHgZtWv1VL1a7V0dhkAUCm5ObsAAAAAAGVHoHchNYLq6Wx6ivLyciXlX9x76twJ1QziXmAAAACuikDvQqr411TjOrfqpx3/liSt37NE1YPq2qbbzFw4Sj/v+dqZJQIAAMDOmEPvYibdO09vLBqjhatfla93oKYM+5dtW3ziNkVHTSi0zzuLH9PmA9/p7MVUvfDRXfL1CtCC5w+XZ9kAAAAoIwK9i6lXs5lmP72x0PrzGadV/ZY6alav8JNuJ903rzxKAwAAgAMw5cbgqvjX0uT3e2jz/pXXbRfkX0MzH/2x1P0/+0FP7Tm6Vt6efmUtEQAAAA7ECL3BfTUt1aH9v/l4jEP7BwAAwM1hhB4AAAAwMAI9AAAAYGAEegAAAMDACPQAAACAgXFRbAXk5iH1LHy7+ArNzcPZFQAAAFROBPoKyGSSzJ7OrgIAAABGwJQbAAAAwMAI9AAAAICBEegBAAAAAyPQAwAAAAZGoAcAAAAMjEAPAAAAGBiBHgAAADAwAj0AAABgYAR6AAAAwMAI9AAAAICBEegBAAAAAyPQAwAAAAZGoAcAAAAMjEAPAAAAGBiBHgAAADAwAj0AAABgYAR6AAAAwMAI9AAAAICBEegBAAAAAyPQAwAAAAZGoAcAAAAMjEAPAAAAGBiBHgAAADAwAj0AAABgYAR6AAAAwMDcnV0AYE/xR09q256DhdZfys62/f7F8p8KLV8V4Oerfnd0lpvJVD4FAwAA3CQCPVxKWGiIVq7ZrNTTZ4vcfiU3T7sPHC12ecx9dxPmAQCAoTDlBi7F3d2s4f17ymwu/T/tjhHN1bxRqAOqAgAAcBwCPVxO7ZrV1Kdbh1LtUy0oUP16dXZQRQAAAI5DoIdL6tahjRrUDS5RW5PJpGH9bpeXp4eDqwIAALA/Aj1ckpubm4b171mikH77bRGqX8LwDwAAUNEQ6OGyqt4SoAF3dLlum5Ba1XRH18hyqggAAMD+uMsNXFpkm6aKO3xccYcSCm1zN5s1vH8vuZvN5V8Y4GQWi0Vf//yuvts0T6nnEhTkV0PdI4Zp9F1/lY+nn7PLAwCUQqUZobdYLFq8eLGio6MVEhIiLy8vhYSEqFevXnr33XeVk5Pj7BLhACaTSUPu7iZ/X59C2+7u0VG1qldxQlWA873/7R/1wbfPKLRWS42PnqPu4UO17OfZ+vPHA2SxWJxdHgCgFCrFCP2pU6c0bNgwrV27VpIUGhqqtm3bKjU1VTExMdq0aZPGjx/v5CrhKP6+PhpyT3d9umSVbV2j+iHq0r61E6sCnCchdZ+Wb5ijqNZDNG30Etv64KoNNXf5BK2J/VK92j3gxAoBAKXh8iP0mZmZ6tu3r9auXasePXooNjZWx48f1+bNm3X8+HHt3btXzz//vMxMu3BpLRvXV4fw5pIkby9PDe17Ow+QQqUVs2uhrFarhnSbVGB9307j5O3hq592/Ns5hQEAysTlR+gnT56s7du3KyoqSj/88IM8PT0LbG/VqpVatWrlpOpQnvr3uk1HTiSpd1R7BQX6O7scwGkOntwqN5ObmoV2LLDe08NbYSFtFX9yq5MqAwCUhclqtVqdXYSjHDhwQK1bt5a7u7vi4+MVGnrjp4AeO3ZMEydOVExMjNzd3TVgwADNmjVL1apVK3MdcxYs1cWMS2XeH/ZjsVrkZnL5L6YAuVnNap89osht495qo/MZp/Sfab8W2va3z4Zp3e7/aOWMy/Jw9yxib9e2zftLWUx5zi4DgANczMyS1WqVyWRSgJ9voWVnC/D30dOjh5RpX5ceof/iiy+Ul5enUaNGlSjMX7x4UT179lTVqlW1cOFCXbp0SVOnTlX//v21YcMGubmVLQhezLik9IzMMu0LAGXhJnepmJmEl3Oy5OHuVeQ2T3fv/DZXsiploE/PzJJFuc4uA4ADWa3WArns98tG5NKB/qeffpIk9e3bt0Tt58+fr6SkJK1bt872AaBu3brq0qWLvvnmG0VHR5epjgD/wndYAQBHcrOapeyit3l5+upSxqkit+Xk5u/k5eH80SpnCPTzZYQecFFGGKEvK5cO9CdPnpQkhYWFlaj9ihUrFBUVVWA0v3PnzgoLC9O3335b5kBf1q9PAKCs8nKkmNlFb6sWGKITv8YpJ/eyPH83Up92IUm3+FWvlKPzkjTl0REyV85DB1zeq3M/V3pGpgL8fPXiUw8WWjYylw70mZn5X59culSy+etxcXEaOnRoofWtWrVSXFxcmetgDj2A8uZmNau9ip5D36xeB22P/0EHT2xRm7ButvU5V7J1NHmX2oR1L68yK5w35jOHHnBVFzOzbL+/OvfzQsvOxhz6YtSrV0/nzp3TL7/8oq5du96w/blz5xQUFFRofdWqVXXw4MEy18EcegDl7Xpz6G+PGK6Fq1/V0vXvFAj0Kzd/qOwrWerVztgjVTeDOfSA62MOvcEMHjxYu3fv1iuvvKKIiAj16dPHti0pKUkLFizQ0KFD1aRJE4fWwRx6AOXtenPoG9Zuo4FdntLyDe9p+oIh6ti8r06c2q9lP89WeFiPSv1QKebQA67LlefQu/RtKzMyMtSjRw/t2LFDkhQcHKx69erp7NmzOnr0qEwmk9LT0+Xn5ydJqlWrloYOHar33nuvQD8DBw7U6dOntXHjxnI/BgAoi+vNoZekPEuelq5/Rys3z9evZxMU6Fddt0cM1+i7/iofr8r7nIaeE8QcesBFXZ0zH+jvV2AO/dVlI3PpEXp/f3+tX79es2bN0n/+8x/Fx8frwoULCg4OVnR0tIYMGWIL85LUokWLIufKx8XFqXv3yjunFIDrMbuZNbTHZA3tMdnZpQAAbpJLB3pJ8vX11UsvvaSXXnrphm379++vF198UYmJiapbt64kafPmzTpy5IjeeOMNR5cKAAAAlBqPzLzGo48+qtq1a2vQoEFasWKFFi9erPvvv18dO3bUoEGDnF0eAAAAUAiB/hqBgYFavXq1ateurREjRuiRRx5Rly5dtGLFijI/JRYAAABwJJefclNajRo10ooVK5xdBgAAAFAiDDsDAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBgBHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDB3ZxcAALA/Nw+p5wRnV2E8bh7OrgAASo9ADwAuyGSSzJ7OrgIAUB6YcgMAAAAYGIEeAAAAMDACPQAAAGBgBHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBgBHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYGIEeAAAAMDACPQAAAGBgBHoAAADAwAj0AAAAgIER6AEAAAADI9ADAAAABkagBwAAAAyMQA8AAAAYmLuzCwAAAADsJe3cBZ09f7HQ+ty8PNvv8ccSCy1fq1H9EJndjDPubbJarVZnFwEAAADYw7kLF/XOx4t1OedKmfbvGNFcQ+7ubueqHMs4Hz0AAACAG6hyS4AG3tm1TPtWDQpQv16d7VyR4xHoAQAA4FJubd1ErZo2KNU+JpNJw/r1lJenh2OKciACPQAAAFyKyWTS4Lu6yd/Pp8T79OgUoQZ1gx1YleMQ6AEAAOBy/H19dN89PUrUtnbNarozKtLBFTkOgR4AAAAuqXmjUHWMaH7dNu5ms0b07yl3s7mcqrI/Aj0AAABcVr9enVUtKLDY7Xf16KBaNaqWY0X2V6kCvcVi0eLFixUdHa2QkBB5eXkpJCREvXr10rvvvqucnBxnlwgAAAA78vL00LB+t8tkMhXaFhYaoq7t2zihKvuqNPehP3XqlIYNG6a1a9dKkkJDQxUcHKzU1FSdOHFCPj4+unjxoswG/roFAAAARVu1botiNu6yLXt5euiPDw9VUKC/84qyk0rxpNjMzEz17dtX27dvV48ePTR79myFh4fbtu/bt09LliwhzAMAALioO7pG6uDRk0r+9YwkaVDvri4R5qVKMkL/+OOPa968eYqKitL//vc/eXp6OrskAAAAlLNf085pzidL1aJxqB4YdGeR03CMyOUD/YEDB9S6dWu5u7srPj5eoaGh122fmJio1157TVu2bFFsbKxycnJ0sz+iOQuW6mLGpZvqAwAAADfvSu4VuZvdK1yYD/D30dOjh5RpX5efcvPFF18oLy9Po0aNumGYl6TDhw9ryZIl6tChgzw9PbVhw4abruFixiWlZ2TedD8AAACwB9e6EYrLB/qffvpJktS3b98Ste/evbtSUlIkSdOnT7dLoA/wL/lTygAAAFD53ExedPlAf/LkSUlSWFhYidq7udn/Tp5l/foEAAAAuBGXD/SZmflTXS5dct4cdubQAwAA4HqYQ38d9erV07lz5/TLL7+oa9euTqmBOfQAAABwFJcP9IMHD9bu3bv1yiuvKCIiQn369LFtS0pK0oIFCzR06FA1adLEYTUwhx4AAADXczN50eVvW5mRkaEePXpox44dkqTg4GDVq1dPZ8+e1dGjR2UymZSeni4/P79C+06fPl1/+ctfbvq2lQAAAICj2P8K0ArG399f69ev19///ndFRETowoUL2rt3rywWi6Kjo7VgwYIiwzwAAABgBC4/5UaSfH199dJLL+mll15ydikAAACAXVWKQF9aixcvliTFxcUVWG7QoIHat2/vtLoAAACA33P5OfRlUdyjgEePHq1PPvmkfIsBAAAAroMR+iLwGQcAAABG4fIXxQIAAACujEAPAAAAGBiBHgAAADAwAj0AAABgYAR6AAAAwMAI9AAAAICBEegBAAAAAyPQAwAAAAZGoAcAAAAMjEAPAAAAGBiBHgAAADAwAj0AAABgYAR6AAAAwMAI9AAAAICBEegBAAAAAyPQAwAAAAZGoAcAAAAMjEAPAAAAGBiBHgAAADAwAj0AAABgYAR6AAAAwMAI9AAAAICBEegBAAAAAyPQAwAAAAZGoAcAAAAMjEAPAAAAGBiBHgAAADAwAj0AAABgYAR6AAAAwMAI9AAAAICBEegBAAAAAyPQAwAAAAZGoAcAAAAMjEAPAAAAGBiBHgAAADAwAj0AAABgYAR6AAAAwMAI9AAAAICBEegBAAAAA/s/wQUzrHghXqcAAAAASUVORK5CYII=\n", 774 | "text/plain": [ 775 | "
" 776 | ] 777 | }, 778 | "execution_count": 30, 779 | "metadata": {}, 780 | "output_type": "execute_result" 781 | } 782 | ], 783 | "source": [ 784 | "from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister\n", 785 | "import numpy as np\n", 786 | "\n", 787 | "\n", 788 | "def u_circuit(qr: QuantumRegister, cr: ClassicalRegister) -> QuantumCircuit:\n", 789 | " # qr is a quantum register with 2 qubits\n", 790 | " # cr is a classical register with 2 bits\n", 791 | "\n", 792 | " qc = QuantumCircuit(qr, cr)\n", 793 | "\n", 794 | " ####### your code goes here #######\n", 795 | " # Initialization\n", 796 | " # Apply control-U operator as many times as needed to get the least significant phase bit\n", 797 | " u_angle = np.pi / 3\n", 798 | " #k = 1\n", 799 | " #cphase_angle = u_angle * 2**k\n", 800 | " #qc.cp(cphase_angle, qr[0], qr[1])\n", 801 | " \n", 802 | " if (step1_bit == 1):\n", 803 | " qc.x(qr[0])\n", 804 | " qc.initialize([0,1],qr[1])\n", 805 | " #qc.h(qr[0])\n", 806 | " \n", 807 | " qc.measure(qr[0], cr[0])\n", 808 | "\n", 809 | " # Reset and re-initialize the auxiliary qubit\n", 810 | " qc.reset(qr[0])\n", 811 | " qc.h(qr[0])\n", 812 | "\n", 813 | " # Apply phase correction conditioned on the first classical bit\n", 814 | " with qc.if_test((cr[0], 1)):\n", 815 | " qc.p(-np.pi / 2, qr[0])\n", 816 | "\n", 817 | " # Apply control-U operator as many times as needed to get the next phase bit\n", 818 | " k = 0\n", 819 | " cphase_angle = u_angle * 2**k\n", 820 | " qc.cp(cphase_angle, qr[0], qr[1])\n", 821 | "\n", 822 | " # Measure the auxiliary qubit in x-basis into the second classical bit\n", 823 | " qc.h(qr[0])\n", 824 | " qc.measure(qr[0], cr[1])\n", 825 | "\n", 826 | " return qc\n", 827 | "\n", 828 | "\n", 829 | "qr = QuantumRegister(2, \"q\")\n", 830 | "cr = ClassicalRegister(2, \"c\")\n", 831 | "qc = QuantumCircuit(qr, cr)\n", 832 | "qc = u_circuit(qr, cr)\n", 833 | "qc.draw(\"mpl\")" 834 | ] 835 | }, 836 | { 837 | "cell_type": "code", 838 | "execution_count": 31, 839 | "metadata": {}, 840 | "outputs": [ 841 | { 842 | "name": "stdout", 843 | "output_type": "stream", 844 | "text": [ 845 | "Submitting your answer. Please wait...\n", 846 | "Congratulations 🎉! Your answer is correct and has been submitted.\n" 847 | ] 848 | } 849 | ], 850 | "source": [ 851 | "# Submit your result\n", 852 | "\n", 853 | "from qc_grader.challenges.spring_2023 import grade_ex3e\n", 854 | "\n", 855 | "grade_ex3e(qc)" 856 | ] 857 | }, 858 | { 859 | "cell_type": "code", 860 | "execution_count": 32, 861 | "metadata": {}, 862 | "outputs": [ 863 | { 864 | "name": "stdout", 865 | "output_type": "stream", 866 | "text": [ 867 | "{'11': 66, '01': 934}\n", 868 | "Success probability: 0.934\n" 869 | ] 870 | } 871 | ], 872 | "source": [ 873 | "from qiskit_aer import AerSimulator\n", 874 | "\n", 875 | "sim = AerSimulator()\n", 876 | "job = sim.run(qc, shots=1000)\n", 877 | "result = job.result()\n", 878 | "counts = result.get_counts()\n", 879 | "print(counts)\n", 880 | "success_probability = counts[\"01\"] / counts.shots()\n", 881 | "print(f\"Success probability: {success_probability}\")" 882 | ] 883 | }, 884 | { 885 | "cell_type": "markdown", 886 | "metadata": {}, 887 | "source": [ 888 | "Now, the success probability is much higher than before!" 889 | ] 890 | }, 891 | { 892 | "cell_type": "markdown", 893 | "metadata": {}, 894 | "source": [ 895 | "## Run on hardware\n", 896 | "\n", 897 | "In the final part of this lab, we will run some circuits on real hardware! The code cells below initialize and run the circuit you created in Exercise 2 to measure the phase of the $S$ gate. Because current quantum hardware suffers from noise, the results will not be as good as what you got on the simulator. Feel free to try running the other circuits you created in this lab, though be aware that larger circuits, like the one from Exercise 3 for measuring the phase of the $T$ gate, will suffer from even more noise." 898 | ] 899 | }, 900 | { 901 | "cell_type": "code", 902 | "execution_count": null, 903 | "metadata": {}, 904 | "outputs": [], 905 | "source": [ 906 | "from qiskit_ibm_provider import IBMProvider\n", 907 | "\n", 908 | "provider = IBMProvider()" 909 | ] 910 | }, 911 | { 912 | "cell_type": "code", 913 | "execution_count": null, 914 | "metadata": {}, 915 | "outputs": [], 916 | "source": [ 917 | "hub = \"YOUR_HUB\"\n", 918 | "group = \"YOUR_GROUP\"\n", 919 | "project = \"YOUR_PROJECT\"\n", 920 | "\n", 921 | "backend_name = \"ibm_peekskill\"\n", 922 | "backend = provider.get_backend(backend_name, instance=f\"{hub}/{group}/{project}\")" 923 | ] 924 | }, 925 | { 926 | "cell_type": "code", 927 | "execution_count": null, 928 | "metadata": {}, 929 | "outputs": [], 930 | "source": [ 931 | "from qiskit import transpile\n", 932 | "\n", 933 | "qr = QuantumRegister(2, \"q\")\n", 934 | "cr = ClassicalRegister(2, \"c\")\n", 935 | "qc = QuantumCircuit(qr, cr)\n", 936 | "qc = step_2_circuit(qr, cr)\n", 937 | "qc_transpiled = transpile(qc, backend)" 938 | ] 939 | }, 940 | { 941 | "cell_type": "code", 942 | "execution_count": null, 943 | "metadata": {}, 944 | "outputs": [], 945 | "source": [ 946 | "job = backend.run(qc_transpiled, shots=1000, dynamic=True)\n", 947 | "job_id = job.job_id()\n", 948 | "print(job_id)" 949 | ] 950 | }, 951 | { 952 | "cell_type": "code", 953 | "execution_count": null, 954 | "metadata": {}, 955 | "outputs": [], 956 | "source": [ 957 | "retrieve_job = provider.retrieve_job(job_id)\n", 958 | "retrieve_job.status()" 959 | ] 960 | }, 961 | { 962 | "cell_type": "code", 963 | "execution_count": null, 964 | "metadata": {}, 965 | "outputs": [], 966 | "source": [ 967 | "from qiskit.tools.visualization import plot_histogram\n", 968 | "\n", 969 | "counts = retrieve_job.result().get_counts()\n", 970 | "plot_histogram(counts)" 971 | ] 972 | }, 973 | { 974 | "cell_type": "markdown", 975 | "metadata": {}, 976 | "source": [ 977 | "This lab was adapted from the [Qiskit Textbook lab](https://learn.qiskit.org/course/ch-labs/lab-6-iterative-phase-estimation-algorithm) on iterative phase estimation as well as material from the [dynamic circuits documentation](https://quantum-computing.ibm.com/services/resources/docs/resources/manage/systems/dynamic-circuits/Getting-started-with-Dynamic-Circuits)." 978 | ] 979 | } 980 | ], 981 | "metadata": { 982 | "kernelspec": { 983 | "display_name": "Python 3 (ipykernel)", 984 | "language": "python", 985 | "name": "python3" 986 | }, 987 | "language_info": { 988 | "codemirror_mode": { 989 | "name": "ipython", 990 | "version": 3 991 | }, 992 | "file_extension": ".py", 993 | "mimetype": "text/x-python", 994 | "name": "python", 995 | "nbconvert_exporter": "python", 996 | "pygments_lexer": "ipython3", 997 | "version": "3.10.8" 998 | }, 999 | "vscode": { 1000 | "interpreter": { 1001 | "hash": "c2040b9df22fb8e6f552d9b589c97ff536ffe03a0da1ea2949f78b5a0e303bb6" 1002 | } 1003 | }, 1004 | "widgets": { 1005 | "application/vnd.jupyter.widget-state+json": { 1006 | "state": {}, 1007 | "version_major": 2, 1008 | "version_minor": 0 1009 | } 1010 | } 1011 | }, 1012 | "nbformat": 4, 1013 | "nbformat_minor": 4 1014 | } 1015 | -------------------------------------------------------------------------------- /Code/lab5.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "6c0b91dd-fd14-4bd9-955c-bb7580ab71ed", 6 | "metadata": {}, 7 | "source": [ 8 | "# Challenge 5: Using 127 Qubits\n", 9 | "\n", 10 | "Congratulations on solving the previous challenges! You have shown that you can successfully use dynamic circuits.\n", 11 | "As a reward for making it this far you will be able to use one of our 127 qubit devices.\n", 12 | "\n", 13 | "As reminder, in order to earn a badge for completing the Challenge, you need to have finished 4 out of the 5 labs. We made that decision on purpose, because we know this lab will be both (a) challenging technically, and (b) using some of our most cutting edge hardware. The truth of releasing devices above 100 qubits for the public to use is that there may be significant delays in your ability to run your jobs. It's possible (although we hope not!) that you won't successfully run your job by the end of the Challenge. Please know we're doing everything possible behind the scenes to make your experience a success, but we also have a record number of participants in this year's Challenge. Be kind, and don't submit your circuits over and over which will clog the queue.\n", 14 | "\n", 15 | "Alright, take a deep breath. Here we go!" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "id": "6d2618d2-cfb6-4902-8e0f-c7fab74a84a0", 21 | "metadata": {}, 22 | "source": [ 23 | "You have seen before that working with actual physical devices brings its own set of challenges. This is even more true when you want to use a large number of qubits, since the pathways can become long, and you have to be mindful of introducing errors. We will use ibm_sherbrook as our device.\n", 24 | "\n", 25 | "In this challenge we want you to prepare a fully entangled 127 qubit state, the so called \"GHZ-state\", in a clever way.\n", 26 | "\n", 27 | "After that, we will guide you to apply your knowledge of error correction to the 127 qubit GHZ-state in order to then create a good 54 qubit GHZ-state. For this, we will use the even numbered qubits for the 54 qubit GHZ-state, which leaves the odd numbered qubits to be used as stabilizers.\n", 28 | "\n", 29 | "*Note: We will use the same register for the odd and even qubits, even though they will be used differently. We do this because it will make it easier to create the initial 127 qubit GHZ-state, especially when you want to optimize the depth manually.*" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 12, 35 | "id": "ff5a01f6-c357-4d6d-8c86-95991b311231", 36 | "metadata": { 37 | "slideshow": { 38 | "slide_type": "-" 39 | }, 40 | "tags": [] 41 | }, 42 | "outputs": [], 43 | "source": [ 44 | "# Importing all the parts we need\n", 45 | "from typing import List, Optional\n", 46 | "\n", 47 | "from qiskit import transpile, QuantumCircuit, QuantumRegister, ClassicalRegister\n", 48 | "from qiskit.result import marginal_counts\n", 49 | "\n", 50 | "import warnings\n", 51 | "\n", 52 | "warnings.filterwarnings(\"ignore\")\n", 53 | "\n", 54 | "import math\n", 55 | "\n", 56 | "pi = math.pi\n", 57 | "\n", 58 | "# Preparing registers\n", 59 | "quantum_register = QuantumRegister(127)\n", 60 | "classical_register = ClassicalRegister(127)\n", 61 | "\n", 62 | "# For simplicity we map the physical qubits to the logical qubits directly using the same number.\n", 63 | "initial_layout = [\n", 64 | " 0,\n", 65 | " 1,\n", 66 | " 2,\n", 67 | " 3,\n", 68 | " 4,\n", 69 | " 5,\n", 70 | " 6,\n", 71 | " 7,\n", 72 | " 8,\n", 73 | " 9,\n", 74 | " 10,\n", 75 | " 11,\n", 76 | " 12,\n", 77 | " 13,\n", 78 | " 14,\n", 79 | " 15,\n", 80 | " 16,\n", 81 | " 17,\n", 82 | " 18,\n", 83 | " 19,\n", 84 | " 20,\n", 85 | " 21,\n", 86 | " 22,\n", 87 | " 23,\n", 88 | " 24,\n", 89 | " 25,\n", 90 | " 26,\n", 91 | " 27,\n", 92 | " 28,\n", 93 | " 29,\n", 94 | " 30,\n", 95 | " 31,\n", 96 | " 32,\n", 97 | " 33,\n", 98 | " 34,\n", 99 | " 35,\n", 100 | " 36,\n", 101 | " 37,\n", 102 | " 38,\n", 103 | " 39,\n", 104 | " 40,\n", 105 | " 41,\n", 106 | " 42,\n", 107 | " 43,\n", 108 | " 44,\n", 109 | " 45,\n", 110 | " 46,\n", 111 | " 47,\n", 112 | " 48,\n", 113 | " 49,\n", 114 | " 50,\n", 115 | " 51,\n", 116 | " 52,\n", 117 | " 53,\n", 118 | " 54,\n", 119 | " 55,\n", 120 | " 56,\n", 121 | " 57,\n", 122 | " 58,\n", 123 | " 59,\n", 124 | " 60,\n", 125 | " 61,\n", 126 | " 62,\n", 127 | " 63,\n", 128 | " 64,\n", 129 | " 65,\n", 130 | " 66,\n", 131 | " 67,\n", 132 | " 68,\n", 133 | " 69,\n", 134 | " 70,\n", 135 | " 71,\n", 136 | " 72,\n", 137 | " 73,\n", 138 | " 74,\n", 139 | " 75,\n", 140 | " 76,\n", 141 | " 77,\n", 142 | " 78,\n", 143 | " 79,\n", 144 | " 80,\n", 145 | " 81,\n", 146 | " 82,\n", 147 | " 83,\n", 148 | " 84,\n", 149 | " 85,\n", 150 | " 86,\n", 151 | " 87,\n", 152 | " 88,\n", 153 | " 89,\n", 154 | " 90,\n", 155 | " 91,\n", 156 | " 92,\n", 157 | " 93,\n", 158 | " 94,\n", 159 | " 95,\n", 160 | " 96,\n", 161 | " 97,\n", 162 | " 98,\n", 163 | " 99,\n", 164 | " 100,\n", 165 | " 101,\n", 166 | " 102,\n", 167 | " 103,\n", 168 | " 104,\n", 169 | " 105,\n", 170 | " 106,\n", 171 | " 107,\n", 172 | " 108,\n", 173 | " 109,\n", 174 | " 110,\n", 175 | " 111,\n", 176 | " 112,\n", 177 | " 113,\n", 178 | " 114,\n", 179 | " 115,\n", 180 | " 116,\n", 181 | " 117,\n", 182 | " 118,\n", 183 | " 119,\n", 184 | " 120,\n", 185 | " 121,\n", 186 | " 122,\n", 187 | " 123,\n", 188 | " 124,\n", 189 | " 125,\n", 190 | " 126,\n", 191 | "]\n", 192 | "# The \"even\"\" qubits will be used for the 54 qubit GHZ-state\n", 193 | "ghz_qubits = [\n", 194 | " 0,\n", 195 | " 2,\n", 196 | " 4,\n", 197 | " 6,\n", 198 | " 8,\n", 199 | " 10,\n", 200 | " 12,\n", 201 | " 18,\n", 202 | " 20,\n", 203 | " 22,\n", 204 | " 24,\n", 205 | " 26,\n", 206 | " 28,\n", 207 | " 30,\n", 208 | " 32,\n", 209 | " 37,\n", 210 | " 39,\n", 211 | " 41,\n", 212 | " 43,\n", 213 | " 45,\n", 214 | " 47,\n", 215 | " 49,\n", 216 | " 51,\n", 217 | " 56,\n", 218 | " 58,\n", 219 | " 60,\n", 220 | " 62,\n", 221 | " 64,\n", 222 | " 66,\n", 223 | " 68,\n", 224 | " 70,\n", 225 | " 75,\n", 226 | " 77,\n", 227 | " 79,\n", 228 | " 81,\n", 229 | " 83,\n", 230 | " 85,\n", 231 | " 87,\n", 232 | " 89,\n", 233 | " 94,\n", 234 | " 96,\n", 235 | " 98,\n", 236 | " 100,\n", 237 | " 102,\n", 238 | " 104,\n", 239 | " 106,\n", 240 | " 108,\n", 241 | " 114,\n", 242 | " 116,\n", 243 | " 118,\n", 244 | " 120,\n", 245 | " 122,\n", 246 | " 124,\n", 247 | " 126,\n", 248 | "]\n", 249 | "# The \"odd\" qubits will be used as the stabilizers\n", 250 | "stabilizer_qubits = [\n", 251 | " 1,\n", 252 | " 3,\n", 253 | " 5,\n", 254 | " 7,\n", 255 | " 9,\n", 256 | " 11,\n", 257 | " 14,\n", 258 | " 15,\n", 259 | " 16,\n", 260 | " 17,\n", 261 | " 19,\n", 262 | " 21,\n", 263 | " 23,\n", 264 | " 25,\n", 265 | " 27,\n", 266 | " 29,\n", 267 | " 31,\n", 268 | " 33,\n", 269 | " 34,\n", 270 | " 35,\n", 271 | " 36,\n", 272 | " 38,\n", 273 | " 40,\n", 274 | " 42,\n", 275 | " 44,\n", 276 | " 46,\n", 277 | " 48,\n", 278 | " 50,\n", 279 | " 52,\n", 280 | " 53,\n", 281 | " 54,\n", 282 | " 55,\n", 283 | " 57,\n", 284 | " 59,\n", 285 | " 61,\n", 286 | " 63,\n", 287 | " 65,\n", 288 | " 67,\n", 289 | " 69,\n", 290 | " 71,\n", 291 | " 72,\n", 292 | " 73,\n", 293 | " 74,\n", 294 | " 76,\n", 295 | " 78,\n", 296 | " 80,\n", 297 | " 82,\n", 298 | " 84,\n", 299 | " 86,\n", 300 | " 88,\n", 301 | " 90,\n", 302 | " 91,\n", 303 | " 92,\n", 304 | " 93,\n", 305 | " 95,\n", 306 | " 97,\n", 307 | " 99,\n", 308 | " 101,\n", 309 | " 103,\n", 310 | " 105,\n", 311 | " 107,\n", 312 | " 109,\n", 313 | " 110,\n", 314 | " 111,\n", 315 | " 112,\n", 316 | " 115,\n", 317 | " 117,\n", 318 | " 119,\n", 319 | " 121,\n", 320 | " 123,\n", 321 | " 125,\n", 322 | "]" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "id": "5ecb607c-a882-49c4-acce-d26d62c2cd69", 328 | "metadata": { 329 | "slideshow": { 330 | "slide_type": "-" 331 | }, 332 | "tags": [] 333 | }, 334 | "source": [ 335 | "## Step 1: Creating a Large GHZ-state\n", 336 | "\n", 337 | "In many quantum algorithms it is required to entangle several qubits with each other. One often used state in algorithms is the generalized GHZ-state, the state $(\\alpha |00...0\\rangle + \\beta |11...1\\rangle)$ with $\\alpha = \\beta$\n", 338 | "\n", 339 | "The GHZ-state is fully entangled and can be generalized to any number of qubits. We will use it to create an 127 qubit GHZ-state! \n", 340 | "**No matter how many qubits the GHZ-state has when measured either all qubits are 0 or all qubits are 1.**\n", 341 | "\n", 342 | "\n", 343 | "The challenge here is not to entangle 127 qubits in theory, _but on an actual device_. This means you should take the layout of the device into account (e.g. avoid using CX-gates between qubits which are not directly connected with each other). You should also try to get the circuit depth as low as possible in order to reduce noise." 344 | ] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "id": "cd7d72be", 349 | "metadata": {}, 350 | "source": [ 351 | "### Exercise 1\n", 352 | "\n", 353 | "Generate a 127 qubit GHZ-state for the 127-qubit device `ibm_sherbrook` using only Hadamard and CNOT gates. Try to do this with the lowest circuit depth possible.\n", 354 | "\n", 355 | "*Hint: It can help to think first about how you would do it (with minimum depth) for an ideal device where all qubits are connected with each other.*" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 13, 361 | "id": "432aaaed-a05b-4397-8cb8-5e9c93980473", 362 | "metadata": { 363 | "slideshow": { 364 | "slide_type": "-" 365 | }, 366 | "tags": [] 367 | }, 368 | "outputs": [ 369 | { 370 | "name": "stdout", 371 | "output_type": "stream", 372 | "text": [ 373 | "16\n" 374 | ] 375 | } 376 | ], 377 | "source": [ 378 | "def generate_ghz127():\n", 379 | " qc = QuantumCircuit(quantum_register, classical_register)\n", 380 | " \n", 381 | " ####### your code goes here #######\n", 382 | " qc.h(0)\n", 383 | " \n", 384 | " for i in range(12):\n", 385 | " qc.cx(i,i+1)\n", 386 | " for i in range(18,32):\n", 387 | " qc.cx(i,i+1)\n", 388 | " for i in range(37,51):\n", 389 | " qc.cx(i,i+1)\n", 390 | " for i in range(56,70):\n", 391 | " qc.cx(i,i+1)\n", 392 | " for i in range(75,89):\n", 393 | " qc.cx(i,i+1)\n", 394 | " for i in range(94,108):\n", 395 | " qc.cx(i,i+1)\n", 396 | " for i in range(114,126):\n", 397 | " qc.cx(i,i+1)\n", 398 | " \n", 399 | " qc.cx(0,14)\n", 400 | " qc.cx(14,18)\n", 401 | " qc.cx(4,15)\n", 402 | " qc.cx(15,22)\n", 403 | " qc.cx(8,16)\n", 404 | " qc.cx(16,26)\n", 405 | " qc.cx(12,17)\n", 406 | " qc.cx(17,30)\n", 407 | " \n", 408 | " qc.cx(20,33)\n", 409 | " qc.cx(33,39)\n", 410 | " qc.cx(24,34)\n", 411 | " qc.cx(34,43)\n", 412 | " qc.cx(28,35)\n", 413 | " qc.cx(35,47)\n", 414 | " qc.cx(32,36)\n", 415 | " qc.cx(36,51)\n", 416 | " \n", 417 | " qc.cx(37,52)\n", 418 | " qc.cx(52,56)\n", 419 | " qc.cx(41,53)\n", 420 | " qc.cx(53,60)\n", 421 | " qc.cx(45,54)\n", 422 | " qc.cx(54,64)\n", 423 | " qc.cx(49,55)\n", 424 | " qc.cx(55,68)\n", 425 | " \n", 426 | " qc.cx(58,71)\n", 427 | " qc.cx(71,77)\n", 428 | " qc.cx(62,72)\n", 429 | " qc.cx(72,81)\n", 430 | " qc.cx(66,73)\n", 431 | " qc.cx(73,85)\n", 432 | " qc.cx(70,74)\n", 433 | " qc.cx(74,89)\n", 434 | " \n", 435 | " qc.cx(75,90)\n", 436 | " qc.cx(90,94)\n", 437 | " qc.cx(79,91)\n", 438 | " qc.cx(91,98)\n", 439 | " qc.cx(83,92)\n", 440 | " qc.cx(92,102)\n", 441 | " qc.cx(87,93)\n", 442 | " qc.cx(93,106)\n", 443 | " \n", 444 | " qc.cx(96,109)\n", 445 | " qc.cx(109,114)\n", 446 | " qc.cx(100,110)\n", 447 | " qc.cx(110,118)\n", 448 | " qc.cx(104,111)\n", 449 | " qc.cx(111,122)\n", 450 | " qc.cx(108,112)\n", 451 | " qc.cx(112,126)\n", 452 | " \n", 453 | " return qc\n", 454 | "\n", 455 | "\n", 456 | "ghz_circuit = generate_ghz127()\n", 457 | "print(ghz_circuit.depth())" 458 | ] 459 | }, 460 | { 461 | "cell_type": "code", 462 | "execution_count": 14, 463 | "id": "449893f2-f50b-4585-825e-4ce15e64a773", 464 | "metadata": { 465 | "tags": [] 466 | }, 467 | "outputs": [ 468 | { 469 | "data": { 470 | "text/plain": [ 471 | "127" 472 | ] 473 | }, 474 | "execution_count": 14, 475 | "metadata": {}, 476 | "output_type": "execute_result" 477 | } 478 | ], 479 | "source": [ 480 | "len(initial_layout)" 481 | ] 482 | }, 483 | { 484 | "cell_type": "code", 485 | "execution_count": 15, 486 | "id": "a689fee0-ede4-485e-a355-a73796403a89", 487 | "metadata": { 488 | "tags": [] 489 | }, 490 | "outputs": [ 491 | { 492 | "name": "stdout", 493 | "output_type": "stream", 494 | "text": [ 495 | "127\n" 496 | ] 497 | } 498 | ], 499 | "source": [ 500 | "def generate_ghz127():\n", 501 | " qc = QuantumCircuit(quantum_register, classical_register)\n", 502 | " \n", 503 | " ####### your code goes here #######\n", 504 | " qc.h(0)\n", 505 | " for i in range(1,len(initial_layout)):\n", 506 | " qc.cx(0,initial_layout[i])\n", 507 | " return qc\n", 508 | "\n", 509 | "\n", 510 | "ghz_circuit = generate_ghz127()\n", 511 | "print(ghz_circuit.depth())" 512 | ] 513 | }, 514 | { 515 | "cell_type": "code", 516 | "execution_count": 21, 517 | "id": "b9db474b-f66b-44ec-9925-fcb3ae09eb0b", 518 | "metadata": { 519 | "tags": [] 520 | }, 521 | "outputs": [], 522 | "source": [ 523 | "# def generate_ghz127():\n", 524 | "# qc = QuantumCircuit(quantum_register, classical_register)\n", 525 | " \n", 526 | "# ####### your code goes here #######\n", 527 | "# qmap = backend.coupling_map\n", 528 | " \n", 529 | "# already_cnoted = [64]\n", 530 | " \n", 531 | "# qc.h(quantum_register[64])\n", 532 | " \n", 533 | "# while len(already_cnoted) < 127:\n", 534 | "# for edge in qmap:\n", 535 | "# if edge[0] in already_cnoted and not edge[1] in already_cnoted:\n", 536 | "# qc.cx(quantum_register[edge[0]], quantum_register[edge[1]])\n", 537 | "# already_cnoted.append(edge[1])\n", 538 | "# if edge[1] in already_cnoted and not edge[0] in already_cnoted:\n", 539 | "# qc.cx(quantum_register[edge[1]], quantum_register[edge[0]])\n", 540 | "# already_cnoted.append(edge[0])\n", 541 | "# return qc\n", 542 | "\n", 543 | "\n", 544 | "# ghz_circuit = generate_ghz127()\n", 545 | "# print(ghz_circuit.depth())" 546 | ] 547 | }, 548 | { 549 | "cell_type": "code", 550 | "execution_count": 20, 551 | "id": "9f75b3a0-344c-4128-a644-93f9501d03f4", 552 | "metadata": { 553 | "tags": [] 554 | }, 555 | "outputs": [], 556 | "source": [ 557 | "ghz_circuit.draw(scale=0.5)" 558 | ] 559 | }, 560 | { 561 | "cell_type": "code", 562 | "execution_count": 19, 563 | "id": "52436751", 564 | "metadata": { 565 | "tags": [] 566 | }, 567 | "outputs": [ 568 | { 569 | "name": "stdout", 570 | "output_type": "stream", 571 | "text": [ 572 | "Submitting your answer. Please wait...\n", 573 | "Congratulations 🎉! Your answer is correct and has been submitted.\n" 574 | ] 575 | } 576 | ], 577 | "source": [ 578 | "# Submit your circuit\n", 579 | "\n", 580 | "from qc_grader.challenges.spring_2023 import grade_ex5a\n", 581 | "\n", 582 | "grade_ex5a(ghz_circuit)" 583 | ] 584 | }, 585 | { 586 | "cell_type": "markdown", 587 | "id": "0bfdf52c-3579-46c3-9765-56eece914c79", 588 | "metadata": { 589 | "slideshow": { 590 | "slide_type": "-" 591 | }, 592 | "tags": [] 593 | }, 594 | "source": [ 595 | "## Step 2: Reducing the Size by half\n", 596 | "\n", 597 | "We now want to use the GHZ-state you created to form a reduced GHZ-state only using the even numbered Qubits. For this we will need to unentangle the odd qubits, so that they can be measured without letting the GHZ-state collapse.\n", 598 | "\n", 599 | "Since we want to unentangle the Qubits, we can do it in a way to generate **stabilizers**, similar to what you did in Lab 4. The stabilizers must be 0 if both qubits that they are connected with have the same value, and they must be 1 if those values is different.\n", 600 | "\n", 601 | "What's the point in doing this? The astute observer might have already realized it - we can use these stabilizers to apply error correction to the reduced GHZ-state." 602 | ] 603 | }, 604 | { 605 | "cell_type": "markdown", 606 | "id": "86c18247", 607 | "metadata": {}, 608 | "source": [ 609 | "### Exercise 2\n", 610 | "\n", 611 | "Unentangle the odd qubits of the created GHZ-state in order to create stabilizers. Again, you can challenge yourself to make the circuit depth as small as possible.\n", 612 | "\n", 613 | "*Hint: Take into account how you created your GHZ-state above. Your method of unentangling is specific to how it was created.*" 614 | ] 615 | }, 616 | { 617 | "cell_type": "code", 618 | "execution_count": 22, 619 | "id": "9e9bd773-9908-4acc-b0ce-64cf5eb1db54", 620 | "metadata": { 621 | "slideshow": { 622 | "slide_type": "-" 623 | }, 624 | "tags": [] 625 | }, 626 | "outputs": [ 627 | { 628 | "name": "stdout", 629 | "output_type": "stream", 630 | "text": [ 631 | "73\n" 632 | ] 633 | } 634 | ], 635 | "source": [ 636 | "def deentangle_qubits():\n", 637 | " qc = QuantumCircuit(quantum_register, classical_register)\n", 638 | " \n", 639 | " ####### your code goes here #######\n", 640 | " # Apply CNOT gates in reverse order to unentangle the odd qubits\n", 641 | " for i in reversed(stabilizer_qubits):\n", 642 | " qc.cx(0,i)\n", 643 | " qc.cx(0,13)\n", 644 | " qc.cx(0,113)\n", 645 | " return qc\n", 646 | "\n", 647 | "\n", 648 | "unentangle_circuit = deentangle_qubits()\n", 649 | "print(unentangle_circuit.depth())\n", 650 | "\n", 651 | "complete_circuit = ghz_circuit.compose(unentangle_circuit)" 652 | ] 653 | }, 654 | { 655 | "cell_type": "code", 656 | "execution_count": 23, 657 | "id": "eec56294", 658 | "metadata": { 659 | "tags": [] 660 | }, 661 | "outputs": [ 662 | { 663 | "name": "stdout", 664 | "output_type": "stream", 665 | "text": [ 666 | "Submitting your answer. Please wait...\n", 667 | "Congratulations 🎉! Your answer is correct and has been submitted.\n" 668 | ] 669 | } 670 | ], 671 | "source": [ 672 | "# Submit your circuit\n", 673 | "\n", 674 | "from qc_grader.challenges.spring_2023 import grade_ex5b\n", 675 | "\n", 676 | "grade_ex5b(complete_circuit)" 677 | ] 678 | }, 679 | { 680 | "cell_type": "markdown", 681 | "id": "92bd8827-441d-4006-8d85-eb7a289bd64f", 682 | "metadata": { 683 | "slideshow": { 684 | "slide_type": "-" 685 | }, 686 | "tags": [] 687 | }, 688 | "source": [ 689 | "Good work. Now since all odd qubits are unentangled from the even qubits, we can measure them without collapsing the GHZ-state." 690 | ] 691 | }, 692 | { 693 | "cell_type": "code", 694 | "execution_count": 24, 695 | "id": "e3148f17-d168-4a9d-a0d8-82213cefd329", 696 | "metadata": { 697 | "slideshow": { 698 | "slide_type": "-" 699 | }, 700 | "tags": [] 701 | }, 702 | "outputs": [], 703 | "source": [ 704 | "# Measuring stabilizers this can also be used in post processing to see what went wrong.\n", 705 | "\n", 706 | "\n", 707 | "def measure_stabilizers():\n", 708 | " qc = QuantumCircuit(quantum_register, classical_register)\n", 709 | " qc.measure(stabilizer_qubits, stabilizer_qubits)\n", 710 | " return qc\n", 711 | "\n", 712 | "\n", 713 | "stabilizer_circuit = measure_stabilizers()" 714 | ] 715 | }, 716 | { 717 | "cell_type": "markdown", 718 | "id": "606df18e-ae9b-41ae-bd0e-cd5b6698cf9d", 719 | "metadata": { 720 | "slideshow": { 721 | "slide_type": "-" 722 | }, 723 | "tags": [] 724 | }, 725 | "source": [ 726 | "These measurement results could be used to improve the 54 qubit GHZ-state, but we'll explore that idea later.\n", 727 | "\n", 728 | "After having measured the odd qubits, you could reset them and use the 54 GHZ-state in your algorithm, using the odd qubits as potential auxilliary qubits. However, before using your GHZ-state, let's test how good it is.\n", 729 | "\n", 730 | "We need to measure the 54 qubit GHZ-state!" 731 | ] 732 | }, 733 | { 734 | "cell_type": "code", 735 | "execution_count": 25, 736 | "id": "0225debb-1fdc-4210-bd7a-9717386e63d5", 737 | "metadata": { 738 | "slideshow": { 739 | "slide_type": "-" 740 | }, 741 | "tags": [] 742 | }, 743 | "outputs": [], 744 | "source": [ 745 | "# Measuring the GHZ qubits\n", 746 | "\n", 747 | "\n", 748 | "def measure_ghz():\n", 749 | " qc = QuantumCircuit(quantum_register, classical_register)\n", 750 | " qc.measure(ghz_qubits, ghz_qubits)\n", 751 | " return qc\n", 752 | "\n", 753 | "\n", 754 | "measure_circuit = measure_ghz()" 755 | ] 756 | }, 757 | { 758 | "cell_type": "markdown", 759 | "id": "626508af-7785-49d6-9af1-aae36925908c", 760 | "metadata": { 761 | "slideshow": { 762 | "slide_type": "-" 763 | }, 764 | "tags": [] 765 | }, 766 | "source": [ 767 | "Now let's put everything together, so that we can test it." 768 | ] 769 | }, 770 | { 771 | "cell_type": "code", 772 | "execution_count": 26, 773 | "id": "d0ed3661-c930-43b8-8096-dd1379faf9cb", 774 | "metadata": { 775 | "slideshow": { 776 | "slide_type": "-" 777 | }, 778 | "tags": [] 779 | }, 780 | "outputs": [], 781 | "source": [ 782 | "# Everything together\n", 783 | "\n", 784 | "simple_ghz = (\n", 785 | " ghz_circuit.compose(unentangle_circuit)\n", 786 | " .compose(stabilizer_circuit)\n", 787 | " .compose(measure_circuit)\n", 788 | ")" 789 | ] 790 | }, 791 | { 792 | "cell_type": "markdown", 793 | "id": "6e8f6b50-781f-4e03-951e-94fe73136bea", 794 | "metadata": { 795 | "slideshow": { 796 | "slide_type": "-" 797 | }, 798 | "tags": [] 799 | }, 800 | "source": [ 801 | "## Step 3: Preparing and Running on the Device\n", 802 | "\n", 803 | "We are now ready to run our GHZ-state on a real device, and for that it's time for `ibm_sherbrooke`\n", 804 | "\n", 805 | "There are not many people in the world who have worked with 127 qubits. You will be soon one of the few brave souls to say you have. One small step for quantum computing, one giant leap for your CV. \n", 806 | "\n", 807 | "Just kidding :-P\n", 808 | "\n", 809 | "-----\n", 810 | "\n", 811 | "First we prepare everything we need:" 812 | ] 813 | }, 814 | { 815 | "cell_type": "code", 816 | "execution_count": 27, 817 | "id": "e7472b15-0be2-447b-9b66-6e57ca915fab", 818 | "metadata": { 819 | "slideshow": { 820 | "slide_type": "-" 821 | }, 822 | "tags": [] 823 | }, 824 | "outputs": [], 825 | "source": [ 826 | "# Importing provider and getting access to the system\n", 827 | "from qiskit_ibm_provider import IBMProvider\n", 828 | "from qiskit import transpile\n", 829 | "\n", 830 | "\n", 831 | "provider = IBMProvider()\n", 832 | "\n", 833 | "hub = \"qc-spring-23-7\"\n", 834 | "group = \"group-3\"\n", 835 | "project = \"recAxYQZODaJM6OLg\"\n", 836 | "\n", 837 | "backend_name = \"ibm_sherbrooke\"\n", 838 | "backend = provider.get_backend(backend_name, instance=f\"{hub}/{group}/{project}\")\n", 839 | "\n", 840 | "number_of_shots: int = 1024" 841 | ] 842 | }, 843 | { 844 | "cell_type": "markdown", 845 | "id": "51277fb1-4759-456b-8b04-1c9a720cf4c8", 846 | "metadata": { 847 | "slideshow": { 848 | "slide_type": "-" 849 | }, 850 | "tags": [] 851 | }, 852 | "source": [ 853 | "We start by transpiling it for the actual device. This should not cause too many changes, since you (should have) had the physical device in mind when making the circuit originally, and only used connections which exist.\n", 854 | "\n", 855 | "If you didn't do that, now's a good time to go back and fix that, or hop over to the Discord to talk with others about how to think through that process." 856 | ] 857 | }, 858 | { 859 | "cell_type": "code", 860 | "execution_count": 28, 861 | "id": "770c2477-0c21-4dd0-8ccb-96268b88f323", 862 | "metadata": { 863 | "slideshow": { 864 | "slide_type": "-" 865 | }, 866 | "tags": [] 867 | }, 868 | "outputs": [], 869 | "source": [ 870 | "# First we transpile the GHZ-state for the actual device\n", 871 | "qc_transpiled = transpile(simple_ghz, backend, initial_layout=initial_layout)" 872 | ] 873 | }, 874 | { 875 | "cell_type": "markdown", 876 | "id": "3d20d85e-cef3-4b4d-a206-1ee9f452fcb0", 877 | "metadata": { 878 | "slideshow": { 879 | "slide_type": "-" 880 | }, 881 | "tags": [] 882 | }, 883 | "source": [ 884 | "Now we're ready to run the job on the 127-qubit device. Let's add some tags here to make it easier to find them in the future.\n", 885 | "\n", 886 | "Running the job will take some time, depending of how many other people are in the queue trying to run their jobs. Have you had your coffee yet today? Or maybe you're more of a tea drinker. I hear there's a great new show on Netflix." 887 | ] 888 | }, 889 | { 890 | "cell_type": "code", 891 | "execution_count": 29, 892 | "id": "2f71e153-d6ee-4502-b60f-35b61f0ef555", 893 | "metadata": { 894 | "slideshow": { 895 | "slide_type": "-" 896 | }, 897 | "tags": [] 898 | }, 899 | "outputs": [ 900 | { 901 | "name": "stdout", 902 | "output_type": "stream", 903 | "text": [ 904 | "chm6m16pqnphtdvn3d6g\n" 905 | ] 906 | } 907 | ], 908 | "source": [ 909 | "# Now we can run the job\n", 910 | "# We add memory=true to be easier able to analyse how good the result were and the tags to make it easier to find it later.\n", 911 | "job = backend.run(\n", 912 | " qc_transpiled,\n", 913 | " shots=number_of_shots,\n", 914 | " memory=True,\n", 915 | " job_tags=[\"ghz_state\", \"spring_challenge\"],\n", 916 | ")\n", 917 | "\n", 918 | "job_id = job.job_id()\n", 919 | "print(job_id)" 920 | ] 921 | }, 922 | { 923 | "cell_type": "markdown", 924 | "id": "e2dc42bd-580a-427e-92c7-edc47de5aa84", 925 | "metadata": { 926 | "slideshow": { 927 | "slide_type": "-" 928 | }, 929 | "tags": [] 930 | }, 931 | "source": [ 932 | "In case you are coming back later, and want to retrieve a job, you can find it in the IBM Quantum Computing Homepage with the tags used above.\n", 933 | "\n", 934 | "Copy the name of your job (its id) and replace the *job_id* in the cell below with yours. A job id should look something like this: *ch36cf1pleju56fajrqg*\n", 935 | "\n", 936 | "Or you can just directly use the job_id of above cell." 937 | ] 938 | }, 939 | { 940 | "cell_type": "code", 941 | "execution_count": 30, 942 | "id": "ae75b448-c873-4d8c-b6ff-234881030e61", 943 | "metadata": { 944 | "slideshow": { 945 | "slide_type": "-" 946 | }, 947 | "tags": [] 948 | }, 949 | "outputs": [ 950 | { 951 | "data": { 952 | "text/plain": [ 953 | "" 954 | ] 955 | }, 956 | "execution_count": 30, 957 | "metadata": {}, 958 | "output_type": "execute_result" 959 | } 960 | ], 961 | "source": [ 962 | "# Change job id to the id of your previous submitted job something like \"ch36cf1pleju56fajrqg\"\n", 963 | "# You only need to run this if you come back at a later time\n", 964 | "job = provider.backend.retrieve_job(job_id)\n", 965 | "job.status()" 966 | ] 967 | }, 968 | { 969 | "cell_type": "code", 970 | "execution_count": 31, 971 | "id": "cded7265", 972 | "metadata": { 973 | "tags": [] 974 | }, 975 | "outputs": [], 976 | "source": [ 977 | "# Getting the data of the job for testing\n", 978 | "data = job.result().get_memory()" 979 | ] 980 | }, 981 | { 982 | "cell_type": "markdown", 983 | "id": "6196bb31-15ed-43f4-a36f-920989715c02", 984 | "metadata": { 985 | "slideshow": { 986 | "slide_type": "-" 987 | }, 988 | "tags": [] 989 | }, 990 | "source": [ 991 | "## Step 4: Testing the GHZ-state\n", 992 | "\n", 993 | "You did it! You've run a GHZ-state circuit on a 127-qubit machine. That's awesome!!!\n", 994 | "\n", 995 | "Now that you have the results of your GHZ-state, it's time to examine it. We did not add any error mitigation or error correction, so you should expect results which still can be improved.\n", 996 | "\n", 997 | "There are different ways to test how \"good\" the results are. You can just look at the raw results, but since the qubits which are used for the GHZ-State are not next to each other, this might be a bit annoying. Having a function tell us about the quality, or about the errors in the GHZ-State, would be useful." 998 | ] 999 | }, 1000 | { 1001 | "cell_type": "markdown", 1002 | "id": "afce684a-490f-4460-8f4b-ed2bd6324cb7", 1003 | "metadata": {}, 1004 | "source": [ 1005 | "### Exercise 3\n", 1006 | "\n", 1007 | "Create a function to test the GHZ-state.\n", 1008 | "\n", 1009 | "As Challenge authors, we decided to give you some freedom here in how you want to test your results. Please find a way which makes sense **for you.** It's important to say that the _lower the output_ of your function, the the _better_ your GHZ-state is.\n", 1010 | "\n", 1011 | "*Hint: This function should be made to test the data we have created, so you only need to test the qubits which are part of the GHZ-state*" 1012 | ] 1013 | }, 1014 | { 1015 | "cell_type": "code", 1016 | "execution_count": 33, 1017 | "id": "7e7f0ff0-ba28-4c1f-bcac-1d439e0a560f", 1018 | "metadata": { 1019 | "slideshow": { 1020 | "slide_type": "-" 1021 | }, 1022 | "tags": [] 1023 | }, 1024 | "outputs": [ 1025 | { 1026 | "data": { 1027 | "text/plain": [ 1028 | "0.0" 1029 | ] 1030 | }, 1031 | "execution_count": 33, 1032 | "metadata": {}, 1033 | "output_type": "execute_result" 1034 | } 1035 | ], 1036 | "source": [ 1037 | "# A function to test the quality of a GHZ-state. The lower the better\n", 1038 | "def test_ghz(data):\n", 1039 | " ghz_qubits = [\n", 1040 | " 0,\n", 1041 | " 2,\n", 1042 | " 4,\n", 1043 | " 6,\n", 1044 | " 8,\n", 1045 | " 10,\n", 1046 | " 12,\n", 1047 | " 18,\n", 1048 | " 20,\n", 1049 | " 22,\n", 1050 | " 24,\n", 1051 | " 26,\n", 1052 | " 28,\n", 1053 | " 30,\n", 1054 | " 32,\n", 1055 | " 37,\n", 1056 | " 39,\n", 1057 | " 41,\n", 1058 | " 43,\n", 1059 | " 45,\n", 1060 | " 47,\n", 1061 | " 49,\n", 1062 | " 51,\n", 1063 | " 56,\n", 1064 | " 58,\n", 1065 | " 60,\n", 1066 | " 62,\n", 1067 | " 64,\n", 1068 | " 66,\n", 1069 | " 68,\n", 1070 | " 70,\n", 1071 | " 75,\n", 1072 | " 77,\n", 1073 | " 79,\n", 1074 | " 81,\n", 1075 | " 83,\n", 1076 | " 85,\n", 1077 | " 81,\n", 1078 | " 89,\n", 1079 | " 94,\n", 1080 | " 96,\n", 1081 | " 98,\n", 1082 | " 100,\n", 1083 | " 102,\n", 1084 | " 104,\n", 1085 | " 106,\n", 1086 | " 108,\n", 1087 | " 114,\n", 1088 | " 116,\n", 1089 | " 118,\n", 1090 | " 120,\n", 1091 | " 122,\n", 1092 | " 124,\n", 1093 | " 126,\n", 1094 | " ]\n", 1095 | "\n", 1096 | " ####### your code goes here #######\n", 1097 | " \n", 1098 | " correlation_sum = 0\n", 1099 | " correlation_count = 0\n", 1100 | " \n", 1101 | " # Calculate pairwise correlation between GHZ-state qubits\n", 1102 | " for i in range(len(ghz_qubits)):\n", 1103 | " for j in range(i + 1, len(ghz_qubits)):\n", 1104 | " qubit_i = ghz_qubits[i]\n", 1105 | " qubit_j = ghz_qubits[j]\n", 1106 | " \n", 1107 | " counts_i = data.count(f'{qubit_i}')\n", 1108 | " counts_j = data.count(f'{qubit_j}')\n", 1109 | " counts_ij = data.count(f'{qubit_i}{qubit_j}')\n", 1110 | " \n", 1111 | " correlation = (counts_ij / len(data)) - (counts_i / len(data)) * (counts_j / len(data))\n", 1112 | " \n", 1113 | " correlation_sum += correlation\n", 1114 | " correlation_count += 1\n", 1115 | " \n", 1116 | " average_correlation = correlation_sum / correlation_count\n", 1117 | " return average_correlation\n", 1118 | "\n", 1119 | "test_ghz(data)" 1120 | ] 1121 | }, 1122 | { 1123 | "cell_type": "markdown", 1124 | "id": "78ed4b94-2f2a-4f95-9bd7-ae9594b13f12", 1125 | "metadata": { 1126 | "slideshow": { 1127 | "slide_type": "-" 1128 | }, 1129 | "tags": [] 1130 | }, 1131 | "source": [ 1132 | "You now have a number rating your results, based on a function you designed. \n", 1133 | "\n", 1134 | "Before we go on, think about your method. \n", 1135 | "- What would the number be for a really good state? \n", 1136 | "- What about for a really bad state? \n", 1137 | "- What does a \"bad state\" even look like? \n", 1138 | "- How can you design a function that's easy for someone to understand what its telling them? \n", 1139 | "\n", 1140 | "These are all questions that IBM Researchers think about daily, and it keeps us extremely motivated to continue to make our devices and services as strong and easy-to-understand as possible. If this type of work is interesting to you as well, let us know!" 1141 | ] 1142 | }, 1143 | { 1144 | "cell_type": "markdown", 1145 | "id": "232165a6-8bd8-4fd9-99e6-eea55a661953", 1146 | "metadata": {}, 1147 | "source": [ 1148 | "Now let's test your testing function and let's see if it does what it should. Remember, it should give low results for good states, which have fewer errors, and high results for states with lots of errors." 1149 | ] 1150 | }, 1151 | { 1152 | "cell_type": "code", 1153 | "execution_count": 34, 1154 | "id": "b6bbc4fe-94f6-4131-95ec-a8243482bb17", 1155 | "metadata": { 1156 | "slideshow": { 1157 | "slide_type": "-" 1158 | }, 1159 | "tags": [] 1160 | }, 1161 | "outputs": [ 1162 | { 1163 | "name": "stdout", 1164 | "output_type": "stream", 1165 | "text": [ 1166 | "Submitting your answer. Please wait...\n", 1167 | "Congratulations 🎉! Your answer is correct and has been submitted.\n" 1168 | ] 1169 | } 1170 | ], 1171 | "source": [ 1172 | "# Submit your circuit\n", 1173 | "\n", 1174 | "from qc_grader.challenges.spring_2023 import grade_ex5c\n", 1175 | "\n", 1176 | "# Since we test here a function, we do not need brackets after test_ghz, since the input is the function\n", 1177 | "grade_ex5c(test_ghz)" 1178 | ] 1179 | }, 1180 | { 1181 | "cell_type": "markdown", 1182 | "id": "f278f65b-4896-46b3-aa7c-bfea2ed866b1", 1183 | "metadata": { 1184 | "slideshow": { 1185 | "slide_type": "-" 1186 | }, 1187 | "tags": [] 1188 | }, 1189 | "source": [ 1190 | "Now the question is: how can we improve on it?\n", 1191 | "\n", 1192 | "One of the first steps would be to try to decrease the depth of the circuit further. Let's look at the depth of your transpiled circuit:\n" 1193 | ] 1194 | }, 1195 | { 1196 | "cell_type": "code", 1197 | "execution_count": 35, 1198 | "id": "7d2ce1e5-8fc7-4ad6-ac80-04688c897285", 1199 | "metadata": { 1200 | "slideshow": { 1201 | "slide_type": "-" 1202 | }, 1203 | "tags": [] 1204 | }, 1205 | "outputs": [ 1206 | { 1207 | "data": { 1208 | "text/plain": [ 1209 | "3170" 1210 | ] 1211 | }, 1212 | "execution_count": 35, 1213 | "metadata": {}, 1214 | "output_type": "execute_result" 1215 | } 1216 | ], 1217 | "source": [ 1218 | "qc_transpiled.depth()" 1219 | ] 1220 | }, 1221 | { 1222 | "cell_type": "markdown", 1223 | "id": "3322071d-a207-494e-ac17-a039a6a31743", 1224 | "metadata": { 1225 | "slideshow": { 1226 | "slide_type": "-" 1227 | }, 1228 | "tags": [] 1229 | }, 1230 | "source": [ 1231 | "We can see that the depth got bigger during the transpilation process, by more than a factor of 2.\n", 1232 | "\n", 1233 | "Take a peek at how it looks, to see where this additional depth comes from:" 1234 | ] 1235 | }, 1236 | { 1237 | "cell_type": "code", 1238 | "execution_count": 36, 1239 | "id": "f6d42633-03fc-405b-af40-970e70e48c2d", 1240 | "metadata": { 1241 | "slideshow": { 1242 | "slide_type": "-" 1243 | }, 1244 | "tags": [] 1245 | }, 1246 | "outputs": [ 1247 | { 1248 | "ename": "ValueError", 1249 | "evalue": "Image size of 2354x1466823 pixels is too large. It must be less than 2^16 in each direction.", 1250 | "output_type": "error", 1251 | "traceback": [ 1252 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1253 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", 1254 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/IPython/core/formatters.py:338\u001b[0m, in \u001b[0;36mBaseFormatter.__call__\u001b[0;34m(self, obj)\u001b[0m\n\u001b[1;32m 336\u001b[0m \u001b[38;5;28;01mpass\u001b[39;00m\n\u001b[1;32m 337\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 338\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mprinter\u001b[49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 339\u001b[0m \u001b[38;5;66;03m# Finally look for special method names\u001b[39;00m\n\u001b[1;32m 340\u001b[0m method \u001b[38;5;241m=\u001b[39m get_real_method(obj, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprint_method)\n", 1255 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/IPython/core/pylabtools.py:152\u001b[0m, in \u001b[0;36mprint_figure\u001b[0;34m(fig, fmt, bbox_inches, base64, **kwargs)\u001b[0m\n\u001b[1;32m 149\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mmatplotlib\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mbackend_bases\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m FigureCanvasBase\n\u001b[1;32m 150\u001b[0m FigureCanvasBase(fig)\n\u001b[0;32m--> 152\u001b[0m \u001b[43mfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcanvas\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mprint_figure\u001b[49m\u001b[43m(\u001b[49m\u001b[43mbytes_io\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkw\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 153\u001b[0m data \u001b[38;5;241m=\u001b[39m bytes_io\u001b[38;5;241m.\u001b[39mgetvalue()\n\u001b[1;32m 154\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m fmt \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msvg\u001b[39m\u001b[38;5;124m'\u001b[39m:\n", 1256 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/backend_bases.py:2308\u001b[0m, in \u001b[0;36mFigureCanvasBase.print_figure\u001b[0;34m(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)\u001b[0m\n\u001b[1;32m 2301\u001b[0m bbox_inches \u001b[38;5;241m=\u001b[39m rcParams[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msavefig.bbox\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[1;32m 2303\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfigure\u001b[38;5;241m.\u001b[39mget_layout_engine() \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mor\u001b[39;00m\n\u001b[1;32m 2304\u001b[0m bbox_inches \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtight\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[1;32m 2305\u001b[0m \u001b[38;5;66;03m# we need to trigger a draw before printing to make sure\u001b[39;00m\n\u001b[1;32m 2306\u001b[0m \u001b[38;5;66;03m# CL works. \"tight\" also needs a draw to get the right\u001b[39;00m\n\u001b[1;32m 2307\u001b[0m \u001b[38;5;66;03m# locations:\u001b[39;00m\n\u001b[0;32m-> 2308\u001b[0m renderer \u001b[38;5;241m=\u001b[39m \u001b[43m_get_renderer\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2309\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfigure\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2310\u001b[0m \u001b[43m \u001b[49m\u001b[43mfunctools\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpartial\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2311\u001b[0m \u001b[43m \u001b[49m\u001b[43mprint_method\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43morientation\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43morientation\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2312\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2313\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mgetattr\u001b[39m(renderer, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_draw_disabled\u001b[39m\u001b[38;5;124m\"\u001b[39m, nullcontext)():\n\u001b[1;32m 2314\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfigure\u001b[38;5;241m.\u001b[39mdraw(renderer)\n", 1257 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/backend_bases.py:1559\u001b[0m, in \u001b[0;36m_get_renderer\u001b[0;34m(figure, print_method)\u001b[0m\n\u001b[1;32m 1556\u001b[0m print_method \u001b[38;5;241m=\u001b[39m stack\u001b[38;5;241m.\u001b[39menter_context(\n\u001b[1;32m 1557\u001b[0m figure\u001b[38;5;241m.\u001b[39mcanvas\u001b[38;5;241m.\u001b[39m_switch_canvas_and_return_print_method(fmt))\n\u001b[1;32m 1558\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1559\u001b[0m \u001b[43mprint_method\u001b[49m\u001b[43m(\u001b[49m\u001b[43mio\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mBytesIO\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1560\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m Done \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[1;32m 1561\u001b[0m renderer, \u001b[38;5;241m=\u001b[39m exc\u001b[38;5;241m.\u001b[39margs\n", 1258 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/backend_bases.py:2204\u001b[0m, in \u001b[0;36mFigureCanvasBase._switch_canvas_and_return_print_method..\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 2200\u001b[0m optional_kws \u001b[38;5;241m=\u001b[39m { \u001b[38;5;66;03m# Passed by print_figure for other renderers.\u001b[39;00m\n\u001b[1;32m 2201\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdpi\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfacecolor\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124medgecolor\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124morientation\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 2202\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbbox_inches_restore\u001b[39m\u001b[38;5;124m\"\u001b[39m}\n\u001b[1;32m 2203\u001b[0m skip \u001b[38;5;241m=\u001b[39m optional_kws \u001b[38;5;241m-\u001b[39m {\u001b[38;5;241m*\u001b[39minspect\u001b[38;5;241m.\u001b[39msignature(meth)\u001b[38;5;241m.\u001b[39mparameters}\n\u001b[0;32m-> 2204\u001b[0m print_method \u001b[38;5;241m=\u001b[39m functools\u001b[38;5;241m.\u001b[39mwraps(meth)(\u001b[38;5;28;01mlambda\u001b[39;00m \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: \u001b[43mmeth\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2205\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43m{\u001b[49m\u001b[43mk\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mk\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mkwargs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mk\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mskip\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[1;32m 2206\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m: \u001b[38;5;66;03m# Let third-parties do as they see fit.\u001b[39;00m\n\u001b[1;32m 2207\u001b[0m print_method \u001b[38;5;241m=\u001b[39m meth\n", 1259 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/_api/deprecation.py:410\u001b[0m, in \u001b[0;36mdelete_parameter..wrapper\u001b[0;34m(*inner_args, **inner_kwargs)\u001b[0m\n\u001b[1;32m 400\u001b[0m deprecation_addendum \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 401\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIf any parameter follows \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mname\u001b[38;5;132;01m!r}\u001b[39;00m\u001b[38;5;124m, they should be passed as \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 402\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mkeyword, not positionally.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 403\u001b[0m warn_deprecated(\n\u001b[1;32m 404\u001b[0m since,\n\u001b[1;32m 405\u001b[0m name\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mrepr\u001b[39m(name),\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 408\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m deprecation_addendum,\n\u001b[1;32m 409\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m--> 410\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43minner_args\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43minner_kwargs\u001b[49m\u001b[43m)\u001b[49m\n", 1260 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:517\u001b[0m, in \u001b[0;36mFigureCanvasAgg.print_png\u001b[0;34m(self, filename_or_obj, metadata, pil_kwargs, *args)\u001b[0m\n\u001b[1;32m 468\u001b[0m \u001b[38;5;129m@_api\u001b[39m\u001b[38;5;241m.\u001b[39mdelete_parameter(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m3.5\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124margs\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 469\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mprint_png\u001b[39m(\u001b[38;5;28mself\u001b[39m, filename_or_obj, \u001b[38;5;241m*\u001b[39margs,\n\u001b[1;32m 470\u001b[0m metadata\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, pil_kwargs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m 471\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 472\u001b[0m \u001b[38;5;124;03m Write the figure to a PNG file.\u001b[39;00m\n\u001b[1;32m 473\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 515\u001b[0m \u001b[38;5;124;03m *metadata*, including the default 'Software' key.\u001b[39;00m\n\u001b[1;32m 516\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 517\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_print_pil\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilename_or_obj\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mpng\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpil_kwargs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m)\u001b[49m\n", 1261 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:463\u001b[0m, in \u001b[0;36mFigureCanvasAgg._print_pil\u001b[0;34m(self, filename_or_obj, fmt, pil_kwargs, metadata)\u001b[0m\n\u001b[1;32m 458\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_print_pil\u001b[39m(\u001b[38;5;28mself\u001b[39m, filename_or_obj, fmt, pil_kwargs, metadata\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m 459\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 460\u001b[0m \u001b[38;5;124;03m Draw the canvas, then save it using `.image.imsave` (to which\u001b[39;00m\n\u001b[1;32m 461\u001b[0m \u001b[38;5;124;03m *pil_kwargs* and *metadata* are forwarded).\u001b[39;00m\n\u001b[1;32m 462\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 463\u001b[0m \u001b[43mFigureCanvasAgg\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdraw\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 464\u001b[0m mpl\u001b[38;5;241m.\u001b[39mimage\u001b[38;5;241m.\u001b[39mimsave(\n\u001b[1;32m 465\u001b[0m filename_or_obj, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbuffer_rgba(), \u001b[38;5;28mformat\u001b[39m\u001b[38;5;241m=\u001b[39mfmt, origin\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mupper\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 466\u001b[0m dpi\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfigure\u001b[38;5;241m.\u001b[39mdpi, metadata\u001b[38;5;241m=\u001b[39mmetadata, pil_kwargs\u001b[38;5;241m=\u001b[39mpil_kwargs)\n", 1262 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:399\u001b[0m, in \u001b[0;36mFigureCanvasAgg.draw\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 397\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdraw\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[1;32m 398\u001b[0m \u001b[38;5;66;03m# docstring inherited\u001b[39;00m\n\u001b[0;32m--> 399\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrenderer \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_renderer\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 400\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrenderer\u001b[38;5;241m.\u001b[39mclear()\n\u001b[1;32m 401\u001b[0m \u001b[38;5;66;03m# Acquire a lock on the shared font cache.\u001b[39;00m\n", 1263 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/_api/deprecation.py:384\u001b[0m, in \u001b[0;36mdelete_parameter..wrapper\u001b[0;34m(*inner_args, **inner_kwargs)\u001b[0m\n\u001b[1;32m 379\u001b[0m \u001b[38;5;129m@functools\u001b[39m\u001b[38;5;241m.\u001b[39mwraps(func)\n\u001b[1;32m 380\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwrapper\u001b[39m(\u001b[38;5;241m*\u001b[39minner_args, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39minner_kwargs):\n\u001b[1;32m 381\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(inner_args) \u001b[38;5;241m<\u001b[39m\u001b[38;5;241m=\u001b[39m name_idx \u001b[38;5;129;01mand\u001b[39;00m name \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m inner_kwargs:\n\u001b[1;32m 382\u001b[0m \u001b[38;5;66;03m# Early return in the simple, non-deprecated case (much faster than\u001b[39;00m\n\u001b[1;32m 383\u001b[0m \u001b[38;5;66;03m# calling bind()).\u001b[39;00m\n\u001b[0;32m--> 384\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43minner_args\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43minner_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 385\u001b[0m arguments \u001b[38;5;241m=\u001b[39m signature\u001b[38;5;241m.\u001b[39mbind(\u001b[38;5;241m*\u001b[39minner_args, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39minner_kwargs)\u001b[38;5;241m.\u001b[39marguments\n\u001b[1;32m 386\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m is_varargs \u001b[38;5;129;01mand\u001b[39;00m arguments\u001b[38;5;241m.\u001b[39mget(name):\n", 1264 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:416\u001b[0m, in \u001b[0;36mFigureCanvasAgg.get_renderer\u001b[0;34m(self, cleared)\u001b[0m\n\u001b[1;32m 414\u001b[0m reuse_renderer \u001b[38;5;241m=\u001b[39m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lastKey \u001b[38;5;241m==\u001b[39m key)\n\u001b[1;32m 415\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m reuse_renderer:\n\u001b[0;32m--> 416\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrenderer \u001b[38;5;241m=\u001b[39m \u001b[43mRendererAgg\u001b[49m\u001b[43m(\u001b[49m\u001b[43mw\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mh\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfigure\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdpi\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 417\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lastKey \u001b[38;5;241m=\u001b[39m key\n\u001b[1;32m 418\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m cleared:\n", 1265 | "File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py:84\u001b[0m, in \u001b[0;36mRendererAgg.__init__\u001b[0;34m(self, width, height, dpi)\u001b[0m\n\u001b[1;32m 82\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mwidth \u001b[38;5;241m=\u001b[39m width\n\u001b[1;32m 83\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mheight \u001b[38;5;241m=\u001b[39m height\n\u001b[0;32m---> 84\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_renderer \u001b[38;5;241m=\u001b[39m \u001b[43m_RendererAgg\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mwidth\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mheight\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdpi\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 85\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_filter_renderers \u001b[38;5;241m=\u001b[39m []\n\u001b[1;32m 87\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_update_methods()\n", 1266 | "\u001b[0;31mValueError\u001b[0m: Image size of 2354x1466823 pixels is too large. It must be less than 2^16 in each direction." 1267 | ] 1268 | }, 1269 | { 1270 | "data": { 1271 | "text/plain": [ 1272 | "
" 1273 | ] 1274 | }, 1275 | "execution_count": 36, 1276 | "metadata": {}, 1277 | "output_type": "execute_result" 1278 | } 1279 | ], 1280 | "source": [ 1281 | "qc_transpiled.draw()" 1282 | ] 1283 | }, 1284 | { 1285 | "cell_type": "markdown", 1286 | "id": "edaa3f49-6fe8-498a-979f-f84a3b6cbfe9", 1287 | "metadata": { 1288 | "slideshow": { 1289 | "slide_type": "-" 1290 | }, 1291 | "tags": [] 1292 | }, 1293 | "source": [ 1294 | "What we see is that the Hadamard gate and the CX-gate got transpiled into other Gates. This is not surprising for the Hadamard gate, since none of the IBM Quantum devices support it directly. A Hadamard is always constructed using 3 rotations. On the other hand, the ECR-gate which you see is new, and only used in some devices. It is also an entangling gate, similar to the CX-gate, but it works a bit different. A CX-gate can be made using only a single ECR-gate and local rotations.\n", 1295 | "\n", 1296 | "You can find more about the ECR-gate here: https://qiskit.org/documentation/stable/0.39/stubs/qiskit.circuit.library.ECRGate.html \n", 1297 | "\n", 1298 | "Reducing depth is often the best way to minimize the error rate. Now that you know that the ECR-gate is used instead, could you make a circuit with a better depth?\n", 1299 | "\n", 1300 | "If you are interested in exploring that question and other methods to make the GHZ-state better, feel free to read on. The following part of the Lab is just a bonus: there are no exercises left. It is meant as a short outlook to show how error correction could be used, but also showing why error correction can be hard. \n" 1301 | ] 1302 | }, 1303 | { 1304 | "cell_type": "markdown", 1305 | "id": "0d92d49b-f0e9-491d-9178-b6535bb9f00c", 1306 | "metadata": {}, 1307 | "source": [ 1308 | "Whether you choose to continue or not, give yourself a round of applause: **You have just completed the IBM Quantum Challenge: Spring 2023!** Go brag about it to everyone else in the Discord, we'll see you there!" 1309 | ] 1310 | }, 1311 | { 1312 | "cell_type": "markdown", 1313 | "id": "9a82183f-8bc3-45e8-a7a0-d08a3e21824b", 1314 | "metadata": { 1315 | "slideshow": { 1316 | "slide_type": "-" 1317 | }, 1318 | "tags": [] 1319 | }, 1320 | "source": [ 1321 | "# Bonus: The Way to Correcting Errors\n", 1322 | "\n", 1323 | "\n", 1324 | "Error correction is still an active and important research topic. So correcting errors on a real device, even in a simple case like our GHZ-state example, is not that straight forward and we want to give you the opportunity to come up with your own ideas, while giving you some guidance and hints on what potential ways could be.\n", 1325 | "\n", 1326 | "\n", 1327 | "\n", 1328 | "## Step 1: How good is the actual State?\n", 1329 | "\n", 1330 | "Before we can correct any errors, we first need to know how good the state was, and even this is not as straight forward as one might think.\n", 1331 | "\n", 1332 | "\n", 1333 | "The simplest way for testing how good your GHZ-state was, is to test how many of the even numbered qubits have different results from the majority. This is what you have most likely used above.\n", 1334 | "\n", 1335 | "\n", 1336 | "However, this does not necessarily mean that this also correlated with the number of errors which occurred . And one could say that the number of errors which occurred is more important, for telling how good the GHZ-state is.\n", 1337 | "\n", 1338 | "\n", 1339 | "**Example A** to illustrate this thought: Let's say we have 10 qubits connected in a line and form a GHZ-state with them:\n", 1340 | "\n", 1341 | "0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9\n", 1342 | "\n", 1343 | "If we now say that error occurred not in the readout, but when applying the entangling gate between qubit 4 and qubit 5 the output could look like this:\n", 1344 | "\n", 1345 | "0000011111 \n", 1346 | "\n", 1347 | "This would be the worst possible result for the measurement \"how many qubits have the same result\".\n", 1348 | "\n", 1349 | "For this reason a run in which more errors occurred, could actually lead to a better measure for \"how many qubits have the same result\" although most likely that state would be a lot less useful.\n", 1350 | "\n", 1351 | "If the above state would have been created and you had (working) stabilizer measurements between the qubits, you would only have the one between qubit 4 and 5 be 1. And to correct that error you could potentially just flip qubits 5-9.\n", 1352 | "\n", 1353 | "\n", 1354 | "To get a first idea on how the errors look like for your case, it might be a good idea, to look at the raw data, the results which you got from running it on the actual device, and taking into account how you built the GHZ-state.\n", 1355 | "\n", 1356 | "\n", 1357 | "For **Example A** we could maybe find an error correction which would look like this:\n" 1358 | ] 1359 | }, 1360 | { 1361 | "cell_type": "code", 1362 | "execution_count": null, 1363 | "id": "4d96b276-ccbd-4183-8d44-6055cea976b7", 1364 | "metadata": { 1365 | "slideshow": { 1366 | "slide_type": "-" 1367 | }, 1368 | "tags": [] 1369 | }, 1370 | "outputs": [], 1371 | "source": [ 1372 | "# Simple idea for Example A find where the error happened and flip accordingly\n", 1373 | "def correct_ghz():\n", 1374 | " qc = QuantumCircuit(quantum_register, classical_register)\n", 1375 | "\n", 1376 | " with qc.if_test((classical_register[9], 1)):\n", 1377 | " qc.x(quantum_register[9])\n", 1378 | "\n", 1379 | " with qc.if_test((classical_register[8], 1)):\n", 1380 | " qc.x(quantum_register[8])\n", 1381 | "\n", 1382 | " with qc.if_test((classical_register[8], 1)):\n", 1383 | " qc.x(quantum_register[9])\n", 1384 | "\n", 1385 | " with qc.if_test((classical_register[7], 1)):\n", 1386 | " qc.x(quantum_register[9])\n", 1387 | "\n", 1388 | " with qc.if_test((classical_register[7], 1)):\n", 1389 | " qc.x(quantum_register[8])\n", 1390 | "\n", 1391 | " with qc.if_test((classical_register[7], 1)):\n", 1392 | " qc.x(quantum_register[7])\n", 1393 | "\n", 1394 | " # ...\n", 1395 | "\n", 1396 | " # qc.barrier()\n", 1397 | " return qc\n", 1398 | "\n", 1399 | "\n", 1400 | "correcting_circuit = correct_ghz()" 1401 | ] 1402 | }, 1403 | { 1404 | "cell_type": "markdown", 1405 | "id": "76751955-fa29-40d8-a033-0949d94af4f2", 1406 | "metadata": { 1407 | "slideshow": { 1408 | "slide_type": "-" 1409 | }, 1410 | "tags": [] 1411 | }, 1412 | "source": [ 1413 | "And if we would now adapt the above code to our 54 GHZ case, we could build everything together:\n" 1414 | ] 1415 | }, 1416 | { 1417 | "cell_type": "code", 1418 | "execution_count": null, 1419 | "id": "ff234bbb-4ef5-461e-b6e0-2d23ba62ddba", 1420 | "metadata": { 1421 | "slideshow": { 1422 | "slide_type": "-" 1423 | }, 1424 | "tags": [] 1425 | }, 1426 | "outputs": [], 1427 | "source": [ 1428 | "# Everything together corrected\n", 1429 | "\n", 1430 | "error_corrected_ghz = (\n", 1431 | " ghz_circuit.compose(unentangle_circuit)\n", 1432 | " .compose(stabilizer_circuit)\n", 1433 | " .compose(correcting_circuit)\n", 1434 | " .compose(measure_circuit)\n", 1435 | ")" 1436 | ] 1437 | }, 1438 | { 1439 | "cell_type": "markdown", 1440 | "id": "c71cfe66-a165-47d6-b8d2-b819c4b0ccb4", 1441 | "metadata": { 1442 | "slideshow": { 1443 | "slide_type": "-" 1444 | }, 1445 | "tags": [] 1446 | }, 1447 | "source": [ 1448 | "## Step 2: Why considering single stabilizers might not be enough.\n", 1449 | "\n", 1450 | "In the error correction exercise, we have seen that you could either use single bits, or the whole bitstring from the measurement of the stabilizer qubits in order to condition operations on them.\n", 1451 | "\n", 1452 | "Since our stabilizer measurements are 54 bits long, using the whole bit strings to condition on them, is not feasible, since this would need 2^54 different bitstrings which need to be considered.\n", 1453 | "\n", 1454 | "\n", 1455 | "On the other hand, if we just consider single bit it might not be possible/overly complicated.\n", 1456 | "\n", 1457 | "\n", 1458 | "**Example B**: We have again 10 qubits connected in a line and form a GHZ-state with them:\n", 1459 | "\n", 1460 | "0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9\n", 1461 | "\n", 1462 | "Now we assume that we get as the measurement result 0000010000\n", 1463 | "\n", 1464 | "If we have stabilizer measurements in this case the one on the right of the 1 and the one on the left of the 1 would both have value 1.\n", 1465 | "\n", 1466 | "This means in this case just looking at a single stabilizer would not be enough to know that you only need to flip qubit number 5 (and no others), unless we would be ok with flipping some qubits several times, which is not ideal. \n", 1467 | "\n", 1468 | "So in this case it would be ideal if we could apply functions to the measurement results of the stabilizers, and use their results for as conditions in the dynamic circuits. \n", 1469 | "\n", 1470 | "This is possible, however, this needs to be done in Open QASM3 code, instead of in Qiskit, which will not be covered in this exercise.\n", 1471 | "If you are interested to learn more about Dynamic Circuits with Open QASM3 you can find information about it here: \n", 1472 | "\n", 1473 | "https://quantum-computing.ibm.com/services/resources/docs/resources/manage/systems/dynamic-circuits/Dynamic-Circuits-basics-with-OpenQASM3\n", 1474 | "\n", 1475 | "\n", 1476 | "Below is a simple example to show you how Open QASM3 code looks like:\n" 1477 | ] 1478 | }, 1479 | { 1480 | "cell_type": "code", 1481 | "execution_count": null, 1482 | "id": "4e502711-6741-4082-a055-ff4f03dbef11", 1483 | "metadata": { 1484 | "slideshow": { 1485 | "slide_type": "-" 1486 | }, 1487 | "tags": [] 1488 | }, 1489 | "outputs": [], 1490 | "source": [ 1491 | "from qiskit import qasm3, QuantumCircuit, transpile\n", 1492 | "\n", 1493 | "# Creating a bell circuit\n", 1494 | "qc_bell = QuantumCircuit(2, 2)\n", 1495 | "qc_bell.h(0)\n", 1496 | "qc_bell.cx(0, 1)\n", 1497 | "qc_bell.measure(0, 0)\n", 1498 | "qc_bell.measure(0, 1)\n", 1499 | "\n", 1500 | "# Transpiling it for our device (as above it does not have the H- and CX- Gates)\n", 1501 | "qc_bell = transpile(qc_bell, backend)\n", 1502 | "\n", 1503 | "# Generate qasm3 code before we can print it\n", 1504 | "exporter = qasm3.Exporter(\n", 1505 | " includes=[], disable_constants=True, basis_gates=backend.configuration().basis_gates\n", 1506 | ")\n", 1507 | "print(qasm3_bell := exporter.dumps(qc_bell))\n", 1508 | "\n", 1509 | "# Draw a circuit as comparison\n", 1510 | "qc_bell.draw(output=\"mpl\", idle_wires=False)" 1511 | ] 1512 | }, 1513 | { 1514 | "cell_type": "markdown", 1515 | "id": "9ff29862-0ee6-45d4-89cb-b1081041c84f", 1516 | "metadata": { 1517 | "slideshow": { 1518 | "slide_type": "-" 1519 | }, 1520 | "tags": [] 1521 | }, 1522 | "source": [ 1523 | "## Step 3: How not to introduce more Errors\n", 1524 | "\n", 1525 | "\n", 1526 | "There are different reasons which can lead to errors. Decoherence over time and errors introduced in entangling gates like the CX-Gate are two of them. Both of them can also apply to the stabilizers and we have to make sure to not introduce more noise by our attempts of correcting it, since that would beat the whole purpose. This might be less of a problem in the future, when the general error rate will go further down, but is still something which needs to be considered.\n", 1527 | "\n", 1528 | "What does this mean for us?\n", 1529 | "\n", 1530 | "Well one can think of when we want to create and measure the stabilizers. Do we unentangle them directly after they are no longer used for entangling the next qubit? Do we wait until the whole circuit is entangled? (This of course depends on which kind of errors we might want to correct). We can also think about resetting the stabilizers and create new ones later (using the same qubits) and use 2 phases in which we try to correct errors.\n", 1531 | "\n", 1532 | "\n", 1533 | "\n", 1534 | "And we can think of what the probability is that an error occurred from entangling a qubit (through the stabilizer) and compare it to the probability that an error is introduced in the stabilizer by unentangling it. So maybe having the stabilizers just makes it worse?\n", 1535 | "\n", 1536 | "When is this worth it? You can play around with the code below to get some impressions and ideas, again this is something which can change in the future, when error rates will go further down." 1537 | ] 1538 | }, 1539 | { 1540 | "cell_type": "code", 1541 | "execution_count": null, 1542 | "id": "2e2e7294-df6e-4d99-bcce-5469c09a40df", 1543 | "metadata": { 1544 | "slideshow": { 1545 | "slide_type": "-" 1546 | }, 1547 | "tags": [] 1548 | }, 1549 | "outputs": [], 1550 | "source": [ 1551 | "# All the probabilities here only consider errors introduced by the CX gate and assumes they are bit flip errors.\n", 1552 | "\n", 1553 | "# Probability for a single CX gate\n", 1554 | "p1 = 0.01\n", 1555 | "# Probability that there is an error after 2 CX gates (going through stabilizer)\n", 1556 | "p2 = p1 * (1 - p1) + (1 - p1) * p1\n", 1557 | "# Probability that the stabilizer shows something wrong even though it is correct\n", 1558 | "p3 = p1 * p1 + (1 - p1) * (1 - p1) * p1\n", 1559 | "\n", 1560 | "print(\"Probability of a single cx having an error: {}\".format(p1))\n", 1561 | "print(\"Probability of having an error after 2 cx: {:.4f}\".format(p2))\n", 1562 | "print(\"Probability of the stabilizer showing a non existent error: {:.4f}\".format(p3))" 1563 | ] 1564 | }, 1565 | { 1566 | "cell_type": "markdown", 1567 | "id": "a122c390-a440-4ad0-9838-deb55ecd1d17", 1568 | "metadata": { 1569 | "slideshow": { 1570 | "slide_type": "-" 1571 | }, 1572 | "tags": [] 1573 | }, 1574 | "source": [ 1575 | "## Step 4: What can one do?\n", 1576 | "\n", 1577 | "There are a lot of possibilities you can try:\n", 1578 | "\n", 1579 | "\n", 1580 | "\n", 1581 | "- You can try to find some good logical functions using several stabilizers and use QASM3\n", 1582 | "\n", 1583 | "- You can think about resetting the stabilizers and reusing them.\n", 1584 | "\n", 1585 | "- You can try if the simple approach as seen in example A could be made to work (by changing the timing of when the measurements are made.)\n", 1586 | "\n", 1587 | "- You can find your own idea! be creative!\n", 1588 | "\n", 1589 | "\n", 1590 | "What is important for all of them is that you not just blindly start trying on the quantum computer, but instead try to verify your ideas first using the data of letting the initial GHZ-state run on the device.\n", 1591 | "\n", 1592 | "You have created testing data above: You have the output of the GHZ-state and also the output of the stabilizers.\n", 1593 | "\n", 1594 | "\n", 1595 | "If your approach does not work as postprocessing, then running it on the actual device, where all the operations have a further error rate, will also not work.\n", 1596 | "\n", 1597 | "When you have an algorithm which works in theory with the data you have (and generated better GHZ-state according to your test you can use the code below to try to let your whole circuit, including the error correction, run on the actual device. \n", 1598 | "\n", 1599 | "*Hint: Make sure you use the error_correction function above and also generate the error_corrected_ghz above.*" 1600 | ] 1601 | }, 1602 | { 1603 | "cell_type": "code", 1604 | "execution_count": null, 1605 | "id": "e073f632-2e2d-4d53-b615-d86c8ef5c5e2", 1606 | "metadata": { 1607 | "slideshow": { 1608 | "slide_type": "-" 1609 | }, 1610 | "tags": [] 1611 | }, 1612 | "outputs": [], 1613 | "source": [ 1614 | "# First we transpile the GHZ-state for the actual device\n", 1615 | "qc_corrected_transpiled = transpile(\n", 1616 | " error_corrected_ghz, backend, initial_layout=initial_layout\n", 1617 | ")\n", 1618 | "\n", 1619 | "# Now we can run the job\n", 1620 | "job_corrected = backend.run(\n", 1621 | " qc_corrected_transpiled,\n", 1622 | " dynamic=True,\n", 1623 | " shots=number_of_shots,\n", 1624 | " memory=True,\n", 1625 | " job_tags=[\"dynamic\", \"spring_challenge\"],\n", 1626 | ")\n", 1627 | "\n", 1628 | "job_id = job_corrected.job_id()\n", 1629 | "print(job_id)" 1630 | ] 1631 | }, 1632 | { 1633 | "cell_type": "code", 1634 | "execution_count": null, 1635 | "id": "d43fa5a3", 1636 | "metadata": {}, 1637 | "outputs": [], 1638 | "source": [ 1639 | "job_corrected = provider.retrieve_job(job_id)\n", 1640 | "job_corrected.status()" 1641 | ] 1642 | }, 1643 | { 1644 | "cell_type": "code", 1645 | "execution_count": null, 1646 | "id": "5c8bb7c6", 1647 | "metadata": {}, 1648 | "outputs": [], 1649 | "source": [ 1650 | "# And get the results back\n", 1651 | "counts_corrected = job_corrected.result().get_counts()" 1652 | ] 1653 | } 1654 | ], 1655 | "metadata": { 1656 | "celltoolbar": "Slideshow", 1657 | "kernelspec": { 1658 | "display_name": "Python 3 (ipykernel)", 1659 | "language": "python", 1660 | "name": "python3" 1661 | }, 1662 | "language_info": { 1663 | "codemirror_mode": { 1664 | "name": "ipython", 1665 | "version": 3 1666 | }, 1667 | "file_extension": ".py", 1668 | "mimetype": "text/x-python", 1669 | "name": "python", 1670 | "nbconvert_exporter": "python", 1671 | "pygments_lexer": "ipython3", 1672 | "version": "3.10.8" 1673 | }, 1674 | "widgets": { 1675 | "application/vnd.jupyter.widget-state+json": { 1676 | "state": {}, 1677 | "version_major": 2, 1678 | "version_minor": 0 1679 | } 1680 | } 1681 | }, 1682 | "nbformat": 4, 1683 | "nbformat_minor": 5 1684 | } 1685 | -------------------------------------------------------------------------------- /Images/Completion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/4808e677cbaf816ded7eb868845b8dfae3a6d98c/Images/Completion.png -------------------------------------------------------------------------------- /Images/Lab1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/4808e677cbaf816ded7eb868845b8dfae3a6d98c/Images/Lab1.png -------------------------------------------------------------------------------- /Images/Lab2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/4808e677cbaf816ded7eb868845b8dfae3a6d98c/Images/Lab2.png -------------------------------------------------------------------------------- /Images/Lab3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/4808e677cbaf816ded7eb868845b8dfae3a6d98c/Images/Lab3.png -------------------------------------------------------------------------------- /Images/Lab4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/4808e677cbaf816ded7eb868845b8dfae3a6d98c/Images/Lab4.png -------------------------------------------------------------------------------- /Images/Lab5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/4808e677cbaf816ded7eb868845b8dfae3a6d98c/Images/Lab5.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IBM Quantum Spring Challenge 2023 2 | 3 | **May 17 — May 25** 4 | 5 | Welcome to the IBM Quantum Challenge, we’re glad you’ve taken on this unique experience. We have many resources to help you, such as the [Qiskit Textbook](https://qiskit.org/learn/) and our [YouTube channel](https://www.youtube.com/Qiskit). We also have an amazing group of mentors who can provide gentle hints towards your solutions, found on Discord. The links for all of these can be found in your registration confirmation email. 6 | 7 | The Challenge runs from May 17th to May 24th, please submit all your labs by May 24th at 5pm ET. Access to the Challenge Portal will stay open until May 31st, so if you’d like to revisit the material you may until then. After May 31st the content will be accessible via GitHub. 8 | 9 | ![Completion](Images/Completion.png) 10 | 11 | --- 12 | 13 | ## Lab 1 : Intro to Dynamic Circuits : [Notebook](https://nbviewer.org/github/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/blob/main/Code/lab1.ipynb) 14 | 15 | This lab consists of simple exercises where you will create small circuits to understand what dynamic circuits are and how they work. There will be also exercises about dynamic circuit gates that simulate the classical `if` statement. Finally we’ll introduce you to the "repeat until success" method. 16 | 17 | ![Lab1](Images/Lab1.png) 18 | 19 | --- 20 | 21 | ## Lab 2 : Quantum Teleportation : [Notebook](https://nbviewer.org/github/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/blob/main/Code/lab2.ipynb) 22 | 23 | In this lab we’ll be sending a quantum message from one person to another. The only issue? Once a superposition is observed, the message is destroyed. This lab walks through the theory behind that problem, and the clever solution called Teleportation. 24 | 25 | ![Lab2](Images/Lab2.png) 26 | 27 | --- 28 | 29 | ## Lab 3 : Iterative Phase Estimation : [Notebook](https://nbviewer.org/github/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/blob/main/Code/lab3.ipynb) 30 | 31 | Iterative Phase Estimation (IPE) is a variant of the phase estimation algorithm which requires the use of only one auxiliary qubit. Because it requires mid-circuit measurements and classical feedforward operations, IPE could not be executed on IBM Quantum hardware before the introduction of dynamic circuits. In this lab, we will use the newly introduced dynamic circuits capabilities to implement IPE. 32 | 33 | ![Lab3](Images/Lab3.png) 34 | 35 | --- 36 | 37 | ## Lab 4 : Quantum Error Correction : [Notebook](https://nbviewer.org/github/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/blob/main/Code/lab4.ipynb) 38 | 39 | In this lab we’ll dive into Error Correction, starting from how it’s used on classical data, and then demonstrating (some of) our approach for quantum computers. We’ll explore how to use a bit flip code, and conclude with a conversation about how to run error correction on a real device. 40 | 41 | ![Lab4](Images/Lab4.png) 42 | 43 | --- 44 | 45 | ## Lab 5 : 127Q System : [Notebook](https://nbviewer.org/github/ashishpatel26/IBM-Quantum-Challenge-Spring-2023-Challenge/blob/main/Code/lab5.ipynb) 46 | 47 | In the final lab we’ll explore how to combine our knowledge of dynamic circuits and error correction to create a GHZ state on one of IBM’s 127-qubit processors. You will try to modify the GHZ state with additional qubits as stabilizers. Please have patience, no one has ever offered a quantum computer of this type to the public before! 48 | 49 | ![Lab5](Images/Lab5.png) 50 | 51 | ### Thanks For Reading 🙏🙏🙏 52 | --------------------------------------------------------------------------------