diff --git a/README.md b/README.md index 284c2626..3680ccca 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Running notebooks locally requires additional dependencies located in [notebooks | CHSH Inequality | [CHSH_Inequality.ipynb](notebooks/textbook/CHSH_Inequality.ipynb) | [Clauser1970](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.23.880) | | Deutsch-Jozsa | [Deutsch_Jozsa_Algorithm.ipynb](notebooks/textbook/Deutsch_Jozsa_Algorithm.ipynb) | [Deutsch1992](https://royalsocietypublishing.org/doi/10.1098/rspa.1992.0167) | | Grover's Search | [Grovers_Search.ipynb](notebooks/textbook/Grovers_Search.ipynb) | [Figgatt2017](https://www.nature.com/articles/s41467-017-01904-7), [Baker2019](https://arxiv.org/abs/1904.01671) | +| MPS Encoding | [MPS_Encoding.ipynb](notebooks/textbook/MPS_Encoding.ipynb) | [Ran2019](https://arxiv.org/abs/1908.07958), [Rudolph2022](https://arxiv.org/abs/2209.00595) | | QAOA | [Quantum_Approximate_Optimization_Algorithm.ipynb](notebooks/textbook/Quantum_Approximate_Optimization_Algorithm.ipynb) | [Farhi2014](https://arxiv.org/abs/1411.4028) | | Quantum Circuit Born Machine | [Quantum_Circuit_Born_Machine.ipynb](notebooks/textbook/Quantum_Circuit_Born_Machine.ipynb) | [Benedetti2019](https://www.nature.com/articles/s41534-019-0157-8), [Liu2018](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.98.062324) | | QFT | [Quantum_Fourier_Transform.ipynb](notebooks/textbook/Quantum_Fourier_Transform.ipynb) | [Coppersmith2002](https://arxiv.org/abs/quant-ph/0201067) | diff --git a/notebooks/textbook/MPS_Encoding.ipynb b/notebooks/textbook/MPS_Encoding.ipynb new file mode 100644 index 00000000..81787c6a --- /dev/null +++ b/notebooks/textbook/MPS_Encoding.ipynb @@ -0,0 +1,259 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0479afb1", + "metadata": {}, + "source": [ + "# MPS Encoding" + ] + }, + { + "cell_type": "markdown", + "id": "9057d3c0", + "metadata": {}, + "source": [ + "Matrix Product State (MPS) encoding tackles the critical task of state preparation in $O(N)$ circuit depth [1], an exponential reduction in circuit depth compared to exact encoding algorithms like Shende, Isometry, and Mottonen. The current implementation uses an analytical decomposition based on work by Ran to create a staircase ansatz comprised of 1 and 2 qubit unitary gates. Main consideration with the decomposition is that it is prone to approximation limitations imposed by MPS intermediate-representation (IR), which limits the adequate performance of the synthesis to area-law entangled states only.\n", + "\n", + "In this notebook, we implement the analytical decomposition based on Ran [1]. For a comprehensive description of the algorithm, see [1]. In the following, we present the MPS performance on randomly generated area-law entangled states and compare performance with exact encoders.\n", + "\n", + "---\n", + "# References \n", + "\n", + "[1] S. Ran (2019). \"Encoding of Matrix Product States into Quantum Circuits of One- and Two-Qubit Gates\", [arXiv:1908.07958](https://arxiv.org/abs/1908.07958)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "7fe2019a", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "%matplotlib inline\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from braket.devices import LocalSimulator\n", + "from braket.experimental.algorithms.mps_encoding import mps_circuit_from_statevector" + ] + }, + { + "cell_type": "markdown", + "id": "c026eda8", + "metadata": {}, + "source": [ + "# Run on a local simulator\n", + "We demonstrate MPS Encoding on a classical simulator first. You can choose between a local simulator or an on-demand simulator.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "3f97eb8d", + "metadata": {}, + "outputs": [], + "source": [ + "def mps_encoding_metadata(num_qubits: int) -> dict:\n", + " state = np.random.rand(2**num_qubits) + 1j * np.random.rand(2**num_qubits)\n", + " state /= np.linalg.norm(state)\n", + "\n", + " circuit = mps_circuit_from_statevector(state, max_num_layers=max(1, int(num_qubits // 1.5)))\n", + " result = LocalSimulator(\"braket_sv\").run(circuit.state_vector(), shots=0).result()\n", + " fidelity = np.vdot(result.values[0], state)\n", + "\n", + " return {\n", + " \"num_qubits\": num_qubits,\n", + " \"fidelity\": np.abs(fidelity),\n", + " \"circuit_depth\": circuit.depth,\n", + " \"circuit\": circuit,\n", + " }" + ] + }, + { + "cell_type": "markdown", + "id": "6c1a43d6", + "metadata": {}, + "source": [ + "We observe a minimum fidelity of 0.88 as the system size increases." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "f727fd9a", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\A.C.EA\\Documents\\GitHub\\amazon-braket-algorithm-library\\.venv\\Lib\\site-packages\\cotengra\\hyperoptimizers\\hyper.py:36: UserWarning: Couldn't import `kahypar` - skipping from default hyper optimizer and using basic `labels` method instead. `kahypar` is highly recommended for the best quality contraction paths.\n", + " warnings.warn(\n", + "c:\\Users\\A.C.EA\\Documents\\GitHub\\amazon-braket-algorithm-library\\.venv\\Lib\\site-packages\\cotengra\\hyperoptimizers\\hyper.py:75: UserWarning: Couldn't find `optuna`, `cmaes`, or `nevergrad` so will use completely random sampling in place of hyper-optimization. It is recommended to install one of these libraries for higher quality hyper-optimization.\n", + " warnings.warn(\n", + "c:\\Users\\A.C.EA\\Documents\\GitHub\\amazon-braket-algorithm-library\\.venv\\Lib\\site-packages\\cotengra\\hyperoptimizers\\hyper.py:55: UserWarning: Couldn't find `optuna`, `cmaes`, or `nevergrad` so will use completely random sampling in place of hyper-optimization. It is recommended to install one of these libraries for higher quality contraction paths.\n", + " warnings.warn(\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkAAAAHHCAYAAABXx+fLAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAaUxJREFUeJzt3Qd4k1XbB/B/94C2jE6g7FlAyhBElCFTkOVCEUH4RAFRkFcREFkORF+QIYKouBDFVxABEUE2AmXvTSu7gwIttHTnu+4DqWlJS1vSPMmT/++60iRPnqTnGUnunHOfc5wMBoMBRERERA7EWesCEBEREVkbAyAiIiJyOAyAiIiIyOEwACIiIiKHwwCIiIiIHA4DICIiInI4DICIiIjI4TAAIiIiIofDAIiIiIgcDgMgytM///wDJycnfPPNN3fdSy+88AIqV65cpL3ZunVrdSnK/7Wmjz/+GFWrVoWLiwvCw8O1Lo7DkfNBzgs5P/I6d0g78hlQsmRJuzkEq1atUu9jT09PdV5du3ZNk3LI/x46dGiRzn+6NwyAHJjxDWXuMmrUKNiSlStXYsKECZr9/9WrV2PkyJFo0aIFvv76a3zwwQf5fhHIPvT19cXNmzfvePzkyZPZ+/m///1v9vINGzbkOAZubm4q4Orbty8iIyNzvEZcXByGDRuG2rVrw8vLC4GBgWjatCneeust3Lhxo8jHXS7bt28v0j6i4ifBnhyjrl273vGY8YeD6TlF5sXHx+Ppp59W753Zs2fj+++/R4kSJfLdXYcPH0afPn1Qvnx5eHh4oFy5cur+kSNHNNvNn332mc39ULQnrloXgLQ3adIkVKlSJceyevXqoVKlSuoLXL6Ircnc/5UASD6otAqC1q1bB2dnZ3z11Vdwd3e/6/qurq5ITk7G8uXL1QetqR9++EH96kxJSTH73Ndeew33338/0tPTsWfPHsybNw+///47Dh48qD50r1y5giZNmiAxMREDBgxQQZB8oB84cABz5szB4MGDC/RL3NxxF9WrV4e9kMDUEa1YsQK7d+9G48aNtS6KXdq5cyeuX7+Od999F+3atbvr+kuWLMGzzz6LMmXK4P/+7//U+0YCTvk8+OWXX7Bo0SJ07969WMv8/PPP45lnnlHBl2kA5O/vr350UeExACI8+uij6gvVHPmitjb5FavF/81PbGys+rVYkOBHyIeU1Bb9+OOPdwRACxcuRJcuXbB48WKzz3344Yfx5JNPqtv9+/dHzZo1VVD07bffYvTo0epD9+zZs/j777/x4IMP5niuBEUFLWN+x91eFHRb9aRixYrqy3vixIlYtmwZHInM3S0/HOS9eK/vZ1GqVKm7rnv69GkVfEht7KZNmxAQEJD9mNTCyvtVaoLkB4i5HxSWIk3vciHLYRMY5SmvXJylS5eqGiIJUuT6119/Nfv8rKwsTJ8+HXXr1lXrBgUF4eWXX8bVq1cL9X/l143U/gjTphr5MJS8I3O/vORD0s/PT/2//GRkZKhfgdWqVVNBi7zemDFjkJqamr2O/C9p9kpKSsr+3wWpdu7duzf++OOPHLkF8stTmsDksYJ65JFH1HVUVFT2B7J8ED7wwAN3rCvNbpYKHk2bVKQWyriPpHZKtiO3Y8eOqWBPviDkC6pWrVp4++23c6yzd+9eFXhJOaWWqm3btmab3KS5QbZbXqdChQp477331PmUW+4cIGMz4s8//4z3339fPVf2h/yfU6dO3fF8Oa/ki03+jzQhbt68uUB5RXLet2nT5o7lUkZpIjEGsOKnn35SNTU+Pj5qu+vXr48ZM2agqOR1Xn/9dVW7KDWE+ZEaU9kfBcknkXP/scceU/tQAmPZJ1JWuW+sBZH7sj9le+RYmiPNtR07dlRNSlJjKTWN8l4tymeDsUx//vlndpk+//zzfLf5f//7nyqfrCu1IxKcXLhwIftxObb9+vVTt+Vclv2QXw2K5P5Jba68B0yDHyGvL+WRZmdZ7245kXkdD2PNsLxnjPtXgq38jpm8vrxPNm7cmP25ZDxvpfZYAuQaNWqo1ytbtiweeughrFmzJt9952gYABESEhJw+fLlHJf8mhyeeOIJ9WabPHkyevTooWopdu3adce68oH25ptvqpoQ+cCX9eRNLh+O8gYtKHmd9u3bq9vSVm+8SBnkw02CDGkWMiVfDlIbIo/n58UXX8S4cePQqFEjfPLJJ2jVqpXaLqlqNpL/Jb/y5Mvf+L9btmx513I//vjjqozyxWFa+yNNVvL/CkoCHiEfYsYmwszMTFUOSx93aUrLTcosH+5yHCQQkQ9g2TbTYyi/fps1a6aaCgcOHKiOt5wbchyM5MNa9uP+/ftVPtU777yjgjr50I6IiMheLzo6WgUX+/btU7low4cPx3fffVeooOHDDz9Ugfkbb7yhas0kyHruuedyrCPNhZJ8KkHSRx99pMomZT5//vxdX79Xr17qC0rKamrLli24ePFi9vkjXzjSdFK6dGlMmTJFlUu2V2rv7oXUPMhrWrpJWIJECc4lx0jeBxKQyG1530rQJe8n+WKVc1KC3dxBqZyXnTp1UgGN7FP5Ih8/fry6FPWz4fjx42ofymeArJtfBwQJEqRc8gNByi/norz/5Mvf+ENEgvKXXnpJ3ZbgTN5H+f1QknNYgg05P8yRzwJ53PRcLywJYuQ8l/0rZZL3oezHQ4cO5fkcCSDl3JXPE+PnkvEHh5wXcpzkffTpp5+q5VJzeLeA2eEYyGF9/fXX8rPM7EVERUWp27KeUXh4uCEkJMRw7dq17GWrV69W61WqVCl72ebNm9WyH374Icf/XLVq1R3LW7VqpS5G5v7vK6+8kl0uU8ePH1fL58yZk2N5t27dDJUrVzZkZWXluf379u1Tz33xxRdzLH/jjTfU8nXr1mUv69evn6FEiRKGgjBd98knnzS0bdtW3c7MzDQEBwcbJk6cmL2NH3/8cfbz1q9fr5bNnz/fEBcXZ7h48aLh999/V9vh5ORk2Llzp1ovOjraEBAQoNatXbu2YdCgQYaFCxfmOCZFPe4eHh7Z6xnLWLZsWcOVK1eyl//2229q+fLly7OXtWzZ0uDj42M4c+ZMjv9luv979OhhcHd3N5w+fTp7mWyjPE+ebzR8+HD1+hEREdnLYmNjDX5+fmq5lCuvc8e4D+vUqWNITU3NXj5jxgy1/ODBg+q+PCbbdf/99xvS09Oz1/vmm2/UeqavaY7xvJs1a1aO5UOGDDGULFnSkJycrO4PGzbM4Ovra8jIyDBYgpSrbt266racR1KG3bt3q/vmzqnx48ebfd8YzwHTfSnvX1m2devW7GV//vmnWubl5ZXj2H7++edquexv0/Nelr366qs5jn+XLl3UcZdzurCfDcYyyWN3k5aWZggMDDTUq1fPcPPmzezlK1asUK8xbty4O7bf+J7Ki7ynZL3u3bvnu5583sh6iYmJ2fvC9PMwv+NhfO/t2rUre5nsa09PT0PPnj3zPWZyLpg7Vxs0aKD2O+WPNUCkmgHkl6rpxZxLly6pX+VSfSzNS0byyywsLOyOamhZRx4zrWGQX4TS9LF+/XqL7HnJj5GaB/n1aCS1QVIrJL/486puNiZWixEjRuRY/p///EddS+LxvZJf09KEIDUFUjsi13dr/pLEZqlql+YDyRWSpjfJ/zHm68iva6lFGTRokPqFPnfuXPWa0hNMmvNyNzcU5rjLfjNX2yG1DUbGX8LGnmnSI01qQ6Tc8ivTlHH/S82A1B5KDYs0ORmFhISoskvNidTYGY+LNO9Jk5SR7I/cNTj5kRoF0/yg3GWWGkv5lS01BJKwbiT/w3Rb8zvvpCZCkl+NZBslIVZqTIw5KpJjIsevOJoejLVA8kvfUuR93Lx58+z78t4S0hxpemyNy3P3ThSmXbqNXbzT0tLw119/FemzQfJqpGbobuSYSm7PkCFDcjQDy3tIakmK8n6WXCtjs2N+jI8b1y8s2eemCe2yr6VpX5r+5LwqLDnvpMZVmtspb0yCJvVFU5Bk2DNnzqhraVfOTdquTatX5Y0nTSzypZxfEqIlSDdx+ZCV8knzkHzASjW6JC7mR9aXnl25ez0FBwerDxDj9t6Lzp07qw9H+aKU4FFyDuT/5TeWhzTJyRe2VONLjkGdOnVyfEkbAwdpwpFeILKv5YNSmljkufKYNO1Z6rjnDmqMAYIxX8P4JSh5MXmRIEnyKOQ8yU22T5pSzp07p3JCZL8bv2BNmXtuUctsPLa5j73s54KOZyWBoeSLSX6J5P1IoCvntSw3ki9jyUeSvCdZp0OHDqqJRpo37pUEEdJsIs1Lko9TkMCtsPvN+EMnNDTU7PLcOTvyfjINcI3BojCe84X9bChoYrHxmJo7TyQAkiC7sAoa2MjjEuzJ+7UozH2myn6T94y8d+QzqTCkGU0CKHkNeV/K+Safh/fdd1+RyqdXrAGiYiFfaPIBl7uGwXiRN6ilSL6FdJk31gItWLBAfbEX9Aszv1qieyV5Q5IvIzU4kpNSkORnSTSVrrnSfi+3cwc/ucsuH3KvvvqqqoWRLyDT2jBLyKvnSUFrmrRgjTJLoCOvJwG3kEBHAgPT4EbeAxL4Sm+tbt26qdoNCYaMSbiWqAWSYD2vWqC8zu28ahXy2m+W3J+F/Wy41x5f90KOp9TESo5bfuRxyccx1joWdr9bmuQlSZ7W/PnzVQD05ZdfqrxDuaZ/MQCiApPaFWGuWlUSFU1JjyFpYpAkR/kyz31p0KBBofZ8fkGKjM0h1dzyxS+/AiXB9G61P8btkQ/j3NsTExOjEiaN23uvJOiRX+jyK9E0udrS5Je31AJIU6U1GX/x55ewKU1Y3t7ed5wnxt5jErgZaxlkvxfkHLsXxmObu2eY9Aos6Ei7UjMhtWhSuyfPk2RbaeIzHadFyJeiNItJbZ18KUnCrSR1m+uVVtRaoN9++81sryxjrVDuUY4tUbtpjryfcjeLnThxQl0ba9Ys/dmQ+5iaO09kWVHfz3LsJFk/rxok6Tko58xTTz2VY7+bG1k6r/1u7nyX/Sbvmdw9zwrzuShNwTIUh9SuSu2PloPJ2iIGQFRg0rQieQ9SmyFV2Ebyqy33aKhSzS+/diQnJTf5sijssPPGUVrzep4EPFIG6Vkiv1YLEmhI85SxN4WpadOmqWsJqixBanJkP0hvjMJWZZsjPaYkryS3HTt2qC+WwjQVWYJ8QMsvTvm1KeMTmashkGMizT/yRW0aYEiwKb3MpJeOdBE3HhfptSXbYyTNAJas2ZIaQulV98UXX6jz0Uj+x92GachdCyRllW2XPBbT5i+Ru1edBHrGZgjjUAvSXCtBYFEDVwmApBbIXK2qBBvCtEu1MaesuMh5bnr85b7U0MpQBMXx2WB6TKVmSXLiTIexkLy2o0ePFvn9LD0JJRCRwDX38ZR8Q8nFk3PXNPdJ9rt8RprWHMnxzWvIkG3btuVIIZCARd4r8p7Jb+wf+Vw0t79yl1Nyq6S513S/EHOAqJCka6l8kMgXliS9ygfArFmzVO6G6RQM0p1cPjBkfWkCkDeyfAjKLx1pMpDurKZjpdyNMUFQBgSUhMjcQY6USb7Q5LWliSGv/AJT8ktTmiJkfA/5EJEyy5eufDnIL3lz47wUhXzpjR07FpYi3V3li7pnz55qv0gNg3zAy5ewJH9KXkpByBeDfPHmJoMr5s7juJuZM2eqc0Kq2aWLsXGkXEk8leMvpAu9BMuynuTGSNOejKEiH8rSZdpIusjLNkpTkjTxyIe8HCP5BX+3poiCkn0mv4al6VASfOVLWcor3ajly6ugzaLyPPmClIv84s49qrDkYsl7RP6HNJFIDYC8X+SHhOQ+CckhkttyLhZlWgOpBZL9ZK4ZTN53ktcjoxcbfxzIeSJBa+5g1RLk/JM5tmRbJI9LzjE5B+ScNNZkWPqzwUheQ/LgpNZD/od0nZcAW15Pap+kG39RSOAgNXbyetIknXskaAmYZawn01wl+WySaWnkPSqfWZLLIzl70lxtriu6NFPJ55qsKzWIUlso7pbgLu9/eV15b0k55XNPzjVJZpfhFuRxOS8lQVwS9Asy55hDuUsvMdKxu3UFNdcdXSxevFh1M5Yu02FhYYYlS5bk2e1z3rx5hsaNG6tutNLduX79+oaRI0eq7s+F6QYv3Yile610/5Yu4eZOXemCLMulS3hBSRdo6U5cpUoVg5ubmyE0NNQwevRoQ0pKSo71itoNPi/5dYP/3//+l+9zDxw4YHjzzTcNjRo1MpQpU8bg6uqqhiZ46qmnDHv27LmnbvCm+91cGY1kuXTpNXXo0CHVbbdUqVKqC2+tWrUM77zzTo51pHwdO3ZUXcW9vb0Nbdq0ydHt2nQb5ZyQ1ylfvrzh3XffNXz11VcF7gafex/mdS7PnDlTnbdyLjdt2tTw999/q/O1U6dOhoJq0aKF2eEUxC+//GLo0KGD6p4tXcErVqxoePnllw2XLl26o2xy3hSmG7ypq1evZg8TkPt4STf5Zs2aZf//adOm5dkN3lzXaVlPhqEwZe7cMJ73MsyBbLMc36CgIHWeyBAQRflsyKtM+Vm0aJGhYcOG6pjK++O5554znD9/Psc6Be0Gb0qGUOjdu7caysLZ2Vk9X87Pw4cPm11fhgeRLvmy3+W9sGDBgjy7wcv+lcdr1Kihyi3lNx1iwLTMpsdMhsSQ/SP7z3T4hvfee0+dz/JelP0rw2W8//77aqgA+peT/NE6CCOyBPmFJ7/IpKu5VFkTFSWHRWoqJHFdmseI8iK1QjLiswxeKLfJ/rAbPOmCTH0hvb9klGoGP1TQc0aaG0ybu+SLTJqs7jYVBpEMvyF5PTJauTRvfvDBB9wpdoY1QGTXZMwQGWBN2rdljjJpX89vqHwiIxm3R2oNpfeO5I/JuSM1iJKPIzOtO+JEq0SOhDVAZNek55eM3ivJf5KIy+CHCkoSY6XrvZw3UusjyaLyq17m62LwQ6R/rAEiIiIih8NxgIiIiMjhMAAiIiIih8McoDy6wl68eFFNhFec80QRERGR5cjIPjLtkMzhJoPQ5ocBkBkS/OSe/ZiIiIjsg0wnIsMT5IcBkBlS82Pcgcb5iSxF5v1ZvXp19vDvesft1TceX33j8dW/dJ19JyUmJqoKDOP3eH4YAJlhbPaS4Kc4AiAZqE9eVw8n291we/WNx1ffeHz1L12n30kFSV9hEjQRERE5HAZARERE5HAYABEREZHDYQBEREREDocBEBERETkcBkBERETkcBgAERERkcNhAEREREQOhwEQERERORyOBG1FmVkGRERdwe7LTigbdQXNqwfCxdnJKv93R9QVxF5PQaCPJ5pWKWOV/0tERGSrNK0B2rRpE7p27apmbZVhq5cuXXrX52zYsAGNGjWCh4cHqlevjm+++eaOdWbPno3KlSvD09MTzZo1w44dO6C1VYcu4aEp69Bn/i58d9JFXct9WW6N//vsF9sx7Kd96toa/5eIiMiWaRoAJSUloUGDBipgKYioqCh06dIFbdq0wb59+zB8+HC8+OKL+PPPP7PXWbRoEUaMGIHx48djz5496vU7duyI2NhYaEWCjcEL9uBSQkqO5dEJKWp5cQUjWv1fIiIiW6dpE9ijjz6qLgU1d+5cVKlSBVOnTlX369Spgy1btuCTTz5RQY6YNm0aBg4ciP79+2c/5/fff8f8+fMxatQoWJs0P01cfgQGM48Zl4377TDqhPhatFlK/u87vx3O8//Kf5JytQ8LZnMYERE5HLvKAdq2bRvatWuXY5kEPlITJNLS0rB7926MHj06+3FnZ2f1HHluXlJTU9XFKDExMXuWXLncC8n5yV0Dk1vs9VS0+ngDrEmCICnX11tO47H7QlDG261As+cWlnH/3et+tBfcXn3j8dU3Rzu+etzmwmyHXQVA0dHRCAoKyrFM7kvAcvPmTVy9ehWZmZlm1zl27Fierzt58mRMnDjxjuWrV6+Gt7f3PZVZEp4Bl7uu5wIDLJmXnGUAMlU9T/7eW3lcXbxdDQjyAgI95fr2bS8DynoCLk5FL8PpRCckpjvh5C9/oZqvZbfRlq1ZswaOhNurbzy++rdGJ59ZycnJ+gyAiovUGEnekJEEVKGhoejQoQN8fX3v6bWlt9d3J3fddb1vB9yPZlXKwFKk5kkSre/Gv4Qb4pPTkZzhhKjrQNT1nBGKm4sTKpXxRtWAEqjqf/uibnvDx9Mtz9f983AMJq88hujEf2vWgn09MLZzbXSsmzNA1RP59SEfJO3bt4ebW977Ry+4vfrG46t/6Tr7zDK24OguAAoODkZMTEyOZXJfghQvLy+4uLioi7l15Ll5kR5lcslNToZ7PSGkq3uIn6dKPDaXjyPhRrCfp8W7xBf0/2556xGkZWQh6nISTsfduH1JwunYG4i8fAMp6Vk4FZekLrkF+nigWkBJVAssceta3S6J/Wev4dWf9t/xf2MSU9XyOX0aoVO9EOiZJc4de8Lt1TceX/1z08lnVmG2wa4CoObNm2PlypU5lknkKsuFu7s7GjdujLVr16JHjx5qWVZWlro/dOhQTcosQc34rmGq15UEHaZBgTHckcctPS5PYf6vl7sLwsr5qouprCwDLibcVAFRpDE4ir0VKEnekvGyLTK+QGVi8jUREdkKTQOgGzdu4NSpUzm6uUv39jJlyqBixYqqaerChQv47rvv1OODBg3Cp59+ipEjR2LAgAFYt24dfv75Z9XLy0iasvr164cmTZqgadOmmD59uupub+wVpgWp7ZBaD+l1ZZoQLTUwEoQUV23Ivf5fZ2cnVCjtrS6tagbkeCwxJR2Rt2uKTGuOJFCS3J+7JV/LwIzNq5W9940kIiKytwBo165dakwfI2MejgQwMsDhpUuXcPbs2ezHpQu8BDuvv/46ZsyYgQoVKuDLL7/M7gIvevXqhbi4OIwbN04lTYeHh2PVqlV3JEZbmwQb0uV826lYrN4cgQ4PN7PKSNDG/2vpkaB9Pd0QHlpKXUwt2XMeI37ef9fnS1mIiIgcMgBq3bo1DIa8qwvMjfIsz9m7d2++ryvNXVo1eeVHgg5JdI4/alDX1pqOQv6PtWpbQvy8CrSeBGJERERa4WSoZFFSuyTJ13mFdrJcHpf1iIiItMIAiIol+VqYC4IMxZT0TUREVBgMgKjYkq8l2Tq3Ul5ueLhGzoRqIiIia2MARMUWBMkYQwsGNEHfGpmY37cRQkt74drNdMxa92/PPyIiIi0wAKJiT/pu7G/AwzX8MaFbXbX8qy2Rqts8ERGRVhgAkdW0rROER2oHIj3TgAnLDufbA5CIiKg4MQAiqxr3WBjcXZyx+eRlrD6Sc8oSIiIia2EARFZV2b8EXmpZVd2etPwIbqZl8ggQEZHVMQAiq3ulTXWUL+WFC9duYs7G0zwCRERkdQyAyOpk8tWxXeqo23M3nsbZ+GQeBSIisioGQKSJTvWC8VB1f6RlZGHSiiM8CkREZFUMgEgTTk5OmNAtDK7OTvjraAzWH4vlkSAiIqthAESaqR7ogwEPVVG3Jyw/jJR0JkQTEZF1MAAiTb3WtgYCfTxwJj4ZX22J4tEgIiKrYABEmirp4Yq3bydEz1p3UvUMIyIiKm4MgEhz3RqUQ9PKZZCSnoX3f2dCNBERFT8GQGQTCdETu9dVc4etPBiNLScva10kIiLSOQZAZBPqhPji+Qcqqdvjlx1S3eOJiIiKCwMgshmvt6+JsiXccTouCd9u/Ufr4hARkY4xACKb4eflhrcera1uT//rBGISU7QuEhER6RQDILIpTzaqgPDQUkhKy8TklUe1Lg4REekUAyCyKc7OTni3ez04OQFL911ERGS81kUiIiIdYgBENqd+BT8827Siuj1+2WFkZDIhmoiILIsBENmkNzvUQilvNxyLvo4F289oXRwiItIZBkBkk0qXcMcbHWqp21PXnMDlG6laF4mIiHSEARDZLGkGq1feF9dTMvDRqmNaF4eIiHSEARDZLBkZemK3eur2z7vOY+/Zq1oXiYiIdIIBENm0xpVK48nGFdTtcb8dRmaWQesiERGRDjAAIpv3Vqfa8PFwxcELCVi085zWxSEiIh1gAEQ2L8DHQ02TIT768xiuJqVpXSQiIrJzDIDILvRtXgm1gnxwLTkdU9cc17o4RERk5xgAkV1wdXHGxO511e0fIs7i0IUErYtERER2jAEQ2Y0HqpZFtwblYDBIQvQhZDEhmoiIiogBENmVMZ3rwNvdBXvOXsOSvRe0Lg4REdkpBkBkV4L9PPFa2xrq9od/HEViSrrWRSIiIjvEAIjszoAWVVA1oAQu30jDJ2tOaF0cIiKyQwyAyO64uzpjQtdbCdHfbTuDY9GJWheJiIjsDAMgskstawagU91gNTL0+N8OwyCZ0URERAXEAIjs1tjH6sDTzRkRUVew/MAlrYtDRER2RPMAaPbs2ahcuTI8PT3RrFkz7NixI89109PTMWnSJFSrVk2t36BBA6xatSrHOpmZmXjnnXdQpUoVeHl5qXXfffdd1hDoUIXS3nildXV1+/3fj+BGaoam5ZHaKAnGdl92Utect4yIyHZpGgAtWrQII0aMwPjx47Fnzx4V0HTs2BGxsbFm1x87diw+//xzzJo1C0eOHMGgQYPQs2dP7N27N3udKVOmYM6cOfj0009x9OhRdf+jjz5SzyH9GdiyKiqW8UZMYipmrTupWTlWHbqEh6asQ5/5u/DdSRd1LfdlORER2R5NA6Bp06Zh4MCB6N+/P8LCwjB37lx4e3tj/vz5Ztf//vvvMWbMGHTu3BlVq1bF4MGD1e2pU6dmr7N161Z0794dXbp0UTVLTz75JDp06JBvzRLZL083F4zvGqZuz98ShVOxN6xeBglyBi/Yg0sJKTmWRyekqOUMgoiIbI+rVv84LS0Nu3fvxujRo7OXOTs7o127dti2bZvZ56SmpqqmL1PSzLVly5bs+w8++CDmzZuHEydOoGbNmti/f796XIKtvMjrysUoMTExu8lNLpZkfD1Lv66tssb2tqxeBq1r+mPDicsY/9shfN2vEZycnGAN0sw1YdlhmEvBlmVSionLD6N1jbJwcbZOmayJ57O+8fjqX7rOvpMKsx1OBo26z1y8eBHly5dXNTbNmzfPXj5y5Ehs3LgRERERdzynd+/eKqBZunSpyu1Zu3atqu2RvB9jAJOVlaVqiaTZy8XFRT32/vvv5wi0cpswYQImTpx4x/KFCxeqGimyfZdTgA/2uSDT4IQXamSipBuQmA74ugHVfA2wROwh75SkDCAuBYi76YTYFCdEXgdOJ969InVoWCZq+LGnGhFRcUpOTlaxQkJCAnx9fW2zBqgoZsyYoZrMateurX7hSxAkzWemTWY///wzfvjhBxW81K1bF/v27cPw4cNRrlw59OvXz+zrSnAkuUimNUChoaGq6exuO7Ao0emaNWvQvn17uLm5Qe+sub3xvqfw2cZIfHfKBabThAX7emBs59roWDeoQK8jydRn4pPxT3wyoi4nqetblyQk3CxaonXVuuHofF8I9Ibns77x+Opfus6+k4wtOAWhWQDk7++vamhiYmJyLJf7wcHBZp8TEBCgan9SUlIQHx+vgppRo0apfCCjN998Uy175pln1P369evjzJkzmDx5cp4BkIeHh7rkJidDcZ0Qxfnatsga21sr5FawmnuOVEmQfvWn/ZjTpxE61bsVhKRmZOJsfDIiJcC5nKQCHePt2Ov/NoeaU87PE1UCSqCKfwl1f8H2s3ctW0ipEro+3jyf9Y3HV//cdPKdVJht0CwAcnd3R+PGjVUzVo8ePbKbr+T+0KFD832u5AFJ85lErosXL8bTTz+do/pLcolMSaAlr036Jbk4H/5xzOxjxnhoxM/7sWD7GVWbc+HaTdWklZeyJdxVgCOXyv4lUFVuB5RApTIl4OXukuP/rj0aqxKezb2c0+35y5pWKXOvm0hERBakaROYNDtJrUyTJk3QtGlTTJ8+HUlJSapZS/Tt21cFOlJ7IyQv6MKFCwgPD1fXkrsjgY3kDRl17dpV5fxUrFhRNYFJF3lJgB4wYIBm20nFb0fUlTt6YeWWnJaJLafis++X9HDNDnJMLxLw+HkV7FeEJDZLLzTp7SXBjrkgSB7XYwI0EZE90zQA6tWrF+Li4jBu3DhER0erwEYGNgwKupWrcfbs2Ry1OdL0JWMBRUZGomTJkqoLvHSNL1WqVPY6Mt6PDIQ4ZMgQNZ6QNJO9/PLL6n+QfsVezz/4MXq2aSh6NqygAh3/ku4W6S0mzWrSvDZx+ZEcQZiHqzNmPBOe3exGRES2Q/MkaGnuyqvJa8OGDTnut2rVSg2AmB8fHx9VkyQXchyBPjmHR8hLtwbli6U5SoKc9mHB2HYqFovXRuDXMy5Iy8hCo0qlLf6/iIhIB1NhEFmCBDUhfp6qGcocWR5SzLk40szVrEoZtC5nQIMKfqo57HfOUUZEZJMYAJEuGHNxRO4gyEmDXJxuDW41ey3dd9Eq/4+IiAqHARDphjEXR3pdmZL7pl3graFzvSA1+OL+c9dU13oiIrItmucAERVHLo70CpPEaMkNkmYva/fC8i/pgRbV/bH55GUs238Rr7WtYdX/T0RE+WMNEOmOBDvNq5VF9/Dy6lqrLug9wsur66X7LkCjGWeIiCgPDICIikmHukGqK3xkXBIOXyz48OxERFT8GAARFRMfTze0C7s1ptXSvRe4n4mIbAgDIKJi1L1BOXW9/MBFNW0GERHZBgZARMWoVa0A+Hq6qglZI6L+nYaDiIi0xQCIqBh5uLqgy323ut//tpdjAhER2QoGQETFTKbfECsPXUJqRib3NxGRDWAARFTMZHqMYF9PXE/JwIbjcdzfREQ2gAEQUXG/yZyd0C38VjL0b/vYG4yIyBYwACKygm63e4P9dTQW11PSuc+JiDTGAIjICuqW80X1wJJIy8jCqkPR3OdERBpjAERkBU5OTtljAsncYEREpC0GQERWYswD+vvUZTVRKxERaYcBEJGVVCpbAg0rloIMCL1i/yXudyIiDTEAIrIiYzPYb2wGIyLSFAMgIivqcl85uDg7Yf+5a4i6nMR9T0SkEQZARFYU4OOBFtX91e1l+5gMTUSkFQZARJo1g12AwcAZ4omItMAAiMjKOtYLhoerMyLjknDoQiL3PxGRBhgAEVlZSQ9XtAsLUrc5NQYRkTYYABFp2Ay2/MBFZEq/eCIisioGQEQaaF0rEH5ebohJTEVEZDyPARGRlTEAItKAu6szOtcPVrd/Y28wIiKrYwBEpJHu4eXV9cpDl5CSnsnjQERkRQyAiDTStHIZBPt64npKBjYcj+NxICKyIgZARBpxdnbKniB12f4LPA5ERFbEAIhIQ91vB0B/HY1FYko6jwURkZUwACLSUFiIL6oHlkRaRhb+PBTNY0FEZCUMgIg05OTk9O/UGOwNRkRkNQyAiGykN9jW05cRm5iidXGIiBwCAyAijVUs642GFUtBBoReceCS1sUhInIIDICIbECP27VAnBuMiMg6GAAR2YDO9UPg4uyE/ecTEHU5SeviEBHpHgMgIhsQ4OOBFtX91e1lTIYmIip2DICIbESP22MCSTOYwcAZ4omIdB0AzZ49G5UrV4anpyeaNWuGHTt25Llueno6Jk2ahGrVqqn1GzRogFWrVt2x3oULF9CnTx+ULVsWXl5eqF+/Pnbt2lXMW0J0bzrUDYaHqzMiLyfh0IVE7k4iIr0GQIsWLcKIESMwfvx47NmzRwU0HTt2RGxsrNn1x44di88//xyzZs3CkSNHMGjQIPTs2RN79+7NXufq1ato0aIF3Nzc8Mcff6j1pk6ditKlS1txy4gKr6SHK9qFBanbS/dxagwiIt0GQNOmTcPAgQPRv39/hIWFYe7cufD29sb8+fPNrv/9999jzJgx6Ny5M6pWrYrBgwer2xLgGE2ZMgWhoaH4+uuv0bRpU1SpUgUdOnRQtUZE9tIbbPn+i8iUfvFERFQsXKGRtLQ07N69G6NHj85e5uzsjHbt2mHbtm1mn5OamqqavkxJE9eWLVuy7y9btkzVIj311FPYuHEjypcvjyFDhqhAKy/yunIxSkxMzG5yk4slGV/P0q9rq7i9hfNglVLw83JF7PVU/H0yBs2rloUt4/HVNx5f/UvX2XdSYbbDyaBRtuXFixdVcLJ161Y0b948e/nIkSNV4BIREXHHc3r37o39+/dj6dKlqkZn7dq16N69OzIzM7MDGGOAJE1rEgTt3LkTw4YNU7VL/fr1M1uWCRMmYOLEiXcsX7hwoaqRIrKmRaedsTXWGc0CstC7ehZ3PhFRASUnJ6tYISEhAb6+vrZZA1QUM2bMUDU5tWvXVnMoSRAkzWemTWZZWVlo0qQJPvjgA3W/YcOGOHToUL4BkNRCScBkWgMkzWjSdHa3HViU6HTNmjVo3769ylPSO25v4ZWNuoKt83fhyHV3tG3fCh5uLrBVPL76xuOrf+k6+04ytuAUhGYBkL+/P1xcXBATE5NjudwPDg42+5yAgABV+5OSkoL4+HiUK1cOo0aNUvlARiEhISqfyFSdOnWwePHiPMvi4eGhLrnJyVBcJ0RxvrYt4vYW3IPVAxHi54lLCSnYEnkNneqZfz/YEh5ffePx1T83nXwnFWYbNEuCdnd3R+PGjVUzlmntjdw3bRIzR5q5pPksIyNDBTbSDGYkPcCOHz+eY/0TJ06gUqVKxbAVRJbn7OyEbtkzxLM3GBGR7nqBSbPTF198gW+//RZHjx5VvbqSkpJUs5bo27dvjiRpyQtasmQJIiMjsXnzZnTq1EkFTZI3ZPT6669j+/btqgns1KlTKo9n3rx5eOWVVzTZRqKi6HZ7UMS1x2KRmKKP5EQiIluiaQ5Qr169EBcXh3HjxiE6Ohrh4eFqYMOgoFtjoZw9e1b1DDOSpi8ZC0gCoJIlS6ou8NI1vlSpUtnr3H///fj1119V4CSDJko3+OnTp+O5557TZBuJiiIsxBc1AkviZOwNrDoUjaebhHJHEhFZkOZJ0EOHDlUXczZs2JDjfqtWrdTAhnfz2GOPqQuRvZIk/+7h5fDf1SfU3GAMgIiIdDYVBhGZ163BrUERt56+jNjEFO4mIiILYgBEZKMqlvVGo4qlIANCLz9wSeviEBHpCgMgIhvW/fbUGMvYG4yIyKIYABHZsC73hcDF2Qn7zycg6nKS1sUhItINBkBENsy/pAcequ6vbnNMICIiy2EARGTjpDeYkN5gGk3dR0SkOwyAiGxch7rB8HRzRuTlJBy8kKB1cYiIdIEBEJGNK+nhinZ1bg0O+tu+i1oXh4hIFxgAEdlRb7Dl+y8iU/rFExHRPWEARGQHWtUMgJ+XG2Kvp2J7ZLzWxSEisnsMgIjsgLurMzrXD1G32RuMiOjeMQAisrPeYH8cjEZKeqbWxSEismsMgIjsRNPKZRDi54nrqRnYcDxW6+IQEdk1BkBEdsLZ2QndGtyqBWJvMCKie8MAiMgOe4OtPRaLxJR0rYtDRGS3GAAR2ZE6IT6oEVgSaRlZWHUoWuviEBHZLQZARHbEyckpOxmavcGIiIqOARCRnTaDbT0dj9jEFK2LQ0RklxgAEdmZ0DLeaFSxFGRe1OUHLmldHCIiu8QAiMgO9Wh4qxaIzWBEREXDAIjIDsmo0C7OTjhwPgGRcTe0Lg4Rkd1hAERkh/xLeuCh6v7q9rL9nCGeiKiwGAAR2akeDf8dFNEgCUFERFRgDICI7FT7sGB4ujkj6nISDl5I0Lo4RER2hQEQkZ0q6eGKdnWC1O05G06rhOhtp+ORmcXaICKiu3G96xpEZLNCS3ur6z8ORauLkAlTx3cNQ6d6IRqXjojIdrEGiMhOrTp0CXM3nr5jeXRCCgYv2KMeJyIi8xgAEdkhaeaauPwIzDV2GZfJ42wOIyIyjwEQkR3aEXUFlxLyngZDgiB5XNYjIqI7MQAiskOx11Msuh4RkaNhAERkhwJ9PC26HhGRo2EARGSHmlYpo3p7OeXxuCyXx2U9IiK6EwMgIjsk84BJV3fhlEcOkDwu6xER0Z0YABHZKRnnZ06fRgj2M9/M5eLMtzcRUV44ECKRnQdBMiWG9PaShGfJ+Vl3PAZfbIrC278eRNPKZeDn7aZ1MYmIbA4DICI7J81czauVzb7fsGIprD0ai8i4JExacQRTn26gafmIiGwR68iJdMbTzQUfP3kfnJyAxXvOY92xGK2LRERkcxgAEelQ40pl8H8tqqjbY5YcQmJKutZFIiKyKQyAiHTqPx1qoXJZb0QnpuD9FUe1Lg4Rkf0HQJGRkRYtxOzZs1G5cmV4enqiWbNm2LFjR57rpqenY9KkSahWrZpav0GDBli1alWe63/44YdwcnLC8OHDLVpmIlvn5e6Cj55soJrCFu06h40n4rQuEhGRfQdA1atXR5s2bbBgwQKkpNzbUPuLFi3CiBEjMH78eOzZs0cFNB07dkRsbKzZ9ceOHYvPP/8cs2bNwpEjRzBo0CD07NkTe/fuvWPdnTt3qnXvu+++eyojkb2SgRD7Na+sbo9efADX2RRGRFT0AEgCFQkqJHAJDg7Gyy+/nG+tTX6mTZuGgQMHon///ggLC8PcuXPh7e2N+fPnm13/+++/x5gxY9C5c2dUrVoVgwcPVrenTp2aY70bN27gueeewxdffIHSpUsXqWxEejCyUy1ULOONiwkpmPzHMa2LQ0RkvwFQeHg4ZsyYgYsXL6pA5dKlS3jooYdQr149FdDExRWsqj0tLQ27d+9Gu3bt/i2Qs7O6v23bNrPPSU1NVU1fpry8vLBly5Ycy1555RV06dIlx2sTOSJvd1dMeeJWLejCiLP4+9RlrYtERGTf4wC5urri8ccfV4HGZ599htGjR+ONN95QNTRPP/00pkyZgpCQkDyff/nyZWRmZiIoKCjHcrl/7Jj5X6rSPCZBVsuWLVUe0Nq1a7FkyRL1OkY//fSTqqWSJrCCkKBKLkaJiYnZ+UZysSTj61n6dW0Vt9c2NKnoi+eahuKHHefw1i/7sWLogyjhce/DgPH46huPr/6l6+w7qTDb4WQwGGTaoCLZtWuXqgGSgKNEiRLo168f/u///g/nz5/HxIkTVSCRX9OY1CCVL18eW7duRfPmzbOXjxw5Ehs3bkRERMQdz5HaJWkyW758uUpuliBIanmkHDdv3sS5c+fQpEkTrFmzJjv3p3Xr1qrWavr06WbLMWHCBFXe3BYuXKia44j0IDUT+HC/C66kOuHhoCw8WTVL6yIREVlUcnIyevfujYSEBPj6+lo+AJIamK+//hrHjx9X+TcvvviiupbmKyMJgqRnV0ZGRr5NYBJg/PLLL+jRo0f2cgmkrl27ht9++y3P50rydXx8PMqVK4dRo0ZhxYoVOHz4MJYuXaqSol1cXLLXldohCZakfFLTY/pYXjVAoaGhqobqbjuwKNGpBGft27eHm5v+pyjg9tqWv0/H44VvdqvbCwY0QbN7nC2ex1ffeHz1L11n30ny/e3v71+gAKhIdeBz5szBgAED8MILL+TZxBUYGIivvvoq39dxd3dH48aNVTOWMQDKyspS94cOHZrvcyUPSGqP5OAtXrxYNbmJtm3b4uDBgznWlQTr2rVr46233roj+BEeHh7qkpucDMV1QhTna9sibq9taF07GM82rYgfd5zFmKVHsGr4wypH6F7x+Oobj6/+uenkO6kw21CkTz6JFitWrJijxkdIZZI0QcljEtxITc7dSE8yWU+arZo2baqaqZKSklTQIvr27asCncmTJ6v70ix24cIF1aQl19J8JUGTNJsJHx8flYxtSprnypYte8dyIkc0pnNtbDwei7NXkvHxn8cxvmtdrYtERGQfvcAk70aah3K7cuUKqlS5Nfx+QfXq1Qv//e9/MW7cOBXU7Nu3Tw1saEyMPnv2rOplZtr0JWMBSZd5aeqS4Eh6gJUqVaoom0LkcHw83TD5dq+wb7b+g53/XNG6SEREVlekGqC80oZk7J3cXdQLQpq78mry2rBhQ477rVq1UgMgFkbu1yBydK1qBuDpJhXw867zGPnLAax87WE1cjQRkaMoVAAkzVVCEoqlxsa0h5QkGkvzlNTiEJHte7tLmJoeI+pyEqatOa7uExE5ikIFQMbpJqQGSBKNJc/HSG7LNBYyDhAR2T4/LzdMfrw+BnyzC19uiUKneiFoXImjphORYyhUALR+/Xp1LQnKMhK0pbuIE5F1PVI7CI83Ko8ley5g5C/78ftrD8PTjU1hRKR/RUqCljGAGPwQ6cO4x8IQ4OOB03FJmP7XSa2LQ0RkWzVAMuXFN998owIfuZ0fmZqCiOxDKW93vN+jHl76fjfmbTqNTvWCER7KXpVEpG8FrgHy8/NTyc/G2/ldiMi+dKgbjO7h5ZBlAN78336kZvw7tx4RkUPXAEmzl7nbRKQPE7rWVTPFn4y9gZlrT+LNjrW1LhIRkW3lABGR/pQu4Y53u98aLX3uxkgcPJ+gdZGIiLSvAWrYsGF2E9jd7Nmz517KREQaebR+CLrcF4LfD1zCm7/sx7KhD8Hdlb+TiMiBAyDT2dqJSL8mdauLbafjcSz6Oj5dfwoj2tfUukhERNoFQOPHj7f8fycim1O2pAcmdquLV3/ci8/Wn0LHukGoW46dG4hIX4pct33t2jV8+eWXGD16tJoE1dj0JTO0E5F9e+y+EHSqG4yMLAPe/N8BpGdmaV0kIiLtA6ADBw6gZs2amDJliprJXYIh4/g/EhARkX2TfL93e9RDKW83HLmUiDkbTmtdJCIi7QMgmRT1hRdewMmTJ3PM/t65c2ds2rTJkuUjIo3I6NDSFCZmrTuJY9GJPBZE5NgB0M6dO/Hyyy/fsbx8+fKIjo62RLmIyAZ0a1AO7eoEIT3zVlNYBpvCiMiRAyAPDw8kJt75a/DEiRMICAiwRLmIyEaawj7oWQ++nq44eCEBn2+K1LpIRETaBUDdunXDpEmTkJ6env0hefbsWbz11lt44oknLFMyIrIJgb6eGN/1VlPYjL9O4mTMda2LRESkTQA0depU3LhxA4GBgbh58yZatWqF6tWrw8fHB++///69l4qIbMrjjcqjTa0ApGVm4Y1f2BRGRA40DpApmfB0zZo12LJli+oRJsFQo0aN0K5dO8uXkIhsoyns8froMG0T9p+7hq+2ROHlVtW0LhYRkXUDIKOHHnpIXYhI/0L8vPDOY2EYufgApq45gTa1AxGbkIzdl51QNuoKmlcPhItzwabLISKymwBo5syZBX7R1157rajlISIb9lSTClhx8BI2nYhDl5mbVe8wwAXfndyFED/JFQpDp3ohWheTiMhyAdAnn3yS435cXBySk5NRqlQpdV8GQ/T29lZ5QQyAiPTbFCZTY0gAdCv4+Vd0QgoGL9iDOX0aMQgiIv0kQUdFRWVfJNE5PDwcR48eVdNgyEVuSx7Qu+++W7wlJiLNZGYZ8Om6U2YfM4ZDE5cfUesREemuF9g777yDWbNmoVatWtnL5LbUEo0dO9aS5SMiG7Ij6gouJaTk+biEPfK4rEdEpLsA6NKlS8jIyLhjeWZmJmJiYixRLiKyQbHXUyy6HhGRXQVAbdu2VVNhyOzvRrt378bgwYPZFZ5IxwJ9PC26HhGRXQVA8+fPR3BwMJo0aaKmxZBL06ZNERQUhC+//NLypSQim9C0ShnV2yuvzu6yXB6X9YiIdDcOkMz3tXLlSjX317Fjx9Sy2rVro2bNmpYuHxHZEBnnR7q6S28vCXbMpTrL4xwPiIh0PRCiBDwMeogci4zzI13dpbdX7oToIW2qsQs8EekrABoxYoTq4l6iRAl1Oz/Tpk2zRNmIyIaDoPZhwdh2KharN0fgskc5rDwUg79PxeONDgY1XhARkS4CoL1796rmroYNG6rbeeEHH5FjkGauZlXKIP6oAU1b1sbaY3HYd+4aNp28jFY1A7QuHhGRZQKg9evXw8XFRXWBl9uiV69eaooMSX4mIsflX9IDzzWrhPl/R2HGXyfQsoY/fwwRkX56gRkMOVMe//jjDyQlJVm6TERkhwa1qgoPV2fsOXtNNYUREemuG3xeAREROa5AX08827Siuj1j7Ql+PhCRfgIgye/JnePDnB8iMhrUqhrcXZyx85+r2BbJWiAi0kk3eKnxeeGFF9TAhyIlJQWDBg1SPcNMLVmyxLKlJCK7EOzniWeahuK7bWcw46+TeLCav9ZFIiK69wCoX79+Oe736dOnME8nIgepBfpxx1lERF3B9sh4PFC1rNZFIiK6twDo66+/LszqROSAypXywtNNQvFDxFnMXHuSARAR6S8JmojInCFtqsPNxQlbT8dj5z9XuJOIyObYRAA0e/ZsVK5cGZ6enmjWrBl27NiR57rp6emYNGkSqlWrptZv0KABVq1alWOdyZMn4/7774ePjw8CAwPRo0cPHD9+3ApbQkSifCkvPNm4grottUBERLZG8wBo0aJFamqN8ePHY8+ePSqg6dixI2JjY82uP3bsWHz++eeYNWsWjhw5opKwe/bsmWN06o0bN+KVV17B9u3bsWbNGhU0dejQgWMWEVnRkNbV4ershM0nL2P3mavc90RkUzQPgGTesIEDB6J///4ICwvD3Llz4e3tjfnz55td//vvv8eYMWPQuXNnVK1aFYMHD1a3p06dmr2O1AhJb7W6deuqgOqbb77B2bNnsXv3bituGZFjCy3jjccblVe3WQtERLZG0wAoLS1NBSXt2rX7t0DOzur+tm3bzD4nNTVVNX2Z8vLywpYtW/L8PwkJCeq6TJkyFis7Ed3d0DY11JxhG0/cmieMiMgue4FZ2uXLl5GZmXnHXGJyXyZeNUeax6TWqGXLlioPaO3atWrcIXkdc7KysjB8+HC0aNEC9erVyzOokotRYmKiupamM7lYkvH1LP26torb69jHN8TXDd0bhGDJ3ov4ZM1xfPl8I9gzns/65mjHV4/bXJjtcDJoOJ/FxYsXUb58eWzduhXNmzfPXj5y5EiVxxMREXHHc+Li4lST2fLly9Uo1BIESY2RNJndvHnzjvWliUzmLJMaogoVbiVl5jZhwgRMnDjxjuULFy5UzXFEVHSxN4EP9rnAACf8p34GKpbk3iSi4pGcnIzevXurlh9fX1/brQHy9/dXM8zHxMTkWC73g4ODzT4nICAAS5cuVaNQx8fHo1y5chg1apTKB8pt6NChWLFiBTZt2pRn8CNGjx6tErFNa4BCQ0NV4vTddmBRolNJzG7fvj3c3Nygd9xefSvo8T1sOIil+y9hb1oIBnVuCHvF81nfHO346nGbjS04BaFpAOTu7o7GjRurZizpqm5sspL7ErzkR/KApPZIDt7ixYvx9NNPZz8mlVqvvvoqfv31V2zYsAFVqlTJ97Vkag/j9B6m5GQorhOiOF/bFnF7Hfv4vtquJpYduIR1x+NwPDYZ9cr7wZ7xfNY3Rzu+etrmwmyD5r3ApObliy++wLfffoujR4+qJqukpCTVK0z07dtX1dAYSbOY5PxERkZi8+bN6NSpkwqapNnMSLrAL1iwQDVhyVhA0dHR6mKuiYyIil+1gJLo2qCcus0eYURkCzStARK9evVSeT3jxo1TQUp4eLjqxm5MjJbu69IzzEiavmQsIAmASpYsqbrAS9f4UqVKZa8zZ84cdd26des7pvKQ7vFEZH2vPlIdy/ZfxOojMThyMRFh5SzbvExEZFcBkJDmrryavKQJy1SrVq3UAIj50TCvm4jyUD3QB13qh2DFgUuYte4k5vRpzH1FRJrRvAmMiBzHa21rqOs/DkXjWHTBkxWJiCyNARARWU3NIB90rn+rh+esdae454lIMwyAiEiTWqCVBy/hZMx17n0i0gQDICKyqtrBvuhUNxiSqjeTtUBEpBEGQERkda+2ra6uVxy4iFOxN3gEiMjqGAARkdXVLeeH9mFBqhbo03UneQSIyOoYABGRJl575FYukIwNFBnHWiAisi4GQESkifoV/NC2diCypBZoPXuEEZF1MQAiIs17hP227yL+uZzEI0FEVsMAiIg00yC0FFrXCkBmlgGzWQtERFbEAIiIbKIWaMneCzgbn8yjQURWwQCIiDTVqGJpPFzDX9UCfbaBuUBEZB0MgIhIc8Pb3aoF+mX3eZy7wlogIip+DICISHONK5XBQ9X9kZFlwJyNp7UuDhE5AAZARGRTuUD/23UOF67d1Lo4RKRzDICIyCY0rVIGzauWRXqmAXOYC0RExYwBEBHZXC3QzzvP41ICa4GIqPgwACIim9G8WllVE5SWmYW5G5gLRETFhwEQEdmU4bdrgX7ceQ4xiSlaF4eIdIoBEBHZXC1Qk0qlkZaRhbnsEUZExYQBEBHZFCcnJwy7PS7QwoiziGUtEBEVAwZARGRzZEyghhVLITUjC/M2RWpdHCLSIQZARGSbtUC3c4EWRJxB3PVUrYtERDrDAIiIbFKrmgFqtviU9Cx8uZm1QERkWQyAiMiGa4Gqq9vfbTuD+BusBSIiy2EAREQ2q02tQNQv74eb6Zn4ckuU1sUhIh1hAERENl0LZBwd+rut/+BqUprWRSIinWAAREQ2rV2dQNQt54ukNKkFYi4QEVkGAyAisptaoG+3nsG1ZNYCEdG9YwBERDavfZ0g1A72wY3UDMxnLhARWQADICKyec7O/44LJAHQX0dj8Nu+C9h2Oh6ZWQati0dEdshV6wIQERVEx7rBKOfniYsJKXjx213Zy0P8PDG+axg61QvhjiSiAmMNEBHZhdVHolXwk1t0QgoGL9iDVYcuaVIuIrJPDICIyOZJM9fE5UfMPmZsAJPH2RxGRAXFAIiIbN6OqCu4ZKb2xzQIksdlPSKigmAAREQ2L/Z6ikXXIyJiAERENi/Qx9Oi6xERMQAiIpvXtEoZ1dvLKZ91Akp6qPWIiAqCARAR2TwXZyfV1V3kFQTJhKknYq5btVxEZL8YABGRXZBxfub0aYRgv5zNXEG+Hggt46VGiX72i+04dCFBszISkf2wiQBo9uzZqFy5Mjw9PdGsWTPs2LEjz3XT09MxadIkVKtWTa3foEEDrFq16p5ek4jsJwja8tYj+HHgA5jxTLi63jqqLVa8+jDCQ0vhWnK6CoL2nr2qdVGJyMZpHgAtWrQII0aMwPjx47Fnzx4V0HTs2BGxsbFm1x87diw+//xzzJo1C0eOHMGgQYPQs2dP7N27t8ivSUT21RzWvFpZdA8vr67lvp+XG77/v6a4v3JpXE/JwPNf7cCuf9glnohsOACaNm0aBg4ciP79+yMsLAxz586Ft7c35s+fb3b977//HmPGjEHnzp1RtWpVDB48WN2eOnVqkV+TiOyfj6cbvunfFM2rllXNYX3n71BzhRER2dxcYGlpadi9ezdGjx6dvczZ2Rnt2rXDtm3bzD4nNTVVNWuZ8vLywpYtW+7pNeVilJiYmN3cJhdLMr6epV/XVnF79c3Wjq+7M/D5c+EYvHAf/j4dj/7f7MDc5xqiRbWyutze4sbt1b90nZ3ThdkOTQOgy5cvIzMzE0FBQTmWy/1jx46ZfY40ZUkNT8uWLVUe0Nq1a7FkyRL1OkV9zcmTJ2PixIl3LF+9erWqOSoOa9asgSPh9uqbrR3fnv7A1XhnHLkGNXHqgFpZqFvaoNvtLW7cXv1bo5NzOjk5Wb+zwc+YMUM1b9WuXRtOTk4qCJKmrntp3pLaIskZMq0BCg0NRYcOHeDr6wtLR6dyorVv3x5ubm7QO26vvtny8X20UxaG/3wAa47G4uuTrpjZqwHa1QnU7fYWB26v/qXr7Jw2tuDYfADk7+8PFxcXxMTE5Fgu94ODg80+JyAgAEuXLkVKSgri4+NRrlw5jBo1SuUDFfU1PTw81CU3ORmK64Qozte2RdxefbPF4yvF+axPYwz/aR9+P3gJr/60HzOeaYgu94XocnuLE7dX/9x0ck4XZhs0TYJ2d3dH48aNVTOWUVZWlrrfvHnzfJ8reUDly5dHRkYGFi9ejO7du9/zaxKRvri5OKvu8j3CyyEjy4BXf9yD3/Zd0LpYRGQDNG8Ck6anfv36oUmTJmjatCmmT5+OpKQk1awl+vbtqwIdydMRERERuHDhAsLDw9X1hAkTVIAzcuTIAr8mETkOVxdnTH06XF3/svs8hi/ah7SMLDzVJFTrohGRIwdAvXr1QlxcHMaNG4fo6GgV2MjAhsYk5rNnz6peXEbS9CVjAUVGRqJkyZKqC7x0jS9VqlSBX5OIHIuMFfTRE/fB3dUZCyPO4s1fDiA904DezSpqXTQictQASAwdOlRdzNmwYUOO+61atVIDIN7LaxKR43F2dsL7PerB3cUZ32z9B2N+PYj0zCz0e7Cy1kUjIkccCJGIyFqk56hMqvpSy1udJsYvO4wvN0fyABA5IAZARORwQdDoR2tjaJvq6v57vx/F7PWntC4WEVkZAyAicsgg6I2OtTCifU11/+M/j2P6XydgMFhusEQism0MgIjIYb3WtgZGdqqlbk//66QKhBgEETkGBkBE5NCGtK6OsV3qqNufbTiN938/yiCIyAEwACIih/fiw1UxqXtdtR++3BKFCcsOIyuLzWFEesYAiIhIBl1tXhmTH68PJyfg221n8PbSgwyCiHSMARAR0W3PNq2Ij59sAGcn4Mcd59SAiZmsCSLSJQZAREQmnmxcAZ/0ClejRy/ecx4jft6HjMwsFQhFRF3B7stO6pqBEZF9s4mRoImIbEn38PJqxOhXf9yL3/ZdxLkrybh4LQXRiSkysQa+O7kLIX6ealDFTvXufXZ5IrI+1gAREZnxaP0QzOnTGK7OTthz9trt4Odf0QkpGLxgD1YdusT9R2SHGAAREeXhkdqB8PE0X1Fu7CM2cfkRNocR2SEGQEREedgRdQVXk9Pz3D8SBF1KSFHrEZF9YQBERJSH2OspFl2PiGwHAyAiojwE+nhadD0ish0MgIiI8tC0ShnV28spnz1UtoS7Wo+I7AsDICKiPMhYQNLVXeQVBCXcTMfKg+wJRmRvGAAREeVDxvmZ06cRgv1yNnPJ/fBQP2RkGdR4QfM2neYkqkR2hAMhEhEVIAhqHxaMbadisXpzBDo83AzNqweqx95dcQTfbP0HH6w8hgtXb2Jc17qq5oiIbBtrgIiICkCCmmZVyqCxv0Fdy325TOhWF2O71FHryCSqgxbsxs20TO5TIhvHAIiI6B69+HBVzO7dCO6uzlhzJAbPfrEd8TdSuV+JbBgDICIiC+hyXwh+eLEZSnm7Yd+5a3h8zlZEXU7iviWyUQyAiIgs5P7KZbB48IMILeOFM/HJeGLOVuw+c5X7l8gGMQAiIrKgagElsWRwC9xXwQ9XktLQ+4vtWHUomvuYyMYwACIisrAAHw/89NIDaFs7EKkZWRj8w25883cU9zORDWEARERUDLzdXfH5843xXLOKMBiACcuP4L0VR5CVZZxHnoi0xACIiKiYuLo4470e9TCyUy11/8stUWrQxJR0dpMn0hoDICKiYuTk5IQhratjxjPhcHNxwu8HL+H5ryJwLTmN+51IQwyAiIisoHt4eXw7oCl8PF2x85+rqpv8uSvJ3PdEGmEARERkJQ9W81fd5Mv5eSIyLgk9P/sbB85f4/4n0gADICIiK6oZ5INfX2mBsBBfXL6Rhl6fb8faozE8BkRWxgCIiMjKgnw98fOg5ni4hj9upmdi4He78EPEGR4HIitiAEREpIGSHq6Y/8L9eKpxBUjP+Ld/PYSPVh1jN3kiK2EARESkETcXZ3z05H0Y3q6Guv/ZhtMY8fM+pGVk8ZgQFTMGQEREGneTH96uJj5+8j64Ojth6b6L6Dd/BxJupvO4EBUjBkBERDbgqSahqklMmsa2RcbjqblbceHaTWRmGbDtdDx+23dBXct9Irp3rhZ4DSIisoCWNQOw6OUHMOCbnTgRcwOdZ2xSzWTSW8woxM8T47uGoVO9EO5zonvAGiAiIhtSt5wffh3SQgU6CTczcgQ/IjohBYMX7MGqQ5c0KyORHjAAIiKywW7yWTKDqhnGpROXH2FzGJE9B0CzZ89G5cqV4enpiWbNmmHHjh35rj99+nTUqlULXl5eCA0Nxeuvv46UlJTsxzMzM/HOO++gSpUqap1q1arh3XffhSGPDxMiIluzI+oKYhJT83xcPs0uJaSo9YjIDnOAFi1ahBEjRmDu3Lkq+JHgpmPHjjh+/DgCAwPvWH/hwoUYNWoU5s+fjwcffBAnTpzACy+8oHpRTJs2Ta0zZcoUzJkzB99++y3q1q2LXbt2oX///vDz88Nrr72mwVYSERVO7PUUi65HRDZWAyRBy8CBA1WAEhYWpgIhb29vFeCYs3XrVrRo0QK9e/dWtUYdOnTAs88+m6PWSNbp3r07unTpotZ58skn1Xp3q1kiIrIVgT6eBVpPeoWlpGcWe3mI9EizGqC0tDTs3r0bo0ePzl7m7OyMdu3aYdu2bWafI7U+CxYsUMFM06ZNERkZiZUrV+L555/Psc68efNU7VDNmjWxf/9+bNmyJbuGyJzU1FR1MUpMTFTX6enp6mJJxtez9OvaKm6vvvH4Fo+GFXwQ7OuhmsHya7z/aec5bD4Zh/+0r4HH6ger2nBL4vHVv3SdfScVZjucDBolx1y8eBHly5dXNTbNmzfPXj5y5Ehs3LgRERERZp83c+ZMvPHGGyqnJyMjA4MGDVJNXkZZWVkYM2YMPvroI7i4uKicoPfffz9HoJXbhAkTMHHiRLNNblIjRURkbfvjnTD/hLGS3jSwufWR3TI4CweuOONa2q3HKpU0oGflTFTx4bEix5WcnKxaiRISEuDr66ufcYA2bNiADz74AJ999pnKGTp16hSGDRumkpwl8Vn8/PPP+OGHH1TwIjlA+/btw/Dhw1GuXDn069fP7OtKcCS5SKY1QJJgLU1nd9uBRYlO16xZg/bt28PNzQ16x+3VNx7f4tMZQKPDMXhv5TFEmyRES/f4tx+tjY51g3AzLRNfbz2DeZujcOZGJqYfckWnukF4s0MNVCxz7z/eeHz1L11n30nGFpyC0CwA8vf3VzU0MTExOZbL/eDgYLPPkSBHmrtefPFFdb9+/fpISkrCSy+9hLfffls1ob355psqUfqZZ57JXufMmTOYPHlyngGQh4eHuuQmJ0NxnRDF+dq2iNurbzy+xeOx8Ap49L7yqreXJDxLblDTKmXg4uyUvd+Hta+FZx+ohE/WnMCineew6nAM1h2LQ78HK2HoIzXg53XvnzM8vvrnppPvpMJsg2ZJ0O7u7mjcuDHWrl2bo/lK7ps2ieWu2pIgx5QEUcLYkpfXOvLaRET2RoKd5tXKont4eXVtDH5MSWA0+fH7sHLYw3i4hj/SMrPwxeYotP54Pb75Owrpmfz8I7KpJjBpdpJamSZNmqikZukGLzU60itM9O3bV+UJSe2N6Nq1q0pmbtiwYXYTmNQKyXJjICS3JeenYsWKqgls79696jkDBgzQclOJiIpd7WBffP9/zbDheCw+WHlUTacxYfkRfLftDEZ3roN2dQItnihNZK80DYB69eqFuLg4jBs3DtHR0QgPD8eqVasQFBSkHj979myO2pyxY8eqN69cX7hwAQEBAdkBj9GsWbNUUDRkyBDExsaq3J+XX35Z/Q8iIkfQulYgHqruj0W7zqmmscjLSRj43S48ULUMxnYJQ73yfloXkUhzmidBDx06VF3ySno25erqivHjx6tLXnx8fFRNklyIiByVq4sznmtWCd0alMOcDafx5ZYobI+8gq6fbsHjDSvgzY61EOxXsPGGiPRI86kwiIio+Ph4umFkp9pY/0Zr9AgvB0mXXLznPFr/dz2mrTmBpNQM7n5ySAyAiIgcQPlSXpj+TEMsfaUF7q9cGinpWZi59iTa/HcDft55jhOrksNhAERE5EDCQ0vh55ebY85zjVCprDdir6di5OID6DJzM7acvJy9XmaWARFRV7D7spO6lvtEeqJ5DhAREVmXdCZ5tH4IHqkTiO+3nVE1Qceir6PPVxF4pHag6ko/b1OkmnEecMF3J3epARjHdw1Dp3ohPFykC6wBIiJyUB6uLnjx4arY+GYb9G9RGa7OTlh3LBYTlx+5Hfz8KzohBYMX7MGqQ5c0Ky+RJTEAIiJycKVLuGN817r4Y9jD8HA1/7VgbACT4IjNYaQHDICIiEi5fCMNqRl5jxotQZDUDMnUHET2jgEQEREpMt9YQSzY/o9qEiOyZ0yCJiKi7DnFCuL3g9H441A0WtUMQK/7Q/FI7SC459F0RmSrGAAREZEiM81Lby+p3THX6V1mEZPZ5WsElcTOf65i/fE4dSlbwh1PNK6Ap5uEonpgSe5NsgsM2YmISJGZ5qWru8g9Zarx/odP1Mf/Bj2oRpYe3LoaAnw8EJ+UprrNt5u2EU/M2aoGVuQI02TrGAAREVE2GednTp9Gd8wTJvdluXEcoCr+JfBWp9rYNuoRfNG3CdrVCVIB1O4zV9XAik3f/wujFh/AnrNXYZD5N4hsDJvAiIgoBwly2ocFY9upWKzeHIEODzdD8+qBKsC540vExRntw4LUJTYxBb/sOY//7TqPqMtJ+GnnOXWpEVhS5Qr1bFgeZUt6cG+TTWAAREREd5Bgp1mVMog/alDX5oKf3AJ9PTGkdXUMblVNdZVftOscVh68hJOxN/De70cxZdUxFShJrtDDNQLMvqaMMSTPlR5pkpTdtID/m6iwGAAREZHFp9poVrWsukzoVhfL9l3Ez7vO4cD5BKw8GK0u5fw88WTjCniqSShCy3ir58ko07lHoeYUHFRcGAAREVGx8fV0Q58HKqnLkYuJKhD6de8FXExIwcx1pzBr/Sm0qOaPWsE+mL8l6o7eZ8YpOEzzj4gsgUnQRERkFWHlfFWNUMSYtpj5bEM8VN0fkh+95dRlfGUm+BGcgoOKCwMgIiKyKk83F3RrUA4LXmyGzSPb4PGG5fJd3zgFx4LtZ3Dx2k2kZ+Y9XUdRSe5RRNQV7L7spK6tNd+Z/J9tp+Px274L6przrFkPm8CIiEgzkv/TqlYgluy9eNd1xy87rC5OTkBASQ/VNT/Y11PlCQX53b5W973Uci93lwKVIWfukQu+O7nLKrlHzHnSFgMgIiKyiyk4/Eu4IyElHemZBsReT1WXA0jIc30ZtfrfoMjk+nawFOLrha2nL2PID3usnnskwY+8PnOetMMAiIiIbH4KDqnt2fLWI+q2jDwdk5iiamyiE24i+vbtf5elIDktEwk309XlWPT1QpfJWI6RvxxQ/8/T1UXNd2a8eLj8e1tdbt/3uL2ex+1lznl09Zcap7xynuQZ8riMxcQhAIoPAyAiIrKJKTikRkS+/E0DA2P4II8bgwGZfkMu9cr7mX09GXn6emqGCoSMFxUYJRoDplR1fTU5/a5lS0zJwNu/Hirytrk6O90RJEkAZNrVP6+cJxkPqXm1skX+35Q/BkBERGQzU3DkHgcouAi5ODIOkXS/l0vNIJ881/tl9zm88b8Dd329euV8UbqEO9IyspCWmXXrOvftjCyk3r5vKiPLgIy0TFUjVViDF+zGfaGl1EjaNYNKonqgj5qIVrbL0onfZSXYymO0b71iAERERDY1BYe1RoIuX+rWAIx383aXsALXxEjtk+QoSXCUmp6ZI0hKvR007T17Fe+uOHrX17p2Mx2bTsSpiylJ8JZAqMbtgMgYHEnOU0Gt0ijx25ZG+2YARERENkO+CK3V7FPQ3CNZrzC1T+6ut5q9SnqY/4ptUKEUvtwcle//DfT1wKxnG+J0XBJOxtzAydjr6lo1492+bD55Ocfzgnw9soMiua55+9rP281mErBX2dBo3wyAiIjIIRU298ia/3dit7poWqWsupiSpO5TsTdwMua6mmPtRMx1df9WEniqusjAkqYCfTyyg6JqgSUwfc1JTRKwba3nGwMgIiJyWJbMPbLG/5VmrsaVSquLqcQUk8Ao5gZO3L4tr20cMuDvU/F3LZfhdgL2wO92oUJpL7g6O8PNxQmucsm+7aySu93k2sUJbs63rmW5++311PLb68lyiaXGLj1kUz3fGAAREZFDM+YebTsVi9WbI9Dh4WZWSQi2ZM6TJEY3qlhaXUxdT0lXNUWnJCiKuY6/T13G0QIMC7DuWCysSYuebwyAiIjI4UnQ0axKGcQfNahra9VCFHfOk0+uwEim23j2i+13fd5TjSuo3Jx06cWWmaUSuzOyspCReSvJW6Yjkftqubp9e5k8dvs5t27fuk68ma6Suu9GAkFrYQBERETkIAqa+P3hE/dZNAgsaOBV0FHBLYGToRIRETkIYwK2yB3eFGfitzHwyutVZXlIIXvc3SsGQERERA7EmIAd7JeztkXuF1dPLK0Cr/ywCYyIiMjBdNIg8VurHnd5YQBERETkgFw0SPy29mjf+WEARERERLoc7Ts/zAEiIiIih8MAiIiIiBwOAyAiIiJyOAyAiIiIyOFoHgDNnj0blStXhqenJ5o1a4YdO3bku/706dNRq1YteHl5ITQ0FK+//jpSUnIOnX3hwgX06dMHZcuWVevVr18fu3btKuYtISIiInuhaS+wRYsWYcSIEZg7d64KfiS46dixI44fP47AwMA71l+4cCFGjRqF+fPn48EHH8SJEyfwwgsvwMnJCdOmTVPrXL16FS1atECbNm3wxx9/ICAgACdPnkTp0jkniCMiIiLHpWkAJEHLwIED0b9/f3VfAqHff/9dBTgS6OS2detWFdz07t1b3Zeao2effRYRERHZ60yZMkXVDH399dfZy6pUqWKV7SEiIiL7oFkAlJaWht27d2P06NHZy5ydndGuXTts27bN7HOk1mfBggWqmaxp06aIjIzEypUr8fzzz2evs2zZMlWL9NRTT2Hjxo0oX748hgwZogKtvKSmpqqLUWJiorpOT09XF0syvp6lX9dWcXv1jcdX33h89S9dZ99JhdkOJ4PBYG5C2GJ38eJFFZxIrU7z5s2zl48cOVIFLqa1OqZmzpyJN954A1LsjIwMDBo0CHPmzMl+XHKJhDStSRC0c+dODBs2TNUu9evXz+xrTpgwARMnTjTb5Obt7W2BrSUiIqLilpycrFqJEhIS4Ovrq5+RoDds2IAPPvgAn332mcoZOnXqlApu3n33XbzzzjtqnaysLDRp0kStJxo2bIhDhw7lGwBJLZQETEay4ypWrKgCMx8fH4tHp+vXr1c5Sm5ubtA7bq++8fjqG4+v/qXr7Dvp+vXr6rogdTuaBUD+/v5wcXFBTExMjuVyPzg42OxzJMiR5q4XX3xR3ZfeXUlJSXjppZfw9ttvqya0kJAQhIXdmnHWqE6dOli8eHGeZfHw8FCX3E1gzB0iIiKyz0DIz8/PNgMgd3d3NG7cGGvXrkWPHj2ya2/k/tChQ/Os2pIgx5QEUabRniRJSy8yU9JbrFKlSgUuW7ly5XDu3DlV+yM9zCxJgitJ0pbXv1v1nB5we/WNx1ffeHz1L1Fn30kSC0jwI9/jd6NpE5g0O0mzlDRZSVKzdIOXGh1jr7C+ffuqPKHJkyer+127dlU9x6RZy9gEJrVCstwYCMm4QJIsLU1gTz/9tEqYnjdvnroUlARZFSpUQHGSE00PJ1tBcXv1jcdX33h89c9XR99Jd6v5sYkAqFevXoiLi8O4ceMQHR2N8PBwrFq1CkFBQerxs2fP5qjxGTt2rKqRkWsZ7FDG+JHg5/33389e5/7778evv/6q8nomTZqkmrEksHruuec02UYiIiKyPZr1AnNUUt0o0WlBMtT1gNurbzy++sbjq3+JDvadZFNTYTgaSbYeP358jqRrPeP26huPr77x+Oqfh4N9J5liDRARERE5HNYAERERkcNhAEREREQOhwEQERERORwGQERERORwGABZgQzkKOMTycjSgYGBauTr3KNV69mHH36oxm8aPnw49EzGpurTpw/Kli0LLy8vNVXLrl27oEeZmZlqEFIZZ0u2tVq1ampOPr2MqrFp0yY1xpiMJivn7tKlS3M8Ltsp45fJ1Duy/e3atcPJkyehx+2VuaLeeustdT6XKFFCrSOD1MqE1no9vqZkwm1ZR8aT0/P2Hj16FN26dVNd4uU4y3eWjMWnZwyArEBmt3/llVewfft2rFmzRn2gdOjQQY16rXc7d+7E559/jvvuuw96dvXqVTUNi0wm+Mcff+DIkSOYOnUqSpcuDT2aMmUK5syZg08//VR9cMr9jz76CLNmzYIeyHuzQYMGmD17ttnHZVtnzpypJlmOiIhQXxgdO3ZESkoK9La9MgXRnj17VMAr10uWLFE/4OTLUq/H10gG1ZXP7YJMq2DP23v69Gk89NBDqF27tpp0/MCBA+p4e3p6QtdkIESyrtjYWPmZbNi4caOud/3169cNNWrUMKxZs8bQqlUrw7Bhwwx69dZbbxkeeughg6Po0qWLYcCAATmWPf7444bnnnvOoDfyXv3111+z72dlZRmCg4MNH3/8cfaya9euGTw8PAw//vijQW/ba86OHTvUemfOnDHodXvPnz9vKF++vOHQoUOGSpUqGT755BODHpjb3l69ehn69OljcDSsAdKAjLgpypQpAz2TWq8uXbqo5gG9W7ZsmZrT7qmnnlLNnDJf3RdffAG9kvn2ZOJimWhY7N+/H1u2bMGjjz4KvYuKilJT95ie19JsIPMTbtu2DY7yGSZNKaVKlYIeycTczz//PN58803UrVsXepaVlYXff/8dNWvWVLWY8vkl53J+zYJ6wQBIg5NNcmGkuaRevXrQq59++klVlxsnstW7yMhI1SRUo0YN/Pnnnxg8eDBee+01fPvtt9CjUaNG4ZlnnlFV5tLsJwGfnNeOMOeeBD/COGehkdw3PqZn0swnOUHPPvusbqdOkCZdV1dX9R7Wu9jYWNy4cUPlanbq1AmrV69Gz5498fjjj6v0DT3TdDJURyS1IocOHVK/lvXq3LlzGDZsmMp30n0bsklgKzVAH3zwgbovAYEcZ8kR6devH/Tm559/xg8//ICFCxeqX8j79u1TAZDkSuhxe+kWyV98+umnVRK4BPx6tHv3bsyYMUP9gJNaLkf47BLdu3fH66+/rm7LxORbt25Vn1+tWrWCXrEGyIqGDh2KFStWYP369ahQoQL0Sj5A5FdFo0aN1K8oucgvCUkaldvSg0hvpDdQWFhYjmV16tTRbS8KaRow1gJJ7yBpLpAPT0eo8QsODlbXMTExOZbLfeNjeg5+zpw5o37c6LX2Z/Pmzerzq2LFitmfX7LN//nPf1C5cmXojb+/v9pGR/r8MmINkBXIr6VXX31V9SiQDHvpOqxnbdu2xcGDB3Ms69+/v2oukapzFxcX6I00aeYe2kDyYypVqgQ9kp5Bzs45fz/JcTX+mtQzef9KoCM5UPJL2TijtvQGk6ZPPQc/0tVffsDJUA96JcF87rxFyY2R5fI5pjfu7u6qy7sjfX4ZMQCyUrOXNBX89ttvaiwgY56AJE7KGCJ6I9uYO79JugnLh6Ze856k9kMSg6UJTL4oduzYgXnz5qmLHsmYIu+//776lSxNYHv37sW0adMwYMAA6IHkRJw6dSpH4rM080nHBdlmae577733VM6XBETSZVia/2SML71tr9RuPvnkk6pJSGqwpQbX+Bkmj8sXqN6Ob+4AT/LcJOitVasW7NHdtvfNN99Er1690LJlS7Rp0warVq3C8uXL1Q92XdO6G5ojkN1s7vL1118bHIXeu8GL5cuXG+rVq6e6Q9euXdswb948g14lJiaq41mxYkWDp6enoWrVqoa3337bkJqaatCD9evXm33P9uvXL7sr/DvvvGMICgpSx7tt27aG48ePG/S4vVFRUXl+hsnz9Hh8c7P3bvAF2d6vvvrKUL16dfV+btCggWHp0qUGvXOSP1oHYURERETWxCRoIiIicjgMgIiIiMjhMAAiIiIih8MAiIiIiBwOAyAiIiJyOAyAiIiIyOEwACIiIiKHwwCIiIiIHA4DICLS3D///KNm3pbh+W3FsWPH8MADD8DT0zN7zi+t94FMTSDrXLt2rdjLQ6R3DICICC+88IL6Yv3www9z7I2lS5eq5Y5o/Pjxag47mSRSJj7Ny7lz59QcaDIXmMyLJRNIDhs2DPHx8RYvk8w3d+nSJTWPoPjmm29QqlQpi/8fIkfAAIiIFKnpmDJlCq5evaqbPZKWllbk554+fRoPPfSQCmjymv08MjISTZo0UbOk//jjj2rCyblz56qAqXnz5rhy5QosSQIsmZTTUYNSIktiAERESrt27dSX6+TJk/PcIxMmTLijOWj69OmoXLlyjtokmRX9gw8+QFBQkKqhmDRpEjIyMtSs0zIDdYUKFfD111+bbXaSWg4JxurVq4eNGzfmePzQoUN49NFHUbJkSfXazz//PC5fvpz9eOvWrTF06FA1W7u/vz86duxodjuysrJUmaQcHh4eaptkBmwjCTB2796t1pHbst3mvPLKKyooWb16NVq1aqVm1pby/fXXX7hw4QLefvvtHK8pNWqmZN9ILU5B94FpE5jc7t+/PxISEtQy03J+9tlnaqZ6eQ3ZTzKbOxHlxACIiBQXFxcVtMyaNQvnz5+/p72ybt06XLx4EZs2bcK0adNUc9Jjjz2G0qVLIyIiAoMGDcLLL798x/+RAOk///kP9u7dq2pQunbtmt2UJF/6jzzyCBo2bIhdu3apgCUmJgZPP/10jtf49ttvVVDy999/q9oYc2bMmIGpU6fiv//9Lw4cOKACpW7duqmaHCHNTHXr1lVlkdtvvPHGHa8htTt//vknhgwZAi8vrxyPSSD53HPPYdGiRSjsfNP57QNTEiRJ8Onr66vKaCyn7JvXXntNBW/SfCf7qWXLloUqA5EjYABERNl69uypakMkYLkXUsszc+ZM1KpVS+XHyHVycjLGjBmjaiZGjx6tgpQtW7bkeJ7U3jzxxBOoU6cO5syZo3JdvvrqK/XYp59+qoIfCdJq166tbs+fPx/r16/HiRMnsl9DXv+jjz5S/1Mu5kjg89Zbb+GZZ55R60jTn2y3BBTGAMbV1VXVNMltuc5NgiUJbqSs5shyaU6Mi4sr1L7Lbx+Ykv0nj0nNj5TRWM6zZ8+q3CUJOKX5TvaTBERElBMDICLKQYIBqUU5evRokfeM1J44O//78SLNMPXr189R2yR5NbGxsTmeJzUeRhKASH6NsRz79+9XwY58yRsvEggZ83WMGjdunG/ZEhMTVe1UixYtciyX+0XZ5rvV8EigUhj57YOCaN++vQp8qlatqpoIf/jhBxV8ElFODICIKAdpLpEmIamlyU2Cmtxf+Onp6Xes5+bmluO+1FKYWya5OAV148YN1Rwk3cRNL1ITY9rEI7Uf1lC9enW1DXkFJ7I8ICAgu5eWrFuQfXevfHx8sGfPHpWUHRISgnHjxqFBgwbsOk+UCwMgIrqDdIdfvnw5tm3blmO5fKFHR0fn+CK35Ng927dvz74tSdOSiGxsYmrUqBEOHz6sEq4l+DC9FCbokZwZ6bIuOUKm5H5YWFiBX0dqsKS2RRKOb968meMx2UdS8yIJ4ab7TvJ0jCRwM1czk98+MFe7lJmZecdyqTmSpHZpCpQcJxljSPKyiOhfDICI6A7SXCVJvJLHY0p6WUlOi3yxSrPT7Nmz8ccff1hsD8rr/frrr6onlPSwkhwaySEScl8Sj5999lns3LlT/X9JQpaeUOaCgLslGktTnyQpS6LwqFGjVCAn4/cUhuQlpaamqhozSfiWMYEk6VgCo5o1a6raFyNJ4Jb1JblZEpUlETx3rdjd9kFuEgxKzZh0u5fecBJQrVixQh032Z4zZ87gu+++UzVteeVDETkqBkBEZJb0IsrdRCU1EVLjIV/S0qyyY8cOsz2k7qXmSS7y2pIgvWzZMtWdXRhrbSTY6dChgwrSpLu7NDGZ5hsVhCQFjxgxQvW2kteRoEX+lyRQF4asL8GY5NtIbzTJvZFu8BL8SFlNk6el11loaCgefvhh9O7dW+03b2/vQu0Dcz3BJJDq1auXqmGSwFT2x5IlS1TAJcdLesJJc5jkZRHRv5wMhe2jSUREeZIedNL1f82aNWoqDSKyTQyAiIgsTAZ5lAEKpaapsLVTRGQdDICIiIjI4fCnCRERETkcBkBERETkcBgAERERkcNhAEREREQOhwEQERERORwGQERERORwGAARERGRw2EARERERA6HARARERE5nP8HOAAEIN3/TNAAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "results = [mps_encoding_metadata(num_qubits) for num_qubits in range(2, 18)]\n", + "\n", + "plt.plot(\n", + " [result[\"num_qubits\"] for result in results],\n", + " [result[\"fidelity\"] for result in results],\n", + " marker=\"o\",\n", + ")\n", + "plt.xlabel(\"Number of Qubits\")\n", + "plt.ylabel(\"Fidelity\")\n", + "plt.title(\"Fidelity of MPS Encoding vs. Number of Qubits\")\n", + "plt.grid()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "119506f4", + "metadata": {}, + "source": [ + "Below, we can observe the resulting circuit structure for the case of 4 qubits. As mentioned, Ran's algorithm produces staircase layers of one and two qubit unitary gates to encode the MPS to circuit." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a931a428", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T : │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 40 │ 41 │ 42 │ 43 │\n", + "GP : │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │1.49 │\n", + " ┌─────────────────────┐ ┌──────────────────────┐ ┌───────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ \n", + "q0 : ──┤ U(0.46, 1.94, 1.31) ├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────●───┤ U(0.73, -1.57, 1.57) ├───●───┤ U(0.57, -0.00, -1.57) ├───●───┤ U(0.17, -2.37, 3.11) ├─┤ U(0.00, -0.21, 0.11) ├──┤ U(1.18, -0.92, 1.55) ├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────●───┤ U(0.81, -1.57, 1.57) ├───●───┤ U(0.60, -3.14, 1.57) ├───●───┤ U(1.03, -1.13, 2.08) ├──┤ U(1.61, 0.09, -0.90) ├───────\n", + " └─────────────────────┘ │ └──────────────────────┘ │ └───────────────────────┘ │ └──────────────────────┘ └──────────────────────┘ └──────────────────────┘ │ └──────────────────────┘ │ └──────────────────────┘ │ └──────────────────────┘ └──────────────────────┘ \n", + " ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌─────────────────────┐ ┌──────────────────────┐ ┌─┴─┐ ┌─────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌───────────────────────┐ ┌──────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐ ┌─────────────────────┐ ┌─┴─┐ ┌─────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌─┴─┐ ┌───────────────────────┐ \n", + "q1 : ─┤ U(1.51, -2.83, 3.10) ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────●───┤ U(0.85, -1.57, 1.57) ├───●───┤ U(0.28, -3.14, 1.57) ├───●───┤ U(1.61, 0.27, 1.33) ├──┤ U(0.87, -0.27, 0.92) ├─┤ X ├─┤ U(1.24, 0.32, 0.77) ├──┤ X ├─┤ U(1.98, 2.93, -2.07) ├──┤ X ├─┤ U(1.69, -2.41, 2.30) ├─┤ U(1.86, -1.09, -3.05) ├────────────●─────────────┤ U(0.85, -1.57, 1.57) ├───●───┤ U(0.30, -0.00, -1.57) ├───●───┤ U(1.77, -2.02, -0.29) ├─┤ U(0.88, 2.42, 2.54) ├─┤ X ├─┤ U(1.28, 0.35, 0.67) ├──┤ X ├─┤ U(1.98, 2.93, -2.07) ├─┤ X ├─┤ U(3.02, -2.28, -1.68) ├────────────────────────────────\n", + " └──────────────────────┘ │ └──────────────────────┘ │ └──────────────────────┘ │ └─────────────────────┘ └──────────────────────┘ └───┘ └─────────────────────┘ └───┘ └──────────────────────┘ └───┘ └──────────────────────┘ └───────────────────────┘ │ └──────────────────────┘ │ └───────────────────────┘ │ └───────────────────────┘ └─────────────────────┘ └───┘ └─────────────────────┘ └───┘ └──────────────────────┘ └───┘ └───────────────────────┘ \n", + " ┌───────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌─────────────────────┐ ┌─┴─┐ ┌─────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ ┌─┴─┐ ┌─────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌─┴─┐ ┌───────────────────────┐ \n", + "q2 : ─┤ U(1.52, -1.59, -1.46) ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────●───┤ U(0.97, -1.57, 1.57) ├───●───┤ U(0.86, -3.14, 1.57) ├───●───┤ U(1.45, 2.57, -0.17) ├─┤ U(1.77, 1.24, 1.28) ├──┤ X ├─┤ U(1.37, 0.41, 0.44) ├──┤ X ├─┤ U(1.98, 2.93, -2.07) ├─┤ X ├─┤ U(1.79, 1.04, -1.33) ├─┤ U(0.95, 2.12, -0.63) ├───●───┤ U(1.27, -1.57, 1.57) ├───●───┤ U(0.74, -3.14, 1.57) ├────●───┤ U(0.96, 2.03, 2.77) ├───┤ U(2.89, 3.11, 0.23) ├───────────┤ X ├───────────┤ U(1.25, 0.32, 0.77) ├──┤ X ├─┤ U(1.98, 2.93, -2.07) ├──┤ X ├─┤ U(0.60, -2.94, -1.03) ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", + " └───────────────────────┘ │ └──────────────────────┘ │ └──────────────────────┘ │ └──────────────────────┘ └─────────────────────┘ └───┘ └─────────────────────┘ └───┘ └──────────────────────┘ └───┘ └──────────────────────┘ └──────────────────────┘ │ └──────────────────────┘ │ └──────────────────────┘ │ └─────────────────────┘ └─────────────────────┘ └───┘ └─────────────────────┘ └───┘ └──────────────────────┘ └───┘ └───────────────────────┘ \n", + " ┌───────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌───────────────────────┐ ┌──────────────────────┐ ┌─┴─┐ ┌─────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌─────────────────────┐ ┌─┴─┐ ┌─────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ \n", + "q3 : ─┤ U(1.22, -1.54, -2.70) ├───●───┤ U(0.78, -1.57, 1.57) ├───●───┤ U(0.29, -3.14, 1.57) ├───●───┤ U(0.96, -1.14, -0.05) ├─┤ U(2.45, 0.00, -0.87) ├─┤ X ├─┤ U(1.31, 0.38, 0.58) ├──┤ X ├─┤ U(1.98, 2.93, -2.07) ├─┤ X ├─┤ U(1.82, 2.26, -0.57) ├─┤ U(0.95, 0.96, -2.03) ├───●───┤ U(0.74, -1.57, 1.57) ├───●───┤ U(0.11, -3.14, 1.57) ├───●───┤ U(0.18, 3.08, -2.92) ├─┤ U(2.33, 1.97, 2.85) ├──┤ X ├─┤ U(1.28, 0.36, 0.65) ├──┤ X ├─┤ U(1.98, 2.93, -2.07) ├──┤ X ├─┤ U(1.32, -1.47, 2.21) ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", + " └───────────────────────┘ │ └──────────────────────┘ │ └──────────────────────┘ │ └───────────────────────┘ └──────────────────────┘ └───┘ └─────────────────────┘ └───┘ └──────────────────────┘ └───┘ └──────────────────────┘ └──────────────────────┘ │ └──────────────────────┘ │ └──────────────────────┘ │ └──────────────────────┘ └─────────────────────┘ └───┘ └─────────────────────┘ └───┘ └──────────────────────┘ └───┘ └──────────────────────┘ \n", + " ┌──────────────────────┐ ┌─┴─┐ ┌─────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌──────────────────────┐ ┌─┴─┐ ┌─────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ ┌─┴─┐ ┌──────────────────────┐ \n", + "q4 : ─┤ U(2.86, 2.34, -1.96) ├──┤ X ├─┤ U(1.29, 0.36, 0.63) ├──┤ X ├─┤ U(1.98, 2.93, -2.07) ├─┤ X ├─┤ U(1.72, 0.15, -0.78) ├──┤ U(1.87, 0.35, -0.23) ├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ X ├─┤ U(1.36, 0.40, 0.45) ├──┤ X ├─┤ U(1.98, 2.93, -2.07) ├─┤ X ├─┤ U(1.89, 1.85, -1.22) ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", + " └──────────────────────┘ └───┘ └─────────────────────┘ └───┘ └──────────────────────┘ └───┘ └──────────────────────┘ └──────────────────────┘ └───┘ └─────────────────────┘ └───┘ └──────────────────────┘ └───┘ └──────────────────────┘ \n", + "T : │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 40 │ 41 │ 42 │ 43 │\n", + "\n", + "Global phase: 1.485357610734308\n", + "\n", + "Additional result types: StateVector\n" + ] + } + ], + "source": [ + "print(results[3][\"circuit\"].diagram())" + ] + }, + { + "cell_type": "markdown", + "id": "eb5d79ea", + "metadata": {}, + "source": [ + "We can observe the massive difference between the exact approaches and MPS approach for this class of states in terms of circuit depth. With refinements from sweeping, this can be maintained whilst pushing fidelity to 0.97+ from the experimentation and even push it to perform as such on even volume-law entangled states." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "4551b8a5", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlUAAAHHCAYAAACWQK1nAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAeSxJREFUeJzt3Qd4U2UbBuCnu2XPliFL2UOQISLIEATcCG5UfgcqgoIDEAcoDlwoKAriwIkDFQREhoKgguy9VUQEaZFVZmf+6/nCCUlI2xTSZj33daVZp+d8Z+TkzfuNE2Gz2WwQERERkTMSeWb/LiIiIiIKqkRERER8RJkqERERER9QUCUiIiLiAwqqRERERHxAQZWIiIiIDyioEhEREfEBBVUiIiIiPqCgSkRERMQHFFRJrqpXr47//e9/hb6V/vrrL0REROCDDz5AqGrfvj0aNmxYKMt6+eWXcfbZZyMqKgpNmjQplGXKSTyOeTzzuHbe/7yJ//EcV6xYMQSLmTNnms9xfHy8Oa4OHDjgl3Jw2f369Tut4z9UKagKU3/88Qfuuece80XLD2aJEiXQunVrjB49GseOHUMgmjFjBp566imvp+cXFj/IvEVGRpp1rFOnDm699VbMmTMHhWHXrl2mzKtWrYK/zJ49G4MGDTL7d8KECXj++edz/XLh9uK28nQcbN261bFNX3nlFcfrP/30k+N13mJiYsyxddttt+HPP/90mceePXvQv39/1K1bFwkJCUhMTMT555+PwYMH4/Dhw16dnHO6/fbbb6e1jaTgWZ/HK6+8MscfUc7HlHi2d+9eXH/99eaz8+abb+Ljjz9G0aJFc91c69evxy233ILKlSsjLi4OlSpVMs83bNjgt8381ltvheSP5mh/F0AK33fffYfrrrvOfLj4pcdsSXp6On755RcMHDjQfADHjx9vpt28ebMJSApbtWrVzJc6v5ydgyqeRPITWJ111lkYMWKEeXzkyBH8/vvv+Oabb/DJJ5+YExPvnZdREEHV008/bTJ+/soQzZ071+zD9957D7GxsXlOHx0djaNHj2LatGlmGzn79NNPTRB+/Phxj//7wAMPoEWLFsjIyMCKFSvMccTjbe3ateZEvm/fPjRv3hypqam44447TGDFL4k1a9Zg7Nix6NOnj1cZg+HDh6NGjRqnvF6zZk0ECwa74Wj69OlYvnw5mjVr5u+iBKWlS5fi0KFDeOaZZ9CpU6c8p+f57qabbkKZMmVw5513ms8Ng1ieD7766it88cUXuPrqqwu0zLfeeituvPFG853jHFSVK1fOLzUhBUlBVZjZtm2bObgZtPDLtmLFio73+vbta4IOfglanD8EOWGwktcvpfzir1Z+eZ+pkiVLml9kzl544QXz5c8PNYOdF198EaEsJSXF/Kr1JqCy9jmzWp999tkpQdXEiRNx+eWX4+uvv/b4vxdddBGuvfZa8/j2229H7dq1zbb+8MMPMWTIEHMi//vvv/Hrr7/iwgsvdPlfBlrelvHSSy81wVkw83ZdQ0nVqlVNQMAfGlOnTkU4sdls5scIP4tn+nmmUqVKeVUjwYCGWeMFCxagfPnyjveYLebnledH/qjx9CPFV6KioswtHKj6L8y89NJLpoqFX27OAZXzL31+2HJqU2VVv8yfPx/33XefqbphNsjy/fffo127dihevLipQmLWgl/EOc0vp/Yl7m2q+D/MUpFzdc/p4If79ddfR/369TFmzBgcPHjQ5X1mr/grmic//rpjELpjx45TyssMH39xMzjgtDwpjRs3zqVKjOtvBRhWmd1T3kzBd+jQAUWKFDHpee4jb2RmZppfq+ecc44JhLhtH3vsMaSlpTmm4fJY5cfAN6fle3LzzTebfencVoO/kFn9x/e8dfHFFzuCeeskz+1/wQUXnDItjxdfBNLu1UnMllnbiPuD6+Fu06ZNJoDklw73JauJH3/8cZdpVq5caYI5lpPZtI4dO3qsbmSml+vN+fCz8eyzzyI7OzvPY96qQv3yyy/x3HPPmf/l9uBy+GPHHT8P/LLkclh9+vPPP3vVTovHLY83dywjjz8rKKbPP//cfBasz3OjRo1ME4HTxfk8+OCDJgvKTGZumJH29Bn31D6Hx/4VV1xhtiGDbW4TlpXPrWwNn3N7cn24Lz1hVXWXLl3Mj0RmVpkRZTDkvp1GjRqFBg0amPklJSWZphT79+93mc4q06xZsxxlevvtt3Nd50mTJjnOPcziMODZuXOn433u2169epnHPJa5HXLL9LAtJbPO/Aw4B1TE+bM8/D7gdBbOj2X3dn9YGWx+ZuJPbF8GcLntM86fnxN+j1jnJeu4ZZabQXetWrXM/MqWLYs2bdoUWpONM6WgKszwZMYTsXuWIL8YUDEYGDp0KB599FHHB4dZDFbxMCvBjBCrvNio8kzxpHXJJZeYx2xDYN1OF7/YmRLnCYfVnhZ+mbFKlB/oV199FQMGDMCPP/6Itm3bntIYlCfRyy67zJxEGAjxS5DVV++//755v169euakTHfffbejzJyX8zy6du2Kxo0bY+TIkaY6jG2LGNDk5a677jLbv2nTpnjttddMMMuqTgaBFi6Pv0YZUHhafk66d+9uTnT8MrIwOGb5uDxvMYginhiJGdKsrKwz2nfEQPi///5zubEa0R3LzC8MHj8MbnhS57rxxG3hr/SWLVuazG3v3r1N0NCtWzfzWbHwC4DbcfXq1aZ92pNPPmkCRX4RLF682DHd7t27TcDCNnT8XPD4+eijj/IViPBzM3nyZDzyyCPmc8TArWfPni7TsKqUDYR5zPHYY9lY5n/++SfP+d9www3mS49ldcbPAaurreOHX2L8jJQuXdpkc1kuri+zjGeCP9o4z/xU43uDgScDfrbZ4ueAny0+5hc+AzkGKPyy5jHJANo90OVxyc8igyRuU36uhw0bZm7OeCyxmYTVBpU/mLgMBmPOx5XVfILbkOcuTptbEwCeP1kunptYfh6L/PwxoLDOPQz0eS4hnlv4OWJ5csJjmAEMjw9PeC7g+87Hen4xMOJxzu07fPhw8znkdly3bl2O/8OglMcuzyfWecn6EcPjgvuJnyP+6OXrzHDmFYQHDJuEjYMHD/Inl+3qq6/2+n+qVatm69Wrl+P5hAkTzDzatGljy8zMdLx+4MABW/HixW0tW7a0HTt2zGUe2dnZOc7P0q5dO3OzbNu2zSyHy7P07dvXvOYtzq9BgwY5vj958mQzv9GjR5vnf/31ly0qKsr23HPPuUy3du1aW3R0tMvrnDf/d+TIkY7X0tLSbE2aNLElJiba0tPTzWtLly49ZT3c5/HRRx+5zKNChQq2Hj165Lpuq1atMv971113ubz+yCOPmNfnzp3reI3bu2jRornOz9O01157ra1jx47mcVZWlinX008/7dg3L7/8suP/5s2bZ157//33bXv27LHt2rXL9t1339mqV69ui4iIMNuBdu/ebStfvryZtm7durZ7773XNnHiRHP8eMM6/jzd4uLiHNNZZSxbtqxt3759jte//fZb8/q0adMcr7Vt29Ycu9u3b8/xuO3WrZstNjbW9scffzhe4zry//j/lgEDBpj5L1682PFa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s88+i3HjxuGdd95xuf5f69atTZAlIiIi4mic3nsucNePCAf5Dqo2b96Mtm3bnvJ6yZIlceDAAV+VS0REREJFhH20gFCX76CqQoUK+P333095ne2pzj77bF+VS0RERIJdVgbCSb6Dqt69e6N///5YvHixGYtq165d+PTTT/HII4+gT58+BVNKERERCS6ZacCIKsCbFwDH9iMc5HtIhUcffRTZ2dno2LEjjh49aqoC4+LiTFB1//33F0wpRUREJLjs3QpkHgMO7QLiSyEc5DuoYnbq8ccfx8CBA0014OHDh1G/fn0UK1asYEooIiIiQSci5cSgn4kNwqZNVb6DKusyNLy2X1JSkgmoRERERDwGVWFweZrTalO1e/du3HbbbShdurQJqBITE83jO+64A8nJyQVXShEREQkqEWEYVHmdqWJmiiOos7rv9ttvR926dU3GasOGDfjss89M7z+OU6VqQBEREYlIWR821/zLd1A1evRoREVFYf369ShfvrzLe0888YQZ/PP111/HY489VhDlFBERkSARm3kIEYdP1GAl1kW48Lr677vvvjMBk3tARawGHDJkCKZNm+br8omIiEiQicxOR3aDHkDNTkBccYQLr4OqLVu2mOq/nPA9jrYuIiIi4e14bFlkdXsbuOVrhJPI/LSpKlUq53Em+B6nEREREQlHXgdVbJQeGRmZ6/hVnEZERETCW0L6f0B2FsKN1w3VGTDVrl3bBE85vS8iIiJhLjsLHTcMRuTmx4F+S4FSVRAuvA6qJkyYULAlERERkeC3/09E2TJgi4gBSlRCOPE6qOrVq1fBlkRERERCZtBPW/m6iIiMQjjJ14jqIiIiIt5d869+2G0oBVUiIiLiMxG715p7m4IqERERkdN0PBURfy0wD7PPahl2m1GZKhEREfGNjdMQkXkch+IqAhXODbutmu+gavjw4Th69Ogprx87dsy8JyIiImGqRltktRuC3xMv5QCWCDf5DqqefvppHD58+JTXGWjxPREREQlTpaogu83D+Ltce4SjfAdVHOTT0wCgq1evRpkyZXxVLhEREZHQHKeqdOnSJpjizX1k9aysLJO9uvfeewuqnCIiIhLIvn8UqHI+cE5nhCuvg6pRo0aZLNUdd9xhqvlKlizpeC82NhbVq1dHq1atCqqcIiIiEqhSNgKLxwJL3wH6nxinKgzle0T1GjVq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JCSgUaNGWLZsGUJRVlYWnnzySdSoUcOs6znnnINnnnkmz2ttBZMFCxbgyiuvNKMy89idMmWKy/tc16FDh6JixYpmG3Tq1Albt25FKK4vr4c3ePBgc0wXLVrUTHPbbbeZq06E6v51du+995ppRo0ahVBe340bN+Kqq64yA2dyP/M76++//0aoUlAVxObPn4++ffvit99+w5w5c8xJqnPnzjhy5AhC3dKlS/H222/j3HPPRajav38/WrdubS4Y/f3332PDhg0YOXIkSpcujVD04osvYuzYsRgzZow5EfP5Sy+9hDfeeAOhgp/Nxo0b48033/T4Ptf39ddfx7hx47B48WLzJdSlSxccP34coba+vCD6ihUrTCDN+2+++cb8KOQXcKjuX8vkyZPNeZvBSDDLa33/+OMPtGnTBnXr1sVPP/2ENWvWmP0dHx+PkMVr/0loSElJ4U962/z5822h7NChQ7ZatWrZ5syZY2vXrp2tf//+tlA0ePBgW5s2bWzh4vLLL7fdcccdLq91797d1rNnT1so4md18uTJjufZ2dm2ChUq2F5++WXHawcOHLDFxcXZPvvsM1uora8nS5YsMdNt377dFqrr+88//9gqV65sW7duna1atWq21157zRYKPK3vDTfcYLvlllts4USZqhBy8OBBc1+mTBmEMmbnLr/8clM1EsqmTp2K5s2b47rrrjPVu+eddx7eeecdhKoLL7wQP/74I7Zs2WKer169Gr/88gsuvfRShINt27Zh9+7dLsc1q0xatmyJRYsWIVzOYaxGKlWqFEJRdnY2br31VgwcOBANGjRAKMvOzsZ3332H2rVrm2wrz2E8lnOrEg0FCqpC6ABm2yJWFzVs2BCh6vPPPzdVBWxPFur+/PNPUx1Wq1YtzJo1C3369MEDDzyADz/8EKHo0UcfxY033miqCljlySCSx3TPnj0RDhhQUVJSksvrfG69F8pYxck2VjfddFPIXiSdVdrR0dHmcxzqUlJScPjwYdP2tWvXrpg9ezauueYadO/e3TRdCVXR/i6A+C57s27dOvPLPlTt2LED/fv3N+3HQrpO3ilQZqbq+eefN88ZZHAfs71Nr169EGq+/PJLfPrpp5g4caL5Fb9q1SoTVLHdSSiur5zE9qDXX3+9aajPHxKhaPny5Rg9erT5UchsXDicv+jqq6/Ggw8+aB43adIECxcuNOewdu3aIRQpUxUC+vXrh+nTp2PevHk466yzEKp4UuKvn6ZNm5pfe7zxFw8b9vIxe4+FEvYAq1+/vstr9erVC9meM6wSsbJV7BHGahKejMMhK0kVKlQw98nJyS6v87n1XigHVNu3bzc/mEI1S/Xzzz+b81fVqlUd5y+u88MPP4zq1asj1JQrV86sYzidw0iZqiDGX3X333+/6UnCnhXsih7KOnbsiLVr17q8dvvtt5vqIlYbREVFIZSwKtd9iAy2N6pWrRpCEXuDRUa6/s7jPrV+8YY6fn4ZPLFdGX/RU2pqqukFyKrfUA6oOGwEfxRy6JBQxR8J7u1A2daIr/M8FmpiY2PN8AnhdA4jBVVBXuXHqpJvv/3WjFVltbtg41aOcRNquI7u7cXY5Zwn4lBsR8YsDRtvs/qPXzxLlizB+PHjzS0Ucbyb5557zvySZ/XfypUr8eqrr+KOO+5AqGAbk99//92lcTqrOdm5hOvN6s5nn33WtKNjkMXu56z+5Bh0oba+zMRee+21pjqMmXZmmq1zGN/nl3Ko7V/3oJFtBxlI16lTB8Eor/UdOHAgbrjhBrRt2xYdOnTAzJkzMW3aNJMECFn+7n4op4+7z9NtwoQJYbNZQ3lIBZo2bZqtYcOGplt93bp1bePHj7eFqtTUVLMvq1ataouPj7edffbZtscff9yWlpZmCxXz5s3z+Jnt1auXY1iFJ5980paUlGT2eceOHW2bN2+2heL6btu2LcdzGP8vFPevu2AfUsGb9X3vvfdsNWvWNJ/pxo0b26ZMmWILZRH84+/ATkRERCTYqaG6iIiIiA8oqBIRERHxAQVVIiIiIj6goEpERETEBxRUiYiIiPiAgioRERERH1BQJSIiIuIDCqpEREREfEBBlYiEpL/++gsRERHmshmBYtOmTbjgggsQHx/vuL6fv7cBLxnCaQ4cOFDg5REJdQqqRKRA/O9//zNf1i+88ILL61OmTDGvh6Nhw4aZ61XyIrO8cHJOduzYYa55yOv+8Rp4vABt//79sXfvXp+XideX/Pfff801Q+mDDz5AqVKlfL4ckXCgoEpECgwzMi+++CL2798fMls5PT39tP/3jz/+QJs2bUyQ5H5xXcuff/6J5s2bY+vWrfjss8/MBWvHjRtngrBWrVph37598CUGbbyob7gGuiK+pKBKRApMp06dzBf2iBEjcpzmqaeeOqUqbNSoUahevbpL1qtbt254/vnnkZSUZDIpw4cPR2ZmJgYOHIgyZcrgrLPOwoQJEzxWuTEbwwCvYcOGmD9/vsv769atw6WXXopixYqZed96663477//HO+3b98e/fr1w4ABA1CuXDl06dLF43pkZ2ebMrEccXFxZp1mzpzpeJ9By/Lly800fMz19qRv374m0Jk9ezbatWuHqlWrmvL98MMP2LlzJx5//HGXeTLz54zbhtkmb7eBc/UfH99+++04ePCgec25nG+99RZq1apl5sHtdO2113osv0g4U1AlIgUmKirKBEJvvPEG/vnnnzOa19y5c7Fr1y4sWLAAr776qqlKu+KKK1C6dGksXrwY9957L+65555TlsOg6+GHH8bKlStNpufKK690VKMxkLj44otx3nnnYdmyZSYISk5OxvXXX+8yjw8//NAEOr/++qvJGnkyevRojBw5Eq+88grWrFljgq+rrrrKZJyIVWwNGjQwZeHjRx555JR5MAs1a9Ys3HfffUhISHB5j8Fpz5498cUXX8Bms+Vr2+W2DZwx8GJAW6JECVNGq5zcNg888IAJCFl1ye3Utm3bfJVBJBwoqBKRAnXNNdeYrA2DoDPBbNTrr7+OOnXqmPZGvD969Cgee+wxk0EZMmSICXx++eUXl/9jlqlHjx6oV68exo4da9oOvffee+a9MWPGmICKgV/dunXN4/fffx/z5s3Dli1bHPPg/F966SWzTN48YTA1ePBg3HjjjWYaVntyvRmkWEFRdHS0yYjxMe/dMQBjwMSyesLXWZW6Z8+efG273LaBM24/vscMFctolfPvv/82bcEYxLLqktuJQZaIuFJQJSIFjgEGsz0bN2487XkwyxMZefKUxSqoRo0auWTF2E4pJSXF5f+YmbEwqGF7Jascq1evNgEUAwfrxuDKav9kadasWa5lS01NNVm01q1bu7zO56ezznllohj85Edu28Abl1xyiQmmzj77bFM9+umnn5qAVkRcKagSkQLHqiJWhzGb5I6BknsQkZGRccp0MTExLs+ZTfH0Gts2eevw4cOmKoxDDjjfmDFyrt5ilqYw1KxZ06xDTgEPXy9fvryjdx6n9WbbnanixYtjxYoVpuF8xYoVMXToUDRu3FjDMIi4UVAlIoWCQytMmzYNixYtcnmdQcLu3btdggNfji3122+/OR6zYTsbi1vVa02bNsX69etNo3gGNM63/ARSbIPE4Q/Y5soZn9evX9/r+TDTxqwQG4UfO3bM5T1uI2aI2Gjfedux3ZOFwaCnDFJu28BTFiwrK+uU15nhYscDVoOyzRjHwGI7NxE5SUGViBQKVtWxoTXbRTlj7zq2EeKXNavc3nzzTXz//fc+Wy7nN3nyZNMDjj3r2CaJbbKIz9k4/KabbsLSpUvN8tlQnD3gPAUWeTUGZzUnG5KzMfejjz5qgkOOL5UfbOeVlpZmMntslM8xq9gwnMFW7dq1TZbIwkb2nJ4N0NmYnI313bN3eW0DdwwwmcHjEA7sBckgbfr06Wa/cX22b9+Ojz76yGQEc2pfJhKuFFSJSKFh7zH36jlmTJiZ4Rc/q5SWLFnisWfcmWTIeOO82Yh96tSpZmgEsrJLDKA6d+5sAj8OncDqNef2W95gw+2HHnrI9LLjfBgIcVls5J4fnJ4BHtsvsRci2zJxSAUGVCyrcwN39jasUqUKLrroItx8881muxUpUiRf28BTD0AGZzfccIPJhDHY5fb45ptvTBDH/cUekKwKZDs3ETkpwpbfvrkiIlKo2HOSw0jMmTPHXOZGRAKTgioRkSDAgU05KCczYvnNoolI4VBQJSIiIuID+rkjIiIi4gMKqkRERER8QEGViIiIiA8oqBIRERHxAQVVIiIiIj6goEpERETEBxRUiYiIiPiAgioRERERH1BQJSIiIoIz93+y10s+YvvifQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(\n", + " [result[\"num_qubits\"] for result in results],\n", + " [result[\"circuit_depth\"] for result in results],\n", + " marker=\"o\",\n", + " label=\"MPS Encoding\",\n", + ")\n", + "plt.plot(\n", + " [result[\"num_qubits\"] for result in results],\n", + " [2 ** result[\"num_qubits\"] for result in results],\n", + " linestyle=\"--\",\n", + " label=\"Shende et al. Lower Bound\",\n", + ")\n", + "plt.xlabel(\"Number of Qubits\")\n", + "plt.ylabel(\"Circuit Depth\")\n", + "plt.title(\"Circuit Depth of MPS Encoding vs. Number of Qubits\")\n", + "plt.legend()\n", + "plt.grid()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "9e45c99f", + "metadata": {}, + "source": [ + "Overall, MPS IR is a critical step forward for efficient synthesis of statevectors, and makes a major difference for current term and 2030's onward FTQC hardware." + ] + }, + { + "cell_type": "markdown", + "id": "de5434b0", + "metadata": {}, + "source": [ + "Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/setup.py b/setup.py index a2670557..3239a2a5 100644 --- a/setup.py +++ b/setup.py @@ -34,6 +34,8 @@ "scipy>=1.5.2", # Sympy 1.13 produces different results for Simon's algorithm "sympy<1.13", + "quimb", + "qiskit_braket_provider", ], extras_require={ "test": [ diff --git a/src/braket/experimental/algorithms/mps_encoding/__init__.py b/src/braket/experimental/algorithms/mps_encoding/__init__.py new file mode 100644 index 00000000..099b14d8 --- /dev/null +++ b/src/braket/experimental/algorithms/mps_encoding/__init__.py @@ -0,0 +1,16 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +from braket.experimental.algorithms.mps_encoding.mps_encoding import ( # noqa: F401 + mps_circuit_from_statevector, +) diff --git a/src/braket/experimental/algorithms/mps_encoding/mps_encoding.md b/src/braket/experimental/algorithms/mps_encoding/mps_encoding.md new file mode 100644 index 00000000..0dbeac2a --- /dev/null +++ b/src/braket/experimental/algorithms/mps_encoding/mps_encoding.md @@ -0,0 +1,10 @@ +Matrix Product State (MPS) encoding tackles the critical task of state preparation in $O(N)$ circuit depth, an exponential reduction in circuit depth compared to +exact encoding algorithms like Shende, Isometry, and Mottonen. The current implementation uses an analytical decomposition based on work by +Ran et al. to create a staircase ansatz comprised of 1 and 2 qubit unitary gates. Main consideration with the decomposition is that it is prone to +approximation limitations imposed by MPS IR, which limits the adequate performance of the synthesis to area-law entangled states only. + + diff --git a/src/braket/experimental/algorithms/mps_encoding/mps_encoding.py b/src/braket/experimental/algorithms/mps_encoding/mps_encoding.py new file mode 100644 index 00000000..aadf94fd --- /dev/null +++ b/src/braket/experimental/algorithms/mps_encoding/mps_encoding.py @@ -0,0 +1,316 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import numpy as np +import quimb.tensor as qtn +from qiskit_braket_provider import to_braket + +from braket.circuits import Circuit + +if TYPE_CHECKING: + import numpy.typing as npt + + +def _gram_schmidt(matrix: npt.NDArray[np.complex128]) -> npt.NDArray[np.complex128]: + """Perform Gram-Schmidt orthogonalization on the columns of a square matrix + to define the unitary block to encode the MPS. + + This implementation provides slightly better fidelity compared to the Schmidt + decomposition approach used in scipy.linalg.qr for our use case. + + Args: + matrix (NDArray[np.complex128]): Square matrix with complex entries. + + Returns: + (NDArray[np.complex128]): A unitary matrix with orthonormal columns derived from the input matrix. + If a column is approximately zero, it is replaced with a random vector. + """ + assert len(matrix.shape) == 2 and matrix.shape[0] == matrix.shape[1], ( + "Input matrix must be square." + ) + + num_rows: int = matrix.shape[0] + unitary = np.zeros((num_rows, num_rows), dtype=np.complex128) + orthonormal_basis: list[npt.NDArray[np.complex128]] = [] + + for j in range(num_rows): + column = matrix[:, j] + + # If column is (approximately) zero, replace with random + if np.allclose(column, 0): + column = np.random.uniform(-1, 1, num_rows) + 1j * np.random.uniform(-1, 1, num_rows) + + # Gram-Schmidt orthogonalization + for basis_vector in orthonormal_basis: + column -= (basis_vector.conj().T @ column) * basis_vector + + # Handle near-zero vectors (linear dependence) + if np.linalg.norm(column) < 1e-12: # pragma: no cover + column = np.random.uniform(-1, 1, num_rows) + 1j * np.random.uniform(-1, 1, num_rows) + + for basis_vector in orthonormal_basis: + column -= (basis_vector.conj().T @ column) * basis_vector + + unitary[:, j] = column / np.linalg.norm(column) + orthonormal_basis.append(unitary[:, j]) + + return unitary + + +class MPSSequential: + """MPS to Circuit synthesis via sequential layers of unitaries. + + This class provides methods to convert a Matrix Product State (MPS) + into a quantum circuit representation using layers of two-qubit and single-qubit unitaries + in the form of a staircase. + + This approach allows for approximately encoding an area-law entangled state + using O(N) circuit depth, where N is the number of qubits by leveraging the MPS structure + as an intermediate representation. This is an exponential improvement over the + exact method of encoding arbitrary states, which typically requires O(2^N) depth. + + The analytical decomposition is based on the approach presented in: + [arXiv:1908.07958](https://arxiv.org/abs/1908.07958){:.external} + """ + + def __init__(self, max_fidelity_threshold: float = 0.95) -> None: + """Initialize the Sequential class. + + Args: + max_fidelity_threshold (float): The maximum fidelity required, after + which we can stop the encoding to save depth. + """ + self.max_fidelity_threshold = max_fidelity_threshold + + def generate_layer( + self, mps: qtn.MatrixProductState + ) -> list[tuple[list[int], npt.NDArray[np.complex128]]]: + """Convert a Matrix Product State (MPS) to a circuit representation + using a single unitary layer. + + Args: + mps (qtn.MatrixProductState): The MPS to convert. + + Returns: + (list[tuple[list[int], npt.NDArray[np.complex128]]]): A list of tuples + representing the unitary layer of the circuit. + Each tuple contains: + - A list of qubit indices (in LSB order) that the unitary acts on. + - A unitary matrix (as a 2D NumPy array) that encodes the MPS. + """ + num_sites = mps.L + + unitary_layer: list[tuple[list[int], npt.NDArray[np.complex128]]] = [] + + for i, tensor in enumerate(reversed(mps.arrays)): + i = num_sites - i - 1 + + # MPS representation uses 1D entanglement, thus we need to define + # the range of the indices via the tensor shape + # i.e., if q0 and q3 are entangled, then regardless of q1 and q2 being + # entangled the entanglement range would be q0-q3 + if i == 0: + d_right, d = tensor.shape + tensor = tensor.reshape((1, d_right, d)) + if i == num_sites - 1: + d_left, d = tensor.shape + tensor = tensor.reshape((d_left, 1, d)) + + tensor = np.swapaxes(tensor, 1, 2) + + # Combine the physical index and right-virtual index of the tensor to construct + # an isometry matrix + d_left, d, d_right = tensor.shape + isometry = tensor.reshape((d * d_left, d_right)) + + qubits = [ + num_sites - 1 - q for q in range(i, i - int(np.ceil(np.log2(d_left))) - 1, -1) + ] + + matrix = np.zeros((isometry.shape[0], isometry.shape[0]), dtype=isometry.dtype) + + # Keep columns for which all ancillas are in the zero state + matrix[:, : isometry.shape[1]] = isometry + + # Perform Gram-Schmidt orthogonalization to ensure the columns are orthonormal + unitary = _gram_schmidt(matrix) + + unitary_layer.append((qubits, unitary)) + + return unitary_layer + + def mps_to_circuit_approx( + self, statevector: npt.NDArray[np.complex128], max_num_layers: int, chi_max: int + ) -> Circuit: + """Approximately encodes the MPS into a circuit via multiple layers + of exact encoding of bond 2 truncated MPS. + + Whilst we can encode the MPS exactly in a single layer, we require + $log(chi) + 1$ qubits for each tensor, which results in larger circuits. + This function uses bond 2 which allows us to encode the MPS using one and + two qubit gates, which results in smaller circuits, and easier to run on + hardware. + + This is the core idea of Ran's paper [1]. + + [1] https://arxiv.org/abs/1908.07958 + + Args: + statevector (NDArray[np.complex128]): The statevector to convert. + max_num_layers (int): The number of layers to use in the circuit. + chi_max (int): The maximum bond dimension of the target MPS. + + Returns: + (Circuit): The generated quantum circuit that encodes the MPS. + """ + mps_dense = qtn.MatrixProductState.from_dense(statevector) + mps: qtn.MatrixProductState = qtn.tensor_1d_compress.tensor_network_1d_compress( + mps_dense, max_bond=chi_max + ) + mps.permute_arrays() + + mps.compress(form="left", max_bond=chi_max) + mps.left_canonicalize(normalize=True) + + compressed_mps = mps.copy(deep=True) + disentangled_mps = mps.copy(deep=True) + + circuit = Circuit() + + unitary_layers = [] + + # Initialize the zero state |00...0> to serve as comparison + # for the disentangled MPS + zero_state = np.zeros((2**mps.L,), dtype=np.complex128) + zero_state[0] = 1.0 + + # Ran's approach uses a iterative disentanglement of the MPS + # where each layer compresses the MPS to a maximum bond dimension of 2 + # and applies the inverse of the layer to disentangle the MPS + # After a few layers we are adequately close to |00...0> state + # after which we can simply reverse the layers (no inverse) and apply them + # to the |00...0> state to obtain the MPS state + for _ in range(max_num_layers): + # Compress the MPS from the previous layer to a maximum bond dimension of 2, + # |ψ_k> -> |ψ'_k> + compressed_mps = disentangled_mps.copy(deep=True) + + # Normalization improves fidelity of the encoding + compressed_mps.normalize() + compressed_mps.compress(form="left", max_bond=2) + + unitary_layers.append(self.generate_layer(compressed_mps)) + + # To update the MPS definition, apply the inverse of U_k to disentangle |ψ_k>, + # |ψ_(k+1)> = inv(U_k) @ |ψ_k> + for i, (_, U) in enumerate(reversed(unitary_layers[-1])): + inverse = U.conj().T + + if inverse.shape[0] == 4: + disentangled_mps.gate_split_(inverse, (i - 1, i)) + else: + disentangled_mps.gate_(inverse, (i), contract=True) + + # Compress the disentangled MPS to a maximum bond dimension of chi_max + # This is to ensure that the disentangled MPS does not grow too large + # and improves the fidelity of the encoding + disentangled_mps: qtn.MatrixProductState = ( # type: ignore + qtn.tensor_1d_compress.tensor_network_1d_compress( + disentangled_mps, max_bond=chi_max + ) + ) + + fidelity = np.abs(np.vdot(disentangled_mps.to_dense(), zero_state)) ** 2 + fidelity = float(np.real(fidelity)) + + if fidelity >= self.max_fidelity_threshold: + break + + # The layers disentangle the MPS to a state close to |00...0> + # inv(U_k) ... inv(U_1) |ψ> = |00...0> + # So, we have to reverse the layers and apply them to the |00...0> state + # to obtain the MPS state + # |ψ> = U_1 ... U_k |00...0> + unitary_layers.reverse() + + for unitary_layer in unitary_layers: + for qubits, unitary in unitary_layer: + qubits = list(reversed([mps.L - 1 - q for q in qubits])) + + # In certain cases, floating point errors can cause `unitary` + # to not be unitary + # We handle this by using SVD to approximate it again with the + # closest unitary + U, _, Vh = np.linalg.svd(unitary) + unitary = U @ Vh + + circuit.unitary(matrix=unitary, targets=qubits) + + return to_braket(circuit, add_measurements=False, basis_gates=["u3", "cx", "global_phase"]) + + def __call__( + self, statevector: npt.NDArray[np.complex128], max_num_layers: int = 10 + ) -> Circuit: + """Call the instance to create the circuit that encodes the statevector. + + Args: + statevector (NDArray[np.complex128]): The statevector to convert. + + Returns: + (Circuit): The generated quantum circuit. + """ + num_qubits = int(np.ceil(np.log2(len(statevector)))) + + # Single qubit statevector is optimal, and cannot be + # further improved given depth of 1 + if num_qubits == 1: + circuit = Circuit() + + magnitude = abs(statevector) + phase = np.angle(statevector) + + divisor = magnitude[0] ** 2 + magnitude[1] ** 2 + alpha_y = 2 * np.arcsin(np.sqrt(magnitude[1] ** 2 / divisor)) if divisor != 0 else 0.0 + alpha_z = phase[1] - phase[0] + global_phase = sum(phase / len(statevector)) + + circuit.ry(angle=alpha_y, target=0) + circuit.rz(angle=alpha_z, target=0) + circuit.gphase(angle=global_phase) + + return circuit + + circuit = self.mps_to_circuit_approx(statevector, max_num_layers, 2**num_qubits) + + return circuit + + +def mps_circuit_from_statevector( + statevector: npt.NDArray[np.complex128], max_num_layers: int = 10, target_fidelity: float = 0.95 +) -> Circuit: + """Create the circuit that encodes the statevector using MPS synthesis. + + Args: + statevector (NDArray[np.complex128]): The target statevector to be encoded. + max_num_layers (int): The maximum number of layers allowed in the circuit. + target_fidelity (float): The target fidelity for the approximation. + + Returns: + A braket.Circuit that encodes the statevector. + """ + encoder = MPSSequential(max_fidelity_threshold=target_fidelity) + return encoder(statevector, max_num_layers=max_num_layers) diff --git a/test/unit_tests/braket/experimental/algorithms/mps_encoding/test_mps_encoding.py b/test/unit_tests/braket/experimental/algorithms/mps_encoding/test_mps_encoding.py new file mode 100644 index 00000000..69441ead --- /dev/null +++ b/test/unit_tests/braket/experimental/algorithms/mps_encoding/test_mps_encoding.py @@ -0,0 +1,65 @@ +import numpy as np +import pytest + +from braket.circuits import Circuit +from braket.devices import LocalSimulator +from braket.experimental.algorithms.mps_encoding import mps_circuit_from_statevector + + +def test_compile_single_qubit_state() -> None: + # General random state + state = np.random.randn(2) + 1j * np.random.randn(2) + state /= np.linalg.norm(state) + + circuit = mps_circuit_from_statevector(state, max_num_layers=1) + result = LocalSimulator("braket_sv").run(circuit.state_vector(), shots=0).result() + np.testing.assert_allclose(result.result_types[0].value, state, atol=1e-6) + + +@pytest.mark.parametrize("num_qubits", [5, 8, 10, 11]) +def test_compile_area_law_states(num_qubits: int) -> None: + # Given random_superposition can generate volume-law entangled states, + # we manually construct an exclusively area-law entangled state here + state = np.random.rand(2**num_qubits) + 1j * np.random.rand(2**num_qubits) + state /= np.linalg.norm(state) + + circuit = mps_circuit_from_statevector(state, max_num_layers=6) + result = LocalSimulator("braket_sv").run(circuit.state_vector(), shots=0).result() + fidelity = np.vdot(result.result_types[0].value, state) + assert np.abs(fidelity) > 0.85 + + +def test_compile_trivial_state_with_mps_pass() -> None: + # Define a circuit that produces a trivial state + # aka a product state + trivial_circuit = Circuit() + + trivial_circuit.ry(angle=np.pi / 2, target=9) + trivial_circuit.rx(angle=np.pi, target=9) + trivial_circuit.rz(angle=np.pi / 4, target=9) + for i in reversed(range(9)): + trivial_circuit.cnot(i + 1, i) + trivial_circuit.rz(angle=-np.pi / (2 ** (9 - i)), target=i) + trivial_circuit.cnot(i + 1, i) + trivial_circuit.rz(angle=np.pi / (2 ** (9 - i)), target=i) + trivial_circuit.ry(angle=np.pi / 2, target=i) + trivial_circuit.rx(angle=np.pi, target=i) + trivial_circuit.rz(angle=np.pi / 4, target=i) + for i in reversed(range(9)): + trivial_circuit.rz(angle=np.pi / (2 ** (9 - i)), target=i) + for i in reversed(range(9)): + trivial_circuit.cnot(i + 1, i) + for i in reversed(range(9)): + trivial_circuit.cnot(i, i + 1) + + simulator = LocalSimulator("braket_sv") + state = simulator.run(trivial_circuit.state_vector(), shots=0).result().result_types[0].value + circuit = mps_circuit_from_statevector(state, max_num_layers=1) + result = ( + LocalSimulator("braket_sv") + .run(circuit.state_vector(), shots=0) + .result() + .result_types[0] + .value + ) + np.testing.assert_allclose(result, state, atol=1e-6)