{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pennylane as pl\n", "from pennylane import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 1: Uniform superposition" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "n_bits = 2\n", "dev = pl.device(\"default.qubit\", wires=n_bits)\n", "wires = list(range(n_bits))\n", "\n", "@pl.qnode(dev)\n", "def circuit():\n", " pl.Snapshot(\"Initial state\")\n", " # build a uniform superposition\n", " pl.Snapshot(\"After applying the Hadamard gates\")\n", " return pl.probs(wires=wires) \n", "\n", "pl.drawer.use_style(\"black_white\")\n", "pl.draw_mpl(circuit)();\n", "results = pl.snapshots(circuit)()\n", "for k, result in results.items():\n", " print(f\"{k}: {result}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y = np.real(results[\"After applying the Hadamard gates\"])\n", "bit_strings = [f\"{x:0{n_bits}b}\" for x in range(len(y))]\n", "plt.bar(bit_strings, y, color = \"#70CEFF\")\n", "plt.xticks(rotation=\"vertical\")\n", "plt.xlabel(\"State label\")\n", "plt.ylabel(\"Probability Amplitude\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 2: Oracle" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def oracle(keys):\n", " # return a diagonal matrix with entries 1 and -1 for the oracle\n", " return matrix\n", "\n", "print(oracle([[0,0],[0,1]]))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@pl.qnode(dev)\n", "def circuit(keys):\n", " # build a uniform superposition\n", " # perform the oracle as a unitary gate\n", " return pl.probs(wires=wires) \n", "\n", "pl.drawer.use_style(\"black_white\")\n", "pl.draw_mpl(circuit)([[0,0],[0,1]]);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 3: Amplitude amplification" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dev = pl.device(\"default.qubit\", wires=n_bits)\n", "\n", "@pl.qnode(dev)\n", "def circuit(keys):\n", " pl.Snapshot(\"Initial state\")\n", " pl.QubitUnitary(oracle(keys), wires=wires)\n", " pl.Snapshot(\"After oracle\")\n", " return pl.state()\n", "\n", "results = pl.snapshots(circuit)([[0,0]])\n", "# inspect the results; plot them in a bar chart using plt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "keys = [[0,1]]\n", "dev = pl.device(\"default.qubit\", wires=n_bits)\n", "\n", "@pl.qnode(dev)\n", "def circuit():\n", " pl.broadcast(pl.Hadamard, wires=wires, pattern=\"single\")\n", " pl.Snapshot(\"Before oracle\")\n", " pl.QubitUnitary(oracle(keys), wires=wires)\n", " pl.Snapshot(\"After oracle\")\n", " return pl.probs(wires=wires)\n", "# inspect the results before and after applying the oracle; plot them in a bar chart using plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 4: Diffusion operator" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def diffusion_operator(wires):\n", " # build the diffusion operator circuit\n", "\n", "@pl.qnode(dev)\n", "def circuit():\n", " pl.broadcast(pl.Hadamard, wires=wires, pattern=\"single\")\n", " pl.Snapshot(\"Uniform superposition\")\n", " pl.QubitUnitary(oracle(keys), wires=wires)\n", " pl.Snapshot(\"State marked by Oracle\")\n", " diffusion_operator(wires)\n", " pl.Snapshot(\"Amplitude after diffusion\")\n", " return pl.probs(wires=wires)\n", "\n", "results = pl.snapshots(circuit)()\n", "# inspect the results; plot them using plt " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 5: Grover" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "n_bits = 4\n", "dev = pl.device(\"default.qubit\", wires=n_bits)\n", "wires = list(range(n_bits))\n", "keys = [[0,1,0,1],[1,1,1,1]]\n", "M = 2\n", "N = 2**n_bits\n", "\n", "@pl.qnode(dev)\n", "def circuit():\n", " # build the grover circuit, and iterate it sqrt(n/m)*pi/4 times\n", " # hint: you can use pl.templates.GroverOperator\n", " return pl.probs(wires=wires)\n", "\n", "results = pl.snapshots(circuit)()\n", "# check the results" ] } ], "metadata": { "kernelspec": { "display_name": "pennylane", "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.12.7" } }, "nbformat": 4, "nbformat_minor": 2 }