{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "3a271506", "metadata": {}, "source": [ "# 2-mode Grover's search algorithm" ] }, { "attachments": {}, "cell_type": "markdown", "id": "34fa32af", "metadata": {}, "source": [ "We implement in this notebook a 2-mode optical realization of Grover's search algorithm, based on Kwiat et al. (2000). Grover’s search algorithm: An optical approach. [Journal of Modern Optics](https://doi.org/10.1080/09500340008244040), 47(2–3), 257–266." ] }, { "attachments": {}, "cell_type": "markdown", "id": "e22c5dde", "metadata": {}, "source": [ "## Introduction" ] }, { "attachments": {}, "cell_type": "markdown", "id": "c04c528f", "metadata": {}, "source": [ "### Motivation\n", "\n", "Searching for a specific item (called the marked item) in an unstructured list of $N$ items requires $O(N)$ accesses to the list classically. Grover showed in 1996 that is possible for a quantum computer to achieve this using only $O\\left(\\sqrt{N}\\right)$ iterations." ] }, { "attachments": {}, "cell_type": "markdown", "id": "08145e4a", "metadata": {}, "source": [ "### Algorithm summary\n", "\n", "For a list of size $N$, Grover's algorithm requires $\\log (N)$ qubits. The algorithm starts by setting each qubit in the superposition state $\\frac{1}{\\sqrt{2}}\\left(|0\\rangle+|1\\rangle\\right)$. Then it applies $O\\left(\\sqrt{N}\\right)$ iterations of a subroutine called inversion-about-mean, whose goal is to skew this initial uniform superposition state towards the desired marked state such the probability of measuring the marked state is amplified. This subroutine requires the application of an oracle unitary, which applies a relative $\\pi$ phase shift only to the quantum state encoding the item we are looking for in the database." ] }, { "attachments": {}, "cell_type": "markdown", "id": "5690fa9d", "metadata": {}, "source": [ "### Kwiat et al. implementation details\n", "\n", "The optical implementation of Kwiat et al. uses the polarization and path degree of freedom of a single beam to achieve a 2-qubit optical implementation of Grover's search algorithm. Although $N=4$ here, calculations show that only a single application of the inversion-about-mean subroutine is required.\n", "\n", "In an effort to reduce the number of optical components used in the experimental setup, the authors work with a compiled version of the circuit, which we will reproduce here using Perceval." ] }, { "attachments": {}, "cell_type": "markdown", "id": "7bc2f8dc", "metadata": {}, "source": [ "## Perceval implementation" ] }, { "attachments": {}, "cell_type": "markdown", "id": "904f535e", "metadata": {}, "source": [ "### Initialisation" ] }, { "cell_type": "code", "execution_count": 11, "id": "4d4c8ff1", "metadata": {}, "outputs": [], "source": [ "import math\n", "\n", "from tabulate import tabulate\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "import perceval as pcvl" ] }, { "attachments": {}, "cell_type": "markdown", "id": "09fa856a", "metadata": {}, "source": [ "We create in Perceval a circuit with two spatial modes, $a$ and $b$ denoting resapectively the lower and upper spatial modes. For clarity, the different equivalent encodings for each of the four basis states are given below in order:\n", "- marked item encoding: $\\left|\"00\"\\right\\rangle$, $\\left|\"01\"\\right\\rangle$, $\\left|\"10\"\\right\\rangle$, $\\left|\"11\"\\right\\rangle$\n", "- Kwiat et al. path and polarization encoding: $\\left|aH\\right\\rangle$, $\\left|aV\\right\\rangle$, $\\left|bH\\right\\rangle$, $\\left|bV\\right\\rangle$\n", "- Perceval path and polarization encoding: $\\left|0, 1:H\\right\\rangle$, $\\left|0, 1:V\\right\\rangle$, $\\left|1:H, 0\\right\\rangle$, $\\left|1:V, 0\\right\\rangle$\n", "\n", "We first define these states and their mode equivalent in Perceval:" ] }, { "cell_type": "code", "execution_count": 12, "id": "b8084f08", "metadata": {}, "outputs": [], "source": [ "states = [pcvl.BasicState(\"|0,{P:H}>\"),\n", " pcvl.BasicState(\"|0,{P:V}>\"),\n", " pcvl.BasicState(\"|{P:H},0>\"),\n", " pcvl.BasicState(\"|{P:V},0>\"),\n", " ]\n", "\n", "states_modes = [\n", " pcvl.BasicState([0, 0, 0, 1]),\n", " pcvl.BasicState([0, 0, 1, 0]),\n", " pcvl.BasicState([0, 1, 0, 0]),\n", " pcvl.BasicState([1, 0, 0, 0])\n", "]" ] }, { "attachments": {}, "cell_type": "markdown", "id": "fab191db", "metadata": {}, "source": [ "We use the following unitary matrix to represent the beamsplitters:" ] }, { "cell_type": "code", "execution_count": 13, "id": "a3560b8f", "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[\\begin{matrix}\\frac{\\sqrt{2}}{2} & - \\frac{\\sqrt{2}}{2}\\\\\\frac{\\sqrt{2}}{2} & \\frac{\\sqrt{2}}{2}\\end{matrix}\\right]$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "BS = pcvl.BS.Ry()\n", "pcvl.pdisplay(BS.U)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "54638f8d", "metadata": {}, "source": [ "The half-wave plates are defined in the article as:" ] }, { "cell_type": "code", "execution_count": 14, "id": "54d17968", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "ξ=pi/2\n", "δ=pi/2\n", "\n", "\n", "Φ=3*pi/2\n", "\n", "0\n", "0\n", "" ], "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def HWP(xsi):\n", " hwp = pcvl.Circuit(m=1)\n", " hwp.add(0, pcvl.HWP(xsi)).add(0, pcvl.PS(-math.pi/2))\n", " return hwp\n", "\n", "pcvl.pdisplay(HWP(math.pi/2))" ] }, { "attachments": {}, "cell_type": "markdown", "id": "3d3c98ab", "metadata": {}, "source": [ "### Circuit Construction" ] }, { "attachments": {}, "cell_type": "markdown", "id": "b2c267cb", "metadata": {}, "source": [ "We divide the compiled circuit of Kwiat et al. in three parts: [state initialization](#state-initialization-circuit), [oracle](#oracle) and [inversion about mean](#inversion-about-mean). However, due to the compilation, each individual part does not act exactly as described in the introduction." ] }, { "attachments": {}, "cell_type": "markdown", "id": "14ee9683", "metadata": {}, "source": [ "\n", "#### State initialization circuit" ] }, { "cell_type": "code", "execution_count": 15, "id": "f6718866", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "ξ=pi/8\n", "δ=pi/2\n", "\n", "\n", "Φ=3*pi/2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Ry\n", "\n", "\n", "Φ=pi\n", "\n", "\n", "\n", "0\n", "1\n", "0\n", "1\n", "" ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "init_circuit = (pcvl.Circuit(m=2, name=\"Initialization\")\n", " // HWP(math.pi / 8)\n", " // BS\n", " // pcvl.PS(-math.pi))\n", "\n", "pcvl.pdisplay(init_circuit)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "e8278f70", "metadata": {}, "source": [ "#### Oracle\n", "\n", "The oracle circuit can be initialised so that any one of the four list elements are marked. This is controlled via the integer parameter $mark \\in [0, 3]$." ] }, { "cell_type": "code", "execution_count": 16, "id": "96aba62a", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "ξ=0\n", "δ=pi/2\n", "\n", "\n", "Φ=3*pi/2\n", "\n", "\n", "\n", "\n", "δ=pi/2\n", "\n", "\n", "\n", "ξ=0\n", "δ=pi/2\n", "\n", "\n", "Φ=3*pi/2\n", "\n", "\n", "\n", "0\n", "1\n", "0\n", "1\n", "" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def oracle(mark):\n", " \"\"\"Values 0, 1, 2 and 3 for parameter 'mark' respectively mark the elements \"00\", \"01\", \"10\" and \"11\" of the list.\"\"\"\n", " oracle_circuit = pcvl.Circuit(m=2, name='Oracle')\n", " # The following dictionary translates n into the corresponding component settings\n", " oracle_dict = {0: (1, 0), 1: (0, 1), 2: (1, 1), 3: (0, 0)}\n", " PC_state, LC_state = oracle_dict[mark]\n", " # Mode b\n", " if PC_state == 1:\n", " oracle_circuit //= HWP(0)\n", " oracle_circuit.add(0, pcvl.PR(math.pi/2))\n", " if LC_state == 1:\n", " oracle_circuit //= HWP(0)\n", " # Mode a\n", " if LC_state == 1:\n", " oracle_circuit //= (1, HWP(0))\n", " if PC_state == 1:\n", " oracle_circuit //= (1, HWP(0))\n", " return oracle_circuit\n", "\n", "pcvl.pdisplay(oracle(0))" ] }, { "attachments": {}, "cell_type": "markdown", "id": "50596a16", "metadata": {}, "source": [ "#### Inversion about mean" ] }, { "cell_type": "code", "execution_count": 17, "id": "ef839994", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Ry\n", "\n", "\n", "\n", "ξ=pi/4\n", "δ=pi/2\n", "\n", "\n", "Φ=3*pi/2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Ry\n", "\n", "\n", "0\n", "1\n", "0\n", "1\n", "" ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "inversion_circuit = (pcvl.Circuit(m=2, name='Inversion')\n", " // BS\n", " // HWP(math.pi / 4)\n", " // BS)\n", "\n", "pcvl.pdisplay(inversion_circuit)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "4daf70f2", "metadata": {}, "source": [ "#### Detection\n", "\n", "The article also uses a detection circuit of the form:" ] }, { "cell_type": "code", "execution_count": 18, "id": "31ad50c7", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "1\n", "2\n", "3\n", "0\n", "1\n", "2\n", "3\n", "" ], "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "detection_circuit = pcvl.Circuit(m=4, name='Detection')\n", "detection_circuit.add((0, 1), pcvl.PBS())\n", "detection_circuit.add((2, 3), pcvl.PBS())\n", "\n", "pcvl.pdisplay(detection_circuit)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "76acc62f", "metadata": {}, "source": [ "However, Perceval allows us to filter out the photon's polarization state, meaning that there is no need to expand the circuit to four output spatial modes.\n", "\n", "For now, we will need this particular circuit." ] }, { "attachments": {}, "cell_type": "markdown", "id": "2326568e", "metadata": {}, "source": [ "#### Final circuit setup \n", "\n", "As above, the value of parameter 'mark' indicates which element of the list needs to be found." ] }, { "cell_type": "code", "execution_count": 19, "id": "1b0bffde", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Grover optical circuit for searching database element \"00\":\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "INITIALIZATION\n", "\n", "\n", "\n", "ξ=pi/8\n", "δ=pi/2\n", "\n", "\n", "Φ=3*pi/2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Ry\n", "\n", "\n", "Φ=pi\n", "\n", "\n", "ORACLE\n", "\n", "\n", "\n", "ξ=0\n", "δ=pi/2\n", "\n", "\n", "Φ=3*pi/2\n", "\n", "\n", "\n", "\n", "δ=pi/2\n", "\n", "\n", "\n", "ξ=0\n", "δ=pi/2\n", "\n", "\n", "Φ=3*pi/2\n", "\n", "\n", "INVERSION\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Ry\n", "\n", "\n", "\n", "ξ=pi/4\n", "δ=pi/2\n", "\n", "\n", "Φ=3*pi/2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Ry\n", "\n", "\n", "\n", "\n", "\n", "\n", "DETECTION\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "1\n", "2\n", "3\n", "0\n", "1\n", "2\n", "3\n", "" ], "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def grover_circuit(mark):\n", " grover_circuit = pcvl.Circuit(m=4, name='Grover')\n", " grover_circuit.add(0, init_circuit).add(0, oracle(mark)).add(0, inversion_circuit)\n", " grover_circuit.add(1, pcvl.PERM([1, 0])).add(0, detection_circuit)\n", " return grover_circuit\n", "\n", "print('Grover optical circuit for searching database element \"00\":')\n", "pcvl.pdisplay(grover_circuit(0), recursive=True)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "922a8f12", "metadata": {}, "source": [ "## Grover algorithm execution\n", "\n", "We can finally simulate Grover's algorithm for marked database elements \"00\", \"01\", \"10\" and \"11\"." ] }, { "cell_type": "code", "execution_count": 24, "id": "0f000dac", "metadata": {}, "outputs": [ { "data": { "image/png": "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UcNeywIAAABAgbPbrn2dO3fWjBkzdPr0aXl5eal3795ydXXVuHHjdOzYMdWqVUsLFizQyZMn9fTTT9trWQAAAAAocHY7IzV06FD17dtX//vf/yRJnp6e+uyzz2QYht5//32NGTNGu3fv1t133623337bLmtevXpVEydOVMOGDVWuXDnVrFlTI0eOzPOlg4mJiXrqqadUt25dOTs7q0qVKgoICNDUqVPtUi8AAACAksFuZ6SaN2+uxYsXZ2obPHiw2rVrp++//14pKSlq2LChevfubZfnSF27dk2dO3fWjh07VKNGDfXp00eJiYmaM2eOvvvuO+3YsUP16tXL9Xzr1q1T//79dfXqVbVs2VJt27bV2bNntX//fn322WcaN25cvmsGAAAAUDLYLUhlx9vbW0899ZTd550yZYp27NihgIAAbdy4UW5ubpKk6dOn66WXXtLIkSMVGRmZq7kOHz6svn37yt3dXZs2bdL9999v6cvIyFBMTIzd6wcAAABQfNnt0j5rUlJSlJKSIsMw7DpvWlqaZs6cKUn65JNPLCFKksaOHatmzZopKipKe/bsydV8Y8eO1bVr1zR37txMIUqSHBwc1Lp1a/sVDwAAAKDYs3uQWr16tYKCguTm5qYqVaqoSpUqcnd3V1BQkL799lu7rLFt2zZduHBBfn5+atGiRZb+/v37S5LWrFmT41xHjx7Vhg0bVK9ePT388MN2qQ8AAABAyWa3S/sMw9CoUaM0b948yxko87Okzp8/r82bN+uHH37Qo48+qjlz5shkMuV5rX379kmSWrZsabXf3B4bG5vjXJGRkcrIyND999+v9PR0ffPNN9q2bZtu3ryppk2bauDAgapUqVKeawUAAABQ8tgtSM2YMUNz585VzZo19cYbb2jw4MGWh/ReunRJixcv1qRJkzR//nz5+/trzJgxeV7L/Lyq2rVrW+03tyclJeU4l3mXQTc3NwUGBmrHjh2Z+l9//XWFh4erU6dOuaqtSZMmVtsTEhLk5+eXqzkAAAAAFG12u7Tv888/V/ny5bV161Y9+eSTlhAlSe7u7nriiSe0detWubi46PPPP8/XWpcvX5YklS9f3mq/q6urpFsBLicpKSmSpC+//FKHDx/WokWLdO7cOcXFxWnYsGE6d+6cQkJC8rylOgAAAICSx25npI4cOaKgoCDVrVs32zF169ZVly5d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CgBKkcR3exR2CUVGuXLlFBERoXfeeUeLFi3SqlWr5OnpqdDQUE2ePNnqw3r37dsnSRo+fHhBl1skBQYGavPmzYVdBgAUCoIUAKDUcnFx0aRJkzRp0qRcjY+IiJCnp6flgbPZcXJykiRdv379tuMSExNztW5ujgkNDVVoaGiOx0dGRuY4xly3s7OzDZUBQOnCPVIAAOTCzZs39eOPP+rf//53js+XqlGjhiTd0fuY7qTdu3dL+ut1AACy4owUAAC54OjomOsH0rZt21aVK1fWli1b1LRpUzVt2lSDBg1ScHDwHa0xP86cOaOxY8fq5MmTioiIkCT17NmzkKsCgKKLM1IAANiZi4uL1q1bp4cfflinTp1SeHi49u7dW9hl3dbly5e1YMECbdu2TU2aNNGHH36o/v37F3ZZAFBkcUYKAIA74N5779XatWsLu4xc8/X1texKCADIGWekAAAlmr+/v958880sD90FACA/inWQunr1qiZOnKiGDRuqXLlyqlmzpkaOHKk//vgj13OcP39eixYt0uDBg1W3bl05OTnJ3d1d9913n2bMmKEbN27cwVcAALjT/P39FRYWRpACANhVsb2079q1a+rcubN27NihGjVqqE+fPkpMTNScOXP03XffaceOHapXr16O83zwwQd6++23ZTKZ5O/vr/vuu0+nT5/Wtm3btGvXLoWHh2vDhg08ZBAAAACARbE9IzVlyhTt2LFDAQEB+vXXX7V06VLt3LlT06ZN0+nTpzVy5MhczePq6qrx48crMTFRMTExWrJkiX744Qft379f3t7e+umnnzRlypQ7/GoAAAAAFCfFMkilpaVp5syZkqRPPvlEbm5ulr6xY8eqWbNmioqK0p49e3Kc69VXX9V7770nb2/vTO0NGjTQu+++K0lavHixHasHAAAAUNwVyyC1bds2XbhwQX5+fmrRokWWfvN2rWvWrMnXOs2bN5ck/fnnn/maBwAAAEDJUiyD1L59+yRJLVu2tNpvbo+Njc3XOr///rskqXr16vmaBwAAAEDJUiw3m0hOTpYk1a5d22q/uT0pKSlf68yYMUOS1KdPn1wf06RJE6vtCQkJ8vPzy1c9AAAAAIqGYnlG6vLly5KU7U56rq6ukqRLly7leY3/+7//0+bNm1WxYkW98soreZ4HAAAAQMlTLM9I3Wlbt27VCy+8IJPJpNmzZ6tmzZq5PvbgwYNW27M7UwUAAACg+CmWQcq8S9+VK1es9qempkqS3N3dbZ77wIED6tOnj9LS0vTxxx8rJCQk74UCAAAAKJGKZZAyb1V+7Ngxq/3mdh8fH5vmPXLkiIKCgpSSkqKwsDA999xz+SsUAIqaMI/CriB3wi7Ybaq5c+fqscce05w5cxQaGpqp7+rVq3rnnXe0ZMkSJScny9PTU926ddPkyZNVq1atfK0bHR2tSZMmKSYmRufOndPrr7+usLCwTGN8fX2z3M/r7u6uRo0aaeDAgXr++efl5OR023UuXryoatWq6fr160pMTMzyOI9/euaZZzRr1iyNHTtW06ZNkySFhYXp7bffVqVKldSyZUu9+eabCggIsP1FA0ApUizvkTJvSx4TE2O139zerFmzXM95/Phxde3aVcePH9cLL7ygN998M/+FAgCKrGvXrqlz586aPHmyLl++rD59+qhOnTqaM2eOWrRoYdm5NS8uX76s7t27a/369apatar69esnf3//bMf369dPI0aM0PDhw9WiRQvt27dP48aNU9euXZWWlnbbtSpUqKDevXvLMAwtXLjwtmNv3LihZcuWSZIeffRRS7u/v7/69++v6tWra8OGDXr44Yct9yMDAKwrlkGqXbt28vDwUEJCgvbu3ZulPzw8XJLUq1evXM2XkpKihx56SAkJCXrsscf04Ycf2rNcAEARNGXKFO3YsUMBAQH69ddftXTpUu3cuVPTpk3T6dOnNXLkyDzPHR0drQsXLqhDhw7av3+/lixZouDg4GzHf/DBB5o7d67mzZunqKgo7dq1Sx4eHvrxxx/1+eef57ieORTlFKTWrVuns2fPqmnTppmCXXBwsBYvXqzY2Fh17dpV58+f144dO3L1WgGgtCqWQcrJyUmjR4+WJD377LOWe6Ikafr06YqNjVWHDh3UqlUrS/vMmTPVuHFjvfrqq5nmunLlinr06KH9+/frkUce0RdffCGTyVQwLwQAUCjS0tI0c+ZMSdInn3xiufdWksaOHatmzZopKipKe/bsydP8J0+elCS1adMmT8f7+/tr7NixkqRVq1blOL5bt27y8vLSwYMH9csvv2Q7bsGCBZKkYcOGZTumdevWkv56DdnZs2ePLl68mGNtAFBSFct7pCRpwoQJ2rx5s7Zv364GDRooMDBQSUlJ2rlzp7y8vDR79uxM48+c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TZs21aBBgxQcHHxHa8yrVatWaenSpTp48KD279+vKlWq6L777ivssgCgSOOMFAAAdubi4qJ169bp4Ycf1qlTpxQeHm51m/WiYu/evVq+fLlOnDih7t276/vvv5eLi0thlwUARRpnpAAAuAPuvfderV27trDLyJWwsDCFhYUVdhkAUKxwRgoAUKL5+/vrzTfflL+/f2GXAgAoQTgjBQAo0fz9/QlRAAC744wUAAAAANiIIAUAAAAANiJIAQAAAICNCFIAAAAAYCOCFAAAAADYiCAFAAAAADYiSAEAAACAjQhSAAAAAGAjghQAAAAA2KhMYRcAACg498y7p7BLyJX9I/bbba65c+fqscce05w5cxQaGprtuEOHDmnChAnasWOHTp8+rSFDhmju3LmZxnTs2FFRUVGZ2lxdXVWvXj316dNH48aNU4UKFXJVV2RkpDp16qQOHTooMjIy23GhoaGaN2+e1fpNJpPKly8vHx8fhYSE6M0335STk1Ou1s/O3Llz9emnn+p///ufnJyc1LZtW02YMEH3339/vuYFgJKGIAUAKPUMw1Dv3r0VHx8vPz8/BQcHq3379tmOf+ihh1S9enVJ0h9//KHt27drypQpCg8P1/bt21WpUqUCqXvEiBE6c+aMIiIi9J///EcuLi6aMGFCnucbM2aMZsyYIRcXFwUFBenatWvatGmTNm7cqPDwcAUHB9uveAAo5ghSAIBSLz4+XvHx8apXr57i4uLk6Oh42/GvvPKKOnbsaPn6yJEj6ty5sw4fPqy3335bH3zwwR2u+BbzGbNt27apffv2Wr9+fZ6D1ObNmzVjxgxVrlxZ0dHRatCggSQpOjpaHTt21GOPPaaOHTuqYsWKdqoeAIo37pECAJR6J0+elCS1atUqxxBlTd26dfXWW29JklatWmXP0nLl3nvvlfTX68iL6dOnS5ImTJhgCVGSFBAQoKeeekrnz5/XV199lemY48eP6/Dhw3leEwCKM4IUAKDUS09PlySVL18+z3O0aNFCknT06FG71GQL831RN27cyNPxV69e1ZYtWyRJ/fv3z9JvbluzZk2m9ri4ON11111q27atZs2apZSUlDytDwDFEUEKAAA7uHTpkiTJ2dk5U3vHjh1lMpmybFxRlMTFxen69evy8vJS7dq1s/S3bNlSkhQbG5up3dfXVw8++KB2796tZ555RjVq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//33atOmTab+mJgYnTlzRl27dlW1atWyHO/i4qJWrVpp7dq1+u2339SoUSP99NNPkqRu3brJw8MjyzGDBw/W0qVLc3zNZlu3bpUk9e/f3+r3avDgwdq5c6fVY69fv67169dr165dOn36tNLS0iRJ+/fvl3Tre3fPPffkuhZJunz5stasWaO9e/fq3LlzunHjhqRb92QZhqGEhASruzAOGjQoS1u3bt1UqVIlJSQk6Pjx46pRo0ae1mnVqpUk6bXXXpOjo6MefPBBlStXzmr9GzdulCT17dvXan9gYKAkadeuXTl+L/Ly/siOua7g4GA5OGS9Ddt8z5S1usqWLWv1uWT16tXTL7/8oqCgIKt90q3vp1lkZKRu3Lihbt26ycXFJcsx1atXV4MGDbR//35dvXo1yxhr6zRs2DDLOgBAkAIAGwwbNkzffPONlixZoiNHjljabictLU2hoaFavHhxtmPMgeqfvL29c6ypX79+Sk9PV2RkZJYQJcnyjJtNmzblGMrOnDmjRo0a6c8//5Qk+fj4WB1n68Np8zrf/v371bt379s+pye77112tmzZokGDBun06dM2zWneIMMaHx8fpaSk6M8//7QEKVvXCQ0N1caNG7Vs2TL16tVL5cqV07333qtu3bpp5MiRql69umWs+fvRrl27277WM2fO3Lb/73PZ8v7Iaa7XX39dr7/+erbjrG3OUb16dash283NTZJUq1atbPuuX7+epYYvvvhCX3zxRbY1SNK5c+eyzFu7du0s48x/739fBwAIUgBgg4cfflgVK1bU119/rT///FN33XVXjs+Pmj59uhYvXqx77rlH77//vlq2bKlKlSqpbNmy+vXXX9WoUSMZhmH12OzOSPzd4MGDNX/+fP373//WunXrLL9cmpl3Baxfv36Ov3hXrlw5x/UKimEYeuSRR5SYmKinnnpKTz31lOrVqyc3NzeZTCa99tpreuedd7L93llz+fJlPfLIIzp37pwmTpyoQYMGycfHRy4uLjKZTBoyZIgWL15s05z2WsfR0VFLly7VK6+8om+//VZbtmzRzp07tXXrVr377rtav3697r//fkl//Z32799frq6u2dbRuHHjHGu15/vDPFf79u3l5+eX49p/Z+0Mli39/6zB399fzZs3v+1YZ2fnPK8DAAQpALCBs7OzBgwYYPmX7ueffz7HY1auXClJWrx4sZo0aZKp7/fff893TXPmzNHNmze1aNEi9ejRQ99//32mX67N/8LeuHFjzZ07N1dzms+qmLcS/6fs2u053+HDh3X48GG1bt1as2bNytKfl+/d1q1bdfbsWfXv319vvfWWTXOmpKTo0qVLVs9KJScnS5Jq1qyZ73VatGihFi1aKCwsTBcvXlRYWJg+/PBDjRkzxnJJXO3atRUXF6dXXnnFcklgXuXl/ZHTXMHBwXrppZfyNVd+a2jfvr3++9//FkoNAEoH/tkFAGz06KOPqnLlyqpSpYqGDh2a4/iUlBRJ1i8ZWrZsWb7rcXR01Ndff61Bgwbpxx9/VM+ePTM99+fee++Vh4eHoqKidO7cuVzN2b59e0nS+vXrdfHixSz9S5YssalG8z07K1assPrcLGvz3e77lpKSok2bNlldy8nJSZKsPivodnPGx8crJiYmu5cgyfrf18aNG3Xu3DnVq1fPEhjzu45ZhQoV9M4778hkMunAgQOW9q5du0r6K6TnR17eH9mxZ1151alTJzk6Ouq7776z3JN2p9zuvQag5CNIAYCNAgMDdebMGZ0+fTrbe37+znyj+v/93/9lag8PD9fXX39tl5ocHR21YMECPfLII4qMjFSvXr109epVSbfOoo0fP16XLl1S3759rZ4N+eOPPzR//nzL135+fgoKCtLFixf10ksv6ebNm5a+77//XsuXL7epvo4dO6px48ZKSEjQlClTMvV99tlnio6OznJM/fr15eDgoC1btmTajOPatWt66qmnsv2l33xWyNoDbM1/F998802me5fOnz+vUaNG5fiL91tvvZXpfq0zZ85o3LhxkqRnn302X+vMnz8/U1gyW7dunQzDUJ06dSxtTz75pKpWrar3339fn3/+eZZwmp6erg0bNlid75/y8v7Izn333aeuXbtq27ZtevbZZ62G8H379t32Icz5VatWLY0cOVKJiYkaPHiwTp48mWVMfHy8VqxYke+1bvdeA1AKFNp+gQBQDOhv25/nJLvtz6OioizPXWrVqpUxePBgy/N0/v3vf1vdRty8/fk/H8L6d9a2+b5x44bRr18/Q5Lx4IMPGlevXjUM49YDVx999FFDkuHk5GTcd999xqBBg4y+ffsaTZo0MUwmk9G8efNMcyUkJFgeOOrn52d5ILDJZDKeffZZmx/Iu2PHDsvDcu+55x5j8ODBxr333nvbB/L+61//MiQZLi4uRo8ePYz+/fsb1apVM6pUqWKEhoZa/R5NmzbNkGRUq1bNGDRokDFq1KhMz0Dq2rWrIcmoWLGiERwcbAQHBxsVK1Y06tevb/Tp08fqs5H0twfyli9f3ujVq5fRt29fo2LFipZnQv39WVt5Wcfc5ufnZwQHBxuDBw822rZta5hMJsPBwcFYtmxZpvmjo6ONKlWqGJKMOnXqGN27dzeGDBlidO7c2VLXypUrc/V3k5f3x+0eyGvesrxixYpGx44djSFDhhg9evSwPOD3hRdeyPL9ze6xAdmtYxiGERERYfV9c+XKFcv339XV1WjXrp0xePBgo3fv3pZnQvXp0yfTMbfbNj+7dVasWGF5TED//v2NUaNGGaNGjbI6B4CShyAFALdhjyBlGLd+6e3cubNRqVIlw93d3bj//vuNFStWGEeOHLFrkDKMW2EqJCTEkGQEBQVZwpRhGMa3335r9OjRw6hatapRtmxZo2rVqkarVq2M8ePHG3v27MkyV2JiojFkyBCjcuXKRrly5Qx/f39j7ty52dadk9jYWKNXr16Gh4eH4erqagQEBBjfffddtr+opqenG9OmTTPuvvtuo1y5cka1atWMoUOHGomJidl+j27cuGFMmDDB8PPzM8qWLZvl7+TKlSvG66+/bjRo0MBwdnY26tSpYzz11FPGmTNnsv2l3TzHtWvXjNdee83w9fU1nJycDB8fH+P111+3+rwiW9eJiooynn32WcPf39/y/a5Xr54xaNAgY/fu3Va/n8ePHzfGjx9vNGnSxChfvrxRvnx5w8/Pz+jTp48xd+5c49KlS7b89dj0/rhdwLl69arx8ccfG/fff7/h4eFhODk5GXXq1DE6dOhgTJ061Th69KjV7681eQlShnHrvTNv3jyjc+fOhqenp1G2bFmjZs2aRkBAgPHWW28ZcXFxmcbnJUgZxq1net19992Gs7Oz5XlYAEoHk2Hkc2siAAAAAChluEcKAAAAAGxEkAIAAAAAGxGkAAAAAMBGBCkAAAAAsBFBCgAAAABsRJACAAAAABsRpAAAAADARgQpAAAAALARQQoAAAAAbESQAgAAAAAbEaQAAAAAwEYEKQAAAACwEUEKAAAAAGxEkAIAAAAAGxGkAAAAAMBGBCkAAAAAsBFBCgAAAABsRJACAAAAABv9P+XYdllyx5HcAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Circuit simulation\n", "input_state = pcvl.BasicState(\"|{P:H},0, 0, 0>\")\n", "results_list = [] # probability amplitudes storage\n", "\n", "for mark in range(4):\n", " sim = pcvl.Processor(\"SLOS\", grover_circuit(mark))\n", " ca = pcvl.algorithm.Analyzer(sim,\n", " input_states=[input_state],\n", " output_states=states_modes,\n", " )\n", " results_list.append(ca.distribution[0])\n", "\n", "# Plot data\n", "labels = ['\"00\"', '\"01\"', '\"10\"', '\"11\"']\n", "x = np.arange(4) # label locations\n", " \n", "fig, ax = plt.subplots(dpi=150)\n", "for i in range(4):\n", " ax.bar(x, results_list[i].real, 0.1, label=str(states[i]))\n", "\n", "ax.set_xlabel('Marked database element')\n", "ax.set_ylabel('Detection probability') \n", "ax.set_xticks(x, labels)\n", "ax.legend()\n", "ax.grid(True, axis='x')\n", "plt.show()" ] }, { "attachments": {}, "cell_type": "markdown", "id": "659482dd", "metadata": {}, "source": [ "As demonstrated by the graph above, Grover's algorithm indeed finds the marked database element!" ] }, { "attachments": {}, "cell_type": "markdown", "id": "d32d028f", "metadata": {}, "source": [ "## Reference\n", "\n", "> Kwiat et al. Grover’s search algorithm: An optical approach. [Journal of Modern Optics](https://doi.org/10.1080/09500340008244040), 47(2–3), 257–266 (2000).\n" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }