{ "cells": [ { "cell_type": "markdown", "id": "5db7e8c6", "metadata": {}, "source": [ "# Using the parameters update functionality \n", "The simple execution examples have been covered so let's dive into other functionalities that CUNQA provides. In this note we treat how to **update parameters**. \n", "\n", "There are several quantum-classical algorithms that require many executions of the same circuit with changed parameter values, optimized with a classical algorithm. In order to optimize this, CUNQA users can upgrade the circuit parameters with no need to resend the circuit, i.e., **sending to the vQPUs ONLY the new parameters**. This reduces the total amout of data sent to the vQPUs. In this notebook, the same example is going to be implemented twice: first without using the parameter update functionality and, then, using it. This way both workflows can be easily compared. \n", "\n", "Let´s see how to work with this feature taking as an example a _Variational Quantum Algorithm_ for state preparation. To start, all the imports are done and the vQPUs are turned ON. After this, the `get_QPUs()` function is called to obtain the `QPU` instance related with the raised vQPU. Note that **only one vQPU is raised**. And this is because here the parallelization is not the pursued goal, but to see how the parameter update functionality works and change the execution. " ] }, { "cell_type": "code", "execution_count": 1, "id": "c532632a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requested QPUs with command:\n", "\tqraise -n 1 -t 00:20:00 --simulator=Aer --co-located\n", "QPUs ready to work ✅\n", "\n", "QPU properties: \n", "\t id: 376623_224855, backend: SimpleBackend, simulator: AerSimulator, version: 0.0.1.\n" ] } ], "source": [ "import os, sys\n", "import time\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "#from qiskit import QuantumCircuit\n", "#from qiskit.circuit import Parameter\n", "from scipy.stats import entropy, norm\n", "from scipy.optimize import minimize\n", "\n", "sys.path.append(os.getenv(\"HOME\"))\n", "\n", "from cunqa import get_QPUs, qraise, qdrop\n", "from cunqa.qpu import run\n", "from cunqa.circuit import CunqaCircuit\n", "from cunqa.circuit.parameter import Param\n", "\n", "family = qraise(1, \"00:20:00\", simulator = \"Aer\", co_located = True)\n", "[qpu] = get_QPUs(co_located = True, family = family)\n", "\n", "print(f\"\\nQPU properties: \\n\\t id: {qpu.id}, backend: {qpu.backend['name']}, simulator: {qpu.backend['simulator']}, version: {qpu.backend['version']}.\")" ] }, { "cell_type": "markdown", "id": "4faa81e1", "metadata": {}, "source": [ "Now, a **Hardware Efficient Ansatz** is employed to build the parametrized circuit. Even though a general function is defined, the ansatz employed in this case has 6 qubits and 3 layers." ] }, { "cell_type": "code", "execution_count": 2, "id": "b0a68703", "metadata": {}, "outputs": [], "source": [ "def hardware_efficient_ansatz(num_qubits, num_layers):\n", " qc = CunqaCircuit(num_qubits)\n", " for p_id in range(num_layers):\n", " for qubit in range(num_qubits):\n", " qc.ry(f\"phi_{p_id}_{qubit}\", qubit)\n", " qc.rz(f\"lam_{p_id}_{qubit}\", qubit)\n", " for qubit in range(num_qubits - 1):\n", " qc.cx(qubit, qubit + 1)\n", " qc.measure_all()\n", " return qc\n", "\n", "num_qubits = 6\n", "num_layers = 3\n", "ansatz = hardware_efficient_ansatz(num_qubits, num_layers)\n", "num_params = 2 * num_qubits * num_layers" ] }, { "cell_type": "markdown", "id": "6b9f1aa6", "metadata": {}, "source": [ "As usual in optimization jobs, a **cost function** must be defined. But, in this case, the goal is to measure how far the solution is from a target distribution. So, before defining the cost function, the target distribution and the measure of distribution divergence must be defined.\n", "\n", "In the case of the target distribution, the chosen one corresponds to a **normal distribution** among all the $2^n$ possible outcomes of the circuit. In case of the measure, the **Kullback-Leibler divergence** is employed." ] }, { "cell_type": "code", "execution_count": 3, "id": "4e4b9c38", "metadata": {}, "outputs": [], "source": [ "def target_distribution(num_qubits):\n", " # Define a normal distribution over the states\n", " num_states = 2 ** num_qubits\n", " states = np.arange(num_states)\n", " mean = num_states / 2\n", " std_dev = num_states / 4\n", " target_probs = norm.pdf(states, mean, std_dev)\n", " target_probs /= target_probs.sum() # Normalize to make it a valid probability distribution\n", " target_dist = {format(i, f'0{num_qubits}b'): target_probs[i] for i in range(num_states)}\n", " return target_dist\n", "\n", "def KL_divergence(counts, n_shots, target_dist):\n", " # Convert counts to probabilities\n", " pdf = pd.DataFrame.from_dict(counts, orient=\"index\").reset_index()\n", " pdf.rename(columns={\"index\": \"state\", 0: \"counts\"}, inplace=True)\n", " pdf[\"probability\"] = pdf[\"counts\"] / n_shots\n", " \n", " # Create a dictionary for the obtained distribution\n", " obtained_dist = pdf.set_index(\"state\")[\"probability\"].to_dict()\n", " \n", " # Ensure all states are present in the obtained distribution\n", " for state in target_dist:\n", " if state not in obtained_dist:\n", " obtained_dist[state] = 0.0\n", " \n", " # Convert distributions to lists for KL divergence calculation\n", " target_probs = [target_dist[state] for state in sorted(target_dist)]\n", " obtained_probs = [obtained_dist[state] for state in sorted(obtained_dist)]\n", " \n", " # Calculate KL divergence\n", " kl_divergence = entropy(obtained_probs, target_probs)\n", " \n", " return kl_divergence" ] }, { "cell_type": "markdown", "id": "1a31cc06-ca50-4936-9947-121470512e7c", "metadata": {}, "source": [ "Finally, because both cases (the one that does not use the feature and the one which does) need a equivalent callback function, we implement a **callback function factory**. This is done to ensure readability of the code." ] }, { "cell_type": "code", "execution_count": 4, "id": "052a5b83", "metadata": { "scrolled": true }, "outputs": [], "source": [ "def make_callback(cost_function):\n", " i = 0\n", " cost = []\n", " individuals = []\n", "\n", " def callback(xk):\n", " nonlocal i\n", "\n", " e = cost_function(xk)\n", " individuals.append(xk)\n", " cost.append(e)\n", "\n", " i += 1\n", "\n", " return callback, cost" ] }, { "cell_type": "markdown", "id": "d23f13db", "metadata": {}, "source": [ "## No parameter update feature" ] }, { "cell_type": "markdown", "id": "fa26a3eb", "metadata": {}, "source": [ "First, as the base case the normal execution method will be employed, i.e., upgrading the parameters and sending the whole circuit to the QPU. For this purpose, the **cost function** defined is the following:" ] }, { "cell_type": "code", "execution_count": 5, "id": "5398907b", "metadata": {}, "outputs": [], "source": [ "def cost_function_run(params):\n", " target_dist = target_distribution(num_qubits)\n", " \n", " result = run(ansatz, qpu, params.tolist(), shots = 1e5).result\n", " counts = result.counts\n", " \n", " return KL_divergence(counts, 1e5, target_dist)" ] }, { "cell_type": "markdown", "id": "d3ec8a31", "metadata": {}, "source": [ "This cost function updates the parameters given by the optimizer, asigns them to the ansatz and sends the circuit to the vQPU. Now everything is in place to perform the optimization:" ] }, { "cell_type": "code", "execution_count": 6, "id": "1700fa65-433a-42d1-8eb2-1e87b053d3d2", "metadata": {}, "outputs": [], "source": [ "callback_run, cost_run = make_callback(cost_function_run)\n", "\n", "optimization_result_run = minimize(fun = cost_function_run, \n", " x0 = [0.0 for _ in range(num_params)], \n", " method = 'COBYLA',\n", " callback = callback_run, \n", " tol = 0.01,\n", " options = {'maxiter': 4000}\n", " )" ] }, { "cell_type": "code", "execution_count": 8, "id": "bcc4cf95", "metadata": {}, "outputs": [ { "data": { "image/png": "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ohugq//vUXhjos+qaf1Bgwa5+po9e3a9tz1SqI7B0RzqqTo2DmCBS8ZkY86f99k5tx14DTg1kccTEZGDEtYHb2YtgJBzLs9/fgEwMVHHE2kMJSUlbN68maKiosPaT5s2bVixYkUDRdU0qY4NKyMjg27dupGamlrrbRJ5kTUbeM3Myo/z/5xz7yTweCIJt3nzZlq1akVOTg7+e7te8vLyaNWqVQNG1vSojg3HOceuXbvYvHkzPXr0qPV2CUvwzrn1wCHn4RY5khQVFR12chepKzOjQ4cO7Nixo07baaoCkTpScpdkqM/7LhAJ/smZa1i6M5LsMEREmpRAJPjH31/NtJUHkh2GSKPYvHkzl19+OT179uT444/nzjvvpLi4uMZt9uzZw9NPPx19vXXrVsaOHVun4/7sZz9jxowZdY739ddfZ/ny5Ye9n4bwq1/9Kvp8w4YN9O1bu3upPPHEE0yePLlBYxk7dizr168H4LzzzuPbb71bDxQXF3PWWWdRWlp62McIRIK/NLczZZozTZoB5xxjxoxh9OjRrFmzhtWrV5Ofn88DDzxQ43YVE3yXLl145ZVX6nTsiRMnct5559U55ooJvr77aQixCb62SktLmTRpEt/73veqLKuPZcuWEYlEOO44726S119/ffT8pKWlce655/Lyyy/Xa9+xApHgzaq5D5lIwMyaNYuMjAxuuukmAMLhML/73e+YNGkSBQUFvPjii1x++eWMGDGCnj178vDDDwNw3333sW7dOgYMGMCECRPiWq8vvvgio0eP5vzzzycnJ4ennnqKxx9/nIEDBzJ06FB2794NwPjx43nllVdYsGABAwYMYMCAAeTm5kb7hp9//nmGDBlC//79ufLKKykoKGDu3Lm88cYbTJgwgQEDBrBu3brofgBmzpzJwIEDyc3N5eabb+bAAe+beE5ODg899BCnnHIKubm5rFy5stLforq6AowePZpBgwbRp08fnnvuuejfoLCwkAEDBnDttd6NrSKRCLfccgt9+vThggsuoLCwsNJxZs2axSmnnEJKijcmZcSIEdx1110MHjyYZ555Jq4+QPSXreXTGIwdO5YTTzyRa6+9tvwHoEyZMoXLL788us2oUaOYOnVqXPxTpkypzVuiRk1qLpr6CpmhWY+lsT38f8tYvnVfvbaNRCKEw+FKy0/u0pqHvlP97WiXLVvGoEGD4pa1bt2aY445hrVrvfuNzJ8/n6VLl5KVlcWQIUO49NJLeeSRR1i6dClLliwBvO6JWEuXLmXx4sUUFRVxwgkn8Oijj7J48WLuvvtuJk+ezF133RVdd/DgwdH9TJgwgYsuugiAMWPGcMst3t36HnzwQSZPnsyECRMYNWoUl112WaUuoaKiIsaPH8/MmTPp1asXN9xwA88880z0WB07dmTRokU8/fTT/Pa3v+VPf/pTpb9HVXUdPHgwkyZNon379hQWFjJkyBCuvPJKHnnkEZ566qm4v8GaNWuYOnUqzz//PFdffTWvvvoq1113XdwxPvroo0p/8+LiYhYsWEBeXh633357tedr8eLFLFu2jC5dujB8+HA++ugjzjjjDD766CPGjRsXXa9du3YcOHCAXbt20aFDB/r27cunn35a7X5rKxAt+JDpVu0i5c4//3w6dOhAZmYmY8aM4cMPPzzkNiNHjqRVq1Z06tSJNm3a8J3vfAeA3NzcSh8G5V5++WUWLVrEI488AngfEmeeeSa5ublMmTKlylZ3rFWrVtGjRw969eoFwI033sgHH3wQLR8zZgwAgwYNqjaG6ur65JNP0r9/f4YOHcqmTZtYs2ZNldv36NGDAQMG1Hicbdu20alT/GSN11xzTY11K3fqqafSrVs3QqEQAwYMiO6/qn0eddRRbN3q3T44HA6TlpZGXl5erY5THbXgReqpppb2odT3BzInn3xypb7zffv28dVXX3HCCSewaNGiSsPpajO8Lj09Pfo8FApFX4dCoSr7mZcuXcrPf/5zPvjgg+g3kfHjx/P666/Tv39/XnzxRd5///0616+qmMLhcLV93VXVdc6cOcyYMYN58+aRlZXFiBEjqv3lcWy9w+FwlV00mZmZlbaPnSI4JSWFsjKvk7isrCzugnfF/ZfXo6p9FhUVkZmZGX194MABMjIyqoy7tgLRgjczXWSVZuHcc8+loKAgOqIjEolwzz33MH78eLKysgB4//332b17N4WFhbz++usMHz6cVq1aHXZrsNyePXsYN24ckydPjmuF5uXl0blzZ0pKSuL6j6s7du/evdmwYUO0a+mll17i7LPPrlMsVdV17969tGvXjqysLFauXMnHH38cXT81NZWSkrrdA/6kk06KxliVnJwcFi5cCMAbb7xRq/1X3Kdzjq+//pry+2Hs2rWLjh071mlagqoEIsGri0aaCzPjtddeY/r06fTs2ZNevXqRkZERNzrk1FNP5corr6Rfv35ceeWVDB48mA4dOjB8+HD69u3LhAkTDiuGv/3tb2zcuJFbbrklerEV4Be/+AWnnXYaw4cP58QTT4yu/93vfpfHHnuMgQMHsm7duujyjIwMXnjhBa666ipyc3MJhULcdtttdYqlqrpedNFFlJaWctJJJ3HfffcxdOjQ6Pq33nor/fr1i15krY2LL744ruuooltuuYV//OMf9O/fn3nz5tXqBiCXXnopc+bMib5euHAhQ4cOjV7InT17NpdeemmtY6xWddNMJuNR3+mC753+mRvws7fqte2RpClMTZpoTb2Oy5cvb5D97Nu3r0H2U9ELL7zgfvSjHyVk33WVqDqWa8y6jh492q1evbrS8vrWsaCgwJ122mmutLTUOefcHXfc4WbMmBEtv+KKK9yqVasqbVfV+49kTRfcWEIhteBFJHEeeeQRtm3b1mD7y8zM5OGHH2bLli0A9O3bl3PPPRfwRuiMHj06evH5cATiIqv64EU848ePZ/z48ckOo1E0Zl179+5N7969G3SfF154YfR5+fBS8H7odMMNNzTIMYLRgjdwasOLiMQJSILXMEkRkYqCk+CTHYSISBMTiARvhvrgRUQqCESCVxeNNAe7du2Kjjs/+uij6dq1a/T1oaYLrquKs082tCVLlvD2228nbP/iCUiC1zBJCb4OHTqwZMkSlixZwm233cbdd98dfZ2WllbtdvWZ0lYJPhgCkuDVgpfmqaopesEbQnjbbbdx2mmnce+997Ju3TqGDh1Kbm4uDz74YHRKW4DHHnuMIUOG0K9fPx566CGg8vTCFU2ePJl+/frRv39/rr/+esCbnfGcc86hX79+nHvuuWzatAmA6dOn07dvX/r3789ZZ51FcXExP/vZz3j55ZcZMGBAg8x7LlULzjj4ZAchzdMLVfycvM9oOPUWKC6AKVdVLh/wPThhFOzfBf9bYbzzTW/V6fAVp+j985//HJ2+dvPmzcydO5dwOMxll13GnXfeybhx43j22Wej27/33nusWbOG+fPn45xj1KhRfPDBB5WmF461bNkyfvnLXzJ37lw6duwYnS/+9ttv58Ybb+TGG29k0qRJ3Hvvvbz55ptMnDiRd999l65du7Jnzx7S0tKYOHEiCxYs4KmnnqpTfaVuAtKCRy14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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "plt.clf()\n", "plt.plot(np.linspace(0, optimization_result_run.nfev, optimization_result_run.nfev), cost_run, label=\"Optimization path (run())\")\n", "upper_bound = optimization_result_run.nfev\n", "plt.plot(np.linspace(0, upper_bound, upper_bound), np.zeros(upper_bound), \"--\", label=\"Target cost\")\n", "plt.xlabel(\"Step\"); plt.ylabel(\"Cost\")\n", "plt.legend(loc=\"upper right\"); plt.title(f\"n = {num_qubits}, l = {num_layers}, # params = {num_params}\")\n", "plt.grid(True)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "bdbc16b7", "metadata": {}, "source": [ "## Using the parameters update feature" ] }, { "cell_type": "markdown", "id": "9113393a", "metadata": {}, "source": [ "The first step now is to create the `qjob.QJob` object by calling the `run` function. This step, that was not necessary in the previous case, is needed now because the circuit needs to be sent before the optimization begins to have it stored in the vQPU." ] }, { "cell_type": "code", "execution_count": 9, "id": "d44dbc23", "metadata": {}, "outputs": [], "source": [ "qjob = run(ansatz, qpu, [0.0] * num_params, shots = 1e5)" ] }, { "cell_type": "markdown", "id": "ada125fd", "metadata": {}, "source": [ "After doing this, the optimization with the parameters update feature can be performed. A cost function must be defined, just as in the previous case. The difference lies in its content, as now, instead of calling the `run` method, the `QJob.upgrade_parameters()` method is called. This method works because the vQPUs automatically detect that the circuit sent is parametrized and store them in case new parameters may come.\n", "\n", "**Important considerations:**\n", "- The method acepts parameters in a `list`, if you have a `numpy.array`, simply apply `.tolist()` to transform it.\n", "- The `qjob.QJob.upgrade_parameters()` is a non-blocking call, as it was `qpu.QPU.run()`." ] }, { "cell_type": "code", "execution_count": 10, "id": "8c416b9b", "metadata": {}, "outputs": [], "source": [ "def cost_function_update(params):\n", " target_dist = target_distribution(num_qubits)\n", " \n", " qjob.upgrade_parameters(params.tolist())\n", " counts = qjob.result.counts\n", " \n", " return KL_divergence(counts, 1e5, target_dist)" ] }, { "cell_type": "markdown", "id": "a4f3a056", "metadata": {}, "source": [ "Now we are ready to start our optimization. We will use `scipy.optimize` to minimize the divergence of our result distribution from the target one:" ] }, { "cell_type": "code", "execution_count": 11, "id": "3f9016ca", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[33m\twarning: [qjob.py] You have not obtained the previous results. They will be discarded.\n", "\u001b[0m\n" ] } ], "source": [ "callback_update, cost_update = make_callback(cost_function_update)\n", "\n", "optimization_result_update = minimize(cost_function_update, \n", " x0 = [0.0 for _ in range(num_params)], \n", " method = 'COBYLA',\n", " callback = callback_update, \n", " tol = 0.01,\n", " options={'maxiter': 4000}\n", " )" ] }, { "cell_type": "code", "execution_count": 12, "id": "0f269cf9", "metadata": {}, "outputs": [ { "data": { "image/png": "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KzwMHDiQ559/nsTERI4ePUpiYiK7d++usDwTJ07k3XffJTY2lrPPPpuEhAQmTJjAwIED6dGjBz/88AMjR47kggsu4JlnniE/P5/mzZszc+ZMYmNjSU1NZeTIkezfv59+/foVfzMegPfee49XX33Vew7feOMN3G53mb8/DRs2ZOzYsSxcuJBWrVoxe/ZsWrRoUea1i4qKYsyYMURERJCUlET//v255ZZbuPfee8nNzSUyMpJp06bRsWNH7+9Qeno6P/30U7m/Q6+++ipvvfUWISEhXHjhhcyePZvt27cTHh5OTEwMAFFRUcTFxbF69Wouuugizj33XFJTUzl06BCtWrWq9N9SWRzRRYMIog9rd6TNmzeTkJDgt65Ro0acc8457NxpPUBp9erVzJ07l40bNzJnzhzWrl3LpEmTOO+880hOTua5554rddyUlBTmzZvHmjVreOyxx4iKiiIpKYl+/fqV6ppITEwkOTmZ5ORkrr76aiZMmADAjTfeyJo1a9iwYQOdO3fmnXfe4eKLL+b666/nueeeIzk5mfPOO897nNzcXMaMGcMHH3zAypUrKSws5M033/Smx8TEsH79ev7f//t/PP/882Wej7LqCjB16lTWrVvH2rVrefXVV0lNTWXSpElERkaSnJzMzJkzAdixYwfjx49n8+bNNGnShLlz55bKY9myZaXOeXnKKs+aNWuYO3cuy5cv58svvyw1gWB+fj5r167lwQcfZMCAAaxcuZKkpCRuueUW/vnPfwLw1FNPMWDAADZv3swNN9zAL7/8AsDWrVv54IMPWLZsGcnJybjdbm/dypKVlUViYiKbN2/msssu46mnngLKvnbF9u3bx/Lly3nxxRfp1KkT33//PUlJSTz99NM8+uij3u1SUlJ47733KvwdmjRpEklJSWzcuJG33nrLe3579erlV87ExES+//5773KvXr1Ytuz0H2fsjBa8uHBpgA+4ilrawTR48GCaN28OWH+4P/zwA8OGDatwn0GDBhEdHU10dDSNGzfmt7/9LQDx8fFs3LixzH0++OAD1q9fz8KFCwHrD/zxxx/nxIkTZGZmctVVV1WY57Zt22jXrh0XXHABGRkZjB49mtdff5377rvPW3aAhIQE5s0r+9ncZdU1MTGRV199lfnz5wOwd+9eduzY4d3OV7t27ejRo4c3n927d5fa5uDBg3Tu3LnCulRUHoChQ4cSERFBdHS099wWu/nmm73v9+3bx80338zBgwfJz8/3foln6dKl3nNw3XXX0bRpUwC+/fZb1q1bR+/evQHIycmhZcuW5ZbP5XJ58xs1apT3HFd07UaMGOH9RJCWlsbo0aPZsWMHIkJBwcnHC1fmd6hbt27ceuutDBs2zPs7efDgQVq08J/dt2XLlvz4449+ywcOHOB0OaMFjwvRLhpHuvDCC1m3zn8IbHp6Or/88gsdOnQASo8Prsx44fDwcO97l8vlXXa5XBQWFpbaPiUlhSeffJLZs2d7//jHjBnD5MmT2bRpE0888cRpT+dQXAa3211mGaDsui5ZsoRvvvmGFStWsGHDBnr27FluWXzrXV4+kZGRfvuHhITg8Vh/XyWPW51z7zt/+t13381dd93Fpk2b+Ne//nXKc2iMYfTo0d5PVNu2bePJJ588ZZ4ly1fRtfMt31//+lcGDRpESkoKn376qd92lfkd+vzzzxk/fjzr16+nd+/eFBYWljq/gLcLqLzl6nJEgDfi0i4ah7r88svJzs72fuQtKiriwQcfZMyYMURFRQHw9ddfc+zYMXJycliwYAH9+/cnOjqajIyMGinDiRMnGDlyJO+++65fyysjI4PWrVtTUFDg101QXt4dO3Zk9+7d3q6lGTNmcNlll1WpLGXVNS0tjaZNmxIVFcWPP/7IypUrvduHhob6tToro3Pnzt4ygjWCpfif7EcffXTK8vTv398bDDMzM/nss8/KzSstLY02bdoA8J///Me7/tJLL+X9998H4Msvv+T48eOA9fvw0UcfcfjwYQCOHTvGnj3lToeOx+Pxlvn9999nwIABQPnXrqLyTZ8+vdztyst77969DBo0iH/84x+kpaWRmZlZ6vwCbN++3W+EU8nl6nJEgEcElz5b1pFEhPnz5zNnzhzOP/98LrjgAiIiIvyG/1100UXcdNNNdOvWjZtuuonExESaN29O//796dq1Kw899NBpleHjjz9mz549jB07lh49eni7OCZOnEifPn3o37+/3w3RW265heeee46ePXuya9cu7/qIiAimTZvGiBEj6Nu3Ly6XizvvvLNKZSmrrldffTWFhYV07tyZhx9+mL59+3q3HzdunLeboLKuueYali5d6l2eMGECb775Jj179iw1VLGs8vTu3Zvrr7+efv36cc011xAfH0/jxo3LzOvJJ59kxIgRJCQkeG86AjzxxBMsXbqULl26MG/ePM455xzA+kT3zDPPcOWVV9KtWzcGDx7MwYMHy61LgwYNWL16NV27dmXRokX87W9/A8q/diX95S9/4ZFHHqFnz57lfqoqT1FREaNGjSI+Pp6ePXtyzz330KRJEy699FKSkpL8bhwvW7aMwYMHA9YEfzt37iQxsQaecFre8JpgvKo7THLVK7eaX/92TrX2PZPUx2GSpzJt2jQzfvz4AJUmcKozvK426zps2DCzffv2apcnIyPDpKenm6ysLJOQkGDWrVsXiGKeku8w0UCo7jDJe+65x3z99dfGGGPWr19vRo0a5U2bN2+eefzxx8vcr6rDJB3RgtebrErVrEmTJlXYMj6VcePG0b9/f3r16sVNN91UatRIfffoo4+SnZ0NwNGjR5k4caI3rbCwkAcffLBG8gnoI/uqKjEx0VTnmayrXhtNh6OLaP7U3gCUqu4IxvMft27dWukRFTWhPkwxC/WjnrVZxz59+pCXl+e3bsaMGcTHxwc039q+jmX9PYpIuY/sc8QwSUS/6KRUfbZq1apgF6FOckQXDdpFo5RSpTgiwOswSaWUKs0RAV5b8EopVZozAjyi32R1MJ0uuPrq0nTBw4cP56effgLgiiuu8H55KT8/n0svvbTK48zVqTkjwGsL3rGMMdx4440MGzaMHTt2sH37djIzM3nssccq3K9kgD/rrLNKfQvzVJ5++mmuuOKKKpe5ZICv7nFqgm+Ar6zCwkKmTp3K7373uzLTqmPz5s0UFRXRvn17AG677Tbv9QkLC+Pyyy/ngw8+qNaxVfkcEeCNuDXAO1R50wVPnTqV7Oxspk+fztChQxk4cCDnn3++d7ZA3+mCH3roIb/W6/Tp0xk2bBiDBw8mLi6OyZMn8+KLL9KzZ0/69u3LsWPHAGu+ko8++oi1a9d6v8EaHx/vnc/k7bffpnfv3nTv3p2bbrqJ7Oxsli9fzieffMJDDz1Ejx492LVrl/c4YE2WVZzPHXfc4R3aFxcXxxNPPEGvXr2Ij4/3m3iqWHl1BWu64ISEBLp06cKUKVO856B4uuDib7IWTxfcpUsXrrzySnJycso85yWnC77vvvtITEzklVde8asPWFPywslhvMOHD6dTp0784Q9/8H5bc+bMmQwdOtS7z/XXX8+sWbP8yl/RlAGqehwyTFK7aGrFlw/DoU01e8xW8XDNpHKTKztdcEpKClFRUfTu3ZvrrruOSZMmkZKSQnJyMkCpWRNTUlJISkoiNzeXDh068I9//IOkpCTuv/9+3n33Xe8Mj3ByumCAhx56iKuvvhqwZk8cO3YsAI8//jjvvPMOd999N9dff713/ndfxdMFf/vtt7Ru3Zrx48fz5ptvevMqni74jTfe4Pnnn+ff//53qfNRVl0TExOZOnUqzZo1Iycnh969e3PTTTcxadIkJk+e7HcOduzYwaxZs3j77bf5n//5H+bOncuoUaP88ihruuDiKX7B+sdXnqSkJDZv3sxZZ51F3759WbZsGQMGDGDZsmWMHDnSu13Tpk3Jy8sjNTWV5s2b07VrV9asWVPucVX1OKIFr1009VvxlLWRkZF+U9ZWpHiq1xYtWpSa6rWsKXTh5HTBkyZZ/5BSUlK45JJLiI+PZ+bMmWzevLnCPH2nCwYYPXq035wvvtMFl1eG8ur66quv0r17d/r27eudLrgslZ0uuOR0tr5T/Fbkoosuom3btrhcLrp16+Y9fnlT5BZPiet2uwkLC6uxCeKUxREteNEAXzsqaGkHyoUXXliq79x3uuD169fX6nTBS5cu9ZsueMGCBXTv3p3p06ezZMmSqlavzDKdznTBUVFRDBw4sNLTBZfVRVPWdLa+U+j6Th/s8Xj8bniXPK/F9ajMFLl5eXlERESUWW5VPY5owRtx4RKD8Wg3jdPodMH+gjFdcEm+0wd/8sknlTp+yWMaYzh06BBxcXEApKamEhMTQ2hoaJXKqirmiACPWNWoS/PqqJqh0wX7C8Z0wSWNHTuW7777ju7du7NixQq/1n15rrvuOr9POOvWraNv377eG7mLFy/muuuuq3QZVSWVN81kMF7VnS54+dS/GPNEI1OQn1et/c8UOl1waTpdcGBUZrrgU/GtY3Z2tunTp48pLCw0xljT5X7zzTfe9BtuuMFs27bttPILhupOF1xd9XK6YBGrT9SjXTRK1YjTnS64pMjISJ566in2798PQNeuXbn88ssBa4TOsGHDvDefVc1xxE1WY9948niKglwSVdvGjBlT4bA9J6nNunbs2JGOHTvW6DF9H2xdPLwUrC86/f73v6/RvJTFIS14uw9eW/BKKeXliACPy6qGtuCVUuokZwR4KQ7w2oJXSqliAQ/wIuIWkSQR+SxwmWiAV0qpkmqjBX8vsDWgOdgBHu2icZzU1FTv2PNWrVrRpk0b7/KppgyuqpIzUNa05ORkvvjii4AdX6mSAhrgRaQtcB1QetakGs1HW/BO1bx5c5KTk0lOTubOO+/k/vvv9y6HhYWVu191prXVAK+cJtDDJF8G/gKU+9hxERkHjAOIjY2t1nweGUeOArBq1UoiGjatRjHPDJmZmac930lVNW7cuFYngCoqKio3v7y8PEJDQ3nttdeYNm0aBQUFtG/fnilTphAVFcWdd95JREQEGzZsoG/fvowdO5Y//vGPZGdnc+211/Lmm296x3a/8sorzJs3j/z8fIYMGcJjjz3Ggw8+yK5du+jWrRuDBg3imWee8cv//fff57XXXkNE6NKlC2+//TZ79uxh/Pjx3q/av/HGG5x99tnMnz+fSZMm4Xa7adSoEZ988gl//etfycnJYenSpdx3332MGDEi4OczmCq6lk5R23XMzc2tUgwIWIAXkSHAYWPMOhEZWN52xpgpwBSAxMREM3BguZuWa9XhNZAKiYkJxLQ6p3oFPgMUz7ddm7Zu3Up09Mn/z7d/dXupba6Ku4pbOt1CTmEOf/7mz6XSh3YYyrAOwziee5wHljzglzbt6ml+yxkZGX75+QoPDyc8PJzf/e533H333YA1Te+HH37I3XffTWhoKL/++iurVq3C7XYzZMgQHnjgAUaOHMlbb70FWPPELFy4kF9++YV169ZhjOH6668nKSmJF154gW3btrFx48ZSeW/evJkXXniB5cuXExMTw7Fjx4iOjuaRRx7hjjvuYPTo0UydOpVHH32UBQsW8Nxzz/H111/Tpk0bTpw4QZMmTZg4cSJr165l8uTJFdbTKbSONS8iIoKePXtWevtAdtH0B64Xkd3AbOA3IvJeQHLScfD1SkXT9I4YMcI72+OKFSu8rWTfpxMtXLiQhQsX0rNnT3r16sWPP/5Y7vS6xRYtWsSIESOIiYkBoFmzZt48io992223eafv7d+/P2PGjOHtt9+mqEjvDangCFgL3hjzCPAIgN2Cn2CMGVXRPtUl9jj43Ky0QBxe+SjZ4vYVGRJZYXrTiKYVpldWRdP0VmbiK2MMjzzyCH/605/81pc3B3t1vPXWW6xatYrPP/+chIQE7+yLStUmR4yDd4VZ08YeWP9VkEuiakN50/SW1LdvX+bOnQvA7Nmzveuvuuoqpk6dSmZmJgD79+/n8OHDFU4x/Jvf/IY5c+aQmpoK4H2s38UXX+w99syZM7nkkksA2LVrF3369OHpp5+mRYsW7N27t0anMFaqMmolwBtjlhhjhgTq+HG9rw3UoVUdVN40vSW9/PLLvPjii3Tr1o2dO3fSuHFjAK688kp+97vf0a9fP+Lj4xk+fDgZGRkVTjHcpUsXHnvsMS677DK6d+/OAw9Y9xKKb/h269aNGTNm8MorrwDWo/3i4+Pp2rUrF198Md27d2fQoEFs2bKFHj16eP/xKBVIYurQHOqJiYmm+LmPVXH8yEGavt6JlR3/l74jHw1AyeqGYN1k7dy5c63lV5M3rbKzs4mMjEREmD17NrNmzeLjjz+ukWOfLr0B6Qy1Xcey/h5FZJ0xJrGs7R0xm6TLbVfD6E1WddK6deu46667MMbQpEkTpk6dGuwiKVWrHBHgi2+yYnS0gjrpkksuYcOGDcEuhlJB44ibrMXD4nSqgsCoS914StVX1fk7dEiAtz6IGA3wNS4iIoLU1FQN8koFkTGG1NRUIiIiqrSfI7poivvgRYNQjWvbti379u3jyJEjtZJfbm5ulX+Jz0T1oZ5ax5oVERFB27Ztq7SPMwK83QdvtA++xoWGhtKuXbtay2/JkiVV+ir2mao+1FPrGHyO6qLRPnillDrJEQFeXC48RnQUjVJK+XBEgAcowqXj4JVSyodjArxBQGeTVEopL8cE+CJciHbRKKWUl2MCvAeX9sErpZQPBwV40T54pZTy4aAA70J0mKRSSnk5JsAXaReNUkr5cUyA9+ACdKoCpZQq5qAAL9pFo5RSPpwT4EW/6KSUUr6cE+B1HLxSSvlxWIDXFrxSShVzTIA3OheNUkr5cUyA16kKlFLKn2MCvAfRLhqllPLhmABvcBGTsyvYxVBKqTrDEY/sA2hs0onxpAW7GEopVWc4pgWf3KB/sIuglFJ1imMCfKE7MthFUEqpOsUxAd6I2/qpT3VSSinASQEeAaCoqDDIJVFKqbrBMQEesari0Ra8UkoBDgrwxS14j7bglVIKCGCAF5EIEVktIhtEZLOIPBWovKwMi1vw+m1WpZSCwI6DzwN+Y4zJFJFQ4AcR+dIYszIQmRk7wBcVaYBXSikIYIA3xhgg014MtV8BfOSS9sErpZSvgPbBi4hbRJKBw8DXxphVAczM+qldNEopBQR4qgJjTBHQQ0SaAPNFpKsxJsV3GxEZB4wDiI2NZcmSJdXKq6DIarmvWLmCiAZNql/oOiwzM7Pa5+dMUR/qCPWjnlrH4KuVuWiMMSdEZDFwNZBSIm0KMAUgMTHRDBw4sFp5fJryGQCJCQnEtDr7dIpbZy1ZsoTqnp8zRX2oI9SPemodgy+Qo2ha2C13RCQSGAz8GKj8sIdJGu2iUUopILAt+NbAf0TEjfWP5ENjzGeByszoMEmllPITyFE0G4GegTp+KaJfdFJKKV+O+SYr3snGAjgSUymlziCOCfA6VYFSSvlzTID3tuD1wdtKKQU4KsAXt+A1wCulFDgqwFtVMUanKlBKKXBSgNdx8Eop5cc5Ab54HLx20SilFOCkAO/SLhqllPLlnACP3mRVSilfzgnwxTdZtQ9eKaUARwV4vcmqlFK+KhXgRWRGZdYFlfeLTtoHr5RSUPkWfBffBXuGyISaL85p0FE0Sinlp8IALyKPiEgG0E1E0u1XBtYj+D6ulRJWlh3gM/duDHJBlFKqbqgwwBtj/s8YEw08Z4xpZL+ijTHNjTGP1FIZKyW0USsATOquIJdEKaXqhsp20XwmIg0ARGSUiLwoIucGsFxVFtWkJelEgdHpgpVSCiof4N8EskWkO/AgsAt4N2ClqiYPLkRvsiqlFFD5AF9ojDHAUGCyMeZ1IDpwxaoegwt0umCllAIq/8i+DBF5BLgNuEREXEBo4IpVPUW4QFvwSikFVL4FfzOQB9xhjDkEtAWeC1ipqsnqotEWvFJKQSUDvB3UZwKNRWQIkGuM0T54pZSqwyr7Tdb/AVYDI4D/AVaJyPBAFqw6PKJdNEopVayyffCPAb2NMYcBRKQF8A3wUaAKVh0G0S4apZSyVbYP3lUc3G2pVdi31nhwaxeNUkrZKtuC/0pE/gvMspdvBr4ITJGqzyN6k1UppYpVGOBFpAMQa4x5SERuBAbYSSuwbrrWKUaHSSqllNepWvAvA48AGGPmAfMARCTeTvttAMtWZTqKRimlTjpVP3qsMWZTyZX2uriAlOg0GHEhaIBXSik4dYBvUkFaZA2Wo0boF52UUuqkUwX4tSIytuRKEfkjsC4wRao+I9pFo5RSxU7VB38fMF9EbuVkQE8EwoAbAliuarGGSWoLXiml4BQB3hjzK3CxiAwCutqrPzfGLAp4yarB6oPX+eCVUgoqOQ7eGLMYWFyVA4vI2VhzxscCBphijHmlyiWsAqPj4JVSyquyX3SqjkLgQWPMehGJBtaJyNfGmC2BytDgwmUKA3V4pZQ6owRsugFjzEFjzHr7fQawFWgTqPyg+JusepNVKaWgluaTEZE4oCewKpD5GHHjQrtolFIKQEyAH1ItIg2B74Bn7W/DlkwfB4wDiI2NTZg9e3a18snMzCQ26XmiPWkcuuyl0ylynZWZmUnDhg2DXYyAqg91hPpRT61j7Rg0aNA6Y0xiWWmB7INHREKBucDMsoI7gDFmCjAFIDEx0QwcOLBaeS1ZsoTQsHBC8oXqHqOuW7JkiWPrVqw+1BHqRz21jsEXsC4aERHgHWCrMebFQOXjy4gLl46iUUopILB98P2xHtL9GxFJtl/XBjA/jLhp79mN8eiNVqWUClgXjTHmB0ACdfyyuD35APy6bxetzjm/NrNWSqk6p849lel05HccCkBRoY6FV0opRwV4cVnV8Xg0wCullKMCPC43AJ4ivdGqlFKOCvBiB3ijLXillHJmgNcWvFJKOS7AW4OCjEcDvFJKOSvAS/FNVg3wSinlrADvtqqjLXillHJagBeri8ZTpDdZlVLKWQHeXTyKRlvwSinlrADvHSapc9EopZSzArzYwyR1HLxSSjkswBd30RRpC14ppRwV4F36TVallPJyVIA/2QevN1mVUsqZAd5oF41SSjkqwLu8ffDaRaOUUo4K8MVz0aDPZVVKKWcF+OIWvEdH0SillMMCvN0Hry14pZRyWIAvfmSfjqJRSimHBXiXzgevlFJezgrwbg3wSilVzGEB3u6D1wCvlFJOC/DFwyR1FI1SSjkqwIeEhgHQcPu8IJdEKaWCz1EBvlnLNgAUusIB8BQVsfKNcezdsSGYxVJKqaBwVIAH2BwWj9uTB8DenZvoe/gDimaNCnKplFKq9jkuwBe5wgm1A3xO+lEAXOhNV6VU/ePIAB/iyWfPj+vp9PlNAIgxQS6VUkrVvpBgF6CmedzhhJp8zp49KNhFUUqpoHJeC94dQajJD3YxlFIq6BwX4I07jFYcDXYxlFIq6AIW4EVkqogcFpGUQOVRFldRXql1bvQBIEqp+ieQLfjpwNUBPH6ZCiObl1oXYXJruxhKKRV0AQvwxpilwLFAHb883W/9O9tDLvBbF2FKt+qVUsrpxARwCKGIxAGfGWO6VrDNOGAcQGxsbMLs2bOrlVdmZiYNGzYEIOPgdn677SFv2k+04ZeBb1TruHWJbx2dqj7UEepHPbWOtWPQoEHrjDGJZSYaYwL2AuKAlMpun5CQYKpr8eLFpdbl5mSZTX+/1Gx9pm+1j1uXlFVHp6kPdTSmftRT61g7gLWmnJjquFE0vsIjoihyhdOpYAubln4c7OIopVStctwXnUoqclsTj8Uv+j0rf7mPkF83kfigzjaplHK+gAV4EZkFDARiRGQf8IQx5p1A5VceIyer2Hfny7WdvVJKBU3AArwxZmSgjl0V4tEx8Eqp+snRffAAYjTAK6XqJ8cHeJenINhFUEqpoHB8gM9u3afUum1rF3H8yMEglEYppWqP4wN839smsiGiN/sl1ruu42c3UPD6xUEslVJKBZ7jA7y4XOQ2OKvUfDQta38WBaWUqlWOD/AAJiSK5qQFuxhKKVWr6keAD2tQ5vqkhe/VckmUUqr21IsAL+UE+J7Lx9dySZRSqvbU6wCvlFJOVi8CvDuqSblp6/87o/YKopRStaheBPjuV41hVaeHy0zrteIuCgv0Id1KKeepFwE+NCycPrc8wuruE8tMXzP1wVoukVJKBV69CPDFLrrhnjLXu/LTWPvCjax+uU7Mj6aUUjWiXgV4gBXt7iq1LiLrAIkZ33LRiS+CUCKllAqMehfg+942keSofn7ruueuCVJplFIqcOpdgBeXi/bjZpabnpb6ay2WRimlAqfeBXiARk2a89PwhSRFlZ5w7MeZE4JQIqWUqnn1MsADtO/ah55/+ZKDtPBb3+fYJ6xZ8HqQSqWUUjWn3gb4YiGUfuJT7+RH2bBoNgCZ6cdZ9eFzHDmwu5ZLppRSpydgz2Q9U5QV4AG6L/0T25e/QHZoM/rkrIQtz8CTOiOlUurMUe8DfKgpBCk77YLC7ZQT/5VSqs6r910026N7A5BrQoNcEqWUqln1PsBf+OdZ7B31AymNL6vU9tvWLuLHVQsDXCqllDp99b6LJiKqIWd3iKfln2dw4NBeigpyObJzPb1W3VdqW09RER0/uwGApO8uxpV4OwU5aZi8bHrfeG8tl1wppSpW7wN8sfCIKM6K6whAVKPmsKr0Nq6Jzbzve2Yvh6XLvcsrTuyj3x3PUViQT0hoWMDLq5RSp1Lvu2jK0qR5K7aGdqnSPv1+mQJPNibk2RbwZGN2blgWoNIppVTlaAu+DO6QEDo/tpxN380j86dVSO4JEg7NYXt4VzKj2xF/9EuiJK/CY3SYfy3Mt95vCe1KWkwvLvrDS7hD9JQrpWqHRpsKxF92I1x2o730L8pr06cdP8qvP6dw7MfvcUc1xbNvPX2OzvWmX1iQAgdT4Jl3WR3/JO7IRjSIOYfQyGhCwyNoHdeZrPTjHPo5hbiu/YiI1EcMKqVOnwb4GtC4aQyNmw6EXgO964zn32xY9AF5W76gz7FPvOsv2vRkmcdoYr/4HI7ShIwRH5J5dD/h0c24wD6up6iQ1F/30Ty2bSCqoZRyGA3wASIuFz2uGAlXWA8RKSzIJ+nzKRTlpOOObETh8b0027+Eswt+LtXdE8MJYuZc6V1O+saaFO3C7B9p/v0xVrb9AyY0kqizuxN7fi/2rFxAj9/+GYCd65fgDgml00WDa6mmSqm6SgN8LQkJDaP3sNIPGylmPB5+3beLrLRUju1aR4fk/6MpGYA9YsdH333vWG9+BpZCK4DN1uMIi7uRcj8P5Vd3Kw416w3GA626ERrdHHd4Azr2uYajB3bTtkPXmq2kUqpO0QBfR4jLRatzzgfO57z4vjBsPAA5WRn8uOxj8o/vJ33PRpp2GUhRZirm+C9IYQ5h2b/SM3sZW8LiyQ5vSWLGtwC48HCuZy/nHt1rZZC64GRm30FbYJe7PYUSyvFm3aHJOWAMIY1i8eTn0OGSETRo1BS3OwS3OwRxuTAeDx6PR28UK3WGCOhfqohcDbwCuIF/G2MmBTI/J4psEE3PK0cBsGTJEhIHDixzuwtLLIdhfTFLREg/kcqxQ7vJz84gbXcyIbsX0zVjGXnuBlyYvwkOb4PDJQ6w6Qm/xXQa0Igs3MAudzvcppB8VyQALlNEviuSgpAGeMSNcYVgxE1BVCzGFQYuN7hCoCgPEMQVgnGHgsuNuEKsNFcI4g4h/chRVh/fiLhCEBGMMYRENEBCwhFxIfY+4hL7pwsRoaggj6gmsYjLRVFBPmGRDQiLaEBoeCThkQ0Ij4jC5XIjUs7EQzYRQVw6elg5Q8ACvIi4gdeBwcA+YI2IfGKM2RKoPJU/l9sNQONmLWjczJ73PvE3wAPAyX8K6SdSKSrIJ+3oflJ/3kBhxhE8eVlQkIM7Yz/heUcpCG1EaEE6YgweVwgGwe0pAMCIi5CiHBrkH0XwEGIKcZtCmqUvJ4QiXHgIEQ8Fxo0BwqSo4oIfqflzUVkeI3gADy4MAIIHwdgvfNKMnFxvpZ3ctng7wE4/uQ8I5xnY953LSpOT+xvA4Dr5Xlze4/m9t4+J+OxjvwfBiE/eYh2v+JgUH8cnX+u9y554z17vsx3e4558752lT07WuXgZgOwcVm/8t9/59duu5PYl06TkP9qT+fkdq6z9yztmmcfFp16uMnYrmc/Jdbnp6azY+THis4PfORLx+Vk+CYui761PVLhNdQSyBX8RsNMY8xOAiMwGhgI1HuC3H9/Oswee5eUFL/utfyDxAS5teykbj2zkb8v+Vmq/x/o+Ru9WvVl1cBX/t+r/SqU/O+BZusR04bu93/HSupdKpb848EXaN2nPVz9/xVsb3iqV/sYVb3BWw7OYv2M+/9n8n1Lp066eRtOIpszcOpM52+aUSp81ZBaRIZG8s+kdPt31KVnZWd46igjzh1oD7V9Pfp2vd3/tt29UaBTvX/c+AM+veZ4f9v/gl94sshlTr5oKwCtb32Ddr+tOJoZDm5g2vH659eCTR79/lC2pW4CTwzc7NO3A85c9D8D9i+/n57Sfgebe9K4xXXlmwDMA3PnNnRzKPGinWL/oibGJPNTzAYoKCxi35M+k5aVhjCE3J4fwiHAuataTO84diSDclfQw+UV5VnAyVgjr2zCem5oOoqioiP/d/xpg3ccoNiCsI1e5O5OTn86z+V959ys2yJzDQHMu6eTxgmu1T4oBA1d5zuHioliOkMPk0E0n02zX57clsbAZ+11ZTAnfSUkjclvTrSCan1yZTGuw39795P43H29CN2nM1tAs3mtQ+j/auLRmtC8MJSkshw8bFk9TXeQtw70nGtG2wM3KiBzmRucWh26vR45G0rJIWBSVz6fRBd71YlfjmcNuGnvgs4ZF/Leh8Um33r90yEOkxzCnkfBtQ//gJMDb+62BAe82CeH7Bm6/8xfpgdcP5oDx8FaDCFZHuv32b1pkeOlQtpVP8wg2RLj94mnrQg//+DULgGdjItkWHoLvuW+fX8TEI5kAPNqyIXtC/fe/MK+Qx49kIBjua9WYX0P880/IyecvqenWeW7djDS3nDw3wIDsPO49ZqWPahNDXongfGVmNn86kYHBMLxtK9+iIRiGpWcxJj2DLBFuPSuWkkamZ3JzRiZHXS7+2LolAE/vzwPOrADfBtjrs7wP6FNyIxEZB4wDiI2NZcmSJVXO6EjBEWIkhpAC/+rsTNmJZ6eHA/kHiC6ILrXf1g1byfoxiz15e8pM37h+I0fCjrAzd2eZ6evXrOeX0F/4OefnMtPXrFxD45DG7M3eW2b6imUriHJHcSjrUJnpP3z/A6ESypHMI0QXRBMpkd46CuI9V8czjpfaP6wwzJuenp5eOr3oZHpOWk6pdEk7efyCEwWl0ouOFXnTzQlDdKF/ev7RfG+6O91NdFEjv/ScwzmsWGkF1qi8BojHajkVhhQSQggmK4xd+1IBaCotKHT7z9scQgxHCxvhMR5ahLYpde7CI88ju2EP8jx5xKbuKJUeEdWLvAY9KSzKIvbYsdL7N+hDXlRXPIUniD1e+kttIQ37kxvZCU/BEVqe+KRUuuusQWRHtMeTf4CWaV+WSi9oPoDMJh3x5O2hZfo3pdLzz76WtLDWeHJ30iLju1LpWecOJTU0hsKcrbTIXF4q/XjccDwhjSnM3khMVumHyh9qP5J0dxSFWetonp1cKn1Ph98TKqHkZ66kWc5mvzRB2Hb+HVY9Mn6gae42v/QwCWNLx9vIzMyk0LOapnk/+6U3cDUgpdMtAJi0hTTN3+u/v7sxGzoPt/I68TlNCg75pbtCYljfZSgAIccX0KQw1S/dE9qatV2vtY51bA6Ni9L90vNbnsOqbtYos8jU98GT45eeFXsey7sPtMp69D+EG//fvROtOvFDdH88xkPUobcJKXFP6nDreJY0vIjcwhyij5V+/vO+1j1YFNWDrKIsoo9bDbud5w7jWDVi3ykZYwLyAoZj9bsXL98GTK5on4SEBFNdixcvrva+Zwqto3PUh3pqHWsHsNaUE1MDeTdpP3C2z3Jbe51SSqlaEMgAvwY4X0TaiUgYcAtQ+rOsUkqpgAhYH7wxplBE7gL+izVMcqoxZvMpdlNKKVVDAjoO3hjzBfBFIPNQSilVNv1Gh1JKOZQGeKWUcigN8Eop5VAa4JVSyqHElPgKdzCJyBFgTzV3jwGO1mBx6iKto3PUh3pqHWvHucaYFmUl1KkAfzpEZK0xJjHY5QgkraNz1Id6ah2DT7tolFLKoTTAK6WUQzkpwE8JdgFqgdbROepDPbWOQeaYPnillFL+nNSCV0op5UMDvFJKOdQZH+BF5GoR2SYiO0Xk4WCXp7pE5GwRWSwiW0Rks4jca69vJiJfi8gO+2dTe72IyKt2vTeKSK/g1qDyRMQtIkki8pm93E5EVtl1+cCeXhoRCbeXd9rpcUEteBWISBMR+UhEfhSRrSLSz2nXUkTut39XU0RklohEOOFaishUETksIik+66p87URktL39DhEZHYy6nNEB3ufB3tdgPUN6pIhcWPFedVYh8KAx5kKgLzDersvDwLfGmPOBb+1lsOp8vv0aB7xZ+0WutnuBrT7L/wBeMsZ0AI4Df7DX/wE4bq9/yd7uTPEK8JUxphPQHau+jrmWItIGuAdINMZ0xZoS/BaccS2nA1eXWFelaycizbAestoH6/nUTxT/U6hV5T3q6Ux4Af2A//osPwI8Euxy1VDdPgYGA9uA1va61sA2+/2/gJE+23u3q8svrCd7fQv8BvgM61nHR4GQktcU61kC/ez3IfZ2Euw6VKKOjYGfS5bVSdeSk89cbmZfm8+Aq5xyLYE4IKW61w4YCfzLZ73fdrX1OqNb8JT9YO/ST2A+w9gfX3sCq4BYY8xBO+kQUPyY9jO17i8DfwE89nJz4IQx3icb+9bDW0c7Pc3evq5rBxwBptldUf8WkQY46FoaY/YDzwO/AAexrs06nHcti1X12tWJa3qmB3jHEZGGwFzgPmOM3+PgjdUUOGPHtYrIEOCwMWZdsMsSYCFAL+BNY0xPIIuTH+kBR1zLpsBQrH9mZwENKN2t4Uhn0rU70wO8ox7sLSKhWMF9pjFmnr36VxFpbae3Bg7b68/EuvcHrheR3cBsrG6aV4AmIlL8dDHfenjraKc3BlJrs8DVtA/YZ4xZZS9/hBXwnXQtrwB+NsYcMcYUAPOwrq/TrmWxql67OnFNz/QA75gHe4uIAO8AW40xL/okfQIU34EfjdU3X7z+9/Zd/L5Ams9HyDrJGPOIMaatMSYO61otMsbcCiwGhtublaxjcd2H29vX+ZaTMeYQsFdEOtqrLge24KBridU101dEouzf3eI6Oupa+qjqtfsvcKWINLU/7Vxpr6tdwb6ZUQM3Q64FtgO7gMeCXZ7TqMcArI99G4Fk+3UtVj/lt8AO4Bugmb29YI0g2gVswhrNEPR6VKG+A4HP7PftgdXATmAOEG6vj7CXd9rp7YNd7irUrwew1r6eC4CmTruWwFPAj0AKMAMId8K1BGZh3VcowPo09ofqXDvgDru+O4Hbg1EXnapAKaUc6kzvolFKKVUODfBKKeVQGuCVUsqhNMArpZRDaYBXSimH0gCv6jURecyeEXGjiCSLSB8RuU9EooJdNqVOlw6TVPWWiPQDXgQGGmPyRCQGCAOWY41nPhrUAip1mrQFr+qz1sBRY0wegB3Qh2PNrbJYRBYDiMiVIrJCRNaLyBx7viBEZLeI/FNENonIahHpEKyKKFUWDfCqPlsInC0i20XkDRG5zBjzKnAAGGSMGWS36h8HrjDG9ML6duoDPsdIM8bEA5OxZspUqs4IOfUmSjmTMSZTRBKAS4BBwAdS+qlgfbEeJrPMmnKFMGCFT/osn58vBbbESlWNBnhVrxljioAlwBIR2cTJCaWKCfC1MWZkeYco571SQaddNKreEpGOInK+z6oewB4gA4i2160E+hf3r4tIAxG5wGefm31++rbslQo6bcGr+qwh8JqINMF6Ju5OrOdqjgS+EpEDdj/8GGCWiITb+z2ONYMpQFMR2Qjk2fspVWfoMEmlqsl+cIkOp1R1lnbRKKWUQ2kLXimlHEpb8Eop5VAa4JVSyqE0wCullENpgFdKKYfSAK+UUg71/wF2lVIb0C/dEQAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "plt.clf()\n", "plt.plot(np.linspace(0, optimization_result_update.nfev, optimization_result_update.nfev), cost_update, label=\"Optimization path (upgrade_params())\")\n", "plt.plot(np.linspace(0, optimization_result_run.nfev, optimization_result_run.nfev), cost_run, label=\"Optimization path (run())\")\n", "upper_bound = max(optimization_result_run.nfev, optimization_result_update.nfev)\n", "plt.plot(np.linspace(0, upper_bound, upper_bound), np.zeros(upper_bound), \"--\", label=\"Target cost\")\n", "plt.xlabel(\"Step\"); plt.ylabel(\"Cost\")\n", "plt.legend(loc=\"upper right\"); plt.title(f\"n = {num_qubits}, l = {num_layers}, # params = {num_params}\")\n", "plt.grid(True)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "b7ea2d2e-8686-46fe-953e-27763187439b", "metadata": {}, "source": [ "And, as usual when using the `qraise()` function in Python, the `qdrop()` function can be used to remove the vQPUs." ] }, { "cell_type": "code", "execution_count": 13, "id": "460043a0-7ba5-4ab1-91f8-f4ba6d4969ec", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Removed job(s) with ID(s): \u001b[1;32m376623 \u001b[0m\n" ] } ], "source": [ "qdrop(family)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.10" } }, "nbformat": 4, "nbformat_minor": 5 }