--- a +++ b/Code/All Qiskit, PennyLane QML Nov 23/19a1 A100 Lightning.gpu 27.52s kkawchak.ipynb @@ -0,0 +1,1011 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "id": "saZVT5NBpGsV", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 0 + }, + "outputId": "28a77a28-3759-474e-f1d9-edfdcee2019d" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Time in seconds since beginning of run: 1700504524.9473941\n", + "Mon Nov 20 18:22:04 2023\n" + ] + } + ], + "source": [ + "# This cell is added by sphinx-gallery\n", + "# It can be customized to whatever you like\n", + "%matplotlib inline\n", + "# !pip install pennylane pennylane-lightning-gpu custatevec-cu11 --upgrade\n", + "import time\n", + "seconds = time.time()\n", + "print(\"Time in seconds since beginning of run:\", seconds)\n", + "local_time = time.ctime(seconds)\n", + "print(local_time)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IrRdSTiapGsX" + }, + "source": [ + "Quantum advantage in learning from experiments\n", + "==============================================\n", + "\n", + "::: {.meta}\n", + ":property=\\\"og:description\\\": Learn how quantum memory can boost quantum\n", + "machine learning algorithms :property=\\\"og:image\\\":\n", + "<https://pennylane.ai/qml/_images/learning_from_exp_thumbnail.png>\n", + ":::\n", + "\n", + "*Author: Joseph Bowles --- Posted: 18 April 2022. Last updated: 30 June\n", + "2022.*\n", + "\n", + "This demo is based on the article [Quantum advantage in learning from\n", + "experiments](https://arxiv.org/abs/2112.00778) [\\[1\\]](#ref1) by\n", + "Hsin-Yuan Huang and co-authors. The article investigates the following\n", + "question:\n", + "\n", + "*How useful is access to quantum memory for quantum machine learning?*\n", + "\n", + "They show that access to quantum memory can make a big difference, and\n", + "prove that there exist learning problems for which algorithms with\n", + "quantum memory require *exponentially less resources* than those\n", + "without. We look at one learning task studied in [\\[1\\]](#ref1) for\n", + "which this is the case.\n", + "\n", + "The learning task\n", + "-----------------\n", + "\n", + "The learning task we focus on involves deciding if a unitary is\n", + "time-reversal symmetric (we'll call them T-symmetric) or not.\n", + "Mathematically, time-reversal symmetry in quantum mechanics involves\n", + "reversing the sense of $i$ so that $i \\rightarrow -i$. Hence, a unitary\n", + "$U$ is T-symmetric if\n", + "\n", + "$$U^*=U.$$\n", + "\n", + "Now for the learning task. Let's say we have a bunch of quantum circuits\n", + "$U_1, \\cdots, U_n$, some of which are T-symmetric and some not, but we\n", + "are not told which ones are which.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LkLkc0PApGsY" + }, + "source": [ + "{.align-center\n", + "width=\"50.0%\"}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5ExBGwcOpGsY" + }, + "source": [ + "The task is to design an algorithm to determine which of the $U$'s are\n", + "T-symmetric and which are not, given query access to the unitaries. Note\n", + "that we do not have any labels here, so this is an unsupervised learning\n", + "task. To make things concrete, let's consider unitaries acting on 8\n", + "qubits. We will also limit the number of times we can use each unitary:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "id": "lLqfHqpCpGsY" + }, + "outputs": [], + "source": [ + "qubits = 8 # the number of qubits on which the unitaries act\n", + "n_shots = 100 # the number of times we can use each unitary" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QqtOm_d4pGsY" + }, + "source": [ + "Experiments with and without a quantum memory\n", + "=============================================\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4lhh8844pGsZ" + }, + "source": [ + "To tackle this task we consider experiments with and without quantum\n", + "memory. We also assume that we have access to a single physical\n", + "realization of each unitary; in other words, we do not have multiple\n", + "copies of the devices that implement $U_i$.\n", + "\n", + "An experiment without quantum memory can therefore only make use of a\n", + "single query to $U_i$ in each circuit, since querying $U_i$ again would\n", + "require storing the state of the first query in memory and re-using the\n", + "unitary. In the paper these experiments are called **conventional\n", + "experiments**.\n", + "\n", + "Experiments with quantum memory do not have the limitations of\n", + "conventional experiments. This means that multiple queries can be made\n", + "to $U_i$ in a single circuit, which can be realized in practice by using\n", + "a quantum memory. These experiments are called **quantum-enhanced\n", + "experiments**.\n", + "\n", + "Note that we are not comparing classical and quantum algorithms here,\n", + "but rather two classes of quantum algorithms.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NQUrpuZmpGsZ" + }, + "source": [ + "{.align-center\n", + "width=\"60.0%\"}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gVDTZPuLpGsZ" + }, + "source": [ + "The conventional way\n", + "====================\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "H4NZdjTMpGsZ" + }, + "source": [ + "First, we will try to solve the task with a conventional experiment. Our\n", + "strategy will be as follows:\n", + "\n", + "- For each $U_i$, we prepare `n_shots` copies of the state\n", + " $U_i\\vert0\\rangle$ and measure each state to generate classical\n", + " measurement data.\n", + "- Use an unsupervised classical machine learning algorithm (kernel\n", + " PCA), to try and separate the data into two clusters corresponding\n", + " to T-symmetric unitaries vs. the rest.\n", + "\n", + "If we succeed in clustering the data then we have successfully managed\n", + "to discriminate the two classes!\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3cBEdL1QpGsa" + }, + "source": [ + "{.align-center\n", + "width=\"70.0%\"}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VEg1RDR4pGsa" + }, + "source": [ + "To generate the measurement data, we will measure the states\n", + "$U_i\\vert0\\rangle$ in the $y$ basis. The local expectation values take\n", + "the form\n", + "\n", + "$$E_i = \\langle 0\\vert U^{\\dagger}\\sigma_y^{(i)} U \\vert 0 \\rangle.$$\n", + "\n", + "where $\\sigma_y^{(i)}$ acts on the $i^{\\text{th}}$ qubit.\n", + "\n", + "Using the fact that $\\sigma_y^*=-\\sigma_y$ and the property $U^*=U$ for\n", + "T-symmetric unitaries, one finds\n", + "\n", + "$$E_i^*=\\langle 0\\vert (U^{\\dagger})^*(\\sigma_y^{(i)})^* (U)^* \\vert 0 \\rangle = - \\langle 0\\vert U^{\\dagger}\\sigma_y^{(i)} U \\vert 0 \\rangle = - E_i.$$\n", + "\n", + "Since $E_i$ is a real number, the only solution to this is $E_i=0$,\n", + "which implies that all local expectations values are 0 for this class.\n", + "\n", + "For general unitaries it is not the case that $E_i=0$, and so it seems\n", + "as though this will allow us to discriminate the two classes of circuits\n", + "easily. However, for general random unitaries the local expectation\n", + "values approach zero exponentially with the number of qubits: from\n", + "finite measurement data it can still be very hard to see any difference!\n", + "In fact, in the article [exponential separations between learning with\n", + "and without quantum memory](https://arxiv.org/abs/2111.05881)\n", + "[\\[2\\]](#ref2) it is proven that using conventional experiments, any\n", + "successful algorithm *must* use the unitaries an exponential number of\n", + "times.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VeMMzIc7pGsa" + }, + "source": [ + "Let's see how this looks in practice. First we define a function to\n", + "generate random unitaries, making use of Pennylane's\n", + "[RandomLayers](https://pennylane.readthedocs.io/en/stable/code/api/pennylane.RandomLayers.html)\n", + "template. For the time-symmetric case we will only allow for Y\n", + "rotations, since these unitaries contain only real numbers, and\n", + "therefore result in T-symmetric unitaries. For the other unitaries, we\n", + "will allow rotations about X,Y, and Z.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "id": "IIqOveLhpGsa" + }, + "outputs": [], + "source": [ + "import pennylane as qml\n", + "from pennylane.templates.layers import RandomLayers\n", + "from pennylane import numpy as np\n", + "\n", + "np.random.seed(234087)\n", + "\n", + "layers, gates = 10, 10 # the number of layers and gates used in RandomLayers\n", + "\n", + "\n", + "def generate_circuit(shots):\n", + " \"\"\"\n", + " generate a random circuit that returns a number of measuement samples\n", + " given by shots\n", + " \"\"\"\n", + " dev = qml.device(\"lightning.gpu\", wires=qubits, shots=shots)\n", + "\n", + " @qml.qnode(dev)\n", + " def circuit(ts=False):\n", + "\n", + " if ts == True:\n", + " ops = [qml.RY] # time-symmetric unitaries\n", + " else:\n", + " ops = [qml.RX, qml.RY, qml.RZ] # general unitaries\n", + "\n", + " weights = np.random.rand(layers, gates) * np.pi\n", + " RandomLayers(weights, wires=range(qubits), ratio_imprim=0.0001, rotations=ops, seed=np.random.randint(0, 10000))\n", + "\n", + " return [qml.sample(op=qml.PauliY(q)) for q in range(qubits)]\n", + "\n", + " return circuit" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hjafWs6opGsa" + }, + "source": [ + "let's check if that worked:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 0 + }, + "id": "PDxmRpoDpGsa", + "outputId": "59fab63c-a8ac-4cc9-b4bb-ca096a3a8eca" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[[ 1 1 1]\n", + " [ 1 1 1]\n", + " [ 1 1 1]\n", + " [ 1 1 1]\n", + " [ 1 1 1]\n", + " [ 1 1 -1]\n", + " [ 1 1 -1]\n", + " [ 1 -1 -1]]\n", + "\n", + "\n", + "[[ 1 1 1]\n", + " [ 1 1 1]\n", + " [ 1 1 1]\n", + " [ 1 1 1]\n", + " [ 1 1 1]\n", + " [ 1 1 1]\n", + " [ 1 1 1]\n", + " [-1 -1 -1]]\n" + ] + } + ], + "source": [ + "# the measurement outcomes for the first 3 shots\n", + "circuit = generate_circuit(n_shots)\n", + "print(np.array(circuit(ts=True))[:, 0:3])\n", + "print(\"\\n\")\n", + "print(np.array(circuit(ts=False))[:, 0:3])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fqoyiIk3pGsb" + }, + "source": [ + "Now we can generate some data. The first 30 circuits in the data set are\n", + "T-symmetric and the second 30 circuits are not. Since we are in an\n", + "unsupervised setting, the algorithm will not know this information.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "id": "m8naW3HRpGsb" + }, + "outputs": [], + "source": [ + "circuits = 30 # the number of circuits in each data set\n", + "\n", + "raw_data = []\n", + "\n", + "for ts in [True, False]:\n", + " for __ in range(circuits):\n", + " circuit = generate_circuit(n_shots)\n", + " raw_data.append(circuit(ts=ts))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XJIyrRYMpGsb" + }, + "source": [ + "Before feeding the data to a clustering algorithm, we will process it a\n", + "little. For each circuit, we calculate the mean and the variance of each\n", + "output bit and store this in a vector of size `2*qubits`. These vectors\n", + "make up our classical data set.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "id": "_tpgsRE_pGsb" + }, + "outputs": [], + "source": [ + "def process_data(raw_data):\n", + " \"convert raw data to vectors of means and variances of each qubit\"\n", + "\n", + " raw_data = np.array(raw_data)\n", + " nc = len(raw_data) # the number of circuits used to generate the data\n", + " nq = len(raw_data[0]) # the number of qubits in each circuit\n", + " new_data = np.zeros([nc, 2 * nq])\n", + "\n", + " for k, outcomes in enumerate(raw_data):\n", + " means = [np.mean(outcomes[q, :]) for q in range(nq)]\n", + " variances = [np.var(outcomes[q, :]) for q in range(nq)]\n", + " new_data[k] = np.array(means + variances)\n", + "\n", + " return new_data\n", + "\n", + "\n", + "data = process_data(raw_data)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GWRIxXZcpGsb" + }, + "source": [ + "Now we use scikit-learn's [kernel\n", + "PCA](https://en.wikipedia.org/wiki/Kernel_principal_component_analysis)\n", + "package to try and cluster the data. This performs principal component\n", + "analysis in a high dimensional feature space defined by a kernel (below\n", + "we use the radial basis function kernel).\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "id": "3r7XYPtspGsb" + }, + "outputs": [], + "source": [ + "from sklearn.decomposition import KernelPCA\n", + "from sklearn import preprocessing\n", + "\n", + "kernel_pca = KernelPCA(\n", + " n_components=None, kernel=\"rbf\", gamma=None, fit_inverse_transform=True, alpha=0.1\n", + ")\n", + "\n", + "# rescale the data so it has unit standard deviation and zero mean.\n", + "scaler = preprocessing.StandardScaler().fit(data)\n", + "data = scaler.transform(data)\n", + "# try to cluster the data\n", + "fit = kernel_pca.fit(data).transform(data)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ebvo16Y5pGsb" + }, + "source": [ + "Let's plot the result. Here we look at the first two principal\n", + "components.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 430 + }, + "id": "MVbFwU-LpGsc", + "outputId": "0e6f4478-2300-4f9c-aecc-bb3a7beaa9b0" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ], + "image/png": "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Q3bIkCG2vr6+Q+vgtlEKlZSUqLCwUKNGjWpYVlxcLMdx9M477zS7XXV1tS677DLNnz9f/fr1S0WpntPWc7u/8vJy5efny+/vdK/9Slh9fb1Wrlyp4uLihmWO46i4uFglJSVNblNSUtKovSSNHz++2fZdWVvO7/6qq6sVDofVs2dPt8r0pLae29tvv119+vTR1KlTU1GmZ7Xl/C5evFhjx47V1Vdfrb59++rYY4/VnXfeqWg02q5auu7f0GlQWlqqPn36NFrm9/vVs2dPlZaWNrvd9ddfr5NPPlkTJ050u0TPauu53deOHTt0xx13aPr06W6U6Bk7duxQNBpV3759Gy3v27evVq9e3eQ2paWlTbZP9Nx3JW05v/u76aabNGDAgAMCY1fXlnP75ptv6rHHHtOHH36Yggq9rS3n97PPPtOyZcs0adIkvfTSS1q7dq2uuuoqhcNhzZ49u8210PPSAWbOnCljTIufRP9S2t/ixYu1bNkyzZs3r2OL9gg3z+2+QqGQzjnnHA0bNky33XZb+wsHXHLXXXdp4cKFWrRokbKzs9NdjqdVVFTo8ssv1yOPPKKioqJ0l9MpxWIx9enTRw8//LBGjhypiy++WDfffLMWLFjQrv3S89IBbrjhBl155ZUtthkyZIj69eunbdu2NVoeiURUVlbW7O2gZcuWad26dSosLGy0/KKLLtK4ceO0fPnydlSe+dw8t3tUVFRowoQJysvL06JFi5SVldXesj2tqKhIPp9PW7dubbR869atzZ7Lfv36JdW+K2vL+d1j7ty5uuuuu/Taa6/puOOOc7NMT0r23K5bt06ff/65zj333IZlsVhMUrznds2aNTrssMPcLdpD2vKz279/f2VlZcnn8zUsO/roo1VaWqr6+noFAoG2FdOhI2jQoj2DSt97772GZa+88kqLg0q3bNliP/roo0YfSfbXv/61/eyzz1JVesZry7m11try8nJ70kkn2dNOO81WVVWlolRPGD16tL3mmmsavo5Go3bgwIEtDtj95je/2WjZ2LFjGbDbjGTPr7XW3n333TY/P9+WlJSkokTPSubc1tTUHPD368SJE+3Xv/51+9FHH9m6urpUlu4Jyf7szpo1yx588ME2Go02LJs3b57t379/u+ogvKTYhAkT7Fe+8hX7zjvv2DfffNMeccQRjR7n/eKLL+xRRx1l33nnnWb3IZ42alKy57a8vNyOGTPGDh8+3K5du9Zu2bKl4ROJRNL1bWSEhQsX2mAwaJ944gm7atUqO336dFtYWGhLS0uttdZefvnldubMmQ3t33rrLev3++3cuXPtp59+amfPns2j0i1I9vzeddddNhAI2Oeee67Rz2lFRUW6voWMley53R9PG7Us2fO7YcMGm5eXZ6+55hq7Zs0a++KLL9o+ffrYn//85+2qg/CSYjt37rSXXnqp7d69u83Pz7dTpkxp9BfQ+vXrrST7+uuvN7sPwkvTkj23r7/+upXU5Gf9+vXp+SYyyAMPPGAHDx5sA4GAHT16tP3HP/7RsO60006zkydPbtT+mWeesUceeaQNBAL2mGOOsX/5y19SXLG3JHN+Dz744CZ/TmfPnp36wj0g2Z/dfRFeWpfs+X377bftmDFjbDAYtEOGDLG/+MUv2v0LorHW2rbdcAIAAEg9njYCAACeQngBAACeQngBAACeQngBAACeQngBAACeQngBAACeQngBAACeQngBAACeQngBAACeQngBAACeQngBAACeQngBAACe8v8BVnJw09zHXDEAAAAASUVORK5CYII=\n" + }, + "metadata": {} + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# make a colour map for the points\n", + "c = np.array([0 for __ in range(circuits)] + [1 for __ in range(circuits)])\n", + "\n", + "plt.scatter(fit[:, 0], fit[:, 1], c=c)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SlrsWm7ZpGsc" + }, + "source": [ + "Looks like the algorithm failed to cluster the data. We can try to get a\n", + "separation by increasing the number of shots. Let's increase the number\n", + "of shots by 100 and see what happens.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 430 + }, + "id": "tfVK7J8OpGsc", + "outputId": "6572747b-1b95-4940-e987-074533be1e66" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ], + "image/png": "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oxUOh3Xcccf17r8RBs+dc845NmHCBPvLX/5if/7zn+2YY46xmTNndmvd73//+3buueeaJFu9enV6g/pUT/fvyy+/bBdeeKE9/PDDtmXLFlu7dq0de+yxdtFFF3mYOjutWrXKQqGQ/eIXv7BXXnnFLr/8chs8eLBVV1d3OP6ZZ56xYDBo3/3ud+3VV1+166+/3vLz8+3ll1/2OLk/9HT/XnzxxbZ8+XJ78cUX7bXXXrPLLrvMSktL7Z133vE4uT/0dP/ut3XrVhs7dqydccYZdsEFF3gT1od6un+bm5tt0qRJdt5559m6dets69at9vTTT9tLL73U421TXjz26quvmiR7/vnn25b94Q9/MOecvfvuuynXffHFF23s2LH2/vvvU1460Zf9e7D77rvPQqGQtbS0pCOmb0yePNnmzZvX9nM8HrcxY8bYkiVLOhz/2c9+1qZNm9ZuWUVFhX3pS19Ka06/6un+PVQsFrPi4mK7++670xXR13qzf2OxmJ1++un2s5/9zC699FLKSwo93b8/+clP7Oijj7ZoNNrnbXPYyGPr16/X4MGDNWnSpLZllZWVCgQCeu655zpdr7GxURdffLGWL1+uUaNGeRHVl3q7fw9VW1urkpIS5eUNuMd/dVs0GtXGjRtVWVnZtiwQCKiyslLr16/vcJ3169e3Gy9JU6dO7XR8LuvN/j1UY2OjWlpaNHTo0HTF9K3e7t9vf/vbGjlypObOnetFTN/qzf59+OGHNWXKFM2bN09lZWU66aSTdMsttygej/d4+7n7X+YMqaqq0siRI9sty8vL09ChQ1VVVdXpel/5yld0+umn64ILLkh3RF/r7f492K5du3TTTTfpiiuuSEdE39i1a5fi8bjKysraLS8rK9Prr7/e4TpVVVUdju/uvs8lvdm/h7r22ms1ZsyYwwojerd/161bp5///Od66aWXPEjob73Zv2+99ZaefPJJzZo1S4899pi2bNmiL3/5y2ppadHixYt7tH1mXvrJwoUL5ZxL+eruf5AO9fDDD+vJJ5/UsmXL+je0j6Rz/x6srq5O06ZN0/jx43XjjTf2PTiQJkuXLtWqVau0evVqRSKRTMfxvfr6el1yySVauXKlhg8fnuk4A1IikdDIkSN15513auLEiZoxY4auu+46rVixosefxcxLP/nqV7+qyy67LOWYo48+WqNGjdKOHTvaLY/FYqqpqen0cNCTTz6pN998U4MHD263/KKLLtIZZ5yhp59+ug/J/SGd+3e/+vp6nXPOOSouLtbq1auVn5/f19i+Nnz4cAWDQVVXV7dbXl1d3em+HDVqVI/G57Le7N/9brvtNi1dulR//OMfdcopp6Qzpm/1dP+++eabevvtt/WpT32qbVkikZCUnL3dvHmzPvCBD6Q3tI/05s/v6NGjlZ+fr2Aw2LbsxBNPVFVVlaLRqEKhUPcD9PmsGfTI/hNKX3jhhbZljz/+eMoTSt9//317+eWX270k2Q9/+EN76623vIruC73Zv2ZmtbW19qEPfcjOPPNMa2ho8CKqL0yePNnmz5/f9nM8HrexY8emPGH3/PPPb7dsypQpnLDbiZ7uXzOzW2+91UpKSmz9+vVeRPS1nuzfpqamw/47e8EFF9gnPvEJe/nll625udnL6L7Q0z+/ixYtsqOOOsri8XjbsmXLltno0aN7vG3KSwacc8459q//+q/23HPP2bp16+zYY49tdynvO++8Y8cff7w999xznX6GuNqoUz3dv7W1tVZRUWEnn3yybdmyxd5///22VywWy9SvkRVWrVpl4XDY7rrrLnv11VftiiuusMGDB1tVVZWZmV1yySW2cOHCtvHPPPOM5eXl2W233WavvfaaLV68mEulU+jp/l26dKmFQiF74IEH2v05ra+vz9SvkNV6un8PxdVGqfV0/27bts2Ki4tt/vz5tnnzZnvkkUds5MiRdvPNN/d425SXDNi9e7fNnDnTBg0aZCUlJTZnzpx2//HZunWrSbKnnnqq08+gvHSup/v3qaeeMkkdvrZu3ZqZXyKL/PjHP7YjjzzSQqGQTZ482f7yl7+0vXfmmWfapZde2m78fffdZ8cdd5yFQiH74Ac/aI8++qjHif2lJ/v3qKOO6vDP6eLFi70P7hM9/fN7MMpL13q6f5999lmrqKiwcDhsRx99tH3nO9/p1f9JdGZm3T/IBAAAkFlcbQQAAHyF8gIAAHyF8gIAAHyF8gIAAHyF8gIAAHyF8gIAAHyF8gIAAHyF8gIAAHyF8gIAAHyF8gIAAHyF8gIAAHyF8gIAAHzl/wN7zPjUP8fR9wAAAABJRU5ErkJggg==\n" + }, + "metadata": {} + } + ], + "source": [ + "n_shots = 10000 # 100 x more shots\n", + "\n", + "raw_data = []\n", + "\n", + "for ts in [True, False]:\n", + " for __ in range(circuits):\n", + " circuit = generate_circuit(n_shots)\n", + " raw_data.append(circuit(ts=ts))\n", + "\n", + "data = process_data(raw_data)\n", + "scaler = preprocessing.StandardScaler().fit(data)\n", + "data = scaler.transform(data)\n", + "\n", + "fit = kernel_pca.fit(data).transform(data)\n", + "\n", + "plt.scatter(fit[:, 0], fit[:, 1], c=c)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n2F2k_CRpGsc" + }, + "source": [ + "Now we have a separation, however we required a lot of shots from the\n", + "quantum circuit. As we increase the number of qubits, the number of\n", + "shots we need will scale exponentially (as shown in [\\[2\\]](#ref2)), and\n", + "so conventional strategies cannot learn to separate the data\n", + "efficiently.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aLJp5ud_pGsc" + }, + "source": [ + "The quantum-enhanced way\n", + "========================\n", + "\n", + "Now let's see what difference having a quantum memory can make. Instead\n", + "of using a single unitary to generate measurement data, we will make use\n", + "of twice the number of qubits, and apply the unitary twice:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jSO6utq0pGsc" + }, + "source": [ + "{.align-center\n", + "width=\"70.0%\"}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UNE5n_sGpGsc" + }, + "source": [ + "In practice, this could be done by storing the output state from the\n", + "first unitary in quantum memory and preparing the same state by using\n", + "the unitary again. Let's define a function `enhanced_circuit()` to\n", + "implement that. Note that since we now have twice as many qubits, we use\n", + "half the number of shots as before so that the total number of uses of\n", + "the unitary is unchanged.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "id": "jpZYLZkzpGsc" + }, + "outputs": [], + "source": [ + "n_shots = 50\n", + "qubits = 8\n", + "\n", + "dev = qml.device(\"lightning.gpu\", wires=qubits * 2, shots=n_shots)\n", + "\n", + "\n", + "@qml.qnode(dev)\n", + "def enhanced_circuit(ts=False):\n", + " \"implement the enhanced circuit, using a random unitary\"\n", + "\n", + " if ts == True:\n", + " ops = [qml.RY]\n", + " else:\n", + " ops = [qml.RX, qml.RY, qml.RZ]\n", + "\n", + " weights = np.random.rand(layers, n_shots) * np.pi\n", + " seed = np.random.randint(0, 10000)\n", + "\n", + " for q in range(qubits):\n", + " qml.Hadamard(wires=q)\n", + "\n", + " qml.broadcast(\n", + " qml.CNOT, pattern=[[q, qubits + q] for q in range(qubits)], wires=range(qubits * 2)\n", + " )\n", + " RandomLayers(weights, wires=range(0, qubits), ratio_imprim=0.0001, rotations=ops, seed=seed)\n", + " RandomLayers(weights, wires=range(qubits, 2 * qubits), ratio_imprim=0.0001, rotations=ops, seed=seed)\n", + " qml.broadcast(\n", + " qml.CNOT, pattern=[[q, qubits + q] for q in range(qubits)], wires=range(qubits * 2)\n", + " )\n", + "\n", + " for q in range(qubits):\n", + " qml.Hadamard(wires=q)\n", + "\n", + " return [qml.sample(op=qml.PauliZ(q)) for q in range(2 * qubits)]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EgGQFWO6pGsc" + }, + "source": [ + "Now we generate some raw measurement data, and calculate the mean and\n", + "variance of each qubit as before. Our data vectors are now twice as long\n", + "since we have twice the number of qubits.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "id": "PeJwszSvpGsd" + }, + "outputs": [], + "source": [ + "raw_data = []\n", + "\n", + "for ts in [True, False]:\n", + " for __ in range(circuits):\n", + " raw_data.append(enhanced_circuit(ts))\n", + "\n", + "data = process_data(raw_data)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6BhOJM0XpGsd" + }, + "source": [ + "Let's throw that into Kernel PCA again and plot the result.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 430 + }, + "id": "PoL0WA_ypGsd", + "outputId": "4eb171d4-3f12-4d45-b49d-327b084776e3" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ], + "image/png": "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A8w777xjJdnXXnutY9lf/vIXa4yxn3zySdxt33jjDXvQQQfZTz/9lDDTpj/Hc2+PPfaYDQQCtqWlJRVlZq2JEyfayy+/vON7LBazo0aNsosXL+6y/XnnnWfPPPPMTsvKysrs9773vZTW6SWJHtN9RaNRm5+fbx9++OFUlegpfTme0WjUnnTSSfb++++3F198MWFmH4ke03vvvdeOGTPGNjc393mf3GYaYCoqKlRYWKgJEyZ0LCsvL5fjOHr11Ve73a6+vl6zZs3S0qVLVVJSko5SPaGvx3Nf1dXVCofD8vsH3OvQutXc3KwNGzaovLy8Y5njOCovL1dFRUWX21RUVHRqL0lTpkzptv1g05djuq/6+nq1tLSoqKgoVWV6Rl+P5w033KCRI0dq7ty56SjTU/pyTFetWqVJkybp8ssvV3FxsY499lj94he/UCwW6/V+B8+/rINEZWWlRo4c2WmZ3+9XUVGRKisru93uqquu0kknnaRzzjkn1SV6Sl+P59527dqlG2+8UZdddlkqSsxau3btUiwWU3FxcaflxcXFevfdd7vcprKyssv2vT3WA11fjum+rrnmGo0aNWq/0DgY9eV4vvjii3rggQe0adOmNFToPX05pu+//77WrVun2bNn68knn9R7772nf/7nf1ZLS4sWLVrUq/1yZcYjFixYIGNM3E9v/zHb16pVq7Ru3TotWbIkuUVnsVQez71FIhGdeeaZGjt2rK6//vr+Fw70w80336zly5dr5cqVCoVCmS7Hc2pqanThhRdq2bJlGjFiRKbLGTBc19XIkSP161//WuPHj9fMmTP1k5/8RPfdd1+v++DKjEdcffXVuuSSS+K2GTNmjEpKSrRz585Oy6PRqKqqqrq9fbRu3Tpt3bpVhYWFnZbPmDFDkydP1nPPPdePyrNTKo9nu5qaGk2dOlX5+flauXKlcnJy+lu2p4wYMUI+n087duzotHzHjh3dHruSkpKE2g82fTmm7W677TbdfPPNeuaZZ3TcccelskzPSPR4bt26VR9++KHOPvvsjmWu60pqvWK7ZcsWHXbYYaktOsv15Xf0wAMPVE5Ojnw+X8eyY445RpWVlWpublYgEOh5x30ebYOs1D5g9fXXX+9Y9tRTT8UdsPrpp5/aN998s9NHkv3Vr35l33///XSVnpX6cjyttba6utp+9atftaeccoqtq6tLR6lZaeLEiXbevHkd32OxmD3ooIPiDgA+66yzOi2bNGkSA4D3kugxtdbaW265xYbDYVtRUZGOEj0lkePZ0NCw37+V55xzjj311FPtm2++aZuamtJZetZK9Hd04cKF9tBDD7WxWKxj2ZIlS+yBBx7Y630SZgagqVOn2q985Sv21VdftS+++KI94ogjOj1K/PHHH9ujjjrKvvrqq932IZ5m6pDo8ayurrZlZWV23Lhx9r333rOffvppxycajWbqr5ERy5cvt8Fg0D700EP2nXfesZdddpktLCy0lZWV1lprL7zwQrtgwYKO9i+99JL1+/32tttus5s3b7aLFi3i0ex9JHpMb775ZhsIBOzjjz/e6XexpqYmU3+FrJLo8dwXTzPtL9Fj+tFHH9n8/Hw7b948u2XLFrt69Wo7cuRIe9NNN/V6n4SZAejzzz+3F1xwgR06dKgNh8N2zpw5nf7h+uCDD6wk++yzz3bbB2Fmj0SP57PPPmsldfn54IMPMvOXyKC77rrLHnLIITYQCNiJEyfaV155pWPdKaecYi+++OJO7R977DF75JFH2kAgYL/85S/bP//5z2muOPslckwPPfTQLn8XFy1alP7Cs1Siv6N7I8x0LdFj+vLLL9uysjIbDAbtmDFj7M9//vOE/s+fsdbaBG6HAQAAZBWeZgIAAJ5GmAEAAJ5GmAEAAJ5GmAEAAJ5GmAEAAJ5GmAEAAJ5GmAEAAJ5GmAEAAJ5GmAEAAJ5GmAEAAJ5GmAEAAJ5GmAEAAJ72/wH0ruwf8pXgywAAAABJRU5ErkJggg==\n" + }, + "metadata": {} + } + ], + "source": [ + "kernel_pca = KernelPCA(\n", + " n_components=None, kernel=\"rbf\", gamma=None, fit_inverse_transform=True, alpha=0.1\n", + ")\n", + "\n", + "scaler = preprocessing.StandardScaler().fit(data)\n", + "data = scaler.transform(data)\n", + "\n", + "fit = kernel_pca.fit(data).transform(data)\n", + "\n", + "c = np.array([0 for __ in range(circuits)] + [1 for __ in range(circuits)])\n", + "plt.scatter(fit[:, 0], fit[:, 1], c=c)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ylz4xQPupGsd" + }, + "source": [ + "Kernel PCA has perfectly separated the two classes! In fact, all the\n", + "T-symmetric unitaries have been mapped to the same point. This is\n", + "because the circuit is actually equivalent to performing\n", + "$U^TU\\otimes \\mathbb{I}\\vert 0 \\rangle$, which for T-symmetric unitaries\n", + "is just the identity operation.\n", + "\n", + "To see this, note that the Hadamard and CNOT gates before\n", + "$U_i\\otimes U_i$ map the $\\vert0\\rangle$ state to the maximally entanged\n", + "state\n", + "$\\vert \\Phi^+\\rangle = \\frac{1}{\\sqrt{2}}(\\vert 00...0\\rangle+ \\vert11...1\\rangle$,\n", + "and the gates after $U_i\\otimes U_i$ are just the inverse\n", + "transformation. The probability that all measurement outcomes give the\n", + "result $+1$ is therefore.\n", + "\n", + "$$p(11\\cdots 1) = \\langle \\Phi^+ \\vert U_i \\otimes U_i \\vert\\Phi^+ \\rangle.$$\n", + "\n", + "A well known fact about the maximally entanged state is that\n", + "$U\\otimes \\mathbb{I}\\vert\\Phi^+\\rangle= \\mathbb{I}\\otimes U^T\\vert\\Phi^+\\rangle$.\n", + "The probabilty is therefore\n", + "\n", + "$$p(11\\cdots 1) = \\langle \\Phi^+ \\vert U_i^T U_i \\otimes \\mathbb{I} \\vert\\Phi^+ \\rangle.$$\n", + "\n", + "For T-symmetric unitaries $U_i^T=U_i^\\dagger$, so this probability is\n", + "equal to one: the $11\\cdots 1$ outcome is always obtained.\n", + "\n", + "If we look at the raw measurement data for the T-symmetric unitaries:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 0 + }, + "id": "tJPkMr8XpGsd", + "outputId": "b0b6a478-4efe-4c09-af1e-3d0a48956eb5" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1],\n", + " [1, 1, 1, 1, 1]], requires_grad=True)" + ] + }, + "metadata": {}, + "execution_count": 31 + } + ], + "source": [ + "np.array(raw_data[0])[:, 0:5] # outcomes of first 5 shots of the first T-symmetric circuit" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RCbeEgB9pGsd" + }, + "source": [ + "We see that indeed this is the only measurement outcome.\n", + "\n", + "To make things a bit more interesting, let's add some noise to the\n", + "circuit. We will define a function `noise_layer(epsilon)` that adds some\n", + "random single qubit rotations, where the maximum rotation angle is\n", + "`epsilon`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "id": "oj_9u5_ipGsd" + }, + "outputs": [], + "source": [ + "def noise_layer(epsilon):\n", + " \"apply a random rotation to each qubit\"\n", + " for q in range(2 * qubits):\n", + " angles = (2 * np.random.rand(3) - 1) * epsilon\n", + " qml.Rot(angles[0], angles[1], angles[2], wires=q)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R1FYa3ltpGse" + }, + "source": [ + "We redefine our `enhanced_circuit()` function with a noise layer applied\n", + "after the unitaries\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "id": "dFNylIKDpGse" + }, + "outputs": [], + "source": [ + "@qml.qnode(dev)\n", + "def enhanced_circuit(ts=False):\n", + " \"implement the enhanced circuit, using a random unitary with a noise layer\"\n", + "\n", + " if ts == True:\n", + " ops = [qml.RY]\n", + " else:\n", + " ops = [qml.RX, qml.RY, qml.RZ]\n", + "\n", + " weights = np.random.rand(layers, n_shots) * np.pi\n", + " seed = np.random.randint(0, 10000)\n", + "\n", + " for q in range(qubits):\n", + " qml.Hadamard(wires=q)\n", + "\n", + " qml.broadcast(\n", + " qml.CNOT, pattern=[[q, qubits + q] for q in range(qubits)], wires=range(qubits * 2)\n", + " )\n", + " RandomLayers(weights, wires=range(0, qubits), ratio_imprim=0.0001, rotations=ops, seed=seed)\n", + " RandomLayers(weights, wires=range(qubits, 2 * qubits), ratio_imprim=0.0001, rotations=ops, seed=seed)\n", + " noise_layer(np.pi / 4) # added noise layer\n", + " qml.broadcast(\n", + " qml.CNOT, pattern=[[qubits + q, q] for q in range(qubits)], wires=range(qubits * 2)\n", + " )\n", + "\n", + " for q in range(qubits):\n", + " qml.Hadamard(wires=qubits + q)\n", + "\n", + " return [qml.sample(op=qml.PauliZ(q)) for q in range(2 * qubits)]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oke1LvWDpGse" + }, + "source": [ + "Now we generate the data and feed it to kernel PCA again.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 430 + }, + "id": "NnBgZF7TpGse", + "outputId": "dd2e7f9a-7ae3-4f4b-f95e-e9b01d9ad82d" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAi8AAAGdCAYAAADaPpOnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABRsUlEQVR4nO3deXxU1d3H8c+5M9n3sIUliDsuiAqCoLii4IpWqyIVtbhURVtxKdhWXNqCFXet1q1qrQ+IVlRUFMFdBAStO1UUWcMWyL7N3PP8MRCJJJMEMnNzk+/79crTJ3fO3PvFm+T+5txzzzHWWouIiIiITzheBxARERFpDhUvIiIi4isqXkRERMRXVLyIiIiIr6h4EREREV9R8SIiIiK+ouJFREREfEXFi4iIiPhK0OsALc11XVavXk1GRgbGGK/jiIiISBNYaykpKaFbt244TvS+lTZXvKxevZr8/HyvY4iIiMgOWLFiBT169Ijaps0VLxkZGUDkH5+ZmelxGhEREWmK4uJi8vPza6/j0bS54mXrraLMzEwVLyIiIj7TlCEfGrArIiIivqLiRURERHxFxYuIiIj4iooXERER8RUVLyIiIuIrKl5ERETEV1S8iIiIiK+oeBERERFfaXOT1ImIiH9UlFawaPZnVJRU0mPvbvQesIfWpZNGqXgREZG4c12X//vrC0y97QUqy6pqt++yXz7XPnYZvQfs6WE6ae1020hEROLu8Rue4Ykbp9YpXABWfL2Sa46+ie8/+9GjZOIHKl5ERCSuNqzayLNTXqr3Nde1hKpDPHHj1DinEj9R8SIiInH11v99QLRRLW7Y5aOZiyguLIlbJvEXFS8iIhJXhQWbcQLRLz/WtRRvUPEi9VPxIiIicdWhWw7hsBu1jRNwyO6cFadE4jcqXkREJK6OOffwqI9DOwGHw04bQHp2WhxTiZ+oeBERkbjKzcvhV388s97XnIBDUkoi599y9k4fZ+W3a5j1+Fxee2wOK/+3eqf3J62H5nkREZG4+9WNZ5KWlcrTt06nZFNZ7fa9+u3G1Q//hl326bHD+968voi/nX8/C2d9Wmd7/2F9uf7JK8nR7SjfM9Za63WIllRcXExWVhZFRUVkZmZ6HUdERKKorqrhi/e+pqy4gvy9u9Frv/yd2l9leRVjB4xnxZLVuD8bV+MEHXrs2ZX7F0wmJS15p44jLa8512/1vIiIiGcSkxI4eOgBLba/uf9+jx+/Wlnva27IZfk3q5jz9HucfOlxLXZMiT+NeRERkTbj9SfeijoY2GB4/Ym34phIYkHFi4iItBmFBZuJNhrCWsumgs3xCyQxoeJFRETajC69OuE4UR7DdgxdenWKYyKJBRUvIiLSZpx40VBct+GeF9e1nHjR0DgmklhQ8SIiIm3GEWceSp8h++A421/enIDD/of35ohfHupBMmlJKl5EpFVyXZdP5n7Of+55hVcfeZMNqwu9jiQ+EEwI8pdXb+DEi48lIemnB2qDiUFOGHMMf33tDyQkJniYUFqC5nkRkVbnmwXfMmnUPaxeuhbjGKxrMY5h+IVHM/b+i0hM0sVHGleyqZQlC5cCsFf/3cjMzfA4kUSjeV5ExLd+/Hol1x5zMzVV1UBkdeGt/zvrn29RVlzBn6aN8zKi+ERGTjr9j+/rdQyJgbjcNnrggQfo1asXycnJDBw4kAULFjTpfVOnTsUYw2mnnRbbgCLSavzfX/9DqLoGN7x9p7B1Le9On8d3n/zgQTIRaS1iXrxMmzaNcePGMXHiRBYvXkzfvn0ZNmwY69ati/q+ZcuWce211zJkyJBYRxSRVqKmuoa3n/2QcMhtsE0gGGDOv9+LYyoRaW1iXrzceeedXHzxxVx44YXsu+++PPTQQ6SmpvL44483+J5wOMyoUaO4+eab2W233WIdUURaiYrSSsI14ahtLJaijcVxSiQirVFMi5fq6moWLVrE0KE/PVPvOA5Dhw5l3rx5Db7vlltuoXPnzowZMyaW8USklUnLTCUlvZEF8yx06alJxkTas5gWLxs2bCAcDtOlS5c627t06UJBQUG973n//fd57LHHeOSRR5p0jKqqKoqLi+t8iYg/BYIBhl14NE6g4T9Nrusy7MKj45hKRFqbVjXPS0lJCeeddx6PPPIIHTt2bNJ7Jk2aRFZWVu1Xfv7OLacuIt4694ZfkNs1h0Cw/j9P5074BXm9Osc5lYi0JjEtXjp27EggEGDt2rV1tq9du5a8vLzt2i9dupRly5ZxyimnEAwGCQaDPPXUU7z00ksEg0GWLl263XsmTJhAUVFR7deKFSti9u8RkdjL6ZLNffP+wqGn9Mdss0ZNTl42V9z7ay649RwP04lIaxDTeV4SExPp168fc+bMqX3c2XVd5syZw9ixY7dr37t3bz7//PM62/74xz9SUlLCPffcU2+vSlJSEklJSTHJLyLe6Ni9Azc9fx0b12xi5ZLVJKYksle/3QgEA15HE5FWIOaT1I0bN47zzz+f/v37M2DAAO6++27Kysq48MILARg9ejTdu3dn0qRJJCcns//++9d5f3Z2NsB220Wk7evQNYcOXXO8jiEirUzMi5ezzz6b9evXc+ONN1JQUMCBBx7IrFmzagfxLl++vN4FtERERETqo7WNRERExHPNuX6ry0NERER8RcWLiIiI+IqKFxEREfEVFS8iIiLiKypeRERExFdUvIiIiIivqHgRERERX1HxIiIiIr6i4kVERER8RcWLiIiI+IqKFxEREfEVFS8iIiLiKypeRERExFdUvIiIiIivqHgRERERX1HxIiIiIr6i4kVERER8RcWLiIiI+IqKFxEREfEVFS8iIiLiKypeRERExFdUvIiIiIivqHgRERERX1HxIiIiIr6i4kVERER8RcWLiIiI+IqKFxEREfGVoNcBRCR2Nq3dzJtPv8e65evJ6pjJMeceTrfd87yOJSKyU1S8iLRB1lqm3TaDJ26ciutaAgEH17U8edM0TrrkOK68bwyBYMDrmCIiO0S3jUTaoFcfeZPHbniGcMjFupZQTRg37IKFVx+ezaPjn/Y6oojIDlPxItLGhENhnrp5eoOvWwsz7nuN4o0lcUwlItJyVLyItDFLFn5H4ZpNUduEasLMf2VxnBKJiLQsFS8ibUxFaWWjbYwxlJdUxCGNiEjLU/Ei0sb02KsbmOhtrLXk9+4en0AiIi1MxYtIG9Nll070P64vTqD+X2/jGLr06sSBR+8X52QiIi1DxYtIGzT2/jGkZ6fhBOv+ijsBh2BCgPFPXYnj6NdfRPxJf73EF6x1sdULsOXTsJWvYd1SryO1at336MoDCydz7LlDCCZE5nMxjmHAiQdxzwd/Yf/D9/E4oYjIjjPWWut1iJZUXFxMVlYWRUVFZGZmeh1HWoCtXoAtmgDhFdtsTcakXwppl2GMavBoKsoq2byuiIycdNKz07yO43sVZZW89cz7LJj1CTVVIXofsgcnXHQMHbt3aPljlVYw59/v886zH1JeXE6v/Xty0qXHse+he7X4sUS81pzrt4oXadVs9X+xhecCYcDdvkHapTgZ18Q7lrRTP3z+I9cfdyub1xVhHIN1LY5jMAGH6/95BcecO6TFjrXm+7Vce8xNrFuxAYPBWksg6BAOuZxx9clcOmU0xjQyMlvER5pz/dZHVmnVbOldNFi4AJQ9ig2vj2ckaacqSiu4/rhbayf3s27kc5/rWsI1YSaPvo9vFnzbIsdyXZc/nPxXNq4uBBt5OgwgHIr8Hjx/10xmPT63RY4l4kcqXqTVsuH1UP0hDRYuEHmt8tV4RZJ2bO4z77N5fVFkmYV6OI7hubtmtsixFr3xX1Z8s7q2WNmOgWdvf5E21nEu0mQqXqT1cqPPEhsRwLobYh5FZP6rizFRJtAJh1w+enlRixxr8ZufE0iIsnCmhZX/W8PGRmZSFmmrVLxI6xXoSKOzrRHGBLrGI420c6HqUKM9HeGaUIscq6HenR1tJ9LWqHiRVss4uZB0NBDlEygJkHxSvCJJO7ZXv90bnPgPIreN9uy3W4sca9/BexOuCUdt06FbDh265bTI8UT8RsWLtGom41owSTT0o2oyrsY4WfENJe3SiRcfG/V117WcduWJLXKsw047hNy87IZnSTaG0686iUAgWmEv0napeJFWzQT3wOT+HyT0rfuC0xGTeQsmbYw3waTd6dyzE9c+djnGGALbzFzsOJFbm8MuPJqjzzmsRY4VTAhyy4u/JzktqU4Bs/VYg0b058xxJ7fIsUT8SPO8iG/Y0FIILQcnHRIOwpig15GkHfpq3hKeu3Mm819ZTDgUYs+Dd+P0q07k6JGHt/i8K+tWbODF+2fx1tT3qSytpOc+PTj18mEcefZg9bpIm6NJ6lS8iIiI+IomqRMREZE2S8WLiIiI+IqKF5+zNqxZNkVEpF3RiEcfsrYCyv6FLf83uGuAZGzySZj0izDB3b2OJyIiElMqXnzGumXYwvMg9BU/rflTCZUzsJWvQO7jmMT+XkYUERGJKd028hlbes/PCpetwkA1dvNVWFvjQTIREZH4UPHiI9ZWQsWzNLzKsgvuBqiaG89YIiIicaXixU/CK8GWN9IoiK35Mi5xREREvKDixVcSm9DGYkxT2omIiPiTihc/CeRDoCcQbQry8JaVmEVERNomFS8+YozBpF0ONDSvSwASBmIS9otnLBERkbhS8eI3KadD2tgt3wSI9MJsWaAtuC8m516PgomIiMSH5nnxGWMMJuMqbMqp2IrpEPoBTAYm5URIHIIxqkdFRKRtU/HiUybYC5NxndcxRERE4k4f00VERMRXVLyIiIiIr+i2kYhIO1BTXcO70z9i9r/eYfPazeTt2oUTxhzDIScchOPoc6z4i4oXEZE2rnhjCdcfdwtLP12G4xhc1/LDFyv4YMYCDj2lHzdOv4aExASvY4o0WVzK7QceeIBevXqRnJzMwIEDWbBgQYNtH3nkEYYMGUJOTg45OTkMHTo0ansREYnubxfczw+fLwfAdSPzRLnhyBpp819ZzBN/nOpZNpEdEfPiZdq0aYwbN46JEyeyePFi+vbty7Bhw1i3bl297d9++21GjhzJW2+9xbx588jPz+f4449n1apVsY4qItLmrPx2DfNfWVxbrPycdS0vPfg6FaUVcU4msuOMtbah6VpbxMCBAznkkEO4//77AXBdl/z8fK688krGjx/f6PvD4TA5OTncf//9jB49utH2xcXFZGVlUVRURGZm5k7nFxHxs5n/mM09lz3caLspb91E3yM1O3esua7Le899xEsPvs6yL1eQkpbMUWcP5tQrhtM5v6PX8TzVnOt3TMe8VFdXs2jRIiZMmFC7zXEchg4dyrx585q0j/LycmpqasjNza339aqqKqqqqmq/Ly4u3rnQ0m7Y8AaonAV2MwS6QdIwjJPmdSyRFuWG3chE3I18TLVuTD/HCpEP43899x7enT4PJ+Dghl2KN5Qw/Y6XefmhN/jb7BvZ+5A9vI7pCzG9bbRhwwbC4TBdunSps71Lly4UFBQ0aR+///3v6datG0OHDq339UmTJpGVlVX7lZ+fv9O5pW2z1sUtuR27fgi25FZs6d+xReOx6w/Dlj/ndTyRFrXfYXs3WrgEE4PsfmCvuORpz2bc+xrvPhf54L7tbTw37FJZVsmfTp1MTXWNV/F8pVU/Hzd58mSmTp3KCy+8QHJycr1tJkyYQFFRUe3XihUr4pxS/MaW3gNljwBhIn/VQ1teKMcW34CtnOVhOpGWtXvfXuw3eG8Cwfr/3DsBh+NGH0lGTnqck7Uvruvy/N0zGywk3bBl09oiPnhBD6g0RUyLl44dOxIIBFi7dm2d7WvXriUvLy/qe6dMmcLkyZN54403OOCAAxpsl5SURGZmZp0vkYZYdzOUPRqlhcGW3EGMh4KJxNUNz/yWDt1yMY6p3WaMAQN7Hrwbv7njfA/TtQ+FBZtZv2Jj1DaBhABffrAkTon8LabFS2JiIv369WPOnDm121zXZc6cOQwaNKjB9/3tb3/j1ltvZdasWfTv3z+WEaW9qZwLROuWtRD+EUJfxyuRSMx17tmJhz65nTF/HUV+7+5kdshgj4N68bsHL+HOd24mNSPF64htXiDQtMut08R27V3MJ6kbN24c559/Pv3792fAgAHcfffdlJWVceGFFwIwevRounfvzqRJkwC47bbbuPHGG3nmmWfo1atX7diY9PR00tPVrSk7yRYRqdnrf2y0llsSjzQicZORk87Z14/g7OtHeB2lXcrunEWPvbux6n+raahjN1wT5qBj+8Q3mE/FvMQ7++yzmTJlCjfeeCMHHnggn376KbNmzaodxLt8+XLWrFlT2/7BBx+kurqaM888k65du9Z+TZkyJdZRpT0I9KTRwgUg2CPmUUSk/TDGcPZ1IxosXJyAQ7c98jjkhAPjmsuvYj7PS7xpnheJxtoa7Poh4G6i/pFzAUgciJP7RJyTiUhbZ63lH9c+xfN3zSQQdAiHtjzGDnTomsOUt26mx55dvQ3poeZcv1W8SLtjK+diN1++5btte2ECYFIwudMwCXt6EU1E2oGv5i1h5j9m8/1nP5KamcKRvxzM0POOIC0z1etonlLxouJFGmGr5mFL74Sa/27ZYiDxSEzm9ZigJomStstay8dv/JeZD73BD58vJzUzhaPOPowTLzqWzA4ZXseTdkzFi4oXaSIbWgl2Ezh5mEAnr+OIxJTrutx1yUPMevyt2hleAYxjyOyQwZS5N9Frv/hN9FlVUcUHMxayZula0nPSOPwXA+nQNSdux5fWRcWLihcRke28+MAs7r/ysXpfcwIOnXp04Mnv7iMQCMQ8yzvPfshdv/kHZZvLCQQDuK6LMYYRY4dz6ZTRcckgrUtzrt96oFxEpB1wXZfn7ny5doDodq+HXdb+uJ75ryyOeZaFsz7hzyPvoqyoHIBwKIx1LW7YZca9r/KPa5+KeQbxNxUvIiLtQGHBZgp+WBd1naNAQoDP3v4y5lkeu+GZyAy/9WSxFl68fxYb12yKeQ7xLxUvIiLtQSsZIbB6aQFLP10WdRVray3vPf9RHFOJ36h4ERFpB3K75tB5l+iD0sM1YQ44cr+Y5ijZVNZoG8dxKG1CO2m/VLyIiLQDjuPwy3GnNPx6wKFzz44MPOngmObo3LNjnQUi6xMOhem6W5eY5hB/U/EiItJOnHrFMI4bfSRQdwFA4xgyctL488wJBIKxfconp3MWg07pH3UBwtTMFA7/xYCY5hB/i/nCjCJbWVsNVe+CuwGczpB0OMYkeh1LpN1wHIfr/nkFR541uM4kdUefczgnXHQM2Z2y4pLj0imj+fzdrykrLq+dawYiRZS1lt8+eAlJKUlxySL+pHleJC5s+XPYktu2rOq8hcnBZP4Bk3Kqd8FExBOrvlvDP659io9eXsTWy9BuB+zCr/8ykoEn9fM4nXhBk9SpeGlVbPl/sMXjG3zdZN2FSTkpjolEpLXYtHYz65ZvIC07je575EUeoZZ2qTnXb902kpiytjrS4xKtTcnfIHk4xmhGTZH2JqdLNjldsr2OIT6jAbsSW9UfRdYOisZdAzWxn9VTRETaBhUvElvuxpZtJyIi7Z6KF4ktJ6+J7brGNoeIiLQZGvPiIRtaji3/F1S+CrYSgr0xab+CpGEY00bqysQBkQLGXUv9i6oYCOwCCQfEO5mIiPhUG7lC+o+tXoDdcBKUPw3uerAlULMIu/m32KLrsNZtfCc+YEwAk3nT1u9+/ipgMJkT9YSBiIg0mYoXD1i3HLvpMqAGCG/zypaCpfJlqJjqQbLYMMnHYHL+Eelh2VZgd0zO45ikw7wJJiIivqTbRl6ofCXS09Iggy37J6SMbDM9EibpKOh4JIS+hPB6CHSB4D5t5t8nIiLxo+LFA7bmEyBA3V6XOi0g/CPYUjAZcUwWW8YYSNgfErxOIiIifqbbRp5w2H78R0PtREREZFu6OnrAJB0OhKK0cCDYB+OkxSuSiIiIb6h48ULSseB0I3LrqD4uJv3ieCYSERHxDRUvHjAmAZP7KDg51Hv7KHEIJA6Key4RERE/UPHiERPcA9PxDUg+dfsXq9/Hrj8WW/NZ/IOJiIi0cnrayEuhpVD5Uj0vWLCl2MJfQ6e5GCf60uAA1lqo+STyRQASB2MS9mrxyCISW9VVNcx95n1ee/RN1q/cSG5eNsMuOJrjzj+K5NQkr+OJtAoqXjxkyx4n0vlV3yPTbmQumIoZkDY6+n5CP2I3Xwmhb/ipM83FJg7CZN+FcXJbNLeIxEZ5SQXXD72FJQu/wzgG61o2rNzIko+X8uIDs5jy1k1kd8ryOqbnNq8vYuWS1SSlJrFb310IBBoaP+gN13VZ/ObnvP+f+VSWV9Kzdw+GXXg0HbrmeB2tzTDW2voWnPGt4uJisrKyKCoqIjOz8R4LL7lrDwJbFqWFgcQhOLmPNtjCuoXYDSeDu4nti6AABPfAdHgeYxJbIrKIxNDtv36AN//1Lm54++VBnIDDIcMP5M8vT/AgWeuwcc0mHhz3BO8991Htf6OO3XM59w9ncPKlx7WKSS83ry/ijydPZsnC7wgEA5FecWsxjmHsfRdx8qXHeR2x1WrO9VtjXrxkG5qkrrYB0R+pBsqfAbeQ+ntvwhBaApWv71g+EYmbzeuLmPP0e/UWLgBu2GX+q4tZvbQgzslah83ri/jt4D/UKVwANqwq5N7LH+FfN0/3MF2EtZYbR/yNbz/5HoBwKIwbdnFdSzjkcs9lDzP/1cUep2wbVLx4KeEAop8CBxIOjLoLW/ECtWsiNbAPW/Fi87OJSFwtWfAd4VAjH2gsfPH+N/EJ1MpMnTyD9Ss3Nljc/evW6RQsWxfnVHV98f43fP3R/3BD9Wd0HMMzf3k+zqnaJhUvHjJp5xO98DCY1LOj78Td3MhR3C09M42zoeW4JVNwN12Gu3kctnIW1tY06b0ispOaeMujNdwaibdwOMxrj81psHABcByHN554O36h6vHhiwsJBBsef+O6lq/m/Y/iwmhr20lTaMCul5KGQur5UP4kddc6CgAWk3U7JtA1+j4C+RD6msgtpnobQHCXBl77iS17HFtyGz8NIHawlTMhsBvkPoEJ5DXt3yQiO2SfgXsSTAgQqonS+2KgzxH7xC9UK1FeXEF5cUX0RgbPe16qKqqbtPJLdaU+FO4s9bx4yBiDybgBk/0gJB4CJhVMJiSfjOnwHCbl5Mb3kXoODRcuAGFMyi+j7sNWvoEtmbxlP1v/cG75hBP+EbvpYtrYuG6RViezQwbHnX8UTqD+P8tOwGHwqYeQ16tznJN5LzktiUBC9CeKDIbM3PQ4Jarfbgfs0uitv8wOGeR01hNjO0vFi8eMMZjkY3Fyn8Lp8ilOl49xsm/HJOzftB2k/AISDqL+U2kg+aRGZ+u1pf9o4P1QO+i3+sOm5WkjbOh73OKbcdcNwV17KG7hxdiqd1XESUxddtcF7DsoMj/T1iLGOJGP8rvun881j13mWTYvJSQmcMSZhxIINnzJCofCHDNqSBxTbe+Ycw+PzMXTQO+L4xhO+c3xUW8tSdOoePE5YxIxOf+E1FFA8jYvZGLSx0ZuPUW5R27dzRD6nOhjb4LYqndaKHHrZ6vexm44BcqngrsWbGFk1uNNF2FLblMBIzGTkpbM7XMmcsMzv6PvUfvRfY889j+8N9c+fjn3zvsrmbkZXkf0zLk3nEEwIYjjbH/ZchzD4NMOYa9+u3uQ7CepGSmM/9dVOI6zXaHlOIa9+u/OORNO9yhd26J5XtoQ65ZC6FsiTynt06S5XWx4PXb9YY20CkLKWThZNzUhQxG4ReB02OlVsW14I1RMw1a+AbYSEvpgUs/FJB60U/uNeky3ELvuSKCahm7Hmez7MMnDYpZBROr31bwl/PXce1j743qcgIN1XcAw9Lwj+O2DF5OU0jpmIP56/rdMnfwCH738Ma5rye2aw6mXD+OMq0/WLMlRNOf6reKlnbG2AtwScLIxJhFrw9j1Q8DdEPV9JvMvmNSGx87Yms+xJfdC9btELvpBSD4Fk3EVJtC9+TlrPsMWXrhlEr+tvUJbBjWnXYGT8dtm77NJxy17FFtyOw2PI4o8vu50mBqT44tIdK7rsmj2Zyz7YgVJKYkcevLBdO7ZyetY9QrVhKiurCElPbldPiXWXCpeVLxsx9YswZbeD1WziRQDSZByOib9cqh4AVt6N/VfsA2YNEyn9zFOav37rpqP3fTrLfvddrBaIHL7qsN0TLBn07PaCuy6o8AW0dDtrFj1fribLoOquUQfBB3AdPlKf4xERFqQZtiVOmz1YuzGM6HqTX4qBqqgYjp24xnY5OGQOJDIKLNtL8gBIIjJvqfhwsWGsUXXEylafj7KPgy2GFv85+YFrpgJdhMNj8NxsGWPNW+fTdaUgXQqWkREvKTipY2z1sUWXQvUUG9x4RZCyW2YnEcxGX+EQC8iF+fkyG2fDv/BJEUZwV/9IbhraLjQCEP1O9hw06c0t9XziV5EuFDzaUwm0DNJgxtpEYDEQ9XrIiLiIU1S19ZVfwThlVEahKHqLXALMWnnYdLOw1rb9Itz6HsiNXC0p5UshJZBkye6s0S/bbNtuxaWfCqU3Am2lPr/TWFM2piWP66IiDSZel7autB3NH6bY0txsUWzehVMKtELly2a8eSRSezfyD4dCO4fk5WyjZOOyXkMTBrb30IDkzEBk9TY01kiIhJL6nlp60wKTeqhMCk7tv+kY4j8GEVZ/drJg+C+Td9n8ilQMuVnTxpty8Wk/bp5OZvBJPaFTrOh/Dls1RywVZBwICZ1JCZh75gdV0REmkbFS1uXdBR1102qh9MJEvbbod2bQAds6rlQ/i8anBcl/SqMafqMksZJh5yHsIUXEZlvZds1n8KQekFk5uAYMk4upF+CSb8kpseR9slay/ef/Ujp5jK67Z5Hpx4dvI4k4isqXto4E+iETTkbKv6PhouLKzBmx38UTMZ4rK2CimlECgxDpMfEwWRcg0k9s/n7TDwEOr2GLX8GKl/f0vuxHyb1V5A4WANmxbfeefZDHv/j/7H6uy2D2A30H3Ygl991Afl7N39OJJH2SPO8tAPWVmOL/gCVL1K3uACTPhbSrmiRYsCGlkPlTKy7CRPoBsmnYgL+/0RprQu4O1XgiQC8+ugc7rrkociv4DZ/eZ2AQ0pGMvfPn0yPPRtZSV6kjdIkdSpe6mVrvsVWvgxbi4uU0zFNfgKo/bHVC7Glj0D1e0AYAnti0kZDypnNug0mAlBeUsFZeRdRVVFd7+tO0GHwKf2Z+Px1cU4m0jo05/qtj5LtiEnYE5MwzusYvmDLn8cW30DkgbwtY27C32GL/wRVH0L2nSpgpFnenT6Pqsr6CxcAN+TywYsLKdpQTFZHffASiUaPSov8jA0XYIv/SKRff9uBzls6Kateg4oXPEgmflawbB2BYPSC17qW9Ss3ximRiH+peBH5GVs+jeiPlxts+VPxiiNtRGaHDNxw43MiZXbIiEMaEX9T8SLyc6GvaXzG4P/RxoaLSYwd8ctBUV83jmHfwXvTOb9jnBKJ+JeKF5GfM0k0/quRoMe1pVk6dsvl9KtOrHfCa2MiM1v/+s8j4x9MxIdUvIj8jEk6iug9LwFIOjpOaaQtueT28/jlNacSTIiMfXECkT/BWZ2yuPmF6+l71I5NFinS3uhRaZGfsbYKu/54cNex/czEBjCY3GmRZQREdkDRhmI+fHEhpZvL6b5HHgNOPIhggh7+lPZNj0qL7ARjkiD3SWzhBeCuJtJBaYkULgFM1t9UuMhOyeqYyQljjvU6hohvqXgRqYcJ9oJOb0DlG9iqt8FWYxL2i0xQ1wZmDRYR8TMVL9KqWLcUbDGYbIyT6mkWYxIh5WRMysme5hARkbpUvEirYGv+hy29F6reJDJYNohNPgmTfiUm2NPreCIi0oroaSPxnK35DLvxTKiaw09P+YQiizxuPAMb+t7LeCIi0sqoeBFPWWuxm68Hqtn+yZ4w2FJs0UQPkomISGul4kW8VfMJhL+n4XlVwlAzHxtaFsdQIiLSmql4EW+FljaxnW4diYhIhIoX8ZZp4hNFTW0nIiJtnooX8VbSECAxehuTDYkHxyONiIj4QFyKlwceeIBevXqRnJzMwIEDWbBgQdT206dPp3fv3iQnJ9OnTx9effXVeMQUDxgnE9IujN4m/fLInCsiIiLEoXiZNm0a48aNY+LEiSxevJi+ffsybNgw1q1bV2/7Dz/8kJEjRzJmzBg++eQTTjvtNE477TS++OKLWEcVwLqF2Mo3sZWzseH6z1FLM+m/g5RRbJ1+PzL9kBP5SrsCUs+PSw4REfGHmC/MOHDgQA455BDuv/9+AFzXJT8/nyuvvJLx48dv1/7ss8+mrKyMmTNn1m479NBDOfDAA3nooYcaPZ4WZtwx1i3HFv8ZKmcAoS1bHUg+AZN5E8bJin2G0HKofAnrbsQ4eZAyAhPIi/lxRUTEe61mYcbq6moWLVrEhAkTarc5jsPQoUOZN29eve+ZN28e48aNq7Nt2LBhzJgxo972VVVVVFVV1X5fXFy888HbGWtD2E0XQ80i6j6y7ELlLGxoKXSYhjEpMc1hgj0hfSwmpkcREWk/rLUs/3olJYWldN6lE53zO3odqUXEtHjZsGED4XCYLl261NnepUsXvvnmm3rfU1BQUG/7goKCettPmjSJm2++uWUCt1dVs6FmYQMvhiH0DVS8CKnnxDWWiN9ZayneWIITcEjPTsMYleYSPx/NXMSjE/7Nj1+uqN128NA+XHbXhfTaL9/DZDvP908bTZgwgaKiotqvFStWNP4mqcOWP0f0HwWDLZ8Wrzgivue6LjPuf43z9xzLmZ3H8IsOF3Lpgdfy5tPvEuM79SIAvD3tA/40YjLLv1pZZ/unb33JVYNuYNmX/r5WxrR46dixI4FAgLVr19bZvnbtWvLy6h/LkJeX16z2SUlJZGZm1vmSZnLX0PAMtwAW3Pp7vkSkLtd1uW30fTzw28dZ88NPg96XfbmC20bfx+M3PONhOmkPqiurueeyRwC2K5bdsEtVRTUPXv2EB8laTkyLl8TERPr168ecOXNqt7muy5w5cxg0aFC97xk0aFCd9gCzZ89usL20AKcLjfW8RNqISGM+eGEBc595HyyRry2sG/lm6m0z+GbBt96Ek3Zh3ksfU7q5rM7P37bcsMviNz9j3YoN8Q3WgmJ+22jcuHE88sgjPPnkk3z99ddcdtlllJWVceGFkbk9Ro8eXWdA729/+1tmzZrFHXfcwTfffMNNN93Exx9/zNixY2Mdtd0yKWcQvecFTMqZ8Qkj4nMv/n0WTqDhP62BoMPMh96IYyJpbwqWrY/6M7jVuh/XxyFNbMR0wC5EHn1ev349N954IwUFBRx44IHMmjWrdlDu8uXLcZyf/iMPHjyYZ555hj/+8Y/ccMMN7LnnnsyYMYP9998/1lHbr+Tjobwv1HzO9kVMAAK9IOV0D4KJ+M8Pny3HDTf8YSAccvn+s+VxTCTtTUZuetSfwdp2HTLikCY2Yj7PS7xpnpcdY90SbPGNUPkaPxUwBpKOxmT9FePkehlPxDdG9bqMdcujdMcb6DNkH+58+5b4hZJ2pXhjCWd3u5hQTbje140x7LJfDx7+7x2t6gm45ly/ff+0kbQM42TgZN+F6fQ2JutOTNYdmI5v4uQ8pMJFpBmOOmtw1C57g+GIMzWGT2Ins0MGZ19/Wv0vGrBYLpo0qlUVLs2l4iVOrK3EhtdibaXXUaIygTxMysmYlFMwQX/PAyDihVOvGE5SSiKOs/2FwQk45HTJ4rjzjvAgmbQno28+i1F/OINgQgCgtqBOz07jD8/8joEn9fMy3k7TbaMYs6Hl2NL7oPIVItPuByH5REz6WEyw187v3y2G8I9gUiCwG8aoHhXx2lfzlvCnU2+jeGMJgWDk4hEOhemySyf++tof6Nm7u8cJpb0o3ljCBzMWULyxlLxdOzPo1P4kJiV4Hatezbl+q3iJIRv6DrvxbLDlwLb3HgNgUjC5z2ASeu/Yvt1CbPHfoPIlatciCvTApI3FpP5iZ6OLyE6qrqzmnenz+OrDJRjH4aBj+zD41P61xYyI1KXipZUUL+7Gs7Y8wVPfoKkABHvjdHyh2fu17ibsxl9CeFW9+zbp12DSL/2pvbVQ818IfQUkQtLhWvBQRERalVazMGN7Zmu+hZpPo7QIQ+hLbM1XmIR9m7fv0ocbLFwir98JKadiAl0jvT+br4bQkm1aONjkUzFZN8d8sUUREZGWpgESsRL+rmntQk1st4W1YaiYRkOFS4SBiv9gw6uxG0fWcwwXKl/CbrpK66yIiIjvqHiJlab2aDS358OWgC1tvFl4BbbssS1t6yt0XKh+B2o+bt7xRUREPKbiJVYSB4JJa6RRCiQObt5+TSrQ2IA/F9wqqHiB6D00AWzFi807voiIiMdUvMSIMSmYtEuiN0r7NcZprMD5+X4TIek4oJHJhareb0IPTRjcwmYdX0RExGsqXmIp7VJI/TWRQiNAZHx0IPJ9ynmY9Ct3fL8NLRdaqwhMeiNtAhDotmMZREREPKKnjWLIGAeTOR6bOgoqX8SG12ECnSB5BCbYc8f362Q1WrpAEAK7Q6i+xRa3CmNSNCeMiPhfqCbEBzMWMvff71G0oZiuu3fhxIuGsv/hvX09Db7UT8VLHJhgPqSPbexGTzN22MRJrhIPALsRwmuod+xLyjnNfkxbRKS1KS4sYfzxf+bbxd/jOA6u6/LNgm9581/vMvS8I7j28csJBDQ5YFui20Z+5ORBYBeij3sJYZKGYnKfhaSh1DnVJhOTfjUm86bY5mwi65Zhy57G3fAL3HVH4G4cia34D9ZWex1NRHxg0qh7WPrfZQC4bqSnORyK/O+bT7/L1EkzPErWdlRX1fDyg69z8QHjOCn1XH7ZZQwPXv0EBcvWeZJHM+w2gQ1vhIrnsaH/Rab1Tz4OEg/3dB0hWz4dW/yHBl4NQHB3TIeXa7tLbXgdhL4FkwgJB2BMUvzCRmHDG7CFoyC8bOsWIoWWCwkHYXIeb/agZhFpP378eiUX7Xd11DYZuelMXfVwq13Tp7Wrqqhiwgl/4Yv3vgZga9XgBB2SU5O4fc5E9uq3+04fpznXb/W8NMKWP49dPyQya23lK5EiZtNF2I2nY8MbvAuWciakjtnyzdbu0C2nM9ANk/Nwnfu8JtAZk3QYJvGQVlO4ANii6yC8nEjRsrWO3jJGp+a/2JJJHiUTET9YPPszTD0reG+rpLCU77f0zEjzPX3Lc3z5/jdY+1PhAuCGXCrLqph4+u2Ew9Gm5Wh5Kl6isFUfYItvILLwoUtk3MiWRRBD/8NuutizGWqNMTiZv8d0eB5SzoCEgyK9QVmTMR1fwfjgKSIb+h6qP6DhuWhcqHgB626OYyoR8ZNwKNyk8YRbbyNJ81RX1fDyQ2/guvVf69ywy4aVG1nw6idxzaUBu1HYsn8QGVdS30mLrE1E9TxIauZEcy3IJPTBZPXx7Pg7pXpRExrVRBa3TBoS8zgi4j+9B+7Z4IV1q4TkBHrtnx+nRG3Lmu/XUlZUHrVNICHAkgXfMeiU/nFKpZ6XBlm3HKo/ouHHjAGC2Ko3d2z/4dXYqrexVR9hbdUO7cP/mvr8lR5zFJH67Td4b3rtn48TqP9y5gQchp1/FGmZqXFO1jYEgk14SsvaprVrQSpeGtSUgsKCrWzWXm14DW7hJdj1R2M3XYLdNBq7bjC29EGsbWfdmomHNKURJBwQ8ygi4k/GGG6cfg0Zuel1CxgDxsAeB+3KxX87z7uAPtdt9y503qVT1DbhkEv/4QfGJ9AWKl4aYrLA6dhIIxcT7N3kXdrweuzGX0L1e9S5FWVLsKV3YYv/skNR/coEd4HEI2l4rSYHUs7EOC3z1JiItE35e3fn4f9OYeT40+nUowPJaUnssk8PLr/n19z5zs2kZjRzAVyp5TgO51w/osHXA0GHfQ7di94D9ohjKj0qHZUt/Tu29F7qv3VkgERM5w+afHF1i/8K5f8i2mKJpuOrmGB8fwi8ZN1CbOFoCP2Pn8YXbXlUOnHglqem9IdHRMQr1lr+cc2TPH/3KwSCDuGQi+MYXNeyy749+NubN5Kbl7PTx2nO9VvFSxTWVmILL4CaT6lbwAQAi8m6E5NyYhP35WLX9W98scSk43ByHtixwD5lbSVUzMRW/Afc9RDojkk5C5KPx5idH1NuQ99D5WtYtwgT6Akpp2CcrBZILiLSfny7+HteefhNVixZRXp2GkedfRiH/2IACYktM3+OipcWnKTO2ioo+ye2/N/grgUMJB2FSbsEk9iv6ftxy7DrDmpSW5P5V0zqmTuYWLaythpb9AeofJHaBTEJAwmYzD9iUs/xNqCIiNRqzvVbj0o3wpgkSP9NZCVnWw4mAWMSd2BHyUASTRkIbItvhuThGKexVaElGls0ESpf2vLdtrfqqrHFN4KTjUke7kU0T9jQCmzF8xD+MbJERMpJkHCIFq0TEd/RgN0mMsZgnLQdK1wAYwKQchpN+09eDZUzd+g4EmHDq6DyP9Q/Rw+AwZbc69kkg/FmS/+O3TAUyv4Bla9BxbPYwl9hC0dj3UZuZYqItDIqXuLIpF0CJDehZQAbXhHrOG1b5ZtEnx/GQvi7bdZUarts+X+wpXcTKeTC/DRbNFCzEFt0rWfZRER2hIqXODLBfMj5RxNauhiTEfM8bZoto0k/3o0NoPY5ay22LNoAcBeq5mJD38Utk4jIztKYlzhzkgbiJvSDmsU0fEvDheSmPcUkDQjuSu06VA0KQKBHPNJ4J/wDNNqL50DlXEiP3SP61lq+nv8tq78rICMnjYOO7UNi8o7dghURUfHiAZP+O+ym87d89/MCxkDy6Zhgz3jHaluSjgWTDbaI+ovEACSfgHF2fm6CVq1JM0A7NG1G6R3zxQffcNclD7H861W129KyUjnvxl/yi9+dpAHD9di8vog3nnibpf9dRkJiAoee0o9Bp/SP+xTsIq2VihcPmKSBkH0ftmgC2GIip8EFbGRG2cyJHif0P2MSIes27ObLiIx9+dk8PU4uJuN6j9LFUaAnkAhUR2kUgmbMFN0cSz5eyvVDbyZcU3dixrKich665kmqKqo594ZfxOTYfjX3/97n9gsfqF0t2TiG1594ix57dWXy63+iSyNTtYu0B5rnxUPWVkHl7MigUZMemZQt0M3rWG2Krf44Mkty9UdbtiRC8qmYjKswgTxPs8WLW3QjVEyn/pmdHXA6YDq90yITAv7c9UNv5r/vfIUbrn/drmBikGmrHiazg8Z4QaSXatwRN9b7FFwg6JC3axce/eJOggn63Cltj+Z58QljkiDlZK9jtGkmsT8m9ymsWwhuKTgdMU77Wl3WZFyDrfkYQt+z/UzRAUz23TEpXDasLuSTuV9EbROuCfPO9Hmc8pvjW/z4fjTtbzMwAYMNbV+8hEMuq75dw7yXPmbIGYd6kE6k9dDTRtIuGCcXE+zZ7goXAONkYXKnQdpvwGwd45MAySdhOvwH06TVvZtv89qiRts4QYfCNZticny/cV2XBa9+ghtqeHX5QNBh3ssfxzGVSOuknheRdsA4GZiM32HTfwtUAomRiRNjKCcvu9E2bsilQ7fcmObwi3Ao3ODtta1c11JdGW38kkj7oJ4XqZet+Rpbeh9uye3Yihcj43PE94wxGJMS88IFoEPXHA4e2gcn0PCfmWBigCPPGhTzLH6QkJhAtz3yGn36arcDesUnkEgrpuJF6rBuCW7hRdiNI7Clf48sSll0HXbdYdiqt72OJz5z0eRfEUgI4Dj1X5DPv/kcMnK0htdWp409gYbnfwIn4DD810fHL5BIK6XiRWpZa7GbLofq97dsCVM70ZstwW66HFvzmVfxxIf2PHg37njrZnrtX3feoozcdK6499ecdd2pHiVrnU657HgOGX4QxlBndQsn4GCM4ZpHLiM3r43PTSTSBHpUWmrZ6kXYwpFRWgQg6WicnL/HLZO0DdZavvvkB1Z/V0Badhp9j9qXhMQEr2O1SqGaEC/9/XVm3Pcqa75fh3EM/YcdyNnXj6Dvkft5HU8kZppz/VbxIrXc4j9D+TNEn1bfwXT5b+QxbxGJqaqKKoIJQc2s2wqUFZfz9tQPWPm/NaRlpXLkWYPI37u717HaFM3zIjvGlhLtfnuEC7YCVLyIxFxSin7PWoPZT73DPZc9TFVlNcFgANe1PDlxGkedcxjXPX55q1un67tPfuDHr1aSkp7MQUP7kJKW7HWkFqfiRWqZQC9sY8WLyQKteC0i7cT8Vxfztwvur/0+tM1SF+88+yGOY5jw9G+9iLad7z79gTvGPMh3n/xQuy05LYmzrh3BqD+dgeO0nWGubedfIjsvpbE1ZhxIPScuj9mKiLQGT06chmngaTnrWuY+8z6rvlsT51TbW7FkFeOOuJHvP/uxzvbKsiqeuvlZHr72KY+SxYaKF6llAp0xGTds/e5nrzoQyMekXRLvWCIinli3YgPfLvoe60Z/fP295+fHMVX9nrr5Waorqxuc6PD5e16hYNm6OKeKHRUvUodJG43Jvg+Ce/3sFRfCP2I3XYqt+cqTbCIi8VReXNFoG8cxlBeXxyFNwyrKKnnvuY8IR1lawnEc5jz9XhxTxZaKF9mOSR4GqRfW/2LNYuzGkdiar+MbSkQkzjrldyCYGH1oaKgmTI+9usUpUf1KCkujFi4QKbI2tqF1xFS8yHasrYSSPzfwqgtUY0tui2ckEZG4S8tM5dhzD8cJNnCpNJCSkcwRv/R2iYuM3PRGH6d3XUuHbm1ngkMVL7K9yje3PDbdkDBUf4gNr45bJBERL1z4l3PJzcvZroBxHAeD4ZpHLyc51dtH2lPSkjnyrEENF1lEBhcfd94RcUwVWypeZHvh1UATnigKez/CXkQkljp0zeH++ZMYdv5RJCT/NCv0voP3YvIbf+JIj3tdtjpv4lkkpyY1uBDqL685hc49O8U5Vexohl3Zji2fji3+Q6PtTMdZmOBucUgkIuK9irJKNq4qJC0rlZwu2V7H2c4PXyznzose5JsF39VuS81M4Zzfn845409rdMVyr2l5ABUvO8W6m7HrDgNqGmhhINgbp+OL8YwlIiJN8MMXy1n+9SpS0pPpe9S+vpmpWcsDyE4xTjak/wZbel99r0b+b8Z1cc0kIiJNs+v+Pdn1Zyu5tzUa8yL1SxuLSb8a2Fqxb+ludHIx2Q9gkg73KpmIiLRz6nmRehljIP0ySP0VVM0FtwgCPSBpCMYkNL4DERGRGFHxIlEZJwNSRngdQ0REpJZuG4mIiIivqHgRERERX1HxIiIiIr6i4kVERER8RcWLiIiI+IqKFxEREfEVFS8iIiLiKypeRERExFdUvIiIiIivqHgRERERX1HxIiIiIr4Ss+KlsLCQUaNGkZmZSXZ2NmPGjKG0tDRq+yuvvJK9996blJQUevbsyVVXXUVRUVGsIoqIiIgPxax4GTVqFF9++SWzZ89m5syZvPvuu1xyySUNtl+9ejWrV69mypQpfPHFFzzxxBPMmjWLMWPGxCqiiLRx1VU1LPtyBcu/WUU4HPY6joi0EGOttS2906+//pp9992XhQsX0r9/fwBmzZrFiSeeyMqVK+nWrVuT9jN9+nR+9atfUVZWRjDYtAWwi4uLycrKoqioiMzMzB3+N4iIf1VX1fD0LdN5+cE3KN1cBkCHbjmcde0ITrvqBBxHd8xFWpvmXL9j8hs8b948srOzawsXgKFDh+I4DvPnz2/yfrb+A6IVLlVVVRQXF9f5EpH2K1QT4o8nT2LqbTNqCxeAjas38eC4J7jnsoeJwWc2EYmjmBQvBQUFdO7cuc62YDBIbm4uBQUFTdrHhg0buPXWW6PeagKYNGkSWVlZtV/5+fk7nFtE/O/Np9/jkzmfY936C5RXH5nDlx98E+dU/vXDF8u5+9J/MGqXyzgn/1L+eu7dfPXR/7yOJe1cs4qX8ePHY4yJ+vXNNzv/R6G4uJiTTjqJfffdl5tuuilq2wkTJlBUVFT7tWLFip0+voj418yHXsc4psHXA0GHmQ/PjtnxK8urWDzncxa89gkbVhfG7Djx8NbUD/jNQdcx659zWbdiAxtXFfLuc/P47eA/8PxdM72OJ+1Y0waSbHHNNddwwQUXRG2z2267kZeXx7p16+psD4VCFBYWkpeXF/X9JSUlDB8+nIyMDF544QUSEhKitk9KSiIpKalJ+UWk7Vv57ZoGe10AwiGXlUtWt/hxw+Ew/7p5Ov+55xUqSioBMI7hsNMGcNUDF5HTJbvFjxlLq5cWcNvoe3HDbp3t4VDk+4eueZK9B+zB/of19iKetHPNKl46depEp06dGm03aNAgNm/ezKJFi+jXrx8Ac+fOxXVdBg4c2OD7iouLGTZsGElJSbz00kskJyc3J56ICGmZqZRtLm/wdeMY0nPSW/y4d4x5kDf/9Q7bDqexruXDFxey9NNlPLBwMhkxOG6szHzoDaINDQoEHWbc96qKF/FETMa87LPPPgwfPpyLL76YBQsW8MEHHzB27FjOOeec2ieNVq1aRe/evVmwYAEQKVyOP/54ysrKeOyxxyguLqagoICCggI94igiTXbsqCE4gYb/tFnXcvQ5h7XoMZcs/I7ZT71T78XeDbus/XE9M+59rUWPGWufvfvVdr0u2wqHXP779ldxTCTyk5g9L/jvf/+b3r17c+yxx3LiiSdy+OGH8/DDD9e+XlNTw5IlSygvj3xCWrx4MfPnz+fzzz9njz32oGvXrrVfGsciIk01YuwJpGWl1lvAOEGHHnt15aizB7foMWc9PpdAsOE/p27Y5ZVHYjfOJiZMw+OGmtFEJCaadduoOXJzc3nmmWcafL1Xr151Hlc86qij9PiiiOy0Dl1zuOOtm5h4+u2s+X4tgWAAay1u2GXPg3blpv9cR1JKy46TW79iY+1YkIYUrtmEtRbjkyt+/+P68u2i7xvsfQkEHfod3zfOqUQiYla8iIh4Zdc+u/DE/+5l0Rv/5at5/yMQDHDw0D7sc+heMSkesjtnEQg6UQuYjNwM3xQuACdeMpRnp7yIdd0GbodZTr/qxPgHE0HFi4i0UY7jcMjwgzhk+EExP9bQ847g9SfeajhLwGHYBUfFPEdL6pzfkYnPX8fNZ9xOOOTW9sAEgg6uaxn3yGXs1W93j1NKe6XiRURkJ/U9aj/6H9+XxW9+hvuzx7SdgENGbjq/uPpkj9LtuIEnHswTS+7l5Ydms3DWJ7hhl75H7scplw+jZ+/uXseTdiwmaxt5SWsbiYgXKsuruO+KR3nz6XfrjBPZq//uTHj6Knrs1bQ13UTaq+Zcv1W8iIi0oI1rNrHojf8Sqg6xZ7/d2PPg3byOJOILzbl+67aRiEgL6tA1h+PPP8rrGCJtmtaFFxEREV9R8SIiIiK+ouJFREREfEXFi4iIiPiKihcRERHxFRUvIiIi4isqXkRERMRXVLyIiIiIr6h4EREREV/RDLsiIq1ERVkln73zFVXlVezapyf5e2vxQ5H6qHgREfGY67o8fctzTL/jJSrLqmq39zliH6559DK679HVw3QirY9uG4mIeOz+Kx/jX7dOr1O4AHz5wRKuGvQH1i1f71EykdZJxYuIiId+/HolLz/4BtjtX3PDLqVFZUydPCPuuURaMxUvIiIeevOpdwgEG/5T7IZc3njybcKhcBxTibRuKl5ERDy0cc0mbD29LtuqqqimvKQiPoFEfEDFi4iIh3K6ZGNM9DaJyQmkZqTEJ5CID6h4ERHx0NDzjiAccht8PRB0OO68IwkEA3FMJdK6qXgREfHQrvv3ZPiYY+rtfXECDikZKZwz4fT4BxNpxTTPi0gMWFsBFa9gq94EWwHBfTCpZ2OCu3odTVqh3z14CdkdM/nPPa9QXVlTu32vfrtx7T+vIK9XZw/TibQ+xtrGhor5S3FxMVlZWRQVFZGZmel1HGmHbOgHbOH54BYAhsgzsAHAxWTcgEk739uA0mqVFZWxeM4XVFdU02v/fHbv28vrSCJx05zrt3peRFqQtTXYwl+Du3VSsa2fDSKPudqSv0BwF0zSUV7Ek1YuLSuNIb8Y6HUMkVZPY15EWlLlbHBXsbVY2Z6DLX00nolERNoc9byIZ6xbBpUvY2s+AwKYpMMh6ViM8e+Ppa1+j8gtooaKFxdqFmBtNcYkxjGZiEjb4d+rhPiarfoQu3ks2FIiF3uDrZgGgR6Q8zgm2MvjhDvI1jTeBmi4uBERkcbotpHEnQ19j910CdiyLVvCQGjL/7sGWzga65Z7FW+nmIQDgIbn7AADgV5AcnwCiYi0QSpeJO5s2ZNECpb6HnQLR57SqZwZ51QtJOU0IoVJw1OmmrQLMI1NqSoiIg1S8SLxVzmL6LdNDLbyjXilaVHGycRk303kVti2M6Ju+VVLGg4pZ8c/mIhIG6IxL+KBykZet5GJ3ZohMincy9jK18CWQGAPTOo5mMQDdzjljjLJR0OHGdiyf0LVG2CrILg3Ju1XkDwCY/SZQURkZ6h4kfgL7gU1n9Pw2JAAJPRu8u5seBW28DwIr6R2UriaL7GV/8GmXoDJmBD32zQmYS9M9iRgUlyPKyKyrbLicua99DHFG0ro1LMjA086mMSkBK9j7TQVLxJ3JvU8bNG1UVqEMSnnNGlf1lrspkshvGbrltp9AFD+BAR3h1TdqhGR9sNay7O3v8S/bn6WqopqHMfgupaMnDTG3n8Rx4w83OuIO0XFi8Rf8slQOQeqZm3ZsLXgcAAXk34NJmHPpu2reh6E/helgcGWPQIpZ2mQrEiMrFuxgRfvn8VbU9+nsrSSnvv04JTLhnHUOYMJBLQatheevf0lHh3/dO33rhv5O1uyqYxJo+4hMTmBw0/372zOWttIPGFtGMqfwZY/CeHlkY0JB2LSLsIkH9/k/bglt0PZP6l91LoBptM7mEDXnUgsIvVZ8vFSrh96M5VlVbjhyK3grZ/yB484hD89O45ggj4nx1N5SQVndb2YqvKq+hsY6L5HV/75zT2t6kNdc67fGjkonjAmgEk7D9NxNqbzIkznT3E6PNuswgUAG21OlW3bRS9uRKT5QjUhbhxxW53CBX76lD/vpY957k6fTnvgYx/NXNRw4QJgYdW3a1j66bK4ZWppKl7EU8YYjJOBcVJ37P2JB9JYrwtOB1Cvi0iL+/DFhRSu2VSncNmWtZYX7n2VcFgzSsdT8YYSjNN4j0rRhuI4pIkNFS/ib0nHgNOZhn+UDSZ1tK/XSxJprb76cAmBhOhjWgrXbGLDysI4JRKALr06Yd3GR4R02aVTHNLEhooX8TVjEjA5D4FJpf5J4Y6CtIs8SCbS9jmBpl1CAkFdauLpkOEHktUps8GJvp2Awz6D9qLHXt3iG6wF6SdKfM8k7I/p+Aqk/RqcPDAZkNAHk/U3TPYDGOP/OQ1EWqODj+tLuCbKLSED3ffsSoduufELJQQTgvz27xcDbDcg1wk4BBICXHH3hV5EazEqXqRNMIGuOBnX4XR+F6fLIpwO0zEpp+l2kUgMHTy0Dz336d5wz4qFs64b0aqeaGkvhpxxKH9+aTw99+leZ/s+h+7JXe/eyt6H7OFRspahR6VFRGSHrfl+LdcecxPrVmzAYLDWEgg6hEMuZ/zuJC6943wVLx6y1rLsi+VsXl9M554d6b5H6314oTnXbxUvIiKyUyrKKpn77/d4Z/qHlBVV0Gu/fE669Dj2PXQvr6OJj6h4UfEiIj6y5oe1rFm6lrTsNPY8eFccR3f0pf1pzvVbAwJERDzy41creOCqx/lk7he127rs0okL/zySY0cN8TCZSOum4kVExAMrlqziqsF/oLKs7kyoa39cz+Tz7qW8uJxTLhvmUTqR1k19kyIiHnhswjPbTau/rYeueYqy4vI4pxLxBxUvIiJxVrShmA9fWthg4QJQXVXNO8/Oi2MqEf9Q8SIiEmcbVhU2On17IBhg3Y/r45RIxF9UvIiIxFlWx4xG27hhl8wmtBNpj1S8iIjEWcfuHegzZB+cKCv/GmM48qzBcUwl4h8qXkREPHDhn0diHFP/7LMGzvjdSXTomhP/YCI+oOJFRMQDfYbsw60vTyAnLxsAs6UXJpgYZOT407notl95mE6kddMMuyIiHgqHwyx64zNWf1dAWlYqh57Sj4ycdK9jicSdZtgVEfGJQCDAgBMO8jqGiK/otpGIiIj4iooXERER8RUVLyIiIuIrKl5ERETEV1S8iIiIiK+oeBERERFfUfEiIiIivhKz4qWwsJBRo0aRmZlJdnY2Y8aMobS0tEnvtdZywgknYIxhxowZsYooIiIiPhSz4mXUqFF8+eWXzJ49m5kzZ/Luu+9yySWXNOm9d999d/3rfYiIiEi7F5MZdr/++mtmzZrFwoUL6d+/PwD33XcfJ554IlOmTKFbt24NvvfTTz/ljjvu4OOPP6Zr166xiCciIiI+FpOel3nz5pGdnV1buAAMHToUx3GYP39+g+8rLy/n3HPP5YEHHiAvL69Jx6qqqqK4uLjOl4iIiLRdMSleCgoK6Ny5c51twWCQ3NxcCgoKGnzf1VdfzeDBgxkxYkSTjzVp0iSysrJqv/Lz83c4t4iIiLR+zSpexo8fjzEm6tc333yzQ0Feeukl5s6dy913392s902YMIGioqLarxUrVuzQ8UVERMQfmjXm5ZprruGCCy6I2ma33XYjLy+PdevW1dkeCoUoLCxs8HbQ3LlzWbp0KdnZ2XW2n3HGGQwZMoS333673vclJSWRlJTU1H+CiIiI+FyzipdOnTrRqVOnRtsNGjSIzZs3s2jRIvr16wdEihPXdRk4cGC97xk/fjwXXXRRnW19+vThrrvu4pRTTmlOTBEREWnDYvK00T777MPw4cO5+OKLeeihh6ipqWHs2LGcc845tU8arVq1imOPPZannnqKAQMGkJeXV2+vTM+ePdl1111jEVNERER8KCbFC8C///1vxo4dy7HHHovjOJxxxhnce++9ta/X1NSwZMkSysvLYxVBRASA9Ss38vm7X2Et7Dt4L7ru2sXrSCKyE4y11nodoiUVFxeTlZVFUVERmZmZXscREQ+VFZVx16X/4N3nPsK6W/7UGRh44sFc+/jlZHfK8jagiNRqzvVbaxuJSJtUU13D74//M+89P/+nwgXAwsLXP2XckROpKK3wLqCI7DAVLyLSJr33/HyWLPwON+xu95obclmxZBVvPPmOB8lEZGepeBGRNun1f87FcaKvkTbr8blxSiMiLUnFi4i0SRtWb8J1owzps7BxdWH8AolIi1HxIiJtUuf8jjiBhv/EGWPo2KNDHBOJSEtR8SIibdLwXx9T73iXrSyWEy8aGsdEItJSVLyISJt0+OkD6DNkn3p7X5yAw+4H7MJxo4/wIJmI7CwVLyLSJgWCAf7y6g0cf8FRBBMCtdudgMORvxzElLduJilF66KJ+JEmqRORNq9oQzFffrgELOw9YA86dM3xOpKI/Exzrt8xWx5ARKS1yOqYyeBTD/E6hoi0EN02EhEREV9R8SIiIiK+ouJFREREfEXFi4iIiPiKihcRERHxFRUvIiIi4isqXkRERMRXVLyIiIiIr6h4EREREV9pczPsbl3toLi42OMkIiIi0lRbr9tNWbWozRUvJSUlAOTn53ucRERERJqrpKSErKysqG3a3MKMruuyevVqMjIyMMZs93pxcTH5+fmsWLFCCze2Qjo/rZ/OUeunc9S66fzUz1pLSUkJ3bp1w3Gij2ppcz0vjuPQo0ePRttlZmbqh6YV0/lp/XSOWj+do9ZN52d7jfW4bKUBuyIiIuIrKl5ERETEV9pd8ZKUlMTEiRNJSkryOorUQ+en9dM5av10jlo3nZ+d1+YG7IqIiEjb1u56XkRERMTfVLyIiIiIr6h4EREREV9R8SIiIiK+0uaLl8LCQkaNGkVmZibZ2dmMGTOG0tLSJr3XWssJJ5yAMYYZM2bENmg71txzVFhYyJVXXsnee+9NSkoKPXv25KqrrqKoqCiOqdu2Bx54gF69epGcnMzAgQNZsGBB1PbTp0+nd+/eJCcn06dPH1599dU4JW2/mnOOHnnkEYYMGUJOTg45OTkMHTq00XMqO6e5v0NbTZ06FWMMp512WmwD+lybL15GjRrFl19+yezZs5k5cybvvvsul1xySZPee/fdd9e7xIC0rOaeo9WrV7N69WqmTJnCF198wRNPPMGsWbMYM2ZMHFO3XdOmTWPcuHFMnDiRxYsX07dvX4YNG8a6devqbf/hhx8ycuRIxowZwyeffMJpp53GaaedxhdffBHn5O1Hc8/R22+/zciRI3nrrbeYN28e+fn5HH/88axatSrOyduH5p6frZYtW8a1117LkCFD4pTUx2wb9tVXX1nALly4sHbba6+9Zo0xdtWqVVHf+8knn9ju3bvbNWvWWMC+8MILMU7bPu3MOdrWs88+axMTE21NTU0sYrYrAwYMsFdccUXt9+Fw2Hbr1s1OmjSp3vZnnXWWPemkk+psGzhwoL300ktjmrM9a+45+rlQKGQzMjLsk08+GauI7dqOnJ9QKGQHDx5sH330UXv++efbESNGxCGpf7Xpnpd58+aRnZ1N//79a7cNHToUx3GYP39+g+8rLy/n3HPP5YEHHiAvLy8eUdutHT1HP1dUVERmZibBYJtbriuuqqurWbRoEUOHDq3d5jgOQ4cOZd68efW+Z968eXXaAwwbNqzB9rJzduQc/Vx5eTk1NTXk5ubGKma7taPn55ZbbqFz587qQW6iNv2XvqCggM6dO9fZFgwGyc3NpaCgoMH3XX311QwePJgRI0bEOmK7t6PnaFsbNmzg1ltvbfLtQGnYhg0bCIfDdOnSpc72Ll268M0339T7noKCgnrbN/X8SfPsyDn6ud///vd069Ztu6JTdt6OnJ/333+fxx57jE8//TQOCdsGX/a8jB8/HmNM1K+m/hL/3EsvvcTcuXO5++67WzZ0OxPLc7St4uJiTjrpJPbdd19uuummnQ8u0sZNnjyZqVOn8sILL5CcnOx1nHavpKSE8847j0ceeYSOHTt6Hcc3fNnzcs0113DBBRdEbbPbbruRl5e33QCpUChEYWFhg7eD5s6dy9KlS8nOzq6z/YwzzmDIkCG8/fbbO5G8/YjlOdqqpKSE4cOHk5GRwQsvvEBCQsLOxm73OnbsSCAQYO3atXW2r127tsHzkZeX16z2snN25BxtNWXKFCZPnsybb77JAQccEMuY7VZzz8/SpUtZtmwZp5xySu0213WBSC/0kiVL2H333WMb2o+8HnQTS1sHg3788ce1215//fWog0HXrFljP//88zpfgL3nnnvs999/H6/o7caOnCNrrS0qKrKHHnqoPfLII21ZWVk8orYbAwYMsGPHjq39PhwO2+7du0cdsHvyySfX2TZo0CAN2I2h5p4ja6297bbbbGZmpp03b148IrZrzTk/FRUV211zRowYYY855hj7+eef26qqqnhG9402XbxYa+3w4cPtQQcdZOfPn2/ff/99u+eee9qRI0fWvr5y5Uq799572/nz5ze4D/S0UUw19xwVFRXZgQMH2j59+tjvvvvOrlmzpvYrFAp59c9oM6ZOnWqTkpLsE088Yb/66it7ySWX2OzsbFtQUGCttfa8886z48ePr23/wQcf2GAwaKdMmWK//vprO3HiRJuQkGA///xzr/4JbV5zz9HkyZNtYmKife655+r8vpSUlHj1T2jTmnt+fk5PGzWuzRcvGzdutCNHjrTp6ek2MzPTXnjhhXV+YX/44QcL2LfeeqvBfah4ia3mnqO33nrLAvV+/fDDD978I9qY++67z/bs2dMmJibaAQMG2I8++qj2tSOPPNKef/75ddo/++yzdq+99rKJiYl2v/32s6+88kqcE7c/zTlHu+yyS72/LxMnTox/8Haiub9D21Lx0jhjrbXxvlUlIiIisqN8+bSRiIiItF8qXkRERMRXVLyIiIiIr6h4EREREV9R8SIiIiK+ouJFREREfEXFi4iIiPiKihcRERHxFRUvIiIi4isqXkRERMRXVLyIiIiIr6h4EREREV/5fz7RneZICeTlAAAAAElFTkSuQmCC\n" + }, + "metadata": {} + } + ], + "source": [ + "raw_data = []\n", + "\n", + "for ts in [True, False]:\n", + " for __ in range(circuits):\n", + " raw_data.append(enhanced_circuit(ts))\n", + "\n", + "data = process_data(raw_data)\n", + "\n", + "kernel_pca = KernelPCA(\n", + " n_components=None, kernel=\"rbf\", gamma=None, fit_inverse_transform=True, alpha=0.1\n", + ")\n", + "scaler = preprocessing.StandardScaler().fit(data)\n", + "data = scaler.transform(data)\n", + "fit = kernel_pca.fit(data).transform(data)\n", + "\n", + "c = np.array([0 for __ in range(circuits)] + [1 for __ in range(circuits)])\n", + "plt.scatter(fit[:, 0], fit[:, 1], c=c)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dQHy4Y0ZpGse" + }, + "source": [ + "Nice! Even in the presence of noise we still have a clean separation of\n", + "the two classes. This shows that using entanglement can make a big\n", + "difference to learning.\n" + ] + }, + { + "cell_type": "code", + "source": [ + "seconds = time.time()\n", + "print(\"Time in seconds since end of run:\", seconds)\n", + "local_time = time.ctime(seconds)\n", + "print(local_time)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 0 + }, + "id": "znxK-ted5Yae", + "outputId": "5f0c4e7e-fbf6-45e0-bd30-45f36c32a8f9" + }, + "execution_count": 35, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Time in seconds since end of run: 1700504552.465268\n", + "Mon Nov 20 18:22:32 2023\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QNYu0GLrpGse" + }, + "source": [ + "References\n", + "==========\n", + "\n", + "\\[1\\] *Quantum advantage in learning from experiments*, Hsin-Yuan Huang\n", + "et. al., [arxiv:2112.00778](https://arxiv.org/pdf/2112.00778.pdf) (2021)\n", + "\n", + "\\[2\\] *Exponential separations between learning with and without quantum\n", + "memory*, Sitan Chen, Jordan Cotler, Hsin-Yuan Huang, Jerry Li,\n", + "[arxiv:2111.05881](https://arxiv.org/abs/2111.05881) (2021)\n", + "\n", + "About the author\n", + "================\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.17" + }, + "colab": { + "provenance": [], + "gpuType": "A100", + "machine_shape": "hm" + }, + "accelerator": "GPU" + }, + "nbformat": 4, + "nbformat_minor": 0 +}