{ "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": 1, "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": 2, "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": 3, "id": "a3560b8f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "$\\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": 4, "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": 4, "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": 5, "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": 5, "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": 6, "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": 6, "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 dictionnary 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": 7, "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": 7, "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": 8, "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": 8, "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": 9, "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", "\n", "\n", "DETECTION\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": 9, "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": 10, "id": "0f000dac", "metadata": {}, "outputs": [ { "data": { "image/png": "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3DcAFFcEKQBAiRcXF6e4uDjVrl1bsbGxWrx4sR5//PFs27/yyiuaNWuWZs2apfXr12v//v3y8/PToUOH9Pbbb+c4njUULVmyRKmpqdm2i4mJ0b59++Tp6amHH344o7xNmzaaN2+etm/frscff1zXr1/XDz/8YMcZZzZy5EjFxcWpV69eio2N1aJFi7R//34999xz+vXXXzVq1Kg89w0AxRVBCgBQ4p04cUKS1Lx5czk6Otp9fK1atfTWW29JkpYvX55j+0aNGikgIEDJyclatWpVtu2sq1GPPPKInJycbLa59957Jf11DvY6duyYFixYICcnJ3366acqVeqvq/4nTZokLy8vzZ07VydPnsx03K5du3ThwoU8jQkAxQFBCgBQ4qWlpUmSypYtm+c+mjZtKkk6cuRIrtoPHjxYkjRv3jyb9YZhaMGCBZIyX9b3T9aAdf369VzP9e/WrFmj9PR0BQUFqUqVKpnqnJ2d1b17d924cUPff/99prr//ve/qlq1qgYNGqT169crPT09T+MDQFFFkAIAwAQXL16UdDN8/F27du1ksViybFwxcOBAOTo66rvvvtP58+ez9BcVFaWjR4/K399f999//22b9969eyVJzZo1s1lvLY+JiclUHhwcrOrVq2v+/PkKDg6Wj4+PXn31VR06dOi2zRUA7iQEKQBAiXft2jVJytNlfVYrV66UJDVu3DhX7atVq6aOHTvq2rVrWrJkSZZ662V91pWr7FjnfKt7rW4lKSlJkuTt7W2z3lqemJiYqXzgwIGKi4vTpk2b9MQTTyglJUXvvvuu7rrrLrVq1UrTp0/PceMNACjKCFIAgBIvPj5eklSpUiW7j/3zzz81efJkTZkyRZL09NNPZ6r38fFR/fr15eHhkeVY6yV7/9y97+rVqxlbnecUpDw9PTOdg70uXbokKfvLGl1dXSX9teL2T23atNFnn32m48ePa/Hixerevbt2796tZ555RtWqVVPfvn21atWqjMsnAaC44DlSAIAS68qVK9q9e7cmT54sSerYsWOujmvfvn2WMovFotdee02DBg3KVP71119n209oaKhcXV31448/6siRI6pZs6YkZVzu16pVK9WpU+eWcwkMDFSZMmW0fPlyLVq0SA899FChPPfJ2dlZffv2Vd++fXXq1CktWLBAX3/9tSIiIhQREaEqVapo5syZ6tKlS4HPDQBuB1akAAAl0kcffaSyZcuqTZs2Sk5O1ueff67g4OBcHWt9jlRYWJiefvppTZ48Wb/++muutj7/O1dXV4WGhsowDM2fPz+j3Nazo7Lj6empNWvWqG7duurfv78qVKigkJCQXM/Bzc1NknT58mWb9SkpKZIkd3f3XPfp5eWl559/Xp999pkeeughSTd3FYyNjc11HwBwp2NFCgBQIt19993q27evdu/erfj4eC1YsECDBg3K1c59r7zyitq1a2fKPB599FHNnTtX8+bN08svv6yzZ89q9erVKl26tPr165erPlatWqWDBw+qUqVKCgwMVIcOHXI9vo+PjyTp6NGjNuut5b6+vrnqLykpSfPmzdOcOXN08OBBSZKfn5+GDBmiRx55JNfzAoA7HUEKAFAiBQcHKzg4WGlpaerRo4dWr16tBQsWaPjw4QU6j44dO6patWrat2+f9u7dq61btyo1NVU9evRQxYoVczw+Li5OkyZNUrVq1fS///3P7sv6mjRpIknavXu3zXpr+a020Th//rwiIiI0d+5cRUdHyzAMubm5KSwsTEOHDlXbtm1lsVjsmhcA3OkIUgCAEq1UqVIaPHiwVq9erX379hX4+I6OjhowYICmTJmiefPmaevWrZJyd1mfpIw5d+/ePU/3RnXu3FkODg7atGmTTp48qcqVK2fUXbt2TStXrpSjo6MefvjhTMelpaVpzZo1mjNnjlasWKGrV6/KYrGoffv2Gjp0qHr37p2xUQUAFEfcIwUAKPGsD6K19Tyn/BoyZIgaNGigZcuWZdvGGppmzJihzZs3q3z58urevXuu+r9w4YIkZXmY7j9FRUXJYrHIz88vU3m1atU0YMAApaam6plnnsm0u96YMWN06tQpDR48OFPAkm7uTti9e3ctXrxYPj4+mjhxohISEvTDDz9oyJAhhCgAxR4rUgCAEs/6LCbDMEzvOykpSbGxsbcMaQEBAWrUqJH2798vSerbt2+WB/tmxzpnB4db/200PT1dklS6dOksdR999JG2bdumpUuXqkGDBmrRooUOHDig/fv3q27duhlbu/+dm5ubnnjiCYWFhSkwMDBXcwWA4oQgBQAlyF2HDhb2FJCNRx99VC+//LKknJ8dlRd79+6VdHOF7J8qVaqkHTt2KDw8XMuXL9eyZctUpUoVPf/883rrrbdsXjL44Ycfmj5H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Y/O1GjBggLZv327z2GvXrmnNmjXasWOHTp06pdTUVEnSvn37JN187e65555cz0WSLl26pJUrV2rPnj06e/asrl+/LunmPVmGYSg+Pt7mLoz9+/fPUta5c2dVqFBB8fHxOnbsmKpVq5ancZo3by5Jeu211+To6KgHH3xQZcqUsTn/devWSZJ69eplsz4oKEiStGPHjhxfi7y8P7JjnVdISIgcHLLehm29Z8rWvEqXLm3zuWS1a9fWL7/8ouDgYJt10s3X0yoqKkrXr19X586d5eLikuWYqlWrqm7dutq3b5+uXLmSpY2tcerVq5dlHAAgSAGAHQYPHqxvvvlGCxcu1OHDhzPKbiU1NVVhYWFasGBBtm2sgeqffHx8cpxT7969lZaWpqioqCwhSlLGM27Wr1+fYyg7ffq06tevrz///FOS5Ovra7OdvQ+nzWt/+/btU48ePW75nJ7sXrvsbNy4Uf3799epU6fs6tO6QYYtvr6+Sk5O1p9//pkRpOwdJywsTOvWrdPixYvVvXt3lSlTRvfee686d+6sYcOGqWrVqhltra9H69atb3mup0+fvmX93/uy5/2RU1+vv/66Xn/99Wzb2dqco2rVqjZDtpubmySpRo0a2dZdu3Ytyxy++OILffHFF9nOQZLOnj2bpV9vb+8s7azf97+PAwAEKQCww8MPP6zy5cvr66+/1p9//qm77rorx+dHTZkyRQsWLNA999yj999/X82aNVOFChVUunRp/frrr6pfv74Mw7B5bHYrEn83YMAAzZkzR//+97+1evXqjF8uray7AtapUyfHX7wrVqyY43gFxTAMPfLII0pISNBTTz2lp556SrVr15abm5ssFotee+01vfPOO9m+drZcunRJjzzyiM6ePatx48apf//+8vX1lYuLiywWiwYOHKgFCxbY1adZ4zg6OmrRokV65ZVX9O2332rjxo3avn27Nm3apHfffVdr1qzR/fffL+mv72mfPn3k6uqa7TwaNGiQ41zNfH9Y+2rTpo38/f1zHPvvbK1g2VP/zzkEBASoSZMmt2zr7Oyc53EAgCAFAHZwdnZW3759M/7S/fzzz+d4zLJlyyRJCxYsUMOGDTPV/f777/me08yZM3Xjxg3Nnz9fXbt21ffff5/pl2vrX9gbNGigWbNm5apP66qKdSvxf8qu3Mz+Dh06pEOHDqlFixaaPn16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", "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", "state_0_prob_list = results_list[0]\n", "state_1_prob_list = results_list[1]\n", "state_2_prob_list = results_list[2]\n", "state_3_prob_list = results_list[3]\n", "x = np.arange(4) # label locations\n", "width = 0.1 # the width of the bars\n", " \n", "fig, ax = plt.subplots(dpi=150)\n", "rects_0 = ax.bar(x - 3*width/2, state_0_prob_list, width, label=str(states[0]))\n", "rects_1 = ax.bar(x - width/2, state_1_prob_list, width, label=str(states[1]))\n", "rects_2 = ax.bar(x + width/2, state_2_prob_list, width, label=str(states[2]))\n", "rects_3 = ax.bar(x + 3*width/2, state_3_prob_list, width, label=str(states[3]))\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 }