diff --git a/binder-index.md b/binder-index.md index 06b87df6042c..7f8ecb460549 100644 --- a/binder-index.md +++ b/binder-index.md @@ -259,6 +259,14 @@ These are noted in the README.md files for each sample, along with complete inst Q# standalone + + + Entanglement Swapping + Q# notebook + Qiskit + Python + Q# standalone + + Process tomography diff --git a/samples/azure-quantum/entanglement-swap/ES-quantinuum-qiskit.ipynb b/samples/azure-quantum/entanglement-swap/ES-quantinuum-qiskit.ipynb new file mode 100644 index 000000000000..27c083517c96 --- /dev/null +++ b/samples/azure-quantum/entanglement-swap/ES-quantinuum-qiskit.ipynb @@ -0,0 +1,875 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Quantum Teleportation" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, Aer, execute, transpile" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$\\providecommand{\\ket}[1]{\\left|#1\\right\\rangle}$\n", + "$\\providecommand{\\bra}[1]{\\left\\langle#1\\right|}$\n", + "\n", + "In this sample, we will be looking at using quantum teleportation on the Azure Quantum service.\n", + "\n", + "To refresh our mind let us review how quantum teleportation works.\n", + "\n", + "We have two parties, Alice and Bob, they would like to share information, and they have an entangled state (usually the Bell state $\\frac{1}{\\sqrt{2}} (\\ket{00} + \\ket{11})$). \n", + "If Alice now wishes to transfer quantum information, she will entangle some payload with her qubit and measure her qubit and payload.She will transmit the results of the measurement to Bob, who can use them to reconstruct Alice's payload on his entangled qubit.\n", + "\n", + "In the following code we will implement this operation." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def create_bell_state():\n", + " (alice, bob) = (QuantumRegister(1), QuantumRegister(1))\n", + " qc = QuantumCircuit(alice, bob)\n", + " qc.name = 'create_bell_state'\n", + " qc.h(alice)\n", + " qc.cx(alice, bob)\n", + " return qc.to_instruction()\n", + "\n", + "\n", + "def send():\n", + " (alice, payload) = (QuantumRegister(1), QuantumRegister(1))\n", + " (cr_x, cr_z) = (ClassicalRegister(1), ClassicalRegister(1))\n", + " qc = QuantumCircuit(alice, payload, cr_x, cr_z)\n", + " qc.name = 'send'\n", + " qc.cx(payload, alice)\n", + " qc.h(payload)\n", + " qc.measure(alice, cr_x)\n", + " qc.measure(payload, cr_z)\n", + " return qc.to_instruction()\n", + "\n", + "\n", + "def recv(qc: QuantumCircuit, bob: QuantumRegister, cr_x: ClassicalRegister, cr_z: ClassicalRegister):\n", + " qc.x(bob).c_if(cr_x, 1);\n", + " qc.z(bob).c_if(cr_z, 1);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will now use Qiskit's visualization tools to look show the unitary responsible from creating the Bell State.\n", + "Printing unitary transformations implemented by operations is a great way to check whether your implementation is mathematically correct (for small operations)." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def create_teleport_circuit_base():\n", + " (alice, bob, payload) = (QuantumRegister(1, 'alice'), QuantumRegister(1,'bob'), QuantumRegister(1,'payload'))\n", + " (cr_x, cr_z, res) = (ClassicalRegister(1, 'cr_x'), ClassicalRegister(1, 'cr_z'), ClassicalRegister(1, 'res'))\n", + " return (QuantumCircuit(alice, bob, payload, cr_x, cr_z, res), alice, bob, payload, cr_x, cr_z, res)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0.707+0.j 0.707-0.j 0. +0.j 0. +0.j]\n", + " [ 0. +0.j 0. +0.j 0.707+0.j -0.707+0.j]\n", + " [ 0. +0.j 0. +0.j 0.707+0.j 0.707-0.j]\n", + " [ 0.707+0.j -0.707+0.j 0. +0.j 0. +0.j]]\n" + ] + } + ], + "source": [ + "alice = QuantumRegister(1, 'alice')\n", + "bob = QuantumRegister(1, 'bob')\n", + "qc = QuantumCircuit(alice, bob)\n", + "qc.append(create_bell_state(), [alice, bob])\n", + "\n", + "backend = Aer.get_backend('unitary_simulator')\n", + "\n", + "job = execute(qc, backend)\n", + "result = job.result()\n", + "\n", + "print(result.get_unitary(qc, decimals=3).data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below we will now verify that our teleportation does indeed work correctly.\n", + "\n", + "We will be visualizing our circuit using Qiskit's tools to manually introspect it for correctness." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
         ┌────────────────────┐ ░ ┌───────┐          \n",
+       "  alice: ┤0                   ├─░─┤0      ├──────────\n",
+       "         │  create_bell_state │ ░ │       │┌───┐┌───┐\n",
+       "    bob: ┤1                   ├─░─┤       ├┤ X ├┤ Z ├\n",
+       "         └────────────────────┘ ░ │       │└─╥─┘└─╥─┘\n",
+       "payload: ───────────────────────░─┤1 send ├──╫────╫──\n",
+       "                                ░ │       │  ║    ║  \n",
+       "   cr_x: ═════════════════════════╡0      ╞══■════╬══\n",
+       "                                  │       │ 0x1   ║  \n",
+       "   cr_z: ═════════════════════════╡1      ╞═══════■══\n",
+       "                                  └───────┘      0x1 \n",
+       "    res: ════════════════════════════════════════════\n",
+       "                                                     
" + ], + "text/plain": [ + " ┌────────────────────┐ ░ ┌───────┐ \n", + " alice: ┤0 ├─░─┤0 ├──────────\n", + " │ create_bell_state │ ░ │ │┌───┐┌───┐\n", + " bob: ┤1 ├─░─┤ ├┤ X ├┤ Z ├\n", + " └────────────────────┘ ░ │ │└─╥─┘└─╥─┘\n", + "payload: ───────────────────────░─┤1 send ├──╫────╫──\n", + " ░ │ │ ║ ║ \n", + " cr_x: ═════════════════════════╡0 ╞══■════╬══\n", + " │ │ 0x1 ║ \n", + " cr_z: ═════════════════════════╡1 ╞═══════■══\n", + " └───────┘ 0x1 \n", + " res: ════════════════════════════════════════════\n", + " " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def perform_teleportation_on_bell_state(qc: QuantumCircuit, \n", + " alice: QuantumRegister, bob: QuantumRegister, payload: QuantumRegister, \n", + " cr_x: ClassicalRegister, cr_z: ClassicalRegister):\n", + " qc.append(send(), [alice, payload], [cr_x, cr_z])\n", + " recv(qc, bob, cr_x, cr_z)\n", + " return qc\n", + "\n", + "def create_full_teleport_circuit():\n", + " (qc, alice, bob, payload, cr_x, cr_z, _) = create_teleport_circuit_base()\n", + "\n", + " qc.append(create_bell_state(), [alice, bob])\n", + " qc.barrier()\n", + " perform_teleportation_on_bell_state(qc, alice, bob, payload, cr_x, cr_z)\n", + " return qc\n", + "\n", + "\n", + "create_full_teleport_circuit().draw(fold=-1, cregbundle=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will now simulate our code and see that we manage to teleport our payload correctly.\n", + "For this Alice rotates the payload at an unusual angle and make sure that the adjoint rotation resets Bob's qubit to $\\ket{0}$ making the overall state of the system $\\ket{000}$." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit.tools.visualization import plot_histogram\n", + "\n", + "(qc_prep, alice, bob, payload, cr_x, cr_z, res) = create_teleport_circuit_base()\n", + "qc_prep.ry(0.2791, payload)\n", + "\n", + "(qc_meas, alice, bob, payload, cr_x, cr_z, res) = create_teleport_circuit_base()\n", + "qc_meas.ry(-0.2791, bob)\n", + "qc_meas.measure(bob, res)\n", + "# Reset cr_x cr_z qubits to clean up output\n", + "qc_meas.reset(payload)\n", + "qc_meas.measure(payload, cr_x)\n", + "qc_meas.measure(payload, cr_z)\n", + "\n", + "qc = qc_prep.compose(create_full_teleport_circuit()).compose(qc_meas)\n", + "\n", + "simulator = Aer.get_backend('aer_simulator')\n", + "\n", + "qc_t = transpile(qc, simulator)\n", + "result = simulator.run(qc_t, shots=500).result()\n", + "counts = result.get_counts(qc_t)\n", + "plot_histogram(counts, title=\"Bob's qubit state\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Seeing empirically that our teleportation works, we can proceed to run it on hardware and see how often we successfully create bell states between Alice and Bob.\n", + "\n", + "\n", + "As a first step we need to set up our Azure Quantum provider and see the backends it offers." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.tools.monitor import job_monitor\n", + "from azure.quantum.qiskit import AzureQuantumProvider" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "provider = AzureQuantumProvider(\n", + " resource_id=\"/subscriptions/2cc419b3-3ace-4156-b256-44663dd90190/resourceGroups/AzureQuantum/providers/Microsoft.Quantum/Workspaces/AdriansProjectWorkspace\",\n", + " location=\"westus\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['ionq.qpu', 'ionq.simulator', 'quantinuum.hqs-lt-s1', 'quantinuum.hqs-lt-s1-apival', 'quantinuum.hqs-lt-s2', 'quantinuum.hqs-lt-s2-apival', 'quantinuum.hqs-lt-s1-sim', 'quantinuum.hqs-lt-s2-sim']\n" + ] + } + ], + "source": [ + "print([backend.name() for backend in provider.backends()])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When running jobs on Azure Quantum, before going to real hardware it is recommended to run your code through a validator to make sure you don't waste precious resources on faulty code. The validator is made available as the `quantinuum.hqs-lt-s2-apival` target.\n", + "\n", + "\n", + "We now transpile our code for the target and run it for validation. For this we create a job, submit it, then monitor it using `job_monitor` (a function provided by Qiskit that blocks execution until execution of the job is complete) and proceed to introspect the results" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Job id cf5a81eb-3054-11ed-a3d6-dc215ca5fadb\n" + ] + } + ], + "source": [ + "validator_backend = provider.get_backend(\"quantinuum.hqs-lt-s2-apival\")\n", + "qc_t = transpile(qc, validator_backend)\n", + "job = validator_backend.run(qc_t, job_name=\"Validate Entanglement Swapping\")\n", + "job_id = job.id()\n", + "print(\"Job id\", job_id)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Job Status: job has successfully run\n" + ] + } + ], + "source": [ + "job_monitor(job)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "API validation succeeded!\n" + ] + } + ], + "source": [ + "result = job.result()\n", + "if not result.success:\n", + " raise Exception(\"API validation Failed\")\n", + "print(\"API validation succeeded!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now with the confidence that our job will work we can submit it to the simulator. The Quantinuum emulator provided by Azure Quantum differs from the simulator running locally, in that it accurately models noise and behavior of the Quantinuum quantum computer." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Job id d6b91b3e-3054-11ed-ab67-dc215ca5fadb\n" + ] + } + ], + "source": [ + "sim_backend = provider.get_backend(\"quantinuum.hqs-lt-s2-sim\")\n", + "qc_t = transpile(qc, validator_backend)\n", + "job = sim_backend.run(qc_t, job_name=\"Simulate Entanglement Swapping\")\n", + "job_id = job.id()\n", + "print(\"Job id\", job_id)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Job Status: job has successfully run\n" + ] + } + ], + "source": [ + "job_monitor(job)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result(backend_name='quantinuum.hqs-lt-s2-sim', backend_version='1', qobj_id='Simulate Entanglement Swapping', job_id='d6b91b3e-3054-11ed-ab67-dc215ca5fadb', success=True, results=[ExperimentResult(shots=500, success=True, meas_level=2, data=ExperimentResultData(counts={'110': 4, '010': 1, '000': 487, '001': 8}, probabilities={'110': 0.008, '010': 0.002, '000': 0.974, '001': 0.016}), header=QobjExperimentHeader(qiskit='True', name='circuit-102', num_qubits='3', metadata=None))])\n" + ] + } + ], + "source": [ + "result = job.result()\n", + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'000': 487, '001': 8, '010': 1, '011': 0, '100': 0, '101': 0, '110': 4, '111': 0}\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAc0AAAFDCAYAAABY/1W1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAuwElEQVR4nO3df5xVVb3/8deHGRlAQAEDZEABR1AGRaehaWwEtJTSovyRQpqWptc0Tf3aNW/lNUtNS8PSrsWta2qK4o/oVppGAaEjNIyiMF3AGIgZBBJIQWBwxs/3j7VnPBzPDPswP8458H4+Hucxc/Zee89nn3PmfPZae621zd0RERGRPeuW6QBERERyhZKmiIhITEqaIiIiMSlpioiIxKSkKSIiEpOSpoiISEz5mQ4gkw455BAfPnx4psMQEZEssnjx4jfc/QOp1u3XSXP48OFUVVVlOgwREckiZramtXVqnhUREYlJSVNERCQmJU0REZGYlDRFRERiUtIUERGJSUlTREQkJiVNERGRmJQ0RUREYlLSFBERiUlJU0REJCYlTRERkZiUNEVERGJS0hQREYlJSVNERCQmJU0REZGYlDRFRERiUtIUERGJSUlTREQkJiVNERGRmJQ0RUREYlLSFBERiUlJU0REJCYlzXZ65plnGD16NEVFRXzve9973/o1a9bw0Y9+lGOPPZZJkyZRV1cHwJ///GeOO+64lkePHj349a9/vdu2V111Fb179+6KwxARkRiUNNuhqamJK664gqeffpqamhoeeeQRampqditz3XXXccEFF/DKK69w4403csMNNwBw0kkn8fLLL/Pyyy/zpz/9iV69enHqqae2bFdVVcWWLVu69HhERKRtSprtsGjRIoqKihg5ciTdu3dn6tSpzJ49e7cyNTU1nHzyyUBIlMnrAR5//HE+8YlP0KtXLyAk46997WvccccdnX8QIiISm5JmO9TX1zNs2LCW50OHDqW+vn63MuPGjePJJ58E4KmnnmLr1q1s2rRptzIzZ85k2rRpLc/vuecepkyZwqGHHtqJ0YuISLqUNDvZD37wA+bNm8fxxx/PvHnzKCwsJC8vr2X966+/zquvvsrkyZMBWLduHbNmzeLKK6/MVMgiItKK/EwHkMsKCwtZu3Zty/O6ujoKCwt3KzNkyJCWmua2bdt44oknOPjgg1vWP/bYY5xxxhkc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", + "text/plain": [ + "
" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "counts = {format(n, \"03b\"): 0 for n in range(8)} # Creates binary values for all possible circuit outcomes\n", + "counts.update(result.get_counts(qc_t))\n", + "print(counts)\n", + "plot_histogram(counts)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that while quite good, we do get some noise from running our code on the emulator.\n", + "Please note, that while this is an emulator, it accurately models the noise of real hardware.\n", + "\n", + "Let us now enhance our code by building entanglement swapping. The idea of entanglement swapping is that if Alice and Bob do not have a direct connection but connections to third parties such that a path exists, then each pair of adjacent parties can create Bell states and teleport Alice's second qubit along this path until it reaches Bob.\n", + "\n", + "First we build the base case of entanglement swapping `entanglement_swap_3`, then we proceed to build the general case `entanglement_swap_n`" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      ┌────────────────────┐ ░                     ░ ┌─┐   \n",
+       "qc_0: ┤0                   ├─░─────────────────────░─┤M├───\n",
+       "      │  create_bell_state │ ░ ┌───────┐           ░ └╥┘   \n",
+       "qc_1: ┤1                   ├─░─┤1      ├───────────░──╫────\n",
+       "      ├────────────────────┤ ░ │       │           ░  ║    \n",
+       "qc_2: ┤0                   ├─░─┤0      ├───────────░──╫────\n",
+       "      │  create_bell_state │ ░ │       │┌───┐┌───┐ ░  ║ ┌─┐\n",
+       "qc_3: ┤1                   ├─░─┤  send ├┤ X ├┤ Z ├─░──╫─┤M├\n",
+       "      └────────────────────┘ ░ │       │└─╥─┘└─╥─┘ ░  ║ └╥┘\n",
+       "c4_0: ═════════════════════════╡0      ╞══■════╬══════╩══╬═\n",
+       "                               │       │       ║         ║ \n",
+       "c4_1: ═════════════════════════╡1      ╞═══════■═════════╩═\n",
+       "                               └───────┘                   
" + ], + "text/plain": [ + " ┌────────────────────┐ ░ ░ ┌─┐ \n", + "qc_0: ┤0 ├─░─────────────────────░─┤M├───\n", + " │ create_bell_state │ ░ ┌───────┐ ░ └╥┘ \n", + "qc_1: ┤1 ├─░─┤1 ├───────────░──╫────\n", + " ├────────────────────┤ ░ │ │ ░ ║ \n", + "qc_2: ┤0 ├─░─┤0 ├───────────░──╫────\n", + " │ create_bell_state │ ░ │ │┌───┐┌───┐ ░ ║ ┌─┐\n", + "qc_3: ┤1 ├─░─┤ send ├┤ X ├┤ Z ├─░──╫─┤M├\n", + " └────────────────────┘ ░ │ │└─╥─┘└─╥─┘ ░ ║ └╥┘\n", + "c4_0: ═════════════════════════╡0 ╞══■════╬══════╩══╬═\n", + " │ │ ║ ║ \n", + "c4_1: ═════════════════════════╡1 ╞═══════■═════════╩═\n", + " └───────┘ " + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def entanglement_swap_3(): \n", + " qc = QuantumCircuit(QuantumRegister(4, 'qc'), ClassicalRegister(2))\n", + " qc.append(create_bell_state(), [0, 1])\n", + " qc.append(create_bell_state(), [2, 3])\n", + " qc.barrier()\n", + " perform_teleportation_on_bell_state(qc, 2, 3, 1, 0, 1)\n", + " qc.barrier()\n", + " # Measure bell state in classical registers\n", + " qc.measure(0, 0)\n", + " qc.measure(3, 1)\n", + " return qc\n", + "\n", + "\n", + "entanglement_swap_3().draw(fold=-1, cregbundle=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will now simulate our entanglement swapping and see that our output is evenly (up to statistical error due to limited shots) split between $\\ket{00}$ and $\\ket{11}$, showing us that in the end Alice and Bob have a bell state shared between them." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAc0AAAFKCAYAAAB/8AR9AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAnxElEQVR4nO3df5zWdZ3v/8dL0JECFFBAfgmkkoCiNEaTCO6m6XE3Tz8s61hqrrlmq1se29pzyrTt56ksrW/H0r650qb93HJrTbcMWRRhB5JEEtn4ESA/RClBcZTxdf74fHAvx5nhMzDMDMPjfrtdN67r/Xl/3tfrmuHiyefX+xOZiSRJ2rUDursASZL2FYamJEkVGZqSJFVkaEqSVJGhKUlSRYamJEkVGZoSEBG3RMSnyuenRMSy7q6pO0XEhRExt4ve69SIWFvzelVEnNYV7y11lKGp/UpEzI6ILRFR11afzPz3zJzQlXXtDWX4bI+IbeVn/nlEjN6X3ysiRkXEjyJic0T8KSKWRMSF5bKxEZER0beDdRvQqszQ1H4jIsYCpwAJnN291fyXKBzezvJhezD8mzKzP3AEsBH46h6M1RPeaxawBjgSGAK8p3wvqUsYmtqfnA88ANwCXNBWp1Z2F46OiB9HxOMR8UREfK1m2UUR8bty6+quiDiyajERMT4irgVWAhe10/WaiFgaER+OiOFVx6+Vmc8CPwQm1rz/IRFxa/m5VkfExyKi9t+EiIivlVt0j0TEG/bgveoi4osR8YeI2BgRN0ZEv934KCcBt2Tm05m5IzN/k5l3lsvmlH/+sdzibYiIV0XEPeXvbXNE/FNEHFrWNAsYA/xL2f/vyvbXRcT9EfHHiFgcEafuRp3qpQxN7U/OB/6pfJxRZQsuIvoAPwNWA2OBkcDt5bL/Dvwv4K3A4cC/A7ftYrxXRMT5EfFr4D+AocC5mfn5dlb7AHAFcDywLCLuiIi3RMSBu6q/9n2Bcyn+07DTV4FDgPHATIqfz3trlk8Dfg8cBnwC+HFEDN7N9/occAxwAnAUxc/x6qr113gA+P8i4p0RMabFshnln4dmZv/MnAcE8FlgBHAsMBq4BiAz3wP8gXILOTP/T0SMBH4OfAoYDFwF/Ki9PQHaz2SmDx+9/gFMB54HDitfPwJ8qGb5LcCnyuenAmvL5w3A40DfVsa8E/irmtcHAM8AR7ZRw83Ak8C/Au8A6nbjcwyg2CqdA2wC/qGdvquAbcAfy8/+GHBcuawP8Bwwsab/XwOzy+cXlv2jZvkC4D278V4BPA28qqZ/A7Cy5c+7ZqzT2nifQRQB/DDQDDwInFQuG0ux6/1lv6ua9d8M/Kat9wI+Asxqsc5dwAXd/XfYR894uKWp/cUFwN2Zubl8/V3a2UVbYzSwOjN3tLLsSOD6cjfeHykCMSi2olozmSKoHgR+m5lNLTuUuy23lY//1XJ5Zm4FfluOcSCwqxOW3pyZhwIHA38D3Fvu4j2sXH91Td/VLWpfl5nZYvmI3Xivw4FXAAtrfla/KNs7JDO3ZOZHM3MSMIzi5/CTiIjW+kfEsIi4PSLWRcRTwHcoPntbjgTevrPOstbpFMdpJUNTvV957OwdwMyI2BARG4APAVMiYsouVl8DjGnjjMw1wF9n5qE1j36ZeX9rA2Xm64A/A/oC90TEgoj4m4gYUtPn0ix2FfbPzM/UfIZREfHRiFhKsXv4cWBKZr6jys8gM5sz88cUW2fTgc0UW4S1x2DHAOtqXo9sEUZjKLYgd+e9tgOTan5Oh2Rx0tBuK/8D9EWKIB9MsZXZ0mfK9uMycyDwbor/2Lw4TIv+ayi2NGt/p6/MzM/tSa3qPQxN7Q/eTPEP+ESKY2onUBzf+neK43jtWQCsBz4XEa+MiIMj4uRy2Y3A30fEJHjxxJq3tzdYZv4uM/+OYgv2Wopjiasi4q/aWicirqHYHTkBuBQ4OjP/ITP/sIvaa8eI8hjsIOB3mdkMfB/4dEQMKE9gupJiS2ynocAVEXFg+bmOpdi13NH3egG4CfhyRAwt+4yMiDOq1l8z9ucjYnJE9I2IAcD7gf/MzCco/iPxAsUx2p0GUOw2/lN5vPLDLYbc2KL/d4A3RcQZEdGn/H2fGhGjOlqreidDU/uDC4BvZ+YfMnPDzgfwNeC8NrYigWKrCXgTxckrfwDWUpzkQmb+M/B54PZy198S4L9VKajcGvt5Zr6dYmtvXjvdfwKMyMz3ZuacFrtMd+VfImIb8BTwaYpjcw+Xyy6nONa4AphLscv6/69Zdz5wNMWW4qeBc8pw2p33+gjwn8AD5c/ql+x613JrXgH8M8Wx0xUUP7uzATLzmfJ97yt3rb6O4j8mU4E/UZzg8+MW430W+FjZ/6rMXAPsPMHrcYotzw/jv5UqRce+f5Ik7b/835MkSRUZmpIkVWRoSpJUkaEpSVJFhqYkSRVVvoVOb3TYYYfl2LFju7sMSVIPsnDhws2Z2eqMVft1aI4dO5bGxsbuLkOS1INExOq2lnX57tmIuCwiVkbEsxGxMCJO2UX/gyLik+U6TeWtha5o0edtUdw6qan88y1791NIkvZHXRqaEXEucD3FfJAnAvcDd7Zyi59atwNnApdQzCDydooJq3eO2QB8j+J2TyeUf/4gIqbthY8gSdqPdemMQBExn+LuDu+raVsO/DAz/76V/m8EfkBxS6HNLZeXfb4HDM7M02vafgk8npnvaq+e+vr6dPesJKlWRCzMzPrWlnXZlmZEHAS8Bri7xaK7gde3sdqbKW7Ue2VErI2I5RFxQ0TU3h2hoZUx72pnTEmSdktXngh0GMWNbze2aN8InNbGOuMpbi3UBLwNOJTibvMjgHPKPsPbGHN4awNGxCUUu3oZMWIEs2fPLt5o/HgGDBjA4sWLARgyZAiTJk1izpw5APTt25fp06ezaNEinnrqKQDq6+vZuHEja9asAeDoo4+mrq6OJUuWADB06FCOOeYY5s6dC0BdXR0NDQ00Njaybds2AKZNm8batWtZt664I9OECRPo06cPS5cuLT7c8OGMGzeOefOK+bz79evHtGnTmD9/Ptu3bwegoaGBlStXsmHDBgAmTpxIc3Mzy5YtA2DkyJGMGjWK+fPnA9C/f3/q6+uZN28eTU3FLR2nT5/Oo48+yqZNmwCYPHkyTU1NLF++HIDRo0czbNiwF0+cGjhwIFOnTmXu3Lns2FHcanLGjBk8/PDDPPFEMaf3lClT2Lp1KytWrACKE68GDx7MokWLABg0aBBTpkzh3nvvJTOJCGbOnMnixYvZsmULAFOnTuXJJ59k1apV/p78Pfl78vfUJb+n9nTZ7tmIGEFxr76ZmTmnpv1q4LzMfNkdDyLibuAUYHhm/qlseyPFluTwzNwYEc8BF2fmrTXrnQ/clJl17dXk7llJUks9Yvcsxe2Fminutl5rGLChjXXWU9w9/k81bb8r/9x58tCGDo4pSdJu6bLQzMzngIXA6S0WnU5xFm1r7gNGtDiGeUz5587raOZ1cExJknZLV1+neR1wYURcHBHHRsT1FMcnbwSIiFsj4taa/t8FngC+HRGTIuJkiktWfpiZm8o+1wN/HhEfjYhXR8TfA38GfKWLPpMkaT/RpTMCZeb3ImII8DHgCIo73Z+VmTu3Gse06L8tIk6jOPnnP4AtFHex/2hNn/sj4p3Ap4BPAr8Hzs3M+Xv540iS9jNdep1mT+OJQJKklnrKiUCSJO3TDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQ3I/94he/YMKECRx11FF87nOfe9nyW265hcMPP5wTTjiBE044gZtvvvnFZWeeeSaHHnoof/mXf/mSdc477zwmTJjA5MmTueiii3j++ef3+ueQpK5iaO6nmpub+cAHPsCdd97J0qVLue2221i6dOnL+p177rk8+OCDPPjgg1x88cUvtn/4wx9m1qxZL+t/3nnn8cgjj/DQQw+xffv2lwStJO3rDM391IIFCzjqqKMYP348Bx10EO985zv56U9/Wnn9N7zhDQwYMOBl7WeddRYRQUTw2te+lrVr13Zm2ZLUrQzN/dS6desYPXr0i69HjRrFunXrXtbvRz/6EccffzznnHMOa9asqTz+888/z6xZszjzzDM7pV5J6gkMTbXpTW96E6tWreK3v/0tp59+OhdccEHldS+77DJmzJjBKaecshcrlKSuZWjup0aOHPmSLce1a9cycuTIl/QZMmQIdXV1AFx88cUsXLiw0tjXXnstjz/+ONddd13nFSxJPYChuZ866aSTWL58OStXruS5557j9ttv5+yzz35Jn/Xr17/4/I477uDYY4/d5bg333wzd911F7fddhsHHOBfL0m9S9/uLkDdo2/fvnzta1/jjDPOoLm5mYsuuohJkyZx9dVXU19fz9lnn80NN9zAHXfcQd++fRk8eDC33HLLi+ufcsopPPLII2zbto1Ro0bxrW99izPOOINLL72UI488koaGBgDe+ta3cvXVV3fTp5SkzhWZ2d01dJv6+vpsbGzs7jIkST1IRCzMzPrWlrn/TJKkigxNSZIqMjQlaR+xq6kvd/rRj35ERLDz8NPzzz/PBRdcwHHHHcexxx7LZz/72Rf7fvnLX2bSpElMnjyZd73rXTz77LN7/XPsywxNSdoHVJ36cuvWrVx//fVMmzbtxbYf/OAHNDU18dBDD7Fw4UK+8Y1vsGrVKtatW8cNN9xAY2MjS5Ysobm5mdtvv70rP9Y+x9CUpH1A1akvP/7xj/ORj3yEgw8++MW2iODpp59mx44dbN++nYMOOoiBAwcCvNi2Y8cOnnnmGUaMGNFln2lfZGhK0j6gytSXixYtYs2aNfzFX/zFS9rPOeccXvnKV3LEEUcwZswYrrrqKgYPHszIkSO56qqrGDNmDEcccQSHHHIIb3zjG7vk8+yrDE1J6gVeeOEFrrzySr70pS+9bNmCBQvo06cPjz32GCtXruRLX/oSK1asYMuWLfz0pz9l5cqVPPbYYzz99NN85zvf6Ybq9x1ObiBJ+4BdTX25detWlixZwqmnngrAhg0bOPvss7njjjv47ne/y5lnnsmBBx7I0KFDOfnkk2lsbCQiGDduHIcffjhQTEZy//338+53v7tLP9u+xC1NSdoH7Grqy0MOOYTNmzezatUqVq1axete9zruuOMO6uvrGTNmDPfccw8ATz/9NA888ACvfvWrGTNmDA888ADPPPMMmcmvfvWrStNl7s8MTUnaB9ROfXnsscfyjne848WpL++444521/3ABz7Atm3bmDRpEieddBLvfe97Of7445k2bRrnnHMOU6dO5bjjjuOFF17gkksu6aJPtG9yGj2n0ZMk1XAaPUmSOoEnAnWC932luyvQ3nDTB7u7Akk9jVuakiRVZGhKklSRoSlJUkWGpiRJFRmakiRVZGhKklSRoSlJUkWGpiRJFRmakiRV5IxAkvY7zuLVO3XFLF5uaUqSVJGhKUlSRYamJEkVGZqSJFVkaEqSVJGhKUlSRYamJEkVGZqSJFVkaEqSVJGhKUlSRYamJEkVGZqSJFXU5aEZEZdFxMqIeDYiFkbEKRXXmx4ROyJiSYv2CyMiW3kcvHc+gSRpf9WloRkR5wLXA58BTgTuB+6MiDG7WG8QcCvwqza6PAMcUfvIzGc7q25JkqDrtzSvBG7JzJsy83eZeTmwHnj/Ltb7FvCPwLw2lmdmbqh9dGLNkiQBXRiaEXEQ8Brg7haL7gZe3856lwHDgE+1M3y/iFgdEWsj4mcRceIeFyxJUgtdeRPqw4A+wMYW7RuB01pbISKOAz4BvC4zmyOitW7LgIuAxcAA4G+B+yJiSmYub2XMS4BLAEaMGMHs2bMBGD9+PAMGDGDx4sUADBkyhEmTJjFnzhwA+vbty/Tp01m0aBFPPfUUAPX19WzcuBF4VdWfgfYhjY2NbNu2DYBp06axdu1a1q1bB8CECRPo06cPS5cuBWD48OGMGzeOefOKnSH9+vVj2rRpzJ8/n+3btwPQ0NDAypUr2bCh2BEyceJEmpubWbZsGQAjR45k1KhRzJ8/H4D+/ftTX1/PvHnzaGpqAmD69Ok8+uijbNq0CYDJkyfT1NTE8uXFX/XRo0czbNgwGhsbARg4cCBTp05l7ty57NixA4AZM2bw8MMP88QTTwAwZcoUtm7dyooVKwAYO3YsgwcPZtGiRQAMGjSIKVOmcO+995KZRAQzZ85k8eLFbNmyBYCpU6fy5JNPsmrVKmDPvk9r1qwB4Oijj6auro4lS4rTGIYOHcoxxxzD3LlzAairq6OhoWG3fk9Q18G/DdoXrF+/vlO+T+2JzNyLH6HmjSJGAOuAmZk5p6b9auC8zJzQon8d8Bvgs5k5q2y7BjgnMye38z59gAeBX2fmFe3VVF9fnzv/cdkT3gW+d+qKu8Cre/id7Z066zsbEQszs761ZV25pbkZaKbY1VprGNDaMcgjgGOBb0fEt8u2A4CIiB3AWZnZclcv5RZpI3B0p1UuSRJdeEwzM58DFgKnt1h0OsVZtC2tA44DTqh53Aj8Z/m8tXWIYh/u8RQnGEmS1Gm6cksT4DpgVkQsAO4DLgVGUIQhEXErQGaen5nPAy2vydwENGXmkpq2TwAPAMuBgcAVFKG5qzNyJUnqkC4Nzcz8XkQMAT5Gsft1CcVu1tVll3av12zDocA3geHAnyiOg87IzAV7XrEkSf+lq7c0ycyvA19vY9mpu1j3GuCaFm0fAj7UOdVJktQ2556VJKkiQ1OSpIoMTUmSKjI0JUmqyNCUJKkiQ1OSpIoMTUmSKjI0JUmqyNCUJKkiQ1OSpIoMTUmSKjI0JUmqyNCUJKkiQ1OSpIoMTUmSKjI0JUmqyNCUJKmiDoVmRBwQEQfUvB4eERdHxMmdX5okST1LR7c0fw5cDhAR/YFG4AvA7Ig4v5NrkySpR+loaNYD95TP3wo8BQwF3gdc1Yl1SZLU43Q0NPsDfyyfvxH458x8niJIX9WJdUmS1ON0NDT/AJwcEa8EzgD+rWwfDDzTmYVJktTT9O1g/+uAWcA2YDUwp2yfATzUiXVJktTjdCg0M/MbEbEQGA38W2a+UC76PfDxzi5OkqSepKNbmmRmI8VZs7VtP++0iiRJ6qE6PLlBRFwWEQ9HxDMRMb5s+0hEvKPzy5Mkqefo6OQGHwQ+BnwTiJpFjwF/03llSZLU83R0S/NS4H2ZeT2wo6Z9ETCp06qSJKkH6mhoHgksaaX9eaDfnpcjSVLP1dHQXAFMbaX9LGDpnpcjSVLP1dGzZ78IfC0iXkFxTLMhIt4D/B1wUWcXJ0lST9LR6zS/HRF9gc8Ar6CY6OAx4IrM/N5eqE+SpB5jd67TvAm4KSIOAw7IzE2dX5YkST1Ph0Nzp8zc3JmFSJLU0+0yNCPit8DMzNwSEQ8B2VbfzDy+M4uTJKknqbKl+SOgqeZ5m6EpSVJvtsvQzMxra55fs1erkSSpB+voNHr3RMShrbQPjIh7Oq0qSZJ6oI5ObnAqcFAr7QcDp+xxNZIk9WCVzp6NiNpZgI6PiCdrXvcBzgDWdWZhkiT1NFUvOWmkOAEogbtbWb4duLyzipIkqSeqGprjKKbNWwG8Fni8ZtlzwKbMbO7k2iRJ6lEqhWZmri6fdvim1ZIk9RZVJjd4K/Avmfl8+bxNmfnjTqtMkqQepsqW5g+B4cCm8nlbkuKkIEmSeqUqkxsc0NpzSZL2N4agJEkVVT2mWYnHNCVJvVnVY5pVeExTktSrdeiYpiRJ+zMDUZKkirxOU5KkirxOU5KkirxOU5KkigxBSZIq6nBoRsTUiLg1IhrLx6wW99uUJKlX6lBoRsR5wH8ARwD/Wj6GAQsi4t0Vx7gsIlZGxLMRsTAiTmmn78yIuD8inoiI7RHxSERc1Uq/t0XE0ohoKv98S0c+lyRJVVS9n+ZOnwY+npmfqW2MiL8HPgV8p72VI+Jc4HrgMmBu+eedETExM//QyirbgBuAh4BngJOBb0TEM5n59XLMBuB7wCeAHwNvBX4QESdn5vwOfj5JktrU0d2zhwPfb6X9B8DQCutfCdySmTdl5u8y83JgPfD+1jpn5sLMvD0zH87MlZn5HeAuoHbr9IPArzPz0+WYnwZml+2SJHWajobmr4FTW2k/Fbi3vRUj4iDgNcDdLRbdDby+yptHxIll39r3amhlzLuqjilJUlUdnbD9TuCzEVEPPFC2vY5il+g1uxjqMIrrODe2aN8InLaLGtZSbOX2Ba7NzBtrFg9vY8zhbYx1CXAJwIgRI5g9ezYA48ePZ8CAASxevBiAIUOGMGnSJObMmQNA3759mT59OosWLeKpp54CoL6+no0bNwKvaq987aMaGxvZtm0bANOmTWPt2rWsW7cOgAkTJtCnTx+WLl0KwPDhwxk3bhzz5s0DoF+/fkybNo358+ezfft2ABoaGli5ciUbNmwAYOLEiTQ3N7Ns2TIARo4cyahRo5g/vziq0L9/f+rr65k3bx5NTU0ATJ8+nUcffZRNmzYBMHnyZJqamli+fDkAo0ePZtiwYTQ2NgIwcOBApk6dyty5c9mxYwcAM2bM4OGHH+aJJ54AYMqUKWzdupUVK1YAMHbsWAYPHsyiRYsAGDRoEFOmTOHee+8lM4kIZs6cyeLFi9myZQsAU6dO5cknn2TVqlXAnn2f1qxZA8DRRx9NXV0dS5YsAWDo0KEcc8wxzJ07F4C6ujoaGhp26/cEdR3826B9wfr16zvl+9SeyMz2O0S8ULHezMw2JzeIiBHAOmBmZs6pab8aOC8zJ7Sz7jigP0VAfx7428ycVS57Drg4M2+t6X8+cFNmtvvNqK+vz53/uOyJ931lj4dQD3TTB7u7Au0tfmd7p876zkbEwsysb21ZV07YvhlopjjbttYwYMMualhZPn0oIoZRbNXOKts27M6YkiR1VJdNbpCZzwELgdNbLDoduL8DQx3AS/etzOuEMSVJ2qWOXnJCRAwC/hswBjiodllmfnIXq18HzIqIBcB9wKXACODGcuxby3HOL19fDqwElpXrzwCuAr5eM+b1wJyI+CjwE+AtwJ8B0zv62SRJak+HQjMiXgf8HGiiODFnHcVEB03AKqDd0MzM70XEEOBj5XpLgLMyc3XZZUyLVfpQHMMcC+wAfg98lDJkyzHvj4h3Ulwn+smyz7leoylJ6mwd3dL8AvBPwN8CTwF/DjwN3AZ8q8oA5aQEX29j2aktXn8F+EqFMX9I+3dgkSRpj3X0mObxwNeyOOW2GajLzI3AR9j1JSeSJO3TOhqaz9U83wgcWT7fRnFsUpKkXquju2cXAScBj1JMVfep8hKQdwO/7dzSJEnqWTq6pfm/gcfK5x8DHge+CgyinGVHkqTeqkNbmpnZWPP8cYpLTyRJ2i90+DpNgIh4FXBs+XJpZq7ovJIkSeqZOnqd5hCKS0vOBl74r+b4GXBRZj7RyfVJktRjdPSY5s3AURT3szy4fMwAxgE3dW5pkiT1LB3dPXsG8IbMnFfTdl9E/DXwy84rS5KknqejW5qPU8wA1NIzgLtmJUm9WkdD85PAVyJi5M6G8vmX2MW8s5Ik7et2uXs2Ih4Cau9UPQ5YFRHrytcjgWeBoRTHPCVJ6pWqHNN0InRJkqgQmpl5bVcUIklST7e7kxv8OTCRYrftw5k5uzOLkiSpJ+ro5AYjgX8GXsN/zUE7IiIagbdk5mNtrixJ0j6uo2fP3kBxH82jMnN0Zo4Gji7bbujs4iRJ6kk6unv2dODUzFy5syEzV0TEFcCvOrUySZJ6mI5uacJLLz9pr02SpF6lo6H5K+CrETF6Z0NEjAG+gluakqRerqOheQXwSmBFRKyOiNXA78u2Kzq7OEmSepKOHtN8AngtcCrw6rLtd5npZO2SpF6vcmhGRB/gT8CUzPw34N/2WlWSJPVAlXfPZmYzsBo4aO+VI0lSz9XRY5r/AHwuIg7bG8VIktSTdfSY5lUUdzlZFxFraXFvzcw8vrMKkySpp+loaP6Q4prM2Au1SJLUo1UKzYh4BfAF4M3AgRTXZF6emZv3XmmSJPUsVY9pXgtcCPwcuA04Dfi/e6kmSZJ6pKq7Z98K/FVm3g4QEf8E3BcRfcqzaiVJ6vWqbmmOBv5954vMXADsAEbsjaIkSeqJqoZmH+C5Fm072M2bWEuStC+qGnoBfCcimmraDgZuiohndjZk5tmdWZwkST1J1dD8x1bavtOZhUiS1NNVCs3MfO/eLkSSpJ5ud25CLUnSfsnQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1Jkirq8tCMiMsiYmVEPBsRCyPilHb6HhER342IRyKiOSJuaaXPhRGRrTwO3qsfRJK03+nS0IyIc4Hrgc8AJwL3A3dGxJg2VqkDNgOfA+a3M/QzwBG1j8x8trPqliQJun5L80rglsy8KTN/l5mXA+uB97fWOTNXZeYVmXkL8GQ742Zmbqh9dH7pkqT9XZeFZkQcBLwGuLvForuB1+/h8P0iYnVErI2In0XEiXs4niRJL9O3C9/rMKAPsLFF+0bgtD0YdxlwEbAYGAD8LXBfREzJzOUtO0fEJcAlACNGjGD27NkAjB8/ngEDBrB48WIAhgwZwqRJk5gzZw4Affv2Zfr06SxatIinnnoKgPr6ejZu3Ai8ag/KV0/V2NjItm3bAJg2bRpr165l3bp1AEyYMIE+ffqwdOlSAIYPH864ceOYN28eAP369WPatGnMnz+f7du3A9DQ0MDKlSvZsKHYETJx4kSam5tZtmwZACNHjmTUqFHMn18ciejfvz/19fXMmzePpqYmAKZPn86jjz7Kpk2bAJg8eTJNTU0sX178VR89ejTDhg2jsbERgIEDBzJ16lTmzp3Ljh07AJgxYwYPP/wwTzzxBABTpkxh69atrFixAoCxY8cyePBgFi1aBMCgQYOYMmUK9957L5lJRDBz5kwWL17Mli1bAJg6dSpPPvkkq1atAvbs+7RmzRoAjj76aOrq6liyZAkAQ4cO5ZhjjmHu3LkA1NXV0dDQsFu/p+LIj3qb9evXd8r3qT2RmXvxI9S8UcQIYB0wMzPn1LRfDZyXmRN2sf7PgM2ZeeEu+vUBHgR+nZlXtNe3vr4+d/7jsife95U9HkI90E0f7O4KtLf4ne2dOus7GxELM7O+tWVdeUxzM9AMDGvRPgzotGOQmdkMNAJHd9aYkiRBF4ZmZj4HLAROb7HodIqzaDtFRARwPMUJRpIkdZquPKYJcB0wKyIWAPcBlwIjgBsBIuJWgMw8f+cKEXFC+XQg8EL5+rnMXFou/wTwALC87HMFRWi2ekauJEm7q0tDMzO/FxFDgI9RXE+5BDgrM1eXXVq7XvM3LV6/CVgNjC1fHwp8ExgO/KnsPyMzF3Rq8ZKk/V5Xb2mSmV8Hvt7GslNbaYtdjPch4EOdUpwkSe1w7llJkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpIkNTkqSKDE1JkioyNCVJqsjQlCSpoi4PzYi4LCJWRsSzEbEwIk7ZRf+ZZb9nI2JFRFy6p2NKkrQ7ujQ0I+Jc4HrgM8CJwP3AnRExpo3+44B/LfudCHwW+GpEvG13x5QkaXd19ZbmlcAtmXlTZv4uMy8H1gPvb6P/pcBjmXl52f8m4B+Bq/ZgTEmSdkuXhWZEHAS8Bri7xaK7gde3sVpDK/3vAuoj4sDdHFOSpN3Stwvf6zCgD7CxRftG4LQ21hkO/LKV/n3L8aKjY0bEJcAl5cttEbGsSvF60WHA5u4uoivc/KHurkDqFH5nO+7IthZ0ZWj2CJn5TeCb3V3HvioiGjOzvrvrkFSN39nO1ZWhuRloBoa1aB8GbGhjnQ1t9N9Rjhe7MaYkSbuly45pZuZzwELg9BaLTqc447U189ro35iZz+/mmJIk7Zau3j17HTArIhYA91GcHTsCuBEgIm4FyMzzy/43An8TEV8BvgGcDFwIvKvqmOp07tqW9i1+ZztRZGbXvmHEZcDfAUcAS4APZeacctlsgMw8tab/TODLwCTgMeDzmXlj1TElSeosXR6akiTtq5x7VpKkigxNSZIqMjQlSarI0JQkqaL9bkYgdVxEjAKOophM4gVgWWY6eYSk/Y5nz6pdEfF+4CJgCvA08J/AWuAB4CeZuSwiDsjMF7qxTEnqEu6eVZsiYgjFfUp/SnENbAPFrdmagfOBGyJiYma+EBHRfZVKAijv/nRMRNR1dy29lVuaalNEXA68OzOntbJsOsVNwUcCr83M/eIuClJPFhEfBD4NfB/4MfAfwOOZ2VzTZyDF7Gq/zMznu6POfZlbmmrPc8CAiJgMEBF15T1Mycy5wHnAs8Abu69ESTXOBRZQnIPwE4r5u78QEdMj4pCyz/8APmFg7h5DU+35IcWJPx+MiAGZ2ZSZz0XEAQCZ+Qfgj8CobqxREhARhwPPAzdl5ikU94T8FvCXwBzgnoj4CPBBYH531bmvc/esWlVzjPK/A9cDgyl2+Xwd+A1FUM4A/i9wXGau6oYyJZUi4gjgncDSzLyrxbITgYvL5YOA0Zm5ruur3PcZmmpXRBwKjAFeD7yF4lgIFPcrDWBWZl7TLcVJeomI6AdkZj5be3Jelv/QR8SngbMy88TuqnFf53WaepmIGAq8B/ifFDf73k6xG3Yu8EXgQIpjJr/IzEe7qUxJLWTm9p1hmS22iCLiFcDbgG93R229hVuaepmIuIXiVmz/AjxJsWv2OOAYYBPwscz0mIjUQ5RnxG5tGZQt+hxMcaLQbZn5XJcV18sYmnqJ8n+pWyl24cypaRsDTKM4LjIeeEdmLuq2QiW9KCK+QXHW7AJgdWY+1UqfQzPzj11dW2/j2bNqaSKwkuJyE6DYzZOZqzPz+8CbKHbVvr17ypNUKyLeBbwP+BLFRCRfiIi3RMSrymOcO491/uPOy8e0+9zS1EuUX66fAa+gmPXn9y2nyCsnPfirzDyh6yuUVCsibqKYpev/AG8FLgBeBSwD/hX4FTABuD4zD+quOnsLtzT1Epm5HfjfQD/gVuD8iBgdEf3hxZMJZgJLuq9KSQAR0Zdiz9AfM3NFZn4xM48DTgLupQjQ7wNfBWZ1X6W9h1uaalW5G+fjwNkUE7XPAx4HTgPWAxdn5kPdV6EkgIgYBAzLzEfKGbuerz0hKCLOBW4Dpmbmg91UZq9haKpd5eUnfwG8mWLKvCXADzLzke6sS1Lbylm7IjObI+J9FLtmX9HddfUGhqYq8xZg0r4nIq4E+mTmF7q7lt7A0JSkXiwiDgSa/Q9v5zA0JUmqyLNnJUmqyNCUJKkiQ1OSpIoMTUmSKjI0JUmqyNCUJKmi/wcqpZ6T098nOwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "qc = entanglement_swap_3()\n", + "\n", + "simulator = Aer.get_backend('aer_simulator')\n", + "\n", + "qc = transpile(qc, simulator)\n", + "result = simulator.run(qc, shots=500).result()\n", + "counts = result.get_counts(qc)\n", + "plot_histogram(counts, title='Alice <-> Bob Bell State')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us now generalize this and build an entanglement swapping circuit for any number for qubits." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      ┌────────────────────┐ ░                     ░                     ░                     ░ ┌─┐   \n",
+       "qc_0: ┤0                   ├─░─────────────────────░─────────────────────░─────────────────────░─┤M├───\n",
+       "      │  create_bell_state │ ░ ┌───────┐           ░                     ░                     ░ └╥┘   \n",
+       "qc_1: ┤1                   ├─░─┤1      ├───────────░─────────────────────░─────────────────────░──╫────\n",
+       "      ├────────────────────┤ ░ │       │           ░                     ░                     ░  ║    \n",
+       "qc_2: ┤0                   ├─░─┤0      ├───────────░─────────────────────░─────────────────────░──╫────\n",
+       "      │  create_bell_state │ ░ │       │┌───┐┌───┐ ░ ┌───────┐           ░                     ░  ║    \n",
+       "qc_3: ┤1                   ├─░─┤       ├┤ X ├┤ Z ├─░─┤1      ├───────────░─────────────────────░──╫────\n",
+       "      ├────────────────────┤ ░ │       │└─╥─┘└─╥─┘ ░ │       │           ░                     ░  ║    \n",
+       "qc_4: ┤0                   ├─░─┤       ├──╫────╫───░─┤0      ├───────────░─────────────────────░──╫────\n",
+       "      │  create_bell_state │ ░ │       │  ║    ║   ░ │       │┌───┐┌───┐ ░ ┌───────┐           ░  ║    \n",
+       "qc_5: ┤1                   ├─░─┤  send ├──╫────╫───░─┤       ├┤ X ├┤ Z ├─░─┤1      ├───────────░──╫────\n",
+       "      ├────────────────────┤ ░ │       │  ║    ║   ░ │       │└─╥─┘└─╥─┘ ░ │       │           ░  ║    \n",
+       "qc_6: ┤0                   ├─░─┤       ├──╫────╫───░─┤  send ├──╫────╫───░─┤0      ├───────────░──╫────\n",
+       "      │  create_bell_state │ ░ │       │  ║    ║   ░ │       │  ║    ║   ░ │       │┌───┐┌───┐ ░  ║ ┌─┐\n",
+       "qc_7: ┤1                   ├─░─┤       ├──╫────╫───░─┤       ├──╫────╫───░─┤  send ├┤ X ├┤ Z ├─░──╫─┤M├\n",
+       "      └────────────────────┘ ░ │       │  ║    ║   ░ │       │  ║    ║   ░ │       │└─╥─┘└─╥─┘ ░  ║ └╥┘\n",
+       " cr1: ═════════════════════════╡0      ╞══■════╬═════╡0      ╞══■════╬═════╡0      ╞══■════╬══════╩══╬═\n",
+       "                               │       │ 0x1   ║     │       │ 0x1   ║     │       │ 0x1   ║         ║ \n",
+       " cr2: ═════════════════════════╡1      ╞═══════■═════╡1      ╞═══════■═════╡1      ╞═══════■═════════╩═\n",
+       "                               └───────┘      0x1    └───────┘      0x1    └───────┘      0x1          
" + ], + "text/plain": [ + " ┌────────────────────┐ ░ ░ ░ ░ ┌─┐ \n", + "qc_0: ┤0 ├─░─────────────────────░─────────────────────░─────────────────────░─┤M├───\n", + " │ create_bell_state │ ░ ┌───────┐ ░ ░ ░ └╥┘ \n", + "qc_1: ┤1 ├─░─┤1 ├───────────░─────────────────────░─────────────────────░──╫────\n", + " ├────────────────────┤ ░ │ │ ░ ░ ░ ║ \n", + "qc_2: ┤0 ├─░─┤0 ├───────────░─────────────────────░─────────────────────░──╫────\n", + " │ create_bell_state │ ░ │ │┌───┐┌───┐ ░ ┌───────┐ ░ ░ ║ \n", + "qc_3: ┤1 ├─░─┤ ├┤ X ├┤ Z ├─░─┤1 ├───────────░─────────────────────░──╫────\n", + " ├────────────────────┤ ░ │ │└─╥─┘└─╥─┘ ░ │ │ ░ ░ ║ \n", + "qc_4: ┤0 ├─░─┤ ├──╫────╫───░─┤0 ├───────────░─────────────────────░──╫────\n", + " │ create_bell_state │ ░ │ │ ║ ║ ░ │ │┌───┐┌───┐ ░ ┌───────┐ ░ ║ \n", + "qc_5: ┤1 ├─░─┤ send ├──╫────╫───░─┤ ├┤ X ├┤ Z ├─░─┤1 ├───────────░──╫────\n", + " ├────────────────────┤ ░ │ │ ║ ║ ░ │ │└─╥─┘└─╥─┘ ░ │ │ ░ ║ \n", + "qc_6: ┤0 ├─░─┤ ├──╫────╫───░─┤ send ├──╫────╫───░─┤0 ├───────────░──╫────\n", + " │ create_bell_state │ ░ │ │ ║ ║ ░ │ │ ║ ║ ░ │ │┌───┐┌───┐ ░ ║ ┌─┐\n", + "qc_7: ┤1 ├─░─┤ ├──╫────╫───░─┤ ├──╫────╫───░─┤ send ├┤ X ├┤ Z ├─░──╫─┤M├\n", + " └────────────────────┘ ░ │ │ ║ ║ ░ │ │ ║ ║ ░ │ │└─╥─┘└─╥─┘ ░ ║ └╥┘\n", + " cr1: ═════════════════════════╡0 ╞══■════╬═════╡0 ╞══■════╬═════╡0 ╞══■════╬══════╩══╬═\n", + " │ │ 0x1 ║ │ │ 0x1 ║ │ │ 0x1 ║ ║ \n", + " cr2: ═════════════════════════╡1 ╞═══════■═════╡1 ╞═══════■═════╡1 ╞═══════■═════════╩═\n", + " └───────┘ 0x1 └───────┘ 0x1 └───────┘ 0x1 " + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def entanglement_swap_n(n_parties: int): \n", + " cr_x = ClassicalRegister(1, 'cr1')\n", + " cr_z = ClassicalRegister(1, 'cr2')\n", + " qc = QuantumCircuit(QuantumRegister(2 * n_parties, 'qc'), cr_x, cr_z)\n", + " for idx_party in range(n_parties):\n", + " qc.append(create_bell_state(), [2 * idx_party, 2 * idx_party + 1])\n", + " qc.barrier()\n", + " for idx_party in range(1, n_parties):\n", + " perform_teleportation_on_bell_state(qc, 2 * idx_party, 2 * idx_party + 1, 2 * idx_party - 1, cr_x, cr_z)\n", + " qc.barrier()\n", + " # Measure bell state in classical registers\n", + " qc.measure(0, cr_x)\n", + " qc.measure(2 * n_parties - 1, cr_z)\n", + " return qc\n", + "\n", + "entanglement_swap_n(4).draw(fold=-1, cregbundle=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We shall now test to see how our circuit performs with different numbers of qubits. As our circuit includes mid-circuit measurements we will be running on Quantinuum hardware (/simulators) as they are the only current provider allowing such operations.\n", + "\n", + "We will first ensure correctness by running on a simulator and seeing the correct being 100%\n", + "\n", + "Then we will use Azure Quantum to run on Quantinuum targets" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "all_results = dict()\n", + "\n", + "def get_result(counts):\n", + " total = sum(counts.values())\n", + " return (counts['1 1'] + counts ['0 0']) / total * 100\n", + "\n", + "for i in range(4, 18):\n", + " qc = entanglement_swap_n(i) \n", + "\n", + " simulator = Aer.get_backend('aer_simulator')\n", + "\n", + " qc_t = transpile(qc, simulator)\n", + " result = simulator.run(qc_t, shots=500).result()\n", + " counts = result.get_counts(qc_t)\n", + " all_results[i] = get_result(counts)\n", + "\n", + "plt.bar(all_results.keys(), all_results.values())\n", + "plt.title(\"Alice <-> Bob chance of bell state with n qubits, locally simulated\")\n", + "plt.xlabel('n')\n", + "plt.ylabel('Chance of bell state in %')\n", + "plt.ylim([90, 100])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us now validate our circuits again:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2-party entanglement swapping uses 4 qubits\n", + "3-party entanglement swapping uses 6 qubits\n", + "4-party entanglement swapping uses 8 qubits\n", + "5-party entanglement swapping uses 10 qubits\n", + "6-party entanglement swapping uses 12 qubits\n", + "7-party entanglement swapping uses 14 qubits\n" + ] + } + ], + "source": [ + "for n_parties in range(2, 8):\n", + " print(f\"{n_parties}-party entanglement swapping uses {entanglement_swap_n(n_parties).num_qubits} qubits\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since the Quantinuum H1-2 target has 12 qubits, we will limit our number of parties to $\\leq 6$" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validating entanglement swap with 2 parties\n", + "Job Status: job has successfully run\n", + "API validation succeeded for 2 parties!\n", + "Validating entanglement swap with 3 parties\n", + "Job Status: job has successfully run\n", + "API validation succeeded for 3 parties!\n", + "Validating entanglement swap with 4 parties\n", + "Job Status: job has successfully run\n", + "API validation succeeded for 4 parties!\n", + "Validating entanglement swap with 5 parties\n", + "Job Status: job has successfully run\n", + "API validation succeeded for 5 parties!\n", + "Validating entanglement swap with 6 parties\n", + "Job Status: job has successfully run\n", + "API validation succeeded for 6 parties!\n" + ] + } + ], + "source": [ + "for n_parties in range(2, 7):\n", + " job_name = f\"Validating entanglement swap with {n_parties} parties\"\n", + " print(job_name)\n", + " qc = entanglement_swap_n(n_parties) \n", + " validator_backend = provider.get_backend(\"quantinuum.hqs-lt-s2-apival\")\n", + " qc_t = transpile(qc, validator_backend)\n", + " job = validator_backend.run(qc_t, job_name=job_name)\n", + " job_id = job.id()\n", + " job_monitor(job)\n", + " result = job.result()\n", + " if not result.success:\n", + " raise RuntimeError(f\"API validation failed for {n_parties} parties\")\n", + " print(f\"API validation succeeded for {n_parties} parties!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we see all our circuits can be run correctly, let us now run them on simulators. We will name our circuits so that when submitted as jobs we will be able to identify them in the Azure Quantum job management to have insight into costs. **Please note that this sample makes use of paid services on Azure Quantum. The cost of running this sample with the provided parameters on Quantinuum in a free trial subscription is approximately 111EHQC. This quantity is only an approximate estimate and should not be used as a binding reference. The cost of the service might vary depending on your region, demand and other factors.** We have a write up of our results below if you want to save on the credits." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "all_results = dict()\n", + "\n", + "def get_result(counts):\n", + " total = sum(counts.values())\n", + " return (counts['11'] + counts ['00']) / total * 100\n", + "\n", + "for n_parties in range(2, 7): # Due to the H1-2 target's 12 qubits, we run up to 6 party entanglement swapping (see previous discussion)\n", + " job_name=f\"Running entanglement swap with {n_parties} parties\"\n", + " print(job_name)\n", + " qc = entanglement_swap_n(n_parties) \n", + " emulator_backend = provider.get_backend(\"quantinuum.hqs-lt-s2-sim\")\n", + " qc_t = transpile(qc, emulator_backend)\n", + " qc_t.name = f\"Entanglement swap with {n_parties} parties\"\n", + " job = emulator_backend.run(qc_t, job_name=job_name)\n", + " job_id = job.id()\n", + " job_monitor(job)\n", + " result = job.result()\n", + " counts = result.get_counts(qc_t)\n", + " all_results[i] = get_result(counts)\n", + "\n", + "plt.bar(all_results.keys(), all_results.values())\n", + "plt.title(\"Alice <-> Bob Bell State chance of bell state on Quantinuum H1-2 emulator\")\n", + "plt.xlabel('n')\n", + "plt.ylabel('Chance of bell state in %')\n", + "plt.ylim([90, 100])\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us look at the results we got. We included our resulting plot below:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we can see we were able to run entanglement swapping on the Quantinuum emulator and were able to use the mid-circuit measurement capability in the process. We also saw how we could use the Azure Quantum service to submit and process our jobs." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.12 ('qsharp-env')", + "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.9.12" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "b4252e63e8a2fdb4c39caf2c09adc0e7447e3e9bad310da9108967fdc06c19c9" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/samples/azure-quantum/entanglement-swap/ES-quantinuum-qsharp.ipynb b/samples/azure-quantum/entanglement-swap/ES-quantinuum-qsharp.ipynb new file mode 100644 index 000000000000..d04aa2f111f1 --- /dev/null +++ b/samples/azure-quantum/entanglement-swap/ES-quantinuum-qsharp.ipynb @@ -0,0 +1,539 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Quantum Teleportation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$\\providecommand{\\ket}[1]{\\left|#1\\right\\rangle}$\n", + "$\\providecommand{\\bra}[1]{\\left\\langle#1\\right|}$\n", + "\n", + "In this sample, we will be looking at using quantum teleportation on the Azure Quantum service.\n", + "\n", + "To refresh our mind let us review how quantum teleportation works.\n", + "\n", + "We have two parties, Alice and Bob, they would like to share information, and they have an entangled state (usually the Bell state $\\frac{1}{\\sqrt{2}} (\\ket{00} + \\ket{11})$). \n", + "If Alice now wishes to transfer quantum information, she will entangle some payload with her qubit and measure her qubit and payload.She will transmit the results of the measurement to Bob, who can use them to reconstruct Alice's payload on his entangled qubit.\n", + "\n", + "In the following code we will implement this operation.\n", + "\n", + "Before that, let's connect to the Az Quantum service and set our ta" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "operation PrepareBellState(alice : Qubit, bob : Qubit) : Unit is Adj + Ctl {\n", + " H(alice);\n", + " CNOT(alice, bob);\n", + "}\n", + "\n", + "operation Send(alice : Qubit, payload: Qubit) : (Result, Result) {\n", + " CNOT(payload, alice);\n", + " H(payload);\n", + " return (M(alice), M(payload));\n", + "}\n", + "\n", + "operation Receive(bob : Qubit, (cr_x : Result, cr_z : Result)) : Unit {\n", + " if cr_x == One { X(bob); }\n", + " if cr_z == One { Z(bob); }\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will now use Q# visualization tools to show the unitary responsible from creating the Bell state.\n", + "Printing unitary transformations implemented by operations is a great way to check whether your implementation is mathematically correct (for small operations)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "open Microsoft.Quantum.Diagnostics; // Contains DumpOperation\n", + "\n", + "operation DumpBellState() : Unit {\n", + " DumpOperation(2, qubits => PrepareBellState(qubits[0], qubits[1]));\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%simulate DumpBellState" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below we will now verify that our teleportation does indeed work correctly.\n", + "\n", + "In order to do this, we will teleport a state of a qubit that we rotate to an unusual angle from Alice to Bob.\n", + "\n", + "We will be using the `DumpRegister` and `AssertQubit` functions from the `Microsoft.Quantum.Diagnostics` to introspect our registers and assert that by the end of the computation the state of Bob's qubit is equivalent to the state of the payload qubit before teleportation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "operation PerformTeleportationOnBellState(alice : Qubit, bob : Qubit, payload : Qubit) : Unit {\n", + " let cr = Send(alice, payload);\n", + " Receive(bob, cr);\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "operation TestTeleportation() : Unit {\n", + " use (alice, bob, payload) = (Qubit(), Qubit(), Qubit());\n", + " Ry(1.727, payload);\n", + " DumpRegister((), [payload]);\n", + " PrepareBellState(alice, bob);\n", + " PerformTeleportationOnBellState(alice, bob, payload);\n", + " Adjoint Ry(1.727, bob); // Uncompute Bob's qubi, returning it to the |0> state\n", + " AssertQubit(Zero, bob);\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%simulate TestTeleportation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Seeing empirically that our teleportation works, we can proceed to run it on hardware.\n", + "\n", + "For this we will recreate our test function but run it multiple times." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "open Microsoft.Quantum.Convert;" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "operation TeleportToBob() : Result {\n", + " use (alice, bob, payload) = (Qubit(), Qubit(), Qubit());\n", + " Ry(1.727, payload);\n", + " PrepareBellState(alice, bob);\n", + " PerformTeleportationOnBellState(alice, bob, payload);\n", + " Adjoint Ry(1.727, bob);\n", + " return M(bob);\n", + "}\n", + "\n", + "operation CountCorrectTeleportation(n : Int) : Double {\n", + " let expected = Count(res -> res == Zero, DrawMany(TeleportToBob, n))\n", + " return IntAsDouble(expected) / IntAsDouble(n);\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us now see if our implementation is correct by seeing if the simulator succeeds in the teleportation 100% of the time." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%simulate CountCorrectTeleportation n=100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that on a perfect machine the teleportation works correctly every time. Now let us try running our work on Azure Quantum." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When running jobs on Azure Quantum, before going to real hardware it is recommended to run your code through a validator to make sure you don't waste precious resources on faulty code. `quantinuum.hqs-lt-s2-apival` is the appropriate target for this." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.connect resourceId=\"\" location=\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.target quantinuum.hqs-lt-s2-apival" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us now submit our job" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.submit TeleportToBob jobName=\"Teleportation API validaton\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now with the confidence that our job will work we can submit it to the simulator. The Quantinuum emulator provided by Azure Quantum differs from the simulator running locally, in that it accurately models noise and behavior of the Quantinuum quantum computer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.target quantinuum.hqs-lt-s2-sim" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.submit TeleportToBob jobName=\"Teleporation simulation\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we will look into our job and wait for its completion using `%azure.status` and once complete see results using `%azure.output`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.status" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.output" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us now enhance our code by building entanglement swapping. The idea of entanglement swapping is that if Alice and Bob do not have a direct connection but connections to third parties such that a path exists, then each pair of adjacent parties can create Bell states and teleport Alice's second qubit along this path until it reaches Bob.\n", + "\n", + "First we build the base case of entanglement swapping `EntanglementSwap3`, then we proceed to build the general case `EntanglementSwapN`\n", + "\n", + "We will test entanglement swapping with 3 parties by using the Bell pair we create to send a specific qubit state. With the advanced debugging tools of Q# we can introspect that states mid-simulation allowing us to perform this test. To validate that teleportation protocol was implemented correctly, we will use assertion features provided by Q#. Later in this notebook we will test entanglement swapping by checking that Alice and Bob have a Bell state since we will run on real hardware (or accurate simulators thereof) which does not allow such introspection. Validating concepts on small scale using Q# debugging features before proceeding to building full-scale algorithms is a good quantum software development practice." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "operation EntanglementSwap3(aliceCharlie : Qubit[], charlieBob : Qubit[]) : (Qubit, Qubit) {\n", + " PrepareBellState(aliceCharlie[0], aliceCharlie[1]);\n", + " PrepareBellState(charlieBob[0], charlieBob[1]);\n", + " PerformTeleportationOnBellState(charlieBob[0], charlieBob[1], aliceCharlie[1]);\n", + " ResetAll([aliceCharlie[1], charlieBob[0]]);\n", + " return (aliceCharlie[0], charlieBob[1]);\n", + "}\n", + "\n", + "operation TestEntanglementSwap3() : Unit {\n", + " use aliceCharlie = Qubit[2];\n", + " use charlieBob = Qubit[2];\n", + " let (alice, bob) = EntanglementSwap3(aliceCharlie, charlieBob);\n", + " use payload = Qubit();\n", + " Ry(1.727, payload);\n", + " DumpRegister((), [payload]);\n", + " PerformTeleportationOnBellState(alice, bob, payload);\n", + " Adjoint Ry(1.727, bob);\n", + " AssertQubit(Zero, bob);\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%simulate TestEntanglementSwap3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let us build entanglement swapping for $n$ parties, given that we have validated the concept for 3 parties. As mentioned above, we will then test that Alice and Bob end up sharing a Bell state." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "operation EntanglementSwapN(nParties : Int, qubits : Qubit[]) : (Qubit, Qubit) {\n", + " for i in 0..nParties-1 {\n", + " // Entangle pairs of qubits\n", + " PrepareBellState(qubits[2 * i], qubits[2 * i + 1]);\n", + " }\n", + " for i in 1..nParties-1 {\n", + " // Teleport previously teleported qubit \n", + " PerformTeleportationOnBellState(qubits[2 * i], qubits[2 * i + 1], qubits[2 * i - 1]);\n", + " }\n", + " return (qubits[0], qubits[2 * nParties - 1]);\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us now test entanglement swapping with 4 qubits locally by teleporting a state again and using Q#'s debugging features." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "operation EntanglementSwap4() : (Result) {\n", + " use qubits = Qubit[2 * 4];\n", + " let (q1, qn) = EntanglementSwapN(4, qubits);\n", + " use payload = Qubit();\n", + " let rot = Ry(1.727, _);\n", + " rot(payload);\n", + " DumpRegister((), [payload]);\n", + " PerformTeleportationOnBellState(q1, qn, payload);\n", + " DumpRegister((), [qn]);\n", + " Adjoint rot(qn);\n", + " return M(qn);\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%simulate EntanglementSwap4" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "open Microsoft.Quantum.Arrays;\n", + "open Microsoft.Quantum.Convert;\n", + "\n", + "operation TeleportNParties(nParties : Int) : Result {\n", + " use qubits = Qubit[2 * nParties];\n", + " let (alice, bob) = EntanglementSwapN(nParties, qubits);\n", + " use payload = Qubit();\n", + " let rot = Ry(1.727, _);\n", + " rot(payload);\n", + " PerformTeleportationOnBellState(alice, bob, payload);\n", + " Adjoint rot(bob);\n", + " return M(bob);\n", + "}\n", + "\n", + "operation CountCorrectTeleportationNParties(n : Int, nParties : Int) : Double {\n", + " let success = Count(res -> res == Zero, DrawMany(TeleportNParties, n, nParties));\n", + " return IntAsDouble(success) / IntAsDouble(n);\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Given that we will run on Quantinuum's H1-2, we can run with up to 6 parties as we have 12 qubits available. So let us run one example job.\n", + "\n", + "**Please note that this sample makes use of paid services on Azure Quantum. The cost of running this sample with the provided parameters on Quantinuum in a free trial subscription is approximately 31.8EHQC. This quantity is only an approximate estimate and should not be used as a binding reference. The cost of the service might vary depending on your region, demand and other factors.** \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%simulate CountCorrectTeleportationNParties n=100 nParties=6" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.target quantinuum.hqs-lt-s2-apival" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.submit TeleportNParties nParties=5 jobName=\"Entanglement Swapping - 6 parties API validation\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.status" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.output" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.target quantinuum.hqs-lt-s2-sim" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.submit TeleportNParties nParties=5 jobName=\"Entanglement Swapping - 6 parties\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.status" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%azure.output" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we can see we were able to run entanglement swapping on the Quantinuum emulator and were able to use the mid-circuit measurement capability in the process. We also saw how we could use the Azure Quantum service to submit and process our jobs." + ] + } + ], + "metadata": { + "kernel_info": { + "name": "iqsharp" + }, + "kernelspec": { + "display_name": "Q#", + "language": "qsharp", + "name": "iqsharp" + }, + "language_info": { + "file_extension": ".qs", + "mimetype": "text/x-qsharp", + "name": "qsharp", + "version": "0.24" + }, + "nteract": { + "version": "nteract-front-end@1.0.0" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/samples/azure-quantum/entanglement-swap/README.md b/samples/azure-quantum/entanglement-swap/README.md new file mode 100644 index 000000000000..fbeed1e2a60c --- /dev/null +++ b/samples/azure-quantum/entanglement-swap/README.md @@ -0,0 +1,42 @@ +--- +page_type: sample +author: adrianleh +description: Entanglement swapping using the Azure Quantum service +ms.author: t-alehmann@microsoft.com +ms.date: 08/02/2021 +languages: +- qsharp +- qiskit +- python +products: +- qdk +- azure-quantum +--- + +# Entanglement Swapping + +In this sample, we will performing entanglement swapping. + +The idea is that Alice and Bob want to use quantum teleportation to share data. +Though, they are too far apart to communicate directly. +Hence, they will be use a number of middlemen to communicate. +Each party will share an entangled pair with the parties next to them and teleport the information along the chain until it reaches Bob. +Since this sample is fundamentally based on teleportation we use Quantinuum's mid-circuit measurement capability. + +This sample is a Q# and Qiskit Jupyter notebook targeted at Quantinuum machines. + +## Q# with Jupyter Notebook + +Make sure that you have followed the [Q# + Jupyter Notebook quickstart](https://docs.microsoft.com/azure/quantum/install-jupyter-qdk) for the Quantum Development Kit, and then start a new Jupyter Notebook session from the folder containing this sample: + +```shell +cd entanglement-swapping +jupyter notebook +``` + +Once Jupyter starts, open the `ES-quantinuum-qsharp.ipynb` or `ES-quantinuum-qiskit.ipynb` notebook and follow the instructions there. + +## Manifest + +- [ES-quantinuum-qsharp.ipynb](https://github.com/microsoft/quantum/blob/main/samples/azure-quantum/entanglement-swapping/ES-quantinuum-qsharp.ipynb): IQ# notebook for this sample targetting Quantinuum. +- [ES-quantinuum-qiskit.ipynb](https://github.com/microsoft/quantum/blob/main/samples/azure-quantum/entanglement-swapping/ES-quantinuum-qiskit.ipynb): Qiskit notebook for this sample targetting Quantinuum. \ No newline at end of file