{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Grover's Search Algorithm" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Use Braket SDK Cost Tracking to estimate the cost to run this example\n", "from braket.tracking import Tracker\n", "t = Tracker().start()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this tutorial, we provide a step-by-step walkthrough explaining Grover's quantum algorithm. We show how to build the corresponding quantum circuit with simple modular building blocks using the Braket SDK. Specifically, we demonstrate how to build custom gates that are not part of the basic gate set provided by the SDK. A custom gate can used as a core quantum gate by registering it as a subroutine. \n", "\n", "After building the circuit, we will run it on two types of devices: 1) classical simulator, and 2) ion-based quantum machine provided by IonQ. For the latter, we will demonstrate how to recover quantum tasks that may be waiting in queue.\n", "\n", "1. [Introduction](#introduction)\n", "2. [Background: What is a Quantum Oracle?](#background)\n", "3. [Anatomy of Grover's Algorithm](#steps)\n", "4. [Circuit Diagram](#diagram)\n", "5. [Code](#code)\n", " 1. [Libraries and Parameters](#setup)\n", " 2. [Helper Functions](#wrappers)\n", " 3. [Device: Classical Simulator](#sim_c)\n", " 4. [Device: IonQ](#ionq)\n", "6. [References](#ref)\n", "\n", "This tutorial is based on ion-trap experiments published as *C. Figgatt, D. Maslov, K. A. Landsman, N. M. Linke, S. Debnath & C. Monroe (2017), \"Complete 3-Qubit Grover search on a programmable quantum computer\", Nature Communications, Vol 8, Art 1918, doi:10.1038/s41467-017-01904-7, arXiv:1703.10535*. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Grover's algorithm is arguably one of the canonical quantum algorithms that kick-started the field of quantum computing. In the future, it could possibly serve as a hallmark application of quantum computing. Grover's algorithm allows us to find a particular register in an unordered database with $N$ entries in just $O(\\sqrt{N})$ steps, compared to the best classical algorithm taking on average $N/2$ steps, thereby providing a __quadratic speedup__.\n", "\n", "For large databases (with a large number of entries, $N$), a quadratic speedup can provide a significant advantage. For a database with one million entries, a quantum computer running Grover's algorithm would need about 1000 runs, while a classical computer would need, on average, $500$k runs.\n", "\n", "Research has been shown that any optimal quantum solution to an unstructured search problem has a speed limit of $O(\\sqrt{N})$ runtime. This research finding matches the performance of Grover's algorithm, thus proving that the algorithm is asymptotically optimal [2]. In fact, Grover's algorithm can be generalized to accelerate any type of search where one can construct a quantum oracle, as described in the next section. \n", "\n", "Consider the following problem [2]: \n", "In a search space with $N$ elements, we are searching the index of those elements, which is a number in the range $0, 1, \\dots, N-1$. \n", "We have $n$ bits at our disposal, with which we can store up to $2^{n}$ elements. \n", "Our search problem can then be expressed with the help of a function $f$, which takes as input an element out of our set of indices (that is, an integer $x$) and generates two possible outputs: $f(x^{*})=1$, if $x^{*}$ is the solution to the search problem or $f(x)=0$ otherwise (if $N<2^{n}$ we can just set $f(x)=0$ for all extra unused elements). \n", "This is done with the help of a quantum oracle, which recognizes solutions to the search problem. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Background: What is a Quantum Oracle? " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Grover's algorithm, like many other quantum algorithms, utilizes the concept of a quantum oracle which we will denote as $\\mathcal{O}$. In essence, an oracle $\\mathcal{O}$ is a black-box operation that serves as a subroutine to another algorithm. Typically, oracles are defined using a classical function $f:\\{0,1\\}^{n} \\rightarrow \\{0,1\\}^{m}$, that maps an $n$-input bitstring to an $m$-output bitstring. With $x \\in \\{0,1\\}^{n}$, i.e., $x=(x_{0}, x_{1}, \\dots, x_{n-1})$ is a bitstring vector, and $y \\in \\{0,1\\}^{m}$, the oracle $\\mathcal{O}$ is a unitary operator, commonly defined by its effect on an arbitrary computational basis state as:\n", "\n", "$$\\mathcal{O} (\\left|x\\right> \\otimes \\left|y\\right>) = \\left|x\\right> \\otimes \\left|y \\oplus f(x)\\right>,$$ where $\\oplus$ denotes addition modulo 2. \n", "\n", "This means that the second qubit register of size $m$ stores the result of the computation. \n", "For $m=1$, which is the scenario we will focus on here, the second register $\\left|y\\right>$ is a single qubit that is flipped if (and only if) $f(x)=1$. \n", "In short, the quantum oracle flips the ancilla qubit only if the function $f(x)$ evaluates to one. \n", "Accordingly, we can check if $x$ is a solution to our search problem by first preparing the state $\\left|x\\right> \\otimes \\left|0\\right>$, then applying the oracle $\\mathcal{O}$ to that state, before finally measuring the state of the oracle qubit. \n", "\n", "In Grover's algorithm, it is useful to initialize the oracle qubit in a superposition, as $\\left|y\\right> = (\\left|0\\right> - \\left|1\\right>)/\\sqrt{2}$. \n", "We can distinguish two cases: \n", "(i) If $x$ is not a solution to our search problem (i.e., $f(x)=0$), then the application of the oracle operator $\\mathcal{O}$ to the input state $\\left|x\\right> \\otimes (\\left|0\\right> - \\left|1\\right>)/\\sqrt{2}$ leaves this state simply untouched. \n", "(ii) Conversely, if $x$ is a solution to our search problem (i.e., $f(x)=1$), then the oracle states $\\left|0\\right>$ and $\\left|1\\right>$ are flipped, such that the state picks up a minus sign, giving the final output state $-\\left|x\\right> \\otimes (\\left|0\\right> - \\left|1\\right>)/\\sqrt{2}$. \n", "Note that global phase factors do not matter in quantum computing, but the relative minus sign we encounter here does make all the difference for a superposition state, which would include the solution among all other possible input states. \n", "\n", "For both cases (i) and (ii), the action of the oracle can be summarized as: \n", "\n", "$$\\left|x\\right> \\otimes (\\left|0\\right> - \\left|1\\right>)/\\sqrt{2} \\longrightarrow (-1)^{f(x)} \\left|x\\right> \\otimes (\\left|0\\right> - \\left|1\\right>)/\\sqrt{2}.$$ \n", "Accordingly, the solution to our search problem gets *marked* by shifting the corresponding phase. \n", "Because the oracle qubit remains unchanged, one can omit this oracle qubit from further discussion and simply express the action of the oracle as: \n", "\n", "$$\\left|x\\right> \\longrightarrow (-1)^{f(x)}\\left|x\\right>.$$ \n", "\n", "This expression also captures the definition of a *phase oracle*, which will be used in our examples below. \n", "If a phase oracle is applied on a computational basis state $\\left|x\\right>$, then we only get a global phase that is not observable. However, when applied to a superposition of computational basis states, this phase oracle becomes a powerful tool. As it turns out, the search oracle needs to be applied only $O(\\sqrt{N})$ times to obtain the solution with high probability [2]; more generally, if there are $G$ solutions, the oracle needs to be applied only $O(\\sqrt{N/G})$ times). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Anatomy of Grover's Algorithm " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this tutorial, we will be working with three bits $(n=3)$, leading to eight possible items $(N=2^{3}=8)$. \n", "To find a given target item, Grover's algorithm uses the following steps:\n", "\n", "1. **Initialize**: Start with a uniform superposition of all possible bit strings by applying Hadamard gates. This will result in all inputs having the same amplitude. Since we do not have any prior knowledge about the solution, we initialize to an equal superposition of all possible candidate solutions. \n", "\n", "2. **Oracle**: Item bits are then passed through an oracle. The oracle produces only two results. If it detects the target item, its amplitude will be flipped to negative. For all other items, their amplitudes will remain positive. Because the oracle is specifically engineered to change amplitudes based on a certain bit pattern, each target item would have its own associated oracle.\n", "\n", "3. **Amplification**: While the oracle in step 2 distinguishes the target item by flipping its amplitude in the negative direction, this difference remains too small to detect. Hence, we use a trick to magnify the difference in amplitudes; by flipping every amplitude around the mean amplitude. Recall that only the target item's amplitude was flipped to negative. In other words, the mean amplitude would still be positive, and its value would only be slightly lower than the amplitudes of other items. By flipping all amplitudes about the mean, the amplitudes of non-target items would decrease only slightly. On the other hand, the amplitude of the target item, being much less than the mean value to start, would be reflected back up into the positive direction by a large margin.\n", "\n", "4. **Repeat**: By repeating steps 2 and 3, we can magnify the amplitude of the target item to a point where it can be identified with overwhelming probability. To get to this point, we need to repeat these steps approximately $\\sqrt{N}$ times (again assuming a single solution and large $N$). As discussed in more detail in our Quantum Amplification Algorithm (QAA) tutorial, to ensure we measure a solution with high probability, we apply the Grover iterator $\\left\\lfloor\\frac{\\pi}{4\\theta}\\right\\rfloor=\\left\\lfloor\\frac{\\pi}{4}\\sqrt{\\frac{N}{G}}\\right\\rfloor$ times, with $G$ denoting the number of solutions. Since we may not know $G$ in advance, we not know the ideal number of iterations a priori. To address this issue, however, we may use quantum counting techniques with the help of the phase estimation procedure (QPE); for details we refer to Ref.[2]. \n", "\n", "5. **Measurement**: Measure the resulting amplitudes to identify the target item." ] }, { "attachments": { "image.png": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA/8AAAD+CAYAAABstrVuAAABQWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAAYY8DCKJycUFjgEBPkAlDDAaFXy7xsAIoi/rgsyyidpR4W293KfOps2wYflcFUz1KIArJbU4GUj/AeK05IKiEgYGxhQgW7m8pADE7gCyRYqAjgKy54DY6RD2BhA7CcI+AlYTEuQMZN8AsgWSMxKBZjC+ALJ1kpDE05HYUHtBgMcpNS9Qwd3HyNzMgIBzSQclqRUlINo5v6CyKDM9o0TBERhKqQqeecl6OgpGBkZAK0FhDlH9+QY4LBnFOBBimTIMDOaXgIJOCLG0RwwMu7IYGHg3I8TUgP7iPcrAcMSiILEoEe4Axm8sxWnGRhA293YGBtZp//9/DmdgYNdkYPh7/f//39v///+7jIGB+RYDw4FvAP8RXwRJQkptAAACC2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjE8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb24+MjwvdGlmZjpQaG90b21ldHJpY0ludGVycHJldGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KD0UqkwAAQABJREFUeAHt3QeAJFWd+PG3u7OBDSyw7BKWJFFyRhAR1MO/4olwZ0AMIKjcnQEDhwh4gNwZQT3hUBAwIWA8UAE5ki6o5AwCShCWzC4ZFjb951vwhpqa6p7unuqa6u7vg97urq56VfWp7pr6vVRjlvanYFJAAQUUUEABBRRQQAEFFFBAga4VGNu1e+aOKaCAAgoooIACCiiggAIKKKBAImDw7xdBAQUUUEABBRRQQAEFFFBAgS4XMPjv8gPs7imggAIKKKCAAgoooIACCihg8O93QAEFFFBAAQUUUEABBRRQQIEuFzD47/ID7O4poIACCiiggAIKKKCAAgooYPDvd0ABBRRQQAEFFFBAAQUUUECBLhcw+O/yA+zuKaCAAgoooIACCiiggAIKKGDw73dAAQUUUEABBRRQQAEFFFBAgS4X6Ovy/XP3FFBAAQUUUEABBRRQQAEFOlhg3rx54cknn0z2YOzY/vrrMf0vl/Y/eO6kxDb3p6VsfP//S5YsCePH94VZs1YKkyZNeunDNv5r8N9GXLNWQAEFFFBAAQUUUEABBRQYmcC1114b5syZE6ZOnRqmTJkSxo0bF5YuXRrGjOms6J9tjmnRokVJgcbkyZPD3nvvHVZZZZX4UdueDf7bRmvGCiiggAIKKKCAAgoooIACIxW45ZZbwjnnnBM233zzsPrqq4cJ4ycMBP9JLXpqBWP6mwMwjeeY4vvsvHyenT87b/w8PW98zXPMM64vvuezIYnY/+XNWrBgQbjhhhvCs88+G3bbbTeD/yFYTlBAAQUUUEABBRRQQAEFFOgpgWnTpoXtttsuqSHfcMMNkybynVrzT2sFtn3BCwvCueeeF373u9+Fvr5y6uTLWUtPfTXdWQUUUEABBRRQQAEFFFBAgaIECJgnTpwYKASYPn16mDBhQlFZj1o+E1+YGKb2d2Ho6+/CUFb3BYP/UTvcrlgBBRRQQAEFFFBAAQUUUGA4AWrKGRxv8eLFyYP3Van5j9vBM9tHYlBCAvpYyx+De+aJiT7/zM+09PT4eTueDf7boWqeCiiggAIKKKCAAgoooIAChQjEQDr9TMYxqC5kJS1kQtCe3oZ4RwJaKNA6IX4Wn9OrYFr6kf6sXa/775NgUkABBRRQQAEFFFBAAQUUUECBRgRibX18ZpkXX3wxXHPNNYHBCenPn/6skTzLmMfgvwxl16GAAgoooIACCiiggAIKKNAVAtTYx1p/Xi9cuDA8+OCD4aKLLgq33357WLJ4SbKfzFOlZLP/Kh0Nt0UBBRRQQAEFFFBAAQUUUKCyAjGgjwUA9O+fN29emDNnTtLXf6211koGJuTzqiVr/qt2RNweBRRQQAEFFFBAAQUUUECBSgrEoD9u3AsvvBD+/ve/J8H/uuuuGzbddNOkECAWEsTnOP9oPhv8j6a+61ZAAQUUUEABBRRQQAEFFOgIAQJ5HgMFAP2V+/fff3+46aabkgH+NtpoozBr1qxB81SpBYDN/jvia+ZGKqCAAgoooIACCiiggAIKjKYAgTy3HIzpxRdeTAL/v/zlL+GNb3xjWHvttcO4ceMGgn/mq1Lwb81/PHI+K6BAWwS++93vhi233DIcc8wxbcnfTBVQQIF2CVx99dXJ+esjH/lIePrpp9u1GvNVQAEF2i7w6U9/Orz+9a8Pp59+etvX1a0riLX+cf94T60/A/zxervttgszV5yZFA6k5+V1VZLBf1WOhNuhQJcKcPFM+slPfhL22muv8MADD3TpnrpbCijQbQLx/MXz2972thDfd9t+uj8KKND9Ar///e+TQsyvf/3r4TOf+YwFmk0ecgL42NQ/1uTHW/s9+eSTScHKjBkzwthxL4XXcR6e4+smV9mW2Q3+28JqpgookCdAySgFAJdccknex05TQAEFKitAzT8tAE488cTKbqMbpoACCjQiwHUY12Ncl5kaEyCAjwUALEHT/3vvvTfQ3H/69OlJrf/EiROTzGKwH5dpbA3lzNWzwT8lNffcc085yg2uhS/QQw891ODcztZuAS70KCXlQo8HzaQ8SY5cHVdKnO0GMDLL559/PjzxxBMjy2SYpa+88sph5hj68eLFi8NTTz019AOnlC5wzTXXDJy/OIdxPjONXICuTN3QDYCL2KuuuqohkL/97W8156v3Wc2FKv4B5zDOZc2kK664opnZC5n3kUceGdT3uFamnX7twnXDb37zm4HzGddjtiKsdbQbn44hBQB2AxjejPNl+sESCxYsCJdffnlYuHBh2HzzzcPMWTMH+vqnc4wFAelpo/m664P/5557LkyePDk8+uijg5wXLVoUPvCBD+SeNDfYYINw6aWXDpo/Lx9GdeSA5j0uuOCCQcvvtNNO4Ze//OWgadk3XJydfPLJ2cmD3h922GHhwAMPHDQt+yZvXX/4wx8SByzyHlzIpFPc37x5eyFoo0SUJp70j+JCjwfNpDhJYtXpf0jTx3q0XtsNoHl5/vCccMIJyR+ZZZddNqywwgphvfXWCwcffHCgMCAvZX/Lyy23XNhhhx3Cr3/967zZB03j+3/ZZZcNmlbrze9+97uw4447BraLEvCVV145HHrooTULKBo9l+Wdg3bfffdam+H0fgHOT5ynPvzhDw+cvziHcTw5r9nyZuRfk27oBnDhhReGz3/+88NiPPPMMzXnmz9/fjjiiCNy8+CcMGnSpIEHo1/z/ePaKZvOP//8sNVWW2UnD3pf65zB9LzzBOe6dBpuHQT8//Zv/xZe9apXJecw8tx5553DRRddlM4m9zUFsXvuuWd49tlncz9n4oorrph7vcj2p1Ot/Yzz3H333eGd73xnMpr4SiutlGzrG97whrrn6lNPPTWw/9n0ox/9KLzlLW/JTq7Ue66N+d78x3/8x8D5jOsxpvHdo2DANDKBTukGkA6+eT2SlM1ruPfpGnxeE/hTiXzjjTeG1VdfPWyxxRZh3NhxA79x8ksvM5JtLXrZrg/+AeOiOO9LwkXtV77ylSGmHND0KI5xhmw+G2+8cVLDxR+Mf//3fw8f/OAHB94z2mM6cf/HeqXItEQ45ZRTwve+972681G6xKNeylvXa1/72uT+k9yDMv04+uijw7Rp03Id2F8ucNLz85o/jt2cCIrq9YXCxAKAYr4BBCl2A2jMkvPSrrvumrSY+MIXvpD8Lrnw5sKIkmdKne+6667czPgt//GPf0yCQr6/XDgSGP7v//5v7vxMvOGGG8Kf/vSn5GKr5kwvf3DIIYckeRKUsy333Xdf+M53vhO4+N9jjz0Cha3Z1Oi57Nvf/vaQc9CPf/zjbHa+f1kgBv4c57xETQ/nt0YKf/KWd9orAgQd/C3gN9iJid/oxRdfHO644466m0/rgLPPPntIJQoLUWNI5UJe4jqKi2JaBvCgUoTrJgYcy56ruD7iHFcv1TpnMP0973nPkPNEtkVCvXXcdtttycU7zXePP/74pFaZ39A222wT3vGOd+QGzultJYh+8MEHwxlnnJGePOg1gQLXi1hSwMBrHtnCk1r7SWZnnXVWcq6ncJXzK4W7HB8C4be+9a3hqKOOGrTO+IZr4A996ENh3rx5cVLyjAnXjFVN2FBwWSvA5zzGb7DW51XdrypuVyd0A8hWtjbqmBfY5y7bH9STsuvJBvG8f+yxx5KKYkb133DDDZPCuGS+MPg2gEyrWuqJ4L8e+pFHHhloGtlKGjt2bBI4EzxPmDAhjB8/fuA9X4ZmEhfhr371qwOluOeee24zizY0L9s2c+bMQQ9O+v/1X/+V/KFjgIq8REl1djlKw7s1ceGc/UOct6/8oeEC2jRygWjZCy1KRqJFwE8NHKXMBO+rrrpqoGaLgkaac++yyy5h3333zS24ZL2zZ89OLsTXXXfd8NnPfjZ86lOfCl/+8pdrbhIXXB//+MfDb3/72+SPXK0Z+fykk05KzqOf+9znwqabbhpWW221pBaMi2daARx00EG1Fh92Oi0Jsucg8jTlC9QruEwvwXnOZrNpkdZf81vptABk7ty5SQuQAw44YNjCi9isNa/QjRplRromv7zEtQfnAx4UUH7ta19L+sVS8FBkWmaZZYacJ7h+aSRRSLHPPvuE3XbbLanlJ5BeZZVVknPZscceG/7v//4vObdS414rsT+c5+rt19SpU5NrRK6hstePtfJNT8eZAJ6KIgooaCnBfnPtyLrpdvCNb3wjKWRJLxdfUzjx0Y9+NL6t/DOBfSOFlFy3UXNtGrlA1bsBZIP44fY4VvwSgGcf6WXjfEv7zwW8Jj5avHjRy8+8XjyoEpmCSgowKXjjvEbwP5D6GyTEdQ1Mq9iLng/+999///C+970vKT0dzWNDU14uHnjU++NR5DZSg09TsXe9611FZtvReXER12jiJNnIH6ZG8+v1+ewGUPsbwIU1F3s//OEPAxeQ2cSF5Le+9a3kIrxebX56OS4cqaHPSxTIUINFiyYuhLnAr5UoSODCi+5S2cR2nXbaacmt0qihMrVXgN9QMwF9M+e79m555+dOQRe/lVotLqq2h7QypBCRriCcV+rVuhP8c77Ingeuv/76pEafAkXmaTRx69dahQWN5lHkfD/96U/D448/nrSq4pyVTbSc/NnPfpbU7Gc/4z01pgQHtCSli2krY6Xk5ZudRq0+rRBqXbNttNFG4atf/WrNiol/+qd/Smoqs8cxu56qvG+mRQ3jATRz7qvKPlZ1O6raDYAR9WnJSIFdDNizhnE6zwThPGcfcfk4nfe0uKEVDPk/++wzSWsSWuY8/czTSXceptNKm5aMd919V9J9icpffndUoJJHfxFDf+T/0hal188U3lcl9VVlQ0ZrO6hNu+6665JSUwLw0Ui33HJLuPnmm8M///M/J18qSnApYaZZWLsSf8hoqse666WXSr8GD3rDH0d+UN2Ymh0Qi9qzRloKdKNVO/YpdgPgwjQvmGzHOjshT2p0Ntlkk7om1CYRfPz5z39OziXD7RfNdWnSmpeo4eOCd4011kgKJCkkpSAg+7unCelf//rXpMltXj5M448jtWqtJv6gch5KJ7Yj7yI9PU8vvm428OSCmYepGAEKzSjAJ0ir8rgUXLwyvhAFheuvv35ybiEArvU7JbCnYInCAgJb7mNNIoik2xaJefh8uMRv+cwzzwyf+MQnhpu1qc/zzhNk0EgrTLo3EVQzPkGtxFhKtRIVNnSjYl377bdfUoETjWot08p0zu15XVXTeb373e8OH/vYx5LAhXNvOtGylFYDVHgxlsE666yT/rhSr7kWaDaY5++fqTgBCrU4Dvxes9+l4tbSXE433HhDeOThR5JYKXs9EnOK03mOAXcMxJmH15wDCfQJ+AnoKfzkmUeczvPSJUvDuL5xSetuWnjzYDR/xoXj7y0tL2MLo2S9Sez/yh0B0uuN2xW3czSfhxZxjubWjMK6+/r6kpopLnbPOeecUdiCkPRnYvBB/vBQq8fJu5kSz2Y3mn4qNOf95je/mQzKVW95mhZjlH50a213s39o6rn5WesCXEBboDLYjz651K4Nl5inVv9dLtQp4KRZKIE9g1jxOi9xMRubh3KRyEVt3mBRXBjQ9zSvNUJevq1Me+973zvo/MO5iNYGpqECNOs1jb4A5y/OY1VN9DmnK00MUOu1OKRpK7XiDOZJ0BhrjbkwpkCAoHf77bdPmpzn7S/jktAqiQeVLWuvvXbSvZFrkCIT10zp6xRe1yrczK6X8xgDp7aS+M1x7bhvf5crEsH/L37xi8QsmVDgPxS0Dvd3gEFg6RbFvHnp7W9/e+CcyjVntlA1b/7Rmlbl389omYzGerkurlKXivvuvS9Q+09hXwzsceF13iOa8RnnLL5XtM6hgpVKVwrUGIvkvPPOS7r3zJkzJyngpFUT43/cfsft4dZbb00qiamEoYKQgtJzzzk3aQlEQE93HMbzoDKEAT8pUEjSy4UP6e1iOu9HO/V8zT8HgJMpF8HUbuWNQtvOg8QXhYFiGHSHLyaJkzIl6F/84heTUqai18/dAvijyACFw6U777wzGcQiPV+90vH0fJ32uiolmyNxiyeVKpUwtrI/9Lc0vSJAn87h7hbC3FzwMW9e4o8cf/B4UOtHE1D642YTA6Fy+6h/+Id/GDgnca6gQCA7KjQX8g8//HDSbapdY4HQJJltTae87U5/3quv21kI06umrew3x6HKf0/4LVPLH685qDElGKcVJE3y04ka/c022yzpW06gT1dBKg5oMcI4IhQgsL8sT20aQXc60VQ2dgnA5PDDD08C5aJ/w2wb25VOjbYO4jyWHYAwnU+919Skv/nNb04CbjypXeduKj/4wQ+SLhX1lm32M1rDcY6v1yqOAITgiBYdtRLXuxxnxnxiQEZT8QJci8XrsPTr4tfU/hypBKxKojUiwXv2tx2t2U4KBvg8FhBQyPVMfzP+xx59LLleYXma8xN/URjAWEqcu6jR5xw1ZQp3RZuS3EGkb3xfWPjiwmRe5iePCy68IOkawO+cwj/yYLnll18+KVTl+pXXkyYtE8aOoyPASy2l09fn8fVouQ4+S4/WVlRgvZR8U3pLAUCZB4WSc76EeSXUlB7vvffeherwB5sBuijxaiTxR71XLij58bKvnAgaTfzIq3RijLU0a6655kBTpEb3pV3zUavSjCkXLRR8mV4R4AKb0mdGpK4V3POHid929gI45kJXCv4gcjsaLhBrXXzTOoDgn99DOlH7zxgB6YtFav0JAGg+TK1gXuLY01qIZrVTpkzJm6XutNgiqu5MfpgIZI/ZcCyc7+oFEsMt3wufU/PVTIsKTIe7Ze9ounE+ptUPj+ygtRQKMHhnOhG4U7NPImCkqTgFkYzlwfUSicGuaA7LHUK23nrrZFr8h/MDzYbbnTiftXqtwvmVgf24+1Gt8yKFpyQu+GMiqMCL82K2UuTee+9NBlVNByVxuVafabFFreM//uM/1syCzxl0tZ4F52GuPbnrQq2uHjVXUNIHrVxXce3Q7DmwXbvDOSO2JuW7Qbe9KqRmBzjfZZddwr/8y79UYdOTbSBWuvmmm8OE8RMGClf4IBu38dvkQX/9Rx95NMy9b26Ye//c8NBDDyXXo7SOYRBS7j7CLUj53nAOGzumv1vz2DFJa0d+u1wzkQ+JLgFchz340INh5oozk7trPPX0U0me3AmNgjkGYSYumL3a7DB71dlJYQCDcnL9lBQDpFoDFHluSDawiX8M/lNYXBxTws2Xo6zEH1tKjrO18FyA81mRwT/3oeVHzGi76Qv4sva1E9ZDrUYzfWAJUvMKbkZjX7ntT7xnM800+T7TtHO0EzUyjf7B4ftO33LTYAEuoGmxw3mCi/bsBQ4l3J/85CeTcUIIsmsl+qZx0cctobhIf81rXjNoVoJ+Anm6DmTHHOFWWlzocoGcTtylgVq/173udYFCp3SiJoxb/REwFHkuS6/D168IcP6iWWKjiQKbKl3YNbrdZc7HoIiNdsPjN0XhW/b3Web2Drcu9ofzCNcd6cT4PzTt5/fMHTZiIvhP98/nfM6gcrQKZNwQEhexBNDMmw3+Yz5Vfqa15X//938nrRLYt2yiSTDzcLvUdKKwlZYOBAXpC3lqETl/0qLzTW96U3qREb3mPvcEkRSmxLEW0hlSqcNtV+nWMVzadtttw2GHHZZ0xSDAq1oi+Oe71Oi1Qyx0q8pvj+4xxx13XMJKa5CqFAhmW/bUO+6MP1arUL/ecu38jOM8cdLEJEDnN0fQzyO+Zt0E60ktfX8XZ5rjc8vPWKFB5cnKK60cll1u2bDstGWTQjIKw2oV+qX3hYpaWk5yPUbB2Wabb5aMFcC6+IxKFQp8mId1EmdRIEUhA91xKAQa2/8fKb296XWU9fqlrShrbRVfD4FS7M9Wxqbyh5IvCSfxbF81/jhz0suroedLxhc6PgjqG0n0k11rrbWSi3Bq49KPWiP98qVOz8frgf4sjay0w+bhQrheiXl6d/jDVJXAn2ZM6du28R2pdb/f9D5U5TXmNEU08K99RI488shkRFlqdajdobaJPzb0V2MwKgat+v73vz/oIjQvN/rwc4FI1yK+N+nE+Y8gnv6v2XMSYwAQMHBhm06MUcLo07QoILAgKKDWg2avNIflnBEvgtLL8bqRcxnnpuw5qNb5Kpt/r71nkLlGgy9+c1W7sOvk48Ut87jAr0rwkWdJE3y60fBbzv6+uV0V55b07fz4ndH3Ndb8kyeFeLQwo5CRC9qY6vX7j/MM98y1Rbyu4bmsihgu/Ol+yb7TJ57BvGg6T7BPgMz5jWObbSVDBQ2tH1g+7clF/r79YwAUfTcNahQ5fnzXuFZh8EXOjRTcMBAgx4BzO4WAjSQqC2hNUNXUTMEk57Iq//aqapy3XXzPKGCq4t8HAvvYnD8G/el94JxFV0S6MHFtRJxF4RyFZq/f+fVJAee2220bNtpwoyQop6aeWvl0nrFAgWlxOncromaffAnqN9l0k6RbAKP8U+nBuZNWQVw/cY1Fd3LGV2NgdQoBGT/g0cceHYifWAcpXWiY3o92vzb4zwhTI8ZIqc0mTvyNlByl8+UPBz+uvL6yfCG5OM/740HNHaXK8VGrmW96XfwIuLAnQKBUn5Nk+vH+978/PfvAa/rCpefjdTffj53SZv7ID1cAQGleI+4DkG1+8aUvfSkJpNKr4cLl5z//eXpSJV9jSTDb6AVLJXeihI2iPxo1UIceemjSeofadAosqZWjFJo/Stma91qbRb9b3LmQ548biWdqOONAf9lld91116RZ3FlnnZX9KPzP//xP0tKEFktcIPM7YrsoEKAlDc3p8lIj5zKapWbPQfVaN+Stp5emcV7i2NZLnN+qHqjW2/4qfYYlrayaCVRGa/u5oOfCnhr+vJQd+O/aa69NfnvpwfBoLkswHJv8x3wIPLnQzqZmLm6pLYvXNTzT2qisROEHYz5x7bXnnnsmzxSq0qKOFg60YEonCjm5qGeAv7yED92d8rqM0JSY83kriSb/bCet+zgPcm4kgL/wwguTYIe/D40mgh4KPMijionKlUYqMSiw6YTfXxWNs9uEJddj2YKu7Hyj9Z7zSfLob0RPigUAFApQEfqXW/+S/C6vuuqqpPafGIbfMdcvW2+1ddIdluVjgB+X5zdJSp+v4mue+R1TKMj5gVv7rbD8SwWfLB8LCIgBGZOA8ysVHxQGcI1GqwPunHDZpZclBadUqsb18jwaaUz/ikdnzaOxtw2uk9JxDlajF9INZutsHSRA0x2a2GWbnMXasiqVMqeb+2eJqYHgto6j2c2jXrN/m/lnj1jj72lST4l21S7cOH8ywjcFAPGPZ+N75ZxFCDAAEQXHsVl2Os94oczxMQ0vgGOtZv+0sqh6M//h97D5ORh7hOCgm3/fjODNhX4r45Q0L9r6ErT+ogXGSI4FtZKM21DVxC3V+B1mr8coyCLor+JtNdPN/gkIG+mKUYZ/rWb/XNvS8rKKlmkXXKnooGUN/fUpRKPFEIVhtJRO+uT3B+o0tSf45jxFn/sYbKfz4jcTp6ef4zxM40FrAu4CQOEphYB0k6EQlJTOIy7HM8uRKJC48cYbk1ZEXLPxXaCgkZYBXLtR6MA1E2POUVhIC8/h7uiRZDzCf+zznwPIF8XAPwemhybFFgAUAvCIo3lWpZl/PBTZ5v5xenzmpMXtlThhxpLN+NloPvOHhovmqnmOpkmz6+aPXqu1R82uq5n5OX/SJ840egJcVHAhx4ML53j+4kKoaoVFo6c0sjXHptcjy6Uzl6416Ghn7k3+VnfKOYxmxyNNVQ782TeuE2iplL4e4xqtqrXTIz0eZS9PSzHGr+oUzxhwE2DTDZHvBd2TeHD9QStSmuUvv9zyQ1pkx2UxZvn4nueYYuAeP6NFEl1rGBgQo3TgzzJx2Th/nEY+tLSmkHjd9dYNV191dTIoKgUC1P7TVYC84vJx/WU8G/yXoew6OlaAPzBVriGjSRz9puslRmA+44wzKtN/q1dry+odIz9ToF0CFrAVK2vBZbGe5qZAowJVvx5rdD+qNB8twSgk7qRC4Ri0L16yODw1/6nAnTgI/Gniz/Ul3ZQIutPBOJVfLJcO7ONxSAff8XWcl77+tDRgjKXddtstiQdiXsxLk/9YsRa3K66D/Olagy1/NybuODHZrmuuviZcOufSpFURBW/MU3Yy+C9b3PUpUJAA/fmzow/Xyvr4449P+oWPZvN/tq2Xa8tqHRunK6BAZwhYcNkZx8mtVECB+gKd0sw/by8GguwlS8M9/QODMsAfgf8u/c3x1+of1JwxhtIBeCwEiIF9Xp5xWlyOeWlVwNge3MaPWv+tttoqCeKZJz0fr5k/vZ44jXzjuErcbYm7otBiky4KjCNAC6P0wKlxO9r9bPDfbmHzV6ANApRCMjp+o2k0m//HPmT0zbMWstEj5nwKKFAFAc5fdJ3g3OWgYlU4Im6DAgq0KkAFzO23356cyzqlmX92XweC7LFjkmCcczN9/AmkGXw9HXjHZVmmkZQO6umLz7mf4J1R/BkDhFr6dP7ZfOP7+Jyel9cUutDnn/EquFNHtqCikW0sYh6D/yIUzUOBkgXox09A30yi+f8P+m+/Vmt04mbyamZeLp5jAUAzyzmvAgooMNoCNDWmv7FJAQUU6HSBbirA7BvXl/TBJ6iOQT/Hh8CbRzrwbvS4xaCdgJ8utQyoyd8AAvax417qOpDOv9460p/F1zwziOir+u9mEhOFDGWnl+5tUPZaXZ8CCrQsQHN/AvlWEreXvOOOO1pZ1GUUUEABBRRQQAEFFBg1gRjYE0hTEx/7zMegPH4en5vZ0HSQTrN/gv5tt902qbHvL1JIsmKeOB/rqJXiZ3nzxjzic6082jXd4L9dsuarQBsEmm3un90ETma0GuDWKCYFFFBAAQUUUEABBTpFIAbT2e2NwX78PD5n56v3PubBIH708yfw524IFDAQ/PN5fJB/IynmWWt7+LzsZPBftrjrU6BFAZohtdLcP7s6av5POeWU7GTfK6CAAgoooIACCihQWYEYLMdnNjQG2DzH6fG52R1hOYL/yZMnB26lST/9JPXH6Ok806+HWwfzxvnj6/g83LLt+Nzgvx2q5qlAGwTor99qc//s5hD82/w/q+J7BRRQQAEFFFBAgU4QSAfQMbgeyXbHPKilTz/iemrV3o9knaOxrMH/aKi7TgWaFCBQp79+Ucnm/0VJmo8CCiiggAIKKKBAuwXSAXk7X2f3I66L6fF1u56z627He0f7b4eqeSpQsMCkSZOGDf5pFXD88ccPrJnCAkZArZeee+65MH369Hqz+JkCCiiggAIKKKCAAqMqEGvg089sUKyxH9WNa3Hl6X0paz/qRwYt7oiLKaBAsQJrrLFG4FEvEcin09Zbbx3Gjx+fnuRrBRRQQAEFFFBAAQU6UoAa98WLFw88eJ8EzQzAx+B5cRw+xtHjdavj6cVlM/ktHdO/vv7/+jsGJH68JqXf83rM0v7pcRv4nOX6p8X54jKM58UjtiRgeruTwX+7hc1fAQUUUEABBRRQQAEFFFCgZQHuVPXEE0+EuXPnhmnTpiWD8hE4l1Vj3vKGZxYk0I9pwYIF4ZFHHgnPP/98UggQp7fz2eC/nbrmrYACCiiggAIKKKCAAgooMCIBRuEnUL7kkkvCnXfeGegSSyL4H2gBMKI1lLNw3FaeCf5vueWWpJsutxQsIxn8l6HsOhRQQAEFFFBAAQUUUEABBVoSWHvttcOWW26ZBPoEzbG5fKfU/A/0JHi5qwJdABYtXBRWWmmlMGvWrFduK9iSTuMLGfw3buWcCiiggAIKKKCAAgoooIACJQtsv/32YbPNNnupf3x/4Dx2zNiXa/zZkFY797eyEzGMZ9n063p5vTJfHBOAcQBYnBYAjNFFV4YyksF/GcquQwEFFFBAAQUUUEABBRRQoCWByZMnJ/38CZa7LZXZesHgv9u+Pe6PAgoooIACCiiggAIKKNBFAjFAjs9dtGul7orBf6ncrkwBBRRQQAEFFKiYwAvPhnD92a1t1JQZIWzy/1pb1qUUUEABBUoVMPgvlduVKaCAAgoooIACFRN44ZkQrjiztY2atZ7Bf2tyLqWAAgqULjC29DW6QgUUUEABBRRQQAEFFFBAAQUUKFXA4L9UblemgAIKKKCAAgoooIACCiigQPkCBv/lm7tGBRRQQAEFFFBAAQUUUEABBUoVMPgvlduVKaCAAgoooIACCiiggAIKKFC+gMF/+eauUQEFFFBAAQUUUEABBRRQQIFSBQz+S+V2ZQoooIACCiiggAIKKKCAAgqUL2DwX765a1RAAQUUUEABBRRQQAEFFFCgVAGD/1K5XZkCCiiggAIKKKCAAgoooIAC5QsY/Jdv7hoVUEABBRRQQAEFFFBAAQUUKFXA4L9UblemgAIKKKCAAgoooIACCiigQPkCBv/lm7tGBRRQQAEFFFBAAQUUUEABBUoVMPgvlduVKaCAAgoooIACCiiggAIKKFC+gMF/+eauUQEFFFBAAQUUUEABBRRQQIFSBQz+S+V2ZQoooIACCiiggAIKKKCAAgqUL2DwX765a1RAAQUUUEABBRRQQAEFFFCgVAGD/1K5XZkCCiiggAIKKKCAAgoooIAC5QsY/Jdv7hoVUEABBRRQQAEFFFBAAQUUKFXA4L9UblemgAIKKKCAAgoooIACCiigQPkCBv/lm7tGBRRQQAEFFFBAAQUUUEABBUoVMPgvlduVKaCAAgoooIACCiiggAIKKFC+gMF/+eauUQEFFFBAAQUUUEABBRRQQIFSBQz+S+V2ZQoooIACCiiggAIKKKCAAgqUL2DwX765a1RAAQUUUEABBRRQQAEFFFCgVAGD/1K5XZkCCiiggAIKKKCAAgoooIAC5QsY/Jdv7hoVUEABBRRQQAEFFFBAAQUUKFXA4L9UblemgAIKKKCAAgoooIACCiigQPkCBv/lm7tGBRRQQAEFFFBAAQUUUEABBUoVMPgvlduVKaCAAgoooIACCiiggAIKKFC+gMF/+eauUQEFFFBAAQUUUEABBRRQQIFSBQz+S+V2ZQoooIACCiiggAIKKKCAAgqUL2DwX765a1RAAQUUUEABBRRQQAEFFFCgVAGD/1K5XZkCCiiggAIKKKCAAgoooIAC5QsY/Jdv7hoVUEABBRRQQAEFFFBAAQUUKFXA4L9UblemgAIKKKCAAgoooIACCiigQPkCBv/lm7tGBRRQQAEFFFBAAQUUUEABBUoVMPgvlduVKaCAAgoooIACCiiggAIKKFC+gMF/+eauUQEFFFBAAQUUUEABBRRQQIFSBQz+S+V2ZQoooIACCiiggAIKKKCAAgqUL2DwX765a1RAAQUUUEABBRRQQAEFFFCgVAGD/1K5XZkCCiiggAIKKKCAAgoooIAC5QsY/Jdv7hoVUEABBRRQQAEFFFBAAQUUKFXA4L9UblemgAIKKKCAAgoooIACCiigQPkCBv/lm7tGBRRQQAEFFFBAAQUUUEABBUoVMPgvlduVKaCAAgoooIACCiiggAIKKFC+gMF/+eauUQEFFFBAAQUUUEABBRRQQIFSBQz+S+V2ZQoooIACCiiggAIKKKCAAgqUL2DwX765a1RAAQUUUEABBRRQQAEFFFCgVAGD/1K5XZkCCiiggAIKKKCAAgoooIAC5QsY/Jdv7hoVUEABBRRQQAEFFFBAAQUUKFXA4L9UblemgAIKKKCAAgoooIACCiigQPkCBv/lm7tGBRRQQAEFFFBAAQUUUEABBUoV6Ct0bXMPDmHh3OazHLNMCGudkr/cPfuEsHRh/mf1pk5YK4TZXxo6x9MXh/DYyUOnNzJl5gEhTN156JzzTw/hyd8Ond7IlFWOCGHSBoPnXPp8CPfsP3hao++W2SyElQ8ZOveLd4dw/2FDpzcyZdk3hzBj38Fzvnhvf3456xk8V/67aW8KYcUa+zf/tH7Lc/OXG27qqkeFMHG94eby814XeOJXITz+i9YUVjoohMlbtbZss0vdvXezS7w0f61z3+LHQ7j3Y63lyT6z79k07/shPHVBdmpj71c9uv/3us7QeR8+NoTnrhk6vZEpaxwfwrgVBs/56AkhPHPZ4GmNvlvt6yGMnz147qLzG5y77xRQQAEFFFBAgbYJWPPfNlozVkABBRRQQAEFFFBAAQUUUKAaAgb/1TgOboUCCiiggAIKKKCAAgoooIACbRMw+G8brRkroIACCiiggAIKKKCAAgooUA0Bg/9qHAe3QgEFFFBAAQUUUEABBRRQQIG2CRj8t43WjBVQQAEFFFBAAQUUUEABBRSohoDBfzWOg1uhgAIKKKCAAgoooIACCiigQNsEDP7bRmvGCiiggAIKKKCAAgoooIACClRDwOC/GsfBrVBAAQUUUEABBRRQQAEFFFCgbQIG/22jNWMFFFBAAQUUUEABBRRQQAEFqiFg8F+N4+BWKKCAAgoooIACCiiggAIKKNA2AYP/ttGasQIKKKCAAgoooIACCiiggALVEDD4r8ZxcCsUUEABBRRQQAEFFFBAAQUUaJtAX9tyNmMFFFBAAQUUUECBYgWWPBXC079vLc++mSFM2aG1ZZtdauHcEJ67ttmlXpp/4johTNp46LKLHgrh2SuHTm9kyoQ1Qlhmi6FzPnddCAvvGzq9kSlTtg+hb9bQOZ+/KYQX7x46vZEpk7cOYfzs/DmfuiCEpc/nfzbc1Om758/xwh0hLLgt/7Phpi6zaQgTXjXcXH6ugAIVEjD4r9DBcFMUUEABBRRQQIG6AoueCGH+mXVnqfnhMpuUF/y/cE/r2zl9t/zg/8UHWs9z2i75wf+zl4fwzKU1yep+QIFCXvBPocdT59ddtOaHFNDUCv6fODuExfNrLlr3g1rB//O3hPD4z+suWvPDGRMN/mvi+IEC1RSw2X81j4tbpYACCiiggAIKKKCAAgoooEBhAgb/hVGakQIKKKCAAgoooIACCiiggALVFDD4r+ZxcasUUEABBRRQQAEFFFBAAQUUKEzA4L8wSjNSQAEFFFBAAQUUUEABBRRQoJoCBv/VPC5ulQIKKKCAAgoooIACCiiggAKFCRj8F0ZpRgoooIACCiiggAIKKKCAAgpUU8Dgv5rHxa1SQAEFFFBAAQUUUEABBRRQoDABg//CKM1IAQUUUEABBRRQQAEFFFBAgWoKGPxX87i4VQoooIACCiiggAIKKKCAAgoUJmDwXxilGSmggAIKKKCAAgoooIACCihQTQGD/2oeF7dKAQUUUEABBRRQQAEFFFBAgcIEDP4LozQjBRRQQAEFFFBAAQUUUEABBaopYPBfzePiVimggAIKKKCAAgoooIACCihQmIDBf2GUZqSAAgoooIACCiiggAIKKKBANQUM/qt5XNwqBRRQQAEFFFBAAQUUUEABBQoTMPgvjNKMFFBAAQUUUEABBRRQQAEFFKimgMF/NY+LW6WAAgoooIACCiiggAIKKKBAYQIG/4VRmpECCiiggAIKKKCAAgoooIAC1RQw+K/mcXGrFFBAAQUUUEABBRRQQAEFFChMwOC/MEozUkABBRRQQAEFFFBAAQUUUKCaAgb/1TwubpUCCiiggAIKKKCAAgoooIAChQkY/BdGaUYKKKCAAgoooIACCiiggAIKVFPA4L+ax8WtUkABBRRQQAEFFFBAAQUUUKAwAYP/wijNSAEFFFBAAQUUUEABBRRQQIFqCvQVulkTZocwZnzzWY6dUHuZCWuFsHRR7c9rfTJ+lfxPxk0LYcKr8j8bburY/mXzUt8KI8hzUk6O/WUyrW7j+JVz8uufNGZi63n2zRiaJ8es1W3Myy+uYdwILNlHkwLDCYydHELfrOHmyv98TM656ulHQnjwtvz5h5s6c50Qlu8/b+alVreR81Fu6j+vtJrnuOm5OYaxU1vPc0yNPz+sq9XtDDnl2eOWbT2/vG0sOr98WacqUFuA8xDXRq2kvhrXCH39ec7epJUc+89hq+UvN67//NDqdo5bPj/Pscu0nmffivl59s1sPU/+nuQlrnNa3fexU/JyfGnahNVDWNx/TisyjVuu9W3lfGhSQIGOEhiztD911Ba7sQookCswZ86ccOCBBw58duWVV4bx41sojBvIwRcNCdw+J4Tzj2lo1iEz7bRfCFvuMWSyExRQQAEFFFCgMwVOPfXUcNxxxyUbv8Yaa4Szzz67M3fEre5KgZxqkq7cT3dKAQUUUEABBRRQQAEFFFBAgZ4VMPjv2UPvjiuggAIKKKCAAgoooIACCvSKgMF/rxxp91MBBRRQQAEFFFBAAQUUUKBnBQz+e/bQu+MKKKCAAgoooIACCiiggAK9ImDw3ytH2v1UQAEFFFBAAQUUUEABBRToWQGD/5499O64AgoooIACCiiggAIKKKBArwgY/PfKkXY/FVBAAQUUUEABBRRQQAEFelbA4L9nD707roACCiiggAIKKKCAAgoo0CsCBv+9cqTdTwUUUEABBRRQQAEFFFBAgZ4VMPjv2UPvjiuggAIKKKCAAgoooIACCvSKgMF/rxxp91MBBRRQQAEFFFBAAQUUUKBnBQz+e/bQu+MKKKCAAgoooIACCiiggAK9ImDw3ytH2v1UQAEFFFBAAQUUUEABBRToWQGD/5499O64AgoooIACCiiggAIKKKBArwgY/PfKkXY/FVBAAQUUUEABBRRQQAEFelbA4L9nD707roACCiiggAIKKKCAAgoo0CsCBv+9cqTdTwUUUEABBRRQQAEFFFBAgZ4VMPjv2UPvjiuggAIKKKCAAgoooIACCvSKQF+v7Kj7qYACCrRFYLmVQ9jk/7WW9Yy1WlvOpRRQQAEFFFBAAQUUaFLA4L9JMGdXQAEFBgmstH4IPEwKKKCAAgoooIACClRYwGb/FT44bpoCCiiggAIKKKCAAgoooIACRQhY81+Eonk0LLB06dKG53XG5gSmTp3a3ALOrYACCiiggAIKKKCAAj0jYPDfM4e6Gju6ePHiamxIF27Fmmuu2YV75S4poIACCiiggAIKKKBAEQI2+y9C0TwUUEABBRRQQAEFFFBAAQUUqLCAwX+FD46bpoACCiiggAIKKKCAAgoooEARAgb/RSiahwIKKKCAAgoooIACCiiggAIVFjD4r/DBcdMUUEABBRRQQAEFFFBAAQUUKELA4L8IRfNQQAEFFFBAAQUUUEABBRRQoMICBv8VPjhumgIKKKCAAgoooIACCiiggAJFCBj8F6FoHgoooIACCiiggAIKKKCAAgpUWMDgv8IHx01TQAEFFFBAAQUUUEABBRRQoAgBg/8iFM1DAQUUUEABBRRQQAEFFFBAgQoLGPxX+OC4aQoooIACCiiggAIKKKCAAgoUIWDwX4SieSiggAIKKKCAAgoooIACCihQYQGD/wofHDdNAQUUUEABBRRQQAEFFFBAgSIEDP6LUDQPBRRQQAEFFFBAAQUUUEABBSosYPBf4YPjpimggAIKKKCAAgoooIACCihQhIDBfxGK5qGAAgoooIACCiiggAIKKKBAhQUM/it8cNw0BRRQQAEFFFBAAQUUUEABBYoQMPgvQtE8FFBAAQUUUEABBRRQQAEFFKiwgMF/hQ+Om6aAAgoooIACCiiggAIKKKBAEQIG/0UomocCCiiggAIKKKCAAgoooIACFRYw+K/wwXHTFFBAAQUUUEABBRRQQAEFFChCwOC/CEXzUEABBRRQQAEFFFBAAQUUUKDCAgb/FT44bpoCCiiggAIKKKCAAgoooIACRQgY/BehaB4KKKCAAgoooIACCiiggAIKVFjA4L/CB8dNU0ABBRRQQAEFFFBAAQUUUKAIAYP/IhTNQwEFFFBAAQUUUEABBRRQQIEKCxj8V/jguGkKKKCAAgoooIACCiiggAIKFCFg8F+EonkooIACCiiggAIKKKCAAgooUGEBg/8KHxw3TQEFFFBAAQUUUEABBRRQQIEiBAz+i1A0DwUUUEABBRRQQAEFFFBAAQUqLGDwX+GD46YpoIACCiiggAIKKKCAAgooUISAwX8RiuahgAIKKKCAAgoooIACCiigQIUFDP4rfHDcNAUUUEABBRRQQAEFFFBAAQWKEDD4L0LRPBRQQAEFFFBAAQUUUEABBRSosIDBf4UPjpumgAIKKKCAAgoooIACCiigQBECBv9FKJqHAgoooIACCiiggAIKKKCAAhUWMPiv8MFx0xRQQAEFFFBAAQUUUEABBRQoQsDgvwhF81BAAQUUUEABBRRQQAEFFFCgwgIG/xU+OG6aAgoooIACCiiggAIKKKCAAkUI9BWRiXkooMDoC8ybN2/QRpx00klh3Lhxg6b5RgEFFFBAAQUUUKB9Atddd137MjdnBUYoYPA/QkAXV6AqAvPnzx+0KSeffPKg975RQAEFFFBAAQUUaK/A0qVLw5gxY9q7EnNXoEUBm/23COdiCiiggAIKKKCAAgoooIACCnSKgDX/nXKk3E4FhhGYNm1a2GabbYaZy48VUEABBRRQQAEF2iXw4IMPhvvvv79d2ZuvAiMSGNPfNGXpiHJwYQWaEFi0aFETcztrMwI0MbOPfzNizquAAgoooIACoyGwZMmS0VhtKeukz/+VV16ZrGv69Olhr732KmW9cSVcD9rtIGr4nBUw+M+K+L6tAgb/7eM1+G+frTkroIACCiigQDEC1DsuXry4mMzMZYjA2LFjAw+TAnkCfjPyVJymgAIKKKCAAgoooIACCiigQBcJGPx30cF0VxRQQAEFFFBAAQUUUEABBRTIEzD4z1NxmgIKKKCAAgoooIACCiiggAJdJGDw30UH011RQAEFFFBAAQUUUEABBRRQIE/A4D9PxWkKKKCAAgoooIACCiiggAIKdJGAwX8XHUx3RQEFFFBAAQUUUEABBRRQQIE8AYP/PBWnKaCAAgoooIACCiiggAIKKNBFAn1dtC/uigIKKKCAAgookCvwzDPPhL/97W+5n02YMCFstNFGuZ85UQEFFFBAgW4RMPjvliPpfiiggAIKKKBATYETTjghPPzww2HmzJlD5pk+fbrB/xAVJyiggAIKdJuAwX+3HVH3RwEFFFBAAQWGCPzxj38MZ511VhgzZsyQz5yggAIKKKBALwjY578XjrL7qIACCiigwAgFli5dGq666qoR5tL84o8//nh44YUXml8wtcRtt90WNthgg8oH/rW6JbAr9T5L7WpTL5988smm5ndmBRRQQIHOFjD47+zj59YroIACCnSIwHPPPRcmT5488FhuueXCDjvsEH79618P2YPsvOnljjnmmCHzv+51rwuTJk1KHsxL//WvfOUrYeHChUPm3WmnnQa2IZ3v7rvvPmTe9IQLL7wwfP7zn09PGvT6pptuSoJratazjwsuuGDQvMO9efbZZ8OnP/3psPbaa4cVVlghTJs2LWy55Zbh5JNPHm7R3M/POOOMsNdeew367MUXXwz33HPPoGmtvmlm3/H/5S9/mbuqz3zmM7nHjJk/+clP5i7T7HeFgP/www8PW2+9ddh0003D6quvHt7znveEu+66Kzd/JyqggAIKdI+Azf6751i6JwoooIACFRd4/vnnw7XXXhtWXHHFpDb77LPPDh/+8IfDiSeeGPbcc89BW8+8t9xyy5A+6lOmTBk0H28IZL/5zW+Gt7/97YEaepq4f+1rXwtz584Nxx9//KD5qUX/9re/Hd7xjncMms6gd/XSd77znXDxxReHO+64I6y//vpDZt14443DU089lUw/+uijk/71cd0UMjSayP8tb3lLWGuttcKpp56aBP1PP/10sk8HH3xw+NWvfpU03x9ue9Prw/yoo45KTwqLFi0KH/jAB8If/vCHMHbs4LoQWglQ0ECg3khqZt/xX7x48ZBsmX7++eeHc845J+yxxx6DPr/55pvDeeedl9T+r7vuuoM+400z35V99tkn8B2aM2dO8sxAiF/96lfD+9///nDppZeGcePGDcnfCQoooIAC3SFg8N8dx9G9UEABBRToEIHZs2eHWbNmJVv72c9+NikE+PKXvzwk+GcGCgnyBqjL29UZM2aE1VZbLfmIWu4111wz7LjjjoG8qTlPp2WXXbbhfFmOQoRLLrkkHHDAAUlBxbHHHpvOLnlNAB3XQ2A+fvz4gfdDZq4xgaD4gx/8YNhtt93CcccdN9BMnwH5qJ1+61vfGnbZZZfwxS9+Mfznf/5njVwGT77mmmuSWu7BU196d9lllyUtJA499NBBHy9YsCAsWbJk0LR6b4rYdwooKMShwCMb/DONdPnll4e84J/PGvmuUMBw7rnnhltvvTUJ/Flu6tSpiecb3/jGQEEA1iYFFFBAge4UGFzU3Z376F4poIACCihQWYGtttoq3HfffYVvH026qcV94IEHRpz39773vfDOd74zaYr/wx/+MBActyP99Kc/DfTxp3Ahb2A+Ci1+9KMfBbo+MHJ/I4km/+9973trznrkkUcG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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Circuit Diagram " ] }, { "attachments": { "circuit.png": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABGwAAADsCAYAAAAhDzCXAAABRWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAysDOIMRgyqCWmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsis4q+p2suv3BQWcPtwNnV50kZM9SiAKyW1OBlI/wHitOSCohIGBsYUIFu5vKQAxO4AskWKgI4CsueA2OkQ9gYQOwnCPgJWExLkDGTfALIFkjMSgWYwvgCydZKQxNOR2FB7QYDHKTUvUMHdx8jczICAc0kHJakVJSDaOb+gsigzPaNEwREYSqkKnnnJejoKRgZGQCtBYQ5R/fkGOCwZxTgQYpkyDAzml4CCTgixtEcMDLuyGBh4NyPE1ID+4j3KwHDEoiCxKBHuAMZvLMVpxkYQNvd2BgbWaf//fw5nYGDXZGD4e/3//9/b////u4yBgfkWA8OBbwDi+2E+A4JvJQAAAZ5pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTEzMjwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yMzY8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KW2oCAQAAQABJREFUeAHtnQncVdP6xxdpUkLznOYRRUkyFZLIeJFkirh0jeHmItO9yHAzkzEhUxIpSopooEJRaS5RSiJpQPX+3++6//0673nPPmefeZ+zf+vzeTunvddee63vWnufvX77Wc+zS0FhMkoiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAK+IbCrb2qiioiACIiACIiACIiACIiACIiACIiACIiACFgCEmw0EERABERABERABERABERABERABERABETAZwQk2PisQ1QdERABERABERABERABERABERABERABEZBgozEgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAj4jIMHGZx2i6oiACIiACIiACIiACIiACIiACIiACIiABBuNAREQAREQAREQAREQAREQAREQAREQARHwGQEJNj7rEFVHBERABERABERABERABERABERABERABCTYaAyIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgM8ISLDxWYeoOiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgwUZjQAREQAREQAREQAREQAREQAREQAREQAR8RkCCjc86RNURAREQAREQAREQAREQAREQAREQAREQAQk2GgMiIAIiIAIiIAIiIAIiIAIiIAIiIAIi4DMCu/msPqqOCIiACIiACIhAgAj8+uuvZubMmWaXXXbx1Ory5cubgw8+2FP+n376ycyZM8dTuWSqXbu2adGihaf8S5cuNStXrvSUl0ytW7c2NWrU8JR/1qxZBi5eEtw6depkypUrFzP7n3/+aaZNm2Z27NgRMy8ZKlSoYA466CBPrNevX2/mzp3rqVwy1alTxzRv3txT/sWLF5tVq1Z5ykumNm3amOrVq3vKz9jbtGmTp7w7d+40BxxwgKlcubKn/MokAiIgAiIgAskSkGCTLEEdLwIiIAIiIAIikDCBRYsWmUsuucS0b9/eUxk1a9a0IkKpUqVi5v/uu+/MU089ZQoKCmLmJUPXrl2tiOBFPPr000/NmDFjPJd9+eWXexZsRo8ebZYsWeKpznDYd999PQk227ZtM88884z5448/PJVdt25d06FDB0+CDeJVPKy7detmmjVr5qnsGTNmmHHjxnlmfdVVV3kWbN544w2zYsUKTzxmz55thg4darp06eKp3p4KVSYREAEREAERiEJgl8KHGG9PMVEK0S4REAEREAEREAERSITAlClTzD333GNef/11s+uusVdqk6d06dKeTsUjjldxggJ3220340UIIi/WFliseE1lypTxPMnfvn27ZysYxCXK9prg4fXRDxYw8ZLSyRqLIJh4Telife6555rzzjvPHHfc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ampZqDQREAEREAEREAEREAEREAEREAEREAER8AUBCTa+6AZVQgREQAREQAREQAREQAREQAREQAREQAT+IiDB5i8W+iYCIiACIiACIpBhAjt37lTUlgwz1+kSI/Dbb7+ZHTt2JHawjhIBERABERCBBAhIsEkAmg4RAREQAREQARFIDYEff/zRTJgwwRQUFKSmQJUiAmkiMHnyZLNmzZo0la5iRUAEREAERKAkAQk2JZloiwiIgAiIgAiIQIYILFy40Dz//PMZOptOIwKJExgxYoSZO3euxMXEEepIERABERCBOAlIsIkTmLKLgAiIgAiIgAiIgAiIgAiIgAiIgAiIQLoJSLBJN2GVLwIiIAIiIAIiIAIiIAIiIAIiIAIiIAJxEpBgEycwZRcBERABEcgugZYtW5oKFSpktxJJnJ26t2rVyuyyyy5JlKJDRUAEREAEREAEREAE8p2ABJt872G1TwREQATyjMDAgQNNvXr1crZVderUMTfccIMEm5ztQVVcBERABERABERABDJDYLfMnEZnEQEREAEREIHUEGjSpElqCspSKaVKlTK53oYsodNpRUAEREAEREAERCBQBGRhE6juVmNFQAREQAREQAREQAREQAREQAREQARygYAEm1zoJdVRBERABERABERABERABERABERABEQgUAQk2ASqu9VYERABERABERABERABERABERABERCBXCAgwSYXekl1FAEREAEREAEREAEREAEREAEREAERCBQBCTaB6m41VgREQAREQAT8RWDXXXdVxCx/dYlq40KAscqfkgiIgAiIgAhkioCiRGWKtM4jAiIgAiIgAiJQgkCVKlVMu3btSmzXBhHwG4H99tvPVK9eXQJjhI557733TEFBgSlTpkyEvf7Z9Oeff9p6du/eXf3on25RTURABKIQ2KXw5loQZb92iYAIiIAI5DCB1atXmx9//NGUK1fOF6345ZdfzAEHHGBKly7ti/pEqsTgwYPNzp07zcCBA337QM+k44svvjB77rlnpCZkfNu2bdtMtWrVTO3ateM+N48hW7duNbvvvrvrsZ9//rmpUKGC6/5M7ti+fbspX768adSoUSZPG/e59t57b/PTTz/52iJk5cqV5tdff/XNJH/Tpk2mffv2rqwZp9xLd9llF9c8bjvWrl1r1qxZY8eOW55Mbt+4caPZf//9TdmyZVNy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LVpkSpUqlariVI4IiIAIiECaCOipOU1gVawIiIAI+IFA8+bNzcqVK8306dP9UB3rQDJVEUR80aAsVQKG7du3902/btu2zTRr1ixtNLp37+6btv7444+mTZs2aWtrkApu1aqV+eqrr8y0adN80WzGWbrEFK4P2uqXe/G+++6bUitFLAc//fRTgyVRuhimYpCsWLHCbNq0KRVFqQwREAERyAiBXQrX0GsRfUZQ6yQiIAIiIAKpINC5c2eDH5vWrVunorgSZQwePNhOOgYOHJiWiceCBQtM3759zdSpU32xxKcEgAxvwHpm9erVpkmTJhk+c36fbu+99zZMov2wjCxfSBNlEEuyihUr5kuTUtaOLl262LHWuHHjtNw3U1VRBFeuC5bW6tpIFVWVIwIikE4CsrBJJ12VLQIiIAIiIAIiEJUAb7yffvppc//99/t6ohe1EdoZCALPPPOMOfXUU82BBx4YiPbG08gRI0YYln352brGaQ9LwSTWODT0KQIi4HcCEmz83kOqnwiIgAiIgAjkMYH169ebJUuW5HEL1bR8IYCFzdq1a5N2GJ4vPELbUatWrdD/6rsIiIAIiECKCGQ/tESKGqJiREAEREAEREAEREAEREAEREAEREAERCBfCEiwyZeeVDtEQAREQAREQAREQAREQAREQAREQATyhoAEm7zpSjVEBERABERABERABERABERABERABEQgXwhIsMmXnlQ7REAEREAEREAEREAEREAEREAEREAE8oaABJu86Uo1RAREQAREQAREQAREQAREQAREQAREIF8ISLDJl55UO0RABEQgIASqV69uypYtm7Otpe41atTIifC3OQtZFRcBERABERABERCBPCAgwSYPOlFNEAEREIEgETj77LOt4JGrbUZw6tOnT65WX/UWAREQAREQAREQARHIEIHdMnQenUYEREAEREAEUkLgb3/7W0rKyVYhFStWNLnehmyx03lFQAREQAREQAREIEgEZGETpN5WW0VABERABERABERABERABERABERABHKCgASbnOgmVVIEREAEREAE8pPAHnvsYerUqZOfjVOr8opA7dq1TaVKleR/Kq96VY0RAREQAX8T0JIof/ePaicCIiACIiACeU2gSZMm1qfPLrvsktftVONyn8AZZ5xhmjVrlvsNUQtEQAREQARyhoAEm5zpKlVUBERABERABPKPABY2nTt3zr+GqUV5R6Bjx4551yY1SAREQAREwN8EtCTK3/2j2omACIiACIiACIiACIiACIiACIiACASQgASbAHa6miwCIiACIiACIiACIiACIiACIiACIuBvAhJs/N0/qp0IiIAIiIAIiIAIiIAIiIAIiIAIiEAACciHTQA7XU0WAREQAREQAREQAREQgVQR+OCDD0xBQYEpW7ZsqopMSznbt28327ZtM927d1e0r7QQVqEiIAKpJiDBJtVEVZ4IiIAI+IjAjz/+aDZs2GDKlCnji1r99ttvplWrVqZUqVJpqw/tXbduXcITB45n4rF8+fKEHuh///13U716dVO5cuW0tXHHjh1m/vz5pmLFimk7RzwF//HHH7a91apVi+cwz3m/+eabhPvT80k8ZoR9+fLl0x6KPNk279y5047hXXdNzJh669at9lr1iCWhbD/88IPZtGmT2W03fzyOMpFv2bJlQm2JdVCy96VY5ce7n3txixYtTOnSpeM9NGL+Cy+80NSvX980bNgwoftmxELTsHH9+vVm8uTJdtwpMl0aAKtIERCBlBPwxy9kypulAkVABERABCDw5ptvmqlTp6Z94uWV9qRJk8ywYcNMrVq1vB5SIh8P3IghbhPR9957z7z11lvmgAMOKHGslw0rVqywgs3rr7/uJXuJPJ9//rk58cQTTe/evSNOXJhIM3mrWrVqiWO9boDBddddZ7p06eL1kLTmmzdvnjnkkEPMJZdcErHNyZ785ptvNu3bt0+2mJQcv2rVKjv+brvttrS01ankv/71L5NMVCLG18iRI53i4v6cNm2aGTVqVFrF1eeff94sW7bMNGrUKO76peOA6dOn23tmOiby7777rnnnnXdM27Zt01H1uMvkXjx06FCzzz77xH1spAMaNGhgrr/++qTGbKRyU70NIX7x4sWpLlbliYAIiEDaCEiwSRtaFSwCIiAC2Sfw4YcfmjVr1phjjz02rZNLry1FzEAQSUawefXVV81ZZ53lasHyySefmKVLl5qTTjopoTY7ljGJWq+88cYbZsqUKVawicRl48aNhjZcdtllCdWPMleuXGlmz55tzjnnHFfhKtK507UNkYyxhmCTjvT222+bk08+2Rdt/frrrw0T+1tvvTXh/vPCaOzYsea0005LuM2XX365tfRKVHy45ZZbzJ9//plWwWbChAlmzz33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KUiyDB0uAiIgAiIgAhkjsHbtWk8TToQAJvfREj+BTIxj/RQyqaxdu3bMULAIQJs2bYp2SrsPsalGjRox8wUhA+yZ7DMZ9pKw+vBqPYEwgWVGrP51zlupUiWz5557Ov+N+kk/Y+XltWwsSsqVKxe1TGfnjz/+6Nnqw+vYpGzqunr1ahOPhU26WMMZ3l5SvKypM+PES4qH9Z9//mn22WefmPcBL+dVHhEQAREQARHwQkCCjRdKyiMCIiACIiACIiACIiACIiACIiACIiACGSQgp8MZhK1TiYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAXAhJsvFBSHhEQAREQAREQAREQAREQAREQAREQARHIIAEJNhmErVOJgAiIgAiIgAiIgAiIgAiIgAiIgAiIgBcCEmy8UFIeERABERABERABERABERABERABERABEcggAQk2GYStU4mACIiACIiACIiACIiACIiACIiACIiAFwISbLxQUh4REAEREAEREAEREAEREAEREAEREAERyCABCTYZhK1TiYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAXAhJsvFBSHhEQAREQAREQAREQAREQAREQAREQARHIIAEJNhmErVOJgAiIgAiIgAiIgAiIgAiIgAiIgAiIgBcCEmy8UFIeERABERABERABERABERABERABERABEcggAQk2GYStU4mACIiACIiACIiACIiACIiACIiACIiAFwISbLxQUh4REAEREAEREAEREAEREAEREAEREAERyCABCTYZhK1TiYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAXAhJsvFBSHhEQAREQAREQAREQAREQAREQAREQARHIIAEJNhmErVOJgAiIgAiIgAiIgAiIgAiIgAiIgAiIgBcCEmy8UFIeERABERABERABERABERABERABERABEcggAQk2GYStU4mACIiACIiACIiACIiACIiACIiACIiAFwISbLxQUh4REAEREAEREAEREAEREAEREAEREAERyCABCTYZhK1TiYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAXAhJsvFBSHhEQAREQAREQAREQAREQAREQAREQARHIIAEJNhmErVOJgAiIgAiIgAiIgAiIgAiIgAiIgAiIgBcCEmy8UFIeERABERABERABERABERABERABERABEcggAQk2GYStU4mACIiACIiACIiACIiACIiACIiACIiAFwISbLxQUh4REAEREAEREAEREAEREAEREAEREAERyCABCTYZhK1TiYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAXAhJsvFBSHhEQAREQAREQAREQAREQAREQAREQARHIIAEJNhmErVOJgAiIgAiIgAiIgAiIgAiIgAiIgAiIgBcCEmy8UFIeERABERABERABERABERABERABERABEcggAQk2GYStU4mACIiACIiACIiACIiACIiACIiACIiAFwISbLxQUh4REAEREAEREAEREAEREAEREAEREAERyCABCTYZhK1TiYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAXAhJsvFBSHhEQAREQAREQAREQAREQAREQAREQARHIIAEJNhmErVOJgAiIgAiIgAiIgAiIgAiIgAiIgAiIgBcCEmy8UFIeERABERABERABERABERABERABERABEcggAQk2GYStU4mACIiACIiACIiACIiACIiACIiACIiAFwISbLxQUh4REAEREAEREAEREAEREAEREAEREAERyCABCTYZhK1TiYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAXArt5yaQ8IiACIiACIpBNAn/++af54YcfzG+//WZ27NhhypUrZypVqmSqVq1qdt3V3+8eqPumTZvMH3/8Yfhep04d39c5m32dinMvXrzYlCpVyjRq1CgVxaWljHSNC8bad999Z8qWLWuqVatm9thjj7TUX4WKgAiIgAiIgAikn8AuBYUp/afRGURABERABEQgfgKIM998841Zs2aN+f77782WLVvM9u3bTfny5Q0/X82aNTMHHHCAryelq1evNlOmTDHz5s2z9b/zzjvtZDp+GjrCCwFEvb///e9mn332MXfccYfZZZddvByW8TxexsXOnTvN8uXLzZ577mnFyViV3Lhxo3njjTessMl1svfee5vzzz8/IoN4y4517lTu93PdUtlOlSUCIiACIiACsQj4+7VkrNprvwiIgAiIQN4SYOL90UcfmWeeecZMnDjRNG/e3FxwwQXm8ssvNyeeeKLZvHmzuf32282IESOsEOJXELTjxx9/NI8++qh56623zG67ybg1nX313nvvmVdffdUsWbIknadJumwv4wKhEtFp/PjxVqCMddKxY8eaBx980PTq1ct8++235pZbbjGIH5FS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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "Following Ref.[1], we will examine Grover's search algorithm for $n=3$ qubits, which corresponds to a search database of size $N = 2^{3} = 8$. Below we show the circuit used to find the item ```111```. To find other items, we can simply swap out the phase oracle, using the table given in Ref.[1].\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Code " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Libraries and Parameters " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Version: 1.0.0.post1\r\n" ] } ], "source": [ "# Check SDK version\n", "!pip show amazon-braket-sdk | grep Version" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Import Braket libraries\n", "from braket.circuits import circuit, Circuit, Gate, Moments\n", "from braket.circuits.instruction import Instruction\n", "from braket.aws import AwsQuantumTask, AwsDevice\n", "from braket.devices import LocalSimulator\n", "import matplotlib.pyplot as plt\n", "# magic word for producing visualizations in notebook\n", "%matplotlib inline\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Helper Functions " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We develop a set of useful helper functions that we will explain in detail below. Specifically, we provide simple building blocks for the four core modules of Grover's search algorithm: 1) initialization, 2) oracle, 3) amplification, and 4) measurement. This approach allows us to solve the problem in a clean and modular way. " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Helper function to build C-C-Z gate\n", "@circuit.subroutine(register=True)\n", "def ccz(targets=[0, 1, 2]):\n", " \"\"\"\n", " implementation of three-qubit gate CCZ\n", " \"\"\"\n", " # define three-qubit CCZ gate\n", " ccz_gate = np.array([[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],\n", " [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],\n", " [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0],\n", " [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0],\n", " [0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0],\n", " [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],\n", " [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0],\n", " [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0]],\n", " dtype=complex)\n", " \n", " # instantiate circuit object\n", " circ = Circuit()\n", " \n", " # add CCZ gate\n", " circ.unitary(matrix=ccz_gate, targets=targets)\n", " \n", " return circ\n", "\n", "\n", "# All possible items and their corresponding oracles\n", "# define oracle dictionary using this CCZ gate\n", "oracle_sim = {\"000\": Circuit().x([0,1,2]).ccz(targets=[0, 1, 2]).x([0,1,2]),\n", " \"001\": Circuit().x([0,1]).ccz(targets=[0, 1, 2]).x([0,1]),\n", " \"010\": Circuit().x([0,2]).ccz(targets=[0, 1, 2]).x([0,2]),\n", " \"011\": Circuit().x([0]).ccz(targets=[0, 1, 2]).x([0]),\n", " \"100\": Circuit().x([1,2]).ccz(targets=[0, 1, 2]).x([1,2]),\n", " \"101\": Circuit().x([1]).ccz(targets=[0, 1, 2]).x([1]),\n", " \"110\": Circuit().x([2]).ccz(targets=[0, 1, 2]).x([2]),\n", " \"111\": Circuit().ccz(targets=[0, 1, 2])\n", " }\n", "\n", "\n", "# helper function for initialization\n", "def initialize(n_qubits=3):\n", " \"\"\"\n", " function to apply hadamard to all qubits\n", " \"\"\"\n", " # Initialize with superposition\n", " circ = Circuit();\n", " circ.h(np.arange(n_qubits))\n", " #print(circ)\n", " return circ\n", "\n", "\n", "# helper function for phase oracle\n", "def oracle(item):\n", " \"\"\"\n", " function to apply oracle for given target item\n", " \"\"\"\n", " # instantiate circuit object\n", " circ = Circuit()\n", " \n", " # add oracle\n", " circ.add_circuit(oracle_sim[item])\n", " \n", " return circ\n", "\n", "\n", "# helper function for amplification\n", "def amplify(n_qubits=3):\n", " \"\"\"\n", " function for amplitude amplification\n", " \"\"\"\n", " # instantiate circuit object\n", " circ = Circuit()\n", " \n", " # Amplification\n", " circ.h(np.arange(n_qubits))\n", " circ.add_circuit(oracle_sim['000'])\n", " circ.h(np.arange(n_qubits))\n", " \n", " return circ\n", "\n", "\n", "# helper function for grover algorithm\n", "def grover(item, n_qubits=3, n_reps=1):\n", " \"\"\"\n", " function to put together individual modules of Grover algorithm\n", " \"\"\"\n", " # initialize\n", " grover_circ = initialize()\n", " # oracle and amplify\n", " for ii in range(n_reps):\n", " # get oracle\n", " or_circ = oracle(item)\n", " grover_circ.add(or_circ)\n", " # amplify\n", " amplification = amplify()\n", " grover_circ.add(amplification)\n", " \n", " return grover_circ\n", " " ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# Function to run quantum task, check the status thereof, and collect results\n", "def get_result(circ):\n", " \n", " # get number of qubits\n", " num_qubits = circ.qubit_count\n", "\n", " # specify desired results_types\n", " circ.probability()\n", "\n", " # submit task: define task (asynchronous)\n", " task = device.run(circ, shots=1000)\n", "\n", " # Get ID of submitted task\n", " task_id = task.id\n", "# print('Task ID :', task_id)\n", "\n", " # Wait for job to complete\n", " status_list = []\n", " status = task.state()\n", " status_list += [status]\n", " print('Status:', status)\n", "\n", " # Only notify the user when there's a status change\n", " while status != 'COMPLETED':\n", " status = task.state()\n", " if status != status_list[-1]:\n", " print('Status:', status)\n", " status_list += [status]\n", "\n", " # get result\n", " result = task.result()\n", "\n", " # get metadata\n", " metadata = result.task_metadata\n", "\n", " # get output probabilities\n", " probs_values = result.values[0]\n", "\n", " # get measurement results\n", " measurement_counts = result.measurement_counts\n", "\n", " # print measurement results\n", " print('measurement_counts:', measurement_counts)\n", "\n", " # bitstrings\n", " format_bitstring = '{0:0' + str(num_qubits) + 'b}'\n", " bitstring_keys = [format_bitstring.format(ii) for ii in range(2**num_qubits)]\n", "\n", " # plot probabalities\n", " plt.bar(bitstring_keys, probs_values);\n", " plt.xlabel('bitstrings');\n", " plt.ylabel('probability');\n", " plt.xticks(rotation=90);\n", " \n", " return measurement_counts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Device: Classical Simulator \n", "We demonstrate Grover's algorithm on a classical simulator first. \n", "You can choose between a local simulator or an on-demand simulator. \n", "In the next section, we will run the same problem on a quantum IonQ device." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# Set up the cloud-based simulator \n", "# device = AwsDevice(\"arn:aws:braket:::device/quantum-simulator/amazon/sv1\")\n", "\n", "# set up the local simulator\n", "device = LocalSimulator()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Quantum Gates supported by StateVectorSimulator:\n", "['ccnot', 'cnot', 'cphaseshift', 'cphaseshift00', 'cphaseshift01', 'cphaseshift10', 'cswap', 'cv', 'cy', 'cz', 'ecr', 'h', 'i', 'iswap', 'pswap', 'phaseshift', 'rx', 'ry', 'rz', 's', 'si', 'swap', 't', 'ti', 'unitary', 'v', 'vi', 'x', 'xx', 'xy', 'y', 'yy', 'z', 'zz']\n" ] } ], "source": [ "# get device name\n", "device_name = device.name\n", "# show the properties of the device \n", "device_properties = device.properties\n", "# show supportedQuantumOperations (supported gates for a device)\n", "device_operations = device_properties.dict()['action']['braket.ir.jaqcd.program']['supportedOperations']\n", "# Note: This field also exists for other devices like the QPUs\n", "print('Quantum Gates supported by {}:\\n {}'.format(device_name, device_operations))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since the ```CCZ``` gate is not part of the default gate set, we have used the ```unitary``` method to build a custom, doubly-controlled Z gate ```CCZ``` for the phase oracle operator. \n", "We will leverage the Amazon Braket `circuit.subroutine` functionality, which allows us to use such a custom-built gate as if it were any other built-in gate. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we are ready to run our circuit for a few test cases. \n", "To recap, the steps are as follows:\n", "\n", "1. Create a uniform superposition\n", "2. Apply the phase oracle corresponding to our target item\n", "3. Define the diffusion operator to magnify the amplitude difference created by the oracle\n", "4. Collect the measurement counts for our target item" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "T : |0|1|2|3|4|5|6|\n", " \n", "q0 : -H-U-H-X-U-X-H-\n", " | | \n", "q1 : -H-U-H-X-U-X-H-\n", " | | \n", "q2 : -H-U-H-X-U-X-H-\n", "\n", "T : |0|1|2|3|4|5|6|\n", "Status: COMPLETED\n", "measurement_counts: Counter({'111': 776, '000': 39, '010': 35, '011': 33, '001': 33, '100': 31, '101': 28, '110': 25})\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Select item to find. Let's start with '111' for now\n", "item = \"111\"\n", "\n", "# get Grover circuit\n", "circ = grover(item)\n", "\n", "# print circuit\n", "print(circ)\n", "\n", "# Measurement\n", "counts = get_result(circ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__DISCUSSION__: We observe a strong peak around the target solution given by the `111` bitstring, with all other bitstrings showing far smaller probabilities. \n", "Let us try one more item: " ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "T : |0|1|2|3|4|5|6|7|8|\n", " \n", "q0 : -H---U-H-X---U-X-H-\n", " | | \n", "q1 : -H-X-U-X-H-X-U-X-H-\n", " | | \n", "q2 : -H-X-U-X-H-X-U-X-H-\n", "\n", "T : |0|1|2|3|4|5|6|7|8|\n", "Status: COMPLETED\n", "measurement_counts: Counter({'100': 792, '111': 34, '011': 32, '010': 32, '001': 30, '110': 28, '000': 26, '101': 26})\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Select item to find. Let's start with '111' for now\n", "item = \"100\"\n", "\n", "# get Grover circuit\n", "circ = grover(item)\n", "\n", "# print circuit\n", "print(circ)\n", "\n", "# Measurement\n", "counts = get_result(circ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__DISCUSSION__: By repeating steps 2 (oracle) and 3 (amplification), we can further magnify the amplitude of the target item, thus maximizing the single-shot probability of identifying the right answer. This repetition is demonstrated below." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "T : |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|\n", " \n", "q0 : -H---U-H-X---U-X-H---U--H--X-----U--X--H--\n", " | | | | \n", "q1 : -H-X-U-X-H-X-U-X-H-X-U--X--H--X--U--X--H--\n", " | | | | \n", "q2 : -H-X-U-X-H-X-U-X-H-X-U--X--H--X--U--X--H--\n", "\n", "T : |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|\n", "Status: COMPLETED\n", "measurement_counts: Counter({'100': 941, '011': 13, '010': 10, '000': 10, '111': 7, '101': 7, '110': 7, '001': 5})\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEPCAYAAABP1MOPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAUl0lEQVR4nO3de7BlZX3m8e8DaFQweKFFQ4NNFBGiEbELsTIxWvGCUgEnXmiIYyQoqXIwodBkMImMIU6CMVpiAqNoEhk1QaIZ0yOtOEbQmSjajdykSUsHQRprpL1lcIxy+80fex3cvfvsPrsPvffazfv9VJ3qvda7zt4Pp6jznLXedUlVIUlq1x59B5Ak9csikKTGWQSS1DiLQJIaZxFIUuP26jvAztpvv/1q1apVfceQpN3KlVde+e2qWrHY2G5XBKtWrWLDhg19x5Ck3UqSW8aNeWhIkhpnEUhS4ywCSWqcRSBJjbMIJKlxFoEkNc4ikKTGWQSS1DiLQJIat9tdWSztLladeUmvn3/zOcf2+vnafbhHIEmNswgkqXEWgSQ1ziKQpMZZBJLUOItAkhpnEUhS4ywCSWqcRSBJjbMIJKlxFoEkNc4ikKTGWQSS1DiLQJIaZxFIUuMsAklqnEUgSY2zCCSpcRaBJDXOIpCkxlkEktQ4i0CSGmcRSFLjLAJJapxFIEmNswgkqXEWgSQ1bqpFkOSYJJuSbE5y5iLjByW5LMlVSa5N8uJp5pEkbW9qRZBkT+A84EXA4cCJSQ4f2ewPgIur6unAGuD8aeWRJC1umnsERwGbq+qmqroTuAg4fmSbAn66e70v8M0p5pEkLWKaRXAAcOvQ8pZu3bC3AK9MsgVYB7x+sTdKcmqSDUk2bN26dRpZJalZfU8Wnwh8oKpWAi8GPphku0xVdUFVra6q1StWrJh5SEl6IJtmEdwGHDi0vLJbN+wU4GKAqvoi8BBgvylmkiSNmGYRrAcOSXJwkgczmAxeO7LNN4BfBkhyGIMi8NiPJM3Q1Iqgqu4GTgMuBW5gcHbQ9UnOTnJct9kbgNcmuQb4W+DVVVXTyiRJ2t5e03zzqlrHYBJ4eN1ZQ683Ar8wzQySpB3re7JYktQzi0CSGmcRSFLjLAJJapxFIEmNswgkqXEWgSQ1ziKQpMZZBJLUOItAkhpnEUhS4ywCSWqcRSBJjbMIJKlxFoEkNc4ikKTGWQSS1DiLQJIaZxFIUuMsAklqnEUgSY2zCCSpcRaBJDXOIpCkxlkEktQ4i0CSGmcRSFLjLAJJapxFIEmNswgkqXEWgSQ1ziKQpMZZBJLUOItAkhpnEUhS46ZaBEmOSbIpyeYkZ47Z5hVJNia5PsnfTDOPJGl7e03rjZPsCZwHPB/YAqxPsraqNg5tcwjwJuAXqup7SR4zrTySpMVNtEeQ5O+THJtkZ/YgjgI2V9VNVXUncBFw/Mg2rwXOq6rvAVTV7Tvx/pKkXWDSX+znAycBNyY5J8mhE3zPAcCtQ8tbunXDngQ8Kck/JbkiyTGLvVGSU5NsSLJh69atE0aWJE1ioiKoqs9U1a8BRwI3A59J8oUkJyd50P34/L2AQ4DnACcC70vyiEU+/4KqWl1Vq1esWHE/Pk6SNGriQz1JHg28GngNcBVwLoNi+J9jvuU24MCh5ZXdumFbgLVVdVdVfR34GoNikCTNyKRzBP8d+F/Aw4BfqarjquojVfV6YJ8x37YeOCTJwUkeDKwB1o5s83EGewMk2Y/BoaKbdvq/QpK0bJOeNfS+qlo3vCLJT1XVj6tq9WLfUFV3JzkNuBTYE/irqro+ydnAhqpa2429IMlG4B7gd6rqO8v+r5Ek7bRJi+CtwLqRdV9kcGhorK481o2sO2vodQFndF+SpB7ssAiSPJbBmT4PTfJ0IN3QTzM4TCRJ2s0ttUfwQgYTxCuBdw6tvwP4vSllkiTN0A6LoKouBC5M8tKq+tiMMkmSZmipQ0OvrKoPAauSbHccv6reuci3SZJ2I0sdGtq7+3fcKaKSpN3cUoeG3tv9+4eziSNJmrWlDg29e0fjVfVbuzaOJGnWljo0dOVMUkiSejPJWUOSpAewpQ4NvauqTk/yP4AaHa+q46aWTJI0E0sdGvpg9++fTTuIJKkfSx0aurL793PdHUSfzGDPYFP31DFJ0m5uopvOJTkWeA/wLwzuN3Rwkt+sqk9OM5wkafomvfvoO4DnVtVmgCRPAC4BLAJJ2s1N+oSyOxZKoHMTgxvPSZJ2c0udNfSr3csNSdYBFzOYI3g5gyeQSZJ2c0sdGvqVodffAn6pe70VeOhUEkmSZmqps4ZOnlUQSVI/Jj1r6CHAKcDPAQ9ZWF9VvzGlXJKkGZl0sviDwGMZPLHscwyeWOZksSQ9AExaBE+sqjcD/6+7/9CxwDOnF0uSNCuTFsFd3b/fT/IUYF/gMdOJJEmapUkvKLsgySOBNwNrGTyx7M1TSyVJmpmJiqCq3t+9/Bzws9OLI0matYkODSV5dJI/T/KVJFcmeVeSR087nCRp+iadI7gIuB14KfAy4NvAR6YVSpI0O5POETyuqv5oaPmtSU6YRiBJ0mxNukfw6SRrkuzRfb0CuHSawSRJs7HUTefuYHCTuQCnAx/qhvYAfgC8carpJElTt9S9hh4+qyCSpH5MOkdAkuOAZ3eLl1fVJ6YTSZI0S5OePnoO8NvAxu7rt5P8yTSDSZJmY9I9ghcDR1TVvQBJLgSuAt40rWCSpNmY9KwhgEcMvd53VweRJPVj0j2CPwauSnIZgzOIng2cObVUkqSZWXKPIMkewL3A0cDfAx8DnlVVS15ZnOSYJJuSbE4ytjiSvDRJJVm9E9klSbvAknsEVXVvkt+tqosZ3Hl0Ikn2BM4Dng9sAdYnWVtVG0e2eziDiegv7VRySdIuMekcwWeSvDHJgUketfC1xPccBWyuqpuq6k4G9ys6fpHt/gh4G/CjyWNLknaVSecITmBwhfHrRtbv6JbUBwC3Di1vYeSpZkmOBA6sqkuS/M64N0pyKnAqwEEHHTRhZEnSJCbdIzicwWGea4CrgT9n8CD7ZevmHt4JvGGpbavqgqpaXVWrV6xYcX8+VpI0YtIiuBA4DHg3gxI4vFu3I7cBBw4tr+zWLXg48BTg8iQ3M5iMXuuEsSTN1qSHhp5SVYcPLV+WZOPYrQfWA4ckOZhBAawBTloYrKp/BfZbWE5yOfDGqtowYSZJ0i4w6R7BV5IcvbCQ5JnADn9hV9XdwGkMbld9A3BxVV2f5OzuvkWSpDkw6R7BM4AvJPlGt3wQsCnJdUBV1c8v9k1VtQ5YN7LurDHbPmfCLJKkXWjSIjhmqikkSb2ZqAiq6pZpB5Ek9WNnbjonSXoAsggkqXEWgSQ1ziKQpMZZBJLUOItAkhpnEUhS4ywCSWqcRSBJjbMIJKlxFoEkNc4ikKTGWQSS1DiLQJIaZxFIUuMsAklqnEUgSY2zCCSpcRaBJDXOIpCkxlkEktQ4i0CSGmcRSFLjLAJJapxFIEmNswgkqXEWgSQ1ziKQpMZZBJLUOItAkhpnEUhS4ywCSWqcRSBJjZtqESQ5JsmmJJuTnLnI+BlJNia5Nsk/Jnn8NPNIkrY3tSJIsidwHvAi4HDgxCSHj2x2FbC6qn4e+Cjwp9PKI0la3DT3CI4CNlfVTVV1J3ARcPzwBlV1WVX9sFu8Alg5xTySpEVMswgOAG4dWt7SrRvnFOCTiw0kOTXJhiQbtm7dugsjSpLmYrI4ySuB1cDbFxuvqguqanVVrV6xYsVsw0nSA9xeU3zv24ADh5ZXduu2keR5wO8Dv1RVP55iHknSIqa5R7AeOCTJwUkeDKwB1g5vkOTpwHuB46rq9ilmkSSNMbUiqKq7gdOAS4EbgIur6vokZyc5rtvs7cA+wN8luTrJ2jFvJ0makmkeGqKq1gHrRtadNfT6edP8fEnS0uZisliS1B+LQJIaZxFIUuMsAklqnEUgSY2zCCSpcRaBJDXOIpCkxlkEktQ4i0CSGmcRSFLjLAJJapxFIEmNswgkqXEWgSQ1ziKQpMZZBJLUOItAkhpnEUhS4ywCSWqcRSBJjbMIJKlxFoEkNc4ikKTGWQSS1DiLQJIaZxFIUuMsAklqnEUgSY2zCCSpcRaBJDXOIpCkxlkEktQ4i0CSGmcRSFLj9prmmyc5BjgX2BN4f1WdMzL+U8B/A54BfAc4oapunlaeVWdeMq23nsjN5xzb6+cv1zz/3OY5m7S7mFoRJNkTOA94PrAFWJ9kbVVtHNrsFOB7VfXEJGuAtwEnTCuTpIF5LlCzjTetPzymuUdwFLC5qm4CSHIRcDwwXATHA2/pXn8U+IskqaqaYq659ED9H0zS/Mu0fucmeRlwTFW9plv+D8Azq+q0oW2+2m2zpVv+l26bb4+816nAqd3iocCmqYRe2n7At5fcqh9mWx6zLY/ZlqfPbI+vqhWLDUx1jmBXqaoLgAv6zpFkQ1Wt7jvHYsy2PGZbHrMtz7xmm+ZZQ7cBBw4tr+zWLbpNkr2AfRlMGkuSZmSaRbAeOCTJwUkeDKwB1o5ssxb49e71y4DPtjg/IEl9mtqhoaq6O8lpwKUMTh/9q6q6PsnZwIaqWgv8JfDBJJuB7zIoi3nW++GpHTDb8phtecy2PHOZbWqTxZKk3YNXFktS4ywCSWqcRSBJjbMIJpDkUUke1XcOSZoGi2CMJAcluSjJVuBLwJeT3N6tW9VvuvmXZP8kR3Zf+/edZylJ9uk7g9QXzxoaI8kXgXcBH62qe7p1ewIvB06vqqP7zDdOkuuq6qk9fv4RwHsYXBy4cAHhSuD7wOuq6it9ZduRJN+oqoPmIMf+wAHd4m1V9a0+8ywlyT5V9YOeM4TBvc3u+7kBX57na5KSPLmq/rnvHAssgjGS3FhVh+zs2Cwk+dVxQ8B7xt1PZBaSXA38ZlV9aWT90cB7q+pp/SSDJGeMGwJ+v6p6O/xngS77818AnA/cyLY/tycy+Ll9uq9sO9L3z23UbnGvoZ5cmeR84ELg1m7dgQyuhL6qt1QDHwE+DCzW4g+ZcZZRe4+WAEBVXZFk7z4CDflj4O3A3YuM9X2Y9AOML9C/Bua1QPs+pHYu8LzR55gkORhYBxzWR6guw7vHDQGPmGWWpVgE472KwfMS/pBtdzkXroju07XAn1XVV0cHkjyvhzzDPpnkEgYPHBou0FcBn+ot1cBXgI9X1ZWjA0le00OeYRbo8uzF4Hkno24DHjTjLKNOBt4A/HiRsRNnnGWHPDS0G0ryi8AtVfWNRcZWV9WGHmINZ3gRg2dNbFOgVbWuv1SQ5FDgO6O3Oe/G9u/zeHz31+MTWLxAvz58+/Yesn0BeP2YAr21qg5c5NtmIsmbgFcAF7Htz20NcHFV/UmP2T4L/EFVfWGRsa9X1cE9xFqURTBGdzfUU4CXsO0vtH8A/rKq7uormx6Y5rxAv1tVWxcZ67VAuwyHsfjPbeP475q+7pTzH1XVD/vMMQmLYIwkf8tgou5CfrLruZLBHMGjqqq3R2oOldS/B36mWz33JZXkgqo6dektZ2+es0nTZhGMkeRrVfWknR2bhTkvqXFn3gS4pqpWzjLPNgHmO9u+wJsY/GW7P4MTAW5nUO7nVNX35yDbS4DHzFO2HUnyyap6Ud85FjNv2ZwsHu+7SV4OfKyq7gVIsgeD6wi+12syeMYiRbQFuCLJ1/oINGQrcAuDX64Lqlt+TC+JfmKes10MfBZ4blX9H4AkjwVe3Y29oL9o92V7zki2X+87W5Ijxw0BR8wyy3YB5jjbKPcIxuiuHn4b8FwGf33D4JSvy4Azq+rr/SSDJFcA72Dxkjqjqp7ZY7YbgV8eM5Hd98TiPGfbVFWH7uzYLMx5tnuAz7FtuS84uqoeOuNI95nnbKPcIxijqm5O8hYG1wxsM1ncZwl01jAoqfOSjJZU3w/3eRfwSGC7X7bAn844y6h5znZLkt8FLlyYfO2uMn41Pzkbpi/znO0GBtdf3Dg6kMRsE3KPYIwk/4nBL9WL2PaKxTXARVV1Tl/ZYOyZEv9QVTf0l2ogyZNZ/CwOs42R5JHAmQyyLRym+haD61bOqareDkfOebaXAddV1aZFxl5SVR/vIdbC589ttlEWwRjdsfafGz0Dp3v+8vU932Jibkuq+8vxpC7b8ES22ZYpyclV9dd951iM2ZZn3rJZBGMk+WfghVV1y8j6xwOf7vm46DyXlNl2sXm7L80wsy3PvGVzjmC804F/7CYYF47nHcTgZla9XeXZuZfB9QO3jKx/XDfWJ7MtQ5Jrxw0xOJ20N2ZbnnnONsoiGKOqPpXkSWx/e9v1C7el7tE8l5TZlmd/4IVsf2pygO1uUTBjZlueec62DYtgB7pTM6/oO8eoeS4psy3bJ4B9qurq0YEkl88+zjbMtjzznG0bzhFIUuP6voWsJKlnFoEkNc4iUHOSrEqy2EN93p/k8O71703wPqcnedgOxu97P2meOUeg5nT3kfpEVT1lB9v8oKp2+BjGJDcDq8c86GbPOZiAlibiHoFatVeSDye5IclHkzwsyeVJVic5B3hokqu7bfZOckmSa5J8NckJSX6LwTUJlyW5DAblkeQdSa4BnrXwfkNj/6V7jyu6e/WQ5And8nVJ3prkB936xyX5fJfhqxk8lU6aCotArToUOL+qDgP+L/C6hYGqOhP4t6o6oqp+DTgG+GZVPa3bi/hUVb0b+CaD20Y/t/vWvYEvddv975HP2xu4oqqeBnweeG23/lzg3Kp6Kts+e/ck4NKqOoLBg+u3OwVR2lUsArXq1qr6p+71h4B/t4NtrwOen+RtSX6xqv51zHb3AB8bM3Yng/PKAa4EVnWvnwX8Xff6b4a2Xw+c3N0B96lVdccO8kn3i0WgVo1Ojo2dLKuqrwFHMiiEtyY5a8ymP9rBvMBd9ZMJuXtY4mLOqvo88GwGF7x9IMmrdrS9dH9YBGrVQUme1b0+CRg9lHNXkgcBJPkZ4IdV9SHg7QxKAeAO4OH3M8cVwEu71/c9S6K7ueG3qup9wPuHPlPa5SwCtWoT8B+T3MDgYTX/dWT8AuDaJB8Gngp8OcnVwH8G3jq0zacWJouX6XTgjO4GZU8EFg47PQe4JslVwAkM5hKkqfD0UalH3XUI/1ZVlWQNcGJVHd93LrXFm85J/XoG8BdJwuDZ2L/Rcx41yD0CSWqccwSS1DiLQJIaZxFIUuMsAklqnEUgSY37/5izyI9sbjyvAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Select item to find\n", "item = \"100\"\n", "\n", "# get Grover circuit\n", "circ = grover(item, n_reps=2)\n", "\n", "# print circuit\n", "print(circ)\n", "\n", "# Measurement\n", "counts = get_result(circ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__DISCUSSION__: We observed how repeated application of the Grover operator has amplified the occurrence of the desired bitstring, while further suppressing wrong answers to our search problem. We get the correct result with high probability. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Device: IonQ \n", "\n", "Finally, we check whether this scheme works on quantum hardware, by submitting our circuit to the IonQ device. To achieve this check, we first need to express the ```CCZ``` gate in terms of the native gate set of IonQ. In doing so, we build a custom gate that can be registered as a subroutine and then used as if it were any other native quantum gate within our SDK. " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# Set up a QPU device\n", "device = AwsDevice(\"arn:aws:braket:us-east-1::device/qpu/ionq/Harmony\")" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Quantum Gates supported by IonQ Device:\n", " ['x', 'y', 'z', 'rx', 'ry', 'rz', 'h', 'cnot', 's', 'si', 't', 'ti', 'v', 'vi', 'xx', 'yy', 'zz', 'swap', 'i']\n" ] } ], "source": [ "# get device name\n", "device_name = device.name\n", "# show the properties of the device \n", "device_properties = device.properties\n", "# show supportedQuantumOperations (supported gates for a device)\n", "device_operations = device_properties.dict()['action']['braket.ir.jaqcd.program']['supportedOperations']\n", "# Note: This field also exists for other devices like the QPUs\n", "print('Quantum Gates supported by {}:\\n {}'.format(device_name, device_operations))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the 𝑁=8 Grover demonstration with three qubits shown in Figgatt et al. (2017), we need to implement the Controlled-Controlled-Z ```CCZ``` gate that is not natively provided on the IonQ device. We will construct this gate using native gates only such as ```CNOT``` and ```T```. Apart from our implementation, other alternative options are available (see [1] and references therein). " ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "@circuit.subroutine(register=True)\n", "def CCNot(controls=[0, 1], target=2):\n", " \"\"\"\n", " build CCNOT from H, CNOT, T, Ti\n", " \"\"\"\n", " cQb1, cQb2 = controls\n", " circ = Circuit().h(target).cnot(cQb2,target).ti(target).cnot(cQb1,target).t(target).cnot(cQb2,target).ti(target).cnot(cQb1,target).t(target).h(target).t(cQb2).cnot(cQb1,cQb2).t(cQb1).ti(cQb2).cnot(cQb1,cQb2)\n", " \n", " return circ \n", "\n", "def CCZ_ionq(controls=[0, 1], target=2):\n", " \"\"\"\n", " build CCZ from H and CCNOT\n", " \"\"\"\n", " circ = Circuit().h(target).CCNot(controls, target).h(target)\n", " return circ\n", "\n", "ccz_ionq = CCZ_ionq()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Following are oracles defined based on target items:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "# Four possible items and their corresponding oracles\n", "oracle_ionq = {\"000\": Circuit().x([0,1,2]).add(ccz_ionq).x([0,1,2]),\n", " \"001\": Circuit().x([0,1]).add(ccz_ionq).x([0,1]),\n", " \"010\": Circuit().x([0,2]).add(ccz_ionq).x([0,2]),\n", " \"011\": Circuit().x([0]).add(ccz_ionq).x([0]),\n", " \"100\": Circuit().x([1,2]).add(ccz_ionq).x([1,2]),\n", " \"101\": Circuit().x([1]).add(ccz_ionq).x([1]),\n", " \"110\": Circuit().x([2]).add(ccz_ionq).x([2]),\n", " \"111\": Circuit().add(ccz_ionq)\n", " }" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "# Select some example item to find\n", "item = \"111\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Same as with the classical simulator, we first initialize the qubits by applying the Hadamard gate ```H``` to every qubit." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "T : |0|\n", " \n", "q0 : -H-\n", " \n", "q1 : -H-\n", " \n", "q2 : -H-\n", "\n", "T : |0|\n" ] } ], "source": [ "# Initialize with superposition\n", "circ = Circuit();\n", "circ.h(np.arange(3))\n", "print(circ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we apply the phase oracle corresponding to our target item.\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "T : |0|1|2|3|4 |5|6|7|8 |9|10|11|12|\n", " \n", "q0 : -H----------C--------C-C--T--C--\n", " | | | | \n", "q1 : -H-----C----|---C-T--|-X--Ti-X--\n", " | | | | \n", "q2 : -H-H-H-X-Ti-X-T-X-Ti-X-T--H--H--\n", "\n", "T : |0|1|2|3|4 |5|6|7|8 |9|10|11|12|\n" ] } ], "source": [ "# Construct phase oracle\n", "circ.add_circuit(oracle_ionq[item])\n", "print(circ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To complete the circuit, we define the diffusion operator, whose job is to magnify the amplitude difference created by the oracle." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "T : |0|1|2|3|4 |5|6|7|8 |9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|\n", " \n", "q0 : -H----------C--------C-C--T--C--H--X--------------C-----------C--C--T--C--X--H--\n", " | | | | | | | | \n", "q1 : -H-----C----|---C-T--|-X--Ti-X--H--X--------C-----|-----C--T--|--X--Ti-X--X--H--\n", " | | | | | | | | \n", "q2 : -H-H-H-X-Ti-X-T-X-Ti-X-T--H--H--H--X--H--H--X--Ti-X--T--X--Ti-X--T--H--H--X--H--\n", "\n", "T : |0|1|2|3|4 |5|6|7|8 |9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|\n" ] } ], "source": [ "# Amplification\n", "circ.h(np.arange(3))\n", "circ.add_circuit(oracle_ionq['000'])\n", "circ.h(np.arange(3))\n", "print(circ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This circuit could potentially be optimized, as detailed in Ref.[1], but we will use this version for simplicity. \n", "\n", "In the final step, we retrieve the probabilistic counts for our target item. \n", "To this end, we submit our circuit to the IonQ device, by setting the device as ```AwsDevice(\"arn:aws:braket:us-east-1::device/qpu/ionq/Harmony\")```. \n", "\n", "This task may not be executed immediately as it enters a queue for this machine. \n", "Should we need to interrupt our kernel to work on something else, we can always recover our results using the unique ID of this task, as shown in the following lines. " ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Status of task: CREATED\n" ] } ], "source": [ "# set up device\n", "ionq = AwsDevice(\"arn:aws:braket:us-east-1::device/qpu/ionq/Harmony\")\n", "\n", "# run circuit \n", "ionq_task = ionq.run(circ, shots=1000)\n", "\n", "# get id and status of submitted task\n", "ionq_task_id = ionq_task.id\n", "ionq_status = ionq_task.state()\n", "# print('ID of task:', ionq_task_id)\n", "print('Status of task:', ionq_status)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Status of (reconstructed) task: QUEUED\n" ] } ], "source": [ "# print status\n", "status = ionq_task.state()\n", "print('Status of (reconstructed) task:', status)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Status of (reconstructed) task: COMPLETED\n" ] } ], "source": [ "# print status\n", "status = ionq_task.state()\n", "print('Status of (reconstructed) task:', status)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Status of (reconstructed) task: COMPLETED\n", "1000 shots taken on machine arn:aws:braket:us-east-1::device/qpu/ionq/Harmony.\n", "Measurement counts: Counter({'111': 354, '011': 166, '010': 103, '001': 93, '110': 87, '100': 72, '101': 69, '000': 56})\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# recover task\n", "task_load = AwsQuantumTask(arn=ionq_task_id)\n", "\n", "# print status\n", "status = task_load.state()\n", "print('Status of (reconstructed) task:', status)\n", "\n", "# wait for job to complete\n", "# terminal_states = ['COMPLETED', 'FAILED', 'CANCELLED']\n", "if status == 'COMPLETED':\n", " # get results\n", " results = task_load.result()\n", " \n", " # get all metadata of submitted task\n", " metadata = task_load.metadata()\n", " # example for metadata\n", " shots = metadata['shots']\n", " machine = metadata['deviceArn']\n", " # print example metadata\n", " print(\"{} shots taken on machine {}.\".format(shots, machine))\n", " \n", " # get measurement counts\n", " counts = results.measurement_counts\n", " print('Measurement counts:', counts)\n", "\n", " # plot results: see effects of noise\n", " plt.bar(counts.keys(), counts.values());\n", " plt.xlabel('bitstrings');\n", " plt.ylabel('counts');\n", " plt.tight_layout();\n", " plt.savefig('ionq.png', dpi=700);\n", " \n", "elif status in ['FAILED', 'CANCELLED']:\n", " # print terminal message \n", " print('Your task is in terminal status, but has not completed.')\n", "\n", "else:\n", " # print current status\n", " print('Sorry, your task is still being processed and has not been finalized yet.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The output looks relatively noisy due to decoherence and gate errors in this relatively long gate sequence. However, we can still observe a dominant peak for the target item. \n", "\n", "In summary, we have shown how to implement Grover's search algorithm on a classical simulator, as well as on the IonQ device, using simple modular building blocks. We have also demonstrated how to build custom gates outside of the basic gate set provided by the SDK, and how to register these as subroutines that can be used as if they were any other pre-defined quantum gate. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "# References \n", "\n", "[1] C. Figgatt, D. Maslov, K. A. Landsman, N. M. Linke, S. Debnath & C. Monroe (2017), \"Complete 3-Qubit Grover search on a programmable quantum computer\", Nature Communications, Vol 8, Art 1918, doi:10.1038/s41467-017-01904-7, arXiv:1703.10535.\n", "\n", "[2] Nielsen, Michael A., Chuang, Isaac L. (2010). Quantum Computation and Quantum Information (2nd ed.). Cambridge: Cambridge University Press." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Task Summary\n", "{'arn:aws:braket:us-east-1::device/qpu/ionq/Harmony': {'shots': 1000, 'tasks': {'QUEUED': 1}}}\n", "Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).\n", "Estimated cost to run this example: 10.31 USD\n" ] } ], "source": [ "print(\"Task Summary\")\n", "print(t.quantum_tasks_statistics())\n", "print('Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).')\n", "print(f\"Estimated cost to run this example: {t.qpu_tasks_cost() + t.simulator_tasks_cost():.2f} USD\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.8.10 ('venv': venv)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" }, "vscode": { "interpreter": { "hash": "590fab68195cf107911461461f81d5c472d3d6127f579badfcfad30f03e5cab2" } } }, "nbformat": 4, "nbformat_minor": 4 }