diff --git a/.github/workflows/test_dev.yml b/.github/workflows/test_dev.yml index af825d930..c5bec4860 100644 --- a/.github/workflows/test_dev.yml +++ b/.github/workflows/test_dev.yml @@ -61,7 +61,7 @@ jobs: run: | source env/bin/activate ipython kernel install --name "env" --user - python -m pytest -v -m 'not (qpu or api)' --cov --cov-report=xml:coverage.xml + python -m pytest -v -m 'not (qpu or api or docker_aws)' --cov --cov-report=xml:coverage.xml - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v3 diff --git a/.github/workflows/test_main_linux.yml b/.github/workflows/test_main_linux.yml index be76a0733..d50f3c07a 100644 --- a/.github/workflows/test_main_linux.yml +++ b/.github/workflows/test_main_linux.yml @@ -60,7 +60,7 @@ jobs: run: | source env/bin/activate ipython kernel install --name "env" --user - python -m pytest -v -m 'not (qpu or api)' + python -m pytest -v -m 'not (qpu or api or docker_aws)' - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v3 diff --git a/.github/workflows/test_main_macos.yml b/.github/workflows/test_main_macos.yml index 45b058afe..26e55d77b 100644 --- a/.github/workflows/test_main_macos.yml +++ b/.github/workflows/test_main_macos.yml @@ -56,4 +56,4 @@ jobs: run: | source env/bin/activate ipython kernel install --user --name "env" - python -m pytest -v -m 'not (qpu or api)' + python -m pytest -v -m 'not (qpu or api or docker_aws)' diff --git a/.github/workflows/test_main_windows.yml b/.github/workflows/test_main_windows.yml index 6d6f4c650..b97ded4e1 100644 --- a/.github/workflows/test_main_windows.yml +++ b/.github/workflows/test_main_windows.yml @@ -68,4 +68,4 @@ jobs: run: | .\env\Scripts\Activate.ps1 ipython kernel install --name "env" --user - python -m pytest -v -m 'not (qpu or api)' + python -m pytest -v -m 'not (qpu or api or docker_aws)' diff --git a/.gitignore b/.gitignore index a7b21d9a7..67a886bb8 100644 --- a/.gitignore +++ b/.gitignore @@ -132,4 +132,10 @@ dmypy.json /.idea/ # Mac Stuff -*.DS_Store \ No newline at end of file +*.DS_Store + +# Braket files +braket-job*/ + +# Visual Studio code +.vscode/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bf4450b2..55a3e03eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,42 @@ +## Version v0.1.1 (February 23rd, 2023) + +This release brings the following new features: +* The ability to plug in custom qubit routing solutions for QAOA circuits. +* AWS managed jobs are now supported through OpenQAOA + +## What's Changed + +* Refactor + * The new `GateMapLabel` introduces an updated and a more consistent way to label QAOA gates in the circuit. +* New Features + * OpenQAOA now supports specifying custom qubit routing algorithms in an expected format in the QAOA workflow. This is implemented in https://github.com/entropicalabs/openqaoa/pull/179 + + +## Version v0.1.0 (February 17th, 2023) + +This release brings major changes to the structure of OpenQAOA. +This is OpenQAOA's first major release! V0.1.0 contains many new features and quite a few **breaking changes** :) + +**notice**: the license has been changed from `apache 2.0` to `MIT` + +## What's Changed + +* Refactor + * The code underwent a considerable refactoring effort. The most noticeable change is in the new `openqaoa-core` and other library plugins in the form `openqaoa-xyz`. + * Refactor of the result objects for RQAOA / QAOA by @raulconchello in https://github.com/entropicalabs/openqaoa/pull/122 +* New Features + * New backend: OpenQAOA is now compatible with Azure by @shahidee44 in https://github.com/entropicalabs/openqaoa/pull/167 + * New circuit Ansatz: now OQ allows for the Alternating Operator Ansatz by @shahidee44 in https://github.com/entropicalabs/openqaoa/pull/85 + * New backend: analytical formula for p=1 by @kidiki in https://github.com/entropicalabs/openqaoa/pull/147 + * Shot Adaptative optimizers by @raulconchello in https://github.com/entropicalabs/openqaoa/pull/123 + * Supporting PennyLane optimizers by @raulconchello in https://github.com/entropicalabs/openqaoa/pull/101 + * JSON dumps methods for RQAOA / QAOA by @raulconchello in https://github.com/entropicalabs/openqaoa/pull/122 +* Bug fixes + * Bugfix: QPU qubit overflow by @shahidee44 in https://github.com/entropicalabs/openqaoa/pull/108 + * fix: Spelling of Oxford Quantum Circuits by @christianbmadsen in https://github.com/entropicalabs/openqaoa/pull/141 + * Bugfix vanishing RQAOA instances after elimination by @kidiki in https://github.com/entropicalabs/openqaoa/pull/158 + + ## Version v0.0.4 (November 14th, 2022) This release brings improvements to RQAOA workflow and AWS authentication, and a bugfix to TSP problem class. diff --git a/README.md b/README.md index 8dca42d6e..f919323c3 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,12 @@ [![Documentation Status](https://readthedocs.org/projects/el-openqaoa/badge/?version=latest)](https://el-openqaoa.readthedocs.io/en/latest/?badge=latest) [![PyPI version](https://badge.fury.io/py/openqaoa.svg)](https://badge.fury.io/py/openqaoa) [![arXiv](https://img.shields.io/badge/arXiv-2210.08695-.svg)](https://arxiv.org/abs/2210.08695) - [![License](https://img.shields.io/badge/%F0%9F%AA%AA%20license-Apache%20License%202.0-lightgrey)](LICENSE.md) + [![License](https://img.shields.io/pypi/l/openqaoa)](LICENSE.md) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md) [![Downloads](https://pepy.tech/badge/openqaoa)](https://pepy.tech/project/openqaoa) [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/entropicalabs/openqaoa.git/main?labpath=%2Fexamples) + [![Discord](https://img.shields.io/discord/991258119525122058)](https://discord.gg/ana76wkKBd) + [![Website](https://img.shields.io/badge/OpenQAOA-Website-blueviolet)](https://openqaoa.entropicalabs.com/) # OpenQAOA @@ -23,6 +25,8 @@ A multi-backend python library for quantum optimization using QAOA on Quantum co Please, consider [joining our discord](https://discord.gg/ana76wkKBd) if you want to be part of our community and participate in the OpenQAOA's development. +Check out OpenQAOA website [https://openqaoa.entropicalabs.com/](https://openqaoa.entropicalabs.com/) + ## Installation instructions You can install the latest version of OpenQAOA directly from PyPi. First, create a virtual environment with python3.8+ and then simply pip install openqaoa with the following command diff --git a/docs/source/conf.py b/docs/source/conf.py index 18fd0ea46..5811abd49 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,4 +1,4 @@ - # Configuration file for the Sphinx documentation builder. +# Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: @@ -11,27 +11,27 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # # import mock - + # MOCK_MODULES = ['matplotlib', 'matplotlib.pyplot', 'numpy', 'scipy', 'networkx'] # for mod_name in MOCK_MODULES: # sys.modules[mod_name] = mock.Mock() import os import sys + # sys.path.insert(0, os.path.abspath('.')) # sys.path.insert(0, os.path.abspath("../../")) -sys.path.insert(0, os.path.abspath('../..')) +sys.path.insert(0, os.path.abspath("../..")) print(sys.path) # from openqaoa.qaoa_parameters.baseparams import shapedArray - # -- Project information ----------------------------------------------------- -project = 'OpenQAOA' -copyright = '2022, Entropica Labs' -author = 'Entropica Labs' +project = "OpenQAOA" +copyright = "2022, Entropica Labs" +author = "Entropica Labs" # -- General configuration --------------------------------------------------- @@ -40,35 +40,39 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.todo', - 'sphinx.ext.viewcode', - 'sphinx.ext.autodoc', + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "sphinx.ext.autodoc", "sphinx.ext.napoleon", "sphinx_autodoc_typehints", "sphinx.ext.mathjax", "IPython.sphinxext.ipython_console_highlighting", "nbsphinx", - "sphinx.ext.intersphinx" + "sphinx.ext.intersphinx", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['.docs/source/notebooks/community_tutorials/*', '.docs/source/notebooks/X_dumping_data.ipynb'] +exclude_patterns = [ + ".docs/source/notebooks/community_tutorials/*", + ".docs/source/notebooks/X_dumping_data.ipynb", +] -intersphinx_mapping = {'python': ('https://docs.python.org/3', None), - 'numpy': ('https://numpy.org/doc/1.23', None), - 'np': ('https://numpy.org/doc/1.23', None), - 'scipy': ('https://docs.scipy.org/doc/scipy-1.8.1', None)} +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "numpy": ("https://numpy.org/doc/1.23", None), + "np": ("https://numpy.org/doc/1.23", None), + "scipy": ("https://docs.scipy.org/doc/scipy-1.8.1", None), +} # Exclude broken python docs # see https://stackoverflow.com/questions/11417221/sphinx-autodoc-gives-warning-pyclass-reference-target-not-found-type-warning -nitpick_ignore = [('py:class', 'type')] - +nitpick_ignore = [("py:class", "type")] # -- Options for HTML output ------------------------------------------------- @@ -76,8 +80,8 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' -html_logo = '../../.github/images/Entropica_logo.png' +html_theme = "sphinx_rtd_theme" +html_logo = "../../.github/images/Entropica_logo.png" # html_favicon ='favicon.ico' # Add any paths that contain custom static files (such as style sheets) here, diff --git a/examples/01_workflows_example.ipynb b/examples/01_workflows_example.ipynb index dc316e406..c7553525b 100644 --- a/examples/01_workflows_example.ipynb +++ b/examples/01_workflows_example.ipynb @@ -71,7 +71,7 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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\n", "text/plain": [ "
" ] @@ -192,7 +192,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 6, @@ -201,7 +201,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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\n", "text/plain": [ "
" ] @@ -324,7 +324,7 @@ "outputs": [ { "data": { - "image/png": "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TR07dtTy5cslSQkJCbriiis0ZcoULVmyRCtXrtRll12mvn370lkwwlkh6+23TeOKOXMCv5dnyKodwH+W+PtvMw2wd297bJ7rZP38s3TXXWZaoXW+uNg879WunRQXF/hvAAAAQNUKi8YXn332mdatW6d169apZcuWbu85nU5JUmFhodauXasD1r+GJT3++OOqVauWRo0apfz8fA0ZMkTPPPNMlY4dVc8KMtZfhUDXyZLskGW1g/dWyZKkzZulrVulLl0kj14r2rvXVKnq1ZOswq3nOllWiLJauFvnrd8CAACA8BEWlazx48fL6XR6fVnatGkjp9OpAQMGlJyrW7eunn76ae3du1d5eXl69913y3weC5HBeo7JClnBtHD3DFW+QtY555jnrL7/vvR7Vvv2xETflaz4ePdja7t2rTRtmumSCAAAgPAQFiELqIg77pCWLpXOP98cBxOyli0zgeeYY8yxr5BVVhv3rCyzTUoy1SzJ/0qWJD34oPTFFwENHwAAANUgLKYLAhXRqZPZWtWfYKYLWpWne+6Rdu3y3YLdar2+a1fp9/ypZFkhy7OSZaG7IAAAQPggZCFiWc9RBVPJspxzTtnvN25strt3l36vrEpW48amy6D1rJa3Spa3YwAAABy5mC6IiPPDD9Ljj0sLF5rjYELWI49IF18sffNN2df5E7ISE8295swxbdols0bWli3S8OHm2ApZTZpIp51mT08kZAEAAIQPKlmIOAsXSjNmSH36SG+95d8iwb588YVZw8rhkPLypH797CYVrsoKWcnJUvfuUlqaWa/L2woCffpI331n33vwYPN6+mmzUDEhCwAAIHwQshBxrOeeOnaUxowJ7l5WJen1181r1Sq7CYarskLWTTeZV1mSkiRva2RbnRIJWQAAAOGDkIWI49lcIhj+tnDv1k26807pqKPKvl96urR6tZkO2Lu3dMYZpjHGK694r7gRsgAAAMIPIQsRxwpZy5ZJ77wjde5sdxysKM9QVdvH/2KOOsp0ICzPJ59I11wjjRxpxrZypelImJFh3qtTR5o8WZo1S/rnP6XzzjPVs6SkwMYPAACAqkfjC0QcK2Slp5uQ8vbbgd/L30pWWfr2NVMXV6/23cI9J0eaOlW6+25znJtrzjVoYKYntmoV0PABAABQDahkIeJYU+wswayTVZGQ9fffpip13HF2mLLO79lj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zPTp0zXF5YGZnJwcpaam+vNzgKBdfrnZ/vabWTfLMnKkaXpxwglSixbSN99IZ59tqlPNm9vXWSErLs6suSXZCxfv2uXfGOrWNdMKXQMdAAAA/FetIWvq1KkaP358mde0bdu2ZH/79u0aOHCg+vXrp+eff77C39enTx9JphLmK2TFxMQoxpqbBVQxp9Ped+00KEk7d0obN5opgZIJT1aAsng+j2VdJ/lfybrqKvMCAABAYKo1ZCUnJyvZmstUjm3btmngwIHq2bOnXn75ZdWqVfHHyVatWiVJahZIyzUghIYNkz75ROrd2/28a8hy/Su+fLn0yitm3zNYuQpFyJKkb7+VZsyQ2raVXnjB/88BAAAgTJ7J2rZtmwYMGKDWrVvrkUce0S6XeU9W58Bt27Zp0KBBevXVV9W7d2+tX79eb7zxhs4880w1atRIq1ev1o033qhTTjlF3bt3r66fAkiSXn1Veu016YIL3M+7hixXd94pLVpk9q3/LuF0Sv/8p1kP6557pMRE8zzXL7+436ei0wUlUy374ouyFzoGAACAd2ERsj777DOtW7dO69atU0uPftLO///XZGFhodauXVvSPTA6Olqff/65Zs+erby8PKWmpmrUqFG64447qnz8gKeGDaUbbih93lfIcp3BaoUmh8MsarxnjzRpkglZsbGS539DqEglq7BQatVKsppqWosfAwAAwH9hEbLGjx9f7rNbbdq0KQlckpSamqqvvvqqkkcGVA1vIUsybdz37DEdBrt29f7ZE04wjTK8LRdn/U/G4TDbbdvcuxVmZUkHDkjlreF9333Sxx9Lt90mnXNOuT8HAAAgooXtOllAJKrt4z97uIYs18cYreBkTev77DMTeL780r6mYUPppJOk9u3d73nggOkieMopdtiy2re3bWsHq+3byx5zYaH011/SDz9Iv/5a9rUAAAA1ASELOII8+qh5/fij+3nXkNWihb1vLUhsVZ/+9z/z/NaCBeV/19Kl0rp1psmFFaSskJWaan9PeVMG5841z5dJ0vr15X8vAABApAuL6YJATXHmmeblyQpZd90luS4P51nJ8tZdUDJB6qOPzNTBc8815/6/2aZq1bKvt0JWq1ZmCuHff5cfstautffXrSv7WgAAgJqAShYQBqyQlZ/vft6zkmWFrPh49+uWLJEeekh67z373IoVZvvAA1KDBmY/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", + "image/png": "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LgAAACBaELJiTOk1siRp4EDzAAAAABAc3JMVY+yQlZoa2nEAAAAA0YpKVow5eNBs7UrWsWNmn2VJGRkhGxYAAAAQNahkxZiy0wW//NKEqyFDQjYkAAAAIKoQsmJMYqLUoYPUsqV5TXdBAAAAILiYLhhjhgxxrVoRsgAAAIDgopIV4whZAAAAQHARsmIcIQsAAAAILkJWjHn8calzZ+m558xrQhYAAAAQXISsGLN5s/Tzz9K+feY1IQsAAAAILhpfxJiyixFnZEgXXeRs6Q4AAACgcghZMabsYsT160sffBC68QAAAADRhumCMabsYsQAAAAAgouQFWPchayiIunQIcmyQjMmAAAAIJoQsmJM2ZBVXCwlJJh7tPbsCd24AAAAgGhByIoxDRpIjRtL6enmdVycCVkSHQYBAACAYKDxRYz5+uvy+5KSpGPHpIKC6h8PAAAAEG2oZIG1sgAAAIAgImSBkAUAAAAEESErhhw6JHXpIvXqJR054txPyAIAAACCh3uyYsiBA9LKleZ5YqJzPyELAAAACB5CVgyx27enppqugrZTT5U6d5bq1AnNuAAAAIBoQsiKIe4WIpakF16o/rEAAAAA0Yp7smKIp5AFAAAAIHgIWTGk9HTBsixLKi6u3vEAAAAA0YiQFUM8VbKGDZPi46W33qr2IQEAAABRh5AVQ+LipOxsqWFD1/0Oh6lk0V0QAAAAqDwaX8SQYcPMoyxauAMAAADBEzGVrH379umyyy5TWlqaMjIydM011+iAPf/Ng/79+8vhcLg8brjhhmoaceQgZAEAAADBEzGVrMsuu0zbt2/XN998o8LCQl111VW67rrr9N5773k9b9SoUXr44YdLXqekpFT1UCMOIQsAAAAInoioZK1atUozZszQ3//+d5100knq27evXnjhBX3wwQfatm2b13NTUlKUlZVV8khLS6umUYefZ5+V+vSR/vY31/2ELAAAACB4IiJkzZ8/XxkZGerevXvJvkGDBikuLk4LFy70eu67776r+vXrq3PnzpowYYIOHTrk9fijR48qPz/f5REt1qyRvv9e2r7ddX9iotkSsgAAAIDKi4jpgjt27FCDBg1c9iUkJKhu3brasWOHx/MuvfRSNWvWTNnZ2VqxYoXuvvturVmzRp988onHcx577DFNnDgxaGMPJ55auHfsKA0eLLVtW/1jAgAAAKJN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McLN0qXB+6wff5Q6dZL+/Gf37/uzTlbr1tK550oXXeR9jSzJ3Af200/StGn+j7kySleyGjY0z6lkAQAAuBcxjS9Gjx5d8rxZs2YaP368hg0bpsLCQtVw080gLy9P//jHP/Tee+/pz///N+E33nhDHTp00IIFC3TyySdX29gRHipqp+6PoiLpl1+coagse50sX66ZmSl98ol5/t57ZuupkhUq7qYLUskCAABwL2IqWaXt27dP7777rnr37u02YEnS0qVLVVhYqEGDBpXsa9++vZo2bar58+d7/OyjR48qPz/f5YHoMG6c2Z51VuU/y65QVbROli+VrNLs0BZuIevOO00HxFGjqGQBAABUJKJC1t13363U1FTVq1dPmzdv1meffebx2B07digxMVEZZdq0NWzYUDvsG0zceOyxx5Senl7yyMnJCdbwEWKXXiotXy5NmVL5z6ponSy7kuVryLIsUxlat8689rbY7wknSE2amLW1qkt2tln3q21bZyVr717p2LHqGwMAAECkCGnIGj9+vBwOh9fH6tWrS44fN26cfvjhB3399deKj4/XiBEjZFlWUMc0YcIE5eXllTy2VOffZFGlHA7puOOCM22wdMhy90fQrmT5eq2xY83CxVOnSuecI3Xv7vnY33+Xtm71PFUxEPn50vbtvh1bt6709tvSV18F7/oAAADRJKT3ZI0dO1YjR470ekxLu/WapPr166t+/fpq27atOnTooJycHC1YsEC9evUqd15WVpYKCgqUm5vrUs3auXOnsrKyPF4vKSlJScG8eQdRqXSL9YKC8mHK3+mCzZqZbbduFVfa0tKkPXuCu1ZW9+6mirZrl1S/fvn3//pXc93LLzfbK64I3rUBAACiTUhDVmZmpjIzMwM6t7i4WJK5h8qdbt26qUaNGpo1a5aGDx8uSVqzZo02b97sNpQB/igdsg4fLh+yXnlF2rdP6tLFt88rvSBxRYK9IHFurvTrr+Z5nJva9rFj0j33mIrd8OHepzICAAAgQroLLly4UIsXL1bfvn1Vp04drV+/Xvfff79atWpVEpi2bt2qgQMH6u2331bPnj2Vnp6ua665RmPGjFHdunWVlpamW2+9Vb169aKzICqtRg2peXMpMdH9fUl/+pN/n2eHrDVrTJhxODwfG+yQtWaN2WZnm6mAZe3ZY8YUF+esci1caLor9uhh1u0C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\n", "text/plain": [ "
" ] @@ -357,45 +357,42 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'angles': [1.3376691454094367,\n", - " 1.8702720571077855,\n", - " 1.7106159414418016,\n", - " 1.7265171540852053],\n", - " 'cost': -2.8102329416649523,\n", - " 'eval_number': 233,\n", - " 'job_id': '8b656d30-7c45-46c4-9e2b-47950a744436',\n", - " 'measurement_outcomes': array([-0.0092713 -0.00533952j, -0.00087562-0.04750412j,\n", - " -0.03625747-0.03697144j, -0.04129102+0.10079314j,\n", - " -0.0460283 -0.02009872j, -0.03484736+0.06093418j,\n", - " -0.06609874+0.06584512j, -0.08054137+0.16913357j,\n", - " -0.00087562-0.04750412j, 0.0326305 +0.03989333j,\n", - " 0.01327079+0.00485964j, -0.02353963+0.12365387j,\n", - " -0.16281772+0.06138876j, -0.07184383+0.13061097j,\n", - " -0.08230322+0.08658721j, -0.06609874+0.06584512j,\n", - " -0.03625747-0.03697144j, 0.01327079+0.00485964j,\n", - " -0.07937384+0.0732019j , -0.17715889+0.16555488j,\n", - " -0.03931647+0.03033797j, 0.006359 +0.07155752j,\n", - " -0.07184383+0.13061097j, -0.03484736+0.06093418j,\n", - " -0.04129102+0.10079314j, -0.02353963+0.12365387j,\n", - " -0.17715889+0.16555488j, -0.15943086+0.08680181j,\n", - " -0.24404612+0.11407484j, -0.03931647+0.03033797j,\n", - " -0.16281772+0.06138876j, -0.0460283 -0.02009872j,\n", - " -0.0460283 -0.02009872j, -0.16281772+0.06138876j,\n", - " -0.03931647+0.03033797j, -0.24404612+0.11407484j,\n", - " -0.15943086+0.08680181j, -0.17715889+0.16555488j,\n", - " -0.02353963+0.12365387j, -0.04129102+0.10079314j,\n", - " -0.03484736+0.06093418j, -0.07184383+0.13061097j,\n", - " 0.006359 +0.07155752j, -0.03931647+0.03033797j,\n", - " -0.17715889+0.16555488j, -0.07937384+0.0732019j ,\n", - " 0.01327079+0.00485964j, -0.03625747-0.03697144j,\n", - " -0.06609874+0.06584512j, -0.08230322+0.08658721j,\n", - " -0.07184383+0.13061097j, -0.16281772+0.06138876j,\n", - " -0.02353963+0.12365387j, 0.01327079+0.00485964j,\n", - " 0.0326305 +0.03989333j, -0.00087562-0.04750412j,\n", - " -0.08054137+0.16913357j, -0.06609874+0.06584512j,\n", - " -0.03484736+0.06093418j, -0.0460283 -0.02009872j,\n", - " -0.04129102+0.10079314j, -0.03625747-0.03697144j,\n", - " -0.00087562-0.04750412j, -0.0092713 -0.00533952j])}\n" + "{'angles': [1.769305782568, 2.897276527017, 0.27595644591, 2.480445026305],\n", + " 'cost': -3.496189444142,\n", + " 'eval_number': 141,\n", + " 'job_id': 'a6a50e53-af90-4ec0-9072-c483d80b6324',\n", + " 'measurement_outcomes': array([ 0.04279569+0.01167147j, 0.0283793 -0.01355j ,\n", + " -0.00222483+0.01917223j, -0.00533755+0.07693892j,\n", + " 0.02755904+0.04136831j, -0.01193869+0.03540263j,\n", + " -0.04662524+0.05500205j, -0.17367993+0.07204963j,\n", + " 0.0283793 -0.01355j , -0.01946334+0.05474171j,\n", + " 0.01592744+0.01604248j, -0.07276544-0.03142119j,\n", + " 0.02799895+0.19571449j, -0.13116855+0.06518103j,\n", + " -0.09375135+0.05517573j, -0.04662524+0.05500205j,\n", + " -0.00222483+0.01917223j, 0.01592744+0.01604248j,\n", + " 0.00146576+0.13127059j, -0.06000884+0.24378125j,\n", + " -0.0239379 -0.02844671j, -0.00676705-0.04078231j,\n", + " -0.13116855+0.06518103j, -0.01193869+0.03540263j,\n", + " -0.00533755+0.07693892j, -0.07276544-0.03142119j,\n", + " -0.06000884+0.24378125j, -0.06935948+0.08524623j,\n", + " 0.14968271+0.31272273j, -0.0239379 -0.02844671j,\n", + " 0.02799895+0.19571449j, 0.02755904+0.04136831j,\n", + " 0.02755904+0.04136831j, 0.02799895+0.19571449j,\n", + " -0.0239379 -0.02844671j, 0.14968271+0.31272273j,\n", + " -0.06935948+0.08524623j, -0.06000884+0.24378125j,\n", + " -0.07276544-0.03142119j, -0.00533755+0.07693892j,\n", + " -0.01193869+0.03540263j, -0.13116855+0.06518103j,\n", + " -0.00676705-0.04078231j, -0.0239379 -0.02844671j,\n", + " -0.06000884+0.24378125j, 0.00146576+0.13127059j,\n", + " 0.01592744+0.01604248j, -0.00222483+0.01917223j,\n", + " -0.04662524+0.05500205j, -0.09375135+0.05517573j,\n", + " -0.13116855+0.06518103j, 0.02799895+0.19571449j,\n", + " -0.07276544-0.03142119j, 0.01592744+0.01604248j,\n", + " -0.01946334+0.05474171j, 0.0283793 -0.01355j ,\n", + " -0.17367993+0.07204963j, -0.04662524+0.05500205j,\n", + " -0.01193869+0.03540263j, 0.02755904+0.04136831j,\n", + " -0.00533755+0.07693892j, -0.00222483+0.01917223j,\n", + " 0.0283793 -0.01355j , 0.04279569+0.01167147j])}\n" ] } ], @@ -420,216 +417,190 @@ { "data": { "text/html": [ - "
      ┌───┐                                                                  »\n",
-       "q0_0: ┤ H ├─■─────────────────────■──────────────────────────────────────────»\n",
-       "      ├───┤ │                     │                                          »\n",
-       "q0_1: ┤ H ├─┼─────────────────────┼─────────────────────■────────────────────»\n",
-       "      ├───┤ │ZZ(3.4212318828836)  │                     │ZZ(3.4212318828836) »\n",
-       "q0_2: ┤ H ├─■─────────────────────┼─────────────────────■────────────────────»\n",
-       "      ├───┤                       │ZZ(3.4212318828836)                       »\n",
-       "q0_3: ┤ H ├───────────────────────■──────────────────────────────────────────»\n",
-       "      ├───┤                                                                  »\n",
-       "q0_4: ┤ H ├──────────────────────────────────────────────────────────────────»\n",
-       "      ├───┤                                                                  »\n",
-       "q0_5: ┤ H ├──────────────────────────────────────────────────────────────────»\n",
-       "      └───┘                                                                  »\n",
-       "«                            ┌───────────────────────┐                      »\n",
-       "«q0_0: ─■────────────────────┤ Rx(-2.67533829081887) ├──────────────────────»\n",
-       "«       │                    └───────────────────────┘                      »\n",
-       "«q0_1: ─┼───────────────────────■──────────────────────■────────────────────»\n",
-       "«       │                       │                      │                    »\n",
-       "«q0_2: ─┼───────────────────────┼──────────────────────┼────────────────────»\n",
-       "«       │                       │ZZ(3.4212318828836)   │                    »\n",
-       "«q0_3: ─┼───────────────────────■──────────────────────┼────────────────────»\n",
-       "«       │ZZ(3.4212318828836)                           │                    »\n",
-       "«q0_4: ─■──────────────────────────────────────────────┼────────────────────»\n",
-       "«                                                      │ZZ(3.4212318828836) »\n",
-       "«q0_5: ────────────────────────────────────────────────■────────────────────»\n",
-       "«                                                                           »\n",
-       "«                                                                              »\n",
-       "«q0_0: ────────────────────────────────────────────────────────────────────────»\n",
-       "«      ┌───────────────────────┐                                               »\n",
-       "«q0_1: ┤ Rx(-2.67533829081887) ├───────────────────────────────────────────────»\n",
-       "«      └───────────────────────┘                      ┌───────────────────────┐»\n",
-       "«q0_2: ───■──────────────────────■────────────────────┤ Rx(-2.67533829081887) ├»\n",
-       "«         │                      │                    └───────────────────────┘»\n",
-       "«q0_3: ───┼──────────────────────┼───────────────────────■─────────────────────»\n",
-       "«         │ZZ(3.4212318828836)   │                       │                     »\n",
-       "«q0_4: ───■──────────────────────┼───────────────────────┼─────────────────────»\n",
-       "«                                │ZZ(3.4212318828836)    │ZZ(3.4212318828836)  »\n",
-       "«q0_5: ──────────────────────────■───────────────────────■─────────────────────»\n",
-       "«                                                                              »\n",
-       "«                                                        »\n",
-       "«q0_0: ──■────────────────────────■──────────────────────»\n",
-       "«        │                        │                      »\n",
-       "«q0_1: ──┼────────────────────────┼──────────────────────»\n",
-       "«        │ZZ(3.45303430817041)    │                      »\n",
-       "«q0_2: ──■────────────────────────┼──────────────────────»\n",
-       "«      ┌───────────────────────┐  │ZZ(3.45303430817041)  »\n",
-       "«q0_3: ┤ Rx(-2.67533829081887) ├──■──────────────────────»\n",
-       "«      └───────────────────────┘┌───────────────────────┐»\n",
-       "«q0_4: ───■─────────────────────┤ Rx(-2.67533829081887) ├»\n",
-       "«         │ZZ(3.4212318828836)  ├───────────────────────┤»\n",
-       "«q0_5: ───■─────────────────────┤ Rx(-2.67533829081887) ├»\n",
-       "«                               └───────────────────────┘»\n",
-       "«                                                    ┌───────────────────────┐»\n",
-       "«q0_0: ────────────────────────■─────────────────────┤ Rx(-3.74054411421557) ├»\n",
-       "«                              │                     └───────────────────────┘»\n",
-       "«q0_1: ─■──────────────────────┼───────────────────────■──────────────────────»\n",
-       "«       │ZZ(3.45303430817041)  │                       │                      »\n",
-       "«q0_2: ─■──────────────────────┼───────────────────────┼──────────────────────»\n",
-       "«                              │                       │ZZ(3.45303430817041)  »\n",
-       "«q0_3: ────────────────────────┼───────────────────────■──────────────────────»\n",
-       "«                              │ZZ(3.45303430817041)                          »\n",
-       "«q0_4: ────────────────────────■──────────────────────────────────────────────»\n",
-       "«                                                                             »\n",
-       "«q0_5: ───────────────────────────────────────────────────────────────────────»\n",
-       "«                                                                             »\n",
-       "«                                                                             »\n",
-       "«q0_0: ───────────────────────────────────────────────────────────────────────»\n",
-       "«                             ┌───────────────────────┐                       »\n",
-       "«q0_1: ─■─────────────────────┤ Rx(-3.74054411421557) ├───────────────────────»\n",
-       "«       │                     └───────────────────────┘                       »\n",
-       "«q0_2: ─┼───────────────────────■───────────────────────■─────────────────────»\n",
-       "«       │                       │                       │                     »\n",
-       "«q0_3: ─┼───────────────────────┼───────────────────────┼─────────────────────»\n",
-       "«       │                       │ZZ(3.45303430817041)   │                     »\n",
-       "«q0_4: ─┼───────────────────────■───────────────────────┼─────────────────────»\n",
-       "«       │ZZ(3.45303430817041)                           │ZZ(3.45303430817041) »\n",
-       "«q0_5: ─■───────────────────────────────────────────────■─────────────────────»\n",
-       "«                                                                             »\n",
-       "«                                                        »\n",
-       "«q0_0: ──────────────────────────────────────────────────»\n",
-       "«                                                        »\n",
-       "«q0_1: ──────────────────────────────────────────────────»\n",
-       "«      ┌───────────────────────┐                         »\n",
-       "«q0_2: ┤ Rx(-3.74054411421557) ├─────────────────────────»\n",
-       "«      └───────────────────────┘┌───────────────────────┐»\n",
-       "«q0_3: ──■──────────────────────┤ Rx(-3.74054411421557) ├»\n",
-       "«        │                      └───────────────────────┘»\n",
-       "«q0_4: ──┼────────────────────────■──────────────────────»\n",
-       "«        │ZZ(3.45303430817041)    │ZZ(3.45303430817041)  »\n",
-       "«q0_5: ──■────────────────────────■──────────────────────»\n",
-       "«                                                        »\n",
-       "«                               \n",
-       "«q0_0: ─────────────────────────\n",
-       "«                               \n",
-       "«q0_1: ─────────────────────────\n",
-       "«                               \n",
-       "«q0_2: ─────────────────────────\n",
-       "«                               \n",
-       "«q0_3: ─────────────────────────\n",
-       "«      ┌───────────────────────┐\n",
-       "«q0_4: ┤ Rx(-3.74054411421557) ├\n",
-       "«      ├───────────────────────┤\n",
-       "«q0_5: ┤ Rx(-3.74054411421557) ├\n",
-       "«      └───────────────────────┘
" + "
      ┌───┐                                                            »\n",
+       "q0_0: ┤ H ├─■───────────────────■──────────────────────────────────────»\n",
+       "      ├───┤ │                   │                                      »\n",
+       "q0_1: ┤ H ├─┼───────────────────┼───────────────────■──────────────────»\n",
+       "      ├───┤ │ZZ(0.55191289182)  │                   │ZZ(0.55191289182) »\n",
+       "q0_2: ┤ H ├─■───────────────────┼───────────────────■──────────────────»\n",
+       "      ├───┤                     │ZZ(0.55191289182)                     »\n",
+       "q0_3: ┤ H ├─────────────────────■──────────────────────────────────────»\n",
+       "      ├───┤                                                            »\n",
+       "q0_4: ┤ H ├────────────────────────────────────────────────────────────»\n",
+       "      ├───┤                                                            »\n",
+       "q0_5: ┤ H ├────────────────────────────────────────────────────────────»\n",
+       "      └───┘                                                            »\n",
+       "«                          ┌─────────────────────┐                    »\n",
+       "«q0_0: ─■──────────────────┤ Rx(-3.538611565136) ├────────────────────»\n",
+       "«       │                  └─────────────────────┘                    »\n",
+       "«q0_1: ─┼─────────────────────■────────────────────■──────────────────»\n",
+       "«       │                     │                    │                  »\n",
+       "«q0_2: ─┼─────────────────────┼────────────────────┼──────────────────»\n",
+       "«       │                     │ZZ(0.55191289182)   │                  »\n",
+       "«q0_3: ─┼─────────────────────■────────────────────┼──────────────────»\n",
+       "«       │ZZ(0.55191289182)                         │                  »\n",
+       "«q0_4: ─■──────────────────────────────────────────┼──────────────────»\n",
+       "«                                                  │ZZ(0.55191289182) »\n",
+       "«q0_5: ────────────────────────────────────────────■──────────────────»\n",
+       "«                                                                     »\n",
+       "«                                                                        »\n",
+       "«q0_0: ──────────────────────────────────────────────────────────────────»\n",
+       "«      ┌─────────────────────┐                                           »\n",
+       "«q0_1: ┤ Rx(-3.538611565136) ├───────────────────────────────────────────»\n",
+       "«      └─────────────────────┘                    ┌─────────────────────┐»\n",
+       "«q0_2: ───■────────────────────■──────────────────┤ Rx(-3.538611565136) ├»\n",
+       "«         │                    │                  └─────────────────────┘»\n",
+       "«q0_3: ───┼────────────────────┼─────────────────────■───────────────────»\n",
+       "«         │ZZ(0.55191289182)   │                     │                   »\n",
+       "«q0_4: ───■────────────────────┼─────────────────────┼───────────────────»\n",
+       "«                              │ZZ(0.55191289182)    │ZZ(0.55191289182)  »\n",
+       "«q0_5: ────────────────────────■─────────────────────■───────────────────»\n",
+       "«                                                                        »\n",
+       "«                                                                        »\n",
+       "«q0_0: ───■──────────────────────■───────────────────────────────────────»\n",
+       "«         │                      │                                       »\n",
+       "«q0_1: ───┼──────────────────────┼────────────────────■──────────────────»\n",
+       "«         │ZZ(4.96089005261)     │                    │ZZ(4.96089005261) »\n",
+       "«q0_2: ───■──────────────────────┼────────────────────■──────────────────»\n",
+       "«      ┌─────────────────────┐   │ZZ(4.96089005261)                      »\n",
+       "«q0_3: ┤ Rx(-3.538611565136) ├───■───────────────────────────────────────»\n",
+       "«      └─────────────────────┘┌─────────────────────┐                    »\n",
+       "«q0_4: ───■───────────────────┤ Rx(-3.538611565136) ├────────────────────»\n",
+       "«         │ZZ(0.55191289182)  ├─────────────────────┤                    »\n",
+       "«q0_5: ───■───────────────────┤ Rx(-3.538611565136) ├────────────────────»\n",
+       "«                             └─────────────────────┘                    »\n",
+       "«                          ┌─────────────────────┐                    »\n",
+       "«q0_0: ─■──────────────────┤ Rx(-5.794553054034) ├────────────────────»\n",
+       "«       │                  └─────────────────────┘                    »\n",
+       "«q0_1: ─┼─────────────────────■────────────────────■──────────────────»\n",
+       "«       │                     │                    │                  »\n",
+       "«q0_2: ─┼─────────────────────┼────────────────────┼──────────────────»\n",
+       "«       │                     │ZZ(4.96089005261)   │                  »\n",
+       "«q0_3: ─┼─────────────────────■────────────────────┼──────────────────»\n",
+       "«       │ZZ(4.96089005261)                         │                  »\n",
+       "«q0_4: ─■──────────────────────────────────────────┼──────────────────»\n",
+       "«                                                  │ZZ(4.96089005261) »\n",
+       "«q0_5: ────────────────────────────────────────────■──────────────────»\n",
+       "«                                                                     »\n",
+       "«                                                                        »\n",
+       "«q0_0: ──────────────────────────────────────────────────────────────────»\n",
+       "«      ┌─────────────────────┐                                           »\n",
+       "«q0_1: ┤ Rx(-5.794553054034) ├───────────────────────────────────────────»\n",
+       "«      └─────────────────────┘                    ┌─────────────────────┐»\n",
+       "«q0_2: ───■────────────────────■──────────────────┤ Rx(-5.794553054034) ├»\n",
+       "«         │                    │                  └─────────────────────┘»\n",
+       "«q0_3: ───┼────────────────────┼─────────────────────■───────────────────»\n",
+       "«         │ZZ(4.96089005261)   │                     │                   »\n",
+       "«q0_4: ───■────────────────────┼─────────────────────┼───────────────────»\n",
+       "«                              │ZZ(4.96089005261)    │ZZ(4.96089005261)  »\n",
+       "«q0_5: ────────────────────────■─────────────────────■───────────────────»\n",
+       "«                                                                        »\n",
+       "«                                                    \n",
+       "«q0_0: ──────────────────────────────────────────────\n",
+       "«                                                    \n",
+       "«q0_1: ──────────────────────────────────────────────\n",
+       "«                                                    \n",
+       "«q0_2: ──────────────────────────────────────────────\n",
+       "«      ┌─────────────────────┐                       \n",
+       "«q0_3: ┤ Rx(-5.794553054034) ├───────────────────────\n",
+       "«      └─────────────────────┘┌─────────────────────┐\n",
+       "«q0_4: ───■───────────────────┤ Rx(-5.794553054034) ├\n",
+       "«         │ZZ(4.96089005261)  ├─────────────────────┤\n",
+       "«q0_5: ───■───────────────────┤ Rx(-5.794553054034) ├\n",
+       "«                             └─────────────────────┘
" ], "text/plain": [ - " ┌───┐ »\n", - "q0_0: ┤ H ├─■─────────────────────■──────────────────────────────────────────»\n", - " ├───┤ │ │ »\n", - "q0_1: ┤ H ├─┼─────────────────────┼─────────────────────■────────────────────»\n", - " ├───┤ │ZZ(3.4212318828836) │ │ZZ(3.4212318828836) »\n", - "q0_2: ┤ H ├─■─────────────────────┼─────────────────────■────────────────────»\n", - " ├───┤ │ZZ(3.4212318828836) »\n", - "q0_3: ┤ H ├───────────────────────■──────────────────────────────────────────»\n", - " ├───┤ »\n", - "q0_4: ┤ H ├──────────────────────────────────────────────────────────────────»\n", - " ├───┤ »\n", - "q0_5: ┤ H ├──────────────────────────────────────────────────────────────────»\n", - " └───┘ »\n", - "« ┌───────────────────────┐ »\n", - "«q0_0: ─■────────────────────┤ Rx(-2.67533829081887) ├──────────────────────»\n", - "« │ └───────────────────────┘ »\n", - "«q0_1: ─┼───────────────────────■──────────────────────■────────────────────»\n", - "« │ │ │ »\n", - "«q0_2: ─┼───────────────────────┼──────────────────────┼────────────────────»\n", - "« │ │ZZ(3.4212318828836) │ »\n", - "«q0_3: ─┼───────────────────────■──────────────────────┼────────────────────»\n", - "« │ZZ(3.4212318828836) │ »\n", - "«q0_4: ─■──────────────────────────────────────────────┼────────────────────»\n", - "« │ZZ(3.4212318828836) »\n", - "«q0_5: ────────────────────────────────────────────────■────────────────────»\n", - "« »\n", - "« »\n", - "«q0_0: ────────────────────────────────────────────────────────────────────────»\n", - "« ┌───────────────────────┐ »\n", - "«q0_1: ┤ Rx(-2.67533829081887) ├───────────────────────────────────────────────»\n", - "« └───────────────────────┘ ┌───────────────────────┐»\n", - "«q0_2: ───■──────────────────────■────────────────────┤ Rx(-2.67533829081887) ├»\n", - "« │ │ └───────────────────────┘»\n", - "«q0_3: ───┼──────────────────────┼───────────────────────■─────────────────────»\n", - "« │ZZ(3.4212318828836) │ │ »\n", - "«q0_4: ───■──────────────────────┼───────────────────────┼─────────────────────»\n", - "« │ZZ(3.4212318828836) │ZZ(3.4212318828836) »\n", - "«q0_5: ──────────────────────────■───────────────────────■─────────────────────»\n", - "« »\n", - "« »\n", - "«q0_0: ──■────────────────────────■──────────────────────»\n", - "« │ │ »\n", - "«q0_1: ──┼────────────────────────┼──────────────────────»\n", - "« │ZZ(3.45303430817041) │ »\n", - "«q0_2: ──■────────────────────────┼──────────────────────»\n", - "« ┌───────────────────────┐ │ZZ(3.45303430817041) »\n", - "«q0_3: ┤ Rx(-2.67533829081887) ├──■──────────────────────»\n", - "« └───────────────────────┘┌───────────────────────┐»\n", - "«q0_4: ───■─────────────────────┤ Rx(-2.67533829081887) ├»\n", - "« │ZZ(3.4212318828836) ├───────────────────────┤»\n", - "«q0_5: ───■─────────────────────┤ Rx(-2.67533829081887) ├»\n", - "« └───────────────────────┘»\n", - "« ┌───────────────────────┐»\n", - "«q0_0: ────────────────────────■─────────────────────┤ Rx(-3.74054411421557) ├»\n", - "« │ └───────────────────────┘»\n", - "«q0_1: ─■──────────────────────┼───────────────────────■──────────────────────»\n", - "« │ZZ(3.45303430817041) │ │ »\n", - "«q0_2: ─■──────────────────────┼───────────────────────┼──────────────────────»\n", - "« │ │ZZ(3.45303430817041) »\n", - "«q0_3: ────────────────────────┼───────────────────────■──────────────────────»\n", - "« │ZZ(3.45303430817041) »\n", - "«q0_4: ────────────────────────■──────────────────────────────────────────────»\n", - "« »\n", - "«q0_5: ───────────────────────────────────────────────────────────────────────»\n", - "« »\n", - "« »\n", - "«q0_0: ───────────────────────────────────────────────────────────────────────»\n", - "« ┌───────────────────────┐ »\n", - "«q0_1: ─■─────────────────────┤ Rx(-3.74054411421557) ├───────────────────────»\n", - "« │ └───────────────────────┘ »\n", - "«q0_2: ─┼───────────────────────■───────────────────────■─────────────────────»\n", - "« │ │ │ »\n", - "«q0_3: ─┼───────────────────────┼───────────────────────┼─────────────────────»\n", - "« │ │ZZ(3.45303430817041) │ »\n", - "«q0_4: ─┼───────────────────────■───────────────────────┼─────────────────────»\n", - "« │ZZ(3.45303430817041) │ZZ(3.45303430817041) »\n", - "«q0_5: ─■───────────────────────────────────────────────■─────────────────────»\n", - "« »\n", - "« »\n", - "«q0_0: ──────────────────────────────────────────────────»\n", - "« »\n", - "«q0_1: ──────────────────────────────────────────────────»\n", - "« ┌───────────────────────┐ »\n", - "«q0_2: ┤ Rx(-3.74054411421557) ├─────────────────────────»\n", - "« └───────────────────────┘┌───────────────────────┐»\n", - "«q0_3: ──■──────────────────────┤ Rx(-3.74054411421557) ├»\n", - "« │ └───────────────────────┘»\n", - "«q0_4: ──┼────────────────────────■──────────────────────»\n", - "« │ZZ(3.45303430817041) │ZZ(3.45303430817041) »\n", - "«q0_5: ──■────────────────────────■──────────────────────»\n", - "« »\n", - "« \n", - "«q0_0: ─────────────────────────\n", - "« \n", - "«q0_1: ─────────────────────────\n", - "« \n", - "«q0_2: ─────────────────────────\n", - "« \n", - "«q0_3: ─────────────────────────\n", - "« ┌───────────────────────┐\n", - "«q0_4: ┤ Rx(-3.74054411421557) ├\n", - "« ├───────────────────────┤\n", - "«q0_5: ┤ Rx(-3.74054411421557) ├\n", - "« └───────────────────────┘" + " ┌───┐ »\n", + "q0_0: ┤ H ├─■───────────────────■──────────────────────────────────────»\n", + " ├───┤ │ │ »\n", + "q0_1: ┤ H ├─┼───────────────────┼───────────────────■──────────────────»\n", + " ├───┤ │ZZ(0.55191289182) │ │ZZ(0.55191289182) »\n", + "q0_2: ┤ H ├─■───────────────────┼───────────────────■──────────────────»\n", + " ├───┤ │ZZ(0.55191289182) »\n", + "q0_3: ┤ H ├─────────────────────■──────────────────────────────────────»\n", + " ├───┤ »\n", + "q0_4: ┤ H ├────────────────────────────────────────────────────────────»\n", + " ├───┤ »\n", + "q0_5: ┤ H ├────────────────────────────────────────────────────────────»\n", + " └───┘ »\n", + "« ┌─────────────────────┐ »\n", + "«q0_0: ─■──────────────────┤ Rx(-3.538611565136) ├────────────────────»\n", + "« │ └─────────────────────┘ »\n", + "«q0_1: ─┼─────────────────────■────────────────────■──────────────────»\n", + "« │ │ │ »\n", + "«q0_2: ─┼─────────────────────┼────────────────────┼──────────────────»\n", + "« │ │ZZ(0.55191289182) │ »\n", + "«q0_3: ─┼─────────────────────■────────────────────┼──────────────────»\n", + "« │ZZ(0.55191289182) │ »\n", + "«q0_4: ─■──────────────────────────────────────────┼──────────────────»\n", + "« │ZZ(0.55191289182) »\n", + "«q0_5: ────────────────────────────────────────────■──────────────────»\n", + "« »\n", + "« »\n", + "«q0_0: ──────────────────────────────────────────────────────────────────»\n", + "« ┌─────────────────────┐ »\n", + "«q0_1: ┤ Rx(-3.538611565136) ├───────────────────────────────────────────»\n", + "« └─────────────────────┘ ┌─────────────────────┐»\n", + "«q0_2: ───■────────────────────■──────────────────┤ Rx(-3.538611565136) ├»\n", + "« │ │ └─────────────────────┘»\n", + "«q0_3: ───┼────────────────────┼─────────────────────■───────────────────»\n", + "« │ZZ(0.55191289182) │ │ »\n", + "«q0_4: ───■────────────────────┼─────────────────────┼───────────────────»\n", + "« │ZZ(0.55191289182) │ZZ(0.55191289182) »\n", + "«q0_5: ────────────────────────■─────────────────────■───────────────────»\n", + "« »\n", + "« »\n", + "«q0_0: ───■──────────────────────■───────────────────────────────────────»\n", + "« │ │ »\n", + "«q0_1: ───┼──────────────────────┼────────────────────■──────────────────»\n", + "« │ZZ(4.96089005261) │ │ZZ(4.96089005261) »\n", + "«q0_2: ───■──────────────────────┼────────────────────■──────────────────»\n", + "« ┌─────────────────────┐ │ZZ(4.96089005261) »\n", + "«q0_3: ┤ Rx(-3.538611565136) ├───■───────────────────────────────────────»\n", + "« └─────────────────────┘┌─────────────────────┐ »\n", + "«q0_4: ───■───────────────────┤ Rx(-3.538611565136) ├────────────────────»\n", + "« │ZZ(0.55191289182) ├─────────────────────┤ »\n", + "«q0_5: ───■───────────────────┤ Rx(-3.538611565136) ├────────────────────»\n", + "« └─────────────────────┘ »\n", + "« ┌─────────────────────┐ »\n", + "«q0_0: ─■──────────────────┤ Rx(-5.794553054034) ├────────────────────»\n", + "« │ └─────────────────────┘ »\n", + "«q0_1: ─┼─────────────────────■────────────────────■──────────────────»\n", + "« │ │ │ »\n", + "«q0_2: ─┼─────────────────────┼────────────────────┼──────────────────»\n", + "« │ │ZZ(4.96089005261) │ »\n", + "«q0_3: ─┼─────────────────────■────────────────────┼──────────────────»\n", + "« │ZZ(4.96089005261) │ »\n", + "«q0_4: ─■──────────────────────────────────────────┼──────────────────»\n", + "« │ZZ(4.96089005261) »\n", + "«q0_5: ────────────────────────────────────────────■──────────────────»\n", + "« »\n", + "« »\n", + "«q0_0: ──────────────────────────────────────────────────────────────────»\n", + "« ┌─────────────────────┐ »\n", + "«q0_1: ┤ Rx(-5.794553054034) ├───────────────────────────────────────────»\n", + "« └─────────────────────┘ ┌─────────────────────┐»\n", + "«q0_2: ───■────────────────────■──────────────────┤ Rx(-5.794553054034) ├»\n", + "« │ │ └─────────────────────┘»\n", + "«q0_3: ───┼────────────────────┼─────────────────────■───────────────────»\n", + "« │ZZ(4.96089005261) │ │ »\n", + "«q0_4: ───■────────────────────┼─────────────────────┼───────────────────»\n", + "« │ZZ(4.96089005261) │ZZ(4.96089005261) »\n", + "«q0_5: ────────────────────────■─────────────────────■───────────────────»\n", + "« »\n", + "« \n", + "«q0_0: ──────────────────────────────────────────────\n", + "« \n", + "«q0_1: ──────────────────────────────────────────────\n", + "« \n", + "«q0_2: ──────────────────────────────────────────────\n", + "« ┌─────────────────────┐ \n", + "«q0_3: ┤ Rx(-5.794553054034) ├───────────────────────\n", + "« └─────────────────────┘┌─────────────────────┐\n", + "«q0_4: ───■───────────────────┤ Rx(-5.794553054034) ├\n", + "« │ZZ(4.96089005261) ├─────────────────────┤\n", + "«q0_5: ───■───────────────────┤ Rx(-5.794553054034) ├\n", + "« └─────────────────────┘" ] }, "execution_count": 16, @@ -650,9 +621,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "test_env", "language": "python", - "name": "python3" + "name": "test_env" }, "language_info": { "codemirror_mode": { @@ -664,7 +635,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.9.0" }, "vscode": { "interpreter": { diff --git a/examples/03_qaoa_on_qpus.ipynb b/examples/03_qaoa_on_qpus.ipynb index 1ea2ca314..32d99e311 100644 --- a/examples/03_qaoa_on_qpus.ipynb +++ b/examples/03_qaoa_on_qpus.ipynb @@ -30,12 +30,6 @@ }, "outputs": [], "source": [ - "#some regular python libraries\n", - "import networkx as nx\n", - "import numpy as np\n", - "from pprint import pprint\n", - "import matplotlib.pyplot as plt\n", - "\n", "#import problem classes from OQ for easy problem creation\n", "from openqaoa.problems import NumberPartition\n", "\n", @@ -75,9 +69,9 @@ }, "outputs": [], "source": [ - "# Find partition of a list of 8 numbers generated randomly\n", - "np = NumberPartition.random_instance(n_numbers=8)\n", - "np_qubo = np.qubo" + "# Find partition of a list of 7 numbers generated randomly\n", + "prob = NumberPartition.random_instance(n_numbers=7)\n", + "prob_qubo = prob.qubo" ] }, { @@ -92,7 +86,7 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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\n", "text/plain": [ "
" ] @@ -106,7 +100,7 @@ "from openqaoa.utilities import plot_graph, graph_from_hamiltonian\n", "\n", "#extract Hamiltonain\n", - "cost_hamil = np_qubo.hamiltonian\n", + "cost_hamil = prob_qubo.hamiltonian\n", "\n", "#convert Hamiltonian to graph\n", "cost_gr = graph_from_hamiltonian(cost_hamil)\n", @@ -129,80 +123,19 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'constant': 308,\n", - " 'metadata': {},\n", - " 'n': 8,\n", - " 'problem_instance': {'n_numbers': 8,\n", - " 'numbers': [5, 2, 8, 6, 4, 9, 9, 1],\n", - " 'problem_type': 'number_partition'},\n", - " 'terms': [[0, 1],\n", - " [0, 2],\n", - " [0, 3],\n", - " [0, 4],\n", - " [0, 5],\n", - " [0, 6],\n", - " [0, 7],\n", - " [1, 2],\n", - " [1, 3],\n", - " [1, 4],\n", - " [1, 5],\n", - " [1, 6],\n", - " [1, 7],\n", - " [2, 3],\n", - " [2, 4],\n", - " [2, 5],\n", - " [2, 6],\n", - " [2, 7],\n", - " [3, 4],\n", - " [3, 5],\n", - " [3, 6],\n", - " [3, 7],\n", - " [4, 5],\n", - " [4, 6],\n", - " [4, 7],\n", - " [5, 6],\n", - " [5, 7],\n", - " [6, 7]],\n", - " 'weights': [20.0,\n", - " 80.0,\n", - " 60.0,\n", - " 40.0,\n", - " 90.0,\n", - " 90.0,\n", - " 10.0,\n", - " 32.0,\n", - " 24.0,\n", - " 16.0,\n", - " 36.0,\n", - " 36.0,\n", - " 4.0,\n", - " 96.0,\n", - " 64.0,\n", - " 144.0,\n", - " 144.0,\n", - " 16.0,\n", - " 48.0,\n", - " 108.0,\n", - " 108.0,\n", - " 12.0,\n", - " 72.0,\n", - " 72.0,\n", - " 8.0,\n", - " 162.0,\n", - " 18.0,\n", - " 18.0]}\n" + "{'terms': [[0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 3], [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6], [4, 5], [4, 6], [5, 6]], 'weights': [112.0, 112.0, 64.0, 64.0, 80.0, 112.0, 98.0, 56.0, 56.0, 70.0, 98.0, 56.0, 56.0, 70.0, 98.0, 32.0, 40.0, 56.0, 40.0, 56.0, 70.0], 'constant': 268, 'n': 7, 'problem_instance': {'problem_type': 'number_partition', 'numbers': [8, 7, 7, 4, 4, 5, 7], 'n_numbers': 7}, 'metadata': {}}\n" ] } ], "source": [ - "pprint(np_qubo.asdict())" + "print(prob_qubo.asdict())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Extract the exact solution\n", + " ### Extract the exact solution\n", "\n" ] }, @@ -220,7 +153,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Ground State energy: 0.0, Solution: ['10100100', '11010100', '10100010', '11010010', '00001110', '11110001', '00101101', '01011101', '00101011', '01011011']\n" + "Ground State energy: 0.0, Solution: ['1001110', '0110001']\n" ] } ], @@ -234,7 +167,9 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ "## Step 2: Build the QAOA model on QPUs and cloud simulators\n", "\n", @@ -256,9 +191,11 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ - "Demo for IBMQ cloud simulators and QPUs" + "## Demo for IBMQ cloud simulators and QPUs" ] }, { @@ -283,7 +220,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "To make our tests run, we load our own credentials through the test-credentials :) " + "To make our tests run, we load our own credentials which have been pre-loaded through `IBMQ.save_account`" ] }, { @@ -291,29 +228,40 @@ "execution_count": 7, "metadata": { "ExecuteTime": { - "end_time": "2022-10-19T06:41:20.034065Z", - "start_time": "2022-10-19T06:41:20.030893Z" + "end_time": "2022-10-19T06:41:20.045470Z", + "start_time": "2022-10-19T06:41:20.043009Z" } }, "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, "source": [ - "hub,group and project can be specified during `save_account` or when `create_device` is called later. Note that if the values that are passed into `create_device` take precendent" + "# initialize model with default configurations\n", + "q_qiskit = QAOA()" ] }, { "cell_type": "code", "execution_count": 8, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2022-10-19T06:41:20.051201Z", + "start_time": "2022-10-19T06:41:20.047078Z" + } + }, "outputs": [], "source": [ - "# overwrite is optional. It ensures that only 1 account exists.\n", - "# This only needs to be done once in a session.\n", - "IBMQ.load_account()" + "# device. If qpu_crendetials is not specified,the default hub, group and provider is used.\n", + "qiskit_cloud = create_device(location='ibmq', name='ibm_oslo', **qpu_credentials, as_emulator=True)\n", + "q_qiskit.set_device(qiskit_cloud)\n", + "\n", + "# circuit properties\n", + "q_qiskit.set_circuit_properties(p=1, param_type='standard', init_type='rand', mixer_hamiltonian='x')\n", + "\n", + "# backend properties (already set by default)\n", + "q_qiskit.set_backend_properties(prepend_state=None, append_state=None)\n", + "\n", + "# classical optimizer properties\n", + "q_qiskit.set_classical_optimizer(method='nelder-mead', maxiter=20, cost_progress=True,\n", + " parameter_log=True, optimization_progress=True)" ] }, { @@ -321,52 +269,73 @@ "execution_count": 9, "metadata": { "ExecuteTime": { - "end_time": "2022-10-19T06:41:20.045470Z", - "start_time": "2022-10-19T06:41:20.043009Z" - } + "end_time": "2022-10-19T06:41:27.106986Z", + "start_time": "2022-10-19T06:41:20.082536Z" + }, + "tags": [] }, "outputs": [], "source": [ - "# initialize model with default configurations\n", - "q_qiskit = QAOA()" + "q_qiskit.compile(prob_qubo)\n", + "# to use routing, pass your custom function as below\n", + "# q_qiskit.compile(prob_qubo, routing_function = my_custom_routing)" ] }, { "cell_type": "code", "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "42\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABsgAAAs+CAYAAACEIcojAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdeXhU1f348fckIQlL2Pd9DciOIKAgGgXFFddaq9YFl9ZSta51abU/64KiVrRa9evW2lqqaKtQFRVUUFGQRWQx7BJIgLAnELLN74+p0UgiSUhmksz79Tx5Qu4995zPHWbuvXM/95wTCAaDQSRJkiRJkiRJkqQoERPpACRJkiRJkiRJkqRwMkEmSZIkSZIkSZKkqGKCTJIkSZIkSZIkSVHFBJkkSZIkSZIkSZKiigkySZIkSZIkSZIkRRUTZJIkSZIkSZIkSYoqJsgkSZIkSZIkSZIUVUyQSZIkSZIkSZIkKaqYIJMkSZIkSZIkSVJUMUEmSZIkSZIkSZKkqGKCTJIkSZIkSZIkSVHFBJkkSZIkSZIkSZKiigkySZIkSZIkSZIkRRUTZJIkSZIkSZIkSYoqJsgkSZIkSZIkSZIUVUyQSZIkSZIkSZIkKaqYIJMkSZIkSZIkSVJUMUEmSZIkSZIkSZKkqGKCTJIkSZIkSZIkSVHFBJkkSZIkSZIkSZKiigkySZIkSZIkSZIkRRUTZJIkSZIkSZIkSYoqJsgkSZIkSZIkSZIUVUyQSZIkSZIkSZIkKaqYIJMkSZIkSZIkSVJUMUEmSZIkSZIkSZKkqGKCTJIkSZIkSZIkSVHFBJkkSZIkSZIkSZKiigkySZIkSZIkSZIkRRUTZJIkSZIkSZIkSYoqJsgkSZIkSZIkSZIUVUyQSZIkSZIkSZIkKaqYIJMkSZIkSZIkSVJUMUEmSZIkSZIkSZKkqGKCTJIkSZIkSZIkSVHFBJkkSZIkSZIkSZKiigkySZIkSZIkSZIkRZW4SAegyhMMQm5BpKMon/hYCAQiHYUkSZIkSZIkSYomJshqkdwCuGVKpKMon4nnQYLvQkmSJEmSJEmSFEYOsShJkiRJkiRJkqSoYoJMkiRJkiRJkiRJUcUEmSRJkiRJkiRJkqKKCTJJkiRJkiRJkiRFFRNkkiRJkiRJkiRJiiomyCRJkiRJkiRJkhRVTJBJkiRJkiRJkiQpqpggkyRJkiRJkiRJUlQxQSZJkiRJkiRJkqSoYoJMkiRJkiRJkiRJUcUEmSRJkiRJkiRJkqKKCbJSzJgxg7Fjx9KsWTPq1atHv379uO+++8jNzY10aJIkSZIkSZIkSToEJshK8NBDD3HiiSfyzjvvkJSURM+ePVmxYgW33XYbKSkp7Nu3L9IhSpIkSZIkSZIkqYLiIh1AdfP5559z0003EQgEeP7557n44osBWL16NWPHjuWTTz7h1ltv5U9/+lNkA1VYFBTChu2QvR/iYqBlQ2hSP9JRSQqnXXshYxfkF0C9BOjYDGKj6PGS/AL4Zhvsy4U6cdCmESTVjXRUksJpWxZk7oH8QmiQAB2aQUwg0lGFT24+bNgGOXkQHwftmoTOB5IkRYsd2bBld+i7Qf1E6NgUYqLoO1G0CwZD34l3ZEMgAI3rQZvGkY5KkipHIBgMBiMdRHVy2mmnMW3aNC677DKeffbZYus++ugjjjnmGOLj49mwYQMtW7aMUJQl258Pt0w59HrSln3A1HtTGHn+gww+5cYSyzx6YYDOA09h3I3TDqmtiedBQjVM02bvh09WwscrYefe75YHAtC7LRzdE3q1iVx8kqreys0w+2v4Kg0Kv3embFQXjuwOI3rU7kTRrr0wJxU+XQ1ZOd8tj42B/h3g6GToWr1Og5IqUTAIyzbC7FRYkV58XbMGoWPg8O5QLz4y8YVD5p7Q/n++JvSQwLfiYmFw59BxsH3TiIUnSVKVW74p9J1g2Ub4/s3DJvXgqB6hn/o+NFJr5RfA/HXwcWro4fHv69gsdD04uHPo2kiSaqpa/7xHZmYmN998M927dycxMZEOHTpw7bXXkp2dzfjx4wkEAjz++OMA7NmzhxkzZgBwxRVXHFDXqFGjSE5OJjc3lzfeeCOs+6HwydgFk96C6YuLJ8cgdLNo6Ub4y0x4/YviN80l1Q7BIPx3Mfz5Pfhyw4Gf81374O0l8OBbsHFHZGKsausy4YH/wrtLiyfHINSzduF6mPwuvLc0MvFJqlqFhfCvz+GZDw9MjkGoR9kbC+GRt0NJpNpo+abQcfDDFcWTYxC6WfTZanj4bZi7OjLxSZJUlQqD8Np8eGpW6B7ID2997Ngbumcy6S3YvCsiIaqK7cuFv8yCf849MDkGoVFGXp4beo/k5IU/PkmqLLU6QbZo0SL69evHgw8+SEZGBr179yYvL4/Jkydz3nnnsXz5cgAGDhwIwMKFC8nNzSUhIYEhQ4aUWOfIkSMBmDt3blj2QeG1cy88+X6o2/jBfLgCpi+q8pAkhdl7S2HGVwcvt3tf6HhR224OZ+wKPQSQvf/gZactCh0LJdUur38Bn646eLmte+DJmbAn5+Bla5I1W+DZD0NDK/6YwmDoptGCdWEJS5KksJm+CD76+uDldmTDE+8f+HCxarb8Anj2I1i1+eBlV26G5z4KbSNJNVGtTZBlZmZy2mmnkZGRwQ033EB6ejoLFiwgIyODiRMnMn36dObNm0cgEKB///4ApKamAtCpUyfi4koe969bt27Fyqp2+e/iUO+Qsnp/GWzeXXXxSAqvHdnw3y/LXj5rfyhJVJv8+4vyPQH4xsIDe5lJqrk2bAsNK1hW27LK9lBBTREMwqvzQvOtldXU+ZDnTSFJUi2RsSt0r6Osdu2Dt8rxHUrV37y1ZUuOfSs1A75YV2XhSFKVqrUJsmuuuYa0tDQmTJjApEmTSEpKKlp38803M2DAAPLz8+ncuTMNGzYEYMeO0FhZTZo0KbXeb9d9W7Y2y8/dy749mSX+1EbZ+2HB+vJv98nKyo9FUmR8uip0c7Q8vtwQmq+rNti6p+Th1H5MQWFoqDFJtcPHFbiumbcG9teSoXXWboVNO8u3TfZ+WFSBa0hJkqqjitzj+GId7C3DCBSq/oLB0Lxz5VWRa0hJqg5qZYJs+fLlTJkyhebNm3PfffeVWGbw4MEADBgwoGhZTk7oEfj4+NJnG09ICM0+um9f8W5Ga9eu5fTTTycpKYkmTZrw85//nG3bth3SfkTa3Kl38vQvW5T4UxstXF+xLuGfryn/DXVJ1VNFEj2FwdrztNy8NRXb7rMKbiepeskvqNjxLCcPlqRVejgR8XkFj2cV3U6SpOokGKzYOS2/IHRPRTXfpp0Vm2v7m22QvrOyo5Gk0gWDQbKzs8nOziZ4CDfnSx5HsIZ7+eWXKSws5IILLqBBgwYllqlbty5QPEGWmJgIQG5ubonbAOzfv7/Y9gB79uwhJSWFpk2b8vLLL7Nv3z5uvvlmTj31VD7++GNiYiqWhxwyZAgZGRllLh9bpy5n/rHyHtnom3IlPYadW+K61+8fUyltJPfoQUFeOcY0rEJ9x/6WXikTyr3dvlzo0q0n+bllmLhMUvUViOGc+7+p0KYPPf4cP3/j95UcUPgNOfdhOg/5Sbm327Q1m/bte1ZBRJLCKTGpFafe8UWFtr3ld/fx9Qd/ruSIwm/k+JdonXxsubdbsHQt7S85uvIDkiQpjOISkzjjD8srtO3/mziZpe88UMkRKdza9DqeEZe+WKFtTz3rQjanflC5AUlSKQoLC0lPDw2DNHDgQBYuXFihemplgmzmzJkApKSklFomLS30mOv3E2RlGT6xpGEYn376aTZu3MhHH31Ex44dAWjfvj1HHXUUb7zxBmeccUaF9iMjI4ONGzeWuXxcQr0KtVOaxq170LHv6Eqt84c2pW8if3/1GJusc1ZWhbdNz0gnd9+eSoxGUrgFAhXvVJ2dnV2u43V11XtvxY7HwSC1Yv+laFe/ScWfutuzZ0+tOA7sz6nY+FAFBQW1Yv8lSdEtvm7DCm+blZXlubAWiG+5vcLbbtu2zfeApIjYvLkcEyf+QK1MkK1fH+rX3alTpxLX5+fn8/HHHwPFE2TJyclF2+fn5xMXd+DLs3r16mJlAaZNm8bIkSOLkmMARx55JF27duXNN9+scIKsdevW5SofW6fuwQtVM23btK02PchiCyqW4Mrdt4sWTRsCFb+QlFQ97NuVQd1G5Tv2AsTk76Zdu3ZVEFF4BfJ2Vmi7fbs31Yr9l6JdTGw8BXk5xNZJLPe2cYXZteI4UJhTsZtCuVlbasX+S5KUl7ObOonlv78RW0u+E0W7urGhh4WCwSCBQKBM23xbtl7cft8DksLm+z3IWrVqVeF6amWCLDs7NNTdD+cJ+9aUKVPIzMwkKSmJLl26FC0fNGgQ8fHx7N+/n/nz5zN8+PADtp0zZw4Aw4YNK1q2bNkyzj33wKEI+/Tpw7Jlyyq8H/Pnzy9X+f35cMuUCjcXEakrV5JQTd6FWTlw1+uQX1i+7UYPbMQTabVk4g0pyk1fBO8uLd82MQF47ZnbaVzv9iqJKZy27oZ73iz/dj87oQfP/cbjoFQb/OPT8s89khAHs157lIQ6j1ZNUGG0ZgtMfrf821134VH84/ceByVJNd/U+TD76/JtExcLb/3jfuon3F81QSlsgkF48C3YtKNsyTGAQCBAh6aw7IuZVRiZJBWXnZ1dNL3Wtzmbiqj4eFLV2Lc9rxYsWHDAuvT0dG666SYA+vfvX+xpiKSkJMaMCc2t9cwzzxyw7UcffURqairx8fGMGzeuaPmOHTto3LjxAeWbNm3K9u0V75qs8GqQCINK7nT4o0b0qPxYJEXGkd2hjA/JFenXHhpX7gi3EdOiIfQsZwe62BgY3q1q4pEUfiOTD17mh47oCgl1Kj+WSOjSAto0Kt829eJhYMeDl5MkqSaoyD2OwztB/YTKj0XhFwjAyAq8B0ZU4BpSkqqDWpkgGz06NG/WxIkTSU1NLVo+b948UlJSyMzMBEKTt/3QHXfcQSAQ4Pnnn+fFF7+blHL16tWMHz8egKuuuoqWLVtW4R4oUk4eAA3LMVLlcYdBq3LeRJFUfTVtACf2K3v5+glw6qCqiycSzhgMieW40X3awNADBpJqh47N4Khy3BRpWh9O6Ft18YRbIADnDA0l/8vq7CMgvpqMiCBJ0qFq3QhSDit7+UZ14aT+VRePwm9oV+jaouzlu7eCIZ2rLBxJqlK1MkF2880306xZMzZs2ECfPn3o168fPXr0YOjQoXTt2pXjjjsOKD7/2LeGDx/O/fffTzAY5JJLLqFz584MGjSIXr16sWrVKoYNG8b99xfvMt6kSRN27tx5QF3bt2+nadOmVbKPqhpN6sMvjytbb5Cje9a+G+OS4MS+MLrPwcs1TAwdL1okVX1M4dSmMVyVUrYnQE8eAMf0qvKQJIXZ2UPK1jO0eQP45fHle7ioJujWEsaPgjqxP14uJgDnDYPBncMSliRJYXPaIDi6DD2CmtQLXQs0qV/1MSl84mLh8mNC10QH070VXDYqtI0k1USBYDAYjHQQVWH58uXcdNNNfPjhhwD07t2b8ePHc8UVV9CtWzfWrl3LZ599xtChQ0vc/p133uGhhx5i3rx55OTk0LVrVy644AJuuOEGEhKK3zU89thjiYmJYebM4mPtdu/enVGjRvHcc89VzU7+QE2cg2zieVSbOci+LysH5qyET1fCrh9MZde7bWj4od7OOyrVal+nw+xUWLoxNA77t5ISQ0MxjkyufTeFv29HNsxJhbmrIXt/8XUDOsKoZOhW8TlQJVVzwSAsSQsdB1Iziq9rUj80/NKR3Wv3cEpbd8NHqTBvDeTkFV93RBcY1RM6NItMbJIkVbVgEJZvCn0nWrEJvn/zsFHdUI/zET0cTaI2yy+AeWtD74FNO4qva98k9J14SBeTY5Ii4/tzkGVlZVG/fsWe1qi1CbLSZGVl0bBhQwKBAHv27KFevUOfOGbSpEncdtttrFmzhvbt2wPw2WefMXz4cF577TXOPPPMQ26jLEyQVb6CQlifCf/3IezNhaQEuPucSEclKZx2ZMOD/w0dA+rHwx/Oiq4vAHkFoePgcx/97ziYCHefHemoJIVT5h54+O3vjoN3nw0xtXIcipLtz4P12+CF2R4HJUnRaVsWPPTWd9cC/+/s8g1HrJotGIRNO+HP74XeAw0SQtdC5Z2/W5IqU2UlyKLudLZ06VKCwSA9evSolOQYwJVXXkmbNm0YN24c06ZN49VXX+X8889n6NChjBs3rlLaUGTExkDXlt8NsRNNN4MkhTSp/90xIC42upJjENr37q2+dxz0S5AUdZonFT8ORtv1UEIdSG7tcVCSFL2aNSh+LWByLLoEAtCuyXfvgdgYk2OSao+oO6UtWbIEKHn+sYpq2LAhM2fOpE2bNvz0pz/l8ssv56ijjmLatGnERNsdBEmSJEmSJEmSpGquGg9uVzWqIkEG0K1bN6ZNm1apdUqSJEmSJEmSJKnyRV33pqpKkEmSJEmSJEmSJKlmiLoeZDNnzox0CJIkSZIkSZIkSYqgqOtBJkmSJEmSJEmSpOhmgkySJEmSJEmSJElRxQSZJEmSJEmSJEmSoooJMkmSJEmSJEmSJEUVE2SSJEmSJEmSJEmKKibIJEmSJEmSJEmSFFVMkEmSJEmSJEmSJCmqmCCTJEmSJEmSJElSVDFBJkmSJEmSJEmSpKgSF+kAVHniY2HieZGOonziYyMdgSRJkiRJkiRJijYmyGqRQAAS/B+VJEmSJEmSJEn6UQ6xKEmSJEmSJEmSpKhigkySJEmSJEmSJElRxQSZJEmSJEmSJEmSoooJMkmSJEmSJEmSJEUVE2SSJEmSJEmSJEmKKibIJEmSJEmSJEmSFFVMkEmSJEmSJEmSJCmqmCCTJEmSJEmSJElSVDFBJkmSJEmSJEmSpKhigkySJEmSJEmSJElRxQSZJEmSJEmSJEmSoooJMkmSJEmSJEmSJEUVE2SSJEmSJEmSJEmKKibIJEmSJEmSJEmSFFVMkEmSJEmSJEmSJCmqmCCTJEmSJEmSJElSVDFBJkmSJEmSJEmSpKgSF+kAVHmCQcgtiHQU5RMfC4FApKPQDwWDUJgX6ShU3cXU8fMrSZIkSZIkqWYyQVaL5BbALVMiHUX5TDwPEnwXVjuFeTBrcqSjUHWXcg3Exkc6CkmSJEmSJEkqP4dYlCRJkiRJkiRJUlQxQSZJkiRJkiRJkqSoYoJMkiRJkiRJkiRJUcUEmSRJkiRJkiRJkqKKCTJJkiRJkiRJkiRFlbhIByBVR9n7IW07bNgOmXtgb25o+b5c+Gw1dGgKrRpBrClmqVYqLIQte2DDNkjb8d0xYG8uvPsVtG8aOg40SIxsnJIkSZIkSZIqxgSZ9D8FhbAkDT5OhZWbSy6TWwAvzw39u148DOsGI3pA86TwxSmp6mzLgk9WhhLhWfsPXJ9XANMXf/d31xYwIhkGdIC42PDFKUmSJEmSJOnQmCCTgMXfwGvzYde+sm+zNxdmLQ/9DOwIZx8BSfYmkWqk7P3w+hfwxVoIlmO7NVtDP/9OhHGHw+DOEAhUVZSSJEmSJEmSKosJMkW1rByYOh8Wrj+0ehZ9E+p1dvYQOLxzpYSmMFq8+gNu/EtKsWWJ8fVp3yKZ0YdfxBkjfk1srIfL2mrJBvjX57Anp+J17MmBlz4JHQt+MhQa1q28+CRJkiRJkiRVPu/4Kmpl7oEnZ4aGVKsM2fvhrx9D+k44eYC9SGqilIHnM7TXyQQJsmNPBu9+8Vf+8ub1fLNlOb855+lIh6dKFgzCe0uLD5l4qL5KC81f+MvjQvMUSpIkSZIkSaqeYiIdgBQJO7Lh8fcqLzn2fe9W8g13hU+PdoczevCFjBl8ET859iYm/3ouLRq1563P/4+dWVsjHZ4qWWUnx761c2/o+LJ1d+XXLUmSJEmSJKlymCArxYwZMxg7dizNmjWjXr169OvXj/vuu4/c3NxIh6ZDlFcAT80K3cSuKu8thc9WV139Co+68fXp1Wk4wWCQTdv8D61NFq6v2kT2npzQcWZ/XtW1IUmSJEmSJKniTJCV4KGHHuLEE0/knXfeISkpiZ49e7JixQpuu+02UlJS2LdvX6RD1CF4+0vI2FW+ba4fC3edGfpdVq9/Eeqpppot/X+JsYb1mkY4ElWWPfvg1Xnl26Yix4DMLJi2qHztSJIkSZIkSQoPE2Q/8Pnnn3PTTTcRCAR44YUXWLduHQsXLmTFihV0796dTz75hFtvvTXSYaqCvtkGM5eXf7uGdaFxvdDvssrJgymfheY5Us2Qk7eXXdmZ7Mzaytr0JUx+7Ves2riQXh2G0r5FcqTDUyV5dX5ozsDyqMgxAGB2KqzaXL5tJEmSJEmSJFW9uEgHUN3cfffdBINBLrvsMi6++OKi5d26dePZZ5/lmGOO4cknn+S2226jZcuWEYy06qQt+4Cp96Yw8vwHGXzKjSWWefTCAJ0HnsK4G6eFObpDM+Or8CasVqTD+m3QuXn42lTF/XXGnfx1xp3Flo3sexa/PvPPEYpIlS19Jyz+JrxtzvgKurcKb5uSJOnQFQbh63T4eCWkbQ8N1V4vHvq0gxE9oEXDSEcoSapqGbvg41RYvgn25UF8LHRsDiN7hL7nBQKRjlCqWjuy4ZOVsHgD7N0PcbHQuhEc1SN0TRRr9xvVcLU+QZaZmckDDzzAa6+9RlpaGi1atOCss87i3nvv5ZprruG5557jscceY8KECezZs4cZM2YAcMUVVxxQ16hRo0hOTiY1NZU33niDyy+/PNy7o0OwPQuWbgx/ux+nmiCrKU4ZdiWj+p9LfmEea9OXMOWDiWTuSiO+TmJRmSVrZnPbsycdsG1+QS6FhQW880BBOENWOc1JDX+bqRmweRe0ahT+tiVJUsVk7ILnPoItu4svz94PH6wI/QzpDOcNhzqxEQlRklSF9ufB3z+FLzcUX54N7Pgm9OBl2yZw2dHQPCkiIUpVqqAwNH3MxysP7Gywc2+oU0CTenDJ0dDJ+56qwWp1gmzRokWcdNJJZGRkUL9+fXr37s2mTZuYPHkyq1evZvv27QAMHDgQgIULF5Kbm0tCQgJDhgwpsc6RI0eSmprK3LlzTZDVMJ+uisxwhwvXwxmDoX5C+NtW+bRr3oPDk0cDMLTXSfTtMpLfPDGSR6f+gtsv/CcA/boezZv3ZBXbLnPXJn41eQjjjpoQ9phVdvvzYf7ayLT9ySo4c3Bk2pYkSeWTvhMmvwv7cn+83Px1sDsHrjw29DS1JKl2yM2HJ2bC+swfL7dpBzw6A649wSSZapfCIPztY1h0kBF4duyFx9+Dq4+HLi3CE5tU2WptJ8jMzExOO+00MjIyuOGGG0hPT2fBggVkZGQwceJEpk+fzrx58wgEAvTv3x+A1NRQ14JOnToRF1dy7rBbt27FyqrmiNQ8QPmFB7+oUvXUp/NRjD78Ij5YPIWl6z4psUxu/n7+8Nez6Nt5JD87/rYwR6jy2LAtlCSLhJXOQyZJUo1QUAjPfnjw5Ni3UjPgrS+rNiZJUnj9e0HZ7+PsyYHnZjv/vGqXD1ccPDn2rbyC0LVTpO63SIeq1ibIrrnmGtLS0pgwYQKTJk0iKem7RzluvvlmBgwYQH5+Pp07d6Zhw9Dg8Tt27ACgSZMmpdb77bpvy9Zm+bl72bcns8SfmqawEDZG8L9sw/bIta1Dc8Ho3xETE8uL7/y+xPWPTv0FuXk53HTeC+ENTOUWyc9hxs7QU4iSJKl6W7oRMrMOXu77PlnleV6Saou9++HzNeXbZtMOWLWlauKRwq2wED5aUb5tsvbDgnVVEo5U5WrlEIvLly9nypQpNG/enPvuu6/EMoMHD2bx4sUMGDCgaFlOTg4A8fHxpdadkBAaJ2/fvn1Fy9LS0rj//vv5/PPPWbx4Mbm5uQRrwaMjc6feydypd0Y6jEqxZQ/kRnBqKBNkNVe75t1JGfBT3l/4d5asmU2/rkcXrXt9zmQ+Wz6Nx6+ZR2J8vQhGqbJIi+DnsDAYGq7JcbklSarePq7AQCH7cmHBehjerfLjkSSF1+drIL8C94/mpEKPVpUfjxRuyzaFhk4srzmpcGT3yo9Hqmq1MkH28ssvU1hYyAUXXECDBg1KLFO3bl2AYgmyxMREAHJzSx9PY//+/cW2B1i1ahVTp07liCOOID4+no8//viQ9wFgyJAhZGRklLl8bJ26nPnHlZXSNkDflCvpMezcEte9fv+YSmkjuUcPCvL2HbzgIWreZTjH/uLVEtddPxYa1i1xVZGGid/9vuvM0svt3gcPv33g8g/mzOOuC35kw2omPq4uT0+ovPdSTXf+8bcza9HLvDjj90z6xSwAFq2axf9Nv4V7L3+L1k07RzbACOmR3IPc/Kr//FaWkeNfonXysSWuO9hxoKzHACj9OHD2eT8n4+uZZQu2Gjr5tnnUa9SG9Ix02rc/ItLhSAozjwG+BtHi9LuWEl+3Ubm3u+eRv7Lw3w63Lan2ipbz4NDzH6fjwDPKvd0nizbwu/OPrPyAqpFoeQ9Euz4n3Mhhx19X7u027oAOHTsTLLRbvcKjsLCw6N8jR45k4cKFFaqnVibIZs4M3YBMSUkptUxaWhpQPEFWluETSxqGcdSoUaSnpwNw1113VVqCLCMjg40bN5a5fFxC5fZgady6Bx37jq7UOn9oU/om8vdX4LGEcoppvLPUdQ3rQuMyvnQxMWUv+30FhZTr/zLSEutEV2+oAd2O5d0HS+/12anVYbzzwHePkGVsX8cfX/oJV5z6IAO6HRuGCKun9E2byMmr+s9vZcnLL/3/uKzHgYoeAwB27Npdo44DP1RQUFD0uybvh6SK8RjgaxAtYusc5Mm5UuQWBHxfSKrVouU8mFcQqNB2gbjEWv26QPS8B6Jd1/0VH4JrS+YOcvftrsRopLLZvHlzhbetlQmy9evXA9CpU6cS1+fn5xclsb6fIEtOTi7aPj8/n7i4A1+e1atXFysLEBNTNVO5tW7dulzlK/plLpLatmkblh5kTRs3LHXd7jI03zAxdGO8sBB255RerrS6YgOFtGvX7uANVRPxcTXvvRQuObl7ufOFMziy9+mcMWJCpMOJqDZt29aoHmR1Ykv/onOw40BZjwE/VleTRkk16jjwQ7GxsUW/a/J+SKoYjwG+BtEiP2cPsQ2alXu7OoF83xeSarVoOQ/GkVeh7Qpzs2v16wLR8x6IdglxFZs2KFhYSItmDSGYVMkRSSUrLCws6rTUqlXFx7itlQmy7OxsoPg8Yd83ZcoUMjMzSUpKokuXLkXLBw0aRHx8PPv372f+/PkMHz78gG3nzJkDwLBhw6og8uLmz59frvL78+GWKVUUTBVJXbmShDC8C7dnwf/7T8nrShoK7YfuOjPUa2R3Dtz1evnbPzFlGC/dkVb+DSOkIBdmTY50FNXT7CVTWZO+mI2ZqXyw+MAP3LM3LqNlk44RiCz8VqauJLb0KRurnSmfwaerSl53sOPAoR4DAN6c+jfaNK7YttXBna/Brn3QpnWbol7YkqKHxwBfg2jx0icwf235t3vg9kvp/cSllR+QJFUT0XIe/GId/K0CA0OdNKIz/3dt7X1dIHreA9Hum21lu1f6Q4e1iyFtw4bKD0gqRXZ2dtH0Wt/mbCqiVibIWrduzY4dO1iwYAFHHll8/N/09HRuuukmAPr3708g8F2PgqSkJMaMGcP06dN55plnDkiQffTRR6SmphIfH8+4ceOqfkdUaZrUh3rxsLf06eWqVPumkWlXlW/M4IsYM/iiSIehCojk5zA+FlqV3pFVkiRVEyOTy58ga9YAerWpmngkSeE1oAO8nghZBxk55IdG9KiaeKRw69gMOjSFDdvLt93I5IOXkaqjqhkbMMJGjw7NmzVx4kRSU1OLls+bN4+UlBQyMzMBGDhw4AHb3nHHHQQCAZ5//nlefPHFouWrV69m/PjxAFx11VW0bNmyCvdAlS0QCB3cIyWSbUsKieTnsF2T0BCNkiSpeuvUDJLLN9I9o/t4npek2iIuFo7vXb5t+neA1o2qJh4pEsb0LV/5dk2gd9uqiUWqarXyMv7mm2+mWbNmbNiwgT59+tCvXz969OjB0KFD6dq1K8cddxxQfP6xbw0fPpz777+fYDDIJZdcQufOnRk0aBC9evVi1apVDBs2jPvvvz/cu6RK0DtCwyPXT4BOzSPTtqTvtGsCjSI0vV6kjj+SJKl8AgG4eCS0bVy28imHwZHdqzQkSVKYHdur7Mf2Ts3hgiMPXk6qSfp3gNMGlq1s8wZwxbE+LKSaq1a+ddu3b8/s2bM55ZRTSExMZN26dTRt2pSnnnqK6dOnF/UqKylBBqEE29tvv82YMWPYtWsXK1asIDk5mXvuuYcPP/yQevXqhXN3wq5972O59qUgg0+5sdQy174UZNyN08IY1aE7omtomLNwG9YN6kSgXUnFxcbAkREY9iI2BoZ740ySpBqjfgL8ekzo+0NsKd+YG9WFc46A0weFNzZJUtULBOAnQ0PH+AYJJZeJi4WjesCvjoeEOuGNTwqH4/vAhUdB0/olr48JwICOcO2JoTnbpZqqVs5BBnDYYYcxbdqBCZysrCzWrVtHTEwMffuW3l/0xBNP5MQTT6zKEBVm9eJhcBf4dFX42gwAR3ljXKo2juwOM5ZAYTB8bQ7sCEmJ4WtPkiQdurrxoR4B4wbB3NXwzhLIKwg9+HbhUdC3fenJM0lSzRcIwHG9YVRPWLwBlm+CReshvxAS68Dvx0G9UpJnUm0xpAsc3glWpIc+B1+sDX0GEuLg1tNMjKl2qLUJstIsXbqUYDBIcnJypfYEe/XVVwFYtmxZsb87d+7MkCFDKq0dHZoT+8HC9ZCTF572RvaE5knhaUvSwTWqGxoK6f1l4WkvPhZO6h+etiRJUuVrkBiaY2z217BrX+ihuwEdIx2VJClc4mJhcOfQz8qM0LkgIc7kmKJHTExo2oje7WDFptBnILGOyTHVHlGXIFuyZAlQ+vCKFXXuueeW+PfFF1/MCy+8UKltqeIa14MzBsM/51Z9W80awKkDq76dSMjNy+Gev/+U9ZuXkVCnLo0btOSas56kXfPuBINB/vXBg7wz7zkIBCgsLGDsEZfxk2NvJuYgAxKnpn3B82/dTlpmKkn1mlInNoGfHHsTI/qeAcA7817g1Y8eoqAwn4KCPEb1P5efn/AH6sTFAzB7yWu8/P49FBQWkJefQ7OGbZl45Xvc8fypbNu1CYA16Yvp3LovMYFY6iUm8cjVs6v0tfpWTu5eHnplPKkb5hEIxHDZSfcyqv85pZbP2L6OXzwykH/fvTMs8QGkbV3Jg1MuZld2JvUTG3HTeS/QuXWfsLUfLif1h6UbIWNX1bd16iCT5JIkSZIkSVJ1ZIKskgSDYRyvS4dkWFf4Ki30U1a79xX/fTCxMfCzI0NPFdVWJw+7kqG9TiIQCPDvjx/n4Vcu56FffsBzb9/OkjUf8civ5tCofnN2ZWdy5wtnsGffDq44ZWKp9a3LWMqtz5zIjec9z5G9TwMgc9cmFqx8F4Dpc59m6uxHuGf8f2nTtAs5uXuZ+PJFPPTKeH57/t/YtjudP716JU9c9wWtmnQCYGXaAgKBAPeO/29RO2NuCvDI1bNpULdx1b04JXjlw0nUiU3gxd+uIn37Wq6ZPIyB3VJoWL9ZWOMoSUFBPrGxcTw69SpOHnYlJx5xCR99+SoPTrmEP187L9LhVbq42NDn87F3Q0MllUV5jwEAPVvDyOTyxydJkiRJkiSp6tXi2/clq6oEmWqOQAB+PgKemgWrt5Rtm4ffLnv9MQG4aAR0a1mx+GqC+DqJDDvs5KK/D+s4nFc/nMS+/VlM/ehhnrxuAY3qNwegUf3m/Oacp/nlI4O44Pg7qJdYcneaf866n7FHXFaUHANo3qgtJwy5GICX3vt/XHf207Rp2gWAxPh6/Oacp/nZPR3YNOYu9u7fQ0xMLEl1mxZt36P94RXex0+Xvcnzb91OIBBDYWE+l469h6P6jmP77gz+/J9r2LxjHfvz9nFUn3FcOvaPACxd9wmTX7uawsJ8kjscwaqNC7l63J8Y0O1YPlw8hevPfRaANk270L/bscz56nVOHnZ5meK57x8XsGHr1+Tn59KicQduOPdZmjZszWOvT6BZw7b87PjbANiw5WtueXo0f7t1LUGCvPDO71i0aiZ5+bm0b5HMdWc/RVK9Jjzwz0uIiYlhU+YqdmZt4aGrPyI1bT73XzEDgKP7nc3jr09gY+Yq2jWvfRPpdWwGlxwNz30EBYUHL1+eY8C39V86KnQ8kCRJkiRJklT9RN20wjNnziQYDHLKKadEOhRFUHwcXJUCvdtWbr11YuHSo2FglM1L8PqcRzmyzzjWb15GnbgEOrXqXWx9p1a9qVMnkfVbSp/4aWXaFxzW6cgS1+3I2kLmro30/sH6hvWb0a55D1ZuXEDXNv3p23kkF97bibteOJN/ffAgmbs2VnifXnj7Dq47+ymeun4RT13/Jf27HQPAA1Mu5vSjfsXj13zOX65bSOqG+Xy4+BXy8nO556XzuOrUSTxz41ekDDyfNemLi+rbsvObop5tAK2bdGbLzm/KHM8vT/8TT1w7n6dv+JJ+XY7mr+/eBcAZI37Nfz97moLCUFeoNz59gpOHXUlsbBz/+uBBEuvU5/FrPuep6xfRpXU/nn/7jqI6V6Z9wR8vm85zN69g684NNG3YhtjY0HMTgUCAlk06livGmqZPO7ji2NDxoDL1aAVXHx8ak1uSJEmSJElS9RR1Pcikb8XHweXHhibcnrao7EOtlaZLc/jpkdCqYWVEV3P84/172ZS5igeuep91GV8RoPQuMwlxdassjpiYGO68eCrfbFnBl6s/ZN7Xb/GP9+/hz9fOr1APqEHdj+eJN67l6H7nMDj5BLq3G8i+3GwWrnqfHXs2F5XLyc0ibevXbNiygtiYOA5PHg3AkJ4n0KZp10rbv5kL/8F7C/5GXl4Oufk5NPxfD70OLXvSsVVvPln6H4b0PJEPFr7M0zeEesp+svTfZOfsYvaSqQDkF+TSqmnnojpH9T+31B590aJXG7jlFHh5LqzafPDyPyYuJjS/WcphoUlsJUmSJEmSJFVfJsgU1WICcEwv6N0O3lgAX22E8k4n16guHNcbjk6Ovpvir3wwiTlfvcYDV75HYnw9OrXqTW5+Dus3LyvWi2z95mXExdShfcuepdbVo/1glq//lJH9zjxgXZMGLWneqB3L1n9abGjH3dnb2Ji5kh7tvhtKsWPLXnRs2YtTj7yKW58Zy6dL3+CcY64v97794vSHWZexlEWrZ/HglIs5btAFnH7U1QA89uu5xNdJLFZ+zaYvD6gjEPguWdiycUc271hPs4ZtAMjYsY7BySeUKZav1s7h33Mm8+ivP6VJg5Z8svQNXnzn90Xrzxx5Lf+aNZFdWVs5PHkMTZJaAaG5EX817jGG9Cy5nboJDYr+3aJxB7bvTi+ajywYDLJlxze0bFz7u0M2axDq8fXpSnhvGezILt/2AeCwtnD64dC6UZWEKEmSJEmSJKmSRdntfKlkLZJg/DHw+3FwQl9o2ZAf6QcVGjrtsLZw2Sj4/RmhJFu0Jcde/fBhZi16mYlXvEuDuo2BUMLlzJHX8qepV7ErOxMIJbH+NPUqxp98P/FxCaXWd96xN/P2vOf4bPn0omXbd2cwY/6LAPzsuNt5atoNpG9fC0BO7l4eefVKRvQ9k7bNu5G5ayNfrf24aNs9e3eQsWMtbZt1q9D+fbNlBZ1b9+GMERM49chfsvybudRNaMDAbin8c9b9ReUyd21i6840OrTsRUFhPotWzQJgQep7bNq2uqjcqP7nMu3TvwCQvn0tX67+gBF9zyhTLHv27aBuQhIN6zUjLz+X6XOfKrZ+SPIJbN+TwT/e/yPjjppQtPyovmfw2uxHyMndC4Res3UZS0tso0mDlnRvdzjvLXgJgNlLptK8cftaOf9YSWICMCIZfnc6XHFMaPjFuvE/vk2LJDi+N9wxDq5MMTkmSZIkSZIk1ST2IJO+p0l9OHlA6CcnDzZuh61ZkF8QuoFeNx7aN4FmSaG/o9XWnWk8Ne0G2jTtyo1/SQEgPi6Bx675jPEn3ce/PniA6/48AoCM7Wv51bjHOHnY5T9aZ5c2/bj38rd47q3befzfvyYxvj71EpI4L+W3AJx21C+Jja3D7587jYJgAfn5uRzd72wuHns3AAWF+bz03v8jY/taEurUo7AwnzGDL+aovuMqtI/PvXUbaVu/Ji42noQ69bj2rCcB+O3P/s5Tb1zPFZP6QiBAYnx9rjv7KVo0bs/tF05h8mtXUxgsoGeHI+jaZkBRfeceexMP/esyfn5fN2JiYplw5uM0+t8wiQdzRM+xvL/gJS57oCcN6zVjUI/RxeZXCwQCjB06nlkL/0Hvzt/N0/bTY2/hb/n7+fVjw4qGvjwv5RY6t+5TYjvXnf0UD065hJdn3ku9xIbc9JPny/261XQxMdCnfegnGIRtWZC2A/buh4JCqBMX6nHWvsnBE2iSJEmSJEmSqq9AMFjeAeVUXe3Ph1umRDqK8pl4HiSYpq12CnJh1uTKqeu12X/i9TmTefCqmbT+3vxX0eDqR4dw1amTGNDt2Cpv647nTuWYAecxZvBFVd7Wt1KugViTRFHjztdg177QsLJ/OCvS0UgKN48BvgbRzv9/SdHO46CvQbTvv3wPqHrJzs6mQYPQ9DFZWVnUr1+/QvVE2aBwksLtrKOv42+3rom65Fi4fL1hPhff351AIIbjBv0s0uFIkiRJkiRJUo1g3x1JYbNq4yIenHLJActPGHIxZ4/6Ta2L54lr5x+0zO+eP50tO74ptiypXhMm/WJWmdro2WEIL/52VYXikyRJkiRJkqRoZYJMUth0bzeQp65fFOkwilSHeO6+9I2Iti9JkiRJkiRJ0cghFiVJkiRJkiRJkhRV7EFWi8THwsTzIh1F+cTHRjoClSSmDqRcE+koVN3F1Il0BJIkSZIkSZJUMSbIapFAABL8H1UlCAQgNj7SUUiSJEmSJEmSVDUcYlGSJEmSJEmSJElRxQSZJEmSJEmSJEmSoooJMkmSJEmSJEmSJEUVE2SSJEmSJEmSJEmKKibIJEmSJEmSJEmSFFVMkEmSJEmSJEmSJCmqmCCTJEmSJEmSJElSVDFBJkmSJEmSJEmSpKhigkySJEmSJEmSJElRxQSZJEmSJEmSJEmSoooJMkmSJEmSJEmSJEUVE2SSJEmSJEmSJEmKKibIJEmSJEmSJEmSFFVMkEmSJEmSJEmSJCmqmCCTJEmSJEmSJElSVDFBJkmSJEmSJEmSpKhigkySJEmSJEmSJElRxQSZJEmSJEmSJEmSokpcpANQ5QkGIbcg0lGUT3wsBAKRjkKSpOKCQSjMi3QUqu5i6ngdI0m1ldcCKguvBSRJqtlMkNUiuQVwy5RIR1E+E8+DBN+FkqRqpjAPZk2OdBSq7lKugdj4SEchSaoKXguoLLwWkCSpZnOIRUmSJEmSJEmSJEUVE2SSJEmSJEmSJEmKKibIJEmSJEmSJEmSFFVMkEmSJEmSJEmSJCmqxEU6AEmSVD0Fg7BrH2zPgvyC0LKCwtBPrI/YSFEhvwAydn13DMgvgKwcaJAY2bikcCkohC27i38Gdu6FRnUhEIhsbJKkqhcMho77O7KLfycqLIQYvxNJUo1ngkySJBXZnwdfrIOv0mDDdtiTU3x91n747b+gXRPo3gqGd4PmSREJVVIV2bgD5q6CtZmQvjN0E+hb2blwx1RoUg86NIOBHaF/B4iLjVi4UqXL3AOfroLVW0Kfh7yC79Zl58Jdr0NSInRoCn3bw+DOkFAnYuFKkirZvlyYvxaWbgx9J8reX3x91n747SvQ/n/fiY7sDk3qRyZWSdKhMUEmSZLYkwMzvoJ5ayAn78fL5hXAuszQz/tL4bC2MKYvdGkRnlglVY2v0kKf6bWZBy+7Y2/o58sN0DARjuwBx/WGBL9dqAZbswXeXQorNkHwIGX35MCyTaGfNxbC0K6hc2GSvSslqcbauRdmLIH56yA3/8fL5ubDmq2hn3eXQp92cEJf6NgsLKFKkiqJX2ElSYpiwSAsXA9T5x/4ZGSZtid0c3D5JhjVC04ZAPFeXdQ4i1d/wI1/SSm2LDG+Pu1bJDP68Is4Y8SviY31P7a2ysoJHQMWrq/Y9rtz4J0loSetzx8eepJaqkly82HaIpj99cETYyXJyYOPvg71wD73CBjYqZIDlMLAawFFs2AQPl8Dr39x8IcFS9v+qzRYtjH0wNDYfvaul6SawqsbSZKiVH4B/HNu6AnJQxUEPlwR+lJ4ZQq0cNjFGill4PkM7XUyQYLs2JPBu1/8lb+8eT3fbFnOb855OtLhqQqs3QrPfhRKkh2qbVnw+Hswpg+cPMD5mVQzbN0NT38AW/ccel3Z++GFOTBkI/x0mDdHVTN5LaBok5sPL30S6hV/qAqD8N5SWJoW+k7ksIuSVP05naQkSVEovwCe+6hykmPft3UPTJ4Bm3dVbr0Kjx7tDmf04AsZM/gifnLsTUz+9VxaNGrPW5//HzuztkY6PFWylRnw5PuVkxz7vneXwtR5oaeppeosYxdMfrdykmPfN39t6BybX3DwslJ147WAoklufughicpIjn1f+i54dEbo4SFJUvVmgqwUM2bMYOzYsTRr1ox69erRr18/7rvvPnJzcyMdmiRJhyQYhL9/GhoasSrsyYEnZ8KuvVVTv8Knbnx9enUaTjAYZNO21ZEOR5UobTv834eQW0U38OeshLe+rJq6pcqwc28oQbynkhPE31q2Cf7xqYli1XxeC6i2KgzCC7Nh1eaqqf/b80xlP4gkSapcDrFYgoceeogbb7wRgE6dOtGxY0e++uorbrvtNqZNm8Z7771H3bp1IxylJEkV8/ma8s81dP1YaFgXdu+Dh98+ePmde2HKZ3DFsQ6zVtOl/+9mWMN6TSMciSpLfkFoKKH9B5l8/vvKewwAePcr6NUGurasWJxSVQkGQ+eoXfvKvk1FPgML1kOvtjC0a8XilKoLrwVUG81JLf8Dg+U9F2RmwWvz4ecjKxajJKnq2YPsBz7//HNuuukmAoEAL7zwAuvWrWPhwoWsWLGC7t2788knn3DrrbdGOkxJkipk597Q5NPl1bAuNK4X+l1WyzbBvLXlb0uRk5O3l13ZmezM2sra9CVMfu1XrNq4kF4dhtK+RXKkw1MleWdJaGi58qjIMSAI/GNuaPgiqTr5fA0sL+dN0Yp8BiB0zrVHtWoSrwUUDTL3wLSF5d+uIueCBesrfwhHSVLlMUH2A3fffTfBYJBLL72Uiy++uGh5t27dePbZZwF48skn2bJlS6RCrHJpyz7g0QsDfDF9UqllHr0wwH8mnRrGqCRJlWH6IsjJC197//7Cm+M1yV9n3Mk5d7Xg3D+05MqH+/Pmp08wsu9Z/OGS/0Q6NFWS7Vnw/rLwtZe5Bz5cEb72pIPJzYf/LAhfe/tyYfri8LUnHSqvBRQN3lhYdcNMl+S1+VBQGL72JEllV+uHWMzMzOSBBx7gtddeIy0tjRYtWnDWWWdx7733cs011/Dcc8/x2GOPMWHCBPbs2cOMGTMAuOKKKw6oa9SoUSQnJ5Oamsobb7zB5ZdfHu7dkSSpwrJyQk8whtPe3NBwjsO6hbddVcwpw65kVP9zyS/MY236EqZ8MJHMXWnE10ksKrNkzWxue/akA7bNL8ilsLCAdx4I490Gldsnq0JzboTTxyvhuN4Q66N5qgYWrA+dm8La5joYdzjUTwhvu1JFeC2g2m5HNixJC2+bO/fCV2kwoGN425UkHVytTpAtWrSIk046iYyMDOrXr0/v3r3ZtGkTkydPZvXq1Wzfvh2AgQMHArBw4UJyc3NJSEhgyJAhJdY5cuRIUlNTmTt3rgkySVKN8vmayDy5+PFKE2Q1RbvmPTg8eTQAQ3udRN8uI/nNEyN5dOovuP3CfwLQr+vRvHlPVrHtMndt4leThzDuqAlhj1lll18Ac1eFv92de2HZRujXIfxtS98XDIbmnAm3/MLQOTjlsPC3LZWX1wKq7T5dFTofhNvHK02QSVJ1VGuf48zMzOS0004jIyODG264gfT0dBYsWEBGRgYTJ05k+vTpzJs3j0AgQP/+/QFITQ19W+rUqRNxcSXnDrt161asrCRJNcWibyLT7jfbQk9qqubp0/koRh9+ER8snsLSdZ+UWCY3fz9/+OtZ9O08kp8df1uYI1R5rN4CWfsj03akjj/S923PhrTtkWl7UZh7cEuVxWsB1TaRuiZJzYDsCF2HSZJKV2sTZNdccw1paWlMmDCBSZMmkZSUVLTu5ptvZsCAAeTn59O5c2caNmwIwI4dOwBo0qRJqfV+u+7bsrVZfu5e9u3JLPFHklSzFBTCpgieujZE6IakDt0Fo39HTEwsL77z+xLXPzr1F+Tm5XDTeS+ENzCVWyQ/hx4DVB1E8n24aafzz6jm8lpAtUVOHmzdHbn2I/WQhiSpdLVyiMXly5czZcoUmjdvzn333VdimcGDB7N48WIGDBhQtCwnJweA+Pj4UutOSAgNHL9v376iZa+++iovv/wy8+fPZ+vWrXTs2JGzzz6bW2+9lQYNGlTGLkXE3Kl3MnfqnZEOQ5JUCdJ3hoZ4ipQN26C/w6vVSO2adydlwE95f+HfWbJmNv26Hl207vU5k/ls+TQev2YeifH1IhilyiKSyYGtu0M3pRLrRC4GacO2yLWdVwCbd0Hb0p/FlKotrwVUW2zcDhEYXbHIhu3Qs00EA5AkHaBWJshefvllCgsLueCCC0pNUNWtWxegWIIsMTE06WxubumzNu/fv7/Y9gCTJk2iY8eO3HvvvbRv355Fixbxhz/8gQ8//JCPPvqImJia2VGvb8qV9Bh2bonrXr9/TJijkSQdisysg5epSlv3RLZ9HZrzj7+dWYte5sUZv2fSL2YBsGjVLP5v+i3ce/lbtG7aObIBqky2RfBzGAS2Z5kcUGRtqwbnQj8Dqqm8FlBtsDXC54FMvxNJUrVTKxNkM2fOBCAlJaXUMmlpaUDxBFlZhk8saRjGN998kxYtWhT9fcwxx9CiRQsuuOAC5syZw6hRoyqwFzBkyBAyMjLKXD62Tl3O/OPKCrVVksate9Cx7+hKq68kyT16UJC37+AFJUmHpOOgsxn600dLXHf9WGhYt8RVRRomfvf7rjNLL7d7Hzz89oHL//vWO9xx/vgyRht58XF1eXpC5Z1Tq7sB3Y7l3QdLf562U6vDeOeBgqK/M7av448v/YQrTn2QAd2ODUOE1VOP5B7k5tec65gTbphFw5Y9Slx3sONAWY8BUPpxYOzJp7F9w8IyRlv9nHzbPOo1akN6Rjrt2x8R6XBUAUdd/Dxte5f8oF84PgO/uPrXbFj0ehmjVaR5LVCc1wIlq2nXAoeiNpwHuw7/OYefeW+J68LxnWjKK69x4znXlDHa6qc2vAd0aHwPqDopLPxumKSRI0eycGHFvmvWygTZ+vWhGZA7depU4vr8/Hw+/vhjoHiCLDk5uWj7/Px84uIOfHlWr15drCxQLDn2rSFDhgCwcePGiuwCABkZGeXaPi6h5g1nsCl9E/n790Y6DEmq9ep33FLquoZ1oXEZTyExMWUv+317s7MO6ZwYbol1at45NVxycvdy5wtncGTv0zljxIRIhxNR6Zs2kZNXc65jcvfnlLqurMeBih4DADZnbGJLDToO/FBBQUHR75p0PNN39u4tvetAOD4D2zK3+N6pQbwWKJ3XAt+padcCh6I2nAeb7Ch9rN1wfCfKztpdY187qB3vAR0a3wOqrjZv3lzhbWtlgiw7OxsoPk/Y902ZMoXMzEySkpLo0qVL0fJBgwYRHx/P/v37mT9/PsOHDz9g2zlz5gAwbNiwH41h1qzQkAOHHXZYhfYBoHXr1uUqH1vnII+6VENt27S1B5kkhUFS3dJP+bvLcBhumBj6IlhYCLtLv8deal2xgTzatWt38Iaqifi4mndODZfZS6ayJn0xGzNT+WDxlAPWP3vjMlo26RiByMKvTdu2Neup8fzSb+Ad7DhQ1mPAj9XVOCmROjXoOPBDsbGxRb9r0vFM34mj9KH0w/EZSKoX53unBvFaoHReC3ynxl0LHILacB6sn1D6FCjh+E5UJya/xr52UDveAzo0vgdUnRQWFpKeng5Aq1atKlxPIBgMRnJ+yirRu3dvli9fzuOPP86vfvWrYuvS09MZPHgw6enpjBgxoijh9a1TTz2V6dOnc9lll/Hss88WW/fRRx9xzDHHEB8fz4YNG2jZsmWJ7W/cuJFBgwYxePBg3nrrrcrduR+xPx9uOfDatNzSln3A1HtTGHn+gww+5cYSyzx6YYDOA09h3I3TDqmtiedBQq1M00pS9bJrH9z5WsW3v+vM0FOSO/fCXRUYHersIXB0z4q3H24FuTBrcqSjUHWXcg3Exkc6irKbOg9mp1Zs20M9BiTWgXvPhZhAxdqvDu58LXQsbVQX/nBWpKNRRXy4Al7/omLbHupnAODusyDJnEuN4bWAyqKmXQscitpwHtyyG+59s+LbH+q54GdHwtCuFW8/0mrDe0CHxveAqpPs7GwaNGgAQFZWFvXr169QPaU/OlGDjR4dmjdr4sSJpKZ+dxdg3rx5pKSkkJmZCcDAgQMP2PaOO+4gEAjw/PPP8+KLLxYtX716NePHh+ZOueqqq0pNjmVlZTFu3Dji4+N57rnnKmuXJEk6JI3qhn4ipX3TyLUtKSSSn8P2TWt2cky1Q4cIfgYa1zM5JkmR1jwpsg9pR/I8JEkqWa1MkN188800a9aMDRs20KdPH/r160ePHj0YOnQoXbt25bjjjgOKzz/2reHDh3P//fcTDAa55JJL6Ny5M4MGDaJXr16sWrWKYcOGcf/995fY7r59+zjttNNYu3YtM2bMoE2bNlW6n5IklUeXA6fMDIv4OGjXJDJtS/pO1wgdAwC6NI9c29K32jWFOrGRaTtS52BJ0ndiApE7HteLh5YNI9O2JKl0tTJB1r59e2bPns0pp5xCYmIi69ato2nTpjz11FNMnz69qFdZSQkyCCXY3n77bcaMGcOuXbtYsWIFycnJ3HPPPXz44YfUq3fgTJx5eXmcc845zJ8/n7feeovevXtX6T5Wpfa9j+Xal4KlDq8IcO1LwUMeXlGSFF5Hdo9Mu4M7h5JkkiKrRUPoXvGh2SssAAyP0PFH+r6EuNA5KRIidQ6WJBUXqePxsG4QWyvvwkpSzVZrb1cddthhTJt2YAInKyuLdevWERMTQ9++fUvd/sQTT+TEE08sU1uFhYVccMEFvP/++/z3v/9l6NChFY5bkqSq0qM1tEiCrXvC2+6IHuFtT1LpRvaAVZvD2+ZhbaFZg/C2KZVmRDLMXR3eNls2hB4RSE5Lkg7Ut31o6Pld+8Lbrt+JJKl6irpnF5YuXUowGKRHjx4l9gSriF/96le88sor/OY3v6FevXrMnTu36Gfr1q2V0oYkSYcqJgDH9wlvm73aOP+YVJ306xD+4X2Or7kDK6gW6tAUeoZ5JPzje0PAOfgkqVqIjYGUMF+bDOwYmv9MklT91NoeZKVZsmQJUPrwihXx1ltvAXD//fcfMD/Z888/zyWXXFJpbUmSdCiGdYWF6+DrjKpvKyEOzhtW9e1EQm5eDvf8/aes37yMhDp1adygJdec9STtmncnGAzyrw8e5J15z0EgQGFhAWOPuIyfHHszMTE//mxSatoXPP/W7aRlppJUryl1YhP4ybE3MaLvGQC8M+8FXv3oIQoK8ykoyGNU/3P5+Ql/oE5cPACzl7zGy+/fQ0FhAXn5OTRr2JaJV77HHc+fyrZdmwBYk76Yzq37EhOIpV5iEo9cPbtKX6tvvf35c0yd/QjfbFnOVadO4qyjr/vR8hnb1/GLRwby77t3hiU+gLStK3lwysXsys6kfmIjbjrvBTq3DnNWuYrFxsD5w2HyuxAMVn17I3tAN3vOqJo5byhMnA7786u+rV5tYGjXqm9H4ee1QMW88ckT/Pvjx4iNiSMmEMNjv/6M+DqJJZb1WkBVZVQyLFoP6zKrvq36CXD2kKpvR5JUMSbIKsG6desqrS5JkqpSIAA/HQ73TyvfjcHd+4r/LoszBkOT+uWLryY5ediVDO11EoFAgH9//DgPv3I5D/3yA557+3aWrPmIR341h0b1m7MrO5M7XziDPft2cMUpE0utb13GUm595kRuPO95jux9GgCZuzaxYOW7AEyf+zRTZz/CPeP/S5umXcjJ3cvEly/ioVfG89vz/8a23en86dUreeK6L2jVpBMAK9MWEAgEuHf8f4vaGXNTgEeunk2Duo2r7sUpQY/2g7njwn/xz5n3hbXdsigoyCc2No5Hp17FycOu5MQjLuGjL1/lwSmX8Odr50U6vErXpQUc2wtmLS/7NhU5BjStD6cNKl9sUjg0bQCnHw6vfF72bSryGUisE3pQxN5jtZfXAuXzyVf/4f0Ff+exCXOpX7cRO7O2EhtbJ6wxlCbargWiXUwMnH8kTPov5BWUfbuKnAvOHgJJdcsXnyQpfEyQSZIUZZrUh8tGwdMfQEFh2bZ5+O3ytXF0Txjerdyh1RjxdRIZdtjJRX8f1nE4r344iX37s5j60cM8ed0CGtVvDkCj+s35zTlP88tHBnHB8XdQL7Hk8VX+Oet+xh5xWdENMYDmjdpywpCLAXjpvf/HdWc/TZumXQBIjK/Hb855mp/d04FNY+5i7/49xMTEklT3uzEte7Q/vML7+OmyN3n+rdsJBGIoLMzn0rH3cFTfcWzfncGf/3MNm3esY3/ePo7qM45Lx/4RgKXrPmHya1dTWJhPcocjWLVxIVeP+xMDuh1Lt7aha69AoGIjfN/3jwvYsPVr8vNzadG4Azec+yxNG7bmsdcn0KxhW352/G0AbNjyNbc8PZq/3bqWIEFeeOd3LFo1k7z8XNq3SOa6s58iqV4THvjnJcTExLApcxU7s7bw0NUfkZo2n/uvmAHA0f3O5vHXJ7AxcxXtmkdoNvcqdOpA2LwLlm0qW/nyHgPqxcMVx0JC9bjvKR3gqO6QvgPmrCxb+fJ+BmJj4NKja/eDItHOa4HyXwv868MHuWjMndSv2wiAxg1alCserwVUmVo1hItGwPOzy96rvrzngtF94PDO5Q5NkhRGUTcH2cyZMwkGg5xyyimRDkWSpIjp2SaUJKsTW/l1j0yGMwdH1xPzr895lCP7jGP95mXUiUugU6viExt0atWbOnUSWb9lWal1rEz7gsM6HVniuh1ZW8jctZHeP1jfsH4z2jXvwcqNC+japj99O4/kwns7cdcLZ/KvDx4kc9fGCu/TC2/fwXVnP8VT1y/iqeu/pH+3YwB4YMrFnH7Ur3j8ms/5y3ULSd0wnw8Xv0Jefi73vHQeV506iWdu/IqUgeezJn1xhdv/oV+e/ieeuHY+T9/wJf26HM1f370LgDNG/Jr/fvY0BYWhx3/f+PQJTh52JbGxcfzrgwdJrFOfx6/5nKeuX0SX1v14/u07iupcmfYFf7xsOs/dvIKtOzfQtGEbYmNDz48FAgFaNunIlp3fVNo+VCexMXDJ0dC7beXXXT8Bfnk8tGlc+XVLlSUQgLOOgBE9Kr/uOrEwflT45zpTZHktcPBrgW82LyM1bT7XPj6Cqx8dwutzJpcrHq8FVNn6d4CLR4Suiyrb8b3hFJ/Nl6RqL+p6kEmSpJA+7WDCaPj7p7Bl96HXFx8Lpw6Co5OjKzn2j/fvZVPmKh646n3WZXxFgNJ3PiGu6sZXiYmJ4c6Lp/LNlhV8ufpD5n39Fv94/x7+fO38Cj31PKj78TzxxrUc3e8cBiefQPd2A9mXm83CVe+zY8/monI5uVmkbf2aDVtWEBsTx+HJowEY0vME2jStvIl3Zi78B+8t+Bt5eTnk5ufQ8H9P5Xdo2ZOOrXrzydL/MKTniXyw8GWeviE0YsAnS/9Nds4uZi+ZCkB+QS6tmnYuqnNU/3NLfYo/GsTHwfhj4L+LYebyypmTrEtz+NlR0CJ6X1bVIDEBOOcIaNkQpi0q3zBbpWnZEC44Ejo1P/S6VHN4LVC2a4GCwnwytq/l4as/ImvfDm548hjaNO3K8N6nlikerwVUFQZ2gqRE+Mdc2JZ16PUlxIUeFhxup0NJqhFMkEmSFMU6NYcbT4K3v4RZKyp+g7xbSzh/ODSPsvsLr3wwiTlfvcYDV75HYnw9OrXqTW5+Dus3Lyv25Pj6zcuIi6lD+5Y9S62rR/vBLF//KSP7nXnAuiYNWtK8UTuWrf+02HBOu7O3sTFzJT3afTd8UseWvejYshenHnkVtz4zlk+XvsE5x1xf7n37xekPsy5jKYtWz+LBKRdz3KALOP2oqwF47Ndzia+TWKz8mk1fHlBHoJIypV+tncO/50zm0V9/SpMGLflk6Ru8+M7vi9afOfJa/jVrIruytnJ48hiaJLUCIBgM8qtxjzGk5wkl1ls3oUHRv1s07sD23elFc5AEg0G27PiGlo07Vso+VFexMaF5wgZ0hH98Chm7KlZPndjQU9Kjeobm9ZBqikAAjukFvdvBy5/Cmq0VryflMDipf9X0zlb15bXAdw52LdCycUdSBp1PbEwsjeo3Z2ivk1n+zdwyJci8FlBV6tYKbj4Z3lwEc1IrXk/PNvDTYQ6vK0k1iV9fJUmKcvFxcPrh8LvTYUwfaJBQtu1iAjCoE/x6dKgnWrQlx1798GFmLXqZiVe8WzTJfd2EBpw58lr+NPUqdmVnAqEbV3+aehXjT76f+LjSX9zzjr2Zt+c9x2fLpxct2747gxnzXwTgZ8fdzlPTbiB9+1oAcnL38sirVzKi75m0bd6NzF0b+Wrtx0Xb7tm7g4wda2nbrGKTwX2zZQWdW/fhjBETOPXIX7L8m7nUTWjAwG4p/HPW/UXlMndtYuvONDq07EVBYT6LVs0CYEHqe2zatrpCbf/Qnn07qJuQRMN6zcjLz2X63KeKrR+SfALb92Twj/f/yLijJhQtP6rvGbw2+xFycvcCoddsXcbSEtto0qAl3dsdznsLXgJg9pKpNG/cPmrmHOnYLHRj6PJjoFc5hoVr1gBOHwR3ngHHHmZyTDVXiyT49ZjQ+Wxgx9A5riwaJIbOnb8fF/osmByLLl4LhJT1WiBl0M+YvyI0idP+vH0sXv0BXduUbQw6rwVU1RLqhHoV33F66IGHevFl2y42BoZ0getOhF+kmByTpJrGHmSSJAmApg3glIFwYj9Ynwkbtod+tmdDfkHoxneDBGjXBDo0hc4tQsORRKOtO9N4atoNtGnalRv/kgJAfFwCj13zGeNPuo9/ffAA1/15BAAZ29fyq3GPcfKwy3+0zi5t+nHv5W/x3Fu38/i/f01ifH3qJSRxXspvATjtqF8SG1uH3z93GgXBAvLzczm639lcPPZuIDRs0Uvv/T8ytq8loU49CgvzGTP4Yo7qO65C+/jcW7eRtvVr4mLjSahTj2vPehKA3/7s7zz1xvVcMakvBAIkxtfnurOfokXj9tx+4RQmv3Y1hcECenY4othNr3fmvcAL79xB1t4dfLL037zy4STuvvRNurcbdNBYjug5lvcXvMRlD/SkYb1mDOoxuticKoFAgLFDxzNr4T/o3fm7uVl+euwt/C1/P79+bFjRcFfnpdxC59Z9SmznurOf4sEpl/DyzHupl9iQm37yfIVeu5oqJgb6tg/97MiGdf87DmzaAftyoTAYuvnfsiG0bxo6DnRoVvZEglTdBQLQvVXoZ08OrNsa+gxs3AFZ+6GwEOJioWn9/73/m4Z6YseZFItKXguU/1rgnFHXhxKFD/YmEAgwst/ZHDPg3DLF4rWAwqV5Eow7PNQjeP02SNsOG7bBjr2h70SxMaGHI9p/7ztR/TI+YChJqn4CwWBlzDag6mB/PtwyJdJRlM/E80LjM0uSVJ0U5MKs8s0bX6rXZv+J1+dM5sGrZtL6e3NeRIOrHx3CVadOYkC3Y6u8rTueO5VjBpzHmMEXVXlb30q5BmLL+HSxar47X4Nd+6BRXfjDWZGORlJV81qgcngtUHt4HpTvAfkeUHWSnZ1NgwahoZKzsrKoX79iXXgdBEWSJKkKnXX0dfzt1jVRd0MsXL7eMJ+L7+9OIBDDcYN+FulwJEk6gNcCVctrAUmSVFH23ZEkSQqTVRsX8eCUSw5YfsKQizl71G9qXTxPXDv/oGV+9/zpbNnxTbFlSfWaMOkXs8rURs8OQ3jxt6sqFJ8kSeHmtcCBvBaQJEmRYoJMkiQpTLq3G8hT1y+KdBhFqkM8d1/6RkTblyQpnKrDuff7qkM8XgtIkqRIcYhFSZIkSZIkSZIkRRUTZJIkSZIkSZIkSYoqDrFYi8THwsTzIh1F+cTHRjoCSZIOFFMHUq6JdBSq7mLqRDoCSVJV8VpAZeG1gCRJNZsJslokEIAE/0clSTpkgQDExkc6CkmSFCleC0iSJNV+DrEoSZIkSZIkSZKkqGKCTJIkSZIkSZIkSVHFBJkkSZIkSZIkSZKiigkySZIkSZIkSZIkRRUTZJIkSZIkSZIkSYoqJsgkSZIkSZIkSZIUVUyQSZIkSZIkSZIkKaqYIJMkSZIkSZIkSVJUMUEmSZIkSZIkSZKkqGKCTJIkSZIkSZIkSVHFBJkkSZIkSZIkSZKiigkySZIkSZIkSZIkRRUTZJIkSZIkSZIkSYoqJsgkSZIkSZIkSZIUVUyQSZIkSZIkSZIkKaqYIJMkSZIkSZIkSVJUMUEmSZIkSZIkSZKkqBIX6QBUeYJByC2IdBTlEx8LgUCko5AkSZL0fcEgFOZFOgpVZzF1/C4nSZKkms0EWS2SWwC3TIl0FOUz8TxI8F0oSZIkVSuFeTBrcqSjUHWWcg3Exkc6CkmSJKniHGJRkiRJkiRJkiRJUcUEmSRJkiRJkiRJkqKKCTJJkiRJkiRJkiRFFRNkkiRJkiRJkiRJiiomyCRJkiRJkiRJkhRV4iIdgCRJkiRVJ3tyIDUD0rbDhu2wcy/szgmty9oPU+dB+6bQoxU0bRDZWCVJqgqbdsCaraHz4MYdoXMjhH4/PSt0HuzYDHq0hgTvLkq1zv680PXwhu2ha+LMrO9dD+fAP+eGjgNdW0DbJpGNVToUnsIkSZIkRb1gENZuhTmpsHgDFBSWXK6gEGanhv4dAA5rCyOToVdbiAmELVxJkipdbj4s+iZ0LvxmW8llCoOwbFPoByCxDgztCiOSoVXD8MUqqWps3gVzVsK8NZCTV3KZgiDMXQ2sDv3dqTmM7AEDO0Gd2LCFKlUKE2SSJEmSotquffDK5/BVWvm2C/LdTcIuzeGnR3pzsKZavPoDbvxLSrFlifH1ad8imdGHX8QZI35NbKxfnyXVXisz4OW5sD27fNvl5MFHX8Psr2FULzhlAMR7uJRqnP35MH1R6PNcXuszQz9vL4Hzh0P3VpUenlRlPGVJkiRJiloL1sGr82Bv7qHVszYTJv03dGPwmF4QsDdZjZQy8HyG9jqZIEF27Mng3S/+yl/evJ5vtiznN+c8HenwJKnS5RXAf74I9Rg5FEHgwxWwdCNceBR0bl4p4UkKg7Vb4e+fhIZRPBTbsuDx9+DoZBh3OMTZm0w1QEykA5AkSZKkSJi1HP768aEnx76VVwD/XgCvzQ8N2aiap0e7wxk9+ELGDL6Inxx7E5N/PZcWjdrz1uf/x86srZEOT5Iq1f58eOaDQ0+OfV/mHvjze7B8U+XVKanqLN0IT7x/6Mmx75udGjq25OZXXp1SVTFBJkmSJCnqzP4a/rOgiupODSXKTJLVfHXj69Or03CCwSCbtq2OdDiSVGnyC+C5DyE1o/LrziuAZz+ElZsrv25JlefrdHjuo9BnttLrzgjVnV8FdUuVyQRZKWbMmMHYsWNp1qwZ9erVo1+/ftx3333k5lbS46WSJEmSImLt1lAvr6r04YrQ8I2q+dL/lxhrWK9phCORpMozbVHoBnZVyS+E5z+CPfuqrg1JFbdrL7wwBwoKq66NFenw3y+rrn6pMjgHWQkeeughbrzxRgA6depEx44d+eqrr7jtttuYNm0a7733HnXr1o1wlJIkSZLKKzcf/vFpaK6U8rh+LDSsC7v3wcNvl22bqfOhR+vQdqoZcvL2sis7k2AwNAfZm5/+hVUbF9Krw1Dat0iOdHiSVCnWbAk9yFEeFTkP7s2FV+bBpUc7N6dUnQSD8K/PYV85+4FU5Dgwazn07+C8hKq+7EH2A59//jk33XQTgUCAF154gXXr1rFw4UJWrFhB9+7d+eSTT7j11lsjHaYkSZKkCnhnCWzdU/7tGtaFxvXKl+zam1v1PdVUuf46407OuasF5/6hJVc+3J83P32CkX3P4g+X/CfSoUlSpSgohJfnlv9BkYqcBwG+3ACLN5SzMUlVauH60Nxj5VWR40AwCC9/CoVV2FNNOhT2IPuBu+++m2AwyGWXXcbFF19ctLxbt248++yzHHPMMTz55JPcdttttGzZMoKRVp20ZR8w9d4URp7/IINPubHEMo9eGKDzwFMYd+O0MEcnSZIkVcz+PPh4ZXjbXPwNbMuCZg3C264q5pRhVzKq/7nkF+axNn0JUz6YSOauNOLrJBaVWbJmNrc9e9IB2+YX5FJYWMA7DzjZhqTq66u0ij0ocihmLYOBHcPbpqSSBYMwc3l429y8G5Ztgr7tw9uuVBa1vgdZZmYmN998M927dycxMZEOHTpw7bXXkp2dzfjx4wkEAjz++OMA7NmzhxkzZgBwxRVXHFDXqFGjSE5OJjc3lzfeeCOs+yFJkiTp0HyxDnLywttmkPAn5VRx7Zr34PDk0QztdRLnpdzM3Ze+yddp83h06i+KyvTrejRv3pNV7Of5m1NpWL85F594dwSjl6SDi8Q5af022LAt/O1KOtD6bZC2PfztzkkNf5tSWdTqBNmiRYvo168fDz74IBkZGfTu3Zu8vDwmT57Meeedx/LloXT5wIEDAVi4cCG5ubkkJCQwZMiQEuscOXIkAHPnzg3LPkiSJEmqHHNXR6bdz1ZDYXnHslK10KfzUYw+/CI+WDyFpes+KbFMbv5+/vDXs+jbeSQ/O/62MEcoSWW3LQtSMyLT9mcROgdLKi5Sn8UV6bAjOzJtSz+m1ibIMjMzOe2008jIyOCGG24gPT2dBQsWkJGRwcSJE5k+fTrz5s0jEAjQv39/AFJTQ6nsTp06ERdX8uiT3bp1K1ZWkiRJUvWXVxCZp2UBsvfDtjAPZ6XKc8Ho3xETE8uL7/y+xPWPTv0FuXk53HTeC+ENTJLKaX1m5NpeF8G2JX1n3dbItb3enqSqhmptguyaa64hLS2NCRMmMGnSJJKSkorW3XzzzQwYMID8/Hw6d+5Mw4YNAdixYwcATZo0KbXeb9d9W7Y2y8/dy749mSX+SJIkSTXJph2R7cW1IULJOR26ds27kzLgpyxc9T5L1swutu71OZP5bPk0/nDJv0mMrxehCCWpbCJ5Ltq0M/SwiqTIyc2HjN2Ra9+hVlUd1coE2fLly5kyZQrNmzfnvvvuK7HM4MGDARgwYEDRspycHADi4+NLrTshIQGAffv2FS2bPXs2o0ePpk2bNiQkJNC+fftiQzjWVHOn3snTv2xR4o8kSZJUk2zaGdn2N9b+5+tqtfOPv52YQAwvzviuF9miVbP4v+m38LuLXqF1086RC06SymhTBM9FhUHYvCty7UuCjF0QjOADY14PqzoqeRzBGu7ll1+msLCQCy64gAYNGpRYpm7dukDxBFliYiIAubm5pda9f//+YttDqDdZv379uOqqq2jZsiVpaWncd999HHnkkXz11Ve0b9++QvsxZMgQMjLKPjh0bJ26nPnHyptttW/KlfQYdm6J616/f0yltJHcowcFefsOXlCSJEk6BD2OvpIBp5Y8RN71Y6Fh3RJXFWmY+N3vu84svdzuffDw2wcuf+r/XuCX/7mjjNFGXnxcXZ6eUHnfLaq7Ad2O5d0HS79j1KnVYbzzwHddHzK2r+OPL/2EK059kAHdjg1DhNVPj+Qe5Ob7XU6qSY771Zs07TioxHUHOxeW9TwIpZ8LTx13Dplr55YxWlU3J982j3qN2pCekU779kdEOhxVQMtuIxh15ZQS14XjenjOJ5/zx5+fVcZopR9XWFhY9O+RI0eycOHCCtVTKxNkM2fOBCAlJaXUMmlpaUDxBFlZhk8saRjG008/ndNPP71YuSOOOIKePXsydepUrr322nLuQUhGRgYbN24sc/m4hMod0qNx6x507Du6Uuv8oU3pm8jfv7dK25AkSZJa7Sl9ErCGdaFxGS+lY2LKXvb79u3LKde1faQl1nG4wNLk5O7lzhfO4Mjep3PGiAmRDidi0jdtIifP73JSTZKXn1/qurKeCyt6HgTYtn17jToXqriCgoKi3/4/1kyxTUofZzUc18N5+b53VDU2b95c4W1rZYJs/fr1AHTq1KnE9fn5+Xz88cdA8QRZcnJy0fb5+fnExR348qxevbpY2dI0a9YMoMQ6yqp169blKh9b5yBp/mqobZu29iCTJElSlWtQN6HUdbvLcDnaMDF0M6CwEHbnlF6utLoS4mNo167dwRuqJuLjat53i3CZvWQqa9IXszEzlQ8WH/gU9rM3LqNlk44RiCy82rRtaw8yqYaJofRJwA52LizrefDH6mrSqAHBGnQuVHGxsbFFv2vSNY2+07hRySOtQXiuh2MDhb53VGkKCwtJT08HoFWrVhWup1YmyLKzs4Hi84R935QpU8jMzCQpKYkuXboULR80aBDx8fHs37+f+fPnM3z48AO2nTNnDgDDhg07YF1BQQGFhYWsX7+eW2+9ldatW/OTn/ykwvsxf/78cpXfnw+3lNxLttpKXbmShFr5LpQkSVJ18nU6PDmz5HUlDQHzQ3edGXpSdncO3PV6+du//YYrGfGXK8u/YYQU5MKsyZGOonoaM/gixgy+KNJhRNzK1JXElj59t6Rq6J9zYe7qktcd7Fx4qOdBgE9nvUH90p9XUTV352uwax+0ad2maGQu1SxZOXDH1JLXheN6+IyTRvCPO33vqHJkZ2cXTa/1bc6mImIqK6Dq5NueVwsWLDhgXXp6OjfddBMA/fv3JxAIFK1LSkpizJjQ3FrPPPPMAdt+9NFHpKamEh8fz7hx4w5Yf8wxxxAfH0+PHj1YtGgRM2fOpEWLFpWyT5IkSZIqrn3TyLbfIcLtS5IUyXNRswaYHJMirEFixYdIrQxeD6s6qpUJstGjQ/NmTZw4kdTU1KLl8+bNIyUlhczMTAAGDhx4wLZ33HEHgUCA559/nhdffLFo+erVqxk/fjwAV111FS1btjxg22effZa5c+fy8ssv07BhQ0444QS++eabytw1SZIkSRVQPyF0cy4SYmOgbePItC1J0rc6NItg294Yl6qFjh4HpGJqZYLs5ptvplmzZmzYsIE+ffrQr18/evTowdChQ+natSvHHXccUHz+sW8NHz6c+++/n2AwyCWXXELnzp0ZNGgQvXr1YtWqVQwbNoz777+/xHZ79uzJsGHD+OlPf8r777/Pnj17eOCBB6p0XyVJkiSVzaCSpyiucv07QFxsZNqWJOlb7ZtC86TItB2pc7Ck4iL1WWzZENo1iUzb0o+plQmy9u3bM3v2bE455RQSExNZt24dTZs25amnnmL69OlFvcpKSpBBKMH29ttvM2bMGHbt2sWKFStITk7mnnvu4cMPP6RevYP3RW3cuDHdu3dn1apVlbpv4dC+97Fc+1KQwafcWGqZa18KMu7GaWGMSpIkSTo0R3WHwMGLVbqRPSLQqCRJPxATgBEROCc1qgt924e/XUkH6tceGiaGv92RyRCIxIW4dBBxkQ6gqhx22GFMm3ZgAicrK4t169YRExND3759S93+xBNP5MQTT6xw+1u2bOHrr79m2LBhFa5DkiRJUuVp2gD6tIevwjg3eJvG0PXA0dklSYqIoV3hrS8hNz98bY7oERpuWFLkxcXCkT3gnSXhazMhDo7oEr72pPKotQmy0ixdupRgMEhycnKZeoKVxYUXXkj37t0ZOHAgjRs3ZuXKlTzyyCPExcXxm9/8plLakCRJknTozjgcUjPCc2MwAJx7hE/LSpKqj/oJcNpAmDo/PO21SIJjDwtPW5LK5rje8MVayMwKT3unHw5148PTllReUZcgW7IklB4vbXjFihg+fDh//etfefTRR8nJyaFDhw6kpKRw22230amTgyxLkiRJ1UXzpPDdGDymV+3tPZabl8M9f/8p6zcvI6FOXRo3aMk1Zz1Ju+bdCQaD/OuDB3ln3nMQCFBYWMDYIy7jJ8feTEzMj3chSE37guffup20zFSS6jWlTmwCPzn2Jkb0PQOAd+a9wKsfPURBYT4FBXmM6n8uPz/hD9SJC911mb3kNV5+/x4KCgvIy8+hWcO2TLzyPe54/lS27doEwJr0xXRu3ZeYQCz1EpN45OrZVfpafevZt27j4yWvUScugdjYOlw69h6O6Pnjo5aMuSnA6/9vBw3qNg5LjDuytvDAyz9n0/bVxMcm8OuznqB/11FhaVtS+IxIhsUbYNXmqm0nAPzsSIiPuruPUvWWEAfnHwmPvwvBKm4ruXVomHOpuoq6U1RVJMgmTJjAhAkTKq0+SZIkSVVnRDKs3Axfbij7Nrv3Ff99MB2bwcmV95WjWjp52JUM7XUSgUCAf3/8OA+/cjkP/fIDnnv7dpas+YhHfjWHRvWbsys7kztfOIM9+3ZwxSkTS61vXcZSbn3mRG4873mO7H0aAJm7NrFg5bsATJ/7NFNnP8I94/9Lm6ZdyMndy8SXL+KhV8bz2/P/xrbd6fzp1St54rovaNUk9KDiyrQFBAIB7h3/36J2xtwU4JGrZ4ct6fStfl2O5sLRvyOhTl1Wb1rM9U+O4p+/20Td+PphjaMkhYWFADz7399yWKfh3HfF23y9YR53vXgmf7t1LXGxdSIcoaTKFBOAnw2HP80o+3mtvOdBgJP6Q5cW5Y9PUtXr1hJO6Fe+oRbLexxoVBfOH+5oCqreTJBJkiRJiioxAbhoBDz7IaxIL9s2D79d9vrbNYGrUmr3E/PxdRIZdtjJRX8f1nE4r344iX37s5j60cM8ed0CGtVvDkCj+s35zTlP88tHBnHB8XdQLzGpxDr/Oet+xh5xWVFyDKB5o7acMORiAF567/9x3dlP06ZpaBKLxPh6/Oacp/nZPR3YNOYu9u7fQ0xMLEl1mxZt36P94RXex0+Xvcnzb91OIBBDYWE+l469h6P6jmP77gz+/J9r2LxjHfvz9nFUn3FcOvaPACxd9wmTX7uawsJ8kjscwaqNC7l63J8Y0O1YhvY6qajuLq37QTDIrqyt1G1atgTZU2/eyJdrPiS/II/6iQ35zTnP0KFlT175YBJpman85pynAcjat5OL7+/O87ek0rBeU175YBIffvkvCgrzaVy/Jded8xStmnTirzPuYm36EvblZrF15wYmXvkuHy7+Fy/esgqAnh2OoFnDtny5+kMOTx5d4ddRUvXUtAH88jj48/uQlXPw8uU5DwKkHAZj+lYsNknhMbYf5OTBhyvKVr48x4GkRPjl8dAk8s8BST+qFn9lK9nMmTMjHYIkSZKkCKsTC5cfA//8DOavrbx6k1vDJUdDvSibZ+H1OY9yZJ9xrN+8jDpxCXRq1bvY+k6telOnTiLrtyzjsI7DSqxjZdoXjBx7T4nrdmRtIXPXRnp3OrLY8ob1m9GueQ9WblzA0f3Opm/nkVx4byf6dz2G3p2P4rhBP6N5o3YV2qcX3r6D685+it6dj6SwsJC9+3cD8MCUizn/uNsY0O0YCgryueO5U/lw8Ssc1Wcc97x0Hjf+5HkOTx7N/K9nMGP+CyXW/c7852ndtGtRT7eyOC/lFq46bRIAsxb9kyf+cy33XfE2Jw27nEsnJnPFKQ/QoG5j3pn3PEf1GUfDek2ZufAfbNj6NY9O+JTYmFje/eJvTH7tau4ZPx2AZd98yl+uW0iTpFbszt5GQUEeTRu2LmqzVZPObNn5TYVeP0nVX5vGcM0Y+L8PYcvuyqkzJhDqOTa6j71GpOouEAjNz1s/Ad76EoKVNN5iy4ZwxbGhOQil6i7qEmSSJEmSBBAXCxceBf3awyufQ9b+itcVHwenD4KjeoRuDkaTf7x/L5syV/HAVe+zLuMrApT+AiTE1a2yOGJiYrjz4ql8s2UFX67+kHlfv8U/3r+HP187n3bNyz/5xaDux/PEG9dydL9zGJx8At3bDWRfbjYLV73Pjj3fTdyTk5tF2tav2bBlBbExcUW9rYb0PIE2TbseUO+Cle/zt3f/wMQr3iVQjrvHC1a+y7/nPMa+/XsoDBayZ+92ABrUbczR/c/h7c+f4+xRv+HNT5/kjgunAPDxV/8mdcM8rv7TYAAKgwXF6hza62SaJLUq3wsjqVZp2RBuPCl0c/yD5Yc2H1HrRqE5xzo2q7TwJFWxQABO6As9W8M/PoXNh5AsDwRCvUdP6h96GE2qCUyQSZIkSYpqAzqG5mGYtRzmrobsciTKEuJgSBc4rjc0a1B1MVZXr3wwiTlfvcYDV75HYnw9OrXqTW5+Dus3LyvWi2z95mXExdShfcuepdbVo/1glq//lJH9zjxgXZMGLWneqB3L1n9abGjH3dnb2Ji5kh7tvhtKsWPLXnRs2YtTj7yKW58Zy6dL3+CcY64v97794vSHWZexlEWrZ/HglIs5btAFnH7U1QA89uu5xNdJLFZ+zaYvD6jjhwmwxas/ZNK/LuXuS9+kw4+8Fj+0Zcc3PP76BB6/Zh5tm3djzaYvuf7JUUXrzxh5Db9//nQ6tjqMRvVb0L3dIACCBPnpcbdyyvArS6y3bvx3b9qG9ZsRGxPH9t0ZRb3INu9YR8vGHcscp6SaKT4Oxh0OAzvCzOWwZAMUliNT1jwJRvaAkcmhh08k1TydmsONJ8OcVPg4FTKzyr5tTAD6dwhdD5sgV00TE+kAJEmSJCnSGiTCaYPgD2eGepUN7hx6qr6k/j3NGoSSauceAX84C84dGp3JsVc/fJhZi15m4hXv0qBuYwDqJjTgzJHX8qepV7ErOxMIJbH+NPUqxp98P/FxCaXWd96xN/P2vOf4bPn0omXbd2cwY/6LAPzsuNt5atoNpG8PjYmZk7uXR169khF9z6Rt825k7trIV2s/Ltp2z94dZOxYS9tm3Sq0f99sWUHn1n04Y8QETj3ylyz/Zi51ExowsFsK/5x1f1G5zF2b2LozjQ4te1FQmM+iVbMAWJD6Hpu2rS4q9+Waj5j4z4v4f5f8h25tyzcndnbOLmJj69C0YRuCwSD/+eTxYus7tuxFm6Zd+dOrVzJuxISi5SP6nMG0uX9h9/96m+UX5LFq48JS2zm6/7lMm/sXAL7eMI/MXRvp3+2YcsUqqebq1BwuPRruPANOGQC924bOjz8UGwPtm8KR3eEXx8Ftp8Gxh5kck2q6OrGhHmC3nR6aT3d4N2jfJPSZ/6GkxNAx4tSBcOeZoSHGTY6pJrIHmSRJkiT9T1xsqEfYkC6hv3PyYNc+KCgI3RxokBiapyHabd2ZxlPTbqBN067c+JcUAOLjEnjsms8Yf9J9/OuDB7juzyMAyNi+ll+Ne4yTh13+o3V2adOPey9/i+feup3H//1rEuPrUy8hifNSfgvAaUf9ktjYOvz+udMoCBaQn5/L0f3O5uKxdwNQUJjPS+/9PzK2ryWhTj0KC/MZM/hijuo7rkL7+Nxbt5G29WviYuNJqFOPa896EoDf/uzvPPXG9VwxqS8EAiTG1+e6s5+iReP23H7hFCa/djWFwQJ6djiCrm2+S4Q99Mp48vL38+CUS4uW/fb8v9GlTb+DxtKlTT+OHfhTrpjUh6T6zRjR54wDypw87Aoe//cERvU/p2jZ8YdfwO6927jpf/9HBYX5nHjEZUU9zH7oilMmcv/LF3HxxB7UiY3nt+e/RFxsnTK9XpJqj0b1YEzf0L+DQdidA/tyobAwdAO9SX2TYVJtFhOAw9qGfgDyC2BHNuQVQEwM1I2HhonOM6jaIRAMVtb0e4q0/flwy5RIR1E+E88LDUsjSZIkqfooyIVZkyunrtdm/4nX50zmwatm0rpp58qptIa4+tEhXHXqJAZ0O7bK23rs9Qk0adCKC8f8rsrbAki5BmLjw9KUJKkauPO10ENDjeqGetBLUiRlZ2fToEFoGI+srCzq169foXpMTUiSJEmSqsxZR1/HWUdfF+kwaq3MXZu4+anjSKrXlPsufyfS4UiSJEk1hgkySZIkSVJYrNq4iAenXHLA8hOGXMzZo35T6+J54tr5By3zp6m/YPn6uQcsn/zrT0moU/eg2zdv1Jbnbl5RofgkSZKkaGaCTJIkSZIUFt3bDeSp6xdFOowi1SGe687+S0TblyRJkqJVTKQDkCRJkiRJkiRJksLJHmS1SHwsTDwv0lGUT3xspCOQJEmS9EMxdSDlmkhHoeospk6kI5AkSZIOjQmyWiQQgAT/RyVJkiQdokAAYuMjHYUkSZIkVR2HWJQkSZIkSZIkSVJUMUEmSZIkSZIkSZKkqGKCTJIkSZIkSZIkSVHFBJkkSZIkSZIkSZKiigkySZIkSZIkSZIkRRUTZJIkSZIkSZIkSYoqJsgkSZIkSZIkSZIUVUyQSZIkSZIkSZIkKaqYIJMkSZIkSZIkSVJUMUEmSZIkSZIkSZKkqGKCTJIkSZIkSZIkSVHFBJkkSZIkSZIkSZKiigkySZIkSZIkSZIkRRUTZJIkSZIkSZIkSYoqJsgkSZIkSZIkSZIUVUyQSZIkSZIkSZIkKaqYIJMkSZIkSZIkSVJUMUEmSZIkSZIkSZKkqBIX6QBUeYJByC2IdBTlEx8LgUCko5AkSZIkSZKk7wSDUJgX6ShUncXU8d52TWeCrBbJLYBbpkQ6ivKZeB4k+C6UJEmSJEmSVI0U5sGsyZGOQtVZyjUQGx/pKHQoHGJRkiRJkiRJkiRJUcUEmSRJkiRJkiRJkqKKCTJJkiRJkiRJkiRFFRNkkiRJkiRJkiRJiipxkQ5AkiRJkiRJklS9ZOXAhu2QsQty8kLL9ufB8k3QoSk0SIxsfJJ0qEyQSZIkSZIkSZLYuRc+XQXz18K2rAPX5+TDU7NC/27WAI7oAkd2h0b1whunJFUGE2SSJEmSJEmSFMV27YN/fwGLv4HCYNm22ZYFby+BGV/BoE4w7nBoWLdq45SkymSCTJIkSZIkSZKiUDAY6i322hewL7didRQG4Yt1oaEXzx4Ch3eGQKAyo1RVW7z6A278S0qxZYnx9WnfIpnRh1/EGSN+TWysqQTVPr6rJUmSJEmSJCnKFBbCK/NCQypWhr258LdPYM1WOPsIiDFJVuOkDDyfob1OJkiQHXsyePeLv/KXN6/nmy3L+c05T0c6PKnSmSCTJEmSJEmSpChSGISX58K8tZVf98crIa8AfjrcJFlN06Pd4YwefGHR36cddTXjH+jFW5//H5eOvYfGDVpEMDqp8sVEOoDqasaMGYwdO5ZmzZpRr149+vXrx3333UdubgX7GkuSJEmSJElSNfDfxVWTHPvW52vgnSVVV7/Co258fXp1Gk4wGGTTttWRDkeqdCbISvDQQw9x4okn8s4775CUlETPnj1ZsWIFt912GykpKezbty/SIUqSJEmSJElSua3LhPeXlW+b68fCXWeGfpfVjK/gm23la0fVT/r/EmMN6zWNcCRS5TNB9gOff/45N910E4FAgBdeeIF169axcOFCVqxYQffu3fnkk0+49dZbIx2mJEmSJEmSJJVLXgH841MIBsu3XcO60Lhe6HdZBYOhtvIKyteWIicnby+7sjPZmbWVtelLmPzar1i1cSG9OgylfYvkSIcnVToTZD9w9913EwwGufTSS7n44ouLlnfr1o1nn30WgCeffJItW7ZEKsQql7bsAx69MMAX0yeVWubRCwP8Z9KpYYxKkiRJkiRJ0qH4fA1s2R2+9jJ2wRdVOJSjKtdfZ9zJOXe14Nw/tOTKh/vz5qdPMLLvWfzhkv9EOjSpStT6BFlmZiY333wz3bt3JzExkQ4dOnDttdeSnZ3N+PHjCQQCPP744wDs2bOHGTNmAHDFFVccUNeoUaNITk4mNzeXN954I6z7IUmSJEmSJEkVFQzCnNTwtzsntfw91hQZpwy7kolXvMs94//L5SdPJKleUzJ3pRFfJ7GozJI1sznt9gYH/Jz023hOvDk2gtFL5RcX6QCq0qJFizjppJPIyMigfv369O7dm02bNjF58mRWr17N9u3bARg4cCAACxcuJDc3l4SEBIYMGVJinSNHjiQ1NZW5c+dy+eWXh2tXJEmSJEmSJKnC1m6F9J3hbzdtB6zfBp2bh79tlU+75j04PHk0AEN7nUTfLiP5zRMjeXTqL7j9wn8C0K/r0bx5T1ax7TJ3beJXk4cw7qgJYY9ZOhS1tgdZZmYmp512GhkZGdxwww2kp6ezYMECMjIymDhxItOnT2fevHkEAgH69+8PQGpq6BGKTp06ERdXcu6wW7duxcpKkiRJkiRJUnW3Ij0621bF9el8FKMPv4gPFk9h6bpPSiyTm7+fP/z1LPp2HsnPjr8tzBFKh6bWJsiuueYa0tLSmDBhApMmTSIpKalo3c0338yAAQPIz8+nc+fONGzYEIAdO3YA0KRJk1Lr/Xbdt2Vrs/zcvezbk1nijyRJkiRJkqSaY8P2yLWdFsG2dWguGP07YmJiefGd35e4/tGpvyA3L4ebznshvIFJlaBWDrG4fPlypkyZQvPmzbnvvvtKLDN48GAWL17MgAEDipbl5OQAEB8fX2rdCQkJAOzbt6/UMieddBJvv/02d955J3fddVcF9qB6mDv1TuZOvTPSYUiSJEmSJEk6RJFMUm3YFrm2dWjaNe9OyoCf8v7Cv7NkzWz6dT26aN3rcybz2fJpPH7NPBLj60UwSqliamWC7OWXX6awsJALLriABg0alFimbt26AMUSZImJockGc3NzS617//79xbb/oX/9618sWrSoImFXO31TrqTHsHNLXPf6/WPCHI0kSZIkSZKkiigshD05kWt/1z4IBiEQiFwMqrjzj7+dWYte5sUZv2fSL2YBsGjVLP5v+i3ce/lbtG7aObIBShVUKxNkM2fOBCAlJaXUMmlpaUDxBFlZhk/8sWEYd+/ezXXXXcekSZO48MILyx/4DwwZMoSMjIwyl4+tU5cz/7jykNv9VuPWPejYd3Sl1VeS5B49KMgrvTeeJEmSJEmSpEMTE5fIWfesKnX99WOhYcn9AQBomPjd77vOLL3c7n3w8Nslr+vYuQvBgrwyRFs9xMfV5ekJlXevtTob0O1Y3n0wWOr6Tq0O450HCor+zti+jj++9BOuOPVBBnQ7NgwRVk89knuQm++97UgoLCws+vfIkSNZuHBhheqplQmy9evXA9CpU6cS1+fn5/Pxxx8DxRNkycnJRdvn5+cTF3fgy7N69epiZb/v9ttvJzk5mQsuuKBSEmQZGRls3LixzOXjEmpeN9ZN6ZvI37830mFIkiRJkiRJtVYgJvZH1zesC43LcGsxJqZs5UqS9s26im0YIYl1at691nDIyd3LnS+cwZG9T+eMERMiHU5EpW/aRE6e97YjbfPmzRXetlYmyLKzs4HS5wmbMmUKmZmZJCUl0aVLl6LlgwYNIj4+nv379zN//nyGDx9+wLZz5swBYNiwYcWWz58/n2eeeYYvvviisnaD1q1bl6t8bJ0fecyjmmrbpq09yCRJkiRJkqQqtj9rGwkNmpW4bvdBbs81TAwlxwoLYfePDNVYWj37dm+mXbt2ZYy0eoiPq3n3WsNh9pKprElfzMbMVD5YPOWA9c/euIyWTTpGILLwa9O2rT3IIqSwsJD09HQAWrVqVeF6amWCrHXr1uzYsYMFCxZw5JFHFluXnp7OTTfdBED//v0JfG/g26SkJMaMGcP06dN55plnDkiQffTRR6SmphIfH8+4ceOKlhcUFHDVVVcxYcIE+vTpU2n7MX/+/HKV358Ptxx4TKrWUleuJKFWvgslSZIkSZKk6uPJmfB1esnrShsW8Vt3nRnqObY7B+56vfxtD+7Viqf+N+VNTVGQC7MmRzqK6mfM4IsYM/iiSIdRLaxMXUlsfKSjiE7Z2dk0aNAA+K5TU0XEVFZA1cno0aF5syZOnEhqamrR8nnz5pGSkkJmZiYAAwcOPGDbO+64g0AgwPPPP8+LL75YtHz16tWMHz8egKuuuoqWLVv+f/buPc6qst4f+GcPMNxRLqIoCgqMCnJTE1RSMW+lRmllZSctU88pj9YxKc1OnZ/HxEunstsx89bNqLQyKSPFu5IgaIYiF0VBGXUUkfswzPz+mOMYMiQzzAVmv9+vFy9gred51ndt9rD32p/9PKtu3/e+97289NJL+frXv94MZwMAAAAAsHV279WKx65/4hpAq2qTAdnEiRPTu3fvLF68OMOGDcvw4cMzZMiQHHTQQdlrr71y5JFHJtn4/mNvGjt2bCZNmpSampqcfvrpGThwYEaPHp199tknCxYsyJgxYzJp0qS69hUVFfnqV7+a//zP/0xVVVVef/31vP7660mStWvX5vXXX9/ohnEAAAAAAC1t74bdzaVJlbXisQE2p00GZP3798/999+f448/Pp06dcqiRYvSq1evXHPNNZkyZUrdrLL6ArKkNmC74447cvTRR2f58uWZO3duysrKcumll+bee+9Nly5v3aBxyZIlWbFiRc4+++z07Nmz7ldSO4OtZ8+eef7555v/pJtQ/6FH5Lyf1eSA47+42Tbn/awmE754ewtWBQAAAAA01uCdk749Wv64/XZI9tqp5Y8L8E7a7N2f9t1339x++6YBzsqVK7No0aKUlJRkv/3222z/Y489Nscee+w7Hmfw4MG5++67N9k+fvz4nHbaaTn99NOzyy6+IgEAAAAAtJ5CITl0SPLbR1v2uIeW1R4bYFvTZgOyzZkzZ05qampSVla20UywxurWrVuOOOKIevcNHDhws/sAAAAAAFrS2MHJfU8nr65smeP16ZYctFfLHAugoYouIHviiSeSbH55RQAAAACAtqhj++SjY5Pv39n8xyok+djBSWkb/AS6cv3aXPrzj+a5l55Mxw6ds2O3vjn3pB9mtz6DU1NTk1/dc2X+POP6pFBIdfWGHPeuT+cjR0xMSck/v+PRvCWP5oY/fSVLKuale5de6dCuYz5yxAU5dL8PJEn+POPG/Oa+b2ZDdVU2bFifw0Z8OJ885r/SoX1pkuT+J27NzXddmg3VG7K+am1699g1l591Zy6+4YS8uvzFJMkzSx/PwF32S0mhXbp06p5vffb+Zn2s3nT9n76Sh5+8LSWFdkmSjx755Ywf9dHNti9/bVH+9Vuj8rtLXm+R+pJkySvzc+Xk07J8VUW6dtohF5xyYwbuMqzFjk/La4P/Pf1zLRWQ1dTUNOv4AAAAAAANNWTn5LC9a2eSbak31mz8+5Y4fJ9kUN+G1bY9ed+Ys3LQPu9NoVDI7x78Xv7n15/JN//tnlx/x1fyxDP35VufeyA7dO2T5asq8rUbP5AVa5blzOMv3+x4i8rn5MJrj80XT7khBw89MUlSsfzFzJr/lyTJlOk/yi33fyuXnvHH9Ou1Z9ZWrs7lN/9LvvnrM/Llj/00r76xNN/+zVn5wecfzc49ByRJ5i+ZlUKhkG+c8ce64xx9QSHf+uz96dZ5x+Z7cOrxkSMuyKffe+n/ndcLOePKfbP/kKOyQ9c+LVpHfTZsqEq7du3znVvOzvvGnJVj33V67vvbb3Ll5NPz/fNmtHZ5NCMBGQAAAABAEZmwf/L66uRvi7es/f/c0bDxR+6RvH90w+vaXpR26JQx+76v7u/77jE2v7n3qqxZtzK33Pc/+eHnZ9UFPzt07ZMvfOhH+bdvjc6p77k4XTp1r3fMX949Kce969N14ViS9Nlh1xxz4GlJkp/d+f/y+ZN/lH699kySdCrtki986Ef5+KW758Wjv57V61akpKRdunfuVdd/SP/9G32ODz/5h9zwp6+kUChJdXVVPnXcpTlkvwl57Y3yfP/35+alZYuybv2aHDJsQj513H8nSeYseihX3/rZVFdXpWz3d2XBC7Pz2QnfzshBR2wUyK1ZtzI1qUl1TfUW13PZL07N4leeTlVVZXbacfec/+Hr0qvHLvnub89J7x675uPvuShJsvjlp/OlHx2Vn174bGpSkxv//NU8tmBa1ldVpv9OZfn8ydeke5eeueKXp6ekpCQvVizI6ytfzjc/e1/mLZmZSWdOTZK8e/jJ+d5vz8kLFQuyW5/BjX4c2bYVXUA2bdq01i4BAAAAAKDVtCtJPnlo8vOHk9nPNe3YBwxMPn5w8g6rCbYpv33gOzl42IQ899KT6dC+YwbsPHSj/QN2HpoOHTrluZefzL57jKl3jPlLHs244y6td9+ylS+nYvkLGTrg4I229+jaO7v1GZL5L8zKu4efnP0GjssnvjEgI/Y6PEMHHpIjR388fXbYrVHndOMdF+fzJ1+ToQMPTnV1dVaveyNJcsXk0/KxIy/KyEGHZ8OGqlx8/Qm59/Ff55BhE3Lpz07JFz9yQ/YvOyozn56aqTNvfNvjdHVue+j7qXh9Sb7w4R+nZ7ctn2L4b+//dnbstlOS5JfTJuUnf/l6Pn/y/+YDh/57LvzxsTll/JfSrqRdbnv4B3nfmLPSrl37/OKub6RTh6753rmPJEl+9pdLcsMdF+fck76fpPYx/9ZnH0iXTt0zb8mj6dWjX9q1q41MCoVC+vbcIy+//ryArA0ruoAMAAAAAKDYtW+X/MuhyV47JX+YnVRu2LrxStvXzho7ZEhSUmiaGrcHv7jrG3mxYkGuOPuuLCr/ewrZ/Ml3bN+52eooKSnJ1067Jc+/PDd/W3hvZjz9p/zirkvz/fNmNirgGT34PfnBbefl3cM/lAPKjsng3UZlTeWqzF5wV5ateKmu3drKlVnyytNZ/PLctCtpn/3LjkqSHLj3MenXa6+NxvzguHPzwXHnZuGLj2fSzZ/IgWXHpEfX3ltUz7TZv8ids36a9evXprJqbXr83wy93fvunT12HpqH5vw+B+59bO6ZfXN+dH7tKnIPzfldVq1dnvufuCVJUrWhMjv3Glg35mEjPrzZGX0UBwEZAAAAAEARKikk79472XfX5JaZyVMvNm6cobsmJ78r6d2taevb1v36nqvywN9vzRVn3ZlOpV0yYOehqaxam+deenKjWWTPvfRk2pd0SP++e292rCH9D8hTzz2cccM/uMm+nt36ps8Ou+XJ5x7eaGnHN1a9mhcq5mfIbm8tpbhH332yR999csLBZ+fCa4/Lw3Nuy4cO/48Gn9u/vv9/sqh8Th5beHeunHxajhx9at5/yGeTJN/99+kp7dBpo/bPvPi3TcYoFOoPCwftOjJ9euyWxxfek3ePOPkda/n7sw/kdw9cne/8+8Pp2a1vHppzW27683/W7f/guPPyq7svz/KVr2T/sqPTs/vOSZKampp8bsJ3c+Dex9Q7bueObz1hd9px97z2xtK6+5HV1NTk5WXPp++Oe7xjfWy/imiiKwAAAAAAb9ene3L2+OTCE5PD90m6lL5zn64da9tedGJy1vjiC8d+c+//5O7Hbs7lZ/6l7v5anTt2ywfHnZdv33J2lq+qSFIbYn37lrNzxvsmpbR9x82Od8oRE3PHjOvz16em1G177Y3yTJ15U5Lk40d+Jdfcfn6WvvZskmRt5ep86zdn5dD9Pphd+wxKxfIX8vdnH6zru2L1spQveza79h7UqPN7/uW5GbjLsHzg0HNywsH/lqeen57OHbtl1KDx+eXdk+raVSx/Ma+8viS7990nG6qr8tiCu5Mks+bdmRdfXVjX7rmXnqz784sVC7PgxdnZ421LUW7OijXL0rlj9/To0jvrqyozZfo1G+0/sOyYvLaiPL+4678z4ZBz6rYfst8Hcuv938raytVJah+zReVz6j1Gz259M3i3/XPnrJ8lSe5/4pb02bG/5RXbODPIAAAAAADIzj2SDx6QfGD/5NWVyeLXkvLlybr1SaFQu4xivx2S/r1qA7HNTBBq8155fUmuuf389Ou1V774v+OTJKXtO+a75/41Z7z3svzqnivy+e8fmiQpf+3ZfG7Cd/O+MZ/5p2Pu2W94vvGZP+X6P30l3/vdv6dTadd06dg9p4z/cpLkxEP+Le3adch/Xn9iNtRsSFVVZd49/OScdtwlSZIN1VX52Z3/L+WvPZuOHbqkuroqRx9wWg7Zb0KjzvH6P12UJa88nfbtStOxQ5ecd9IPkyRf/vjPc81t/5Ezr9ovKRTSqbRrPn/yNdlpx/75yicm5+pbP5vqmg3Ze/d3Za9+I+vGu3bKxJS/9mzalXRIu3btc84HvpcBO++7RbW8a+/jctesn+XTV+ydHl16Z/SQo1Kx/IW6/YVCIccddEbunv2LDB341n3aPnrEl/LTqnX59++OqVv68pTxX8rAXYbVe5zPn3xNrpx8em6e9o106dQjF3zkhgY/bmxfCjU1NTWtXQRNY11V8qXJrV1Fw1x+StJRTAsAAAAAbEM2VCZ3X73149x6/7fz2weuzpVnT8su/3D/q2Lw2e8cmLNPuCojBx3R7Me6+PoTcvjIU3L0Af/S7Md60/hzk3ZbMNuSprdq1ap061Y7bXXlypXp2rVro8axxCIAAAAAADSDk979+fz0wmeKLhxrKU8vnpnTJg1OoVCSI0d/vLXLYTtj7g4AAAAAADSzBS88lisnn77J9mMOPC0nH/aFNlfPD86b+Y5tvnrD+/Pysuc32ta9S89c9a93b9Ex9t79wNz05QWNqg8ssdiGWGIRAAAAAGDrNdUSi7RdllhsPZZYBAAAAAAAgEYwg6wNqalJKje0dhUNU9ouKRRauwoAAAAAgLfU1CTV61u7CrZlJR18tt1ammoGmcXt2pBCwXKFAAAAAABbq1CwfB60dZZYBAAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgq7Vu7AJpOTU1SuaG1q2iY0nZJodDaVQAAAAAAAMVEQNaGVG5IvjS5tatomMtPSTp6FgIAAAAAAC3IEosAAAAAAAAUFQEZAAAAAAAARUVABgAAAAAAQFERkAEAAAAAAFBUBGQAAAAAAAAUFQEZAAAAAAAARUVABgAAAAAAQFERkAEAAAAAAFBUBGQAAAAAAAAUFQEZAAAAAAAARUVAthlTp07Ncccdl969e6dLly4ZPnx4LrvsslRWVrZ2aQAAAAAAAGwFAVk9vvnNb+bYY4/Nn//853Tv3j1777135s6dm4suuijjx4/PmjVrWrtEAAAAAAAAGklA9jaPPPJILrjgghQKhdx4441ZtGhRZs+enblz52bw4MF56KGHcuGFF7Z2mQAAAAAAADSSgOxtLrnkktTU1ORTn/pUTjvttLrtgwYNynXXXZck+eEPf5iXX365tUpsdkuevCff+UQhj065arNtvvOJQn5/1QktWBUAAAAAAEDTaPMBWUVFRSZOnJjBgwenU6dO2X333XPeeedl1apVOeOMM1IoFPK9730vSbJixYpMnTo1SXLmmWduMtZhhx2WsrKyVFZW5rbbbmvR8wAAAAAAAKBptOmA7LHHHsvw4cNz5ZVXpry8PEOHDs369etz9dVX55RTTslTTz2VJBk1alSSZPbs2amsrEzHjh1z4IEH1jvmuHHjkiTTp09vkXMAAAAAAACgabXZgKyioiInnnhiysvLc/7552fp0qWZNWtWysvLc/nll2fKlCmZMWNGCoVCRowYkSSZN29ekmTAgAFp3759veMOGjRoo7YAAAAAAABsX9psQHbuuedmyZIlOeecc3LVVVele/fudfsmTpyYkSNHpqqqKgMHDkyPHj2SJMuWLUuS9OzZc7PjvrnvzbZtWVXl6qxZUVHvLwAAAAAAgO1V/dOktnNPPfVUJk+enD59+uSyyy6rt80BBxyQxx9/PCNHjqzbtnbt2iRJaWnpZsfu2LFjkmTNmjV12+65556MHz9+k7YjR47MY4891phT2CZMv+VrmX7L11q7DAAAAAAAgCbVJgOym2++OdXV1Tn11FPTrVu3ett07tw5STYKyDp16pQkqays3OzY69at26j/P/r+97+f/fffv+7vXbt2bXjx25D9xp+VIWM+XO++3046uoWrAQAAAAAAaBptMiCbNm1aktQ7q+tNS5YsSbJxQLYlyyf+s2UYhw4dmrFjxza84M048MADU15evsXt23XonA/+9/wmO/6OuwzJHvsd1WTj1adsyJBsWL/mnRsCAAAAAABFr7q6uu7P48aNy+zZsxs1TpsMyJ577rkkyYABA+rdX1VVlQcffDDJxgFZWVlZXf+qqqq0b7/pw7Nw4cKN2jan8vLyvPDCC1vcvn3HLs1YTfN4cemLqVq3urXLAAAAAAAAtjMvvfRSo/u2yYBs1apVSTa+T9g/mjx5cioqKtK9e/fsueeeddtHjx6d0tLSrFu3LjNnzqx3NtgDDzyQJBkzZswm+0455ZRUVFSkd+/eef/7359JkyalT58+jT6PXXbZpUHt23XYdNnHbd2u/XY1gwwAAAAAANgi1dXVWbp0aZJk5513bvQ4bTIg22WXXbJs2bLMmjUrBx988Eb7li5dmgsuuCBJMmLEiBQKhbp93bt3z9FHH50pU6bk2muv3SQgu++++zJv3ryUlpZmwoQJddt32GGHXHDBBTnssMPSrVu3PPzww7nssssyffr0zJw5s+7eZg01c+bMBrVfV5V8aXKjDtVq5s2fn45t8lkIAAAAAAA0tVWrVqVbt25J3prU1BglTVXQtuSoo2rvm3X55Zdn3rx5ddtnzJiR8ePHp6KiIkkyatSoTfpefPHFKRQKueGGG3LTTTfVbV+4cGHOOOOMJMnZZ5+dvn371u0bPXp0rrjiipxwwgk54ogjcuGFF+bnP/955syZk5tvvrk5ThEAAAAAAIBGapMB2cSJE9O7d+8sXrw4w4YNy/DhwzNkyJAcdNBB2WuvvXLkkUcm2fj+Y28aO3ZsJk2alJqampx++ukZOHBgRo8enX322ScLFizImDFjMmnSpHes4YQTTkjXrl0bPAsMAAAAAACA5tUmA7L+/fvn/vvvz/HHH59OnTpl0aJF6dWrV6655ppMmTKlblZZfQFZUhuw3XHHHTn66KOzfPnyzJ07N2VlZbn00ktz7733pkuXLltcyz8u4bi96D/0iJz3s5occPwXN9vmvJ/VZMIXb2/BqgAAAAAAAJpGm73707777pvbb980wFm5cmUWLVqUkpKS7Lfffpvtf+yxx+bYY49t9PFvu+22rFq1KgcddFCjxwAAAAAAAKDptdmAbHPmzJmTmpqalJWVNWgm2D/ziU98InvttVf233//dOvWLQ8//HCuuOKKjBo1Kh/96Eeb5BgAAAAAAAA0jaILyJ544okkm19esTGGDRuWX/ziF/n2t7+dNWvWpH///jnzzDPzta99LaWlpU12HAAAAAAAALaegKwJXHjhhbnwwgubbDwAAAAAAACaT0lrF9DSmiMgAwAAAAAAYPtRdDPIpk2b1tolAAAAAAAA0IqKbgYZAAAAAAAAxU1ABgAAAAAAQFERkAEAAAAAAFBUBGQAAAAAAAAUFQEZAAAAAAAARUVABgAAAAAAQFERkAEAAAAAAFBUBGQAAAAAAAAUFQEZAAAAAAAARUVABgAAAAAAQFEp1NTU1LR2ETSNmpqkckNrV9Ewpe2SQqG1qwAAAAAAALYHq1atSrdu3ZIkK1euTNeuXRs1TvumLIrWVSgkHf2LAgAAAAAA/FOWWAQAAAAAAKCoCMgAAAAAAAAoKgIyAAAAAAAAioqADAAAAAAAgKIiIAMAAAAAAKCoCMgAAAAAAAAoKgIyAAAAAAAAioqADAAAAAAAgKIiIAMAAAAAAKCoCMgAAAAAAAAoKgIyAAAAAAAAioqADAAAAAAAgKIiIAMAAAAAAKCoCMgAAAAAAAAoKgIyAAAAAAAAioqADAAAAAAAgKIiIAMAAAAAAKCotG/tAmg6NTVJ5YbWrqJhStslhUJrVwEAAAAAABQTAVkbUrkh+dLk1q6iYS4/JenoWQgAAAAAALQgSywCAAAAAABQVARkAAAAAAAAFBUBGQAAAAAAAEVFQAYAAAAAAEBREZABAAAAAABQVARkAAAAAAAAFBUBGQAAAAAAAEVFQAYAAAAAAEBREZABAAAAAABQVARkAAAAAAAAFBUBGQAAAAAAAEVFQLYZU6dOzXHHHZfevXunS5cuGT58eC677LJUVla2dmkAAAAAAABsBQFZPb75zW/m2GOPzZ///Od07949e++9d+bOnZuLLroo48ePz5o1a1q7RAAAAAAAABpJQPY2jzzySC644IIUCoXceOONWbRoUWbPnp25c+dm8ODBeeihh3LhhRe2dpkAAAAAAAA0koDsbS655JLU1NTkU5/6VE477bS67YMGDcp1112XJPnhD3+Yl19+ubVKbHZLnrwn3/lEIY9OuWqzbb7ziUJ+f9UJLVgVAAAAAABA02jzAVlFRUUmTpyYwYMHp1OnTtl9991z3nnnZdWqVTnjjDNSKBTyve99L0myYsWKTJ06NUly5plnbjLWYYcdlrKyslRWVua2225r0fMAAAAAAACgabTpgOyxxx7L8OHDc+WVV6a8vDxDhw7N+vXrc/XVV+eUU07JU089lSQZNWpUkmT27NmprKxMx44dc+CBB9Y75rhx45Ik06dPb5FzAAAAAAAAoGm12YCsoqIiJ554YsrLy3P++edn6dKlmTVrVsrLy3P55ZdnypQpmTFjRgqFQkaMGJEkmTdvXpJkwIABad++fb3jDho0aKO2AAAAAAAAbF/abEB27rnnZsmSJTnnnHNy1VVXpXv37nX7Jk6cmJEjR6aqqioDBw5Mjx49kiTLli1LkvTs2XOz47657822bVlV5eqsWVFR7y8AAAAAAIDtVf3TpLZzTz31VCZPnpw+ffrksssuq7fNAQcckMcffzwjR46s27Z27dokSWlp6WbH7tixY5JkzZo1m+z77W9/myuvvDKPP/542rdvn/322y8/+tGPMmzYsK05nVYz/ZavZfotX2vtMgAAAAAAAJpUmwzIbr755lRXV+fUU09Nt27d6m3TuXPnJNkoIOvUqVOSpLKycrNjr1u3bqP+b7r66qtz/vnn5wtf+EIuueSSrFu3Ln/961/rDdK21IEHHpjy8vItbt+uQ+d88L/nN/p4b7ff+LMyZMyH693320lHN8kxyoYMyYb1jX+MAAAAAACA4lFdXV3353HjxmX27NmNGqdNBmTTpk1LkowfP36zbZYsWZJk44BsS5ZPrG8ZxoULF+aCCy7It771rZxzzjl129/3vvc1ovq3lJeX54UXXtji9u07dtmq473djrsMyR77HdWk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1dpG9xWQJfngBz+YSy65JH/84x/z5JNPZujQof+0/cknn5xJkyblrrvuyrPPPps999xzo/3XXnttkuRDH/rQVtXVmHuQufcYAAAAAABQDBqTo7ypUFNTU9OEtWy3TjnllPzqV7/KHnvskZ/85Cc5/PDD6/a99NJLuf7663Puueema9euSZL3vve9ueOOOzJ27Nj8/ve/T9++fVNdXZ1vfOMb+epXv5rOnTtn3rx5WzWDrKHevPfYq6+/kfe69xgAAAAAAEC9BGT/54033siECRNyzz33JKldHnHXXXfN0qVL88ILL6SmpibLli3LjjvumCQpLy/PoYcemmeeeSadO3fOvvvum6VLl2bp0qVp3759fv7zn+cjH/lIi57Do0/My6//eE+6du6Uif/6sXQs7dCixwcAAAAAANgelLR2AduKHj165M4778x1112XI444IqtXr87jjz+ekpKSHHvssbnuuuvSvXv3uva77LJLZs2alQsuuCC77rpr5syZk6qqqnzgAx/IQw891OLhWJLMX7QkSXLYmBHCMQAAAAAAgM0wg6wNqampyfxnl2RA/10EZAAAAAAAAJshIAMAAAAAAKCoWGIRAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgIyAAAAAAAACgqAjIAAAAAAACKioAMAAAAAACAoiIgAwAAAAAAoKgI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UFQEZAAAAAAAABQVARkAAAAAAABFRUAGAAAAAABAURGQAQAAAAAAUFQEZAAAAAAAABQVARkAAAAAAABFRUAGAAAAAABAURGQAQAAAAAAUFQEZAAAAAAAABQVARkAAAAAAABFRUAGAAAAAABAURGQAQAAAAAAUFQEZAAAAAAAABQVARkAAAAAAABFRUAGAAAAAABAURGQAQAAAAAAUFQEZAAAAAAAABQVARkAAAAAAABFRUAGAAAAAABAURGQAQAAAAAAUFQEZAAAAAAAABQVARkAAAAAAABFRUAGAAAAAABAURGQAQAAAAAAUFQEZAAAAAAAABQVARkAAAAAAABFRUAGAAAAAABAURGQAQAAAAAAUFQEZAAAAAAAABQVARkAAAAAAABFRUAGAAAAAABAURGQAQAAAAAAUFQEZAAAAAAAABQVARkAAAAAAABFRUAGAAAAAABAURGQAQAAAAAAUFQEZJsxderUHHfccendu3e6dOmS4cOH57LLLktlZWVrlwYAAAAAAMBWEJDV45vf/GaOPfbY/PnPf0737t2z9957Z+7cubnooosyfvz4rFmzprVLBAAAAAAAoJEEZG/zyCOP5IILLkihUMiNN96YRYsWZfbs2Zk7d24GDx6chx56KBdeeGFrlwkAAAAAAEAjtW/tArY1l1xySWpqavLpT386p512Wt32QYMG5brrrsvhhx+eH/7wh7nooovSt2/fVqwUoPmtXpf8bXHyxpqkUEh6d0uG7550aNfalUHLqKyq/RlYtiqpSbJD52TE7knn0tauDACgZTz/arLw5WTd+qRTh2TILsluPVu7KqClrF1fe030+uqkkGTHLrXXRB07tHZlAFuvzQdkFRUVueKKK3LrrbdmyZIl2WmnnXLSSSflG9/4Rs4999xcf/31+e53v5tzzjknK1asyNSpU5MkZ5555iZjHXbYYSkrK8u8efNy22235TOf+UxLnw5Ai3h1ZTL178mji5KqDRvv69oxGTMoOXqYkIC2a9W62p+BR55J1rzt9qO3zEwOHJgcM7z24hAAoC2atSi5+6lk8Wub7tuzT3Lk0NovzwFt0xtraq+JZjyTrKvaeN8tM5N37ZUcs1/SvVPr1AfQFNp0QPbYY4/lve99b8rLy9O1a9cMHTo0L774Yq6++uosXLgwr71W+y5v1KhRSZLZs2ensrIyHTt2zIEH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G/VPameTDR8+PFdffXWmTp2ayy+/PHPmzMnBBx+cJUuWbPX50Lo+9p6vpKRQkpumvvWN0ccW3J0fT/lSvvovv84uvQa2XnGwhVauTaqqW+/4r7fCvc8A2Fhr/1/c2seHreGaALZ/y9fULv/eWrwOAsC2p/4bbW3npk2bliQZP378Ztu8GVz9Y0C2Jcsn1rcM4/vf//68//3v36jdu971ruy999655ZZbct555zXwDN4yZMiQlJS0fI5Z2r5zfnTO/BY/bmsYOeiI/OXKzb9NHrDzvvnzFW/dsKP8tUX57599JGeecGVGDjqiBSrcNg0pG5LKqjXv3LCNeN9FM9Jlh35ZWr40/fu/q7XLabAuPXfP+7788Gb3/8dxSY/Om92dHp3e+v3rH9x8uzfWJP9zx6bbX33t9fTvv98WVrvt2d7//dl6ngO0Bcecf0969B1c776meh1INv9a8L7jT8xri2dvWbG0uGJ6/18f1wRbr61fHxT7e4G2cP477LJvjv7CX+rd906vg8nWXxMten5J+vcfu4XVbnvawnOAreM5QLHzM7Btqa5+aybAuHHjMnt2464122RA9txzzyVJBgwYUO/+qqqqPPjgg0k2DsjKysrq+ldVVaV9+00fnoULF27UdnN69+6dJPWO0RBLly7dqv6N1amD5UHqs7Zydb524wdy8ND35wOHntPa5bSqpS++mLXri+crcBs2bKj7/YUXXmjlahqu6+p//l3JHp2THbfgx76kZMvavV3V+nXb5eP2pu3935+t5zlAW1C5dvOv2839OpAk5UuX5BU/P9ss7/+3nGuC+rX164Nify/QFs5/dXX9KwwlW/46mDT+tXD9ujXb7WOXtI3nAFvHc4Bi52dg2/XSSy81um+bDMhWrVqVZOP7hP2jyZMnp6KiIt27d8+ee+5Zt3306NEpLS3NunXrMnPmzIwdu+k3ex544IEkyZgxYzbZt2HDhlRXV+e5557LhRdemF122SUf+chHtupc+vXr12ozyNjU/U/ckmeWPp4XKublnscnb7L/ui8+mb4992iFylpev113bdPfEH27du3a1f2+2267tXI1DVfSvmOqN1SlpF39/+2/8Q7/lD061V4IVlcnb/yTe8hsbpz1q5dtl4/bm7b3f3+2nucAbcGGda9vdl9TvQ78s7F26No+pX5+tlne/2851wT1a+vXB8X+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kAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArhCQAQAAAAAAAAAAwK4QkAEAAAAAAAAAAMCuEJABAAAAAAAAAADArjjZugAAQPFhMknGdFtXgZLGwVkyGGxdBQAAAACTyaTk5GRbl5EnHh4eMnBCAQCwAQIyAICFMV1aP9PWVaCkCR0jObrYugoAAAAAycnJ8vLysnUZeZKYmChPT09blwEAsENMsQgAAAAAAAAAAAC7QkAGAAAAAAAAAAAAu0JABgAAAAAAAAAAALtCQAYAAAAAAAAAAAC7QkAGAAAAAAAAAAAAu0JABgAAAAAAAAAAALtCQAYAAAAAAAAAAAC74mTrAgAAsLV94Rv0wiehWZa5uXgqsHywurZ4SP07Pi1HRz4yAQAAAAAAgNKC0T4AAP4R2uw+tanXSyaZFHclRqv/+lKf/Pqczpw/rGcHf2rr8gAAAAAAAAAUEgIyAAD+EVSlhbq2fNDy974dRmnYtHr6fcfnerTHJJX1Km/D6gAAAAAAAAAUFp5BloNVq1apR48eKleunDw8PNS4cWNNnjxZaWlpti4NAGAl7i6eqle9nUwmk6Iuhtu6HAAAAAAocerXr6+yZcvaugwAAG7AHWTZePfdd/XCCy9IkqpXr65q1arp77//1sSJE7Vs2TKtWbNG7u7uNq4SAGAN0f8EYz4efjauBAAAAACso1mzZgoJCVHLli3VvHlzlS1bVk5OTkpJSdHx48f1119/adeuXVqzZo0SExNzbKdx48Zat26dTp48qTvvvFOXL1+23osAAOAWCMj+Y8eOHRo3bpwMBoPmz5+voUOHSpLCw8PVo0cPbd26VRMmTNCMGTNsWygAoNClpicrPilWJpP5GWS/bvtExyP3qF7VNgosH2zr8gAAAACgyLi7u+u+++7TqFGj1LJlyxy3q1Onjnr06CFJSkhI0JdffqnZs2fr0KFDWba7Fo75+/vL399fkydP1pNPPlmkrwEAgLwwmEwmk62LKE769u2rZcuW6bHHHtPcuXOzrNu0aZNuv/12ubi46OzZswoICLBRlQCs5XyCdPycdDVDcnGSagdIFcvYuqqik5kmrZ9p6yqsb1/4Br3wSWi260IaDdTTAz6Sn09FK1dVcoSOkRxdbF0FAAAAgKSkJHl5eeV5vzvuuENz585V9erVb1iXnp6u2NhYZWZmytvbW2XKZH9SPHPmTE2YMEHJyclZwjFJ2rZtm3r06KGEhIQb9ktMTJSnp2eeawYAoKBK/TPIYmNjNX78eNWpU0dubm6qWrWqnnnmGSUlJWnYsGEyGAyaNWuWJOnKlStatWqVJGn48OE3tNWpUycFBwcrLS1NS5cuterrAGBdR6Ol2Wult3+Vvt8h/bJb+mGHNGWZNGuNdDDC1hWiKPRuO0JTh6/WpGG/6fFeU+Xt4afY+Ai5OLtZtknLuKrHpzfUN2snZdl32nePaOLnPa1dMgAAAADkm6urq2bPnq01a9ZkCcd27dql0aNHq3Xr1vL29lblypVVtWpVlS1bVtWqVdOAAQP02WefKSkpybLPmDFjtH//fj3wwAO5DscAALClUh2Q7d27V40bN9Y777yjmJgYNWjQQOnp6Zo5c6aGDBmiw4cPSzLPqyxJe/bsUVpamlxdXdWqVats2wwJCZEkbd++3SqvAYD1bTgszV4nHY3Jfv3xc9JnG6VVB6xbF4peFf8gtQjuqjb1empI6Hi99eivOhqxUx8sfsKyjYuTq8bf+6W+W/u2wqP2SZL++HuJth/+Vc/dPTenpgEAAACgWPH09NRvv/2mJ57493xn3bp1at26tVq3bq2PPvpIu3bt0tWrV7Psd/bsWS1ZskQjRoxQlSpV9NJLLyk5OVmSVLt2bX311VeEYwCAEqHUBmSxsbHq27evYmJi9Pzzzys6Olq7d+9WTEyMpk6dquXLl2vnzp0yGAxq0qSJJCksLEySVL16dTk5Zf94ttq1a2fZFkDpsuOEtGR37rb9bb+0hbeCUq1hjQ7q2uIhbdi3SAdPbbUsDw5sqcG3v6Bp3z2sC5cjNOPHEXp6wEfyL1PZhtUCAAAAQO64urrql19+UZcuXSSZp2Z88skn1bVrV+3atSvX7cTHx2vq1Klq2rSpdu82n0wbDAZJ0qFDhwjHAADFWqkNyMaMGaOIiAiNHj1a06dPl7e3t2Xd+PHj1bRpU2VkZKhGjRry8fGRJMXFxUmSfH19c2z32rpr2wIoPTIypWV78rbP8n1SWkbR1IPi4YGur8rBwVFfrHztP8tfkaODk56c0VxN64QqtNm9NqoQAAAAAPJmypQpuuOOOySZx7hCQ0P1ySefyGQy5as9d3d3VatWLcuySpUqycPDo8C1AgBQVEplQHb48GEtWrRI/v7+mjx5crbbtGzZUpLUtGlTy7LU1FRJkouLS45tu7q6SpJSUlKyLD958qTuuusueXt7y9fXVw8//LAuXrxYoNcBwLoOREgJqXnbJyVN2n26aOpB8VDFv45Cm96rPcfX6sCJzZblTo7OalCjg+KTYtW91aM2rBAAAAAAci8kJERjxoyRZB7f6tGjh3bu3Jnv9ho3bpzlmWOXLl2SZL7I/JNPPil4wQAAFJFSGZAtXLhQRqNRDzzwgLy8vLLdxt3dXVLWgMzNzU2SlJaWlmPb1+Zdvra/JF25ckWhoaGKiIjQwoUL9emnn2rz5s3q06ePjEZjnus3mUxKSkpSUlJSvq/cAZB3u09Zdz+UHPfd8bIcDA76YtW/d5EdOLFZq3YtUL+Oo/Xx0md0NT3lJi0AAAAAgO05OTlp3rx5cnAwDwm+/PLL2rFjR77b+284tm3bNrVs2VLnzp2TJPXr10933313wQsHAOA6hZWhZP+grRJu3bp1kqTQ0NAct4mIiJCUNSDLzfSJ2U3D+OmnnyoyMlKbNm2y3E4eGBioDh06aOnSperfv3+e6k9OTrYEe5UqVbIctAAoWqGjlqhc9VZ53m/HnsN6e2i3IqjI+lyc3PXp6GO2LsPqmtburNXv5PxhWr1Cfa2clmn5e8rVRL2z6BEN6zlFfds/qec/uV3zfp+oJ+963xrlFjtBwUFKyyAgBAAAAGztVhdq9+vXT0FBQZKkrVu36oMPPsh3X9mFY9eeOfbEE0/o559/liS98MIL+uGHH3JsJygoiLEvAECeGI1GRUdHS5KaNWumPXvy+Nycf5TKgOz0afN8Z9WrV892fUZGhv744w9JWQOy4OBgy/4ZGRlycrrxxxMeHp5lW0latmyZQkJCssy13L59e9WqVUu//vprngOy6137RwZQ9FJTkvO139XUZEVGRhZyNbbh5sz88Lkx59fnVdGvpu7qMEoGg0Hj7lmgJ2Y0U8dGA9SkVidbl2d10VFRSk3P3+8PAAAAAOsZNWqU5c+vvfZavmY+km4ejknSkiVLtHv3brVo0UJt2rRRq1attGvXrmzbYuwLAFAQ1+5azo9SGZAlJSVJuvE5YdcsWrRIsbGx8vb2Vs2aNS3LmzdvLhcXF129elW7du1Su3btbth3y5YtkqS2bdtalh06dCjb28UbNmyoQ4cOFei1cAcZYD1pV6Lyt19CpKpUqVLI1diGi5P7rTeyczuO/K4N+xbp0+f2y2AwSJIq+9fWsJ5TNH3Ro5rz/H65u3jauErrqlS5MneQAQAAAMXA9VfU/1eNGjXUpUsXSdLRo0ctMzDl1a3CsWs+/vhjff7555KkRx99NMeAjLEvAEBeXf95V6FChXy3UyoDsooVKyouLk67d+9W+/bts6yLjo7WuHHjJElNmjSxDG5Kkre3t7p166bly5frs88+uyEg27Rpk8LCwuTi4qJ+/fpZlsfFxals2bI31OHn56ejR48W6LUcO3ZMnp72NdAK2MqpWGnGyrzv9/azd6nutLsKvyAbyEyT1s+0dRXFW5t6PbXkrcs3LO/X8Sn16/iU9QsqBo6FHZOji62rAAAAAJCUlGR5bMd/XT/O9e233+brmS25Dcck6bvvvtOcOXPk6Oh4w/jc9Rj7AgDk1fWfd9duasqPUnl5RteuXSVJU6dOVVhYmGX5zp07FRoaqtjYWEnmuSn/65VXXpHBYND8+fP1xRdfWJaHh4dr2LBhkqSRI0cqICCgCF8BAFuoXk4K9L31dtcr7y0FVSyaegAAAAAAKCwtW7a0/HnHjh153j8v4ZhkHry8NrNSo0aN5Orqmo+qAQAoOqUyIBs/frzKlSuns2fPqmHDhmrcuLGCgoLUpk0b1apVy3I7+fXPH7umXbt2mjJlikwmkx555BHVqFFDzZs3V7169XT8+HG1bdtWU6ZMybKPr6+vLl++fENbly5dkp+fX5G8RgCFz2CQ7m8vueby3lpnR+nBDpKD4dbbAgDw/+zdd3gUVdvH8d9ueqUkBAIBQkmooXcRCIKAithRwRcUEAtiBQX1UR+lgwUrFoqPiqhYEKQJiCAgIEWkhQQCBBIgENJI333/WFiNSSAJyW6y+/1cV65kZ86cc8+2zMw95xwAAAB7+ud1sB07dpRo25Imx/7djpubm5o1a1bCiAEAKF8OmSALCQnRhg0bdOONN8rT01OxsbGqXr265syZo2XLlll7lRWWIJMsCbYVK1aob9++Sk5O1oEDBxQeHq5JkyZp/fr18vb2zle+WbNmhc41tm/fPv75A5VM7WrSI9dJvle4sc3LXXqot1Q/0DZxAQAAAABwNfz9/SVZ5m05ffp0sbcrbXJMkhISEgq0DwBARWEwl2bA4UosLS1N/v7+MhgMSk1NLZDsKo2ZM2dq4sSJOnz4sEJCQiRJv//+u7p06aJvv/1Wt956a4nq++f4mWlpaYzDDNjBhSxp62Fp4yEpMfXv5QaDdFNrqXMjydfTfvGVF+YgQ2lEjhVzkAEAAAAVwOXmIAsMDJSvr688PT114MCBYtc5ZMgQffrppzIajSVKjklSUFCQ/P39lZmZqdOnTys7O7tAGa59AQBKqqxyKE6XILuUuGrSpEmJDgYuJyUlRREREQoMDNQrr7yizMxMjR8/XjVq1NDmzZtlNJasox4JMqDiMJml5AvSrOVSWpbk7yn993Z7R1V+SJChNEiQAQAAABXD5RJkV2P48OEaOXKkbrjhhmInx4qLa18AgJIqqxyKQw6xeDl79uyRVPTwiqXh7++vtWvXKjg4WHfffbdGjhypbt26aenSpSVOjgGoWIwGqZqP5HLxo2xw8vnG3v1+rIZODlXfcQZFn9hlXZ6Tm62Plj2rYVMb64EZzTRqZkst3/rJFev7dNXL6jvOoI17vrMuM5vNum9yA93yYlXrsqGTQ63tPf/JjVq0brp1XfSJnbr71TpKSrMMEdJ3nEGjZkVo9OttrD8p6Wf/ta61RsxorhXb5l3Fs1E6cWcO6fF3umn4tHA9+lZHxSbsvWz5ldvm66X5t9gmuIu27FuqB6Y31bBpYXp5wW1KzyzbE2AAAAAAlcv8+fPVo0ePMk+OAQBgT672DsDWyiNBJkmNGjXS0qVLy7ROAKhorm11h+7qNV5Pvtc93/IZi4YrJzdLHzy1W17uPko4F6uJnwxQbm62BnZ7+LJ1hoW018ptc9U9wjIc7c5Da+TvE6jUjKRCyz9158d65K326tzsRtUObKxpX/6fHhn0lqr5BlnLvPHIBvl6VS10+0vrYk7u1pjZHdWxSX8F+AeX4Fm4Om8tHq0bOj+ofh2H69c/v9GMRcP17uPbbNb+5eTl5So7N1Ozvh6hWQ+vV72gpnr7uzH6/OdX9eBNM+wdHgAAAAA7MplM9g4BAIAy5XTdm8orQQYAzqBVwx6qUTUk37K4M4e0ae/3evKOD+XlbunOXKt6qEbfNEufrXn1inW2DO2uk2djdC7FMnnzim1z1b/jA0WWD/AP1uibZmr6l/+nuT9NUGitlurR6o4S70uj2q3l61VNiclxly33+c+v6YEZzay90U4lHZUkHTy+TeM+6K1H3uqgh95oq/W7v7Zus3TzHA2bFqaH3mirz1a/qr7jLF0Pk9JOKypuu/q0GypJujbidp05f1wnEqOLFfO5lAQ980GkHnmzvUbObKG3vxtjPUkdNStCe2M3Wcsu2/KhXvtssHW7V/93l8bM7qRRsyI0b8UL1nJDJ4fqo2XPaszsTpq+aJi2HliuxrXbql5QU0nSzd0e0bpdC4sVHwAAAAAAAFBZOF0PsrVr19o7BABwKDEnd6pOYJj8fQLyLW9ev6vOpcQrKfWUqvnVvGwd17UbqlV/LNBNXUbrYNw23d//NX2yfEKR5Xu3vVerti/Q6j8+1bzxBwusf/K9a2U0uEiS/LyraeZD6wqU2R2zXlV8AtUwuOgbJlIvJOnr9TO16D/x8nDzUmb2BRkNRqVlnNcb3zyoSSN+UoB/sJLTE/Xwm+3UIrSbUjOS9Omql/T+kzsV4B+sT5ZPtNZ35vxxVfcPlouL5d+vwWBQULV6On3+mOoENr7scyRJvl5V9er9P8rLw1d5pjy9NH+Q1v/5lSLb3K1bu4/VD7+9oxah3SRJSza9qzG3vCNJmr5omO7pPVGtG/VUXl6uXph7k9bv/lo9W98pSUq5cFZvP/a7DAaDvl4/SzWr1be2WbNaqM6lxCsvL9caNwAAAAAAAFDZcaULAFCu3N28rljm+g7D9OyHfeXl7quere6SwXD5Ds6JySd1JGGPXIyuij93pEBy7nJDLD753rXKzslQwrkjevG+b+Tm6l5kO96e/qoTGKapXwxV+/Dr1bnZjapRNUQ7o9cq/txhTfx4QL7yx88cVGzCX+rYdIB12MaBXR/Wl2unXPE5KA6T2aSPlj2rvbEbZTabdT7ttEJrtVRkm7t1XbuhWrDyP0pKPaUTiYckGRTR8FplZKdrZ/QaJaWestaTmZ2muDN/Jxb7dRgug7NPsAcAAAAAAACnQoIMAHBVGtVuqxOJh5SSfjZfomrf0c0KrdlCPp7+V6wjsEod1axWX5+tfkVvjtl0xfKvfz1Cd/R4WkFV62nmouF674kdl010/dOl5NnKbfM146vhahHarcgebi5GF81+bIv2xW7S7phfNPadLpp470JJZoXWbKG3Cok1NuGvfI8N+jvxVKNq3Xy9scxms04nHVNQ1XrFin3xr6/rfPppvf3Y73J389QHS55Sdk6mJMnDzUvXdxiupVvm6Njp/Rp0zaOWjcxmSdLbj22Ru5tnofV6uvta/w6qWk87olZbH59Kis3X6w0AAAAAAABwBE43BxkAoGyF1AhTl+YD9cY3Dyoz+4IkKeFcrD7+6Vk9OHBWsesZ1u9VDe//2hWHGly6eY4uZKXq9mufVM/Wd6p+rRb6dPXLJY67X8fhatv4On2xdnKRZS5kpiop9ZQiGl6roX1fVMvQ7oo+uVPN63dTwrkj2hH1s7Vs9IldysnNVpvGvbX94ArrnGpLt3xgLVPNN0iN67TTzzs+kyRt2LNYgVVDijW8oiSlZiSpul8tubt56lxKgn798+t862/u9qh++v1D7Ypeq95th0iSvDx81aZRpL5cN9VaLjH5pM6cL3zutY5N+iv6xA4dO31AkrRk03vq1fruYsUHAAAAAAAAVBbcDg4AKLY3vxmt3w8s07nUBE34uJ+8Pfy04Llojb/7Uy1Y8aIenBUhg9GohHNH9Nr9S9WxSb9i192kbgc1qdvhsmXizx3Rp6te0huPbpTRaLnH47Fb39Xo11ure8tb1aRuR0n55yCTpBeGLlLdoCYF6ht5wzQ9+lZ7De41XoFV6hRYn56ZrP/+7w5lZqfLIIPqBIbp+vbD5ONVRa89sEwfLn1Gc5Y+rdy8HAVVradXhn+vBrVa6r6+L+vJ96+Vl7uvure8LV+dT9w+RzMWDdfCtZPl7emvcXfNK/ZzdFv3x/Xf/92hkTNbKMC/ttqG9cm3vkbVEDWu3VZ1aoTL093buvy5ez/XnCVPadTMlpLBIE93Hz1x+xzVqBpSoA1vTz89eefHenn+Lcoz5Sq0VkuNH7yg2DECAAAAAAAAlYHBbL449hIqjPT0dPn6Woa7SktLk4+Pj50jAvDSt1JyhlTFS3rltiuXr6zysqV1s6+uDpPJpE9+ek5/HFqt6aPXyN+7etkEV0llZKXp5hf8tHpG+f+7zchO1wPTm+j1RzYouHqDcm/vksixkkvxRrgEAAAAUI7+eU2psuDaFwCgpMoqh0IPMgBAmTIajRp103SNsncgTubHzR9o4ZpJGtj1EZsmxwAAAAAAAIDKiAQZAKBc/b7/J81dPrHA8nt6T1CvNoPtEFFBP/3+sX747Z0Cy8fc8rYiGl57VXV7efhesfdYUtppPffh9QWWtw/vqwdvmlGsdgZ2fUgDuz5UqhgBAAAAAAAAZ0OCDABQrjo3u0Gdm91g7zAu64bOI3VD55F2a7+ab5DmPLXLbu0DAAAAAAAAzsZo7wAAAAAAAAAAAAAAWyJBBgAAAAAAAAAAAKfCEIsAACujmxQ51t5RoLIxutk7AgAAAACS5O3trbS0tDKrb8acL5WSfkH+Pt4aN/ruAo/Lgre3d5nUAwBASZEgAwBYGQySi7u9owAAAAAAlIbBYJCPj0+Z1efu4Sn3nDy5e3jKx8enwGMAACozhlgEAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAU3G1dwAAAAAAAAAAAPszmyVTjr2jQGVjdJMMBntHAZQcCTIAAAAAAAAAgEw50rrZ9o4ClU3kWMnF3d5RACXHEIsAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnIqrvQMAAAAAAAAAAMBedsf8omc+iMy3zNPdRyE1wtWn3X265ZrH5OLCpXTA0fCpBgAAAAAAAAA4vcg296hT0xtklllJqQla/cen+uDHp3Ts9H49eceH9g4PQBkjQQYAAAAAAAAAcHphddqpT/uh1scDuz2iEdObavnWj3V//0mq6lvDjtEBKGvMQQYAAAAAAAAAwL94ufuoaf0uMpvNOnk2xt7hAChjJMiKsGrVKvXv318BAQHy9vZWRESEpkyZouzsbHuHBgAAAAAAAACwgfiLiTF/7+p2jgRAWSNBVohZs2apX79+Wrlypfz8/NSkSRMdOHBAEydOVGRkpDIyMuwdIgAAAAAAAACgDGXmXFByeqLOp53Rkfg9mv3to4o+sVNN63ZSSI1we4cHoIwxB9m/bN26VePGjZPBYNC8efM0bNgwSVJMTIz69++vTZs2acKECXrzzTftGygAwGayc6XcPMnTTTJyawmcUG6e5XPg4Sa58BkAAACAk8kzSVk5krur5Opi72hQnj5d9ZI+XfVSvmXdW96mx259104RAShPJMj+5dVXX5XZbNYDDzxgTY5JUqNGjfTJJ5+oZ8+eev/99zVx4kQFBQXZMVIAQHlKz5K2HpZ+OyQlplqWGQ1SizpS93AprJblMeCosnOlHbHSxkNS3Lm/l4fVtHwGWoaQLAMAAIDjyjNJ+05YjocPxv+9vHZV6ZpwqUOo5QYyOJYbOz+oHq3uVK4pR0fi92jRL9OUmBwndzdPa5ns3Cw98mY7Rba9V0Oue966fPqXw3U+7ZQmj1xuj9ABlILDX9ZITEzU+PHj1bhxY3l6eqpu3bp6/PHHlZ6erhEjRshgMOidd96RJKWmpmrVqlWSpFGjRhWoq0ePHgoPD1d2draWLFli0/0AANjO3jjple+lH3b8nRyTJJNZ2hMnvb9Wevdn6UKW3UIEytWxs9JrP0hf/p4/OSZJh05J8zZI05dJZ9PsEx8AAABQns5fkGatkD75NX9yTJJOnpe+3ir99wfpyBm7hIdyVCcwTO3C+6hT0wEaHDler97/ow7GbdNbix+ylnF39dD4uz/Vl2smK+bkbknSb399ry37f9RTd35ir9ABlIJDJ8h27dqliIgIzZgxQwkJCWrevLlycnI0e/ZsDR48WPv375cktWnTRpK0c+dOZWdny8PDQx06dCi0zu7du0uStmzZYpN9AADY1r4TlpOg7NzLl4s5Lb231jLMBuBI4s5ZEsApmZcvdypFenu15eIBAAAA4ChSMy3HuSeTLl8uPUt6b410NNE2ccE+WoR2U5929+mX3Yu0N3aTdXl4SHvd0fMZTf/y/3TmfJze/OZBPXbruwqsUtuO0QIoKYdNkCUmJmrgwIFKSEjQ008/rfj4eO3YsUMJCQmaNm2ali1bpm3btslgMKhVq1aSpKioKElS/fr15epa+OiTjRo1ylcWAOA4MnOkT3+z9BQrjrhz0rLd5RsTYEsms7Rgo5R1hQTxJecvSF/9Xr4xAQAAALb0zbbij5SQkyfN32AZjhGOa0ifF2U0umjByv/8a/kLcjG66uE326p140hFtrnbThECKC2HTZCNHTtWcXFxGjNmjGbOnCk/Pz/ruvHjx6t169bKzc1VaGio/P39JUlJSZZbQ6pVq1ZkvZfWXSoLAHAc2w5bkmQlsfUwvcjgOA7GS2dSr1zun/afzD8UKQAAAFBZnb8g7Tlesm2SLkh7T5RPPKgY6gQ2VmTru7Uzeo32HN5gXe7q4qbmod2UnJ6ofh3ut2OEAErLIRNk+/fv16JFixQYGKgpU6YUWqZ9+/aSpNatW1uXZWZaxhJyd3cvsm4PDw9JUkZGhnXZpURcp06d5OHhIYPBcNX7AACwvU2HSr5NZo6042jZxwLYQ2k+A2ZJm6PLPBQAAADA5rZEF39EkX8qzXE0Kpd7rnteRoNRC1b93Ytsz+ENWrV9vgZdM0bvLXlcWTkZl6kBQEVU+DiCldzChQtlMpk0ZMgQ+fr6FlrGy8tLUv4EmaenpyQpOzu7yLqzsrLybS9J0dHRWrx4sTp27Ch3d3f99ttvV70Pl4SFhclodMg8JlCp3DBxm7yrBCs+IV4hIR3tHQ7Kye1TjspgdCnxdq/O/FB/Lv1vOUQE2Fa/Z9bLr0ajEm/3v29W6+GB3DEJAADgaG69/wn5+PpfPBcOKfDY0XS+9z3VbX1zibfbsf+EQv6vczlEZHvurl76cIzzZfxaN+ql1TOKzo7Wr9lMK6fnWR9nZKVpxqLhGjFgqgZ2fVhPf9BTc5dP1MM3v2GLcCucsPAwZeeSIITtmEx/j23bvXt37dy5s1T1OGSCbO3atZKkyMjIIsvExcVJyp8gK87wiYUNw9ijRw/Fx8dLkl5++eUyTZBdqheAfeXl5Vl/nzjB2AmOyOjiWqrkmCRlZuXyvoBDMKt0n4HcPPEZAAAAcECmi+fCpovnwv9+7Giyc0o5mZjBzWGeD083b3uHUCnM+fFp1areQDd3e0QGg0Hj7pqvh95so2ta3qpWDXvYOzybiz95Upk5F+wdBpzUqVOnSr2tQybIjh61jHVVv379Qtfn5uZak1j/TJCFh4dbt8/NzZWra8GnJyYmJl9ZSeXawys4OJgeZEAF4OLiYv1dp04dO0eD8pKTmSI3T/8Sb+dmyOZ9AYeQl5VSyg3T+QwAAAA4IOPFc2HjxXPhfz92NEZzZqm2y81Kdpjnw93V68qFnNzWA8v1y+5F+vCpP61T7dQObKQRA6Zq5qL7NefpP+Xl7mPnKG0ruHZtepDBpkwmk7VzUc2aNUtdj0MmyNLT0yXlnyfsnxYtWqTExET5+fmpQYMG1uVt27aVu7u7srKytH37dnXp0qXAths3bpQkde5sm27Thw4dko+Pc32hAhXRS99KyRlScK1gaw9UOJ4vNktbD5d8u7mznlCdak+UeTyAra3+S1q2u+TbvfTYLWo945YyjwcAAAD2Nfndz5WSlm49F/73Y0ez74T04S8l3+6O3mGa+6RjPB952dK62faOomLr1HSAvn/1fIHlg655VIOuedT2AVUAh6IOycXd3lHAmaSnp1un17qUsykNh+yaVKtWLUnSjh07CqyLj4/XuHHjJEmtWrWyZvklyc/PT3379pUkffTRRwW2/fXXXxUVFSV3d3cNGjSoPEIHANjRteFXLvNvDWpIdapduRxQGXRpLLmU8OiwipfU0vGmnwAAAIATalpbCvAt2TZGg9QtrHziAQCUL4dMkPXp00eSNG3aNEVFRVmXb9u2TZGRkUpMTJQktWnTpsC2L7zwggwGg+bNm6cFCxZYl8fExGjEiBGSpNGjRysoKKgc9wAAYA91A6TWdYtf3miQBrQqv3gAW/PzlHo1Ldk2A1qVPKkGAAAAVERGg3RD6yuX+6drwqWqTNsFAJWSQ17OGD9+vAICAnT8+HG1aNFCERERCgsLU6dOndSwYUP17t1bUv75xy7p0qWLpk6dKrPZrOHDhys0NFRt27ZV06ZNFR0drc6dO2vq1Km23iUAgI0M6SaF17pyOaNBurdr8coClcmNbaSODYtXdkArS68zAAAAwFG0D5UGtSte2bb1pVuKWRYAUPE4ZIIsJCREGzZs0I033ihPT0/FxsaqevXqmjNnjpYtW2btVVZYgkyyJNhWrFihvn37Kjk5WQcOHFB4eLgmTZqk9evXy9ub20IAwFG5u0oP9pL6t5L8PQsvE1ZTeuQ6qUODwtcDlZnRIN3bRbq9gxToV3iZkOrS8GulfhG2jQ0AAACwhchm0sieUv2AwtdX95FuaS/ddw2jKQBAZeZq7wDKS7NmzbR06dICy9PS0hQbGyuj0aiWLVsWuX2/fv3Ur1+/8gwRAFBBubpI/SOkvi2kPXHSws1SVq7k4So92V+qVcXeEQLly2CQrm1iGS7mYLw0f8Pfn4GHr7NcKPjHNK4AAACAw2kZYvk5flbaf1L6eZ+UnSt5u0sv3CwZSYwBQKXnsAmyouzdu1dms1nh4eFl2hPsm2++kSTt27cv3+PQ0FB16NChzNoBANiOi1FqU0/6brslOeDpRnIMzsVokJrVtrz3L30GQgPtHRUAAABgO3UDLD+/HbIkyNxcSI4BgKNwugTZnj17JBU9vGJp3XnnnYU+HjZsmObPn1+mbQEAAAAAAACArb37/Vht3rdEp5KO6v0ndqpxnTaSpJzcbM1f+aI27lksFxc3uRhcdFuPJzWg04jL1vfpqpf1v9Wv6KX/+1bdI26VJJnNZv3flIZKzUjS96+elyQNnRyql4d9r8Z12uj5T25Uq4Y9NThyvCQp+sROvTD3Jr3/5E5V8w1S33EGhdZqKaPBxdrOjNFr5O8T8I91RuXm5ejOXuPUv+P9Zf9EXUZRz2FRVm6br017v9crw7+3SXyStGXfUn249BnlmfPUoFaExg2eLx9Pf5u1D9gKCbIyYjaby7Q+AAAAAAAAAKhIrm11h+7qNV5Pvtc93/IZi4YrJzdLHzy1W17uPko4F6uJnwxQbm62BnZ7+LJ1hoW018ptc60Jsp2H1sjfJ1CpGUmFln/qzo/1yFvt1bnZjaod2FjTvvw/PTLoLVXzDbKWeeORDfL1qlro9pfWxZzcrTGzO6pjk/4K8A8uwbNwdYp6DiuCvLxcZedmatbXIzTr4fWqF9RUb383Rp///KoevGmGvcMDyhwJMgAAAAAAAADAFbVq2KPAsrgzh7Rp7/f64vnj8nL3kSTVqh6q0TfN0uvfjLxigqxlaHf9EbVK51ISVN2/llZsm6v+HR/QJ8snFFo+wD9Yo2+aqelf/p9aNeyp0Fot1aPVHSXel0a1W8vXq5oSk+MumyD7/OfXtGbn53Jz8ZAk/ff+H1SzWn0dPL5NHy97VulZKTKZ8nRP74nq2doyqtjSzXP09a8z5eXuq+4tb9OCVf/R6hmWDhaFPYfFdS4lQZO/uEcXMlOUnZup1o0i9eig2TIajRo1K0JP3D5HLUK7SZKWbflQO6PX6IWhi3QuJUHv/jBWp5JilZWToW4tBun+/q9JsvTO69l6sHbHrFOdwDB1a3GLGtduq3pBTSVJN3d7RM99dD0JMjgkp0uQrV271t4hAAAAAAAAAIBDiDm5U3UCw+TvE5BvefP6XXUuJV5JqadUza/mZeu4rt1QrfpjgW7qMloH47bp/v6vFZkgk6Tebe/Vqu0LtPqPTzVv/MEC659871rrEIt+3tU086F1BcrsjlmvKj6BahhcdEeK1AtJ+nr9TC36T7w83LyUmX1BRoNRaRnn9cY3D2rSiJ8U4B+s5PREPfxmO7UI7abUjCR9uuolvf/kTgX4B+uT5RMvu+8l4etVVa/e/6O8PHyVZ8rTS/MHaf2fXymyzd26tftY/fDbO9YE2ZJN72rMLe9IkqYvGqZ7ek9U60Y9lZeXqxfm3qT1u7+2JvRSLpzV24/9LoPBoK/Xz1LNavWtbdasFqpzKfHKy8uVi4vTpRPg4HhHAwAAAAAAAADKhbub1xXLXN9hmJ79sK+83H3Vs9VdMhiMly2fmHxSRxL2yMXoqvhzRwok5y43xOKT712r7JwMJZw7ohfv+0Zuru5FtuPt6a86gWGa+sVQtQ+/Xp2b3agaVUO0M3qt4s8d1sSPB+Qrf/zMQcUm/KWOTQdYe6UN7Pqwvlw75YrPQXGYzCZ9tOxZ7Y3dKLPZrPNppxVaq6Ui29yt69oN1YKV/1FS6imdSDwkyaCIhtcqIztdO6PXKCn1lLWezOw0xZ35O7HYr8NwGQyGMokRqExIkAEAAAAAAAAASqVR7bY6kXhIKeln8yWq9h3drNCaLeTj6X/FOgKr1FHNavX12epX9OaYTVcs//rXI3RHj6cVVLWeZi4arvee2HHZRNc/XUqerdw2XzO+Gq4Wod2K7OHmYnTR7Me2aF/sJu2O+UVj3+miifculGRWaM0WequQWGMT/sr32KCySzwt/vV1nU8/rbcf+13ubp76YMlTys7JlCR5uHnp+g7DtXTLHB07vV+DrnnUspHZMrTj249tkbubZ6H1err7Wv8OqlpPO6JWWx+fSopVdf9geo/BIV0+FQ8AAAAAAAAAQBFCaoSpS/OBeuObB5WZfUGSlHAuVh//9KweHDir2PUM6/eqhvd/TXUCG1+23NLNc3QhK1W3X/ukera+U/VrtdCnq18ucdz9Og5X28bX6Yu1k4sscyEzVUmppxTR8FoN7fuiWoZ2V/TJnWpev5sSzh3RjqifrWWjT+xSTm622jTure0HV+hcSoIl3i0flDi2oqRmJKm6Xy25u3nqXEqCfv3z63zrb+72qH76/UPtil6r3m2HSJK8PHzVplGkvlw31VouMfmkzpyPK7SNjk36K/rEDh07fUCStGTTe+rV+u4y2wegIiHtCwAAAAAAAAC4oje/Ga3fDyzTudQETfi4n7w9/LTguWiNv/tTLVjxoh6cFSGD0aiEc0f02v1L1bFJv2LX3aRuBzWp2+GyZeLPHdGnq17SG49ulNFo6fvx2K3vavTrrdW95a1qUrejpPxzkEnSC0MXqW5QkwL1jbxhmh59q70G9xqvwCp1CqxPz0zWf/93hzKz02WQQXUCw3R9+2Hy8aqi1x5Ypg+XPqM5S59Wbl6OgqrW0yvDv1eDWi11X9+X9eT718rL3VfdW95WrOewOG7r/rj++787NHJmCwX411bbsD751teoGqLGtduqTo1webp7W5c/d+/nmrPkKY2a2VIyGOTp7qMnbp+jGlVDCrTh7emnJ+/8WC/Pv0V5plyF1mqp8YMXFCs+oLIxmM0X+1iiwkhPT5evr6Vba1pamnx8fOwcEYCXvpWSM6QqXtIrt125PBwLrz+cHZ8BAAAA5zT53c+VkpYuf18fTXx0SIHHzsRZjonzsqV1s6+uDpPJpE9+ek5/HFqt6aPXyN+7etkEV0llZKXp5hf8tHpG+V+Gz8hO1wPTm+j1RzYouHqDcm/vksixkkvxRrgEykRZ5VDoQQYAAAAAAAAAKBNGo1GjbpquUfYOxMn8uPkDLVwzSQO7PmLT5BhQmZEgAwAAAAAAAACUi9/3/6S5yycWWH5P7wnq1WawHSIq6KffP9YPv71TYPmYW95WRMNrr6puLw/fK/YeS0o7rec+vL7A8vbhffXgTTOK1c7Arg9pYNeHShUj4KxIkAEAAAAAAAAAykXnZjeoc7Mb7B3GZd3QeaRu6DzSbu1X8w3SnKd22a19wFkZ7R0AAAAAAAAAAAAAYEv0IAMAAAAAAAAAyOgmRY61dxSobIxu9o4AKB0SZAAAAAAAAAAAGQySi7u9owAA22CIRQAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCgqwIq1atUv/+/RUQECBvb29FRERoypQpys7OtndoAAAAAAAAAAAAuAokyAoxa9Ys9evXTytXrpSfn5+aNGmiAwcOaOLEiYqMjFRGRoa9QwQAAAAAAAAAAEApkSD7l61bt2rcuHEyGAyaP3++YmNjtXPnTh04cECNGzfWpk2bNGHCBHuHCQAAAAAAAAAAgFJytXcAFc2rr74qs9msBx54QMOGDbMub9SokT755BP17NlT77//viZOnKigoCA7RgoAAMpb/Hlp62HpXLpkNktVvaWODaS6AfaODLCNpHRpS4x0KlnKM0m+nlLb+lJYTclgsHd0AAAAQPm6kGU5Jzx+TsrKlbzcpea1pYgQydXF3tEB5S87V9pxVIpOkDJzJU9XqVFNqV2o5OEA2SUH2IXLS0xM1PTp0/Xtt98qLi5ONWrU0G233abJkydr7Nixmjt3rt5++22NGTNGqampWrVqlSRp1KhRBerq0aOHwsPDFRUVpSVLlmjkyJG23h0AAGADJ5OkxdulmNMF1/16UKoXIN3aXmpQw/axAbZw/oL0zTZp7wlLcvifNkdLQf7STW2kVnXtEh4AAABQrrJypR/+kLYdkXLy8q/bdljy95R6t5B6NuHGMTgmk0lasUfaECVlZOdftz1W+mGHdE2YdENryaUSj1NYiUO/sl27dikiIkIzZsxQQkKCmjdvrpycHM2ePVuDBw/W/v37JUlt2rSRJO3cuVPZ2dny8PBQhw4dCq2ze/fukqQtW7bYZB8AAIBtxSZKs1cXnhy75NhZ6d2fpX0nbBcXYCuJqdKbK6W/4gomxy45nSLN+1XadMi2sQEAAADlLTNHeu9naVN0weTYJSmZ0vd/WG6sLOqYGais8kzS/I3Sqr8KJscuycyR1uyT5v5qKV9ZOWyCLDExUQMHDlRCQoKefvppxcfHa8eOHUpISNC0adO0bNkybdu2TQaDQa1atZIkRUVFSZLq168vV9fCO9c1atQoX1kAAOA4UjKkj36xHOhdSe7FA8ZTKeUeFmAzuXnSh79YepBdiVnS11ulqITyjgoAAACwnc82SUfPFq/sxijLKCOAI1m6S/rzePHK7j1hSRZXVg6bIBs7dqzi4uI0ZswYzZw5U35+ftZ148ePV+vWrZWbm6vQ0FD5+/tLkpKSkiRJ1apVK7LeS+sulQUAAI7jt0NSelbxy2fnSusPlF88gK3tOmbpHVZcZkk/7y23cAAAAACbOplkGUmhJNbsq9w9aIB/Ss+yDKtYEpuipdTM8omnvDlkgmz//v1atGiRAgMDNWXKlELLtG/fXpLUunVr67LMTMur6O7uXmTdHh4ekqSMjAzrsm+++Ua333676tevL29vbzVt2lTPP/+80tLSrnpfAACAbeSZLHMrldT2I8XrcQZUBhtLMUhCVAI9KQEAAOAYfivFEOIpGdKeYva2ASq6rYctI4uURJ5J2lKK6ykVgUMmyBYuXCiTyaQhQ4bI19e30DJeXl6S8ifIPD09JUnZ2UUMrCkpKysr3/aSNHPmTLm4uGjy5Mlavny5Hn74Yb3//vvq37+/TCZuHwAAoDI4mWQ5sSmp7NzLz1cGVBYZ2ZY5+ErjwMmyjQUAAACwh/2lPK7dx/EwHERpPwOl3c7eCp9oq5Jbu3atJCkyMrLIMnFxlr6y/0yQFWf4xMKGYfzxxx9Vo0YN6+OePXuqRo0aGjJkiDZu3KgePXqUYi8swsLCZDQ6ZB4TqFRumLhN3lWCFZ8Qr5CQjvYOBzbG6+8cajTqpp4PflWqbUeOHqPju74v24AqED4DzsGram3dOGFrqbZ9bcpMDVnzZtkGBAAA7O7W+5+Qj6//xePAkAKPnQnHxM7h5pf+krt31RJv992S5Rp/56iyDwiwsd5jlqp63TYl3m7Hn/sV8kDfsg+oCP/smNS9e3ft3LmzVPU4ZILs6NGjkqT69esXuj43N1e//fabpPwJsvDwcOv2ubm5cnUt+PTExMTkKyspX3Lskg4dOkiSTpw4UZpdsIqPj7+q7QGUjby8POvvq/1co/Lh9XcOeZ7HSr3t6fjjDv3e4DPgHDyTSz9o/Nkz8bw3AABwQKaLx4Gmi8eB/37sTDgmdg5ZmWmlSpClnE/kfQGHcCHtvKqXYruMtPN2+wycOnWq1Ns6ZIIsPT1dUv55wv5p0aJFSkxMlJ+fnxo0aGBd3rZtW7m7uysrK0vbt29Xly5dCmy7ceNGSVLnzp0vG8O6deskSc2aNSvVPlwSHBxMDzKgAnBxcbH+rlOnjp2jga3x+jsHVyUrN/uCXN29S7Sd2ZQnY1a8Q783+Aw4CYNBaWdj5RsQWuxNzGazDAaDTKmxvDcAAHBAxovHgcaLx4H/fuxMOCZ2Dikn/5Jf9ZL3jsw6e4j3BRxC+ukDUrNeJd4u7fR+m34GTCaTtXNRzZo1S12PQybIatWqpaSkJO3YsUNdu3bNty4+Pl7jxo2TJLVq1UoGg8G6zs/PT3379tWyZcv00UcfFUiQ/frrr4qKipK7u7sGDRpUZPsnTpzQiy++qP79+6tNmzZXtS+HDh2Sj4/PVdUB4Oq99K2UnCEF1wq2DtEK58Hr7zwW/S5tLuHEshH1XPTWX6Ublq6y4DPgPNbuk5aUYGQKg8GgWlWknb8u1j8OqwEAgIOY/O7nSklLtx4H/vuxM+GY2DkcjJfeX1uybdxdpJ8++6+83f9bPkEBNpSYKr22pOTbfTLlAdV674GyD6gI6enp8vX1lfR3p6bScMiuSX369JEkTZs2TVFRUdbl27ZtU2RkpBITLbOPF5a8euGFF2QwGDRv3jwtWLDAujwmJkYjRoyQJI0ePVpBQUGFtp2WlqZBgwbJ3d1dc+fOLatdAgAANnBtuGQs4UX+nk3KJxbAHjo3kjxKeAtdz6YiOQYAAACHEFZLqlWlZNt0aiR5u5dPPICtBfpJLUvYibJpcMk/NxWFQybIxo8fr4CAAB0/flwtWrRQRESEwsLC1KlTJzVs2FC9e/eWlH/+sUu6dOmiqVOnymw2a/jw4QoNDVXbtm3VtGlTRUdHq3Pnzpo6dWqh7WZkZGjgwIE6cuSIVq1apeDg4HLdTwAAULZqV5Pu7FT88je2tpxAAY7Cx0N6oIfkUsyzhE4NpS6NyjcmAAAAwFaMBmlED8nXo3jlGwRKN7ct35gAW7unixTkX7yygb7SkG7lG095csgEWUhIiDZs2KAbb7xRnp6eio2NVfXq1TVnzhwtW7bM2qussASZZEmwrVixQn379lVycrIOHDig8PBwTZo0SevXr5e3d8G5SXJycnTHHXdo+/btWr58uZo3b16u+wgAAMpH18bS0G6Sp1vRZdxcpNs6SH1b2i4uwFaaBEsPRUr+nkWXMRqk3s2ku7vQewwAAACOpYa/9Pj1UvAVesS0ris91Ftyd8hJjODMfDyksX2lsCtM7dWwhjT2esnvMueOFZ3DfnybNWumpUuXFlielpam2NhYGY1GtWxZ9FWtfv36qV+/fsVqy2QyaciQIVqzZo1++ukndepUglvPAQBAhdOhgRQRIv0RK/0eIx07K5llSQoMaid1bCB5F/OOQqAyCqsl/ecW6c/jlnn5ok/9/Rm4vqUlkVyl4D1jAAAAgEOo4S+Nv1E6dEraGCXtiZPMZsvx8DXh0jVhlXdIOaA4fD2lR/tYrodsjLKcEyalW84L3Vws6+oHVP4bJh2yB9nl7N27V2azWWFhYYX2BCuNRx99VF9//bWefPJJeXt7a8uWLdafM2fOlEkbAADAtjzcpG5h0pP9JX8vyzI/T8t8SyTH4AxcXaR2oZYTn39+Bvq3IjkGAAAAx2cwSOG1LEOQXxpdwc9Tur0DyTE4j3oB0r1dLTdQXjov9HaXQgMrf3JMcsIE2Z49eyQVPbxiaSxfvlySNHXqVHXt2jXfz7Jly8qsHQAAAAAAAAAAAFw9hx1isSjlkSCLjY0ts7oAAAAAAAAAAABQvuhBBgAAAAAAAAAAAKfidD3I1q5da+8QAAAAAAAAAAAAYEdO14MMAAAAAAAAAAAAzo0EGQAAAAAAAAAAAJwKCTIAAAAAAAAAAAA4FRJkAAAAAAAAAAAAcCokyAAAAAAAAAAAAOBUSJABAAAAAAAAAADAqZAgAwAAAAAAAAAAgFMhQQYAAAAAAAAAAACnQoIMAAAAAAAAAAAAToUEGQAAAAAAAAAAAJwKCTIAAAAAAAAAAAA4FRJkAAAAAAAAAAAAcCokyAAAAAAAAAAAAOBUSJABAAAAAAAAAADAqZAgAwAAAAAAAAAAgFMhQQYAAAAAAAAAAACnQoIMAAAAAAAAAAAAToUEGQAAAAAAAAAAAJwKCTIAAAAAAAAAAAA4FRJkAAAAAAAAAAAAcCokyAAAAAAAAAAAAOBUSJABAAAAAAAAAADAqZAgAwAAAAAAAAAAgFMhQQYAAAAAAAAAAACnQoIMAAAAAAAAAAAAToUEGQAAAAAAAAAAAJwKCTIAAAAAAAAAAAA4FRJkAAAAAAAAAAAAcCokyAAAAAAAAAAAAOBUSJABAAAAAAAAAADAqZAgAwAAAAAAAAAAgFMhQQYAAAAAAAAAAACnQoIMAAAAAAAAAAAAToUEGQAAAAAAAAAAAJwKCTIAAAAAAAAAAAA4FRJkAAAAAAAAAAAAcCokyAAAAAAAAAAAAOBUSJABAAAAAAAAAADAqZAgAwAAAAAAAAAAgFMhQQYAAAAAAAAAAACnQoIMAAAAAAAAAAAAToUEWRFWrVql/v37KyAgQN7e3oqIiNCUKVOUnZ1t79AAAAAAAAAAAABwFUiQFWLWrFnq16+fVq5cKT8/PzVp0kQHDhzQxIkTFRkZqYyMDHuHCAAAAAAAAAAAgFIiQfYvW7du1bhx42QwGDR//nzFxsZq586dOnDggBo3bqxNmzZpwoQJ9g4TAAAAAAAAAAAApUSC7F9effVVmc1m3X///Ro2bJh1eaNGjfTJJ59Ikt5//32dPn3aXiECAAAAAGwkOUM6GC/9FSfFnJZy8+wdEQAAAGzpTKq0/6S0N046dlYyme0dEcqKq70DKG+JiYmaPn26vv32W8XFxalGjRq67bbbNHnyZI0dO1Zz587V22+/rTFjxig1NVWrVq2SJI0aNapAXT169FB4eLiioqK0ZMkSjRw50ta7AwAAAACwgZjT0q8HpT3H818E8fWQujSWuodLVb3tFx8AAADKj8ks/XlM2nhIij6Vf10NP+maMMsxoaebfeJD2XDoBNmuXbs0YMAAJSQkyMfHR82bN9fJkyc1e/ZsxcTE6Ny5c5KkNm3aSJJ27typ7OxseXh4qEOHDoXW2b17d0VFRWnLli0kyAAAAADAwZjN0uq90k+7C1+fliX9vFfaHC2N6iWFBto0PAAAAJSz3Dzpi83SjqOFrz+TKn2/Q9oSI42OlKr52DY+lB2HHWIxMTFRAwcOVEJCgp5++mnFx8drx44dSkhI0LRp07Rs2TJt27ZNBoNBrVq1kiRFRUVJkurXry9X18Jzh40aNcpXFgAAAADgONYfKDo59k/pWdIHa6X48+UeEgAAAGzEbJa+3FJ0cuyfEpKl99dajgtROTlsgmzs2LGKi4vTmDFjNHPmTPn5+VnXjR8/Xq1bt1Zubq5CQ0Pl7+8vSUpKSpIkVatWrch6L627VBYAAAAA4BhSM6UfdxW/fGaO9MOOcgsHAAAANhZ9StoeW/zyp1OkX/aXWzgoZw6ZINu/f78WLVqkwMBATZkypdAy7du3lyS1bt3auiwzM1OS5O7uXmTdHh4ekqSMjAzrsg0bNqhPnz4KDg6Wh4eHQkJCNHjwYO3fzycDAAAAACqLLdFSnqlk2xyIlxJTyyceAAAA2NbGQyXfZnOMZVhGVD4OmSBbuHChTCaThgwZIl9f30LLeHl5ScqfIPP09JQkZWdnF1l3VlZWvu0lS2+yiIgIzZ49W6tWrdK0adO0d+9ede3aVXFxcVe9PwAAAACA8rf1cOm223akbOMAAACA7V3IlvYcL/l2aZnSvpNlHw/KX+ETbVVya9eulSRFRkYWWeZS4uqfCbLiDJ9Y2DCMN998s26++eZ85Tp27KgmTZpo8eLFevzxx0u4B38LCwuT0eiQeUygUrlh4jZ5VwlWfEK8QkI62jsc2BivP5z9PeDs+w/eA3Aet7x6SK7uXlcu+C8fzP1So755phwiAgD7uvX+J+Tj63/xGCCkwGNnwvGQc+P1dw5+NRqp3zPrS7XtY0+/qJhN88o4ooqlIn0OTKa/h33o3r27du7cWap6HDJBdvSoZQa9+vXrF7o+NzdXv/32m6T8CbLw8HDr9rm5uXJ1Lfj0xMTE5CtblICAAEkqtI6SiI+Pv6rtAZSNvLw86+8TJ07YORrYGq8/nP094Oz7D94DcB5ms7lU2124cIHPBgCHZLp4DGC6eAzw78fOhOMh58br7xyqmQofja44ks+fd/j3RkX9HJw6darU2zpkgiw9PV1S/nnC/mnRokVKTEyUn5+fGjRoYF3etm1bubu7KysrS9u3b1eXLl0KbLtx40ZJUufOnQusy8vLk8lk0tGjRzVhwgTVqlVLd91111XtS3BwMD3IgArAxcXF+rtOnTp2jga2xusPZ38POPv+g/cAnEdmSrzcajQq8XaGnGQ+GwAckvHiMYDx4jHAvx87E46HnBuvv3Nw8zTKlJcjo4tbibd11wWHf29UpM+ByWSydi6qWbNmqetxyARZrVq1lJSUpB07dqhr16751sXHx2vcuHGSpFatWslgMFjX+fn5qW/fvlq2bJk++uijAgmyX3/9VVFRUXJ3d9egQYMKtNuzZ09rz7TGjRtr7dq1qlGjxlXty6FDh+Tj43NVdQC4ei99KyVnSMG1gplb0Anx+sPZ3wPOvv/gPQDnsfovadnukm/3xewnFej3ZNkHBAB2Nvndz5WSlm49Bvj3Y2fC8ZBz4/V3HvM2SLuPlWwbX09p0/JP5OpSPjFVFBXpc5Ceni5fX0uPv0udmkrDIbsm9enTR5I0bdo0RUVFWZdv27ZNkZGRSkxMlCS1adOmwLYvvPCCDAaD5s2bpwULFliXx8TEaMSIEZKk0aNHKygoqMC2n3zyibZs2aKFCxfK399f119/vY4dK+GnCQAAAABgF10aSy4lPEtuGiwF+pVPPAAAALCt7mEl36ZrIzl8csxROWSCbPz48QoICNDx48fVokULRUREKCwsTJ06dVLDhg3Vu3dvSfnnH7ukS5cumjp1qsxms4YPH67Q0FC1bdtWTZs2VXR0tDp37qypU6cW2m6TJk3UuXNn3X333VqzZo1SU1M1ffr0ct1XAAAAAEDZ8POUBrYpfnlPN+mW9uUWDgAAAGyscU2pQ4Mrl7ukpr8U2az84kH5csgEWUhIiDZs2KAbb7xRnp6eio2NVfXq1TVnzhwtW7bM2qussASZZEmwrVixQn379lVycrIOHDig8PBwTZo0SevXr5e3t/cVY6hataoaN26s6OjoMt03AAAAAED56dlUurHwU8V8fDykh3pLtaqUf0wAAACwDYNBuruz1K7+lcvWqmI5HvT2KP+4UD4ccg4ySWrWrJmWLl1aYHlaWppiY2NlNBrVsmXLIrfv16+f+vXrV+r2T58+rYMHD6pz586lrgMAAAAAYFsGg9S3pdQwSNpwUPrzuGQy/73e10Pq2li6JlyqeuV7JwEAAFDJuLpIQ6+RWtWTfouSDp3Kv76Gn+VYsEsjy4gCqLwcNkFWlL1798psNis8PLxYPcGKY+jQoWrcuLHatGmjqlWr6tChQ3rjjTfk6uqqJ59komYAAAAAqGwaBVl+kjOk6Uul9GzJx116+VbmmAAAAHB0RoPUpp7l50yq9MYK6UK2ZRSBCQMt61H5OV2CbM+ePZKKHl6xNLp06aJPP/1Ub731ljIzM1W3bl1FRkZq4sSJql+/GH0xAQAAAAAVUhWvvxNiri4kxwAAAJxNDT/J7dLxoJHkmCMhQVYGxowZozFjxpRZfQAAAAAAAAAAACg/RnsHYGvlkSADAAAAAAAAAABA5eF0PcjWrl1r7xAAAAAAAAAAAABgR07XgwwAAAAAAAAAAADOjQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRc7R0AKgazWTLl2DsKVGZGN8lgsHcUAAAAAFA6nBfjanBODABA5UOCDJIsJwHrZts7ClRmkWMlF3d7RwEAAAAApcN5Ma4G58QAAFQ+DLEIAAAAAAAAAAAAp0KCDAAAAAAAAAAAAE6FBBkAAAAAAAAAAACcCgkyAAAAAAAAAAAAOBUSZAAAAAAAAAAAAHAqrvYOAAAAoKLJzpVOnpeOn5Xik6UL2ZblF7KlXw5IdatLIdUkDze7hgkAKCcmk3Q61fJ/IC4p//+BFX9e/D8QIFXxsm+cAAAAKB+5eRevC5yT4v91PLh2nxRS3fLj7W7XMHGVSJABAABIMpulo2eljVHSrqNSrqlgmZw86fs/LH8bDVJEiNQ9XGpcUzIYbBsvAKDsJaVLmw5Jm2OktMyC63PypBV7/n5cL0C6JkxqW19y5+waAACg0juRZLku8Ees5ebZf8vJk5bstPxtkNSstnRNuNQsWDIyXl+lwyE8AABwevHnpUW/S7GJxd/GZJZ2H7f8BFeVBneWQgPLK0IAQHm6kC39sEPaethyw0RxHTtr+flhhzSwrdSlETdMAAAAVEZn06SvfpcOJhR/G7OkfSctP4G+0p2dpCbB5RYiygEJMji93TG/6JkPIvMt83T3UUiNcPVpd59uueYxubjwUQEAR5RnsgyNsGKP5e/Sij8vvbVKimwmDWglubmUWYgAgHK274TlJonkjNLXcSHbUseuY9LdnaVqPmUXH2ALnBcDAJyVySz9FiX9uKvwHmPFlZgmvb9W6tZYurmd5MmUDJUCRzfARZFt7lGnpjfILLOSUhO0+o9P9cGPT+nY6f168o4P7R0eAKCM5eRJCzZKf8WVTX1msyXZFntGGtVL8mIccgCo8H7ZL32/o+zqOxgvzVohPRRpmZMCqGw4LwYAOJM8k+Ump62Hy67OTdFS7Fnp4UjJj/lqKzxGxQQuCqvTTn3aD1Xf9vfprl7jNPuxLapRJUTLt36s82ln7B0eAKAM5eZJ834tu+TYPx0+I32wTsq6ijvPAADlr6yTY5ekZUrvrbH0LgYqG86LAQDOwmSWvtxStsmxS04mSe/8XPictqhYSJAVYdWqVerfv78CAgLk7e2tiIgITZkyRdnZ2fYODTbi5e6jpvW7yGw26+TZGHuHAwAoQ9/vsIwRXl6OJkpfbCrZPDYAANv5K658kmOXXMiWPlgrXcgqvzYAW+C8GADgqFb/JW07Un71n0qR5m2wJOJQcZEgK8SsWbPUr18/rVy5Un5+fmrSpIkOHDigiRMnKjIyUhkZVzE4PSqV+IsnAP7ejI8CAI4iKkHaGFWybZ7qL718q+V3ce0+Lu08WrJ2AADlLz3LMgF7SZTm/0ByhvRdOSbhAFvhvBgA4Gjizkkr95Rsm9IcD8acljYcLFk7sC0SZP+ydetWjRs3TgaDQfPnz1dsbKx27typAwcOqHHjxtq0aZMmTJhg7zBRDjJzLig5PVHn087oSPwezf72UUWf2KmmdTsppEa4vcMDAJSBrFzLEAol5e8lVfW2/C6JxdulVIZUAIAK5bs/pJQSfjeX9v/AtsPS3hMl2wawJ86LAQCOLs8kfbGl5D27Sns8uHSXlJhasm1gO672DqCiefXVV2U2m/XAAw9o2LBh1uWNGjXSJ598op49e+r999/XxIkTFRQUZMdIUdY+XfWSPl31Ur5l3VvepsdufddOEQEAytq2w9K5dNu1l55l6a02oJXt2gQAFC0xVdpejkPpFGblHqlFHdu2CZQW58UAAEf3V5xljjBbycmT1u6X7upkuzZRfA6fIEtMTNT06dP17bffKi4uTjVq1NBtt92myZMna+zYsZo7d67efvttjRkzRqmpqVq1apUkadSoUQXq6tGjh8LDwxUVFaUlS5Zo5MiRtt4dlKMbOz+oHq3uVK4pR0fi92jRL9OUmBwndzdPa5k9hzdo4icDCmybm5ctkylPK6fn2TJkAEAJmM3SbyUcWrEsbI6Wrm8pudBvHwDs7rdDtm/z2FnLT70A27cNlBTnxQAAR1fSKRfKwvYj0s1tJU8327eNy3PoBNmuXbs0YMAAJSQkyMfHR82bN9fJkyc1e/ZsxcTE6Ny5c5KkNm3aSJJ27typ7OxseXh4qEOHDoXW2b17d0VFRWnLli0kyBxMncAwtQvvI0nq1HSAWjboriff6663Fj+k54d+KUmKaHitfpyUlm+7xOSTenR2Bw3qNsbmMQMAiu/IGSk+2fbtpmRY7lBrXc/2bQMA/pabJ/0eY5+2Nx0iQYbKgfNiAIAjO50iHTpl+3azcy1Jsu6MVlzhOOy9zImJiRo4cKASEhL09NNPKz4+Xjt27FBCQoKmTZumZcuWadu2bTIYDGrVyjLuUVSUJX1cv359uboWnjts1KhRvrJwXC1Cu6lPu/v0y+5F2hu7qdAy2blZeuXT29QytLvuvW6ijSMEAJSEPQ6CL4m2Y9sAAIuT56UL2fZpm/8DqKw4LwYAOBJ7HpNxPFgxOWyCbOzYsYqLi9OYMWM0c+ZM+fn5WdeNHz9erVu3Vm5urkJDQ+Xv7y9JSkqyDD5arVq1Iuu9tO5SWTi2IX1elNHoogUr/1Po+rcWP6TsnEyNGzzftoEBAErs+DnnbBsAYGHP7+LENPsl54CrxXkxAMBRcF0A/+aQCbL9+/dr0aJFCgwM1JQpUwot0759e0lS69atrcsyMzMlSe7u7kXW7eHhIUnKyMgossyAAQNkMBj08ssvlzR0VDB1AhsrsvXd2hm9RnsOb8i37ruNs/X7/qV6Zfj38nT3tlOEAIDiirPjweiJJMlksl/7AAD7/h+QpBNcFEElxXkxAMBR2PN48Cw3TFVIDjkH2cKFC2UymTRkyBD5+voWWsbLy0tS/gSZp6dl0tns7KLfqVlZWfm2/7evvvpKu3btKk3YhQoLC5PRWP55THdXL304xg4zVlcC91z3vNbtWqgFq/6jmQ+tkyTtil6nj5c9q8kjl6tW9VD7BlhBhIWHKTu36MRxZXfDxG3yrhKs+IR4hYR0tHc4sDFef8dwy6uH5Ope+P/vp/pL/oWvkiT5e/79++Vbiy6XkiG9vqLg8pw8qWHjJsrNTi9BxBUHnwHwHoAj6HrfR6rTckCh68rq/4BU9P+C+x54SHF/Li1mtLAHzouLxnnxlTnqOfGt9z8hH1//i8cAIQUeOxOOh5wbr79jGPDsZvlUr1voOlscD7bt2F3pZ2OLF2wFVJE+B6Z/3IXcvXt37dy5s1T1OGSCbO3atZKkyMjIIsvExcVJyp8gK87wiZcbhjElJUVPPPGEZs6cqaFDh5Y88ELEx8eXST1X4unmvHd6tW7US6tnmItcX79mM62cnmd9nHAuVq99dpdG3TRDrRv1skGElUP8yZPKzLlg7zDKTV5envX3iRMn7BwNbI3X3zEYjEUf9vh7SVWL8a/QaCxeucKcOpOozLTK2X2AzwB4D8ARZGXnFrnOFv8Hzqek8fmp4Dgv5rz4ajjqObHp4jGA6eIxwL8fOxOOh5wbr79jMF9mQD1bHA8mJp7TuZOV9/1TUT8Hp06VfoI3h0yQHT16VJJUv379Qtfn5ubqt99+k5Q/QRYeHm7dPjc3V66uBZ+emJiYfGX/6fnnn1d4eLiGDBlSZgmy4OBgm/Ugw5VlZl/QS/NvUdfmN+uWa8bYO5wKJbh2bYe8W+4SFxcX6+86derYORrYGq+/YzDnZUuuboWuS7nC15e/p+Ug2GSSUjKLLne5eoICqyuvSuX8f8tnALwH4Ajc3Yo+ryqr/wOXq6uKnw+fnwqO8+Li4by4cI56Tmy8eAxgvHgM8O/HzoTjIefG6+8gzEXfMGWL48HAgKryMlTe909F+hyYTCZr56KaNWuWuh6HTJClp1uGLypqnrBFixYpMTFRfn5+atCggXV527Zt5e7urqysLG3fvl1dunQpsO3GjRslSZ07d863fPv27froo4/0xx9/lNVuSJIOHTokHx+fMq2zMHnZ0rrZ5d5Mpbdhz2Idjt+tE4lR+mX3ogLrP3lmn4Kq1bNDZPZ3KOqQXIqevq/Se+lbKTlDCq4VbO2BCufB6+8YJv8onU4pfF1hQx/808u3Wu4QS8mUXv6u5G17u0uxhw/JYCj5thUBnwHwHoAj+O4Paf2BwteV9/8BSfrqf3NUP7B028I2OC8uHs6LC+eo58ST3/1cKWnp1mOAfz92JhwPOTdef8fw9mop5nTh68r7eNBokPbs2CT3SpyRqUifg/T0dOv0WpdyNqVRiV+OotWqVUtJSUnasWOHunbtmm9dfHy8xo0bJ0lq1aqVDP+4UuXn56e+fftq2bJl+uijjwokyH799VdFRUXJ3d1dgwYNsi7Py8vT6NGjNWbMGLVo0aIc9wz21rf9ferb/j57hwEAKIW61YtOkNmi7cqaHAMAR1G3uv3aNhqk2gVH6QcqJc6LAQCVVd3qRSfIylutKqrUyTFHVf5j99lBnz59JEnTpk1TVFSUdfm2bdsUGRmpxMRESVKbNm0KbPvCCy/IYDBo3rx5WrBggXV5TEyMRowYIUkaPXq0goKCrOveeecdnTp1Si+//HI57A0AACgLdQPs13aIHS/KAgAs7JkgC64qubnYr30AAABwXQAFOWSCbPz48QoICNDx48fVokULRUREKCwsTJ06dVLDhg3Vu3dvSfnnH7ukS5cumjp1qsxms4YPH67Q0FC1bdtWTZs2VXR0tDp37qypU6dayycmJurFF1/Uf/7zH+Xm5ur8+fM6f/68JCkzM1Pnz5+XyWSyyX4DAICiNa9tv7ZbVN4hxgHAYdTwlwL97NO2Pf8HAQAAwKJJLcnFThkRrgtUTA6ZIAsJCdGGDRt04403ytPTU7GxsapevbrmzJmjZcuWWXuVFZYgkywJthUrVqhv375KTk7WgQMHFB4erkmTJmn9+vXy9va2lo2Li1NqaqpGjx6tatWqWX8kSw+2atWq6dixY+W/0wAA4LKC/C0Hw7ZWu6rUoIbt2wUA5Gc0SNeE2b5dg0HqZod2AQAAkJ+vp9TGDtNkVvGSWobYvl1cmcOOetmsWTMtXbq0wPK0tDTFxsbKaDSqZcuWRW7fr18/9evX74rtNG7cWOvWrSuwPDIyUsOGDdPw4cNVq5YdrsYBAIACrgmXDibYvk3mHwOAiqFTQ+mn3VJOnu3abFFHquZju/YAAABQtO7h0h+xtm2za5j9eq7h8hw2QVaUvXv3ymw2Kzw8PF9PsNLy9fVVr169Cl0XGhpa5DoAAGB7LUOkRkG2m5Q3uIrUuaFt2gIAXJmPh3R9S2nZbtu052KUbmpjm7YAAABwZaGBUuu60u7jtmmvqrfUq6lt2kLJOV2CbM+ePZKKHl4RhcvOydSkz+/W0VP75OHmpaq+QRp72/uqE9hYZrNZX/0yQyu3zZUMBplMeerf8QHd1Wu8jMbLp8aj4v7QvOXPKy4xSn7e1eXm4qG7eo3TNS1vkSSt3DZf3/w6S3mmXOXl5ahHqzv1f9e/IjdXd0nShj3fauGaScoz5SknN1MB/rU17cGf9cK8m3Q2+aQk6XD8boXWaimjwUXenn5645EN5fpcXbJi61wt3vCGjp3er9E3zdRt1z5hXffJ8on6bc+3cnP1kIuLm+7vP0kdm1y+x2LfcQZ9998k+XpVLd/AL0pKO63pC/9PJ8/FyN3FQ4/d9p5aNexhk7YBoLwYDdI9XaTpy6Tscu49YDRI93aVXF3Ktx0AQMn0bi79eVw6fq782xrQSqpVpfzbQfnjnLjkLndOPP3L4dpxaLWq+FjGoW4f3lcP3jSjyLoSzsXqoTfa6PtXz5dz1H+LO3NIMxYNU3J6onw8q2jc4PkKrdXCZu0DAMqHwSDd0UmKPi2lZ5V/e4M7S55u5d8OSocEWTkxm83lWr893ND5QXVqOkAGg0Hf//aOXv96pGY9/Ivmrnheew7/qjce3agqPoFKTk/US/NvUWpGkkbdOK3I+mIT9mrCR/30zOB56tp8oCQpMfmkdhxaLUlatuVDLd7whiaN+EnB1RsoM/uCpi28T7O+HqHn7vmfzqbE681vHtR7T/yhmtXqS5IOxe2QwWDQ5BE/WdvpO86gNx7ZYLPE0iVhIe31wtCv9OXaKQXWRTS4VkP7vCgPNy/FnNytp97voS9fPCkvd/uPvWIymSRJn/z0nJrV76Ipo1bo4PFtennBrfrfhCNydeEbHUDlFugn3dJe+mpr8bdJycj/uzj6RUh1A0oWGwCg/LkYLTcwvLlSysot3jal+T/QsIYU2azk8aHi4py4ZC53TixJd/Ualy9pVlHk5eXKxcVVby0erRs6P6h+HYfr1z+/0YxFw/Xu49vsHR4AoAz4eVoSV/N+lYp7Fb80x4Pdw6VmtUscHmyIBBmKxd3NU52b3WB93KxeF32zfqYystK0+NfX9f4TO1TFJ1CSVMUnUE/e8aEefqOthlz3grw9/Qqt88t1U9W/4wPWEwFJCqxSW9d3GCZJ+uzn/+qJ2z9UcPUGkiRPd289eceHundSXZ3s+7IuZKXKaHSRn1d16/ZhIe1KvY+b9/2oecufl8FglMmUq/v7T1K3loN0LiVB7/4wVqeSYpWVk6FuLQbp/v6vSZL2xm7S7G8fkcmUq/C6HRV9YqceGfSmWjfqpUa1Le8xg6HgHYOdmg6w/t2gVoRkNis57Yy8qhcvQTbnx2f05+H1ys3LkY+nv5684yPVDWqir3+ZqbjEKD15x4eSpLSM8xo2tbHmPRslf+/q+vqXmVr/51fKM+Wqqk+QnrhjjmpWq69PV72sI/F7lJGdpjPnj2vag6u1fvdXWvBstCSpSd2OCvCvrT9j1qtdeJ9SP8cAUFF0C7Mc1K7YU7zyr68oWf3XhFmG8AIAVEzBVaWRvaQP1xVvPrKS/h+oU81SP3NNOA7Oicv2nPhqTfliiI6fOajc3GzVqFpXT9/5iar719Lb341RgH9t3XvdREnS8dMH9eyHffS/CUdkllnzV76oXdFrlZObrZAa4Xri9jny866m6V8Ol9Fo1MnEaJ1PO61Zj/yqqLjtmjpqlSTp2ojb9c53Y3QiMVp1AhuX+f4AAGyvVV3p9o7SN8W896Gkx4Nt6km3tS95XLAtp0uQrV271t4hOITvNr6lri0G6eipfXJz9VD9ms3zra9fs7nc3Dx19PQ+NavXudA6DsX9oe79JxW6LinttBKTT6h5/a75lvv7BKhOYJgOndihayNuV8vQ7ho6ub5aNeyp5qHd1LvtvQqsUqdU+zR/xQt64vY5ah7aVSaTSReyUiRJ0xcN0z29J6p1o57Ky8vVC3Nv0vrdX6tbi0Ga9NlgPXPXPLUL76PtB1dp1fb5JW535fZ5qlW9ofWOv+IYHPmsRg+cKUlat+tLvffD45oyaoUGdB6p+6eFa9SN0+XrVVUrt81TtxaD5O9dXWt3fqHjZw7qrTGb5WJ00eo//qfZ3z6iSSOWSZL2HdusD57YqWp+NZWSflZ5eTmq7l/L2mbNaqE6ff5YifcPACqq/q0kNxdp6a7i3zFWHL2bSQPbWoZtAABUXGE1pYd6Sx+vlzKyy67eBjWkUT0lb/eyqxMVD+fEV39O/N2Gt7Ri61wFVaun4f1eU+M6bYq97cM3v6mqvpbhGb9cO1Wfrn5ZT9z+gW655jFN+LifBkc+Kxeji5Zsfk83dH5QLi6u+mLNZHm6+eidsZZhBD5b/armrXhBY297V5Ll9XjjkY3y9vRTVNwfqu4fLBcXy2Uzg8GgoGr1dPr8MRJkAOBAuodLrkbLCDOmMrww0KmhpYfaFUZaRgXgdAkyXL0v1kzWycRoTR+9RrEJf8mgoq8Aerh6lVscRqNRLw1brGOnD+jPmPXadnC5vlgzSe8+vr1UB6xtG1+n95Y8rmsj7lD78OvVuE4bZWSna2f0GiWlnrKWy8xOU9yZgzp++oBcjK7WHlUdmlyv4OoNS9TmjkNr9L/Vr2jaqNUylOBK6o5Dq/X9xreVkZUqk9mk1AuWCRR8varq2lZ3aMXWubq9x5P6cfP7emHoIknSb399r6jj2/TIm5ZbF0zm/LfKdmp6g6r51SxR/ABQ2V3XwjJB7xdbpLNpV1dXFS/prs5Si9JdkwIA2EGjIOnZG6VFv0v7T15dXS5Gy/C61zWn55ij45z46s+JHxgwSdX9gmU0GrVxz3d6/pMBmv/sIXl5+BZr+7U7v9DPO/6nnJxMZedmyv9i7726QU1Ur2Zzbdr7gzo06adfdi7Uh09bhgzYtPd7pWcma8OexZKk3Lxs1aweaq2zR6s7i+ztBwBwXF0aS3WqS19sluLPX11d3u7S7R2kdqHcNFtZkCBDiXz9y0xt/OtbTX/wZ3m6e6t+zebKzs3U0VP78t0xd/TUPrka3RQS1KTIusJC2mv/0c3qHnFrgXXVfIMUWKWO9h3dnG8Yi5T0szqReEhhdf4eNqJeUFPVC2qqm7qO1oSP+mvz3iW6o+dTJd63h25+XbEJe7UrZp1mLBqm3m2H6OZuj0iS3n5si9zdPPOVP3zyzwJ1lCTJtTtmvWZ+db9evf9H1b3M8/Rvp5OO6Z3vxuidsdtUO7CRDp/8U0+938O6/pbuY/WfeTerXs1mquJTQ43rtJUkmWXW3b0n6MYuDxZar5f73yci/j4BcjG66lxKgrUX2amkWAVVrVfsOAGgsmhUUxp/o7Ryj7TpkJSZU7Lt3V0sd4fd0Fry9iifGAEA5aeqt/RgL2nbEWnVX1JiasnraBos3dxWql2tzMNDBcM58d+u5pz4n73cukfcqk+WP6fjZw4qPOTKY1H9dWSjvt84W289tlnVfIO0ae8SLVj5H+v6W7s/rq/WTVNy2hm1C+9rvRHUbDbr0UFvq0OT6wut95/JuRpV6+pcSrx1PjKz2azTScc4JwYAB1W3uvR0f2ntPunXg1JaVsm2dzFakmID20j+5XdvDMoB97Wh2L5Z/7rW7VqoaaNWWyf39fLw1a3dH9ebi0crOT1RkuWA/c3FozXihqlydy36SuHgXuO1Yttc/b5/mXXZuZQErdq+QJJ0b+/nNWfp04o/d0SSlJl9QW9886CuaXmragc2UmLyCf115DfrtqkXkpSQdES1AxqVav+OnT6g0FotdMs1Y3RT14e1/9gWeXn4qk2jSH25bqq1XGLySZ05H6e6QU2VZ8rVruh1kqQdUT/r5NmYYrX15+FfNe3L+/Tf4T9Yx2UvrvTMZLm4uKm6f7DMZrN+2PROvvX1gpoquHpDvfnNgxp0zRjr8mta3KKlWz5QysXeZrl5OYo+sbPIdq5tdaeWbvlAknTw+DYlJp9Qq0Y9SxQrAFQWHq6WC5uv3Cbd3VlqWMMy/GJRXIxSvQDptg6Wbe7oRHIMACozg8Fys8PEgdLDvaXWdSWfK3yv1/CTIptJz99sGaqR5Jjj45zYoizOic+cj7P+ve/oFqWkn1WdgOL1ekvNSJKXh5/8vQOUk5utZVvm5FvfIfx6nUtN0BdrXtOgbn+fE3dreYu+3fCGMrMvSLI8n7EJewtto5pvkBrXaaefd3wmSdqwZ7ECq4YwvCIAODBXF+n6COnlW6X7uknhtSzXCopiNFjmnR3YRnrlVmlIV5JjlRE9yFAsZ87Hac7SpxVcvaGe+SBSkuTu6qG3x/6uEQOm6KtfpuuJd6+RJCWcO6JHB72tGzqPvGydDYIjNHnkcs1d/rze+f4xebr7yNvDT4Mjn5MkDez2sFxc3PSfuQOVZ85Tbm62ro24XcP6vypJyjPl6rOf/6uEc0fk4eYtkylXfdsPU7eWg0q1j3OXT1TcmYNydXGXh5u3Hr/tfUnSc/d+rjlLntKomS0lg0Ge7j564vY5qlE1RM8PXWSZkNicpyZ1O6ph8N/JrpXb5mv+yheUdiFJm/Z+r6/Xz9Sr9/+oxnXaatbXI5STm6UZi+63ln/unv+pQXDEFeNsEByhXm3u1qiZLeTnE6BrWtxSoMwNnUfpne/HqEerO6zLrms3RCkXzmrcxdcvz5Srfh0fsPYw+7dRN07T1IX3adi0MLm5uOu5ez6Tq4tbsZ5LAKisPFwtwyt0aSzlmaRTyZYhFrJyLfOUebhKNatIwVUsB88AAMdiNEhNgi0/ZrOUlC7FJUnpWZb/C24uUnVfKaSa5MUcY06Fc+KyPSeesWi4ktJOyWhwkYebl16872v5eFUpVpwdm/TXmh2f6YHpTeTvHaC2YX2UmHzCut5gMKh/pxFat/MLNQ/9ew63u3s9q//lZumxtztbh8UcHPmsQmu1KLSdJ26foxmLhmvh2sny9vTXuLvmlfg5BQBUPq4uUvsGlh+TSTqdKp1MslwXMJkkN1eppr/l5qjL3ViLysFgNpvLcl56lIH09HT5+lq69qelpcnHx6fc28zLltbNLpu6vt3wpr7bOFszRq9VrX+M5+0MHnmrg0bfNFOtG/WyaxxvfzdG1XxramjfF23WZuRYycWBLxK89K2UnGGZY+iV2+wdDWyN1x/Ojs8AeA8AcAZldV7MObH9z4lfmHuTerYerL7t77NZm456Tjz53c+VkpYuf18fTXx0SIHHzoTjIefG6w9UrM9BWeVQGGIRZe62a5/Q/yYcdroTgYogMfmkHpjeVNEndui2a5+wdzgAAAAA4HQ4J7afg8e3a9jUxjIYjOrd9l57hwMAACo4hlhEuYo+sUszFg0vsPz6DsN0e48nHS6e9x7fflXbv7n4Ie0/uqXA8tmPbZaH25UHsQ2sUltzxx+4qhgAAAAAAGWDc+KSeXHezTqddCzfMj/vapr50Lpibd+kbgcteC76qmIAAADOgwQZylXjOm0056ld9g7DqqLF829P3P6BvUMAAAAAAJSRinYOWtHi+bdX719i7xAAAIATYYhFAAAAAAAAAAAAOBV6kEGSZHSzTCgLlJbRzd4RAAAAAEDpcV6Mq8E5MQAAlQ8JMkiSDAbJxd3eUQAAAAAAYB+cFwMAADgXhlgEAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKdCggwAAAAAAAAAAABOhQQZAAAAAAAAAAAAnAoJMgAAAAAAAAAAADgVEmQAAAAAAAAAAABwKiTIAAAAAAAAAAAA4FRIkAEAAAAAAAAAAMCpkCADAAAAAAAAAACAUyFBBgAAAAAAAAAAAKfiau8AAAAAAAD2ZTZLphx7R4HKzOgmGQz2jgIAAAAoPhJkAAAAAODkTDnSutn2jgKVWeRYycXd3lEAAAAAxccQiwAAAAAAAAAAAHAqJMgAAAAAAAAAAADgVEiQAQAAAAAAAAAAwKmQIAMAAAAAAAAAAIBTIUEGAEARcvOkE0mW35cen78gmc32jQsAbCUnTzp+Lv/3YGqmfWMCAAAAbCXPJMWfz388fC6N6wKAo3C1dwAAAFQkp5KlzdHS4TOW5Fie6e916dnSy99Jfp5S3epSq7pSu1DJnf+mABzI8XPS79HSkUTLxQDTP07+07OlFxdLVb0t34Nt6kut60quLnYLFwAAAChTZ9OkLdHSoVOW6wI5eX+vS8+W/vuD5OMhhVSXWtSROjaQvNztFy+A0uOSHgAAkqISpNV/WQ6AryQ1U9p30vLzw06pU0Pp+paWA2QAqKz+PC6t2ScdTbxy2fMXLD974qTvPKVujaXrmksebuUfJwAAAFAeYhOlVXuk/SelK3UQS8+SDsZbfpbuktqHSv0iLDeSAag8SJABAJxaZo70/R/SlpjSbZ+RLa0/IP0RK93VydKrDAAqk9RM6Ztt0u5jpds+LVNa9Ze0/Yh0TxcprFbZxgfYwu6YX/TMB5H5lnm6+yikRrj6tLtPt1zzmFxcOH0GAMARZedKy/+UfjlQuqETs3MtI9HsPCrd1sHSo8xgKPs4AZQ9jvABAE4r/rz04Top6cLV15WWKc39VerSSLqzk+TCLJ8AKoHDp6VPfrXcAXu1zqVL766R+rSQbmzNRQFUTpFt7lGnpjfILLOSUhO0+o9P9cGPT+nY6f168o4P7R0eAAAoY2fTLNcFTqVcfV2ZOdIXm6W/4qSh3ZiOAagMuHwHAHBKceekt1eXTXLsn7bESJ9uzD93GQBURFEJ0vtryyY59k8/77X0SGPiclRGYXXaqU/7oerb/j7d1WucZj+2RTWqhGj51o91Pu2MvcMDAABl6EyqNHtV2STH/unP49JHv1h6lgGo2EiQFWHVqlXq37+/AgIC5O3trYiICE2ZMkXZ2dn2Dg0AcJUSU6UP1koXyukrffdx6aut5VM3AJSFuHPSx+vzTzheln47JP20u3zqBmzJy91HTet3kdls1smzpRyPGQAAVDipmdJ7a6TkjPKp/9ApacFGycRNY0CFRkfPQsyaNUvPPPOMJKl+/fqqV6+e/vrrL02cOFFLly7Vzz//LC8vLztHCQAoDZNZWrhFSitBj4mn+kv+XlJKhvT6iuJt83uM1Ky21KZe6eIEgPKSkyd9tqlkd7SW5nvw571S09pSo6DSxQlUFPEXE2P+3tXtHAkAACgLZrP0zVYpKb3425TmeHjvCem3KOnaJqWLE0D5owfZv2zdulXjxo2TwWDQ/PnzFRsbq507d+rAgQNq3LixNm3apAkTJtg7TABAKW2MkmJOl2wbfy+pqrfld0l8s9UyNxkAVCQr90gJySXbpjTfg2ZJCzcztAwql8ycC0pOT9T5tDM6Er9Hs799VNEndqpp3U4KqRFu7/AAAEAZ2HXMMvJLSZT2usCPuyyj2AComEiQ/curr74qs9ms+++/X8OGDbMub9SokT755BNJ0vvvv6/Tp0t4dRUAYHcXsqWlu2zXXlqWtGKP7doDgCs5myat3We79hLTpF8O2K494Gp9uuol3fFyDd35SpAefL2Vftz8nrq3vE2vDP/B3qEBAIAykJsnfbfddu1l51qSZAAqJodPkCUmJmr8+PFq3LixPD09VbduXT3++ONKT0/XiBEjZDAY9M4770iSUlNTtWrVKknSqFGjCtTVo0cPhYeHKzs7W0uWLLHpfgAArt62w7bvybDtsJSZY9s2AaAomw7Zfh6ETYekPJNt2wRK68bOD2raqNWaNOInjbxhmvy8qysxOU7ubp7WMnsOb9DA530L/Ax4zl39xrvYMXoAAHAlfx6XUmw80sue49L5C7ZtE0DxOPQcZLt27dKAAQOUkJAgHx8fNW/eXCdPntTs2bMVExOjc+fOSZLatGkjSdq5c6eys7Pl4eGhDh06FFpn9+7dFRUVpS1btmjkyJG22hUAwFUym6XfDtm+3axcafsRqTujMgGws9w8aUuM7ds9f8Ey/0KrurZvGyipOoFhahfeR5LUqekAtWzQXU++111vLX5Izw/9UpIU0fBa/TgpLd92ickn9ejsDhrUbYzNYwYAAMVnj+sCJrO0OVoa0Mr2bQO4PIftQZaYmKiBAwcqISFBTz/9tOLj47Vjxw4lJCRo2rRpWrZsmbZt2yaDwaBWrSzfTlFRUZKk+vXry9W18Nxho0aN8pUFAFQOCcnS6RT7tL37mH3aBYB/ijktpWfZp22+B1FZtQjtpj7t7tMvuxdpb+ymQstk52bplU9vU8vQ7rr3uok2jhAAABRXWmbJ5yQvKxwPAxWTwybIxo4dq7i4OI0ZM0YzZ86Un5+fdd348ePVunVr5ebmKjQ0VP7+/pKkpKQkSVK1atWKrPfSuktlAQCVw/Fz9m3bbOMhzQDg3+z9PQhUVkP6vCij0UULVv6n0PVvLX5I2TmZGjd4vm0DAwAAJWLPY9JTKZYRZgBULA6ZINu/f78WLVqkwMBATZkypdAy7du3lyS1bt3auiwz0zIArbu7e5F1e3h4SJIyMjKsy3755RcZDIYCP5eGbgQA2N/xs/ZrOzNHSky7cjkAKE/2vCBwJoX5GFF51QlsrMjWd2tn9BrtObwh37rvNs7W7/uX6pXh38vT3dtOEQIAgOKw53UBs1k6SX8LoMJxyDnIFi5cKJPJpCFDhsjX17fQMl5eXpLyJ8g8PS0TL2dnZxdZd1ZWVr7t/+ndd99Vu3btrI99fHxKHjwAoFzYO0GVmCrV8LtyOQAoL2dT7de2WdK5NKl20QM1ABXaPdc9r3W7FmrBqv9o5kPrJEm7otfp42XPavLI5apVPdS+AQIAgCuy93WBM6lSgxr2jQFAfg6ZIFu7dq0kKTIyssgycXFxkvInyIozfOLlhmFs3ry5unTpUvKALyMsLExGo0N29AMqlRsmbpN3lWDFJ8QrJKSjvcNBKfQYtUhBja8pdN1T/SX/gvc9WPl7/v375Vsv305KhvT6ioLLhw0foZP7VhYzWqBi4TvQMVz/9Dr5B4UVus4W34P9bxioc8d3FjNa2Jq7q5c+HGOHWesriNaNemn1jKLHQ65fs5lWTs+zPk44F6vXPrtLo26aodaNetkgwoovLDxM2bkZVy4IoFK59f4n5OPrf/E4MKTAY2fCMXHl1+med1SvzS2FrrPF8fDTzzyrI1s/L16wQAVUkb4HTSaT9e/u3btr587SnWs6ZILs6NGjkqT69esXuj43N1e//fabpPwJsvDwcOv2ubm5cnUt+PTExMTkK1ve4uPjbdIOgMvLy8uz/j5x4oSdo0FpZGZcKHKdv5dUtRijIhmNxStXmMQzp3jvoNLiO9AxZGdlFrnOFt+DpxJO6jTvnwrL043hAYsrM/uCXpp/i7o2v1m3XDPG3uFUGPEnTyozp+jjLQCVk+nicaDp4nHgvx87E46JK78L6UV3IbPF8fC5s2d476BSq6jfg6dOnSr1tg6ZIEtPT5eUf56wf1q0aJESExPl5+enBg0aWJe3bdtW7u7uysrK0vbt2wvtDbZx40ZJUufOnQusGzx4sBITExUQEKCbb75ZU6dOVWBg4FXtS3BwMD3IgArAxcXF+rtOnTp2jgalYTAXfWE45Qo3O/t7Wg6CTSYppehqLluXn7cr7x1UWnwHOgZzTnqR62zxPVjVz0NuvH8qLHfXy9wyjXw27Fmsw/G7dSIxSr/sXlRg/SfP7FNQtXp2iMy+gmvXpgcZ4ICMF48DjRePA//92JlwTFz5uaroSXFtcTzs48l7B5VbRfoeNJlM1s5FNWvWLHU9Dpkgq1WrlpKSkrRjxw517do137r4+HiNGzdOktSqVSsZDAbrOj8/P/Xt21fLli3TRx99VCBB9uuvvyoqKkru7u4aNGiQdXmVKlU0btw49ejRQ76+vtq8ebOmTJmiLVu2aPv27da5zUrj0KFDzGUGVAAvfSslZ0jBtYKtQ7Sicln9l7Rsd+HrChv64J9evtVyh1hKpvTydyVv2yDp91++l6dbybcFKgK+Ax3D4u3ShoOFryvv70FPN2n/7k0yGq5cFvaRly2tm23vKCqHvu3vU9/299k7jArnUNQhubjbOwoAZW3yu58rJS3dehz478fOhGPiym9LtPTl74WvK+/jYUlavvgjBfiWblugIqhI34Pp6eny9bV8oC51aioNh+ya1KdPH0nStGnTFBUVZV2+bds2RUZGKjExUZLUpk2bAtu+8MILMhgMmjdvnhYsWGBdHhMToxEjRkiSRo8eraCgIOu6tm3bavr06brpppvUq1cvTZgwQZ9//rn27t2rhQsXlscuAgBKKKS6/dqu4S+SYwDsLqTgFLq2a7u6SI4BAADArux5XcDbXapOHwigwnHIBNn48eMVEBCg48ePq0WLFoqIiFBYWJg6deqkhg0bqnfv3pLyzz92SZcuXTR16lSZzWYNHz5coaGhatu2rZo2baro6Gh17txZU6dOvWIMN910k3x8fLR9+/Yy3z8AQMnVD5Bc7PRfr2EN+7QLAP/UMOjKZcqtbb4HAQAAYGfBVSUvO/V2blBDMnDDGFDhOGSCLCQkRBs2bNCNN94oT09PxcbGqnr16pozZ46WLVtm7VVWWIJMsiTYVqxYob59+yo5OVkHDhxQeHi4Jk2apPXr18vbu/gzMRr45gOACsHbQ2pjp+lAuja2T7sA8E81/KSw0g/NXmoGSZ0b2b5dAAAA4J9cjFKnhvZpm+sCQMXkkHOQSVKzZs20dOnSAsvT0tIUGxsro9Goli1bFrl9v3791K9fv1K3v2TJEqWnp6tTp06lrgMAULauCZP+iLVtm3WrS/UCbNsmABTlmnDp0Cnbttm8jphrAQAAABXCNWHS+gO2bbOat9S8tm3bBFA8DpsgK8revXtlNpsVHh5eop5glzN06FA1bNhQ7dq1k6+vrzZv3qzp06erTZs2uvvuu8ukDQDA1WtQwzLM1+EztmvzuhYMowCg4ogIkYL8pdMptmvzuua2awsAAAC4nCB/qXU9afcx27XZu7lkdMhx3IDKz+kSZHv27JFU9PCKpdGiRQt98cUXevPNN5WRkaGQkBCNGjVKL730ktzd7TSwLQCgAINBuqeLNP0nKSev/NtrXdfyAwAVhYtRurer9NYqyWwu//auDbfv3GcoO9k5mZr0+d06emqfPNy8VNU3SGNve191AhvLbDbrq19maOW2uZLBIJMpT/07PqC7eo2X8QpXg6Li/tC85c8rLjFKft7V5ebiobt6jdM1LW+RJK3cNl/f/DpLeaZc5eXlqEerO/V/178iN1fLedaGPd9q4ZpJyjPlKSc3UwH+tTXtwZ/1wrybdDb5pCTpcPxuhdZqKaPBRd6efnrjkQ3l+lxdsmLrXC3e8IaOnd6v0TfN1G3XPmFdN3f589q8b4mMBhdJ0t29n1Nkm6Jvrkw4F6uH3mij7189X85R/y3uzCHNWDRMyemJ8vGsonGD5yu0VgubtQ8AQHm5vYN0KEG6kF3+bTWsYRnFAUDFRIKsDEyYMEETJkwos/oAAOWnhr90Y2vp+x3F3yYlI//v4vDxkO7oSO8xABVPaKAU2VRau7/425TmezDAV7qpTYlCQwV3Q+cH1anpABkMBn3/2zt6/euRmvXwL5q74nntOfyr3nh0o6r4BCo5PVEvzb9FqRlJGnXjtCLri03Yqwkf9dMzg+epa/OBkqTE5JPacWi1JGnZlg+1eMMbmjTiJwVXb6DM7AuatvA+zfp6hJ675386mxKvN795UO898YdqVqsvSToUt0MGg0GTR/xkbafvOIPeeGSDfL2qlt+TU4iwkPZ6YehX+nLtlALr7uo1Tg8MmCRJSkw+oREzmqldWB9V8Qm0aYyFycvLlYuLq95aPFo3dH5Q/ToO169/fqMZi4br3ce32Ts8AACumr+XJUn2v03F36Y0x8NuLtI9XSUj1wWACosEGQDA6fRsKp08L209XLzyr68oWf1uLtKIHpKfV4lDAwCbuLGNdCpF2nuieOVL+j3o7S6N7Cl5uJU4NFRQ7m6e6tzsBuvjZvW66Jv1M5WRlabFv76u95/YYU3uVPEJ1JN3fKiH32irIde9IG9Pv0Lr/HLdVPXv+IA1OSZJgVVq6/oOwyRJn/38Xz1x+4cKrt5AkuTp7q0n7/hQ906qq5N9X9aFrFQZjS7y86pu3T4spF2p93Hzvh81b/nzMhiMMplydX//SerWcpDOpSTo3R/G6lRSrLJyMtStxSDd3/81SdLe2E2a/e0jMplyFV63o6JP7NQjg95U60a91Ki25ZzTYCjYi+6fybqMrDSZZZbJbCp2rFO+GKLjZw4qNzdbNarW1dN3fqLq/rX09ndjFOBfW/deN1GSdPz0QT37YR/9b8IRmWXW/JUvalf0WuXkZiukRrieuH2O/LyrafqXw2U0GnUyMVrn005r1iO/Kipuu6aOWiVJujbidr3z3RidSIxWncDGpX2KAQCoMNo3sFwXWLOveOVLejxsNEjDu0s1Cj8MAlBBOF2CbO3atfYOAQBgZwaDNLiz5e/iJsmKy8NVGtmLIcUAVGwuRmn4tdL8DcVPkhWXr4f0UG8puGrZ1ouK5buNb6lri0E6emqf3Fw9VL9m/snm6tdsLjc3Tx09vU/N6nUutI5DcX+oe/9Jha5LSjutxOQTal6/a77l/j4BqhMYpkMndujaiNvVMrS7hk6ur1YNe6p5aDf1bnuvAqvUKdU+zV/xgp64fY6ah3aVyWTShSzLZH3TFw3TPb0nqnWjnsrLy9ULc2/S+t1fq1uLQZr02WA9c9c8tQvvo+0HV2nV9vnFbu+7jbO1ZNO7Sjwfpyfv/FjVfIt/8PDwzW+qqm8NSdKXa6fq09Uv64nbP9At1zymCR/30+DIZ+VidNGSze/phs4PysXFVV+smSxPNx+9M3arJOmz1a9q3ooXNPa2dyVZXo83Htkob08/RcX9oer+wXJxsVwyMBgMCqpWT6fPHyNBBgBwGDe1sQw7XpKRFYrDxSgN6y61CCnbegGUPadLkAEAIFkOWO/uItWqIv20W8ot/k3bRapdTRra1fIbACo6NxfpgR7Sij8td86aymBOsoY1LHOcBXKnrEP7Ys1knUyM1vTRaxSb8JcMKnrcIA/X8utObTQa9dKwxTp2+oD+jFmvbQeX64s1k/Tu49tLlcRp2/g6vbfkcV0bcYfah1+vxnXaKCM7XTuj1ygp9ZS1XGZ2muLOHNTx0wfkYnRVu/A+kqQOTa5XcPWGxW7v1u5jdWv3sYo5uVtTFw5Vh/Dr5e8TUKxt1+78Qj/v+J9ycjKVnZsp/4u99+oGNVG9ms21ae8P6tCkn37ZuVAfPm0ZRWXT3u+VnpmsDXsWS5Jy87JVs3qotc4ere4ssrcfAACOyGCQBra1TMXw/R9SVu7V1xnoJw3pKjWocfV1ASh/JMgAAE7LaJB6N5da1JG+2CIdTSx9PX1bSn1bSK4uZRsjAJQnF6NluMWIutLCzVJ8cunqcXOx3IF7bRPmWHB0X/8yUxv/+lbTH/xZnu7eql+zubJzM3X01L58vciOntonV6ObQoKaFFlXWEh77T+6Wd0jbi2wrppvkAKr1NG+o5vzDe2Ykn5WJxIPKazO30Mp1gtqqnpBTXVT19Ga8FF/bd67RHf0fKrE+/bQza8rNmGvdsWs04xFw9S77RDd3O0RSdLbj22Ru5tnvvKHT/5ZoA5DKSYfbVS7tQL962h3zC+6ttXtVyz/15GN+n7jbL312GZV8w3Spr1LtGDlf6zrb+3+uL5aN03JaWfULryvqvnVlCSZzWY9OuhtdWhyfaH1enn4Wv+uUbWuzqXEW+cjM5vNOp10TEFV65V4/wAAqMgMBqlrY6lpsPTlFulgQinrkdSjqWXOc3euuAOVRsHB0AEAcDI1q0hPXC89cp3Uum7xL+5W8ZL6t5JeukUa0IrkGIDKq16ANO4GaVRPqVltXaY/UH6BvtKgdtLLt1rmdyQ55ti+Wf+61u1aqGmjVlvn0PLy8NWt3R/Xm4tHKzndcqdJSvpZvbl4tEbcMFXurh5F1je413it2DZXv+9fZl12LiVBq7YvkCTd2/t5zVn6tOLPHZEkZWZf0BvfPKhrWt6q2oGNlJh8Qn8d+c26beqFJCUkHVHtgEal2r9jpw8otFYL3XLNGN3U9WHtP7ZFXh6+atMoUl+um2otl5h8UmfOx6luUFPlmXK1K3qdJGlH1M86eTamWG0dPfX3hCcnE2MUfXKn6v1rmMqipGYkycvDT/7eAcrJzdayLXPyre8Qfr3OpSboizWvaVC3Mdbl3Vreom83vKHM7AuSLM9nbMLeQtuo5hukxnXa6ecdn0mSNuxZrMCqIQyvCABwWNV8LMOEP9FP6tDAciNZcfh4SNc1l14YJN3anuQYUNnwkQUAQJa7xsJrWX5SM6TYROn4OelEknQhS8ozW3pIBPhKdatLIdUtF5SLe9AMABWd0WiZJ6FFiHT+wsXvwbOWycszsi1DMLq5SEH+lu/AS9+FJMWcw5nzcZqz9GkFV2+oZz6IlCS5u3ro7bG/a8SAKfrql+l64t1rJEkJ547o0UFv64bOIy9bZ4PgCE0euVxzlz+vd75/TJ7uPvL28NPgyOckSQO7PSwXFzf9Z+5A5ZnzlJubrWsjbtew/q9KkvJMufrs5/8q4dwRebh5y2TKVd/2w9St5aBS7ePc5RMVd+agXF3c5eHmrcdve1+S9Ny9n2vOkqc0amZLyWCQp7uPnrh9jmpUDdHzQxdp9rePyGTOU5O6HdUwuLW1vpXb5mv+yheUdiFJm/b+P3t3HhdVvf9x/D0sw46iiBsKiuCK4L6mUZqWmdlmZaVpZplXy60y235WamqLrVZu3VvmzZZrWmqpuaaioplLKKmJgkmayr7N74/JSQIMRmBgzuv5ePiQOed8v+dz5naH8bzP9/v9Up+un6Wp93+lJvXb6P0Vk5R85ohcXdzl6uqm0Te/qZDazUtUZ4emfbVm13807OWm8veuqTbhvZRy7q/FBE0mk/p2HK51cR+rRehfa7jdefXj+ndulv71RifbtJiDYh5XaJ2WRZ7n0VvnauaSoVq89iV5e/pr4h0LSv2eAgBQlZhMUmig9c/Adn/dF0g8I6VlSXn5kpuLNUxr8Of34YaB1u/IAKomk8ViKYPVBlCW0tLS5Otrnd4iNTVVPj4+Dq4IwLOfS+cyrCOGnr/F0dUAQMXiMxBwfnnZ0ro5ZdPX5xtf0xeb5mjmyLWqc8kaV0Yw6vX2GnnjLEWFXe3QOqbMv1E9owapd7t7K+ycMWMkV3OFnQ5ABXnprY90PjVN/r4+mvzI4EKvjYTvxACMrjJ9DpZVhsJz7wAAAACAMnPLVY/q30/+YrhwrDL4+fgODZneRCaTi65pc7ejywEAAAAqNaZYBAAAAACUi8MndmvmkqGFtl/Xfohu7fGY09Xz9tgdV9T+6QU36bezvxbY5ucdoFkPrStR+6YN2mvRE4evqAYAAADAKAjIAAAAAADlokn9aM0dt9vRZdhUtnr+bur9yxxdAgAAAGAYTLEIAAAAAAAAAAAAQyEgAwAAAAAAAAAAgKEwxSIAAAAAGJyLuxQzxtFVoCpzcXd0BQAAAEDpEJABAAAAgMGZTJKr2dFVAAAAAEDFYYpFAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAyFgAwAAAAAAAAAAACGQkAGAAAAAAAAAAAAQyEgAwAAAAAAAAAAgKEQkAEAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMhYAMAAAAAAAAAAAAhkJABgAAAAAAAAAAAEMhIAMAAAAAAAAAAIChEJABAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADAUAjIAAAAAAAAAAAAYipujCwAAAAAczWKR8nMcXQWqMhd3yWRydBUAAAAAgJIiIAMAAIDh5edI6+Y4ugpUZTFjJFezo6sAAAAAAJQUUywCAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADMXN0QUAQGVzLl2KT5aOn5ESz0jnMqTzmdZ9qVnSZzukBjWk8NpSgI9jawWA8vB7qnTolJT4u3T87F+fgRcypTe+lYJrWD8Hm9aR/LwcWysAAABQ1lIzC94XOJt2yX2BTOm/263fh5vUlmr5ObZWACgPf6RLhwxwf5SADAAkWSzWm8Gb46W9iVK+pejj8vKljT9bfzaZpJb1pW7hUtO6koup4uoFgLKWny8dOCltjJcOJhVzjEVK+M36R5JcXaTWDaTuEVLjWtbPRQAAAKCqOnLael8g7lfrv/+LkmeRthz663VEHev34Zb1rd+PAaCqunh/dFO89FMp7492j7B+Hla1+6MEZAAM72ya9MlW6efk0rWzWKy/LH5KlMKCpLs6S4E8OQagCko+Jy3+QTr2e+na5eVLccesf1rWl+7oJFVjRFmVtCfhe014N6bANk+zj4JrRahX23t1c7d/ydWVfzoAAADndCFTWhor7fm19G3jk61/gmtId3eW6gWUfX0AUN7OpEqfbLN+npXGpfdHm9SW7uxUte6P8q9cAIa2LUH6fIeUlXtl/ST8Jr28QrqprXVEGaMoAFQFFov0/UFpxW4pt5gnZEtq3wlp+nLp9g5S29CyqA6OEBN9lzo2u0EWWXT2QrK+3fmh3v1qnH797YAeu+09R5cHAABQ5n48Li3ZJqVlXVk/iWek2SulvpHStS2r3igKAMa1NUH6ogzujx4+Zb0/OqCt1C2ibGorbwRkAAzJYpFW7ZVW7i27PrPzrE+cnUmV+rchJANQueVbpM9ipc2H/vnYksrIlj7cbJ2bPKZ52fWLihNev616tbvH9rp/11Ea/nIzfbP9A93f90VV963lwOoAAADK1qZ467/jy0pevrRij3T6gnUUhQtTLgKoxCwW673RVWV8f/TTWOlMmnRjdOW/P8rHNABD+m5f2YZjl1p7QPp6T/n0DQBlwWKRvthZtuHYpf6366/5yFG1eZl91CyksywWi07+nuDocgAAAMrM1sNlG45davsv0n+3W793A0Bl9e2+sg3HLrVmv/TNj+XTd1kiICvG6tWr1bdvX9WsWVPe3t6KjIzUtGnTlJ2d7ejSAFyhg0nWJ7rK07f7rNM0AEBltONI+QdYn++wLnKOqi/pz2DM37uGgysBAAAoG8fPWAOs8rQ1QfrhcPmeAwDsdeBk+T/gv/on69pklRlTLBZh9uzZmjBhgiQpJCREDRs21E8//aTJkydr+fLl+u677+TlxQr0QFWUmSN9srX07cb1lfy9pPMZ0isrS9bm0+1SWJDk41H68wFAeTmXLn2+s3Rt7PkMtEj6+Adp4g2SmW+cVUZmTrrOpaXIYrGuQfbVD+/q8Ik4NWvQUcG1qsgk8gAAAJeRm2f9nppfytFd9nwn/t8uqVldqYZv6esEgPKSkW1de7G07Pkc/O82qVGtynt/lBFkf7N9+3ZNnDhRJpNJCxcu1NGjRxUXF6eDBw+qSZMm2rJli5588klHlwnATst3S3+kl76dv5dU3dv6d0ldyLR+GQaAyuSzHdYvw6Vhz2egZF17obyma0D5+HD1s7rtuVq6/fkgPfhKa331w9vq3uoWPT/0f44uDQAAoEys2S8l/VH6dvZ8J87Kta7FAwCVSUXeHz2fKS2LK/25KgrP8/7N1KlTZbFYNGzYMA0ZMsS2PSwsTPPmzVPPnj31zjvvaPLkyQoKCnJgpQBKKy1L2lbBy6fsOCL1i5aqMegUQCVw+kLFT/+6+ZB0XaTkwbfOKqFfpwfVo/Xtys3P0ZGkvVry/QylnEuU2d3TdszeXzZq8rzrC7XNzctWfn6eVr2cV5ElAwAAlFhOnrShgtfKPXDSGsjVrV6x5wWAoqRmOuj+aFTpH7qtCE4/giwlJUWTJk1SkyZN5OnpqQYNGmjs2LFKS0vT8OHDZTKZ9Oabb0qSLly4oNWrV0uSRowYUaivHj16KCIiQtnZ2Vq2bFmFXgeAK7f9F+uX4YqUb2HOcQCVx5ZDFX/OzBxp19GKPy/sUz8wXG0jeqljs+s1KGaSpt7/lX5OjNXrnz1kOyay8VX66sXUAn8WTIqXv0+ghvSZ6sDqAQAALm/Pr9aHZyva5viKPycAFGX7L1JufsWeMy9f2lpJ7486dUC2e/duRUZGaubMmUpOTlaLFi2Uk5OjOXPmaNCgQTpw4IAkKTo6WpIUFxen7OxseXh4qH379kX22b17d0nS1q12LGIEwKEq+ukI23kr6S8AAMaSb3Hc52Bl/SKMf9YytKt6tb1X3+9Zon1HtxR5THZulp7/8Ba1Cu2uu6+dXMEVAgAAlJyjvg/HHrGufQYAjrbVUfcFHHTef+K0AVlKSor69++v5ORkjR8/XklJSdq1a5eSk5M1Y8YMrVixQrGxsTKZTGrdurUkKT7e+jhHSEiI3NyKngcoLCyswLEAqob0bCn5nGPOfTZdOmfHvL4AUJZOn7d+FjpC4lluCFRlg3s9LRcXVy1a9UyR+1//7CFl52Rq4qCFFVsYAABAKeTnS8dSHHPurFzH3ZMAgIvSsqTfzjvm3GfSpPMZjjn35ThtQDZmzBglJiZq9OjRmjVrlvz8/Gz7Jk2apKioKOXm5io0NFT+/v6SpLNnz0qSAgICiu334r6LxwKoGhLPOPb8xx18fgBw5OdQXr508g/HnR9Xpn5gE8VE3am4w2u095eNBfZ9sWmOth1YrueHfilPs7eDKgQAAPhnp85L2Q58aIv7AgAcjfujhTllQHbgwAEtWbJEgYGBmjZtWpHHtGvXTpIUFRVl25aZmSlJMpvNxfbt4eEhScrIKBx3fvHFF+ratat8fHxUrVo1devWTfv27bP7OgCUHUffmD1Jpg7AwfgcxJW469qn5GJy0aLVf40i2314nT5Y8bievvdT1akR6rjiAAAASoDvwwCMjs/BwoqeR7CKW7x4sfLz8zV48GD5+voWeYyXl5ekggGZp6enJCk7u/j5h7Kysgq0v2jOnDkaP368HnvsMU2dOlVZWVnatm1bkUFaaYSHh8vFxSlzTKBCNb/2UbW8bkKR+8b1lfy9itxl4+/519/PDSz+uPMZ0isrC29/dc7bGvbNSyWsFgDKXpubX1JYl/uK3PdPn4Ml/QyUiv8cfHLKczq06YMSVlvxzG5eem/0IUeX4TBRYVfr25mWYveH1G6uVS//9ch18pmjeuE/d2jEjTMVFXZ1BVRY+YVHhCs7txLOGQIAwBUYeP+j8vH1V1JykoKDgwu9rkoadRqsdrfMKHJfRdwX+PfH/9XYgeNKWC0AlL0WvcapRe+iP4cq4nNw9mtv6v6V00tY7eXl5+fbfu7evbvi4uLs6scpA7K1a9dKkmJiYoo9JjExUVLBgKwk0ycWNQ1jQkKCJk6cqFdffVWjR4+2bb/hhhvsqL6gpKSkK+4DgBScmlrsPn8vqXoJZ4VycSn5sZdKTUvXiRMnSt8QAMpI08s8tFPSz0F7PwMl6fyF1Er9OejpzvSAJZWZna5nF96sLi1u0s3dRv9zA4NIOnlSmTksOgoAcC75eXm2v0+cOFHodVVS8/yFYvdVxH2BjMysKveeAXAuDdLSit1Xle+Pnjp1yu62ThmQHTt2TJIUEhJS5P7c3Fxt3rxZUsGALCIiwtY+NzdXbm6F356EhIQCx0rS/Pnz5e7urhEjRpTNBVyibt26jCADyoCPZ/FTp5ZkgUh/T+uHf36+dD6z+OOK68vb003169f/5xMBQDnxNLsWu++fPgdL+hl4ub58vMyV+nPQ7PYPj8rBZuPez/RL0h6dSInX93uWFNo/b8J+BQU0dEBljlW3Xj1GkAEAnI6Lq6vt7/r16xd6XZX4+ngWu68i7gt4uLtUufcMgHPx8XQvdl/F3B91L7PPwfz8fNvgotq1a9vdj8lisRQ/l0oVVaNGDZ09e1ZbtmxRly5dCu3/6KOPdM8998jPz0/nzp2TyWSSJF24cEGBgYHKzs7WDz/8oM6dOxdq27RpU8XHx+u9996zBWIxMTE6f/68Ro0apRdeeEHHjx9XeHi4nnnmGd11112lrj8tLc02NWRqaqp8fHxK3QeAgn48Ls3fYH/75wZan4z4I1167ovSt7+nq9S+kf3nB4ArtSleWhprX9sr/QyUpFHXShF17GtbEfKypXVzHF0FqrKYMZJr8c/jAABQJb301kc6n5omf18fTX5kcKHXVcmR09Lrq+1vf6XfiQe0lWKa239+ALhSe36VFmy0v/2Vfg7e21VqV0b3R8sqQ3HKoUl16ljvvuzatavQvqSkJE2cOFGS1Lp1a1s4Jkl+fn7q3bu3JOn9998v1HbDhg2Kj4+X2WzWgAEDCvQZHx+vJ598Us8884xWrlyp6Oho3X333fruu+/K9NoA2KdBDWOfHwAc/TkUHPDPxwAAAADlpX6AdMltwArn6O/jAODoz6EGNR17/qI4ZUDWq1cvSdKMGTMUHx9v2x4bG6uYmBilpKRIkqKjowu1nTJlikwmkxYsWKBFixbZtickJGj48OGSpJEjRyooKMi2Lz8/X6mpqXrvvfd0//33q1evXvr444/VunVrTZ06tTwuEUApVfeWfIufTaFcebhJtfwdc24AuKhegOTqoG9+gX6St4djzg0AAABIktlNqlPNMec2SQomIAPgYAE+kq+D/m3u6W69N1DZOGVANmnSJNWsWVPHjx9Xy5YtFRkZqfDwcHXs2FGNGzfWNddcI6ng+mMXde7cWdOnT5fFYtHQoUMVGhqqNm3aqFmzZjp8+LA6deqk6dOnF2hTo4b1N9zFYE6STCaTevXqpZ9++qkcrxRASZlMUtuilyUsd21CJBcHPqUGAJLk7ipFBjvm3I76/AUAAAAu5ajvpS3qW28OA4AjmUzW+5SOUFnvjzplQBYcHKyNGzeqX79+8vT01NGjR1WjRg3NnTtXK1assI0qKyogk6wB28qVK9W7d2+dO3dOBw8eVEREhF588UWtX79e3t7eBY5v2bJlsbVkZv7DSvYAKky3cAedN8Ix5wWAv3PE55HJJHVpUvHnBQAAAP6uc5hjZlVw1P0IAPg7R92nrKyfg26OLqC8NG/eXMuXLy+0PTU1VUePHpWLi4tatWpVbPs+ffqoT58+JTrXgAEDNH/+fK1evVq33HKLJOu0i99++606dOhg3wUAKHO1q0lN60g/J1fcORsFOn5+XwC4qEmQVLe6lPRHxZ0zMtg6jQMAAADgaH5eUpuG0o6jFXfOQD+pWb2KOx8AXE6dalJEHSm+Au+PNq5VeaeZdcoRZJezb98+WSwWhYeHFxoJZq/+/fvrqquu0oMPPqj3339fq1at0qBBg7Rv3z4988wzZXIOAGXjlvaSWwV98rmYpFvJyAFUIiaTdHsH6xoIFcHDTRrQtoJOBgAAAJRA/zaSl7nizndHx8o5rRgA47qlfcWNpq3s90eddgRZcfbu3Sup+OkV7WEymbRs2TI9/vjjmjx5ss6fP6+oqCh9/fXXtvXOAFQOtatJN0RJy+LK/1y9W1XepyMAGFfjIKlHM2n9wfI/101tpJq+5X+eipCdk6kXP7pTx07tl4e7l6r7BmnMLe+ofmATWSwW/ff7mVoVO18ymZSfn6e+HYbpjqsnycXl8v/qiE/cqQXfPKXElHj5edeQu6uH7rh6orq1ulmStCp2oZZumK28/Fzl5eWoR+vbdd91z8vdzXpXZ+Pez7V4zYvKy89TTm6mavrX04wHv9OUBTfq93MnJUm/JO1RaJ1WcjG5ytvTT6+O2liu79VFK7fP12cbX9Wvvx3QyBtn6ZarHrXty8xO1+xPhyv+eKxMJhcNu/4l9Wh9W7F9JZ85qodejdaXU/8o/8L/lHj6kGYuGaJzaSny8aymiYMWKrRO8VOrAwCAqqGatzSwnfTxD+V/rq7h1pEaAFCZ1KkmXd9aWr67/M91XaRUP6D8z2MvArIyUr16dc2dO1dz584t034BlL2rm1mHER9MKnmb8xkF//4nYUFSb+6hAaik+kVJR05Lv/5esuNL+xkoSVENrTcEnMkNnR5Ux2bXy2Qy6cvNb+qVTx/Q7Ie/1/yVT2nvLxv06iObVM0nUOfSUvTswpt1IeOsRvSbUWx/R5P36cn3+2jCoAXq0qK/JCnl3EntOvStJGnF1vf02cZX9eLwr1W3RiNlZqdrxuJ7NfvT4Xrirn/r9/NJem3pg3r70Z2qHWBdaflQ4i6ZTCa9NPxr23l6TzTp1VEb5etVvfzenCKEB7fTlHv+q0/WTiu079P1s+Tu6qFFTxxW0pkjGjOnk6LDYuTvU7NCayxKXl6uXF3d9PpnI3VDpwfVp8NQbfhxqWYuGaq3xsY6ujwAAFAGOjSS4pNKN9Viab8T1w+wPjAGAJVRTHPp0Cnp53K8Pxpeu/LfHyUgA2A4Li7SsB7Se99Lh0+VrM0rK0vef0igNOJqyc3VnuoAoPyZ3aSRMdLba6QTZ//5+NJ8BkpSi3rSvV2tUzo6C7O7pzo1v8H2unnDzlq6fpYyslL12YZX9M6ju1TNJ1CSVM0nUI/d9p4efrWNBl87Rd6efkX2+cm66erbYZgtHJOkwGr1dF37IZKk/3z3f3r01vdUt0YjSZKn2VuP3fae7n6xgU72fk7pWRfk4uIqP6+/hiuHB9s/p+UP+7/Sgm+eksnkovz8XN3f90V1bTVAZ84n663/jdGps0eVlZOhri0H6P6+L0iS9h3dojmfj1J+fq4iGnTQ4RNxGjXgNUWFXa2wetbv2yZT4VF06/cs0bjb50mS6tZopNZhV2vTT1/ohk4PlKjWaR8P1vHTPys3N1u1qjfQ+NvnqYZ/Hb3xxWjV9K+nu6+dLEk6/tvPevy9Xvr3k0dkkUULVz2t3YfXKic3W8G1IvTorXPl5x2glz8ZKhcXF51MOaw/Un/T7FEbFJ+4Q9NHrJYkXRV5q978YrROpBxW/cAmdr/HAACgcjCZpLu6SNl50o/HS9amNN+J61STHoqRPN3tqw8Aypvrxfuj66SE30rWpjSfg40CpeE9K24qR3tV8vLK3tq1a2WxWNSvXz9HlwLAgcxu0oNXS21CyrbflvWlUdfwJRhA5efjIT3SS2paxlO+dGxs/ZLt7A8JfLHpdXVpOUDHTu2Xu5uHQmq3KLA/pHYLubt76thv+4vt41DiTjUP6VLkvrOpvynl3Am1+Nt+f5+aqh8YrkMndqlx3dZqFdpd97wUoucWDtR/v5+plHMn7L6mhSun6NFb52ruuN2aO+5HtQ7rKUl6eckQ3dT1Eb05ZrvefTRO8cd3aP2eT5WTm60X/zNII2+cpfcn/KSY6Lv0S9KeEp3rtz9+tY16k6Q6AaH67Y9fS1zrwze9prfH7tB7439UZKOr9OG3z0mSbu72L3297T3l5edJkpb98LZu6PSgXF3d9N/vZ8rT3UdvjtmuueN2q1GdSC1YOcXW56HEnXph2ArNn3RQp/84rhr+deXqan2e0GQyKSigYalqBAAAlZurizSku9StjGc9CAuS/tVb8vMq234BoKx5/PnwbHTDsu23VbD00LVV4/6o4UaQAcBFZjfpvm5SZLD02Q4pLcv+vjzdrQtcdmjkXCMmADg3b7P00DXSlkPWtRmzcu3vy8/TugB5ZIOyq6+y+njNSzqZclgvj1yjo8k/yaTiP/g93MrvzoiLi4ueHfKZfv3toH5MWK/Yn7/Rx2te1Ftjd9g1yqlNk2v19rKxuiryNrWLuE5N6kcrIztNcYfX6OyFv4ZcZ2anKvH0zzr+20G5uripbUQvSVL7ptepbo3GZXZ9l7M27mN9t+vfysnJVHZupvz/HL3XIKipGtZuoS37/qf2Tfvo+7jFem+8dQaJLfu+VFrmOW3c+5kkKTcvW7VrhNr67NH69mJH+wEAAOfk6iLd3tH6sOuSbdK5Ukwp/nfurtKN0dJVTSUX7gsAqCLMbtaHBSKPSZ/FSunZ9vflZZZuaSe1r0L3RwnIABiaySS1DbXOibvuoLQtoXRBmZfZOloiprlU3bvcygSAcmMySd0ipOb1pHUHpO2/lC4o8/WUuoRJVze3jkpzdp9+P0ubfvpcLz/4nTzN3gqp3ULZuZk6dmp/gVFkx07tl5uLu4KDmhbbV3hwOx049oO6Rw4stC/AN0iB1epr/7EfCkzteD7td51IOaTw+n9NpdgwqJkaBjXTjV1G6sn3++qHfct0W89xpb62h256RUeT92l3wjrNXDJE17QZrJu6jpIkvfGvrTK7exY4/peTPxbqw1TCfwUFVW+oU2ePqaZ/XUlS8tmjahdxXYna/nRkk77cNEev/+sHBfgGacu+ZVq06hnb/oHdx+q/62boXOpptY3orQC/2pIki8WiRwa8ofZNiz6Pl4ev7eda1RvozPkk23pkFotFv539VUHVy/jRSgAAUCm0qC89fqO0/qD0w+HSrb1rdpPah0rXtJACedYGQBVkMkntQqWI2tb7AlsTSheUeZmlTn/eH61Wxe6PGm6KRQAoip+XdfHc5wZKg7tYfykE+avIMQG1/KxTM97ZWXp+oDSwHeEYgKqvhq90awfp+VusI8GiG0qBvoWPM5msayq0byTd20167mapX7QxwrGl61/Rut2LNWPEt/L1qi7JGqoM7D5Wr302UufSUiRZQ6zXPhup4TdMl9mt+Ddm0NWTtDJ2vrYdWGHbduZ8slbvWCRJuvuapzR3+XglnTkiScrMTterSx9Ut1YDVS8wTCnnTuinI5ttbS+kn1Xy2SOqVzPMruv79beDCq3TUjd3G60buzysA79ulZeHr6LDYvTJuum241LOndTpPxLVIKiZ8vJztfvwOknSrvjvdPL3hBKdq0fr27X8h3clSUlnjujHhO/VrdXNJWp7IeOsvDz85O9dUzm52VqxdW6B/e0jrtOZC8n6eM0LGtB1tG1711Y36/ONryozO12S9f08mryvyHME+AapSf22+m7XfyRJG/d+psDqwaw/BgCAE/M2S9e3lp69WRraXerQWKpbrehREDV9paiG0m0drPcF7uhEOAag6vPzkm5qa70/encJ7o+2DZHu+vP+6M3tql44JjGCDAAKcHe1fgnu8OcMUZk50oVMKTdPcnOxjpTwMju2RgAoT57uUtdw6x/J+tRYWqaUm29dV8zfU/KoAvOIl7XTfyRq7vLxqlujsSa8GyNJMrt56I0x2zT8+mn67/cv69G3ukmSks8c0SMD3tANnR64bJ+N6kbqpQe+0fxvntKbX/5LnmYfeXv4aVDME5Kk/l0flquru56Z3195ljzl5mbrqshbNaTvVElSXn6u/vPd/yn5zBF5uHsrPz9XvdsNUddWA+y6xvnfTFbi6Z/l5mqWh7u3xt7yjiTpibs/0txl4zRiVivJZJKn2UeP3jpXtaoH66l7lmjO56OUb8lT0wYd1LhulK2/VbELtXDVFKWmn9WWfV/q0/WzNPX+r9SkfhvdfvVEzf7vMN03LUwuLq4aPfBNVftzmsR/0qFpX63Z9R8Ne7mp/L1rqk14rwJrr5lMJvXtOFzr4j5Wi9C/1nC78+rH9e/cLP3rjU62aTEHxTyu0DotizzPo7fO1cwlQ7V47Uvy9vTXxDsWlPo9BQAAVY+rixQdYv0jSdm51qkXL94X8PYwxsNhAIzL7GadMaujAe6PmiwWi8XRRaCgtLQ0+fpaH9lOTU2Vj4+PgysCAABwbnnZ0ro5ZdPX5xtf0xeb5mjmyLWqc8kaV0Yw6vX2GnnjLEWFXe3QOqbMv1E9owapd7t7K+ycMWMkVyf5RyIAABe99NZHOp+aJn9fH01+ZHCh1wAAOEJZZShMsQgAAACUoVuuelT/fvIXw4VjlcHPx3doyPQmMplcdE2bux1dDgAAAACgEmOKRQAAAKCcHD6xWzOXDC20/br2Q3Rrj8ecrp63x+64ovZPL7hJv539tcA2P+8AzXpoXYnaN23QXoueOHxFNQAAAAAAjIGADAAAACgnTepHa+643Y4uw6ay1fN3U+9f5ugSAAAAAAAGwRSLAAAAAAAAAAAAMBRGkAEAAMDwXNylmDGOrgJVmYu7oysAAAAAAJQGARkAAAAMz2SSXM2OrgIAAAAAAFQUplgEAAAAAAAAAACAoRCQAQAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAyFgAwAAAAAAAAAAACGQkAGAAAAAAAAAAAAQyEgAwAAAAAAAAAAgKEQkAEAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMhYAMAAAAAAAAAAAAhkJABgAAAAAAAAAAAEMhIAMAAAAAAAAAAIChEJABAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADIWArAoLDQ2VyWQq9Kdly5aOLg0AAAAAAAAo5Ouvv1Z0dLQ8PDwUGhqqV155xdElAQAMys3RBcB+sbGxysvLs71OTU1V69atdeeddzqwKgAAAAAAAKCwHTt2aMCAAZowYYIWL16sbdu26aGHHpK3t7ceeughR5cHADAYArIqrFatWgVev//++8rJydEDDzzgoIoAAAAAAACAor3yyivq0KGDpk2bJklq3ry59u3bp+nTpxOQAQAqHFMsOpG5c+eqf//+qlu3rqNLAQAAAAAAQBWRn5+vM+cuFPqTb8m37rfkF/n60j/pGZn/eJ7Nmzerb9++Bbb17dtXx44dU2JiYtlfGAAAl8EIMiexY8cO7dy5Uy+++KKjSwEAAAAAAEAVYjKZtOzbzTqY8GuR+1PTMvTyu4uLfe3q4qJR990sby/Py54nKSlJderUKbDt4uukpCQFBwfbewkAAJQaI8icxNy5c9WoUSNdd911ji4FAAAAAAAAVYjJZNKtfXvI28vDrva9urdT/dqBZVwVAADli4DMCZw/f16LFy/Wgw8+KJPJ5OhyAAAAAAAAUMX4+Xrrlj49St0upH5t9ewUVaJj69atq+Tk5ALbTp06ZdsHAEBFIiBzAv/5z3+UnZ2t+++/39GlAAAAAAAAoIpq1bSR2raKKPHxZnc33dEvRi4uJbvF2K1bN61atarAtpUrVyokJITpFQEAFY6AzAnMnTtXN998s2rXru3oUgAAAAAAAFCF3dSrq6r7+5bo2Buv6aKaAf4l7vuxxx7T9u3b9dRTT+ngwYNatGiR3njjDT3xxBP2lgsAgN0IyK7A+fPn9cQTTyg8PFyenp6qXbu2br31Vu3YsaPCati6dat+/PFHjRw5ssLOCQAAAAAAAOfk6WHWHf2u1j8t4tEsrKE6RDUrVd8dOnTQl19+qeXLlysqKkrPPPOMXnzxRT300EP2FwwAgJ1MFovF4ugiqqLffvtNXbt2VUJCgjw9PdWiRQudPHlSycnJcnNz0yeffKJbb73Vrr7T0tLk62t9Uic1NVU+Pj5XXO+ZcxcU4O/LGmUAAAAAAAD4RyvWbtXG2B+L3Ofj5alHh90mP1/vCq4KAICyy1AYQWanYcOGKSEhQZ06ddKxY8e0c+dOJSYmaurUqcrNzdV9992nEydOOLpMSVJ2Tq7e/vBLvfnhF/rjfKqjywEAAAAAAEAld12P9qodGFDkvoF9ryIcAwBUeQRkdti5c6dWrFghNzc3LV68WEFBQZIkV1dXTZkyRTExMUpPT9esWbMcXKnVtrj9Sk3PUHpGlvx8+PICAAAAAACAy3N3c9Og/tfI1aXg7cN2rSLUKqKRg6oCAKDsEJBdIi8vT//+97913XXXqVatWvLw8FDDhg3Vt29fffDBB8rLy5MkffbZZ5Kka6+9Vo0aFf5CMGLECEnS0qVLK674YmTn5Gr9tj2SpGu6tJGrK/+TAwAAAAAA4J/VC6qp3le1t72u7u+r/r26OrAiAADKDmnJn86fP6/evXvrvvvu07fffiuz2ayoqCjl5+dr9erVGjFihC5cuCBJ2rp1qySpe/fuRfZ1cXtiYqISExMr5gKKcXH0WEA1P7VtFeHQWgAAAAAAAFC19OjYWqHBdWSSdEe/q+XpYXZ0SQAAlAk3RxdQWQwfPlzr1q1TcHCwPvzwQ8XExNj2nTp1SvPmzZO7u7skKT4+XpIUFhZWZF/BwcEym83Kzs5WfHy8goOD7a5r5txPZPbwtKutxWJRanq6JCkjM0sz3l1sdx0AAAAAAAAwpnxLvsxmd33y1TpHlwIAgLKzMm0/v/PR/zThwbvt6oeATNY1xZYuXSo3Nzd98803atWqVYH9tWvX1uTJk22vz549K0kKCCh6oVKTyaTq1avrt99+sx1rr/Np6TLn5F1RH5KUmZWtzKzsK+4HAAAAAAAAxpSVnePoEgAAUHZ2lu3n1NQMu/shIJP05ZdfSpL69etXKBwrSmamNZ00m4sfUu7h4SFJysiw/38cSfL38bZrBNnF0WMWi+TpYZb5z9FvAAAAAAAAAAAAVVV2lqvtZ19fL7v7ISCTtH//fklSly5dSnS8p6en0tPTlZ1d/IisrCxrgunlZf//OJI0ceSd8vHxKXW7jdt/1Ip1WxVQzU8TRgySqyvLzQEAAAAAAAAAgKotLS1Nz49/QJL08OABdvdDaiLp/PnzkqRq1aqV6PiLUysWN32ixWLRH3/8UeDYipSdk6v12/ZIkq7p0oZwDAAAAAAAAAAA4BKMIJPk7+8vSTp37lyJjo+IiNCJEyeUkJBQ5P7ExETb6LKIiIhS1+Pt7a3U1FS989H/9NqCL2QymUrVPis7R1nZ2TKZTFq9cYe+3bSz1DUAAAAAAAAAAABUNhaLRc/O/kCSNO/TlRoz9Fa7+iEgk9SyZUt9/vnn+uGHH0p0fKdOnbRu3Tpt2rSpyP0Xt9evX1/BwcGlrsdkMsnHx0fZORZdSEsvdfuLLJYraw8AAAAAAAAAAFBZpaZl2t2WgEzSwIEDNXXqVH399dfav3+/WrRocdnjb731Vk2fPl1r1qzRkSNH1KhRowL733//fUnSbbfddkV1+dmxuNylo8d8vb1KPfoMAAAAAAAAAACgKrAnR7nIZLFYLGVYS5U1aNAg/fe//1XDhg314YcfqmfPnrZ9p06d0vz58zVmzBj5+PhIkq6//nqtXLlSnTt31v/+9z8FBQUpPz9fL730kp5++ml5eXkpPj7erhFk9srOydXL7y5WanqGbu3bQx2imlXYuQEAAAAAAAAAAKoKArI/nT9/XgMGDND3338vyTo9Yr169ZSUlKQTJ07IYrHo7Nmzql69uiQpOTlZ3bp10y+//CIvLy81b95cSUlJSkpKkpubmz766CPdcccdFXoNG7f/qBXrtiqgmp8mjBgkV1eXCj0/AAAAAAAAAABAVUCC8id/f3999913mjdvnq6++mqlp6drz549cnFxUZ8+fTRv3jz5+fnZjq9Tp4527dqliRMnql69etq3b59yc3N18803a8uWLRUejknS+dR0mUwmXdOlDeEYAAAAAAAAAABAMRhB5mRSzp5TgL8fARkAAAAAAAAAAEAxCMgAAAAAAAAAAABgKAwzAgAAAAAAAAAAgKEQkAEAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMhYAMAAAAAAAAAAAAhkJABgAAAAAAAAAAAEMhIAMAAAAAAAAAAIChEJABAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADIWADAAAAAAAAAAAAIZCQAYAAAAAAAAAAABDISADAAAAAAAAANnpRJAAAQAASURBVACAoRCQAQAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAyFgAwAAAAAAAAAAACGQkAGAAAAAAAAAAAAQyEgAwAAAAAAAAAAgKEQkAEAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMhYAMAAAAAAAAAAAAhkJABgAAAAAAAAAAAEMhIAMAAAAAAAAAAIChEJABAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADIWADAAAAAAAAAAAAIZCQAYAAAAAAAAAAABDISADAAAAAAAAAACAoRCQAQAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAyFgAwAAAAAAAAAAACGQkAGAAAAAAAAAAAAQyEgAwAAAAAAAAAAgKEQkAEAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMhYAMAAAAAAAAAAAAhkJABgAAAAAAAAAAAEMhIAMAAAAAAAAAAIChEJABAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADIWADAAAAAAAAAAAAIZCQAYAAAAAAAAAAABDISADAAAAAAAAAACAoRCQAQAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAyFgAwAAAAAAAAAAACGQkAGAAAAAAAAAAAAQyEgAwAAAAAAAAAAgKEQkAEAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMhYAMAAAAAAAAAAAAhkJABgAAAAAAAAAAAEMhIAMAAAAAAAAAAIChEJABAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADAUAjIAAAAAAAAAAAAYCgEZAAAAAAAAAAAADIWADAAAAAAAAAAAAIZCQAYAAAAAAAAAAABDISADAAAAAAAAAACAoRCQAQAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAwFAIyAAAAAAAAAAAAGAoBGQAAAAAAAAAAAAyFgAwAAAAAAAAAAACGQkAGAAAAAAAAAAAAQyEgAwAAAAAAAAAAgKEQkAEAAAAAAAAAAMBQCMgAAAAAAAAAAABgKARkAAAAAAAAAAAAMBQC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iSd2ahs4cGCBqulc9fX1OfHEEzNs2LAsXbo0Bx54YNavX7/T8x0AoHMIyLqwv548LlmyJFu2bMlFF11UoIqAvZk5c+ZOvx900EG555578uijjwrIAKBINDU15YMf/GAuu+yybN68WUAGFJ2ysrIMHjy40GUUxI033piGhob88Ic/TGVlZZLtgSEA0PlssdiNLF68OHPnzs2QIUMKXQrQAs3NzXnqqafys5/9LNOnTy90OQBAJ7n++utTUlKST33qU4UuBaAg1qxZk+HDh2f48OGZNWtWHn/88UKX1GnuvvvuTJkyJVdeeWWGDBmSww47LFdffXUaGhoKXRoAFB0ryLqJZ555JsuXL88NN9xQ6FKgS/rP9S9n0+bGndq2vrXFxdZt2/Li79bssS1Jelb0yIhhg1p0rTfeeCPDhg1LY2Njmpqacu211+byyy/viI8BALTR2g2vZOOmzTu1tWYuUNGjPCOH7301xLJly7Jo0aI899xzKSkp6ajyAdrtpbV/yJuNW3Zqa819sFfPihwwpHav1zn22GPzjW98I+PGjUtdXV0WL16cqVOn5v7778+pp57aUR+n1V6vq8/Lr76+S/tff949ff4kGTV8cHr0eOdHbatWrcrKlSszf/78/OAHP8i6devysY99LOvWrcudd97ZMR8GAGiRkubm5uZCF8HONm7cmJqamiTb96aurq7e65iLL744Dz/8cFatWuUPbWiDX7/4+9z+/QfaPP7cOdNz5PjRLerb1NSU1atXp6GhIY8//ng+85nP5KabbsqFF17Y5usDAO3z29+tya3fua/N48+cOSWTjhj3jn1eeeWVTJw4MbfeemtOO+20JMl1112XO+64IytXrmzztQE6wrO/ejHf+dGjbR6/4KwZGTd6ZJvGTps2LRUVFXnggbb/TdZeGxs253/d9t3Ub9zUpvHjRo/Mh848da/PZCorKzNgwIC89NJL6dGjR5Lkrrvuytlnn51XX301/fv3b9P1AYDWs8ViN1BXV5elS5fmIx/5iHAM2mj8mJE56j1j2jT2PYcelCPGHdLi/qWlpTnkkENy+OGHZ+HChfnkJz+Zz372s226NgDQMUaPGp7J7x3fprGHHnRAjp04dq/9fvWrX2XdunWZM2dOysvLU15ens9//vNZtWpVysvL861vfatN1wfoCEeOH50JY0a1aezRhx/a5nAsSSZPnpzf//73bR7fEaqremb+rJPaNLamqlfOOm1qi57JDBkyJGPGjNkRjiXJ+PHb//956aWX2nR9AKBtBGTdwB133JHGxsacf/75hS4FurS5pxyffn17t2pM75qqnDFzSrvC6aampmzevHnvHQGAd9WsaZMysH/fVo2p6lWZ+bNOatFc4Jhjjskvf/nLrFixYsfPwoULc8ABB2TFihWZPXt2W0sHaLeSkpKcOXNqelf3atW4/n17Z+7Jk9t17WeffTYHHHBAu87REQ47eESOnXhYq8edNevE1FS17N9t6tSpWblyZbZu3bqj7YUXXkiSjBw5stXXBgDaTkDWDSxevDhnnHFGBg1q2fuPgN3rWVmRs2dPS2uirvmzTkp1r54t7n/ttdfmoYceyurVq/PCCy9kyZIl+fKXv5zzzjuv9QUDAB2qokd5zpkzPaWt+OLLWTNPTO+aqhb1ra6uzoQJE3b6qa2tTUVFRSZMmJC+fVsXzgF0tNauoipJcs6c6amsrGjxmE984hN55JFHsnr16qxYsSKXXXZZHnzwwVxxxRWtL/hdMPvkyRmwX58W9z/m8MMy7pADW9z/qquuyh//+Mdceuml+c1vfpNly5blqquuyoIFC9KvX7+2lAwAtJGArB3q6ury6U9/OqNHj07Pnj0zaNCgzJs3L88880yn1fDkk0/mF7/4RS655JJOuyZ0ZwcdMCRTjz28RX2PO3JcDj2odd9yrKury8KFCzN+/Pgcd9xxWbRoUb74xS/m5ptvbku5AEAHO2BIbU4+4b0t6vveCaMz4dC2bUcGsK869OARmXTE3reNTZITJ03MyOGDW3X+9evXZ8GCBRk7dmxmzJiRF154IQ899FDmzp3blnI7XGVFj5wzZ3qLVgb336935px8XKvOP3HixNx333157rnncsQRR+T888/PmWeema9//ettLRkAaKOS5ubm5kIX0RW9/PLLOf7447Nq1ar07Nkz48aNy7p167Jhw4aUl5fn29/+dubNm9emc2/cuDE1NTVJkvr6+lRXV3dk6cBebN26Lf/0ze9nwx//3x777N+vby7/8FmpqOixxz4AQNe0rakpi+64N/+5/o977LNfn5pcccH89GzFqgmArqKxcUv+4V/vzquv1e2xz5DaAbnsQ2ekvLysEyvrPD/5t6ez7Inn9ni8pKQkl/zXua0OCAGAfYcV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\n", + "text/plain": [ + "
" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(q_qiskit.backend.parametric_circuit.count_ops()[\"cx\"])\n", + "q_qiskit.backend.parametric_circuit.draw('mpl')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, "metadata": { "ExecuteTime": { - "end_time": "2022-10-19T06:41:20.051201Z", - "start_time": "2022-10-19T06:41:20.047078Z" + "end_time": "2022-10-19T06:49:41.817496Z", + "start_time": "2022-10-19T06:41:30.833779Z" } }, "outputs": [], "source": [ - "# device. If qpu_crendetials is not specified,the default hub, group and provider is used.\n", - "qiskit_cloud = create_device(location='ibmq', name='simulator_statevector', **qpu_credentials)\n", - "q_qiskit.set_device(qiskit_cloud)\n", - "\n", - "# circuit properties\n", - "q_qiskit.set_circuit_properties(p=2, param_type='standard', init_type='rand', mixer_hamiltonian='x')\n", - "\n", - "# backend properties (already set by default)\n", - "q_qiskit.set_backend_properties(prepend_state=None, append_state=None)\n", - "\n", - "# classical optimizer properties\n", - "q_qiskit.set_classical_optimizer(method='nelder-mead', maxiter=10, cost_progress=True,\n", - " parameter_log=True, optimization_progress=True)" + "q_qiskit.optimize()" ] }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ - "Demo for Rigetti QPUs and QVMs" + "## For Rigetti" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2022-10-19T06:41:20.054802Z", @@ -378,13 +347,13 @@ "rigetti_args ={\n", " 'as_qvm':True, \n", " 'execution_timeout':10,\n", - " 'compiler_timeout':10\n", + " 'compiler_timeout':100\n", "}" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2022-10-19T06:41:20.062343Z", @@ -399,7 +368,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 16, "metadata": { "ExecuteTime": { "end_time": "2022-10-19T06:41:20.080981Z", @@ -408,14 +377,14 @@ }, "outputs": [], "source": [ - "n_qubits = np_qubo.n\n", "# device\n", - "rigetti_device = create_device(location='qcs', name=f'{n_qubits}q-qvm', **rigetti_args)\n", + "# rigetti_device = create_device(location='qcs', name='Aspen-M-3', **rigetti_args)\n", + "rigetti_device = create_device(location='qcs', name='7q-qvm', **rigetti_args)\n", "\n", "q_pyquil.set_device(rigetti_device)\n", "\n", "# circuit properties\n", - "q_pyquil.set_circuit_properties(p=2, param_type='standard', init_type='rand', mixer_hamiltonian='x')\n", + "q_pyquil.set_circuit_properties(p=1, param_type='standard', init_type='rand', mixer_hamiltonian='x')\n", "\n", "# backend properties (already set by default)\n", "q_pyquil.set_backend_properties(prepend_state=None, append_state=None)\n", @@ -427,9 +396,11 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ - "## Step 3: Compile and Optimize\n", + "### Step 3: Compile and Optimize\n", "\n", "- Once the QAOA model is configured, we need to compile it. **Compilation is necessary** because the QAOA solver has to interact with the problem in to be able to create the underlying QAOA circuit.\n", "- The problem is ready to be optimized now. The user can call `model.optimize()` to initiate the optimization loop. " @@ -437,72 +408,628 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 17, "metadata": { "ExecuteTime": { - "end_time": "2022-10-19T06:41:27.106986Z", - "start_time": "2022-10-19T06:41:20.082536Z" - } + "end_time": "2022-10-19T06:41:30.832113Z", + "start_time": "2022-10-19T06:41:27.108848Z" + }, + "tags": [] }, "outputs": [], "source": [ - "q_qiskit.compile(np_qubo)" + "q_pyquil.compile(prob_qubo)\n", + "# to use routing, pass your custom function as below\n", + "# q_pyquil.compile(prob_qubo, routing_function = my_custom_routing)" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 18, "metadata": { - "ExecuteTime": { - "end_time": "2022-10-19T06:41:30.832113Z", - "start_time": "2022-10-19T06:41:27.108848Z" - } + "tags": [] }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DECLARE ro BIT[7]\n", + "DECLARE twoQ_COST_seq0_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq1_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq2_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq3_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq4_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq5_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq6_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq7_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq8_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq9_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq10_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq11_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq12_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq13_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq14_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq15_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq16_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq17_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq18_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq19_layer0 REAL[1]\n", + "DECLARE twoQ_COST_seq20_layer0 REAL[1]\n", + "DECLARE oneQ_MIXER_seq0_layer0 REAL[1]\n", + "DECLARE oneQ_MIXER_seq1_layer0 REAL[1]\n", + "DECLARE oneQ_MIXER_seq2_layer0 REAL[1]\n", + "DECLARE oneQ_MIXER_seq3_layer0 REAL[1]\n", + "DECLARE oneQ_MIXER_seq4_layer0 REAL[1]\n", + "DECLARE oneQ_MIXER_seq5_layer0 REAL[1]\n", + "DECLARE oneQ_MIXER_seq6_layer0 REAL[1]\n", + "RZ(pi) 0\n", + "RX(pi/2) 0\n", + "RZ(pi/2) 0\n", + "RX(-pi/2) 0\n", + "RZ(1.0*twoQ_COST_seq0_layer0[0]) 0\n", + "RZ(pi) 1\n", + "RX(pi/2) 1\n", + "RZ(pi/2) 1\n", + "RX(-pi/2) 1\n", + "RZ(1.0*twoQ_COST_seq0_layer0[0]) 1\n", + "RX(pi/2) 1\n", + "RZ(pi/2) 1\n", + "RX(-pi/2) 1\n", + "RZ(pi) 1\n", + "CZ 0 1\n", + "RZ(-pi) 0\n", + "RX(pi/2) 1\n", + "RZ(pi/2) 1\n", + "RX(-pi/2) 1\n", + "RZ(-pi + 1.0*twoQ_COST_seq0_layer0[0]) 1\n", + "RX(pi/2) 1\n", + "RZ(pi/2) 1\n", + "RX(-pi/2) 1\n", + "CZ 1 0\n", + "RZ(pi + -1.0*twoQ_COST_seq0_layer0[0] + 1.0*twoQ_COST_seq1_layer0[0]) 0\n", + "RZ(pi) 2\n", + "RX(pi/2) 2\n", + "RZ(pi/2) 2\n", + "RX(-pi/2) 2\n", + "RZ(1.0*twoQ_COST_seq1_layer0[0]) 2\n", + "RX(pi/2) 2\n", + "RZ(pi/2) 2\n", + "RX(-pi/2) 2\n", + "CZ 2 0\n", + "RZ(pi) 0\n", + "RZ(pi) 2\n", + "RX(pi/2) 2\n", + "RZ(pi/2) 2\n", + "RX(-pi/2) 2\n", + "RZ(pi + 1.0*twoQ_COST_seq1_layer0[0]) 2\n", + "RX(pi/2) 2\n", + "RZ(pi/2) 2\n", + "RX(-pi/2) 2\n", + "CZ 2 0\n", + "RZ(pi) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "RZ(1.0*twoQ_COST_seq2_layer0[0]) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "RZ(pi) 1\n", + "RX(pi/2) 1\n", + "RZ(pi/2) 1\n", + "RX(-pi/2) 1\n", + "RZ(pi + -1.0*twoQ_COST_seq0_layer0[0] + 1.0*twoQ_COST_seq6_layer0[0]) 1\n", + "RZ(pi) 2\n", + "RX(pi/2) 2\n", + "RZ(pi/2) 2\n", + "RX(-pi/2) 2\n", + "RZ(pi + 1.0*twoQ_COST_seq6_layer0[0] + -1.0*twoQ_COST_seq1_layer0[0]) 2\n", + "RX(pi/2) 2\n", + "RZ(pi/2) 2\n", + "RX(-pi/2) 2\n", + "CZ 2 1\n", + "RZ(pi) 1\n", + "RZ(pi) 2\n", + "RX(pi/2) 2\n", + "RZ(pi/2) 2\n", + "RX(-pi/2) 2\n", + "RZ(pi + 1.0*twoQ_COST_seq6_layer0[0]) 2\n", + "RX(pi/2) 2\n", + "RZ(pi/2) 2\n", + "RX(-pi/2) 2\n", + "RZ(pi) 2\n", + "CZ 1 2\n", + "RZ(pi + 1.0*twoQ_COST_seq2_layer0[0] + -1.0*twoQ_COST_seq1_layer0[0]) 0\n", + "CZ 3 0\n", + "RZ(pi) 0\n", + "RZ(pi) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "RZ(pi + 1.0*twoQ_COST_seq2_layer0[0]) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "CZ 3 0\n", + "RZ(-pi + -1.0*twoQ_COST_seq6_layer0[0] + 1.0*twoQ_COST_seq7_layer0[0]) 1\n", + "RZ(pi) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "RZ(pi + 1.0*twoQ_COST_seq7_layer0[0] + -1.0*twoQ_COST_seq2_layer0[0]) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "CZ 3 1\n", + "RZ(pi) 1\n", + "RZ(pi) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "RZ(pi + 1.0*twoQ_COST_seq7_layer0[0]) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "CZ 3 1\n", + "RZ(pi + 1.0*twoQ_COST_seq3_layer0[0] + -1.0*twoQ_COST_seq2_layer0[0]) 0\n", + "RZ(pi) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(1.0*twoQ_COST_seq3_layer0[0]) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "CZ 4 0\n", + "RZ(pi) 0\n", + "RZ(pi) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(pi + 1.0*twoQ_COST_seq3_layer0[0]) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "CZ 4 0\n", + "RX(pi/2) 2\n", + "RZ(pi/2) 2\n", + "RX(-pi/2) 2\n", + "RZ(-pi + 1.0*twoQ_COST_seq11_layer0[0] + -1.0*twoQ_COST_seq6_layer0[0]) 2\n", + "RZ(pi) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "RZ(pi + 1.0*twoQ_COST_seq11_layer0[0] + -1.0*twoQ_COST_seq7_layer0[0]) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "CZ 3 2\n", + "RZ(pi) 2\n", + "RZ(pi) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "RZ(pi + 1.0*twoQ_COST_seq11_layer0[0]) 3\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "RZ(pi) 3\n", + "CZ 2 3\n", + "RZ(pi + 1.0*twoQ_COST_seq8_layer0[0] + -1.0*twoQ_COST_seq7_layer0[0]) 1\n", + "RZ(pi) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(pi + 1.0*twoQ_COST_seq8_layer0[0] + -1.0*twoQ_COST_seq3_layer0[0]) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "CZ 4 1\n", + "RZ(pi) 1\n", + "RZ(pi) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(pi + 1.0*twoQ_COST_seq8_layer0[0]) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "CZ 4 1\n", + "RZ(pi + 1.0*twoQ_COST_seq4_layer0[0] + -1.0*twoQ_COST_seq3_layer0[0]) 0\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(1.0*twoQ_COST_seq4_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "CZ 5 0\n", + "RZ(pi) 0\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi + 1.0*twoQ_COST_seq4_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "CZ 5 0\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(1.0*twoQ_COST_seq5_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq12_layer0[0] + -1.0*twoQ_COST_seq11_layer0[0]) 2\n", + "RZ(pi) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(pi + 1.0*twoQ_COST_seq12_layer0[0] + -1.0*twoQ_COST_seq8_layer0[0]) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "CZ 4 2\n", + "RZ(pi) 2\n", + "RZ(pi) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(pi + 1.0*twoQ_COST_seq12_layer0[0]) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "CZ 4 2\n", + "RZ(pi + 1.0*twoQ_COST_seq9_layer0[0] + -1.0*twoQ_COST_seq8_layer0[0]) 1\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi + 1.0*twoQ_COST_seq9_layer0[0] + -1.0*twoQ_COST_seq4_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "CZ 5 1\n", + "RZ(pi) 1\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi + 1.0*twoQ_COST_seq9_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "CZ 5 1\n", + "RZ(pi + 1.0*twoQ_COST_seq5_layer0[0] + -1.0*twoQ_COST_seq4_layer0[0]) 0\n", + "CZ 6 0\n", + "RZ(pi) 0\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq5_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 6 0\n", + "RZ(3*pi/2 + -1.0*twoQ_COST_seq5_layer0[0]) 0\n", + "RX(pi/2) 0\n", + "RZ(1.0*oneQ_MIXER_seq0_layer0[0]) 0\n", + "RX(-pi/2) 0\n", + "RZ(-pi/2) 0\n", + "MEASURE 0 ro[0]\n", + "RX(pi/2) 3\n", + "RZ(pi/2) 3\n", + "RX(-pi/2) 3\n", + "RZ(-pi + 1.0*twoQ_COST_seq15_layer0[0] + -1.0*twoQ_COST_seq11_layer0[0]) 3\n", + "RZ(pi) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(pi + 1.0*twoQ_COST_seq15_layer0[0] + -1.0*twoQ_COST_seq12_layer0[0]) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(pi) 4\n", + "CZ 3 4\n", + "RZ(-pi) 3\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(-pi + 1.0*twoQ_COST_seq15_layer0[0]) 4\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(pi) 4\n", + "CZ 3 4\n", + "RZ(pi + 1.0*twoQ_COST_seq13_layer0[0] + -1.0*twoQ_COST_seq12_layer0[0]) 2\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi + 1.0*twoQ_COST_seq13_layer0[0] + -1.0*twoQ_COST_seq9_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "CZ 5 2\n", + "RZ(pi) 2\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi + 1.0*twoQ_COST_seq13_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "CZ 5 2\n", + "RZ(pi + 1.0*twoQ_COST_seq10_layer0[0] + -1.0*twoQ_COST_seq9_layer0[0]) 1\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq10_layer0[0] + -1.0*twoQ_COST_seq5_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 6 1\n", + "RZ(pi) 1\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq10_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 6 1\n", + "RZ(3*pi/2 + -1.0*twoQ_COST_seq10_layer0[0]) 1\n", + "RX(pi/2) 1\n", + "RZ(1.0*oneQ_MIXER_seq1_layer0[0]) 1\n", + "RX(-pi/2) 1\n", + "RZ(-pi/2) 1\n", + "MEASURE 1 ro[1]\n", + "RZ(-pi + -1.0*twoQ_COST_seq15_layer0[0] + 1.0*twoQ_COST_seq16_layer0[0]) 3\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi + 1.0*twoQ_COST_seq16_layer0[0] + -1.0*twoQ_COST_seq13_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "CZ 5 3\n", + "RZ(pi) 3\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi + 1.0*twoQ_COST_seq16_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "CZ 5 3\n", + "RZ(pi + 1.0*twoQ_COST_seq14_layer0[0] + -1.0*twoQ_COST_seq13_layer0[0]) 2\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq14_layer0[0] + -1.0*twoQ_COST_seq10_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 6 2\n", + "RZ(pi) 2\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq14_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 6 2\n", + "RZ(3*pi/2 + -1.0*twoQ_COST_seq14_layer0[0]) 2\n", + "RX(pi/2) 2\n", + "RZ(1.0*oneQ_MIXER_seq2_layer0[0]) 2\n", + "RX(-pi/2) 2\n", + "RZ(-pi/2) 2\n", + "MEASURE 2 ro[2]\n", + "RX(pi/2) 4\n", + "RZ(pi/2) 4\n", + "RX(-pi/2) 4\n", + "RZ(-pi + 1.0*twoQ_COST_seq18_layer0[0] + -1.0*twoQ_COST_seq15_layer0[0]) 4\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi + 1.0*twoQ_COST_seq18_layer0[0] + -1.0*twoQ_COST_seq16_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "CZ 5 4\n", + "RZ(pi) 4\n", + "RZ(pi) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi + 1.0*twoQ_COST_seq18_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(pi) 5\n", + "CZ 4 5\n", + "RZ(pi + 1.0*twoQ_COST_seq17_layer0[0] + -1.0*twoQ_COST_seq16_layer0[0]) 3\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq17_layer0[0] + -1.0*twoQ_COST_seq14_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 6 3\n", + "RZ(pi) 3\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq17_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 6 3\n", + "RZ(3*pi/2 + -1.0*twoQ_COST_seq17_layer0[0]) 3\n", + "RX(pi/2) 3\n", + "RZ(1.0*oneQ_MIXER_seq3_layer0[0]) 3\n", + "RX(-pi/2) 3\n", + "RZ(-pi/2) 3\n", + "MEASURE 3 ro[3]\n", + "RZ(-pi + 1.0*twoQ_COST_seq19_layer0[0] + -1.0*twoQ_COST_seq18_layer0[0]) 4\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq19_layer0[0] + -1.0*twoQ_COST_seq17_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 6 4\n", + "RZ(pi) 4\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq19_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 6 4\n", + "RZ(3*pi/2 + -1.0*twoQ_COST_seq19_layer0[0]) 4\n", + "RX(pi/2) 4\n", + "RZ(1.0*oneQ_MIXER_seq4_layer0[0]) 4\n", + "RX(-pi/2) 4\n", + "RZ(-pi/2) 4\n", + "MEASURE 4 ro[4]\n", + "RX(pi/2) 5\n", + "RZ(pi/2) 5\n", + "RX(-pi/2) 5\n", + "RZ(-1.0*twoQ_COST_seq18_layer0[0] + 1.0*twoQ_COST_seq20_layer0[0]) 5\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq20_layer0[0] + -1.0*twoQ_COST_seq19_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "CZ 5 6\n", + "RZ(pi) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi + 1.0*twoQ_COST_seq20_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(pi) 6\n", + "CZ 5 6\n", + "RX(pi/2) 6\n", + "RZ(pi/2) 6\n", + "RX(-pi/2) 6\n", + "RZ(-pi/2 + -1.0*twoQ_COST_seq20_layer0[0]) 6\n", + "RX(pi/2) 6\n", + "RZ(1.0*oneQ_MIXER_seq6_layer0[0]) 6\n", + "RX(-pi/2) 6\n", + "RZ(-pi/2) 6\n", + "MEASURE 6 ro[6]\n", + "RZ(-pi/2 + -1.0*twoQ_COST_seq20_layer0[0]) 5\n", + "RX(pi/2) 5\n", + "RZ(1.0*oneQ_MIXER_seq5_layer0[0]) 5\n", + "RX(-pi/2) 5\n", + "RZ(-pi/2) 5\n", + "MEASURE 5 ro[5]\n", + "HALT\n", + "\n" + ] + } + ], "source": [ - "q_pyquil.compile(np_qubo) " + "print(q_pyquil.backend.qaoa_circuit(q_pyquil.variate_params))" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 19, "metadata": { "ExecuteTime": { - "end_time": "2022-10-19T06:49:41.817496Z", - "start_time": "2022-10-19T06:41:30.833779Z" - } + "end_time": "2022-10-19T06:54:04.390726Z", + "start_time": "2022-10-19T06:49:41.819224Z" + }, + "tags": [] }, "outputs": [], "source": [ - "q_qiskit.optimize()" + "q_pyquil.optimize()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Accessing the results\n", + "\n", + "The process of obtaining the results for models with either device looks exactly the same. Therefore, to keep this notebook succinct, we only analyze results produced by one device." ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 20, "metadata": { "ExecuteTime": { - "end_time": "2022-10-19T06:54:04.390726Z", - "start_time": "2022-10-19T06:49:41.819224Z" + "end_time": "2022-10-19T06:54:04.393796Z", + "start_time": "2022-10-19T06:54:04.391978Z" } }, "outputs": [], "source": [ - "q_pyquil.optimize()" + "opt_results = q_qiskit.result" ] }, { - "cell_type": "markdown", - "metadata": {}, + "cell_type": "code", + "execution_count": 21, + "metadata": { + "ExecuteTime": { + "end_time": "2022-10-19T06:54:04.567078Z", + "start_time": "2022-10-19T06:54:04.398505Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "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zp3RtGlT9O/fH2vXrsWqVaswcOBAdOjQAa1bt8a5c+fw4IMP4ocffsDu3bvx888/Y/Xq1WjUqBEAoFatWjh9+jQWLVqEI0eO4GxhHTUMwCBFRERERESWqFOnDtauXYurr74aI0aMQJMmTdClSxcsWrQIU6dOhcfjwZdffokKFSqgffv26Ny5M+rUqYOPP/4YABAeHo6jR49i4MCBaNCgAW655RZ0794d48aNAwBcfvnlGDRoEG699VZUrlwZkyZNMu178XgDWfUV4tLS0hAbG4uTJ08iJibG7uEQERERERUqPT0dO3fuRO3atVE6/+InCkhRP8NAswErUkRERERERBoxSBEREREREWnEIEVERERERKQRgxSFpHPngJ9+AubNs3skRERERBSKStk9ACIzHDwIXHklEBUlocrjsXtERERERMZizzj9jPjZsSJFIWnBArnOyABOnbJ3LERERERGioiIAABT90gKdepnp36WerAiRSHv4EGAXe2JiIgoVISHhyMuLg6HDh0CAERHR8PD6TcB8Xq9OHv2LA4dOoS4uDiEh4frPhaDFIWk9HTf7UOHgPr17RsLERERkdESEhIAIDdMkTZxcXG5P0O9GKQoJOUPUkREREShxOPxoFq1aqhSpQrOnz9v93BcJSIiIqhKlMIgRSHJP0gdPGjfOIiIiIjMFB4ebkgoIO3YbIJCEitSRERERGQmBikKSSpIlSsHXHedvWMhIiIiotDDqX0UkurWBTp2BPr1A1q2tHs0RERERBRqPF7u5IW0tDTExsbi5MmTiGGfbCIiIiKiEivQbMCpfRSyzp4FfvwRmD/f7pEQERERUaixNUiNHTsWHo8nz6Vhw4a5X09PT8fQoUMRHx+PcuXKoU+fPjiYrwXbnj170KNHD0RHR6NKlSoYOXIksrKyrP5WyIF27QLatwf69rV7JEREREQUamyvSDVu3BgHDhzIvfz000+5Xxs2bBi+/vprfPrpp1i6dCn279+P3r175349OzsbPXr0QGZmJpYvX46ZM2dixowZePrpp+34VshBevcGGjeW28ePA5mZ9o6HiIiIiEKL7c0mSpUqVeCuwidPnsS7776L2bNno2PHjgCA6dOno1GjRli5ciXatm2LBQsWYNOmTVi4cCGqVq2K5s2b49lnn8WoUaMwduxYREZGWv3tkEOcOJH348OHgYsusmUoRERERBSCbK9I/fXXX6hevTrq1KmD/v37Y8+ePQCANWvW4Pz58+jcuXPufRs2bIiaNWtixYoVAIAVK1agadOmqFq1au59unXrhrS0NGzcuLHQ58zIyEBaWlqeC4UW/32kAO4lRURERETGsjVItWnTBjNmzMB3332HqVOnYufOnbjyyitx6tQppKamIjIyEnFxcXkeU7VqVaSmpgIAUlNT84Qo9XX1tcJMnDgRsbGxuZfExERjvzGyHYMUEREREZnJ1ql93bt3z73drFkztGnTBklJSfjkk09QpkwZ05539OjRGD58eO7HaWlpDFMhRgWpiAjg/HkgX48SIiIiIqKg2D61z19cXBwaNGiAbdu2ISEhAZmZmTiRb7HLwYMHc9dUJSQkXNDFT31c0LorJSoqCjExMXkuFFpUkEpKkmtWpIiIiIjISI4KUqdPn8b27dtRrVo1tGrVChEREVi0aFHu17ds2YI9e/YgJSUFAJCSkoINGzbgkN9Z8vfff4+YmBgkJydbPn5yjnPn5Pree4EpU4CuXe0dDxERERGFFlun9v3rX//C9ddfj6SkJOzfvx/PPPMMwsPD0bdvX8TGxuKee+7B8OHDUbFiRcTExOChhx5CSkoK2rZtCwDo2rUrkpOTMWDAAEyaNAmpqakYM2YMhg4diqioKDu/NbJZq1bSqe+WW4Date0eDRERERGFGluD1N69e9G3b18cPXoUlStXxhVXXIGVK1eicuXKAIBXXnkFYWFh6NOnDzIyMtCtWze89dZbuY8PDw/H3LlzMXjwYKSkpKBs2bK44447MH78eLu+JXKIuXPtHgERERERhTKP1+v12j0Iu6WlpSE2NhYnT57keqkQc/o0sHYtkJEBdOli92iIiIiIyOkCzQa2b8hLZKY//wQ6dJDNePfutXs0RERERBQqHNVsgsgIp04BVatKxz61DdmhQwBrr0RERERkFFakKOScO+drd37RRXJ9/jxw4gRQoYJtwyIiIiKiEMKKFIUctYdUVBRQpgygprZyLykiIiIiMgqDFIUcFaTKlJHrKlXkmkGKiIiIiIzCIEUhRwWp0qXlumpVuT540J7xEBEREVHoYZCikJM/SLEiRURERERGY7MJCjn5g9Tdd8seUh062DcmIiIiIgotDFIUcqKigBYtgNq15ePrrrN3PEREREQUehikKOS0aQOsXWv3KIjI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HTqExx57DLt378Z3332HCRMmYPTo0TZpl6568cUXMXXqVEyfPh1//vkntm3bhpkzZ+LNN980PycyMhIDBgzA+PHjsWvXLgwePNj8WI0aNRAeHo53330X+/btw/fff4/JkyeX+JrO7Hf169fHnDlzsGvXLmzYsAFDhgy5amavVq1aWLZsGXJycoot86/HvjFq1CgsWbIE+/fvxx9//IEVK1aYTwgQERmBgRQRUSmaNGnSVSlejRs3xnvvvYcZM2YgJSUFv//+u8OKdu6aNm0apk2bhpSUFPz666/4/vvvUalSJQAwzxQUFhaiR48eaN68OUaNGoW4uDiXA4ORI0di9OjRePLJJ9G8eXMsXrwY33//PerXr+/xzzBu3Dh07doV/fr1Q9++fTFgwADUrVvXpW1UrFgRy5cvx/nz59G1a1e0bt0aH330kTmd7MEHH0TDhg3Rpk0bVK5c+aoZFACoVq0afvzxR/z+++9ISUnBww8/jOHDh+P555/36Od74IEH8PHHH2PmzJlo3rw5unbtilmzZtnMSAGS3rdlyxZ07twZNWrUMN9fuXJlzJo1C/Pnz0eTJk0wbdo0vP766yW+pjP73SeffIIzZ87guuuuwz333IORI0eiSpUqNs954403sHTpUlSvXh2tWrVy+Fp67BuFhYVIS0tD48aN0atXLzRo0MCmRDwRUWkzafYJ0kRERERERFQizkgRERERERG5iIEUERERERGRixhIERERERERuYiBFBERERERkYsYSBEREREREbmIgRQREREREZGLGEgRERERERG5iIEUERERERGRixhIERERERERuYiBFBERERERkYsYSBEREREREbno/wHP6HrJfx8/pAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "## Step 4: Accessing the results\n", - "\n", - "The process of obtaining the results for models with either device looks exactly the same. Therefore, to keep this notebook succinct, we only analyze results produced by one device." + "# print the cost history\n", + "opt_results.plot_cost()" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 22, "metadata": { "ExecuteTime": { "end_time": "2022-10-19T06:54:04.393796Z", @@ -516,7 +1043,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 23, "metadata": { "ExecuteTime": { "end_time": "2022-10-19T06:54:04.567078Z", @@ -526,7 +1053,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1IAAAK9CAYAAAAuQ13kAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOydeZxN5R/HP7MYDMbYt8ZOjLVoGS0qolAqlaK0KiUVUj8RSUqrNu0lJSntiYTQQmVJhMgu+z62mWHm/v749jjPPXPuveece+/cM+Pzfr3u65x771mee+5Zns/z3eJ8Pp8PhBBCCCGEEEJsEx/rBhBCCCGEEEJIYYNCihBCCCGEEEIcQiFFCCGEEEIIIQ6hkCKEEEIIIYQQh1BIEUIIIYQQQohDKKQIIYQQQgghxCEUUoQQQgghhBDiEAopQgghhBBCCHEIhRQhhBBCCCGEOIRCihBCyEnFe++9h7i4OCxcuDDkshdccAEuuOCC6DeKEEJIoYNCihBCSERZu3Yt7rzzTtStWxclSpRASkoKzjnnHLz44os4evRoxPd35MgRPProo5gzZ07Et+2GefPm4dFHH8X+/ftj3RRCCCFRJDHWDSCEEFJ0+Pbbb3HNNdegePHi6NWrF5o2bYqcnBz8/PPPGDRoEJYvX44333wzovs8cuQIRowYAQARtx59//33jteZN28eRowYgZtvvhmpqakRbQ8hhBDvQCFFCCEkIqxfvx7XXXcdatWqhR9++AHVqlU78V3fvn2xZs0afPvttzFsoXOSkpJi3QQAgM/nQ1ZWFkqWLBnrphBCCPkPuvYRQgiJCE8//TQOHTqEd955x09EKerXr4/77rvvxPvjx49j5MiRqFevHooXL47atWvj4YcfRnZ2tt96CxcuRMeOHVGxYkWULFkSderUwa233goA2LBhAypVqgQAGDFiBOLi4hAXF4dHH300ZHuzs7MxYMAAVKpUCaVKlcKVV16JXbt2+S1jFSP18ssvo0mTJkhOTka5cuXQunVrTJw4EQDw6KOPYtCgQQCAOnXqnGjPhg0bHP3m2rVro0uXLpg+fTpat26NkiVL4o033kDbtm3RokULy99z6qmnomPHjiF/NyGEkMhAixQhhJCI8M0336Bu3bpo06aNreVvv/12jB8/HldffTUGDhyI3377DU8++SRWrlyJL774AgCwc+dOdOjQAZUqVcL//vc/pKamYsOGDfj8888BAJUqVcJrr72Gu+66C1deeSWuuuoqAEDz5s1D7r9fv34oV64chg8fjg0bNuCFF17APffcg48//jjgOm+99RbuvfdeXH311bjvvvuQlZWFpUuX4rfffkOPHj1w1VVXYfXq1fjoo48wZswYVKxY8UQ77f5mxapVq3D99dfjzjvvRO/evXHqqaeidOnS6N27N/766y80bdr0xLILFizA6tWrMXToUFvHnhBCSATwEUIIIWFy4MABHwBf165dbS2/ZMkSHwDf7bff7vf5Aw884APg++GHH3w+n8/3xRdf+AD4FixYEHBbu3bt8gHwDR8+3Na+x40b5wPga9++vS8vL+/E5/379/clJCT49u/ff+Kztm3b+tq2bXvifdeuXX1NmjQJuv1nnnnGB8C3fv16v8/t/mafz+erVauWD4Dvu+++81t2//79vhIlSvgeeughv8/vvfdeX6lSpXyHDh0K2jZCCCGRg659hBBCwiYzMxMAUKZMGVvLT506FQAwYMAAv88HDhwIACdiqVSyhilTpuDYsWORaOoJ7rjjDsTFxZ14f9555yE3NxcbN24MuE5qair+/fdfLFiwwPH+7P5mRZ06dfK56pUtWxZdu3bFRx99BJ/PBwDIzc3Fxx9/jCuuuAKlSpVy3C5CCCHuoJAihBASNikpKQCAgwcP2lp+48aNiI+PR/369f0+r1q1KlJTU0+ImbZt26Jbt24YMWIEKlasiK5du2LcuHH5YorcULNmTb/35cqVAwDs27cv4DoPPfQQSpcujTPPPBMNGjRA37598csvv9jan93frKhTp47ldnr16oVNmzbhp59+AgDMnDkTO3bswI033mirHYQQQiIDhRQhhJCwSUlJQfXq1fHXX385Wk+3CAX6/tNPP8X8+fNxzz33YMuWLbj11lvRqlUrHDp0KJwmIyEhwfJzZemxonHjxli1ahUmTZqEc889F5999hnOPfdcDB8+3PZ+Q/1mRaAMfR07dkSVKlUwYcIEAMCECRNQtWpVtG/f3nYbCCGEhA+FFCGEkIjQpUsXrF27FvPnzw+5bK1atZCXl4d//vnH7/MdO3Zg//79qFWrlt/nZ599NkaNGoWFCxfiww8/xPLlyzFp0iQA9oVJpChVqhS6d++OcePGYdOmTejcuTNGjRqFrKysoO1x+psDkZCQ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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1IAAAK9CAYAAAAuQ13kAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3gUVfcH8G8SklCT0Jt0RHoRUJqgiKKiomBBsCuCYkNEX6wgKrZXsXcFfUUs2LCgCIpIk2KhSROkdxJ66v7+OL/D3J2drdnNDsn38zx5drPZ7M7uzs7cc++55yZ4PB4PiIiIiIiIKGSJ8d4AIiIiIiKi4w0DKSIiIiIiojAxkCIiIiIiIgoTAykiIiIiIqIwMZAiIiIiIiIKEwMpIiIiIiKiMDGQIiIiIiIiChMDKSIiIiIiojAxkCIiIiIiIgoTAykiIipRJkyYgISEBCxatCjofU8//XScfvrpsd8oIiI67jCQIiKiqFq3bh2GDBmChg0bonTp0khLS0PXrl3x/PPP48iRI1F/vsOHD2P06NH4+eefo/7YkZg7dy5Gjx6NzMzMeG8KERHFUKl4bwARERUf33zzDS699FKkpqbi6quvRsuWLZGTk4Nff/0VI0eOxPLly/HGG29E9TkPHz6MMWPGAEDUR49++OGHsP9n7ty5GDNmDK699lpkZGREdXuIiMg9GEgREVFUrF+/HgMGDEC9evUwc+ZM1KxZ89jfhg0bhrVr1+Kbb76J4xaGLyUlJd6bAADweDw4evQoypQpE+9NISKi/8fUPiIiioqnnnoKBw8exNtvv+0VRKnGjRvjjjvuOPZ7Xl4exo4di0aNGiE1NRX169fHfffdh+zsbK//W7RoEXr37o0qVaqgTJkyaNCgAa6//noAwIYNG1C1alUAwJgxY5CQkICEhASMHj066PZmZ2fjrrvuQtWqVVGuXDlcfPHF2LVrl9d9nOZIvfjii2jRogXKli2LihUrokOHDpg0aRIAYPTo0Rg5ciQAoEGDBse2Z8OGDWG95vr16+P888/H999/jw4dOqBMmTJ4/fXX0aNHD7Rp08bx9Zx00kno3bt30NdNRETRwREpIiKKiqlTp6Jhw4bo0qVLSPe/8cYbMXHiRFxyySUYMWIEFixYgHHjxmHlypX4/PPPAQA7d+7E2WefjapVq+I///kPMjIysGHDBnz22WcAgKpVq+LVV1/FzTffjIsvvhj9+vUDALRu3Tro8992222oWLEiHn74YWzYsAHjx4/Hrbfeio8++sjv/7z55pu4/fbbcckll+COO+7A0aNH8ddff2HBggUYOHAg+vXrh9WrV+PDDz/Ec889hypVqhzbzlBfs1q1ahWuuOIKDBkyBIMHD8ZJJ52E8uXLY/DgwVi2bBlatmx57L4LFy7E6tWr8cADD4T03hMRURR4iIiICikrK8sDwNO3b9+Q7v/HH394AHhuvPFGr9vvvvtuDwDPzJkzPR6Px/P55597AHgWLlzo97F27drlAeB5+OGHQ3rud9991wPA06tXL09BQcGx24cPH+5JSkryZGZmHrutR48enh49ehz7vW/fvp4WLVoEfPynn37aA8Czfv16r9tDfc0ej8dTr149DwDPtGnTvO6bmZnpKV26tOfee+/1uv3222/3lCtXznPw4MGA20ZERNHD1D4iIiq0/fv3AwAqVKgQ0v2//fZbAMBdd93ldfuIESMA4NhcKi3W8PXXXyM3Nzcam3rMTTfdhISEhGO/n3baacjPz8e///7r938yMjKwefNmLFy4MOznC/U1qwYNGvik6qWnp6Nv37748MMP4fF4AAD5+fn46KOPcNFFF6FcuXJhbxcREUWGgRQRERVaWloaAODAgQMh3f/ff/9FYmIiGjdu7HV7jRo1kJGRcSyY6dGjB/r3748xY8agSpUq6Nu3L959912fOUWRqFu3rtfvFStWBADs27fP7//ce++9KF++PE455RSceOKJGDZsGObMmRPS84X6mlWDBg0cH+fqq6/Gxo0bMXv2bADAjz/+iB07duCqq64KaTuIiCg6GEgREVGhpaWloVatWli2bFlY/2eOCPn7+6effop58+bh1ltvxZYtW3D99dejffv2OHjwYGE2GUlJSY6360iPk2bNmmHVqlWYPHkyunXrhilTpqBbt254+OGHQ37eYK9Z+avQ17t3b1SvXh3/+9//AAD/+9//UKNGDfTq1SvkbSAiosJjIEVERFFx/vnnY926dZg3b17Q+9arVw8FBQVYs2aN1+07duxAZmYm6tWr53V7p06d8Nhjj2HRokX44IMPsHz5ckyePBlA6IFJtJQrVw6XX3453n33XWzcuBF9+vTBY489hqNHjwbcnnBfsz9JSUkYOHAgPv30U+zbtw9ffPEFrrjiCr+BIRERxQYDKSIiiop77rkH5cqVw4033ogdO3b4/H3dunV4/vnnAQDnnXceAGD8+PFe93n22WcBAH369AEgaXb2EaK2bdsCwLH0vrJlywIAMjMzo/I6AtmzZ4/X7ykpKWjevDk8Hs+xOVw6T8m+PaG+5lBcddVV2LdvH4YMGYKDBw/iyiuvDOdlEBFRFLD8ORERRUWjRo0wadIkXH755WjWrBmuvvpqtGzZEjk5OZg7dy4++eQTXHvttQCANm3a4JprrsEbb7yBzMxM9OjRA7/99hsmTpyIiy66CGeccQYAYOLEiXjllVdw8cUXo1GjRjhw4ADefPNNpKWlHQtMypQpg+bNm+Ojjz5CkyZNUKlSJbRs2dKrPHi0nH322ahRowa6du2K6tWrY+XKlXjppZfQp0+fY4U22rdvDwC4//77MWDAACQnJ+OCCy4I+TWHol27dmjZsiU++eQTNGvWDCeffHLUXysREQUR36KBRERU3KxevdozePBgT/369T0pKSmeChUqeLp27ep58cUXPUePHj12v9zcXM+YMWM8DRo08CQnJ3vq1KnjGTVqlNd9lixZ4rniiis8devW9aSmpnqqVavmOf/88z2LFi3yes65c+d62rdv70lJSQlaCl3Ln9tLqv/0008eAJ6ffvrp2G328uevv/66p3v37p7KlSt7UlNTPY0aNfKMHDnSk5WV5fVYY8eO9dSuXduTmJjoVQo9lNfs8Uj58z59+gR6mz1PPfWUB4Dn8ccfD3g/IiKKjQSPJ8CsWiIiInKl559/HsOHD8eGDRt8KhASEVHsMZAiIiI6zng8HrRp0waVK1fGTz/9FO/NISIqkThHioiI6Dhx6NAhfPXVV/jpp5+wdOlSfPnll/HeJCKiEosjUkRERMeJDRs2oEGDBsjIyMAtt9yCxx57LN6bRERUYjGQIiIiIiIiChPXkSIiIiIiIgoTAykiIiIiIqIwsdgEgIKCAmzduhUVKlRAQkJCvDeHiIiIiIjixOPx4MCBA6hVqxYSE/2POzGQArB161bUqVMn3ptBREREREQusWnTJpxwwgl+/85ACkCFChUAyJuVlpYW560hIiIiIqJ42b9/P+rUqXMsRvCHgRRwLJ0vLS2NgRQREREREQWd8sNiE0RERERERGFiIEVERERERBQmBlJERERERERh4hwpIiIiIqLjkMfjQV5eHvLz8+O9KceVpKQklCpVqtDLHjGQIiIiIiI6zuTk5GDbtm04fPhwvDfluFS2bFnUrFkTKSkpET8GAykiIiIiouNIQUEB1q9fj6SkJNSqVQspKSmFHl0pKTweD3JycrBr1y6sX78eJ554YsBFdwNhIEVEREREdBzJyclBQUEB6tSpg7Jly8Z7c447ZcqUQXJyMv7991/k5OSgdOnSET0Oi00QERERER2HIh1Joei8d3z3iYiIiIiIwsRAioiIiIiIKEwMpIiIiIiIiMLEQIqIiIiIiIrM9u3bcdttt6Fhw4ZITU1FnTp1cMEFF2DGjBmFfuwJEyYgIyOj8BsZAlbtIyIiIiKiIrFhwwZ07doVGRkZePrpp9GqVSvk5ubi+++/x7Bhw/D333/HexNDxhEpIiIiIqJi4NAh/z9Hj4Z+3yNHQrtvJG655RYkJCTgt99+Q//+/dGkSRO0aNECd911F+bPnw8A2LhxI/r27Yvy5csjLS0Nl112GXbs2HHsMf7880+cccYZqFChAtLS0tC+fXssWrQIP//8M6677jpkZWUhISEBCQkJGD16dGQbGgKOSBERERERFQPly/v/23nnAd98Y/1erRpw+LDzfXv0AH7+2fq9fn1g927f+3k84W3f3r17MW3aNDz22GMoV66cz98zMjJQUFBwLIiaNWsW8vLyMGzYMFx++eX4+f83atCgQWjXrh1effVVJCUl4Y8//kBycjK6dOmC8ePH46GHHsKqVasAAOUDvSmFxECKiIiIiIhibu3atfB4PGjatKnf+8yYMQNLly7F+vXrUadOHQDAe++9hxYtWmDhwoXo2LEjNm7ciJEjRx57nBNPPPHY/6enpyMhIQE1atSI7YsBAykiIiIiomLh4EH/f0tK8v59507/97WvVbthQ8Sb5MUTwhDWypUrUadOnWNBFAA0b94cGRkZWLlyJTp27Ii77roLN954I95//3306tULl156KRo1ahSdjQwD50gRERERERUD5cr5/yldOvT7likT2n3DdeKJJyIhIaHQBSVGjx6N5cuXo0+fPpg5cyaaN2+Ozz//vFCPGQkGUkREREREFHOVKlVC79698fLLL+OQQ7WKzMxMNGvWDJs2bcKmTZuO3b5ixQpkZmaiefPmx25r0qQJhg8fjh9++AH9+vXDu+++CwBISUlBfn5+7F8MGEgREREREVERefnll5Gfn49TTjkFU6ZMwZo1a7By5Uq88MIL6Ny5M3r16oVWrVph0KBBWLJkCX777TdcffXV6NGjBzp06IAjR47g1ltvxc8//4x///0Xc+bMwcKFC9GsWTMAQP369XHw4EHMmDEDu3fvxmF/FTWigIEUEREREREViYYNG2LJkiU444wzMGLECLRs2RJnnXUWZsyYgVdffRUJCQn48ssvUbFiRXTv3h29evVCw4YN8dFHHwEAkpKSsGfPHlx99dVo0qQJLrvsMpx77rkYM2YMAKBLly4YOnQoLr/8clStWhVPPfVUzF5LgieUWV/F3P79+5Geno6srCykpaXFe3OIiIiIiPw6evQo1q9fjwYNGqC0ffIThSTQexhqbMARKSIiIiIiojAxkCIiIiIiIgoT15FykcOHgXnzgOxsWX2aiIiIiIjciYGUi+zcCfTqJXX+jxyJ99YQEREREZE/TO1zkQoV5PLoUSAvL77bQkRERETuxppxkYvGe8dAykU0kAKAAwfitx1ERERE5F7JyckAENM1koo7fe/0vYwEU/tcJCUFSE2VOVL79wMVK8Z7i4iIiIjIbZKSkpCRkYGdO3cCAMqWLYuEhIQ4b9XxwePx4PDhw9i5cycyMjKQlJQU8WMxkHKZChUkkOKIFBERERH5U6NGDQA4FkxReDIyMo69h5FiIOUyaWnA7t0MpIiIiIjIv4SEBNSsWRPVqlVDbm5uvDfnuJKcnFyokSjFQMpldJ4UAykiIiIiCiYpKSkqQQGFj4GUy9xzD5CVBTRtGu8tISIiIiIifxhIuczAgfHeAiIiIiIiCoblz4mIiIiIiMLEESmX2bABWL8eqF0baNIk3ltDREREREROOCLlMi+8APTsCbz1Vry3hIiIiIiI/GEg5TJpaXLJqn1ERERERO7FQMplWP6ciIiIiMj9GEi5jI5I7d8f3+0gIiIiIiL/GEi5DEekiIiIiIjcj4GUy2ggxREpIiIiIiL3YiDlMiw2QURERETkflxHymUaNwaeeAKoUSPeW0JERERERP4wkHKZmjWBe++N91YQEREREVEgTO0jIiIiIiIKEwMpl/F4gEWLgJ9+AnJy4r01RERERETkhKl9LtS5M5CXB2zaBJxwQry3hoiIiIiI7Dgi5TIJCVyUl4iIiIjI7RhIuRAX5SUiIiIicjcGUi7EQIqIiIiIyN0YSLlQcrJc5uXFdzuIiIiIiMgZAykXSvz/T6WgIL7bQUREREREzhhIuVBCglx6PPHdDiIiIiIicsby5y50yy3Atm1Akybx3hIiIiIiInLCQMqFrrsu3ltARERERESBMLWPiIiIiIgoTByRcqE1a6T0eYMGQMWK8d4aIiIiIiKy44iUC11/PdC+PTBzZry3hIiIiIiInDCQciEtf86qfURERERE7sRAyoW0/DnXkSIiIiIicicGUi7EESkiIiIiIndjIOVCGkhxRIqIiIiIyJ0YSLkQU/uIiIiIiNyNgZQLMbWPiIiIiMjduI6UCw0YAHTsCLRsGe8tISIiIiIiJwykXOi66+K9BUREREREFAhT+4iIiIiIiMLEESkX2roVOHAAqF4dyMiI99YQEREREZEdR6RcaOhQoGlT4NNP470lRERERETkhIGUC7FqHxERERGRuzGQciGuI0VERERE5G4MpFyII1JERERERO7GQMqFNJDiiBQRERERkTsxkHIhpvYREREREbkbAykXYmofEREREZG7cR0pFzrvPKBmTaBNm3hvCREREREROUnweDjusX//fqSnpyMrKwtpaWnx3hwiIiIiIoqTUGMDpvYRERERERGFial9LrRvH3DoEJCWJj9EREREROQuHJFyoTvvBOrUAV5/Pd5bQkREREREThhIuRCr9hERERERuRsDKRfiOlJERERERO7GQMqFOCJFRERERORuDKRciCNSRERERETuxkDKhTgiRURERETkbgykXEgDKY5IERERERG5E9eRcqFu3YD8fKBdu3hvCREREREROUnweJhAtn//fqSnpyMrKwtpXAGXiIiIiKjECjU2YGofERERERFRmJja50JHjgBHjwKpqUDZsvHeGiIiIiIisov7iNSWLVtw5ZVXonLlyihTpgxatWqFRYsWHfu7x+PBQw89hJo1a6JMmTLo1asX1qxZ4/UYe/fuxaBBg5CWloaMjAzccMMNOHjwYFG/lKgZNQqoVAkYOzbeW0JERERERE7iGkjt27cPXbt2RXJyMr777jusWLEC//3vf1GxYsVj93nqqafwwgsv4LXXXsOCBQtQrlw59O7dG0ePHj12n0GDBmH58uWYPn06vv76a/zyyy+46aab4vGSooLlz4mIiIiI3C2uqX1PPvkk6tSpg3fffffYbQ0aNDh23ePxYPz48XjggQfQt29fAMB7772H6tWr44svvsCAAQOwcuVKTJs2DQsXLkSHDh0AAC+++CLOO+88PPPMM6hVq1bRvqgo4IK8RERERETuFtcRqa+++godOnTApZdeimrVqqFdu3Z48803j/19/fr12L59O3r16nXstvT0dJx66qmYN28eAGDevHnIyMg4FkQBQK9evZCYmIgFCxY4Pm92djb279/v9eMmHJEiIiIiInK3uAZS//zzD1599VWceOKJ+P7773HzzTfj9ttvx8SJEwEA27dvBwBUr17d6/+qV69+7G/bt29HtWrVvP5eqlQpVKpU6dh97MaNG4f09PRjP3Xq1In2SysUjkgREREREblbXAOpgoICnHzyyXj88cfRrl073HTTTRg8eDBee+21mD7vqFGjkJWVdexn06ZNMX2+cHFEioiIiIjI3eIaSNWsWRPNmzf3uq1Zs2bYuHEjAKBGjRoAgB07dnjdZ8eOHcf+VqNGDezcudPr73l5edi7d++x+9ilpqYiLS3N68dNOCJFRERERORucQ2kunbtilWrVnndtnr1atSrVw+AFJ6oUaMGZsyYcezv+/fvx4IFC9C5c2cAQOfOnZGZmYnFixcfu8/MmTNRUFCAU089tQheRfS1bQsMHAi0bx/vLSEiIiIiIicJHk/8EsgWLlyILl26YMyYMbjsssvw22+/YfDgwXjjjTcwaNAgAFLZ74knnsDEiRPRoEEDPPjgg/jrr7+wYsUKlC5dGgBw7rnnYseOHXjttdeQm5uL6667Dh06dMCkSZNC2o79+/cjPT0dWVlZrhudIiIiIiKiohNqbBDXQAoAvv76a4waNQpr1qxBgwYNcNddd2Hw4MHH/u7xePDwww/jjTfeQGZmJrp164ZXXnkFTZo0OXafvXv34tZbb8XUqVORmJiI/v3744UXXkD58uVD2gYGUkREREREBBxHgZQbuC2Qys+Xn4QEIDk53ltDRERERFRyhBobxHWOFDl79FEgNRW47bZ4bwkRERERETlhIOVCLH9ORERERORuDKRciOXPiYiIiIjcjYGUC3FEioiIiIjI3RhIuRBHpIiIiIiI3I2BlAtxRIqIiIiIyN0YSLkQR6SIiIiIiNyNgZQLNWkCXHQRcPLJ8d4SIiIiIiJyUireG0C+LrpIfoiIiIiIyJ04IkVERERERBQmBlJERERERERhYiDlQq+8AiQnA1dcEe8tISIiIiIiJwykXMjjAfLygPz8eG8JERERERE5YSDlQix/TkRERETkbgykXIgL8hIRERERuRsDKRfiiBQRERERkbsxkHIhjkgREREREbkbAykX4ogUEREREZG7MZByoRNOAHr1Atq2jfeWEBERERGRk1Lx3gDydc458kNERERERO7EESkiIiIiIqIwMZAiIiIiIiIKEwMpF/r4YyA9Hbj44nhvCREREREROWEg5UJ5ecD+/cDBg/HeEiIiIiIicsJAyoVY/pyIiIiIyN0YSLkQF+QlIiIiInI3BlIuxBEpIiIiIiJ3YyDlQhyRIiIiIiJyNwZSLsQRKSIiIiIid2Mg5UJVqgBdugCtWsV7S4iIiIiIyEmpeG8A+erRA5gzJ95bQURERERE/nBEioiIiIiIKEwMpIiIiIiIiMLEQMqFZswAatUCzjkn3ltCREREREROGEi5UHY2sG0bsHt3vLeEiIiIiIicMJByIa4jRURERETkbgykXEgDKa4jRURERETkTgykXIgL8hIRERERuRsDKRdiah8RERERkbsxkHIhjkgREREREblbqXhvAPmqUAFo0wZo3DjeW0JERERERE4YSLlQx47AH3/EeyuIiIiIiMgfpvYRERERERGFiYEUERERERFRmBhIudCSJTI/qmfPeG8JERERERE54RwpF8rOBtatY9U+IiIiIiK34oiUC3EdKSIiIiIid2Mg5UJcR4qIiIiIyN0YSLmQjkgxkCIiIiIicicGUi7E1D4iIiIiIndjIOVCTO0jIiIiInI3Vu1zodKlgRNPBKpVi/eWEBERERGREwZSLtSsGbB6dby3goiIiIiI/GFqHxERERERUZgYSBEREREREYWJgZQLrV8PtGkDnHZavLeEiIiIiIiccI6UC2VnA3/9BWRkxHtLiIiIiIjICUekXIjrSBERERERuRsDKRfiOlJERERERO7GQMqFOCJFRERERORuDKRcSAMpjkgREREREbkTAykXYmofEREREZG7sWqfCyUnA7VqAaVLx3tLiIiIiIjICQMpF6pdG9iyJd5bQURERERE/jC1j4iIiIiIKEwMpIiIiIiIiMLEQMqF9u4FunQBOneO95YQEREREZETzpFyobw8YN68eG8FERERERH5wxEpF0o0PhUuyktERERE5D4MpFxI15ECuJYUEREREZEbMZByIY5IERERERG5GwMpF+KIFBERERGRuzGQciGOSBERERERuRur9rlQYiKQni4jUxyRIiIiIiJyHwZSLlS+PJCZGe+tICIiIiIif5jaR0REREREFCYGUkRERERERGFiIOVCublAr17AmWcCBw/G9rneew9o2xbYsCG2z0NEREREVJxwjpRLzZghl7m5sX2ea66Ry1tvBb7+OrbPRURERERUXHBEyoXiUf68WbOieR4iIiIiouKAgZQLFeWCvGefLZdt2sT2eYiIiIiIihMGUi5kBlKxHpHSQM18TiIiIiIiCoyBlAsV5YjUP//I5a5dsX0eIiIiIqLihIGUS+k8qViPSGkg9emnsX0eIiIiIqLihFX7XCo1FcjPj/2IlGrRomieh4iIiIioOOCIlEsdPgxkZwO1asX2eQYNksumTWP7PERERERExQkDqRJOUwiLauSLiIiIiKg4YCBVwq1dK5d798Z3O4iIiIiIjicMpFzq8suBCy8EduyI7fPMmyeXP/4Y2+chIiIiIipOWGzCpb75Bjh0SH6KQqyrAxIRERERFScckXKpoip/rrp3L5rnISIiIiIqDhhIuZQuyhvrIhCnnCKXPXrE9nmIiIiIiIoTBlIuVVQjUvr4GrgREREREVFwDKRcqqhGpLZvl8tdu2L7PERERERExQkDKZcqqhGpTZvk8oUXYvs8RERERETFCQMplyqqEanSpeWyfv3YPg8RERERUXHCQMqltm4FcnOB5s1j+zy33SaXjRvH9nmIiIiIiIoTriPlUsnJRfM8mkIY65EvIiIiIqLihCNSJdzGjXJ58GB8t4OIiIiI6HjCQMqlbr0VGDAA+Oef2D7Phx/K5Zw5sX0eIiIiIqLihIGUS335JfDRR8DevfHeEiIiIiIismMg5VJFVf5c9epVNM9DRERERFQcMJByqaIqf37SSXLZr19sn4eIiIiIqDhhIOVSRTUipY+fyD2BiIiIiChkbD67VFGNSGVlyeWePbF9HiIiIiKi4oSBlEsV1YjUjh1yec89sX0eIiIiIqLihIGUSxXViFRGhlxWrx7b5yEiIiIiKk4YSLnUokWSdte5c2yf56GH5LJOndg+DxERERFRcVIq3htAztLSiuZ5kpLkMtYjX0RERERExQlHpEq47dvl8ujR+G4HEREREdHxhIGUS40eDdxwA7BihfPft2wBmjUDnn22cM8zbpxc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SUZqwhHpiFTz5nJZp47/+xRVIGUfkZo3Ty7N72mTJtIjDERnrkEgZmB30kmRPcZ990kKjr6W5s2lwEDFis5zDSm2PB7g7bet3/PyvPfpd94p/HPoMTnaVdIKY8oUee062j1xYmznGM6e7T/trGNHICtLRpzjyTx3htvBu3x5ePd/+mmrSFM0A6lgx469e62UvmgHUvZzgb8RKb2fZrOURAykihGzQXriibKGhZb/tNOGupb11obze+/JAdh8rKQk7/VrunWTNaRGj/Zd+M8NX6SRI6V64d9/e98e6YhUuN56y0p7jPR5Qg2kPB6ZS+IvxSRceuDet8+aPwJIitKGDd452dEwf773os75+f57vo53r78u6ZJvvhn+uiaRBlKhFD4xK0NGu9Gv233CCdYoq/KXihytFJlg9L05+2xZJy0S48bJ5d13+/5Nj6luOCaWFHPmeM9Lzc31X300UvoY994rmRhuysJISJB5LddeG7tqugUFUhr7rLOcMyaSkoDffgPatgUuvDA22xAKPd+ffbZ0zoUjISG8++t8vFKlvIt2hWP/fik3bs7tC3bsWLXKOvdHO7XPfi7wV4hI3+cuXWT0qiQqoRmNxVOZMtITetZZssDuoUP+h9e1YfXPP5LDryf9ihWlZHFWlvf9168HLr5YFu6sVctKFerSBVizxrqfGxoNemKz94AX1YgUELw8biBvvmmt8xUskJoyBRgyRK5H44RuHjzthTLy8qTgQV6eTKKORoGIFSuk91Tl57urYRJN//xjXQ/3exJpIHXBBcB33wGbNvm/z113SVWm/PzYjUg99xxwySXef/MXSJUrJ5exDqSikaJVpYo0JjU98fnn5T285hqm9sXD339L51716jL6W7Zs9KvImcHYX3/J5xvvNDZAih1s3QqsXSu/x2q/M1//1q1Wp6EpNxf491+rIFU8FKZ6bqSB1D33yHff5PFIFkKTJtLJ688558jI9m23WbcF+wzNv8cqtU8FG5ECij6Dxi04IlWMXHGF9Ep89JGUXU1PB2rXdr6veXAx50Tpl8feyCkocO5hnTDBO70v0Bd/1SpgxAj/ZdqjRUeilizxvt08odaoEfrjabn3Bx8M/X8KE0iZJ6pgB6Y//wz/8QMxD572A6nHIwf54cODT4INlb1hk58vc/aKo0jXkSoo8A4uwwmk0tNlroguIOpP27byE+1Kkfo6nR7X6baffgKuvFKuxzq1LxpzpDR1UquTPfywHOP27GEgFQ833ijv/fLlUjExKSn6C/La95V4V8kDpGragAHSKaJz9jp1is1zmccfp1GKv/6yqhXGcx2pSAKpkSNlfu4NN4T3XHo+LFPG929LlkiWSrDlPTQ9+LXXrNuC7a/mvh3tEalQUvvs5yIGUlSs6JfAqfQ54H1wSUiQeQnvvis/I0b4/l9WFjBjhlxfvVrmsMyaJRWMzAVaA51UevcGnn029KINhWU/EJxyiqSRTZ4c3vwbnQDv1PPmpEwZGc058cTgRT+cmNsd7CTdsmX4jx/qc+v1rCxpZHfpEvp2hcp+os3Pl9GLRx8FvvoqOs/hFoVZkHfKFGm0P/BAePuUju4ECkr275cAZtEia25ltOg+tHmz71pWTr345v5w3XXOj+nxRCc40df6zTfyvkbCPqplVu1LT5fKZfHslS+pzBGFaI9INWkCtGrl/PhKG9T9+xf++ULhVB0wVnPzypYFGjWS606v/d9/5QeIbyClnaVffCEZOqF46imZ3tC4cXjPpQHlH39I2XVzNF1Tle3zyf2pWtW6Hmyk0zwORppS6E8oqX32z5+BFBUL48dLSenBg+V3f70Ut99uXU9MlAICnTvLQefdd317cdatswKmmTOl1+bZZ73T+oDADRw9KJx+emivpbDs29K7t7w/9rkaoT5OKL31Ho/VIzh7trXeSCTPBwQfndGDdIcO4T+PE7MogR5Ijx6Vka9Fi6wAO5aBVJcusu7RBRdE5zncwhxVCncds379pJd97FjrMw+F5s8Hqv7YvbvsZ9pREk0ffihz+G6/XdZVMzl9n/R9ad9e0mGc9Osn6/cUdsTq4outuZ+RNgC0dPuKFfL5moHU9ddLg/KFFwq3nRS+J5+UObz79kV/jtTTT8uxUDl9l599VoJznUMXa2aAuGyZXP72W+yeTzsXtRS8yS0L8vbta6XJrVgR2+fSIGPKFMlg2bDB+luo7Qedx3XTTXIs8XiknRWIPnarVtEvztS3r8w5bNpUfnf6LO37PgMpOu7NnStpV7/+6j0fw0nDhlYPifbemRXbkpOBgQOd/1cbcomJ3pM4hw/3P29m3z5rlff27YO+lLB8+inwxBO+t0crpUYPkubJ0x/zOSOde6GPcdVVwKhRod03WilZVapYqVX62OYio9GuJmg2bLQCWnFVmBGpSOk6ZIFWvY9lueKGDa0g334iHj7c9/6h7M9ffCEjXD/8UPjti9b+PGuWvI8aLJeEBabdqH9/Cdj/8x9ZFHfvXglodV+JVsPe3D+dvstDh0qnx4knRuf5gjFL8OscqWinepkqVJBjtdP7aX6X4jkiBYT3/fZ4JLXv/POlEzQc9tEac0Qq1HN0JMeiaJ//TdWrS6fmgw9Kp8DJJ8t8208/te6TmCjfL8VAio57e/ZY10PptdaTfmIi8P33VtlYHXVwGsqtV89aAC4x0ZpY2b+/9MKZ68CYtBRqw4a+lf4K69JLJeBYuND7dnsgtW+fjNYlJEjO8vr1oQVb3bvLZShFEMwDSWEDqVAOjlo6OtwqcIHYyzabgVRh5n450RPxLbcAjz0m+8/bb8tndNZZkT9mx47WqKzpyy9lHx4wIPJtjlSkgdTRozKyM3aszD+IpDEYqEGj++yZZ1qNsGjSoMK+3QMHyui2+b3Vff/ff+W1BhLOyJw/+h2NdH/WFKcWLbzfYzeVxi5Jfv1V9imVmysN/i5dpHH89dfReR4z9d1p3zl8WObq2jM2YqUoR362bpUR7pYtndenC7R2XGHs3Bn+/4QTnOTmyqKy33wTfidNjx7eC9ibgZQW7tq5M/DnpMeM7OzQ0zL1ePnHH9KmidbcZdPAgXLuad8eOO88aW/pZ5GaKufrhg3ldwZSdNwze5QHDAB69pT0Bie//WZ9wRMSJBVC12/Rk4S9ahsgjWxz5GroUBn+fe+9wNumozn//COpEdFiBjc6H0SZ6zkB8l78+qtc//hj+fLbK4k50fcjlEDKPInUrClzT8IVTiAVat51qDIzrQV3daTSnLRb2IannRmkqUcekUt/65QEM2OG7G9vveX7mb3zjiwc+NFHkT12Yeh7N3iwpJiGau9eOZk99JCUW45kfZhQAinAu2c7Gl58UY4tgG8jIi1N1l4x01J1v9qxQ16rU0dH3bpyWdh9f9w4KQ4BRN4A0LVjKlXyfn2pqbJ8wCmnOI+8UfTl5/umsOr+VK6cpD6dfHLhn+ess6x9sFYt5/PChx9KWnevXoV/vlA4NdCjfW5QR45IARt/6XLmuaFJk+g851NPyQjJSy+F/j9PPmkde0L5fhcm6Lv3XjmndO4svzulPAbbDk3D3r9fzv0JCbI8TSAtW1rFKQYPliDXlJcnj5OQEH6q5+LFMl952jT53dzH7K/v8svl+c35XSUJA6lixGx4lykjDUptKNhpr13lytLgN3vY9HG0p/jPP62hbnsglZQkvX2ZmdJA9dfANtPizJGzwjIPfrrGkQYA9oO4uW06OfeLL4I/hz31MRDzQHnoUHgN0+xs6YnXk/Tbb/sPhJXOwQq1EEYwy5ZJfneTJtbaOLEckbr3Xkn5HDBAqjrm5BR+knSgUuE6CToWVq6UE72/Xu///tda9yucRo795Bvq+2M28AL1hNpTcX7/PXoT1V94wepksTdUfvlFCr9oyi/gGzg5zYOKVjqeucRDpI9lVubT9zgxUb4ne/bIMbS4rovmNrt3y36bkABUqya35eZKQ/CWW3wLDpx3ntw33IIQ27ZJJ+OMGdKp4VQB9sYb5XLjxvBfR7jMebmAVdwk3MpzodJjv7+MC/17nz4y3SAadC6jWRo8GLOxH8r32zxGhlL+fPRoqZLolAlkjkiZbatA26HHXDO9PViGQL16svzJCSfI7/YS6Obz+VsHyp9Zs+T1Pf+8jK6axYL0+1VQIMfR+++X81pRpbK6DQOpYsQMpPxV61PaID7vPOmtM++v1/U+lSpZDZw1a6Sn3/4cJ50kX2qnhqrH490bEs1ywGZDq1w5ea6LLpKFAO3zbSJt/OvaDzrfJJDClMY95RSZRH/SSdboYLADabRLLDtVezQDqQ8/lDRQDfYKq2JFGRk8+2yZ1LphQ+Eb8dpAPvNM31G9WJainjNHTvTaCxot9n0q1Ndg3i/QiLH5+DffLL32kVaxs7On+ZjB3aOPypIN5qKdVatKmoyyryXl8Vi9roF6kLdtk9z9QPMazf+P9NjwySdyuXevHCdnzbLSguwpshRbmm5UpQpQurRcz82VYPbVV4FBgyQbQj+P776Ty88+C+959PvilvRN8/v78cdWUZfCrI8WiH5XMjO9S3Xb/x7vtbXCXd7APB6EcowdP15GbPbskZS6/HznQErT3oDAxxn9W6gdYCadLjF7tv/iKuEeh/T+06ZJh+3YsfJ7UpI1hWP7dukULK5LloSKgVQxYh64wp3Y6BRImQ0B88upDRmnUSynA1BCAvD++9bvsQqk9u+X5xozRuZx2XsDI11HKhylSnmnFIbTQNM5IR9+GHqvu/ZARWsxPqd1xBITZdSyenVJVTn77OjMTzGZ+09hG567dsmlU5pBLAMpHYnS9FEn8+dLqtebb4b+uJGOSJn/17On//uZ+6h2eESr2pj9/TZP7NrYWLHC2oaePWXNKz0x20ekjhyxelbti4abnn9eqo8GGtE1359IC+DohP7NmyWdr3t3qyHrtO4exY7OF61WzTsF2Xz/77mn8PN2nNKR4yklRV7jkSOSqq7LI5iV46LJ/N788Yfv36+8UtoI2uEaL+ZxLdxAKpT7a7B+9Kh0fpYqZRX1MQOpGjWs81ugx9V5zp9/bt0WLKNl+3bJrtFz3ogR1uid/fnCPa/aj1tatVlft3mfggJpg8SzSmM8MZAqRszGr7mzO9ETzeTJ0ljRk/4jj0jPOmB9KVq08K4e17u3pEnccovvc/trNPToIcPEQHR7aM3Jlbo47Ztvygll8mTv+5oH1pNOkst27UJ/rmCjfICkVXz/vRS1AMJrRGl63vnnhx5Iaf5ytOhns3y5NQJ38slyYrQX84iGSZPkwK+BYDQDqd9+804bA+K7eObzz0sO/fjx4a2RFWkgZb7WQL3TF18c+raES7ehUyfvJRcA7+OV/QTs1LMLeDd27OXUTTpf0t+C5ID1vo4ZYx2bIhVowWEGUkVDA6nq1a1Oxdxc3/e/sI093Qf79ZO09lgFLOFITJRzfkKCNS/Xfv6LFvO44jQXqGxZGSE5/XRJEY90mYKlS+U83a2b1dERqEPITr/f99wDTJwY/P7mfhEs2P74Y2t/O3rU6ty57joZpbJvZyjnc/3bpk3WbcECqZkzpWMzJUVSKQFJMbc/ZrDndmI/z2ggdeiQdFoD3t+tSpVkXmhJxECqGClVSr5QzZsDt94a+L5mw2rPHitIqF3byrdVBw9KkYghQ+T3E0+UlJyuXa37hNJo0FS7WI1I6YFCq4Q5rVGkkpLkNYeSC63CuW8kc4m08fj009bK8JHO3fj1V5n/tX17eP9nvkfmAVlNmSKB6rZtkW2X3ddfy0Ri8/lDKeoRiAZS//zjG7DEslEbbP9YujSy7Yg0kEpOBh5/XDpCJkzwvy+++abvApTRGrHV1/nGGxJImmXBIwmkzPfCXlzGpA2bQOX0ozmycOON8l178UVrLg4DqaKVlyedUTVqyKj+ggXSUWbf73VfC+d4btL9ZssWYN483300Xn7+Wb5nHTvG9nnM76C/ogqlSkln3Jo1kQeuo0fLCM+cOZKi6/GEt9adbmfZsqF91mZ7IVggpYUhAO9Aql8/4M47vUe49+2zAqJwz+fB3js9tjRpIm0ywP/IWrifg/08Y87D1mCP60gJBlLFSKdO8mVZvjz4fc1AKjHRCqT8NdLy8wPfx1+j4fHH5eAybVpsGhZt2liNwJwc6Sl55hn53X6QN0+o7dtLj9077wR/Dp1AGc7CmpEEUnoADDfFwMlpp8lIwzffhPd/5mfr9Dk/+KAsGBitCfROwW5hG7bXXGPta/ZAMpbpOMFO1pGWP480kCpdWlI9li+XwNxfowcAGjSQ/VwXQXYqaxyJQPMlzIBZGxoTJkhKplOKDGDtL6VKBX6/daR6/Xr/DQizGmUkzO1v3VoC99tvl+qKQMkMpD7/XILJWJg3L3C1zWuukU6U//1PAqhTTpEUUX8jUsGyNvwpzDzYWNi6VUpvn3GGdHbqd6Zly9g8n/ld1pEJ0/Tp3pUqIw2kdAQkUuF+v6tWlXObLqcSiFl4wUw3duq40aVfgPDnjQUbkTIr/HbtKp045vzWwgRS9u9N6dKS4g9Y+7x932cgRSWK+YVOSJDh7yeekIa3jhB8+aU1srVvn5XDu2KFTNA1e2X8NRp+/llOrtu2Se5606aSehEtSUnW4+Xmen+x7dtyxhlSyWjGDHn9l10WWiCVni6XoRRYWLpUJmJOny5lnStWDO11ANbcMzOFLtiBSR/fX+98uCNHZiNd37+ff5aD9K23xm4dKfM5n3lGTmTz5kX2mN26yZpUgG8g1b69nBCcJknHmtnwDqdx3aiRFIto104WGg2nxKxZadEpxcbjkeBk2jQJXoYPlxPxeeeF/hyB6OvMypIefHN/Nvch3Q8OHbJKWN9zjxSwMen/5+UFTjXVQOqrr/x3LOlj3313ZGWqze1PSbFeg466lSkjqb56/CgJ+vWTYDIW65F16SLVPZcsCXw/e4Dtb56e2egNp7pqixYSpGjHYqBjoa65GEt791pFTwDrOBOrAL5jR+Dbb+W6U+fMwoXewXSkc9LMIO3gQfmMwslWqF9fLu+/P7Q5n9WrA6+/Lml7deoEvq+Zzrl/v7VdR49KpUKzyI1+Dm3bWtsUqmAdf2YgVb++jEqZxXrsqXfh0LaAHs+OHrXaebrPc0RKMJAqZkaPljlMWpHIH3N+QWKiND47dZJ0sAkT5PYLL/TuWdIT2KefSsnYV16x/uavga0HnAYNgGHDJF3MX0n2SJn5x+YX274tQ4bIBNiePcOrvBTOuk7Z2XLQr1NHTiiatxwO8+QUrKiDWX3RSbjpK02bWo+pB9KdO+XksGxZ7NaRUvn50lh6/HHZH50cPiz3CdQ7ralp9kDqf/+T3kNNUy1KkY5IVa0KXHWVfP/GjbPK/Adz9Kh0fuhzOQVSBQVyokxKkhTfM86Q6kxmJb3CmDFD9p0zz5SUYbOB7RRI6Xft8sul+mHz5t6PZ56o//7b//OacyfN3mPTo49aDdBIGnvm/yxZ4htInXuuBIXmqPB338lI8RNPhP98xwPzWNy+vbUmXDSFUsb5448lRXrVKv+pfeaxP5xiPXPmSIeZBuJOAcs998i5M1ajcyZ7Z5R2MPjb76NBq7Y5BVL29zvSQMosJlOhggS+geY82j3wgFXk6qefwp97+8MP/he6N99bc9+ZO1c6Hc12U6jthw8/lMuePSUw83i8C084CfbYTZpYjxVuZ9HVV0uHsC6D8s8/1tqiDKS8MZAqRjZtkonTP/wQfNHOmjWtRrZ9nSSnanwm7ckz7zdwoDROzd7yggKrHHqDBqG/jnDMmSMjJoAcsEOt1KM5vpoGGIi+3lBWOy9MupAOm6uHH5ZRwcxM/z1xwQ6k4QZSDRtKOpj52LFcR0ofu2VLyS0PZW7Oiy9KEDVggPPfp061GuzhzhHz56WXJLgzJwLbDRwY+DEiDaQitWmTdzDqFEiZ35HkZBlRSE6OXsWt9u2lwIaOypiNvjFjrOv2QMrf/hxq2msogRRQuI4B8/k//DD4nKvvvpMG/hdfSPXG4sbjsd6Td96R4DKanWZ6HPbXkXDppRKw//GHfF/vuUcqoY4eLfuApvLpvrZliwREO3dGliVh7503Pfkk8OyzRVMW2j6appUko724tklfl1O6mL/ANVxOaYOBKnU60fPVP/9IRkyglL2sLOloGzZMzjG9ezt35h06ZJXanztXimoA0h7S/cgMrpyOafv2+QaheiwKJ/A0H3v3bgm8gnWih6phQwm++veXwNCcO6/Pm5bmfR4uqYFUnCv9UzSZDaVQRk+0cZ6YKGlU2iMSKJA6/XTptX74Ye/7Pf647+Nv3SoHhaSk8HqSwmFO4LePSNkPSPv3S+PtjTfCmyB8/fVywFyzJvh9gy1WGEiXLlLMQSUlSVWeM8+UtDqn3k09WU6eLCcBc8FkILIJ1fb1b8zRO7MaVjToZzR2rKz/BUia2eWXSyrErFm+/6MNBSe5ud6jKfZAasMGGb0rWzbwGkN2zz4rjbEzzvCf9tGxo2y3v8WRndImQ7F9u1QgPHpUApNatQIXUVD2zyhYINWhgwSgHk/ggDESTgHLOedIj2dBgdXRYqYCbtgga5SYixeb1wPtg1qVEwgcSBVmfy5TRuZG/fWXfM/sI1Imj0eCVP2+OjUSj3eBsgGiQT8jf/PtfvhB3teUFO/9rWJF+fnuO9nXdE5tYmLh5hHpdjh9lwsKJFDLy5ORq1AqvkaqqEtOz5oloxTXXeecGm//LkUjtU+F+z7qfqDVW594wn+a3y+/yMg/4J1S7PF4n0e1czg9XTqJdu6UYMPjsVLtzUBKj/u//SY/bdtKh3N+vuwfer7VDphIA6mVK+UYc+KJMhoeLe3ayc8HH8jxGrC+3/XqSbsxMVHmZ5XUQIojUsVIOOtImQ2lhASpqKVr29gDKfvjOo1cOdG0vrp15THef1/yy++5J/D/hcNsHJ56qvdJTSvfqYsvlgaxPYgKNuQfrBCHSQ8kq1ZJznIoc7CUvYGgB0fAf7Wik0+2rusJ1TwQh3vi2b3b6i3X1xvLESmnNJtLLpGT6C+/OP9PoEniOr/G/N3cJ266Sd5TcwJwKLQx7i/VA5CTyuTJ0hvuRDsuhg71ntMQzPz5Uvzh8sulERhsjoiyn9TMURqn+6xZY21jtFKynnpKFpfWfci+TboumfZw62f1zTcSXNm/P7Vry/7h9FimceOs49k//zjf54orZKmBYI/lT2qq1RtbUOAbSC1ZIh1P110no8rmCEG4PevHA/M91Pme0eLxOKeorlsnC+3+9JPV8G7QwLnc9OmnS9qUpqVFYs8e6alv1kw6Y5zmvxUUyDGmbl25byipiIXhb+SpadPYPN+uXdIJ5W8enHluaNQosiDSLOBgjkCG0kGsrrnGOlaos87yf38zINXjUJUqvp2RW7fK596smfxerZpMd5gyxZqHZHb2meefQ4dkH9LbdGQLsBa81TL2CQlWYOdPt25yfL36audqxcuWWY/17LOBH8tu/nzpdNZznrmf2c//XbvK8dTswCpJOCJVjJgHmWAHHLPqWoUK/kehataUk9H778uXNSnJOgiY/3PggHyBK1SwGsXa+NTe5r17pVBF69bhva5A9KQ6ZIgEadrzVK6cjB6Y/DX+c3ICN84jCaQA6bkKtfJQTo415yctTQ7q999vPbe9JL3S9aoA63MxTwjhjkjNnCk/3bpJcK3bBkjjJNpzpD75RPad8uUl/7py5eDvc6BJs1r6vGJF4L77ZP8tKLD2aV0jLVL2dalMCxfKCGmrVs4liCdNkh97D2cw0ViQFwg+IhVtBQXW4pCVK8ulud9Mny77ateuVk9uKPMrQl1jrWFDufQ3IqX5/qE8lj9mkR17IJWVJb33u3b5ploXxxEp8z3s2FHSGKOViWA2RhcutIKEW2+VEWwtOV+7towUmh0+kydLUNunjzUR/+hROZ998olkHFx1lZWiFci6dbI/1arlvDwEIMczc6Qr1mm8/kakzOpt0RQs60L/PmqUc6ZKMM8+K+9tz55y/ly0yDoPhhOU6TpPJl2s2Il5rNHvp1O7oFcv2a6vv5YKnT17WvuOHseOHpWf0qV9R2rNY7+Zyq7HCHM0zCkjw9S2rfwA1uLI5uswA7VwO2+mTJGpD3fcId8rs82o37+CAvm5+WbvdUVLGgZSxYgZAAU74OhBsGlT+bKb93f6Xz0Y/PCDpLnZ79etm6S4fP+99DADcjAqXdqqVBOLcsDaONSqdaVLS26zU3qNvxNadnbgQOraa+Uy0GiEsjfIQn2t5ijZPffICf+003zT6/bulV7wq6+WFeTNz9wpkAp3iF8fIznZOuCbI1IPPyyNlw4dwntcfzTIbtdOTgTTpgWvzHTDDXICcirEoYFUjRrWJFlTYfe9QA3uTz6RCe633hp4LZdwg9toBFJTpjjn+8eykWc+tn6/zNuGDJFG6Q03SKdBgwYS+HboYKVd2l97drbVIAgW/Oi+tWGDc/BqNjgieR/277dScfPz5bjzzTdW0Gh2wNhHaIp7IBXtkWvzsc39v1Ur70XJNXg2g+3vvpOqlwsWSCM4NVU+Ix0Vfucd6YQLJZDS0U19nmDb6vR7tOlIQZUqMgo7ZIg0oMMttR0qfT0zZ8pyCW+95T3HLNCSB6HQObozZvgubBvOiJTT+z57tv/7m+dN/X5u3mwFRHZffy1V/hIT5XydkGB1ShcUSHpfzZqyj5rbZL4/5jFJbzf373DmuTmlBprvQbhz5nQ7li71Tme/6iprlPDXX+W1n3RS4OI/xR1T+4qRcFL77L26oQZSgNXodxrFMu83bJgEOjq3xz73Jho0kFq8WEaAateW0bObb5Yvub/X0KSJdT3UHPNQSq9mZHgvVBxqQ8I8+Hk8vr19WlBjzBjpydchf6cUgooVpTT9ggXeB/FQ6Gdj7j+lSskoWblyEtxddJH/EbJQ6GRds4fM3H+Cvc/ly0uam1NFRA2k/JUINz+PSPbDQJ+n5s77S+3T+zz4YHhpFpEG57qtTZpI7rzTJP1YNvLM7dSGiFP587fftgKn66+XEYdhw5y3b9Ysq/RyoG1v104Csu7dpWPC6T0z/79Ll+Cvx27jRpnzAMjjn3CCzL879VS5zdynNZDS405xDKTMRmGjRlJ23n4MjpR5PDTPc3fe6X2/Ro2875OXZ+1nv/wiIwj33uvbex5q1T4dkdbncWI/RsR6ROqyy2R/WrdOjs3acRms4JQ6elSCyFDTec3X8/XXvunUDz8sacK33x7a49npXFld/sI8HxQ2kAo0v9bf3CR/c6P1mPbVV7JdnTtLm0jncepzNW1qdWKZ87jtr0VHjz74wLotWNtk0ybp2P7nH+dAyrwe6YK89vm4ZlBpZifl5HCOFBUD4YxI6X3XrZOdX+9/3XWSCqGOHJH5GWb1pU6dJHf2sst8H8/eYElMtIbT9TliMSI1a5b0OgISQJx7LnDXXd73NU8AXbpYB55QDzChpBV06yaNh5tu8n3OQMxtuP12/2kTe/Z4/26WoDdHk9q2lQUpw6UHzx9/tNZauuMOCXqitfZS+fLSg5mRIXNoxo61Xld+fuECbTOQWrhQRkjNFI/CTogvzIni6aflu/Poo+G9l4UdkQpU+KR06egtvmtnvr+XXCJBklmZMtBikf4qWOn/VKpkrXHnZOtWaci89JI0EJ16x/WxZ8wA3n038GtxYm6b0zHNKZDSeRV5ecWv0VGpkhRDASSt77TTpNMgGkqVkhE/wPu9rlnTu9NEAxwzBdnps7HvV4Ea2CZzROruuyX7wj7KUdSLlCYlyUiIzjPUlEMd2Qnmww/l/BlqhUX767FXn6tSReZy3n+/dGhogYJQ6ef8/fdy3NDvDBDetAD9HCZM8F7Pa/Fimc9jT9P21w6wzy395huZa6Wp73v3SrCn3/cHHwTGj/feL52WaMnOtsqz+xNsFOm996Tj9vHHnedIRWNBXns65MyZ1vqUep+VK+X577svvOcoLhhIFSNmIHXxxYHva/byHDliBQlNmniXKi8okB6XLVuswKR9e2DwYOmBsT93oCAplql9gO/aUPaTpX2xXj3whHqACSclK1BFJye6rWlp0oOuDRI7zfFv0cL38c3ra9fKCczMaw6F+RhOqYxz58p8BH+P++67ku4Qqqefll5i7RH2F0iZn91338lnUa2a77wfDciqVJHe6nPOsVJR7SJp4AT6H3P/cHoNc+daVQTDCeIiDaTq15fGUZcu0lgyF9BWNWpIOe5Ak7AjZb7GsWNl5MkcIXVaR0rpdzg3V6pR6qi2fk9OOinwQrfa+Ak0J6IwSxWY2wJIZ8PixbL/6yiVUyDVooVsW05O5M8bjt275Vj/wAMyKhmtESJ/9DVlZUkDM5zqqME4Ha+3bvV+HzWQuu8+afD17x/aMTjUQMockVq4UI6x9sqgRT0ipZYtk9EMezpcMIFG15zYX4+/0dW1ayVd2z5iFYwGUrNnS+rsqlVWyncoS5Ao/X5XqeKdBt6hg3QWX3qp9/3N77POdQJ8A6mNG6WjUek5R5/jzjvleFCtmvy+e7dMe9BtMvdHHV33JycncIaGObpltnv0fwoTSOl5xn4MXbfO6jzgOlKCgVQxUrmy7Mjm5Hp/7KNX/goqmPfTL6dTQ84pSBo5UtKv9OQdi0DqjTekgQDIAeT3360DsR4Y+/SREuLm5OCdO4GJEyVA1HK4/uh7o1XAQhFojREn5jwkc4KonTYmNLXOKZDaulVKoJ59trw/4TA/W6fP+cUXpUrW99/7/i07W0Ydhg4NPXVJX7emD+Tn+wasK1dKb7euO6QNl127fBsx550noxBXXOE7T8M8IVWoEN7IlwYawRZIVk6fu/n8RRFINWwoa+hUqCBrXJkjzXZVqkjqn6bUmb3AkTL3TafjkVMg9dhjEgD+97/ye06OpLHefrvMpwplIW2Px2r8HDokDTGnBn2wdZ+C0W1p0kSC1c8+k/1fU3PM492gQcALL0iVwDJlIluWIFzffiu94rfdJu/r559bi63Hin7ntMf666+j87gHD0qHHuDdIHziCStIHTrUqqLYsqUUGzrhhNC+a06pfYcOSSquvhbAe0TK3zG+qOdITZ0q+12/fjJvVlOmQ13DSov3+EuHtktO9i74Yx+R+vBDKTSh6brhlPPOzrYqaZoiWRPL7Ci54w7rdk2Lt88ZPeUUmV82dKgEyDoPeNMmuV1TDe2ftx5bdJ623RdfWJ9J+fKyT+qCvaEsMxEoADIDqfR0aaOYo+vRmCNlBlJawEuft6hHX92KgVQxkpDgO4HRHzPVJSFBUvpGjJDeVPOLaKaz/fmnXK5YIQ1pM3fYKUiaO1dO5ppuVaGCTFr0t85OJDIyrEAoN9c5P3j2bOmdPO88OdEuXy4Hp379Ak8+VdrzHUrj8oMPJN3kxRfl/qG+Vj1Y6qJ6doMHy6W+v/YRr4YNrZObztUBwl/Dw2mto5dflqBs4sTA6+6Yn32o1ZWcAqnRo62GMyAnnQMH5Hb7NtpHpE45RYKBHj18A6nsbOu2zZvDK4OsE9EDdQI4TRw2Rbog7xlnAK++aq0nVrdu6P8LWCd4p/LnatIka9R5+HA5HhSWvkbNn8/K8m4UOJ3k9+yR/bdpU5nnaDZ2ypa1/mfWLFms2ol2JgEyMt+0qfNITKNGsj906hRZdTl7IGav2leqlKROli4to/e33eY9ih9ruvjoyy9bt/mrNBcNK1da73O0R2H0HAL4LxLStKnzuS/SEalbbpGgvnlz+b2gQAK0E0+09h2nxze36ZZbYr8or46E2ufyhNphGW5hkMGD5XuqhYzsgdSXX0qAq51p4YyE5OVJ+8LO/hyhaNRIRpbuvlvOx3oc9Ndp3L27pFy/+qpkhGgA8eGH0iGpc778BQv6+Js3S9tHz1/6OVx0kRTnKFPGmhbhL5DS40RqamiBlB5rbrxRyr7r98D8TM1qgKFwSu3TzkB9XI5ICQZSxcyIERIgOKXxmMyJ5wkJkmfboYMcBM28XbMneeZMuZw1S1KmzN5Np0DK3rC45BIZFp84MayXFJQ5pG1//txc6yB86aVyUGzePLy0Hn+TQ53s3y+jJP36yQnBPhnan2ABj07A1R7Rb77x3rZLL7UOeOaBN9xAqn17K/jTE82KFdJD988/gU+65m2hVmzSbdVtz8uT3Prnn7cmTWtDRpmfcaDgwL6tpUvL556bG/5aMrfdJnOtnBZFdhLNQKpVK+kl/fFHeX77++FPZqZ0GmjqiVP58wUL5Dugj9mwoRTCGDky9O3zp2JFWd9n+nSZh5WR4b1+ltOIlN520UUy/0/3e0B6c8392UyvMZn7hJYXdlqG4McfrcZnqMUGTHoMWbZMOmTsgVWbNpI2bW/gjholxwdzMfFYMFO0VSwXhtV1f2rXjn6qqNlA02IegLW/PPqo96jDnDnSIJ4/37rPK69IwQmniq5OI+ha4Ef3ncRE6RhcvVrStvwdC9PTpRPgrrskiDVLXMeC/RiowazT992JNubD/Q7oMdT+3oWyhIE/5rF99WppZwAyipSQELgaqt2UKTKKtHSptGn0HKNBRqC007//ttYx1OIKwbJMNFvhscekPaXtHKf2g2aUbNli/V2LgyQlyf5bUCAdTIFSmIO1Ta69Vu6Tk+N/IWJ/brlFRtPMtaz0O8FAyhsDqWIkP18aQZ9/bi2G64/Zy2DvoQlWwc/pb2edJWkFZm+502Kr0TZ2rJxEAd/845wc75ODeV2/8IMGWfnL/mius5Y6DiTYGhv+NGvmvSYUIAdiXeBOD9Ka/64NX6cDaWECqXbtZM4S4Ft6PSUl8DpSwVK5nGgP18UXS0+nU75+r15yqfPG7AscmpYulUB/2zb/DR1z1DaUgCYnR+Z9ffhh4H3ZDJqdTihmal8001v9+fZb6UHXgiT+0tvMymZt2kgAtHBh4Z8/NdVaBNVpJNOsbqj7rH1/NvfflBTv//d30taGZVKSla60YoV8v+wLIRemTLe5bY8+6ttxpAoKrEZdfr4EcJ9/Lp1KsTRwoFzqvEogtimFZudUsBThSB+7ShXvqqj2EXr1ySfSEPzqKxllWLpUshFOO81qmP76q6QFbtggAb9dsM4gfw3rWrXkO6fpqbGm+7uOiIS7Lwc7//mjz2dfcNj+/OGMSJnHxXr1fCvGhTvn15yzp6Oa2gGsqYdqxw4Z3Rs3zrsirLaVtENKX98FF0gGT//+8ru+H/ZFee3HtB07rDTr/HyrGJKeW3SecCjfVftjT58u6bRmGl9iYmTzMdu0kQ6w1q1lpMuk70H16vI+BMpUKQkYSBUj5hcv2A5tntwSEqTnWnPQzQApIcH79+uus+ZRmLffd5/0+phlhLWh4dQDGKncXGnQau/N2297P589kDJTNg4ckP894QRrQvjRo8HLxOoJ0V8qkX37gPDX0EhPt9bfUklJVm+hnujtJeT19X76qZWHXZhACvCtrmj2tAdqeJrvfbiNxP/8R9InTj1VGj0nnmilN9iLhwQakXrkEWm8f/aZ/209/XSpanjXXRKgzp8feNsOHZIRmjvvDNwoPOUUOalcfLFzIBnpiNTatVJZbuFCCRDtDRfTkSPWe28/Bjj1uut2rFkj392//pIeeDM9NBqcPosbb5SFUj/7zJrbYube79rlXXFx507v+Yz+jnEej+xHHTpYpYjHjpWGs1lpFPCuphXK8gamtm2tkRenBXnN7b7kEgkAPB4r1SvWJdD9Fd2JFTOQinQ+YCiPbfK3ZpHZ4VO3rnQoaAGBF1+Uxc+bN5c07Hr1vKtJ2h/Dn2AFhTIz5bMP9v4vWCCBn2YbhEuPgaGOstv383A7Ot95RzpHmjeXff6ee7z/rp+JfR3CUNg74+yBVLj7sv0zNNsn9nPUI4/IMeO++7w/C+3cW7tWLvX11a4tI2Rnny3zsjX1X/cz7bjV4/7HH0sQt3Gj94i/nuPNzyHUgMQeSJ1/vpyDzFTYwkpIkLlXZnCpz9uli7QbdTkPBlJ03DMDm2CNArOx7fFIj/tHH8nv9kag+XtSkvPIVaDn0APErFnSwLH3boRj8WLpaW3dWrZDRySuvFIaK+ZJ++mnvcuFjxol/2sPnIJNwvSXU+1EDyQffCAVunReTyjsB/2kJCs9QEut2oOcM8+Uy9WrrRODv3koodi1S1KVAOv16skrOTn0OVKB3qt27eTSnFRsnkRat5aT1vz53p+xfk6BRqT0PmXK+DbeN22SIGfWLJnv99xz8l7p/DN/zH0qUC9zQoKcVD77zGrAm/Q9ufPO8KqnvfOOjMqdcor0dmtap5NOnaRhuGqVbwPWKXXH/Bx1MjXgW9EqEvv2SWrThAn+RzLbtbPmMQHWZ/veezISbKaVbNwoDbinn/bddlPt2rLvzJ9vjT7oAqrmkgCtW3tXxwx3lLBuXVlMWP/XHkht3SqNDx1B0XSwogqknKrcxTK1Tz+PNWusNHAguoHUtm3eixv7C6QCHacuu0x+zMpsTuyP+e67kqanS1uUKiU/9nNtTo4EUCedJD322mnnz+OPy/bMmBH4fv5oIGWfi9W9u+9933tPilKZc4P1O6JFmoJZt0469jZvluO2feRE3/OqVeX1B1rs3s4+z1azQeyPHYouXaSzw3Tvvd6Pb3IaObvjDunsUeb+pvvHTTdJVcHrr5ff7YGU+Zp27fI9zmzaJM+t73+1ahLYJyQAF14YOMA+91zpJNJOWHvnyRdfyGeQkCABVjh+/VUqpuq8SrMDz/6dbtRItlULdJQ0MVr7muItWCBVpYo1oTI1NXA638GDcrAfM8Zatdt+P00PMg8w9oZFZqacVApzMp81Sy67d5fH0Yb02LEyp0arybVtKwHb1KnBHzNY6oGeKMIJpABJJwp1UcR167yrAjZqJGtf6IlEG6JffCGXOu/i4ovl5L59u/f6FCrcHrxJkyQVpk8fq/qYOSIVKLXPvC3QCU9PTHl5EtDoQn4HD/r2QBYUyHwDwHrNZtBlH5HSg33p0nJi69HDasju2WO9f6ZgRUTM1zJlijWJ3+6XX+Rz6NjReX7KV1/JZ5ScHF6qRahV+zweK03n66+tVJPKleW1Bwukom3bNimOUaWKFfDr8+XnS2O7VCn5LtvTpHQ/MNMRdb+2LyYeiAa0ul/oscnj8Z2jpMevcJhzQ+1zpI4c8S5vrA3dogqkxo6VS7MhWBSpfYAE4n/8IdejkcZqPvYTT0gFRMDaX+ydf2YnyltvSaN/wAArYJ8+XbIT6teXz6FCBd91lOz7wsGDMkKqI//2NFE1f753OmWw/VRTxw4flg6zQ4fCW4/H34jUq6/63veaa+Tywgut40G41SuDZV3oZzJ+vFRPDYe5wGtCgnR2nXWWNRpSUCD3CSV1fPVq3yIi5pSGSZO8/+Z0rixd2vt17tsnqe8PPSSj9k89JYGT2RnnL7UP8J5+kJYmQUrFinK7ZkZ07Gh1lk2dKutSaUeQXa9eVuo74BtILV9uVQEON0vk1VflPXr2WenA0+kiZ57pG6Sfd578lFQckSqhEhMlqJk1yzd9zx7opKRYgdkbb1jrBJn3u+wyafy89ZZ1mx4wNJCyp6VFQic7nn66PI42kPQAmZ4ui+JqT1Qoja1AgZTHY42cBCpLruzPF2ojYtEia42SAQMkCMvNtQIxPTlpJSCTvdCH+Xq0xzxU+hgZGVZPojlHauBASeG8/HL/22FubyClSkkw37mzjDxUquS7MGp+vpXOpUVQbr5Z5plMmmRV01M6IlW6tJx8b7/dWsTRPvKooxH2Xks78zMNVNzi6aflfTF7402pqbKfhpuvHmogZZaCr17d+r9WrWRUS0c1TbFc48Zs5NoD8MOHpRe1Z08ZsdIRulq1JLDVYjhm1cucHNm39TFC+W5rb7seJ7SB4fS6ww0qN2ywOm7y8yXF6aOPrHQ/e2NPGzkaSGmDPFa0WMuzz8o6UoA15zIWzPcvVql9gPfxrW9fed9PPtn7/ub+9vbb0gm4erXctmSJNITffVdSov/7X+e17+zf01CLDoW7jpR+n/ftk9Hq++/3LrkejB6TLrhARhBUoE4Bp4WxQz0u6f1nzpRMEHsBHn+jhKFISJCRXnOutf24bQY8c+ZIYYhA22ky10Y00/zsj6u2b/ceETLXxFq/Xka4xo/3/h/7iJRZqTM313p/atWSnzJlvPcReyd4OGXL7YFUNNaRSkqS1Fh9H0aMsM6pEyfKeU3niZVUDKSKqVDy/bXXR68rpxOFU0Dg9D/m/XbulAOE9gLa09LClZdnNbjuvNO7MuGqVfLTqZMEWzfcIAf6vn3lxBRIKOVFQ1W9ukzS1AZgqI0Iezqe/aSmB0T757prl5Xqott6wQXyPv31V/jD+ebB06QTVtu3l5OnpueZatSwqhEFapRqAGyWtPW3xlh+vjUqUbmydfuZZ0pvp72nzkzts7OfkHR/DDZqZ76WQPOT9LO+8Ub/ZaYPH5bJzGPHhj4nJ9Tg3JzXZAYctWrJ3EYtVxzosUN5nlCZhQDsqVb2uVLae/7YY9KJMHSo/J6SYqXjZWfLyPjddwfe9unTpSF26aWSanLbbVblNZ1gbv5vy5bS+RKub7+1Oo7y8yVt+bLLrMDf/h3SDqWiGpEyO5nuvls6ZTQtMhbMNdY8HumoW7Ik/AqZTpo3t6r1mcfKQYOAJ5/0bRSb+5t91Orpp63efx21deqc0GO4/bwVLKMi3LV1Pv5YLj/5xNpHwskk+PxzOQfcfbe8H3rs27PH9xijQb454qUjJ599FrijSOnr27BBshbsS4i8+66MRupIiZktEUzNmnIcMzsM7cdtfT+3bJHvrb8qpk7vu3YoAL77pVM7YOJE75Fr8zG1o3HFCvlO6yiSPZDq1k2OQfr/TgF5oEV6A7VPNm6UrA7t5LUvxRCNdaQSE73TM83rOTlWwaKSjIFUMRXuxGk9OZxxhu/JduhQ7zSBypWlF8YcUvbXEE5KsoK1wi7Iu2SJd6qPWdK4e3drnYe8PKnOdOaZzuligPQS6cTzUAOpUFISb7lFTiIavIX6WvXE2bixpK3YU3D0ceyf6/Dh1m16n2rVJJ2tVavQntukB8/33vMuspGfL6mGwQSrgqaLRZctKyefJ5+UVEKnKm2APK/23DvNO7IzU/t0BXYNMOwnks2b5dLeoP30U+/qUKEGUuZn7fT6H39cRqzuu096xEMdmQ11RKpTJ2tx6oMHQ+tprlLF+3tsKmyRArMBe+qp8tq1U8X+/tg/G93mnBzvXlZ9TWee6V31z5SZKfMOdu6U44KmgZnM93TRItlPwm3wm++P0/c82IhUJGvjhEP31TJlZGSuVq3oBDX+9OhhpeE++KD0Uv/yS2QjE3ZVq1oFSULZL80RKXvD1ZxLpMGf0+f33/96r5dof5xXX5Xy/BoIqXBHpNTRo1ZgF2rpckA+05o1favodeni+73SxzVT3JzWDgxEvzs62msPvho2tKp/6rp39uAgVB98IMGhatzY2kY9L5iLAzttpzkKZXrtNe/fg+1XM2fKSMxrr0lKvVl86sABaz+vU0fSRB980Pq7mY6s2798uczBmjkz8D4SKAB65BHJqNBpAfZA3HxN4Y5ImR0HZgGdBQt818iaOlVeo9O8vJKAgVQxoyeGYOlKdhoktG0rFdNMU6ZIr5WeJHv2lAOAuaZDKEFSYQMpTc1Q9tQYp4ZjTo6kfuTl+aaeOU3GtjMPcOHMLwi3rLIe8Nq0kZOPvZdNX5v2duvkUvO9NK9nZsqigOb8iFCYj6FpSyohQRoVX37p/3EDzaECfE8K//mPnAz0s7H/PT/fSinQQPn99+XkfMYZvtthpvY99ZQc2N97z/mxNX3GnOT9+ecykmHOmzJfS6AeW/N+Tq9/2jSZuxToPsEeFwgcgD3yiKS7DBgg38+775aRKJ0TYm+8n366/E0n0Jt++kmClXA7ZezbXaqUdMZMniwjxE6vyf4d1KBj40ZrFFrXhQMklatOHefn1c/IbCzamQ2MSEoDA97B2EMPyef7ySdWiqW/Eanbb5cG7TvvRPa8odIF1K+5RvaHq6+OffBmvpebNgVeqydc9t52QEYl/vnHN/C4+GKZkzh8uG+JdDOYDDQi1by5HGd11Ns+Wv/nn3IstJfktnd8hJOVEMri2f5s2SJzQHXtJcD3XGt+N/R7fckl4W2r3kcD0kDbqoto++v0CEZHWgYOlO1ds8Ya8Qk0t8vjsbazfn3nysH2Kqz2Y1CTJt6/6+v9/Xd5n+2VTbXtVamSFJnS6sY7d3pX/DM/kxdekAJagdpEgQIpe3Afq9Q+cxRq1CirCJa53EteXtFVCHUbBlLFzJYtcvLSnt9QBapMp19SPfAGuo9ZMvvii6UXWnvIChtI2Q/y1avLqMMjj1jP+cUX3osNjxghJ5Zp06znrV5dTvJXXCEHuUCL5prbqg3yUARbvM/OPCn8849vaph9fSpt6DsFUnPmyGvr2jX0Con33y8nDnPk0elzmjJFemFfftn3b2vXWr239gpSymlEJyXFer/Mg719PRpNy1q3Tj6/n3/2LtAByGjPuHFy8rQHs+YJyVwk86mnrOs6B88MHho0sD77UFL7gODrSNnvH0ioI1KAVIrs0kX2cR1dvvxyaYgMHOh/wnG5ctLD/Pjj1m19+khKymefhbaddv7W+AH8B1K33SYNWO3tNbdX00iAwMGP2VjMz/du8GjwrO9pUlLkxW90W268UVJoR42SUW4NYMxA6oUXrPSeMmVk25w6ZnbtkoatvRMjEuZ7/NFH0gHhNBcomuyfyzPPRLbYsd3GjdY6fmZj7eqrpTCPvahQ48bymbRp45vaZwZSgUakPB7pQNyyxSpyYD6Ov2N8uKl9assWqxR2OCNSI0dKx+bHH8s518zUsL8ubRCfe65VItucNxfKMSkpSQITDWjsgdSrr8q6auvXW+efn34KrSG/fr1VUhywskmcjrv+lhsAvF93qVKy79SrJ7+blUDNx734YunEHDNGvn9mhT/A2m/0PbKP7moQbPfCC9bSMunpkm48fbrVWRosNS6UjBndF0eNknOzdoZHI5AyU/tq1/Z+Xr20z6cuaRhIFTNpafKFDrdxcOGFMo9i7Vrfk5J+SbVXZcUKazFD+330i3XkiAQ1H39sbUtqqvTWhJKi5eSMMyTtSnk80ltoFpY4dMh77Zm5c2XofPduOVBeeKE09vfulSozR44ETj0xD8iaox/I/ffLSXzSJDlw64KgwehB7sMPrYaYaeJE7142+xomnTpZJ8Svv5bAEQi9h+iHH+R90RM5YB1I77hDUsb++CPwSJuelKpV859W6HRCTE31bnQOGSJz3A4f9j1J5ucHXkfqhhtklKtmTf+B1HnnSYNaT6xmGWR9PHNeXfnyVtWovDz/J4tgI1L2ACjUQGrgQGmQXnWVVCI011IyXXaZjD44BUv6nfPXqH32WWmAjRolo1PamwpEXpbZbMB6PPK5+SsUofv/v/9KJ0KFCtJINsuVn3ee9X/jxvkG0coMpNats4oupKRIgAnI9tSvL/tAs2Zye7jr+Nh7xO2/6z6dkCAjcvYJ2bt3+84veeYZafSZowqRcgoOpk8v/OP6M3my7/IAmZneS1BEat48q4iL2SD0V7XPZG9sOo1IOb1XU6dKGvsJJ0j6b/XqMjdUCyH4W0fK/F5fc411nPFHt+uMM6zbwgmk3n5bGutOI0P2bZs3z+pE0mN9YmJ485dff12OpZq6Zn/el16Sv23YIA36ypXlexvKwr+HDkmHmc5/1gZ6oEBqwwarUJPSIkX16sm2fPutVTSqXDmrE8McMR02TApnPPSQBHLmeSE1VdKJH3/c+nzNOYH239eskbbH/v3We3rHHfLYmk6taXC6hp09MNPfwxmRGjRIphfoaL15nK1TR0amtRpvME6pfeY6f+bvGvCGEkgVFMh3OdbFdooSAykCIA3x1q1lwqSuuq30S/rjj3K5cqXMQTLLvwaqHKe9lF26yEl1zpzItrFePWmM6GiMPZXPzD9W2gN9663SW//ll3KACrVSkX2BwGC2bZODep8+coC352H7EyjgSUuTRnRCgtWLqA0W3b5rr7VOkJGUPzdXedcFCPWxZ8yQlLe9e0NbRyrQ+xRsRColRd6zt96S58rP964QaF90OVCDwx5IXXONPL/ut049mjqx2B4IZmRIR8KWLf4D72BzpOyBVKgjs+eeKyOr770njabTTvO9T06OjBy99540ZL76Sr5rGzbICUsbBWZvNSBVODMyvEcuX39dHkNTmiJJMwLkPfzmG+khHTVK3jft5fU3R0rfkzZtpPNAS8136iQBull0xawQarLPDVJVqlgNqNq1pfd73ToZld65M/weW7N62axZvvtTRoZ85gUF3seZdetk0n/VqtKYMr97ut9pUQC7bdtkXqHTvC87M/VamaNgCxbIKLS/5wqXFi3o3z/8dLFgzOON02Pbv5Pr1sl3Yfp035FRc7Q8UGrfG29Y148csRaQ1gDC34hUvXpyrBk3TipSduoU+LW1aCGX5ppm4Xzn7OXPzQXGnV6XNrJ1juiiRdb9wvmszLLtJjN7IiHB2g8XLgz+mPZziDbQp02Tx2rb1gqazHOb/biWmirBzIYNUsnwlVes+x8+bG27v9TTn36yshPatpUAaPNmeW7dF+2BlDkidf75khHyxx/+z4tmu6VePQm6dCRp9mw5JuXmBq68G2jUH5Dj+P79sv/ee6+MTF95pf/HM919twRdp59uHdM0bVk/Y/tyFaEEUq+8IkFpz56hbcfxgIEUHeNvoV1/DWPzfu3by4iP5hWbKTjhjo6ZE+Wd6AHozz+loaUls+2NbMA6yB88aPWs5+dbaVZDh8oJd8cOOQHZe7YSE63hbLO0rD+Rln4dMEBGBE36u1k+VasO6YnA6UBamAV5L7jASnWzL8gbbB2pUAIpp961lBRpbAwcaDUqVFqad0pldrb/ESmPR4L0xYu91wTSbU1IkB5Ofe/0pKBl1QsKrLVvzJPili3SqPr9d0kb9TdXzlyHxun9iTS1LxTr11vvy9NPSxDy2GOSljhunP8RqUOHJNA6ckSua+XFI0esICacUsymypVlFOmMM3w/iypVZBRMq0rqPmsfYdB9z6mamb992xyRMgOprVt9v2NAeOtSmXRb/v5bGtn2QCohQX7+/VcaZZr2euCA1SkFWOuzAMHnVm7bJiOuZjqqP+bovbIvmr1mTfgjcf6YnVPmexnNQOq887zn8/lrSP76qwQzzz4rHQwLFlhBqgYcTZrIyPOKFd4VYJ2226kDyOmzmj1bvnMTJsjnFAp9Deax0T4/J9D/6n7nlE7t1FmjgZSOSOnxD4huIKXvjy7SanYY+OMvkFJ//mkFP+Z5LlAFTH1fdX7qe+9ZHXCHDsm+0b69BBk7dkg2Sc+eVmfF4cNWxdg9e6zXV7Gi9+Lo5jnDrNxnn1u3bp10VunosPld0dHs3FzfNayc2N+v5cslCNRjdkqK7O+lS1vtsFAXXu7RQ87JjRp5r4sGWO9B3bryXrVp4/ta/JkwQS7Dnb/tZgykCICczDXQCBRIjRkjk/Ht97v5ZjlhaW9hoPxlQA58ZhqZOnBAvvj2gheANFgmT5YDU/fucrB44gmrapJZ6tbJ0aPSUNYRF0B67ufMkYNs586SDnDmmVbaYqVK1uPrApeBhLsmhzrxRKvimtKG2i+/yHbm5PgGKXog/fZbKzAozIK85ct7p3nk5lqPm54euKGnt23e7F3RyORvROqGG6T364IL5GTVs6ekV+zY4Vs8xN+IVE6OlJrt0EFu97etw4dbi/QCVsrQhg3We6f7OCAjsDffbM3F80cbeWef7Zy+Gmlq39KlEuRv3SrfD6eREx2pVAcPevcM+xuR0vvomlw7dkjguGeP9R30V8p99WoZbcrJkd5Tcx0rO/tIZqVK8jm8/roEfU88Ibeb6SSHD1vrtsyaJe9Bhw7We+vvpF25ssw/qF3be5I0ICdxe0AbaJTV7rPP5HualSWXWlHMbNDaj3kffijBpM4/q1/fu9FlNkSDzSPVtOVQFvp2Ovaax4NA808iEctAyl8Hlb/bzQ6fVq0kRVQDqFNOkbTQl16SfaVZM+fAJdRAyqzC1rOntU9oqrm+5x6PHB/s6Y+nnirHVh2xOessa52eYMztcqrIaJ9D2727NedRz79ODflARo+W4/S2bfL9tHc+2j+TwoxI2b+/gPV+msfBQEVU9P7btlmdourgQRlBXbJEOjNr1PCuEtiwoRxz9DF277ZeX+nSkh1w1lnSdjC/0+aivGYH1/33y7IAQ4da61+Z779ZrTQU9vfrnntkH3SaY6mFO0KdbmDSQmNK34MBA6TdqKnwoRxDi2OpdAZSBEBGW7REaaBAKinJ/8iVSQ9y5oF5zRppUFxyiQx9163r2yuxeLFc2iviABLsXHGFVOyaNctahLFhQ/kiDxvmfeIwJ84D0uvYrp3vY2dne5+QZs70bqAHKsRhpweSX36RE4hTNTR/7MHXoEFy0D1yRKqdHTjgm8uuq4l/9pncV1+PCuWAbN7/6FGrtGlBgZz8DhyQE0Pz5qGl9tkf01S2rJXqoo9lNvg2bJDRip9+kh67vXvlZKf3tQdSZiPU7NEtXdp3pOHjjyVFcvx4yV+3M9cLMRvb+v9Ll0qee6BG7Ouvy0nMvkAoYO0/990nz1+5srxPwfar226TE/UJJ0iv8xtvyP88+6z1Ouz55gcOWNtdqpT/ESl7GXBVp4700AL+q6+ddJKkzD73nMwfqVnT+3v0778SuEyb5n8ks2ZNmQula1zpZ/v339IwMedqTZsm74UG6f5O2iNGSKN25Ej5vVo139e8bJk0kC6+OHilSVP//pLm+vDDkqp8xx3WdtuPeXl5Mm9NR/bMlL+1a62y8+Y+rIub/vKL8/PPmxd8G5VTZ475nl1xhVxGOuJop8ea99/3Lndd2PXIAGu7t2/37oDzF0gFOk41aCAjiMFSGu2B1JNPSifcuHFymz21b+9eub5unZw/BgyQjikt8LFggQRwug6aGjhQvr9apttf0QIn5r5jTzW77jrvQOTwYe85efo+6uf26KPehZr8WbBAzsU7dsgxzD5q5BRIXX65zO8Mxh4Y2F8TYH2mvXvLZwn4jkjt2CHnerPDDJDjlenQocBplCNGSCeTVow1R6SSkyV4/eEHOQ6b7SRzRMrc/9es8f0+5ObKqPDZZ1vfxYsuklS8K64IPKepf38Z+dR1He3zNcePl/0gIUGCLMAqwhPM7NlyrNu82TeTJC9POtL0eF+xonRAO6Wd20WyZp/bMZAiAN5BkT1AWrjQGmkKN5AyG8mHDkmKy9y51gHd3tMRqMS4/QCtB4tGjeQkcPvt1gHikktCr1hnD6TM5wIiC6R00uyECXKiDNaDPGeO9FyrevWA55+Xk7e5TXpS1vf31lutk4Vuc7iBlNkI//xz4K67ZJu/+85KPzjzTPnsA41ImQdnf43cli2lMejxyAjLrFkSEBQUyLbaT2pTpkjwoM+Xk+O935kBrx7sExLkhKKTg7Xk9uLFzumZ2tg4+2yr0EpOjhVMma/1hRf8NzxnzJBUD38FHX78UXoFH3pIAqPcXGm4nH668/2Vfoa6nQUFMs9rxAjrs7ePNNnXkfI3IhWoB1ErOC5f7rwWmzKDUp0nA8j7fd118t00G7affy6Bwpw5voVV7JOXTfaKfaGm4pnpffo4WVmyfUuXhvd4Ol9PC1iYI0j2NETAex6p2alUo4Y0LB9+2HtuTLBy4WaAH6gsfUGBFUCaz2vOMdMe8Wgx37/LL7feo2XLpEG4fHnhH/u33+R7rfwVmzCD4xdflNEAHd0EJO31jjukI++hhyRl2v5+2teP27VLGrz6/X7oITnWjh8vv2uq24YNEgDoyI/ZoeH02PYy/Vu3ehdMCkSPl2XKeAfOKSlSXt9cY8l+bLWPSAUbjZoxQzqidGTDX9aF/fXWrCmZJMOHB358wDeQ6tLFe4QIsL5n5cpZAYR9ROrwYck+0VRtpfdr00bObSef7F3B1d9rUbt3y/Hr6FFJHX3nHelIshdU8RdImfO427eX0vmjR8txefp0ec/q1JHH//13ed8CpUQOGiSBvRbCsgdSP/5opdKpN97wTif256GHZNR9zhzv49KTT8qx5aSTrNHGxo3luUKZ/qDnu1CCruNFmDM5qLgyG6f2k1JamnWw195V+//ce69UnBoxQvL3ndZ4cKoM9Ntv0jCtWVN+1wNQaqqc2MzAyh5IOZ0AKleWg2vDhtacj0ApR4ActOyBlG7jv/9aB6lwAilz8uWHH8pJOFDFrHfftdZmaNpU0qnatvVuaOblWSN2Jn+FPk44IXBpd2VvXAOSAlGpkrXN2nvbubMUg9DKVSaz9zOU3v2qVa00g5EjZf+xVyvTE1TXrtILmpYmqTEjR0q6o5mmYC7Gm5AgB2rzYG3vVTvrLHl92vAtU0ZO3IBVZa5UKd+Tqb8ezCFDpDd6zhzrcUz2dL8FCyTwsFduszMDqSNHZD+0N0r1MzzhBOlBtAdS/fvLiU9z2VWwz6lMGd81zewaNpT7HTninNJVqpTV6Fq61PvEXrOm7E8FBdILW7267FtmxayGDaUBq6N34aTiAb7vu7keVUqKdYwJ5fG06t/OnRIg6BpX+flSCCQnx9on/a0jpXREyBSsp9g+Uuqv8XvkiBU47N4tveaXXOKd5mR/3lCK6QRi/+z1c7r2WrmcOjXydaXMxzY7hwYNkk6qE07wvr+5j4wZI8eRPn1ktDs725pretppVsr2I484n28AOXbYG/n2QMLfSJI+jvndy8qSbQF8P8PffpPOJbMTzR9zPmDTpjI68cQTznNrzE6nLl2sKq+hLCkA+C7cnZAgHaGHD0uKr44eRTpPGJD3tkoV7++//bht7guazmgPpPyl2Ouxtk8f6/U0auSdvmympmrboV49aQvs3SuvW7/L990nQW+vXtY8KsA7ta9nTxnVysz0nn5Qo4aVUqrzFEuVss7f+hjhrP1mX2vN3zFtzx7vKQ5OzLld5kjePfdYhX6WL5ftvPlm6ZwIRdOmcv7WYkbFAUekCEDgESnA+QRvv5+51sYpp8gBcNky6+9mg99MXTGLCeiXt1Il39EpPQC98YY0VsxJsqtWyaThAQOkl/GGG+QAt2yZ9zaYtPpfdrb/CbPm6E4ogVStWtI7oydJFaiEqf159OBn763Py/Ptkc7MtEaU9L0fO1bSoObOlcDWvP+yZb6jVNoIr1vX6jVMTJTXW768HJz1pNOkiQQMmopl6tjRKjEbrIHu8VhlXwHndaQAa4SjcWNpEOs+V6OGpE1efLF1X3MxXif2YFn3L/P9MBs1TosaOj2O0ve/a1drXp2TN96QhpLe3563b6fbocF5QYFv77nuv9qgPHDAu0HTsaOMDtlTDoMFD9qB0ru31fhUGkwPHOg88dwsBKCNKvt3aN8+GTEcOFB+/+QTabDofpSSYvVI5+TIqKGWRPe37dddJ0VLdHK5fX+wr0fVvLl0vgRawFfpKM/OnTLSZqb2DRwoQYM+jhabUP7mi5q0caG95Pv2yf6k67aZ71+gY4r5OZQrJx0Uq1dbKXf2xc2jMU/KbPzm5krv9OzZ1kT1UKuFOTnvPCslzjxGjBolc53sc5zMUUZ7w95smJr7hr8y5rVry+dhzt9z4m9eqNmo12DLzALQYgyA9R0Ltfx5kybScfLbb3Lu0fS5nBx5nU5p0FWrSmePNoZ1+4YPdy66oexzeFNT5Vj23nve7+n06fL4Ztl3XZQ2UFEIQNK+d+3ynk9l3zf1u/vrr1bnoz2IdRoFBKxAypxPds893gsGm3/TuZuVK8vxrmFD7+3RkUN7x5k5ItW/v1W4whyRMjsuzI5bDd5CCaQ2b5b3Ve8TaEFeUyhLEgTKPDLfo337grdvTJUqSbbQgAGh/4/bMZAiANaXpUEDSe0yPfaYNV/CvM1MSbGPimivjZnjbN7ntNOsnF1NFQB8F541mY3z3butFIudO6WXw1xz5sYb5aD888/Ok3ArVbJOWoFS+8znDJRKo956S/Kg7WvGmL1VTvTAd8011uJ9dmbgAciBrk8fK+DS9751a2n4anUmNXGiTLw2ywcD0kh45BGZf6IHzyeflJSBadMk0NJcdCdHj0oQCwQfLXjvPXkvEhPloD9ihKSM6P5nPyDrAT+Utcf0fzXg2L1bgmqdDG1/bHtxjhde8D6h6mdiDwr9jUiZ93OaIzZ2rKzxMWSIvG6dixasgW1P7cvP9z25jRwpz68NC/uIlD916sj3REda7MqUkRSgH36Q9+a332REcPp0a3TB47E+J/N7ZKZdNWwowZE9P16PD9nZ3vu22SAwe1n1NY0YYa2VZvfPP7I/6uc9caKMFun7YB+R+uQT2U9CWSdOjxlz5ngH4P5GkszGkv1z3rdPttNc90sD4cGD5XLhQukQufVW74nrQODgR/+Wmir7SrlyUjxEg3YzkGrRIjoLaY4YYVVQ/eorCSoTEiSdF/CdqxaO5s2tMtChpCubKciB1pEy9zn7Z/jss5LGtXixHDft1de++06C/Fdekd/9fc/M44KmmfpbQ0cDglDLn5cqJZ+pBuDmeSstzVr7EbCCM3uHgfl+Bnpv7f+XnOzcgdK+vQQWZnruwIGy/2nnRqj27rWC/6QkGcHW91/nlA0a5D2XEvA+9ulcaTPFd9kySZNftEjaIsOGWcdUpw6V8uUlyFmzRtJEr7zSO+XOPtLapYuk7WoqsNP+uGiRjGh98IFzx2MogdQ118j7qinp0QykzI4D83uycKFvRsTOnRI8mqmk/jz8sIyGaueQ6ehR33PB8YCBFAGwDiJdu/r27n35pXzRr75afu/eXQ4AuhAuELzalNN9mjeXnsamTa371K0r27Jtm+/Jxn6w0RODnnycRhays6VxYq6toY+lDVOnQConR24Ld0RK2XvCdM0Of3Tbu3SRxrbZS2lus77Wa6+V98lelcnc1r/+koO13q7Bjj3/vm5dWRvl7ru9H2PSJLk0T4i7d0sutDnp/fTTpTE2dWrwifv793vPo3nuOWno6r5hD3b0vs8/L43LNWtkzkOfPvI+ffWV9bmYqX2A5Je3by/7qtNj6wKR+t4//bR36qqehEIdkQq2IO/kyda8I8Daf/PyQlvZ3pwjdeON0jgxUy6SkqQX+NtvJdA5+2ypDtWqlQTD06b5Bh/Dhsln6S8FtEwZ7/lpM2bIfjJ5smyPphsqfyNS558v+4dZIh6wAqmCAu/3wGyUTpliPb9+Ft26+aYp2rdB99sGDaSnXhtI5ohUKFXKnGzYYG1LmzYyOvXFFzJHzjxOmIGU/blefVW+N2Y1SPt2nXWWdZx9803rve7Vy3sEyE7vl50twUyrVt7FdzSQuvNOaVQGeqxQOHWA/f23fOdCTR0Lxp62BEhnyI4dvt+fVq1kH33mGd95VGZAa34+9uN7jx5WuingG5D9/bccI3VdxGBzhpYutarBmuc2c3v0McJZkFcdOCAjSuYcMqcRKfvojVn8ItBxyD5v0RxhCxb46bErnJELwHtE98gRef80/TvQd9jcHzXV1uxY/OILOTZqYJeVZX3++pp0wVzAez+ZNk2CH/0snZx6qsx96ttXzpnaaWeOSG3dKp2Vn3/u3G4KFEjNnCkFtvS7YK7DCFjvjT0w1ikU4YxIJSV5LwJ/yim+FYxTUuQcs29f8CBIM2Cc5gHedJPsK888E3z73IRzpAhA4JXN9UuqXxCngMIeJC1YIA3eFi2sxql5n5dflgbWp596H6CrVZNtyc2VXh6zF8l+kB84UNINjhyxJu+/9JI0zjXneNAgaayZ+bjVqkkPSu3aErCVLStD/rVry8EvJUWCBXvFn1BXBAd8AymzZ9CJWfFryRI5eJYr531CNV9/p05yknEKpD75RF6fNrIzM+V91B5hzY03vf++9MCak3Od9oWFCyX4bd/e6pHTnsHr/o+9K4+zqfz/n9ln7Ma+S2QNIUsqJVHZitKispVEu7R8v4lW2lfRNyXtpdAuQpSQhOyEyL5kHWaMcX9/vH8fz+c89znnnruMmeF5v17zunfuPfec5zznWT7vz9pHLdBuAbyhCvJKISkhwUm6xo7FM//jD6WlHD0afVSoEAjzk08q4VxPjMGbeEKC896mTcPYZstox47wH+dN6ZJLQNj69sWmGCmRcnPH27QJQhYHTuswufZVqWIejykpyu3y/PNVwpX58/F5tWrmQOOkJPzdfDPiBTiBRKFCztom0mWmTx/EO8kAY5NFSs4FPQWytFhnZkLTu2GDs04Sj8msLH8EyJT0gQj3xYk3WLFiygrmB5IgDB6MMcNW5+xstZ7yuL7ttuBaLCZtPo93VnrExYHs9O6N9ZRjFS+6yLsPdMF22TIIXseOIYichZhQbqV+8NpriJH98cdgMjF6tIrVevRRWMPZpTocLFum3MGlcNikCdbwxYudxLpcOWUNMNWauvVWVVieYVrvsrPRl8nJwa59pjp1JvCckVaLevVUDHBKilr3mNT4JVKLFmHtZo+Mnj3h4lemDFzk9EQHhQtjjlaqhNc9e0AY6tZFf3gRqbfecv6fmKjGsGzvc8/hu9tuU9/7JVLz5iHOq25djB3pennkiHN8eZVYkRYpjlGKj1fuZDfeCItURgbmGtcvTEqC/HDkCMgQW4jl2Ak3Buyee9RaXawY9s/KlaF0GTvWvWwLKzdMREqSZSK1znTpgnNzZlxdCcjrnU6kFi7E/vbss6rOlHTt8/JIIXLKcBxb7Aaex6+9FlxYPFTZnPwKa5GyICIIXV27YoJxADWDJylrYFavxgIus5PpRGr9eiwesvBkYiImSFIShPwBA8yaLF2rwrj+elgvmAgUL47NU1rQduwILjC5dy8W9PbtsZF//z0+794dAn+xYhCEhg3D5paVpbLRMCpXRur2ULjmGrTpjz+c7nz793u7Tch0pbxwzp2LjeXtt7GpVKgQLBTw/127qsK9jz3mtFTo2ild2NmyBRouPcPR6tXYYGRQvFfWPn6WLVsGuw8y3Ary8vhJT8cmx65qUhPG96ALPLyJV6kCYZHjVtyI1LvvKmtUmTIQug4eVP3z2WewgDGJr1IFdVO4Erub9jVU1kJdASGFD6/YgQcfxDPt2hXCoUkQ/c9/8J1ueWW4Ze1jDB6M+x87FoSLXSnT0pzpvLnm1v/+hzZv2eLULJqSTUhtrk5CdSK1dCnIVna20z22cWPcI5//1Vfdi9K6jfMKFRC7mJAAAbZsWfzfqxcULW4xLiZ8842T1Mn7lvfLQveQIUq4YZiIFFsqOINnIADhLy0Nfd2mDfqeyx64wY3ss+BSsiQEblMR13Bx1124XuvWirwwvvjCGXfDJRrCxbhxyn0rO1vNJbesfRKmY/73PyjPJBnV5+cXX+D7EiWQEKVcOew1HP+qr8H6nC9ZEusguzbycbVqQXlSpgzWdpPQ6de1b8UKCP4TJjjTsZs8RNq3B5lbtAh7+d69SnANVQhaokULHNe2bfAYzsmBy/599znHoF8itWsXMrlyUiVJpPTf8vwbMya40HZ8PPb2MmXg3r94sVNpwOP+0CFnkoQnnsD6162b8/jmzWEFbtxYKUXl+qKPv+xsENPfflPP4KWXsG7UqAFLJytq2WVfd9fmceYn2QRf/5JLsNawgkAfk6zM04nUrbdiT5Qxx1Jx4BZ3zJDfh3IT9uN9YYmURYFEs2YgKFOnqrStDJ6kXLB31y5oAqWbkL5wmzTHVatiMZRZ9PRNZPdutSjrE7JpU2jMdW2LXNBMAkTVqoj5KV0ai66f2BF90fab0Wr1aixIDRs6653UrOkuxBKp/pIJJooXx6bVty9IJ9cdIkKcSlaW6u9Bg5SLpB6fw+dm98J33nF+P3q0yqQWH+90K1yxwklMvWKg2rfHq1dfmZ5PSor6zVlnQcPKQvIFFziL45qIlJvQoQsHX36JsdutW/CCzdaoIkXckw48/zyeb69e5u9DWaR0QU3eh1vMBBEE1UcfhfvlJ59gs5s4EcI0Z/aaPh0EcNcuaF9ffRVt3bULfcbEaP9+53XvvhsCw5gx6rNHHoHg8fbbIHFynsh74LnNmvaqVaGQYFx6KWIr77sPlufU1OCA9aQk9QxkZrS0NPyGhecuXeCuxWP5hx/QNpMbiZ90zjfdBAL44YdYjzZsCB0IL7OINmmi2jJ/vlobk5Kclolt20CYTRpddiGShJqFOnZDGjIE6xbPm7PPRj9On+7tLpyS4oxhZUgiumULlEp163qnWA4Xzz/vdKOSc3716sjOKdcbGcvpZh3Ytw/jZ/JkNUZMhMUU8M+Q6bqPHIGQvXq1Ktmh15GSe97VV2ONnjABY02ePyEBc3jPHliM+V5kDSe/FimZtY/bI4tjm7xH9GLQM2aoGnp+iBRneIyPDyZS8veyv6UbfahzE6l7kXPpkkug8J00Kfhceir/Fi0w9+bNg1Li2WdVTKo8b0aGs81btuCzqVPhssl76qWXYl9fskSt1fL+9LG1cyesjuedZ04uQeRMiHLppTiO4wCfegqWoT17gu8tEFDX4zHjtuf+/DP6YdYs/P/XXyBxuls0r9uyZMzQoVA4NGgQem2URCpUDKNX+Efv3kjw4SdeNT/BuvZZnIAeTMtwm6RSg3LmmRCk2UTupVmQC1eJErB4cDyO3NDdJiQvQN99h0VICv4mjVfVqjj/oUOIR+BNeccObMqFC0OjlZ0N16eiRZ3BlJUqIdD0gw9CZ56SJI2JU3w8YhK8amQ99hgWfY7nITL3+8SJEPZXrsTmblqk3YiUqcgxkZPgdesG9xKpPZeCtElzWaUKSCNbCsMlUsnJ+G3XrsHubQ8+iNcLL8Sm4EWk9uyBcJmejjbpbU1LUy4I3EebN4M4sIa/bFm4V2VmQoBNToZb0aJF0CTrVgWJl19WG6Ef17527XDeH38MvVHp+PlnCMHffw8NMD/DEiVgjdy0CZtbZiaEOc6CRwRBgTWye/ZAO334MKyoV1+NuTxtmsoAJoU6KTC88AJemUjpxOXMM1WK3S++CB6XN90E4ejPP1Wcom490Ivc6gTe5EbiZpEaORJz4J57nO6tftOpy6yZKSnq+JdeUsfo1yxSBMqIw4fRFzIWyWSR0q0cBw44XcIOHsR9rFgBoqSn/Waw6+0FFzg9DPR7XLcOgppb7bNIINNHE8GF6q+/EKMVKZHicTFsGNyv9c/1MbBpExQwZctCiMzJCa4nRoRxtmAB1mjdOqfXkdKhry98fK9eEEB1yGLTLVpAaL/vPuUyx2O9enVzanwTJJEyEUWT0JqYiPl09CjmNheulvfiBakM8SJSci74tUi5kQ4ilX2X3fOkfOBltWGSyO6yRGq8Hzrk3JdXr4ayigkFZzll906JxESsX9Ong5xI8DzPyVHEi+9p6VIQMvYAkeOM5SVOsmNK3nDggOrnkiWxfvOz37EDa1zJktivWIHGclWzZoqISpjmkbwn3QuCS4cQYa+VoRP6GrN/P8Z4jx6QxdxcaJOSgvuxoMBapCyICBoUdgvSTczy/7feUqk+5efXXgstMWvxdAFIQl+sTXEVRMFEatEimMYDAQgKCxdCa/LTT+ZzMSpXVgv5jh3K7H3kCGKq3n0XmpCzz8Z5u3Rx1mtid6Y77ww+tw4TkSpRwptEEcFtkDWXDF54FyzAYr13b3C6Xl6UZs1S2b/ciJSbuVwSqWPHgp+/3BBNySTYPY5JyuzZKm0sEQTlfv1AttyIVPfuKgA4MxNk4KqrFKGVgeb6Qsz39+WXcL1gjbGbu8rbbzuL4L72mrJIlS0LbV2lSmrj/uYbWEJNwpFE377QWrdurYJ6JXTtcGZm6CxegQAIzrJlKuNTTo7zXNnZzrHG7nIstLDVh5+rJEbcl9Ong9ht2AALZEaG2apsEnD4fF4WXl3I69wZGRx79QIReecd9L0UpAIBJaC9/z7GR5s2zlTDJvJTuTIUIrpl8ZNPYHnTFQp+C/LKefXCCyCneoZTUx/cfjtchaWbM5E3keIxKwl2kSJ4TiwQ+gnc1+e8vqZyG2KR/pyhE6m0NBW4H2kRYDcvAlP8k/z/2DFc++KLzXtRXByEyyZNgs8h1w0/RKp6dazPK1YoN/hAINh6RqTiSqtWhStZhQrK3WrsWH/1/4jMFikJuVZ+8gkURq+/7hx7ckx4uXryb2bMAJn5+29YwXfuVAJwKItUJETquuswn7mwOo8F2W4vRRS7Ho8fjxiyxo2VxUO3SE2d6nQZ7toVbm8VKwaPHxb8W7QITn+elqbmHscIDhoEgjx5MvZ6Lvsi74PHt5dVR7rl6f310Udoz2OPOX/D+5usuyjhli6e0bUrlLfsuZKTo7JfzpiBvY/3F30dveMOkHUOPdD379WrQfxkoqeCBkukLIgIk5s1l7ogLRc1uWC71dMgMlukDh6E8MEuYAy5aHgRqZdfhgBWuzY0LOxilZICAjdkiHkhSElRi5lMICG13rwhrV2L7GIyJTvfZzgFeTdvVtYVP6m7iYKFBG5fnz4QchcvdvZ5To7aXB5/XGU3cyNSkoRJ64gU4nftct673i4TORk9Gq5CcoGUG9s550BQvvFGbIjnnuvcsOUGNWkSNqFRozAmt21Dv8u4OTcipdeR0i0NgwdDqJ0xIzhVuSRSbilkf/0V1iuTRo/xyCOYR9dfj026QweVHpnHz0svQahu1Ur1g5sgkJMDcn/22disEhOhPPAiUnq6/8RECIwmVzLuhy1blJZ2/XoI7VdeCcE3MRFC05Yt5iQibDFZudJZJmHlSghaCxcGj235zPv0wV+JEk7BID1dWapXrwY5f/ttJyExkZ9ff0V79ULCUtv7xBMgZZ9+GjrTJEOmYn/6abjvSgsyUfB93nuvCq7WBTETkeJ6WjweeVy88w7WT47vJPJHfvRrMgm//36MPxbo/cbkmBAI4K9zZ/w/cKBT2Dt2TMWb7NoV2TVkwoZt24LLU7i5TfmxsLhBL8h7//2Yhxy/prv23XgjhPQ5cxAb89xzWK/ZSm3SxJctizEoLZVuhX1N8LJIXXut06KxahXGz/LlZiI1e7Yz+YYO3ld+/BFtPnAA7S9TxhlHyZDtOf98KCJNhcolTETq44+xJnEfcXuHDQM5JIKSrkULFW4wa5a6JiMpCV4lf/yhznXoUPAYkWvro49CgdaoUbBSIjERJGHePLhfS8TFqWvIMT9vnrpH3qeyszFmunVTyuwRI3DcbbdhTZAWN5ZliDDv7rxT1ezS964HH8T3PAZnzsRvdNdRtlg995z67OefQSx5X6hTR42bY8eCE42cfz7Gjz4Xp07FKysXdIXxgw/iHCNHqkzD4Xpo5DUskbIgIu+CvB9+qHyFExK8C7UxTFaQY8eQqUbP3GUKUNc/l9/pAnJyMjLOPfussoqwEGVKI87gYzMzg4USSTRMRConB4Rw4EDzvRw7pjae9evRf14al2++cdaPSk9X9ynJy5NPOtswcmSwD74bkZIWFXm/0iI1Zw7I7oAByoXGRKTks3ntNWzaMlhfPkd2U2nYEH3w228gb8uWYTzIwnz6M7/0Uow5jkE5ejSY0LoRqbp1kXyCCfd778EioQuNR4/CDei33yBg61pBvpfVq+G7zjU7JAIBuDrMnKnuYeZMbCKDBmHzmzMHAv7tt8MlZNo0VXfHzSIllQluBXkPHFDHFS8enImO78dEpHjMmLT133+PpBtxcdioK1YMLspLhLnGFjhpcZg0CeNi9OhgIe/gQSgGZA0l2Z6EhOAN2eSyF079I2nV5CxwO3b4t0ilp+O37Ca5c2dwG/X7lIWZdUGsWjVYtLhmFJEzfpRICRRsuZTz1ku7/957iMuSxIuRnQ2riUxM4tci9emnoQvPEuHa7C777LPKUyHSelX8u5EjMQ553Li59sk04q+9BmWGW2zG889DcNXnoO7at3Ejxg1nVrz6aryX/cFz7KqrVPwin8fkEcDZ3KT19ODB4IRJbnCzSDVvDpIhEzHJ9OeSSPmJGZbeDwyvWo9xcU754MoroWxjxZ/XdYiC51V8vLre9OlQAJQs6SR+v/0GzxIizOs5cyCYcx9wrG1cHFy0v/gCxIGvmZSE9c5NYcrrx8SJUBS4lV9g8JyVbrMy/XmbNiB1H3+M8TxpktqLExPRB+PG4Xvda4Rx993oV5bPdCI1dqyzNmJmJsahXjfQFGt6661QBLJnBhFCNzgpF1v6eFzNmoU1NVS9OHYl5X1Kkqabb4ai1S1pUn6FJVIWRORNpEqXVibh3r1V3Qx53Nix0IT37In/Ta59brEzJotU3brBAYf6pmkSrMqUwcJZrBi057K6ug4ZL8OCBG8w8nfsHywX2PnzIQjLukCyjXqWm9WrYe1yw8CBqKHA2LpVabQkefn2W3UMt0cSLc46SAT3kKFD1aJZqJByMZQaLlMSjLPOUoGsUkipVAluTbL2DX/vJuDywqprWuvXh7BVqxbiKBIT1fjR8c47sPLdeCM2sqNH8dmoUSqQXy/IW78+iCdr43jB5w2OM4wFAljUzz0XZM/NIsWCkCmeJDsbxLptW0VUOnZUPvZjx6I/q1VT55FpyHXrCUPODVlHSgo1rPGMj8d9uBGpkSPRDpmNiserW2IG3T2udu3g4tLnnKPIslsdKV3QnToVv7v3XihWvv8eG3N6Os6fnKza3bAhXrkv5DoSjsVBWqR4/Bct6p9IMXg+TZnizHT50ksQyCW8CvJWrYq5JOv46MIqCxlsZZT960V+du/G+LrhBoxHufZIYY7hxyK1bh2UHldeaRY2Zf9lZztjQtiK6KeYrgn6szl6FPO2Tx/sSfraImPN7roLygy3+jZDh8KyqK+Dumufnv48JQVrtLy2fM/Pm8/Ttq1y52JwciE5z9q3R3IiP0VJ5b5VooQiFiaSI0lX48YgEykp/koKmOZZYiLW4kGDFJkMNzW4jvh4rN+mLHHcvmnT0Pbx44Ot7yzcS3I4ezb6XSohK1aEBei881Sbx4/HWAlFpDh2KVRdNP7+0kuVJU7OvVKlsAbWrKk+42vzb/n+5H593nlq79LnhdvexbGqHAuekeFUuJqsoPp4J8I+NXy4ykRJBLLFheBN0GWwkiWhTLztNvwvFULR1vfLK1giZUFEzsni5WstB73uZnbokFqs//MfbOYyVkae97PPlICrb8BECGDUJxMveKNGwR+dJ29yMojHhg0QSlavRurwbducGmEdTFwCgWCBhVNdE6nJLTe26tWD74kI5K1CBacwyxYXryxbuoAh+8RUFZ0I76VGkb/76itkrBo5EoSHA9Lj49WCKQPYWYBYsEC1lTe0qlWd2qsyZaBF52DcvXuV3/SVV0Io4bYy3NLZ6/DK5lOpEv4KFVLayT59QECZ8OkFeSVkvA0TKTl+TcWc9c2ICaGJSMm2V62KTTsuTrl8jBql+mT2bBBHdqsaOFAVu9Yh28WC2fHjzs/Zjap4cdyTLlzwptyrF+Ycp9WV7Q5FpB59FNrPHTuc8WVXXQU3NyavpnjHhATVhtq1nWUEEhPhenLFFeiPZcuwbtSrp9rEqY2zsiDASLdQfjZLluC8v/4K4aR5c2cNMnmPWVlOIlWxIhQHfl1weT5MmuS8l379lEac4VWQ1wReN7iPeV364gv0kSTfXhYpKWAXKoRg8EWL0L9pacFCkh+LlCzCLed3airGOluNifBchg0D2WTi/uyzquxAuOjf36m04kLDY8dCa6/H9piE3FBJk/T1h+/xwgvhBumWjIlxzz1OrwKeE3It1xNelC2Lec3un2w9CAT8xcA99hisi7fdhrHDZS8SE4NjKWUB+wkT8DybNVPta9oUn5uQkqJihRlJSVCqvvGGqjtXqhSO0y2hnK03lGvnDTdgnTZZ/fVnOmEC3P11ZGU5C/KWKwevDbcU3v37w3rIha/d9qHSpbG/+83gy+3t3x/jlMi5h5sUQpxanecjr+VyvyZSa8mmTZBzdAKi710TJ+LvjTfUeJfut7Ifedx5jXdJwg4e9FbEcP08VhgdOgTPBpYNufhuuXIFN/25zdpnQUROoVK3Crz7rlooGf/9LywJDN1fPCUleDLICdmhAzb4t99W2kVZmM6k0eLvDh92phZPTsYmsH17cGFGL/fD225T6YZZYClSBMKi6XdyU+JFkjcrPp4FBQ5oT00F6fjkk+DFUIIXkDffhCVFLvrS318KMDk50DSxO1BODoQLmaFN4pVXVBtkW+66C/dcubK6x0ceQUyRW6Y/htSUHT9udv3j2jVLlyKO4s8/sanv2QPN4vvvh96c/Gg4dde+w4dBXhMSnKmFWeiSbX/9dVyjW7fgzYj7vGxZjDtdQJfH8HmZnF57LYjS5s0gMhUq4P454xGR96YhN0hZYkBuZGecgeuzoORmkTKhenVYfNzcMVgYHDMGQlClSojXK14cFsGiRbH5c9yY3FDlXE5PB+moWtXp45+U5HSxNbWbrahHj2Ke5uTAJapyZUUKmzTB+Lv5ZlhO5O8YbhapESOCLUkmrF8PYdkk5BF5FzOX12ccP464s8OHsZbKdNLsVtuiBfp8//5g4dSL/PB33Lfx8UpQlG2tVMl5XS9cdpl6n53tJKaMFStAgnfswPo6cybG1pYtiC9izbgJK1fimbGbkkS7dvgbMQLCYyiljL5exMe7J/wx1Vwiwhg7dgxrQlqaivWQz3TsWIz9AQOCM8dx38u1QSdSRYu630tGhrPQqQllyjgTCPC1Zs1CH0ydqoo4S4uUhN/sd/rvkpKC4/xSU831Fj/4AK5inTs7yWY40K0mM2bg7+qroThk7NrlJFIm/Psvsv4mJyObnIQbkeL5N3AgnvlTTzmVUjpuuQV7c40azkQMfP6dO6GEKlxYrdm6FZI/158Lz70XXsDf3LnYS/U5yftw6dLKsl+qFPpo9261L9asifkRCGCtSU01W6QyMiATyKzGRJgTzZvju6lTnTLYs89i3vK9NWgA+WPtWly3YkWsFeXLK8JZ0IiUtUhZEJGaLO3bOwkSERYcIlVktU4daNzlhue2GUnoNTvKloW2omlTuGwVKwZLVM2a0DD/8Yfz9zKNtURSUmirx5tv4rVlS7WhJiUFb7isAUpIwMIv3aBMNXSIzC5B0opk0tbr4Ha3bIngy0suCc6kI4nU0KFYeHQLlcTmzRBOmCQyGe7RwynQDBkCrVD58uoeDx1y1/bNnasSk8h7kqmoTRmv1q+H5XDTJnVv8+bhfKGI1DffwA3su+8w9m64ARkkf/pJuXPorn0LFsAC0rmzU8BnYeabb9Rnzz0Hjdn69e5aPbZE/PsvYoHefDM46J1x7Bg0gG3aqGt/9BE2PT3QNyUFyovk5OBsS5JIyVi9999HpsOuXbHpJSQogjhgAFxAu3WDJpYFraVLYSGQcUmjRmGuuaWdZUGJBZJXXoFbBhczLVIEz4AzyenjgQhtq18fQs+77zoFssRERXz1+SHLHBA560xdeiksBamp6A8et9Lf3i3BRVaWUiTopNMLu3ebSVTfvkhB//PPwfWYvCxSWVkglnXqqDGhx5Z++im0/no8xvjxwcVvJbgvX3sN611cnNMtmPvxhRdg5dJjPU0wWQJ1yD5fuBBj1k8MzpEjIGB163rXGuJ+ycpSQt+hQ8ECaNGiUNKxosxrfXFLJnTttZiXvJ6YLAl//IHx+fPPwX0ikwkQOUkNQ7/XrCx1j35rSTFycqDAkQmV5J7A59MJESu6iLxdZfXfJSaaE6aY4LeOlBeefNIcO8OKE4YkUm4KuH/+wdqoJ4kgUtnl9DgixrhxiDcOdc8DB8IjpGxZRYR0IvXf/zrjtHSYXPv+8x+MbQkek3Lvki7gcu7xfcl4TOnJwEpAUyz8b79hLWdvCkZiokpUpSvE4uLMRdn37sW8rV4dirrhw61rn0UBh1dmOp4EvFl5HcMT9913IdCxFk8eQ4SFYONGCGFjxkDIzMrCQlmtGjSYeqpcnUi1aAGBvnNntVA88AA0L+xuxmDhOTVVbVSbN8PVZfNmLE6DB6ssRy+9BO2IdOPiDEFEqsAdUWgixYugF5GSG8ycOXD14GcirTzcv5dc4nTRIcL7jAzc+2efgTDVq6dcMniRats2WICcOxdZd6Rmz7S4794NH23WOsrN5MMPsTEQOQtyMhITVR9Izay0trhhzhwQu19/hQvRxx/DZeLii9X9XXopSCjHCchnwO1MTnZa+xo1gisoj+myZeFC1bev8u3u2xfjk5MC7N0LgW/AABXzoAsg2dkYw7/9FnwvukAyciTOn53trJFDZLZIHT+OzYkLjuqZ9Bo1wj188QXaxzU+hg5FqmVTAgI+94UXEj30kPqc5xpvbCyMDR2KuIhp05zJEtwsUoxnnnG6D0kilZkJq8NFF4Ec8zV5DZGCpdxopbuYtLrom/Err8D9t08fp0WKkZXlLejxd5UrO+/p0UfR5i5dlN8/g/v1gguCnxO7xBGpfuP5sXq1kxzormudO5vnGMMk5HXvDne7f/+NLJZFCmOhavwxxo9XwepPPIFkM6b1Ulp5+dncfjus61lZmEfTp6uEEEeP4j1nqTTFivTtq7wrvO4zlBIwJ8ccI0Wkih7//ntwn+gWqV27VDu7d1f3ITF4sLK8+IlbGzMG42/FCvTToEFYKzmuV94TX7twYSilqlbFHnfTTUpJ6kak1q1TFg2GySK1Zw/cxz74wHms3/Tn33yD2FIZEiBh8gbQidTOnaHHt9wbli6F0o3H1iOPYN10szyHShWuo3NnFSublob+/vBDNTalJ44Ok2ufqRYbj+HatTEebr3VOSfkWsiJgbZtU599/LFSQnE/mFz73O5Zum/rc3HqVMyZFi2cSUuaN8eY7dMH3hobNxZc1z5LpCyICG4XbduqhUWCJxJPsHXrUGBWLvT6ZjRjBjT2UsiRG9CQIYi50NGkibt16a67sEizxu2MM/C+fHk1if/6C+2X/r9EIEitW8OszD65zzyDhadSJWgun38eGvvsbCx2gYAzw44sRCi1ObxwHD+OxeG885x9M3kyXt2IlFxc2LRNpPqrf39ojps0Cd4g+Hf9+8P1ZudOlU7azbIihZ3jx7EwL1yokogwDh3C/ciUqNLNUMYdESk3wJ49IbDpGDlS9YGe/lwu1lddBVeAzExlTeEN26uOVJcuuAZrfU1EqlAhCBtPP43/mzSBBZY3kfR0kPG331bJTpo0QTIFjluR98zB4qb4Ct39jhHKXUeiZEmQ07vvxljt1EkVvWZw5sMxY7zPZcrax+jWDe2dMQNrAUO3SPG933wznpGeQMWUOEY+Wz0bWVKSU8iaPRtKiuxsVXuICEI1ZzgkgqWG63/99JP6XFqQdaG+fHloP4sUwTVTU5WgctttEMq93I5YCCxZ0mnNTE52t7rwHB4+PNh9Mi4uWBCVSX2kcCUJ3wsvhLak8TyTa25WFjTku3fj98WL+xdY9u51au/dLFK6W9egQer9rFmYnyZhWs6prCycf8wYjO29e0Ew2rVTaeFlHAyRu4Dnlh5dQiooGNnZUFTceSfO3bw53KMqV3b2PROpP/4IJuHVq0Nxce65+F+uEVyqwtSPelppL7z7LgjqX38579Gk9PzhB/THNdfA6vDPP2qf1F3zdeht2bcP80Ufv//8g2f+wAPO4/0SqfXrYeFbtMj8vSk+VU+VvWsXnlnRou4uq3If69ULz5etXY0bY//n58YYPhwyhMnKY8LWrfAI4T6eNAlEsEkTeFTw+U3JXxgmixS7Rsvr8/M76yx4Ndxyi3NsyWNZoSNlGKlA1WMG5RoSCZHifWnRouA5kp0Npe9770F+KKgWKRsjZUFEEJ4qV8aAnjLFKUzxJOXMSzk5EOp+/BGWEXmMnoJb36iPHcOm07y5c1KWLYtNMj5eucfoRKpjR7xyXR6TxoUFCH3C794NAfSyy0ACicwLoYx9kvehb8RyQeB2ZGer1O7p6XCTnDoVlo0aNdyD2fVU4gzWVnPaViK10Y0ZA5cgbucDD8Bdj614KSmqT/QChmPGIMi4YUNsbHpMQrt26lkvWIBnxZD9evy4UwC6+moIuHpfFS6MjZivRxRMpLg/L74YLnGMyy7DRsSWQq86UjokkapZE1aOzEz0qxyfUtvsVZCyWDG4NKSnK/fXqlXVNSSys9U1+vUDQS5dGvfiFY+ik6xy5ZzZpliLOWwYSMw990BZ8emn+O2AAcr/f8cOEJC0NPc6UtdcAzI4erSayzfcgHtdv149e30sEQUrBm68ES6HjBtugHXs7LMh6DVvHiwI6RYp6T712muYP2vW4Fwys+Hw4dCotmwJktm+PcZBmTIQLrl2lhv02L+UFFz/55+d801Cjpl27dTny5erRAz6mjJrFoRaPTaGUagQngc/k19+UceuWgXBrVIlpaFv0QLP6Z13MAZlUhyJcuWwRmdmBt/r0aPKyvfpp3gu7dop5YIJf/yhEiG8+677WrZhg7KGu8FEHlhQ5KQyMo6udGk1vxo3RjKRihXVWNFTbTOmTFGxHH5c++S6cuiQcxxkZqpU5RL16+P3+/eruN3KlTHmb7zRWTPRRFL0tatKlfCIFK+/aWnOe+SkDvpaycfwNQ4exFrBygg3IqULwKmpztg6boebJSiagryMSZPMWV1ffBGv8+Zh7O3bh6QbunVYQnp5+LXOrlnjjBUPdfwttzit/26F7rOz4QZ4660qlozHzZtvwo1Q7ks8N77/Hgq+XbvM/VWoENx2jx1zemG0bInnzp4KRKoP3npLlYx54gnMAxlf7GXhcyNS0t1Zf/4yUUWbNrjm0aPOumoFAZZIWZyAW5aWUNmOiECEWrdWBMyU/pzPxZN20yZsklyfhQhCNG8Cofzwv/gC7l5du6rPeKLqbZ49GwtSxYpKWE1Kgkl71ixoiS6/XLnL6BvKrFk49rrrsHHzJte3r9I06xog9jWuXz/Y/UDvk/HjsYBINykTFi5En33wAax6+sYjhT03i9SCBbifhg2DN9q6daH5l25DpjpSfD5eBFu2hJCjEylptSpcWD0fKVimpEDL266d0zWLSLnOceyQJFIpKbhfvr+NG/HcypfHtSSRSkhwWgQkqZR9ULgwvsvMVG6AnAGycWNFLDp0gIaXLQjFiqnA361bnRYpmW2PSAkfvXtj45B97ddCMHUqBIePP1aWG+7T7dtVbbH774dwW726mUht3AhCduQInt2TT2ITf+EF5/VMSge9HpxOAps3V/21bp1Zm3zppaqI5pEjwSn9pYZSzi+ZES0uTpGsDRvU8Tq++w7JDy68UBWPZVxwAYibbpWVkM9TtkXGveiCRno6LOS7d4P46OuSLojK3//7LwSNgwedmukpU+B+2bu3O5F65hn8jRgRXDRYtn3PHjxHVgi4gQlJt26qLhsjMdG5XuoE9rbbsFbVrBl8fYbuasljpWhRnJ9/89RTqj7Vli3q+iZ06oS5/fbbTkuljkmT0H4ZN6q30c2bgN3bDh1S6/3TTwcXHSUKXmu7dsX+Ja3VhQsjNmvXLvcYHQkZUyfHFltB3CwdPO7+/VcpKL2Ol0TqgQeUxYvPw79zS/IQCyIlE0xJtGgBL5ADB6DI8WPNMCVwCkWM9POGOl7vA76nhQsh+/BY51IBCQnqM36upmQW/GxLlw7ur8xMKMACAcgdpvIvAwe617+U98SZeSX4+zJlsBZw7HnJku5ESq4H+vOX7oVEsDyH47GRX2Bd+yyICIsQu+HpmhO5qH35pfKxlce1bQttKgeuevm6yk13zx78sdugTBGua+vmz1fxMGxFufdeaG55EvOGpy/EMuHDgw/i/ZYtEK7efBObfbNm0Mxff72zyOKPP2LBuuEGZzIGIqebh06kWBgIlVY5KQmuUqaFiwhC6Lx5WHRKllSmeekS+PvvECKli5EbkZLtN7mkuWnO9Pf8HJkM87nGjVOp7Y8cUZvud9+pcaFbpNq0QbzNs8/is+eeg0aXk1rIjGt8HX6mfH99+0JYY/csU+ILIgjLMkvbW2/htUgR3Hu/fiAlo0bh8xdeQEyD1C7KjZjv5777ILw2agRypCcO4LHDhCYzM9gCdvCgMzbm0CG4Xuqp86Vgw64tfF5dKOZ+8CrIu3w5lATLlkFgkW6tRP6EE69jdKHjlVdwjS5doPl/9VWn9l5XDEycCOXBBRfAxdJt0w4EsD7p8UhEUKY8/zzIlA62MHJs5g03qAQaDLmmxcfDTbhYMed968JTZibGQ9265pgX/ZnoRIoI1+BxsmKFIjV+0mObnolcV/0mC2AtuKlfdRcoHWXLgqR41eviMcz3yWvnwYN47gsX4n/ZP6Hc9vjYdu2g+HBDq1YYV3It19cMr/hWJglnnKHSzP/8c/Bx+lpbqBAyqLElmAiKjeHDsfaYshfqkOu9yQIrr3nzzSBp//yjnrusnVWnjrL86+CxVq0aFDVcl6t1a+w9nIXULX6I18BoiBSP5auuwrVZAcWf63PRCyaLVKg4XV2WCZdIde2KcThyJEgIuwebPGvclMiBgJqLRYuqecttX70aBEpazP3AL5nk68THq7Xg9ttxX3J+79oFZUKvXt5EautW5//RJCPJS1giZUFEICh+iFSZMkpr4pVaXBciGb16qQxhUjhmyFolO3aA9HDM1sCB2HQqV4bvMReFS07GwjRwoKqZpC+KH32EV642T6Tq0jDS0nD9Tz5xxonJTdUvkYqLU/EjXv3kB0OHYrP/9FP8L90or7oK76+5BgK/1AjqREr2M7dfFxj27QtO0+5mkTp2DJvDvHnoexZ2iNQCKQW0ceNUZi63pAD//S/u74EH4ErDljx5L25ESk/5LInUokWIdxg1KlgLxmAhTiZW+PVXdV62YA4caN4EiUD+Fi+G5pw3hZdeQiwFKws6dULc3AMPBMe65OQ4N5tffoGA07kznm9qKqyW8hjW5vN8KlLEOa75+ZmIFD9/6Uo1YQLGbOXK6thPPoFrC9dPM2HUKGyed96JxAC//w7yvGlTsFAhUxlffDF+w/EmRBgD3burZ/XMM7CuffMNiJDctIcNw29LlMB6sXWr2QLMz3XNGpCxG25Q37FlcfduELqPP3Zq6omca1pyMlyKJkwwlypgSHc5k1JJEpmcHGehSyYTxYrBYs5rI7tP+qn9ZLpmdjaUDu3aKTfnUOdiUrd0KZ4Bj2UizJFAQGnPdddIPabEJCRecgmEsbVr8Xyl9VJad+LiMN5ljJSb8KcrO8KBySLVrx8s7zpJ4lpdzz2HOfrSS5jbM2dinJtipIjwbIoWdbrI+3mmpnaaLMadOjmJ7+TJcH3LzFTjTj7HFSuUAkwHr2XHjsFLYPx4PIuyZTH3pEWEKLhmU7lyiNvlOoVuMMXlMPTx89VXan3U8d57GE+sDNPBY4bLrsjP3KCTNL8FeRk5OfAk4DWV96njx2EVvfFGpazj/psxA+7arOzbv1/10Zlnor/79lXKWrlP7tkDC8+jjwa3TdbOJFJz5KabVEz0r79C6SjHpNxTdSVMnTpYp4oWhZX7gw/wHCSRKlzYaQ3T9+LffoMiy08x6vwES6QsiMi5cOmLmEzJnJBgToupw821jwMuiZyCMAuU0qz7zDOwUHC2IH3j5AUwORmuI6NGKddCfVE0baZxcU5f3LQ09TspqHoRqaefBql75RVVTI/N9IwiRUCE6tUzC/EZGcgQJAtaSsjF6/77lYtDTg4EXE7skJPj3BR0IjV7tirYyMK3vrnv2oXYioceCs5+x/fG4Gt99hk2ba4lxG0lQv+ym9ixYxCuV6xA9q4pU/BbmW4/O9sZIN27N54La06zstT3vNnw/embeHo6YogGDsTi/PrrsGyYNswnn1TZ5Ljfhg2DxpXTbycmYmPgwqAJCUopkJEBQVcGSaemKkLDMSbLl4M4dO0KYYTdlCRkYLF0bTt+XLky6gURiZxCsynpgpdFyiRwb9+ukkOccQae07vvOpOuMDi4/IMPcJ/t2mH+duyIsa33+b59mC9SYJZjUboAS/B9S6HqzTfRv/v3ByezkOB73LIFrq1s7SRSJECm8NeD2Hv3xvV4nF96KUiXvDddePr4Y/fviBBLdPfdsCIePepM3iEtUvHxwdpaL+1+x45YN0114I4eVdkveQ4fPoz+7t9fFTqX4Lb8/DNIvZ5khCiYfLAL4NNPg+CywOWWYCEnB+Nh2zazGygRBL1ixRAjxuMlVGa2N990BtPreP99rN9SO26KeVy2DF4RknwQIQ4lIwPKIZ5j8+ZhfTt8WM23lBSnq9by5Wpv5ZiyWrUguO7c6V3TieEWnH/ZZZh37Pabna3aUbSoaievq24WLQaPvVAug261qqpWxTOTikwT/Fikfv8dfdOgAdZnlh2WLgUZueceKAimTjVnuCPCGPrwQygnw3Xtu/lm7MGhLFhuRIvnbalSmE/z5iFO9cMPcU6O9SLCmHvzTWXxO3TIuV9eey1cV9ltXSqn//0Xyp5XXnFef/167KnSpVyOd3aZvewyZPKV86J0aZCzPXuUZw+Pq3fegTL1kkucGZfluCpXDnIaPzNdHurQwRkLW1BgiZQFEXkTqXLllKVn4EBFGORxP/0ElxrWrLm59snFhxfb7Gzl688T+oorlAshQ/e/5k1ELlilSkGI1DX9550X3J74+GCLFC+mMhBTFrhlIV4uDgMGYPHmbIK8Kd16KwTthg1BHlaudFp7Zs2C9vKff+DidPXVyl9eWuakZlVm9dNj2nJynH102WUQ/hITcWxqqgocNbn2ycxgjRuDUMnrc5898QRc43TLjwQLSwkJamHUXTU7dID2ulQpCHUlSqiMihKZmdi8Vq2CC9icORC0Xn0VG7OuzWUiVaYM+vfJJ50bPN9Ps2YqsPacc9QYcXMPSUpyjperrlJxDOvW4feSGI0YgQ3nnHPw/5lnoi/4/HPnIs6qcGGca+BAkDQphEgriCxRYCJSUgtsIlIXXoj+6NtXfcfjRd6znNe6v3qbNsHxH61bB7ul1qvnJLa6UHH//RAIXnsNm+nPP0MQKlxYBc5zmziVM1HwnNeLVHu5hvD5WBiU4z0lRVkku3bFK2dplEhMdF/T+vbFfJPwih0iggLo5ZehANLnh7RIEQVbK7yI1KpV6M9u3dC/a9aotUVmCeM+OHIEgtxbbwXfg2wLw0SG9M+kQoRddt1+S6TWbBlv5HZMVhbGyvXXm4k9kVqXnn0W/eyGJ57A+s3xdUTmunBu1hJd465ff+VKzJHrroOiKisLBJu19kSYP1OmYE24/XasK5xUyQu6RYrHph5b8/ffeB5paRC6y5XDHOXjQrnEpaWp5CU61q2Dtemaa4K9AsKFW5w2kbrH7dsxJ/T5uX8/xvA334QuyJuSAot0jx7BcZlu4D5KT4c85EU89WvLJBnchykpICotWjjb0KKF2mf0rH2VK2MuszLPlPafCHOISbT+bEuXxhg8cMCs3GBFgWm8ly2LPVrGE37+uVMpJe9R/z3jpptg/TStBSkpofs2v8Emm7AgIudgNy1iPKmk+5b8TXY2FjjWjHz/PTQVsuq6PPewYUjV2bMnzLh8Ll6I69TB4i81Frw4zpkDH20ZWH7oEBaFN94IroBOBK3NM89A2OH00RdcEGyR4vbdfDNcB/SiwGxyfustaIk2blQxKeXLox9YoP3f/5znPnAAv+nbFwIkbwSSdJrcUUz+3ER4JoGA02JVrx426SJFQACzsyEYffstNHR6XQppkThwAIIy17AqVAgLuk5KH3lEvX/rLWWNuOEGuGN17+5sZ6hiydwOXdMrUa6cU/Alwv1Jkuu1iZuIlHRPkAK4XyIl3Wb4frdvB0Fo3VrVMtMzWm7dCrcfrjE1caIzPkjCrSCvbC/ftxTwZaYlvt/GjYOTeZgsUmlpwcU7P/oI2tGrrnIqONaswf2yFpNxySUqxkgqKIhg8WBrRWIiLIF33w3tqlQ0cLv798eYy8iAICE1/3rq4OXLIZyceWawZYXvkYmUPq47dHBmjPIajxL8fO+6K7hwrleBch1yfgwZ4oy/I1JuvAwvNzDpely+PP4mTcK4qV1btYv74PBhpzvz0aPOeaDX75ECUIsW5npp110H6xVbW378EUKcFMIY332nykQcOoQ1ZNIkCGmcLe/553GOdevQvkqVlMu2Cab00CaYsvbx/aWkKKsju4u6nYvXToZUbPz6K6zVF1yAfmVSu3EjxltamtL8s5uWm1VOYtYsPFM+3733IgZHJ1JsQaxZE/d7zTX4W70a+1xGBvZcLi6t4/LL8ZeYGDymExOx1iUkQGn1zTfBWSoDAVwjMxOKMzdBedgwuLKbXLv0dZlrC/bvj3WKZQ8/daQkBg/GXDfF/0kUKqSSn/gBj7/HHoN73eTJqg/0trnFaZnSnxOpvtixA20vWhTPVfYRpzfXyWTRohhvR47gmBo18Pyeew5yklcdKYa+l+trkfyf190vv8RY3b8fyg1ee4YOxZjnfiloqc+JLJGy+H9IUqQHKk6ZEmyCvece58Kj1zUqXdqccYYnZbduzngL3kRl9qqOHZ0B37zYZGc7P09KAln44gu4FcnaJYwyZZS1o1YtbCwdOjg1n1Lgy8kxT2ipZdVdpho2hIXBBBbuuW0yaxgvXElJICaZmc5aQZIo6ZXq5XPLyQHhkH7oXDi4SRMkQ3j5ZfzPC3PhwniWekHmp56C4LZ9u7cvuHTxOXYsmAiuXat8tDdtghBVpAg2/D59sMj++2/4gbsmsPDPzyMnB+P22DEnMeBrZWUpoeXpp/G79u3dF/LERCfx/vhjKAJatnQSx7/+cmZL4us9+igEzgYN4ILC8MrU51aQVxKpcePwrNyIlFffVq0KoUWSVNnXPG4nTMAcnTPHaX0qUgT3xAkQGBUqKKVLaira36IF2iKJrp7+XEJanpOT1TPctw/z/MABWPtMyURMJIifK68xOjFndxp2hdHPMWECSG+HDk6rjVdB11DxORkZuJ9ChZxui88+C1eZVq2UZVjvHy+LlCmGU5I8me4/PR3zQLrUbNkC4XzpUnz3+ecQUK+8EolPJJGSlpylS5V79VNPOd2VmzVzTwMvC7cfOoT5U60antWHH8JjYfBgFdPlJyhdjns/BXnl2l6xIoTKpCRlgWUXc12wHDoUCjdJoohA+Bs1UrXm5Fjgc2Rn4/nL++E1xs0qJyFj6uQ1Xn4ZVovRo7HOcr+ddZbzeCkQr14NwdwLSUnB47xaNbR57170oR5bSIRnKi2regyVhFvIgGkPuPdePB9W+hFhbzORFYlAAIJ9djb2ZD/ZUocOhffJ44/DNV0mLDKhXTvsKS1bOtsvMwu/+iqeAbsR6+2VROqXX3Cf0qthzhzMz+3bsfeb9i693+LisD6vX4/9sUYNrDGXXIIxz+POFMKRk4P5r2dQTEyEMuzrr5EsRRKpH35Q5G36dHhtNG2q0qKnpIAMz5+Pv4JWjJfIEimL/wdriBo3DtYYcparK66A5jA9HS5CEqEK+unH5eRgwjRrhonJ2pN27XCOn35SCxBvzLx564twcnLobDdubXBz7Tt2DPfLRfoYcrPla3LfeW3uLDzyhtO0KYSK5cuVsJOUhA180CAsipz6W7aJ+/d//3O6PPH9SBw4oM6xfj2eYyAAVxa25OjPku9vyRL83X9/8EK8fDnutV49ZzKJY8eC49fWrlUppQ8cwF/hwuo+WEMVyt987Vr4s1eqBEK2ezeE2eRk3MOZZypBm/tz3z7lB/7f/+JVWqRWrsQfERb1Dz7wJlK6RWrPHlgYdSLFffHww9gYeAz98Qf+dC06bxzLl2MeNGigXAZNFqmcHBw3eDCea5UqwQJq9+6wetaoofr24EGVUIbdUFnQnT9f/bZYMbWZskWK+2T2bKfAWLQohDYZC0QE0sHzIi0N98j9wJk3iZzESicGfL/TpjkFjORk1X7uDx2mZ6hv0KaittnZUCwQKRdmxpIliEksXdpJpO65B89u/XqMD6kgCrUeDh6MGIjHHlPkmtvet6/TDZORlIT+LVXKfM6cHDUvFy1Sbsrr1qn33GdNmjiLlz/9NI775x/0F5MHzpJWpkwwkZL3KNeD334zZyQzQWrcpVWSxzULmnwOjpXkmDaTheOJJ2Ad+fzz8C1S6enBfe8WGzx/vophkShRAolnJkzAGvfbb3jOnTsHp62X7WMi5ccipYMLz8+ZowobEymFl4yvIYJA/eqraNeePaHHa1KSmcAXLoz2utW+knt2ZqY3kXJDp054/ro1hOe1HF+hiFRcHJS5gYAiIX6wdy+UOCVKhCZSV1+NvyNH0B49/johAfP/2DGl/NTHKSujt2xBfPOSJSCAprIyROYahSZiKokUg+eal2vf7t3mhEMJCVC0bNiAPpJzOC5OnZvvPRDAdbhMySuvYG9s2rRgWqRsjJQFEQVbJCR4kpqqpevH8OR75BEsEroli4/75BP4iC9Y4BSs2rRBMP5vv2FRPnpUCX+8yEuN9g8/wN2HheN774Vgy5YYE3izP3gQxHHsWPjad+mi2jdiBLTCcoEdP15tADffrKxi336LV69rcpuZpFau7MwOR6RSpk+d6jyXybWvS5dg4Zm1RV98Ae3VXXep5zFhghKYrrwy2MVrxw5o2mXBQT6njjZtsOCtX+8UnCZOVPEK7O5o2lj1mif6/yZs2AAN9/jxIFRjx8JVs3lzuLIEAsj8NnCgIjtyE2VBTBIpIriScFwTa/8aNICbmcRbb6HP9PTA/Dz0fsrOhhBrSrWtu56yIDBoEBQJP/2kvnOLkSpUCNrmH35wpk9mNG4MMvTHH0rIXLkSbm8yWx2D+79KFZW8hEiNUZ1Mr1uHMXPhhcEkigj3bnK1vPZap8Y6KUnNqc2bEdfHMUq86f74o3sKfiKz8GfajLt2hXsiEyXdIkWkatgRBWefc4v7vP9+aOWvuSY4mJ7XD12AZcjiq/ysMzIwt9xcYdPTcS/nn2/+Xs5J2Vevvw73naVL3YP6WfGwebPT2sxrvinznhz7umJFFmh+7z24fv39d3CbdSI1ZQoUDkwmfv8dRJz3oOxs/J+crOpT6ejVC5puIn8WqVBumG595kYK+PhrroEVNysL6/ratcHtkcIqW8lDWaSOHwdZHDlSzbXXXweJYlc/bsPBg7gGj8M//4QirHt3tW4SuROpsWOh0HRLgMFr2uzZcBOTIQBETrJriqlhvPceXEFNxY8PHzbPCZ6Pcqxzf3g9d/5u8WLs5V6u5wy/Gf4kzjoLa+Du3XgGAwZAEXr++cFlW/Tz1q+Pz/bsUZbNBg3ca1QlJ2PtlUVw9RTjRMqbiBXYY8bgj8jbtc/tvhMSnGuDtOZnZUFplZQEJSgR9qUSJSAv3HijIv5EBdMiZYmUBRFBy9CsGSa8vtHp1qZ9+4K1kvpmNGYMMsboWjXeMJ59FoIxkdOS07mzEoL++gsuCbyhDBsGQYA1IjVqwIJQuLBTcJo/33sT4mx0a9ZAkOnXD5v2rbfCbL9vH4TNQ4dU2/r0AXni60jyJ83cF1+M43TIVKdEWDg5wxsvOsnJqgaSPGeHDtAYSoE5IcG58T/yCDbsX3+FFozdTSRYCJGL8NGjuNY//zjdaxgXXaQKpjKk+55efyYzE9fmzGb8fVycqjGWmurUIEu3NSI803Hj1MaRlBS6jlRcHITYUaOUC4kbkTr3XJVqu2FDJVzw77p3B9GXuOUWCMtuRMpkkZLjWhYD1mO4+N5M/vANG8Jl4vLLQb4vvjjYnefRR9E+3b1OhylrH6NxY8zVFSucta34Oekbd3Iy2i2zFOrQk38QQfiVGm3p2vfvvyCG7B4rC5W+9pqy2KSkgGy+8w7IIfe93IBNRCo9HYIJu8DoROqpp1SSjvLlnTGORN4bvVsaanbxfPjh4N8QqWfC84TXtjPPVO5YDD63yXVKgrXB8fHOGnbvvYf4lwUL0O/8x7/JyMA6N3IkxgPPyYoVYdF99tlgizORc+xffLGzLdLNetQorA26pY/ImSExKQnrfM+eECDZqt6qldpP5DrgJdT6qRFkcu3bswfr3i+/4Hlz0eESJYLHlhuR0o+TRMyr6L1fi9TRo5j7Dz+sSIBM6y3v6b33MMauv159v3KlGmNuNfcYW7dCCcEYPtz5PY/j8eMxhnQiFBen+unWW9UerIMteDJej+HWH9x2OfeyszH+vcYGH3/ZZVgXmFS44fvvVdiDHyJ18CCIw86d+P/33zEGHngAfVC7ttndTyI1VVmFibB/Va+OveCyy9Tn8neNGztLSZgIIq9z7F3wwgtwyyPCmhUIqDEkSX64ROqVV0DuMzIwtvRMqFOmqDInXIKjIFqkrGufBRFBmExPhzD9889O8y1PUum+UKUKtFrsdqcTKTehY/lyCMl33eWMVSHCNYsVU5aeWbMgNI4eDS3Obbfh8wUL8KoXwJXwWujcUsYSKQ0x34+pUCZRcK0lxk8/mbXPFSvCSsPkRgpJvNAmJSlyKYNt27fHn1wQ338fliHGY49hweMNLDERwo+pbsdHH6Et/fohu5ceIN+jh4oXWbRItY8hN10WABs3hiC8aZNzUef+69ZN1VNJSXHenyRS1aopQXrHDmxcMoNbVpZ7HSkd8pkNHw6yWbx4sDWMiYvJQqGjdWuQbHbP4zFoIlLcrokTEcPEpER3v/AiUhdeqLIvEcESefgwtO0pKUiuMmkShJzrr3fG1ukwEak2bbC5ffGFcvtq2xZKEP0ZScg6ZYxXXwXx5o1/+HCcmwnRWWcpjSRDEimeU/x8BgyAZTglBePnn3/gflm9OoTyzz/HJr1qFcZErVqwVt54o3dM3UMP4U+3rMu1yuTq47amrV/vJP0Sb7+N37m54UmLVJ06sLxWrAhLfs+esJC9+CLm8UUXYQ1u3hzz/NgxlbRDIjtbxcLIthYpAoKQna0UNZmZeN5sOe3fH66GRKqmTUYGyFWhQhCUe/Y0x1sxJkwItuYlJ3vXkeIx/8UXeNZNmuD/WrVgMe7dG8+rSRP8vlGj0AkFFi2CNZPIn2vfoUNwBWzbFnvb5ZfDasPzeM4cp0KEoY+HRo2wj7Fb1u+/o985IYtfIhXKImVym2RBlee4fDaynTzutm+HMM1KGDernO62rq+VvLawRdfkYpaa6oydCQSCXTK90p+byJW0dMnfvP469jCvekT6uAlFjrZtc0/gYMKLLzoJp+k3/NlTT2FPMSlpJkwAoe/VC+MxPh576eefK/dkU3916IC9VNZtYvTsCWXwXXfhf55L8+djfQkEsPYeP+70oPAqfi3n99tvYyxUrOj0ftHjTnkM8zp21lnutczyM6xFyuIE3NK7uk0eeVyRIpgwrC13qyNVpIhaLBITQcQ4FiolBRo2PdvW7bebkzz88w9cro4eDdbye22cuvb4gQdgxZE1aGRiCyJsNl9/jfsKBJTQt3ZtsBbWtGB+9pmzpou0FjVoAMHwgQe8034mJeEcpUsjcYQ8Bz8LKVxcey2si7oV5fHHYeUgCi6WSRRsjXEjqZJIDRmChZvITKQKF3Yv1piUBMHjvPNUOnIiCLPTpkFrFaogb1YWhFBZWFa2u2hRuABxFkken2zZIHJaYnJynOPwhx8g2JQsCSGWa2hwf9eogX69+mr8n53tFLzlhi7jjo4fVwTGLUOTjkOHoGF+6y20mTXFoeIOeEPMzFR9+Oef0AIfOwaLXqtW8MG/916MMYbJIqXP7TJlnEqEK6+E2xCTElMNtfr1Vbt5rPD40Yt6czxbnTrOTfussxAvmJjorSRZvx4Kh9dfx//6OiczjJYrh2cTCGBMPfqour7ez507K/devZ+KFHEmO9HBY1gKmHz/27bhj8cRj89//gFZ5KQfY8c6XYGrVkXigNWrnf3AQpdUPCQlOd1PZUZGXuNY+ElPx/geONAZR6sL3/r/jRvD1csPkeI5wCSiZEk8B17/b74Za2nv3qGJVP/+EGb79PGOZ3nlFZDGd9/Fs+zTx5k+O5S1Rh8PkyZhv2Aye//9sB5wPyckQLnw11+qsLdcMytXhqDLa4kb9OdIpPqNCQ0/C11pIIlOmzZKceZ2jzwGy5TBfiytJHy+hITg2EoJvZ9MpM2LSLVpg/3hrruUolfO4bg4jNXDh9Vc9tpP9XETyr1cziU/Fik397v586Gw3rFDHZOYiPllyjhco4ZK6CK9EfS6ezqaNME6Jku5MJo3h/KH3YP1uRQXB2XTf/7jfJbyvqULuixxkZ2NdaRhQ8gqcr7rFikdw4djvhQ0WIuUBRFBuHJL7yr/nzNHBXrLRaxuXeXmI6uFe7nBJCY6hSt945c4cgQaqfh4CB/p6bCA9O8PC4G+AHktdJwhcP58WLm4kvfBg1ikJ01yxn288AImd5cu0EiVKKEWsTJl1KJ+0UVYXPxoq848U2nY7rlHxTvJbG6M3bvRT8WLQ0iqWROfyQWKa/DoJLFaNSyEevrijAwVrE2E58S/zcnBQmpyBSRyuvdwXZ20NHWuoUOh7ZoxQxGtjz9WApk+JuLiIBxzUgoiaOdmzYJgw0HGRO5EatUqCGwVKiif8Ph4dR9SQNixQ5EPFoCJlBA3bhwCzdmCRgRBaN48ZJ6TfcDnPfNM3DcXV6xaVRHnlBSnICPbLVP/m4jU3r3ow2LF1Pem1Od8HS/IOXL4MM7H7d+1CxsnkTOlPEMfA0lJWBfkOGF3P/7syBFnHJ88x8KF0K6mpsJN+KmnMEZfeEH1rSRFc+bgN6zh3LwZ3+lCeUIC+sqUSGLjRmzU9eurwtQSkkhNnYpz/fUXhAkWNIm8a+Pp/TR1KlxFW7c2x4WY4nP4/vnZ8tiXbsFEeHazZ8NNiMisfdctUkRml2xGnz4g1gcOBFvdZcZKibPOcmZR1Z9JzZrOuA4/RIrduEqWVOs1kbN/Q7ntcT927RqciVaC68dx3SaZpIHdH/V6ZRKSIJx9drBST/e8YAv7mWfimbZq5ezb6tVVfSkvcBvj4tz7YONG3F8ggDWM4x9NROeMM9wtp9x2Frz/+MPZp998gzbceCPWblMJCp1IyeREDC8iVaiQ8kbp3x9jSiq/iIL/90I4XixE0ROphx/G76ZNw9z6/HPvOSHBFsNwiNQTTyB5jBv08jVEoe9Lfi8z09asGXwvw4ZhnZYeLW4lJTiJiFcm0vwMa5GyICIsjBwb5WWRql5d+d27pSmVmjJd6Bg6VAkxuKLcyQAAkb1JREFU0hzMMJnviSD4tWkDQbZkSaeffXIytC8yNimUdonIma2KCJN4yRKYpfX7kYH+UsAoXFjdLx/jtRixMMvxQsnJTmHT1Kdvvw3tDrsJ8L0lJMD9hAjf33GHWUvrZqk4fNgcX5KZ6e0XLWOkpkzBYlmypDPzGwtWrInPzoalg9MamwRdIlgxihXDvfzvfypo2RQjxfd19Kh6Jm6E+tVXsZEtW+aM65IbLwtxfH96v8l+MNX7IoJ1dc0aCBYsfDz9tDMmoGRJCEqff+4Ufk1E6umnoaF+/HG4rZUqBUJvQiiLVFqa0tDqrj+yT0zj9777nBpIFiqkcNGjB8YN39OXX0LQN23S5cqp9lauDLLSpw/+5/HNRVx378b3v/+ODIHXXKP6PyMDLqz//S9SoT//PNwHJfHR27x8OciNjPkgCq55R4SNn92XGeEQqXHj8MoCoA5JpObMgcad12EWKvic/fohrkKWTvCKUdPbKolU9+4gGDK5xoABIDDnnANriG4ZTU+HVW7mTEVkidCfvB4XLhysUdbXJCk0/vwzrJ9ffQXL2r33QjHGAlfJkmgrIykJa7AsBeG23voVUhlsZatXz9lmPv+VVyJOVY/x4nH8wAOw8Or1iExEilGrFuJapULHL6TSzGR5ufhiWF/nzsU6ymn0iYKJ1Pnnw2L7wgvma/FY3LYNrvaff+78nl3sZL0+HV27Oq1spufiRaQkqlfHOJwwwfz9yJFwETXF/co2e/2vQ84lP8pS/ZiffoKSVrow8zFvvon5x66oOvg+uazFH38oT5PrrjP3V6g+3L8fVtjx49V479ABY3L1aoyZRYvcCZvsj4wMjPvatbFHDR2KPYu9PRhnnWWOIWcZaMWK4FCCggBrkbIgIqfgrAvzvXsrbXVCgnsaWIbcgHXB9ssv1XsZZ6EnT9DBwYpEWPDkIpyYiE3uyishzK9e7b2IJCXh93oR1CNHzItpdrbaqHQi1bcvUsITKauPaZF96SW4hMkMfUTYhLduRZvLljX3Kbdp715kQmTLTXo6rv3++1iccnK8idSnn2LD5EDTgwfNBVmLFoUA/5//mO9Ht8b8+qvKtMbg7wYPRnwQa32XLYNAd/CgWet66BC+401i+HBsPuxuaLJIZWUF15Bi3HorBPsvvkAft2jhdB9kV6YmTZS2lcfkzz87zyX74cYbYWXgLGd798LlqlgxZaHk8b1uHTTDfftis2QydMMNsNR9+inGq4lISatMdjbGmBthCkWk4uIg4GRkqP4yEWnTHKhSBeTns8/QDu6L5GT0//33qzptjAED8Lp/P46XY3v/fvxfsqRqty5EyXkmiTSRuv6BA8GlGHRLmH4OIsStyeyERGYideCAIlKNG0N4C4dIseuWWxxf/fpw0eM05DLbmXQvI0KSiY4dndZNmZCD8f33UBq0bu0sni1d+77+WrmfPvccrFAvvKCsXbt24b5Ll1busunp6LMJE5D8Q1r1pFBfpQqsvt26oZ8nTwYBNhEbjv9LTARhmjcP1mUm41yslts1diws+FdfDfc3/q0J/Plbb2HsuiU4+P57xC+tXq1+Z3LtY9KqJ9gZMQJusW77oWwflwI4cABW2EBAKQwkjh5VrsRuQruXG2u3bljzLr8cyq7XXnPGy3I5BR5LoQL8mQTKLIAmeBVFf+kl9OucOXSisO/hw5AJUlOhIPBLpAoXVgXtJe6+G2vkihUgG6xoNOG553CsVOx6gfuoRAk1r72gP7fUVGe/JSSAxBw9irn33XcgIibr6ciR2Ge5KDe3tXx5c9ZUP9i9G8orLuZLpGLANm9W7cjIUMQ4Lg6xuB9/DLLElqTDh6FIeOABjCm3vmzfHvNwwwbn/lq8ONac55+HYoZlqoICS6QsiMibSMnCukOGKD9Xedzff0NbV7iwcsWQxU8ZeipNXpwuv9y5OA0aBFcL3lAPHlSLfmKiU1srtXHFipkzK0n89RfcbDjFNS8G559vXgC4oCwR2nD4MDbDrCxnet/Fi1WbdGze7BSSZHDwI49Ac92pEwKrJ01SbiZ8v0QQ1l98UX2ubzo5OWbt/zPPYDG88EIIFEWLoj8PHXISKbmxtm6tiknq93PLLdAasWnf1GcsiJQr5xw/vPkXLaoEISJoQ88/X7l6SmH1wAGQk4ULsRmVKoXzs3tjjRrmAqREiD0jUgGvMv15XBxcUidPRt9wILk+dooXV2SAceaZzjiRH37ABnPxxSqjI7tjXHcdiFTjxspdMCNDjXeeRxdeiGclLSAy1pCP06vIM/ykjX3sMdw3uxLx8/fjtpKcHJxEoFIl9H3//k4i9cUXypLAQpW0vnFSjDFjQDCXLVMWTR7Psn95XMqitUROVxBWkLjVc5P3GBcXnBRGEqkGDdCm/fvV+D1wwJkFj8H9de65zsQgftCmjUoao2v5Te0mwjjgNYvLDBApV6nt2zFvK1aEoMV13ziJRHa2c+2QFqS0NEVcqlTBusQWsPR0NfZ0a4IkUvxsJOF7+WX1zE0uclOmqIBzGWeTnOwkUjyWsrOxtnTp4rS0SPCzmjoV15TFgSWee84ZJzZzpnKhkhYphr4/+nWHevpp5Ya5fbsiUCYiVaUK1liZ0EmHW6ZIIjW2eb3VFQtxceg3jvsLRaRKlIDlmC2rq1Y5v//4YyhZOFGQySJFhL2ualUo2EqUAOHhcgybNvknUg0bgvj+8ovTBfvTT0HiK1fG/17P5vrrMaeZSPmNkapc2azA0CGfy1VX4V6lBTghQSnveG66tZdjcvVz+0nZ7gbpLs/3XqQI1nOZIVEf708+ief9ySdYM7dsce67Bw+a3YzPPlspCy+5BHsHK0jl+LTpzy0KLLyIlLQUSeKgV7xevx6ahqpV8frbb8HX4Ql7zTXQhrhp25o1c2bOkkGKBw6orE78e47J+PFHLAKcwMKEqlWxeHNbli2Dxufxx9Vn112HxV5HIADhOzNTCZWyOGdqqtkyoGvoLr1UvedAcZnZSvY5f6YLiCYideml0NpyIDoRyNk116j+5MVMEimOceINOD5epR3XN9m77sJiWrMmNgjWkjVurOLs9DgMHituQu7x4854Oekew7WGmjSB2025cliEGzXCM+vd290ixZAuJzJFMPedbJe839RUtSn4SbO8YQPaJTMqmopVc3p4IqUIaNYMGj2pRTXVkXIjUn6KXA4eDDe99HTcFwu7oSxS8+ZBgy4tykQQxP75x0lKqlRRsWTSfYU3WxkLt38//po0QRB7To7KKMdEvXt3JQRzRifdXYpIzTF2adIh77Fq1eA5WbgwMrZdeaXqy/37VUY+mYxGgp8vW4EihRSKBg1yr+FFpNonlUg8LqRSIS4Oc+acc2DJmTEDxNVUI4bPxxbrrVuVQEqEMaNblQ4fBkHi5AO7dqljWrRQdZySkkAY5swxp29ftgwuY4zJk5VbEK8F557rFP44MYqJiBCB2PM665XNUu+DX35xKqQuusjpvWASuPfvh0Kndu1gomhyaZRzrGJF53pBpEigFGinTlVJB4gwP3791amA5JTY9erh1S3pExEE+7fewvspU5Aym7O46Xj1VcxLN0XBqlV4Zg0aQMjm+S8RCMA9d/58tZ/LfT0zE+7cBw+qZEhu+OsvjAHdq0GvyxTKBS8pCSRl8ODQx4ablpvPd8UVsMzKuUTkHAN+CaTeFulVEi7kXJo2Da6HdeviMxlTrbdJWkIXLgShlTF+bnFQs2bBte/wYVizPv4Y7d+zx5nZryCmP7dEyoKInBsykxSGXlyPCAKNTIEqhfnERFgQTJsXH3fTTTDx8qTRTeWJiU7XETk5ExKUZofP9/XXEJJ1dz0/qFULi2mRImpxy8kxL6w//AB3s2PHlCAmM10dOGD2y9Y1dHJTle5+992HRZeLxBKpNumBmMuX47zssnHsGDayfv0gEErs3QtXq3vvVQLtoUNoe//+ynedBawxY2Cx27bN7ELB55w8WS2sx44Fxw699x40sXzeunWVy6CE7J++fZ2ZEP0E9rpZpPbvx1jh8aMX5OVxP3q0efM1JfAgghDy5pvqWfP9Hj8OLbIMvucx+tRTsDhlZ5tT0pogNy0+jz4OrrsOWkE9O2Mo5ORAaC5fPjSR+uUXaJOvvTZ4rs6YAQUGZ238z3/MGRrr1QPJlJ8dPer8PytLEUZeG0yxFDffDBcztionJKh72LAhWGMuz0fkbsWYPh0klzXO+/c7k0T06hUcW+W3oKsJ2dmwwBw4oJ71FVeACHbpAoJiclPktYcVF0RmIiVRpw7mFbujyrZLcMKBRYuc2Qb79QsmUtnZzrHev7+qTfP552ptSk7GfnDeeeYU4kROK3ynTurZclzI3Xd7jwkdNWpgfm7aFOz+KWHqg2bNQB5uvx3j7Icf1HPQj58+HeR7wwbER+rfm7L+yWO2bYMVRUInUgsWYH7JDGxpaSCT7DZNpPpl6FA8R1ZauAmnsh//+MNZhNkEnfAxWIHVtCmeuRxjjI4dlUKErb/S1S0zE+2UmX3dwGOdY40ZoQrcSsydC/IweDBIdygSc/75WNs7dYKyMhTq1EEyK97LTS7BX32FvYf73W+hXzkP/JTt8DpHIIAsfm3aKGWrl0WKFZ4JCTies1O+9x6sTrff7jz+pZewPxUvju8KF1axeEWKYN9q1UodXxAtUta1z4KI1GSpVMnpLkKkXNbatFHWkzffdC48foUJ/bjatZXGl3H99dA0XnQRFuaFC51EyuR/zYK47r8eLqT1QE/xSqQ0rFLTLkloVpaZgOltTk+HMDhmjBJWkpPRL++/DyHm8cfxuUn7/tlnOKfMyuPW9/Pn47m9+SZ+M2kSFuB69bDZslsBkSI8H36Ivy5d3LN16aRVZmHiDfqdd5ypmffvdwaqMypWhFWweHFsPhyTR4T+zMqCW+PRoyBGCQmwAOzdi/53SzZRt67T0lWokHNjkEUYs7PRP1LokAlJ5HP96SdYDbp3Rz+wkMSkIDsbG2hiorrenj24Lzet7+HDEEqPHVMWVUmk+DwtWmADfucd+JKfe64SNkPhr7/Qf5wKnp+FFORM80vW8erd25lmvmdP9OP8+SCLW7aojVKeiws+SuTkOInUkSPqNzzn//wTws4LLyirRePG+GPrFWeP1NsrIb93I1IMTkKyf79zTL33HuLjZPasa6/FPMrMxHh0my8mfP45rONt2yJZh2y7WyA9EVJ2p6YqUtu+vbouryduCV1CZftiQn7PPc7PTbWgdOuLXH///NPb/YwISqMJE6CdLlFCufVlZKhnIJ8FC+DhuDSZhHoJU2xT7drBY8TNarBxo0rEYkr8cPPNEBQXLgSZ6NMneO3Uz6nXkuL4LSLnHNFx+eWwVC1f7kz+4yactmiBPWTBAuwLbpkJGf/5D56HblX0KvbNkPO8a1f0m06kokU4RGrQIOyz33/vLG7rhrg4WOBHjoRsIr0+TGjVyukZYyJSzzwDq6L8zA/k+uYWmxcKck4ePYq+YmWBF5FiJa3cA4hgxWJ3aIlixdT+xM84JQVjjTNO9uuHPeSRRwomkbIWKQsicmal08GTW/q96sdJrdv8+XBRMgVB8rm++Qabw6efYmFidOkCrcXnnyNA9qefILzJjUduIuyawAv50qUIkpQuEOGA72PSJFhv2L2oShUIcexy8OijKrsfx+EQubuucZt5c87MdGYeI8L///yj6pDobeJFqGRJuOrprgI5OejTKVOcG++zzyof66QkaDY7dQpOdXvddcH95kWM9eDtVauUu2PVqhgjpo3VbaF88EFYzeLinIt3UhLa8Z//wBo4ahQ0kfPmgQxecQUsHQMGBFvi9I20UCGMlcaNoTGUmyELnmXKBFsQmzVzxsfI8f711yrrFgsLWVnYoL/+Ongjctv41qwBKWJXSSIzkUpIgFb/oYcwTmS9p1AYMAAabFlcm8/JkLFrDLnpyk28d29FRosWheLjxRcV4ZHC05YtcLW65hq0uWJFWOYSE9X1O3bEvCNS2dH+/hsCx6pVqig3Q6bAlu0yEanSpZXGNRSRatQIa0716sFzQB+/gwZhbt50U7DrIyceqVPHfB2pWOJnfeQIiK2XYHnttRBGeU1u00Y9IzeL1B9/wOojM4N5WaQY6emYm3qtGG63hCRS2dkq7ispCdd96SWny/dVVynrbJkyaoyPHq1IMl9z/nynO9K4cXgWoeothQL3Aa8dbqnS3YiUHOMmwnjFFWrf+O47rLH6OfQ1QbdISXLOsZf//IO5xkXYiaBwePttpeHv1g0kqXnz4HbNnIkx+/PPyvrntt736QNSsGABYurYBYzB++/nnyM+0pSMQnc9PnQo2LXvtdewpnCcabiQrv5E3kSKv1u9OrhQuBtC1S7TweUt4uPVvGzWDPOgZs3gdcrveeU48yo67AV57WefhRWcnxG79sXFedfiMrVJJ1hZWRhfJUuqbKp3360Sudx2G9Y8r+Qp+R2WSFkQEYSM+vXxKgMiicyb7Z49TjLFxxw/Dj/o557DgqqDN4y331Y+8JJ8DBigJtLq1bhOUhKIyJNPImuUXJB505OC7/Tp7nEkoXD99RD4atWCMMNtu+02tI0tUhJSA3PppaoulYQecL97t7LEyXpNLGTwZkkE7fcDD2BTJDJb/4YMwaY4fjy0kmPGqO+80rYePYrNOiPDnIK3Y0dnIWEJk8AxZw4EnL//xrNmInX//RBO9fa44YEHsKlym02/kfWY2reH8CXj1YjMRCouDtrhZcuU9r1IETU269ULVgL06eO0THA//vsvyD8nWOE2SSFYd81yI1KmrH3t24Ps1a0LAbd5cxX/QIRxNGAAnr8fSO2+RHo6rFPbtpnbJzc3OYb+/DP4GKnokO/374cwPWMGrEubNysLA8/pefMUyXviCYy/zz/HmK9dW23qK1dCCTN3Lv5PTHTG1Zk24+RkaOBTU92JDePOO+HOdeONwdYPr9p4+vzieDcWVHXIuZycjP744Qfci5+U2GyxkCTfjUj98ANI33vvBV9fokcPCFbch2+9BWVXhQqhidTEic7/WdGVlITA8vvuCybxsoYUz5WHHoLVlUgpbN57z3n97GxnFs9IIRUURDjn5s1QUqxZgzFTrBj2FOliy5D7kZcQKIlYqGKwukVK7pHcB2vWgDhJRaR+TzVrQnA3uYcWKgQL+OLFoYsO//kniKxeW0yei3H11cGuikTBzyk7O9giNWMG9rBQLoZuCCelOX93zz3BxNCEHTtCZ4qUyM5WslQggFTjR46gH++5B4pQt6K9oZCaGqxIDRfy2o89hjWP62Lyuu23PfJ8LHs1bAg55rffQKB4LOv43/9UjDtRwbRIWdc+CyKCS19CAhbMJUucQjJrxaSVpEIFLCzs7y4nHB9vWrwnTcKE/eijYJe1u+6CkCg1ltWrg5wVKoRaMURODQwv/LpLVzgLgEThwvjT/Y75fFKINWHRIvOizOdbs0Z9JvuTCJswW7mkVqdJE/z9+ScE0N27sTDxvVerpgKuWaB2qyOVnIz+5QK2f/2lCobyb2rXVhatDRvc3SU7dADxzM6GJYWtXrLv+bfXXAMheMkSf0kRSpYEgWzVCn7XnLDCrbCtG/ie3nkHAfcsoLCgoRcCZeiWNF3DyufVPzdtAm++iefGmn43IiVdszIyMA71WKr580E2Bg3CRnXxxTh/sWJmAq+DM9Dt2gVtcIcO6NtZs1SSARPkputmndKJVO3azoxwbDmQ2k5Gaqrqcx4/pUu7pxmePBkWyhtvhKWFCM+3f38I724C7ZdfYgyFo8XV43H0Z7xrl7Ke6YLRI48g1tMtLkjGZN52G/4uvhiW+KuvhkJnyhRnbAwRBOAlSxQpef11kM5q1TBuypULjpnjtiUlYe1wS1PcuTP+PvgAa46cGx074txs4TAJ3uyGWbeuygons/nJ/vz6a+XS+McfaFOlSiD055yDz9k9iuP5rrgC/RKudcANsi4ft+/zz2EZvf56jMuDByHky9hNRiiL1Pr1SNzByUoSEryL3hMFW6R4j2zbVimkvNwm/bja8162bZuKKXQjUqaYRwl9/zW5HkrrExHar1ukwk26oIP7YvJkrG1eY0P2m5/ryX3GTx2pH390xjoXKRLcf3yeZ5+FssVvnGuhQvB4OPts9wyJoRAXBzniyBGVMXPYMKTzP3AgvOLGROpeWreG1wgrwN99N/jY1FSnsnH0aLV/cSbDggRrkbI4AV7E/Prc6u5XZ52FzZMXf9NETE9XAmNiIgRCjvNJSYGrB2+sjJtucla3lwIYay31xSTazZU3FHZbWrAAli6ZUe3++yFEyWQTROZFtls3ZzC1RMOGWEi7dPHu+7POggBVvz4W3SlT8LncBEIV5E1KggaoVy8IMSYt6cSJznty2zQSEkCIJ0yABYldY2R7ZDY9Fgb8apwuugj+4xzDpQvHkkjt2YM/XejlezrjDBBHfcPk2jAyjoqv/f33Smj57jsniePzSsvnQw85i4cyuIgoIy5OadllFsz0dOV6pic0kFi2DGNpwADlouaHnBIpC9CuXXge8+bBihgfD4G/XTtnVj2Gm9uciVTxc7ntNqfrpFvWO739foQa7v/4eAjcLHTz8/eyDMTH+xfUAoHQRKpvX2W11a9bsSIEVlkCQMKU0VG2be1as7v1++8jtooF0ZUrFZl75RWsW1zHiyGJDMd4erntmCxbF18MZQ0nHdAF9c6dVXulMD16tJlI9evnFKh27sRcjItTMaqSMDRpAkvdyy873TqjwZAhIE68ns6da64j5UYyQlmkXnwR852tp0yk/vxTKcD0e2jWDEqCM87A2Lr0UsxLmTTDyxWKz/fCC3CL1d2tiJwEmeuNud1jqLVbJ1Im4d5kkbrkEpDGqlXhPu+XSOl7LmPKFKxtV1yB5+LHIqW/d4PsZz9jzs3axGtuRoY6pnhx9IFbXKMJbpk3w8E118DNn8H9UKwYPAKeeCL4NxzvpBc953tJS8O+Wa+ee1IYuR4mJKg5dPXVyvOmIMESKQsiwgLGpMFrYkqXM71+0+rVEPTZCmGySBE5hX0pwM6bpwRbiQ8/hBVl8WJnhigilQEuVhapJUtgGZMuS507w4+8XTu12Y4Zg2QQpUura+nF8nSY/MarVgWhGTIE5zcJNocPQwjduRNElTWJvJFmZ+P7jRv9ESlT+nNJpI4dC6735Qd8rp49YaHat08RqZ9/BoHT2+OG6dOhEeY6E0TeROrWW/Es2KKnt91NQDBlpNy4ERaAHj1UrMHs2U4rhh7fVqgQNHm9ejkTP6Sk4JnqRMqtD5i4cYKXvXvRj7L9pjg8v+RUEik+Z3w8nt2oUej3LVuCf+dmkZLEXydSunutiRAw7rlHWTn8jDe358op7f1ojL3w/fdYvy68MDSR8irIGwomy4F+/yZB2VQ8OJQ7s9+MdwcPYl4w8fUS7uLiIACfdRbG1OTJ6vw8DurXx5qlZ/SUbalRA33O6/9ZZ6nrcvzK3387r819Fq3SrFUrKEA4W23fvs51NBwiJWufMUwCdVwcrAnNm4Mw1qzpPKZ7d7i4vfoq3FATExHb2KABCLMk+F4WKSIoeGQ6azeULeueKCUUkTr/fGfiHpNFShZCJ0L7W7bEGsd19vwSKY4Lvekm5+elSmEf8DMP5THhEik/cUN6GyZORHtbtUJ/rV1rVi74RbTWO4abEscNPC/dFMh8L5MnB2fwY0gilZKi5lAsEo7kBSyRsiAiuHBxhrJQVhGG23GsJTVZpMaMcRafk4uNrHStY8UKaJ051SsHdfMGVKiQU5MR6eKybp2KzWEcPRp8r61bB7uW8TFuizgTqTvuUMVLL7zQmSXR1KezZmGD1mOkChVSmuEzz0Q8jWlz1TWmvBDKGhS6wKBbG72QmQmL3bx56rPff8fnLNyNGKEWSVNRUx0LFkDrLFPJ6wIl39fRo+6ZyvieHnjAWaeG8d//YkxLtzgu+JyZ6RQIZJ/weVlpcPgwNM7Fi4OIsAtnSgpixjgrFAfv3ncfXB5k2lciRaQ4fu6SSyDcTJ+O+VGlirMsgN4XoSCJlNyIJUk0bept2qhMim7jQSdS06crKwmRt5vR/fcrpUg42t5//oFFe/RoKCPWrIFiQs84Fy6Sk7GO7d2LGBTpbqL3dayI1Ouvo5+5qKnXOSMhUnyenTth0b7xRvNxP//sFHql5WLHDsxNfq7VqoHorF4N4Sg+Xinbtm7Fq7TuEDnHF7+fNg1zhIv/yngKt8QDsXLtY7Drbdu2zjpSfP4rroDXgK4Q4/FQubIzQynDKx6qTRvM9Y8+Cv5dfDz25cxMKBxzctDHtWqhz72IVJUqzgQTbgSIY0qHDcOz1cceIxSRSkxUa0hcnPm4Bg2QJp5hWmf8koPu3eH26zbP770XpMUr1ioai5SXUoihP5dly5x1r6T88+yz2BN0RbEXmPhLmSxcfP01CDsR+nzBAsz9jh3h7inXb9luomDFQtGicL/95Rdkb33+efPc7drVGd+VkqLGy6ZNkce35yUskbIgIu+CvLJ2hFxA3IgUB7KbLFLffafeJyb6z9DC5Iwnse7WkJSE5BZ64HC4MC2oR48Ga6ASE+EDffvtEEyIvIsArluHZBlEWHB4Y0pNxXe//QaNnknTxW366y9kC2QrTYMGiKXgxAg5OWbhghepyy+HRU3WkZLuMdxnTZsiOx4jlHC4ZQs2bd1Skp2NhXn2bJUI4IsvECMXCtyWceNUpjZ9c2aBPSdHjTndMtmxI4SKRYuCCTIRrEerVztjeaTmXm7E8tm0aAGNGz9TIoxtVkbI8blmDa5/zjlqY0lJgQZeuqwSKSI1cyYIE2vok5NVEDxD3qtfixTH6kiLlMyap98no3RpxGuNG4caNQx24alTR7WBn8uMGc4kGKGEj3BctXh8b9gAMvzss3BvmzsXArzfTFNukEk56tdX2SjPO89ZKFxvb7hEqmJFxOFcfjnGoR436XZOLyJ11VVwJVu61HyevXvhlqO75jBknMaddzr///BDzHW5Puh47TVYiEeMwP+rV0Ng8yJSurVKlp44+2z1ftkyjLnKlWNHpObPxxrK/ZWYaHbtI3K6QzMaNsT+JGt6SbgRqREjQGDcgvCJlHV71ixYp9htfutWb9e+227Dfek12XSMGYNzc/yxG0LFSBGp8ZeWZp5/N9yAGOnzz8eYiovD85wzB32XkeGfSJ1xBtZ2vebl6NFwaX35ZZAWL0tc//4qNsjPmiP7cNiw0Mfrz1230iUkgDx99RX24pdeCra6eoGthzKxVLgYNAhKRiIVO7lwIfayunWDrYhEyhLF3jmMK67A/nTddXAVXbAg+Lf//S/2PBnzKYnUn3+qBDUFCXlKpEaPHk0NGzakYsWKUbFixahVq1b0/fffn/g+MzOTBg0aRKVKlaIiRYpQ9+7daYeWDmbTpk3UsWNHKlSoEJUtW5aGDBlCx0IVQ7AIglz4dILEE7ZIEeeCK4/LycGGUr++ihcwESndZYw3UL2uBhf3ZLCgrBMpPQ1oSgo+i5RImX43c6bTbYGP+/NP5yLGJNEk+MhA1aJF1cY0diw2gxYtoBni5AK8wMvz7d/v9FnWXVtycpyaVEaXLki28OijsH6Fcu0jclamDyUcugkyOTlYiC+4QAn9fuu/mJKXTJyITXfJEpCTkiUR2P7QQ0pLrFuknnhCESi/wbNyw+TNT98EK1SAZk1qfTmrJBHmwfHjEHi4f1q3VsWN165F1jndCnv++bCwrFrlTKsv058z5L36tUjVqQMidO+9zmfvpUhhVKkCDXbXruqzMmXwHIYMUffZq5dKViP7zYvcHD3qjCEJBb0kgCzI61aCIBwwQeTzsytKSop7ooDUVFUuwS8aNIA1YsQI97nh5dpXsaJ6HizILlgArbCu8dezarn1MxOnYsUgvMt548cVqX59uPFyUWMiEBU/ROq77yCQyQD1226DtXL6dLT5yBFYgKtVg8XWT8Y1L4waBSGf13hZT0lXMhCZC+4WLepOVnis3nkn1oQ+ffD/U0/BPdxL2Od5/fXXzjIHBw+GrtHFCUWI3NuWkgKviFBrfIkS2M/d1pmMDKVsCKXU+flnKJzatkUa7PPPh2fJ6NHRu6t9952zLqIXyeZSK6GOM53LKzEPQ/Zp+/ZmS3azZrDCsldKJFnywqmppkOOC1lHimHaC/g5y8RZEiyr6cqeli1Vv519tlLqpaY6+8Zm7QsTlStXppEjR1KtWrUoEAjQ+PHjqWvXrrRo0SKqX78+3XvvvfTtt9/ShAkTqHjx4nTHHXdQt27daM7/R0Pn5ORQx44dqXz58vTrr7/Stm3b6Oabb6akpCR6WlYqtQgJL0FKBjWyS5rpN6zR++MP/K8X9uVzEMFn/uKLnfWOJJo3d7oZ6BYpTkOqawH37jVvfn7B52/cGEI4u5rokHEY9eo5TfKhCvKyCxOD700mJfATo6RvOjk5cNdp0sTpiiSD8YnMrn0JCbiHEiUgqEjrgV8ixUJOejpImhSYZP0XPzDdv6kWCo9HLl6qW6SIvF1NTZD3y8K/Wx/o50xIAHHMykJQfJky5oQCHAOl1+2qVg3k8KmnnJkDk5PNrhSsV/K7+VSpogo989zT54qJ8GzbBuJXtCgSBDBkKm1G/foQcH/80blBdusGi6TJMvjf/yIwvndv96QsEvw8mOjIgryc0TCa7E+SlH36qRpfpqB9Hp9PPhmcXS8c8NyoXBmKDC4f4WWR2rUrOCbNLf15mzYQyA8eBHEIRaQOHHAW2ZZt4bm9ejVcqCpUMNfQqlEDsVZJSVizW7VSBXJzcpylH4hgmZMJfYhw/aeewnte748exT3ccIP5HsKB3g+ffurMfnr22bAacdysm7Ltrruw9rKrlGw/kSpAyvOLz3PmmRj348YFn5fnj16u4OBB9NPUqe6Z3uRaG2p9WLEClpyyZVXtL4lQdZbi41W8qSkduxv09Odffok5F27GOIY+V0IRpLJlYfn3U0Q7Lk55BvhR1nBbSpeGLCMThRA5x1Ek8X5+Yx79nOPhh6Hk80Ok+N7dyDmP1bJlVbxt/fpQ7hw9ijl/yy1QuP37L+5dJlcqiHWk8pRIddak1KeeeopGjx5N8+bNo8qVK9Pbb79NH330EbX9/3Rg48aNo7p169K8efOoZcuWNHXqVFqxYgX9+OOPVK5cOWrcuDE98cQT9OCDD9Lw4cMp2eWJZGVlUZaYCQf0vJynIeSE4SKSDBbW5GLetq1z0vMGEQjAjcstqw4vHgMGgKzwI5KxMETQUN19N4Sx5cuDLVIMmZq7Th1oSebMUbFU4UJad7wmtCRStWuDgPz6KwQuWVCV4VaJXiI5GZqrKlWcwcdui+v330P4lETq0kvxp2PxYrg61K6tYgEOHcImfsMNcOeT9/vtt4jZ6NzZTE4kZA0xrvl06BBcHidOxOLM5+7VC4KiXjhXRzgxWnwvRMFtzc5WmuZILFJuRGrnTozZwoVh6WNykpgIF7M9ezBvypRRz2/MGFU4mOO1ZFITef1//3UKPykpwZs3C8qlSjmTcoQD1jRLmIjUxo2qUO455yiXmsOHYQEpVAgJRhjSzYdRsSLGtclSzbFif/zhb660bg2rxV9/gcBIixRRsAU5XEji/+yzKsW67i5H5C/VtBsCAWU5YMF38GBYLZYvx/j1IlLZ2Sp19fPPw02I10qdSFWqhD/WJLsRKRnDuHo1hCCGTqQOHsTzZ3IkUbYsSPd//4vfnXmmMxmDFAD9ukRGE5zvBlM/XH45CMq550IpsH+/6hf9+MOHsebv329OzMHzX2+zPI8pwQuRN5GqWNGZ2EZizBinW20o4fTwYRWDGQlSU9X+36WL/9/p6c/9xM96IRwitXYtPAbuv9+/JXniRIz3lStD91V6OpQHvN7pZDYxEeRz+XK1roSjAGY376ZNoy/Ke9FFkD30+D9Te/gYfZ9YskS5lBKpNap1a7gEL1+O/a9SJbQ9KUm5SUsFVUG0SOWbGKmcnBz65JNPKCMjg1q1akULFy6k7OxsaicKGtWpU4eqVq1Kc//fB2Tu3Ll09tlnUznhtN6hQwc6cOAALZfp5TSMGDGCihcvfuKvSqSrxykEmShBjwFgzfg556iF6f333bNXeQkUUugmMtdXueMOaCgqVVLuDLpFiqHXopHtjQTSeqD3g7yOdEs8elT1hZ7xjmFKB6vXCEpKgqvPjTeq2ilE5s1g3DgQpt271cLm5tG6bRuErBdeQFxE8+ZY2J56CoTmww9VP/NzeeopPId160LHm3D7AgFnbZp//oHb3SOPOMeKV0wAwxR38umnIC1XX63idDZtgjDN59QFmU6dlA+4XyIlr80B8xz7xPjrL2jiH3jAqRFOTFRj+oILYH2U55PuOV5ITnb6/0vXvlKlVMxdkyZwgw2nOONff0E7WLEiLLi6X75JC6kXb2Rs2oRNmJNpEMECwe410iL16qsQXvRMW0RK8bF0abDQaELNmiDlHL+px1tGq9WUFqlQQnvbtnBlLFo0fDebBQvQ1rPOcsa8FC+uUpqb5n9aGuKQiKAk+eUXCFQzZ6pj3LLthXKfktdr0MD5nU5kQsW1ecXxJCbC5fjNN/2RZ3ke1mzHAqa2X3wx1q5LLsH/ck8zHc9j1rT3XXQR1tPFi5EJlJPyyPO49R/3iz4n3Arjyu/lMX69CiItbhwXp5RYofbfhx/GnJk6NdgiFS3CIVIjRuDZ6MXXvTBnDtY/GevthooVobxkF22TvPTRR043/lglTvEL3VNEFqYnMu8FnCpfROEQEcg4kygip/txtWpqDJtkIelBUBAtUnlOpJYuXUpFihShlJQUGjBgAE2aNInq1atH27dvp+TkZCqhqSjKlStH2/9f3bh9+3YHieLv+Ts3PPzww7R///4Tf//8809sb6oAgieMKSBcEiQ/xw0ZgjgPUyFX/v2MGdDYP/KI03pUtixcf154AULqxRfDfYXdRnihYQFNJyNE0KxE6jfM51+5Eq5IbBlq0wZkZOtWaNsrVVKL9rffKgHGzeSva+aJgvvQbQHRN4eWLeEKwmnQeYHOyYEg+ssvKgEGEYKJP/xQnatyZVihOF6H8eijqv18TT/ZieTi36MHrl26tNMqIe/NTzyPiUi98grcLb/4QtVfqVsXWawuugj3pLtoyLa5pePXIYlj9+4Qph591Hze7GznNRMTFQHftw9xHbINPP779sWrLNioo3Fj9V4SqWLF4DLVsSM0mvxs/eKyy0DyODMggwVveV15fdP7V1/Fq4zzmDNHWbHluP/mG2juX345+PycjCQQCM9dSwryUlCJNv15Who29ksuUQLe448H9xkR0c03w2I1cKB7wgE3yLVVrh2HDoV2H2LLd5Mm0Prq1lj9/+3b4XbGrluRuD/rRMrLJenwYRWQnpSENfV//1OfJSbC8ta/v//nJcfeww9j7kliHwl4XjExNd2LF5GS4860XrZuDYVKSgo8Flg5Y1oXdNSqBS2+3iZOUf/mm1jvdXAba9RAQiK/yjCTMm7NGqyz/ft7n4OJmyTzJixZgmO2bg0mUiNGQIHHhZzDhd5Pfgrybt6s4nBDIdwEJxs2YB5WrOgcJ08+if3IrdbUyQLPp1GjoGSNi3MqHL3ao3+n3wsTqawsKEwuvBD/lyiB/Zu9mJhossxmLVIRoHbt2rR48WKaP38+3X777dSrVy9aEU4OyAiQkpJyIsEF/53uKFQIi26VKsHaLrnZ84J85EiwRpAXl08+gTuHSWPI5/rqK+XOxwJDmzYqGxRvSEeOqJSvDz+sNjsOMJZxM7HQ5jRtqlxf1q9XC+eAAXC5kS6LJuLTuzeIlQ6ZRpfvTTeaugkTZcog7oPvWdceli0LIe6WW4gefBBCstSY6XWkJI4dQ//n5DjdK9nCw7FoXpD9/sUXIG67dikSmpbmJLx+FsoePVRQK7fZVBCRP3v1VRAKPV5Ati2cad60KV7POgvupbqwxm3auDFYoyitrHpyAhaYXnsNAq2XNlQSmmLFQHQaNFBFeIkgkNx/v3sGNhNkfI3EokWwgJjcXNzqSJmWajne5Ps1a5Cx6fffvdvnR9u7c6dTgZGY6LTARKvVLFYMrk4//qjm6yWXOLPJSYQK/HeDXFuTkrAO33cfrFsvvOD9W56jrCCQVgsZm8dYuRLrEysFvIQkTv4TqlaMl3Vr2zaloU5KQn/edlt0WcZk//77L/ogmmB7ItV26Y2wfj2Iyo4d2HNYOSJjnPTfE3krnvS+8mORGjcOliwWQmvVwppcrx7G/4ABzpTaDF5nmjd3Zt11gxeR+v13uI+a3FpNCFV6QHpy6ETq008hWEeq2w7HIsXfjRpldoc3gctk6LGtJgQCsM4dPozX7t2x5h46BPmoaNHwY7ok3MInwgGvk1OmQHYgcoZ2eJXC0cesvubeeiueZ4kSCBNgFC/ulA0nTcJrqBT7+Rl5TqSSk5OpZs2a1LRpUxoxYgQ1atSIXnnlFSpfvjwdPXqU9ml+QDt27KDy/6++LF++fFAWP/6fj7Hwh+LFMcH//jvY1Ye1sMuXq8Fuql2gbwwmE+5zz6mJqgeMDx2KmBxZpPfuu/FaowasXIMHO38r3W7kBIyUVKWlYbPic+mBwRJuQpNb7QrepHhD1TO2uQl/FStiIWKSuWYNNlEmYhUrYjMYOTK4ZguRs1+Sk9HfkyfDreDFFyHs9utnFgi06WVESorTYsPnkRap1q0VsfJjkSpZEhaBs89WmX7kfehEyk2Y4nFwyy348wu3mCv9vDoSEpwuoSkpiC1ics4bU6FC2Fi9yF2PHnBxzc6GMqFBAwgzXbrA7WjJEgiqL7wQnIrWC0ykZs+GSxrXkqlZEzEspnEtPwtFUqQVSlo9OY7MzYLGLiN6Bk8Tfv8dbpuff455NGYM1gcmmbF0DzFlCJXIyFACYbhESipFvvgC5+Ln8d//egvBnEp/5kxY+ZiAPvaY08WGwW0780y4Srsl+iFSbdAz4tWvj7nOmee8XPv0JBX6mn3kCNo8fbp7O3Rwlrl27dR5otXim4jNI48go9q774KgBgKwiIeyEpqI1J49UFLosWl+iBSDrztwIIhT167+CvL6ddXzIlKcRMKUCtuEUC6XMg2/RGZm9Fn7+Nx33w23dy+XZ9lv4V7PT4HjvXudqfvT0rCOyz2F23DppVB06K60XuAC9zI2NVw89BDIOJEaA4sWQUF4333ee6ZOsmR//vQT5KisLCQk4jIeRJA19fIsGzcqOTMcN/X8gjwnUjqOHz9OWVlZ1LRpU0pKSqLpYpVdvXo1bdq0iVr9f2Ryq1ataOnSpbRT+DFNmzaNihUrRvXY78nCN3gRc8vap0PXzMlQs2LFzO4EZcuq4xITEWvFhCAlBSlzZQDt7t1IUaoXIeUAaw4C598zvDQpfsAbCmueVqyA4Nm6NQS4w4fhImUSAtyE7CeeQCFM02L56KPOoG4T2rVDTMU556AN77yDz+UmYHI90C1Shw7BLahnTyUkyvTnn33mLMIZCklJEN6YIJuIFFH4Gqe77kIyBtaUeVmkduwwkym+p0aNwgukfuMNaNPclhHTM77jDmiAdYtUXJyaQ+HUNypXDmNCv9YnnxA98wwysD38sLqOXzCRWr0a4/f/k6B6QvZ9KLLAz7t+fWfmvFCxT8OHgxj5cVXkPilWDNfgeDKvmJxIwQKr2zllFs5ILVJSgJXz2cvFaexY9Z4TgRDBVVqmHtfblpOD+e3l6uqW+a9uXcx1JlJegq/87JZbgonU9u1wT3XLjGpCcjIs3tOmqTEfrSdCz54Q9mS5AXZLl3WkOJmOF0zE5fPPMT5Z+OZ+mTxZufiG2q+GDoXHgKmgrReRmjDBmUreDaEsUkTKSh8KoYiUjKkdMQLn7dkTe2u0ROrxx6EIfvxxxJJ6nSfcgrwS4Rbk5eOPHwcxXbzYmdCqcmUky/IbK0gUfV8RQWl17bXB7a1aFQo63aWdSJVG0WUy/n3RolAAJSWZ40tLlAhW9HI/xMe777n5GXlKpB5++GGaPXs2/f3337R06VJ6+OGH6aeffqKePXtS8eLFqV+/fnTffffRzJkzaeHChdSnTx9q1aoVtfz/SPz27dtTvXr16KabbqIlS5bQDz/8QI888ggNGjSIUgqifTAPEQiohA76os6++HXqeLvdLFumasF4bdJS2JfZWpYuDV7Is7KgbR41Cm5H7F/ObWUyQRQbk/COHRBO5YZYuDCE1zZtkJnv22/RX4ULK/N6yZKqnovbZvvIIziPrEFx++1YWB97zJ1I5eSgXUeOQCvIRIyFxrg4fL9tm7mOlE6kpHDE/SiJVE6Ov43C1E4iaE0vukhZ3NLSQETZXcPPc/rzTwgP8vlKQVYvNNmunVmT5SUgeKFtW1iEuH6Q23kZnTrBXe+yy1S8j2wf92e0BJ9ICbnS4hsJkeIwUj9CRCQWqXAr1CckwErn1ucSbs81lPUoHJxxBlxFuZ/czinJcTSufQz5PLz62k0T7bb2hpPxbv16vMpYSxMSEiCwmrKt8X3ExTktnXz9SN0hGZGkjDaheXMkQGEF3pAhap5Kl2w/a4hX1j4GP/NzzkEM8JlnurtpPfooNPszZsBqUb06xvihQ95KA7nO+Ikh431Bb//x48qaEIpIscKrR4/Q1+LXhx4CUfvgA+yF0ZKD0qXhmuzHjVuOu3DHkJ9EJ/Kcx4/DU6VvX+zh55wDsh5NFspYECmi8OO+eKzqdaL0e1mzxpk5kmGySPH+dfx4+Ht1fkCeEqmdO3fSzTffTLVr16ZLLrmEFixYQD/88ANd+v8Oqy+99BJ16tSJunfvThdeeCGVL1+eJk6ceOL3CQkJ9M0331BCQgK1atWKbrzxRrr55pvpcfYhsfANWeBPH8g1akBQX7IEmn0i90nHWme3hezLLxXZ0jNtmRJHSKGgVi2lPeHsZ9ddp77ntkWDPXuC62BkZ7sXZZQBkn4Fg/ffV7Fdl18eXJ1dx44dEM51i0/x4liUixXD91Wr+nPtk3E77DmrCwzhEqmVKxVRWrQIWmP+Py3N6cfvx7Vv+XIE5MrfeVmkiMxWNL6np58OXQslHOjP+JtvMBb374f2nWuGpKRACOrWDf9HQ6TWrIEyg62wMsmF34K8RGoDZBdaPxtxeroSpPxapNavd6Y35tgY6S8fKfi5LlsGl6svv0TcZZ06sBDFYi3Yuxd/b7wB65+pLh6RU6iKhkjdfTeSj0gru9f5Jk6EIPrkk87zua29fK4tWyDQsSulCZyRSy+6efgwlCJz58Id59xzoQybPTv4HHo2T7eMf5ESqXAFwFDg59izpyLHsibhkCHKEqejVi28yjqLDK+EAjfeCAWh25zYswffM6H94AOsKd27e+83UhnhxzpbqRJkgFdfxbhgK/Xatfg8LS104WPeZ0KVy/AiD7EgB9nZWIMHDPDOBBiNRcqPy6Rukdq501ljTGb+/eADKA5NdercwGEObqEEfrB4sapXx30wciRiQR97zOza76ZY4HGWmQkZZ+NGZYWVY1BPnpKS4ty/wlXA5QfkKZF6++236e+//6asrCzauXMn/fjjjydIFBFRamoqjRo1iv7991/KyMigiRMnBsU+VatWjb777js6fPgw7dq1i55//nlKPNk5JE8BhHI5KlsWkyGUZp0FJzet6I8/qvc6kTJBFwr0mhxysWJfX1Nsll+YFvCjR80Bxn//DfczItxHOBpWXuBTUuCmuHy5OcshkXPhGjkSQh0RSNiCBWoTzskJ7do3bBjuhUkHE6mEBNX+m25S2kW/lg6ZGIGvd+mliN948kl1ngEDlNDhBX4OM2eqVNqhiJSp2jxr7XftijyA2YQyZeCCJl3XPv1UkTVJsDduxDOOjw8v1a6O7GxnXIskUtFYpPwILcnJGGevvw4hjiFjABjSPYXjeIiQaGDfPiROiRZyfN9zD8jOli1wVVy5MjbZr7hPzz8fFke3dOJS6RCuS2HRooh569QJwuv33zvLA3idr3JluEZxvOoFF2CMmOJXiZzr0rhx5sKrjIkTsQ789JPz80WLYDk/7zwodrysFPIZLFoUO4tUrVqwgLF7d7Tb/apVIOGsWEhMdK6j8vxCj+vAL7+A9LDbk4SbRWr8eGQv02OSJXgt/fBDxMSwoC0Vn6b+695d7bXhrA2TJyNV+6+/4v8FC/DauHHofub9K9T+yxaI/fuhNNi4EZ4nGRnRE6lp04juvJPo7bexb3gpBC+9VHl3+L0e7zFXXx36WD3m2JT+vEMHxCoTYZ/0UxqEwXtuNHaDl15SCi5+vps3wzto+HBYTP2iQgWlgHnxRefaxWtns2bIcqoremXfeFQuyrfIdzFSFnkDSYy8SBVr2k3xKN26KbO+G5GSi4vUyOgTlrVaF13kbA9PdpNbQyy0WXKzkKZrWXmbr7Ftm9LEbtqERZwoPCL1zjvQ9DVo4AzIdGvTww+ruAneJPh+AwHVL/I3FStC0zhunHJ/44WNLYgJCc5+5gKpfuOKdA0TEVx+LroIFrdQSSF0yGfIm8uQIbD8fPONEhKkRdKUbe6OO9Rz9Jv+3A8KF0aabr34JGukBw+GYDF6tOqbSy+FC2Kk0Md1pBapJk2w+XJGRr+CaMuWIEEXXKA+q18fz/b669Vn0sVSb1esnoEpzTGPu2izuDF4zIZKMBBN/aqyZWFN++QTJbyHm8ZdulKassq5ncvrudeogbghnSjr5/DShsvzz5jhTqTCJUL79mHdqlIFY9KtKK1fvP++cssmApngRAgyRorIfW8pWxZWW9O98GctW4IAsfLlxRehsPLqQ2ndve02FbN78GDoeEAet+GMSS7szbX3ChWClVfOeTewgo/JlxtGj8b+16IFiHj16lgn2rSJfg+fO1cp3oi8x9aFFyqrjt8xyFY5U/1LHXIeNmliJlK1a2PtZPIZzn3L7IeRwhT7Ktdok8L8iSeQCMdUpoLlieLFnfdbtixkHE44Jeesntm2INpBLJGyICL/Lkcvvuj+3eLFeH3zTbhSmSAnTK1aaiLrPsfs+laxotMqxZOMF0uZraxmTZALvXhqOOD2paW5pziNi0N/yUWoU6fgNrrh5ZeVy8ynn6rP3YQmt/OZNp077kDfS6tPiRLQ0nEmLiIzkXr/ffU9kzS/ixoft2CB0vJJ1w2/QilDjkfulwYNEJzesaO6xsMPw7eeyL06fSh302hQtaqTHLGA0749xvDx4+aEApFAn6OSSIWj1W/QAG4k7CbrZ/MOBIjeeguWH+l6MWAAnilrVYkwturUwftwgqfDgcldijfub7/1XxfGC3y+N96A9cBt7LLSZ+DA6IQAHh9NmiiLsR8hmPs4VEHT8uVhEWWLYDR1pCQuvlgJpBKSRKelIS5k0iRVRyxSixT3yX/+A8FZKlMigd4PjzwCKwkRnmfVqqqNbn326qsgSjJhBYPHBKfo5//5XO3bu8cx6YoIdtk7dAjeEJMmqRhmHeHU5TlyBB4OOrp1gyunH6vHSy8hUQDX+AsFznTJ/ZCZCUvYunVmS7cfhJtOvGZNuGv6TX8erkKQCdJHHwU/B7meR+Kmym2JJL5KP8fZZysX4VBEqk4dHKvXbCRyJ1Jt2iAWnPeJDh2wRv/1F0gZEcI1rr7af1KT/IQCyP0scgNywnhpjePiIFSZ/KV5Qaxf330h5GMGD4bgy1XedReSLl2gFa1dG+3hCaovNHJBGzsWwkznzsrvN1xINzo3IYbvgRftcuXg6vLNN6h9pFspdGzebP7c7Xpui+s770BolCmmb77ZvHF++y3Rb7/h2IsvVkSqalWY5M8+2+nbfuwYNIeyWLIXuI1Fiqjrcz2ppk3VYv/hh7CMhRKeTAV53cBCj4lIZWWpMRJLIpWdjecdHw8yz/efmYn2zp0L4WTHDvXd9OnIiBgqGNsNXkSKSVG4SEryJ6zHxamCnOeeGzrlLgv14VjKwkGVKnAz/PhjuMRJ6zZRbAKWuV/GjcPflVea51a4qabdIF1rr70WAp6fWjFMpJYtQ+yTTNAiUbgwSEeJEhD4Y0WkfvrJLHAlJUHp8e23ECjLlfOfdc5PG2JleTS1/Zpr0K9nn43n0bEjYjvc+uyBB7DWpKYGu666xZTIdd3N7diNSB08CNcuU/FsIiSFYoLl1yLlVkIhLs4fGbv8cjMZc0NGBl5Ll8Y6mZkZfeprOZZY4emGXbvQv//5j7KUhMLHH0P+8Rs+cNVVGKepqc62SA+Qdeuc2XP9gmsHDh6sYsbDBY+Njh2VV5CU/8Jpz7FjsJoSBSuaH3kE82fdOlinzz8f65BMUhOqbl5+hiVSFkTknORusQBE2Ni3bnVqoBl+BAq+jluqdSJoK2RRP5NF6ttv4csthQZOt+kWa+QH0nrgVSuIr0eEa/JGk5wceuPizbFrV7j1MNwEitRUXJP7rE4dWJ6mT4dGUmrfTX1//DiC0pctw31dfDEsEgcOgFjx5iXP8+KLiE96/333IqQSUljg+5gwAZvVkCHOxdmP1s1k6v/9d9zvb79BU3r77bgHrpljIlK8sBOFl9I9FI4eVQkkDh1Cfz31lKrYzlab//3PSToGD46cSMk+WbwYAkjt2uhvvRCxFw4fxoZWo0Zkwuh773kTqUBAxX2Ek+49HJQurQTWOXPQNyYrZjTQhUe3c9avjzllSjkeCnv3gmDk5Kh5mJgIVyq/yVHq1cN8fuIJc9IHHdG4T4VSLunwIktnnglLTrgKjnCtAqFgavt11znrJoXqM7ZW/vVX8HdnnQVh/cUXQY6HDYM7m6lQtw4vIuUFzuxJ5I9ImVxld+7EHChaNDbZRhkffggXQnZpLFlSEaloodcu88LHHyPBS48eTs8QL4Q7VmWyJI5JJXI++xEj1PtwLFKRZNbVYZpLktyE89zlPcm4p6JFsbbt24f1IFQykoII69pnQUTOCeM1Qfk40zE8kUaMcHev42Pmz4dA17at+o4n3ujRzt9MmaKK0fJCc8UVEKC4ACeRyjATTnFSHTLTVNOmEDaJoOl9/HG45MkaI0TITPPtt3jvx3WNN0ed9LhtePHxzngtjlVp3Tr4dwsXIoBXksnjx1WMFwv4XbogY5TUAL79tnrP9+Z3sebn2rs3rp2WpjbGtDSn66Yf4dpkkfrqK7gt/vijcg/q2VONNVOQvRQoYpGAgCE3vOxs1PHZtSu4RtiPPzqPjUYg4d+mpkK7l5aGQPmlS8PbnJYsATmWcSGxhHy+sv9zA9IlRvZtLOpInX22c0y5CWaNGkHp8NRT4V8jPh7j5/hxtXYkJqpMd35QogTWBCJvb4LsbGedrlhZpIjcBcBfflHv9+7FtSdMwP+VKsHluFevyNpw7bVYv/h8kYL7oV8/ZZnQSZpf8ml6ZnXqYGyULImaTjLBj94GHaVLO60lpUqp9n3/PQR1TlUvIeeCzOroBv36aWnYm0uUwNiOJdasgTWfE+ew4J6ZCYXAAw9gLY0E4aQ0l4WB/bqch4uff8befdFFTsWMdIXl51OqVHgxpLHYz3idfPddVa4klGufG+S6X6iQM2Z13TpFJEuUwL7I8Zx+6hjmd1giZUFEmDBXX43NyWsB8iJSLCxPmeK+MPHknzsXGik+LiEBNTOeeCJ4MalUCYv6XXd5uw7EIm1myZLKSrRypdpAb7sNi3ytWqoP5KLN2ck+/9yZWc0EXmDYJY3hpUHjxABEznpPRBCse/eGINC5MwigTFus17Nwg3Sv5BTMbrFuOvgaCxdCWDp8WGU2Sk0NneJdR6tWijxyv3hl7XvjDZUeXiK3UqnKZ1WyJLIpmgjivn3+NM9+kJwMq4e0fLz5JpQMnMHM73mIck94IAJRK1TInMUsFsjMxHjlBC96spRYEKn33lPCBZH7uhhNPSQ5Nng+v/wyxolbqm0TQmVLJYJAc801KnNkLImU27lYobNvHyxsN96oMp1GCn62W7ciU2O041h6SfD9rVqFv4wMpNdnC2yo+Wsqts5g0s995YdIXXcd9km2OJcujTX++uuxNt90k1kQ5fOdd15oN1wi833xmIp1bKk+hiSRevVVoueeCy97ndu5QxEp/n7aNOyduYHMTGRa/PdfzM0NGzBupdKlfHkkrlqyJLwMi+EUmHcDz6V//1WuddJlPFKylpYGS/vjj0NhJ7M1Fy/ulEMWLozsGvkJlkhZEBGEkAkTYHL3WjjZ3cS0OMuaA1qW+hOQ/uOJiWoTTElBBqOBA82b9QUXYEPjSvAmxCIeIzFRFcbV0+DqcBPWQmnTWOBbutT5uZcg9vzzyiq3fTu0hH/+if9TUhDDMXasapPbuVhYW7wYFp527XBvI0Y4+4/T7IYihQxOPU+k+opJTFqaqsGjF/FzQ/Hi8NuuUUMJh15Eys3Nh5/lOef4u65fxMc7BXc9/oE1js8+iyK906fj/2hc3SpUAGHv2lUFtb/zDgLVw6klwn22eTPO9cQTkbfJDQsXYgzllhvHrl1wp/v2WyhuhgxRmSbj4mJnfZSZ5dyeHVteI4mRku1cvx4CBgdbv/eeyp7mhawslU3Vy31VrgmrViE7XbgoVsycWCJUf8fFBWft27kTcZR6RtRQaNgQz5pjw6J91vz748fV3OjXD3HAv/yihPobbwxesxmLFuE348YFf3fkCBRbvC/w9fxkA2TwPlm4MNbtjz5yFrZ1u6dwxqQc3xkZzsQBsYTeXhbcMzOjz9rH527UKPS4iqYgr1+0b4/XpUuxZ1SvjnVcX0vKlzeX7/DC3XfjNVJXcSJ49ui1QVu0gHzQv3/kXgtXXYW5tHkzYrl4/yPCGmLK8luQYYmURcwgi2+6ae7KlVMaqKQkZfk4fBjCYKlSwbEukycjJmjSJO/r9+uH34ejyTVBkqctW/B++XK4I7RrR3TrrfisTBm4phA5/YpDaaZNAln//qE1f336QPCoXBkWOpOLTqjsP6wJevFFLJLTp6vNi0kOE7Zw8NBD6j23RxIpSZj9Ytw4uARwgLr8LY8vDlh286/nPvWjlQ0Xso91Uv3cc1AsdOuG45ikRhtrsH49rF9c++O33/DKBTv9QPbjV1+phC+xRGJi7mXsI1JzLD4eMZWNGjktQ7GKzWKC7jWnX3kFryx4hgM5hnJy0G75mR+CfPSoGgde80veQ3q6f6WGRLFiUOrs3QvLGVuaQwm+TZoEE6mZM+HyxGuoX4wfj+xunNk1WiH40kuxHr73HqwCEjL9eWqqO1Ft3BiKLJMwvGiR0wWd++r55xX5D7UufP45aljJ5CNellDpQi/dK73Aa1SNGhCwc9siVbo0sq527Yo1/uqrg6124eLKK9VeHcpiE01B3kiRlQVPF5M7ZriIRbmXpk2VNU72QaNG8HZ4+OHwzseWU05vzuvnOecg3fz11wfXZsuthEQnEzbZhEVYeOstEAlT1pp33kHWOBn3ZIIU9qUmn92TdFeNX3+FBv7ff0Fk3Daz0qVhrYlmYcnJUalos7OJpk5F+te33lJuPuXKqfaz/3qHDvh+69bQREp+/9VXEMLbtvX+3fHj6PN69YIzJiYkIBYlJ8cZZ+F2HqJgwT8hwT27lB9IzeeXX4L0fvcd/k9LU8Uu3TIW6ti8GYkuSpRQ6c1NFimuXfLQQ6qIsEQ09xQKnNxEbxsRBGJZayRUIWu/4Jgj3dITTuCx3taCWLeD23z8OP7i40PX1QkXAweqeE2vc0YT9G1SgoSTsZLISVi92smWupyc6FImE2Fe3n03iNu997oTuBIlYNEpVSp2daQYkaSMNqFxY5AHznw2ahQUd4EAEi9FW77AlMiBCMJlx45w93Kz+ixYACVbtWpOC+KxY0p5ZHrmcp15/31n4XCvdiYmEv3wA/Y4JlC5RaTatlWu45x1lO8l0j28ZElzWm4T8oJI9eiBPT8+Pvosn7EgUkTRz0MJmZI9EEDsFRHaOmuWOk4vyFvQYS1SFmGB3U6kBYbhlYaa8euvShhMTITGvlMnaNk5XauedY83mY8/NgvLEl4uOH7BMQRHj0JbeffdznPKhUvW6vAbK8Hm8pQU+Lt36BD6N08/DQ3yQw85r1+3LrSUpUvjmXDfhao9ZarDo8dehQNJkLZuVSSKCIJeuBnz/vkHma64wC2RmUhxFis37Tr7X8v2xApeFimJNWugYCCKjkjt26fGjm7tCee8psKQ4cArDuRkQfb9m28i5vKMM6BF12MPI8W//+K1TRuzyxYjGiIln1uPHohh4usS+SNSfsehPN+AAcqqGQ4CAfTvzJlI8nLbbbA8m7K4yrbJbJ46kYo0w2KsiJQ8FxGIC+9vRYuq87/7LuJ4w4XePjnf/vtfKJncvACysuBmtWKF+uzcc9Fnv/+O/039JzPv+lUsTJoEV9I1a5zlRmJtWeb+MJH5WJCDjRuxZ4dKsiH7LZaJiLzw1Vd4jUXGPXYV5QypkWDbNpWcS47Ttm2RVXPduvDOxwklDh92yky6x4h17bM4reGlWfdDpObOVe+59svXX3sTJFP689yCm0Cq14AgglDBpu/sbP+CAVuNUlOxcaxdi8VQL0oswUTh7bdV5Xguljh0aPBGoLeBFysuHmuySrAb44gRMMETudcp0XHZZeo9k5uSJbFxtG4NYXTmTP8WKb6f9evVmDERqe++gxuKW2Yprr5+443+rhsOXn1VvfcSVnbtUsWdOdtgJJCbL1uk2JXIb0FJIrM10g8+/hgKD1m3LK8g14GBA9G2+HgIvuGkgvcCz5mOHd2LnhJFLxS1b4+/mTPhwiWFer9CMCsqQsVU8brw9ddKqAsHx48jzqNtW8zzL77wVrxwrOX27erax45hreP7DJdI9euHcc9lD6IVgrdscWZ6ZQs/kbOALlFkcWUmpRURrvn6696xPOz2tHYtyOrx4/7S8l9wAeIGifwLqjNmQGH3/fdOt75YlzDg9q5fj/viVO45OWouRfpM164luuUWrM1sDXGD9OwoiFb5oUPhTvr555GfY+pUlbBHjqOZM/F8LrggvPO98QZkB92VXpdtrEXK4rTG++/jlYVuCWnJcYOpPlAohFuDKBrITUMmzJBESraBhYE5c1RQcijBQBYrff11pFgOVYNGuomxdUUKMPrGo/fT6NGIA+A0ySZhWi52HH9gKrxsguw3Jn01a8Lixv7SF13kP6BW3g9b2S66CJvjK6+gPhMRFuxvv1VJJXRcdRWEuWef9XfdcNCrF6yJRN6bAd/LGWc4CWe4kH3CWuK1a6FV5GQeflC4MARuVlD4nVPXXQeFh4z3yCu4uUvFEn7rFUVbRPSHH/DHz1fGDPglGexqHaqt0Wrh9d9cc42/+j+BQHDB5EgtUnv3wupNhBT10SZD+PprZ1bUr75SbZMWKaLI+kz+fvt2tR7+73+ID5OZIXXIsdCzJ9ZZvc6jG9kO19WVSe/rr2M9PftspVCLJfr0Qf9Wroy977PPoPyItp+JYEHhDHGh1oR69ZTiIbflilgpdyQKF4ZSgUMNIoEcG6Y+CFWvTMftt4Pw6+fSiZT0UDkViFQB5OEWeQkOrDZZT774AkTLy7rkt/CvxMm0SBFhYmdlOYN0TRYpSR4GDIArGlFowYA1kDt2OAsPe2n+pOsaL34mInXddTDJ632rJ+AwaUmHDIF2KyEhfCGHXWFGjVIB0dJFKVyYiqtWqRJ+zRkiVXslN1C3LrS3XptZrOK0ZJ8wkUpLC9/1JjWV6Jln0ObBg0+eW0ss4eUuFSvwBj9+PFya3UgwuzpGQ5IDATWfpVLF7/zjMRAq3f9rr0FrPGdO7NbS9u0hcN9xR/B3M2ZgvbvkEoz/99/HPXH9LKLwiRQf/8or0adSJwoeO5zchgjrqBSCoyFSxYs71wk+18CBGGumjLSSSKWkYI9gIfSKK2Bxd1NshJvgh5VTjJdfDh3vHAn4vmWdQf7ss89QdytSchxuJr6GDeFS69fzIlxcdBHKNHCW1fwGSaRMe2us6gDq8iK7DR48qGp1FmRYImURFjjAXmYPYnTooDT0buAF8+qrzQkrTDiZFikic3CxiUgRQSuUkeG0iISyunTpgoX7iiv812mSFile/L75Btft31+1aehQaNpCQS6g7dqBpPAGXbw46o+MHu0/bTifr1w5JXisW4dMWF26mGPqvBBuwH1e4Jdf4FL36KPeAc58L//8A8tDqDniBjkG/c4dL0SbISsvkZAAMshKm9xYF1gAXbsWiQjciFIkqaZ1yN926ID4jhdf9B9byHESa9d61+664QZYzufMid1z//VX97i5iy/GHxHmsXSxjTTI3a+l0C9M7tyFCyOpUmIi+qxoUaxj0RApXZEi79vN5VknUkRqTFxwgdOSJvHnnyoGLtLkK5wRNbcgPTNkxsCzz478nOEkkDh8GAqS5s1RHzI30LIl1mq3cjB5DR4bLVoob5XcgMkd/FQgUAzr2mcRFpgweAVfe8FL6GDLge7mdrItUqakC25ESqZhJkJbQ222RYogJa4syhcK0iJ1zjlwVatUCTFSu3aFL8x17Aii9PPP8JHu1Mnpnz52LMz0P/3k73ySfEoNbq9eKmNfODC5gO7YgeDs889HKuC8Rp8+6MeVK72Pk/cSKlmK3/OYtP/hYMMGPPNDh/CsCxri4uCWw6mzc4MMSgHUi8xXq4Z4RT+Z0UyoUcNpVUxMxDjfswcxaX4wZgyInlcsFyNW2b4kIlmXL7wQ8Zjh1sGRmcFiAVM/DB+uanMRRddnJUpgvmZkoI4iuyr7KdQtiRT3MXsbeLldyYRNkbpObd0am6QIOhYuhOcEFxKWRMqPm6gXwrFILVwIj4JOnaK7phdGjIDreX6IKzUh1koJHWeeiddwk00VNFgiZREWeMGPdoFdtizY3MuF4XSCUb++SpJwMogUB9pyogIixALcfz+IB9dsIVJxUVyoUU/dHitIi06lSnDD4wxuCQlqQVy0CEV0vRJXECG2aMAAp/DHQaeSmPl9zuwCcPfdwdaZSLI+mcjq6tWw4M2Zg0xteQ2v7FOm44iiC9yWwla0cTmNGmFebduWfy1+fsACbm6sCxzLQuTdRxdcALfmSDK6EUEgltaKSO7lttuQJCBUAeTZs1XChFgSKb/n+uorFH4/fBiWgIceQhxlOOBn8Z//wHrxzz/h/V4Ht71DB1VTRxcseZxFknWzZEkVo/nGG2ZS5tZ/kkjx2sF7wTvv4Fma3K9kO/3279tvw0WTLeYDBhDddJO/34aD7duJPv1U/Z+Wpu7zwQeJHn88cutuOESKj80tEkEEV8UzzkACDCKViCk3rT/hQMoNXH4mN86v9/GOHRjPcXGIeSzosETKIixES6SYpKxdGyzsX3cdNlY9wUFqKtJH9+vn39UsGgwbhlfp2tC3L4qsnn++WVj59lu8ZmXlzsIsBXDedOSG3KUL3Mx69YKPeSTgdLpEStj64gt/v+XYjB07oAGVmsVIiJRMnsAbnilrX16CN+qLLvIuautH8+wH8fFwnaxQITRRDgXWUucW8T8ZWLgQxIAod8bDnXeqIuC5STb1tk+dCnegSC1cXrj9dsQtma4bDfyeq0cP/HFig0gg14Fly6JPz81zMidHPecVK1Qbf/gBruhEkfeZKZ7VD5EqUkRZbphANWpEdPnlICRXXYU1Vwefr3Jl/25rffsiUYBUhEWbyMMEneBIi9ScOdh/I13fwiFS/P3ff/t3sQ8X+/fj/FwwfcECyD6cECOvIeeSLGEQqyK5H34IxTOXzWFIeYZlwoIMS6QswgIL25Gaw2WcgS5U9u2LYrgNGwb/7qab4IIUrvYyEjRpgtdwChFKchWtkOuG667Da6FCWJzYCpaQgGBWTveakBDa8rF1K9H06bBuFS8OVzl5D3v24JXrMIXCFVc4/5d9EImgU6gQLCblyimhXy760Ra2jQXkRu31zM88U7nCRtPuxES4et15p1l4Cgfcl1dfrTJxFjS0awdB+umnlaAba7gVXI4lWOidOxfWhcREKCbmzCH65JPYXosFzTfegGIoEphi/Pxa0WQtqU2bsJ+YMsB6oXJlZ8xJuPGXOqT1nZ/zhx+qpBPsQle7tn/FksTx487aZnw92Wde64KeNKJ7d2Ru5baaxmY0cXtyH4h1MV6iYKWEJFKMSAmrPPcHH3gfezIK8vbvj1cuHF+9OrLZhrIcnyzIMArZB99+i3hG6d4aCc45B94vumtfLDI05ifkA3HE4nQCa7tMi/+kSdgsODhZ4rHH4GfORehyEyZ3oR074JJy1VVO18OaNfHavj2I3nvvheeTznFhzZqFPvahh7DAFS2K4NBff8XnvAmFU6Dyu+8giG7dCo1QTo4KGJcxC35JEG8YvGDK7GGRaoyXLYPWlfs4v1mk5KbtJWgnJqrnHG1NlrFj4dIkC3RGAh6jq1YR/fFHdOfKK3D/d+niP01/uIi2aKwfSMG6cGF/SQgiBd9H1aqRB8BPmQLFweuvq8/8zkdJpF55BUIWZ4L1iwceUFa1EiWiF4IbN4Ylf8YMZ204Xsv43kqVUq5Z4SAjw5mMg893xx2KBHr1X/36cBGTJRwCAe+xyefbti1810eZrCg3LFKyvXfeiXF43nlqD2SXr0hQowaUjH/+CdLitx0naz85fBgKhJMhx/hBxYrK7VAvyPv++86swrmF/LCXRwtLpCzCwuOP4zXSTdirCCMnJTAF0T77LKwu0frD+8Fbb+FVav1vvx0EY/JkxCIw2I2uZEm4HobrU/7JJ9ByssbKC40awfLDAZwMzuDGAcZ+BAtT+nOZXeqHH3Bv06eHPhdRsN//I4+4X8sPDh2CUCMFG0lQ88PiK/s5lMXCq5B1OJCFQqNBfiOlkSBWaeXd8MUXKitabhIp/T7kuIr1dSWRiRaDBqn045EQqUgL8hKp0gqxKG1Qpw5izBisuGEiFe04c0vV37AhkpQUK+btStWvH/Y/6bKdk6Os4Kb+k+sMF3D3i/vug9WLKHctUmecgfW9QgVk4IxF7F5aGsi5n8x/J8MipeOWW5CcRmbhzWuEo4CNFeS4ikQ5kd9giZRFWOBCrZESqeXL8WpKrcqb8qJFwd8xSXj++ciuGw6YKEltsNSQyYWe3S4idf1p1w6baTj9KTfJKlWQJe/GG5VW3o9gYirIKwWG9u2Rja5VK39t4qQbbInyKjLpBwcOIHHFffepz/Kb8O+XSB04gMBtouiJ1JIleJVZuSKBJKUncwONJbjd772HuINYQwbxy3EYa/BYvv56CPS5mfqfzzd4MBI/RIJNm2DJzMiANSknRynY/F4/Ozs6ax+7Hseq0CkLk2edpeo56UTqt98iS3Kjzy+5l7z9NuJobr/d/feLF8MFcv9+9ZlMhGJae+RnkexNfK3cJFI6mY9VNskFC2C1//BDf+0gOnlrYH7INiuRlaX26pO5DyQmYl/cv79gJztiWCJlERai1aybSFI4iFaAjBRu6c850x3XcQkXR47AvY6JiB/w9Zs1g1Bz7bXB6ZNDwUSkWEiPRMBi1z4mlqw91YNMw0VOjtrU8xuRksVAvYSVrCy4KBIhrXUsEO2ml9/6MhJwH7z4IhI0xBrcR23bIpFLbqFpU8QC/v03LNThWDrDBQst69ertStcVKsGpU3p0kTz52PtisQiFSmReucdlbE0FhapvXudwiR7RLDVVz6Pb74J//xufbNwIeJaQ1mMtm7F68yZ6jOpCDH1X61aKgtuJGOIEwDkZrKJzZvhhcKWtVgQqcOHEUs8YgSKy3tBxtadrDUwv621O3ei3iPRyVeoFS2aO0Q9L2CJlEVY4I1kw4bIfu8VlO/HL/pkEinpPuVGpBhVqkR2jUceQcKHcGI8TIHEsq1+BBP9mMTE6DK46c+Os+6Z4t38QI4Tfl+yJJIt3HYbNI55jauvVpuPl7Aix0ukxXh1ROsOcf316n1BtUjltkb5ZGU2/OQTVa8tMTF3XftiGeSdmYk0zuFYn2NBpGSWL93NORL8+qtScOzapTwSdIsUUWR9JvcOzsBHhBTgffo4U4GbwMrL4cPVZ9KDwa3/OHtsuHWkPv1UlfioVi283/pBgwZQABLBspaVBddFLtAazbg8cgRKAqLQ8kR6ukpelVtroF4KJL+ttXLfym9tK0iwRMoiLLzxBl4jzf3v5RvstfANGwY/chlwm1tgTZ50DZCboVxw/v4bG0+k9TZefBGvbLHwA1ONJ5kVR/r7u8FkkeJMjJFkwWKfdA5c5Q0k0nEi743HRWoq6oyMGWPO7HiyEQhgrJx9tndCDTleoo3neeEFBGi3aBHdee67T42T/KYl9YvczvzEc2TOHASv5yZknIKcf7EmUoMGBSdRiBZXXeUvxpOI6Mkn4c5Ws2bkRIqPv/pqZ8KLSCH7YdcuuNIRqX6SczvSPmMyIxVufK4XXkBMaihI5RIr3ipWdG9TtG7nbdqovTCWSEhwkruUFNXGM8/0H5drQrhkoFkzFFWX5TZiCfbUuPdevOa3tVaOjdat864dBR2WSFmEBQ6KjTR9JxcS9ZOlTmL4cLh4NW4c2XXDgcni42aRqlYNSShOZjpuvtaSJdAIr1ypLFK9eqk6WF6QC+h554H4sOBQqVL4beKEF7whseUwlHuFG6TFJb+kitWxejWEoO+/947VkONFaqQjwX33IUA72ux/REp4z2+bu1/ccYd6n5sWKaLwM8uFC0mk6tRBjGJycuxd+zp3Jrr1VnWtWCAQwFzwgx49EINUvnzkRMqtyGekcFu7eY9q2ZLotdfwPtK5YkpYIc/F7ntekESKa0PJciISu3Ypy0y4Y4j3ElMcc6zAsbSpqVjLeP0880wki4gUciyFKkNy/Dgsgq+9lnuuu2eeCULK1rb8ZvWRY8NvvTGLYFgiZREWLrwQr6NHR/Z7r/oWtWt7/zY3a7lImDY9t2QTeYEaNYgefRTv589HO3nzM1W5N6FWLSTueO89CPfNmqlnEgkp1PuM45pkgHQ4SEuD+8fmzc7N59FH4S6YGzEx4eKRR1CM98svvY+T4+XBB3O1Sb6xbx/asmlT7iZSyE3cfjsIB1HuWqSIcjcgumNHVWicx/oPP8CikBv1saKNRZk0CdlDpcAbybmuvhpzKFzBOZaZB4nMbe/UieiSS9T/bCGPtM/Y2v/CC+br+jmvJAZs2XLLYiv7JlzXPlaKmbLnxgL79qlsmKyYZSLF2RgjRThEKiMDir8aNZwF5GOJW2+F2y4rffJadtAh17hYKSZOR1giZREWTG5l4YAnq6k+ChdAlEH8eQH2D3/iCfVZ+/ZYFD/9VBW+zSuccQbqajF5KlRIvV++3F+x1ipVkLlLuiRybSIu9BsOeEPnIp+PPQbSzYVoI0GVKsHWsSeewMb08suRnzdW4E07lLueJIKRzptY49ZbkaHsyy8jr/OVH2Cq+RYrSHfZ3FTicAY6otzXWK9apZJMRCrUXXkl6tmxdwGR/3avWoXfrlkD69QTT4TvpsrP4vvviX78MbzfmsCKo3r1VHFqXaiMRslERDR0KF5lPFS4RErOU3b/dEsYItspn5Mf8Hq2enXuCNdZWcoyrxOp33+H63ak8FskXT82VqQ8FHLDVTIayD44GaVlTlVYImURFniBjlQg5EBhU0G6886D5oatXnkFLkgr3ctuvpnof//Dd3oAaV4gEFDuc4UKQauWlgZBhbX04SKaTXPLFryyy0apUkSzZhH17h35Ob2QW7WDwgELwHff7X2cFJLyC5GKtXtUXmDDBlVMODc0vU2aoPgr0ckpyEsEwWbdOqIyZaAwiTWeeUYpTKLts0gyPz7/PKwzkbr86tc1eTaEC+klwc9582a1xqxbp6y2kfaZqVaPXyLFVuxevdRnnA3VbYzI84Wbec9vofFIYUoSI12jZcH7cBGOy7Nsx8lKSz5uHDIXx7rQdqSQ/RVNbNrpDkukLMLCt9/ilWtthIuePZF57Zdfgr/r1An+ylwMMK/AbjYVKuRtO9xw5AgWYxbKCxUiOv98FBAl8qcdPnIEboFxcQhYXrIElsBBg4i++y78NoUb8xYtYiFARQu/ZC4uTlk3y5TJvfaEA3b3GTzYmVa5IKFPHyQz6dIl+uQbboim1pFfsNA7ZgwyyAUCRLt3I5EN192LFfg+evRQtc0iRSQZv9iSsm8fYnhWrgzfhUymTI5FHSnpZcH3tGIFrCNEzqyNbHEPF5x0R1pJJNnxsnTx9aWLXpUqUF65JUGR5w53rTz/fMQMhVIQRQo5l7idsaoHJnH//d7fR9NHkaJCBcR5RxKHnNvIDwriggpLpCxOKuLjoWHLzxliTNrDAweIPvgArnDvvRe7a3G9pXAE7GXLnPWZ2Ked2+1H6PvnHwRRE6GWx/Hj2Khff53o8sv9t4XB5PdkZdPLD0QqlOuIBMc05JdgYykEr1qVd+2IBtyX116bO2maiU4ukSpeHJZcOUYijTF0A99HnTqRF1VnsCs2kX9LjSRSvXvDnc5PxjqJ9u3VmheLOlJVq0IRtHats6yCnv68RAnU+4oEXAZCul1zLSwi7/674QZkOuzWzfl5xYrOshduCDd9f2IiYlBzy31azqWrrsJryZKqD6L1Npg9G4raULF30hoTzlp+qqF5c7zGYi6drrBEyiIsDBqE15o187YduQmulfXXX+ozjif64AOiGTNid63x40HMwkmeoLsC6cHXkRbkjQYm8pmbyA9EKhw3vWgLWccaUrud3wKg/cKUFCaW2LFDpdfOTSLF92GK94q1axWfOxYxId26KaVLJEQqUpKamancmmNhyahSRaWplvehE6lYj7O6deHGHh/v3X/nngsPkHCSckhikNt10MKFfN5cvyspSdVSk7GJkeCCC6Co5fgrPzidiVQ4coOFGflkW7coKGAXGk7neSpi/ny8ctIJotAFeSNF8+YgaOGkdZdtYffDjRuVVciPYBJrIsWb9cmKuSloRIo13dFmpYoVToVCjDzOJ040x1zGEldckXvn5rl3yy1wHZNzMdYEjs83YgTRvHnRn2/iRFjrb7jB3/GxIFI8hxISwo//cQOTJLmvsbWH58ehQ0STJ8fmeoxZs7CWSeteLFCqFFw3b789d9zmokFCgrIGSXIabTZJxpQpiLOaNcv/b05nIrVsGV7zG+EuSLBEyiIs5DfN+slCbhGpSMDXL1tWVYhnVxcifwG3uvAS7T2NHIlXXpRzG/mBSHXo4P9YLrjMiUzyGqeSRerLLxHjF2tIspmb2bbYup+ZCUFdEttYk1w57+fOje5cu3cjEcOBA/4tZ7EgUhxfm5MTm3pqmZmqCC8nyyEKtkgRxSZLIGP9eqLPPjPHC8cCo0cTvfFG7pw7WjBx4eRTRNFnRmT06IG0+h9+6P83p3N8EM9DTkJjET5OM3HYIlrwor9mTd6242RAbqD5kUhJMiF95f1YhXTBJ1qBLRYCjR88/jhcip5++uRczwtt2uD1rLNCH8v+5+GQr9xEtDWA8gNyk3AQOclmblpaX38dAjUR7sMts1ssYAr0jxSvvELUoIFSovhBLIhU+/awxN98c3i/c8OaNcjISqSSQsh2xeJ5cLFTLuxLhNTl117rrC11uoDTwcu6elwzLVqBnpOXcCZZL7ASo2LF6K5ZkHH++Xi9/vq8bUdBhiVSFmFh7Fi8ctX0UxFsNXj8cfWZJFJ57QplquUl/cFZwPdCrF37mCDkVvY0xtChyE4oi2XmFZKTEbTvx83VqxB1XqBrVxUAn9fjOVLkJuEgcs6Rv/+O/fklZIxhJGnF/UIS+VilP3/9dZWGPhRq1UISgyefjJxIlSiBZDnjx4f3OzfIfti2Lfj7WMwPzjQo1wq+7uTJuWNRzc9gQl24sPqMEyjJ2obRwI+7XsuWKKrO7Tkd8dNPUCBUr57XLSm4sETKIiwU5OKdfqEHfxPlL4sUt2XvXqI778T7uDi1Wfup3SSFtSpVwgvMNYEtLqfTYly1Kgp4+nGf2bkTr/lJYGLhPa/Hc6To0kW9zw0yKPsl1rExOiSRKlxYXVsKmrFA69YqU1q0z11a7PwW8yxXDmm1e/SILiNiLMesXNs7dMCa+vbb6rP0dKIhQ/A+0uQfpuLd8h52747svAUVmZl4lfvOmWc6X6OFHyL1/vso/1C/fmyuWRCRkHB6E8lYwBIpi7DACQ2efz5v25GbMGVpkq5reS14pqeravWyzgy79x06FPocCQlEw4fDRW7lyuhrZpnIZ27g9dfhDvP997l7HT8YOxYuciNG+P/No4/mXnvCQXY2ikMuX07UsWNetyYyXH+9SnueG3PyZKVHvu8+5aYms+plZ+dOLbtYZdiM1nLWvz/Rvffmfb0+2fZixYhefTW4TmK08TtcOFeuW7ltUc3P4Gx9MkkMJ8WIVUKe0zmBhMXJhSVSFmGBN5JwMpYVNEyZglcZBNyiBWJzXnjBWWskL1CqFNFjj+G9KcmErFXihWHDiB5+ODZab04y8fnn0Z/LC3feiXiS3CoWGQ5MWuZQyC/z5r33EB/w4IPOMVTQYEoZnhvITUFXzle+j7g4vI917OHOnSj6SxQ71z6i8Pp/7lwUdr/7bqIXX1Q11vIKvKcVLepeOynajHLXXYfXRYvUZ/JcpxuRYsg6aRyfJq2B0cASKYuTBUukLMKCKT7nVMNnnxG1beu0NFx/PWJz7rsvfxSu4+xSUgjm4FoZwHuykJt1dkzID7FG332H13Hj/P8mv8wbFoJPVrr63MCePUSbN+N9bgmiHIjtJ6FIpMjtpBkSX3yBfiOKLZEK51ydOxN16oSSDfkBoeIXjx9HYg0iooyMyK5hImKWSDnHO4+HSPvYwiKvYImURVj44AO8PvRQ3rYjN9GmDdH06SiYmB+Rk6MyG0kixZnsmjXzd56lS6HxrlzZmYY2Ejz5JNw1OI1wbiM/EKl9+/wfy4Ws/T6b3AbHt0ydSrR6dd62JVKwVbZ0aeXqGmtEE8fjFyxEDxyIlNW5Cb6P0qVVMd1IESmR4niMRYtQviG3Cir7RSjloLQK9usX2TU4JkhaSWSfnW7lRBiyD1im6NYtunOWK4fXTp2iO4+FhV8U0HxNFnkFFixON2RlEX30EdHChch4dumledeW3btVggNJpFgg8Sv0XXghXv2kiQ2FokVBpnIb6enwob/ooty/ViiEY5nkbF35xY1OCsGbNxPVrp13bYkUrM2+5ZbcsxKfTCJVsSJqw+Um+D6aNSMqUya6czVooN6HY0ljInXjjXjduBGJW/IKxYohvvTQIaRB79/f+T27WR47BgIaCbhgsazdJZUqp6tFSiorL7yQaOvW6OfA5MlwGQynyL2FRTQ4TfUgFpHi2mvx2rBh3rbjZGP4cAQgjxoVfSHLaCE3XZlFMdwsbPkppbtf/P476tawq01eYuxYpM+dODH0sfmtkPWpVJA3N5U7nNZ7w4bcu8bJTI3PRCoWfdakiarDE4lFSm9TXqFECWVpcktzb0pAFC2qV1eW1II6ByNFkyZ41evqVagQfV+0bInzsmXKwiK3kU+2dYuCAi7keboRqfxEOmRbpIWD6175rWafn1K6+8UZZyAGrHjxvG4J0vTOnavSSXuBXbbWrs3dNvlFbtYqOlngeThliooZjDVeeQWuvrEq/moC38ewYUQTJuTedYgUaZk+neivv6I/37x5qL0kCzyHQn4jUkShMxmya97s2bG97vr1OPfpZj05GUoQC4uTBUukLMJCftOsnyzkJ9Ihr//II8Hf+83Cl5/u6VQHWzRYE5vXkBapvFYMRAoWwJcvz706PHfdhYKVXFogNyA15z/+mHvXIXI+a1k6IRJkZcEdLisrvPpK+Y1I5eSoOMFQc2HWrNhdd/duxCjOm3f67aec5MYSKYtTAafZ9LWIFlxQtKAGqEeK/EQ65PVlgPTcuXBr8CuM2axRJw8tW+I1L2PrJMqXV+8L6rM/VerwDB2q6ovlNqmVpCXaPps3D+5pl10W3u/yG5Hav1+tmaHSzUeaUpv76NZb1WeLFyMhAhdVP53QoQOUOfXq5XVLLCyihyVSFmHhww/xOn9+3rbjZCM/ESnZFhlX0bKlIlPhnifW9WosnDiZcTB+ULMmUaVKeF9QLVJyHhbUe2CcrHpYMqlIrNKfr1qFJAF+0aUL3BgZeU2kTsY6yIqLM89Un3H/L10K98jTCSNHEh08mH8z41pYhANLpCzCQn7JOnayITfYvBbapAA0c2bk55HuXRa5i+3b8RqLuJRYIdzkJPkN0k2yoN4DI1SMTqxQq5aKb41lHalwSgFceCFSvTPy03rqRqR69MBro0aRXcOUrEJe99ChyM5bkJHXBNrCIlawRMoiLNx+O16HDMnbdpxs5CeLlBQ8oqn/NGQIaj8tWxZ9myy8wQSKa33lNQIBop9/Rla6OnXyujWRoW1b9T6vhfFo8MYbRM88g/cn4z5MxWEjQTQJS1JSUFttwIC8t4b7sWzGqs9kshnrWm1hcWqgAG8/FnkBJhRuxQtPVdSvT9S6NWp/cAr4vEJCArI8LV4ceV0TIggxFicX+WXebN1KdNZZ0Apz4HdBg5t2v6Bhxw71PreJ1JEjKslEtNeKJmFJ8eJEr78e3fVjBakkc1sToyVSHAskkyucKjF+FhanOyyRsggLpyuRuuoqf2muTxYOH8br6epqWVCRX+YNWxOys9Gmgpg1TLpDFWSL1MmM9VqxwnzdSHAqpNAnck/eIzF5Ml5XrozsGiYiJt8XxPlnYWEB2OlrERZGjcLrSy/lbTtOd2zciNfU1MjPMW8ehKHTrSZYXoCtmFdemafNOAEpBO/cmXftiAay5lJBjrdggbp1a7i75SZkPzVoEN25ThUi5Za8R4L7rVWryK4RikgV5P6zsDjdYYmURVjgCvC5WaAyPyIQIBo3DqmK//wzr1uD2i1ESN0bKfr1g0Vi6dLYtMnCHZytKxpXzFhCumXt2ZN37YgGXC/t8ssLtiDKba9Vi6hs2dy9FhOC9PTgNOThomhR9b4g978kUr/+aj6GXfPS0yO7xsMP4/Xdd9VnVaqo9wW5/ywsTncUYIcIi7zA888TXXNNeJXsTwW8+CLR/ffjfd26+ceKU6NG5L+17iQnD1x/Jr/0ubQm5JeU7OHClAmtIILv42Q8ByZSsSiEKosUF2TXyrg4onbtUEvKLXtetGPNVH+qVCn13hIpC4uCi3yyrVsUFCQmwgUlnEr2pwKkAJwfhIa5c4m+/jo6ImU375MHjrH4/fc8bcYJxMcjW1/p0gU3ax/Hs8yZk7ftiBY8D99/H/M6N8Fr18GDsbFEbtiAjJSSFBREhEo/v3AhXiPNcDp2LF6ffNL5+b59eA6RWrosLCzyHvlAJLSwyP/IT+nPifwX3fVCfrGOnA7Yuxev7I6WH7BsGawgBVUpsns3XjnxSkFFsWLq/YIFkcfh+IGMkdq2LToCFBdHVL161E3KF9iyxd9xixZFdv5+/RAfKfs7M1Od76KLIjuvhYVF3sOKUhYWPpDfiFQsYInUyUP79ni95JK8bYdEQkLBJVFEeV9/KFbo14+oe3e8z+2kGfL8dv4rcH0nLpyto1YtvEZT+kInrdu3E118MVHHjpGf08LCIu9hLVIWFj5giZRFNDhV4nnyE04VIkUU2rUsVpBxTXb+B8NtTC1cSLR6NVHTprG7Fj/zw4dRy60gKzUsLE5n2KXUwsIH5AabH2KkYoH85GZ2qoOLrm7blrftOJVQsWJetyB2OFlEqlAhRaYKcsr43IIbkSpaFMXYY0neZXIRUzIKCwuLggFLpCwsfOBUtEgNHkx0991EEyfmdUtOfXz7LV5fey1v23EqoW5dvJYrl7ftiBbffafGx8lQ0phqGlkAeWXltM/CwqLg4hTRrVtY5C6qV0ctoLPPJmrRIq9bExt06oQ/i9xHvXpEK1bkrxipgg624hR0IZSTZhCdHCJ15EjuX6OgoXRpPIc2bU7eNcuUUe+tm6WFRcGFJVIWFj5w2WVI82thEQmmTSMaP57ollvyuiWnDo4exatb7Z+CAkkET6bbsHUnU+BnwCn1TwZKlSKaPp0oNdUSKQuLggxLpCwsTlP88AME+2bNiCZNyuvWnNqoWJHo4YfzuhWnFrj2TkpK3rYjWjB5Klr05FgsP/0UtYvOOCP3r1VQkBdEioiobduTez0LC4vYwxIpCwufGDOG6MABohtvPDUC3Z9/nmjzZvxZWBQ01KpFtHFjwS8Gy0J848YnpzBrjx65f42ChoMH8Woz51lYWIQLS6QsLHzgww+Jbr8d7y+66NQgUgU9tsTComrVvG5B9OB5KLO4WZxczJxJtGoVYhktLCwswoElUhYWPiBdPk4VAmL98i0s8h68nvz6K9HffyOxjcXJRdOmsa0RZWFhcfrAilIWFj4gScepUkfqiivwKot0WlhYnFykpqr3GzbkXTssLCwsLMLHKSISWljkLk7FOlK3344UvK1b53VLLCxOX7RvT1S7NtHq1aeOksbCwsLidIFdti0sfOBUJFIJCUTXXpvXrbCwsMjOxqslUhYWFhYFC9a1z8LCB2TF+1OFSFlYWOQPcHFhS6QsLCwsChYskbKw8IFTMUbKwsIi77FsGdGmTXhv1xYLCwuLggW7bFtY+EDZsqgxUqcOUYUKed0aCwuLUwUHDqj3lkhZWFhYFCzYZdvCwgcuvJAoKyuvW2FhYXGqQboKWyJlYWFhUbBgXfssLCwsLCzyCJI8VauWd+2wsLCwsAgfVv9lYeEDgQDRa69Be9y3L1FaWl63yMLC4lQAW6QqVCAqVChv22JhYWFhER4skbKw8IEpU4juvhvvr7vOEikLC4vYgIlUTk7etsPCwsLCInxY1z4LCx+Q8VE2/bmFhUWswOvJzp1Ehw/nbVssLCwsLMKDJVIWFj4QCKj3NiDcwsIiVpDrSUZG3rXDwsLCwiJ8WCJlYeEDkkhZi5SFhUWsUKOGem+VNBYWFhYFC5ZIWVj4gCVSFhYWuYFjx9R7S6QsLCwsChYskbKw8IHjx9V7S6QsLCxiBUukLCwsLAouLJGysPABSaTi7ayxsLCIEXbuVO+tksbCwsKiYMGKhBYWPsCFMosVI4qLy9u2WFhYnDqw1m4LCwuLggvrSGBh4QMtWzrjpCwsLCxigZo1ifr3JypZ0hIpCwsLi4IGS6QsLCwsLCzyEG++mdctsLCwsLCIBJZIWVj4wP79RJ9/TpSWRnTDDXndGgsLCwsLCwsLi7yGJVIWFj4wZQrRLbfgvSVSFhYWFhYWFhYWNtmEhYUPZGbmdQssLCwsLCwsLCzyEyyRsrDwAZlZy8LCwsLCwsLCwsISKQsLHyhZMq9bYGFhYWFhYWFhkZ9gY6QsLHygSxekKG7ePK9bYmFhYWFhYWFhkR9giZSFhQ/Ex9sUxRYWFhYWFhYWFgrWtc/CwsLCwsLCwsLCwiJMWCJlYWFhYWFhYWFhYWERJiyRsrCwsLCwsLCwsLCwCBOWSFlYWFhYWFhYWFhYWIQJS6QsLCwsLCwsLCwsLCzChCVSFhYWFhYWFhYWFhYWYcISKQsLCwsLCwsLCwsLizBhiZSFhYWFhYWFhYWFhUWYsETKwsLCwsLCwsLCwsIiTFgiZWFhYWFhYWFhYWFhESYskbKwsLCwsLCwsLCwsAgTlkhZWFhYWFhYWFhYWFiECUukLCwsLCwsLCwsLCwswoQlUhYWFhYWFhYWFhYWFmHCEikLCwsLCwsLCwsLC4swYYmUhYWFhYWFhYWFhYVFmLBEysLCwsLCwsLCwsLCIkxYImVhYWFhYWFhYWFhYREmLJGysLCwsLCwsLCwsLAIE5ZIWVhYWFhYWFhYWFhYhAlLpCwsLCwsLCwsLCwsLMKEJVIWFhYWFhYWFhYWFhZhwhIpCwsLCwsLCwsLCwuLMGGJlIWFhYWFhYWFhYWFRZiwRMrCwsLCwsLCwsLCwiJMJOZ1A/IDAoEAEREdOHAgj1tiYWFhYWFhYWFhYZGXYE7AHMENlkgR0cGDB4mIqEqVKnncEgsLCwsLCwsLCwuL/ICDBw9S8eLFXb+PC4SiWqcBjh8/Tlu3bqWiRYtSXFxcnrXjwIEDVKVKFfrnn3+oWLFiedYOi/wHOzYsvGDHh4Ub7NiwcIMdGxZeON3HRyAQoIMHD1LFihUpPt49EspapIgoPj6eKleunNfNOIFixYqdloPWIjTs2LDwgh0fFm6wY8PCDXZsWHjhdB4fXpYohk02YWFhYWFhYWFhYWFhESYskbKwsLCwsLCwsLCwsAgTlkjlI6SkpNCwYcMoJSUlr5tikc9gx4aFF+z4sHCDHRsWbrBjw8ILdnz4g002YWFhYWFhYWFhYWFhESasRcrCwsLCwsLCwsLCwiJMWCJlYWFhYWFhYWFhYWERJiyRsrCwsLCwsLCwsLCwCBOWSFlYWFhYWFhYWFhYWIQJS6TyCUaNGkXVq1en1NRUatGiBf3222953SSLXMbs2bOpc+fOVLFiRYqLi6PJkyc7vg8EAvToo49ShQoVKC0tjdq1a0dr1651HPPvv/9Sz549qVixYlSiRAnq168fHTp06CTehUVuYMSIEXTuuedS0aJFqWzZsnTllVfS6tWrHcdkZmbSoEGDqFSpUlSkSBHq3r077dixw3HMpk2bqGPHjlSoUCEqW7YsDRkyhI4dO3Yyb8UiFzB69Ghq2LDhiUKZrVq1ou+///7E93ZsWDBGjhxJcXFxdM8995z4zI6P0xfDhw+nuLg4x1+dOnVOfG/HRviwRCof4NNPP6X77ruPhg0bRn/88Qc1atSIOnToQDt37szrplnkIjIyMqhRo0Y0atQo4/fPPvssvfrqqzRmzBiaP38+FS5cmDp06ECZmZknjunZsyctX76cpk2bRt988w3Nnj2b+vfvf7JuwSKXMGvWLBo0aBDNmzePpk2bRtnZ2dS+fXvKyMg4ccy9995LX3/9NU2YMIFmzZpFW7dupW7dup34Picnhzp27EhHjx6lX3/9lcaPH0/vvvsuPfroo3lxSxYxROXKlWnkyJG0cOFC+v3336lt27bUtWtXWr58ORHZsWEBLFiwgN58801q2LCh43M7Pk5v1K9fn7Zt23bi75dffjnxnR0bESBgkedo3rx5YNCgQSf+z8nJCVSsWDEwYsSIPGyVxckEEQUmTZp04v/jx48HypcvH3juuedOfLZv375ASkpK4OOPPw4EAoHAihUrAkQUWLBgwYljvv/++0BcXFxgy5YtJ63tFrmPnTt3BogoMGvWrEAggLGQlJQUmDBhwoljVq5cGSCiwNy5cwOBQCDw3XffBeLj4wPbt28/cczo0aMDxYoVC2RlZZ3cG7DIdZQsWTIwduxYOzYsAoFAIHDw4MFArVq1AtOmTQu0adMmcPfddwcCAbt2nO4YNmxYoFGjRsbv7NiIDNYilcc4evQoLVy4kNq1a3fis/j4eGrXrh3NnTs3D1tmkZfYsGEDbd++3TEuihcvTi1atDgxLubOnUslSpSgZs2anTimXbt2FB8fT/Pnzz/pbbbIPezfv5+IiNLT04mIaOHChZSdne0YH3Xq1KGqVas6xsfZZ59N5cqVO3FMhw4d6MCBAycsFxYFHzk5OfTJJ59QRkYGtWrVyo4NCyIiGjRoEHXs2NExDojs2mFBtHbtWqpYsSLVqFGDevbsSZs2bSIiOzYiRWJeN+B0x+7duyknJ8cxKImIypUrR6tWrcqjVlnkNbZv305EZBwX/N327dupbNmyju8TExMpPT39xDEWBR/Hjx+ne+65h1q3bk0NGjQgIjz75ORkKlGihONYfXyYxg9/Z1GwsXTpUmrVqhVlZmZSkSJFaNKkSVSvXj1avHixHRunOT755BP6448/aMGCBUHf2bXj9EaLFi3o3Xffpdq1a9O2bdvoscceowsuuICWLVtmx0aEsETKwsLCIh9j0KBBtGzZMocfu4VF7dq1afHixbR//376/PPPqVevXjRr1qy8bpZFHuOff/6hu+++m6ZNm0apqal53RyLfIbLL7/8xPuGDRtSixYtqFq1avTZZ59RWlpaHras4MK69uUxSpcuTQkJCUFZUXbs2EHly5fPo1ZZ5DX42XuNi/LlywclJDl27Bj9+++/duycIrjjjjvom2++oZkzZ1LlypVPfF6+fHk6evQo7du3z3G8Pj5M44e/syjYSE5Oppo1a1LTpk1pxIgR1KhRI3rllVfs2DjNsXDhQtq5cyc1adKEEhMTKTExkWbNmkWvvvoqJSYmUrly5ez4sDiBEiVK0FlnnUV//fWXXTsihCVSeYzk5GRq2rQpTZ8+/cRnx48fp+nTp1OrVq3ysGUWeYkzzjiDypcv7xgXBw4coPnz558YF61ataJ9+/bRwoULTxwzY8YMOn78OLVo0eKkt9kidggEAnTHHXfQpEmTaMaMGXTGGWc4vm/atCklJSU5xsfq1atp06ZNjvGxdOlSB9meNm0aFStWjOrVq3dybsTipOH48eOUlZVlx8ZpjksuuYSWLl1KixcvPvHXrFkz6tmz54n3dnxYMA4dOkTr1q2jChUq2LUjUuR1tguLQOCTTz4JpKSkBN59993AihUrAv379w+UKFHCkRXF4tTDwYMHA4sWLQosWrQoQESBF198MbBo0aLAxo0bA4FAIDBy5MhAiRIlAl9++WXgzz//DHTt2jVwxhlnBI4cOXLiHJdddlngnHPOCcyfPz/wyy+/BGrVqhW4/vrr8+qWLGKE22+/PVC8ePHATz/9FNi2bduJv8OHD584ZsCAAYGqVasGZsyYEfj9998DrVq1CrRq1erE98eOHQs0aNAg0L59+8DixYsDU6ZMCZQpUybw8MMP58UtWcQQDz30UGDWrFmBDRs2BP7888/AQw89FIiLiwtMnTo1EAjYsWHhhMzaFwjY8XE6Y/DgwYGffvopsGHDhsCcOXMC7dq1C5QuXTqwc+fOQCBgx0YksEQqn+C1114LVK1aNZCcnBxo3rx5YN68eXndJItcxsyZMwNEFPTXq1evQCCAFOhDhw4NlCtXLpCSkhK45JJLAqtXr3acY8+ePYHrr78+UKRIkUCxYsUCffr0CRw8eDAP7sYiljCNCyIKjBs37sQxR44cCQwcODBQsmTJQKFChQJXXXVVYNu2bY7z/P3334HLL788kJaWFihdunRg8ODBgezs7JN8NxaxRt++fQPVqlULJCcnB8qUKRO45JJLTpCoQMCODQsndCJlx8fpi2uvvTZQoUKFQHJycqBSpUqBa6+9NvDXX3+d+N6OjfARFwgEAnljC7OwsLCwsLCwsLCwsCiYsDFSFhYWFhYWFhYWFhYWYcISKQsLCwsLCwsLCwsLizBhiZSFhYWFhYWFhYWFhUWYsETKwsLCwsLCwsLCwsIiTFgiZWFhYWFhYWFhYWFhESYskbKwsLCwsLCwsLCwsAgTlkhZWFhYWFhYWFhYWFiECUukLCwsLCwsLCwsLCwswoQlUhYWFhanKP7++2+Ki4ujxYsX53VTTmDVqlXUsmVLSk1NpcaNGxuPCQQC1L9/f0pPT8/z9ufHPowUP/30E8XFxdG+ffty/VrDhw93fb4WFhYWpwoskbKwsLDIJfTu3Zvi4uJo5MiRjs8nT55McXFxedSqvMWwYcOocOHCtHr1apo+fbrxmClTptC7775L33zzDW3bto0aNGhwUtrWu3dvuvLKKx2fValS5aS2oSAiLi6OJk+e7Pjs/vvvd32+FhYWFqcKLJGysLCwyEWkpqbSM888Q3v37s3rpsQMR48ejfi369ato/PPP5+qVatGpUqVcj2mQoUKdN5551H58uUpMTEx4utFi4SEhDxvQ0FEkSJFXJ+vhYWFxakCS6QsLCwschHt2rWj8uXL04gRI1yPMblBvfzyy1S9evUT/7O15Omnn6Zy5cpRiRIl6PHHH6djx47RkCFDKD09nSpXrkzjxo0LOv+qVavovPPOo9TUVGrQoAHNmjXL8f2yZcvo8ssvpyJFilC5cuXopptuot27d5/4/qKLLqI77riD7rnnHipdujR16NDBeB/Hjx+nxx9/nCpXrkwpKSnUuHFjmjJlyonv4+LiaOHChfT4449TXFwcDR8+POgcvXv3pjvvvJM2bdpEcXFxJ/qgevXq9PLLLzuObdy4seMccXFxNHbsWLrqqquoUKFCVKtWLfrqq68cv1m+fDl16tSJihUrRkWLFqULLriA1q1bR8OHD6fx48fTl19+SXFxcRQXF0c//fST0bVv1qxZ1Lx5c0pJSaEKFSrQQw89RMeOHXP011133UUPPPAApaenU/ny5Y33qmPs2LFUt25dSk1NpTp16tAbb7xx4rvzzjuPHnzwQcfxu3btoqSkJJo9ezYREb3//vvUrFkzKlq0KJUvX55uuOEG2rlzp+v1/Iy7BQsW0KWXXkqlS5em4sWLU5s2beiPP/448T0fe9VVVzmel37uUGOD+3nixIl08cUXU6FChahRo0Y0d+7cE8ds3LiROnfuTCVLlqTChQtT/fr16bvvvvPsUwsLC4vchCVSFhYWFrmIhIQEevrpp+m1116jzZs3R3WuGTNm0NatW2n27Nn04osv0rBhw6hTp05UsmRJmj9/Pg0YMIBuu+22oOsMGTKEBg8eTIsWLaJWrVpR586dac+ePUREtG/fPmrbti2dc8459Pvvv9OUKVNox44d1KNHD8c5xo8fT8nJyTRnzhwaM2aMsX2vvPIKvfDCC/T888/Tn3/+SR06dKAuXbrQ2rVriYho27ZtVL9+fRo8eDBt27aN7r//fuM5WODetm0bLViwIKw+euyxx6hHjx70559/0hVXXEE9e/akf//9l4iItmzZQhdeeCGlpKTQjBkzaOHChdS3b186duwY3X///dSjRw+67LLLaNu2bbRt2zY677zzgs6/ZcsWuuKKK+jcc8+lJUuW0OjRo+ntt9+mJ598Mqi/ChcuTPPnz6dnn32WHn/8cZo2bZpruz/88EN69NFH6amnnqKVK1fS008/TUOHDqXx48cTEVHPnj3pk08+oUAgcOI3n376KVWsWJEuuOACIiLKzs6mJ554gpYsWUKTJ0+mv//+m3r37h1W/+k4ePAg9erVi3755ReaN28e1apVi6644go6ePAgEdGJ5zNu3DjP5xVqbDD++9//0v3330+LFy+ms846i66//voTJHXQoEGUlZVFs2fPpqVLl9IzzzxDRYoUier+LCwsLKJCwMLCwsIiV9CrV69A165dA4FAINCyZcvA/7V3dyFRPX0cwL+lGbFqgZlovmLmG+vi24WYbnShUUleJiKSLyBaJkqUYVhptEYlKduNhoZoRJGkkEqUkG2WZq2arJvoQkLZq2ArRLrO/0I8j0fN3DSfm+8HDuyZMztnZs6w7M+ZHdPS0oQQQjQ2Nor5H7/FxcVCpVLJ3lteXi68vLxkZXl5eQmLxSKl+fv7i5iYGOl8enpaKBQKcfv2bSGEECaTSQAQGo1GyjM1NSXc3d1FWVmZEEKIkpISERcXJ7v36OioACCMRqMQQgi1Wi1CQ0P/2F43Nzdx8eJFWVpkZKTIzs6WzlUqlSguLl62nIVtF0IILy8vUV5eLktbWBYAUVRUJJ2bzWYBQLS0tAghhCgsLBQ+Pj7i169fS953/vOaM9eHb968EUIIcebMGeHv7y9mZmakPFqtVtjb20vPRq1Wiz179sjKiYyMFKdOnfptm319fUVDQ4MsraSkRERFRQkhhPj8+bOwtbUVT58+la5HRUUtW2Z3d7cAIH78+CGEEKK9vV0AEOPj40KIlY27hSwWi3BwcBDNzc1SGgDR2Ngoy7ew7D+Njbl+rq6ulq4PDAwIAMJgMAghhFAqleLcuXO/rRsR0XrjjBQR0TooKyvDrVu3YDAY/rqM4OBgbNz4v49tFxcXKJVK6dzGxgZOTk6LlnNFRUVJr21tbRERESHVo7e3F+3t7bC3t5eOgIAAALO/VZoTHh6+bN0mJibw4cMHREdHy9Kjo6NX1WZrhYSESK8VCgUcHR2l/tDr9YiJicGmTZv+unyDwYCoqCjZZiHR0dEwm82ymcD59QAAV1fX3y6zm5ycxPDwMNLT02XPobS0VHoGzs7OiIuLQ319PQDAZDKhs7MTycnJUjk9PT1ISEiAp6cnHBwcoFarAQDv37//6/Z++vQJmZmZ8PPzw9atW+Ho6Aiz2WxVmdaMjfn95urqCgBSv+Xm5qK0tBTR0dEoLi5GX1/f3zaLiGhNMJAiIloHsbGxiI+PR2Fh4aJrGzdulC3ZAmaXaS20MADYsGHDkmkzMzMrrpfZbEZCQgL0er3sGBoaQmxsrJRPoVCsuMx/YTV9NNcfW7Zs+XcVtKIeC5nNZgBAVVWV7Bm8ffsWL168kPIlJyfj3r17mJqaQkNDA5RKpRRIT05OIj4+Ho6Ojqivr0d3dzcaGxsB/H5zkJX0aWpqKvR6Pa5fv47nz59Dr9fDyclpVRuOLGd+v80Fq3P9lpGRgZGREaSkpKC/vx8RERGorKz8J/UgIloJBlJEROtEo9GgublZ9gN6YHa2YWxsTPaldi3/b9H8L+PT09Po6elBYGAgACAsLAwDAwPw9vbGrl27ZIc1wZOjoyPc3Nyg0+lk6TqdDkFBQatug7OzMz5+/CidT0xMwGQyWVVGSEgIOjo6lgzAAMDOzg4Wi2XZMgIDA9HZ2Sl7VjqdDg4ODnB3d7eqPnNcXFzg5uaGkZGRRc/Ax8dHynf48GH8/PkTra2taGhokM1GDQ4O4tu3b9BoNIiJiUFAQMCyG00AKxt3Op0Oubm5OHDgAIKDg7F582bZRiTAbPCzXL+t5djw8PBAVlYW7t+/j4KCAlRVVVn1fiKitcRAiohonSiVSiQnJ6OiokKWvnfvXnz58gWXL1/G8PAwtFotWlpa1uy+Wq0WjY2NGBwcRE5ODsbHx5GWlgZg9gf8379/R1JSErq7uzE8PIy2tjYcPXr0j0HFQidPnkRZWRnu3LkDo9GI06dPQ6/X48SJE6tuw759+1BXV4eOjg709/cjNTUVNjY2VpVx7NgxTExM4MiRI3j16hWGhoZQV1cHo9EIYHYHur6+PhiNRnz9+nXJgCs7Oxujo6M4fvw4BgcH8eDBAxQXFyM/P1+27NJa58+fx6VLl1BRUYF3796hv78fNTU1uHbtmpRHoVAgMTERZ8+ehcFgQFJSknTN09MTdnZ2qKysxMjICJqamlBSUrLsPVcy7vz8/FBXVweDwYCXL18iOTl50cyet7c3Hj9+jLGxsd9u878WYyMvLw9tbW0wmUx4/fo12tvbpT8IEBH9PzCQIiJaRxcuXFi0xCswMBA3btyAVquFSqVCV1fXkjva/S2NRgONRgOVSoVnz56hqakJ27dvBwBppsBisSAuLg5KpRJ5eXnYtm2b1YFBbm4u8vPzUVBQAKVSidbWVjQ1NcHPz2/VbSgsLIRarcahQ4dw8OBBJCYmwtfX16oynJyc8OTJE5jNZqjVaoSHh6OqqkpaTpaZmQl/f39ERETA2dl50QwKAOzcuRMPHz5EV1cXVCoVsrKykJ6ejqKiolW1LyMjA9XV1aipqYFSqYRarUZtba1sRgqYXd7X29uLmJgYeHp6SunOzs6ora3F3bt3ERQUBI1GgytXrix7z5WMu5s3b2J8fBxhYWFISUlBbm4uduzYIctz9epVPHr0CB4eHggNDV3yXmsxNiwWC3JychAYGIj9+/dj9+7dsi3iiYjW2waxcIE0ERERERERLYszUkRERERERFZiIEVERERERGQlBlJERERERERWYiBFRERERERkJQZSREREREREVmIgRUREREREZCUGUkRERERERFZiIEVERERERGQlBlJERERERERWYiBFRERERERkJQZSREREREREVvoPQtJTnAw7hmUAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] @@ -542,7 +1069,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 24, "metadata": { "ExecuteTime": { "end_time": "2022-10-19T06:54:04.575097Z", @@ -557,7 +1084,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 25, "metadata": { "ExecuteTime": { "end_time": "2022-10-19T06:54:04.587450Z", @@ -569,7 +1096,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'angles': [1.0697214021077555, 2.66020191842812, 1.008830150888525, 1.1339416740189403], 'cost': 145.87999999999994, 'measurement_outcomes': Counter({'00111000': 4, '11011001': 4, '10100010': 3, '00010011': 3, '11111000': 3, '10000011': 3, '01110011': 3, '10101101': 2, '11101010': 2, '01011101': 2, '10101001': 2, '10011100': 2, '01001010': 2, '00110111': 2, '01111010': 2, '00000111': 2, '00100110': 2, '01010110': 2, '00011111': 2, '10000110': 2, '00010101': 2, '01100100': 2, '10010111': 1, '01010010': 1, '10000101': 1, '01110000': 1, '00001001': 1, '10110111': 1, '10100001': 1, '10010011': 1, '01010111': 1, '00101100': 1, '01101000': 1, '11100000': 1, '01001100': 1, '00010110': 1, '10011010': 1, '11101100': 1, '01101001': 1, '00101010': 1, '01010101': 1, '11101011': 1, '01100011': 1, '01111000': 1, '10110011': 1, '11101101': 1, '01001000': 1, '00110101': 1, '10111001': 1, '10001010': 1, '10101000': 1, '01010100': 1, '11101000': 1, '10001101': 1, '10001001': 1, '10100100': 1, '11001000': 1, '00110001': 1, '01111001': 1, '01110101': 1, '00101110': 1, '01101100': 1, '11010001': 1, '11110000': 1, '00001011': 1, '11010110': 1, '00100010': 1, '11010011': 1, '01101110': 1}), 'job_id': '413b5394-1f58-4404-8ba3-c969abe3dfbe', 'eval_number': 243}\n" + "{'angles': [2.42314122678, 2.046944474081], 'cost': 226.64, 'measurement_outcomes': Counter({'0111101': 14, '0001110': 12, '1110001': 10, '1000010': 8, '0001111': 5, '1001100': 5, '0110001': 4, '0101110': 4, '0000010': 3, '0110111': 2, '1010010': 2, '0001100': 2, '0111100': 2, '0000110': 2, '0011101': 2, '1010001': 2, '1000011': 2, '0101101': 2, '1111001': 2, '0101111': 1, '1101100': 1, '0111001': 1, '0101001': 1, '1001110': 1, '0111011': 1, '1110011': 1, '0111000': 1, '1000100': 1, '1011100': 1, '0110011': 1, '0001010': 1, '1110000': 1, '0010110': 1, '1111101': 1}), 'job_id': '3d562f4d-2e13-44ef-9a9b-5c672fe20fd6', 'eval_number': 77}\n" ] } ], @@ -579,7 +1106,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 26, "metadata": { "ExecuteTime": { "end_time": "2022-10-19T06:54:04.598220Z", @@ -590,10 +1117,10 @@ { "data": { "text/plain": [ - "{'solutions_bitstrings': ['00111000', '11011001'], 'bitstring_energy': 64.0}" + "{'solutions_bitstrings': ['0111101'], 'bitstring_energy': 256.0}" ] }, - "execution_count": 22, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -601,13 +1128,20 @@ "source": [ "opt_results.most_probable_states" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "OQ_reviews", "language": "python", - "name": "python3" + "name": "oq_reviews" }, "language_info": { "codemirror_mode": { @@ -619,7 +1153,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.10.0" }, "toc": { "base_numbering": 1, @@ -636,7 +1170,7 @@ }, "vscode": { "interpreter": { - "hash": "d2582286b70c3b030a2fde61b871db03dec7fee33191883f4394b540a2eb90c7" + "hash": "2374e833df7d90fe0779e245413a800a00448ba720136fdc7edf28b169de91eb" } } }, diff --git a/examples/04_qaoa_variational_parameters.ipynb b/examples/04_qaoa_variational_parameters.ipynb index 367791818..cf36aaaa5 100644 --- a/examples/04_qaoa_variational_parameters.ipynb +++ b/examples/04_qaoa_variational_parameters.ipynb @@ -689,7 +689,7 @@ "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "python3" + "name": "oq_reviews" }, "language_info": { "codemirror_mode": { diff --git a/examples/X_dumping_data.ipynb b/examples/X_dumping_data.ipynb index 83cc5fefa..870a86cce 100644 --- a/examples/X_dumping_data.ipynb +++ b/examples/X_dumping_data.ipynb @@ -68,19 +68,16 @@ "data": { "text/plain": [ "{'atomic_id': None,\n", - " 'experiment_id': '1fac3395-7ae8-4591-a5b8-02a1360cc003',\n", + " 'experiment_id': '907f60a2-5b6a-42b8-831b-4189988b3dc9',\n", " 'project_id': None,\n", " 'algorithm': 'qaoa',\n", - " 'name': None,\n", + " 'description': None,\n", " 'run_by': None,\n", " 'provider': None,\n", " 'target': None,\n", " 'cloud': None,\n", " 'client': None,\n", " 'qubit_number': None,\n", - " 'qubit_routing': None,\n", - " 'error_mitigation': None,\n", - " 'error_correction': None,\n", " 'execution_time_start': None,\n", " 'execution_time_end': None}" ] @@ -104,15 +101,12 @@ "# set the header\n", "q.set_header(\n", " project_id=\"8353185c-b175-4eda-9628-b4e58cb0e41b\", \n", - " name=\"test\", \n", + " description=\"test\", \n", " run_by=\"raul\", \n", " provider=\"-\", \n", " target=\"-\", \n", " cloud=\"local\", \n", " client=\"-\", \n", - " qubit_routing=\"-\", \n", - " error_mitigation=\"-\", \n", - " error_correction=\"-\"\n", " )\n" ] }, @@ -134,20 +128,17 @@ { "data": { "text/plain": [ - "{'atomic_id': '1272908f-ec6a-4274-9376-d3c1cc504a7e',\n", - " 'experiment_id': '1fac3395-7ae8-4591-a5b8-02a1360cc003',\n", + "{'atomic_id': '3022f14a-4900-47f5-9516-1d214003800a',\n", + " 'experiment_id': '907f60a2-5b6a-42b8-831b-4189988b3dc9',\n", " 'project_id': '8353185c-b175-4eda-9628-b4e58cb0e41b',\n", " 'algorithm': 'qaoa',\n", - " 'name': 'test',\n", + " 'description': 'test',\n", " 'run_by': 'raul',\n", " 'provider': '-',\n", " 'target': '-',\n", " 'cloud': 'local',\n", " 'client': '-',\n", " 'qubit_number': 9,\n", - " 'qubit_routing': '-',\n", - " 'error_mitigation': '-',\n", - " 'error_correction': '-',\n", " 'execution_time_start': None,\n", " 'execution_time_end': None}" ] @@ -182,22 +173,19 @@ { "data": { "text/plain": [ - "{'atomic_id': '1272908f-ec6a-4274-9376-d3c1cc504a7e',\n", - " 'experiment_id': '1fac3395-7ae8-4591-a5b8-02a1360cc003',\n", + "{'atomic_id': '3022f14a-4900-47f5-9516-1d214003800a',\n", + " 'experiment_id': '907f60a2-5b6a-42b8-831b-4189988b3dc9',\n", " 'project_id': '8353185c-b175-4eda-9628-b4e58cb0e41b',\n", " 'algorithm': 'qaoa',\n", - " 'name': 'test',\n", + " 'description': 'test',\n", " 'run_by': 'raul',\n", " 'provider': '-',\n", " 'target': '-',\n", " 'cloud': 'local',\n", " 'client': '-',\n", " 'qubit_number': 9,\n", - " 'qubit_routing': '-',\n", - " 'error_mitigation': '-',\n", - " 'error_correction': '-',\n", - " 'execution_time_start': 1673339931,\n", - " 'execution_time_end': 1673339931}" + " 'execution_time_start': '2023-02-03T03:49:22',\n", + " 'execution_time_end': '2023-02-03T03:49:22'}" ] }, "execution_count": 9, @@ -234,15 +222,13 @@ "# set the header\n", "q.set_header(\n", " project_id=\"8353185c-b175-4eda-9628-b4e58cb0e41b\", \n", - " name=\"test\", \n", + " experiment_id=\"8353185c-b175-4eda-9628-b4e58cb0e400\", \n", + " description=\"test\", \n", " run_by=\"raul\", \n", " provider=\"-\", \n", " target=\"-\", \n", " cloud=\"local\", \n", " client=\"-\", \n", - " qubit_routing=\"-\", \n", - " error_mitigation=\"-\", \n", - " error_correction=\"-\"\n", " )\n", "\n", "# set experimental tags \n", @@ -297,23 +283,28 @@ { "data": { "text/plain": [ - "{'atomic_id': 'c8496110-918b-4019-9295-0a448afc2608',\n", - " 'experiment_id': 'c85d2413-8c88-47a3-b86f-b8013c0bc93f',\n", + "{'atomic_id': 'c6e4df16-c0bc-43ea-b273-3d52fd73f15e',\n", + " 'experiment_id': '8353185c-b175-4eda-9628-b4e58cb0e400',\n", " 'project_id': '8353185c-b175-4eda-9628-b4e58cb0e41b',\n", " 'algorithm': 'qaoa',\n", - " 'name': 'test',\n", + " 'description': 'test',\n", " 'run_by': 'raul',\n", " 'provider': '-',\n", " 'target': '-',\n", " 'cloud': 'local',\n", " 'client': '-',\n", " 'qubit_number': 9,\n", - " 'qubit_routing': '-',\n", - " 'error_mitigation': '-',\n", - " 'error_correction': '-',\n", - " 'execution_time_start': 1673339932,\n", - " 'execution_time_end': 1673339932,\n", - " 'metadata': {'tag1': 'value1', 'tag2': 'value2'}}" + " 'execution_time_start': '2023-02-03T03:49:23',\n", + " 'execution_time_end': '2023-02-03T03:49:23',\n", + " 'metadata': {'tag1': 'value1',\n", + " 'tag2': 'value2',\n", + " 'problem_type': 'knapsack',\n", + " 'n_shots': 100,\n", + " 'optimizer_method': 'vgd',\n", + " 'jac': 'finite_difference',\n", + " 'param_type': 'standard',\n", + " 'init_type': 'rand',\n", + " 'p': 1}}" ] }, "execution_count": 14, @@ -477,320 +468,320 @@ " 'seed': None}},\n", " 'results': {'method': 'vgd',\n", " 'evals': {'number_of_evals': 77, 'jac_evals': 60, 'qfim_evals': 0},\n", - " 'most_probable_states': {'solutions_bitstrings': ['101010010'],\n", - " 'bitstring_energy': 66.0},\n", - " 'intermediate': {'angles': [[0.961598839379682, 2.786612782414809],\n", - " [0.961598839379682, 2.786612782414809],\n", - " [0.8778947093027151, 20.62296238008736],\n", - " [-1.3295727279988867, 393.3382878260254],\n", - " [-0.06387937446778147, 694.4894550827307],\n", - " [4.382383028198652, 499.5612609660036],\n", - " [4.034755897405481, 207.84620096901494],\n", - " [4.0438932149960385, 287.2731196952707],\n", - " [3.938054112152364, 320.2546238821633],\n", - " [1.1081218180471444, 565.5667660824683],\n", - " [1.6909504691660606, 453.72667276626476],\n", - " [1.7968190972488776, 445.6672666700563],\n", - " [3.473945011987886, 358.99267793942545],\n", - " [3.9620621476479903, 364.4638932026958],\n", - " [4.203098713387695, 377.5526974553138],\n", - " [4.162283648438566, 380.2026436339354],\n", - " [4.8367966885485805, 380.49080241131537]],\n", - " 'cost': [217.66678135369375,\n", - " 217.66678135369375,\n", - " 367.55919340954955,\n", - " 175.8201445779456,\n", - " 244.73332574020256,\n", - " 174.04193186722156,\n", - " 212.25448692503699,\n", - " 241.96335705258392,\n", - " 322.32590966722125,\n", - " 231.54724472313052,\n", - " 215.33642348798784,\n", - " 164.3343206429513,\n", - " 207.0467286939396,\n", - " 182.11550406056568,\n", - " 212.11088251151435,\n", - " 248.21045430023918,\n", - " 214.2806923658714],\n", + " 'most_probable_states': {'solutions_bitstrings': ['010100100'],\n", + " 'bitstring_energy': 4.0},\n", + " 'intermediate': {'angles': [[1.696394537853, 2.595712606584],\n", + " [1.696394537853, 2.595712606584],\n", + " [1.996119067834, -50.328769100425],\n", + " [1.64899721785, -385.694963130427],\n", + " [2.059630894828, -387.383627862428],\n", + " [2.718757856834, -353.098122162415],\n", + " [3.166788834826, -381.087060361417],\n", + " [3.182734816826, -381.245561721422],\n", + " [3.230430103835, -382.492231644428],\n", + " [0.774184417829, -445.031778234416],\n", + " [1.78247387985, -522.41038271442],\n", + " [2.477285593877, -511.188344804403],\n", + " [2.124756497872, -532.051847827383],\n", + " [2.324583746892, -612.776430421385],\n", + " [2.4102619469, -348.047678058386],\n", + " [2.325951441898, -281.10976680538],\n", + " [2.264961223895, 189.551090999621]],\n", + " 'cost': [215.036622653159,\n", + " 215.036622653159,\n", + " 227.373907240102,\n", + " 214.856475631767,\n", + " 196.698283560032,\n", + " 229.019841661881,\n", + " 216.530677718379,\n", + " 216.463567563053,\n", + " 240.337346150857,\n", + " 216.831565289346,\n", + " 208.609841808658,\n", + " 180.347792284209,\n", + " 209.704850720122,\n", + " 167.15172430448,\n", + " 192.608394059029,\n", + " 228.477166999451,\n", + " 191.279742660462],\n", " 'measurement_outcomes': [],\n", - " 'job_id': ['b339e282-1bbe-4ff2-8e8d-82cfca2bb915',\n", - " '850a5886-c76a-4fab-8f8a-941ba2b5d91d',\n", - " '42c6bd8b-1ef3-424f-8965-986ddd26dc2a',\n", - " '671762ed-f043-4b4a-8d36-43a4d04172d8',\n", - " '3fc2a92e-776a-437a-94cd-ab1548831fa0',\n", - " 'bafdc8da-2c9e-4e53-96de-f1616ce1d55f',\n", - " 'fe71c476-f4c4-4da5-8ee9-f1fc114675c5',\n", - " '70e8d4d7-7edc-4244-9a64-dd5a474e835f',\n", - " '4015ec5e-bd92-41e7-968b-0f8b7eb20550',\n", - " '1626ad8c-2528-4c5b-a261-5b9b2534111f',\n", - " 'c6ac3ce8-3137-4680-9355-b5acbbb14410',\n", - " '50f19698-03c9-49ce-81ad-7e44de613f27',\n", - " '74e647fd-525d-4a92-be09-c5827f00990a',\n", - " 'd82cc3bb-9535-4729-8e29-8faac09ae9f4',\n", - " '1230dadd-97b2-4a7d-9159-8332889ef0a5',\n", - " 'a5ef7c3c-39c3-44cf-a122-2c260d4266f6',\n", - " '8d83bc8e-7d51-458d-bf2b-a8e0e92cf3e9']},\n", - " 'optimized': {'angles': [1.7968190972488776, 445.6672666700563],\n", - " 'cost': 164.3343206429513,\n", - " 'measurement_outcomes': array([ 0.01619151-0.02864081j, 0.03024684+0.04614672j,\n", - " -0.0127619 +0.02493825j, -0.00318874-0.03090919j,\n", - " -0.01554524+0.05267722j, 0.03632544+0.02011092j,\n", - " -0.00543552-0.03138719j, 0.00273637-0.0165203j ,\n", - " 0.01070208+0.00074234j, -0.07984975+0.00034532j,\n", - " 0.00397966-0.02491389j, 0.05058108+0.01382725j,\n", - " -0.06871628+0.0016793j , 0.04418875+0.02874949j,\n", - " 0.06055318-0.03575926j, -0.02074348-0.00414534j,\n", - " -0.03719728-0.02985245j, -0.01133581+0.0448255j ,\n", - " 0.02340255+0.02059182j, 0.00559422-0.00242775j,\n", - " -0.01034938-0.01964009j, 0.01287315-0.05062488j,\n", - " 0.04535449+0.03687866j, -0.0303996 +0.04054481j,\n", - " 0.01729275-0.0614252j , -0.04656089+0.00855521j,\n", - " 0.04197644+0.06983273j, 0.00483728+0.00796475j,\n", - " 0.02977079-0.01481006j, -0.01585076-0.0338518j ,\n", - " 0.03087442+0.01450779j, 0.00591654+0.04195249j,\n", - " -0.03118636+0.01043138j, -0.01646663-0.03732331j,\n", - " 0.02112846-0.00781727j, -0.02076124-0.01798277j,\n", - " -0.03739527+0.05183181j, 0.02355193+0.00983103j,\n", - " 0.02724984-0.00739285j, 0.0027919 -0.01301383j,\n", - " 0.0177045 -0.05941735j, 0.05310731+0.01362334j,\n", - " -0.00123357+0.03715929j, 0.00251598-0.03235504j,\n", - " -0.06502303+0.03816643j, -0.00110178+0.05912931j,\n", - " 0.03637953-0.01005635j, 0.01879737-0.007679j ,\n", - " -0.05499735-0.03880723j, -0.03341435+0.00746296j,\n", - " 0.00558539+0.02383979j, 0.02067644+0.00632258j,\n", - " 0.02454549+0.00752596j, -0.05621771+0.0531319j ,\n", - " -0.0284444 -0.00042648j, 0.0409819 +0.00641302j,\n", - " -0.00426631-0.06940679j, -0.0622031 +0.01788358j,\n", - " -0.01341096+0.03855315j, 0.01913013+0.00597589j,\n", - " 0.03346488-0.00239782j, -0.01066825+0.03833332j,\n", - " -0.03473778+0.00795168j, -0.00539074-0.01979299j,\n", - " -0.01092558-0.03628224j, 0.01248454+0.03068853j,\n", - " -0.03606216-0.03896457j, -0.00090456+0.05181394j,\n", - " 0.01745515+0.00948952j, 0.03639558+0.01478903j,\n", - " 0.01396715+0.00028095j, 0.02409921-0.04117628j,\n", - " 0.0463994 +0.00802948j, -0.05828657+0.02024023j,\n", - " 0.03517111-0.0418634j , -0.05696188+0.0277151j ,\n", - " 0.01727359+0.0578283j , 0.01829263-0.01173621j,\n", - " 0.03188561+0.01596561j, -0.00268294-0.03813337j,\n", - " -0.02845314+0.00735274j, -0.00985907+0.02820307j,\n", - " -0.00383755+0.01508457j, 0.03503879+0.0221902j ,\n", - " -0.04166655+0.05486914j, -0.01188239-0.05983595j,\n", - " 0.033857 +0.04624715j, -0.01739782-0.05313528j,\n", - " -0.05870573+0.03456085j, -0.0185342 -0.00731106j,\n", - " 0.00628612+0.02882146j, 0.00347523-0.00938895j,\n", - " -0.00057942+0.0330614j , -0.05095123-0.01133002j,\n", - " 0.00839542-0.01230667j, -0.02919776+0.0252997j ,\n", - " -0.010452 -0.00490611j, 0.02041669-0.03557304j,\n", - " -0.05505414-0.02688393j, -0.01554177+0.00459173j,\n", - " -0.02058219+0.04465779j, -0.00335216+0.01472846j,\n", - " 0.02320418+0.03339113j, -0.03170138+0.04406404j,\n", - " -0.00253116-0.03540805j, 0.02836155+0.01142426j,\n", - " -0.01656487-0.07078843j, -0.04707658+0.00601723j,\n", - " -0.01622444+0.04126663j, -0.02207982+0.03867694j,\n", - " 0.02929103+0.01789723j, -0.01277355+0.03575851j,\n", - " -0.03610236-0.02333366j, -0.01141035-0.01067738j,\n", - " -0.02321354+0.01197148j, -0.03655455-0.05886434j,\n", - " 0.02486109-0.00761777j, -0.02739347+0.0176754j ,\n", - " 0.06022808-0.01381799j, -0.02416424-0.05970473j,\n", - " -0.01916964-0.0374955j , -0.03477653-0.01429797j,\n", - " -0.00450347-0.00807422j, -0.05741806-0.02420446j,\n", - " 0.00469823-0.04143753j, -0.0022936 +0.00495381j,\n", - " -0.02745295-0.02963354j, -0.01400342+0.02453825j,\n", - " -0.01419618+0.04300912j, -0.04932915-0.01971552j,\n", - " 0.01276586-0.02166532j, -0.01770053+0.00042018j,\n", - " 0.00744529+0.04587568j, 0.0105917 -0.01716598j,\n", - " 0.01201879-0.01786026j, -0.02009802-0.00553431j,\n", - " -0.03945953-0.05753372j, 0.0685039 -0.03730846j,\n", - " 0.02563777+0.03613274j, -0.02273865-0.02326882j,\n", - " 0.00012347+0.05534189j, 0.0269911 +0.03675309j,\n", - " 0.00340065-0.02165871j, 0.0040548 -0.01393614j,\n", - " -0.04827113+0.01724542j, -0.0151045 +0.01810105j,\n", - " 0.01316847+0.00524219j, 0.01933238-0.02182597j,\n", - " 0.03826391-0.01336213j, 0.00240341+0.09605579j,\n", - " -0.03656572+0.01371532j, 0.03631675-0.02981574j,\n", - " -0.03769923-0.02875078j, -0.0156658 +0.05301197j,\n", - " 0.00366575+0.02249685j, 0.01504244-0.0164721j ,\n", - " 0.02231575-0.0249529j , 0.03526177+0.04489523j,\n", - " -0.02340774+0.03325958j, -0.01899506-0.02088103j,\n", - " 0.01100391-0.03677736j, 0.01255529+0.00348103j,\n", - " -0.00717065-0.02720427j, -0.04790626+0.02036757j,\n", - " -0.00191998+0.03804899j, 0.01177486+0.04123584j,\n", - " 0.02770988+0.00156626j, 0.07069775+0.01568347j,\n", - " 0.02723347+0.03487347j, -0.04401486-0.00240086j,\n", - " 0.01590828-0.02033747j, -0.04196795-0.01649352j,\n", - " -0.05642681+0.04821123j, 0.01626427+0.02706101j,\n", - " 0.03496796+0.01041992j, 0.04812754-0.01240074j,\n", - " -0.04001003-0.03084082j, -0.02531331+0.00321283j,\n", - " -0.00049332+0.03148536j, -0.03096693+0.05731175j,\n", - " -0.06857302-0.00783978j, 0.00847303-0.04788617j,\n", - " 0.02161936+0.02803437j, 0.00495575-0.02304873j,\n", - " -0.05638843-0.05042687j, -0.03439543-0.01951046j,\n", - " 0.00046795+0.02854154j, -0.00651783+0.0311373j ,\n", - " -0.03172336+0.00993489j, -0.0367455 -0.04879769j,\n", - " -0.00125985-0.01818764j, -0.02333326+0.01357364j,\n", - " -0.01123803+0.01604682j, -0.00852075-0.03769102j,\n", - " -0.04300865+0.02553961j, -0.00997428+0.00126163j,\n", - " 0.01691319+0.03916886j, -0.00134851-0.00037501j,\n", - " 0.04574227+0.00296095j, 0.01288368+0.07114118j,\n", - " -0.04005447-0.02169991j, 0.0395108 -0.01004487j,\n", - " -0.05570612-0.02272316j, -0.01876648+0.02790827j,\n", - " 0.01823866+0.02365544j, 0.00700955+0.03954118j,\n", - " 0.03219734-0.0137583j , 0.031357 +0.04212761j,\n", - " -0.03325409+0.01081756j, -0.00528341-0.00335335j,\n", - " -0.00691017+0.03471814j, -0.08354702-0.01191482j,\n", - " 0.01880585-0.0362936j , -0.00663812+0.04568657j,\n", - " 0.0205063 -0.04513603j, -0.05138129-0.01363715j,\n", - " -0.02631422-0.01548596j, -0.02618467+0.01793138j,\n", - " -0.00485797+0.00318318j, -0.05970644+0.03533922j,\n", - " -0.02782153-0.03608164j, 0.01574167+0.00845125j,\n", - " -0.03651857-0.00137162j, 0.00517894+0.0175688j ,\n", - " 0.03770208-0.02123496j, -0.02223873-0.04485772j,\n", - " -0.02545104-0.01475045j, -0.01419319+0.01697418j,\n", - " -0.0276847 +0.02483538j, -0.01660784+0.06854972j,\n", - " -0.04902014+0.00613643j, -0.00428373-0.05212332j,\n", - " 0.01899058+0.01281767j, 0.00675345-0.05531301j,\n", - " -0.0368599 -0.04371215j, -0.0112379 +0.00112098j,\n", - " -0.05164693+0.02391172j, 0.00092298+0.038557j ,\n", - " -0.03753574+0.01178676j, -0.05213956-0.03119872j,\n", - " -0.01121318-0.0310729j , -0.0489162 -0.02954268j,\n", - " 0.02047975-0.06398136j, 0.04837707-0.00382246j,\n", - " -0.01923332-0.00494717j, 0.04114758-0.00668754j,\n", - " 0.03845296-0.05977569j, -0.00090683-0.01595412j,\n", - " -0.01556035-0.04823021j, -0.01588485-0.02432548j,\n", - " -0.01462986-0.06444388j, 0.03061584-0.03979476j,\n", - " -0.00046712-0.01156166j, -0.0093988 -0.03342147j,\n", - " -0.02803502+0.00621835j, 0.02236207+0.02686271j,\n", - " -0.02496765+0.01604619j, 0.01553567-0.02108329j,\n", - " -0.05707342+0.01506893j, 0.0548755 +0.02928323j,\n", - " 0.00492488-0.02688902j, 0.01076174-0.01671569j,\n", - " 0.00187519-0.00545455j, -0.0223956 -0.04991441j,\n", - " 0.01156897-0.02691035j, 0.03231566+0.03761007j,\n", - " -0.03952859-0.0532555j , -0.00170461+0.07305461j,\n", - " 0.06467723-0.01162153j, -0.01756766-0.01111438j,\n", - " 0.0134717 -0.01181794j, -0.04301657-0.02138505j,\n", - " 0.01178602+0.02433131j, 0.00866935+0.00334104j,\n", - " 0.01047471-0.00423091j, 0.04478105-0.01498652j,\n", - " 0.03274415+0.04691524j, -0.04705719+0.01919723j,\n", - " 0.05347594-0.03817592j, -0.06082138-0.00898172j,\n", - " 0.01593357+0.07348573j, -0.00294283+0.00805411j,\n", - " 0.01054109-0.02033823j, -0.00030828-0.01153934j,\n", - " 0.02316631+0.02269984j, -0.01081446+0.04107056j,\n", - " -0.03226496-0.0123943j , 0.01509379+0.03488603j,\n", - " 0.01362887+0.00456387j, -0.01267736-0.0273492j ,\n", - " -0.05249263+0.04507485j, 0.00608669+0.01004549j,\n", - " 0.02817032+0.00865874j, 0.01157841-0.00504761j,\n", - " 0.04945042-0.00120331j, 0.02944096+0.04234346j,\n", - " -0.01999479+0.02505362j, 0.01803191-0.02233439j,\n", - " -0.0821567 -0.02112283j, -0.00647222+0.04691662j,\n", - " 0.03386807+0.00530731j, 0.02114895+0.00927213j,\n", - " 0.02946422-0.02513466j, 0.02852032+0.0325991j ,\n", - " -0.00949946+0.02261117j, 0.00711874+0.01401294j,\n", - " -0.00417918+0.03425677j, -0.06386875+0.01423293j,\n", - " -0.02084647-0.01648931j, 0.02266212+0.02508074j,\n", - " 0.0186066 -0.07089237j, -0.06696623+0.00741344j,\n", - " -0.02676529+0.0233774j , 0.00350697+0.01682622j,\n", - " -0.00526893-0.00362493j, -0.05120103+0.04687009j,\n", - " -0.03620315-0.00532771j, 0.00217537-0.01408061j,\n", - " -0.04310225+0.01218775j, 0.01857094+0.02692264j,\n", - " -0.01630167-0.05233033j, -0.01949708+0.04939053j,\n", - " 0.02574362+0.00692809j, 0.00509358-0.01354842j,\n", - " 0.01680178+0.00891205j, 0.03558159-0.02397399j,\n", - " 0.03057262+0.0157384j , -0.05270557+0.03887628j,\n", - " 0.05351103-0.01670189j, -0.0691916 +0.00172516j,\n", - " 0.02124039+0.06760763j, -0.00661537-0.0272125j ,\n", - " 0.02356188+0.03511964j, 0.01489749-0.03208308j,\n", - " 0.00249268+0.02458863j, 0.01755715+0.04868441j,\n", - " -0.01665863+0.0139209j , 0.02145433+0.03121488j,\n", - " -0.04341415+0.02291248j, -0.0195956 -0.05191143j,\n", - " -0.00028844+0.06155794j, 0.00755135-0.06192942j,\n", - " -0.08680367+0.03315639j, 0.03100781-0.01015304j,\n", - " -0.01571087+0.03429425j, 0.00194151-0.00980569j,\n", - " -0.03710066+0.0410235j , -0.03673783-0.00812171j,\n", - " 0.01477733-0.00103556j, -0.04170455+0.00594863j,\n", - " 0.03860916+0.0349083j , -0.01307116-0.04128192j,\n", - " -0.04079653-0.04500441j, -0.01515827-0.00295714j,\n", - " 0.00875183+0.01630399j, -0.01311407+0.02131166j,\n", - " 0.00289006+0.0390965j , -0.04780896+0.03176401j,\n", - " -0.03865001-0.03983371j, -0.00582309+0.02276175j,\n", - " 0.01266307-0.07315621j, -0.04500038-0.00924181j,\n", - " 0.00610062+0.01913954j, -0.01369122+0.02157298j,\n", - " 0.01266587+0.03193608j, -0.02810716+0.02982438j,\n", - " -0.05179687+0.01642839j, -0.00024993-0.01539805j,\n", - " -0.02523371-0.003275j , -0.01456154-0.07170687j,\n", - " 0.03327597-0.03339071j, -0.03174141-0.0158757j ,\n", - " 0.0611005 +0.01046564j, -0.00389254-0.06530761j,\n", - " -0.02281002+0.00701214j, -0.02197854-0.01740589j,\n", - " -0.00232566-0.0161757j , -0.04590735-0.04561326j,\n", - " -0.00841646-0.03159762j, 0.00914521+0.00733645j,\n", - " -0.00870691-0.03960435j, -0.02135533+0.01825103j,\n", - " 0.04513114+0.01356032j, 0.01495047+0.00332904j,\n", - " 0.01736457-0.00569451j, -0.02125895-0.00875104j,\n", - " 0.00505473+0.05887162j, -0.0043524 +0.00581102j,\n", - " 0.02170115-0.01102244j, -0.00869805-0.01219931j,\n", - " 0.0324578 -0.04513198j, 0.06990196+0.00805597j,\n", - " 0.00115597+0.04016528j, -0.00336198-0.02955932j,\n", - " -0.05470451+0.04374659j, 0.02159249+0.02649149j,\n", - " 0.011211 -0.0176539j , 0.01642846-0.00718023j,\n", - " -0.00091474-0.0443259j , 0.0565304 -0.00959064j,\n", - " 0.00771475+0.01420607j, 0.01969485-0.00508485j,\n", - " 0.03234348+0.03175687j, -0.03659485+0.07336443j,\n", - " -0.03739799-0.00692205j, 0.03964226-0.00037027j,\n", - " -0.03281666-0.04614828j, -0.03043379+0.0497555j ,\n", - " -0.00767661+0.01917935j, 0.01706459+0.00264055j,\n", - " 0.00710418+0.00295848j, 0.0079374 +0.07704732j,\n", - " -0.03392198+0.02258024j, -0.00477764-0.02074554j,\n", - " -0.0152423 +0.03339997j, 0.02494633+0.00545277j,\n", - " 0.00442054-0.02984467j, -0.0480286 +0.00026998j,\n", - " -0.00951317+0.01533874j, 0.02868967-0.0122037j ,\n", - " 0.02175685+0.02016739j, 0.05260649+0.04566206j,\n", - " -0.01442629+0.05100943j, -0.0711367 +0.01254532j,\n", - " 0.01959202-0.00799126j, -0.03484912-0.03258591j,\n", - " -0.047762 +0.01874423j, 0.01601171-0.00458178j,\n", - " 0.02039265+0.03076571j, 0.04489711+0.01396441j,\n", - " -0.00836286+0.04661723j, -0.04620256+0.0519877j ,\n", - " -0.01991699+0.02033497j, -0.05161544+0.0345774j ,\n", - " -0.05264435-0.04157863j, 0.00260398-0.06649838j,\n", - " -0.00023709+0.02637427j, 0.01513518-0.02338415j,\n", - " -0.04372206-0.05323457j, 0.00038937+0.00306824j,\n", - " -0.02138628+0.01791709j, -0.0230867 +0.01876317j,\n", - " -0.07225605-0.01554793j, -0.03290983-0.04653542j,\n", - " 0.00123835-0.01438916j, -0.02699701-0.00320724j,\n", - " -0.00972243+0.02909854j, 0.02048767-0.01979863j,\n", - " -0.04914653+0.00872712j, -0.00860888-0.00461721j,\n", - " 0.01880486+0.00116633j, 0.0156254 +0.01561811j,\n", - " 0.03634708+0.02316581j, -0.0147329 +0.07285504j,\n", - " -0.05954412-0.00083179j, 0.0144249 +0.0217751j ,\n", - " -0.04449373-0.04547667j, -0.02316331+0.02062563j,\n", - " 0.01469298-0.00550095j, 0.01530866+0.02164255j,\n", - " 0.03303754+0.00628314j, 0.01177328+0.05327176j,\n", - " -0.02500874+0.04771406j, -0.01156037-0.01397516j,\n", - " -0.02146099+0.02532025j, -0.07620738-0.0426547j ,\n", - " 0.00754089-0.04885412j, -0.03175946+0.01682308j,\n", - " 0.03909851-0.03528757j, -0.04606685-0.02769845j,\n", - " 0.00640871+0.01463272j, -0.0239384 +0.01066616j,\n", - " -0.00986099-0.00385625j, -0.06998404+0.0110299j ,\n", - " -0.02642496-0.02645759j, 0.01618326-0.00036893j,\n", - " -0.03206338-0.02152906j, 0.00015552+0.01894648j,\n", - " 0.02639002-0.02958574j, 0.00789508-0.00529591j,\n", - " -0.0176853 -0.02448531j, -0.02804227+0.00765134j,\n", - " -0.03879306+0.01014687j, -0.06920041+0.03614348j,\n", - " -0.05174603-0.01202422j, 0.01856117-0.04762491j,\n", - " -0.01242017-0.00372691j, 0.04567685-0.05177898j,\n", - " -0.01907424-0.05273683j, -0.01386202-0.00701015j,\n", - " -0.03505736+0.00973954j, -0.04581656+0.02354226j,\n", - " -0.04420427-0.00413388j, -0.03826318-0.04862974j,\n", - " -0.00104144-0.0189931j , -0.02288811-0.0313017j ,\n", - " 0.04365924-0.05721453j, 0.04367138+0.01402919j,\n", - " -0.00045259-0.03155676j, 0.02163468+0.02321569j,\n", - " 0.05647199-0.0447728j , 0.00659291-0.01860098j,\n", - " -0.01111806-0.03654456j, -0.03532952-0.03219077j,\n", - " 0.01120632-0.069278j , 0.04425755-0.02777196j,\n", - " 0.00536805+0.00566116j, 0.01676278-0.0064611j ,\n", - " -0.02676764-0.00315392j, 0.01340241+0.03431843j,\n", - " 0.01978686+0.02822087j, 0.04342908+0.03629703j]),\n", - " 'job_id': '50f19698-03c9-49ce-81ad-7e44de613f27',\n", - " 'eval_number': 12}}}" + " 'job_id': ['7e268f06-6259-4665-b73d-77aa9bc52f48',\n", + " 'fdd97f20-11f4-4207-b2dd-f426e06cbccb',\n", + " '278edfa5-05c6-459c-b90e-3287574c81c7',\n", + " 'e40b57a0-31f9-4c7c-bd79-7d49dff06614',\n", + " '4d3193fe-58cc-4943-8a5c-fad7fc679ae3',\n", + " '9f6a24b4-26a6-4c98-9973-df88064dc8ef',\n", + " '4d00c5b2-3afa-4436-97bb-94eac763d4a8',\n", + " '076a3f72-5612-4749-b7f5-4c03fbfb731c',\n", + " '7bd1f184-a1a9-4f95-9144-14db36c60cd7',\n", + " 'a18784bb-cf17-4286-a19a-97c58b86b760',\n", + " 'eff50f77-0224-409f-83c0-504219e4d580',\n", + " 'b0c20a57-28b8-4435-bc1b-a3b684f5f187',\n", + " 'aa3ca3ae-9046-4721-98eb-09e29d29e9ae',\n", + " '8646cd83-af5e-4a38-b49e-0a5b6f025963',\n", + " '38c159dc-6910-4b8e-83b5-d277eaf40c86',\n", + " '7423e07b-d4f1-47ea-a9ee-505622e59fcd',\n", + " '5dbce945-3340-4fba-9048-f9edcaffc46e']},\n", + " 'optimized': {'angles': [2.324583746892, -612.776430421385],\n", + " 'cost': 167.15172430448,\n", + " 'measurement_outcomes': array([ 1.47465215e-02-2.00730828e-02j, -7.27171252e-03-3.81774001e-03j,\n", + " 5.02878963e-02-2.65685629e-02j, -1.54756068e-02+7.92107431e-03j,\n", + " 1.11028554e-02-4.17034895e-02j, -6.91502249e-03+7.06052023e-03j,\n", + " -9.37592355e-03+7.52398779e-03j, 2.57997597e-03+1.42141931e-02j,\n", + " -2.73677076e-02-4.45385159e-02j, -1.63426856e-02+4.68385544e-02j,\n", + " 6.28607919e-02+1.19923003e-01j, -2.10790239e-02-1.19611313e-02j,\n", + " 8.64608059e-03-4.65860748e-03j, -7.72493413e-04-1.29581738e-03j,\n", + " -3.23329692e-02-1.70234391e-02j, 1.49656662e-02+1.41915070e-02j,\n", + " 2.19894317e-02-5.36895028e-02j, -1.45819036e-02+1.17782404e-02j,\n", + " 1.16427617e-02+9.93279587e-03j, -3.67046308e-03+1.91458112e-02j,\n", + " 1.08830831e-02-1.68886025e-02j, -1.38382809e-02+1.89022477e-02j,\n", + " 1.19595890e-02+3.34321684e-02j, -5.94743409e-04+6.49380526e-03j,\n", + " -2.31072850e-02-3.83382929e-02j, -1.37272572e-02+1.98664577e-02j,\n", + " 1.97961888e-02+3.52051356e-02j, 2.38625750e-03+1.39374913e-02j,\n", + " -6.77232976e-02-5.25186288e-02j, -2.01664837e-02+1.56394293e-02j,\n", + " 8.99314891e-02+3.28011206e-02j, -1.37331553e-02+1.01237333e-02j,\n", + " 6.97833071e-03-1.53079773e-02j, 2.54954154e-02-1.33329052e-02j,\n", + " 7.31746662e-03-9.85964688e-04j, 1.64551173e-02+1.17486265e-03j,\n", + " 4.15604484e-04-9.81202924e-03j, 1.00474076e-02-6.96651354e-03j,\n", + " -1.67328548e-03+1.57905074e-02j, -1.09714119e-03-2.99596243e-03j,\n", + " -3.00048738e-02+2.99235713e-02j, -7.51546465e-03-1.73230416e-03j,\n", + " -4.18326843e-03+2.99113370e-02j, -1.25754795e-02+3.48129251e-03j,\n", + " 6.08007092e-03-4.11795950e-04j, 1.11796054e-02+6.89418359e-03j,\n", + " 2.43283315e-03+8.52747583e-03j, -2.68620926e-03-5.54388506e-04j,\n", + " 2.30104870e-03-9.90707728e-03j, 2.72407394e-02-8.61461824e-03j,\n", + " 7.12450875e-04+2.20935787e-02j, 3.71762393e-03-1.17061924e-03j,\n", + " -2.74199687e-03+1.48595069e-02j, 2.35328028e-02+6.17808807e-03j,\n", + " 2.02081281e-03+1.93821295e-02j, -2.71296061e-03+3.96908310e-03j,\n", + " -1.89898282e-02+7.99520308e-03j, 9.56251920e-03+5.87655356e-03j,\n", + " 7.54771787e-03+2.65918528e-02j, -2.21599821e-03+9.76929043e-04j,\n", + " -4.24422116e-02-4.65074258e-03j, 3.61989923e-03-2.54103171e-03j,\n", + " 2.12854870e-02+2.20052602e-02j, 1.39700506e-02+1.28357677e-03j,\n", + " 4.21874063e-02-3.56457196e-02j, -1.56257399e-02+1.38648686e-02j,\n", + " -4.22489947e-02-1.21861680e-02j, 8.21416024e-03+2.30768559e-02j,\n", + " 6.72247043e-03+1.62232554e-02j, -8.34832455e-04+4.12150747e-03j,\n", + " 3.72299563e-02+6.71772298e-02j, -1.85773775e-03-3.65301468e-02j,\n", + " -1.59910422e-04+5.23805017e-02j, -1.31440361e-02+2.50627187e-02j,\n", + " -1.45048736e-01-1.55908781e-01j, 4.02545997e-02+6.30286068e-02j,\n", + " 1.11865111e-02-1.06335635e-02j, -4.16589612e-03+1.42069702e-02j,\n", + " 1.16199194e-01+2.45851501e-02j, -5.30825335e-02+6.57110494e-04j,\n", + " 3.07755324e-02-1.78429854e-03j, -1.52914681e-02+2.39028242e-02j,\n", + " 3.41827474e-02+1.69196990e-02j, -1.64978239e-02+3.26008841e-03j,\n", + " 2.86958921e-02-1.91112525e-02j, -2.46538303e-02+4.46989423e-02j,\n", + " 3.87086347e-02-1.38531472e-01j, -5.29076729e-02+9.38330847e-02j,\n", + " 3.58335093e-02+9.93544458e-03j, -1.98057393e-02+2.98513285e-02j,\n", + " 7.26167605e-02-3.86917373e-02j, -4.80561310e-02+2.75289028e-02j,\n", + " 7.18126760e-02+4.47713464e-03j, -2.95623853e-02+2.19635300e-02j,\n", + " 1.73764527e-02-4.01138688e-02j, -2.38486914e-02+2.15428446e-02j,\n", + " 7.79948615e-03-1.61912063e-03j, 2.67307039e-02-8.90103049e-03j,\n", + " -5.74107570e-03+1.25091648e-02j, 3.90667193e-03-1.87113101e-02j,\n", + " 7.32874845e-03+8.67593367e-03j, 1.78351561e-02-3.38574633e-03j,\n", + " 2.73197585e-02-1.12419556e-02j, 4.46217567e-02+4.77303618e-03j,\n", + " -1.90486676e-02+4.29842785e-02j, -1.27086122e-02+1.79046076e-03j,\n", + " -8.62315534e-03+9.57571935e-03j, 7.46192062e-03-1.58561502e-03j,\n", + " -6.45571784e-04+1.26343364e-02j, 7.53158871e-04+6.36343971e-03j,\n", + " -1.36953398e-02+1.22453165e-02j, -8.06898043e-04+1.33518273e-02j,\n", + " 2.62834414e-03+2.22982274e-02j, 2.42771571e-02-2.08174834e-03j,\n", + " 6.08245599e-03+1.02908991e-02j, 3.23600835e-02+4.19195298e-03j,\n", + " -1.95118959e-02+4.06153914e-02j, -8.33734964e-03+1.00283435e-02j,\n", + " -5.60974476e-02+4.80143430e-02j, -3.90077674e-02+1.21475653e-02j,\n", + " -5.39816863e-03+3.46852342e-02j, 1.01629794e-02+5.72171498e-03j,\n", + " -1.47899496e-02+1.54119845e-02j, 2.68714090e-02+7.42271554e-03j,\n", + " 8.21919227e-03+2.15433521e-02j, 4.08463995e-02-4.34826333e-03j,\n", + " 7.18985580e-03+1.43925463e-03j, 7.43681252e-02-1.73119288e-02j,\n", + " -4.34859108e-05-1.10521008e-02j, 2.75777080e-02-2.27661165e-02j,\n", + " -5.26463420e-03+5.93397228e-03j, 1.17084369e-02+1.59874600e-02j,\n", + " -3.15092217e-03-2.19577693e-03j, 1.17356686e-02-1.30641593e-02j,\n", + " 1.00223913e-03+1.57467688e-02j, 1.82885975e-03+1.42268619e-03j,\n", + " -2.26264948e-02+3.64684873e-02j, -4.97110178e-03-1.50660171e-02j,\n", + " -9.70305084e-03+7.55755424e-03j, 4.95293891e-03-1.14245153e-03j,\n", + " 3.51118266e-03-7.76279793e-04j, 1.68632953e-02+7.59499847e-03j,\n", + " 7.36298580e-03+1.08454397e-02j, -1.15889696e-02-4.41845666e-03j,\n", + " -5.32133274e-03-8.87114995e-04j, 3.41305031e-02-2.08607903e-02j,\n", + " -1.79788083e-03+2.20791411e-02j, 2.17562619e-03+7.97124546e-03j,\n", + " -6.46530162e-03+1.53952802e-02j, 3.54201662e-02-2.81751413e-03j,\n", + " -4.86181830e-04+1.25369704e-02j, -1.01050187e-02+2.80848409e-03j,\n", + " -1.48366844e-02+1.31746517e-02j, 1.85583462e-02+9.18019641e-05j,\n", + " 4.18712028e-03+1.89443095e-02j, -6.93525826e-03-5.65224739e-03j,\n", + " -2.99616996e-02+4.83108799e-03j, 1.03885447e-02-9.00282653e-03j,\n", + " 2.35047262e-03+1.52704884e-02j, 7.94695437e-03-1.27389574e-03j,\n", + " 2.56148125e-02-5.84008727e-03j, -7.47742519e-03+5.69217272e-02j,\n", + " 2.53372939e-02-1.49816594e-02j, 4.49740124e-02-9.83668982e-02j,\n", + " 9.48493223e-03-3.71150927e-03j, -4.45836217e-03+2.80588084e-02j,\n", + " -4.64231508e-03-7.21970281e-03j, -2.01935680e-02-4.07089644e-02j,\n", + " -1.25936227e-02+8.69486453e-03j, 4.96080773e-05+3.37627515e-02j,\n", + " -2.74493498e-02+1.47578255e-02j, -8.36917529e-02+4.01197596e-02j,\n", + " 6.65515296e-03+6.23309482e-03j, -3.23307903e-02-4.67428939e-03j,\n", + " 4.04925889e-03+2.52880439e-03j, 3.80082606e-02+9.84112436e-03j,\n", + " 2.29520799e-02-1.09561550e-04j, -2.85237214e-02+5.76378034e-02j,\n", + " 6.17957707e-03-9.77766397e-03j, 1.33308291e-02-7.42388186e-02j,\n", + " 1.33185917e-02+1.42645314e-02j, -5.71024777e-02+3.12101395e-02j,\n", + " 5.06704951e-03+7.44335284e-03j, 4.52700173e-02+1.26457815e-03j,\n", + " -4.11771488e-04+9.47738338e-03j, -3.97407119e-02+1.29787796e-02j,\n", + " 3.20185117e-03+9.82743773e-03j, 2.55655691e-02+2.63217143e-02j,\n", + " -6.96916351e-03+3.47375984e-04j, -2.10789993e-02+2.21517453e-02j,\n", + " 2.57665030e-02+6.01451847e-03j, 4.97858668e-02+3.79690717e-03j,\n", + " -4.30355953e-03+7.18507415e-03j, 2.69156975e-02-3.07549814e-03j,\n", + " 3.66971940e-03+1.52972200e-02j, 1.74769019e-02-3.51322674e-02j,\n", + " 2.54364376e-03+6.44936315e-03j, 1.41690770e-02-2.39772223e-03j,\n", + " 9.03994092e-03-2.50744146e-02j, 2.40997186e-02+9.38007479e-04j,\n", + " -1.42647324e-02+3.18811309e-02j, -2.94329770e-03-9.83279101e-03j,\n", + " 1.18534769e-02+3.58049562e-02j, -1.86934769e-02-1.03409945e-02j,\n", + " -2.59085729e-03+1.24990560e-02j, -6.82446744e-05+8.38342219e-04j,\n", + " -3.09886017e-02+5.28446831e-03j, 1.64233104e-02+8.43475255e-03j,\n", + " -6.60213497e-03+2.27316153e-02j, 2.41879389e-02-3.84014598e-03j,\n", + " -5.81723386e-03+3.31690175e-03j, 3.01638038e-02-1.51669609e-02j,\n", + " -2.04537547e-02+4.04361590e-02j, 1.83380771e-03-3.54866841e-03j,\n", + " -4.82659212e-02+6.70877702e-02j, -7.37538613e-04-1.51515280e-02j,\n", + " -1.26070568e-02+3.02334557e-02j, 1.10589461e-02-5.59624831e-03j,\n", + " -3.09035479e-02+2.01979760e-02j, 3.30738538e-02-1.89956850e-04j,\n", + " -1.21667036e-02+2.06695222e-02j, 3.50105700e-02-9.58090646e-03j,\n", + " -9.99287156e-03+1.14958727e-02j, 6.76510699e-02-1.78813403e-02j,\n", + " 3.06094508e-02-1.72743518e-02j, 1.37602500e-02-5.21305515e-02j,\n", + " -1.23203497e-02-4.37100370e-03j, -9.28493136e-02+7.38594119e-02j,\n", + " 2.28769734e-02-3.52078141e-03j, 2.24125421e-02-1.20615214e-02j,\n", + " 6.98874504e-02+1.33171374e-02j, 1.25056855e-01+5.51347845e-02j,\n", + " -2.37355948e-02+1.61878987e-02j, -4.58167681e-02+4.55007639e-02j,\n", + " 2.53558071e-02-1.29454210e-03j, 1.15547225e-01-9.91101530e-03j,\n", + " 2.04836251e-03+1.16481887e-02j, 9.53843870e-03+1.88209268e-02j,\n", + " -1.15781799e-02+1.99087508e-02j, -4.86721094e-02+2.77861289e-02j,\n", + " 2.73254645e-02-5.58241644e-04j, 1.54506061e-02-1.64458096e-02j,\n", + " 3.79059905e-02+2.48073630e-02j, 2.89491853e-02+1.08657313e-01j,\n", + " -1.79272251e-02+2.27141328e-02j, -3.58168759e-02+3.69799041e-02j,\n", + " -7.82987116e-02+3.09715749e-02j, -1.76354388e-01+7.20856277e-02j,\n", + " 1.14260482e-02+1.78511443e-02j, 1.44507463e-02+3.65504769e-02j,\n", + " 2.60877909e-02+1.29371708e-02j, 1.13883920e-02+1.42429436e-02j,\n", + " 5.28823227e-02+1.00319891e-03j, 6.36117743e-02+4.55500886e-03j,\n", + " 8.62920727e-02-1.99040003e-02j, 6.18266404e-02-2.71251974e-02j,\n", + " -2.83918687e-02+2.05261651e-02j, -2.77665677e-02+3.16633245e-02j,\n", + " -8.57591870e-03+1.47644855e-02j, 1.08013327e-02+4.57776564e-03j,\n", + " -1.31116385e-02-7.39342880e-02j, 5.87322732e-02-3.75894812e-02j,\n", + " -1.49958739e-02+4.99116238e-02j, 7.58387702e-04-6.62729261e-03j,\n", + " 8.04145045e-02-5.64530448e-02j, 2.11375016e-02-8.47707767e-02j,\n", + " 2.99237045e-02+5.01584527e-02j, 6.70283741e-03-4.07780481e-02j,\n", + " -5.56358937e-02+1.86535871e-02j, -2.34103928e-03+9.00779161e-03j,\n", + " -6.60201638e-03+7.25606432e-03j, 3.68259484e-03+9.28348635e-04j,\n", + " -2.60882622e-02-4.01103362e-02j, 3.42400645e-02-1.96655724e-02j,\n", + " -2.07572851e-02+5.87720064e-02j, 1.13914876e-02-1.04809320e-02j,\n", + " -1.65762127e-02+8.03477057e-02j, -4.71046974e-02+1.45907916e-02j,\n", + " -1.30344617e-03+1.32733357e-02j, 1.90468049e-02-1.65569800e-02j,\n", + " -7.81838367e-02-3.27323735e-02j, 1.23386352e-03-2.13701529e-02j,\n", + " 3.14244375e-02+4.76929879e-02j, 1.33527074e-02-1.71549108e-02j,\n", + " -1.46896682e-01-8.45547298e-02j, -1.15208870e-02-3.52714687e-03j,\n", + " 8.41720613e-02+6.58992551e-02j, 2.03998297e-02-1.29037389e-02j,\n", + " -3.35849995e-02+3.82414785e-02j, 1.58917068e-02+2.49328955e-03j,\n", + " -1.21313240e-03+1.37036698e-02j, -2.52162743e-02+1.11753521e-02j,\n", + " 3.21045947e-02-5.93624909e-02j, -7.04846556e-02+4.84711944e-03j,\n", + " -5.98727601e-03+1.41449320e-02j, -4.15103453e-03+1.08448215e-02j,\n", + " 7.72828574e-02-1.03008012e-01j, 7.10222032e-02-2.82880062e-03j,\n", + " 1.85922327e-02-2.34805460e-02j, 5.94043177e-04-1.44215714e-03j,\n", + " -3.41902516e-02+1.94179582e-02j, -3.52124532e-02+1.39417432e-02j,\n", + " -1.26067853e-03+1.51517415e-03j, -7.62304448e-03-5.70233793e-03j,\n", + " 1.12499724e-02-2.86211177e-02j, -4.38456666e-02+1.11792897e-02j,\n", + " -3.59193479e-03+1.33737383e-02j, -2.26456555e-02+1.01263524e-02j,\n", + " -3.26499949e-02+4.84391350e-02j, 6.26144269e-02+2.31644750e-02j,\n", + " 9.92316043e-03-1.53406157e-02j, -2.72561118e-02-1.15689574e-02j,\n", + " -2.90759827e-02-3.20717544e-02j, -1.33692684e-02+3.36448627e-03j,\n", + " 2.16932525e-02-1.74633237e-03j, -8.35874274e-03-5.08877110e-03j,\n", + " -6.32067486e-02-4.27680216e-02j, -6.38581830e-03-2.48644359e-02j,\n", + " 4.81650413e-02+1.26994752e-02j, -3.41729523e-03+4.23873493e-03j,\n", + " -3.36708143e-02+3.34992386e-02j, 7.06326254e-03+1.10956221e-02j,\n", + " -4.15526282e-02+3.66468176e-02j, 1.78849143e-02-1.38341196e-02j,\n", + " -1.98054062e-02+1.91568485e-02j, 1.99601083e-02-2.13439979e-02j,\n", + " 3.49337346e-03-1.33267845e-02j, -4.64611593e-03-6.53232548e-03j,\n", + " 4.76214586e-02+1.17525283e-02j, 2.12897557e-02-7.53045434e-02j,\n", + " -2.50132412e-02-6.01770487e-02j, 1.39464514e-02-1.74372720e-02j,\n", + " -2.51491285e-02+1.49280482e-02j, 2.70667158e-03+3.84206480e-04j,\n", + " 3.08759948e-03+5.67388728e-03j, -4.14783253e-04-1.09951536e-02j,\n", + " -3.91172386e-02+4.36362363e-02j, 2.74592277e-02-2.40688625e-02j,\n", + " -2.08369392e-02-1.28500387e-04j, 1.03130328e-02-2.23205571e-02j,\n", + " -1.85312297e-02+4.14402994e-02j, 1.18764238e-02-2.20240469e-02j,\n", + " -3.00749074e-02+2.84432054e-03j, 2.38039906e-02-3.24518540e-02j,\n", + " -7.36091905e-03+3.01575087e-02j, 1.96201485e-02-3.17300353e-02j,\n", + " -2.97125527e-02-1.98008737e-02j, 1.39031252e-02-2.31155746e-02j,\n", + " 6.97778713e-03+3.46073335e-02j, 2.59263803e-02-1.95276965e-02j,\n", + " -7.12951824e-02-1.22423196e-02j, 2.55442634e-02-1.86743549e-02j,\n", + " -1.51950351e-02+2.70875343e-02j, -2.86603112e-02+1.35352722e-02j,\n", + " -4.50537697e-03+1.73028802e-03j, -2.43459213e-02+7.78231033e-03j,\n", + " 2.68274640e-03-1.00046527e-02j, -3.24381814e-02+1.23953489e-02j,\n", + " -6.62180261e-03-1.06783210e-02j, -1.03300879e-02+1.97960350e-03j,\n", + " 5.07278233e-02-7.07749190e-02j, 2.87648131e-02-3.13519779e-03j,\n", + " 1.02311444e-02-3.89574639e-02j, 1.06354706e-02-3.95476256e-03j,\n", + " -1.25903332e-02+4.34399198e-03j, -1.90498174e-02-2.78352450e-03j,\n", + " 1.60373773e-03-1.03122098e-02j, 1.43530247e-03-3.76250369e-03j,\n", + " -5.06544789e-04-3.93387351e-03j, -4.40066176e-02+1.32292388e-02j,\n", + " -1.67711903e-03-2.14664549e-02j, -1.68138235e-02+2.06633988e-03j,\n", + " 5.03514645e-03-9.56568898e-03j, -3.36954006e-03-6.27012244e-03j,\n", + " 1.68542769e-02-3.25870927e-02j, 5.74117064e-03-5.81162982e-03j,\n", + " 1.31276926e-02-2.28068971e-02j, -1.49778373e-02-6.27364875e-03j,\n", + " 2.60480802e-03-3.13968092e-02j, -6.60467462e-03-5.33389764e-03j,\n", + " 2.29158963e-02-8.23976061e-03j, -1.74929862e-02-4.86326010e-03j,\n", + " -9.95950288e-03-2.26430715e-02j, -3.45992419e-02-2.89097146e-04j,\n", + " -2.71352421e-02+3.11841693e-02j, 3.61493717e-02-1.99186105e-02j,\n", + " 4.21485228e-03+1.10001508e-02j, -2.98622224e-02+2.27270009e-02j,\n", + " 4.11136959e-02-4.63062630e-02j, -9.76579512e-02+1.54379178e-02j,\n", + " -2.12449690e-03+4.69789750e-03j, -2.38218351e-03+1.79633936e-02j,\n", + " 4.81120864e-02-8.94234239e-02j, 7.00181938e-02+2.42200597e-02j,\n", + " 1.26285684e-02-3.08226010e-02j, 1.01286007e-03+8.20749932e-03j,\n", + " -1.72078145e-02+1.44761697e-02j, -3.18646298e-02+1.53157239e-02j,\n", + " 1.38289233e-04+1.09711691e-03j, -1.44847046e-02-6.48776218e-03j,\n", + " 2.18169263e-02-2.38258472e-02j, -5.10254584e-02+1.16596848e-02j,\n", + " 3.24391347e-03+3.44315121e-03j, -2.84567102e-02+2.36460658e-02j,\n", + " -3.34379277e-02+3.02264281e-02j, 1.01217797e-01+1.83404380e-02j,\n", + " 1.19169775e-02-1.47210144e-02j, -4.33532292e-02-4.24409160e-03j,\n", + " -1.28210904e-02-2.48880959e-02j, -8.87250479e-03+1.24087648e-02j,\n", + " 1.58769968e-02-8.97733430e-03j, -1.79692687e-02-5.95353182e-04j,\n", + " -3.60104477e-02-2.31843713e-02j, -1.38005912e-03-3.00973684e-02j,\n", + " 3.26557291e-02+5.02634133e-04j, -1.15976961e-02+1.09877683e-02j,\n", + " -5.81902086e-03+2.55603088e-02j, -9.45916889e-02+9.91917828e-02j,\n", + " -2.23501585e-02+1.22778545e-03j, 1.91538672e-02-7.02350099e-02j,\n", + " -4.75030677e-02-8.85076614e-03j, 1.05201511e-01-1.51588362e-02j,\n", + " -6.93247792e-03+7.14846606e-03j, -9.52236823e-03-3.55683413e-02j,\n", + " 8.20092538e-02-3.27976703e-02j, -1.37736687e-02-8.60627029e-02j,\n", + " 2.33494885e-03-8.18799848e-03j, -8.78143967e-03-1.70830682e-02j,\n", + " -4.38691998e-02+1.41799883e-02j, -1.58456645e-02-1.29855765e-02j,\n", + " -1.60633065e-03-4.68266949e-03j, 3.66171423e-02+5.17246970e-03j,\n", + " -4.04819418e-02+9.31423471e-03j, 1.01814403e-02+2.27959971e-02j,\n", + " -1.90950484e-02+6.90965840e-04j, 2.55293976e-02-6.72081548e-02j,\n", + " 2.62724868e-02+3.28507919e-02j, -1.81333757e-01+3.91262898e-03j,\n", + " -1.25339062e-02-1.83646557e-02j, 7.63037203e-02-2.28170607e-02j,\n", + " -2.27180229e-02-7.61410497e-03j, -2.71513417e-02-3.13576267e-02j,\n", + " 2.71071659e-03-6.78921506e-03j, 4.38126232e-02-8.07436344e-03j,\n", + " -2.00658145e-02-2.63849630e-02j, -2.19211997e-02+3.53412336e-02j,\n", + " 9.49690147e-03+1.99024223e-03j, 2.95290488e-02-2.65430223e-02j,\n", + " -3.33970362e-03+1.91517325e-02j, -2.66827833e-02+1.44860322e-02j,\n", + " 7.06818438e-03-7.52700276e-03j, -2.45447298e-02-4.74350879e-04j,\n", + " 1.04463999e-02-1.39978164e-02j, -3.93775909e-02+2.28898545e-02j,\n", + " -5.13428656e-03-8.60551615e-03j, -7.37370215e-03+1.53656391e-03j,\n", + " 3.48627948e-02-6.94913290e-02j, 2.44554698e-02+1.94885071e-02j,\n", + " 1.02157756e-02-2.60685716e-02j, -7.14235174e-05+6.98356783e-03j,\n", + " -5.52448428e-03+2.53295901e-03j, -2.39349508e-02-1.88800063e-03j,\n", + " 9.64877307e-04-9.95839478e-03j, 3.84407260e-03+4.96955512e-04j,\n", + " 1.24866095e-02-1.19280522e-02j, -5.27823105e-02+2.65055038e-02j,\n", + " 4.53249856e-03-2.18840960e-02j, -1.65616829e-02+1.80119154e-03j,\n", + " 7.63331825e-03-1.45826793e-02j, -9.18390150e-03+1.86598306e-03j,\n", + " 1.91218688e-02-3.10616658e-02j, -1.97137532e-03+2.75939017e-03j,\n", + " 1.51205912e-02-2.55970154e-02j, -2.32009587e-02+4.35326114e-03j,\n", + " 8.43198317e-03-2.54201047e-02j, -6.10833821e-03+4.59283832e-03j,\n", + " 2.37326706e-02-1.29449354e-02j, -2.21642558e-02+1.65100936e-03j,\n", + " 9.26601870e-03-1.95036930e-02j, -2.85574585e-02+5.07450424e-03j,\n", + " -3.43637405e-02+1.51749883e-02j, -1.71261242e-02-1.32829894e-02j,\n", + " -2.80895338e-02+1.86017711e-02j, -1.62322810e-02+6.63506028e-02j,\n", + " -2.81845418e-02+3.91364829e-03j, 2.38104728e-02-3.69259982e-02j,\n", + " -1.36178918e-02+1.66394600e-03j, -1.28271571e-02+1.03049554e-02j,\n", + " 3.84612493e-02-2.48540252e-02j, 5.53969144e-03-6.34820121e-02j,\n", + " 2.09887044e-02-1.82656572e-02j, 5.03329256e-02-4.87044248e-02j,\n", + " -1.67091627e-02-2.94107906e-03j, 2.62382535e-02-3.02330445e-03j,\n", + " -5.46857572e-04-7.95430562e-03j, -1.42099809e-02-1.48346601e-02j,\n", + " -3.96592853e-02+3.45564777e-03j, 2.75843710e-02-4.92708029e-02j,\n", + " -1.90759528e-02+2.44758842e-03j, -1.15774190e-02+2.60205051e-02j,\n", + " 1.45077020e-03-1.22123789e-02j, 2.26474550e-02-2.58810623e-02j,\n", + " 1.24725749e-02-1.42524803e-02j, 2.21673245e-02-1.90898542e-02j,\n", + " -7.63210918e-03-1.52451410e-02j, 2.94789415e-02-2.94619027e-02j,\n", + " -8.76367539e-03-1.66722337e-02j, -1.69209308e-02-3.54975059e-02j,\n", + " -1.32078208e-02-9.39696834e-03j, 1.83081383e-03-1.69538535e-02j,\n", + " -4.64500458e-02-6.50497503e-03j, -6.14052721e-02-9.43205455e-03j]),\n", + " 'job_id': '8646cd83-af5e-4a38-b49e-0a5b6f025963',\n", + " 'eval_number': 14}}}" ] }, "execution_count": 15, @@ -812,7 +803,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "oq_restructure", "language": "python", "name": "python3" }, @@ -826,11 +817,11 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.8.16" }, "vscode": { "interpreter": { - "hash": "d2582286b70c3b030a2fde61b871db03dec7fee33191883f4394b540a2eb90c7" + "hash": "c2624fc7126dc84539db96afb108ab094dd5f0ccef8d91873b73b01fbef81918" } } }, diff --git a/pytest.ini b/pytest.ini index 8fca51dd6..bc405ff5f 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,7 @@ [pytest] markers = - qpu: marks tests that requirea QPU connection (deselect with '-m "not qpu"') - api: marks tests that requirea coonection to a QC cloud (deselect with '-m "not api"') - qvm: marks tests that requirea attive Rigetti QVM and QILC compiler (deselect with '-m "not qvm"') + qpu: marks tests that require a QPU connection (deselect with '-m "not qpu"') + api: marks tests that require a coonection to a QC cloud (deselect with '-m "not api"') + qvm: marks tests that require an attive Rigetti QVM and QILC compiler (deselect with '-m "not qvm"') + docker_aws: marks tests that require to build aws docker (deselect with '-m "not docker_aws"') + notebook: marks tests that run on jupyter noteboks (deselect with '-m "not notebook"') \ No newline at end of file diff --git a/src/openqaoa-azure/backends/__init__.py b/src/openqaoa-azure/backends/__init__.py index 3c6cb1823..08a487ac3 100644 --- a/src/openqaoa-azure/backends/__init__.py +++ b/src/openqaoa-azure/backends/__init__.py @@ -1 +1 @@ -from .devices import DeviceAzure \ No newline at end of file +from .devices import DeviceAzure diff --git a/src/openqaoa-azure/backends/devices.py b/src/openqaoa-azure/backends/devices.py index f012e3b77..f147b0d90 100644 --- a/src/openqaoa-azure/backends/devices.py +++ b/src/openqaoa-azure/backends/devices.py @@ -1,3 +1,5 @@ +from typing import List + from azure.quantum.qiskit import AzureQuantumProvider from openqaoa.backends.devices_core import DeviceBase @@ -96,3 +98,6 @@ def _check_provider_connection(self) -> bool: ) ) return False + + def connectivity(self) -> List[List[int]]: + return self.backend_device.configuration().coupling_map diff --git a/src/openqaoa-braket/backends/__init__.py b/src/openqaoa-braket/backends/__init__.py index 21f17207b..bd127b2eb 100644 --- a/src/openqaoa-braket/backends/__init__.py +++ b/src/openqaoa-braket/backends/__init__.py @@ -1,2 +1,2 @@ from .devices import DeviceAWS -from .qaoa_braket_qpu import QAOAAWSQPUBackend \ No newline at end of file +from .qaoa_braket_qpu import QAOAAWSQPUBackend diff --git a/src/openqaoa-braket/backends/devices.py b/src/openqaoa-braket/backends/devices.py index 817a7fe9d..a263fe1b3 100644 --- a/src/openqaoa-braket/backends/devices.py +++ b/src/openqaoa-braket/backends/devices.py @@ -1,5 +1,5 @@ import numpy as np - +from typing import List from boto3.session import Session from botocore.exceptions import NoRegionError from braket.aws import AwsDevice @@ -147,3 +147,6 @@ def _check_provider_connection(self) -> bool: ) ) return False + + def connectivity(self) -> List[List[int]]: + return self.backend_device.topology_graph.edges diff --git a/src/openqaoa-braket/backends/qaoa_braket_qpu.py b/src/openqaoa-braket/backends/qaoa_braket_qpu.py index 4861efb4d..ca8dfde4b 100644 --- a/src/openqaoa-braket/backends/qaoa_braket_qpu.py +++ b/src/openqaoa-braket/backends/qaoa_braket_qpu.py @@ -1,5 +1,6 @@ import os from typing import Optional, List +import warnings from braket.circuits import Circuit from braket.circuits.gates import H @@ -14,7 +15,9 @@ QAOABaseBackendParametric, ) from openqaoa.qaoa_components import QAOADescriptor -from openqaoa.qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from openqaoa.qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) class QAOAAWSQPUBackend( @@ -56,8 +59,8 @@ def __init__( append_state: Optional[Circuit], init_hadamard: bool, cvar_alpha: float, - qubit_layout: List[int] = [], disable_qubit_rewiring: bool = False, + initial_qubit_mapping: Optional[List[int]] = None, ): QAOABaseBackendShotBased.__init__( @@ -71,8 +74,18 @@ def __init__( ) QAOABaseBackendCloud.__init__(self, device) - self.qureg = self.qaoa_descriptor.qureg - self.qubit_layout = self.qureg if qubit_layout == [] else qubit_layout + self.qureg = list(range(self.n_qubits)) + self.problem_reg = self.qureg[0 : self.problem_qubits] + if self.initial_qubit_mapping is None: + self.initial_qubit_mapping = ( + initial_qubit_mapping + if initial_qubit_mapping is not None + else list(range(self.n_qubits)) + ) + else: + warnings.warn( + "Ignoring the initial_qubit_mapping since the routing algorithm chose one" + ) self.disable_qubit_rewiring = disable_qubit_rewiring if self.prepend_state: @@ -145,14 +158,16 @@ def parametric_qaoa_circuit(self) -> Circuit: # Initial state is all |+> if self.init_hadamard: - for each_qubit in self.qubit_layout: + for each_qubit in self.problem_reg: parametric_circuit += H.h(each_qubit) self.braket_parameter_list = [] for each_gate in self.abstract_circuit: - angle_param = FreeParameter(str(each_gate.pauli_label)) - self.braket_parameter_list.append(angle_param) - each_gate.rotation_angle = angle_param + # if gate is of type mixer or cost gate, assign parameter to it + if each_gate.gate_label.type.value in ["MIXER", "COST"]: + angle_param = FreeParameter(each_gate.gate_label.__repr__()) + self.braket_parameter_list.append(angle_param) + each_gate.angle_value = angle_param decomposition = each_gate.decomposition("standard") # using the list above, construct the circuit for each_tuple in decomposition: @@ -164,6 +179,7 @@ def parametric_qaoa_circuit(self) -> Circuit: if self.append_state: parametric_circuit += self.append_state + # TODO: needs to be fixed --> measurement operations on problem qubits parametric_circuit += Probability.probability() return parametric_circuit @@ -233,9 +249,13 @@ def get_counts(self, params: QAOAVariationalBaseParams, n_shots=None) -> dict: "An Error Occurred with the Task(s) sent to AWS." ) - # Expose counts - self.measurement_outcomes = counts - return counts + final_counts = counts + # if self.final_mapping is not None: + # final_counts = permute_counts_dictionary(final_counts, + # self.final_mapping) + # # Expose counts + self.measurement_outcomes = final_counts + return final_counts def log_with_backend(self, metric_name: str, value, iteration_number) -> None: diff --git a/src/openqaoa-core/__init__.py b/src/openqaoa-core/__init__.py index 8b1c336e8..6eee62d87 100644 --- a/src/openqaoa-core/__init__.py +++ b/src/openqaoa-core/__init__.py @@ -1,3 +1,3 @@ from .algorithms import QAOA, RQAOA from .problems import QUBO -from .backends import create_device \ No newline at end of file +from .backends import create_device diff --git a/src/openqaoa-core/_version.py b/src/openqaoa-core/_version.py index 3dc1f76bc..485f44ac2 100644 --- a/src/openqaoa-core/_version.py +++ b/src/openqaoa-core/_version.py @@ -1 +1 @@ -__version__ = "0.1.0" +__version__ = "0.1.1" diff --git a/src/openqaoa-core/algorithms/__init__.py b/src/openqaoa-core/algorithms/__init__.py index de000bbee..3b4557928 100644 --- a/src/openqaoa-core/algorithms/__init__.py +++ b/src/openqaoa-core/algorithms/__init__.py @@ -1,2 +1,3 @@ from .qaoa import QAOA, QAOAResult -from .rqaoa import RQAOA, RQAOAResult \ No newline at end of file +from .rqaoa import RQAOA, RQAOAResult +from .jobs.managed_job import AWSJobs diff --git a/src/openqaoa-core/algorithms/baseworkflow.py b/src/openqaoa-core/algorithms/baseworkflow.py index 6e9fbe0f1..7dfcca187 100644 --- a/src/openqaoa-core/algorithms/baseworkflow.py +++ b/src/openqaoa-core/algorithms/baseworkflow.py @@ -89,16 +89,13 @@ def __init__(self, device=DeviceLocal("vectorized")): "experiment_id": generate_uuid(), # the id of the experiment it is generated automatically here "project_id": None, "algorithm": None, # qaoa or rqaoa - "name": None, + "description": None, "run_by": None, "provider": None, "target": None, "cloud": None, "client": None, "qubit_number": None, # it is set automatically in the compilation from the problem object - "qubit_routing": None, - "error_mitigation": None, - "error_correction": None, "execution_time_start": None, "execution_time_end": None, } @@ -123,15 +120,13 @@ def __setattr__(self, __name, __value): def set_header( self, project_id: str, - name: str, + description: str, run_by: str, provider: str, target: str, cloud: str, client: str, - qubit_routing: str, - error_mitigation: str, - error_correction: str, + experiment_id: str = None, ): """ Method to set the identification stamps of the optimizer object in self.header. @@ -146,16 +141,21 @@ def set_header( "The project_id is not a valid uuid, example of a valid uuid: 8353185c-b175-4eda-9628-b4e58cb0e41b" ) + if experiment_id != None: + if not is_valid_uuid(experiment_id): + raise ValueError( + "The experiment_id is not a valid uuid, example of a valid uuid: 8353185c-b175-4eda-9628-b4e58cb0e41b" + ) + else: + self.header["experiment_id"] = experiment_id + self.header["project_id"] = project_id - self.header["name"] = name + self.header["description"] = description self.header["run_by"] = run_by self.header["provider"] = provider self.header["target"] = target self.header["cloud"] = cloud self.header["client"] = client - self.header["qubit_routing"] = qubit_routing - self.header["error_mitigation"] = error_mitigation - self.header["error_correction"] = error_correction def set_exp_tags(self, tags: dict): """ @@ -365,21 +365,29 @@ def _serializable_dict( data["input_parameters"]["backend_properties"][item] ) - data["result"] = self.result.asdict( - False, complex_to_string, intermediate_mesurements - ) if not self.result in [None, {}] else None + data["result"] = ( + self.result.asdict(False, complex_to_string, intermediate_mesurements) + if not self.result in [None, {}] + else None + ) # create the final header dictionary header = self.header.copy() header["metadata"] = { **self.exp_tags.copy(), - **({ - "problem_type": - data["input_problem"]["problem_instance"]["problem_type"] - } if data["input_problem"] is not None else {}), **( - data["input_problem"]["metadata"].copy() - if data["input_problem"] is not None else {} + { + "problem_type": data["input_problem"]["problem_instance"][ + "problem_type" + ] + } + if data["input_problem"] is not None + else {} + ), + **( + data["input_problem"]["metadata"].copy() + if data["input_problem"] is not None + else {} ), **{"n_shots": data["input_parameters"]["backend_properties"]["n_shots"]}, **{ @@ -578,9 +586,9 @@ def dump( file[len(file_path) :], file_path ) ) - + @classmethod - def from_dict(cls, dictionary:dict): + def from_dict(cls, dictionary: dict): """ Creates an Optimizer object from a dictionary (which is the output of the asdict method) Parameters @@ -593,51 +601,67 @@ def from_dict(cls, dictionary:dict): """ # check if the class is correct - algorithm = dictionary['header']['algorithm'] - assert algorithm.lower() == cls.__name__.lower(), \ - f"The class {cls.__name__} does not match the algorithm ({algorithm}) of the dictionary." + algorithm = dictionary["header"]["algorithm"] + assert ( + algorithm.lower() == cls.__name__.lower() + ), f"The class {cls.__name__} does not match the algorithm ({algorithm}) of the dictionary." # create the object obj = cls() # header - obj.header = dictionary['header'].copy() - obj.header.pop('metadata', None) # remove the metadata from the header + obj.header = dictionary["header"].copy() + obj.header.pop("metadata", None) # remove the metadata from the header # tags - obj.exp_tags = dictionary['data']['exp_tags'].copy() + obj.exp_tags = dictionary["data"]["exp_tags"].copy() # problem - obj.problem = QUBO.from_dict(dictionary['data']['input_problem']) \ - if dictionary['data']['input_problem'] is not None else None + obj.problem = ( + QUBO.from_dict(dictionary["data"]["input_problem"]) + if dictionary["data"]["input_problem"] is not None + else None + ) # input parameters map_inputs = { - 'backend_properties': obj.set_backend_properties, - 'circuit_properties': obj.set_circuit_properties, - 'classical_optimizer': obj.set_classical_optimizer, - 'rqaoa_parameters': obj.set_rqaoa_parameters if algorithm == 'rqaoa' else None, + "backend_properties": obj.set_backend_properties, + "circuit_properties": obj.set_circuit_properties, + "classical_optimizer": obj.set_classical_optimizer, + "rqaoa_parameters": obj.set_rqaoa_parameters + if algorithm == "rqaoa" + else None, } - for key, value in dictionary['data']['input_parameters'].items(): - if key == 'device': continue + for key, value in dictionary["data"]["input_parameters"].items(): + if key == "device": + continue map_inputs[key](**value) # results - if 'result' in dictionary['data'].keys() and dictionary['data']['result'] is not None: + if ( + "result" in dictionary["data"].keys() + and dictionary["data"]["result"] is not None + ): obj.result = obj.results_class.from_dict( - dictionary['data']['result'], - **({'cost_hamiltonian':obj.problem.hamiltonian} if algorithm == 'qaoa' else {}) - ) + dictionary["data"]["result"], + **( + {"cost_hamiltonian": obj.problem.hamiltonian} + if algorithm == "qaoa" + else {} + ), + ) # print a message when the object is loaded print(f"Loaded {cls.__name__} object.") print("The device has to be set manually using the set_device method.") - print(f"Name of the device used was: {dictionary['data']['input_parameters']['device']}") + print( + f"Name of the device used was: {dictionary['data']['input_parameters']['device']}" + ) return obj @classmethod - def loads(cls, string:str): + def loads(cls, string: str): """ Creates an Optimizer object from a string (which is the output of the dumps method) Parameters @@ -651,7 +675,7 @@ def loads(cls, string:str): return cls.from_dict(json.loads(string)) @classmethod - def load(cls, file_name:str, file_path:str=""): + def load(cls, file_name: str, file_path: str = ""): """ Creates an Optimizer object from a file (which is the output of the dump method) Parameters @@ -665,9 +689,9 @@ def load(cls, file_name:str, file_path:str=""): QAOA or RQAOA """ file = file_path + file_name - if '.gz' == file_name[-3:]: - with gzip.open(file, 'r') as f: - return cls.loads(f.read().decode('utf-8')) + if ".gz" == file_name[-3:]: + with gzip.open(file, "r") as f: + return cls.loads(f.read().decode("utf-8")) else: - with open(file, 'r') as f: + with open(file, "r") as f: return cls.loads(f.read()) diff --git a/src/openqaoa-core/algorithms/jobs/__init__.py b/src/openqaoa-core/algorithms/jobs/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/openqaoa-core/algorithms/jobs/managed_job.py b/src/openqaoa-core/algorithms/jobs/managed_job.py new file mode 100644 index 000000000..d1fc1f69d --- /dev/null +++ b/src/openqaoa-core/algorithms/jobs/managed_job.py @@ -0,0 +1,103 @@ +import os + +from openqaoa_braket.backends import DeviceAWS + +from openqaoa.algorithms import QAOA, RQAOA +from openqaoa.algorithms.baseworkflow import Workflow +from openqaoa.backends.qaoa_device import create_device + + +class AWSJobs(Workflow): + """ + This class is meant to be used *only* within the framework of AWS managed hybrid jobs. + """ + + def __init__(self, algorithm: str = "qaoa"): + """ + Initialize the QAOA class. + + Parameters + ---------- + algorithm: str + The algorithm to be used. Chose between QAOA and RQAOA + """ + # the input data directory opt/braket/input/data + self.input_dir = os.environ["AMZN_BRAKET_INPUT_DIR"] + # the output directory opt/braket/model to write ob results to + self.results_dir = os.environ["AMZN_BRAKET_JOB_RESULTS_DIR"] + # the name of the job + self.job_name = os.environ["AMZN_BRAKET_JOB_NAME"] + # the checkpoint directory + self.checkpoint_dir = os.environ["AMZN_BRAKET_CHECKPOINT_DIR"] + # the hyperparameter + self.hyperparameter_file_name = os.environ["AMZN_BRAKET_HP_FILE"] + # the device ARN (AWS Resource Number) + self.device_arn = os.environ["AMZN_BRAKET_DEVICE_ARN"] + # the output S3 bucket, as specified in the CreateJob request’s OutputDataConfig + self.out_s3_bucket = os.environ["AMZN_BRAKET_OUT_S3_BUCKET"] + # the entry point as specified in the CreateJob request’s ScriptModeConfig + self.script_entry_point = os.environ["AMZN_BRAKET_SCRIPT_ENTRY_POINT"] + # the compression type as specified in the CreateJob request’s ScriptModeConfig + self.compression_type = os.environ["AMZN_BRAKET_SCRIPT_COMPRESSION_TYPE"] + # the S3 location of the user’s script as specified in the CreateJob request’s ScriptModeConfig + self.script_sr_uri = os.environ["AMZN_BRAKET_SCRIPT_S3_URI"] + # the S3 location where the SDK would store the task results by default for the job + self.task_results_se_uri = os.environ["AMZN_BRAKET_TASK_RESULTS_S3_URI"] + # the S3 location where the job results would be stored, as specified in CreateJob request’s OutputDataConfig + self.results_s3_path = os.environ["AMZN_BRAKET_JOB_RESULTS_S3_PATH"] + # the string that should be passed to CreateQuantumTask’s jobToken parameter for quantum tasks created in the job container + # if os.environ["AMZN_BRAKET_JOB_TOKEN"]: + # self.job_token = os.environ["AMZN_BRAKET_JOB_TOKEN"] + + self.device = DeviceAWS( + device_name=self.device_arn, + folder_name=self.results_dir, + s3_bucket_name=self.out_s3_bucket, + ) + self.algorithm = algorithm.lower() + self.completed = False + + def load_compile_data(self): + """ + A helper method to load the parameters. + + .. note:: + Note tha this function is executed within the AWS job-docker + """ + + path = os.path.join(self.input_dir, "input_data/") + + if "qaoa" == self.algorithm.lower(): + workflow = QAOA() + elif "rqaoa" == self.algorithm.lower(): + workflow = RQAOA() + else: + raise ValueError( + f"Specified algorithm {self.algorithm} is not supported. Please choose between [QAOA, RQAOA]" + ) + + self.workflow = workflow.load(file_name="openqaoa_params.json", file_path=path) + + # Extract the original uuid + self.atomic_uuid = self.workflow.asdict()["header"]["atomic_id"] + self.workflow.set_device(create_device("aws", self.device_arn)) + + self.workflow.compile(self.workflow.problem) + + self.workflow.header["atomic_id"] = self.atomic_uuid + + def run_workflow(self): + """ + Function to execute the workflow on the Jobs instance + + .. note:: + Note tha this function is executed within the AWS job-docker + """ + + try: + self.workflow.optimize() + self.completed = True + print("Job completed!!!!") + except Exception as e: + print("An Exception has occurred when to run the workflow: {}".format(e)) + return False diff --git a/src/openqaoa-core/algorithms/qaoa/__init__.py b/src/openqaoa-core/algorithms/qaoa/__init__.py index 4f4c76c58..435b000b4 100644 --- a/src/openqaoa-core/algorithms/qaoa/__init__.py +++ b/src/openqaoa-core/algorithms/qaoa/__init__.py @@ -1,2 +1,2 @@ from .qaoa_workflow import QAOA -from .qaoa_result import QAOAResult \ No newline at end of file +from .qaoa_result import QAOAResult diff --git a/src/openqaoa-core/algorithms/qaoa/qaoa_result.py b/src/openqaoa-core/algorithms/qaoa/qaoa_result.py index 86f8fabe1..d22206eb7 100644 --- a/src/openqaoa-core/algorithms/qaoa/qaoa_result.py +++ b/src/openqaoa-core/algorithms/qaoa/qaoa_result.py @@ -49,7 +49,7 @@ class QAOAResult: def __init__( self, - log: 'Logger', + log: "Logger", method: Type[str], cost_hamiltonian: Type[Hamiltonian], type_backend: Type[QAOABaseBackend], diff --git a/src/openqaoa-core/algorithms/qaoa/qaoa_workflow.py b/src/openqaoa-core/algorithms/qaoa/qaoa_workflow.py index a7df69709..f6c78e47b 100644 --- a/src/openqaoa-core/algorithms/qaoa/qaoa_workflow.py +++ b/src/openqaoa-core/algorithms/qaoa/qaoa_workflow.py @@ -1,9 +1,9 @@ -import time - +from typing import List, Callable, Optional +import requests from .qaoa_result import QAOAResult from ..workflow_properties import CircuitProperties from ..baseworkflow import Workflow -from ...backends.devices_core import DeviceLocal +from ...backends.devices_core import DeviceLocal, DeviceBase from ...backends.qaoa_backend import get_qaoa_backend from ...problems import QUBO from ...qaoa_components import ( @@ -11,7 +11,7 @@ QAOADescriptor, create_qaoa_variational_params, ) -from ...utilities import get_mixer_hamiltonian +from ...utilities import get_mixer_hamiltonian, generate_timestamp from ...optimizers.qaoa_optimizer import get_optimizer @@ -173,7 +173,12 @@ def set_circuit_properties(self, **kwargs): return None - def compile(self, problem: QUBO = None, verbose: bool = False): + def compile( + self, + problem: QUBO = None, + verbose: bool = False, + routing_function: Optional[Callable] = None, + ): """ Initialise the trainable parameters for QAOA according to the specified strategies and by passing the problem statement @@ -192,7 +197,17 @@ def compile(self, problem: QUBO = None, verbose: bool = False): verbose: bool Set True to have a summary of QAOA to displayed after compilation """ + # if isinstance(routing_function,Callable): + # #assert that routing_function is supported only for Standard QAOA. + # if ( + # self.backend_properties.append_state is not None or\ + # self.backend_properties.prepend_state is not None or\ + # self.circuit_properties.mixer_hamiltonian is not 'x' or\ + # ) + + # connect to the QPU specified + self.device.check_connection() # we compile the method of the parent class to genereate the id and # check the problem is a QUBO object and save it super().compile(problem=problem) @@ -209,7 +224,11 @@ def compile(self, problem: QUBO = None, verbose: bool = False): ) self.qaoa_descriptor = QAOADescriptor( - self.cost_hamil, self.mixer_hamil, p=self.circuit_properties.p + self.cost_hamil, + self.mixer_hamil, + p=self.circuit_properties.p, + routing_function=routing_function, + device=self.device, ) self.variate_params = create_qaoa_variational_params( qaoa_descriptor=self.qaoa_descriptor, @@ -272,14 +291,14 @@ def optimize(self, verbose=False): raise ValueError("Please compile the QAOA before optimizing it!") # timestamp for the start of the optimization - self.header["execution_time_start"] = time.time_ns() + self.header["execution_time_start"] = generate_timestamp() self.optimizer.optimize() # TODO: result and qaoa_result will differ self.result = self.optimizer.qaoa_result # timestamp for the end of the optimization - self.header["execution_time_end"] = time.time_ns() + self.header["execution_time_end"] = generate_timestamp() if verbose: print(f"optimization completed.") diff --git a/src/openqaoa-core/algorithms/rqaoa/__init__.py b/src/openqaoa-core/algorithms/rqaoa/__init__.py index 3c15ed36d..a64ea2601 100644 --- a/src/openqaoa-core/algorithms/rqaoa/__init__.py +++ b/src/openqaoa-core/algorithms/rqaoa/__init__.py @@ -1,3 +1,3 @@ from .rqaoa_workflow import RQAOA from .rqaoa_result import RQAOAResult -from .rqaoa_utils import * \ No newline at end of file +from .rqaoa_utils import * diff --git a/src/openqaoa-core/algorithms/rqaoa/rqaoa_result.py b/src/openqaoa-core/algorithms/rqaoa/rqaoa_result.py index ca7c86c72..d5a51cd41 100644 --- a/src/openqaoa-core/algorithms/rqaoa/rqaoa_result.py +++ b/src/openqaoa-core/algorithms/rqaoa/rqaoa_result.py @@ -68,38 +68,37 @@ def asdict( ) @classmethod - def from_dict( - cls, - dictionary:dict - ): + def from_dict(cls, dictionary: dict): """ - Creates a RQAOAResults object from a dictionary (which is the output of the asdict method). + Creates a RQAOAResult object from a dictionary (which is the output of the asdict method). Parameters ---------- dictionary : dict The input dictionary. Returns ------- - RQAOAResults - The RQAOAResults object. + RQAOAResult + The RQAOAResult object. """ # deepcopy the dictionary, so that the original dictionary is not changed dictionary = copy.deepcopy(dictionary) - # create a new RQAOAResults object + # create a new RQAOAResult object results = cls() - # add the keys of the dictionary to the RQAOAResults object + # add the keys of the dictionary to the RQAOAResult object for key, value in dictionary.items(): results[key] = value # convert the intermediate steps to objects - for step in results['intermediate_steps']: - step['problem'] = QUBO.from_dict(step['problem']) - step['qaoa_results'] = QAOAResult.from_dict(step['qaoa_results'], cost_hamiltonian=step['problem'].hamiltonian) - step['exp_vals_z'] = np.array(step['exp_vals_z']) - step['corr_matrix'] = np.array(step['corr_matrix']) + for step in results["intermediate_steps"]: + step["problem"] = QUBO.from_dict(step["problem"]) + step["qaoa_results"] = QAOAResult.from_dict( + step["qaoa_results"], cost_hamiltonian=step["problem"].hamiltonian + ) + step["exp_vals_z"] = np.array(step["exp_vals_z"]) + step["corr_matrix"] = np.array(step["corr_matrix"]) return results diff --git a/src/openqaoa-core/algorithms/rqaoa/rqaoa_workflow.py b/src/openqaoa-core/algorithms/rqaoa/rqaoa_workflow.py index 1bb466b02..19836865f 100644 --- a/src/openqaoa-core/algorithms/rqaoa/rqaoa_workflow.py +++ b/src/openqaoa-core/algorithms/rqaoa/rqaoa_workflow.py @@ -7,7 +7,11 @@ from ..workflow_properties import CircuitProperties from ...backends.devices_core import DeviceLocal, DeviceBase from ...problems import QUBO -from ...utilities import ground_state_hamiltonian, exp_val_hamiltonian_termwise +from ...utilities import ( + ground_state_hamiltonian, + exp_val_hamiltonian_termwise, + generate_timestamp, +) from ...backends.qaoa_analytical_sim import QAOABackendAnalyticalSimulator from . import rqaoa_utils from .rqaoa_result import RQAOAResult @@ -51,7 +55,7 @@ class RQAOA(Workflow): For a complete list of its parameters and usage please see the method set_circuit_properties rqaoa_parameters: `RqaoaParameters` Set of parameters containing all the relevant information for the recursive procedure of RQAOA. - results: `RQAOAResults` + results: `RQAOAResult` The results of the RQAOA optimization. Dictionary containing all the information about the RQAOA run: the solution states and energies (key: 'solution'), the output of the classical @@ -59,9 +63,9 @@ class RQAOA(Workflow): (key: 'elimination_rules'), the number of eliminations at each step (key: 'schedule'), total number of steps (key: 'number_steps'), the intermediate QUBO problems and the intermediate QAOA objects that have been optimized in each RQAOA step (key: 'intermediate_problems'). - This object (`RQAOAResults`) is a dictionary with some custom methods as - RQAOAResults.get_hamiltonian_step(i) which get the hamiltonian of reduced problem of the i-th step. - To see the full list of methods please see the RQAOAResults class. + This object (`RQAOAResult`) is a dictionary with some custom methods as + RQAOAResult.get_hamiltonian_step(i) which get the hamiltonian of reduced problem of the i-th step. + To see the full list of methods please see the RQAOAResult class. Examples -------- @@ -366,7 +370,7 @@ def optimize( f_max_terms = rqaoa_utils.max_terms # timestamp for the start of the optimization - self.header["execution_time_start"] = int(time.time()) + self.header["execution_time_start"] = generate_timestamp() # flag, set to true if the problem vanishes due to elimination before reaching cutoff total_elimination = False @@ -450,10 +454,10 @@ def optimize( ) # timestamp for the end of the optimization - self.header["execution_time_end"] = int(time.time()) + self.header["execution_time_end"] = generate_timestamp() # Compute description dictionary containing all the information - self.result = self.results_class() + self.result = self.results_class() self.result["solution"] = full_solutions self.result["classical_output"] = { "minimum_energy": cl_energy, diff --git a/src/openqaoa-core/algorithms/workflow_properties.py b/src/openqaoa-core/algorithms/workflow_properties.py index df63e6548..cf07ae09e 100644 --- a/src/openqaoa-core/algorithms/workflow_properties.py +++ b/src/openqaoa-core/algorithms/workflow_properties.py @@ -202,7 +202,7 @@ class BackendProperties(WorkflowProperties): The value of the CVaR parameter. noise_model: NoiseModel The `qiskit` noise model to be used for the shot-based simulator. - qubit_layout: Union[List[int], numpy.ndarray] + initial_qubit_mapping: Union[List[int], numpy.ndarray] Mapping from physical to logical qubit indices, used to eventually construct the quantum circuit. For example, for a system composed by 3 qubits `qubit_layout=[1,3,2]`, maps `1<->0`, `3<->1`, `2<->2`, where the left hand side is the physical qubit @@ -229,7 +229,7 @@ def __init__( n_shots: int = 100, cvar_alpha: float = 1, noise_model=None, - qubit_layout: Optional[Union[List[int], np.ndarray]] = None, + initial_qubit_mapping: Optional[Union[List[int], np.ndarray]] = None, qiskit_simulation_method: Optional[str] = None, seed_simulator: Optional[int] = None, active_reset: Optional[bool] = None, @@ -243,7 +243,7 @@ def __init__( self.append_state = append_state self.cvar_alpha = cvar_alpha self.noise_model = noise_model - self.qubit_layout = qubit_layout + self.initial_qubit_mapping = initial_qubit_mapping self.seed_simulator = seed_simulator self.qiskit_simulation_method = qiskit_simulation_method self.active_reset = active_reset diff --git a/src/openqaoa-core/backends/__init__.py b/src/openqaoa-core/backends/__init__.py index 06647dbdf..6f7bd9af2 100644 --- a/src/openqaoa-core/backends/__init__.py +++ b/src/openqaoa-core/backends/__init__.py @@ -16,4 +16,4 @@ from .qaoa_vectorized import QAOAvectorizedBackendSimulator from .qaoa_analytical_sim import QAOABackendAnalyticalSimulator from .devices_core import DeviceLocal -from .qaoa_device import create_device \ No newline at end of file +from .qaoa_device import create_device diff --git a/src/openqaoa-core/backends/basebackend.py b/src/openqaoa-core/backends/basebackend.py index d8335fa4f..80796074e 100644 --- a/src/openqaoa-core/backends/basebackend.py +++ b/src/openqaoa-core/backends/basebackend.py @@ -16,11 +16,12 @@ from .devices_core import DeviceBase from ..qaoa_components import ( - RotationGateMap, - TwoQubitRotationGateMap, + GateMap, QAOADescriptor, ) -from ..qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from ..qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) from ..utilities import qaoa_probabilities, round_value from .cost_function import cost_function @@ -110,6 +111,7 @@ class QAOABaseBackend(VQABaseBackend): Appending a user-defined circuit/state to the end of the QAOA routine init_hadamard: `bool` Initialises the QAOA circuit with a hadamard when ``True`` + cvar_alpha: `float` """ def __init__( @@ -118,19 +120,35 @@ def __init__( prepend_state: Optional[Union[QuantumCircuitBase, List[complex], np.ndarray]], append_state: Optional[Union[QuantumCircuitBase, np.ndarray]], init_hadamard: bool, - cvar_alpha: float = 1, + cvar_alpha: float, ): super().__init__(prepend_state, append_state) self.qaoa_descriptor = qaoa_descriptor self.cost_hamiltonian = qaoa_descriptor.cost_hamiltonian - self.n_qubits = self.cost_hamiltonian.n_qubits + self.n_qubits = self.qaoa_descriptor.n_qubits self.init_hadamard = init_hadamard self.cvar_alpha = cvar_alpha + self.problem_qubits = self.qaoa_descriptor.cost_hamiltonian.n_qubits self.abstract_circuit = deepcopy(self.qaoa_descriptor.abstract_circuit) + # pass the generated mappings if the circuit is routed + if self.qaoa_descriptor.routed == True: + self.initial_qubit_mapping = self.qaoa_descriptor.initial_mapping + + if self.qaoa_descriptor.p % 2 != 0: + self.final_mapping = self.qaoa_descriptor.final_mapping + else: + # if even, the initial mapping [0,...,n_qubits-1] is taken as the final mapping + self.final_mapping = list( + range(len(self.qaoa_descriptor.final_mapping)) + ) + else: + self.initial_qubit_mapping = None + self.final_mapping = None + def assign_angles(self, params: QAOAVariationalBaseParams) -> None: """ @@ -143,80 +161,68 @@ def assign_angles(self, params: QAOAVariationalBaseParams) -> None: The variational parameters(angles) to be assigned to the circuit gates """ # if circuit is non-parameterised, then assign the angle values to the circuit - abstract_pauli_circuit = self.abstract_circuit - - for each_pauli in abstract_pauli_circuit: - pauli_label_index = each_pauli.pauli_label[2:] - if isinstance(each_pauli, TwoQubitRotationGateMap): - if each_pauli.pauli_label[1] == "mixer": - angle = params.mixer_2q_angles[ - pauli_label_index[0], pauli_label_index[1] - ] - elif each_pauli.pauli_label[1] == "cost": - angle = params.cost_2q_angles[ - pauli_label_index[0], pauli_label_index[1] - ] - elif isinstance(each_pauli, RotationGateMap): - if each_pauli.pauli_label[1] == "mixer": - angle = params.mixer_1q_angles[ - pauli_label_index[0], pauli_label_index[1] - ] - elif each_pauli.pauli_label[1] == "cost": - angle = params.cost_1q_angles[ - pauli_label_index[0], pauli_label_index[1] - ] - each_pauli.rotation_angle = angle - self.abstract_circuit = abstract_pauli_circuit + abstract_circuit = self.abstract_circuit + + for each_gate in abstract_circuit: + gate_label_layer = each_gate.gate_label.layer + gate_label_seq = each_gate.gate_label.sequence + if each_gate.gate_label.n_qubits == 2: + if each_gate.gate_label.type.value == "MIXER": + angle = params.mixer_2q_angles[gate_label_layer, gate_label_seq] + elif each_gate.gate_label.type.value == "COST": + angle = params.cost_2q_angles[gate_label_layer, gate_label_seq] + elif each_gate.gate_label.n_qubits == 1: + if each_gate.gate_label.type.value == "MIXER": + angle = params.mixer_1q_angles[gate_label_layer, gate_label_seq] + elif each_gate.gate_label.type.value == "COST": + angle = params.cost_1q_angles[gate_label_layer, gate_label_seq] + each_gate.angle_value = angle + + self.abstract_circuit = abstract_circuit def obtain_angles_for_pauli_list( - self, input_pauli_list: List[RotationGateMap], params: QAOAVariationalBaseParams + self, input_gate_list: List[GateMap], params: QAOAVariationalBaseParams ) -> List[float]: """ This method uses the pauli gate list information to obtain the pauli angles from the VariationalBaseParams object. The floats in the list are in the order - of the input RotationGateMaps list. + of the input GateMaps list. Parameters ---------- - input_pauli_list: `List[RotationGateMap]` - The RotationGateMaps list + input_gate_list: `List[GateMap]` + The GateMap list including rotation gates params: `QAOAVariationalBaseParams` The variational parameters(angles) to be assigned to the circuit gates Returns ------- angles_list: `List[float]` - The list of angles in the order of gates in the `RotationGateMap` list + The list of angles in the order of gates in the `GateMap` list """ angle_list = [] - for each_pauli in input_pauli_list: - pauli_label_index = each_pauli.pauli_label[2:] - if isinstance(each_pauli, TwoQubitRotationGateMap): - if each_pauli.pauli_label[1] == "mixer": + for each_gate in input_gate_list: + gate_label_layer = each_gate.gate_label.layer + gate_label_seq = each_gate.gate_label.sequence + + if each_gate.gate_label.n_qubits == 2: + if each_gate.gate_label.type.value == "MIXER": angle_list.append( - params.mixer_2q_angles[ - pauli_label_index[0], pauli_label_index[1] - ] + params.mixer_2q_angles[gate_label_layer, gate_label_seq] ) - elif each_pauli.pauli_label[1] == "cost": + elif each_gate.gate_label.type.value == "COST": angle_list.append( - params.cost_2q_angles[ - pauli_label_index[0], pauli_label_index[1] - ] + params.cost_2q_angles[gate_label_layer, gate_label_seq] ) - elif isinstance(each_pauli, RotationGateMap): - if each_pauli.pauli_label[1] == "mixer": + elif each_gate.gate_label.n_qubits == 1: + if each_gate.gate_label.type.value == "MIXER": angle_list.append( - params.mixer_1q_angles[ - pauli_label_index[0], pauli_label_index[1] - ] + params.mixer_1q_angles[gate_label_layer, gate_label_seq] ) - elif each_pauli.pauli_label[1] == "cost": + elif each_gate.gate_label.type.value == "COST": angle_list.append( - params.cost_1q_angles[ - pauli_label_index[0], pauli_label_index[1] - ] + params.cost_1q_angles[gate_label_layer, gate_label_seq] ) return angle_list @@ -515,13 +521,12 @@ def __init__( prepend_state: Optional[QuantumCircuitBase], append_state: Optional[QuantumCircuitBase], init_hadamard: bool, - cvar_alpha: float = 1, + cvar_alpha: float, ): super().__init__( qaoa_descriptor, prepend_state, append_state, init_hadamard, cvar_alpha ) - # assert self.n_qubits >= len(prepend_state.qubits), \ # "Cannot attach a bigger circuit to the QAOA routine" # assert self.n_qubits >= len(append_state.qubits), \ diff --git a/src/openqaoa-core/backends/devices_core.py b/src/openqaoa-core/backends/devices_core.py index 2e948302f..4eadd751d 100644 --- a/src/openqaoa-core/backends/devices_core.py +++ b/src/openqaoa-core/backends/devices_core.py @@ -1,6 +1,7 @@ -from __future__ import annotations import abc import logging +from typing import List +import networkx as nx logging.getLogger().setLevel(logging.ERROR) @@ -34,6 +35,17 @@ def check_connection(self) -> bool: """ pass + @abc.abstractmethod + def connectivity(self): + """ + obtain the device connectivity as a list of qubit pairs + + Returns + ------- + List[List[int]] + """ + pass + class DeviceLocal(DeviceBase): """ @@ -49,3 +61,10 @@ def check_connection(self) -> bool: return True else: return False + + def connectivity(self, n_qubits: int) -> List[List[int]]: + """ + The number of qubits for simulators depend on the problem + """ + G = nx.complete_graph(n_qubits) + return list(G.edges()) diff --git a/src/openqaoa-core/backends/qaoa_analytical_sim.py b/src/openqaoa-core/backends/qaoa_analytical_sim.py index 5cd52e063..25e822301 100644 --- a/src/openqaoa-core/backends/qaoa_analytical_sim.py +++ b/src/openqaoa-core/backends/qaoa_analytical_sim.py @@ -6,7 +6,9 @@ QAOADescriptor, QAOAVariationalStandardParams, ) -from ..qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from ..qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) from ..utilities import energy_expectation_analytical, generate_uuid, round_value diff --git a/src/openqaoa-core/backends/qaoa_backend.py b/src/openqaoa-core/backends/qaoa_backend.py index c9c2d6e18..2387dbbdb 100644 --- a/src/openqaoa-core/backends/qaoa_backend.py +++ b/src/openqaoa-core/backends/qaoa_backend.py @@ -46,8 +46,8 @@ def _backend_arg_mapper( noise_model=None, active_reset: Optional[bool] = None, rewiring=None, - qubit_layout=None, disable_qubit_rewiring: Optional[bool] = None, + initial_qubit_mapping=None, ): BACKEND_ARGS_MAPPER = { @@ -60,18 +60,22 @@ def _backend_arg_mapper( "seed_simulator": seed_simulator, "qiskit_simulation_method": qiskit_simulation_method, "noise_model": noise_model, + "initial_qubit_mapping": initial_qubit_mapping, + }, + QAOAQiskitQPUBackend: { + "n_shots": n_shots, + "initial_qubit_mapping": initial_qubit_mapping, }, - QAOAQiskitQPUBackend: {"n_shots": n_shots, "qubit_layout": qubit_layout}, QAOAPyQuilQPUBackend: { "n_shots": n_shots, "active_reset": active_reset, "rewiring": rewiring, - "qubit_layout": qubit_layout, + "initial_qubit_mapping": initial_qubit_mapping, }, QAOAAWSQPUBackend: { "n_shots": n_shots, - "qubit_layout": qubit_layout, "disable_qubit_rewiring": disable_qubit_rewiring, + "initial_qubit_mapping": initial_qubit_mapping, }, } @@ -145,7 +149,7 @@ def get_qaoa_backend( The value of the CVaR parameter. kwargs: Additional keyword arguments for the backend. - qubit_layout: `list` + initial_qubit_mapping: `list` A list of physical qubits to be used for the QAOA circuit. n_shots: `int` The number of shots to be used for the shot-based computation. diff --git a/src/openqaoa-core/backends/qaoa_device.py b/src/openqaoa-core/backends/qaoa_device.py index ebbe5ce83..c029f12bf 100644 --- a/src/openqaoa-core/backends/qaoa_device.py +++ b/src/openqaoa-core/backends/qaoa_device.py @@ -12,6 +12,7 @@ def device_class_arg_mapper( hub: str = None, group: str = None, project: str = None, + as_emulator: bool = None, as_qvm: bool = None, noisy: bool = None, compiler_timeout: float = None, @@ -26,7 +27,12 @@ def device_class_arg_mapper( az_location: str = None, ) -> dict: DEVICE_ARGS_MAPPER = { - DeviceQiskit: {"hub": hub, "group": group, "project": project}, + DeviceQiskit: { + "hub": hub, + "group": group, + "project": project, + "as_emulator": as_emulator, + }, DevicePyquil: { "as_qvm": as_qvm, "noisy": noisy, diff --git a/src/openqaoa-core/backends/qaoa_vectorized.py b/src/openqaoa-core/backends/qaoa_vectorized.py index 1ee06123c..7ee3207bf 100644 --- a/src/openqaoa-core/backends/qaoa_vectorized.py +++ b/src/openqaoa-core/backends/qaoa_vectorized.py @@ -10,7 +10,9 @@ from .basebackend import QAOABaseBackendStatevector from ..qaoa_components import QAOADescriptor, Hamiltonian -from ..qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from ..qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) from ..utilities import generate_uuid, round_value diff --git a/src/openqaoa-core/derivatives/derivative_functions.py b/src/openqaoa-core/derivatives/derivative_functions.py index 2ee9a45b6..299e42938 100644 --- a/src/openqaoa-core/derivatives/derivative_functions.py +++ b/src/openqaoa-core/derivatives/derivative_functions.py @@ -3,7 +3,9 @@ import numpy as np from ..qaoa_components import QAOAVariationalExtendedParams -from openqaoa.qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from openqaoa.qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) from ..backends.basebackend import QAOABaseBackend from ..optimizers.logger_vqa import Logger from ..backends.cost_function import cost_function diff --git a/src/openqaoa-core/derivatives/qfim.py b/src/openqaoa-core/derivatives/qfim.py index aff04af56..d9e1282a5 100644 --- a/src/openqaoa-core/derivatives/qfim.py +++ b/src/openqaoa-core/derivatives/qfim.py @@ -4,7 +4,9 @@ from ..backends.basebackend import QAOABaseBackend, QAOABaseBackendShotBased from ..optimizers.logger_vqa import Logger -from ..qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from ..qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) def log_qfim_evals(logger: Logger) -> Logger: diff --git a/src/openqaoa-core/optimizers/__init__.py b/src/openqaoa-core/optimizers/__init__.py index 3bf6ed9bc..d3c21f095 100644 --- a/src/openqaoa-core/optimizers/__init__.py +++ b/src/openqaoa-core/optimizers/__init__.py @@ -7,4 +7,4 @@ """ from .training_vqa import * -from .qaoa_optimizer import * \ No newline at end of file +from .qaoa_optimizer import * diff --git a/src/openqaoa-core/optimizers/optimization_methods/CANS.py b/src/openqaoa-core/optimizers/optimization_methods/CANS.py index ee94c4001..d64172d58 100644 --- a/src/openqaoa-core/optimizers/optimization_methods/CANS.py +++ b/src/openqaoa-core/optimizers/optimization_methods/CANS.py @@ -1,6 +1,7 @@ import numpy as np from scipy.optimize import OptimizeResult + def CANS( fun, x0, @@ -103,4 +104,4 @@ def CANS( return OptimizeResult( fun=besty, x=bestx, nit=niter, nfev=funcalls, success=(niter > 1) - ) \ No newline at end of file + ) diff --git a/src/openqaoa-core/optimizers/optimization_methods/SPSA.py b/src/openqaoa-core/optimizers/optimization_methods/SPSA.py index 02db27ac6..ce91e8e70 100644 --- a/src/openqaoa-core/optimizers/optimization_methods/SPSA.py +++ b/src/openqaoa-core/optimizers/optimization_methods/SPSA.py @@ -110,4 +110,4 @@ def grad_SPSA(params, c): return OptimizeResult( fun=besty, x=bestx, nit=niter, nfev=funcalls, success=(niter > 1) - ) \ No newline at end of file + ) diff --git a/src/openqaoa-core/optimizers/optimization_methods/__init__.py b/src/openqaoa-core/optimizers/optimization_methods/__init__.py index cee687a8f..3e56ab9f5 100644 --- a/src/openqaoa-core/optimizers/optimization_methods/__init__.py +++ b/src/openqaoa-core/optimizers/optimization_methods/__init__.py @@ -3,6 +3,7 @@ from .newton_descent import newton_descent from .natural_grad_descent import natural_grad_descent from .SPSA import SPSA + # from .stochastic_grad_descent import stochastic_grad_descent from .CANS import CANS -from .iCANS import iCANS \ No newline at end of file +from .iCANS import iCANS diff --git a/src/openqaoa-core/optimizers/optimization_methods/grad_descent.py b/src/openqaoa-core/optimizers/optimization_methods/grad_descent.py index b6dab98f1..4811d379b 100644 --- a/src/openqaoa-core/optimizers/optimization_methods/grad_descent.py +++ b/src/openqaoa-core/optimizers/optimization_methods/grad_descent.py @@ -1,6 +1,7 @@ import numpy as np from scipy.optimize import OptimizeResult + def grad_descent( fun, x0, @@ -79,4 +80,4 @@ def grad_descent( return OptimizeResult( fun=besty, x=bestx, nit=niter, nfev=funcalls, success=(niter > 1) - ) \ No newline at end of file + ) diff --git a/src/openqaoa-core/optimizers/optimization_methods/iCANS.py b/src/openqaoa-core/optimizers/optimization_methods/iCANS.py index a6ab3f2b5..525f45cd8 100644 --- a/src/openqaoa-core/optimizers/optimization_methods/iCANS.py +++ b/src/openqaoa-core/optimizers/optimization_methods/iCANS.py @@ -1,6 +1,7 @@ import numpy as np from scipy.optimize import OptimizeResult + def iCANS( fun, x0, diff --git a/src/openqaoa-core/optimizers/optimization_methods/natural_grad_descent.py b/src/openqaoa-core/optimizers/optimization_methods/natural_grad_descent.py index ce35f5bfb..2cd16b172 100644 --- a/src/openqaoa-core/optimizers/optimization_methods/natural_grad_descent.py +++ b/src/openqaoa-core/optimizers/optimization_methods/natural_grad_descent.py @@ -1,6 +1,7 @@ import numpy as np from scipy.optimize import OptimizeResult + def natural_grad_descent( fun, x0, @@ -91,4 +92,4 @@ def natural_grad_descent( return OptimizeResult( fun=besty, x=bestx, nit=niter, nfev=funcalls, success=(niter > 1) - ) \ No newline at end of file + ) diff --git a/src/openqaoa-core/optimizers/optimization_methods/newton_descent.py b/src/openqaoa-core/optimizers/optimization_methods/newton_descent.py index e43ed408f..524523e96 100644 --- a/src/openqaoa-core/optimizers/optimization_methods/newton_descent.py +++ b/src/openqaoa-core/optimizers/optimization_methods/newton_descent.py @@ -1,6 +1,7 @@ import numpy as np from scipy.optimize import OptimizeResult + def newton_descent( fun, x0, @@ -88,4 +89,4 @@ def newton_descent( return OptimizeResult( fun=besty, x=bestx, nit=niter, nfev=funcalls, success=(niter > 1) - ) \ No newline at end of file + ) diff --git a/src/openqaoa-core/optimizers/optimization_methods/rmsprop.py b/src/openqaoa-core/optimizers/optimization_methods/rmsprop.py index b6522fb31..b8ad7349e 100644 --- a/src/openqaoa-core/optimizers/optimization_methods/rmsprop.py +++ b/src/openqaoa-core/optimizers/optimization_methods/rmsprop.py @@ -1,6 +1,7 @@ import numpy as np from scipy.optimize import OptimizeResult + def rmsprop( fun, x0, @@ -88,4 +89,4 @@ def rmsprop( return OptimizeResult( fun=besty, x=bestx, nit=niter, nfev=funcalls, success=(niter > 1) - ) \ No newline at end of file + ) diff --git a/src/openqaoa-core/optimizers/optimization_methods/stochastic_grad_descent.py b/src/openqaoa-core/optimizers/optimization_methods/stochastic_grad_descent.py index bf5828b2e..0feb55889 100644 --- a/src/openqaoa-core/optimizers/optimization_methods/stochastic_grad_descent.py +++ b/src/openqaoa-core/optimizers/optimization_methods/stochastic_grad_descent.py @@ -29,4 +29,4 @@ # if callback is not None: # callback(x) -# return OptimizeResult(x=x, fun=fun(x), jac=g, nit=i + 1, nfev=i + 1, success=True) \ No newline at end of file +# return OptimizeResult(x=x, fun=fun(x), jac=g, nit=i + 1, nfev=i + 1, success=True) diff --git a/src/openqaoa-core/optimizers/pennylane/__init__.py b/src/openqaoa-core/optimizers/pennylane/__init__.py index 3b3516728..ac05e7040 100644 --- a/src/openqaoa-core/optimizers/pennylane/__init__.py +++ b/src/openqaoa-core/optimizers/pennylane/__init__.py @@ -21,7 +21,7 @@ from . import math from . import fourier -#empty class to be used as a placeholder for the QNode class from PennyLane +# empty class to be used as a placeholder for the QNode class from PennyLane class QNode: - def __init__(self): - pass + def __init__(self): + pass diff --git a/src/openqaoa-core/optimizers/pennylane/fourier/reconstruct.py b/src/openqaoa-core/optimizers/pennylane/fourier/reconstruct.py index b1ec6f514..dab59edda 100644 --- a/src/openqaoa-core/optimizers/pennylane/fourier/reconstruct.py +++ b/src/openqaoa-core/optimizers/pennylane/fourier/reconstruct.py @@ -23,7 +23,9 @@ import numpy as np from autoray import numpy as anp -from openqaoa.optimizers import pennylane as qml # changed from the original PennyLane code +from openqaoa.optimizers import ( + pennylane as qml, +) # changed from the original PennyLane code def _reconstruct_equ(fun, num_frequency, x0=None, f0=None, interface=None): @@ -58,7 +60,9 @@ def _reconstruct_equ(fun, num_frequency, x0=None, f0=None, interface=None): differentiable. """ if not abs(int(num_frequency)) == num_frequency: - raise ValueError(f"num_frequency must be a non-negative integer, got {num_frequency}") + raise ValueError( + f"num_frequency must be a non-negative integer, got {num_frequency}" + ) a = (num_frequency + 0.5) / np.pi b = 0.5 / np.pi @@ -69,7 +73,9 @@ def _reconstruct_equ(fun, num_frequency, x0=None, f0=None, interface=None): shifts = anp.asarray(shifts, like=interface) f0 = fun(0.0) if f0 is None else f0 evals = ( - list(map(fun, shifts[:num_frequency])) + [f0] + list(map(fun, shifts[num_frequency + 1 :])) + list(map(fun, shifts[:num_frequency])) + + [f0] + + list(map(fun, shifts[num_frequency + 1 :])) ) evals = anp.asarray(evals, like=interface) @@ -138,8 +144,12 @@ def _reconstruct_gen(fun, spectrum, shifts=None, x0=None, f0=None, interface=Non zero_idx = R need_f0 = True elif have_f0: - zero_idx = qml.math.where(qml.math.isclose(shifts, qml.math.zeros_like(shifts[0]))) - zero_idx = zero_idx[0][0] if (len(zero_idx) > 0 and len(zero_idx[0]) > 0) else None + zero_idx = qml.math.where( + qml.math.isclose(shifts, qml.math.zeros_like(shifts[0])) + ) + zero_idx = ( + zero_idx[0][0] if (len(zero_idx) > 0 and len(zero_idx[0]) > 0) else None + ) need_f0 = zero_idx is not None # Take care of shifts close to zero if f0 was provided @@ -198,7 +208,9 @@ def _parse_ids(ids, info_dict): """ if ids is None: # Infer all id information from info_dict - return {outer_key: inner_dict.keys() for outer_key, inner_dict in info_dict.items()} + return { + outer_key: inner_dict.keys() for outer_key, inner_dict in info_dict.items() + } if isinstance(ids, str): # ids only provides a single argument name but no parameter indices return {ids: info_dict[ids].keys()} @@ -226,7 +238,9 @@ def _parse_shifts(shifts, R, arg_name, par_idx, atol, need_f0): f"number of frequencies (2R+1={2*R+1}) for parameter {par_idx} in " f"argument {arg_name}." ) - if any(qml.math.isclose(_shifts, qml.math.zeros_like(_shifts), rtol=0, atol=atol)): + if any( + qml.math.isclose(_shifts, qml.math.zeros_like(_shifts), rtol=0, atol=atol) + ): # If 0 is among the shifts, f0 is needed return _shifts, True # If 0 is not among the shifts, f0 is not needed @@ -306,7 +320,9 @@ def _prepare_jobs(ids, nums_frequency, spectra, shifts, atol): # Determine spectrum and number of frequencies, discounting for 0 _spectrum = spectra[arg_name][par_idx] R = len(_spectrum) - 1 - _shifts, need_f0 = _parse_shifts(shifts, R, arg_name, par_idx, atol, need_f0) + _shifts, need_f0 = _parse_shifts( + shifts, R, arg_name, par_idx, atol, need_f0 + ) # Store job if R > 0: @@ -330,7 +346,9 @@ def _prepare_jobs(ids, nums_frequency, spectra, shifts, atol): for par_idx in inner_dict: _num_frequency = nums_frequency[arg_name][par_idx] - _jobs[par_idx] = {"num_frequency": _num_frequency} if _num_frequency > 0 else None + _jobs[par_idx] = ( + {"num_frequency": _num_frequency} if _num_frequency > 0 else None + ) jobs[arg_name] = _jobs @@ -621,7 +639,9 @@ def circuit(x, Y, f=1.0): # pylint: disable=cell-var-from-loop, unused-argument atol = 1e-8 - ids, recon_fn, jobs, need_f0 = _prepare_jobs(ids, nums_frequency, spectra, shifts, atol) + ids, recon_fn, jobs, need_f0 = _prepare_jobs( + ids, nums_frequency, spectra, shifts, atol + ) sign_fn = qnode.func if isinstance(qnode, qml.QNode) else qnode arg_names = list(signature(sign_fn).parameters.keys()) arg_idx_from_names = {arg_name: i for i, arg_name in enumerate(arg_names)} @@ -652,7 +672,9 @@ def constant_fn(x): x0 = args[arg_idx] else: shift_vec = qml.math.zeros_like(args[arg_idx]) - shift_vec = qml.math.scatter_element_add(shift_vec, par_idx, 1.0) + shift_vec = qml.math.scatter_element_add( + shift_vec, par_idx, 1.0 + ) x0 = args[arg_idx][par_idx] def _univariate_fn(x): diff --git a/src/openqaoa-core/optimizers/pennylane/math/__init__.py b/src/openqaoa-core/optimizers/pennylane/math/__init__.py index eb2c5b883..3106229a5 100644 --- a/src/openqaoa-core/optimizers/pennylane/math/__init__.py +++ b/src/openqaoa-core/optimizers/pennylane/math/__init__.py @@ -30,7 +30,7 @@ The following frameworks are currently supported: * NumPy -""" # changed from the original PennyLane code +""" # changed from the original PennyLane code import autoray as ar @@ -59,7 +59,14 @@ ) from .quantum import cov_matrix, marginal_prob -from .quantum import reduced_dm, vn_entropy, mutual_info, sqrt_matrix, fidelity, relative_entropy +from .quantum import ( + reduced_dm, + vn_entropy, + mutual_info, + sqrt_matrix, + fidelity, + relative_entropy, +) from .utils import ( allclose, diff --git a/src/openqaoa-core/optimizers/pennylane/math/is_independent.py b/src/openqaoa-core/optimizers/pennylane/math/is_independent.py index 8300d08d8..12aa85414 100644 --- a/src/openqaoa-core/optimizers/pennylane/math/is_independent.py +++ b/src/openqaoa-core/optimizers/pennylane/math/is_independent.py @@ -30,7 +30,9 @@ from autograd.tracer import isbox, new_box, trace_stack from autograd.core import VJPNode -from openqaoa.optimizers.pennylane import numpy as np # changed from the original PennyLane code +from openqaoa.optimizers.pennylane import ( + numpy as np, +) # changed from the original PennyLane code def _autograd_is_indep_analytic(func, *args, **kwargs): @@ -113,7 +115,9 @@ def _jax_is_indep_analytic(func, *args, **kwargs): """ import jax # pylint: disable=import-outside-toplevel - mapped_func = lambda *_args: func(*_args, **kwargs) # pylint: disable=unnecessary-lambda + mapped_func = lambda *_args: func( + *_args, **kwargs + ) # pylint: disable=unnecessary-lambda _vjp = jax.vjp(mapped_func, *args)[1] if _vjp.args[0].args != ((),): return False @@ -185,7 +189,9 @@ def _get_random_args(args, interface, num, seed, bounds): tf.random.set_seed(seed) rnd_args = [] for _ in range(num): - _args = (tf.random.uniform(tf.shape(_arg)) * width + bounds[0] for _arg in args) + _args = ( + tf.random.uniform(tf.shape(_arg)) * width + bounds[0] for _arg in args + ) _args = tuple( tf.Variable(_arg) if isinstance(arg, tf.Variable) else _arg for _arg, arg in zip(_args, args) @@ -196,7 +202,8 @@ def _get_random_args(args, interface, num, seed, bounds): torch.random.manual_seed(seed) rnd_args = [ - tuple(torch.rand(np.shape(arg)) * width + bounds[0] for arg in args) for _ in range(num) + tuple(torch.rand(np.shape(arg)) * width + bounds[0] for arg in args) + for _ in range(num) ] else: np.random.seed(seed) @@ -207,12 +214,16 @@ def _get_random_args(args, interface, num, seed, bounds): if interface == "autograd": # Mark the arguments as trainable with Autograd - rnd_args = [tuple(pnp.array(a, requires_grad=True) for a in arg) for arg in rnd_args] + rnd_args = [ + tuple(pnp.array(a, requires_grad=True) for a in arg) for arg in rnd_args + ] return rnd_args -def _is_indep_numerical(func, interface, args, kwargs, num_pos, seed, atol, rtol, bounds): +def _is_indep_numerical( + func, interface, args, kwargs, num_pos, seed, atol, rtol, bounds +): """Test whether a function returns the same output at random positions. Args: @@ -383,4 +394,6 @@ def lin(x, weights=None): " is a sufficient test, or change the interface." ) - return _is_indep_numerical(func, interface, args, kwargs, num_pos, seed, atol, rtol, bounds) + return _is_indep_numerical( + func, interface, args, kwargs, num_pos, seed, atol, rtol, bounds + ) diff --git a/src/openqaoa-core/optimizers/pennylane/math/matrix_manipulation.py b/src/openqaoa-core/optimizers/pennylane/math/matrix_manipulation.py index 1214a9e2a..ef6e7c9fe 100644 --- a/src/openqaoa-core/optimizers/pennylane/math/matrix_manipulation.py +++ b/src/openqaoa-core/optimizers/pennylane/math/matrix_manipulation.py @@ -24,7 +24,10 @@ import numpy as np from scipy.sparse import csr_matrix, eye, issparse, kron -from openqaoa.optimizers import pennylane as qml # changed from the original PennyLane code +from openqaoa.optimizers import ( + pennylane as qml, +) # changed from the original PennyLane code + Wires = None @@ -110,7 +113,9 @@ def expand_matrix(base_matrix, wires, wire_order=None, sparse_format="csr"): interface = qml.math.get_interface(base_matrix) # pylint: disable=protected-access if interface == "scipy" and issparse(base_matrix): - return _sparse_expand_matrix(base_matrix, wires, wire_order, format=sparse_format) + return _sparse_expand_matrix( + base_matrix, wires, wire_order, format=sparse_format + ) wire_order = qml.wires.Wires(wire_order) n = len(wires) @@ -143,14 +148,19 @@ def expand_matrix(base_matrix, wires, wire_order=None, sparse_format="csr"): sources = [s + 1 for s in sources] mat = qml.math.moveaxis(mat_tensordot, sources, perm) - shape = [batch_dim] + [2 ** len(wire_order)] * 2 if batch_dim else [2 ** len(wire_order)] * 2 + shape = ( + [batch_dim] + [2 ** len(wire_order)] * 2 + if batch_dim + else [2 ** len(wire_order)] * 2 + ) mat = qml.math.reshape(mat, shape) return mat def reduce_matrices( - mats_and_wires_gen: Generator[Tuple[np.ndarray, Wires], None, None], reduce_func: callable + mats_and_wires_gen: Generator[Tuple[np.ndarray, Wires], None, None], + reduce_func: callable, ) -> Tuple[np.ndarray, Wires]: """Apply the given ``reduce_func`` cumulatively to the items of the ``mats_and_wires_gen`` generator, from left to right, so as to reduce the sequence to a tuple containing a single @@ -165,7 +175,9 @@ def reduce_matrices( Tuple[tensor, Wires]: a tuple containing the reduced matrix and the wires it acts on """ - def expand_and_reduce(op1_tuple: Tuple[np.ndarray, Wires], op2_tuple: Tuple[np.ndarray, Wires]): + def expand_and_reduce( + op1_tuple: Tuple[np.ndarray, Wires], op2_tuple: Tuple[np.ndarray, Wires] + ): mat1, wires1 = op1_tuple mat2, wires2 = op2_tuple expanded_wires = wires1 + wires2 @@ -184,7 +196,9 @@ def _local_sparse_swap_mat(i, n, format="csr"): assert i < n - 1 swap_mat = csr_matrix([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) - j = i + 1 # i is the index of the qubit, j is the number of qubits prior to and include qubit i + j = ( + i + 1 + ) # i is the index of the qubit, j is the number of qubits prior to and include qubit i return kron( kron(eye(2 ** (j - 1)), swap_mat), eye(2 ** (n - (j + 1))), format=format ) # (j - 1) + 2 + (n - (j+1)) = n @@ -199,7 +213,8 @@ def _sparse_swap_mat(i, j, n, format="csr"): (small_i, big_j) = (i, j) if i < j else (j, i) store_swaps = [ - _local_sparse_swap_mat(index, n, format=format) for index in range(small_i, big_j) + _local_sparse_swap_mat(index, n, format=format) + for index in range(small_i, big_j) ] res = eye(2**n, format=format) diff --git a/src/openqaoa-core/optimizers/pennylane/math/multi_dispatch.py b/src/openqaoa-core/optimizers/pennylane/math/multi_dispatch.py index 9502ca498..6282d31e4 100644 --- a/src/openqaoa-core/optimizers/pennylane/math/multi_dispatch.py +++ b/src/openqaoa-core/optimizers/pennylane/math/multi_dispatch.py @@ -85,7 +85,9 @@ def _multi_dispatch(values): if len(set(interfaces) - {"numpy", "scipy", "autograd"}) > 1: # contains multiple non-autograd interfaces - raise ValueError("Tensors contain mixed types; cannot determine dispatch library") + raise ValueError( + "Tensors contain mixed types; cannot determine dispatch library" + ) non_numpy_scipy_interfaces = set(interfaces) - {"numpy", "scipy"} @@ -274,7 +276,9 @@ def concatenate(values, axis=0, like=None): device = ( "cuda" - if any(t.device.type == "cuda" for t in values if isinstance(t, torch.Tensor)) + if any( + t.device.type == "cuda" for t in values if isinstance(t, torch.Tensor) + ) else "cpu" ) @@ -282,13 +286,16 @@ def concatenate(values, axis=0, like=None): # flatten and then concatenate zero'th dimension # to reproduce numpy's behaviour values = [ - np.flatten(torch.as_tensor(t, device=torch.device(device))) # pragma: no cover + np.flatten( + torch.as_tensor(t, device=torch.device(device)) + ) # pragma: no cover for t in values ] axis = 0 else: values = [ - torch.as_tensor(t, device=torch.device(device)) for t in values # pragma: no cover + torch.as_tensor(t, device=torch.device(device)) + for t in values # pragma: no cover ] if like == "tensorflow" and axis is None: diff --git a/src/openqaoa-core/optimizers/pennylane/math/quantum.py b/src/openqaoa-core/optimizers/pennylane/math/quantum.py index a2596b461..0fd15dd5c 100644 --- a/src/openqaoa-core/optimizers/pennylane/math/quantum.py +++ b/src/openqaoa-core/optimizers/pennylane/math/quantum.py @@ -24,7 +24,9 @@ from autoray import numpy as np from numpy import float64 -from openqaoa.optimizers import pennylane as qml # changed from the original PennyLane code +from openqaoa.optimizers import ( + pennylane as qml, +) # changed from the original PennyLane code from . import single_dispatch # pylint:disable=unused-import from .multi_dispatch import diag, dot, scatter_element_add, einsum, get_interface @@ -322,7 +324,10 @@ def _partial_trace_autograd(density_matrix, indices): ] # index for summation over Kraus operators kraus_index = ABC[ - rho_dim + 2 * num_partial_trace_wires : rho_dim + 2 * num_partial_trace_wires + 1 + rho_dim + + 2 * num_partial_trace_wires : rho_dim + + 2 * num_partial_trace_wires + + 1 ] # new state indices replace row and column indices with new ones new_state_indices = functools.reduce( @@ -393,7 +398,9 @@ def _density_matrix_from_state_vector(state, indices, check_state=False): traced_system = [x for x in consecutive_wires if x not in indices] # Return the reduced density matrix by using numpy tensor product - density_matrix = np.tensordot(state, np.conj(state), axes=(traced_system, traced_system)) + density_matrix = np.tensordot( + state, np.conj(state), axes=(traced_system, traced_system) + ) density_matrix = np.reshape(density_matrix, (2 ** len(indices), 2 ** len(indices))) return density_matrix @@ -540,7 +547,9 @@ def _compute_vn_entropy(density_matrix, base=None): # pylint: disable=too-many-arguments -def mutual_info(state, indices0, indices1, base=None, check_state=False, c_dtype="complex128"): +def mutual_info( + state, indices0, indices1, base=None, check_state=False, c_dtype="complex128" +): r"""Compute the mutual information between two subsystems given a state: .. math:: @@ -592,7 +601,9 @@ def mutual_info(state, indices0, indices1, base=None, check_state=False, c_dtype # the subsystems cannot overlap if len([index for index in indices0 if index in indices1]) > 0: - raise ValueError("Subsystems for computing mutual information must not overlap.") + raise ValueError( + "Subsystems for computing mutual information must not overlap." + ) # Cast to a complex array state = cast(state, dtype=c_dtype) @@ -602,7 +613,12 @@ def mutual_info(state, indices0, indices1, base=None, check_state=False, c_dtype len_state = state_shape[0] if state_shape in [(len_state,), (len_state, len_state)]: return _compute_mutual_info( - state, indices0, indices1, base=base, check_state=check_state, c_dtype=c_dtype + state, + indices0, + indices1, + base=base, + check_state=check_state, + c_dtype=c_dtype, ) raise ValueError("The state is not a state vector or a density matrix.") @@ -716,7 +732,9 @@ def fidelity(state0, state1, check_state=False, c_dtype="complex128"): num_indices1 = int(np.log2(len_state1)) if num_indices0 != num_indices1: - raise qml.QuantumFunctionError("The two states must have the same number of wires.") + raise qml.QuantumFunctionError( + "The two states must have the same number of wires." + ) # Two pure states, squared overlap if state1.shape == (len_state1,) and state0.shape == (len_state0,): @@ -815,7 +833,9 @@ def _compute_relative_entropy(rho, sigma, base=None): return (rel - ent) / div_base -def relative_entropy(state0, state1, base=None, check_state=False, c_dtype="complex128"): +def relative_entropy( + state0, state1, base=None, check_state=False, c_dtype="complex128" +): r""" Compute the quantum relative entropy of one state with respect to another. @@ -894,7 +914,9 @@ def relative_entropy(state0, state1, base=None, check_state=False, c_dtype="comp num_indices1 = int(np.log2(len_state1)) if num_indices0 != num_indices1: - raise qml.QuantumFunctionError("The two states must have the same number of wires.") + raise qml.QuantumFunctionError( + "The two states must have the same number of wires." + ) if state0.shape == (len_state0,): state0 = qml.math.outer(state0, np.conj(state0)) diff --git a/src/openqaoa-core/optimizers/pennylane/math/single_dispatch.py b/src/openqaoa-core/optimizers/pennylane/math/single_dispatch.py index fcac2d6d0..bc7e1eeac 100644 --- a/src/openqaoa-core/optimizers/pennylane/math/single_dispatch.py +++ b/src/openqaoa-core/optimizers/pennylane/math/single_dispatch.py @@ -178,9 +178,13 @@ def _take_autograd(tensor, indices, axis=None): ar.register_function("autograd", "take", _take_autograd) -ar.register_function("autograd", "eigvalsh", lambda x: _i("autograd").numpy.linalg.eigh(x)[0]) ar.register_function( - "autograd", "entr", lambda x: -_i("autograd").numpy.sum(x * _i("autograd").numpy.log(x)) + "autograd", "eigvalsh", lambda x: _i("autograd").numpy.linalg.eigh(x)[0] +) +ar.register_function( + "autograd", + "entr", + lambda x: -_i("autograd").numpy.sum(x * _i("autograd").numpy.log(x)), ) ar.register_function("autograd", "diagonal", lambda x, *args: _i("qml").numpy.diag(x)) @@ -197,10 +201,14 @@ def _take_autograd(tensor, indices, axis=None): ar.autoray._SUBMODULE_ALIASES["tensorflow", "arctan2"] = "tensorflow.math" ar.autoray._SUBMODULE_ALIASES["tensorflow", "diag"] = "tensorflow.linalg" ar.autoray._SUBMODULE_ALIASES["tensorflow", "kron"] = "tensorflow.experimental.numpy" -ar.autoray._SUBMODULE_ALIASES["tensorflow", "moveaxis"] = "tensorflow.experimental.numpy" +ar.autoray._SUBMODULE_ALIASES[ + "tensorflow", "moveaxis" +] = "tensorflow.experimental.numpy" ar.autoray._SUBMODULE_ALIASES["tensorflow", "sinc"] = "tensorflow.experimental.numpy" ar.autoray._SUBMODULE_ALIASES["tensorflow", "isclose"] = "tensorflow.experimental.numpy" -ar.autoray._SUBMODULE_ALIASES["tensorflow", "atleast_1d"] = "tensorflow.experimental.numpy" +ar.autoray._SUBMODULE_ALIASES[ + "tensorflow", "atleast_1d" +] = "tensorflow.experimental.numpy" ar.autoray._FUNC_ALIASES["tensorflow", "arcsin"] = "asin" ar.autoray._FUNC_ALIASES["tensorflow", "arccos"] = "acos" @@ -353,11 +361,17 @@ def _transpose_tf(a, axes=None): ar.register_function("tensorflow", "transpose", _transpose_tf) -ar.register_function("tensorflow", "diagonal", lambda x, *args: _i("tf").linalg.diag_part(x)) -ar.register_function("tensorflow", "outer", lambda a, b: _i("tf").tensordot(a, b, axes=0)) +ar.register_function( + "tensorflow", "diagonal", lambda x, *args: _i("tf").linalg.diag_part(x) +) +ar.register_function( + "tensorflow", "outer", lambda a, b: _i("tf").tensordot(a, b, axes=0) +) # for some reason Autoray modifies the default behaviour, so we change it back here -ar.register_function("tensorflow", "where", lambda *args, **kwargs: _i("tf").where(*args, **kwargs)) +ar.register_function( + "tensorflow", "where", lambda *args, **kwargs: _i("tf").where(*args, **kwargs) +) def _eigvalsh_tf(density_matrix): @@ -445,7 +459,9 @@ def _asarray_torch(x, dtype=None, **kwargs): ar.register_function("torch", "asarray", _asarray_torch) ar.register_function("torch", "diag", lambda x, k=0: _i("torch").diag(x, diagonal=k)) -ar.register_function("torch", "expand_dims", lambda x, axis: _i("torch").unsqueeze(x, dim=axis)) +ar.register_function( + "torch", "expand_dims", lambda x, axis: _i("torch").unsqueeze(x, dim=axis) +) ar.register_function("torch", "shape", lambda x: tuple(x.shape)) ar.register_function("torch", "gather", lambda x, indices: x[indices]) ar.register_function("torch", "equal", lambda x, y: _i("torch").eq(x, y)) @@ -454,7 +470,9 @@ def _asarray_torch(x, dtype=None, **kwargs): "torch", "sqrt", lambda x: _i("torch").sqrt( - x.to(_i("torch").float64) if x.dtype in (_i("torch").int64, _i("torch").int32) else x + x.to(_i("torch").float64) + if x.dtype in (_i("torch").int64, _i("torch").int32) + else x ), ) @@ -608,7 +626,9 @@ def _ndim_torch(tensor): ar.register_function("torch", "ndim", _ndim_torch) ar.register_function("torch", "eigvalsh", lambda x: _i("torch").linalg.eigvalsh(x)) -ar.register_function("torch", "entr", lambda x: _i("torch").sum(_i("torch").special.entr(x))) +ar.register_function( + "torch", "entr", lambda x: _i("torch").sum(_i("torch").special.entr(x)) +) def _sum_torch(tensor, axis=None, keepdims=False, dtype=None): @@ -651,7 +671,9 @@ def _to_numpy_jax(x): ) ar.register_function("jax", "coerce", lambda x: x) ar.register_function("jax", "to_numpy", _to_numpy_jax) -ar.register_function("jax", "block_diag", lambda x: _i("jax").scipy.linalg.block_diag(*x)) +ar.register_function( + "jax", "block_diag", lambda x: _i("jax").scipy.linalg.block_diag(*x) +) ar.register_function("jax", "gather", lambda x, indices: x[np.array(indices)]) @@ -672,10 +694,14 @@ def _scatter_jax(indices, array, new_dimensions): ar.register_function("jax", "unstack", list) # pylint: disable=unnecessary-lambda ar.register_function("jax", "eigvalsh", lambda x: _i("jax").numpy.linalg.eigvalsh(x)) -ar.register_function("jax", "entr", lambda x: _i("jax").numpy.sum(_i("jax").scipy.special.entr(x))) +ar.register_function( + "jax", "entr", lambda x: _i("jax").numpy.sum(_i("jax").scipy.special.entr(x)) +) ar.register_function( "jax", "cond", - lambda pred, true_fn, false_fn, args: _i("jax").lax.cond(pred, true_fn, false_fn, *args), + lambda pred, true_fn, false_fn, args: _i("jax").lax.cond( + pred, true_fn, false_fn, *args + ), ) diff --git a/src/openqaoa-core/optimizers/pennylane/math/utils.py b/src/openqaoa-core/optimizers/pennylane/math/utils.py index 391af13fe..8c3e33771 100644 --- a/src/openqaoa-core/optimizers/pennylane/math/utils.py +++ b/src/openqaoa-core/optimizers/pennylane/math/utils.py @@ -294,7 +294,9 @@ def function(x): import jax from jax.interpreters.partial_eval import DynamicJaxprTracer - if isinstance(tensor, (jax.ad.JVPTracer, jax.interpreters.batching.BatchTracer)): + if isinstance( + tensor, (jax.ad.JVPTracer, jax.interpreters.batching.BatchTracer) + ): # Tracer objects will be used when computing gradients or applying transforms. # If the value of the tracer is known, it will contain a ConcreteArray. # Otherwise, it will be abstract. diff --git a/src/openqaoa-core/optimizers/pennylane/numpy/random.py b/src/openqaoa-core/optimizers/pennylane/numpy/random.py index 68a884149..0de8e054b 100644 --- a/src/openqaoa-core/optimizers/pennylane/numpy/random.py +++ b/src/openqaoa-core/optimizers/pennylane/numpy/random.py @@ -34,7 +34,9 @@ class Generator(_random.Generator): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.__doc__ = "PennyLane wrapped NumPy Generator object\n" + super().__doc__ + self.__doc__ = ( + "PennyLane wrapped NumPy Generator object\n" + super().__doc__ + ) for name in dir(_random.Generator): if name[0] != "_": diff --git a/src/openqaoa-core/optimizers/pennylane/numpy/tensor.py b/src/openqaoa-core/optimizers/pennylane/numpy/tensor.py index 8acaa9397..a8e11156e 100644 --- a/src/openqaoa-core/optimizers/pennylane/numpy/tensor.py +++ b/src/openqaoa-core/optimizers/pennylane/numpy/tensor.py @@ -25,7 +25,9 @@ from autograd.core import VSpace -__doc__ = "NumPy with automatic differentiation support, provided by Autograd and PennyLane." +__doc__ = ( + "NumPy with automatic differentiation support, provided by Autograd and PennyLane." +) # Hotfix since _np.asarray doesn't have a gradient rule defined. @primitive @@ -165,7 +167,8 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): # if any of the inputs were trainable, the output is also trainable requires_grad = any( - isinstance(x, onp.ndarray) and getattr(x, "requires_grad", True) for x in inputs + isinstance(x, onp.ndarray) and getattr(x, "requires_grad", True) + for x in inputs ) # Iterate through the ufunc outputs and convert each to a PennyLane tensor. @@ -310,4 +313,6 @@ def tensor_to_arraybox(x, *args): Box.type_mappings[tensor] = tensor_to_arraybox -VSpace.mappings[tensor] = lambda x: ComplexArrayVSpace(x) if onp.iscomplexobj(x) else ArrayVSpace(x) +VSpace.mappings[tensor] = ( + lambda x: ComplexArrayVSpace(x) if onp.iscomplexobj(x) else ArrayVSpace(x) +) diff --git a/src/openqaoa-core/optimizers/pennylane/numpy/wrapper.py b/src/openqaoa-core/optimizers/pennylane/numpy/wrapper.py index dee567dac..c91fde1ff 100644 --- a/src/openqaoa-core/optimizers/pennylane/numpy/wrapper.py +++ b/src/openqaoa-core/optimizers/pennylane/numpy/wrapper.py @@ -111,7 +111,9 @@ def _wrapped(*args, **kwargs): # Equivalently: if any tensor is trainable, the output is also trainable. # NOTE: Use of Python's ``any`` results in an infinite recursion, # and I'm not sure why. Using ``np.any`` works fine. - tensor_kwargs["requires_grad"] = _np.any([i.requires_grad for i in tensor_args]) + tensor_kwargs["requires_grad"] = _np.any( + [i.requires_grad for i in tensor_args] + ) # evaluate the original object res = obj(*args, **kwargs) diff --git a/src/openqaoa-core/optimizers/pennylane/optimization_methods_pennylane.py b/src/openqaoa-core/optimizers/pennylane/optimization_methods_pennylane.py index 27be11716..9a02bc159 100644 --- a/src/openqaoa-core/optimizers/pennylane/optimization_methods_pennylane.py +++ b/src/openqaoa-core/optimizers/pennylane/optimization_methods_pennylane.py @@ -25,23 +25,34 @@ import numpy as np AVAILABLE_OPTIMIZERS = { # optimizers implemented - 'pennylane_adagrad': pl.AdagradOptimizer, - 'pennylane_adam': pl.AdamOptimizer, - 'pennylane_vgd': pl.GradientDescentOptimizer, - 'pennylane_momentum': pl.MomentumOptimizer, - 'pennylane_nesterov_momentum': pl.NesterovMomentumOptimizer, - 'pennylane_rmsprop': pl.RMSPropOptimizer, - 'pennylane_rotosolve': pl.RotosolveOptimizer, - 'pennylane_spsa': pl.SPSAOptimizer, - } - - - -def pennylane_optimizer(fun, x0, args=(), maxfev=None, pennylane_method='vgd', - maxiter=100, tol=10**(-6), jac=None, callback=None, - nums_frequency=None, spectra=None, shifts=None, **options): - - ''' + "pennylane_adagrad": pl.AdagradOptimizer, + "pennylane_adam": pl.AdamOptimizer, + "pennylane_vgd": pl.GradientDescentOptimizer, + "pennylane_momentum": pl.MomentumOptimizer, + "pennylane_nesterov_momentum": pl.NesterovMomentumOptimizer, + "pennylane_rmsprop": pl.RMSPropOptimizer, + "pennylane_rotosolve": pl.RotosolveOptimizer, + "pennylane_spsa": pl.SPSAOptimizer, +} + + +def pennylane_optimizer( + fun, + x0, + args=(), + maxfev=None, + pennylane_method="vgd", + maxiter=100, + tol=10 ** (-6), + jac=None, + callback=None, + nums_frequency=None, + spectra=None, + shifts=None, + **options +): + + """ Minimize a function `fun` using some pennylane method. To check available methods look at the available_methods_dict variable. Read https://docs.pennylane.ai/en/stable/introduction/interfaces.html#optimizers @@ -87,31 +98,34 @@ def pennylane_optimizer(fun, x0, args=(), maxfev=None, pennylane_method='vgd', ------- OptimizeResult : OptimizeResult Scipy OptimizeResult object. - ''' + """ - def cost(params, **k): # define a function to convert the params list from pennylane to numpy + def cost( + params, **k + ): # define a function to convert the params list from pennylane to numpy return fun(np.array(params), *k) + optimizer = AVAILABLE_OPTIMIZERS[pennylane_method] # define the optimizer - optimizer = AVAILABLE_OPTIMIZERS[pennylane_method] # define the optimizer - - #get optimizer arguments + # get optimizer arguments arguments = inspect.signature(optimizer).parameters.keys() options_keys = list(options.keys()) - #check which values of the options dict can be passed to the optimizer (pop the others) + # check which values of the options dict can be passed to the optimizer (pop the others) for key in options_keys: - if key not in arguments: options.pop(key) - if 'maxiter' in arguments: options['maxiter'] = maxiter + if key not in arguments: + options.pop(key) + if "maxiter" in arguments: + options["maxiter"] = maxiter + + optimizer = optimizer(**options) # pass the arguments - optimizer = optimizer(**options) #pass the arguments - bestx = pl.numpy.array(x0, requires_grad=True) besty = cost(x0, *args) funcalls = 1 # tracks no. of function evals. niter = 0 improved = True - stop = False + stop = False testx = np.copy(bestx) testy = np.real(besty) @@ -119,21 +133,32 @@ def cost(params, **k): # define a function to convert the params list from penny improved = False # compute step (depends on the optimizer) - if pennylane_method in ['pennylane_adagrad', 'pennylane_adam', 'pennylane_vgd', 'pennylane_momentum', 'pennylane_nesterov_momentum', 'pennylane_rmsprop']: + if pennylane_method in [ + "pennylane_adagrad", + "pennylane_adam", + "pennylane_vgd", + "pennylane_momentum", + "pennylane_nesterov_momentum", + "pennylane_rmsprop", + ]: testx, testy = optimizer.step_and_cost(cost, bestx, *args, grad_fn=jac) - elif pennylane_method in ['pennylane_rotosolve']: + elif pennylane_method in ["pennylane_rotosolve"]: testx, testy = optimizer.step_and_cost( - cost, bestx, *args, - nums_frequency={'params': {(i,):1 for i in range(bestx.size)}} if not nums_frequency else nums_frequency, - spectra=spectra, - shifts=shifts, - full_output=False, - ) - elif pennylane_method in ['pennylane_spsa']: + cost, + bestx, + *args, + nums_frequency={"params": {(i,): 1 for i in range(bestx.size)}} + if not nums_frequency + else nums_frequency, + spectra=spectra, + shifts=shifts, + full_output=False, + ) + elif pennylane_method in ["pennylane_spsa"]: testx, testy = optimizer.step_and_cost(cost, bestx, *args) # check if stable - if np.abs(besty-testy) < tol and niter > 1: + if np.abs(besty - testy) < tol and niter > 1: improved = False else: @@ -148,8 +173,7 @@ def cost(params, **k): # define a function to convert the params list from penny break niter += 1 - - return OptimizeResult(fun=besty, x=np.array(bestx), nit=niter, - nfev=funcalls, success=(niter > 1)) - + return OptimizeResult( + fun=besty, x=np.array(bestx), nit=niter, nfev=funcalls, success=(niter > 1) + ) diff --git a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/__init__.py b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/__init__.py index 945e765f7..82c309c22 100644 --- a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/__init__.py +++ b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/__init__.py @@ -23,4 +23,4 @@ from .nesterov_momentum import * from .rms_prop import * from .rotosolve import * -from .spsa import * \ No newline at end of file +from .spsa import * diff --git a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/adagrad.py b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/adagrad.py index 9230f144c..e0920cba2 100644 --- a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/adagrad.py +++ b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/adagrad.py @@ -16,7 +16,7 @@ # Lines modified by Entropica Labs will bear the comment # changed from the original PennyLane code """Adagrad optimizer""" -from numpy import sqrt # changed from the original PennyLane code +from numpy import sqrt # changed from the original PennyLane code from .gradient_descent import GradientDescentOptimizer diff --git a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/adam.py b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/adam.py index 21de6d52a..b69743c4b 100644 --- a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/adam.py +++ b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/adam.py @@ -16,7 +16,7 @@ # Lines modified by Entropica Labs will bear the comment # changed from the original PennyLane code """Adam optimizer""" -from numpy import sqrt # changed from the original PennyLane code +from numpy import sqrt # changed from the original PennyLane code from .gradient_descent import GradientDescentOptimizer @@ -92,9 +92,9 @@ def apply_grad(self, grad, args): if getattr(arg, "requires_grad", False): self._update_accumulation(index, grad[trained_index]) - args_new[index] = arg - new_stepsize * self.accumulation["fm"][index] / ( - sqrt(self.accumulation["sm"][index]) + self.eps - ) + args_new[index] = arg - new_stepsize * self.accumulation["fm"][ + index + ] / (sqrt(self.accumulation["sm"][index]) + self.eps) trained_index += 1 diff --git a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/gradient_descent.py b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/gradient_descent.py index e73e4a801..a8b9e942f 100644 --- a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/gradient_descent.py +++ b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/gradient_descent.py @@ -17,7 +17,8 @@ """Gradient descent optimizer""" -get_gradient = None # changed from the original PennyLane code +get_gradient = None # changed from the original PennyLane code + class GradientDescentOptimizer: r"""Basic gradient-descent optimizer. diff --git a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/momentum.py b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/momentum.py index 5cb25e48f..027ce8ac2 100644 --- a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/momentum.py +++ b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/momentum.py @@ -77,7 +77,9 @@ def _update_accumulation(self, index, grad): index (int): index of argument to update. grad (ndarray): gradient at index """ - self.accumulation[index] = self.momentum * self.accumulation[index] + self.stepsize * grad + self.accumulation[index] = ( + self.momentum * self.accumulation[index] + self.stepsize * grad + ) def reset(self): """Reset optimizer by erasing memory of past steps.""" diff --git a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/nesterov_momentum.py b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/nesterov_momentum.py index a1681fbe0..e25762d3f 100644 --- a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/nesterov_momentum.py +++ b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/nesterov_momentum.py @@ -16,7 +16,7 @@ # Lines modified by Entropica Labs will bear the comment # changed from the original PennyLane code """Nesterov momentum optimizer""" -get_gradient = None # changed from the original PennyLane code +get_gradient = None # changed from the original PennyLane code from .momentum import MomentumOptimizer @@ -69,7 +69,9 @@ def compute_grad( if self.accumulation: for index in trainable_indices: - shifted_args[index] = args[index] - self.momentum * self.accumulation[index] + shifted_args[index] = ( + args[index] - self.momentum * self.accumulation[index] + ) g = get_gradient(objective_fn) if grad_fn is None else grad_fn grad = g(*shifted_args, **kwargs) diff --git a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/rotosolve.py b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/rotosolve.py index 74e7577e2..1f6ddec3f 100644 --- a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/rotosolve.py +++ b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/rotosolve.py @@ -22,7 +22,9 @@ import numpy as np from scipy.optimize import brute, shgo -from openqaoa.optimizers import pennylane as qml # changed from the original PennyLane code +from openqaoa.optimizers import ( + pennylane as qml, +) # changed from the original PennyLane code def _brute_optimizer(fun, num_steps, bounds=None, **kwargs): @@ -34,7 +36,9 @@ def _brute_optimizer(fun, num_steps, bounds=None, **kwargs): center = (bounds[0][1] + bounds[0][0]) / 2 for _ in range(num_steps): range_ = (center - width / 2, center + width / 2) - center, y_min, *_ = brute(fun, ranges=(range_,), full_output=True, Ns=Ns, **kwargs) + center, y_min, *_ = brute( + fun, ranges=(range_,), full_output=True, Ns=Ns, **kwargs + ) # We only ever use this function for 1D optimization center = center[0] width /= Ns @@ -100,7 +104,9 @@ def _restrict_to_univariate(fn, arg_idx, par_idx, args, kwargs): shift_vec = qml.math.scatter_element_add(shift_vec, par_idx, 1.0) def _univariate_fn(x): - return fn(*args[:arg_idx], the_arg + shift_vec * x, *args[arg_idx + 1 :], **kwargs) + return fn( + *args[:arg_idx], the_arg + shift_vec * x, *args[arg_idx + 1 :], **kwargs + ) return _univariate_fn @@ -416,10 +422,15 @@ def step_and_cost( """ # todo: does this signature call cover all cases? - sign_fn = objective_fn.func if isinstance(objective_fn, qml.QNode) else objective_fn + sign_fn = ( + objective_fn.func if isinstance(objective_fn, qml.QNode) else objective_fn + ) arg_names = list(signature(sign_fn).parameters.keys()) requires_grad = { - arg_name: True for arg_name, arg in zip(arg_names, args) # changed from the original PennyLane code + arg_name: True + for arg_name, arg in zip( + arg_names, args + ) # changed from the original PennyLane code } nums_frequency = nums_frequency or {} spectra = spectra or {} @@ -453,7 +464,10 @@ def step_and_cost( if spectrum is not None: spectrum = np.array(spectrum) - if num_freq == 1 or (spectrum is not None and len(spectrum[spectrum > 0])) == 1: + if ( + num_freq == 1 + or (spectrum is not None and len(spectrum[spectrum > 0])) == 1 + ): _args = before_args + [arg] + after_args univariate = _restrict_to_univariate( objective_fn, arg_idx, par_idx, _args, kwargs @@ -465,24 +479,32 @@ def step_and_cost( else: ids = {arg_name: (par_idx,)} _nums_frequency = ( - {arg_name: {par_idx: num_freq}} if num_freq is not None else None + {arg_name: {par_idx: num_freq}} + if num_freq is not None + else None + ) + _spectra = ( + {arg_name: {par_idx: spectrum}} + if spectrum is not None + else None ) - _spectra = {arg_name: {par_idx: spectrum}} if spectrum is not None else None # Set up the reconstruction function recon_fn = qml.fourier.reconstruct( objective_fn, ids, _nums_frequency, _spectra, shifts ) # Perform the reconstruction - recon = recon_fn(*before_args, arg, *after_args, f0=_fun_at_zero, **kwargs)[ - arg_name - ][par_idx] + recon = recon_fn( + *before_args, arg, *after_args, f0=_fun_at_zero, **kwargs + )[arg_name][par_idx] if spectrum is None: spectrum = list(range(num_freq + 1)) x_min, y_min = self._min_numeric(recon, spectrum) # Update the currently treated argument - arg = qml.math.scatter_element_add(arg, par_idx, x_min - arg[par_idx]) + arg = qml.math.scatter_element_add( + arg, par_idx, x_min - arg[par_idx] + ) first_substep_in_step = False if full_output: diff --git a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/spsa.py b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/spsa.py index 256e8fbbc..b66d00fb7 100644 --- a/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/spsa.py +++ b/src/openqaoa-core/optimizers/pennylane/pennylane_optimizers/spsa.py @@ -17,7 +17,9 @@ """SPSA optimizer""" -from openqaoa.optimizers.pennylane import numpy as np # changed from the original PennyLane code +from openqaoa.optimizers.pennylane import ( + numpy as np, +) # changed from the original PennyLane code class SPSAOptimizer: diff --git a/src/openqaoa-core/optimizers/qaoa_optimizer.py b/src/openqaoa-core/optimizers/qaoa_optimizer.py index df5f9d2bf..3c6584d20 100644 --- a/src/openqaoa-core/optimizers/qaoa_optimizer.py +++ b/src/openqaoa-core/optimizers/qaoa_optimizer.py @@ -1,9 +1,11 @@ from .training_vqa import ( ScipyOptimizer, CustomScipyGradientOptimizer, - PennyLaneOptimizer + PennyLaneOptimizer, +) +from ..qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, ) -from ..qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams from ..backends.basebackend import VQABaseBackend diff --git a/src/openqaoa-core/optimizers/training_vqa.py b/src/openqaoa-core/optimizers/training_vqa.py index 70e321ef4..e584d0f8c 100644 --- a/src/openqaoa-core/optimizers/training_vqa.py +++ b/src/openqaoa-core/optimizers/training_vqa.py @@ -11,7 +11,9 @@ from ..backends.basebackend import VQABaseBackend from ..backends.qaoa_vectorized import QAOAvectorizedBackendSimulator -from ..qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from ..qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) from . import optimization_methods as om from .pennylane import optimization_methods_pennylane as ompl diff --git a/src/openqaoa-core/problems/knapsack.py b/src/openqaoa-core/problems/knapsack.py index e39b24503..65728ad01 100644 --- a/src/openqaoa-core/problems/knapsack.py +++ b/src/openqaoa-core/problems/knapsack.py @@ -215,7 +215,7 @@ def terms_and_weights(self): ) ) ) - + @property def qubo(self): """ diff --git a/src/openqaoa-core/qaoa_components/ansatz_constructor/__init__.py b/src/openqaoa-core/qaoa_components/ansatz_constructor/__init__.py index 5024191ac..3eebf81d9 100644 --- a/src/openqaoa-core/qaoa_components/ansatz_constructor/__init__.py +++ b/src/openqaoa-core/qaoa_components/ansatz_constructor/__init__.py @@ -1,3 +1,3 @@ from .gatemap import * from .baseparams import QAOADescriptor -from .operators import PauliOp, Hamiltonian \ No newline at end of file +from .operators import PauliOp, Hamiltonian diff --git a/src/openqaoa-core/qaoa_components/ansatz_constructor/baseparams.py b/src/openqaoa-core/qaoa_components/ansatz_constructor/baseparams.py index 1e2de6e54..7e7663e50 100644 --- a/src/openqaoa-core/qaoa_components/ansatz_constructor/baseparams.py +++ b/src/openqaoa-core/qaoa_components/ansatz_constructor/baseparams.py @@ -1,12 +1,15 @@ from __future__ import annotations -from abc import ABC -from typing import List, Union, Tuple, Any, Callable, Iterable +from abc import ABC, abstractproperty +from typing import List, Union, Tuple, Any, Callable, Iterable, Optional import numpy as np +from enum import Enum +import copy from .operators import Hamiltonian from .hamiltonianmapper import HamiltonianMapper +from .gatemap import RotationGateMap, SWAPGateMap +from .gatemaplabel import GateMapType -from .gatemap import RotationGateMap def _is_iterable_empty(in_iterable): if isinstance(in_iterable, Iterable): # Is Iterable @@ -92,7 +95,7 @@ class AnsatzDescriptor(ABC): Parameters ---------- algorithm: `str` - + The algorithm corresponding to the ansatz Attributes ---------- algorithm: `str` @@ -101,6 +104,10 @@ class AnsatzDescriptor(ABC): def __init__(self, algorithm: str): self.algorithm = algorithm + @abstractproperty + def n_qubits(self) -> int: + pass + class QAOADescriptor(AnsatzDescriptor): @@ -108,23 +115,6 @@ class QAOADescriptor(AnsatzDescriptor): Create the problem attributes consisting of the Hamiltonian, QAOA 'p' value and other specific parameters. - Parameters - ---------- - cost_hamiltonian: `Hamiltonian` - The cost hamiltonian of the problem the user is trying to solve. - - mixer_block: `Union[List[RotationGateMap], Hamiltonian]` - The mixer hamiltonian or a list of initialised RotationGateMap objects - that defines the gates to be used within the "mixer part" of the circuit. - - p: `int` - Number of QAOA layers; defaults to 1 if not specified - - mixer_coeffs: `List[float]` - A list containing coefficients for each mixer GateMap. The order of the - coefficients should follow the order of the GateMaps provided in the relevant gate block. - This input isnt required if the input mixer block is of type Hamiltonian. - Attributes ---------- cost_hamiltonian: `Hamiltonian` @@ -143,11 +133,13 @@ class QAOADescriptor(AnsatzDescriptor): mixer_block_coeffs: `List[float]` + cost_blocks: `List[RotationGateMap]` + + mixer_blocks: `List[RotationGateMap]` + Properties ---------- - cost_block: `List[RotationGateMap]` - - mixer_block: `List[RotationGateMap]` + n_qubits: `int` abstract_circuit: `List[RotationGateMap]` """ @@ -158,13 +150,32 @@ def __init__( mixer_block: Union[List[RotationGateMap], Hamiltonian], p: int, mixer_coeffs: List[float] = [], + routing_function: Optional[Callable] = None, + device: Optional["DeviceBase"] = None, ): + """ + Parameters + ---------- + cost_hamiltonian: `Hamiltonian` + The cost hamiltonian of the problem the user is trying to solve. + mixer_block: Union[List[RotationGateMap], Hamiltonian] + The mixer hamiltonian or a list of initialised RotationGateMap objects + that defines the gates to be used within the "mixer part" of the circuit. + p: `int` + Number of QAOA layers; defaults to 1 if not specified + mixer_coeffs: `List[float]` + A list containing coefficients for each mixer GateMap. The order of the + coefficients should follow the order of the GateMaps provided in the relevant gate block. + This input isnt required if the input mixer block is of type Hamiltonian. + routing_function Optional[Callable] + A callable function running the routing algorithm on the problem + device: DeviceBase + The device on which to run the Quantum Circuit + """ super().__init__(algorithm="QAOA") self.p = p - - self.qureg = cost_hamiltonian.qureg self.cost_block_coeffs = cost_hamiltonian.coeffs try: @@ -175,87 +186,55 @@ def __init__( # Needed in the BaseBackend to compute exact_solution, cost_funtion method # and bitstring_energy self.cost_hamiltonian = cost_hamiltonian - self.cost_block = cost_hamiltonian - self.mixer_block = mixer_block - + self.cost_block = self.block_setter(cost_hamiltonian, GateMapType.COST) ( self.cost_single_qubit_coeffs, self.cost_pair_qubit_coeffs, self.cost_qubits_singles, self.cost_qubits_pairs, - ) = self._assign_coefficients(self.cost_block[0], self.cost_block_coeffs) + ) = self._assign_coefficients(self.cost_block, self.cost_block_coeffs) + + # route the cost block and append SWAP gates + if isinstance(routing_function, Callable): + try: + ( + self.cost_block, + self.initial_mapping, + self.final_mapping, + ) = self.route_gates_list(self.cost_block, device, routing_function) + self.routed = True + except TypeError: + raise TypeError( + "The specified function can has a set signature that accepts" + " device, problem, and initial_mapping" + ) + except Exception as e: + raise e + elif routing_function == None: + self.routed = False + else: + raise ValueError( + f"Routing function can only be a Callable not {type(routing_function)}" + ) + self.mixer_block = self.block_setter(mixer_block, GateMapType.MIXER) ( self.mixer_single_qubit_coeffs, self.mixer_pair_qubit_coeffs, self.mixer_qubits_singles, self.mixer_qubits_pairs, - ) = self._assign_coefficients(self.mixer_block[0], self.mixer_block_coeffs) - - def _assign_coefficients( - self, input_block: List[RotationGateMap], input_coeffs: List[float] - ) -> None: - - """ - Splits the coefficients and gatemaps into qubit singles and qubit pairs. - """ - - single_qubit_coeffs = [] - pair_qubit_coeffs = [] - qubit_singles = [] - qubit_pairs = [] - - if len(input_block) != len(input_coeffs): - - raise ValueError( - "The number of terms/gatemaps must match the number of coefficients provided." - ) - - for each_gatemap, each_coeff in zip(input_block, input_coeffs): - - if each_gatemap.pauli_label[0] == "1q": - single_qubit_coeffs.append(each_coeff) - # Giving a string name to each gatemap (?) - qubit_singles.append(type(each_gatemap).__name__) - elif each_gatemap.pauli_label[0] == "2q": - pair_qubit_coeffs.append(each_coeff) - qubit_pairs.append(type(each_gatemap).__name__) - - return (single_qubit_coeffs, pair_qubit_coeffs, qubit_singles, qubit_pairs) - - @property - def cost_block(self): - - return self._cost_block + ) = self._assign_coefficients(self.mixer_block, self.mixer_block_coeffs) - @cost_block.setter - def cost_block(self, input_object: Hamiltonian) -> None: - - self._cost_block = HamiltonianMapper.repeat_gate_maps( - input_object, "cost", self.p - ) + self.mixer_blocks = HamiltonianMapper.repeat_gate_maps(self.mixer_block, self.p) + self.cost_blocks = HamiltonianMapper.repeat_gate_maps(self.cost_block, self.p) + self.qureg = list(range(self.n_qubits)) @property - def mixer_block(self): - - return self._mixer_block - - @mixer_block.setter - def mixer_block( - self, input_object: Union[List[RotationGateMap], Hamiltonian] - ) -> None: - - if type(input_object) == Hamiltonian: - - self._mixer_block = HamiltonianMapper.repeat_gate_maps( - input_object, "mixer", self.p - ) - + def n_qubits(self) -> int: + if self.routed == True: + return len(self.final_mapping) else: - - self._mixer_block = HamiltonianMapper.repeat_gate_maps_from_gate_map_list( - input_object, "mixer", self.p - ) + return self.cost_hamiltonian.n_qubits def __repr__(self): @@ -296,12 +275,230 @@ def __repr__(self): return string + def _assign_coefficients( + self, input_block: List[RotationGateMap], input_coeffs: List[float] + ) -> None: + + """ + Splits the coefficients and gatemaps into qubit singles and qubit pairs. + """ + + single_qubit_coeffs = [] + pair_qubit_coeffs = [] + qubit_singles = [] + qubit_pairs = [] + + if len(input_block) != len(input_coeffs): + raise ValueError( + "The number of terms/gatemaps must match the number of coefficients provided." + ) + for each_gatemap, each_coeff in zip(input_block, input_coeffs): + + if each_gatemap.gate_label.n_qubits == 1: + single_qubit_coeffs.append(each_coeff) + # Giving a string name to each gatemap (?) + qubit_singles.append(type(each_gatemap).__name__) + elif each_gatemap.gate_label.n_qubits == 2: + pair_qubit_coeffs.append(each_coeff) + qubit_pairs.append(type(each_gatemap).__name__) + + return (single_qubit_coeffs, pair_qubit_coeffs, qubit_singles, qubit_pairs) + + @staticmethod + def block_setter( + input_object: Union[List["RotationGateMap"], Hamiltonian], block_type: Enum + ) -> List["RotationGateMap"]: + + """ + Converts a Hamiltonian Object into a List of RotationGateMap Objects with + the appropriate block_type and sequence assigned to the GateLabel + + OR + + Remaps a list of RotationGateMap Objects with a block_type and sequence + implied from its position in the list. + + Parameters + ---------- + input_object: `Union[List[RotationGateMap], Hamiltonian]` + A Hamiltonian Object or a list of RotationGateMap Objects (Ordered + according to their application order in the final circuit) + block_type: Enum + The type to be assigned to all the RotationGateMap Objects generated + from input_object + + Returns + ------- + `List[RotationGateMap]` + """ + + if isinstance(input_object, Hamiltonian): + block = HamiltonianMapper.generate_gate_maps(input_object, block_type) + elif isinstance(input_object, list): + input_object = QAOADescriptor.set_block_sequence(input_object) + for each_gate in input_object: + if isinstance(each_gate, RotationGateMap): + each_gate.gate_label.update_gatelabel(new_gatemap_type=block_type) + else: + raise TypeError( + f"Input gate is of unsupported type {type(each_gate)}." + "Only RotationGateMaps are supported" + ) + block = input_object + else: + raise ValueError( + "The input object defining mixer should be a List of RotationGateMaps or type Hamiltonian" + ) + return block + + @staticmethod + def set_block_sequence( + input_gatemap_list: List["RotationGateMap"], + ) -> List["RotationGateMap"]: + + """ + This method assigns the sequence attribute to all RotationGateMap objects in the list. + The sequence of the GateMaps are implied based on their positions in the list. + + Parameters + ---------- + input_gatemap_list: `List[RotationGateMap]` + A list of RotationGateMap Objects + + Returns + ------- + `List[RotationGateMap]` + """ + + one_qubit_count = 0 + two_qubit_count = 0 + + for each_gate in input_gatemap_list: + if isinstance(each_gate, RotationGateMap): + if each_gate.gate_label.n_qubits == 1: + each_gate.gate_label.update_gatelabel( + new_application_sequence=one_qubit_count, + ) + one_qubit_count += 1 + elif each_gate.gate_label.n_qubits == 2: + each_gate.gate_label.update_gatelabel( + new_application_sequence=two_qubit_count, + ) + two_qubit_count += 1 + else: + raise TypeError( + f"Input gate is of unsupported type {type(each_gate)}." + "Only RotationGateMaps are supported" + ) + return input_gatemap_list + + def reorder_gates_block(self, gates_block, layer_number): + """Update the qubits that the gates are acting on after application + of SWAPs in the cost layer + """ + for gate in gates_block: + + if layer_number % 2 == 0: + mapping = self.final_mapping + gate.qubit_1 = mapping[gate.qubit_1] + if gate.gate_label.n_qubits == 2: + gate.qubit_2 = mapping[gate.qubit_2] + else: + pass + + return gates_block + + @staticmethod + def route_gates_list( + gates_to_route: List["GateMap"], + device: "DeviceBase", + routing_function: Callable, + ) -> List["GateMap"]: + """ + Apply qubit routing to the abstract circuit gate list + based on device information + + Parameters + ---------- + gates_to_route: `List[GateMap]` + The gates to route + device: `DeviceBase` + The device on which to run the circuit + routing_function: `Callable` + The function that accepts as input the device, problem, initial_mapping and + outputs the list of gates with swaps + """ + original_qubits_to_gate_mapping = { + (gate.qubit_1, gate.qubit_2): gate + for gate in gates_to_route + if gate.gate_label.n_qubits == 2 + } + problem_to_solve = list(original_qubits_to_gate_mapping.keys()) + ( + gate_list_indices, + swap_mask, + initial_physical_to_logical_mapping, + final_mapping, + ) = routing_function(device, problem_to_solve) + + gates_list = [gate for gate in gates_to_route if gate.gate_label.n_qubits == 1] + swapped_history = [] + for idx, pair_ij in enumerate(gate_list_indices): + mask = swap_mask[idx] + qi, qj = pair_ij + if mask == True: + swapped_history.append(pair_ij) + gates_list.append(SWAPGateMap(qi, qj)) + elif mask == False: + old_qi, old_qj = qi, qj + # traverse each SWAP application in reverse order to obtain + # the original location of the current qubit + for swap_pair in swapped_history[::-1]: + if old_qi in swap_pair: + old_qi = ( + swap_pair[0] if swap_pair[1] == old_qi else swap_pair[1] + ) + if old_qj in swap_pair: + old_qj = ( + swap_pair[0] if swap_pair[1] == old_qj else swap_pair[1] + ) + try: + ising_gate = original_qubits_to_gate_mapping[ + tuple([old_qi, old_qj]) + ] + except KeyError: + ising_gate = original_qubits_to_gate_mapping[ + tuple([old_qj, old_qi]) + ] + except Exception as e: + raise e + ising_gate.qubit_1, ising_gate.qubit_2 = qi, qj + gates_list.append(ising_gate) + + return ( + gates_list, + list(initial_physical_to_logical_mapping.keys()), + final_mapping, + ) + @property def abstract_circuit(self): + # even layer inversion if the circuit contains SWAP gates + even_layer_inversion = -1 if self.routed == True else 1 _abstract_circuit = [] for each_p in range(self.p): - _abstract_circuit.extend(self.cost_block[each_p]) - _abstract_circuit.extend(self.mixer_block[each_p]) + # apply each cost_block with reversed order to maintain the SWAP sequence + _abstract_circuit.extend( + self.cost_blocks[each_p][:: (even_layer_inversion) ** each_p] + ) + # apply the mixer block + if self.routed == True: + mixer_block = self.reorder_gates_block( + self.mixer_blocks[each_p], each_p + ) + else: + mixer_block = self.mixer_blocks[each_p] + _abstract_circuit.extend(mixer_block) return _abstract_circuit diff --git a/src/openqaoa-core/qaoa_components/ansatz_constructor/gatemap.py b/src/openqaoa-core/qaoa_components/ansatz_constructor/gatemap.py index 81c6a5e82..a7f0fa75a 100644 --- a/src/openqaoa-core/qaoa_components/ansatz_constructor/gatemap.py +++ b/src/openqaoa-core/qaoa_components/ansatz_constructor/gatemap.py @@ -1,25 +1,25 @@ from abc import ABC, abstractmethod import numpy as np -from typing import List, Tuple +from typing import List, Tuple, Union +from copy import deepcopy from .operators import Hamiltonian from .gates import * from .rotationangle import RotationAngle +from .gatemaplabel import GateMapLabel, GateMapType class GateMap(ABC): - def __init__(self, qubit_1: int): - self.qubit_1 = qubit_1 + self.gate_label = None def decomposition(self, decomposition_type: str) -> List[Tuple]: - try: - return getattr(self, '_decomposition_'+decomposition_type) + return getattr(self, "_decomposition_" + decomposition_type) except Exception as e: - print(e, '\nReturning default decomposition.') - return getattr(self, '_decomposition_standard') + print(e, "\nReturning default decomposition.") + return getattr(self, "_decomposition_standard") @property @abstractmethod @@ -28,182 +28,205 @@ def _decomposition_standard(self) -> List[Tuple]: class SWAPGateMap(GateMap): - def __init__(self, qubit_1: int, qubit_2: int): super().__init__(qubit_1) self.qubit_2 = qubit_2 + self.gate_label = GateMapLabel(n_qubits=2, gatemap_type=GateMapType.FIXED) @property def _decomposition_standard(self) -> List[Tuple]: - return [(CX, [[self.qubit_1, self.qubit_2]]), - (CX, [[self.qubit_2, self.qubit_1]]), - (CX, [[self.qubit_1, self.qubit_2]])] - + return [ + (CX, [[self.qubit_1, self.qubit_2]]), + (CX, [[self.qubit_2, self.qubit_1]]), + (CX, [[self.qubit_1, self.qubit_2]]), + ] + @property def _decomposition_standard2(self) -> List[Tuple]: - return [(RZ, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - - # X gate decomposition - (RZ, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RX, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RZ, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RX, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - -np.pi/2)]), - - # X gate decomposition - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RX, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RX, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - -np.pi/2)]), - - (RiSWAP, [[self.qubit_1, self.qubit_2, - RotationAngle(lambda x: x, self.pauli_label,np.pi)]]), - (CZ, [[self.qubit_1, self.qubit_2]]), - - # X gate decomposition - (RZ, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RX, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RZ, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RX, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - -np.pi/2)]), - - # X gate decomposition - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RX, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RX, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - -np.pi/2)])] - - -class RotationGateMap(GateMap): + return [ + ( + RZ, + [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + ( + RZ, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + # X gate decomposition + (RZ, [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RX, + [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RZ, [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RX, + [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, -np.pi / 2)], + ), + # X gate decomposition + (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RX, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RX, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, -np.pi / 2)], + ), + ( + RiSWAP, + [ + [self.qubit_1, self.qubit_2], + RotationAngle(lambda x: x, self.gate_label, np.pi), + ], + ), + (CZ, [[self.qubit_1, self.qubit_2]]), + # X gate decomposition + (RZ, [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RX, + [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RZ, [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RX, + [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, -np.pi / 2)], + ), + # X gate decomposition + (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RX, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RX, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, -np.pi / 2)], + ), + ] - def __init__(self, qubit_1: int, pauli_label: List = []): - - super().__init__(qubit_1) - - self.pauli_label = pauli_label - self.rotation_angle = None - - @property - def pauli_label(self) -> List: - return self._pauli_label +class RotationGateMap(GateMap): + def __init__(self, qubit_1: int): - @pauli_label.setter - def pauli_label(self, input_label: List) -> None: + super().__init__(qubit_1) + self.angle_value = None + self.gate_label = GateMapLabel(n_qubits=1) - gate_type = ['1q'] - gate_type.extend(input_label) - self._pauli_label = gate_type - @property def _decomposition_trivial(self) -> List[Tuple]: return self._decomposition_standard class RYGateMap(RotationGateMap): - @property def _decomposition_standard(self) -> List[Tuple]: - return [(RY, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)])] + return [ + ( + RY, + [ + self.qubit_1, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ) + ] class RXGateMap(RotationGateMap): - @property def _decomposition_standard(self) -> List[Tuple]: - return [(RX, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)])] + return [ + ( + RX, + [ + self.qubit_1, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ) + ] class RZGateMap(RotationGateMap): - @property def _decomposition_standard(self) -> List[Tuple]: - return [(RZ, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)])] + return [ + ( + RZ, + [ + self.qubit_1, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ) + ] class TwoQubitRotationGateMap(RotationGateMap): + def __init__(self, qubit_1: int, qubit_2: int): - def __init__(self, qubit_1: int, qubit_2: int, pauli_label: List = []): - - super().__init__(qubit_1, pauli_label) + super().__init__(qubit_1) self.qubit_2 = qubit_2 - - @property - def pauli_label(self) -> List: - - return self._pauli_label - - @pauli_label.setter - def pauli_label(self, input_label: List) -> None: - - gate_type = ['2q'] - gate_type.extend(input_label) - self._pauli_label = gate_type + self.gate_label = GateMapLabel(n_qubits=2) @property def _decomposition_trivial(self) -> List[Tuple]: - low_level_gate = eval(type(self).__name__.strip('GateMap')) - return [(low_level_gate, [[self.qubit_1, self.qubit_2], - RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)])] + low_level_gate = eval(type(self).__name__.strip("GateMap")) + return [ + ( + low_level_gate, + [ + [self.qubit_1, self.qubit_2], + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ) + ] class RXXGateMap(TwoQubitRotationGateMap): - @property def _decomposition_standard(self) -> List[Tuple]: - return [(RY, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RX, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RY, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RX, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (CX, [[self.qubit_1, self.qubit_2]]), - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)]), - (CX, [[self.qubit_1, self.qubit_2]]), - (RY, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RX, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (RY, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RX, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi)])] + return [ + ( + RY, + [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RX, [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RY, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RX, [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + (CX, [[self.qubit_1, self.qubit_2]]), + ( + RZ, + [ + self.qubit_2, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ), + (CX, [[self.qubit_1, self.qubit_2]]), + ( + RY, + [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RX, [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ( + RY, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RX, [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ] class RXYGateMap(TwoQubitRotationGateMap): - @property def _decomposition_standard(self) -> List[Tuple]: @@ -211,66 +234,110 @@ def _decomposition_standard(self) -> List[Tuple]: class RYYGateMap(TwoQubitRotationGateMap): - @property def _decomposition_standard(self) -> List[Tuple]: - return [(RX, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RX, [self.qubit_2,RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (CX, [[self.qubit_1, self.qubit_2]]), - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)]), - (CX, [[self.qubit_1, self.qubit_2]]), - (RY, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - -np.pi/2)]), - (RX, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - -np.pi/2)])] + return [ + ( + RX, + [self.qubit_1, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + ( + RX, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (CX, [[self.qubit_1, self.qubit_2]]), + ( + RZ, + [ + self.qubit_2, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ), + (CX, [[self.qubit_1, self.qubit_2]]), + ( + RY, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, -np.pi / 2)], + ), + ( + RX, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, -np.pi / 2)], + ), + ] class RZXGateMap(TwoQubitRotationGateMap): - @property def _decomposition_standard(self) -> List[Tuple]: - return [(RY, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RX, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi)]), - (CX, [[self.qubit_1, self.qubit_2]]), - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)]), - (CX, [[self.qubit_1, self.qubit_2]]), - (RY, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi/2)]), - (RX, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - np.pi)])] + return [ + ( + RY, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RX, [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + (CX, [[self.qubit_1, self.qubit_2]]), + ( + RZ, + [ + self.qubit_2, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ), + (CX, [[self.qubit_1, self.qubit_2]]), + ( + RY, + [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi / 2)], + ), + (RX, [self.qubit_2, RotationAngle(lambda x: x, self.gate_label, np.pi)]), + ] class RZZGateMap(TwoQubitRotationGateMap): - @property def _decomposition_standard(self) -> List[Tuple]: - return [(CX, [[self.qubit_1, self.qubit_2]]), - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)]), - (CX, [[self.qubit_1, self.qubit_2]])] + return [ + (CX, [[self.qubit_1, self.qubit_2]]), + ( + RZ, + [ + self.qubit_2, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ), + (CX, [[self.qubit_1, self.qubit_2]]), + ] @property def _decomposition_standard2(self) -> List[Tuple]: - return [(RZ, [self.qubit_1, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)]), - (RZ, [self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)]), - (CPHASE, [[self.qubit_1, self.qubit_2], - RotationAngle(lambda x: -2*x, self.pauli_label, self.rotation_angle)])] + return [ + ( + RZ, + [ + self.qubit_1, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ), + ( + RZ, + [ + self.qubit_2, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ], + ), + ( + CPHASE, + [ + [self.qubit_1, self.qubit_2], + RotationAngle(lambda x: -2 * x, self.gate_label, self.angle_value), + ], + ), + ] class RYZGateMap(TwoQubitRotationGateMap): - @property def _decomposition_standard(self) -> List[Tuple]: @@ -292,103 +359,100 @@ def _decomposition_standard(self) -> List[Tuple]: @property def _decomposition_standard2(self) -> List[Tuple]: - return [(RiSWAP, [[self.qubit_1, self.qubit_2, RotationAngle(lambda x: x, self.pauli_label, - self.rotation_angle)]])] + return [ + ( + RiSWAP, + [ + [ + self.qubit_1, + self.qubit_2, + RotationAngle(lambda x: x, self.gate_label, self.angle_value), + ] + ], + ) + ] class RotationGateMapFactory(object): - def convert_hamiltonian_to_gate_maps(hamil_obj: Hamiltonian, - input_label: List) -> List[RotationGateMap]: - + PAULI_OPERATORS = ["X", "Y", "Z", "XX", "ZX", "ZZ", "XY", "YY", "YZ"] + GATE_GENERATOR_GATEMAP_MAPPER = { + term: eval(f"R{term}GateMap") for term in PAULI_OPERATORS + } + + def rotationgatemap_list_from_hamiltonian( + hamil_obj: Hamiltonian, gatemap_type: GateMapType = None + ) -> List[RotationGateMap]: """ - Converts a Hamiltonian Object into a List of RotationGateMap Objects. + Constructs a list of Rotation GateMaps from the input Hamiltonian Object. + + Parameters + ---------- + hamil_obj: Hamiltonian + Hamiltonian object to construct the circuit from + gatemap_type: GateMapType + Gatemap type constructed """ pauli_terms = hamil_obj.terms - output_gates = [] one_qubit_count = 0 two_qubit_count = 0 for each_term in pauli_terms: - if each_term.pauli_str in ['XX', 'XZ', 'ZX', 'ZZ', 'XY', 'YX', 'YY', 'YZ', 'ZY']: - if each_term.pauli_str == 'XX': - output_gates.append(RXXGateMap(each_term.qubit_indices[0], - each_term.qubit_indices[1], - [*input_label, two_qubit_count])) - elif each_term.pauli_str == 'XZ': - output_gates.append(RZXGateMap(each_term.qubit_indices[1], - each_term.qubit_indices[0], - [*input_label, two_qubit_count])) - elif each_term.pauli_str == 'ZX': - output_gates.append(RZXGateMap(each_term.qubit_indices[0], - each_term.qubit_indices[1], - [*input_label, two_qubit_count])) - elif each_term.pauli_str == 'ZZ': - output_gates.append(RZZGateMap(each_term.qubit_indices[0], - each_term.qubit_indices[1], - [*input_label, two_qubit_count])) - elif each_term.pauli_str == 'XY': - output_gates.append(RXYGateMap(each_term.qubit_indices[0], - each_term.qubit_indices[1], - [*input_label, two_qubit_count])) - elif each_term.pauli_str == 'YX': - output_gates.append(RXYGateMap(each_term.qubit_indices[1], - each_term.qubit_indices[0], - [*input_label, two_qubit_count])) - elif each_term.pauli_str == 'YY': - output_gates.append(RYYGateMap(each_term.qubit_indices[0], - each_term.qubit_indices[1], - [*input_label, two_qubit_count])) - elif each_term.pauli_str == 'ZY': - output_gates.append(RYZGateMap(each_term.qubit_indices[1], - each_term.qubit_indices[0], - [*input_label, two_qubit_count])) - elif each_term.pauli_str == 'YZ': - output_gates.append(RYZGateMap(each_term.qubit_indices[0], - each_term.qubit_indices[1], - [*input_label, two_qubit_count])) + if each_term.pauli_str in RotationGateMapFactory.PAULI_OPERATORS: + pauli_str = each_term.pauli_str + qubit_indices = each_term.qubit_indices + elif each_term.pauli_str[::-1] in RotationGateMapFactory.PAULI_OPERATORS: + pauli_str = each_term.pauli_str[::-1] + qubit_indices = each_term.qubit_indices[::-1] + else: + raise ValueError("Hamiltonian contains non-Pauli terms") + + try: + gate_class = RotationGateMapFactory.GATE_GENERATOR_GATEMAP_MAPPER[ + pauli_str + ] + except Exception: + raise Exception("Generating gates from Hamiltonian terms failed") + + if len(each_term.qubit_indices) == 2: + gate = gate_class(qubit_indices[0], qubit_indices[1]) + gate.gate_label.update_gatelabel( + new_application_sequence=two_qubit_count, + new_gatemap_type=gatemap_type, + ) + output_gates.append(gate) two_qubit_count += 1 - - elif each_term.pauli_str in ['X', 'Y', 'Z']: - - if each_term.pauli_str == 'X': - output_gates.append(RXGateMap(each_term.qubit_indices[0], - [*input_label, one_qubit_count])) - elif each_term.pauli_str == 'Y': - output_gates.append(RYGateMap(each_term.qubit_indices[0], - [*input_label, one_qubit_count])) - elif each_term.pauli_str == 'Z': - output_gates.append(RZGateMap(each_term.qubit_indices[0], - [*input_label, one_qubit_count])) + elif len(each_term.qubit_indices) == 1: + gate = gate_class(qubit_indices[0]) + gate.gate_label.update_gatelabel( + new_application_sequence=one_qubit_count, + new_gatemap_type=gatemap_type, + ) + output_gates.append(gate) one_qubit_count += 1 return output_gates - - def remap_gate_map_labels(gatemap_list: List[RotationGateMap], input_label: List) -> List[RotationGateMap]: - + + def gatemaps_layer_relabel( + gatemap_list: List[GateMap], new_layer_number: int + ) -> List[RotationGateMap]: """ - Recreates a list of RotationGateMap Objects with the appropriately - assigned pauli_label attribute. + Reconstruct a new gatemap list from a list of RotationGateMap Objects with the input + layer number in the gate_label attribute. + + Parameters + ---------- + gatemap_list: `List[RotationGateMap] + The list of GateMap objects whose labels need to be udpated """ - - output_gates = [] + output_gate_list = [] - one_qubit_count = 0 - two_qubit_count = 0 - for each_gatemap in gatemap_list: - - if each_gatemap.pauli_label[0] == '1q': - each_gatemap.pauli_label = [*input_label, one_qubit_count] - one_qubit_count += 1 - - elif each_gatemap.pauli_label[0] == '2q': - each_gatemap.pauli_label = [*input_label, two_qubit_count] - two_qubit_count += 1 - - output_gates.append(each_gatemap) + new_gatemap = deepcopy(each_gatemap) + new_gatemap.gate_label.update_gatelabel(new_layer_number=new_layer_number) + output_gate_list.append(new_gatemap) - return output_gates + return output_gate_list diff --git a/src/openqaoa-core/qaoa_components/ansatz_constructor/gatemaplabel.py b/src/openqaoa-core/qaoa_components/ansatz_constructor/gatemaplabel.py new file mode 100644 index 000000000..2b48c9498 --- /dev/null +++ b/src/openqaoa-core/qaoa_components/ansatz_constructor/gatemaplabel.py @@ -0,0 +1,90 @@ +from enum import Enum +from typing import Union + + +class GateMapType(Enum): + + MIXER = "MIXER" + COST = "COST" + FIXED = "FIXED" + + @classmethod + def supported_types(cls): + return list(map(lambda c: c.name, cls)) + + +class GateMapLabel: + """ + This object helps keeps track of labels associated with + gates for their identification in the circuit. + """ + + def __init__( + self, + n_qubits: int = None, + layer_number: int = None, + application_sequence: int = None, + gatemap_type: GateMapType = None, + ): + """ + Parameters + ---------- + layer_number: `int` + The label for the algorthmic layer + application_sequence: `int` + The label for the sequence of application + for the gate + gate_type: `GateMapType` + Gate type for distinguishing gate between different QAOA blocks, + and between parameterized or non-parameterized + n_qubits: `int` + Number of qubits in the gate + """ + if ( + isinstance(layer_number, (int, type(None))) + and isinstance(application_sequence, (int, type(None))) + and isinstance(gatemap_type, (GateMapType, type(None))) + ): + self.layer = layer_number + self.sequence = application_sequence + self.type = gatemap_type + self.n_qubits = n_qubits + else: + raise ValueError("Some or all of input types are incorrect") + + def __repr__(self): + """ + String representation of the Gatemap label + """ + representation = f"{self.n_qubits}Q_" if self.n_qubits is not None else "" + representation += f"{self.type.value}" if self.type.value is not None else "" + representation += f"_seq{self.sequence}" if self.sequence is not None else "" + representation += f"_layer{self.layer}" if self.layer is not None else "" + + return representation + + def update_gatelabel( + self, + new_layer_number: int = None, + new_application_sequence: int = None, + new_gatemap_type: GateMapType = None, + ) -> None: + """ + Change the properties of the gatemap label to update + the gate identity + """ + if ( + new_layer_number is None + and new_gatemap_type is None + and new_application_sequence is None + ): + raise ValueError( + "Pass atleast one updated attribute to update the gatemap label" + ) + else: + if isinstance(new_layer_number, int): + self.layer = new_layer_number + if isinstance(new_application_sequence, int): + self.sequence = new_application_sequence + if isinstance(new_gatemap_type, GateMapType): + self.type = new_gatemap_type diff --git a/src/openqaoa-core/qaoa_components/ansatz_constructor/hamiltonianmapper.py b/src/openqaoa-core/qaoa_components/ansatz_constructor/hamiltonianmapper.py index 90408589c..9d01f51ed 100644 --- a/src/openqaoa-core/qaoa_components/ansatz_constructor/hamiltonianmapper.py +++ b/src/openqaoa-core/qaoa_components/ansatz_constructor/hamiltonianmapper.py @@ -1,114 +1,54 @@ from typing import List from copy import deepcopy -from .gatemap import RotationGateMap, RotationGateMapFactory +from .gatemap import RotationGateMapFactory, GateMap +from .gatemaplabel import GateMapType from .operators import Hamiltonian class HamiltonianMapper(object): - def get_gate_maps( - hamil_obj: Hamiltonian, input_label: List = [] - ) -> List[RotationGateMap]: + def generate_gate_maps( + hamil_obj: Hamiltonian, gatemap_type: GateMapType + ) -> List[GateMap]: """ - This method gets the pauli gates based on the input Hamiltonian into the Mapper + This method gets the rotation gates based on the input Hamiltonian into the Mapper Parameters ---------- hamil_obj : `Hamiltonian` The Hamiltonian object to construct the gates from - input_label : `list` + input_label : `GateMapType` Input label defining the type of gate - Return - ------ - `list[RotationGateMap]` + Returns + ------- + `list[GateMap]` List of RotationGateMap objects defining part of the circuit """ - - assert type(input_label) is list, "input_label must be of type list" - - return RotationGateMapFactory.convert_hamiltonian_to_gate_maps( - hamil_obj, input_label + assert isinstance( + gatemap_type, GateMapType + ), f"gatemap_type must be of supported types: {GateMapType.supported_types}" + return RotationGateMapFactory.rotationgatemap_list_from_hamiltonian( + hamil_obj, gatemap_type ) def repeat_gate_maps( - hamil_obj: Hamiltonian, tag: str, n_repetitions: int - ) -> List[List[RotationGateMap]]: + gatemap_list: List[GateMap], n_layers: int + ) -> List[List[GateMap]]: """ - Repeat the gates for n_repetitions layers based on the input Hamiltonian into the Mapper. + Repeat the gates for n_layers based on the input gatelist Parameters ---------- - hamil_obj : `Hamiltonian` - The Hamiltonian object to construct the gates from - tag : `str` - The tag to be used for the repeated gates - n_repetitions: `int` + gatemap_list : `List[GateMap]` + Repeat the gates from the gatemap_list + n_layers: `int` The number of times the layer of gates have to be repeated. """ output_gate_list = [] - - for each_repetition in range(n_repetitions): - output_gate_list.append( - HamiltonianMapper.get_gate_maps( - hamil_obj, [tag.lower(), each_repetition] - ) - ) - - return output_gate_list - - def remap_gate_map_labels( - gatemap_list: List[RotationGateMap], input_label: List = [] - ) -> List[RotationGateMap]: - - """ - This method reassigns the pauli_label of all the gates in the - RotationGateMap list. The newly assigned labels help the circuit - identify which variational angles fit into which gate. - - Parameters - ---------- - gatemap_list: `list[RotationGateMap]` - The list of RotationGateMap objects that needs the pauli_label attribute to be remapped. - input_label : `list` - Input label defining the type of gate - - Return - ------ - `list[RotationGateMap]` - List of RotationGateMap objects defining part of the circuit - """ - - assert type(input_label) is list, "input_label must be of type list" - - return RotationGateMapFactory.remap_gate_map_labels(gatemap_list, input_label) - - def repeat_gate_maps_from_gate_map_list( - gatemap_list: List[RotationGateMap], tag: str, n_repetitions: int - ) -> List[List[RotationGateMap]]: - - """ - Repeat the gates for n_repetitions layers based on the input list of RotationGateMap objects. - - Parameters - ---------- - gatemap_list: `list[RotationGateMap]` - The list of RotationGateMap objects that needs to be cloned. - tag : `str` - The tag to be used for the repeated gates - n_repetitions: `int` - The number of times to clone the RotationGateMap objects in the list. - """ - - output_gate_list = [] - - for each_repetition in range(n_repetitions): + for each_layer in range(n_layers): output_gate_list.append( - deepcopy( - HamiltonianMapper.remap_gate_map_labels( - gatemap_list, [tag.lower(), each_repetition] - ) - ) + RotationGateMapFactory.gatemaps_layer_relabel(gatemap_list, each_layer) ) return output_gate_list diff --git a/src/openqaoa-core/qaoa_components/ansatz_constructor/rotationangle.py b/src/openqaoa-core/qaoa_components/ansatz_constructor/rotationangle.py index 1381a524c..7107331ee 100644 --- a/src/openqaoa-core/qaoa_components/ansatz_constructor/rotationangle.py +++ b/src/openqaoa-core/qaoa_components/ansatz_constructor/rotationangle.py @@ -1,3 +1,4 @@ +from __future__ import annotations from typing import List, Union, Callable @@ -5,15 +6,30 @@ class RotationAngle(object): def __init__( self, angle_relationship: Callable, - pauli_label: List, - pauli_angle: Union[int, float] = None, + gate_label: GateMapLabel, + value: Union[int, float] = None, ): + """ + Angle object as placeholder for assigning angles to the parameterized + gates in the circuit + + Parameters + ---------- + angle_relationship: `Callable` + A function that takes input a parameter and assigns + the angle to the gate depending on the relationship + between the parameter and the angle + gate_label: `GateMapLabel` + The label for the gatemap object to which the rotationangle + is assigned + value: `int` or `float` + Value of the parameter + """ self._angle = angle_relationship - self.pauli_label = pauli_label - self.pauli_angle = pauli_angle + self.gate_label = gate_label + self.value = value @property def rotation_angle(self) -> Union[int, float]: - - return self._angle(self.pauli_angle) + return self._angle(self.value) diff --git a/src/openqaoa-core/utilities.py b/src/openqaoa-core/utilities.py index 436485c2c..078f53bd2 100644 --- a/src/openqaoa-core/utilities.py +++ b/src/openqaoa-core/utilities.py @@ -9,11 +9,15 @@ import uuid import matplotlib.pyplot as plt import networkx as nx +import datetime from .qaoa_components import Hamiltonian, PauliOp -from .qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams #ff -from .qaoa_components.ansatz_constructor.gatemap import TwoQubitRotationGateMap #ff +from .qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) # ff +from .qaoa_components.ansatz_constructor.gatemap import TwoQubitRotationGateMap # ff + def X_mixer_hamiltonian(n_qubits: int, coeffs: List[float] = None) -> Hamiltonian: """Construct a Hamiltonian object to implement the X mixer. @@ -1534,10 +1538,22 @@ def convert2serialize(obj, complex_to_string: bool = False): ################################################################################ -# UUID +# UUID and Timestamp ################################################################################ +def generate_timestamp() -> str: + """ + Generate a timestamp string in UTC+0. Format: YYYY-MM-DDTHH:MM:SS. + + Returns + ------- + timestamp: `str` + String representation of a timestamp. + """ + return datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S") + + def generate_uuid() -> str: """ Generate a UUID string. @@ -1574,6 +1590,48 @@ def is_valid_uuid(uuid_to_test: str) -> bool: return False +def permute_counts_dictionary( + counts_dictionary: dict, final_qubit_layout: List[int] +) -> dict: + """Permutes the order of the qubits in the counts dictionary to the + original order if SWAP gates were used leading to modified qubit layout. + Parameters + ---------- + counts_dictionary : `dict` + The measurement outcomes obtained from the Simulator/QPU + original_qubit_layout: List[int] + The qubit layout in which the qubits were initially + final_qubit_layout: List[int] + The final qubit layout after application of SWAPs + + Returns + ------- + `dict` + The permuted counts dictionary with qubits in the original place + """ + + # Create a mapping of original positions to final positions + original_qubit_layout = list(range(len(final_qubit_layout))) + mapping = { + original_qubit_layout[i]: final_qubit_layout[i] + for i in range(len(original_qubit_layout)) + } + permuted_counts = {} + + for basis, counts in counts_dictionary.items(): + + def permute_string(basis_state: str = basis, mapping: dict = mapping): + # Use the mapping to permute the string + permuted_string = "".join( + [basis_state[mapping[i]] for i in range(len(basis_state))] + ) + return permuted_string + + permuted_counts.update({permuted_string: counts}) + + return permuted_counts + + ################################################################################ # CHECKING FUNCTION ################################################################################ @@ -1619,14 +1677,14 @@ def check_kwarg(expected_param, default_value, **kwargs): return tuple(params) -### +#################################################################################### # QAOALIB -### +#################################################################################### def dicke_basis(excitations: int, n_qubits: int) -> np.ndarray: """ - Generates the Dicke basis state \|ek\> with k excitations + Generates the Dicke basis state $|ek>$ with $k$ excitations Parameters ---------- @@ -1634,7 +1692,7 @@ def dicke_basis(excitations: int, n_qubits: int) -> np.ndarray: Number of excitations in the basis vector n_qubits: `int` Total number of qubits in the system - + Returns ------- `np.ndarray` @@ -1666,11 +1724,11 @@ def dicke_wavefunction(excitations, n_qubits): n_qubits: int The number of qubits in the register - + Returns ------- `np.ndarray` - The wavefunction vector for a given cumulative Dicke states with <=k excitations + The wavefunction vector for a given cumulative Dicke states with $<=k$ excitations """ k_dicke = dicke_basis(excitations, n_qubits) @@ -1687,8 +1745,8 @@ def dicke_wavefunction(excitations, n_qubits): def k_cumulative_excitations(k: int, n_qubits: int) -> np.ndarray: """ - Generates the Upper bound excitations basis vector \|Ek\>, which a superposition of all - Dicke basis vectors upto excitation number \"k\" + Generates the Upper bound excitations basis vector $|Ek>$, which a superposition of all + Dicke basis vectors upto excitation number $k$ Parameters ---------- @@ -1699,8 +1757,8 @@ def k_cumulative_excitations(k: int, n_qubits: int) -> np.ndarray: Returns ------- - `np.ndarray` - The wavefunction vector for a given cumulative Dicke states with <=k excitations + wavefunction: `np.ndarray` + The wavefunction vector for a given cumulative Dicke states with $<=k$ excitations """ cumulative_dicke_bases = np.array(["0" * n_qubits]) for exc in range(1, k + 1): @@ -1793,326 +1851,3 @@ def to_bin(number, n_qubits): ) / np.sqrt(len(wavefn_locs)) return wavefunction - - -# ############################################################################ -# Lightcone QAOA building blocks -# ############################################################################ - -# def _lightcone_registers(graph: nx.Graph, -# n_steps: int, -# edge: Tuple) -> Tuple[List, List, List]: -# """ -# Determine the qubits in the lightcone for each step. Note this is slightly modified -# from the corresponding method in EntropicaQAOA, to return lists instead of sets at -# the end. - -# Parameters -# ---------- -# graph: -# The graph whose lightcones we want to determine. Nodes must be Ints. -# n_steps: -# Depth of the QAOA circuit (i.e. ``p``) -# edge: -# The edge whose lightcone you want. Should be a tuple ``(node1, node2)`` - - -# Returns -# ------- -# Tuple[List, List, List]: -# Three lists. -# The first contains the sets of qubits to apply the RX rotations for -# all steps. -# The second contains the sets of qubits to apply the RZ rotations -# for all steps. -# The third contains the qubit pairs to apply the RZZ rotations for -# all steps - -# """ -# # will be a list of lists of qubits that need a mixer rotation at each step -# regs = [] -# # will be a list of lists of qubits that need a bias rotation at each step -# qubits_singles = [] -# # will be a list of lists of pairs of qubits that need a cost rotation at each step -# qubits_pairs = [{edge}] -# # get a list of the qubits with a bias on them -# bias_qubits = [n[0] for n in graph.nodes(data=True) if 'weight' in n[1]] - -# # fill the lists -# for _ in range(n_steps): -# new_pairs = set() -# old_pairs = qubits_pairs[-1] -# new_reg = {q for pair in old_pairs for q in pair} -# regs.append(new_reg) -# qubits_singles.append(new_reg.intersection(bias_qubits)) -# for pair in old_pairs: -# new_pairs.update(graph.edges(pair[0])) -# new_pairs.update(graph.edges(pair[1])) -# new_pairs = {tuple(sorted(p)) for p in new_pairs} -# qubits_pairs.append(new_pairs) -# qubits_pairs.pop(0) - -# # Now reverse the lists: this is because we are essentially working 'outwards' from the operator corresponding -# # to the edge of interest, back to the beginning of the circuit - we have the 'time-reversed' order of operations. -# # Thus, in order to get the operations in the correct time order, we need to reverse them. -# qubits_pairs.reverse() -# qubits_singles.reverse() -# regs.reverse() - -# regs = [list(i) for i in regs] -# qubits_singles = [list(i) for i in qubits_singles] -# qubits_pairs = [list(i) for i in qubits_pairs] - -# return regs, qubits_singles, qubits_pairs - - -# def _lightcone_param_indices(params: Type[AbstractParams], -# regs: List, -# qubits_singles: List, -# qubits_pairs: List) -> Tuple[List, List, List]: -# """ -# Return index arrays for ``params.x_rotation_angles``, -# ``params.z_rotation_angles``, to act on the qubits specified by ``regs``, -# ``qubits_singles``,.... - -# Parameter -# --------- -# params: -# QAOAParameter object -# regs: -# The first list produced by ``_lightcone_registers`` -# qubits_singles: -# The second list produced by ``_lightcone_registers`` -# qubits_pairs: -# The third list produced by ``_lightcone_registers`` - -# Returns -# ------- -# Tuple[List, List, List]: -# Index arrays for ``params.x_rotation_angles``, -# ``params.z_rotation_angles``, ... to get exactly the angles that -# act on the qubits in ``regs``, ``qubits_singles``,... -# """ -# reg_index_dict = {q: i for i, q in enumerate(params.reg)} -# singles_index_dict = {q: i for i, q in enumerate(params.qubits_singles)} -# pairs_index_dict = {tuple(sorted(pair)): i -# for i, pair in enumerate(params.qubits_pairs)} - -# x_indices_list = [] -# z_indices_list = [] -# zz_indices_list = [] - -# for i in range(params.n_steps): -# x_indices = np.array([reg_index_dict[q] for q in regs[i]], dtype=int) -# z_indices = np.array([singles_index_dict[q] -# for q in qubits_singles[i]], dtype=int) -# zz_indices = np.array([pairs_index_dict[p] for p in qubits_pairs[i]], -# dtype=int) - -# x_indices_list.append(x_indices) -# z_indices_list.append(z_indices) -# zz_indices_list.append(zz_indices) - -# return x_indices_list, z_indices_list, zz_indices_list - -# def _prepare_lightcone_params(lc_qubits: List, -# lc_regs: List, -# lc_singles: List, -# lc_pairs: List, -# params: Type[AbstractParams], -# x_indices, -# z_indices, -# zz_indices) -> tuple: -# """ -# Prepare the QAOA lightcone program on the qubits specified in -# ``regs``, ``qubits_singles``,... - -# Parameters -# ---------- -# lc_regs: -# The first list produced by ``_lightcone_registers`` for the lc in question -# lc_qubits_singles: -# The second list produced by ``_lightcone_registers`` for the lc in question -# lc_qubits_pairs: -# The third list produced by ``_lightcone_registers`` for the lc in question -# params: -# QAOAParameter object, corresponding to the whole problem - -# Returns -# ------- -# tuple: -# A tuple with the QAOA circuit parameters, and the relevant biases and couplings, for the lightcone program -# """ - -# # Map qubits_singles and qubits_pairs to this register -# pairs = lc_pairs[0] -# #pairs_reg = [(lc_qubits.index(pair[0]), lc_qubits.index(pair[1])) for pair in pairs] -# singles = lc_singles[0] -# #singles_reg = [lc_qubits.index(qb) for qb in singles] - -# # Get the biases and couplings -# all_system_pairs = [tuple(sorted(pair)) for pair in params.qubits_pairs] - -# lc_couplings = [] -# for pair in pairs: -# ind = all_system_pairs.index(pair) -# lc_couplings.append(params.pair_qubit_coeffs[ind]) - -# all_system_singles = params.qubits_singles -# lc_biases = [] -# if singles: -# for qb in singles: -# ind = all_system_singles.index(qb) -# lc_biases.append(params.single_qubit_coeffs[ind]) - -# # Angles needed for the lightcone -# x_angles_lc = [] -# z_angles_lc = [] -# zz_angles_lc = [] -# for i in range(params.n_steps): - -# # X rotation angles needed -# angles_x = [0]*len(lc_qubits) -# for j in lc_regs[i]: -# ind = lc_qubits.index(j) -# angles_x[ind] = params.x_rotation_angles[i, j] -# x_angles_lc.append(angles_x) - -# if singles: -# # Z rotation angles needed -# angles_z = [0]*len(singles) -# for j,qb in enumerate(lc_singles[i]): -# ind = singles.index(qb) -# angles_z[ind] = params.z_rotation_angles[i, z_indices[i][j]] -# z_angles_lc.append(angles_z) - -# # ZZ rotation angles needed -# angles_zz = [0]*len(lc_pairs[0]) -# for k, pair in enumerate(lc_pairs[i]): -# ind = pairs.index(pair) -# angles_zz[ind] = params.zz_rotation_angles[i,zz_indices[i][k]] -# zz_angles_lc.append(angles_zz) - -# #lc_params = (params.n_steps, x_angles_lc, lc_biases, z_angles_lc, lc_couplings, zz_angles_lc) -# lc_params = (x_angles_lc, z_angles_lc, zz_angles_lc) - -# return lc_params - -# def lightcone_hams(graph: nx.Graph) -> List[np.array]: -# """ -# Extracts the local QAOA terms from a graph and returns them as a list. - -# Parameters -# ---------- -# graph: -# The graph with edge and possibly node weights. - -# Returns -# ------- -# List[np.array]: -# A list of 4x4 numpy arrays corresponding to the cost terms in the total -# hamiltonian. Sorted in the way graph.edges() returns the edges. -# """ -# terms = [] -# all_qubits = {n[0]: n[1] for n in graph.nodes(data=True)} -# for edge in graph.edges(data=True): -# mat = np.zeros(shape=(4, 4)) -# mat += edge[2]['weight'] * np.diag([1, -1, -1, 1]) -# edge = tuple(sorted([edge[0], edge[1]])) -# if edge[0] in all_qubits: -# attrs = all_qubits.pop(edge[0]) -# try: -# mat += attrs['weight'] * np.diag([1, -1, 1, -1]) -# except KeyError: -# pass -# if edge[1] in all_qubits: -# attrs = all_qubits.pop(edge[1]) -# try: -# mat += attrs['weight'] * np.diag([1, 1, -1, -1]) -# except KeyError: -# pass -# terms.append(mat) -# return terms - - -# class Lightcone(object): -# """A container class for QAOA lightcones. - -# Parameters -# ---------- -# graph: -# The graph whose lightcones we want to build. -# params: -# QAOA parameter object to use for this QAOA run. -# edge: -# The edge whose lightcone you want to build. - -# Attributes -# ---------- -# regs: List[Set] -# The i-th set in the list contains the qubits that need a RX rotation -# in the i-th QAOA layer -# qubits_singles: List[Set] -# The i-th set in the list contains the qubits that need a RZ rotation -# in the i-th QAOA layer -# qubits_pairs: List[Set[Tuple]] -# The i-th set in the list contains the qubits that need a RZ rotation -# in the i-th QAOA layer -# prepare_ansatz: Program -# The lightcone QAOA pyquil program -# self.n_qubits: int -# The actual size of the lightcone in qubits -# self.i: -# The index of the first qubit in ``edge`` -# self.j: -# The index of the second qubit in ``edge`` -# """ - -# ## TODO: -# # - Fix the docstring above -# # - make __str__ or __repr___ method for this class, which would output something -# # similar to what is done with the ordinary QAOA param objects - -# def __init__(self, -# graph: nx.Graph, -# params: Type[AbstractParams], -# edge: Tuple): - -# # get the lists of relevant qubits and pairs in each step -# self.lc_regs, self.lc_singles, self.lc_pairs\ -# = _lightcone_registers(graph, params.n_steps, edge) - -# # get the correct indices for the rotation angles -# self.x_indices, self.z_indices, self.zz_indices\ -# = _lightcone_param_indices(params, self.lc_regs, -# self.lc_singles, self.lc_pairs) - -# # all qubits in this lightcone -# self.lc_qubits = sorted({q for pair in self.lc_pairs[0] for q in pair}) -# self.lc_n_qubits = len(self.lc_qubits) - -# # get the angles needed for the circuit, and the biases and couplings -# self.lc_params =\ -# _prepare_lightcone_params(self.lc_qubits, self.lc_regs, self.lc_singles, -# self.lc_pairs, params, self.x_indices, -# self.z_indices, self.zz_indices) - -# # Some helper parameters needed to compute the density matrix corresponding to the output -# # of this lightcone circuit -# final_qubits = sorted(self.lc_regs[-1]) -# self.i = self.lc_n_qubits - 1 - self.lc_qubits.index(final_qubits[0]) -# self.j = self.lc_n_qubits - 1 - self.lc_qubits.index(final_qubits[1]) - -# def density_matrix(self, wf): -# """ -# compute the reduced density matrix on the two qubits in `edge` -# from a wavefunction on all the qubits in that anything is happening on -# """ -# einstring = ascii_letters[0:self.j] + "W" + ascii_letters[self.j:self.i-1] -# einstring += "X" + ascii_letters[self.i:self.lc_n_qubits - 1] + "," -# einstring += ascii_letters[0:self.j] + "Y" + ascii_letters[self.j:self.i-1] -# einstring += "Z" + ascii_letters[self.i:self.lc_n_qubits - 1] -# einstring += "->WXYZ" -# wf = wf.reshape([2]*self.lc_n_qubits) -# rho = np.einsum(einstring, wf, wf.conj()) -# return rho.reshape((4, 4)) diff --git a/src/openqaoa-pyquil/backends/__init__.py b/src/openqaoa-pyquil/backends/__init__.py index 35d185e64..729075a54 100644 --- a/src/openqaoa-pyquil/backends/__init__.py +++ b/src/openqaoa-pyquil/backends/__init__.py @@ -1,3 +1,3 @@ from .devices import DevicePyquil from .qaoa_pyquil_qpu import QAOAPyQuilQPUBackend -from .qaoa_pyquil_sim import QAOAPyQuilWavefunctionSimulatorBackend \ No newline at end of file +from .qaoa_pyquil_sim import QAOAPyQuilWavefunctionSimulatorBackend diff --git a/src/openqaoa-pyquil/backends/devices.py b/src/openqaoa-pyquil/backends/devices.py index 22345ddb0..78b5b9694 100644 --- a/src/openqaoa-pyquil/backends/devices.py +++ b/src/openqaoa-pyquil/backends/devices.py @@ -1,3 +1,4 @@ +from typing import List from qcs_api_client.client import QCSClientConfiguration from pyquil.api._engagement_manager import EngagementManager from pyquil import get_qc @@ -103,3 +104,9 @@ def check_connection(self) -> bool: """ return True + + def connectivity(self) -> List[List[int]]: + # returns a networkx graph of qubit topology + G = self.quantum_computer.qubit_topology() + connectivity_as_list = list(G.edges()) + return connectivity_as_list diff --git a/src/openqaoa-pyquil/backends/qaoa_pyquil_qpu.py b/src/openqaoa-pyquil/backends/qaoa_pyquil_qpu.py index e091b044d..a3b059cd0 100644 --- a/src/openqaoa-pyquil/backends/qaoa_pyquil_qpu.py +++ b/src/openqaoa-pyquil/backends/qaoa_pyquil_qpu.py @@ -1,6 +1,8 @@ from collections import Counter import numpy as np from pyquil import Program, gates, quilbase +from typing import List, Optional +import warnings from .devices import DevicePyquil from openqaoa.backends.basebackend import ( @@ -9,7 +11,9 @@ QAOABaseBackendParametric, ) from openqaoa.qaoa_components import QAOADescriptor -from openqaoa.qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from openqaoa.qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) from openqaoa.qaoa_components.ansatz_constructor.gatemap import RZZGateMap, SWAPGateMap from openqaoa.utilities import generate_uuid @@ -96,7 +100,7 @@ def __init__( cvar_alpha: float, active_reset: bool = False, rewiring: str = "", - qubit_layout: list = [], + initial_qubit_mapping: Optional[List[int]] = None, ): QAOABaseBackendShotBased.__init__( @@ -112,11 +116,18 @@ def __init__( self.active_reset = active_reset self.rewiring = rewiring - self.qureg = self.qaoa_descriptor.qureg + self.qureg = list(range(self.n_qubits)) + self.problem_reg = self.qureg[0 : self.problem_qubits] + + if self.initial_qubit_mapping is None: + self.initial_qubit_mapping = ( + initial_qubit_mapping + if initial_qubit_mapping is not None + else list(range(self.n_qubits)) + ) # self.qureg_placeholders = QubitPlaceholder.register(self.n_qubits) - self.qubit_layout = self.qureg if qubit_layout == [] else qubit_layout - self.qubit_mapping = dict(zip(self.qureg, self.qubit_layout)) + self.qubit_mapping = dict(zip(self.qureg, self.initial_qubit_mapping)) if self.prepend_state: assert self.n_qubits >= len(prepend_state.get_qubits()), ( @@ -204,14 +215,14 @@ def parametric_qaoa_circuit(self) -> Program: ) # declare the read-out register - ro = parametric_circuit.declare("ro", "BIT", self.n_qubits) + ro = parametric_circuit.declare("ro", "BIT", self.problem_qubits) if self.prepend_state: parametric_circuit += self.prepend_state # Initial state is all |+> if self.init_hadamard: - for i in self.qureg: + for i in self.problem_reg: parametric_circuit += gates.RZ(np.pi, self.qubit_mapping[i]) parametric_circuit += gates.RX(np.pi / 2, self.qubit_mapping[i]) parametric_circuit += gates.RZ(np.pi / 2, self.qubit_mapping[i]) @@ -219,9 +230,16 @@ def parametric_qaoa_circuit(self) -> Program: # create a list of gates in order of application on quantum circuit for each_gate in self.abstract_circuit: - gate_label = "".join(str(label) for label in each_gate.pauli_label) - angle_param = parametric_circuit.declare(f"pauli{gate_label}", "REAL", 1) - each_gate.rotation_angle = angle_param + # if gate is of type mixer or cost gate, assign parameter to it + if each_gate.gate_label.type.value in ["MIXER", "COST"]: + gatelabel_pyquil = each_gate.gate_label.__repr__() + gatelabel_pyquil = ( + "one" + gatelabel_pyquil[1:] + if each_gate.gate_label.n_qubits == 1 + else "two" + gatelabel_pyquil[1:] + ) + angle_param = parametric_circuit.declare(gatelabel_pyquil, "REAL", 1) + each_gate.angle_value = angle_param if isinstance(each_gate, RZZGateMap) or isinstance(each_gate, SWAPGateMap): decomposition = each_gate.decomposition("standard2") else: @@ -230,21 +248,38 @@ def parametric_qaoa_circuit(self) -> Program: # using the list above, construct the circuit for each_tuple in decomposition: gate = each_tuple[0]() - qubits, rotation_angle = each_tuple[1] + if len(each_tuple[1]) == 1: + qubits, rotation_angle = each_tuple[1][0], None + elif len(each_tuple[1]) == 2: + qubits, rotation_angle = each_tuple[1] + else: + raise ValueError( + f"Specified an incorrect gate decomposition {each_tuple[1]}" + ) if isinstance(qubits, list): new_qubits = [self.qubit_mapping[qubit] for qubit in qubits] else: new_qubits = self.qubit_mapping[qubits] - parametric_circuit = gate.apply_pyquil_gate( - new_qubits, rotation_angle, parametric_circuit - ) + if rotation_angle is None: + parametric_circuit = gate.apply_pyquil_gate( + new_qubits, parametric_circuit + ) + else: + parametric_circuit = gate.apply_pyquil_gate( + new_qubits, rotation_angle, parametric_circuit + ) if self.append_state: parametric_circuit += self.append_state - # Measurement instructions - for i, qubit in enumerate(self.qureg): - parametric_circuit += gates.MEASURE(self.qubit_mapping[qubit], ro[i]) + if self.final_mapping is None: + for i, qbit in enumerate(self.problem_reg): + parametric_circuit += gates.MEASURE(self.qubit_mapping[qbit], ro[i]) + else: + # Measurement instructions + for i, qubit in enumerate(self.final_mapping[0 : len(self.problem_reg)]): + cbit = ro[i] + parametric_circuit += gates.MEASURE(self.qubit_mapping[qubit], cbit) parametric_circuit.wrap_in_numshots_loop(self.n_shots) @@ -275,7 +310,6 @@ def get_counts(self, params: QAOAVariationalBaseParams, n_shots=None) -> dict: executable_program.wrap_in_numshots_loop(n_shots) result = self.device.quantum_computer.run(executable_program) - # we create an uuid for the job self.job_id = generate_uuid() @@ -286,9 +320,9 @@ def get_counts(self, params: QAOAVariationalBaseParams, n_shots=None) -> dict: ] # Expose counts - counts = Counter(list(meas_list)) - self.measurement_outcomes = counts - return counts + final_counts = Counter(list(meas_list)) + self.measurement_outcomes = final_counts + return final_counts def circuit_to_qasm(self, params: QAOAVariationalBaseParams) -> str: """ diff --git a/src/openqaoa-pyquil/backends/qaoa_pyquil_sim.py b/src/openqaoa-pyquil/backends/qaoa_pyquil_sim.py index f1c092ad1..3225948b8 100644 --- a/src/openqaoa-pyquil/backends/qaoa_pyquil_sim.py +++ b/src/openqaoa-pyquil/backends/qaoa_pyquil_sim.py @@ -6,7 +6,9 @@ from openqaoa.backends.basebackend import QAOABaseBackendStatevector from openqaoa.qaoa_components import QAOADescriptor -from openqaoa.qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from openqaoa.qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) from openqaoa.qaoa_components.ansatz_constructor.gatemap import ( RXGateMap, RYGateMap, @@ -21,7 +23,7 @@ class QAOAPyQuilWavefunctionSimulatorBackend(QAOABaseBackendStatevector): A local Wavefunction simulator backend for the PyQuil service provider """ - PYQUIL_PAULIGATE_LIBRARY = [RXGateMap, RYGateMap, RZGateMap] + PYQUIL_ROTATIONGATES_LIBRARY = [RXGateMap, RYGateMap, RZGateMap] def __init__( self, @@ -71,7 +73,10 @@ def qaoa_circuit(self, params: QAOAVariationalBaseParams) -> Program: # create a list of gates in order of application on quantum circuit low_level_gate_list = [] for i, each_gate in enumerate(self.abstract_circuit): - if type(each_gate) in self.PYQUIL_PAULIGATE_LIBRARY: + if ( + type(each_gate) + in QAOAPyQuilWavefunctionSimulatorBackend.PYQUIL_ROTATIONGATES_LIBRARY + ): decomposition = each_gate.decomposition("trivial") else: decomposition = each_gate.decomposition("standard") diff --git a/src/openqaoa-qiskit/backends/devices.py b/src/openqaoa-qiskit/backends/devices.py index 1ea45b2a6..996c7242c 100644 --- a/src/openqaoa-qiskit/backends/devices.py +++ b/src/openqaoa-qiskit/backends/devices.py @@ -1,5 +1,6 @@ from qiskit import IBMQ - +from qiskit_aer import AerSimulator +from typing import List from openqaoa.backends.devices_core import DeviceBase @@ -22,7 +23,12 @@ class DeviceQiskit(DeviceBase): """ def __init__( - self, device_name: str, hub: str = None, group: str = None, project: str = None + self, + device_name: str, + hub: str = None, + group: str = None, + project: str = None, + as_emulator: bool = False, ): """The user's IBMQ account has to be authenticated through qiskit in order to use this backend. This can be done through `IBMQ.save_account`. @@ -47,6 +53,7 @@ def __init__( self.hub = hub self.group = group self.project = project + self.as_emulator = as_emulator self.provider_connected = None self.qpu_connected = None @@ -92,6 +99,8 @@ def _check_backend_connection(self) -> bool: if self.device_name in self.available_qpus: self.backend_device = self.provider.get_backend(self.device_name) self.n_qubits = self.backend_device.configuration().n_qubits + if self.as_emulator is True: + self.backend_device = AerSimulator.from_backend(self.backend_device) return True else: print(f"Please choose from {self.available_qpus} for this provider") @@ -117,3 +126,6 @@ def _check_provider_connection(self) -> bool: "for how to save your IBMQ account locally: {}".format(e) ) return False + + def connectivity(self) -> List[List[int]]: + return self.backend_device.configuration().coupling_map diff --git a/src/openqaoa-qiskit/backends/qaoa_qiskit_qpu.py b/src/openqaoa-qiskit/backends/qaoa_qiskit_qpu.py index 5e5e03070..1931d79ce 100644 --- a/src/openqaoa-qiskit/backends/qaoa_qiskit_qpu.py +++ b/src/openqaoa-qiskit/backends/qaoa_qiskit_qpu.py @@ -1,8 +1,9 @@ from time import time from typing import Optional, List +import warnings # IBM Qiskit imports -from qiskit import QuantumCircuit, QuantumRegister, execute +from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, transpile from qiskit.providers.ibmq.job import ( IBMQJobApiError, IBMQJobInvalidStateError, @@ -18,7 +19,9 @@ QAOABaseBackendParametric, ) from openqaoa.qaoa_components import QAOADescriptor -from openqaoa.qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams +from openqaoa.qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) from openqaoa.utilities import flip_counts @@ -57,7 +60,7 @@ def __init__( prepend_state: Optional[QuantumCircuit], append_state: Optional[QuantumCircuit], init_hadamard: bool, - qubit_layout: List[int] = [], + initial_qubit_mapping: Optional[List[int]] = None, cvar_alpha: float = 1, ): @@ -73,9 +76,13 @@ def __init__( QAOABaseBackendCloud.__init__(self, device) self.qureg = QuantumRegister(self.n_qubits) - self.qubit_layout = ( - self.qaoa_descriptor.qureg if qubit_layout == [] else qubit_layout - ) + self.problem_reg = self.qureg[0 : self.problem_qubits] + if self.initial_qubit_mapping is None: + self.initial_qubit_mapping = ( + initial_qubit_mapping + if initial_qubit_mapping is not None + else list(range(self.n_qubits)) + ) if self.prepend_state: assert self.n_qubits >= len(prepend_state.qubits), ( @@ -125,8 +132,22 @@ def qaoa_circuit(self, params: QAOAVariationalBaseParams) -> QuantumCircuit: angles_list = self.obtain_angles_for_pauli_list(self.abstract_circuit, params) memory_map = dict(zip(self.qiskit_parameter_list, angles_list)) - new_parametric_circuit = self.parametric_circuit.bind_parameters(memory_map) - return new_parametric_circuit + circuit_with_angles = self.parametric_circuit.bind_parameters(memory_map) + if self.qaoa_descriptor.routed == True: + transpiled_circuit = transpile( + circuit_with_angles, + self.backend_qpu, + initial_layout=self.initial_qubit_mapping, + optimization_level=0, + routing_method="none", + ) + else: + transpiled_circuit = transpile( + circuit_with_angles, + self.backend_qpu, + initial_layout=self.initial_qubit_mapping, + ) + return circuit_with_angles @property def parametric_qaoa_circuit(self) -> QuantumCircuit: @@ -141,19 +162,22 @@ def parametric_qaoa_circuit(self) -> QuantumCircuit: Object of type QAOAVariationalBaseParams """ # self.reset_circuit() - parametric_circuit = QuantumCircuit(self.qureg) + creg = ClassicalRegister(len(self.problem_reg)) + parametric_circuit = QuantumCircuit(self.qureg, creg) if self.prepend_state: parametric_circuit = parametric_circuit.compose(self.prepend_state) # Initial state is all |+> if self.init_hadamard: - parametric_circuit.h(self.qureg) + parametric_circuit.h(self.problem_reg) self.qiskit_parameter_list = [] for each_gate in self.abstract_circuit: - angle_param = Parameter(str(each_gate.pauli_label)) - self.qiskit_parameter_list.append(angle_param) - each_gate.rotation_angle = angle_param + # if gate is of type mixer or cost gate, assign parameter to it + if each_gate.gate_label.type.value in ["MIXER", "COST"]: + angle_param = Parameter(each_gate.gate_label.__repr__()) + self.qiskit_parameter_list.append(angle_param) + each_gate.angle_value = angle_param decomposition = each_gate.decomposition("standard") # using the list above, construct the circuit for each_tuple in decomposition: @@ -164,7 +188,14 @@ def parametric_qaoa_circuit(self) -> QuantumCircuit: if self.append_state: parametric_circuit = parametric_circuit.compose(self.append_state) - parametric_circuit.measure_all() + + # only measure the problem qubits + if self.final_mapping is None: + parametric_circuit.measure(self.problem_reg, creg) + else: + for idx, qubit in enumerate(self.final_mapping[0 : len(self.problem_reg)]): + cbit = creg[idx] + parametric_circuit.measure(qubit, cbit) return parametric_circuit @@ -195,14 +226,10 @@ def get_counts(self, params: QAOAVariationalBaseParams, n_shots=None) -> dict: max_job_retries = 5 while job_state == False: - # initial_layout only passed if not azure device - input_items = {"shots": n_shots, "initial_layout": self.qubit_layout} - if type(self.device).__name__ == "DeviceAzure": - input_items.pop("initial_layout") - job = self.backend_qpu.run(circuit, **input_items) - else: - job = execute(circuit, backend=self.backend_qpu, **input_items) + # if type(self.device).__name__ == "DeviceAzure": + # job = self.backend_qpu.run(circuit, **input_items) + job = self.backend_qpu.run(circuit, shots=n_shots) api_contact = False no_of_api_retries = 0 @@ -233,9 +260,9 @@ def get_counts(self, params: QAOAVariationalBaseParams, n_shots=None) -> dict: raise ConnectionError("An Error Occurred with the Job(s) sent to IBMQ.") # Expose counts - counts_flipped = flip_counts(counts) - self.measurement_outcomes = counts_flipped - return counts_flipped + final_counts = flip_counts(counts) + self.measurement_outcomes = final_counts + return final_counts def circuit_to_qasm(self, params: QAOAVariationalBaseParams) -> str: """ diff --git a/src/openqaoa-qiskit/backends/qaoa_qiskit_sim.py b/src/openqaoa-qiskit/backends/qaoa_qiskit_sim.py index 15ff50188..b0580b161 100644 --- a/src/openqaoa-qiskit/backends/qaoa_qiskit_sim.py +++ b/src/openqaoa-qiskit/backends/qaoa_qiskit_sim.py @@ -15,8 +15,14 @@ QAOABaseBackendStatevector, ) from openqaoa.qaoa_components import QAOADescriptor -from openqaoa.qaoa_components.variational_parameters.variational_baseparams import QAOAVariationalBaseParams -from openqaoa.utilities import flip_counts, generate_uuid, round_value +from openqaoa.qaoa_components.variational_parameters.variational_baseparams import ( + QAOAVariationalBaseParams, +) +from openqaoa.utilities import ( + flip_counts, + generate_uuid, + round_value, +) from openqaoa.backends.cost_function import cost_function from openqaoa.qaoa_components.ansatz_constructor import ( RXGateMap, @@ -101,7 +107,6 @@ def __init__( ) self.qureg = QuantumRegister(self.n_qubits) - self.qubit_layout = self.qaoa_descriptor.qureg if self.prepend_state: assert self.n_qubits >= len(prepend_state.qubits), ( @@ -153,10 +158,15 @@ def parametric_qaoa_circuit(self) -> QuantumCircuit: self.qiskit_parameter_list = [] for each_gate in self.abstract_circuit: - angle_param = Parameter(str(each_gate.pauli_label)) - self.qiskit_parameter_list.append(angle_param) - each_gate.rotation_angle = angle_param - if type(each_gate) in self.QISKIT_GATEMAP_LIBRARY: + # if gate is of type mixer or cost gate, assign parameter to it + if each_gate.gate_label.type.value in ["MIXER", "COST"]: + angle_param = Parameter(each_gate.gate_label.__repr__()) + self.qiskit_parameter_list.append(angle_param) + each_gate.angle_value = angle_param + if ( + type(each_gate) + in QAOAQiskitBackendShotBasedSimulator.QISKIT_GATEMAP_LIBRARY + ): decomposition = each_gate.decomposition("trivial") else: decomposition = each_gate.decomposition("standard") @@ -201,9 +211,10 @@ def get_counts(self, params: QAOAVariationalBaseParams, n_shots=None) -> dict: .result() .get_counts() ) - flipped_counts = flip_counts(counts) - self.measurement_outcomes = flipped_counts - return flipped_counts + + final_counts = flip_counts(counts) + self.measurement_outcomes = final_counts + return final_counts def circuit_to_qasm(self): """ @@ -280,7 +291,6 @@ def __init__( ), "Please use the shot-based simulator for simulations with cvar_alpha < 1" self.qureg = QuantumRegister(self.n_qubits) - self.qubit_layout = self.qaoa_descriptor.qureg if self.prepend_state: assert self.n_qubits >= len(prepend_state.qubits), ( @@ -363,10 +373,15 @@ def parametric_qaoa_circuit(self) -> QuantumCircuit: self.qiskit_parameter_list = [] for each_gate in self.abstract_circuit: - angle_param = Parameter(str(each_gate.pauli_label)) - self.qiskit_parameter_list.append(angle_param) - each_gate.rotation_angle = angle_param - if type(each_gate) in self.QISKIT_GATEMAP_LIBRARY: + # if gate is of type mixer or cost gate, assign parameter to it + if each_gate.gate_label.type.value in ["MIXER", "COST"]: + angle_param = Parameter(each_gate.gate_label.__repr__()) + self.qiskit_parameter_list.append(angle_param) + each_gate.angle_value = angle_param + if ( + type(each_gate) + in QAOAQiskitBackendStatevecSimulator.QISKIT_GATEMAP_LIBRARY + ): decomposition = each_gate.decomposition("trivial") else: decomposition = each_gate.decomposition("standard") diff --git a/tests/jobs_test_input/aws_braket_source_module/openqaoa_qaoa_script.py b/tests/jobs_test_input/aws_braket_source_module/openqaoa_qaoa_script.py new file mode 100644 index 000000000..10196962b --- /dev/null +++ b/tests/jobs_test_input/aws_braket_source_module/openqaoa_qaoa_script.py @@ -0,0 +1,18 @@ +from braket.jobs import save_job_result +from openqaoa.algorithms import AWSJobs + + +def main(): + """ + The entry point is kept clean and simple and all the load statements are hidden in the `aws_jobs_load` function (which will become part of the OpenQAOA library) + """ + + job = AWSJobs(algorithm="QAOA") + job.load_compile_data() + job.run_workflow() + + save_job_result({"result": job.workflow.asdict()}) + + +if __name__ == "__main__": + main() diff --git a/tests/jobs_test_input/aws_braket_source_module/openqaoa_rqaoa_script.py b/tests/jobs_test_input/aws_braket_source_module/openqaoa_rqaoa_script.py new file mode 100644 index 000000000..073ca64f1 --- /dev/null +++ b/tests/jobs_test_input/aws_braket_source_module/openqaoa_rqaoa_script.py @@ -0,0 +1,19 @@ +from braket.jobs import save_job_result + +from openqaoa.algorithms import AWSJobs + + +def main(): + """ + The entry point is kept clean and simple and all the load statements are hidden in the `aws_jobs_load` function (which will become part of the OpenQAOA library) + """ + + job = AWSJobs(algorithm="RQAOA") + job.load_compile_data() + job.run_workflow() + + save_job_result({"result": job.workflow.asdict()}) + + +if __name__ == "__main__": + main() diff --git a/tests/jobs_test_input/input_data/openqaoa_params.json b/tests/jobs_test_input/input_data/openqaoa_params.json new file mode 100644 index 000000000..51c0d302d --- /dev/null +++ b/tests/jobs_test_input/input_data/openqaoa_params.json @@ -0,0 +1,286 @@ +{ + "header": { + "atomic_id": "210a6aaa-932d-45a6-b260-f3fdd085c547", + "experiment_id": "74779bb1-867c-4131-89d2-ac9238422cd9", + "project_id": null, + "algorithm": "rqaoa", + "description": null, + "run_by": null, + "provider": null, + "target": null, + "cloud": null, + "client": null, + "qubit_number": 10, + "execution_time_start": null, + "execution_time_end": null, + "metadata": { + "problem_type": "minimum_vertex_cover", + "n_shots": 100, + "optimizer_method": "cobyla", + "param_type": "standard", + "init_type": "ramp", + "p": 1, + "rqaoa_type": "custom", + "rqaoa_n_max": 1, + "rqaoa_n_cutoff": 3 + } + }, + "data": { + "exp_tags": {}, + "input_problem": { + "terms": [ + [ + 0, + 9 + ], + [ + 0, + 1 + ], + [ + 1, + 2 + ], + [ + 2, + 3 + ], + [ + 3, + 4 + ], + [ + 4, + 5 + ], + [ + 5, + 6 + ], + [ + 6, + 7 + ], + [ + 8, + 7 + ], + [ + 8, + 9 + ], + [ + 0 + ], + [ + 1 + ], + [ + 2 + ], + [ + 3 + ], + [ + 4 + ], + [ + 5 + ], + [ + 6 + ], + [ + 7 + ], + [ + 8 + ], + [ + 9 + ] + ], + "weights": [ + 2.5, + 2.5, + 2.5, + 2.5, + 2.5, + 2.5, + 2.5, + 2.5, + 2.5, + 2.5, + 4.5, + 4.5, + 4.5, + 4.5, + 4.5, + 4.5, + 4.5, + 4.5, + 4.5, + 4.5 + ], + "constant": 30.0, + "n": 10, + "problem_instance": { + "problem_type": "minimum_vertex_cover", + "G": { + "directed": false, + "multigraph": false, + "graph": {}, + "nodes": [ + { + "id": 0 + }, + { + "id": 1 + }, + { + "id": 2 + }, + { + "id": 3 + }, + { + "id": 4 + }, + { + "id": 5 + }, + { + "id": 6 + }, + { + "id": 7 + }, + { + "id": 8 + }, + { + "id": 9 + } + ], + "links": [ + { + "source": 0, + "target": 9 + }, + { + "source": 0, + "target": 1 + }, + { + "source": 1, + "target": 2 + }, + { + "source": 2, + "target": 3 + }, + { + "source": 3, + "target": 4 + }, + { + "source": 4, + "target": 5 + }, + { + "source": 5, + "target": 6 + }, + { + "source": 6, + "target": 7 + }, + { + "source": 7, + "target": 8 + }, + { + "source": 8, + "target": 9 + } + ] + }, + "field": 1.0, + "penalty": 10 + }, + "metadata": {} + }, + "input_parameters": { + "device": { + "device_location": "local", + "device_name": "vectorized" + }, + "backend_properties": { + "init_hadamard": true, + "n_shots": 100, + "prepend_state": null, + "append_state": null, + "cvar_alpha": 1, + "noise_model": null, + "initial_qubit_mapping": null, + "seed_simulator": null, + "qiskit_simulation_method": null, + "active_reset": null, + "rewiring": null, + "disable_qubit_rewiring": null + }, + "classical_optimizer": { + "optimize": true, + "method": "cobyla", + "maxiter": 3, + "maxfev": null, + "jac": null, + "hess": null, + "constraints": null, + "bounds": null, + "tol": null, + "optimizer_options": null, + "jac_options": null, + "hess_options": null, + "parameter_log": true, + "optimization_progress": false, + "cost_progress": true, + "save_intermediate": false + }, + "circuit_properties": { + "param_type": "standard", + "init_type": "ramp", + "qubit_register": [], + "p": 1, + "q": null, + "variational_params_dict": { + "q": null, + "total_annealing_time": 0.7 + }, + "annealing_time": 0.7, + "linear_ramp_time": 0.7, + "mixer_hamiltonian": "x", + "mixer_qubit_connectivity": null, + "mixer_coeffs": null, + "seed": null + }, + "rqaoa_parameters": { + "rqaoa_type": "custom", + "n_max": 1, + "steps": [ + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ], + "n_cutoff": 3, + "original_hamiltonian": null, + "counter": 0 + } + }, + "result": null + } +} \ No newline at end of file diff --git a/tests/test_all.py b/tests/test_all.py index 1d3ee824b..1990f71a2 100644 --- a/tests/test_all.py +++ b/tests/test_all.py @@ -2,5 +2,5 @@ for pathfile in os.listdir(): print(pathfile) - if pathfile != 'test_all.py' and pathfile[-3:] == '.py': - os.system('python3 {} -b'.format(pathfile)) + if pathfile != "test_all.py" and pathfile[-3:] == ".py": + os.system("python3 {} -b".format(pathfile)) diff --git a/tests/test_aws_managed_jobs.py b/tests/test_aws_managed_jobs.py new file mode 100644 index 000000000..5510f5155 --- /dev/null +++ b/tests/test_aws_managed_jobs.py @@ -0,0 +1,138 @@ +# Copyright 2022 Entropica Labs +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License 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. + +import os +import pytest +import unittest +import networkx as nw +from braket.jobs.local import LocalQuantumJob + +from openqaoa.problems import MinimumVertexCover +from openqaoa.algorithms import AWSJobs +from openqaoa.algorithms import QAOA, RQAOA +from openqaoa.backends import create_device + + +class TestingAwsJobs(unittest.TestCase): + def setUp(self): + # the input data directory opt/braket/input/data + os.environ["AMZN_BRAKET_INPUT_DIR"] = "./tests/jobs_test_input/" + # the output directory opt/braket/model to write ob results to + os.environ["AMZN_BRAKET_JOB_RESULTS_DIR"] = "/oq_release_tests/testing_jobs/" + # the name of the job + os.environ["AMZN_BRAKET_JOB_NAME"] = "oq_release_test" + # the checkpoint directory + os.environ["AMZN_BRAKET_CHECKPOINT_DIR"] = "oq_test_suite_checkpoint" + # the hyperparameter + os.environ["AMZN_BRAKET_HP_FILE"] = "" + # the device ARN (AWS Resource Number) + os.environ[ + "AMZN_BRAKET_DEVICE_ARN" + ] = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" + # the output S3 bucket, as specified in the CreateJob request’s OutputDataConfig + os.environ["AMZN_BRAKET_OUT_S3_BUCKET"] = "amazon-braket-us-east-1-oq-testing" + # the entry point as specified in the CreateJob request’s ScriptModeConfig + os.environ["AMZN_BRAKET_SCRIPT_ENTRY_POINT"] = "" + # the compression type as specified in the CreateJob request’s ScriptModeConfig + os.environ["AMZN_BRAKET_SCRIPT_COMPRESSION_TYPE"] = "" + # the S3 location of the user’s script as specified in the CreateJob request’s ScriptModeConfig + os.environ["AMZN_BRAKET_SCRIPT_S3_URI"] = "" + # the S3 location where the SDK would store the task results by default for the job + os.environ["AMZN_BRAKET_TASK_RESULTS_S3_URI"] = "" + # the S3 location where the job results would be stored, as specified in CreateJob request’s OutputDataConfig + os.environ["AMZN_BRAKET_JOB_RESULTS_S3_PATH"] = "" + # the string that should be passed to CreateQuantumTask’s jobToken parameter for quantum tasks created in the job container + # os.environ["AMZN_BRAKET_JOB_TOKEN"] = '' + + self.vc = MinimumVertexCover( + nw.circulant_graph(10, [1]), field=1.0, penalty=10 + ).qubo + + def testOsEnvironAssignment(self): + + qaoa_workflow = AWSJobs(algorithm="QaoA") + assert qaoa_workflow.algorithm == "qaoa" + assert qaoa_workflow.input_dir == "./tests/jobs_test_input/" + assert qaoa_workflow.device.device_name == os.environ["AMZN_BRAKET_DEVICE_ARN"] + + rqaoa_workflow = AWSJobs(algorithm="rqAoa") + assert rqaoa_workflow.algorithm == "rqaoa" + assert rqaoa_workflow.device.device_name == os.environ["AMZN_BRAKET_DEVICE_ARN"] + + @pytest.mark.docker_aws + def testLocalJob(self): + """Test an end-to-end qaoa running on a local docker instance""" + + input_data_path = os.path.join( + os.environ["AMZN_BRAKET_INPUT_DIR"], "input_data/" + ) + + # Create the qubo and the qaoa + q = QAOA() + q.set_device( + create_device("aws", "arn:aws:braket:::device/quantum-simulator/amazon/sv1") + ) + q.set_classical_optimizer(maxiter="5") + q.compile(self.vc) + q.dump( + file_name="openqaoa_params.json", + file_path=input_data_path, + prepend_id=False, + overwrite=True, + ) + + job = LocalQuantumJob.create( + device="arn:aws:braket:::device/quantum-simulator/amazon/sv1", + source_module="./tests/jobs_test_input/aws_braket_source_module/openqaoa_qaoa_script.py", + image_uri="amazon-braket-oq-dev", + input_data={"input_data": input_data_path}, + ) + + assert (job.state() == "COMPLETED") and (job.result() != None) == True + + @pytest.mark.docker_aws + def testLocalJobRQAOA(self): + """Test an end-to-end rqaoa running on a local docker instance""" + + input_data_path = os.path.join( + os.environ["AMZN_BRAKET_INPUT_DIR"], "input_data/" + ) + + # Create the rqaoa + r = RQAOA() + r.set_rqaoa_parameters(n_cutoff=6) + r.set_classical_optimizer(maxiter=3, save_intermediate=False) + r.set_device( + create_device("aws", "arn:aws:braket:::device/quantum-simulator/amazon/sv1") + ) + r.compile(self.vc) + r.dump( + file_name="openqaoa_params.json", + file_path=input_data_path, + prepend_id=False, + overwrite=True, + ) + + job = LocalQuantumJob.create( + device="arn:aws:braket:::device/quantum-simulator/amazon/sv1", + source_module="./tests/jobs_test_input/aws_braket_source_module/openqaoa_rqaoa_script.py", + image_uri="amazon-braket-oq-dev", + input_data={"input_data": input_data_path}, + ) + + assert (job.state() == "COMPLETED") and (job.result() != None) == True + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_backends.py b/tests/test_backends.py index fc633a086..a61452880 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -4,10 +4,15 @@ import pytest import subprocess -from openqaoa.backends.qaoa_backend import get_qaoa_backend, DEVICE_NAME_TO_OBJECT_MAPPER, DEVICE_ACCESS_OBJECT_MAPPER +from openqaoa.backends.qaoa_backend import ( + get_qaoa_backend, + DEVICE_NAME_TO_OBJECT_MAPPER, + DEVICE_ACCESS_OBJECT_MAPPER, +) from openqaoa.qaoa_components import ( - Hamiltonian, create_qaoa_variational_params, - QAOADescriptor + Hamiltonian, + create_qaoa_variational_params, + QAOADescriptor, ) from openqaoa.utilities import X_mixer_hamiltonian from openqaoa.backends.qaoa_device import create_device @@ -19,110 +24,184 @@ def get_params(): mixer_hamil = X_mixer_hamiltonian(2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - variational_params_std = create_qaoa_variational_params(qaoa_descriptor, 'standard', 'ramp') + variational_params_std = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) return qaoa_descriptor, variational_params_std + class TestingBackendLocal(unittest.TestCase): """ These tests check that the methods of the local backends are working properly. """ def test_get_counts_and_expectation_n_shots(self): - """ + """ Check that the .get_counts admit n_shots as an argument, and works properly for the backend of all local devices. Also check that .expectation and .expecation_w_uncertainty methods admit n_shots as an argument for the QAOABaseBackendShotBased backends. """ for device_name in DEVICE_NAME_TO_OBJECT_MAPPER.keys(): - - # Analytical device doesn't have any of those so we are skipping it in the tests. - if device_name in ['analytical_simulator']: continue - qaoa_descriptor, variational_params_std= get_params() - - device = create_device(location='local', name=device_name) - backend = get_qaoa_backend(qaoa_descriptor=qaoa_descriptor, device=device, n_shots=1000) - - assert sum(backend.get_counts(params=variational_params_std, n_shots=58).values())==58, "`n_shots` is not being respected for the local simulator `{}` when calling backend.get_counts(n_shots=58).".format(device_name) - if isinstance(backend, QAOABaseBackendShotBased): - try: backend.expectation(params=variational_params_std, n_shots=58) - except Exception: raise Exception("backend.expectation does not admit `n_shots` as an argument for the local simulator `{}`.".format(device_name)) - try: backend.expectation_w_uncertainty(params=variational_params_std, n_shots=58) - except Exception: raise Exception("backend.expectation_w_uncertainty does not admit `n_shots` as an argument for the local simulator `{}`.".format(device_name)) + # Analytical device doesn't have any of those so we are skipping it in the tests. + if device_name in ["analytical_simulator"]: + continue + qaoa_descriptor, variational_params_std = get_params() -class TestingBackendQPUs(unittest.TestCase): - """ + device = create_device(location="local", name=device_name) + backend = get_qaoa_backend( + qaoa_descriptor=qaoa_descriptor, device=device, n_shots=1000 + ) + + assert ( + sum( + backend.get_counts( + params=variational_params_std, n_shots=58 + ).values() + ) + == 58 + ), "`n_shots` is not being respected for the local simulator `{}` when calling backend.get_counts(n_shots=58).".format( + device_name + ) + if isinstance(backend, QAOABaseBackendShotBased): + try: + backend.expectation(params=variational_params_std, n_shots=58) + except Exception: + raise Exception( + "backend.expectation does not admit `n_shots` as an argument for the local simulator `{}`.".format( + device_name + ) + ) + try: + backend.expectation_w_uncertainty( + params=variational_params_std, n_shots=58 + ) + except Exception: + raise Exception( + "backend.expectation_w_uncertainty does not admit `n_shots` as an argument for the local simulator `{}`.".format( + device_name + ) + ) + + +class TestingBackendQPUs(unittest.TestCase): + """ These tests check methods of the QPU backends. For all of these tests, credentials.json MUST be filled with the appropriate - credentials. + credentials. """ @pytest.mark.qpu def setUp(self): - self.HUB = 'ibm-q' - self.GROUP = 'open' - self.PROJECT = 'main' - + self.HUB = "ibm-q" + self.GROUP = "open" + self.PROJECT = "main" + bashCommand = "az resource list" process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE) output, error = process.communicate() - + if error is not None: print(error) - raise Exception('You must have the Azure CLI installed and must be logged in to use the Azure Quantum Backends') + raise Exception( + "You must have the Azure CLI installed and must be logged in to use the Azure Quantum Backends" + ) else: output_json = json.loads(output) - output_json_s = [each_json for each_json in output_json if each_json['name'] == 'TestingOpenQAOA'][0] - self.RESOURCE_ID = output_json_s['id'] - self.AZ_LOCATION = output_json_s['location'] - + output_json_s = [ + each_json + for each_json in output_json + if each_json["name"] == "TestingOpenQAOA" + ][0] + self.RESOURCE_ID = output_json_s["id"] + self.AZ_LOCATION = output_json_s["location"] @pytest.mark.qpu def test_get_counts_and_expectation_n_shots(self): - """ Check that the .get_counts, .expectation and .expecation_w_uncertainty methods admit n_shots as an argument for the backends of all QPUs. """ - - list_device_attributes = [ - {'QPU': 'Qiskit', 'device_name': 'ibmq_qasm_simulator', 'hub': self.HUB, 'group': self.GROUP, 'project': self.PROJECT}, - {'QPU': 'Pyquil', 'device_name': "2q-qvm", 'as_qvm': True, 'execution_timeout': 3, 'compiler_timeout': 3}, - {'QPU': 'AWS', 'device_name': 'arn:aws:braket:::device/quantum-simulator/amazon/sv1'}, - {'QPU': 'Azure', 'device_name': 'rigetti.sim.qvm', 'resource_id': self.RESOURCE_ID, 'az_location': self.AZ_LOCATION} - ] - - assert len(list_device_attributes) == len(DEVICE_ACCESS_OBJECT_MAPPER), "The number of QPUs in the list of tests is not the same as the number of QPUs in the DEVICE_ACCESS_OBJECT_MAPPER. The list should be updated." - - for (device, backend), device_attributes in zip(DEVICE_ACCESS_OBJECT_MAPPER.items(), list_device_attributes): + """Check that the .get_counts, .expectation and .expecation_w_uncertainty methods admit n_shots as an argument for the backends of all QPUs.""" + + list_device_attributes = [ + { + "QPU": "Qiskit", + "device_name": "ibmq_qasm_simulator", + "hub": self.HUB, + "group": self.GROUP, + "project": self.PROJECT, + }, + { + "QPU": "Pyquil", + "device_name": "2q-qvm", + "as_qvm": True, + "execution_timeout": 3, + "compiler_timeout": 3, + }, + { + "QPU": "AWS", + "device_name": "arn:aws:braket:::device/quantum-simulator/amazon/sv1", + }, + { + "QPU": "Azure", + "device_name": "rigetti.sim.qvm", + "resource_id": self.RESOURCE_ID, + "az_location": self.AZ_LOCATION, + }, + ] + + assert len(list_device_attributes) == len( + DEVICE_ACCESS_OBJECT_MAPPER + ), "The number of QPUs in the list of tests is not the same as the number of QPUs in the DEVICE_ACCESS_OBJECT_MAPPER. The list should be updated." + + for (device, backend), device_attributes in zip( + DEVICE_ACCESS_OBJECT_MAPPER.items(), list_device_attributes + ): qaoa_descriptor, variational_params_std = get_params() - QPU_name = device_attributes.pop('QPU') + QPU_name = device_attributes.pop("QPU") print("Testing {} backend.".format(QPU_name)) - # if QPU_name in ["AWS", 'Qiskit']: # print(f"Skipping test for {QPU_name} backend.") - # continue + # continue - try: + try: device = device(**device_attributes) - backend = backend(qaoa_descriptor = qaoa_descriptor, device = device, cvar_alpha = 1, n_shots=100, prepend_state = None, append_state = None, init_hadamard = True) + backend = backend( + qaoa_descriptor=qaoa_descriptor, + device=device, + cvar_alpha=1, + n_shots=100, + prepend_state=None, + append_state=None, + init_hadamard=True, + ) # Check that the .get_counts, .expectation and .expectation_w_variance methods admit n_shots as an argument - assert sum(backend.get_counts(params=variational_params_std, n_shots=58).values()) == 58, "`n_shots` is not being respected when calling .get_counts(n_shots=58).".format(QPU_name) + assert ( + sum( + backend.get_counts( + params=variational_params_std, n_shots=58 + ).values() + ) + == 58 + ), "`n_shots` is not being respected when calling .get_counts(n_shots=58).".format( + QPU_name + ) backend.expectation(params=variational_params_std, n_shots=58) - backend.expectation_w_uncertainty(params=variational_params_std, n_shots=58) + backend.expectation_w_uncertainty( + params=variational_params_std, n_shots=58 + ) - except Exception as e: + except Exception as e: raise e from type(e)(f"Error raised for `{QPU_name}`: " + str(e)) print("Test passed for {} backend.".format(QPU_name)) - - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_circuit_routing.py b/tests/test_circuit_routing.py new file mode 100644 index 000000000..f7d72793d --- /dev/null +++ b/tests/test_circuit_routing.py @@ -0,0 +1,1143 @@ +# unit testing for circuit routing functionality in OQ +import unittest +import numpy as np +from typing import List, Callable, Optional +import pytest + +from openqaoa import QAOA +from openqaoa.qaoa_components import ( + create_qaoa_variational_params, + QAOADescriptor, + PauliOp, + Hamiltonian, +) +from openqaoa.utilities import X_mixer_hamiltonian +from openqaoa.backends import QAOAvectorizedBackendSimulator, create_device +from openqaoa.problems import NumberPartition, QUBO, Knapsack, MaximumCut, ShortestPath +from openqaoa_pyquil.backends import DevicePyquil, QAOAPyQuilQPUBackend +from openqaoa.backends.devices_core import DeviceBase +from openqaoa.qaoa_components.ansatz_constructor.gatemap import SWAPGateMap + + +class TestingQAOAPyquilQVM_QR(unittest.TestCase): + + """Tests pyquil backend compatibility with routing_function. + + For all of these tests, qvm and quilc must be running. + """ + + def test_no_swap(self): + """ + Tests that QAOADescriptor with a trivial `routing_function` input (with no swaps) returns identical + results as QAOADescriptor with no `routing_function` input, by comparing output of seeded QVM run. + Different values of p, arguments, and cost hamiltonian coefficients are tested. + + """ + + def routing_function_test1(device, problem_to_solve): + + # tuples ordered from 0,n, both SWAP and ising gates + gate_list_indices = [[0, 1]] + + # True for SWAP + swap_mask = [False] + + # {QPU: (0 to n index)} + initial_physical_to_logical_mapping = {0: 0, 1: 1} + + # 0 to n, permuted + final_mapping = [0, 1] + + return ( + gate_list_indices, + swap_mask, + initial_physical_to_logical_mapping, + final_mapping, + ) + + args_lst = [ + [np.pi / 8, np.pi / 4], + [np.pi / 3.5, np.pi / 3], + [np.pi / 8, np.pi / 4], + [np.pi / 3.5, np.pi / 3], + [1, 2, 3, 4], + [np.pi / 8, np.pi / 4, np.pi / 8, np.pi / 4], + [1, 2, 3, 4], + [np.pi / 8, np.pi / 4, np.pi / 8, np.pi / 4], + ] + p_lst = [1, 1, 1, 1, 2, 2, 2, 2] + cost_hamil_lst = [ + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [0.5, 0, 2], + 0.7, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1.2, 1], + 0, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [0.5, 0, 2], + 0.7, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1.2, 1], + 0, + ), + ] + shots = 2 + seed = 1 + + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=5, compiler_timeout=5 + ) + device_pyquil.quantum_computer.qam.random_seed = seed + + for i in range(len(p_lst)): + + p = p_lst[i] + args = args_lst[i] + cost_hamil = cost_hamil_lst[i] + + # With routing + mixer_hamil = X_mixer_hamiltonian(n_qubits=2) + qaoa_descriptor = QAOADescriptor( + cost_hamil, mixer_hamil, routing_function=routing_function_test1, p=p + ) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) + + variate_params.update_from_raw(args) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=shots, + ) + expt_pyquil_w_qr = backend_obj_pyquil.expectation(variate_params) + + # No routing + mixer_hamil = X_mixer_hamiltonian(n_qubits=2) + qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) + + variate_params.update_from_raw(args) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=shots, + ) + expt_pyquil_no_qr = backend_obj_pyquil.expectation(variate_params) + + self.assertAlmostEqual(expt_pyquil_w_qr, expt_pyquil_no_qr) + + def test_cancelled_swap(self): + """ + Tests that QAOADescriptor with a trivial `routing_function` input (with two swaps that cancel each other) returns identical + results as QAOADescriptor with no `routing_function` input, by comparing output of seeded QVM run. + Different values of p, arguments, and cost hamiltonian coefficients are tested. + + """ + + def routing_function_test1(device, problem_to_solve): + + # tuples ordered from 0,n, both SWAP and ising gates + gate_list_indices = [[0, 1], [0, 1], [0, 1]] + + # True for SWAP + swap_mask = [True, True, False] + + # {QPU: (0 to n index)} + initial_physical_to_logical_mapping = {0: 0, 1: 1} + + # 0 to n, permuted + final_mapping = [0, 1] + + return ( + gate_list_indices, + swap_mask, + initial_physical_to_logical_mapping, + final_mapping, + ) + + args_lst = [ + [np.pi / 8, np.pi / 4], + [np.pi / 3.5, np.pi / 3], + [np.pi / 8, np.pi / 4], + [np.pi / 3.5, np.pi / 3], + [1, 2, 3, 4], + [np.pi / 8, np.pi / 4, np.pi / 8, np.pi / 4], + [1, 2, 3, 4], + [np.pi / 8, np.pi / 4, np.pi / 8, np.pi / 4], + ] + p_lst = [1, 1, 1, 1, 2, 2, 2, 2] + cost_hamil_lst = [ + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [0.5, 0, 2], + 0.7, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1.5, 1.2, 1], + 0, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [0.5, 0, 2], + 0.7, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 5.2, 1], + 0, + ), + ] + shots = 3 + seed = 4 + + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=5, compiler_timeout=5 + ) + device_pyquil.quantum_computer.qam.random_seed = seed + + for i in range(len(p_lst)): + + p = p_lst[i] + args = args_lst[i] + cost_hamil = cost_hamil_lst[i] + + # With routing + mixer_hamil = X_mixer_hamiltonian(n_qubits=2) + qaoa_descriptor = QAOADescriptor( + cost_hamil, mixer_hamil, routing_function=routing_function_test1, p=p + ) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) + + variate_params.update_from_raw(args) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=shots, + ) + expt_pyquil_w_qr = backend_obj_pyquil.expectation(variate_params) + + # No routing + mixer_hamil = X_mixer_hamiltonian(n_qubits=2) + qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) + + variate_params.update_from_raw(args) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=shots, + ) + expt_pyquil_no_qr = backend_obj_pyquil.expectation(variate_params) + + self.assertAlmostEqual(expt_pyquil_w_qr, expt_pyquil_no_qr) + + def test_simplest_swap(self): + """ + Tests that QAOADescriptor with a trivial `routing_function` input (with no swaps) returns identical + results as QAOADescriptor with no `routing_function` input, by comparing output of seeded QVM run. + Different values of p, arguments, and cost hamiltonian coefficients are tested. + + Note : Even with a fixed seed, insertion of swaps changes measurement statistics. + Final assertion is therefore only up to a tolerance, chosen by eyeballing results for a chosen seed. + + """ + + def routing_function_test1(device, problem_to_solve): + + # tuples ordered from 0,n, both SWAP and ising gates + gate_list_indices = [[0, 1], [0, 1]] + + # True for SWAP + swap_mask = [True, False] + + # {QPU: (0 to n index)} + initial_physical_to_logical_mapping = {0: 0, 1: 1} + + # 0 to n, permuted + final_mapping = [1, 0] + + return ( + gate_list_indices, + swap_mask, + initial_physical_to_logical_mapping, + final_mapping, + ) + + args_lst = [ + [np.pi / 8, np.pi / 4], + [np.pi / 3.5, np.pi / 3], + [np.pi / 8, np.pi / 4], + [np.pi / 3.5, np.pi / 3], + [1, 2, 3, 4], + [np.pi / 8, np.pi / 4, np.pi / 8, np.pi / 4], + [1, 2, 3, 4], + [np.pi / 8, np.pi / 4, np.pi / 8, np.pi / 4], + ] + p_lst = [1, 1, 1, 1, 2, 2, 2, 2] + cost_hamil_lst = [ + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [0.5, 0, 2], + 0.7, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1.5, 1.2, 1], + 0, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [0.5, 0, 2], + 0.7, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 5.2, 1], + 0, + ), + ] + shots = 10 + seed = 4 + + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=10, compiler_timeout=10 + ) + device_pyquil.quantum_computer.qam.random_seed = seed + + for i in range(len(p_lst)): + + p = p_lst[i] + args = args_lst[i] + cost_hamil = cost_hamil_lst[i] + + # With routing + mixer_hamil = X_mixer_hamiltonian(n_qubits=2) + qaoa_descriptor = QAOADescriptor( + cost_hamil, mixer_hamil, routing_function=routing_function_test1, p=p + ) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) + + variate_params.update_from_raw(args) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=shots, + ) + expt_pyquil_w_qr = backend_obj_pyquil.expectation(variate_params) + + # No routing + mixer_hamil = X_mixer_hamiltonian(n_qubits=2) + qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) + + variate_params.update_from_raw(args) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=shots, + ) + expt_pyquil_no_qr = backend_obj_pyquil.expectation(variate_params) + + # Note : Even with a fixed seed, insertion of swaps changes measurement statistics. + # Final assertion is therefore only up to a tolerance, chosen by eyeballing results for a chosen seed. + self.assertAlmostEqual(expt_pyquil_w_qr, expt_pyquil_no_qr, delta=1) + + def test_different_topologies(self): + """ + Tests QAOADescriptor with different devices. + results as QAOADescriptor with no `routing_function` input, by comparing output of seeded QVM run. + Different values of p, arguments, and cost hamiltonian coefficients are tested. + + """ + + def routing_function_test1(device, problem_to_solve): + + # tuples ordered from 0,n, both SWAP and ising gates + gate_list_indices = [[0, 1], [1, 0], [0, 1]] + + # True for SWAP + swap_mask = [True, True, False] + + # {QPU: (0 to n index)} + initial_physical_to_logical_mapping = {0: 0, 1: 1} + + # 0 to n, permuted + final_mapping = [0, 1] + + return ( + gate_list_indices, + swap_mask, + initial_physical_to_logical_mapping, + final_mapping, + ) + + args_lst = [[np.pi / 8, np.pi / 4], [np.pi / 8, np.pi / 4, 1, 2], [1, 2, 3, 4]] + p_lst = [1, 2, 2] + cost_hamil_lst = [ + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1.5, 2], + 0.5, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1.5, 2], + 0.5, + ), + Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1.5, 2], + 0.5, + ), + ] + + device_name_lst = ["2q-qvm", "3q-qvm", "Aspen-M-3"] + + shots = 2 + seed = 1 + + for i in range(len(p_lst)): + + p = p_lst[i] + args = args_lst[i] + cost_hamil = cost_hamil_lst[i] + + device_pyquil = DevicePyquil( + device_name=device_name_lst[i], + as_qvm=True, + execution_timeout=5, + compiler_timeout=5, + ) + device_pyquil.quantum_computer.qam.random_seed = seed + + # With routing + mixer_hamil = X_mixer_hamiltonian(n_qubits=2) + qaoa_descriptor = QAOADescriptor( + cost_hamil, mixer_hamil, routing_function=routing_function_test1, p=p + ) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) + + variate_params.update_from_raw(args) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=shots, + ) + expt_pyquil_w_qr = backend_obj_pyquil.expectation(variate_params) + + # No routing + mixer_hamil = X_mixer_hamiltonian(n_qubits=2) + qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) + + variate_params.update_from_raw(args) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=shots, + ) + expt_pyquil_no_qr = backend_obj_pyquil.expectation(variate_params) + + self.assertAlmostEqual(expt_pyquil_w_qr, expt_pyquil_no_qr) + + +class ExpectedRouting: + def __init__( + self, + qubo, + device_name, + device_location, + qpu_credentials, + problem_to_solve, + initial_mapping, + gate_indices_list, + swap_mask, + initial_physical_to_logical_mapping, + final_logical_qubit_order, + ): + self.qubo = qubo + self.device = create_device( + name=device_name, location=device_location, **qpu_credentials + ) + + self.device_name = device_name + self.device_location = device_location + self.problem_to_solve = problem_to_solve + self.initial_mapping = initial_mapping + + self.gate_indices_list = gate_indices_list + self.swap_mask = swap_mask + self.initial_physical_to_logical_mapping = initial_physical_to_logical_mapping + self.final_logical_qubit_order = final_logical_qubit_order + + def values_input(self): + return ( + self.device_name, + self.device_location, + self.problem_to_solve, + self.initial_mapping, + ) + + def values_return(self): + return ( + self.gate_indices_list, + self.swap_mask, + self.initial_physical_to_logical_mapping, + self.final_logical_qubit_order, + ) + + +class TestingQubitRouting(unittest.TestCase): + @pytest.mark.qpu + def setUp(self): + + # case qubits device > qubits problem (IBM NAIROBI) + self.IBM_NAIROBI_KNAPSACK = ExpectedRouting( + qubo=Knapsack.random_instance(n_items=3, seed=20).qubo, + device_location="ibmq", + device_name="ibm_nairobi", + qpu_credentials={ + "hub": "ibm-q", + "group": "open", + "project": "main", + "as_emulator": True, + }, + problem_to_solve=[ + (0, 1), + (2, 3), + (2, 4), + (3, 4), + (0, 2), + (0, 3), + (0, 4), + (1, 2), + (1, 3), + (1, 4), + ], + initial_mapping=None, + gate_indices_list=[ + [2, 4], + [1, 2], + [3, 5], + [0, 5], + [4, 5], + [4, 5], + [2, 4], + [0, 5], + [2, 4], + [1, 2], + [4, 5], + [0, 5], + [1, 2], + [2, 4], + [2, 4], + [0, 5], + [4, 5], + ], + swap_mask=[ + False, + False, + True, + False, + False, + True, + False, + False, + True, + False, + True, + False, + True, + False, + True, + True, + False, + ], + initial_physical_to_logical_mapping={6: 0, 2: 1, 1: 2, 4: 3, 3: 4, 5: 5}, + final_logical_qubit_order=[5, 4, 0, 1, 2, 3], + ) + + # case qubits problem == 2 (IBM OSLO) + self.IBM_OSLO_QUBO2 = ExpectedRouting( + qubo=QUBO.from_dict( + { + "terms": [[0, 1], [1]], + "weights": [9.800730090617392, 26.220558065741773], + "n": 2, + } + ), + device_location="ibmq", + device_name="ibm_oslo", + qpu_credentials={ + "hub": "ibm-q", + "group": "open", + "project": "main", + "as_emulator": True, + }, + problem_to_solve=[(0, 1)], + initial_mapping=None, + gate_indices_list=[[0, 2], [1, 2]], + swap_mask=[True, False], + initial_physical_to_logical_mapping={2: 0, 3: 1, 1: 2}, + final_logical_qubit_order=[2, 1, 0], + ) + + # case qubits device == qubits problem (IBM OSLO) + self.IBM_OSLO_NPARTITION = ExpectedRouting( + qubo=NumberPartition.random_instance(n_numbers=7, seed=2).qubo, + device_location="ibmq", + device_name="ibm_oslo", + qpu_credentials={ + "hub": "ibm-q", + "group": "open", + "project": "main", + "as_emulator": True, + }, + problem_to_solve=[ + (0, 1), + (0, 2), + (0, 3), + (0, 4), + (0, 5), + (0, 6), + (1, 2), + (1, 3), + (1, 4), + (1, 5), + (1, 6), + (2, 3), + (2, 4), + (2, 5), + (2, 6), + (3, 4), + (3, 5), + (3, 6), + (4, 5), + (4, 6), + (5, 6), + ], + initial_mapping=None, + gate_indices_list=[ + [0, 5], + [1, 5], + [3, 4], + [4, 5], + [2, 3], + [3, 6], + [4, 5], + [0, 5], + [1, 5], + [3, 4], + [3, 4], + [2, 3], + [3, 6], + [4, 5], + [0, 5], + [1, 5], + [2, 3], + [3, 6], + [3, 4], + [3, 4], + [3, 6], + [0, 5], + [1, 5], + [4, 5], + [4, 5], + [1, 5], + [3, 6], + [3, 4], + [3, 4], + [1, 5], + [4, 5], + ], + swap_mask=[ + False, + False, + False, + False, + False, + False, + True, + False, + False, + False, + True, + False, + False, + True, + False, + False, + True, + False, + False, + True, + False, + True, + False, + False, + True, + False, + True, + False, + True, + True, + False, + ], + initial_physical_to_logical_mapping={ + 0: 0, + 2: 1, + 4: 2, + 5: 3, + 3: 4, + 1: 5, + 6: 6, + }, + final_logical_qubit_order=[3, 5, 1, 0, 6, 2, 4], + ) + + # case qubits device > qubits problem (RIGETTI) + self.RIGETTI_SHORTESTPATH = ExpectedRouting( + qubo=ShortestPath.random_instance( + n_nodes=4, edge_probability=0.9, seed=20 + ).qubo, + device_location="qcs", + device_name="9q-square-qvm", + qpu_credentials={ + "as_qvm": True, + "execution_timeout": 10, + "compiler_timeout": 100, + }, + problem_to_solve=[ + (2, 3), + (0, 2), + (2, 4), + (2, 5), + (0, 4), + (4, 5), + (0, 5), + (1, 3), + (3, 5), + (1, 5), + ], + initial_mapping=None, + gate_indices_list=[ + [4, 5], + [2, 4], + [1, 3], + [3, 5], + [4, 5], + [1, 4], + [2, 4], + [0, 6], + [2, 6], + [2, 6], + [2, 4], + [4, 5], + [2, 4], + [1, 3], + [1, 6], + ], + swap_mask=[ + False, + False, + False, + False, + True, + False, + False, + True, + False, + True, + False, + True, + False, + True, + False, + ], + initial_physical_to_logical_mapping={ + 8: 0, + 4: 1, + 6: 2, + 1: 3, + 3: 4, + 0: 5, + 7: 6, + }, + final_logical_qubit_order=[2, 3, 6, 1, 4, 5, 0], + ) + + # case qubits device == qubits problem (RIGETTI) + self.RIGETTI_MACUT = ExpectedRouting( + qubo=MaximumCut.random_instance( + n_nodes=9, edge_probability=0.9, seed=20 + ).qubo, + device_location="qcs", + device_name="9q-square-qvm", + qpu_credentials={ + "as_qvm": True, + "execution_timeout": 10, + "compiler_timeout": 100, + }, + problem_to_solve=[ + (0, 2), + (0, 3), + (0, 4), + (0, 5), + (0, 7), + (0, 8), + (1, 2), + (1, 4), + (1, 5), + (1, 6), + (1, 7), + (1, 8), + (2, 3), + (2, 5), + (2, 6), + (2, 7), + (2, 8), + (3, 4), + (3, 5), + (3, 6), + (3, 8), + (4, 7), + (4, 8), + (5, 6), + (5, 7), + (5, 8), + (6, 7), + (6, 8), + (7, 8), + ], + initial_mapping=None, + gate_indices_list=[ + [5, 6], + [3, 5], + [0, 3], + [1, 7], + [0, 4], + [1, 8], + [4, 7], + [6, 8], + [6, 7], + [1, 2], + [2, 4], + [4, 7], + [0, 4], + [1, 2], + [6, 7], + [5, 6], + [1, 7], + [3, 7], + [4, 7], + [6, 8], + [0, 3], + [0, 4], + [3, 5], + [5, 6], + [6, 8], + [3, 5], + [1, 8], + [1, 2], + [6, 8], + [1, 7], + [3, 7], + [4, 7], + [4, 7], + [6, 7], + [0, 4], + [0, 4], + [2, 4], + ], + swap_mask=[ + False, + False, + False, + False, + False, + False, + False, + False, + False, + False, + True, + False, + False, + False, + True, + False, + False, + False, + False, + False, + True, + False, + False, + True, + False, + False, + True, + False, + False, + True, + False, + False, + True, + False, + False, + True, + False, + ], + initial_physical_to_logical_mapping={ + 2: 0, + 7: 1, + 8: 2, + 1: 3, + 5: 4, + 0: 5, + 3: 6, + 4: 7, + 6: 8, + }, + final_logical_qubit_order=[3, 8, 7, 4, 2, 6, 1, 5, 0], + ) + + # create a list of all the cases + self.list_of_cases = [] + for value in self.__dict__.values(): + if isinstance(value, ExpectedRouting): + self.list_of_cases.append(value) + + def __routing_function_mock( + self, + device: DeviceBase, + problem_to_solve: List[List[int]], + initial_mapping: Optional[List[int]] = None, + ): + """ + function that imitates the routing function for testing purposes. + """ + + for case in self.list_of_cases: + if case.values_input() == ( + device.device_name, + device.device_location, + problem_to_solve, + initial_mapping, + ): + return case.values_return() + + raise ValueError( + """The input values are not in the list of expected values, + check the expected cases and the input values. + The input values are: device_name: {}, device_location: {}, problem_to_solve: {}, + initial_mapping: {}""".format( + device.device_name, + device.device_location, + problem_to_solve, + initial_mapping, + ) + ) + + def __compare_results(self, expected: ExpectedRouting, p: int): + """ + function that runs qaoa with the routing function and the problem to solve and + compares the expected and actual results of the routing function. + + :param expected: ExpectedRouting object that contains the input and the expected results of the routing function + :param p: number of layers of the qaoa circuit + """ + print(f"\t Testing p={p}") + + device = expected.device + qubo = expected.qubo + + qaoa = QAOA() + qaoa.set_device(device) + qaoa.set_circuit_properties( + p=p, param_type="standard", init_type="rand", mixer_hamiltonian="x" + ) + qaoa.set_backend_properties(prepend_state=None, append_state=None) + qaoa.set_classical_optimizer( + method="nelder-mead", + maxiter=1, + cost_progress=True, + parameter_log=True, + optimization_progress=True, + ) + qaoa.compile(qubo, routing_function=self.__routing_function_mock) + qaoa.optimize() + + backend, result = qaoa.backend, qaoa.result + + # do the checks + + assert backend.n_qubits == len( + expected.final_logical_qubit_order + ), """Number of qubits in the circuit is not equal to the number of qubits given by routing""" + + assert ( + backend.problem_qubits == qubo.n + ), f"""Number of nodes in problem is not equal to backend.problem_qubits, + is '{backend.problem_qubits }' but should be '{qubo.n}'""" + + assert ( + len(list(result.optimized["measurement_outcomes"].keys())[0]) == qubo.n + ), "The number of qubits in the optimized circuit is not equal to the number of qubits in the problem." + + # check that swap gates are applied in the correct position + swap_mask_new = [] + for gate in backend.abstract_circuit: + if not gate.gate_label.n_qubits == 1: + swap_mask_new.append(isinstance(gate, SWAPGateMap)) + + # create the expected swap mask (for p==2 the second swap mask is reversed) + expected_swap_mask = [] + for i in range(p): + expected_swap_mask += expected.swap_mask[:: (-1) ** (i % 2)] + + assert ( + swap_mask_new == expected_swap_mask + ), "Swap gates are not in the correct position" + + # check that the correct qubits are used in the gates + gate_indices_list_new = [] + for gate in backend.abstract_circuit: + if not gate.gate_label.n_qubits == 1: + gate_indices_list_new.append([gate.qubit_1, gate.qubit_2]) + + # create the expected swap mask (for p==2 the second swap mask is reversed) + expected_gate_indices_list = [] + for i in range(p): + expected_gate_indices_list += expected.gate_indices_list[:: (-1) ** (i % 2)] + + assert ( + gate_indices_list_new == expected_gate_indices_list + ), "The qubits used in the gates are not correct" + + @pytest.mark.qpu + def test_qubit_routing(self): + + for i, case in enumerate(self.list_of_cases): + print("Test case {} out of {}:".format(i + 1, len(self.list_of_cases))) + self.__compare_results(case, p=i % 4 + 1) + print("Test passed for case: {}".format(case.values_input())) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_converters.py b/tests/test_converters.py index b7734cd04..909521510 100644 --- a/tests/test_converters.py +++ b/tests/test_converters.py @@ -9,7 +9,7 @@ class TestDocplex2IsingClass(unittest.TestCase): """ Test the converter from docplex models - + """ def test_qubo(self): @@ -80,35 +80,35 @@ def test_slack_penalization(self): self.assertEqual(ising_problem.weights, weights) def test_unbalanced_penalizations(self): - """ - Test the equality and inequality constraints are encoded in the QUBO - model using the unblanaced penalization method. - - """ - weights = [3.85, 0.25, -1.15] - # Creating a basic docplex model - mdl = Model("Test inequal") # Docplex model - num_z = 2 # Number of variables - z = mdl.binary_var_list(num_z, name="Z") # docplex variables - objective = mdl.sum(z) - 2 * z[0] + z[1] * z[0] + 5 # objective function - # Adding constraints - mdl.add_constraint(mdl.sum(z[i] for i in range(num_z)) == 1) - mdl.add_constraint(2 * z[0] + 3 * z[1] >= 1) - mdl.add_constraint(2 * z[1] + z[0] <= 2) - mdl.minimize(objective) # Optimization - - ising_problem = FromDocplex2IsingModel( - mdl, unbalanced_const=True - ).ising_model # Ising model of the Docplex model - - self.assertIsInstance(ising_problem, QUBO) - - for weight_1, weight_2 in zip(ising_problem.weights, weights): - self.assertAlmostEqual(weight_1, weight_2) + """ + Test the equality and inequality constraints are encoded in the QUBO + model using the unblanaced penalization method. + + """ + weights = [3.85, 0.25, -1.15] + # Creating a basic docplex model + mdl = Model("Test inequal") # Docplex model + num_z = 2 # Number of variables + z = mdl.binary_var_list(num_z, name="Z") # docplex variables + objective = mdl.sum(z) - 2 * z[0] + z[1] * z[0] + 5 # objective function + # Adding constraints + mdl.add_constraint(mdl.sum(z[i] for i in range(num_z)) == 1) + mdl.add_constraint(2 * z[0] + 3 * z[1] >= 1) + mdl.add_constraint(2 * z[1] + z[0] <= 2) + mdl.minimize(objective) # Optimization + + ising_problem = FromDocplex2IsingModel( + mdl, unbalanced_const=True + ).ising_model # Ising model of the Docplex model + + self.assertIsInstance(ising_problem, QUBO) + + for weight_1, weight_2 in zip(ising_problem.weights, weights): + self.assertAlmostEqual(weight_1, weight_2) def test_model_maxcut(self): """ - Test the Maxcut application of OpenQAOA gives the same result as the + Test the Maxcut application of OpenQAOA gives the same result as the Docplex translation model. """ diff --git a/tests/test_custom_mixer.py b/tests/test_custom_mixer.py new file mode 100644 index 000000000..7f26fc2f1 --- /dev/null +++ b/tests/test_custom_mixer.py @@ -0,0 +1,335 @@ +import unittest + +import networkx as nx + +from openqaoa.qaoa_components.ansatz_constructor import ( + GateMap, + SWAPGateMap, + RotationGateMap, + RXGateMap, + RZXGateMap, + RXXGateMap, + RYYGateMap, +) +from openqaoa.qaoa_components import QAOADescriptor, create_qaoa_variational_params +from openqaoa.backends import create_device +from openqaoa.optimizers import get_optimizer +from openqaoa.backends.qaoa_backend import get_qaoa_backend +from openqaoa.utilities import ( + quick_create_mixer_for_topology, + X_mixer_hamiltonian, + XY_mixer_hamiltonian, +) +from openqaoa.problems import MinimumVertexCover +from openqaoa.qaoa_components.ansatz_constructor.gatemaplabel import GateMapType + + +class TestingCustomMixer(unittest.TestCase): + def setUp(self): + + nodes = 6 + edge_probability = 0.7 + g = nx.generators.fast_gnp_random_graph(n=nodes, p=edge_probability, seed=34) + mini_cov = MinimumVertexCover(g, field=1.0, penalty=1.0) + self.PROBLEM_QUBO = mini_cov.qubo + + # Case with Mixer with 1 AND 2-qubit terms + self.MANUAL_GATEMAP_LIST, self.MANUAL_COEFFS = [ + RXGateMap(0), + RZXGateMap(0, 1), + RZXGateMap(0, 2), + RZXGateMap(0, 3), + RZXGateMap(0, 4), + RXGateMap(4), + RZXGateMap(0, 5), + RXXGateMap(1, 2), + ], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] + self.MANUAL_SEQUENCE = [0, 0, 1, 2, 3, 1, 4, 5] + + zx_gatemap_list, zx_gatemap_coeffs = quick_create_mixer_for_topology( + RZXGateMap, 6, qubit_connectivity="star" + ) + xx_gatemap_list, xx_gatemap_coeffs = quick_create_mixer_for_topology( + RXXGateMap, 6, qubit_connectivity="full" + ) + + zx_gatemap_list.extend(xx_gatemap_list) + zx_gatemap_coeffs.extend(xx_gatemap_coeffs) + + # Case with Multiple types of 2-qubit gates + self.COMPLICATED_GATEMAP_LIST, self.COMPLICATED_COEFFS = ( + zx_gatemap_list, + zx_gatemap_coeffs, + ) + self.COMPLICATED_SEQUENCE = [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + ] + + self.TESTING_GATEMAPS = [ + [self.MANUAL_GATEMAP_LIST, self.MANUAL_COEFFS, self.MANUAL_SEQUENCE], + [ + self.COMPLICATED_GATEMAP_LIST, + self.COMPLICATED_COEFFS, + self.COMPLICATED_SEQUENCE, + ], + ] + + def test_custom_mixer_basic_workflow(self): + + """ + Check that using custom mixers works. + Custom Mixers are only available in Manual mode. + """ + + for each_gatemap_list, each_gatemap_coeffs, _ in self.TESTING_GATEMAPS: + + custom_mixer_block_gatemap = each_gatemap_list + custom_mixer_block_coeffs = each_gatemap_coeffs + + qaoa_descriptor = QAOADescriptor( + self.PROBLEM_QUBO.hamiltonian, + custom_mixer_block_gatemap, + p=1, + mixer_coeffs=custom_mixer_block_coeffs, + ) + device_local = create_device(location="local", name="qiskit.shot_simulator") + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "rand" + ) + backend_local = get_qaoa_backend(qaoa_descriptor, device_local, n_shots=500) + optimizer = get_optimizer( + backend_local, variate_params, {"method": "cobyla", "maxiter": 10} + ) + optimizer.optimize() + + def test_mixer_block_properties_sequence(self): + + """ + The custom mixers should have sequences that are correct. + The sequence values are based on the position of the gate in the block + relative to other gates of the same qubit count. + """ + + for ( + each_gatemap_list, + each_gatemap_coeffs, + correct_seq, + ) in self.TESTING_GATEMAPS: + + gatemap_list_sequence = [] + one_qubit_count = 0 + two_qubit_count = 0 + + for each_gatemap in each_gatemap_list: + + if each_gatemap.gate_label.n_qubits == 1: + + gatemap_list_sequence.append(one_qubit_count) + one_qubit_count += 1 + + elif each_gatemap.gate_label.n_qubits == 2: + + gatemap_list_sequence.append(two_qubit_count) + two_qubit_count += 1 + + # Test Equality between hand-written and programmatic assignment + self.assertEqual(gatemap_list_sequence, correct_seq) + + qaoa_descriptor = QAOADescriptor( + self.PROBLEM_QUBO.hamiltonian, + each_gatemap_list, + p=1, + mixer_coeffs=each_gatemap_coeffs, + ) + + descriptor_mixer_seq = [ + each_mixer_gatemap.gate_label.sequence + for each_mixer_gatemap in qaoa_descriptor.mixer_block + ] + + # Test Equality between OQ and hand-written sequence + self.assertEqual(descriptor_mixer_seq, correct_seq) + + def test_set_block_sequence(self): + + """ + Check that the set block sequence method is correct. + """ + + for ( + each_gatemap_list, + each_gatemap_coeffs, + correct_seq, + ) in self.TESTING_GATEMAPS: + + output_gatemap_list = QAOADescriptor.set_block_sequence(each_gatemap_list) + output_seq = [ + each_gatemap.gate_label.sequence for each_gatemap in output_gatemap_list + ] + + self.assertEqual(output_seq, correct_seq) + + def test_set_block_sequence_error_raises(self): + + """ + Check that the set block sequence method raises the right error when the + wrong type is passed. A TypeError should be raised if the input_gatemap_list + if not a List of RotationGateMap Objects. + """ + + incorrect_input_iterable = [""], [1], [SWAPGateMap(0, 1)], [RXGateMap] + + for each_iterable in incorrect_input_iterable: + with self.assertRaises(TypeError): + QAOADescriptor.set_block_sequence(each_iterable) + + def test_block_setter(self): + + """ + Check that block_setter method correctly maps the sequence and the type + of the RotationGateMap Objects returned. + """ + + input_enum_type = GateMapType.MIXER + + for ( + each_gatemap_list, + each_gatemap_coeffs, + correct_seq, + ) in self.TESTING_GATEMAPS: + + output_gatemap_list = QAOADescriptor.block_setter( + each_gatemap_list, input_enum_type + ) + + output_type = [ + each_gatemap.gate_label.type for each_gatemap in output_gatemap_list + ] + output_seq = [ + each_gatemap.gate_label.sequence for each_gatemap in output_gatemap_list + ] + + # sequence and type should be labelled correctly. + self.assertEqual(output_seq, correct_seq) + self.assertEqual( + output_type, [input_enum_type for _ in range(len(correct_seq))] + ) + + def test_block_setter_error_raises(self): + + """ + The block_setter method should raise a ValueError if the input_object is + not of the type Hamiltonian or List. It should also raise a TypeError if + the List contains elements that are not of the type RotationGateMap. + """ + + incorrect_input_object = [(), "", 1] + + for each_input in incorrect_input_object: + with self.assertRaises(ValueError): + QAOADescriptor.block_setter( + input_object=each_input, block_type=GateMapType.MIXER + ) + + incorrect_input_iterable = [ + [SWAPGateMap(0, 1)], + [RXGateMap], + [RXGateMap(0), SWAPGateMap(0, 1)], + ] + + for each_input_iterable in incorrect_input_iterable: + with self.assertRaises(TypeError): + QAOADescriptor.block_setter( + input_object=each_input_iterable, block_type=GateMapType.MIXER + ) + + def test_block_setter_equivalence_simple(self): + + """ + A Hamiltonian Object and a list of RotationGateMap should have both their + sequence and type assigned the same if they represent the same gate sequence. + """ + + # 1-Qubit + test_hamiltonian = X_mixer_hamiltonian(3) + test_gatemap_list = [RXGateMap(0), RXGateMap(1), RXGateMap(2)] + + return_gatemap_list_h = QAOADescriptor.block_setter( + input_object=test_hamiltonian, block_type=GateMapType.MIXER + ) + return_gatemap_list_gl = QAOADescriptor.block_setter( + input_object=test_gatemap_list, block_type=GateMapType.MIXER + ) + + # Both gatemap list should be equivalent + self.assertEqual( + [ + each_gatemap.gate_label.sequence + for each_gatemap in return_gatemap_list_h + ], + [ + each_gatemap.gate_label.sequence + for each_gatemap in return_gatemap_list_gl + ], + ) + self.assertEqual( + [each_gatemap.gate_label.type for each_gatemap in return_gatemap_list_h], + [each_gatemap.gate_label.type for each_gatemap in return_gatemap_list_gl], + ) + + # 2-Qubit + test_hamiltonian = XY_mixer_hamiltonian(3) + test_gatemap_list = [ + RXXGateMap(0, 1), + RXXGateMap(0, 2), + RXXGateMap(1, 2), + RYYGateMap(0, 1), + RYYGateMap(0, 2), + RYYGateMap(1, 2), + ] + + return_gatemap_list_h = QAOADescriptor.block_setter( + input_object=test_hamiltonian, block_type=GateMapType.MIXER + ) + return_gatemap_list_gl = QAOADescriptor.block_setter( + input_object=test_gatemap_list, block_type=GateMapType.MIXER + ) + + # Both gatemap list should be equivalent + self.assertEqual( + [ + each_gatemap.gate_label.sequence + for each_gatemap in return_gatemap_list_h + ], + [ + each_gatemap.gate_label.sequence + for each_gatemap in return_gatemap_list_gl + ], + ) + self.assertEqual( + [each_gatemap.gate_label.type for each_gatemap in return_gatemap_list_h], + [each_gatemap.gate_label.type for each_gatemap in return_gatemap_list_gl], + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_derivative.py b/tests/test_derivative.py index 700245d9a..2360eeb62 100644 --- a/tests/test_derivative.py +++ b/tests/test_derivative.py @@ -4,7 +4,11 @@ # OpenQAOA imports from openqaoa.backends import QAOAvectorizedBackendSimulator -from openqaoa.qaoa_components import QAOADescriptor, Hamiltonian, create_qaoa_variational_params +from openqaoa.qaoa_components import ( + QAOADescriptor, + Hamiltonian, + create_qaoa_variational_params, +) from openqaoa.utilities import X_mixer_hamiltonian from openqaoa.optimizers.logger_vqa import Logger from openqaoa.derivatives.derivative_functions import derivative @@ -16,10 +20,10 @@ class TestQAOACostBaseClass(unittest.TestCase): - ''' + """ def test_gradient_agreement(self): "Test agreement between gradients computed from finite difference, parameter shift and SPS (all gates sampled) for weighted and unweighted graphs at several parameters." - + # unweighted graph terms = [[0,1], [0,2], [1,3], [2]] weights = [1, 1, 1, 1] @@ -36,7 +40,7 @@ def test_gradient_agreement(self): qaoa_qaoa_descriptor, 'standard', 'ramp') backend_vectorized = QAOAvectorizedBackendSimulator( qaoa_qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True) - + grad_stepsize = 0.00000001 gradient_ps = backend_vectorized.derivative_function(variational_params_std, 'gradient', 'param_shift') gradient_fd = backend_vectorized.derivative_function(variational_params_std, 'gradient', 'finite_difference', {'stepsize': grad_stepsize}) @@ -49,7 +53,7 @@ def test_gradient_agreement(self): grad_ps = gradient_ps(param) grad_sps = gradient_sps(param) - for i, grad in enumerate(grad_fd): + for i, grad in enumerate(grad_fd): assert np.isclose(grad, grad_ps[i], rtol=1e-05, atol=1e-05) assert np.isclose(grad, grad_sps[i], rtol=1e-05, atol=1e-05) @@ -69,12 +73,12 @@ def test_gradient_agreement(self): qaoa_qaoa_descriptor, 'standard', 'ramp') backend_vectorized = QAOAvectorizedBackendSimulator( qaoa_qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True) - + grad_stepsize = 0.00000001 gradient_ps = backend_vectorized.derivative_function(variational_params_std, 'gradient', 'param_shift') gradient_fd = backend_vectorized.derivative_function(variational_params_std, 'gradient', 'finite_difference', {'stepsize': grad_stepsize}) gradient_sps = backend_vectorized.derivative_function(variational_params_std, 'gradient', 'stoch_param_shift', {'stepsize':grad_stepsize, 'n_beta_single':-1, 'n_beta_pair':-1, 'n_gamma_pair':-1, 'n_gamma_single':-1}) - + params = [[0,0,0,0], [1,1,1,1], [np.pi/2, np.pi/2, np.pi/2, np.pi/2]] for param in params: @@ -82,135 +86,198 @@ def test_gradient_agreement(self): grad_ps = gradient_ps(param) grad_sps = gradient_sps(param) - for i, grad in enumerate(grad_fd): + for i, grad in enumerate(grad_fd): assert np.isclose(grad, grad_ps[i], rtol=1e-05, atol=1e-05) assert np.isclose(grad, grad_sps[i], rtol=1e-05, atol=1e-05) - ''' - + """ + def setUp(self): - - self.log = Logger({'func_evals': - { - 'history_update_bool': False, - 'best_update_string': 'HighestOnly' - }, - 'jac_func_evals': - { - 'history_update_bool': False, - 'best_update_string': 'HighestOnly' - }, - 'n_shots': - { - 'history_update_bool': True, - 'best_update_string': 'Replace' - } - }, - { - 'root_nodes': ['func_evals', 'jac_func_evals', 'n_shots'], - 'best_update_structure': [] - }) - - self.log.log_variables({'func_evals': 0}) - self.log.log_variables({'jac_func_evals': 0}) - - def __backend_params(self, terms:list, weights:list, p:int, nqubits:int): + + self.log = Logger( + { + "func_evals": { + "history_update_bool": False, + "best_update_string": "HighestOnly", + }, + "jac_func_evals": { + "history_update_bool": False, + "best_update_string": "HighestOnly", + }, + "n_shots": { + "history_update_bool": True, + "best_update_string": "Replace", + }, + }, + { + "root_nodes": ["func_evals", "jac_func_evals", "n_shots"], + "best_update_structure": [], + }, + ) + + self.log.log_variables({"func_evals": 0}) + self.log.log_variables({"jac_func_evals": 0}) + + def __backend_params(self, terms: list, weights: list, p: int, nqubits: int): cost_hamiltonian = Hamiltonian.classical_hamiltonian(terms, weights, constant=0) mixer_hamiltonian = X_mixer_hamiltonian(nqubits) qaoa_qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = create_qaoa_variational_params(qaoa_qaoa_descriptor, 'standard', 'ramp') - backend_vectorized = QAOAvectorizedBackendSimulator(qaoa_qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True) + variational_params_std = create_qaoa_variational_params( + qaoa_qaoa_descriptor, "standard", "ramp" + ) + backend_vectorized = QAOAvectorizedBackendSimulator( + qaoa_qaoa_descriptor, + prepend_state=None, + append_state=None, + init_hadamard=True, + ) return backend_vectorized, variational_params_std def test_gradient_computation(self): "Test gradient computation by param. shift, finite difference, and SPS (all gates sampled) on barbell graph." # Analytical cost expression : C(b,g) = -sin(4b)*sin(2g) - backend, params = self.__backend_params(terms=[[0, 1]], weights=[1], p=1, nqubits=2) - - gradients_types_list = ['finite_difference', 'param_shift', 'stoch_param_shift'] - gradients_fun_list = [derivative(backend, params, self.log, 'gradient', type_, {'stepsize': 0.0000001}) for type_ in gradients_types_list] + backend, params = self.__backend_params( + terms=[[0, 1]], weights=[1], p=1, nqubits=2 + ) - test_points = [[0, 0], [np.pi/2, np.pi/3], [1, 2]] + gradients_types_list = ["finite_difference", "param_shift", "stoch_param_shift"] + gradients_fun_list = [ + derivative( + backend, params, self.log, "gradient", type_, {"stepsize": 0.0000001} + ) + for type_ in gradients_types_list + ] + + test_points = [[0, 0], [np.pi / 2, np.pi / 3], [1, 2]] for point in test_points: beta, gamma = point - dCdb, dCdg = -4*np.cos(4*beta)*np.sin(2*gamma), -2*np.sin(4*beta)*np.cos(2*gamma) + dCdb, dCdg = -4 * np.cos(4 * beta) * np.sin(2 * gamma), -2 * np.sin( + 4 * beta + ) * np.cos(2 * gamma) - for gradient_fun, gradient_name in zip(gradients_fun_list, gradients_types_list): + for gradient_fun, gradient_name in zip( + gradients_fun_list, gradients_types_list + ): dCdb_, dCdg_ = gradient_fun(point) - assert np.isclose(dCdb, dCdb_, rtol=1e-05, atol=1e-05), f'Gradient computation failed for {gradient_name} on barbell graph. dCdb: {dCdb}, dCdb_: {dCdb_}' - assert np.isclose(dCdg, dCdg_, rtol=1e-05, atol=1e-05), f'Gradient computation failed for {gradient_name} on barbell graph. dCdg: {dCdg}, dCdg_: {dCdg_}' + assert np.isclose( + dCdb, dCdb_, rtol=1e-05, atol=1e-05 + ), f"Gradient computation failed for {gradient_name} on barbell graph. dCdb: {dCdb}, dCdb_: {dCdb_}" + assert np.isclose( + dCdg, dCdg_, rtol=1e-05, atol=1e-05 + ), f"Gradient computation failed for {gradient_name} on barbell graph. dCdg: {dCdg}, dCdg_: {dCdg_}" def test_gradient_w_variance_computation(self): "Test gradient computation by param. shift, finite difference, and SPS (all gates sampled) on barbell graph." # Analytical cost expression : C(b,g) = -sin(4b)*sin(2g) - backend, params = self.__backend_params(terms=[[0, 1]], weights=[1], p=1, nqubits=2) - - gradients_types_list = ['finite_difference', 'param_shift', 'stoch_param_shift'] - gradients_fun_list = [derivative(backend, params, self.log, 'gradient_w_variance', type_, {'stepsize': 0.0000001}) for type_ in gradients_types_list] + backend, params = self.__backend_params( + terms=[[0, 1]], weights=[1], p=1, nqubits=2 + ) + + gradients_types_list = ["finite_difference", "param_shift", "stoch_param_shift"] + gradients_fun_list = [ + derivative( + backend, + params, + self.log, + "gradient_w_variance", + type_, + {"stepsize": 0.0000001}, + ) + for type_ in gradients_types_list + ] + + test_points = [[0, 0], [np.pi / 2, np.pi / 3], [1, 2]] - test_points = [[0, 0], [np.pi/2, np.pi/3], [1, 2]] - - for point in test_points: + for point in test_points: - for gradient_fun, gradient_name in zip(gradients_fun_list, gradients_types_list): + for gradient_fun, gradient_name in zip( + gradients_fun_list, gradients_types_list + ): - #compute gradient for each point with number of shots 1000 for ech function evaluation + # compute gradient for each point with number of shots 1000 for ech function evaluation grad, var, n_shots = gradient_fun(point, n_shots=1000) - #check if there is a gradient and variance (we can't check the value of the gradient and variance because it is randomly computed, since n_shots is 1000) - for g in grad: assert np.abs(g)>=0, f'Gradient computation failed for {gradient_name} on barbell graph. grad: {grad}' - for v in var: assert v>0, f'Error computing the variance of the gradient for {gradient_name} on barbell graph.' - - #check if the number of shots is correct - x = 4 if gradient_name == 'finite_difference' else 6 #that is also checking that SPS samples all gates when (n_beta, n_gamma_pair, n_gamma_single) is (-1, -1, -1) - assert n_shots == x*1000, f'The number of shots should be {x*1000} but is {n_shots}.' + # check if there is a gradient and variance (we can't check the value of the gradient and variance because it is randomly computed, since n_shots is 1000) + for g in grad: + assert ( + np.abs(g) >= 0 + ), f"Gradient computation failed for {gradient_name} on barbell graph. grad: {grad}" + for v in var: + assert ( + v > 0 + ), f"Error computing the variance of the gradient for {gradient_name} on barbell graph." + + # check if the number of shots is correct + x = ( + 4 if gradient_name == "finite_difference" else 6 + ) # that is also checking that SPS samples all gates when (n_beta, n_gamma_pair, n_gamma_single) is (-1, -1, -1) + assert ( + n_shots == x * 1000 + ), f"The number of shots should be {x*1000} but is {n_shots}." def test_SPS_sampling(self): "Test that SPS samples the number of gates specified by the user." - backend, params = self.__backend_params(terms=[[0, 1]], weights=[1], p=1, nqubits=2) - gradient_fun = derivative( backend, params, self.log, 'gradient_w_variance', - 'stoch_param_shift', {'stepsize':0.1, 'n_beta_single':1, 'n_beta_pair':0, 'n_gamma_pair':1, 'n_gamma_single':0}) - - n_shots = gradient_fun([0,0], n_shots=1000)[2] - #check if the number of shots is correct, we know that we are sampling 2 gates (1 beta and 1 gamma) -> 2*2*1000 (the second 2* comes from two evaluations for each gradient) - assert n_shots == 4000, f'The number of shots should be {4000} but is {n_shots}.' + backend, params = self.__backend_params( + terms=[[0, 1]], weights=[1], p=1, nqubits=2 + ) + gradient_fun = derivative( + backend, + params, + self.log, + "gradient_w_variance", + "stoch_param_shift", + { + "stepsize": 0.1, + "n_beta_single": 1, + "n_beta_pair": 0, + "n_gamma_pair": 1, + "n_gamma_single": 0, + }, + ) + + n_shots = gradient_fun([0, 0], n_shots=1000)[2] + # check if the number of shots is correct, we know that we are sampling 2 gates (1 beta and 1 gamma) -> 2*2*1000 (the second 2* comes from two evaluations for each gradient) + assert ( + n_shots == 4000 + ), f"The number of shots should be {4000} but is {n_shots}." - def test_hessian_computation(self): "Test Hessian computation by finite difference on barbell graph" # Analytical cost expression : C(b,g) = -sin(4b)*sin(2g) - backend, params = self.__backend_params(terms=[[0, 1]], weights=[1], p=1, nqubits=2) + backend, params = self.__backend_params( + terms=[[0, 1]], weights=[1], p=1, nqubits=2 + ) - hessian_fd = derivative(backend, params, - self.log,'hessian', 'finite_difference', - {'stepsize': 0.001}) + hessian_fd = derivative( + backend, + params, + self.log, + "hessian", + "finite_difference", + {"stepsize": 0.001}, + ) - test_points = np.round([[0, 0], [np.pi/2, np.pi/3], [1, 2]], 12) + test_points = np.round([[0, 0], [np.pi / 2, np.pi / 3], [1, 2]], 12) for point in test_points: beta, gamma = point[0], point[1] - dCdbb = 16*np.sin(4*beta)*np.sin(2*gamma) - dCdbg = -8*np.cos(4*beta)*np.cos(2*gamma) + dCdbb = 16 * np.sin(4 * beta) * np.sin(2 * gamma) + dCdbg = -8 * np.cos(4 * beta) * np.cos(2 * gamma) dCdgb = dCdbg - dCdgg = 4*np.sin(4*beta)*np.sin(2*gamma) - - assert np.isclose(dCdbb, hessian_fd( - point)[0][0], rtol=1e-05, atol=1e-05) - assert np.isclose(dCdbg, hessian_fd( - point)[0][1], rtol=1e-05, atol=1e-05) - assert np.isclose(dCdgb, hessian_fd( - point)[1][0], rtol=1e-05, atol=1e-05) - assert np.isclose(dCdgg, hessian_fd( - point)[1][1], rtol=1e-05, atol=1e-05) + dCdgg = 4 * np.sin(4 * beta) * np.sin(2 * gamma) + assert np.isclose(dCdbb, hessian_fd(point)[0][0], rtol=1e-05, atol=1e-05) + assert np.isclose(dCdbg, hessian_fd(point)[0][1], rtol=1e-05, atol=1e-05) + assert np.isclose(dCdgb, hessian_fd(point)[1][0], rtol=1e-05, atol=1e-05) + assert np.isclose(dCdgg, hessian_fd(point)[1][1], rtol=1e-05, atol=1e-05) if __name__ == "__main__": with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=PendingDeprecationWarning) + warnings.simplefilter("ignore", category=PendingDeprecationWarning) unittest.main() diff --git a/tests/test_gates.py b/tests/test_gates.py index 226c11472..caff86615 100644 --- a/tests/test_gates.py +++ b/tests/test_gates.py @@ -14,323 +14,418 @@ from braket.circuits import Circuit from braket.circuits.free_parameter import FreeParameter -from openqaoa.qaoa_components.ansatz_constructor.gates import (RY, RX, RZ, CZ, CX, - RXX, RYY, RZZ, RZX, - CPHASE, RiSWAP) +from openqaoa.qaoa_components.ansatz_constructor.gates import ( + RY, + RX, + RZ, + CZ, + CX, + RXX, + RYY, + RZZ, + RZX, + CPHASE, + RiSWAP, +) from openqaoa.qaoa_components.ansatz_constructor.rotationangle import RotationAngle + class TestingGate(unittest.TestCase): - def test_braket_gates_1q(self): - + # One Qubit Gate Tests - rotation_angle_obj = RotationAngle(lambda x: x, [], FreeParameter('test_angle')) - + rotation_angle_obj = RotationAngle(lambda x: x, [], FreeParameter("test_angle")) + empty_circuit = Circuit() llgate = RY() - output_circuit = llgate.apply_braket_gate(0,rotation_angle_obj,empty_circuit) - output_circuit = output_circuit.make_bound_circuit({'test_angle': np.pi}) - + output_circuit = llgate.apply_braket_gate(0, rotation_angle_obj, empty_circuit) + output_circuit = output_circuit.make_bound_circuit({"test_angle": np.pi}) + test_circuit = Circuit() - test_circuit += braketgates.Ry.ry(0,np.pi) - + test_circuit += braketgates.Ry.ry(0, np.pi) + self.assertEqual(test_circuit, output_circuit) - + empty_circuit = Circuit() llgate = RX() - output_circuit = llgate.apply_braket_gate(0,rotation_angle_obj,empty_circuit) - output_circuit = output_circuit.make_bound_circuit({'test_angle': np.pi}) - + output_circuit = llgate.apply_braket_gate(0, rotation_angle_obj, empty_circuit) + output_circuit = output_circuit.make_bound_circuit({"test_angle": np.pi}) + test_circuit = Circuit() - test_circuit += braketgates.Rx.rx(0,np.pi) - + test_circuit += braketgates.Rx.rx(0, np.pi) + self.assertEqual(test_circuit, output_circuit) - + empty_circuit = Circuit() llgate = RZ() - output_circuit = llgate.apply_braket_gate(0,rotation_angle_obj,empty_circuit) - output_circuit = output_circuit.make_bound_circuit({'test_angle': np.pi}) - + output_circuit = llgate.apply_braket_gate(0, rotation_angle_obj, empty_circuit) + output_circuit = output_circuit.make_bound_circuit({"test_angle": np.pi}) + test_circuit = Circuit() - test_circuit += braketgates.Rz.rz(0,np.pi) - + test_circuit += braketgates.Rz.rz(0, np.pi) + self.assertEqual(test_circuit, output_circuit) - + def test_braket_gates_2q(self): - + # Two Qubit Gate Tests empty_circuit = Circuit() llgate = CZ() - output_circuit = llgate.apply_braket_gate([0, 1],empty_circuit) + output_circuit = llgate.apply_braket_gate([0, 1], empty_circuit) test_circuit = Circuit() test_circuit += braketgates.CZ.cz(0, 1) - + self.assertEqual(test_circuit, output_circuit) - + empty_circuit = Circuit() - llgate = CX(mode='CX') - output_circuit = llgate.apply_braket_gate([0, 1],empty_circuit) + llgate = CX(mode="CX") + output_circuit = llgate.apply_braket_gate([0, 1], empty_circuit) test_circuit = Circuit() test_circuit += braketgates.CNot.cnot(0, 1) - + self.assertEqual(test_circuit, output_circuit) - + def test_braket_gates_2q_w_gates(self): - + # Two Qubit Gate with Angles Tests - rotation_angle_obj = RotationAngle(lambda x: x, [], FreeParameter('test_angle')) - + rotation_angle_obj = RotationAngle(lambda x: x, [], FreeParameter("test_angle")) + empty_circuit = Circuit() llgate = RXX() - output_circuit = llgate.apply_braket_gate([0, 1], rotation_angle_obj, empty_circuit) - output_circuit = output_circuit.make_bound_circuit({'test_angle': np.pi}) - + output_circuit = llgate.apply_braket_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) + output_circuit = output_circuit.make_bound_circuit({"test_angle": np.pi}) + test_circuit = Circuit() test_circuit += braketgates.XX.xx(0, 1, np.pi) - + self.assertEqual(test_circuit, output_circuit) - + empty_circuit = Circuit() llgate = RYY() - output_circuit = llgate.apply_braket_gate([0, 1], rotation_angle_obj, empty_circuit) - output_circuit = output_circuit.make_bound_circuit({'test_angle': np.pi}) - + output_circuit = llgate.apply_braket_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) + output_circuit = output_circuit.make_bound_circuit({"test_angle": np.pi}) + test_circuit = Circuit() test_circuit += braketgates.YY.yy(0, 1, np.pi) - + self.assertEqual(test_circuit, output_circuit) - + empty_circuit = Circuit() llgate = RZZ() - output_circuit = llgate.apply_braket_gate([0, 1], rotation_angle_obj, empty_circuit) - output_circuit = output_circuit.make_bound_circuit({'test_angle': np.pi}) - + output_circuit = llgate.apply_braket_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) + output_circuit = output_circuit.make_bound_circuit({"test_angle": np.pi}) + test_circuit = Circuit() test_circuit += braketgates.ZZ.zz(0, 1, np.pi) - + self.assertEqual(test_circuit, output_circuit) - + empty_circuit = Circuit() llgate = CPHASE() - output_circuit = llgate.apply_braket_gate([0, 1], rotation_angle_obj, empty_circuit) - output_circuit = output_circuit.make_bound_circuit({'test_angle': np.pi}) - + output_circuit = llgate.apply_braket_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) + output_circuit = output_circuit.make_bound_circuit({"test_angle": np.pi}) + test_circuit = Circuit() test_circuit += braketgates.CPhaseShift.cphaseshift(0, 1, np.pi) - + self.assertEqual(test_circuit, output_circuit) - + empty_circuit = Circuit() llgate = RiSWAP() - output_circuit = llgate.apply_braket_gate([0, 1], rotation_angle_obj, empty_circuit) - output_circuit = output_circuit.make_bound_circuit({'test_angle': np.pi}) - + output_circuit = llgate.apply_braket_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) + output_circuit = output_circuit.make_bound_circuit({"test_angle": np.pi}) + test_circuit = Circuit() test_circuit += braketgates.XY.xy(0, 1, np.pi) - + self.assertEqual(test_circuit, output_circuit) - + def test_ibm_gates_1q(self): - + # One Qubit Gate Tests rotation_angle_obj = RotationAngle(lambda x: x, [], np.pi) - + empty_circuit = QuantumCircuit(1) llgate = RY() - output_circuit = llgate.apply_ibm_gate(0,rotation_angle_obj,empty_circuit) + output_circuit = llgate.apply_ibm_gate(0, rotation_angle_obj, empty_circuit) test_circuit = QuantumCircuit(1) test_circuit.ry(np.pi, 0) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + empty_circuit = QuantumCircuit(1) llgate = RX() - output_circuit = llgate.apply_ibm_gate(0,rotation_angle_obj,empty_circuit) + output_circuit = llgate.apply_ibm_gate(0, rotation_angle_obj, empty_circuit) test_circuit = QuantumCircuit(1) test_circuit.rx(np.pi, 0) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + empty_circuit = QuantumCircuit(1) llgate = RZ() output_circuit = llgate.apply_ibm_gate(0, rotation_angle_obj, empty_circuit) test_circuit = QuantumCircuit(1) test_circuit.rz(np.pi, 0) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + def test_ibm_gates_2q(self): - + # Two Qubit Gate Tests empty_circuit = QuantumCircuit(2) llgate = CZ() - output_circuit = llgate.apply_ibm_gate([0, 1],empty_circuit) + output_circuit = llgate.apply_ibm_gate([0, 1], empty_circuit) test_circuit = QuantumCircuit(2) test_circuit.cz(0, 1) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + empty_circuit = QuantumCircuit(2) - llgate = CX(mode='CX') - output_circuit = llgate.apply_ibm_gate([0, 1],empty_circuit) + llgate = CX(mode="CX") + output_circuit = llgate.apply_ibm_gate([0, 1], empty_circuit) test_circuit = QuantumCircuit(2) test_circuit.cx(0, 1) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + empty_circuit = QuantumCircuit(2) - llgate = CX(mode='CZ') + llgate = CX(mode="CZ") output_circuit = llgate.apply_ibm_gate([0, 1], empty_circuit) test_circuit = QuantumCircuit(2) - test_circuit.ry(np.pi/2, 1) + test_circuit.ry(np.pi / 2, 1) test_circuit.rx(np.pi, 1) test_circuit.cz(0, 1) - test_circuit.ry(np.pi/2, 1) + test_circuit.ry(np.pi / 2, 1) test_circuit.rx(np.pi, 1) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + def test_ibm_gates_2q_w_gates(self): - + # Two Qubit Gate with Angles Tests rotation_angle_obj = RotationAngle(lambda x: x, [], np.pi) - + empty_circuit = QuantumCircuit(2) llgate = RXX() - output_circuit = llgate.apply_ibm_gate([0, 1], rotation_angle_obj, empty_circuit) + output_circuit = llgate.apply_ibm_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) test_circuit = QuantumCircuit(2) test_circuit.rxx(np.pi, 0, 1) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + empty_circuit = QuantumCircuit(2) llgate = RYY() - output_circuit = llgate.apply_ibm_gate([0, 1], rotation_angle_obj, empty_circuit) + output_circuit = llgate.apply_ibm_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) test_circuit = QuantumCircuit(2) test_circuit.ryy(np.pi, 0, 1) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + empty_circuit = QuantumCircuit(2) llgate = RZZ() - output_circuit = llgate.apply_ibm_gate([0, 1], rotation_angle_obj, empty_circuit) + output_circuit = llgate.apply_ibm_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) test_circuit = QuantumCircuit(2) test_circuit.rzz(np.pi, 0, 1) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + empty_circuit = QuantumCircuit(2) llgate = RZX() - output_circuit = llgate.apply_ibm_gate([0, 1], rotation_angle_obj, empty_circuit) + output_circuit = llgate.apply_ibm_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) test_circuit = QuantumCircuit(2) test_circuit.rzx(np.pi, 0, 1) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + empty_circuit = QuantumCircuit(2) llgate = CPHASE() - output_circuit = llgate.apply_ibm_gate([0, 1], rotation_angle_obj, empty_circuit) + output_circuit = llgate.apply_ibm_gate( + [0, 1], rotation_angle_obj, empty_circuit + ) test_circuit = QuantumCircuit(2) test_circuit.crz(np.pi, 0, 1) - - self.assertEqual(test_circuit.to_instruction().definition, output_circuit.to_instruction().definition) - + + self.assertEqual( + test_circuit.to_instruction().definition, + output_circuit.to_instruction().definition, + ) + def test_pyquil_gates_1q(self): - + # One Qubit Gate Tests rotation_angle_obj = RotationAngle(lambda x: x, [], np.pi) - + empty_program = Program() llgate = RY() - output_program = llgate.apply_pyquil_gate(0,rotation_angle_obj,empty_program) + output_program = llgate.apply_pyquil_gate(0, rotation_angle_obj, empty_program) test_program = Program().inst(p_RY(np.pi, 0)) - - output_gate_names = [instr.name for instr in output_program if type(instr) == quilbase.Gate] - test_gate_names = [instr.name for instr in test_program if type(instr) == quilbase.Gate] + + output_gate_names = [ + instr.name for instr in output_program if type(instr) == quilbase.Gate + ] + test_gate_names = [ + instr.name for instr in test_program if type(instr) == quilbase.Gate + ] self.assertEqual(output_gate_names, test_gate_names) - + empty_program = Program() llgate = RX() - output_program = llgate.apply_pyquil_gate(0,rotation_angle_obj,empty_program) + output_program = llgate.apply_pyquil_gate(0, rotation_angle_obj, empty_program) test_program = Program().inst(p_RX(np.pi, 0)) - - output_gate_names = [instr.name for instr in output_program if type(instr) == quilbase.Gate] - test_gate_names = [instr.name for instr in test_program if type(instr) == quilbase.Gate] + + output_gate_names = [ + instr.name for instr in output_program if type(instr) == quilbase.Gate + ] + test_gate_names = [ + instr.name for instr in test_program if type(instr) == quilbase.Gate + ] self.assertEqual(output_gate_names, test_gate_names) - + empty_program = Program() llgate = RZ() - output_program = llgate.apply_pyquil_gate(0,rotation_angle_obj,empty_program) - + output_program = llgate.apply_pyquil_gate(0, rotation_angle_obj, empty_program) + test_program = Program().inst(p_RZ(np.pi, 0)) - - output_gate_names = [instr.name for instr in output_program if type(instr) == quilbase.Gate] - test_gate_names = [instr.name for instr in test_program if type(instr) == quilbase.Gate] + + output_gate_names = [ + instr.name for instr in output_program if type(instr) == quilbase.Gate + ] + test_gate_names = [ + instr.name for instr in test_program if type(instr) == quilbase.Gate + ] self.assertEqual(output_gate_names, test_gate_names) - + def test_pyquil_gates_2q(self): - + # Two Qubit Gate Tests empty_program = Program() llgate = CZ() - output_program = llgate.apply_pyquil_gate([0, 1],empty_program) + output_program = llgate.apply_pyquil_gate([0, 1], empty_program) test_program = Program().inst(p_CZ(0, 1)) - - output_gate_names = [instr.name for instr in output_program if type(instr) == quilbase.Gate] - test_gate_names = [instr.name for instr in test_program if type(instr) == quilbase.Gate] + + output_gate_names = [ + instr.name for instr in output_program if type(instr) == quilbase.Gate + ] + test_gate_names = [ + instr.name for instr in test_program if type(instr) == quilbase.Gate + ] self.assertEqual(output_gate_names, test_gate_names) - + empty_program = Program() llgate = CX() output_program = llgate.apply_pyquil_gate([0, 1], empty_program) test_program = Program().inst(p_CX(0, 1)) - - output_gate_names = [instr.name for instr in output_program if type(instr) == quilbase.Gate] - test_gate_names = [instr.name for instr in test_program if type(instr) == quilbase.Gate] + + output_gate_names = [ + instr.name for instr in output_program if type(instr) == quilbase.Gate + ] + test_gate_names = [ + instr.name for instr in test_program if type(instr) == quilbase.Gate + ] self.assertEqual(output_gate_names, test_gate_names) - + def test_pyquil_gates_2q_w_gates(self): - + # Two Qubit Gate with Angles Tests rotation_angle_obj = RotationAngle(lambda x: x, [], np.pi) - + empty_program = Program() llgate = CPHASE() - output_program = llgate.apply_pyquil_gate([0, 1], rotation_angle_obj, empty_program) + output_program = llgate.apply_pyquil_gate( + [0, 1], rotation_angle_obj, empty_program + ) test_program = Program().inst(p_CPHASE(np.pi, 0, 1)) - - output_gate_names = [instr.name for instr in output_program if type(instr) == quilbase.Gate] - test_gate_names = [instr.name for instr in test_program if type(instr) == quilbase.Gate] + + output_gate_names = [ + instr.name for instr in output_program if type(instr) == quilbase.Gate + ] + test_gate_names = [ + instr.name for instr in test_program if type(instr) == quilbase.Gate + ] self.assertEqual(output_gate_names, test_gate_names) - + empty_program = Program() llgate = RiSWAP() - output_program = llgate.apply_pyquil_gate([0, 1], rotation_angle_obj, empty_program) + output_program = llgate.apply_pyquil_gate( + [0, 1], rotation_angle_obj, empty_program + ) test_program = Program().inst(p_XY(np.pi, 0, 1)) - - output_gate_names = [instr.name for instr in output_program if type(instr) == quilbase.Gate] - test_gate_names = [instr.name for instr in test_program if type(instr) == quilbase.Gate] + + output_gate_names = [ + instr.name for instr in output_program if type(instr) == quilbase.Gate + ] + test_gate_names = [ + instr.name for instr in test_program if type(instr) == quilbase.Gate + ] self.assertEqual(output_gate_names, test_gate_names) - -if __name__ == '__main__': + +if __name__ == "__main__": unittest.main() diff --git a/tests/test_imports.py b/tests/test_imports.py index 93790dc63..af62ea0bb 100644 --- a/tests/test_imports.py +++ b/tests/test_imports.py @@ -3,6 +3,7 @@ from setuptools import find_namespace_packages + class TestImports(unittest.TestCase): """ @@ -13,15 +14,31 @@ def test_all_module_import(self): """ Test all the main module imports for OQ """ - - package_names = ['openqaoa', 'openqaoa_braket', 'openqaoa_qiskit', 'openqaoa_pyquil', 'openqaoa_azure'] - folder_names = ['openqaoa-core', 'openqaoa-braket', 'openqaoa-qiskit', 'openqaoa-pyquil', 'openqaoa-azure'] + + package_names = [ + "openqaoa", + "openqaoa_braket", + "openqaoa_qiskit", + "openqaoa_pyquil", + "openqaoa_azure", + ] + folder_names = [ + "openqaoa-core", + "openqaoa-braket", + "openqaoa-qiskit", + "openqaoa-pyquil", + "openqaoa-azure", + ] packages_import = find_namespace_packages(where="./src") updated_packages = [] for each_package_name in packages_import: for _index, each_folder_name in enumerate(folder_names): if each_folder_name in each_package_name: - updated_packages.append(each_package_name.replace(each_folder_name, package_names[_index])) + updated_packages.append( + each_package_name.replace( + each_folder_name, package_names[_index] + ) + ) continue for each_package in updated_packages: diff --git a/tests/test_logger.py b/tests/test_logger.py index ad6d41e3a..161e7c441 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -1,177 +1,210 @@ import unittest from openqaoa.optimizers.logger_vqa import ( - Logger, LoggerVariable, LoggerVariableFactory, - EmptyValue, AppendValue, ReplaceValue, - IfLowerDo, IfHigherDo + Logger, + LoggerVariable, + LoggerVariableFactory, + EmptyValue, + AppendValue, + ReplaceValue, + IfLowerDo, + IfHigherDo, ) + class TestingLoggerClass(unittest.TestCase): - def test_logger_var_setting_1(self): - - test_var = LoggerVariable('test_var', EmptyValue, EmptyValue) - + + test_var = LoggerVariable("test_var", EmptyValue, EmptyValue) + test_var.update(10) - + self.assertEqual(test_var.history, []) self.assertEqual(test_var.best, []) - + def test_logger_var_setting_2(self): - - test_var = LoggerVariable('test_var', AppendValue, AppendValue) - + + test_var = LoggerVariable("test_var", AppendValue, AppendValue) + test_var.update(5) test_var.update(10) - + self.assertEqual(test_var.history, [5, 10]) self.assertEqual(test_var.best, [5, 10]) - + def test_logger_var_setting_3(self): - - test_var = LoggerVariable('test_var', ReplaceValue, ReplaceValue) - + + test_var = LoggerVariable("test_var", ReplaceValue, ReplaceValue) + test_var.update(5) test_var.update(10) - + self.assertEqual(test_var.history, [10]) self.assertEqual(test_var.best, [10]) - + def test_logger_var_setting_4(self): - - test_var = LoggerVariable('test_var', IfLowerDo(EmptyValue), IfLowerDo(EmptyValue)) - - test_var.update(5) # First value gets appended regardless + + test_var = LoggerVariable( + "test_var", IfLowerDo(EmptyValue), IfLowerDo(EmptyValue) + ) + + test_var.update(5) # First value gets appended regardless test_var.update(10) - + self.assertEqual(test_var.history, [5]) self.assertEqual(test_var.best, [5]) - + test_var.update(1) - + self.assertEqual(test_var.history, []) self.assertEqual(test_var.best, []) - + def test_logger_var_setting_5(self): - - test_var = LoggerVariable('test_var', IfLowerDo(AppendValue), IfLowerDo(AppendValue)) - - test_var.update(5) # First value gets appended regardless + + test_var = LoggerVariable( + "test_var", IfLowerDo(AppendValue), IfLowerDo(AppendValue) + ) + + test_var.update(5) # First value gets appended regardless test_var.update(10) - + self.assertEqual(test_var.history, [5]) self.assertEqual(test_var.best, [5]) - + test_var.update(1) - + self.assertEqual(test_var.history, [5, 1]) self.assertEqual(test_var.best, [5, 1]) - + def test_logger_var_setting_6(self): - - test_var = LoggerVariable('test_var', IfLowerDo(ReplaceValue), IfLowerDo(ReplaceValue)) - - test_var.update(5) # First value gets appended regardless + + test_var = LoggerVariable( + "test_var", IfLowerDo(ReplaceValue), IfLowerDo(ReplaceValue) + ) + + test_var.update(5) # First value gets appended regardless test_var.update(10) - + self.assertEqual(test_var.history, [5]) self.assertEqual(test_var.best, [5]) - + test_var.update(1) - + self.assertEqual(test_var.history, [1]) self.assertEqual(test_var.best, [1]) - + def test_logger_var_setting_7(self): - - test_var = LoggerVariable('test_var', IfHigherDo(EmptyValue), IfHigherDo(EmptyValue)) - - test_var.update(5) # First value gets appended regardless + + test_var = LoggerVariable( + "test_var", IfHigherDo(EmptyValue), IfHigherDo(EmptyValue) + ) + + test_var.update(5) # First value gets appended regardless test_var.update(1) - + self.assertEqual(test_var.history, [5]) self.assertEqual(test_var.best, [5]) - + test_var.update(10) - + self.assertEqual(test_var.history, []) self.assertEqual(test_var.best, []) - + def test_logger_var_setting_8(self): - - test_var = LoggerVariable('test_var', IfHigherDo(AppendValue), IfHigherDo(AppendValue)) - - test_var.update(5) # First value gets appended regardless + + test_var = LoggerVariable( + "test_var", IfHigherDo(AppendValue), IfHigherDo(AppendValue) + ) + + test_var.update(5) # First value gets appended regardless test_var.update(1) - + self.assertEqual(test_var.history, [5]) self.assertEqual(test_var.best, [5]) - + test_var.update(10) - + self.assertEqual(test_var.history, [5, 10]) self.assertEqual(test_var.best, [5, 10]) - + def test_logger_var_setting_9(self): - - test_var = LoggerVariable('test_var', IfHigherDo(ReplaceValue), IfHigherDo(ReplaceValue)) - - test_var.update(5) # First value gets appended regardless + + test_var = LoggerVariable( + "test_var", IfHigherDo(ReplaceValue), IfHigherDo(ReplaceValue) + ) + + test_var.update(5) # First value gets appended regardless test_var.update(1) - + self.assertEqual(test_var.history, [5]) self.assertEqual(test_var.best, [5]) - + test_var.update(10) - + self.assertEqual(test_var.history, [10]) self.assertEqual(test_var.best, [10]) - + def test_logger_var_methods(self): - - test_var = LoggerVariable('test_var', ReplaceValue, ReplaceValue) - test_var_2 = LoggerVariable('test_var', ReplaceValue, ReplaceValue) - + + test_var = LoggerVariable("test_var", ReplaceValue, ReplaceValue) + test_var_2 = LoggerVariable("test_var", ReplaceValue, ReplaceValue) + test_var.update(1) - + test_var_2.update_history(1) test_var_2.update_best(1) - + self.assertEqual(test_var.history, test_var_2.history) self.assertEqual(test_var.best, test_var_2.best) - + def test_logger_var_fact_hist_bool(self): - - var_1 = LoggerVariableFactory.create_logger_variable('new_attribute', True, 'Replace') - var_2 = LoggerVariableFactory.create_logger_variable('new_attribute', False, 'Replace') - + + var_1 = LoggerVariableFactory.create_logger_variable( + "new_attribute", True, "Replace" + ) + var_2 = LoggerVariableFactory.create_logger_variable( + "new_attribute", False, "Replace" + ) + var_1.update(1) var_2.update(1) - + var_1.update(2) var_2.update(2) - - self.assertEqual(var_1.name, 'new_attribute') - self.assertEqual(var_2.name, 'new_attribute') + + self.assertEqual(var_1.name, "new_attribute") + self.assertEqual(var_2.name, "new_attribute") self.assertEqual(var_1.history, [1, 2]) self.assertEqual(var_2.history, []) - + def test_logger_var_fact_best_str(self): - + """ Testing all possible settings of a variable created through the Factory Class """ - - var_1 = LoggerVariableFactory.create_logger_variable('new_attribute', True, 'Append') - var_2 = LoggerVariableFactory.create_logger_variable('new_attribute', True, 'Replace') - var_3 = LoggerVariableFactory.create_logger_variable('new_attribute', True, 'LowestSoFar') - var_4 = LoggerVariableFactory.create_logger_variable('new_attribute', True, 'LowestOnly') - var_5 = LoggerVariableFactory.create_logger_variable('new_attribute', True, 'HighestSoFar') - var_6 = LoggerVariableFactory.create_logger_variable('new_attribute', True, 'HighestOnly') - + + var_1 = LoggerVariableFactory.create_logger_variable( + "new_attribute", True, "Append" + ) + var_2 = LoggerVariableFactory.create_logger_variable( + "new_attribute", True, "Replace" + ) + var_3 = LoggerVariableFactory.create_logger_variable( + "new_attribute", True, "LowestSoFar" + ) + var_4 = LoggerVariableFactory.create_logger_variable( + "new_attribute", True, "LowestOnly" + ) + var_5 = LoggerVariableFactory.create_logger_variable( + "new_attribute", True, "HighestSoFar" + ) + var_6 = LoggerVariableFactory.create_logger_variable( + "new_attribute", True, "HighestOnly" + ) + values_list = [5, 7, 10, 1] - + for each_value in values_list: var_1.update(each_value) var_2.update(each_value) @@ -179,253 +212,256 @@ def test_logger_var_fact_best_str(self): var_4.update(each_value) var_5.update(each_value) var_6.update(each_value) - + self.assertEqual(var_1.best, [5, 7, 10, 1]) self.assertEqual(var_2.best, [1]) self.assertEqual(var_3.best, [5, 1]) self.assertEqual(var_4.best, [1]) self.assertEqual(var_5.best, [5, 7, 10]) self.assertEqual(var_6.best, [10]) - + def test_logger_obj_update_struct_1(self): - + """ The best update structure ensures that the best value for that particular attribute respects a relation with another attribute. - + In the code below, the following can be observed: Even though the lowest in attribute 2 is 10. The best of attribute 2 is 15 instead. This is because the best value of attribute 2 depends on whether attribute 1 for that set of update values is the highest. If it is not the highest value, attribute 2's best value is not updated. This way updating - the best value of attribute 2 respects the update on the best value of + the best value of attribute 2 respects the update on the best value of attribute 1. - + Histories are always updated Indepedent of the best update structure provided. """ - - logger_obj = Logger({'attribute_1': - { - 'history_update_bool': True, - 'best_update_string': 'HighestOnly' - }, - 'attribute_2': - { - 'history_update_bool': True, - 'best_update_string': 'LowestSoFar' - }, - 'attribute_3': - { - 'history_update_bool': False, - 'best_update_string': 'Replace' - } - }, - { - 'root_nodes': ['attribute_1'], - 'best_update_structure': - (['attribute_1', 'attribute_2'], - ['attribute_1', 'attribute_3']) - }) - - logger_obj.log_variables({'attribute_1': 10, - 'attribute_2': 3, - 'attribute_3': 'string 1'}) - + + logger_obj = Logger( + { + "attribute_1": { + "history_update_bool": True, + "best_update_string": "HighestOnly", + }, + "attribute_2": { + "history_update_bool": True, + "best_update_string": "LowestSoFar", + }, + "attribute_3": { + "history_update_bool": False, + "best_update_string": "Replace", + }, + }, + { + "root_nodes": ["attribute_1"], + "best_update_structure": ( + ["attribute_1", "attribute_2"], + ["attribute_1", "attribute_3"], + ), + }, + ) + + logger_obj.log_variables( + {"attribute_1": 10, "attribute_2": 3, "attribute_3": "string 1"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10]) self.assertEqual(logger_obj.attribute_2.history, [3]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [10]) self.assertEqual(logger_obj.attribute_2.best, [3]) - self.assertEqual(logger_obj.attribute_3.best, ['string 1']) - - logger_obj.log_variables({'attribute_1': 5, - 'attribute_2': 1, - 'attribute_3': 'string 2'}) - + self.assertEqual(logger_obj.attribute_3.best, ["string 1"]) + + logger_obj.log_variables( + {"attribute_1": 5, "attribute_2": 1, "attribute_3": "string 2"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10, 5]) self.assertEqual(logger_obj.attribute_2.history, [3, 1]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [10]) self.assertEqual(logger_obj.attribute_2.best, [3]) - self.assertEqual(logger_obj.attribute_3.best, ['string 1']) - - logger_obj.log_variables({'attribute_1': 15, - 'attribute_2': 4, - 'attribute_3': 'string 3'}) - + self.assertEqual(logger_obj.attribute_3.best, ["string 1"]) + + logger_obj.log_variables( + {"attribute_1": 15, "attribute_2": 4, "attribute_3": "string 3"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10, 5, 15]) self.assertEqual(logger_obj.attribute_2.history, [3, 1, 4]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [15]) self.assertEqual(logger_obj.attribute_2.best, [3]) - self.assertEqual(logger_obj.attribute_3.best, ['string 3']) - - logger_obj.log_variables({'attribute_1': 20, - 'attribute_2': 2, - 'attribute_3': 'string 4'}) - + self.assertEqual(logger_obj.attribute_3.best, ["string 3"]) + + logger_obj.log_variables( + {"attribute_1": 20, "attribute_2": 2, "attribute_3": "string 4"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10, 5, 15, 20]) self.assertEqual(logger_obj.attribute_2.history, [3, 1, 4, 2]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [20]) self.assertEqual(logger_obj.attribute_2.best, [3, 2]) - self.assertEqual(logger_obj.attribute_3.best, ['string 4']) - + self.assertEqual(logger_obj.attribute_3.best, ["string 4"]) + def test_logger_obj_update_struct_2(self): - + """ Single layer test """ - - logger_obj = Logger({'attribute_1': - { - 'history_update_bool': True, - 'best_update_string': 'HighestOnly' - }, - 'attribute_2': - { - 'history_update_bool': True, - 'best_update_string': 'LowestSoFar' - }, - 'attribute_3': - { - 'history_update_bool': False, - 'best_update_string': 'Replace' - } - }, - { - 'root_nodes': ['attribute_1', 'attribute_2', 'attribute_3'], - 'best_update_structure': ([]) - }) - - logger_obj.log_variables({'attribute_1': 10, - 'attribute_2': 3, - 'attribute_3': 'string 1'}) - + + logger_obj = Logger( + { + "attribute_1": { + "history_update_bool": True, + "best_update_string": "HighestOnly", + }, + "attribute_2": { + "history_update_bool": True, + "best_update_string": "LowestSoFar", + }, + "attribute_3": { + "history_update_bool": False, + "best_update_string": "Replace", + }, + }, + { + "root_nodes": ["attribute_1", "attribute_2", "attribute_3"], + "best_update_structure": ([]), + }, + ) + + logger_obj.log_variables( + {"attribute_1": 10, "attribute_2": 3, "attribute_3": "string 1"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10]) self.assertEqual(logger_obj.attribute_2.history, [3]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [10]) self.assertEqual(logger_obj.attribute_2.best, [3]) - self.assertEqual(logger_obj.attribute_3.best, ['string 1']) - - logger_obj.log_variables({'attribute_1': 5, - 'attribute_2': 1, - 'attribute_3': 'string 2'}) - + self.assertEqual(logger_obj.attribute_3.best, ["string 1"]) + + logger_obj.log_variables( + {"attribute_1": 5, "attribute_2": 1, "attribute_3": "string 2"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10, 5]) self.assertEqual(logger_obj.attribute_2.history, [3, 1]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [10]) self.assertEqual(logger_obj.attribute_2.best, [3, 1]) - self.assertEqual(logger_obj.attribute_3.best, ['string 2']) - - logger_obj.log_variables({'attribute_1': 15, - 'attribute_2': 4, - 'attribute_3': 'string 3'}) - + self.assertEqual(logger_obj.attribute_3.best, ["string 2"]) + + logger_obj.log_variables( + {"attribute_1": 15, "attribute_2": 4, "attribute_3": "string 3"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10, 5, 15]) self.assertEqual(logger_obj.attribute_2.history, [3, 1, 4]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [15]) self.assertEqual(logger_obj.attribute_2.best, [3, 1]) - self.assertEqual(logger_obj.attribute_3.best, ['string 3']) - - logger_obj.log_variables({'attribute_1': 20, - 'attribute_2': 2, - 'attribute_3': 'string 4'}) - + self.assertEqual(logger_obj.attribute_3.best, ["string 3"]) + + logger_obj.log_variables( + {"attribute_1": 20, "attribute_2": 2, "attribute_3": "string 4"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10, 5, 15, 20]) self.assertEqual(logger_obj.attribute_2.history, [3, 1, 4, 2]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [20]) self.assertEqual(logger_obj.attribute_2.best, [3, 1]) - self.assertEqual(logger_obj.attribute_3.best, ['string 4']) - + self.assertEqual(logger_obj.attribute_3.best, ["string 4"]) + def test_logger_obj_update_struct_3(self): - + """ Multi layer test """ - - logger_obj = Logger({'attribute_1': - { - 'history_update_bool': True, - 'best_update_string': 'HighestOnly' - }, - 'attribute_2': - { - 'history_update_bool': True, - 'best_update_string': 'LowestSoFar' - }, - 'attribute_3': - { - 'history_update_bool': False, - 'best_update_string': 'Replace' - } - }, - { - 'root_nodes': ['attribute_1'], - 'best_update_structure': - (['attribute_1', 'attribute_2'], - ['attribute_2', 'attribute_3']) - }) - - logger_obj.log_variables({'attribute_1': 10, - 'attribute_2': 3, - 'attribute_3': 'string 1'}) - + + logger_obj = Logger( + { + "attribute_1": { + "history_update_bool": True, + "best_update_string": "HighestOnly", + }, + "attribute_2": { + "history_update_bool": True, + "best_update_string": "LowestSoFar", + }, + "attribute_3": { + "history_update_bool": False, + "best_update_string": "Replace", + }, + }, + { + "root_nodes": ["attribute_1"], + "best_update_structure": ( + ["attribute_1", "attribute_2"], + ["attribute_2", "attribute_3"], + ), + }, + ) + + logger_obj.log_variables( + {"attribute_1": 10, "attribute_2": 3, "attribute_3": "string 1"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10]) self.assertEqual(logger_obj.attribute_2.history, [3]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [10]) self.assertEqual(logger_obj.attribute_2.best, [3]) - self.assertEqual(logger_obj.attribute_3.best, ['string 1']) - - logger_obj.log_variables({'attribute_1': 5, - 'attribute_2': 1, - 'attribute_3': 'string 2'}) - + self.assertEqual(logger_obj.attribute_3.best, ["string 1"]) + + logger_obj.log_variables( + {"attribute_1": 5, "attribute_2": 1, "attribute_3": "string 2"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10, 5]) self.assertEqual(logger_obj.attribute_2.history, [3, 1]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [10]) self.assertEqual(logger_obj.attribute_2.best, [3]) - self.assertEqual(logger_obj.attribute_3.best, ['string 1']) - - logger_obj.log_variables({'attribute_1': 15, - 'attribute_2': 4, - 'attribute_3': 'string 3'}) - + self.assertEqual(logger_obj.attribute_3.best, ["string 1"]) + + logger_obj.log_variables( + {"attribute_1": 15, "attribute_2": 4, "attribute_3": "string 3"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10, 5, 15]) self.assertEqual(logger_obj.attribute_2.history, [3, 1, 4]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [15]) self.assertEqual(logger_obj.attribute_2.best, [3]) - self.assertEqual(logger_obj.attribute_3.best, ['string 1']) - - logger_obj.log_variables({'attribute_1': 20, - 'attribute_2': 2, - 'attribute_3': 'string 4'}) - + self.assertEqual(logger_obj.attribute_3.best, ["string 1"]) + + logger_obj.log_variables( + {"attribute_1": 20, "attribute_2": 2, "attribute_3": "string 4"} + ) + self.assertEqual(logger_obj.attribute_1.history, [10, 5, 15, 20]) self.assertEqual(logger_obj.attribute_2.history, [3, 1, 4, 2]) self.assertEqual(logger_obj.attribute_3.history, []) - + self.assertEqual(logger_obj.attribute_1.best, [20]) self.assertEqual(logger_obj.attribute_2.best, [3, 2]) - self.assertEqual(logger_obj.attribute_3.best, ['string 4']) + self.assertEqual(logger_obj.attribute_3.best, ["string 4"]) + -if __name__ == '__main__': - unittest.main() \ No newline at end of file +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_notebooks.py b/tests/test_notebooks.py index 40dde4793..07e93ab94 100644 --- a/tests/test_notebooks.py +++ b/tests/test_notebooks.py @@ -7,17 +7,17 @@ import pytest import sys, os + myPath = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, myPath + '/../') +sys.path.insert(0, myPath + "/../") def notebook_test_function(name): - - with open(name, encoding='utf-8') as f: + with open(name, encoding="utf-8") as f: nb = nbformat.read(f, as_version=4) - ep = ExecutePreprocessor(timeout=600, kernel_name='env') + ep = ExecutePreprocessor(timeout=600, kernel_name="env") ep.preprocess(nb) @@ -26,63 +26,80 @@ def notebook_test_function(name): def test_01_workflows_example(): notebook_test_function("./examples/01_workflows_example.ipynb") + # @pytest.mark.notebook def test_02_simulators_comparison(): notebook_test_function("./examples/02_simulators_comparison.ipynb") + @pytest.mark.qpu def test_03_qaoa_on_qpus(): notebook_test_function("./examples/03_qaoa_on_qpus.ipynb") + # @pytest.mark.notebook def test_04_qaoa_variational_parameters(): notebook_test_function("./examples/04_qaoa_variational_parameters.ipynb") + # @pytest.mark.notebook def test_05_advanced_parameterization(): notebook_test_function("./examples/05_advanced_parameterization.ipynb") + # @pytest.mark.notebook def test_06_fast_qaoa_simulator(): notebook_test_function("./examples/06_fast_qaoa_simulator.ipynb") + # @pytest.mark.notebook def test_07_cost_landscapes_w_manual_mode(): notebook_test_function("./examples/07_cost_landscapes_w_manual_mode.ipynb") + # @pytest.mark.notebook def test_08_results_example(): notebook_test_function("./examples/08_results_example.ipynb") + def test_09_RQAOA_example(): notebook_test_function("./examples/09_RQAOA_example.ipynb") + @pytest.mark.qpu def test_10_workflows_on_Amazon_braket(): notebook_test_function("./examples/10_workflows_on_Amazon_braket.ipynb") - + + def test_11_Mixer_example(): notebook_test_function("./examples/11_Mixer_example.ipynb") + def test_X_dumping_data(): notebook_test_function("./examples/X_dumping_data.ipynb") - + + ### Community Tutorials # @pytest.mark.notebook def test_tutorial_quantum_approximate_optimization_algorithm(): - notebook_test_function("./examples/community_tutorials/01_tutorial_quantum_approximate_optimization_algorithm.ipynb") + notebook_test_function( + "./examples/community_tutorials/01_tutorial_quantum_approximate_optimization_algorithm.ipynb" + ) + # @pytest.mark.notebook def test_docplex_example(): notebook_test_function("./examples/community_tutorials/02_docplex_example.ipynb") - + + # @pytest.mark.notebook def test_portfolio_optimization(): - notebook_test_function("./examples/community_tutorials/03_portfolio_optimization.ipynb") - + notebook_test_function( + "./examples/community_tutorials/03_portfolio_optimization.ipynb" + ) + + # @pytest.mark.notebook def test_binpacking(): notebook_test_function("./examples/community_tutorials/04_binpacking.ipynb") - - diff --git a/tests/test_operators.py b/tests/test_operators.py index 3579ffcb3..e7e0a1326 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -3,12 +3,13 @@ import unittest from openqaoa.qaoa_components import PauliOp, Hamiltonian + """ Unittest based testing of the PauliOp and Hamiltonian classes """ -class TestingOperators(unittest.TestCase): +class TestingOperators(unittest.TestCase): def test_pauli_init(self): """ Test the initialization method of the PauliOp class. @@ -17,44 +18,66 @@ def test_pauli_init(self): """ # Define input examples of indices and strings - input_indices = [(0, 1, 1), (4, 5, 0, 1), (2, 0, 7, 4, 5), - (0, 1, 5, 3, 7, 6), (6, 5, 4, 3, 1, 1, 0)] - input_strings = ['XZX', 'YYYY', 'ZYXZX', 'YYZZXX', 'ZYXYZYX'] + input_indices = [ + (0, 1, 1), + (4, 5, 0, 1), + (2, 0, 7, 4, 5), + (0, 1, 5, 3, 7, 6), + (6, 5, 4, 3, 1, 1, 0), + ] + input_strings = ["XZX", "YYYY", "ZYXZX", "YYZZXX", "ZYXYZYX"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Correctly ordered indices and strings - correct_indices = [(0, 1), (0, 1, 4, 5), (0, 2, 4, 5, 7), - (0, 1, 3, 5, 6, 7), (0, 1, 3, 4, 5, 6)] - correct_strings = ['XY', 'YYYY', 'YZZXX', 'YYZZXX', 'XXYXYZ'] - correct_phases = [1j,1,1,1,-1j] + correct_indices = [ + (0, 1), + (0, 1, 4, 5), + (0, 2, 4, 5, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 3, 4, 5, 6), + ] + correct_strings = ["XY", "YYYY", "YZZXX", "YYZZXX", "XXYXYZ"] + correct_phases = [1j, 1, 1, 1, -1j] # Extract indices and strings generated by the Pauli operators indices = [pauli.qubit_indices for pauli in paulis] strings = [pauli.pauli_str for pauli in paulis] phases = [pauli.phase for pauli in paulis] - - # Test that indices and strings were generated correctly - assert indices == correct_indices, f'Pauli indices not generated correctly' - assert strings == correct_strings, f'Pauli strings not generated correctly' - assert np.allclose(phases,correct_phases), f'Pauli phases not generated correctly' + # Test that indices and strings were generated correctly + assert indices == correct_indices, f"Pauli indices not generated correctly" + assert strings == correct_strings, f"Pauli strings not generated correctly" + assert np.allclose( + phases, correct_phases + ), f"Pauli phases not generated correctly" # Exception cases - not valid Pauli operators - input_exc_indices = [(0, 2, 1), (1,), (2, 2, 2, 4, 5), (0, 1, 5, 3, 7, 6), (6, 5, 4, 3, 2, 1, 0)] - input_exc_strings = ['XY', 'XZZYZXYZ', 'YXZZ', 'XYZZX', 'Z'] + input_exc_indices = [ + (0, 2, 1), + (1,), + (2, 2, 2, 4, 5), + (0, 1, 5, 3, 7, 6), + (6, 5, 4, 3, 2, 1, 0), + ] + input_exc_strings = ["XY", "XZZYZXYZ", "YXZZ", "XYZZX", "Z"] # Test the exceptions are raised - for string,index in zip(input_exc_strings, input_exc_indices): - - # Attempt construction of Pauli operator + for string, index in zip(input_exc_strings, input_exc_indices): + + # Attempt construction of Pauli operator with self.assertRaises(AssertionError) as context: pauli = PauliOp(string, index) # Check exception message - self.assertEqual(f"Each Pauli operator must have a unique qubit index", str(context.exception)) + self.assertEqual( + f"Each Pauli operator must have a unique qubit index", + str(context.exception), + ) def test_sort_pauli_op(self): """ @@ -65,47 +88,67 @@ def test_sort_pauli_op(self): """ # Define input examples of indices and strings - input_indices = [(0, 2, 1), (4, 5, 0, 1), (2, 0, 7, 4, 5), - (0, 1, 5, 3, 7, 6), (6, 5, 4, 3, 2, 1, 0)] - input_strings = ['XXZ', 'YYYY', 'ZYXZX', 'YYZZXX', 'ZYXYZYX'] + input_indices = [ + (0, 2, 1), + (4, 5, 0, 1), + (2, 0, 7, 4, 5), + (0, 1, 5, 3, 7, 6), + (6, 5, 4, 3, 2, 1, 0), + ] + input_strings = ["XXZ", "YYYY", "ZYXZX", "YYZZXX", "ZYXYZYX"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Correctly ordered indices and strings - correct_indices = [(0, 1, 2), (0, 1, 4, 5), (0, 2, 4, 5, 7), - (0, 1, 3, 5, 6, 7), (0, 1, 2, 3, 4, 5, 6)] - correct_strings = ['XZX', 'YYYY', 'YZZXX', 'YYZZXX', 'XYZYXYZ'] + correct_indices = [ + (0, 1, 2), + (0, 1, 4, 5), + (0, 2, 4, 5, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 2, 3, 4, 5, 6), + ] + correct_strings = ["XZX", "YYYY", "YZZXX", "YYZZXX", "XYZYXYZ"] # Extract indices and strings generated by the Pauli operators indices = [pauli.qubit_indices for pauli in paulis] strings = [pauli.pauli_str for pauli in paulis] # Test that indices and strings were correctly ordered when creating the Pauli Operator - assert indices == correct_indices, f'Pauli indices not sorted correctly' - assert strings == correct_strings, f'Pauli strings not sorted correctly' - + assert indices == correct_indices, f"Pauli indices not sorted correctly" + assert strings == correct_strings, f"Pauli strings not sorted correctly" # Exception cases - not valid Pauli operators - input_exc_indices = [(0, 2, 1), (1,), (2, 0, 7, 4, 5), (0, 1, 5, 3, 7, 6), (6, 5, 4, 3, 2, 1, 0)] - input_exc_strings = ['LXY', 'Q', 'ZYXZR', 'FYZZXX', 'ZYXYZYN'] + input_exc_indices = [ + (0, 2, 1), + (1,), + (2, 0, 7, 4, 5), + (0, 1, 5, 3, 7, 6), + (6, 5, 4, 3, 2, 1, 0), + ] + input_exc_strings = ["LXY", "Q", "ZYXZR", "FYZZXX", "ZYXYZYN"] # Pauli set - PAULIS_SET = set('XYZI') + PAULIS_SET = set("XYZI") # Test the exceptions are raised - for string,index in zip(input_exc_strings, input_exc_indices): - + for string, index in zip(input_exc_strings, input_exc_indices): + # Extract exception from string non_pauli_operator = list(set(string) - PAULIS_SET)[0] - # Attempt construction of Pauli operator + # Attempt construction of Pauli operator with self.assertRaises(ValueError) as context: pauli = PauliOp(string, index) # Check exception message - self.assertEqual(f"{non_pauli_operator} is not a valid Pauli. Please choose from the set {PAULIS_SET}", str(context.exception)) + self.assertEqual( + f"{non_pauli_operator} is not a valid Pauli. Please choose from the set {PAULIS_SET}", + str(context.exception), + ) def test_pauli_simplify(self): """ @@ -116,17 +159,23 @@ def test_pauli_simplify(self): """ # Define input examples of indices and strings - input_indices = [(0, 1, 1), (0, 0, 0, 2), - (0, 1, 3, 3, 4), (1, 1, 1, 1, 1, 1, 1)] - input_strings = ['ZXY', 'YYYY', 'ZYIZX', 'ZZZZZXZ'] + input_indices = [ + (0, 1, 1), + (0, 0, 0, 2), + (0, 1, 3, 3, 4), + (1, 1, 1, 1, 1, 1, 1), + ] + input_strings = ["ZXY", "YYYY", "ZYIZX", "ZZZZZXZ"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Indices, strings and phases from correctly simplified Pauli operators correct_indices = [(0, 1), (0, 2), (0, 1, 3, 4), (1,)] - correct_strings = ['ZZ', 'YY', 'ZYZX', 'X'] + correct_strings = ["ZZ", "YY", "ZYZX", "X"] correct_phases = [1j, 1, 1, -1] # Extract indices, strings and phases generated by the Pauli operators @@ -135,10 +184,9 @@ def test_pauli_simplify(self): phases = [pauli.phase for pauli in paulis] # Test that indices and strings were correctly ordered when creating the Pauli Operator - assert indices == correct_indices, f'Indices not simplified correctly' - assert strings == correct_strings, f'Strings not simplified correctly' - assert np.allclose( - phases, correct_phases), f'Phases not simplified correctly' + assert indices == correct_indices, f"Indices not simplified correctly" + assert strings == correct_strings, f"Strings not simplified correctly" + assert np.allclose(phases, correct_phases), f"Phases not simplified correctly" def test_pauli_is_trivial(self): """ @@ -149,13 +197,20 @@ def test_pauli_is_trivial(self): """ # Define input examples of indices and strings - input_indices = [(0, 1, 2), (0, 1, 4, 5), (0, 2, 4, 5, 7), - (0, 1, 3, 5, 6, 7), (0, 1, 2, 3, 4, 5, 6)] - input_strings = ['III', 'IYYY', 'YZIXX', 'IIIIII', 'XIIIIII'] + input_indices = [ + (0, 1, 2), + (0, 1, 4, 5), + (0, 2, 4, 5, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 2, 3, 4, 5, 6), + ] + input_strings = ["III", "IYYY", "YZIXX", "IIIIII", "XIIIIII"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Correct list containing whether the Pauli Operator is trivial or not correct_triviality = [True, False, False, True, False] @@ -165,7 +220,8 @@ def test_pauli_is_trivial(self): # Test that indices and strings were correctly ordered when creating the Pauli Operator assert np.allclose( - triviality, correct_triviality), f'Triviality classification is incorrect' + triviality, correct_triviality + ), f"Triviality classification is incorrect" def test_pauli_matrix(self): """ @@ -176,32 +232,57 @@ def test_pauli_matrix(self): # Define input examples of indices and strings input_indices = [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1, 2)] - input_strings = ['IX', 'XY', 'XZ', 'ZY', 'IIZ'] + input_strings = ["IX", "XY", "XZ", "ZY", "IIZ"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Correct pauli representations - correct_matrix_representations = [np.array(([0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]), dtype=complex), - np.array( - ([0, 0, 0, -1j], [0, 0, 1j, 0], [0, -1j, 0, 0], [1j, 0, 0, 0]), dtype=complex), - np.array( - ([0, 0, 1, 0], [0, 0, 0, -1], [1, 0, 0, 0], [0, -1, 0, 0]), dtype=complex), - np.array(([0, -1j, 0, 0], [1j, 0, 0, 0], [0, 0, 0, 1j], - [0, 0, -1j, 0]), dtype=complex), - np.array(([1, 0, 0, 0, 0, 0, 0, 0], [0, -1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, -1, 0, 0, 0, 0], - [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, -1, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, -1]), dtype=complex)] + correct_matrix_representations = [ + np.array( + ([0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]), dtype=complex + ), + np.array( + ([0, 0, 0, -1j], [0, 0, 1j, 0], [0, -1j, 0, 0], [1j, 0, 0, 0]), + dtype=complex, + ), + np.array( + ([0, 0, 1, 0], [0, 0, 0, -1], [1, 0, 0, 0], [0, -1, 0, 0]), + dtype=complex, + ), + np.array( + ([0, -1j, 0, 0], [1j, 0, 0, 0], [0, 0, 0, 1j], [0, 0, -1j, 0]), + dtype=complex, + ), + np.array( + ( + [1, 0, 0, 0, 0, 0, 0, 0], + [0, -1, 0, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, -1, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0], + [0, 0, 0, 0, 0, -1, 0, 0], + [0, 0, 0, 0, 0, 0, 1, 0], + [0, 0, 0, 0, 0, 0, 0, -1], + ), + dtype=complex, + ), + ] # Compute matrix representations matrix_representations = [pauli.matrix for pauli in paulis] # Compare each matrix representation - matrix_comparison = [(correct_matrix_representations[i] == matrix_representations[i]).all( - ) for i in range(len(matrix_representations))] + matrix_comparison = [ + (correct_matrix_representations[i] == matrix_representations[i]).all() + for i in range(len(matrix_representations)) + ] # Test that the computed representations are correct - assert np.all(matrix_comparison), f'Matrix representation is incorrect' + assert np.all(matrix_comparison), f"Matrix representation is incorrect" def test_pauli_len(self): """ @@ -211,13 +292,20 @@ def test_pauli_len(self): """ # Define input examples of indices and strings - input_indices = [(0, 1, 2), (0, 1, 4, 5), (0, 2, 4, 5, 7), - (0, 1, 3, 5, 6, 7), (0, 1, 2, 3, 4, 5, 6)] - input_strings = ['III', 'IYYY', 'YZIXX', 'IIIIII', 'XIIIIII'] + input_indices = [ + (0, 1, 2), + (0, 1, 4, 5), + (0, 2, 4, 5, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 2, 3, 4, 5, 6), + ] + input_strings = ["III", "IYYY", "YZIXX", "IIIIII", "XIIIIII"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Correct Pauli operator lengths correct_lengths = [3, 4, 5, 6, 7] @@ -226,8 +314,7 @@ def test_pauli_len(self): lengths = [pauli.__len__() for pauli in paulis] # Test that computed lengths are correct - assert np.allclose( - lengths, correct_lengths), f'Computed lengths are incorrect' + assert np.allclose(lengths, correct_lengths), f"Computed lengths are incorrect" def test_pauli_eq(self): """ @@ -237,25 +324,33 @@ def test_pauli_eq(self): """ # Define input examples of indices and strings - input_indices = [(0, 1, 2), (0, 1, 2), (0, 1, 4, 5), (0, 2, 4, 5, 7), - (0, 1, 3, 5, 6, 7), (0, 1, 3, 5, 6, 7), (0, 1, 2, 3, 4, 5, 6)] - input_strings = ['XZX', 'XZX', 'YYYY', - 'YZZXX', 'YYZZXX', 'YYZZXX', 'XYZYXYZ'] + input_indices = [ + (0, 1, 2), + (0, 1, 2), + (0, 1, 4, 5), + (0, 2, 4, 5, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 2, 3, 4, 5, 6), + ] + input_strings = ["XZX", "XZX", "YYYY", "YZZXX", "YYZZXX", "YYZZXX", "XYZYXYZ"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Check equivalence between contiguous Pauli operators in the list - equivalences = [paulis[i].__eq__(paulis[i+1]) - for i in range(len(paulis)-1)] + equivalences = [paulis[i].__eq__(paulis[i + 1]) for i in range(len(paulis) - 1)] # Correct equivalences correct_equivalences = [True, False, False, False, True, False] # Test the checks have been performes correctly assert np.allclose( - equivalences, correct_equivalences), f'Equivalences have not been computed correctly' + equivalences, correct_equivalences + ), f"Equivalences have not been computed correctly" def test_pauli_copy(self): """ @@ -265,24 +360,31 @@ def test_pauli_copy(self): """ # Define input examples of indices and strings - input_indices = [(0, 1, 2), (0, 1, 4, 5), (0, 2, 4, 5, 7), - (0, 1, 3, 5, 6, 7), (0, 1, 2, 3, 4, 5, 6)] - input_strings = ['XZX', 'YYYY', 'YZZXX', 'YYZZXX', 'XYZYXYZ'] + input_indices = [ + (0, 1, 2), + (0, 1, 4, 5), + (0, 2, 4, 5, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 2, 3, 4, 5, 6), + ] + input_strings = ["XZX", "YYYY", "YZZXX", "YYZZXX", "XYZYXYZ"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Generate copies of the Pauli operators copy_paulis = [pauli.__copy__() for pauli in paulis] # Test the copies have been correctly performes - check_copy = [paulis[j].__eq__(copy_paulis[j]) - for j in range(len(paulis))] + check_copy = [paulis[j].__eq__(copy_paulis[j]) for j in range(len(paulis))] assert sum(check_copy) == len( - check_copy), f'Copies were not performed correctly' + check_copy + ), f"Copies were not performed correctly" def test_pauli_str(self): """ @@ -292,23 +394,37 @@ def test_pauli_str(self): """ # Define input examples of indices and strings - input_indices = [(0, 1, 2), (0, 1, 4, 5), (0, 2, 4, 5, 7), - (0, 1, 3, 5, 6, 7), (0, 1, 2, 3, 4, 5, 6)] - input_strings = ['XZX', 'YYYY', 'YZZXX', 'YYZZXX', 'XYZYXYZ'] + input_indices = [ + (0, 1, 2), + (0, 1, 4, 5), + (0, 2, 4, 5, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 2, 3, 4, 5, 6), + ] + input_strings = ["XZX", "YYYY", "YZZXX", "YYZZXX", "XYZYXYZ"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Correct string representations - correct_str_rep = ['X_{0}Z_{1}X_{2}', 'Y_{0}Y_{1}Y_{4}Y_{5}', 'Y_{0}Z_{2}Z_{4}X_{5}X_{7}', - 'Y_{0}Y_{1}Z_{3}Z_{5}X_{6}X_{7}', 'X_{0}Y_{1}Z_{2}Y_{3}X_{4}Y_{5}Z_{6}'] + correct_str_rep = [ + "X_{0}Z_{1}X_{2}", + "Y_{0}Y_{1}Y_{4}Y_{5}", + "Y_{0}Z_{2}Z_{4}X_{5}X_{7}", + "Y_{0}Y_{1}Z_{3}Z_{5}X_{6}X_{7}", + "X_{0}Y_{1}Z_{2}Y_{3}X_{4}Y_{5}Z_{6}", + ] # Generate string rtepresentations str_rep = [pauli.__str__() for pauli in paulis] # Test that string representations were correctly generated - assert str_rep == correct_str_rep, f'String representations were not correctly generated' + assert ( + str_rep == correct_str_rep + ), f"String representations were not correctly generated" def test_pauli_repr(self): """ @@ -318,23 +434,37 @@ def test_pauli_repr(self): """ # Define input examples of indices and strings - input_indices = [(0, 1, 2), (0, 1, 4, 5), (0, 2, 4, 5, 7), - (0, 1, 3, 5, 6, 7), (0, 1, 2, 3, 4, 5, 6)] - input_strings = ['XZX', 'YYYY', 'YZZXX', 'YYZZXX', 'XYZYXYZ'] + input_indices = [ + (0, 1, 2), + (0, 1, 4, 5), + (0, 2, 4, 5, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 2, 3, 4, 5, 6), + ] + input_strings = ["XZX", "YYYY", "YZZXX", "YYZZXX", "XYZYXYZ"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Correct string representations - correct_str_rep = ['PauliOp(XZX,(0, 1, 2))', 'PauliOp(YYYY,(0, 1, 4, 5))', 'PauliOp(YZZXX,(0, 2, 4, 5, 7))', - 'PauliOp(YYZZXX,(0, 1, 3, 5, 6, 7))', 'PauliOp(XYZYXYZ,(0, 1, 2, 3, 4, 5, 6))'] + correct_str_rep = [ + "PauliOp(XZX,(0, 1, 2))", + "PauliOp(YYYY,(0, 1, 4, 5))", + "PauliOp(YZZXX,(0, 2, 4, 5, 7))", + "PauliOp(YYZZXX,(0, 1, 3, 5, 6, 7))", + "PauliOp(XYZYXYZ,(0, 1, 2, 3, 4, 5, 6))", + ] # Generate string rtepresentations str_rep = [pauli.__repr__() for pauli in paulis] # Test that string representations were correctly generated - assert str_rep == correct_str_rep, f'String representations for Pauli operator object were not correctly generated' + assert ( + str_rep == correct_str_rep + ), f"String representations for Pauli operator object were not correctly generated" def test_pauli_mul(self): """ @@ -344,32 +474,47 @@ def test_pauli_mul(self): """ # Define input examples of indices and strings - input_indices = [(0, 1, 2), (0, 1, 4, 5), (0, 2, 4, 5, 7), - (0, 1, 3, 5, 6, 7), (0, 1, 2, 3, 4, 5, 6)] - input_strings = ['XZX', 'YYYY', 'YZZXX', 'YYZZXX', 'XYZYXYX'] + input_indices = [ + (0, 1, 2), + (0, 1, 4, 5), + (0, 2, 4, 5, 7), + (0, 1, 3, 5, 6, 7), + (0, 1, 2, 3, 4, 5, 6), + ] + input_strings = ["XZX", "YYYY", "YZZXX", "YYZZXX", "XYZYXYX"] # Create Pauli operators from input examples - paulis = [PauliOp(string, index) - for string, index in zip(input_strings, input_indices)] + paulis = [ + PauliOp(string, index) + for string, index in zip(input_strings, input_indices) + ] # Compute multiplication between contiguous Pauli operators in the list - pauli_mult = [paulis[j].__mul__(paulis[j+1]) - for j in range(len(paulis)-1)] + pauli_mult = [paulis[j].__mul__(paulis[j + 1]) for j in range(len(paulis) - 1)] indices = [pauli.qubit_indices for pauli in pauli_mult] strings = [pauli.pauli_str for pauli in pauli_mult] phases = [pauli.phase for pauli in pauli_mult] # Correct matrix multiplications - correct_indices = [(0, 1, 2, 4, 5), (1, 2, 4, 5, 7), - (1, 2, 3, 4, 5, 6), (0, 2, 3, 4, 5, 7)] - correct_strings = ['ZXXYY', 'YZXZX', 'YZZZYX', 'ZZXXXX'] + correct_indices = [ + (0, 1, 2, 4, 5), + (1, 2, 4, 5, 7), + (1, 2, 3, 4, 5, 6), + (0, 2, 3, 4, 5, 7), + ] + correct_strings = ["ZXXYY", "YZXZX", "YZZZYX", "ZZXXXX"] correct_phases = [1, 1, -1j, 1j] # Test that matrix multiplications are correct - assert indices == correct_indices, f'Indices from matrix multiplications are not correct' - assert strings == correct_strings, f'Strings from matrix multiplications are not correct' + assert ( + indices == correct_indices + ), f"Indices from matrix multiplications are not correct" + assert ( + strings == correct_strings + ), f"Strings from matrix multiplications are not correct" assert np.allclose( - phases, correct_phases), f'Phases from matrix multiplications are not correct' + phases, correct_phases + ), f"Phases from matrix multiplications are not correct" def test_pauli_XYZI(self): """ @@ -398,29 +543,50 @@ def test_pauli_XYZI(self): matrix_rep = [pauli.matrix for pauli in paulis] # Correct attributes - correct_strings = ['X', 'Y', 'Z', 'I'] + correct_strings = ["X", "Y", "Z", "I"] correct_indices = [(1,), (1,), (1,), (1,)] correct_phases = [1, 1, 1, 1] - correct_string_rep = ['X_{1}', 'Y_{1}', 'Z_{1}', 'I_{1}'] + correct_string_rep = ["X_{1}", "Y_{1}", "Z_{1}", "I_{1}"] correct_string_obj_rep = [ - 'PauliOp(X,(1,))', 'PauliOp(Y,(1,))', 'PauliOp(Z,(1,))', 'PauliOp(I,(1,))'] - correct_matrix_rep = [np.array(([0, 1], [1, 0]), dtype=complex), np.array(([0, -1j], [1j, 0]), dtype=complex), - np.array(([1, 0], [0, -1]), dtype=complex), np.array(([1, 0], [0, 1]), dtype=complex)] + "PauliOp(X,(1,))", + "PauliOp(Y,(1,))", + "PauliOp(Z,(1,))", + "PauliOp(I,(1,))", + ] + correct_matrix_rep = [ + np.array(([0, 1], [1, 0]), dtype=complex), + np.array(([0, -1j], [1j, 0]), dtype=complex), + np.array(([1, 0], [0, -1]), dtype=complex), + np.array(([1, 0], [0, 1]), dtype=complex), + ] # Check indices, strings, phases and matrix representations - assert strings == correct_strings, f'Strings are not correctly defined for Pauli matrices' - assert indices == correct_indices, f'Indices are not correctly defined for Pauli matrices' + assert ( + strings == correct_strings + ), f"Strings are not correctly defined for Pauli matrices" + assert ( + indices == correct_indices + ), f"Indices are not correctly defined for Pauli matrices" assert np.allclose( - phases, correct_phases), f'Phases are not correctly defined for Pauli matrices' - assert string_rep == correct_string_rep, f'String representations are not correctly defined for Pauli matrices' - assert string_obj_rep == correct_string_obj_rep, f'String object representations are not correctly defined for Pauli matrices' - assert np.all([(matrix_rep[i] == correct_matrix_rep[i]).all() for i in range(len( - matrix_rep))]), f'Matrix representations are not correctly defined for Pauli matrices' + phases, correct_phases + ), f"Phases are not correctly defined for Pauli matrices" + assert ( + string_rep == correct_string_rep + ), f"String representations are not correctly defined for Pauli matrices" + assert ( + string_obj_rep == correct_string_obj_rep + ), f"String object representations are not correctly defined for Pauli matrices" + assert np.all( + [ + (matrix_rep[i] == correct_matrix_rep[i]).all() + for i in range(len(matrix_rep)) + ] + ), f"Matrix representations are not correctly defined for Pauli matrices" def test_hamiltonian_init(self): """ Test initialization method of the Hamiltonian class. - + The tests consists in checking correct initializations for representative examples. """ @@ -431,14 +597,14 @@ def test_hamiltonian_init(self): # Define Pauli terms using shifted indices idx_ref = 3 - indices_ref = list(range(idx_ref,n_qubits+idx_ref)) + indices_ref = list(range(idx_ref, n_qubits + idx_ref)) trivial_indices = [(i,) for i in indices_ref] singlet_indices = [(i,) for i in indices_ref] - pair_indices = [(i, j) for j in indices_ref for i in range(idx_ref,j)] + pair_indices = [(i, j) for j in indices_ref for i in range(idx_ref, j)] - trivial_terms = [PauliOp('I', indices) for indices in trivial_indices] - linear_terms = [PauliOp('Z', indices) for indices in singlet_indices] - quadratic_terms = [PauliOp('ZZ', indices) for indices in pair_indices] + trivial_terms = [PauliOp("I", indices) for indices in trivial_indices] + linear_terms = [PauliOp("Z", indices) for indices in singlet_indices] + quadratic_terms = [PauliOp("ZZ", indices) for indices in pair_indices] terms = trivial_terms + linear_terms + quadratic_terms @@ -457,8 +623,12 @@ def test_hamiltonian_init(self): correct_indices = list(range(n_qubits)) correct_singlet_indices = [(i,) for i in correct_indices] correct_pair_indices = [(i, j) for j in correct_indices for i in range(j)] - correct_linear_terms = [PauliOp('Z', indices) for indices in correct_singlet_indices] - correct_quadratic_terms = [PauliOp('ZZ', indices) for indices in correct_pair_indices] + correct_linear_terms = [ + PauliOp("Z", indices) for indices in correct_singlet_indices + ] + correct_quadratic_terms = [ + PauliOp("ZZ", indices) for indices in correct_pair_indices + ] correct_linear_coeffs = [-1 for _ in range(len(correct_singlet_indices))] correct_quadratic_coeffs = [0.5 for _ in range(len(correct_pair_indices))] @@ -467,9 +637,15 @@ def test_hamiltonian_init(self): correct_constant = constant + sum(trivial_coeffs) # Test Hamiltonian was defined correctly - assert hamiltonian.terms == correct_terms, f'Terms in the Hamiltonian were not constructed correctly' - assert hamiltonian.coeffs == correct_coefficients, f'Coefficients in the Hamiltonian were not constructed correctly' - assert hamiltonian.constant == correct_constant, f'Constant in the Hamiltonian was not correctly constructed' + assert ( + hamiltonian.terms == correct_terms + ), f"Terms in the Hamiltonian were not constructed correctly" + assert ( + hamiltonian.coeffs == correct_coefficients + ), f"Coefficients in the Hamiltonian were not constructed correctly" + assert ( + hamiltonian.constant == correct_constant + ), f"Constant in the Hamiltonian was not correctly constructed" ## Second example @@ -477,10 +653,13 @@ def test_hamiltonian_init(self): trivial_indices = [(i,) for i in range(n_qubits)] pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - trivial_terms = [PauliOp('I', indices) for indices in trivial_indices] - terms_strings = ['XX', 'YY'] - quadratic_terms = [PauliOp(string, indices) - for indices in pair_indices for string in terms_strings] + trivial_terms = [PauliOp("I", indices) for indices in trivial_indices] + terms_strings = ["XX", "YY"] + quadratic_terms = [ + PauliOp(string, indices) + for indices in pair_indices + for string in terms_strings + ] terms = trivial_terms + quadratic_terms @@ -490,7 +669,7 @@ def test_hamiltonian_init(self): coefficients = trivial_coeffs + quadratic_coeffs constant = 2 - + # Define Hamiltonian hamiltonian = Hamiltonian(terms, coefficients, constant) @@ -500,45 +679,57 @@ def test_hamiltonian_init(self): correct_constant = constant + sum(trivial_coeffs) # Test Hamiltonian was defined correctly - assert hamiltonian.terms == correct_terms, f'Terms in the Hamiltonian were not constructed correctly' - assert hamiltonian.coeffs == correct_coefficients, f'Coefficients in the Hamiltonian were not constructed correctly' - assert hamiltonian.constant == correct_constant, f'Constant in the Hamiltonian was not correctly constructed' + assert ( + hamiltonian.terms == correct_terms + ), f"Terms in the Hamiltonian were not constructed correctly" + assert ( + hamiltonian.coeffs == correct_coefficients + ), f"Coefficients in the Hamiltonian were not constructed correctly" + assert ( + hamiltonian.constant == correct_constant + ), f"Constant in the Hamiltonian was not correctly constructed" ## Exception case - number of terms does not match number of coefficients - + # Number of qubits n_qubits = 5 # Define terms and coefficients pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - terms = [PauliOp('ZZ', indices) for indices in pair_indices] - coefficients = [1 for _ in range(len(terms)+1)] + terms = [PauliOp("ZZ", indices) for indices in pair_indices] + coefficients = [1 for _ in range(len(terms) + 1)] # Attempt construction of Hamiltonian with self.assertRaises(AssertionError) as context: - hamiltonian = Hamiltonian(terms, coefficients, constant = 0) - + hamiltonian = Hamiltonian(terms, coefficients, constant=0) + # Check exception message - self.assertEqual("Number of Pauli terms in Hamiltonian should be same as number of coefficients", str(context.exception)) + self.assertEqual( + "Number of Pauli terms in Hamiltonian should be same as number of coefficients", + str(context.exception), + ) ## Exception case - non Pauli object term present in list of terms - + # Number of qubits n_qubits = 5 # Define terms and coefficients pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - error_term = (0,5) - terms = [PauliOp('ZZ', indices) for indices in pair_indices] + [error_term] + error_term = (0, 5) + terms = [PauliOp("ZZ", indices) for indices in pair_indices] + [error_term] coefficients = [1 for _ in range(len(terms))] - + # Attempt construction of Hamiltonian with self.assertRaises(TypeError) as context: - hamiltonian = Hamiltonian(terms, coefficients, constant = 0) + hamiltonian = Hamiltonian(terms, coefficients, constant=0) # Check exception message - self.assertEqual(f"Pauli terms should be of type PauliOp and not {type(error_term)}", str(context.exception)) - + self.assertEqual( + f"Pauli terms should be of type PauliOp and not {type(error_term)}", + str(context.exception), + ) + def test_hamiltonian_qureg(self): """ Tests the function that generated the register in the Hamiltonian object. @@ -551,9 +742,12 @@ def test_hamiltonian_qureg(self): # Define Pauli terms terms_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - terms_strings = ['XX', 'YY'] - terms = [PauliOp(string, indices) - for indices in terms_indices for string in terms_strings] + terms_strings = ["XX", "YY"] + terms = [ + PauliOp(string, indices) + for indices in terms_indices + for string in terms_strings + ] # Define coefficients and constant coefficients = [1 for _ in range(len(terms))] @@ -570,7 +764,8 @@ def test_hamiltonian_qureg(self): # Test if the extracted register is correct assert np.allclose( - register, correct_register), f'Register has been incorrectly constructed' + register, correct_register + ), f"Register has been incorrectly constructed" def test_hamiltonian_divide_into_singlets_pairs(self): """ @@ -585,12 +780,10 @@ def test_hamiltonian_divide_into_singlets_pairs(self): # Define Pauli terms singlet_indices = [(i,) for i in range(n_qubits)] pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - correct_linear_terms = [PauliOp('Z', indices) - for indices in singlet_indices] - correct_quadratic_terms = [ - PauliOp('ZZ', indices) for indices in pair_indices] + correct_linear_terms = [PauliOp("Z", indices) for indices in singlet_indices] + correct_quadratic_terms = [PauliOp("ZZ", indices) for indices in pair_indices] - constant_term = [PauliOp('I', (0,))] + constant_term = [PauliOp("I", (0,))] terms = correct_linear_terms + correct_quadratic_terms + constant_term @@ -614,30 +807,45 @@ def test_hamiltonian_divide_into_singlets_pairs(self): constant = hamiltonian.constant # Test if the hamiltonian terms and coefficients have been correctly separated - assert linear_terms == correct_linear_terms, f'Linear terms have not been correctly generated' + assert ( + linear_terms == correct_linear_terms + ), f"Linear terms have not been correctly generated" assert np.allclose( - linear_coeffs, correct_linear_coeffs), f'Linear coefficients have not been correctly generated' - assert quadratic_terms == correct_quadratic_terms, f'Quadratic terms have not been correctly generated' + linear_coeffs, correct_linear_coeffs + ), f"Linear coefficients have not been correctly generated" + assert ( + quadratic_terms == correct_quadratic_terms + ), f"Quadratic terms have not been correctly generated" assert np.allclose( - quadratic_coeffs, correct_quadratic_coeffs), f'Quadratic coefficients have not been correctly generated' + quadratic_coeffs, correct_quadratic_coeffs + ), f"Quadratic coefficients have not been correctly generated" assert np.allclose( - constant, correct_constant), f'Constant coefficient have not been correctly generated' + constant, correct_constant + ), f"Constant coefficient have not been correctly generated" # Exception case - generating terms beyond quadratic order # Define hamiltonian attributes - terms_exc = [PauliOp('Z',(0,)), PauliOp('ZZ',(0,1)), PauliOp('ZZ',(0,2)), - PauliOp('ZZ',(1,2)), PauliOp('ZZZ',(1,2,3))] - coefficients_exc = [1,0.5,0.5,0.5,3] + terms_exc = [ + PauliOp("Z", (0,)), + PauliOp("ZZ", (0, 1)), + PauliOp("ZZ", (0, 2)), + PauliOp("ZZ", (1, 2)), + PauliOp("ZZZ", (1, 2, 3)), + ] + coefficients_exc = [1, 0.5, 0.5, 0.5, 3] constant_exc = 2 # Test the exception is raised - Attempt construction of Hamiltonian with self.assertRaises(NotImplementedError) as context: - hamiltonian_exc = Hamiltonian(terms_exc,coefficients_exc,constant_exc) + hamiltonian_exc = Hamiltonian(terms_exc, coefficients_exc, constant_exc) # Check exception message - self.assertEqual("Hamiltonian only supports Linear and Quadratic terms", str(context.exception)) - + self.assertEqual( + "Hamiltonian only supports Linear and Quadratic terms", + str(context.exception), + ) + def test_hamiltonian_str(self): """ Tests the function that constructs a string representation of the Hamiltonian object. @@ -651,8 +859,8 @@ def test_hamiltonian_str(self): # Define Pauli terms singlet_indices = [(i,) for i in range(n_qubits)] pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - linear_terms = [PauliOp('Z', indices) for indices in singlet_indices] - quadratic_terms = [PauliOp('ZZ', indices) for indices in pair_indices] + linear_terms = [PauliOp("Z", indices) for indices in singlet_indices] + quadratic_terms = [PauliOp("ZZ", indices) for indices in pair_indices] terms = linear_terms + quadratic_terms @@ -670,10 +878,12 @@ def test_hamiltonian_str(self): string_rep = hamiltonian.__str__() # Correct string representation - correct_string_rep = '-1*Z_{0} + -1*Z_{1} + -1*Z_{2} + 0.5*Z_{0}Z_{1} + 0.5*Z_{0}Z_{2} + 0.5*Z_{1}Z_{2} + 2' + correct_string_rep = "-1*Z_{0} + -1*Z_{1} + -1*Z_{2} + 0.5*Z_{0}Z_{1} + 0.5*Z_{0}Z_{2} + 0.5*Z_{1}Z_{2} + 2" # Test the obtained string representation - assert string_rep == correct_string_rep, f'Hamiltonian string representation was incorrectly constructed' + assert ( + string_rep == correct_string_rep + ), f"Hamiltonian string representation was incorrectly constructed" def test_hamiltonian_len(self): """ @@ -690,15 +900,13 @@ def test_hamiltonian_len(self): for n_qubits in range(3, 10): # Compute correct lengths - correct_lengths.append(n_qubits + n_qubits*(n_qubits-1)/2) + correct_lengths.append(n_qubits + n_qubits * (n_qubits - 1) / 2) # Define Pauli terms singlet_indices = [(i,) for i in range(n_qubits)] pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - linear_terms = [PauliOp('Z', indices) - for indices in singlet_indices] - quadratic_terms = [PauliOp('ZZ', indices) - for indices in pair_indices] + linear_terms = [PauliOp("Z", indices) for indices in singlet_indices] + quadratic_terms = [PauliOp("ZZ", indices) for indices in pair_indices] terms = linear_terms + quadratic_terms @@ -718,7 +926,8 @@ def test_hamiltonian_len(self): # Test that computed lengths are correct assert np.allclose( - lengths, correct_lengths), f'Hamiltonian lengths are incorrectly computed' + lengths, correct_lengths + ), f"Hamiltonian lengths are incorrectly computed" def test_hamiltonian_expression(self): """ @@ -733,8 +942,8 @@ def test_hamiltonian_expression(self): # Define Pauli terms singlet_indices = [(i,) for i in range(n_qubits)] pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - linear_terms = [PauliOp('Z', indices) for indices in singlet_indices] - quadratic_terms = [PauliOp('ZZ', indices) for indices in pair_indices] + linear_terms = [PauliOp("Z", indices) for indices in singlet_indices] + quadratic_terms = [PauliOp("ZZ", indices) for indices in pair_indices] terms = linear_terms + quadratic_terms @@ -755,15 +964,18 @@ def test_hamiltonian_expression(self): correct_sym_rep = Symbol(str(constant)) for ind, coeff in enumerate(linear_coeffs): - correct_sym_rep += Symbol(str(coeff)+'Z'+'_{'+str(ind)+'}') + correct_sym_rep += Symbol(str(coeff) + "Z" + "_{" + str(ind) + "}") for ind, coeff in enumerate(quadratic_coeffs): i, j = pair_indices[ind] - correct_sym_rep += Symbol(str(coeff) + - 'Z'+'_{'+str(i)+'}'+'Z'+'_{'+str(j)+'}') + correct_sym_rep += Symbol( + str(coeff) + "Z" + "_{" + str(i) + "}" + "Z" + "_{" + str(j) + "}" + ) # Test if string representation was correctly generated - assert sym_rep == correct_sym_rep, f'Symbolic representation was incorrectly generated' + assert ( + sym_rep == correct_sym_rep + ), f"Symbolic representation was incorrectly generated" def test_hamiltonian_add(self): """ @@ -776,32 +988,33 @@ def test_hamiltonian_add(self): n_qubits = 4 # Define the first Hamiltonian - pair_indices = [(i, j) for j in range(n_qubits-1) for i in range(j)] - input_terms = [PauliOp('ZZ', indices) for indices in pair_indices] + pair_indices = [(i, j) for j in range(n_qubits - 1) for i in range(j)] + input_terms = [PauliOp("ZZ", indices) for indices in pair_indices] quadratic_coeffs = [0.5 for _ in range(len(pair_indices))] input_coefficients = quadratic_coeffs input_constant = 2 - hamiltonian = Hamiltonian( - input_terms, input_coefficients, input_constant) + hamiltonian = Hamiltonian(input_terms, input_coefficients, input_constant) # Define the other Hamiltonian singlet_indices = [(i,) for i in range(n_qubits)] pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - linear_terms = [PauliOp('Z', indices) for indices in singlet_indices] - quadratic_terms = [PauliOp('ZZ', indices) for indices in pair_indices] + linear_terms = [PauliOp("Z", indices) for indices in singlet_indices] + quadratic_terms = [PauliOp("ZZ", indices) for indices in pair_indices] other_input_terms = linear_terms + quadratic_terms linear_coeffs = [-1 for _ in range(len(singlet_indices))] - quadratic_coeffs = [0.5 for _ in range( - int((n_qubits-1)*(n_qubits-2)/2))] + [1 for _ in range(n_qubits-1)] + quadratic_coeffs = [ + 0.5 for _ in range(int((n_qubits - 1) * (n_qubits - 2) / 2)) + ] + [1 for _ in range(n_qubits - 1)] other_input_coefficients = linear_coeffs + quadratic_coeffs other_input_constant = 0 other_hamiltonian = Hamiltonian( - other_input_terms, other_input_coefficients, other_input_constant) + other_input_terms, other_input_coefficients, other_input_constant + ) # Add hamiltonians hamiltonian.__add__(other_hamiltonian) @@ -812,8 +1025,10 @@ def test_hamiltonian_add(self): constant = hamiltonian.constant # Create Hamiltonian dictionary - To be removed upon implementation of _simplify() - hamiltonian_dict = {term.qubit_indices: coeff for term, - coeff in zip(hamiltonian.terms, hamiltonian.coeffs)} + hamiltonian_dict = { + term.qubit_indices: coeff + for term, coeff in zip(hamiltonian.terms, hamiltonian.coeffs) + } # Correct terms, coefficients and constants correct_terms = input_terms + other_input_terms @@ -821,8 +1036,10 @@ def test_hamiltonian_add(self): correct_constant = input_constant + other_input_constant # Create Hamiltonian dictionary for correct Hamiltonian - To be removed upon implementation of _simplify() - correct_hamiltonian_dict = {term.qubit_indices: coeff for term, coeff in zip( - input_terms, input_coefficients)} + correct_hamiltonian_dict = { + term.qubit_indices: coeff + for term, coeff in zip(input_terms, input_coefficients) + } # Add terms and coefficients from the other hamiltonian for term, coeff in zip(other_input_terms, other_input_coefficients): @@ -836,8 +1053,12 @@ def test_hamiltonian_add(self): correct_hamiltonian_dict[term.qubit_indices] += coeff # Test if Hamiltonians were added correctly - assert hamiltonian_dict == correct_hamiltonian_dict, f'Hamiltonian adder did not yield correct terms and/or coefficients' - assert np.allclose(constant, correct_constant), f'Hamiltonian adder did not yield correct constant' + assert ( + hamiltonian_dict == correct_hamiltonian_dict + ), f"Hamiltonian adder did not yield correct terms and/or coefficients" + assert np.allclose( + constant, correct_constant + ), f"Hamiltonian adder did not yield correct constant" def test_hamiltonian_squared(self): """ @@ -854,8 +1075,8 @@ def test_hamiltonian_squared(self): # Define Pauli terms singlet_indices = [(i,) for i in range(n_qubits)] pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - linear_terms = [PauliOp('Z', indices) for indices in singlet_indices] - quadratic_terms = [PauliOp('ZZ', indices) for indices in pair_indices] + linear_terms = [PauliOp("Z", indices) for indices in singlet_indices] + quadratic_terms = [PauliOp("ZZ", indices) for indices in pair_indices] terms = linear_terms + quadratic_terms # Define coefficients and constant @@ -875,23 +1096,34 @@ def test_hamiltonian_squared(self): constant_sq = hamiltonian_sq.constant # Correct Hamiltonian squared attributes - correct_terms_sq = [PauliOp('ZZ', (0, 1)), PauliOp('Z', (1,)), - PauliOp('ZZ', (0, 1)), PauliOp('Z', (0,)), - PauliOp('Z', (1,)), PauliOp('Z', (0,)), - PauliOp('Z', (0,)), PauliOp('Z', (1,)), - PauliOp('ZZ', (0, 1))] + correct_terms_sq = [ + PauliOp("ZZ", (0, 1)), + PauliOp("Z", (1,)), + PauliOp("ZZ", (0, 1)), + PauliOp("Z", (0,)), + PauliOp("Z", (1,)), + PauliOp("Z", (0,)), + PauliOp("Z", (0,)), + PauliOp("Z", (1,)), + PauliOp("ZZ", (0, 1)), + ] correct_coefficients_sq = [1, -0.5, 1, -0.5, -0.5, -0.5, -4, -4, 2] - correct_constant_sq = 4 + n_qubits * \ - (-1)**2 + n_qubits*(n_qubits-1)/2*(0.5)**2 + correct_constant_sq = ( + 4 + n_qubits * (-1) ** 2 + n_qubits * (n_qubits - 1) / 2 * (0.5) ** 2 + ) # Test if Hamiltonian squared was correctly computed - assert terms_sq == correct_terms_sq, f'Hamiltonian squared did not yield correct terms' + assert ( + terms_sq == correct_terms_sq + ), f"Hamiltonian squared did not yield correct terms" assert np.allclose( - coefficients_sq, correct_coefficients_sq), f'Hamiltonian squared did not yield correct coefficients' + coefficients_sq, correct_coefficients_sq + ), f"Hamiltonian squared did not yield correct coefficients" assert np.allclose( - constant_sq, correct_constant_sq), f'Hamiltonian squared did not yield correct constant' + constant_sq, correct_constant_sq + ), f"Hamiltonian squared did not yield correct constant" # Second example @@ -900,9 +1132,12 @@ def test_hamiltonian_squared(self): # Define Pauli terms pair_indices = [(i, j) for j in range(n_qubits) for i in range(j)] - terms_strings = ['XX', 'YY'] - terms = [PauliOp(string, indices) - for indices in pair_indices for string in terms_strings] + terms_strings = ["XX", "YY"] + terms = [ + PauliOp(string, indices) + for indices in pair_indices + for string in terms_strings + ] # Define coefficients and constant coefficients = [1 for _ in range(len(terms))] @@ -919,17 +1154,25 @@ def test_hamiltonian_squared(self): constant_sq = hamiltonian_sq.constant # Correct Hamiltonian squared attributes - correct_terms_sq = [PauliOp('ZZ', (0, 1)), PauliOp( - 'ZZ', (0, 1)), PauliOp('XX', (0, 1)), PauliOp('YY', (0, 1))] + correct_terms_sq = [ + PauliOp("ZZ", (0, 1)), + PauliOp("ZZ", (0, 1)), + PauliOp("XX", (0, 1)), + PauliOp("YY", (0, 1)), + ] correct_coefficients_sq = [-1, -1, 4, 4] correct_constant_sq = 6 # Test if Hamiltonian squared was correctly computed - assert terms_sq == correct_terms_sq, f'Hamiltonian squared did not yield correct terms' + assert ( + terms_sq == correct_terms_sq + ), f"Hamiltonian squared did not yield correct terms" assert np.allclose( - coefficients_sq, correct_coefficients_sq), f'Hamiltonian squared did not yield correct coefficients' + coefficients_sq, correct_coefficients_sq + ), f"Hamiltonian squared did not yield correct coefficients" assert np.allclose( - constant_sq, correct_constant_sq), f'Hamiltonian squared did not yield correct constant' + constant_sq, correct_constant_sq + ), f"Hamiltonian squared did not yield correct constant" def test_classical_hamiltonian(self): """ @@ -943,14 +1186,16 @@ def test_classical_hamiltonian(self): n_nodes = 5 # Graph properties - input_edges = [(i,) for i in range(n_nodes)] + [(i, j) - for j in range(n_nodes) for i in range(j)] + input_edges = [(i,) for i in range(n_nodes)] + [ + (i, j) for j in range(n_nodes) for i in range(j) + ] input_weights = [-1 for _ in range(len(input_edges))] input_constant = 2 # Generate classical Hamiltonian and extract attributes cl_hamiltonian = Hamiltonian.classical_hamiltonian( - input_edges, input_weights, input_constant) + input_edges, input_weights, input_constant + ) terms = cl_hamiltonian.terms terms_indices = [term.qubit_indices for term in terms] @@ -958,44 +1203,59 @@ def test_classical_hamiltonian(self): constant = cl_hamiltonian.constant # Test that the generated Hamiltonian match the properties of the input graph - assert terms_indices == input_edges, f'Classical Hamiltonian terms did not match input graph edges' + assert ( + terms_indices == input_edges + ), f"Classical Hamiltonian terms did not match input graph edges" assert np.allclose( - coefficients, input_weights), f'Hamiltonian squared did not yield correct coefficients' + coefficients, input_weights + ), f"Hamiltonian squared did not yield correct coefficients" assert np.allclose( - constant, input_constant), f'Hamiltonian squared did not yield correct constant' + constant, input_constant + ), f"Hamiltonian squared did not yield correct constant" # Exception case - inserting coefficients that are not interegers or floats # Define hamiltonian attributes - terms_exc = [(0,1),(0,2),(1,2)] + terms_exc = [(0, 1), (0, 2), (1, 2)] constant_exc = 2 # Define different types of coefficients containing exceptions - coefficients_exc_types = [[-1j,1,-1j],[2,3,0.1*1j]] - + coefficients_exc_types = [[-1j, 1, -1j], [2, 3, 0.1 * 1j]] + # Check for every coefficient type for coefficients_exc in coefficients_exc_types: - + # Test the exception is raised - Attempt construction of Hamiltonian with self.assertRaises(ValueError) as context: - hamiltonian_exc = Hamiltonian.classical_hamiltonian(terms_exc,coefficients_exc,constant_exc) - + hamiltonian_exc = Hamiltonian.classical_hamiltonian( + terms_exc, coefficients_exc, constant_exc + ) + # Check exception message - self.assertEqual("Classical Hamiltonians only support Integer or Float coefficients", str(context.exception)) - + self.assertEqual( + "Classical Hamiltonians only support Integer or Float coefficients", + str(context.exception), + ) + # Exception case - generating terms beyond quadratic order # Define hamiltonian attributes - terms_exc = [(0,),(0,1),(0,2),(1,2),(1,2,3)] - coefficients_exc = [1,0.5,0.5,0.5,3] + terms_exc = [(0,), (0, 1), (0, 2), (1, 2), (1, 2, 3)] + coefficients_exc = [1, 0.5, 0.5, 0.5, 3] constant_exc = 2 # Test the exception is raised - Attempt construction of Hamiltonian with self.assertRaises(ValueError) as context: - hamiltonian_exc = Hamiltonian.classical_hamiltonian(terms_exc,coefficients_exc,constant_exc) + hamiltonian_exc = Hamiltonian.classical_hamiltonian( + terms_exc, coefficients_exc, constant_exc + ) # Check exception message - self.assertEqual("Hamiltonian only supports Linear and Quadratic terms", str(context.exception)) + self.assertEqual( + "Hamiltonian only supports Linear and Quadratic terms", + str(context.exception), + ) + if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/tests/test_optimizers.py b/tests/test_optimizers.py index 860675175..d7152fd5c 100644 --- a/tests/test_optimizers.py +++ b/tests/test_optimizers.py @@ -9,7 +9,12 @@ import numpy as np from scipy.optimize._minimize import MINIMIZE_METHODS -from openqaoa.qaoa_components import create_qaoa_variational_params, QAOADescriptor, PauliOp, Hamiltonian +from openqaoa.qaoa_components import ( + create_qaoa_variational_params, + QAOADescriptor, + PauliOp, + Hamiltonian, +) from openqaoa.utilities import X_mixer_hamiltonian from openqaoa.backends.qaoa_backend import get_qaoa_backend from openqaoa.backends import create_device @@ -19,188 +24,328 @@ from openqaoa.optimizers.logger_vqa import Logger from openqaoa.derivatives.qfim import qfim from openqaoa.problems import MinimumVertexCover + """ Unittest based testing of custom optimizers. """ -cost_hamiltonian_1 = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), PauliOp('ZZ', (0, 3)), PauliOp('Z', (2,)), PauliOp('Z', (1,))], [1, 1.1, 1.5, 2, -0.8], 0.8) +cost_hamiltonian_1 = Hamiltonian( + [ + PauliOp("ZZ", (0, 1)), + PauliOp("ZZ", (1, 2)), + PauliOp("ZZ", (0, 3)), + PauliOp("Z", (2,)), + PauliOp("Z", (1,)), + ], + [1, 1.1, 1.5, 2, -0.8], + 0.8, +) + class TestQAOACostBaseClass(unittest.TestCase): - def setUp(self): - - self.log = Logger({'func_evals': - { - 'history_update_bool': False, - 'best_update_string': 'HighestOnly' - }, - 'jac_func_evals': - { - 'history_update_bool': False, - 'best_update_string': 'HighestOnly' - }, - 'qfim_func_evals': - { - 'history_update_bool': False, - 'best_update_string': 'HighestOnly' - } - }, - { - 'root_nodes': ['func_evals', 'jac_func_evals', - 'qfim_func_evals'], - 'best_update_structure': [] - }) - - self.log.log_variables({'func_evals': 0, 'jac_func_evals': 0, 'qfim_func_evals': 0}) + + self.log = Logger( + { + "func_evals": { + "history_update_bool": False, + "best_update_string": "HighestOnly", + }, + "jac_func_evals": { + "history_update_bool": False, + "best_update_string": "HighestOnly", + }, + "qfim_func_evals": { + "history_update_bool": False, + "best_update_string": "HighestOnly", + }, + }, + { + "root_nodes": ["func_evals", "jac_func_evals", "qfim_func_evals"], + "best_update_structure": [], + }, + ) + + self.log.log_variables( + {"func_evals": 0, "jac_func_evals": 0, "qfim_func_evals": 0} + ) def __backend_params(self, cost_hamil, n_qubits): - """ Helper function to create a backend and a parameters onjects for testing. """ + """Helper function to create a backend and a parameters onjects for testing.""" mixer_hamil = X_mixer_hamiltonian(n_qubits=n_qubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - device = create_device('local','vectorized') - backend_obj_vectorized = get_qaoa_backend(qaoa_descriptor,device) - variate_params = create_qaoa_variational_params(qaoa_descriptor, 'standard', 'ramp') + device = create_device("local", "vectorized") + backend_obj_vectorized = get_qaoa_backend(qaoa_descriptor, device) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) return backend_obj_vectorized, variate_params - + def test_saving_feature(self): - """ Test save_intermediate in OptimizeVQA """ - backend_obj_vectorized, variate_params = self.__backend_params(cost_hamiltonian_1, 4) + """Test save_intermediate in OptimizeVQA""" + backend_obj_vectorized, variate_params = self.__backend_params( + cost_hamiltonian_1, 4 + ) niter = 5 grad_stepsize = 0.0001 stepsize = 0.001 params_array = variate_params.raw().copy() - jac = derivative(backend_obj_vectorized, variate_params, self.log, - 'gradient', 'finite_difference', - {'stepsize': grad_stepsize}) + jac = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "gradient", + "finite_difference", + {"stepsize": grad_stepsize}, + ) # Optimize - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, - optimizer_dict = {'method': 'vgd', - 'tol': 10**(-9), - 'jac': jac, - 'maxiter': niter, - 'optimizer_options' : - {'stepsize': stepsize}, - 'save_intermediate': True - }) + vector_optimizer = get_optimizer( + backend_obj_vectorized, + variate_params, + optimizer_dict={ + "method": "vgd", + "tol": 10 ** (-9), + "jac": jac, + "maxiter": niter, + "optimizer_options": {"stepsize": stepsize}, + "save_intermediate": True, + }, + ) vector_optimizer() def test_scipy_optimizers_global(self): - " Check that final value of all scipy MINIMIZE_METHODS optimizers agrees with pre-computed optimized value." + "Check that final value of all scipy MINIMIZE_METHODS optimizers agrees with pre-computed optimized value." # Create problem instance, cost function, and gradient functions - backend_obj_vectorized, variate_params = self.__backend_params(cost_hamiltonian_1, 4) + backend_obj_vectorized, variate_params = self.__backend_params( + cost_hamiltonian_1, 4 + ) niter = 5 stepsize = 0.001 - y_precomp = [-2.4345058914425626, -2.5889608823632795, -2.588960865651421, -2.5889608823632786, -2.5889608823632795, -2.588960882363273, -2.5889608823632786, - 0.7484726235465329, -2.588960882363272, -2.588960882363281, -2.5889608823632786, -2.5889608823632795, -2.5889608823632786, -2.5889608823632786] + y_precomp = [ + -2.4345058914425626, + -2.5889608823632795, + -2.588960865651421, + -2.5889608823632786, + -2.5889608823632795, + -2.588960882363273, + -2.5889608823632786, + 0.7484726235465329, + -2.588960882363272, + -2.588960882363281, + -2.5889608823632786, + -2.5889608823632795, + -2.5889608823632786, + -2.5889608823632786, + ] optimizer_dicts = [] for method in MINIMIZE_METHODS: optimizer_dicts.append( - {'method': method, 'maxiter': niter, 'tol': 10**(-9)}) + {"method": method, "maxiter": niter, "tol": 10 ** (-9)} + ) for i, optimizer_dict in enumerate(optimizer_dicts): - optimizer_dict['jac'] = derivative(backend_obj_vectorized, - variate_params, self.log, 'gradient', 'finite_difference') - optimizer_dict['hess'] = derivative(backend_obj_vectorized, - variate_params, self.log, 'hessian', 'finite_difference') + optimizer_dict["jac"] = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "gradient", + "finite_difference", + ) + optimizer_dict["hess"] = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "hessian", + "finite_difference", + ) # Optimize vector_optimizer = get_optimizer( - backend_obj_vectorized, variate_params, optimizer_dict=optimizer_dict) + backend_obj_vectorized, variate_params, optimizer_dict=optimizer_dict + ) vector_optimizer() - y_opt = vector_optimizer.qaoa_result.intermediate['cost'] + y_opt = vector_optimizer.qaoa_result.intermediate["cost"] - assert np.isclose(y_precomp[i], y_opt[-1], rtol=1e-04, - atol=1e-04), f"{optimizer_dict['method']} failed the test." + assert np.isclose( + y_precomp[i], y_opt[-1], rtol=1e-04, atol=1e-04 + ), f"{optimizer_dict['method']} failed the test." def test_gradient_optimizers_global(self): - " Check that final value of all implemented gradient optimizers agrees with pre-computed optimized value." + "Check that final value of all implemented gradient optimizers agrees with pre-computed optimized value." - backend_obj_vectorized, variate_params = self.__backend_params(cost_hamiltonian_1, 4) + backend_obj_vectorized, variate_params = self.__backend_params( + cost_hamiltonian_1, 4 + ) niter = 10 stepsize = 0.001 # pre-computed final optimized costs - y_precomp = [-2.4212581335011456, -2.4246393953483825, - - 2.47312715451289, -2.5031221706241906] + y_precomp = [ + -2.4212581335011456, + -2.4246393953483825, + -2.47312715451289, + -2.5031221706241906, + ] optimizer_dicts = [] - optimizer_dicts.append({'method': 'vgd', 'tol': 10**(-9), 'jac': 'finite_difference', 'maxiter': niter, - 'optimizer_options' : {'stepsize': stepsize}}) - optimizer_dicts.append({'method': 'newton', 'tol': 10**(-9), 'jac': 'finite_difference', 'hess': 'finite_difference', 'maxiter': niter, - 'optimizer_options' : {'stepsize': stepsize}}) - optimizer_dicts.append({'method': 'natural_grad_descent', 'tol': 10**(-9), 'jac': 'finite_difference', 'maxiter': niter, - 'optimizer_options' : {'stepsize': 0.01}}) - optimizer_dicts.append({'method': 'rmsprop', 'tol': 10**(-9), 'jac': 'finite_difference', 'maxiter': niter, - 'optimizer_options' : {'stepsize': stepsize, 'decay': 0.9, 'eps': 1e-07}}) + optimizer_dicts.append( + { + "method": "vgd", + "tol": 10 ** (-9), + "jac": "finite_difference", + "maxiter": niter, + "optimizer_options": {"stepsize": stepsize}, + } + ) + optimizer_dicts.append( + { + "method": "newton", + "tol": 10 ** (-9), + "jac": "finite_difference", + "hess": "finite_difference", + "maxiter": niter, + "optimizer_options": {"stepsize": stepsize}, + } + ) + optimizer_dicts.append( + { + "method": "natural_grad_descent", + "tol": 10 ** (-9), + "jac": "finite_difference", + "maxiter": niter, + "optimizer_options": {"stepsize": 0.01}, + } + ) + optimizer_dicts.append( + { + "method": "rmsprop", + "tol": 10 ** (-9), + "jac": "finite_difference", + "maxiter": niter, + "optimizer_options": {"stepsize": stepsize, "decay": 0.9, "eps": 1e-07}, + } + ) for i, optimizer_dict in enumerate(optimizer_dicts): # Optimize - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, optimizer_dict=optimizer_dict) + vector_optimizer = get_optimizer( + backend_obj_vectorized, variate_params, optimizer_dict=optimizer_dict + ) vector_optimizer() - y_opt = vector_optimizer.qaoa_result.intermediate['cost'] + y_opt = vector_optimizer.qaoa_result.intermediate["cost"] - assert np.isclose(y_precomp[i], y_opt[-1], rtol=1e-04, atol=1e-04), f"{optimizer_dict['method']} method failed the test." + assert np.isclose( + y_precomp[i], y_opt[-1], rtol=1e-04, atol=1e-04 + ), f"{optimizer_dict['method']} method failed the test." def test_gradient_optimizers_cans(self): n_qubits = 10 graph = nw.circulant_graph(n_qubits, [1]) cost_hamil = MinimumVertexCover(graph, field=1, penalty=10).qubo.hamiltonian - backend_obj_vectorized, variate_params = self.__backend_params(cost_hamil, n_qubits) - - optimizer_list = [ { 'method':method, 'jac':'param_shift', 'maxiter':1000, - 'optimizer_options':{'stepsize': 0.0001,'n_shots_min':5, 'n_shots_max':200, 'n_shots_budget': 1000} } - for method in ['cans', 'icans'] ] + backend_obj_vectorized, variate_params = self.__backend_params( + cost_hamil, n_qubits + ) + + optimizer_list = [ + { + "method": method, + "jac": "param_shift", + "maxiter": 1000, + "optimizer_options": { + "stepsize": 0.0001, + "n_shots_min": 5, + "n_shots_max": 200, + "n_shots_budget": 1000, + }, + } + for method in ["cans", "icans"] + ] for optimizer_dict in optimizer_list: # optimize qaoa - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, optimizer_dict=optimizer_dict) + vector_optimizer = get_optimizer( + backend_obj_vectorized, variate_params, optimizer_dict=optimizer_dict + ) vector_optimizer() # check that the final cost is the optimal value - assert int(vector_optimizer.qaoa_result.most_probable_states['bitstring_energy']) == 5, '{} failed the test.'.format(optimizer_dict['method']) + assert ( + int( + vector_optimizer.qaoa_result.most_probable_states[ + "bitstring_energy" + ] + ) + == 5 + ), "{} failed the test.".format(optimizer_dict["method"]) # check that the number of shots are correct n_shots_used = np.array(vector_optimizer.qaoa_result.n_shots) - assert np.sum(np.int0(n_shots_used<5) + np.int8(n_shots_used>200))==0 , 'Optimizer {} did not use the correct number of shots.'.format(optimizer_dict['method']) + assert ( + np.sum(np.int0(n_shots_used < 5) + np.int8(n_shots_used > 200)) == 0 + ), "Optimizer {} did not use the correct number of shots.".format( + optimizer_dict["method"] + ) # check n_shots_budget worked - assert np.sum(20*n_shots_used[:-1].T[0] + 40*n_shots_used[:-1].T[1]) < 1000 and np.sum(20*n_shots_used.T[0] + 40*n_shots_used.T[1]) >= 1000, \ - 'Optimizer {} did not use the correct number of shots.'.format(optimizer_dict['method']) - - assert np.sum(n_shots_used<5) == 0 , 'Optimizer {} did not use the correct number of shots.'.format(optimizer_dict['method']) - + assert ( + np.sum(20 * n_shots_used[:-1].T[0] + 40 * n_shots_used[:-1].T[1]) < 1000 + and np.sum(20 * n_shots_used.T[0] + 40 * n_shots_used.T[1]) >= 1000 + ), "Optimizer {} did not use the correct number of shots.".format( + optimizer_dict["method"] + ) + + assert ( + np.sum(n_shots_used < 5) == 0 + ), "Optimizer {} did not use the correct number of shots.".format( + optimizer_dict["method"] + ) def test_gradient_descent_step(self): - ''' + """ Check that implemented gradient descent takes the first two steps correctly. - ''' - - backend_obj_vectorized, variate_params = self.__backend_params(cost_hamiltonian_1, 4) + """ + + backend_obj_vectorized, variate_params = self.__backend_params( + cost_hamiltonian_1, 4 + ) niter = 5 grad_stepsize = 0.0001 stepsize = 0.001 params_array = variate_params.raw().copy() - jac = derivative(backend_obj_vectorized, variate_params, self.log, - 'gradient', 'finite_difference', - {'stepsize': grad_stepsize}) + jac = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "gradient", + "finite_difference", + {"stepsize": grad_stepsize}, + ) # Optimize - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, optimizer_dict={ - 'method': 'vgd', 'tol': 10**(-9), 'jac': jac, 'maxiter': niter, - 'optimizer_options' : {'stepsize': stepsize}}) + vector_optimizer = get_optimizer( + backend_obj_vectorized, + variate_params, + optimizer_dict={ + "method": "vgd", + "tol": 10 ** (-9), + "jac": jac, + "maxiter": niter, + "optimizer_options": {"stepsize": stepsize}, + }, + ) vector_optimizer() - y_opt = vector_optimizer.qaoa_result.intermediate['cost'][1:4] + y_opt = vector_optimizer.qaoa_result.intermediate["cost"][1:4] # Stepwise optimize def step(x0): - x1 = x0 - stepsize*jac(x0) + x1 = x0 - stepsize * jac(x0) variate_params.update_from_raw(x1) @@ -218,34 +363,55 @@ def step(x0): assert np.isclose(yi, y_opt[i], rtol=1e-05, atol=1e-05) def test_newton_step(self): - ''' + """ Check that implemented Newton descent takes the first two steps correctly. - ''' - - backend_obj_vectorized, variate_params = self.__backend_params(cost_hamiltonian_1, 4) + """ + + backend_obj_vectorized, variate_params = self.__backend_params( + cost_hamiltonian_1, 4 + ) niter = 5 grad_stepsize = 0.0001 stepsize = 0.001 params_array = variate_params.raw().copy() - jac = derivative(backend_obj_vectorized, variate_params, self.log, - 'gradient', 'finite_difference', - {'stepsize': grad_stepsize}) - hess = derivative(backend_obj_vectorized, variate_params, self.log, - 'hessian', 'finite_difference', - {'stepsize': grad_stepsize}) + jac = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "gradient", + "finite_difference", + {"stepsize": grad_stepsize}, + ) + hess = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "hessian", + "finite_difference", + {"stepsize": grad_stepsize}, + ) # Optimize - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, optimizer_dict={ - 'method': 'newton', 'tol': 10**(-9), 'jac': jac, 'hess': hess, 'maxiter': niter, - 'optimizer_options' : {'stepsize': stepsize}}) + vector_optimizer = get_optimizer( + backend_obj_vectorized, + variate_params, + optimizer_dict={ + "method": "newton", + "tol": 10 ** (-9), + "jac": jac, + "hess": hess, + "maxiter": niter, + "optimizer_options": {"stepsize": stepsize}, + }, + ) vector_optimizer() - y_opt = vector_optimizer.qaoa_result.intermediate['cost'][1:4] + y_opt = vector_optimizer.qaoa_result.intermediate["cost"][1:4] # Stepwise optimize def step(x0): scaled_gradient = np.linalg.solve(hess(x0), jac(x0)) - x1 = x0 - stepsize*scaled_gradient + x1 = x0 - stepsize * scaled_gradient variate_params.update_from_raw(x1) return [x1, np.real(backend_obj_vectorized.expectation(variate_params))] @@ -261,32 +427,47 @@ def step(x0): assert np.isclose(yi, y_opt[i], rtol=1e-05, atol=1e-05) def test_natural_gradient_descent_step(self): - ''' + """ Check that implemented natural gradient descent takes the first two steps correctly. - ''' + """ - backend_obj_vectorized, variate_params = self.__backend_params(cost_hamiltonian_1, 4) + backend_obj_vectorized, variate_params = self.__backend_params( + cost_hamiltonian_1, 4 + ) niter = 5 grad_stepsize = 0.0001 stepsize = 0.001 params_array = variate_params.raw().copy() - jac = derivative(backend_obj_vectorized, variate_params, self.log, - 'gradient', 'finite_difference', - {'stepsize': grad_stepsize}) + jac = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "gradient", + "finite_difference", + {"stepsize": grad_stepsize}, + ) # Optimize - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, optimizer_dict={ - 'method': 'natural_grad_descent', 'tol': 10**(-9), 'jac': jac, 'maxiter': niter, - 'optimizer_options' : {'stepsize': stepsize}}) + vector_optimizer = get_optimizer( + backend_obj_vectorized, + variate_params, + optimizer_dict={ + "method": "natural_grad_descent", + "tol": 10 ** (-9), + "jac": jac, + "maxiter": niter, + "optimizer_options": {"stepsize": stepsize}, + }, + ) vector_optimizer() - y_opt = vector_optimizer.qaoa_result.intermediate['cost'][1:4] + y_opt = vector_optimizer.qaoa_result.intermediate["cost"][1:4] # Stepwise optimize def step(x0): qfim_ = qfim(backend_obj_vectorized, variate_params, self.log) scaled_gradient = np.linalg.solve(qfim_(x0), jac(x0)) - x1 = x0 - stepsize*scaled_gradient + x1 = x0 - stepsize * scaled_gradient variate_params.update_from_raw(x1) return [x1, np.real(backend_obj_vectorized.expectation(variate_params))] @@ -302,42 +483,61 @@ def step(x0): assert np.isclose(yi, y_opt[i], rtol=1e-05, atol=1e-05) def test_rmsprop_step(self): - ''' + """ Check that implemented RMSProp takes the first two steps correctly. - ''' - - backend_obj_vectorized, variate_params = self.__backend_params(cost_hamiltonian_1, 4) + """ + + backend_obj_vectorized, variate_params = self.__backend_params( + cost_hamiltonian_1, 4 + ) niter = 5 grad_stepsize = 0.0001 stepsize = 0.001 params_array = variate_params.raw().copy() - jac = derivative(backend_obj_vectorized, variate_params, self.log, - 'gradient', 'finite_difference', - {'stepsize': grad_stepsize}) + jac = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "gradient", + "finite_difference", + {"stepsize": grad_stepsize}, + ) decay = 0.9 eps = 1e-07 # Optimize - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, optimizer_dict={ - 'method': 'rmsprop', 'tol': 10**(-9), 'jac': jac, 'maxiter': niter, - 'optimizer_options' : {'stepsize': stepsize, 'decay': decay, 'eps': eps}}) - + vector_optimizer = get_optimizer( + backend_obj_vectorized, + variate_params, + optimizer_dict={ + "method": "rmsprop", + "tol": 10 ** (-9), + "jac": jac, + "maxiter": niter, + "optimizer_options": {"stepsize": stepsize, "decay": decay, "eps": eps}, + }, + ) + vector_optimizer() - y_opt = vector_optimizer.qaoa_result.intermediate['cost'][1:4] + y_opt = vector_optimizer.qaoa_result.intermediate["cost"][1:4] # Stepwise optimize def step(x0, sqgrad0): - sqgrad = decay*sqgrad0 + (1-decay)*jac(x0)**2 - x1 = x0 - stepsize*jac(x0)/(np.sqrt(sqgrad) + eps) + sqgrad = decay * sqgrad0 + (1 - decay) * jac(x0) ** 2 + x1 = x0 - stepsize * jac(x0) / (np.sqrt(sqgrad) + eps) variate_params.update_from_raw(x1) - return [x1, np.real(backend_obj_vectorized.expectation(variate_params)), sqgrad0] + return [ + x1, + np.real(backend_obj_vectorized.expectation(variate_params)), + sqgrad0, + ] x0 = params_array variate_params.update_from_raw(x0) y0 = backend_obj_vectorized.expectation(variate_params) - sqgrad0 = jac(x0)**2 + sqgrad0 = jac(x0) ** 2 [x1, y1, sqgrad1] = step(x0, sqgrad0) [x2, y2, sqgrad2] = step(x1, sqgrad1) @@ -345,47 +545,63 @@ def step(x0, sqgrad0): for i, yi in enumerate(y): assert np.isclose(yi, y_opt[i], rtol=1e-05, atol=1e-05) - + def test_optimize_loop_crash(self): - + """ This tests that the optimization loop doesnt crash silently. An Exception gets raised. """ - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), PauliOp( - 'ZZ', (0, 3)), PauliOp('Z', (2,)), PauliOp('Z', (1,))], [1, 1.1, 1.5, 2, -0.8], 0.8) + + cost_hamil = Hamiltonian( + [ + PauliOp("ZZ", (0, 1)), + PauliOp("ZZ", (1, 2)), + PauliOp("ZZ", (0, 3)), + PauliOp("Z", (2,)), + PauliOp("Z", (1,)), + ], + [1, 1.1, 1.5, 2, -0.8], + 0.8, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=4) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=2) - device = create_device('local','vectorized') - backend_obj_vectorized = get_qaoa_backend(qaoa_descriptor,device) + device = create_device("local", "vectorized") + backend_obj_vectorized = get_qaoa_backend(qaoa_descriptor, device) variate_params = create_qaoa_variational_params( - qaoa_descriptor, 'standard', 'ramp') + qaoa_descriptor, "standard", "ramp" + ) niter = 5 # Optimize - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, - optimizer_dict = {'method': 'nelder-mead', - 'maxiter': niter, - }) - vector_optimizer.vqa.expectation = Mock(side_effect = Exception("Error!")) + vector_optimizer = get_optimizer( + backend_obj_vectorized, + variate_params, + optimizer_dict={ + "method": "nelder-mead", + "maxiter": niter, + }, + ) + vector_optimizer.vqa.expectation = Mock(side_effect=Exception("Error!")) self.assertRaises(Exception, lambda: vector_optimizer.optimize()) - + # Check that QAOA Result exists self.assertEqual(type(vector_optimizer.qaoa_result), QAOAResult) - + @classmethod def tearDownClass(cls): - - output_csv = ['oq_saved_info_job_ids.csv', 'oq_saved_info_param_log.csv'] + + output_csv = ["oq_saved_info_job_ids.csv", "oq_saved_info_param_log.csv"] for each_csv in output_csv: - if (os.path.exists(each_csv)): + if os.path.exists(each_csv): os.remove(each_csv) else: - raise FileNotFoundError('Unable to remove the generated csv file: {}'.format(each_csv)) - + raise FileNotFoundError( + "Unable to remove the generated csv file: {}".format(each_csv) + ) + if __name__ == "__main__": with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=PendingDeprecationWarning) + warnings.simplefilter("ignore", category=PendingDeprecationWarning) unittest.main() diff --git a/tests/test_optimizers_pennylane.py b/tests/test_optimizers_pennylane.py index c4667b5fe..360987fc9 100644 --- a/tests/test_optimizers_pennylane.py +++ b/tests/test_optimizers_pennylane.py @@ -9,10 +9,17 @@ import openqaoa.optimizers.pennylane as pl from openqaoa.backends import create_device from openqaoa.optimizers.training_vqa import PennyLaneOptimizer -from openqaoa.optimizers.pennylane.optimization_methods_pennylane import AVAILABLE_OPTIMIZERS +from openqaoa.optimizers.pennylane.optimization_methods_pennylane import ( + AVAILABLE_OPTIMIZERS, +) from openqaoa.derivatives.derivative_functions import derivative from openqaoa.optimizers.logger_vqa import Logger -from openqaoa.qaoa_components import create_qaoa_variational_params, QAOADescriptor, PauliOp, Hamiltonian +from openqaoa.qaoa_components import ( + create_qaoa_variational_params, + QAOADescriptor, + PauliOp, + Hamiltonian, +) from openqaoa.utilities import X_mixer_hamiltonian from openqaoa.backends.qaoa_backend import get_qaoa_backend from openqaoa.optimizers import get_optimizer @@ -20,87 +27,101 @@ from openqaoa.problems import QUBO, MinimumVertexCover -#list of optimizers to test, pennylane optimizers +# list of optimizers to test, pennylane optimizers list_optimizers = PennyLaneOptimizer.PENNYLANE_OPTIMIZERS -#create a problem +# create a problem g = nx.circulant_graph(4, [1]) -problem = MinimumVertexCover(g, field =1.0, penalty=10) +problem = MinimumVertexCover(g, field=1.0, penalty=10) qubo_problem_1 = problem.qubo qubo_problem_2 = QUBO.random_instance(5) qubo_problem_3 = QUBO.random_instance(6) class TestPennylaneOptimizers(unittest.TestCase): - def setUp(self): - - self.log = Logger({'func_evals': - { - 'history_update_bool': False, - 'best_update_string': 'HighestOnly' - }, - 'jac_func_evals': - { - 'history_update_bool': False, - 'best_update_string': 'HighestOnly' - }, - 'qfim_func_evals': - { - 'history_update_bool': False, - 'best_update_string': 'HighestOnly' - } - }, - { - 'root_nodes': ['func_evals', 'jac_func_evals', - 'qfim_func_evals'], - 'best_update_structure': [] - }) - - self.log.log_variables({'func_evals': 0, 'jac_func_evals': 0, 'qfim_func_evals': 0}) + + self.log = Logger( + { + "func_evals": { + "history_update_bool": False, + "best_update_string": "HighestOnly", + }, + "jac_func_evals": { + "history_update_bool": False, + "best_update_string": "HighestOnly", + }, + "qfim_func_evals": { + "history_update_bool": False, + "best_update_string": "HighestOnly", + }, + }, + { + "root_nodes": ["func_evals", "jac_func_evals", "qfim_func_evals"], + "best_update_structure": [], + }, + ) + + self.log.log_variables( + {"func_evals": 0, "jac_func_evals": 0, "qfim_func_evals": 0} + ) def _run_method_workflows(self, method, problem): - " helper function to run the test for any method using workflows" + "helper function to run the test for any method using workflows" q = QAOA() - q.set_classical_optimizer(method=method, maxiter=3, jac='finite_difference') - q.compile(problem) + q.set_classical_optimizer(method=method, maxiter=3, jac="finite_difference") + q.compile(problem) q.optimize() - assert len(q.result.most_probable_states['solutions_bitstrings'][0]) > 0 + assert len(q.result.most_probable_states["solutions_bitstrings"][0]) > 0 def _run_method_manual(self, method, problem): - " helper function tu run the test for any method using manual mode" + "helper function tu run the test for any method using manual mode" cost_hamil = problem.hamiltonian mixer_hamil = X_mixer_hamiltonian(n_qubits=problem.n) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=2) - device = create_device('local','vectorized') - backend_obj_vectorized = get_qaoa_backend(qaoa_descriptor,device) - variate_params = create_qaoa_variational_params(qaoa_descriptor, 'standard', 'ramp') + device = create_device("local", "vectorized") + backend_obj_vectorized = get_qaoa_backend(qaoa_descriptor, device) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) niter = 5 grad_stepsize = 0.0001 stepsize = 0.001 # declare needed functions - jac = derivative(backend_obj_vectorized, variate_params, self.log, - 'gradient', 'finite_difference', - {'stepsize': grad_stepsize}) - qfim = Qfim(backend_obj_vectorized, variate_params, self.log) - + jac = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "gradient", + "finite_difference", + {"stepsize": grad_stepsize}, + ) + qfim = Qfim(backend_obj_vectorized, variate_params, self.log) # Optimize - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, optimizer_dict={ - 'method': method, 'jac': jac, 'maxiter': niter, 'qfim': qfim, - 'optimizer_options' : {'stepsize': stepsize}}) + vector_optimizer = get_optimizer( + backend_obj_vectorized, + variate_params, + optimizer_dict={ + "method": method, + "jac": jac, + "maxiter": niter, + "qfim": qfim, + "optimizer_options": {"stepsize": stepsize}, + }, + ) vector_optimizer() # saving the results results = vector_optimizer.qaoa_result - assert len(results.most_probable_states['solutions_bitstrings'][0]) == problem.n + assert len(results.most_probable_states["solutions_bitstrings"][0]) == problem.n def test_pennylane_optimizers_workflows(self): - " function to run the tests for pennylane optimizers, workflows" + "function to run the tests for pennylane optimizers, workflows" i = 0 for problem in [qubo_problem_3, qubo_problem_2, qubo_problem_1]: @@ -108,10 +129,10 @@ def test_pennylane_optimizers_workflows(self): self._run_method_workflows(opt, problem) i += 1 - assert i == 3*len(list_optimizers) + assert i == 3 * len(list_optimizers) def test_pennylane_optimizers_manual(self): - " function to run the tests for pennylane optimizers, manual mode" + "function to run the tests for pennylane optimizers, manual mode" i = 0 for problem in [qubo_problem_3, qubo_problem_2, qubo_problem_1]: @@ -119,77 +140,113 @@ def test_pennylane_optimizers_manual(self): self._run_method_manual(opt, problem) i += 1 - assert i == 3*len(list_optimizers) + assert i == 3 * len(list_optimizers) def _pennylane_step(self, params_array, cost, optimizer, method, jac, qfim): - " helper function to run a setp of the pennylane optimizer" + "helper function to run a setp of the pennylane optimizer" params_array = pl.numpy.array(params_array, requires_grad=True) - if method in ['pennylane_adagrad', 'pennylane_adam', 'pennylane_vgd', 'pennylane_momentum', 'pennylane_nesterov_momentum', 'pennylane_rmsprop']: + if method in [ + "pennylane_adagrad", + "pennylane_adam", + "pennylane_vgd", + "pennylane_momentum", + "pennylane_nesterov_momentum", + "pennylane_rmsprop", + ]: x, y = optimizer.step_and_cost(cost, params_array, grad_fn=jac) - if method in ['pennylane_rotosolve']: + if method in ["pennylane_rotosolve"]: x, y = optimizer.step_and_cost( - cost, params_array, - nums_frequency={'params': {(i,):1 for i in range(params_array.size)}}, - ) - if method in ['pennylane_spsa']: + cost, + params_array, + nums_frequency={"params": {(i,): 1 for i in range(params_array.size)}}, + ) + if method in ["pennylane_spsa"]: x, y = optimizer.step_and_cost(cost, params_array) return x, y def test_step_and_cost(self): - " function to run the tests for steps of pennylane optimizers " + "function to run the tests for steps of pennylane optimizers" # define some problem - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), PauliOp( - 'ZZ', (0, 3)), PauliOp('Z', (2,)), PauliOp('Z', (1,))], [1, 1.1, 1.5, 2, -0.8], 0.8) + cost_hamil = Hamiltonian( + [ + PauliOp("ZZ", (0, 1)), + PauliOp("ZZ", (1, 2)), + PauliOp("ZZ", (0, 3)), + PauliOp("Z", (2,)), + PauliOp("Z", (1,)), + ], + [1, 1.1, 1.5, 2, -0.8], + 0.8, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=4) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=2) - device = create_device('local','vectorized') - backend_obj_vectorized = get_qaoa_backend(qaoa_descriptor,device) - variate_params = create_qaoa_variational_params(qaoa_descriptor, 'standard', 'ramp') + device = create_device("local", "vectorized") + backend_obj_vectorized = get_qaoa_backend(qaoa_descriptor, device) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) niter = 5 grad_stepsize = 0.0001 stepsize = 0.001 # declare needed functions - jac = derivative(backend_obj_vectorized, variate_params, self.log, - 'gradient', 'finite_difference', - {'stepsize': grad_stepsize}) - qfim = Qfim(backend_obj_vectorized, variate_params, self.log) + jac = derivative( + backend_obj_vectorized, + variate_params, + self.log, + "gradient", + "finite_difference", + {"stepsize": grad_stepsize}, + ) + qfim = Qfim(backend_obj_vectorized, variate_params, self.log) + def cost(params): variate_params.update_from_raw(params) return np.real(backend_obj_vectorized.expectation(variate_params)) i = 0 for method in list_optimizers: - + pennylane_method = method # copy the parameters x0 = copy.deepcopy(variate_params.raw().copy()) # Optimize with the implemented optimizer in OpenQAOA - vector_optimizer = get_optimizer(backend_obj_vectorized, variate_params, optimizer_dict={ - 'method': method, 'jac': jac, 'maxiter': niter, 'qfim': qfim, - 'optimizer_options' : {'stepsize': stepsize}}) + vector_optimizer = get_optimizer( + backend_obj_vectorized, + variate_params, + optimizer_dict={ + "method": method, + "jac": jac, + "maxiter": niter, + "qfim": qfim, + "optimizer_options": {"stepsize": stepsize}, + }, + ) vector_optimizer() # formatting the data - y_opt = vector_optimizer.qaoa_result.intermediate['cost'][1:4] - if pennylane_method in ['pennylane_rotosolve']: y_opt = vector_optimizer.qaoa_result.intermediate['cost'][4:40:12] + y_opt = vector_optimizer.qaoa_result.intermediate["cost"][1:4] + if pennylane_method in ["pennylane_rotosolve"]: + y_opt = vector_optimizer.qaoa_result.intermediate["cost"][4:40:12] # get optimizer to try optimizer = AVAILABLE_OPTIMIZERS[pennylane_method] - #get optimizer arguments + # get optimizer arguments arguments = inspect.signature(optimizer).parameters.keys() - #check if stepsize is in the optimizer arguments + # check if stepsize is in the optimizer arguments options = {} - if 'stepsize' in arguments: options['stepsize'] = stepsize - if 'maxiter' in arguments: options['maxiter'] = niter + if "stepsize" in arguments: + options["stepsize"] = stepsize + if "maxiter" in arguments: + options["maxiter"] = niter - #pass the argument to the optimizer - optimizer = optimizer(**options) + # pass the argument to the optimizer + optimizer = optimizer(**options) # reinitialize variables variate_params.update_from_raw(x0) @@ -197,26 +254,32 @@ def cost(params): y0 = cost(x0) # compute steps (depends on the optimizer) - x1, y1 = self._pennylane_step(x0, cost, optimizer, pennylane_method, jac, qfim) - x2, y2 = self._pennylane_step(x1, cost, optimizer, pennylane_method, jac, qfim) - x3, y3 = self._pennylane_step(x2, cost, optimizer, pennylane_method, jac, qfim) + x1, y1 = self._pennylane_step( + x0, cost, optimizer, pennylane_method, jac, qfim + ) + x2, y2 = self._pennylane_step( + x1, cost, optimizer, pennylane_method, jac, qfim + ) + x3, y3 = self._pennylane_step( + x2, cost, optimizer, pennylane_method, jac, qfim + ) # list of results y = [y1, y2, y3] # check that the results are ok - if pennylane_method in ['pennylane_spsa']: + if pennylane_method in ["pennylane_spsa"]: assert np.sum(np.abs(np.array(y)) >= 0) == 3 else: for yi, y_opt_i in zip(y, y_opt): assert np.isclose(yi, y_opt_i, rtol=0.001, atol=0.001) - i += 1 + i += 1 assert i == len(list_optimizers) if __name__ == "__main__": with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=PendingDeprecationWarning) + warnings.simplefilter("ignore", category=PendingDeprecationWarning) unittest.main() diff --git a/tests/test_parameters.py b/tests/test_parameters.py index e203a5fda..363071b7c 100644 --- a/tests/test_parameters.py +++ b/tests/test_parameters.py @@ -7,8 +7,10 @@ from openqaoa.qaoa_components import * from openqaoa.utilities import X_mixer_hamiltonian, XY_mixer_hamiltonian - -from openqaoa.qaoa_components.variational_parameters.variational_params_factory import PARAMS_CLASSES_MAPPER +from openqaoa.qaoa_components.ansatz_constructor.gatemaplabel import GateMapType +from openqaoa.qaoa_components.variational_parameters.variational_params_factory import ( + PARAMS_CLASSES_MAPPER, +) register = [0, 1, 2] terms = [[0, 1], [2], [0, 2]] @@ -17,207 +19,272 @@ terms_wo_bias = [[0, 1], [1, 2]] weights_wo_bias = [1, 0.5] -cost_hamiltonian = Hamiltonian.classical_hamiltonian( - terms, weights, constant=0) -cost_hamiltonian_wo_bias = Hamiltonian.classical_hamiltonian(terms_wo_bias, - weights_wo_bias, - constant=0.7) +cost_hamiltonian = Hamiltonian.classical_hamiltonian(terms, weights, constant=0) +cost_hamiltonian_wo_bias = Hamiltonian.classical_hamiltonian( + terms_wo_bias, weights_wo_bias, constant=0.7 +) mixer_hamiltonian = X_mixer_hamiltonian(len(register)) class TestingQAOADescriptor(unittest.TestCase): - def setUp(self): - + self.p = 2 - self.cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2)), PauliOp('Z', (0, ))], - [1, 1, 1, 0.5], 1) - self.mixer_hamil = X_mixer_hamiltonian(n_qubits = 3) + self.cost_hamil = Hamiltonian( + [ + PauliOp("ZZ", (0, 1)), + PauliOp("ZZ", (1, 2)), + PauliOp("ZZ", (0, 2)), + PauliOp("Z", (0,)), + ], + [1, 1, 1, 0.5], + 1, + ) + self.mixer_hamil = X_mixer_hamiltonian(n_qubits=3) self.mixer_gatemap = [RXGateMap(0), RXGateMap(1), RXGateMap(2)] self.mixer_gatemap_coeffs = self.mixer_hamil.coeffs - + def test_QAOADescriptor(self): - + """ - QAOADescriptor accept 2 types of inputs for mixer_block argument on initilisation. This test checks that the same mixer block when presented in Hamiltonian or as a List of RotationGateMap, plus the appropriate mixer coefficients, produces similar internal attributes. + QAOADescriptor accept 2 types of inputs for mixer_blocks argument on initilisation. This test checks that the same mixer block when presented in Hamiltonian or as a List of RotationGateMap, plus the appropriate mixer coefficients, produces similar internal attributes. """ - + qaoa_descriptor = QAOADescriptor(self.cost_hamil, self.mixer_hamil, p=self.p) - - qaoa_descriptor_gm = QAOADescriptor(self.cost_hamil, self.mixer_gatemap, p=self.p, - mixer_coeffs = self.mixer_gatemap_coeffs) - + + qaoa_descriptor_gm = QAOADescriptor( + self.cost_hamil, + self.mixer_gatemap, + p=self.p, + mixer_coeffs=self.mixer_gatemap_coeffs, + ) + # Check same number of mixer gates - self.assertEqual(len(qaoa_descriptor.mixer_block), self.p) - self.assertEqual(len(qaoa_descriptor_gm.mixer_block), self.p) + self.assertEqual(len(qaoa_descriptor.mixer_blocks), self.p) + self.assertEqual(len(qaoa_descriptor_gm.mixer_blocks), self.p) for each_p_value in range(self.p): - self.assertEqual(len(qaoa_descriptor.mixer_block[each_p_value]), 3) - self.assertEqual(len(qaoa_descriptor_gm.mixer_block[each_p_value]), 3) + self.assertEqual(len(qaoa_descriptor.mixer_blocks[each_p_value]), 3) + self.assertEqual(len(qaoa_descriptor_gm.mixer_blocks[each_p_value]), 3) # Check similar coefficients and qubit singles/pairs names - self.assertEqual(qaoa_descriptor.mixer_single_qubit_coeffs, - qaoa_descriptor_gm.mixer_single_qubit_coeffs) - self.assertEqual(qaoa_descriptor.mixer_pair_qubit_coeffs, - qaoa_descriptor_gm.mixer_pair_qubit_coeffs) - self.assertEqual(qaoa_descriptor.mixer_qubits_singles, - qaoa_descriptor_gm.mixer_qubits_singles) - self.assertEqual(qaoa_descriptor.mixer_qubits_pairs, - qaoa_descriptor_gm.mixer_qubits_pairs) - + self.assertEqual( + qaoa_descriptor.mixer_single_qubit_coeffs, + qaoa_descriptor_gm.mixer_single_qubit_coeffs, + ) + self.assertEqual( + qaoa_descriptor.mixer_pair_qubit_coeffs, + qaoa_descriptor_gm.mixer_pair_qubit_coeffs, + ) + self.assertEqual( + qaoa_descriptor.mixer_qubits_singles, + qaoa_descriptor_gm.mixer_qubits_singles, + ) + self.assertEqual( + qaoa_descriptor.mixer_qubits_pairs, qaoa_descriptor_gm.mixer_qubits_pairs + ) + def test_QAOADescriptor_mixer_coeffs_selector_hamiltonian(self): - + """ If a mixer hamiltonian is used for mixer_block, the coefficients will be obtained from it. Even if the user inputs his own mixer coefficient, it will be ignored. """ - + verify_mixer_coeffs = [-1, -1, -1] - - mixer_hamil = X_mixer_hamiltonian(n_qubits = 3) - - qaoa_descriptor = QAOADescriptor(self.cost_hamil, self.mixer_hamil, p = self.p) - qaoa_descriptor_2 = QAOADescriptor(self.cost_hamil, self.mixer_hamil, p = self.p, - mixer_coeffs = [1, 0, 1]) - + + mixer_hamil = X_mixer_hamiltonian(n_qubits=3) + + qaoa_descriptor = QAOADescriptor(self.cost_hamil, self.mixer_hamil, p=self.p) + qaoa_descriptor_2 = QAOADescriptor( + self.cost_hamil, self.mixer_hamil, p=self.p, mixer_coeffs=[1, 0, 1] + ) + self.assertEqual(qaoa_descriptor.mixer_block_coeffs, verify_mixer_coeffs) self.assertEqual(qaoa_descriptor_2.mixer_block_coeffs, verify_mixer_coeffs) - + def test_QAOADescriptor_mixer_coeffs_selector_gatemap(self): - + """ If a mixer gatemap is used for mixer_block, the user is required to input his own mixer coefficients, there should be an error message if the user does not input the appropriate number of mixer coefficients. """ - + verify_mixer_coeffs = [-1, -1, -1] - - qaoa_descriptor = QAOADescriptor(self.cost_hamil, self.mixer_gatemap, p = self.p, - mixer_coeffs = self.mixer_gatemap_coeffs) - + + qaoa_descriptor = QAOADescriptor( + self.cost_hamil, + self.mixer_gatemap, + p=self.p, + mixer_coeffs=self.mixer_gatemap_coeffs, + ) + self.assertEqual(qaoa_descriptor.mixer_block_coeffs, verify_mixer_coeffs) - + with self.assertRaises(ValueError) as cm: QAOADescriptor(self.cost_hamil, self.mixer_gatemap, self.p, []) - self.assertEqual('The number of terms/gatemaps must match the number of coefficients provided.', str(cm.exception)) - + self.assertEqual( + "The number of terms/gatemaps must match the number of coefficients provided.", + str(cm.exception), + ) + def test_QAOADescriptor_assign_coefficients(self): - + """ The method should split the coefficients and gatemaps in the proper order. Regardless of their positions within the hamiltonian or gatemap list. """ - + verify_mixer_coeffs = [-1, -1, -1, -0.5] - - + # TestCase 1: GateMap Mixer mixer_gatemap = [RXGateMap(0), RXGateMap(1), RXGateMap(2), RXXGateMap(0, 2)] - - qaoa_descriptor = QAOADescriptor(self.cost_hamil, mixer_gatemap, p = self.p, - mixer_coeffs = [-1, -1, -1, -0.5]) - + + qaoa_descriptor = QAOADescriptor( + self.cost_hamil, mixer_gatemap, p=self.p, mixer_coeffs=[-1, -1, -1, -0.5] + ) + self.assertEqual(qaoa_descriptor.cost_single_qubit_coeffs, [0.5]) self.assertEqual(qaoa_descriptor.cost_pair_qubit_coeffs, [1, 1, 1]) - self.assertEqual(qaoa_descriptor.cost_qubits_singles, ['RZGateMap']) - self.assertEqual(qaoa_descriptor.cost_qubits_pairs, ['RZZGateMap', 'RZZGateMap', 'RZZGateMap']) - + self.assertEqual(qaoa_descriptor.cost_qubits_singles, ["RZGateMap"]) + self.assertEqual( + qaoa_descriptor.cost_qubits_pairs, + ["RZZGateMap", "RZZGateMap", "RZZGateMap"], + ) + self.assertEqual(qaoa_descriptor.mixer_single_qubit_coeffs, [-1, -1, -1]) self.assertEqual(qaoa_descriptor.mixer_pair_qubit_coeffs, [-0.5]) - self.assertEqual(qaoa_descriptor.mixer_qubits_singles, ['RXGateMap', 'RXGateMap','RXGateMap']) - self.assertEqual(qaoa_descriptor.mixer_qubits_pairs, ['RXXGateMap']) - + self.assertEqual( + qaoa_descriptor.mixer_qubits_singles, + ["RXGateMap", "RXGateMap", "RXGateMap"], + ) + self.assertEqual(qaoa_descriptor.mixer_qubits_pairs, ["RXXGateMap"]) + # TestCase 2: Hamiltonian Mixer - mixer_gatemap = XY_mixer_hamiltonian(n_qubits = 3) - - qaoa_descriptor = QAOADescriptor(self.cost_hamil, mixer_gatemap, p = self.p) - + mixer_gatemap = XY_mixer_hamiltonian(n_qubits=3) + + qaoa_descriptor = QAOADescriptor(self.cost_hamil, mixer_gatemap, p=self.p) + self.assertEqual(qaoa_descriptor.cost_single_qubit_coeffs, [0.5]) self.assertEqual(qaoa_descriptor.cost_pair_qubit_coeffs, [1, 1, 1]) - self.assertEqual(qaoa_descriptor.cost_qubits_singles, ['RZGateMap']) - self.assertEqual(qaoa_descriptor.cost_qubits_pairs, ['RZZGateMap', 'RZZGateMap', 'RZZGateMap']) - + self.assertEqual(qaoa_descriptor.cost_qubits_singles, ["RZGateMap"]) + self.assertEqual( + qaoa_descriptor.cost_qubits_pairs, + ["RZZGateMap", "RZZGateMap", "RZZGateMap"], + ) + self.assertEqual(qaoa_descriptor.mixer_single_qubit_coeffs, []) - self.assertEqual(qaoa_descriptor.mixer_pair_qubit_coeffs, - [0.5, 0.5, 0.5, 0.5 , 0.5, 0.5]) + self.assertEqual( + qaoa_descriptor.mixer_pair_qubit_coeffs, [0.5, 0.5, 0.5, 0.5, 0.5, 0.5] + ) self.assertEqual(qaoa_descriptor.mixer_qubits_singles, []) - self.assertEqual(qaoa_descriptor.mixer_qubits_pairs, - ['RXXGateMap', 'RYYGateMap', 'RXXGateMap', 'RYYGateMap', 'RXXGateMap', 'RYYGateMap']) - - def test_QAOADescriptor_cost_block(self): - + self.assertEqual( + qaoa_descriptor.mixer_qubits_pairs, + [ + "RXXGateMap", + "RYYGateMap", + "RXXGateMap", + "RYYGateMap", + "RXXGateMap", + "RYYGateMap", + ], + ) + + def test_QAOADescriptor_cost_blocks(self): + """ - cost_block property should always return a list of RotationGateMaps based on the input cost hamiltonian. + cost_blocks property should always return a list of RotationGateMaps based on the input cost hamiltonian. """ - + mixer_gatemap = [RXGateMap(0), RXGateMap(1), RXGateMap(2), RXXGateMap(0, 2)] - - qaoa_descriptor = QAOADescriptor(self.cost_hamil, mixer_gatemap, p = self.p, - mixer_coeffs = [-1, -1, -1, -0.5]) - - for each_p_block in qaoa_descriptor.cost_block: + + qaoa_descriptor = QAOADescriptor( + self.cost_hamil, mixer_gatemap, p=self.p, mixer_coeffs=[-1, -1, -1, -0.5] + ) + + for p_index, each_p_block in enumerate(qaoa_descriptor.cost_blocks): for each_item in each_p_block: self.assertTrue(isinstance(each_item, RotationGateMap)) - - def test_QAOADescriptor_mixer_block(self): - + self.assertEqual(each_item.gate_label.type, GateMapType.COST) + self.assertEqual(each_item.gate_label.layer, p_index) + + self.assertEqual( + [each_item.gate_label.sequence for each_item in each_p_block], + [0, 1, 2, 0], + ) + + def test_QAOADescriptor_mixer_blocks(self): + """ - mixer_block property should always return a list of RotationGateMaps based on the input cost hamiltonian. + mixer_blocks property should always return a list of RotationGateMaps based on the input cost hamiltonian. """ - + mixer_gatemap = [RXGateMap(0), RXGateMap(1), RXGateMap(2), RXXGateMap(0, 2)] - - qaoa_descriptor = QAOADescriptor(self.cost_hamil, mixer_gatemap, p = self.p, - mixer_coeffs = [-1, -1, -1, -0.5]) - - for each_p_block in qaoa_descriptor.mixer_block: + + qaoa_descriptor = QAOADescriptor( + self.cost_hamil, mixer_gatemap, p=self.p, mixer_coeffs=[-1, -1, -1, -0.5] + ) + + for p_index, each_p_block in enumerate(qaoa_descriptor.mixer_blocks): for each_item in each_p_block: self.assertTrue(isinstance(each_item, RotationGateMap)) - + self.assertEqual(each_item.gate_label.type, GateMapType.MIXER) + self.assertEqual(each_item.gate_label.layer, p_index) + + self.assertEqual( + [each_item.gate_label.sequence for each_item in each_p_block], + [0, 1, 2, 0], + ) + def test_QAOADescriptor_weird_cases(self): - + """ Testing various weird cases """ - + # TestCase 1: Empty List Mixer Block - qaoa_descriptor = QAOADescriptor(self.cost_hamil, [], p = self.p) + qaoa_descriptor = QAOADescriptor(self.cost_hamil, [], p=self.p) # TestCase 2: Wrong Type Cost Block self.assertRaises(AttributeError, QAOADescriptor, [], self.mixer_hamil, self.p) - self.assertRaises(AttributeError, QAOADescriptor, [RZGateMap(0)], - self.mixer_hamil, self.p) - + self.assertRaises( + AttributeError, QAOADescriptor, [RZGateMap(0)], self.mixer_hamil, self.p + ) + # TestCase 3: p is not an int - self.assertRaises(TypeError, QAOADescriptor, self.cost_hamil, - self.mixer_hamil, 'test') - + self.assertRaises( + TypeError, QAOADescriptor, self.cost_hamil, self.mixer_hamil, "test" + ) + def test_QAOADescriptor_abstract_circuit(self): - + """ The abstract circuit should be consistent with the cost hamiltonian, mixer block and the p value. """ - - mixer_hamil = X_mixer_hamiltonian(n_qubits = 3) + + mixer_hamil = X_mixer_hamiltonian(n_qubits=3) mixer_gatemap = [RXGateMap(0), RXGateMap(1), RXGateMap(2)] - - qaoa_descriptor = QAOADescriptor(self.cost_hamil, self.mixer_hamil, p = self.p) - qaoa_descriptor_gm = QAOADescriptor(self.cost_hamil, self.mixer_gatemap, - p = self.p, - mixer_coeffs = self.mixer_gatemap_coeffs) - + + qaoa_descriptor = QAOADescriptor(self.cost_hamil, self.mixer_hamil, p=self.p) + qaoa_descriptor_gm = QAOADescriptor( + self.cost_hamil, + self.mixer_gatemap, + p=self.p, + mixer_coeffs=self.mixer_gatemap_coeffs, + ) + # Checks if the gates are identical - for each_cp_gate, each_cpgm_gate in zip(qaoa_descriptor.abstract_circuit, qaoa_descriptor_gm.abstract_circuit): + for each_cp_gate, each_cpgm_gate in zip( + qaoa_descriptor.abstract_circuit, qaoa_descriptor_gm.abstract_circuit + ): self.assertTrue(type(each_cp_gate), type(each_cpgm_gate)) - if hasattr(each_cp_gate, 'qubit_1'): + if hasattr(each_cp_gate, "qubit_1"): self.assertEqual(each_cp_gate.qubit_1, each_cpgm_gate.qubit_1) - if hasattr(each_cpgm_gate, 'qubit_2'): + if hasattr(each_cpgm_gate, "qubit_2"): self.assertEqual(each_cp_gate.qubit_2, each_cpgm_gate.qubit_2) class TestingQAOAVariationalParameters(unittest.TestCase): - def test_QAOAVariationalExtendedParams(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) params = QAOAVariationalExtendedParams.linear_ramp_from_hamiltonian( - qaoa_descriptor, time=2) + qaoa_descriptor, time=2 + ) assert np.allclose(qaoa_descriptor.qureg, [0, 1, 2]) assert np.allclose(params.betas_singles, [[0.75] * 3, [0.25] * 3]) @@ -231,18 +298,15 @@ def test_QAOAVariationalExtendedParams(self): # TODO check that the values also make sense def test_QAOAVariationalExtendedParamsCustomInitialisation(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) betas_singles = [[0.0, 0.1, 0.3], [0.5, 0.2, 1.2]] betas_pairs = [] gammas_singles = [[0.0], [0.5]] gammas_pairs = [[0.1, 0.3], [0.2, 1.2]] - params = QAOAVariationalExtendedParams(qaoa_descriptor, - betas_singles, - betas_pairs, - gammas_singles, - gammas_pairs) + params = QAOAVariationalExtendedParams( + qaoa_descriptor, betas_singles, betas_pairs, gammas_singles, gammas_pairs + ) cost_2q_angles = 2 * np.array([1, -2.0]) * gammas_pairs cost_1q_angles = 2 * np.array([0.5]) * gammas_singles @@ -260,16 +324,14 @@ def test_QAOAVariationalExtendedParamsCustomInitialisation(self): assert np.allclose(params.cost_2q_angles, cost_2q_angles) def test_QAOAVariationalStandardWithBiasParamsCustomInitialisation(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) betas = [np.pi, 0.4] gammas_singles = [10, 24] gammas_pairs = [8.8, 2.3] - params = QAOAVariationalStandardWithBiasParams(qaoa_descriptor, - betas, - gammas_singles, - gammas_pairs) + params = QAOAVariationalStandardWithBiasParams( + qaoa_descriptor, betas, gammas_singles, gammas_pairs + ) cost_2q_angles = 2 * np.outer(gammas_pairs, np.array([1, -2.0])) cost_1q_angles = 2 * np.outer(gammas_singles, np.array([0.5])) @@ -288,66 +350,61 @@ def test_QAOAVariationalStandardWithBiasParamsCustomInitialisation(self): def test_QAOAVariationalAnnealingParamsCustomInitialisation(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) schedule = [0.4, 1.0] - annealing_params = QAOAVariationalAnnealingParams(qaoa_descriptor, total_annealing_time=5, - schedule=schedule) + annealing_params = QAOAVariationalAnnealingParams( + qaoa_descriptor, total_annealing_time=5, schedule=schedule + ) assert type(annealing_params) == QAOAVariationalAnnealingParams def test_QAOAVariationalFourierParamsCustomInitialisation(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) v = [0.4, 1.0] u = [0.5, 1.2] - fourier_params = QAOAVariationalFourierParams( - qaoa_descriptor, q=2, v=v, u=u) + fourier_params = QAOAVariationalFourierParams(qaoa_descriptor, q=2, v=v, u=u) - assert np.allclose(fourier_params.betas, dct( - v, n=qaoa_descriptor.p, axis=0)) - assert np.allclose(fourier_params.gammas, dst( - u, n=qaoa_descriptor.p, axis=0)) + assert np.allclose(fourier_params.betas, dct(v, n=qaoa_descriptor.p, axis=0)) + assert np.allclose(fourier_params.gammas, dst(u, n=qaoa_descriptor.p, axis=0)) assert type(fourier_params) == QAOAVariationalFourierParams def test_QAOAVariationalFourierExtendedParamsCustomInitialisation(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) - v_singles = [[0.4]*3, [1.0]*3] + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) + v_singles = [[0.4] * 3, [1.0] * 3] v_pairs = [] u_singles = [[0.5], [1.2]] - u_pairs = [[4.5]*2, [123]*2] - fourier_params = QAOAVariationalFourierExtendedParams(qaoa_descriptor, - 2, - v_singles, - v_pairs, - u_singles, - u_pairs) - - assert np.allclose(fourier_params.betas_singles, dct( - v_singles, n=qaoa_descriptor.p, axis=0)) - assert np.allclose(fourier_params.gammas_singles, dst( - u_singles, n=qaoa_descriptor.p, axis=0)) - assert np.allclose(fourier_params.gammas_pairs, dst( - u_pairs, n=qaoa_descriptor.p, axis=0)) + u_pairs = [[4.5] * 2, [123] * 2] + fourier_params = QAOAVariationalFourierExtendedParams( + qaoa_descriptor, 2, v_singles, v_pairs, u_singles, u_pairs + ) + + assert np.allclose( + fourier_params.betas_singles, dct(v_singles, n=qaoa_descriptor.p, axis=0) + ) + assert np.allclose( + fourier_params.gammas_singles, dst(u_singles, n=qaoa_descriptor.p, axis=0) + ) + assert np.allclose( + fourier_params.gammas_pairs, dst(u_pairs, n=qaoa_descriptor.p, axis=0) + ) assert type(fourier_params) == QAOAVariationalFourierExtendedParams def test_QAOAVariationalAnnealingParams(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) - params = QAOAVariationalAnnealingParams.linear_ramp_from_hamiltonian(qaoa_descriptor, - total_annealing_time=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) + params = QAOAVariationalAnnealingParams.linear_ramp_from_hamiltonian( + qaoa_descriptor, total_annealing_time=2 + ) assert np.allclose(qaoa_descriptor.qureg, [0, 1, 2]) - assert np.allclose(params.mixer_1q_angles, [ - [-2*0.75] * 3, [-2*0.25] * 3]) - assert np.allclose(params.cost_1q_angles, [[2*0.125], [2*0.375]]) - assert np.allclose(params.cost_2q_angles, [ - [2*0.25, -0.5*2], [2*0.75, -1.5*2]]) + assert np.allclose(params.mixer_1q_angles, [[-2 * 0.75] * 3, [-2 * 0.25] * 3]) + assert np.allclose(params.cost_1q_angles, [[2 * 0.125], [2 * 0.375]]) + assert np.allclose( + params.cost_2q_angles, [[2 * 0.25, -0.5 * 2], [2 * 0.75, -1.5 * 2]] + ) # Test updating and raw output raw = np.random.rand(len(params)) @@ -356,16 +413,16 @@ def test_QAOAVariationalAnnealingParams(self): def test_QAOAVariationalStandardWithBiasParams(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) - params = QAOAVariationalStandardWithBiasParams.linear_ramp_from_hamiltonian(qaoa_descriptor, - time=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) + params = QAOAVariationalStandardWithBiasParams.linear_ramp_from_hamiltonian( + qaoa_descriptor, time=2 + ) assert np.allclose(qaoa_descriptor.qureg, [0, 1, 2]) - assert np.allclose(params.mixer_1q_angles, [ - [-2*0.75] * 3, [-2*0.25] * 3]) - assert np.allclose(params.cost_1q_angles, [[2*0.125], [2*0.375]]) - assert np.allclose(params.cost_2q_angles, [ - [2*0.25, -0.5*2], [2*0.75, -1.5*2]]) + assert np.allclose(params.mixer_1q_angles, [[-2 * 0.75] * 3, [-2 * 0.25] * 3]) + assert np.allclose(params.cost_1q_angles, [[2 * 0.125], [2 * 0.375]]) + assert np.allclose( + params.cost_2q_angles, [[2 * 0.25, -0.5 * 2], [2 * 0.75, -1.5 * 2]] + ) # Test updating and raw output raw = np.random.rand(len(params)) @@ -374,17 +431,17 @@ def test_QAOAVariationalStandardWithBiasParams(self): def test_QAOAVariationalStandardParams(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) - params = QAOAVariationalStandardParams.linear_ramp_from_hamiltonian(qaoa_descriptor, - time=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) + params = QAOAVariationalStandardParams.linear_ramp_from_hamiltonian( + qaoa_descriptor, time=2 + ) assert np.allclose(qaoa_descriptor.qureg, [0, 1, 2]) - assert np.allclose(params.mixer_1q_angles, [ - [-2*0.75] * 3, [-2*0.25] * 3]) - assert np.allclose(params.cost_1q_angles, [[2*0.125], [2*0.375]]) - assert np.allclose(params.cost_2q_angles, [ - [2*0.25, -0.5*2], [2*0.75, -1.5*2]]) + assert np.allclose(params.mixer_1q_angles, [[-2 * 0.75] * 3, [-2 * 0.25] * 3]) + assert np.allclose(params.cost_1q_angles, [[2 * 0.125], [2 * 0.375]]) + assert np.allclose( + params.cost_2q_angles, [[2 * 0.25, -0.5 * 2], [2 * 0.75, -1.5 * 2]] + ) # Test updating and raw output raw = np.random.rand(len(params)) @@ -395,14 +452,16 @@ def test_non_fourier_params_are_consistent(self): """ Check that StandardParams, StandardWithBiasParams and ExtendedParams give the same rotation angles, given the same data""" - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) p1 = QAOAVariationalStandardParams.linear_ramp_from_hamiltonian( - qaoa_descriptor, time=2) + qaoa_descriptor, time=2 + ) p2 = QAOAVariationalExtendedParams.linear_ramp_from_hamiltonian( - qaoa_descriptor, time=2) + qaoa_descriptor, time=2 + ) p3 = QAOAVariationalStandardWithBiasParams.linear_ramp_from_hamiltonian( - qaoa_descriptor, time=2) + qaoa_descriptor, time=2 + ) assert np.allclose(p1.mixer_1q_angles, p2.mixer_1q_angles) assert np.allclose(p2.mixer_1q_angles, p3.mixer_1q_angles) @@ -413,15 +472,15 @@ def test_non_fourier_params_are_consistent(self): def test_QAOAVariationalFourierParams(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=3) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=3) params = QAOAVariationalFourierParams.linear_ramp_from_hamiltonian( - qaoa_descriptor, q=2, time=2) + qaoa_descriptor, q=2, time=2 + ) # just access the angles, to check that it actually creates them assert len(params.cost_1q_angles) == len(params.cost_2q_angles) - assert np.allclose(params.v, [1/3, 0]) - assert np.allclose(params.u, [1/3, 0]) + assert np.allclose(params.v, [1 / 3, 0]) + assert np.allclose(params.u, [1 / 3, 0]) # Test updating and raw output raw = np.random.rand(len(params)) params.update_from_raw(raw) @@ -429,17 +488,16 @@ def test_QAOAVariationalFourierParams(self): def test_QAOAVariationalFourierWithBiasParams(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=3) - params = QAOAVariationalFourierWithBiasParams.linear_ramp_from_hamiltonian(qaoa_descriptor, - q=2, - time=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=3) + params = QAOAVariationalFourierWithBiasParams.linear_ramp_from_hamiltonian( + qaoa_descriptor, q=2, time=2 + ) # just access the angles, to check that it actually creates them assert len(params.cost_1q_angles) == len(params.cost_2q_angles) - assert np.allclose(params.v, [1/3, 0]) - assert np.allclose(params.u_singles, [1/3, 0]) - assert np.allclose(params.u_pairs, [1/3, 0]) + assert np.allclose(params.v, [1 / 3, 0]) + assert np.allclose(params.u_singles, [1 / 3, 0]) + assert np.allclose(params.u_pairs, [1 / 3, 0]) # Test updating and raw output raw = np.random.rand(len(params)) params.update_from_raw(raw) @@ -447,19 +505,18 @@ def test_QAOAVariationalFourierWithBiasParams(self): def test_QAOAVariationalFourierExtendedParams(self): - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=3) - params = QAOAVariationalFourierExtendedParams.linear_ramp_from_hamiltonian(qaoa_descriptor, - q=2, - time=2) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=3) + params = QAOAVariationalFourierExtendedParams.linear_ramp_from_hamiltonian( + qaoa_descriptor, q=2, time=2 + ) # just access the angles, to check that it actually creates them assert len(params.cost_1q_angles) == len(params.cost_2q_angles) # Test updating and raw output - assert np.allclose(params.v_singles, [[1/3] * 3, [0] * 3]) - assert np.allclose(params.u_singles, [[1/3] * 1, [0] * 1]) - assert np.allclose(params.u_pairs, [[1/3] * 2, [0] * 2]) + assert np.allclose(params.v_singles, [[1 / 3] * 3, [0] * 3]) + assert np.allclose(params.u_singles, [[1 / 3] * 1, [0] * 1]) + assert np.allclose(params.u_pairs, [[1 / 3] * 2, [0] * 2]) # Test updating and raw output raw = np.random.rand(len(params)) params.update_from_raw(raw) @@ -469,15 +526,17 @@ def test_FourierParams_are_consistent(self): """ Check, that both Fourier Parametrizations give the same rotation angles, given the same data""" - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=3) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=3) params1 = QAOAVariationalFourierParams.linear_ramp_from_hamiltonian( - qaoa_descriptor, q=2, time=2) + qaoa_descriptor, q=2, time=2 + ) params2 = QAOAVariationalFourierWithBiasParams.linear_ramp_from_hamiltonian( - qaoa_descriptor, q=2, time=2) + qaoa_descriptor, q=2, time=2 + ) params3 = QAOAVariationalFourierExtendedParams.linear_ramp_from_hamiltonian( - qaoa_descriptor, q=2, time=2) + qaoa_descriptor, q=2, time=2 + ) assert np.allclose(params1.mixer_1q_angles, params2.mixer_1q_angles) assert np.allclose(params1.cost_1q_angles, params2.cost_1q_angles) @@ -498,30 +557,33 @@ def test_inputChecking(self): gammas_singles = [] gammas_pairs = [1, 2, 3] qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=n_layers) - self.assertRaises(ValueError, - QAOAVariationalExtendedParams, - qaoa_descriptor, - betas_singles, - betas_pairs, - gammas_singles, - gammas_pairs) - + cost_hamiltonian, mixer_hamiltonian, p=n_layers + ) + self.assertRaises( + ValueError, + QAOAVariationalExtendedParams, + qaoa_descriptor, + betas_singles, + betas_pairs, + gammas_singles, + gammas_pairs, + ) + def test_str_and_repr(self): - - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p=2) - + + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p=2) + for each_key_value in PARAMS_CLASSES_MAPPER.keys(): - variate_params = create_qaoa_variational_params(qaoa_descriptor, - params_type = each_key_value, - init_type = 'rand', - q = 1, - total_annealing_time = 1) - + variate_params = create_qaoa_variational_params( + qaoa_descriptor, + params_type=each_key_value, + init_type="rand", + q=1, + total_annealing_time=1, + ) + self.assertEqual(variate_params.__str__(), variate_params.__repr__()) - - + # # Plot Tests # def test_StandardParams_plot(self): diff --git a/tests/test_parameters_plots.py b/tests/test_parameters_plots.py index 391525838..0cdf9ac7a 100644 --- a/tests/test_parameters_plots.py +++ b/tests/test_parameters_plots.py @@ -7,8 +7,10 @@ # import the OpenQAOA Parameterisation classes manually: Manual Mode from openqaoa.qaoa_components import ( - create_qaoa_variational_params, PauliOp, - Hamiltonian, QAOADescriptor + create_qaoa_variational_params, + PauliOp, + Hamiltonian, + QAOADescriptor, ) # import the other OpenQAOA modules required for this example @@ -17,56 +19,68 @@ # Create a hamiltonian problem on 15 qubits and create Circuit Params Class -hamiltonian1 = MaximumCut.random_instance(n_nodes=15, edge_probability = 0.9).qubo.hamiltonian -mixer_hamiltonian1 = X_mixer_hamiltonian(n_qubits = 15) -qaoa_descriptor1 = QAOADescriptor(cost_hamiltonian = hamiltonian1, mixer_block = mixer_hamiltonian1, p=4) +hamiltonian1 = MaximumCut.random_instance( + n_nodes=15, edge_probability=0.9 +).qubo.hamiltonian +mixer_hamiltonian1 = X_mixer_hamiltonian(n_qubits=15) +qaoa_descriptor1 = QAOADescriptor( + cost_hamiltonian=hamiltonian1, mixer_block=mixer_hamiltonian1, p=4 +) # Create a hamiltonian on 3 qubits with 2 coupling terms and 1 bias term and create Circuit Params Class -Term1 = PauliOp('ZZ', (0, 1)) -Term2 = PauliOp('ZZ', (0, 2)) -Term3 = PauliOp('Z', (0, )) +Term1 = PauliOp("ZZ", (0, 1)) +Term2 = PauliOp("ZZ", (0, 2)) +Term3 = PauliOp("Z", (0,)) hamiltonian2 = Hamiltonian([Term1, Term2, Term3], [0.7, 1.2, -0.5], 0.0) -mixer_hamiltonian2 = X_mixer_hamiltonian(n_qubits = 3) -qaoa_descriptor2 = QAOADescriptor(cost_hamiltonian = hamiltonian2, mixer_block = mixer_hamiltonian2, p=4) +mixer_hamiltonian2 = X_mixer_hamiltonian(n_qubits=3) +qaoa_descriptor2 = QAOADescriptor( + cost_hamiltonian=hamiltonian2, mixer_block=mixer_hamiltonian2, p=4 +) class TestingQAOAParametersPlots(unittest.TestCase): - - def _plot(self, qaoa_descriptor, params_type, init_type = 'rand'): - #generic function to create the plots - print(f'Example of {params_type} params') - if params_type in ['fourier', 'fourier_extended', 'fourier_w_bias']: - params = create_qaoa_variational_params(qaoa_descriptor = qaoa_descriptor, params_type = params_type, init_type = init_type, q=2) + def _plot(self, qaoa_descriptor, params_type, init_type="rand"): + # generic function to create the plots + print(f"Example of {params_type} params") + if params_type in ["fourier", "fourier_extended", "fourier_w_bias"]: + params = create_qaoa_variational_params( + qaoa_descriptor=qaoa_descriptor, + params_type=params_type, + init_type=init_type, + q=2, + ) else: - params = create_qaoa_variational_params(qaoa_descriptor = qaoa_descriptor, params_type = params_type, init_type = init_type) + params = create_qaoa_variational_params( + qaoa_descriptor=qaoa_descriptor, + params_type=params_type, + init_type=init_type, + ) params.plot() - def test_QAOAVariationalStandardParamsPlots(self): # standard params - self._plot(qaoa_descriptor1, 'standard') + def test_QAOAVariationalStandardParamsPlots(self): # standard params + self._plot(qaoa_descriptor1, "standard") + + def test_QAOAVariationalStandardBiasParamsPlots(self): # standard_w_bias params + self._plot(qaoa_descriptor2, "standard_w_bias") - def test_QAOAVariationalStandardBiasParamsPlots(self): # standard_w_bias params - self._plot(qaoa_descriptor2, 'standard_w_bias') + def test_QAOAVariationalExtendedParamsPlots(self): # extended params + self._plot(qaoa_descriptor1, "extended") + self._plot(qaoa_descriptor2, "extended") - def test_QAOAVariationalExtendedParamsPlots(self): # extended params - self._plot(qaoa_descriptor1, 'extended') - self._plot(qaoa_descriptor2, 'extended') - - def test_QAOAVariationalFourierParamsPlots(self): # fourier params - self._plot(qaoa_descriptor2, 'fourier') - - def test_QAOAVariationalFourierBiasParamsPlots(self): # fourier_w_bias params - self._plot(qaoa_descriptor2, 'fourier_w_bias') - - def test_QAOAVariationalFourierExtendedParamsPlots(self): # fourier_extended params - self._plot(qaoa_descriptor1, 'fourier_extended') - self._plot(qaoa_descriptor2, 'fourier_extended') - - def test_QAOAVariationalAnnealingParamsPlots(self): # annealing params - self._plot(qaoa_descriptor2, 'annealing', init_type = 'ramp') + def test_QAOAVariationalFourierParamsPlots(self): # fourier params + self._plot(qaoa_descriptor2, "fourier") + def test_QAOAVariationalFourierBiasParamsPlots(self): # fourier_w_bias params + self._plot(qaoa_descriptor2, "fourier_w_bias") + + def test_QAOAVariationalFourierExtendedParamsPlots(self): # fourier_extended params + self._plot(qaoa_descriptor1, "fourier_extended") + self._plot(qaoa_descriptor2, "fourier_extended") + + def test_QAOAVariationalAnnealingParamsPlots(self): # annealing params + self._plot(qaoa_descriptor2, "annealing", init_type="ramp") if __name__ == "__main__": unittest.main() - diff --git a/tests/test_problems.py b/tests/test_problems.py index 06ad60332..8c6274b3c 100644 --- a/tests/test_problems.py +++ b/tests/test_problems.py @@ -3,12 +3,19 @@ import numpy as np from random import randint, random from openqaoa.problems import ( - NumberPartition, QUBO, TSP, Knapsack, ShortestPath, - SlackFreeKnapsack, MaximumCut, MinimumVertexCover + NumberPartition, + QUBO, + TSP, + Knapsack, + ShortestPath, + SlackFreeKnapsack, + MaximumCut, + MinimumVertexCover, ) from openqaoa.utilities import convert2serialize from openqaoa.problems.helper_functions import create_problem_from_dict + def terms_list_equality(terms_list1, terms_list2): """ Check the terms equality between two terms list @@ -48,8 +55,7 @@ def test_qubo_cleaning_terms(self): weights = [3, 4, -3, -2, -1] cleaned_terms = [[1, 2], [0], [2, 3]] - self.assertEqual(QUBO.clean_terms_and_weights( - terms, weights)[0], cleaned_terms) + self.assertEqual(QUBO.clean_terms_and_weights(terms, weights)[0], cleaned_terms) def test_qubo_cleaning_weights(self): """Test that cleaning weights works for a QUBO problem""" @@ -57,8 +63,9 @@ def test_qubo_cleaning_weights(self): weights = [3, 4, -3, -2, -1] cleaned_weights = [1, 3, -3] - self.assertEqual(QUBO.clean_terms_and_weights( - terms, weights)[1], cleaned_weights) + self.assertEqual( + QUBO.clean_terms_and_weights(terms, weights)[1], cleaned_weights + ) def test_qubo_ising_conversion(self): """Test that conversion to Ising formulation works for a QUBO problem""" @@ -70,8 +77,7 @@ def test_qubo_ising_conversion(self): expected_ising_terms = [[0], [1], []] expected_ising_weights = [-2, -1.5, 3.5] - ising_terms, ising_weights = QUBO.convert_qubo_to_ising( - n, terms, weights) + ising_terms, ising_weights = QUBO.convert_qubo_to_ising(n, terms, weights) self.assertEqual(expected_ising_terms, ising_terms) self.assertEqual(expected_ising_weights, ising_weights) @@ -81,11 +87,9 @@ def test_qubo_ising_conversion(self): weights = [3, 4, -3, -2, -1] expected_ising_terms = [[1, 2], [2, 3], [2, 1], [0], [1], [2], [3], []] - expected_ising_weights = [ - 0.75, -0.75, -0.5, -1.5, -0.25, 0.5, 0.75, 1.0] + expected_ising_weights = [0.75, -0.75, -0.5, -1.5, -0.25, 0.5, 0.75, 1.0] - ising_terms, ising_weights = QUBO.convert_qubo_to_ising( - n, terms, weights) + ising_terms, ising_weights = QUBO.convert_qubo_to_ising(n, terms, weights) self.assertEqual(expected_ising_terms, ising_terms) self.assertEqual(expected_ising_weights, ising_weights) @@ -95,96 +99,116 @@ def test_qubo_type_checking(self): """ # n type-check - n_list = [1.5, 'test', [], (), {}, np.array(1)] + n_list = [1.5, "test", [], (), {}, np.array(1)] terms = [[0], []] weights = [1, 2] with self.assertRaises(TypeError) as e: for each_n in n_list: QUBO(each_n, terms, weights) - self.assertEqual("The input parameter, n, has to be of type int", - str(e.exception)) + self.assertEqual( + "The input parameter, n, has to be of type int", str(e.exception) + ) n_list = [-1, 0] with self.assertRaises(TypeError) as e: for each_n in n_list: QUBO(each_n, terms, weights) - self.assertEqual("The input parameter, n, must be a positive integer greater than 0", - str(e.exception)) + self.assertEqual( + "The input parameter, n, must be a positive integer greater than 0", + str(e.exception), + ) # weights type-check n = 1 terms = [[0], []] - weights_list = [{'test': 'oh', 'test1': 'oh'}, np.array([1, 2])] + weights_list = [{"test": "oh", "test1": "oh"}, np.array([1, 2])] for each_weights in weights_list: with self.assertRaises(TypeError) as e: QUBO(n, terms, each_weights) - self.assertEqual("The input parameter weights must be of type of list or tuple", - str(e.exception)) + self.assertEqual( + "The input parameter weights must be of type of list or tuple", + str(e.exception), + ) - weights_list = [['test', 'oh'], [np.array(1), np.array(2)]] + weights_list = [["test", "oh"], [np.array(1), np.array(2)]] for each_weights in weights_list: with self.assertRaises(TypeError) as e: QUBO(n, terms, each_weights) - self.assertEqual("The elements in weights list must be of type float or int.", - str(e.exception)) + self.assertEqual( + "The elements in weights list must be of type float or int.", + str(e.exception), + ) # terms type-check n = 1 - terms_list = [{'test': [0], 'test1': []}] + terms_list = [{"test": [0], "test1": []}] weights = [1, 2] for each_terms in terms_list: with self.assertRaises(TypeError) as e: QUBO(n, each_terms, weights) - self.assertEqual("The input parameter terms must be of type of list or tuple", - str(e.exception)) + self.assertEqual( + "The input parameter terms must be of type of list or tuple", + str(e.exception), + ) def test_qubo_metadata(self): """Test that metadata is correctly stored""" qubo_problem = QUBO.random_instance(3) - qubo_problem.set_metadata({'tag1': 'value1', 'tag2': 'value2'}) - qubo_problem.set_metadata({'tag2': 'value2.0'}) + qubo_problem.set_metadata({"tag1": "value1", "tag2": "value2"}) + qubo_problem.set_metadata({"tag2": "value2.0"}) - assert qubo_problem.metadata['tag1'] == 'value1', "qubo metadata is not well set" - assert qubo_problem.metadata['tag2'] == 'value2.0', "qubo metadata is not well set, should have overwritten previous value" + assert ( + qubo_problem.metadata["tag1"] == "value1" + ), "qubo metadata is not well set" + assert ( + qubo_problem.metadata["tag2"] == "value2.0" + ), "qubo metadata is not well set, should have overwritten previous value" error = False try: - qubo_problem.set_metadata({'tag10': complex(1, 2)}) + qubo_problem.set_metadata({"tag10": complex(1, 2)}) except: error = True - assert error, "Should have thrown an error when setting metadata that is not json serializable" + assert ( + error + ), "Should have thrown an error when setting metadata that is not json serializable" error = False try: - qubo_problem.set_metadata({(1,2): 'value'}) + qubo_problem.set_metadata({(1, 2): "value"}) except: error = True - assert error, "Should have thrown an error when setting key metadata that is not json serializable" + assert ( + error + ), "Should have thrown an error when setting key metadata that is not json serializable" def test_qubo_problem_instance_serializable(self): - """ test that when problem instance is not serializable, it throws an error """ - + """test that when problem instance is not serializable, it throws an error""" + qubo = QUBO.random_instance(3) error = False try: - qubo.problem_instance={'tag10': complex(1, 2)} + qubo.problem_instance = {"tag10": complex(1, 2)} except: error = True - assert error, "Should have thrown an error when setting qubo problem instance that is not json serializable" + assert ( + error + ), "Should have thrown an error when setting qubo problem instance that is not json serializable" error = False try: - qubo.problem_instance={(1,2): 'value'} + qubo.problem_instance = {(1, 2): "value"} except: error = True - assert error, "Should have thrown an error when setting key qubo problem instance that is not json serializable" - + assert ( + error + ), "Should have thrown an error when setting key qubo problem instance that is not json serializable" # TESTING NUMBER PARITION CLASS - + def test_number_partitioning_terms_weights_constant(self): """Test that Number Partitioning creates the correct terms, weights, constant""" list_numbers = [1, 2, 3] @@ -195,8 +219,7 @@ def test_number_partitioning_terms_weights_constant(self): np_problem = NumberPartition(list_numbers) qubo_problem = np_problem.qubo - self.assertTrue(terms_list_equality( - qubo_problem.terms, expected_terms)) + self.assertTrue(terms_list_equality(qubo_problem.terms, expected_terms)) self.assertEqual(qubo_problem.weights, expected_weights) self.assertEqual(qubo_problem.constant, expected_constant) @@ -205,14 +228,11 @@ def test_number_partitioning_random_problem(self): # regenerate the same numbers randomly rng = np.random.default_rng(1234) random_numbers_list = list(map(int, rng.integers(1, 10, size=5))) - manual_np_prob = NumberPartition( - random_numbers_list).qubo + manual_np_prob = NumberPartition(random_numbers_list).qubo - np_prob_random = NumberPartition.random_instance( - n_numbers=5, seed=1234).qubo + np_prob_random = NumberPartition.random_instance(n_numbers=5, seed=1234).qubo - self.assertTrue(terms_list_equality( - np_prob_random.terms, manual_np_prob.terms)) + self.assertTrue(terms_list_equality(np_prob_random.terms, manual_np_prob.terms)) self.assertEqual(np_prob_random.weights, manual_np_prob.weights) self.assertEqual(np_prob_random.constant, manual_np_prob.constant) @@ -222,21 +242,23 @@ def test_num_part_type_checking(self): """ # numbers type-check - numbers_list = [(1, 2), {'test': 1, 'test1': 2}, np.array([1, 2])] + numbers_list = [(1, 2), {"test": 1, "test1": 2}, np.array([1, 2])] for each_number in numbers_list: with self.assertRaises(TypeError) as e: NumberPartition(numbers=each_number) - self.assertEqual("The input parameter, numbers, has to be a list", - str(e.exception)) + self.assertEqual( + "The input parameter, numbers, has to be a list", str(e.exception) + ) numbers_list = [[0.1, 1], [np.array(1), np.array(2)]] for each_number in numbers_list: with self.assertRaises(TypeError) as e: NumberPartition(numbers=each_number) - self.assertEqual("The elements in numbers list must be of type int.", - str(e.exception)) + self.assertEqual( + "The elements in numbers list must be of type int.", str(e.exception) + ) # TESTING MAXIMUMCUT CLASS @@ -245,7 +267,7 @@ def test_maximumcut_terms_weights_constant(self): gr = nx.generators.random_graphs.fast_gnp_random_graph(n=10, p=0.8) gr_edges = [list(edge) for edge in gr.edges()] - gr_weights = [1]*len(gr_edges) + gr_weights = [1] * len(gr_edges) maxcut_prob_qubo = MaximumCut(gr).qubo @@ -257,20 +279,19 @@ def test_maximumcut_random_problem(self): """Test MaximumCut random instance method""" seed = 1234 - gr = nx.generators.random_graphs.fast_gnp_random_graph( - n=10, p=0.8, seed=seed) + gr = nx.generators.random_graphs.fast_gnp_random_graph(n=10, p=0.8, seed=seed) maxcut_manual_prob = MaximumCut(gr).qubo np.random.seed(1234) maxcut_random_prob = MaximumCut.random_instance( - n_nodes=10, edge_probability=0.8, seed=seed).qubo + n_nodes=10, edge_probability=0.8, seed=seed + ).qubo - self.assertTrue(terms_list_equality( - maxcut_manual_prob.terms, maxcut_random_prob.terms)) - self.assertEqual(maxcut_manual_prob.weights, - maxcut_random_prob.weights) - self.assertEqual(maxcut_manual_prob.constant, - maxcut_random_prob.constant) + self.assertTrue( + terms_list_equality(maxcut_manual_prob.terms, maxcut_random_prob.terms) + ) + self.assertEqual(maxcut_manual_prob.weights, maxcut_random_prob.weights) + self.assertEqual(maxcut_manual_prob.constant, maxcut_random_prob.constant) def test_maximumcut_type_checking(self): """ @@ -278,13 +299,14 @@ def test_maximumcut_type_checking(self): """ # graph type-check - graph_list = [(1, 2), {'node1': 1, 'node2': 2}, np.array([1, 2])] + graph_list = [(1, 2), {"node1": 1, "node2": 2}, np.array([1, 2])] for each_graph in graph_list: with self.assertRaises(TypeError) as e: MaximumCut(G=each_graph) - self.assertEqual("Input problem graph must be a networkx Graph.", - str(e.exception)) + self.assertEqual( + "Input problem graph must be a networkx Graph.", str(e.exception) + ) # TESTING KNAPSACK CLASS @@ -295,23 +317,88 @@ def test_knapsack_terms_weights_constant(self): weights = [3, 6, 9, 1] weight_capacity = 15 n_qubits = len(values) + int(np.ceil(np.log2(weight_capacity))) - penalty = 2*max(values) - knap_terms = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3], [4, 5], [4, 6], [4, 7], [5, 6], - [5, 7], [6, 7], [0, 4], [0, 5], [0, 6], [ - 0, 7], [1, 4], [1, 5], [1, 6], [1, 7], - [2, 4], [2, 5], [2, 6], [2, 7], [3, 4], [ - 3, 5], [3, 6], [3, 7], [0], [1], [2], - [3], [4], [5], [6], [7]] - knap_weights = [10.0, 20.0, 40.0, 40.0, 80.0, 160.0, 90.0, 135.0, 15.0, 270.0, 30.0, 45.0, - 15.0, 30.0, 45.0, 5.0, 30.0, 60.0, 90.0, 10.0, 60.0, 120.0, 180.0, 20.0, 120.0, - 240.0, 360.0, 40.0, -20.0, -40.0, -80.0, -160.0, -59.0, -118.0, -178.5, -17.5] + penalty = 2 * max(values) + knap_terms = [ + [0, 1], + [0, 2], + [0, 3], + [1, 2], + [1, 3], + [2, 3], + [4, 5], + [4, 6], + [4, 7], + [5, 6], + [5, 7], + [6, 7], + [0, 4], + [0, 5], + [0, 6], + [0, 7], + [1, 4], + [1, 5], + [1, 6], + [1, 7], + [2, 4], + [2, 5], + [2, 6], + [2, 7], + [3, 4], + [3, 5], + [3, 6], + [3, 7], + [0], + [1], + [2], + [3], + [4], + [5], + [6], + [7], + ] + knap_weights = [ + 10.0, + 20.0, + 40.0, + 40.0, + 80.0, + 160.0, + 90.0, + 135.0, + 15.0, + 270.0, + 30.0, + 45.0, + 15.0, + 30.0, + 45.0, + 5.0, + 30.0, + 60.0, + 90.0, + 10.0, + 60.0, + 120.0, + 180.0, + 20.0, + 120.0, + 240.0, + 360.0, + 40.0, + -20.0, + -40.0, + -80.0, + -160.0, + -59.0, + -118.0, + -178.5, + -17.5, + ] knap_constant = 563.0 - knapsack_prob_qubo = Knapsack( - values, weights, weight_capacity, penalty).qubo + knapsack_prob_qubo = Knapsack(values, weights, weight_capacity, penalty).qubo - self.assertTrue(terms_list_equality( - knap_terms, knapsack_prob_qubo.terms)) + self.assertTrue(terms_list_equality(knap_terms, knapsack_prob_qubo.terms)) self.assertEqual(knap_weights, knapsack_prob_qubo.weights) self.assertEqual(knap_constant, knapsack_prob_qubo.constant) self.assertEqual(n_qubits, knapsack_prob_qubo.n) @@ -323,18 +410,18 @@ def test_knapsack_random_problem(self): n_items = 5 values = list(map(int, rng.integers(1, n_items, size=n_items))) weights = list(map(int, rng.integers(1, n_items, size=n_items))) - weight_capacity = int(rng.integers( - np.min(weights) * n_items, np.max(weights) * n_items)) - penalty = 2*np.max(values) + weight_capacity = int( + rng.integers(np.min(weights) * n_items, np.max(weights) * n_items) + ) + penalty = 2 * np.max(values) - knap_manual = Knapsack( - values, weights, weight_capacity, int(penalty)).qubo + knap_manual = Knapsack(values, weights, weight_capacity, int(penalty)).qubo - knap_random_instance = Knapsack.random_instance( - n_items=n_items, seed=1234).qubo + knap_random_instance = Knapsack.random_instance(n_items=n_items, seed=1234).qubo - self.assertTrue(terms_list_equality( - knap_manual.terms, knap_random_instance.terms)) + self.assertTrue( + terms_list_equality(knap_manual.terms, knap_random_instance.terms) + ) self.assertEqual(knap_manual.weights, knap_random_instance.weights) self.assertEqual(knap_manual.constant, knap_random_instance.constant) self.assertEqual(knap_manual.n, knap_random_instance.n) @@ -346,18 +433,18 @@ def test_knapsack_random_problem_smallsize(self): n_items = 3 values = list(map(int, rng.integers(1, n_items, size=n_items))) weights = list(map(int, rng.integers(1, n_items, size=n_items))) - weight_capacity = int(rng.integers( - np.min(weights) * n_items, np.max(weights) * n_items)) - penalty = 2*np.max(values) + weight_capacity = int( + rng.integers(np.min(weights) * n_items, np.max(weights) * n_items) + ) + penalty = 2 * np.max(values) - knap_manual = Knapsack( - values, weights, weight_capacity, int(penalty)).qubo + knap_manual = Knapsack(values, weights, weight_capacity, int(penalty)).qubo - knap_random_instance = Knapsack.random_instance( - n_items=n_items, seed=1234).qubo + knap_random_instance = Knapsack.random_instance(n_items=n_items, seed=1234).qubo - self.assertTrue(terms_list_equality( - knap_manual.terms, knap_random_instance.terms)) + self.assertTrue( + terms_list_equality(knap_manual.terms, knap_random_instance.terms) + ) self.assertEqual(knap_manual.weights, knap_random_instance.weights) self.assertEqual(knap_manual.constant, knap_random_instance.constant) self.assertEqual(knap_manual.n, knap_random_instance.n) @@ -370,70 +457,79 @@ def test_knapsack_type_checking(self): # values type-check weights = [1, 2] weight_capacity = 5 - penalty = .1 - values_list = [(1, 2), {'test': 'oh', 'test1': 'oh'}, np.array([1, 2])] + penalty = 0.1 + values_list = [(1, 2), {"test": "oh", "test1": "oh"}, np.array([1, 2])] for each_values in values_list: with self.assertRaises(TypeError) as e: Knapsack(each_values, weights, weight_capacity, penalty) - self.assertEqual("The input parameter, values, has to be a list", - str(e.exception)) + self.assertEqual( + "The input parameter, values, has to be a list", str(e.exception) + ) - values_list = [['test', 'oh'], [np.array(1), np.array(2)], [.1, .5]] + values_list = [["test", "oh"], [np.array(1), np.array(2)], [0.1, 0.5]] for each_values in values_list: with self.assertRaises(TypeError) as e: Knapsack(each_values, weights, weight_capacity, penalty) - self.assertEqual("The elements in values list must be of type int.", - str(e.exception)) + self.assertEqual( + "The elements in values list must be of type int.", str(e.exception) + ) # weights type-check values = [1, 2] weight_capacity = 5 - penalty = .1 - weights_list = [ - (1, 2), {'test': 'oh', 'test1': 'oh'}, np.array([1, 2])] + penalty = 0.1 + weights_list = [(1, 2), {"test": "oh", "test1": "oh"}, np.array([1, 2])] for each_weights in weights_list: with self.assertRaises(TypeError) as e: Knapsack(values, each_weights, weight_capacity, penalty) - self.assertEqual("The input parameter, weights, has to be a list", - str(e.exception)) + self.assertEqual( + "The input parameter, weights, has to be a list", str(e.exception) + ) - weights_list = [['test', 'oh'], [np.array(1), np.array(2)], [.1, .5]] + weights_list = [["test", "oh"], [np.array(1), np.array(2)], [0.1, 0.5]] for each_weights in weights_list: with self.assertRaises(TypeError) as e: Knapsack(values, each_weights, weight_capacity, penalty) - self.assertEqual("The elements in weights list must be of type int.", - str(e.exception)) + self.assertEqual( + "The elements in weights list must be of type int.", str(e.exception) + ) # weight capacity type-check values = [1, 2] weights = [1, 2] - weight_capacity_list = [.5, np.array(1), np.array(.5), 'oh'] - penalty = .1 + weight_capacity_list = [0.5, np.array(1), np.array(0.5), "oh"] + penalty = 0.1 for each_weight_capacity in weight_capacity_list: with self.assertRaises(TypeError) as e: Knapsack(values, weights, each_weight_capacity, penalty) - self.assertEqual("The input parameter, weight_capacity, has to be of type int", - str(e.exception)) + self.assertEqual( + "The input parameter, weight_capacity, has to be of type int", + str(e.exception), + ) with self.assertRaises(TypeError) as e: Knapsack(values, weights, -1, penalty) - self.assertEqual("The input parameter, weight_capacity, must be a positive integer greater than 0", - str(e.exception)) + self.assertEqual( + "The input parameter, weight_capacity, must be a positive integer greater than 0", + str(e.exception), + ) # penalty capacity type-check values = [1, 2] weights = [1, 2] - penalty_list = [np.array(1), np.array(.5), 'oh'] + penalty_list = [np.array(1), np.array(0.5), "oh"] weight_capacity = 5 for each_penalty in penalty_list: with self.assertRaises(TypeError) as e: Knapsack(values, weights, weight_capacity, each_penalty) - self.assertEqual("The input parameter, penalty, has to be of type float or int", - str(e.exception)) + self.assertEqual( + "The input parameter, penalty, has to be of type float or int", + str(e.exception), + ) # TESTING SLACKFREEKNAPSACK CLASS @@ -444,18 +540,38 @@ def test_slackfreeknapsack_terms_weights_constant(self): weights = [3, 6, 9, 1] weight_capacity = 15 n_qubits = len(values) - penalty = 2*max(values) - slknap_terms = [[0, 1], [0, 2], [0, 3], [ - 1, 2], [1, 3], [2, 3], [0], [1], [2], [3]] - slknap_weights = [90.0, 135.0, 15.0, 270.0, - 30.0, 45.0, 166.0, 332.0, 496.5, 57.5] + penalty = 2 * max(values) + slknap_terms = [ + [0, 1], + [0, 2], + [0, 3], + [1, 2], + [1, 3], + [2, 3], + [0], + [1], + [2], + [3], + ] + slknap_weights = [ + 90.0, + 135.0, + 15.0, + 270.0, + 30.0, + 45.0, + 166.0, + 332.0, + 496.5, + 57.5, + ] slknap_constant = 613.0 slknapsack_prob_qubo = SlackFreeKnapsack( - values, weights, weight_capacity, penalty).qubo + values, weights, weight_capacity, penalty + ).qubo - self.assertTrue(terms_list_equality( - slknap_terms, slknapsack_prob_qubo.terms)) + self.assertTrue(terms_list_equality(slknap_terms, slknapsack_prob_qubo.terms)) self.assertEqual(slknap_weights, slknapsack_prob_qubo.weights) self.assertEqual(slknap_constant, slknapsack_prob_qubo.constant) self.assertEqual(n_qubits, slknapsack_prob_qubo.n) @@ -467,21 +583,24 @@ def test_slackfreeknapsack_random_problem(self): n_items = 5 values = list(map(int, rng.integers(1, n_items, size=n_items))) weights = list(map(int, rng.integers(1, n_items, size=n_items))) - weight_capacity = int(rng.integers( - np.min(weights) * n_items, np.max(weights) * n_items)) - penalty = 2*np.max(values) + weight_capacity = int( + rng.integers(np.min(weights) * n_items, np.max(weights) * n_items) + ) + penalty = 2 * np.max(values) slknap_manual = SlackFreeKnapsack( - values, weights, weight_capacity, int(penalty)).qubo + values, weights, weight_capacity, int(penalty) + ).qubo slknap_random_instance = SlackFreeKnapsack.random_instance( - n_items=n_items, seed=1234).qubo + n_items=n_items, seed=1234 + ).qubo - self.assertTrue(terms_list_equality( - slknap_manual.terms, slknap_random_instance.terms)) + self.assertTrue( + terms_list_equality(slknap_manual.terms, slknap_random_instance.terms) + ) self.assertEqual(slknap_manual.weights, slknap_random_instance.weights) - self.assertEqual(slknap_manual.constant, - slknap_random_instance.constant) + self.assertEqual(slknap_manual.constant, slknap_random_instance.constant) self.assertEqual(slknap_manual.n, slknap_random_instance.n) # TESTING MINIMUMVERTEXCOVER CLASS @@ -489,15 +608,24 @@ def test_slackfreeknapsack_random_problem(self): def test_mvc_terms_weights_constant(self): """Test terms,weights,constant of QUBO generated by MVC class""" - mvc_terms = [[0, 3], [0, 4], [1, 2], [1, 3], [2, 4], [3, 4], - [0], [1], [2], [3], [4]] - mvc_weights = [1.25, 1.25, 1.25, 1.25, - 1.25, 1.25, 2.0, 2.0, 2.0, 3.25, 3.25] + mvc_terms = [ + [0, 3], + [0, 4], + [1, 2], + [1, 3], + [2, 4], + [3, 4], + [0], + [1], + [2], + [3], + [4], + ] + mvc_weights = [1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 2.0, 2.0, 2.0, 3.25, 3.25] mvc_constant = 10.0 gr = nx.generators.fast_gnp_random_graph(5, 0.8, seed=1234) - mvc_prob = MinimumVertexCover( - gr, field=1.0, penalty=5).qubo + mvc_prob = MinimumVertexCover(gr, field=1.0, penalty=5).qubo self.assertTrue(terms_list_equality(mvc_terms, mvc_prob.terms)) self.assertEqual(mvc_weights, mvc_prob.weights) @@ -505,13 +633,25 @@ def test_mvc_terms_weights_constant(self): def test_mvc_random_problem(self): """Test the random_instance method of MVC class""" - mvc_terms = [[0, 3], [0, 4], [1, 2], [1, 3], - [2, 4], [3, 4], [0], [1], [2], [3], [4]] + mvc_terms = [ + [0, 3], + [0, 4], + [1, 2], + [1, 3], + [2, 4], + [3, 4], + [0], + [1], + [2], + [3], + [4], + ] mvc_weights = [2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 4.5, 4.5, 4.5, 7.0, 7.0] mvc_constant = 17.5 mvc_prob_random = MinimumVertexCover.random_instance( - n_nodes=5, edge_probability=0.8, seed=1234).qubo + n_nodes=5, edge_probability=0.8, seed=1234 + ).qubo self.assertTrue(terms_list_equality(mvc_terms, mvc_prob_random.terms)) self.assertEqual(mvc_weights, mvc_prob_random.weights) @@ -523,121 +663,130 @@ def test_mvc_type_checking(self): """ # graph type-check - graph_list = [(1, 2), {'node1': 1, 'node2': 2}, np.array([1, 2])] - field = .1 - penalty = .1 + graph_list = [(1, 2), {"node1": 1, "node2": 2}, np.array([1, 2])] + field = 0.1 + penalty = 0.1 for each_graph in graph_list: with self.assertRaises(TypeError) as e: MinimumVertexCover(each_graph, field, penalty) - self.assertEqual("Input problem graph must be a networkx Graph.", - str(e.exception)) + self.assertEqual( + "Input problem graph must be a networkx Graph.", str(e.exception) + ) # field capacity type-check graph = nx.circulant_graph(6, [1]) - field_list = [np.array(1), np.array(.5), 'oh'] - penalty = .1 + field_list = [np.array(1), np.array(0.5), "oh"] + penalty = 0.1 for each_field in field_list: with self.assertRaises(TypeError) as e: MinimumVertexCover(graph, each_field, penalty) - self.assertEqual("The input parameter, field, has to be of type float or int", - str(e.exception)) + self.assertEqual( + "The input parameter, field, has to be of type float or int", + str(e.exception), + ) # penalty capacity type-check graph = nx.circulant_graph(6, [1]) - field = .1 - penalty_list = [np.array(1), np.array(.5), 'oh'] + field = 0.1 + penalty_list = [np.array(1), np.array(0.5), "oh"] for each_penalty in penalty_list: with self.assertRaises(TypeError) as e: MinimumVertexCover(graph, field, each_penalty) - self.assertEqual("The input parameter, penalty, has to be of type float or int", - str(e.exception)) + self.assertEqual( + "The input parameter, penalty, has to be of type float or int", + str(e.exception), + ) # TESTING TSP PROBLEM CLASS def test_tsp_terms_weights_constant(self): """Testing TSP problem creation""" city_coordinates = [(4, 1), (4, 4), (3, 3), (1, 3.5)] - expected_terms = [[0, 3], - [1, 4], - [2, 5], - [0, 6], - [1, 7], - [8, 2], - [3, 6], - [4, 7], - [8, 5], - [0, 1], - [0, 2], - [1, 2], - [3, 4], - [3, 5], - [4, 5], - [6, 7], - [8, 6], - [8, 7], - [0, 4], - [1, 3], - [3, 7], - [4, 6], - [0, 5], - [2, 3], - [8, 3], - [5, 6], - [1, 5], - [2, 4], - [8, 4], - [5, 7], - [0], - [1], - [2], - [3], - [4], - [5], - [6], - [7], - [8]] - expected_weights = [3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 3.905124837953327, - 0.3535533905932738, - 0.3535533905932738, - 0.7603453162872774, - 0.7603453162872774, - 0.3535533905932738, - 0.3535533905932738, - 0.5153882032022076, - 0.5153882032022076, - 0.7603453162872774, - 0.7603453162872774, - 0.5153882032022076, - 0.5153882032022076, - -10.424148382787205, - -9.797225258452029, - -11.038545614372802, - -10.038047089667756, - -9.548132863497614, - -10.361716714885624, - -10.424148382787205, - -9.797225258452029, - -11.038545614372802] + expected_terms = [ + [0, 3], + [1, 4], + [2, 5], + [0, 6], + [1, 7], + [8, 2], + [3, 6], + [4, 7], + [8, 5], + [0, 1], + [0, 2], + [1, 2], + [3, 4], + [3, 5], + [4, 5], + [6, 7], + [8, 6], + [8, 7], + [0, 4], + [1, 3], + [3, 7], + [4, 6], + [0, 5], + [2, 3], + [8, 3], + [5, 6], + [1, 5], + [2, 4], + [8, 4], + [5, 7], + [0], + [1], + [2], + [3], + [4], + [5], + [6], + [7], + [8], + ] + expected_weights = [ + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 3.905124837953327, + 0.3535533905932738, + 0.3535533905932738, + 0.7603453162872774, + 0.7603453162872774, + 0.3535533905932738, + 0.3535533905932738, + 0.5153882032022076, + 0.5153882032022076, + 0.7603453162872774, + 0.7603453162872774, + 0.5153882032022076, + 0.5153882032022076, + -10.424148382787205, + -9.797225258452029, + -11.038545614372802, + -10.038047089667756, + -9.548132863497614, + -10.361716714885624, + -10.424148382787205, + -9.797225258452029, + -11.038545614372802, + ] expected_constant = 62.51983851122417 tsp_qubo = TSP(city_coordinates).qubo print(tsp_qubo.weights) @@ -651,16 +800,13 @@ def test_tsp_random_instance(self): n_cities = 4 box_size = np.sqrt(n_cities) - city_coordinates = list( - map(tuple, box_size * rng.random(size=(n_cities, 2)))) + city_coordinates = list(map(tuple, box_size * rng.random(size=(n_cities, 2)))) tsp_prob = TSP(city_coordinates).qubo - tsp_prob_random = TSP.random_instance( - n_cities=n_cities, seed=1234).qubo + tsp_prob_random = TSP.random_instance(n_cities=n_cities, seed=1234).qubo - self.assertTrue(terms_list_equality( - tsp_prob_random.terms, tsp_prob.terms)) + self.assertTrue(terms_list_equality(tsp_prob_random.terms, tsp_prob.terms)) self.assertEqual(tsp_prob_random.weights, tsp_prob.weights) self.assertEqual(tsp_prob_random.constant, tsp_prob.constant) @@ -671,115 +817,165 @@ def test_tsp_type_checking(self): # If nothing is given, must return a ValueError with self.assertRaises(ValueError) as e: TSP() - self.assertEqual("Input missing: city coordinates, distance matrix or (weighted graph) required", - str(e.exception)) + self.assertEqual( + "Input missing: city coordinates, distance matrix or (weighted graph) required", + str(e.exception), + ) # coordinates type-check - coordinates_list = [ - (1, 2), {'test': 'oh', 'test1': 'oh'}, np.array([1, 2])] + coordinates_list = [(1, 2), {"test": "oh", "test1": "oh"}, np.array([1, 2])] for each_coordinates in coordinates_list: with self.assertRaises(TypeError) as e: TSP(each_coordinates) - self.assertEqual("The coordinates should be a list", - str(e.exception)) + self.assertEqual("The coordinates should be a list", str(e.exception)) - coordinates_list = [[[1, 2], [2, 1]], [ - np.array([1, 2]), np.array([2, 1])]] + coordinates_list = [[[1, 2], [2, 1]], [np.array([1, 2]), np.array([2, 1])]] for each_coordinates in coordinates_list: with self.assertRaises(TypeError) as e: TSP(each_coordinates) - self.assertEqual("The coordinates should be contained in a tuple", - str(e.exception)) + self.assertEqual( + "The coordinates should be contained in a tuple", str(e.exception) + ) - coordinates_list = [[('oh', 'num'), ('num', 'oh')], - [(np.array(1), np.array(2)), (np.array(2), np.array(1))]] + coordinates_list = [ + [("oh", "num"), ("num", "oh")], + [(np.array(1), np.array(2)), (np.array(2), np.array(1))], + ] for each_coordinates in coordinates_list: with self.assertRaises(TypeError) as e: TSP(each_coordinates) - self.assertEqual("The coordinates must be of type float or int", - str(e.exception)) + self.assertEqual( + "The coordinates must be of type float or int", str(e.exception) + ) # coordinates type-check - distance_matrices = [(1, 2), np.array([[1, 2], [3, 4]]), { - 'test': 'oh', 'test1': 'oh'}] + distance_matrices = [ + (1, 2), + np.array([[1, 2], [3, 4]]), + {"test": "oh", "test1": "oh"}, + ] for distance_matrix in distance_matrices: with self.assertRaises(TypeError) as e: TSP(distance_matrix=distance_matrix) - self.assertEqual("The distance matrix should be a list", - str(e.exception)) + self.assertEqual("The distance matrix should be a list", str(e.exception)) # Distance matrix type-check - distance_matrices = [[(1, 2), (2, 1)], [ - np.array([1, 2]), np.array([2, 1])]] + distance_matrices = [[(1, 2), (2, 1)], [np.array([1, 2]), np.array([2, 1])]] for distance_matrix in distance_matrices: with self.assertRaises(TypeError) as e: TSP(distance_matrix=distance_matrix) - self.assertEqual("Each row in the distance matrix should be a list", - str(e.exception)) - - distance_matrices = [[['oh', 'num'], ['num', 'oh']], - [[np.array(1), np.array(2)], [np.array(2), np.array(1)]]] + self.assertEqual( + "Each row in the distance matrix should be a list", str(e.exception) + ) + + distance_matrices = [ + [["oh", "num"], ["num", "oh"]], + [[np.array(1), np.array(2)], [np.array(2), np.array(1)]], + ] for distance_matrix in distance_matrices: with self.assertRaises(TypeError) as e: TSP(distance_matrix=distance_matrix) - self.assertEqual("The distance matrix entries must be of type float or int", - str(e.exception)) + self.assertEqual( + "The distance matrix entries must be of type float or int", + str(e.exception), + ) distance_matrix = [[1, 2.3], [-2, 3]] with self.assertRaises(ValueError) as e: TSP(distance_matrix=distance_matrix) - self.assertEqual("Distances should be positive", - str(e.exception)) + self.assertEqual("Distances should be positive", str(e.exception)) # Graph type-check G = nx.complete_graph(5) for (u, v) in G.edges(): - G[u][v]['weight'] = 'a' + G[u][v]["weight"] = "a" with self.assertRaises(TypeError) as e: TSP(G=G) - self.assertEqual("The edge weights must be of type float or int", - str(e.exception)) + self.assertEqual( + "The edge weights must be of type float or int", str(e.exception) + ) for (u, v) in G.edges(): - G[u][v]['weight'] = -2. + G[u][v]["weight"] = -2.0 with self.assertRaises(ValueError) as e: TSP(G=G) - self.assertEqual("Edge weights should be positive", - str(e.exception)) + self.assertEqual("Edge weights should be positive", str(e.exception)) # TESTING SHORTESTPATH PROBLEM CLASS def test_shortestpath_terms_weights_constant(self): """Test terms,weights,constant of QUBO generated by Shortest Path class""" - sp_terms = [[0], [1], [2], [3], [1], [1, 2], [2, 1], [2], [2], [2, 3], - [3, 2], [3], [0], [0, 1], [1], [1, 3], [0, 3], [3, 1], [3]] - sp_weights = [1, 1, 1, 1, -1, 1, 1, - - 1, -1, 1, 1, -1, 4, -4, 1, 1, -4, 1, 1] - conv_sp_terms = [[1, 2], [2, 1], [2, 3], [3, 2], [ - 0, 1], [1, 3], [0, 3], [3, 1], [0], [1], [2], [3], []] - conv_sp_weights = [0.25, 0.25, 0.25, 0.25, -1.0, - 0.25, -1.0, 0.25, -0.5, -0.5, -0.5, -0.5, 2.5] - sp_qubo_terms = [[1, 2], [2, 3], [0, 1], - [1, 3], [0, 3], [0], [1], [2], [3]] + sp_terms = [ + [0], + [1], + [2], + [3], + [1], + [1, 2], + [2, 1], + [2], + [2], + [2, 3], + [3, 2], + [3], + [0], + [0, 1], + [1], + [1, 3], + [0, 3], + [3, 1], + [3], + ] + sp_weights = [1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 4, -4, 1, 1, -4, 1, 1] + conv_sp_terms = [ + [1, 2], + [2, 1], + [2, 3], + [3, 2], + [0, 1], + [1, 3], + [0, 3], + [3, 1], + [0], + [1], + [2], + [3], + [], + ] + conv_sp_weights = [ + 0.25, + 0.25, + 0.25, + 0.25, + -1.0, + 0.25, + -1.0, + 0.25, + -0.5, + -0.5, + -0.5, + -0.5, + 2.5, + ] + sp_qubo_terms = [[1, 2], [2, 3], [0, 1], [1, 3], [0, 3], [0], [1], [2], [3]] sp_qubo_weights = [0.5, 0.5, -1.0, 0.5, -1.0, -0.5, -0.5, -0.5, -0.5] sp_qubo_constant = 2.5 gr = nx.generators.fast_gnp_random_graph(3, 1, seed=1234) for (u, v) in gr.edges(): - gr.edges[u, v]['weight'] = 1 + gr.edges[u, v]["weight"] = 1 for w in gr.nodes(): - gr.nodes[w]['weight'] = 1 + gr.nodes[w]["weight"] = 1 source, dest = 0, 2 sp = ShortestPath(gr, source, dest) n_variables = sp.G.number_of_nodes() + sp.G.number_of_edges() - 2 bin_terms, bin_weights = sp.terms_and_weights() - terms, weights = QUBO.convert_qubo_to_ising( - n_variables, bin_terms, bin_weights) + terms, weights = QUBO.convert_qubo_to_ising(n_variables, bin_terms, bin_weights) qubo = sp.qubo print(terms) self.assertTrue(terms_list_equality(bin_terms, sp_terms)) @@ -792,32 +988,28 @@ def test_shortestpath_terms_weights_constant(self): def test_shortestpath_random_instance(self): """Test random instance method of Shortest Path problem class""" - sp_rand_terms = [[1, 2], [2, 3], [0, 1], - [1, 3], [0, 3], [0], [1], [2], [3]] + sp_rand_terms = [[1, 2], [2, 3], [0, 1], [1, 3], [0, 3], [0], [1], [2], [3]] sp_rand_weights = [0.5, 0.5, -1.0, 0.5, -1.0, -0.5, -0.5, -0.5, -0.5] sp_rand_constant = 2.5 gr = nx.generators.fast_gnp_random_graph(3, 1, seed=1234) for (u, v) in gr.edges(): - gr.edges[u, v]['weight'] = 1.0 + gr.edges[u, v]["weight"] = 1.0 for w in gr.nodes(): - gr.nodes[w]['weight'] = 1.0 + gr.nodes[w]["weight"] = 1.0 sp_prob = ShortestPath.random_instance( - n_nodes=3, edge_probability=1, seed=1234, source=0, dest=2).qubo + n_nodes=3, edge_probability=1, seed=1234, source=0, dest=2 + ).qubo print(sp_prob.terms) self.assertTrue(terms_list_equality(sp_rand_terms, sp_prob.terms)) self.assertEqual(sp_rand_weights, sp_prob.weights) self.assertEqual(sp_rand_constant, sp_prob.constant) - self.assertEqual(sp_prob.terms, ShortestPath( - gr, 0, 2).qubo.terms) - self.assertEqual(sp_prob.weights, ShortestPath( - gr, 0, 2).qubo.weights) - self.assertEqual(sp_prob.constant, ShortestPath( - gr, 0, 2).qubo.constant) + self.assertEqual(sp_prob.terms, ShortestPath(gr, 0, 2).qubo.terms) + self.assertEqual(sp_prob.weights, ShortestPath(gr, 0, 2).qubo.weights) + self.assertEqual(sp_prob.constant, ShortestPath(gr, 0, 2).qubo.constant) def test_assertion_error(self): - def test_assertion_fn(): n_row = 1 n_col = 1 @@ -832,8 +1024,8 @@ def test_assertion_fn(): node_dict = dict(zip(list(G.nodes()), node_weights)) edge_dict = dict(zip(list(G.edges()), edge_weights)) - nx.set_edge_attributes(G, values=edge_dict, name='weight') - nx.set_node_attributes(G, values=node_dict, name='weight') + nx.set_edge_attributes(G, values=edge_dict, name="weight") + nx.set_node_attributes(G, values=node_dict, name="weight") shortest_path_problem = ShortestPath(G, 0, -1) shortest_path_qubo = shortest_path_problem.qubo @@ -842,15 +1034,27 @@ def test_assertion_fn(): def __generate_random_problems(self): problems_random_instances = { - "tsp":TSP.random_instance(n_cities=randint(2, 15)), - "number_partition":NumberPartition.random_instance(n_numbers=randint(2, 15)), - "maximum_cut":MaximumCut.random_instance(n_nodes=randint(2, 15), edge_probability=random()), - "knapsack":Knapsack.random_instance(n_items=randint(2, 15)), - "slack_free_knapsack":SlackFreeKnapsack.random_instance(n_items=randint(2, 15)), - "minimum_vertex_cover":MinimumVertexCover.random_instance(n_nodes=randint(2, 15), edge_probability=random()), - "shortest_path":ShortestPath.random_instance(n_nodes=randint(3, 15), edge_probability=random()), + "tsp": TSP.random_instance(n_cities=randint(2, 15)), + "number_partition": NumberPartition.random_instance( + n_numbers=randint(2, 15) + ), + "maximum_cut": MaximumCut.random_instance( + n_nodes=randint(2, 15), edge_probability=random() + ), + "knapsack": Knapsack.random_instance(n_items=randint(2, 15)), + "slack_free_knapsack": SlackFreeKnapsack.random_instance( + n_items=randint(2, 15) + ), + "minimum_vertex_cover": MinimumVertexCover.random_instance( + n_nodes=randint(2, 15), edge_probability=random() + ), + "shortest_path": ShortestPath.random_instance( + n_nodes=randint(3, 15), edge_probability=random() + ), + } + qubo_random_instances = { + k: v.qubo for k, v in problems_random_instances.items() } - qubo_random_instances = {k:v.qubo for k,v in problems_random_instances.items()} qubo_random_instances["generic_qubo"] = QUBO.random_instance(randint(2, 15)) return problems_random_instances, qubo_random_instances @@ -864,20 +1068,37 @@ def test_problem_instance(self): _, qubos = self.__generate_random_problems() expected_keys = { - "tsp":['problem_type', 'n_cities', 'G', 'A', 'B'], - "number_partition":['problem_type', 'numbers', 'n_numbers'], - "maximum_cut":['problem_type', 'G'], - "knapsack":['problem_type', 'values', 'weights', 'weight_capacity', 'penalty', 'n_items'], - "slack_free_knapsack":['problem_type', 'values', 'weights', 'weight_capacity', 'penalty', 'n_items'], - "minimum_vertex_cover":['problem_type', 'G', 'field', 'penalty'], - "shortest_path":['problem_type', 'G', 'source', 'dest'], - "generic_qubo":['problem_type'] + "tsp": ["problem_type", "n_cities", "G", "A", "B"], + "number_partition": ["problem_type", "numbers", "n_numbers"], + "maximum_cut": ["problem_type", "G"], + "knapsack": [ + "problem_type", + "values", + "weights", + "weight_capacity", + "penalty", + "n_items", + ], + "slack_free_knapsack": [ + "problem_type", + "values", + "weights", + "weight_capacity", + "penalty", + "n_items", + ], + "minimum_vertex_cover": ["problem_type", "G", "field", "penalty"], + "shortest_path": ["problem_type", "G", "source", "dest"], + "generic_qubo": ["problem_type"], } - for k,v in qubos.items(): - assert list(v.problem_instance.keys()) == expected_keys[k], "Problem instance keys are not correct for problem type {}".format(k) - assert k == v.problem_instance['problem_type'], "Problem type is not correct for problem type {}".format(k) - + for k, v in qubos.items(): + assert ( + list(v.problem_instance.keys()) == expected_keys[k] + ), "Problem instance keys are not correct for problem type {}".format(k) + assert ( + k == v.problem_instance["problem_type"] + ), "Problem type is not correct for problem type {}".format(k) def test_problem_from_instance_dict(self): """ @@ -904,10 +1125,17 @@ def test_problem_from_instance_dict(self): problem = create_problem_from_dict(problem_instance) - assert problem.problem_instance == problems[type].problem_instance, "Problem from instance method is not correct for problem type {}".format(type) - assert convert2serialize(problem) == convert2serialize(problems[type]), "Problem from instance method is not correct for problem type {}".format(type) + assert ( + problem.problem_instance == problems[type].problem_instance + ), "Problem from instance method is not correct for problem type {}".format( + type + ) + assert convert2serialize(problem) == convert2serialize( + problems[type] + ), "Problem from instance method is not correct for problem type {}".format( + type + ) - def test_qubo_from_dict(self): """ Test qubo from dict method of the QUBO class. @@ -921,15 +1149,26 @@ def test_qubo_from_dict(self): new_qubo = QUBO.from_dict(qubo_dict) for term, new_term in zip(qubo.terms, new_qubo.terms): - assert set(term) == set(new_term), "QUBO from dict method is not correct for problem type {}, terms compared: {}, {}".format(qubo.problem_instance['problem_type'], term, new_term) - - assert set(qubo.weights) == set(new_qubo.weights), "QUBO from dict method is not correct for problem type {}".format(qubo.problem_instance['problem_type']) + assert set(term) == set( + new_term + ), "QUBO from dict method is not correct for problem type {}, terms compared: {}, {}".format( + qubo.problem_instance["problem_type"], term, new_term + ) + + assert set(qubo.weights) == set( + new_qubo.weights + ), "QUBO from dict method is not correct for problem type {}".format( + qubo.problem_instance["problem_type"] + ) for key in qubo.__dict__: if key != "terms" and key != "weights": - assert qubo.__dict__[key] == new_qubo.__dict__[key], "QUBO from dict method is not correct for problem type {}".format(qubo.problem_instance['problem_type']) - + assert ( + qubo.__dict__[key] == new_qubo.__dict__[key] + ), "QUBO from dict method is not correct for problem type {}".format( + qubo.problem_instance["problem_type"] + ) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_pyquil_qvm.py b/tests/test_pyquil_qvm.py index 2141d61c9..5ac90e5e0 100644 --- a/tests/test_pyquil_qvm.py +++ b/tests/test_pyquil_qvm.py @@ -6,7 +6,12 @@ from pyquil.gates import RX, RY, RZ from openqaoa import QAOA -from openqaoa.qaoa_components import create_qaoa_variational_params, QAOADescriptor, PauliOp, Hamiltonian +from openqaoa.qaoa_components import ( + create_qaoa_variational_params, + QAOADescriptor, + PauliOp, + Hamiltonian, +) from openqaoa.utilities import X_mixer_hamiltonian from openqaoa.backends import QAOAvectorizedBackendSimulator, create_device from openqaoa.problems import NumberPartition, QUBO @@ -14,127 +19,273 @@ class TestingQAOACostPyquilQVM(unittest.TestCase): - + """This Object tests the QAOA Cost PyQuil QPU object, which is tasked with the creation and execution of a QAOA circuit for the selected QPU provider and backend. `as_qvm` is set to be True throughout. - + For all of these tests, qvm and quilc must be running. """ + @pytest.mark.qvm def test_connection(self): - + """ Checks if connection to qvm and quilc is successful. TODO : improve test """ - + # Check connection to qvm - device_pyquil = DevicePyquil(device_name = "2q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) - + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) + # Check connection to quilc compiler program = Program().inst(RX(np.pi, 0)) device_pyquil.quantum_computer.compiler.quil_to_native_quil(program) pass - + @pytest.mark.qvm def test_active_reset(self): - + """ Test if active_reset works fine. Check for RESET instruction in parametric circuit when active_reset = True / False """ - - device_pyquil = DevicePyquil(device_name = "2q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,))], [1,2], 1) + + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) + cost_hamil = Hamiltonian([PauliOp("Z", (0,)), PauliOp("Z", (1,))], [1, 2], 1) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - - backend_obj_pyquil = QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = None, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=1, active_reset = True) - assert 'RESET' in [str(instr) for instr in backend_obj_pyquil.parametric_circuit] - - backend_obj_pyquil = QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = None, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=1, active_reset = False) - assert 'RESET' not in [str(instr) for instr in backend_obj_pyquil.parametric_circuit] - + + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=1, + active_reset=True, + ) + assert "RESET" in [ + str(instr) for instr in backend_obj_pyquil.parametric_circuit + ] + + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=1, + active_reset=False, + ) + assert "RESET" not in [ + str(instr) for instr in backend_obj_pyquil.parametric_circuit + ] + @pytest.mark.qvm def test_rewiring(self): - + """ Test if rewiring works fine. - + """ - device_pyquil = DevicePyquil(device_name = "2q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,))], [1,2], 1) + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) + cost_hamil = Hamiltonian([PauliOp("Z", (0,)), PauliOp("Z", (1,))], [1, 2], 1) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - + # Test if error is raised correctly - self.assertRaises(ValueError, lambda : QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = None, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=1, rewiring = 'illegal string')) - + self.assertRaises( + ValueError, + lambda: QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=1, + rewiring="illegal string", + ), + ) + # Test when rewiring = 'PRAGMA INITIAL_REWIRING "NAIVE"' - backend_obj_pyquil = QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = None, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=1, rewiring = 'PRAGMA INITIAL_REWIRING "NAIVE"') - assert 'PRAGMA INITIAL_REWIRING "NAIVE"' in [str(instr) for instr in backend_obj_pyquil.parametric_circuit] - + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=1, + rewiring='PRAGMA INITIAL_REWIRING "NAIVE"', + ) + assert 'PRAGMA INITIAL_REWIRING "NAIVE"' in [ + str(instr) for instr in backend_obj_pyquil.parametric_circuit + ] + # Test when rewiring = 'PRAGMA INITIAL_REWIRING "PARTIAL"' - backend_obj_pyquil = QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = None, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=1, rewiring = 'PRAGMA INITIAL_REWIRING "PARTIAL"') - assert 'PRAGMA INITIAL_REWIRING "PARTIAL"' in [str(instr) for instr in backend_obj_pyquil.parametric_circuit] - + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=1, + rewiring='PRAGMA INITIAL_REWIRING "PARTIAL"', + ) + assert 'PRAGMA INITIAL_REWIRING "PARTIAL"' in [ + str(instr) for instr in backend_obj_pyquil.parametric_circuit + ] + @pytest.mark.qvm def test_qaoa_pyquil_expectation(self): - + """ Checks if expectation value agrees with known values. Since angles are selected such that the final state is one of the computational basis states, shots do not matter (there is no statistical variance). """ - device_pyquil = DevicePyquil(device_name = "2q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) # Without interaction terms - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,))], [1,1], 1) + cost_hamil = Hamiltonian([PauliOp("Z", (0,)), PauliOp("Z", (1,))], [1, 1], 1) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - variate_params = create_qaoa_variational_params(qaoa_descriptor,'standard','ramp') + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) - args = [np.pi/4, np.pi/4] # beta, gamma + args = [np.pi / 4, np.pi / 4] # beta, gamma variate_params.update_from_raw(args) - - backend_obj_pyquil = QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = None, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=1) + + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=1, + ) backend_obj_pyquil.expectation(variate_params) assert np.isclose(backend_obj_pyquil.expectation(variate_params), -1) @pytest.mark.qvm def test_qaoa_pyquil_gate_names(self): - + """ Checks if names of gates are correct, and no. of measurement gates match the no. of qubits. """ - device_pyquil = DevicePyquil(device_name = "2q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) # Without interaction terms - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,))], [1,1], 1) + cost_hamil = Hamiltonian([PauliOp("Z", (0,)), PauliOp("Z", (1,))], [1, 1], 1) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - backend_obj_pyquil = QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = None, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=1) - - gate_names = [instr.name for instr in backend_obj_pyquil.parametric_circuit if type(instr) == quilbase.Gate] - assert gate_names == ['RZ','RX','RZ','RX','RZ','RX','RZ','RX', 'RZ', 'RZ', 'RX', 'RX'] - - measurement_gate_no = len([instr for instr in backend_obj_pyquil.parametric_circuit if type(instr) == quilbase.Measurement]) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=1, + ) + + gate_names = [ + instr.name + for instr in backend_obj_pyquil.parametric_circuit + if type(instr) == quilbase.Gate + ] + assert gate_names == [ + "RZ", + "RX", + "RZ", + "RX", + "RZ", + "RX", + "RZ", + "RX", + "RZ", + "RZ", + "RX", + "RX", + ] + + measurement_gate_no = len( + [ + instr + for instr in backend_obj_pyquil.parametric_circuit + if type(instr) == quilbase.Measurement + ] + ) assert measurement_gate_no == 2 # With interaction terms - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,)), PauliOp('ZZ',(0,1))], [1,1,1], 1) + cost_hamil = Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - backend_obj_pyquil = QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = None, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=1) - - gate_names = [instr.name for instr in backend_obj_pyquil.parametric_circuit if type(instr) == quilbase.Gate] - assert gate_names == ['RZ', 'RX', 'RZ', 'RX', 'RZ', 'RX', 'RZ', 'RX', 'RZ', 'RZ', 'RZ', 'RZ', 'CPHASE', 'RX', 'RX'] - - measurement_gate_no = len([instr for instr in backend_obj_pyquil.parametric_circuit if type(instr) == quilbase.Measurement]) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=1, + ) + + gate_names = [ + instr.name + for instr in backend_obj_pyquil.parametric_circuit + if type(instr) == quilbase.Gate + ] + assert gate_names == [ + "RZ", + "RX", + "RZ", + "RX", + "RZ", + "RX", + "RZ", + "RX", + "RZ", + "RZ", + "RZ", + "RZ", + "CPHASE", + "RX", + "RX", + ] + + measurement_gate_no = len( + [ + instr + for instr in backend_obj_pyquil.parametric_circuit + if type(instr) == quilbase.Measurement + ] + ) assert measurement_gate_no == 2 @pytest.mark.qvm @@ -144,27 +295,73 @@ def test_circuit_init_hadamard(self): Checks correctness of circuit for the argument `init_hadamard`. """ - device_pyquil = DevicePyquil(device_name = "2q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) # With hadamard - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,)), PauliOp('ZZ',(0,1))], [1,1,1], 1) + cost_hamil = Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - pyquil_backend = QAOAPyQuilQPUBackend(device_pyquil, qaoa_descriptor, - n_shots = 10, prepend_state = None, - append_state = None, init_hadamard = True, cvar_alpha = 1) - - assert ['RZ', 'RX', 'RZ', 'RX', 'RZ', 'RX', 'RZ', 'RX', 'RZ', 'RZ', 'RZ', 'RZ', 'CPHASE', 'RX', 'RX'] == [instr.name for instr in pyquil_backend.parametric_circuit if type(instr) == quilbase.Gate] + pyquil_backend = QAOAPyQuilQPUBackend( + device_pyquil, + qaoa_descriptor, + n_shots=10, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + ) + + assert [ + "RZ", + "RX", + "RZ", + "RX", + "RZ", + "RX", + "RZ", + "RX", + "RZ", + "RZ", + "RZ", + "RZ", + "CPHASE", + "RX", + "RX", + ] == [ + instr.name + for instr in pyquil_backend.parametric_circuit + if type(instr) == quilbase.Gate + ] # Without hadamard - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,)), PauliOp('ZZ',(0,1))], [1,1,1], 1) + cost_hamil = Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - pyquil_backend = QAOAPyQuilQPUBackend(device_pyquil, qaoa_descriptor, - n_shots = 10, prepend_state = None, - append_state = None, init_hadamard = False, cvar_alpha = 1) - - assert ['RZ', 'RZ', 'RZ', 'RZ', 'CPHASE', 'RX', 'RX'] == [instr.name for instr in pyquil_backend.parametric_circuit if type(instr) == quilbase.Gate] + pyquil_backend = QAOAPyQuilQPUBackend( + device_pyquil, + qaoa_descriptor, + n_shots=10, + prepend_state=None, + append_state=None, + init_hadamard=False, + cvar_alpha=1, + ) + + assert ["RZ", "RZ", "RZ", "RZ", "CPHASE", "RX", "RX"] == [ + instr.name + for instr in pyquil_backend.parametric_circuit + if type(instr) == quilbase.Gate + ] @pytest.mark.qvm def test_circuit_append_state(self): @@ -173,21 +370,36 @@ def test_circuit_append_state(self): Checks correctness of circuit for the argument `append_state`. """ - device_pyquil = DevicePyquil(device_name = "2q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) # With append_state - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,)), PauliOp('ZZ',(0,1))], [1,1,1], 1) + cost_hamil = Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - append_circuit = Program().inst(RX(np.pi, 0), RY(np.pi/2, 1), RZ(np.pi, 0)) + append_circuit = Program().inst(RX(np.pi, 0), RY(np.pi / 2, 1), RZ(np.pi, 0)) + pyquil_backend = QAOAPyQuilQPUBackend( + device_pyquil, + qaoa_descriptor, + n_shots=10, + prepend_state=None, + append_state=append_circuit, + init_hadamard=False, + cvar_alpha=1, + ) - pyquil_backend = QAOAPyQuilQPUBackend(device_pyquil, qaoa_descriptor, - n_shots = 10, prepend_state = None, - append_state = append_circuit, init_hadamard = False, cvar_alpha = 1) - - assert ['RZ', 'RZ', 'RZ', 'RZ', 'CPHASE', 'RX', 'RX', 'RX', 'RY', 'RZ'] == [instr.name for instr in pyquil_backend.parametric_circuit if type(instr) == quilbase.Gate] + assert ["RZ", "RZ", "RZ", "RZ", "CPHASE", "RX", "RX", "RX", "RY", "RZ"] == [ + instr.name + for instr in pyquil_backend.parametric_circuit + if type(instr) == quilbase.Gate + ] @pytest.mark.qvm def test_circuit_prepend_state(self): @@ -196,25 +408,51 @@ def test_circuit_prepend_state(self): Checks correctness of circuit for the argument `prepend_state`. """ - device_pyquil = DevicePyquil(device_name = "2q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) # With prepend_state - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,)), PauliOp('ZZ',(0,1))], [1,1,1], 1) + cost_hamil = Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - prepend_circuit = Program().inst(RX(np.pi, 0), RY(np.pi/2, 1), RZ(np.pi, 0)) + prepend_circuit = Program().inst(RX(np.pi, 0), RY(np.pi / 2, 1), RZ(np.pi, 0)) + pyquil_backend = QAOAPyQuilQPUBackend( + device_pyquil, + qaoa_descriptor, + n_shots=10, + prepend_state=prepend_circuit, + append_state=None, + init_hadamard=False, + cvar_alpha=1, + ) - pyquil_backend = QAOAPyQuilQPUBackend(device_pyquil, qaoa_descriptor, - n_shots = 10, prepend_state = prepend_circuit, - append_state = None, init_hadamard = False, cvar_alpha = 1) + assert ["RX", "RY", "RZ", "RZ", "RZ", "RZ", "RZ", "CPHASE", "RX", "RX"] == [ + instr.name + for instr in pyquil_backend.parametric_circuit + if type(instr) == quilbase.Gate + ] - assert ['RX', 'RY', 'RZ', 'RZ', 'RZ', 'RZ', 'RZ', 'CPHASE', 'RX', 'RX'] == [instr.name for instr in pyquil_backend.parametric_circuit if type(instr) == quilbase.Gate] - # Test if error is raised correctly - prepend_circuit = Program().inst(RX(np.pi, 0), RY(np.pi/2, 1), RZ(np.pi, 2)) - self.assertRaises(AssertionError, lambda : QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = prepend_circuit, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=1)) + prepend_circuit = Program().inst(RX(np.pi, 0), RY(np.pi / 2, 1), RZ(np.pi, 2)) + self.assertRaises( + AssertionError, + lambda: QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=prepend_circuit, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=1, + ), + ) @pytest.mark.qvm def test_pyquil_vectorized_agreement(self): @@ -224,29 +462,50 @@ def test_pyquil_vectorized_agreement(self): """ # Without interaction terms - device_pyquil = DevicePyquil(device_name = "2q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) - - cost_hamil = Hamiltonian([PauliOp('Z',(0,)), PauliOp('Z',(1,)), PauliOp('ZZ',(0,1))], [1,1,1], 1) + device_pyquil = DevicePyquil( + device_name="2q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) + device_pyquil.quantum_computer.qam.random_seed = 1 + + cost_hamil = Hamiltonian( + [PauliOp("Z", (0,)), PauliOp("Z", (1,)), PauliOp("ZZ", (0, 1))], + [1, 1, 1], + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - variate_params = create_qaoa_variational_params(qaoa_descriptor,'standard','ramp') - args = [np.pi/8, np.pi/4] # beta, gamma + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "ramp" + ) + args = [np.pi / 8, np.pi / 4] # beta, gamma variate_params.update_from_raw(args) - backend_obj_pyquil = QAOAPyQuilQPUBackend(qaoa_descriptor = qaoa_descriptor, device = device_pyquil, prepend_state = None, append_state = None, init_hadamard = True, cvar_alpha = 1, n_shots=100) + backend_obj_pyquil = QAOAPyQuilQPUBackend( + qaoa_descriptor=qaoa_descriptor, + device=device_pyquil, + prepend_state=None, + append_state=None, + init_hadamard=True, + cvar_alpha=1, + n_shots=10, + ) expt_pyquil = backend_obj_pyquil.expectation(variate_params) - + variate_params.update_from_raw(args) - backend_obj_vectorized = QAOAvectorizedBackendSimulator(qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True) - expt_vec, std_dev_vec = backend_obj_vectorized.expectation_w_uncertainty(variate_params) + backend_obj_vectorized = QAOAvectorizedBackendSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) + expt_vec, std_dev_vec = backend_obj_vectorized.expectation_w_uncertainty( + variate_params + ) + + self.assertAlmostEqual(expt_vec, expt_pyquil, delta=std_dev_vec) - self.assertAlmostEqual(expt_vec, expt_pyquil, delta = std_dev_vec) - @pytest.mark.qvm def test_remote_qubit_overflow(self): """ If the user creates a circuit that is larger than the maximum circuit size - that is supported by the QPU. An Exception should be raised with the + that is supported by the QPU. An Exception should be raised with the appropriate error message alerting the user to the error. """ @@ -255,14 +514,23 @@ def test_remote_qubit_overflow(self): qubo = NumberPartition(set_of_numbers).qubo mixer_hamil = X_mixer_hamiltonian(n_qubits=6) qaoa_descriptor = QAOADescriptor(qubo.hamiltonian, mixer_hamil, p=1) - variate_params = create_qaoa_variational_params(qaoa_descriptor, 'standard', 'rand') - - device_qvm = DevicePyquil(device_name = "5q-qvm", as_qvm=True, execution_timeout = 3, compiler_timeout=3) + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "rand" + ) + + device_qvm = DevicePyquil( + device_name="5q-qvm", as_qvm=True, execution_timeout=3, compiler_timeout=3 + ) try: - qvm_backend = QAOAPyQuilQPUBackend(device_qvm, qaoa_descriptor, shots, None, None, True, 1.) + qvm_backend = QAOAPyQuilQPUBackend( + device_qvm, qaoa_descriptor, shots, None, None, True, 1.0 + ) qvm_backend.expectation(variate_params) except Exception as e: - self.assertEqual(str(e), 'There are lesser qubits on the device than the number of qubits required for the circuit.') + self.assertEqual( + str(e), + "There are lesser qubits on the device than the number of qubits required for the circuit.", + ) @pytest.mark.qvm def test_job_ids(self): @@ -270,14 +538,14 @@ def test_job_ids(self): Test if correct job ids are generated and returned when running on qvm """ - #define problem + # define problem problem = QUBO.random_instance(3) # initialize q = QAOA() # device - device = create_device(location='qcs', name="3q-qvm") + device = create_device(location="qcs", name="3q-qvm") q.set_device(device) # classical optimizer only 3 iterations @@ -290,14 +558,17 @@ def test_job_ids(self): q.optimize() # check if we have job ids - opt_id = q.result.optimized['job_id'] - assert len(opt_id) == 36 and isinstance(opt_id, str), f'QCS QVM: job id is not a string of length 36, but {opt_id}' + opt_id = q.result.optimized["job_id"] + assert len(opt_id) == 36 and isinstance( + opt_id, str + ), f"QCS QVM: job id is not a string of length 36, but {opt_id}" - inter_id = q.result.intermediate['job_id'] + inter_id = q.result.intermediate["job_id"] for id in inter_id: - assert len(id) == 36 and isinstance(id, str), f'QCS QVM: on intermediate job id is not a string of length 36, but {id}' - - + assert len(id) == 36 and isinstance( + id, str + ), f"QCS QVM: on intermediate job id is not a string of length 36, but {id}" + -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_qpu_braket.py b/tests/test_qpu_braket.py index 4d841a0da..023226b6d 100644 --- a/tests/test_qpu_braket.py +++ b/tests/test_qpu_braket.py @@ -5,11 +5,16 @@ from braket.circuits import Circuit -from openqaoa.qaoa_components import (PauliOp, Hamiltonian, QAOADescriptor, - create_qaoa_variational_params, QAOAVariationalStandardParams) +from openqaoa.qaoa_components import ( + PauliOp, + Hamiltonian, + QAOADescriptor, + create_qaoa_variational_params, + QAOAVariationalStandardParams, +) from openqaoa.utilities import X_mixer_hamiltonian from openqaoa.problems import NumberPartition -from openqaoa_braket.backends import (DeviceAWS, QAOAAWSQPUBackend) +from openqaoa_braket.backends import DeviceAWS, QAOAAWSQPUBackend class TestingQAOABraketQPUBackend(unittest.TestCase): @@ -17,7 +22,7 @@ class TestingQAOABraketQPUBackend(unittest.TestCase): """This Object tests the QAOA Braket QPU Backend objects, which is tasked with the creation and execution of a QAOA circuit for the selected QPU provider and backend. - + These tests require authentication through the AWS CLI. """ @@ -32,54 +37,56 @@ def test_circuit_angle_assignment_qpu_backend(self): nqubits = 3 p = 2 weights = [1, 1, 1] - gammas = [0, 1/8*np.pi] - betas = [1/2*np.pi, 3/8*np.pi] + gammas = [0, 1 / 8 * np.pi] + betas = [1 / 2 * np.pi, 3 / 8 * np.pi] shots = 100 - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) - aws_device = DeviceAWS('arn:aws:braket:::device/quantum-simulator/amazon/sv1') + aws_device = DeviceAWS("arn:aws:braket:::device/quantum-simulator/amazon/sv1") - aws_backend = QAOAAWSQPUBackend(qaoa_descriptor, aws_device, - shots, None, None, False, 1.) + aws_backend = QAOAAWSQPUBackend( + qaoa_descriptor, aws_device, shots, None, None, False, 1.0 + ) qpu_circuit = aws_backend.qaoa_circuit(variate_params) # Standard Decomposition main_circuit = Circuit() main_circuit.cnot(0, 1) - main_circuit.rz(1, 2*gammas[0]) + main_circuit.rz(1, 2 * gammas[0]) main_circuit.cnot(0, 1) main_circuit.cnot(1, 2) - main_circuit.rz(2, 2*gammas[0]) + main_circuit.rz(2, 2 * gammas[0]) main_circuit.cnot(1, 2) main_circuit.cnot(0, 2) - main_circuit.rz(2, 2*gammas[0]) + main_circuit.rz(2, 2 * gammas[0]) main_circuit.cnot(0, 2) - main_circuit.rx(0, -2*betas[0]) - main_circuit.rx(1, -2*betas[0]) - main_circuit.rx(2, -2*betas[0]) + main_circuit.rx(0, -2 * betas[0]) + main_circuit.rx(1, -2 * betas[0]) + main_circuit.rx(2, -2 * betas[0]) main_circuit.cnot(0, 1) - main_circuit.rz(1, 2*gammas[1]) + main_circuit.rz(1, 2 * gammas[1]) main_circuit.cnot(0, 1) main_circuit.cnot(1, 2) - main_circuit.rz(2, 2*gammas[1]) + main_circuit.rz(2, 2 * gammas[1]) main_circuit.cnot(1, 2) main_circuit.cnot(0, 2) - main_circuit.rz(2, 2*gammas[1]) + main_circuit.rz(2, 2 * gammas[1]) main_circuit.cnot(0, 2) - main_circuit.rx(0, -2*betas[1]) - main_circuit.rx(1, -2*betas[1]) - main_circuit.rx(2, -2*betas[1]) + main_circuit.rx(0, -2 * betas[1]) + main_circuit.rx(1, -2 * betas[1]) + main_circuit.rx(2, -2 * betas[1]) main_circuit.probability() self.assertEqual(main_circuit, qpu_circuit) - @pytest.mark.qpu def test_circuit_angle_assignment_qpu_backend_w_hadamard(self): """ @@ -89,21 +96,24 @@ def test_circuit_angle_assignment_qpu_backend_w_hadamard(self): nqubits = 3 p = 2 weights = [1, 1, 1] - gammas = [0, 1/8*np.pi] - betas = [1/2*np.pi, 3/8*np.pi] + gammas = [0, 1 / 8 * np.pi] + betas = [1 / 2 * np.pi, 3 / 8 * np.pi] shots = 100 - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) - aws_device = DeviceAWS('arn:aws:braket:::device/quantum-simulator/amazon/sv1') + aws_device = DeviceAWS("arn:aws:braket:::device/quantum-simulator/amazon/sv1") - aws_backend = QAOAAWSQPUBackend(qaoa_descriptor, aws_device, - shots, None, None, True, 1.) + aws_backend = QAOAAWSQPUBackend( + qaoa_descriptor, aws_device, shots, None, None, True, 1.0 + ) qpu_circuit = aws_backend.qaoa_circuit(variate_params) # Standard Decomposition @@ -112,34 +122,33 @@ def test_circuit_angle_assignment_qpu_backend_w_hadamard(self): main_circuit.h(1) main_circuit.h(2) main_circuit.cnot(0, 1) - main_circuit.rz(1, 2*gammas[0]) + main_circuit.rz(1, 2 * gammas[0]) main_circuit.cnot(0, 1) main_circuit.cnot(1, 2) - main_circuit.rz(2, 2*gammas[0]) + main_circuit.rz(2, 2 * gammas[0]) main_circuit.cnot(1, 2) main_circuit.cnot(0, 2) - main_circuit.rz(2, 2*gammas[0]) + main_circuit.rz(2, 2 * gammas[0]) main_circuit.cnot(0, 2) - main_circuit.rx(0, -2*betas[0]) - main_circuit.rx(1, -2*betas[0]) - main_circuit.rx(2, -2*betas[0]) + main_circuit.rx(0, -2 * betas[0]) + main_circuit.rx(1, -2 * betas[0]) + main_circuit.rx(2, -2 * betas[0]) main_circuit.cnot(0, 1) - main_circuit.rz(1, 2*gammas[1]) + main_circuit.rz(1, 2 * gammas[1]) main_circuit.cnot(0, 1) main_circuit.cnot(1, 2) - main_circuit.rz(2, 2*gammas[1]) + main_circuit.rz(2, 2 * gammas[1]) main_circuit.cnot(1, 2) main_circuit.cnot(0, 2) - main_circuit.rz(2, 2*gammas[1]) + main_circuit.rz(2, 2 * gammas[1]) main_circuit.cnot(0, 2) - main_circuit.rx(0, -2*betas[1]) - main_circuit.rx(1, -2*betas[1]) - main_circuit.rx(2, -2*betas[1]) + main_circuit.rx(0, -2 * betas[1]) + main_circuit.rx(1, -2 * betas[1]) + main_circuit.rx(2, -2 * betas[1]) main_circuit.probability() self.assertEqual(main_circuit, qpu_circuit) - @pytest.mark.qpu def test_prepend_circuit(self): """ @@ -149,8 +158,8 @@ def test_prepend_circuit(self): nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 100 # Prepended Circuit @@ -159,17 +168,20 @@ def test_prepend_circuit(self): prepend_circuit.x(1) prepend_circuit.x(2) - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) - aws_device = DeviceAWS('arn:aws:braket:::device/quantum-simulator/amazon/sv1') + aws_device = DeviceAWS("arn:aws:braket:::device/quantum-simulator/amazon/sv1") - aws_backend = QAOAAWSQPUBackend(qaoa_descriptor, aws_device, - shots, prepend_circuit, None, True, 1.) + aws_backend = QAOAAWSQPUBackend( + qaoa_descriptor, aws_device, shots, prepend_circuit, None, True, 1.0 + ) qpu_circuit = aws_backend.qaoa_circuit(variate_params) # Standard Decomposition @@ -181,22 +193,21 @@ def test_prepend_circuit(self): main_circuit.h(1) main_circuit.h(2) main_circuit.cnot(0, 1) - main_circuit.rz(1, 2*gammas[0]) + main_circuit.rz(1, 2 * gammas[0]) main_circuit.cnot(0, 1) main_circuit.cnot(1, 2) - main_circuit.rz(2, 2*gammas[0]) + main_circuit.rz(2, 2 * gammas[0]) main_circuit.cnot(1, 2) main_circuit.cnot(0, 2) - main_circuit.rz(2, 2*gammas[0]) + main_circuit.rz(2, 2 * gammas[0]) main_circuit.cnot(0, 2) - main_circuit.rx(0, -2*betas[0]) - main_circuit.rx(1, -2*betas[0]) - main_circuit.rx(2, -2*betas[0]) + main_circuit.rx(0, -2 * betas[0]) + main_circuit.rx(1, -2 * betas[0]) + main_circuit.rx(2, -2 * betas[0]) main_circuit.probability() self.assertEqual(main_circuit, qpu_circuit) - @pytest.mark.qpu def test_append_circuit(self): """ @@ -207,8 +218,8 @@ def test_append_circuit(self): nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 100 # Appended Circuit @@ -217,17 +228,20 @@ def test_append_circuit(self): append_circuit.x(1) append_circuit.x(2) - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) - aws_device = DeviceAWS('arn:aws:braket:::device/quantum-simulator/amazon/sv1') + aws_device = DeviceAWS("arn:aws:braket:::device/quantum-simulator/amazon/sv1") - aws_backend = QAOAAWSQPUBackend(qaoa_descriptor, aws_device, - shots, None, append_circuit, True, 1.) + aws_backend = QAOAAWSQPUBackend( + qaoa_descriptor, aws_device, shots, None, append_circuit, True, 1.0 + ) qpu_circuit = aws_backend.qaoa_circuit(variate_params) # Standard Decomposition @@ -236,27 +250,27 @@ def test_append_circuit(self): main_circuit.h(1) main_circuit.h(2) main_circuit.cnot(0, 1) - main_circuit.rz(1, 2*gammas[0]) + main_circuit.rz(1, 2 * gammas[0]) main_circuit.cnot(0, 1) main_circuit.cnot(1, 2) - main_circuit.rz(2, 2*gammas[0]) + main_circuit.rz(2, 2 * gammas[0]) main_circuit.cnot(1, 2) main_circuit.cnot(0, 2) - main_circuit.rz(2, 2*gammas[0]) + main_circuit.rz(2, 2 * gammas[0]) main_circuit.cnot(0, 2) - main_circuit.rx(0, -2*betas[0]) - main_circuit.rx(1, -2*betas[0]) - main_circuit.rx(2, -2*betas[0]) + main_circuit.rx(0, -2 * betas[0]) + main_circuit.rx(1, -2 * betas[0]) + main_circuit.rx(2, -2 * betas[0]) main_circuit.x(0) main_circuit.x(1) main_circuit.x(2) main_circuit.probability() self.assertEqual(main_circuit, qpu_circuit) - + @pytest.mark.qpu def test_prepend_exception(self): - + """ Test that the error catching for a prepend ciruit larger than the problem circuit is invalid @@ -265,8 +279,8 @@ def test_prepend_exception(self): nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 100 # Prepended Circuit @@ -276,128 +290,154 @@ def test_prepend_exception(self): prepend_circuit.x(2) prepend_circuit.x(3) - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) + + aws_device = DeviceAWS("arn:aws:braket:::device/quantum-simulator/amazon/sv1") - aws_device = DeviceAWS('arn:aws:braket:::device/quantum-simulator/amazon/sv1') - try: - aws_backend = QAOAAWSQPUBackend(qaoa_descriptor, aws_device, - shots, prepend_circuit, None, True, 1.) + aws_backend = QAOAAWSQPUBackend( + qaoa_descriptor, aws_device, shots, prepend_circuit, None, True, 1.0 + ) except Exception as e: - self.assertEqual(str(e), "Cannot attach a bigger circuit to the QAOA routine") + self.assertEqual( + str(e), "Cannot attach a bigger circuit to the QAOA routine" + ) @pytest.mark.qpu def test_exceptions_in_init(self): - + """ Testing the Exceptions in the init function of the QAOAAWSQPUBackend """ - + nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 100 - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) # If the user's aws credentials is not correct. mock_device = Mock() - mock_device.configure_mock(**{'check_connection.return_value': False, - 'provider_connected.return_value': False, - 'qpu_connected.return_value': None, - 'n_qubits': 3}) - + mock_device.configure_mock( + **{ + "check_connection.return_value": False, + "provider_connected.return_value": False, + "qpu_connected.return_value": None, + "n_qubits": 3, + } + ) + try: - QAOAAWSQPUBackend(qaoa_descriptor, mock_device, - shots, None, None, True, 1.) + QAOAAWSQPUBackend( + qaoa_descriptor, mock_device, shots, None, None, True, 1.0 + ) except Exception as e: - self.assertEqual(str(e), 'Error connecting to AWS.') + self.assertEqual(str(e), "Error connecting to AWS.") # Wrong arn string name - aws_device = DeviceAWS('arn:aws:braket:::device/quantum-simulator/amazon/invalid_backend_arn') - + aws_device = DeviceAWS( + "arn:aws:braket:::device/quantum-simulator/amazon/invalid_backend_arn" + ) + try: - QAOAAWSQPUBackend(qaoa_descriptor, aws_device, - shots, None, None, True, 1.) + QAOAAWSQPUBackend(qaoa_descriptor, aws_device, shots, None, None, True, 1.0) except Exception as e: - self.assertEqual(str(e), 'Connection to AWS was made. Error connecting to the specified backend.') - + self.assertEqual( + str(e), + "Connection to AWS was made. Error connecting to the specified backend.", + ) + # No device specified - aws_device = DeviceAWS('') - + aws_device = DeviceAWS("") + try: - QAOAAWSQPUBackend(qaoa_descriptor, aws_device, - shots, None, None, True, 1.) + QAOAAWSQPUBackend(qaoa_descriptor, aws_device, shots, None, None, True, 1.0) except Exception as e: - self.assertEqual(str(e), 'Connection to AWS was made. A device name was not specified.') - + self.assertEqual( + str(e), "Connection to AWS was made. A device name was not specified." + ) + # Correct device arn (Errorless) - aws_device = DeviceAWS('arn:aws:braket:::device/quantum-simulator/amazon/sv1') - - QAOAAWSQPUBackend(qaoa_descriptor, aws_device, shots, None, None, True, 1.) - - @pytest.mark.qpu + aws_device = DeviceAWS("arn:aws:braket:::device/quantum-simulator/amazon/sv1") + + QAOAAWSQPUBackend(qaoa_descriptor, aws_device, shots, None, None, True, 1.0) + + @pytest.mark.qpu def test_remote_qubit_overflow(self): - + """ If the user creates a circuit that is larger than the maximum circuit size - that is supported by the QPU. An Exception should be raised with the + that is supported by the QPU. An Exception should be raised with the appropriate error message alerting the user to the error. """ - + shots = 100 - + set_of_numbers = np.random.randint(1, 10, 100).tolist() qubo = NumberPartition(set_of_numbers).qubo mixer_hamil = X_mixer_hamiltonian(n_qubits=6) qaoa_descriptor = QAOADescriptor(qubo.hamiltonian, mixer_hamil, p=1) - variate_params = create_qaoa_variational_params(qaoa_descriptor, 'standard', 'rand') + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "rand" + ) aws_device = DeviceAWS("arn:aws:braket:::device/quantum-simulator/amazon/sv1") - + try: - braket_backend = QAOAAWSQPUBackend(qaoa_descriptor, aws_device, - shots, None, None, True, 1.) + braket_backend = QAOAAWSQPUBackend( + qaoa_descriptor, aws_device, shots, None, None, True, 1.0 + ) braket_backend.expectation(variate_params) except Exception as e: - self.assertEqual(str(e), 'There are lesser qubits on the device than the number of qubits required for the circuit.') - + self.assertEqual( + str(e), + "There are lesser qubits on the device than the number of qubits required for the circuit.", + ) + @pytest.mark.qpu def test_remote_integration_qpu_run(self): - + """ - Run a toy example in manual mode to make sure everything works as + Run a toy example in manual mode to make sure everything works as expected for a remote backend """ - + shots = 100 - + set_of_numbers = np.random.randint(1, 10, 10).tolist() qubo = NumberPartition(set_of_numbers).qubo mixer_hamil = X_mixer_hamiltonian(n_qubits=6) qaoa_descriptor = QAOADescriptor(qubo.hamiltonian, mixer_hamil, p=1) - variate_params = create_qaoa_variational_params(qaoa_descriptor, 'standard', 'rand') + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "rand" + ) aws_device = DeviceAWS("arn:aws:braket:::device/quantum-simulator/amazon/sv1") - - braket_backend = QAOAAWSQPUBackend(qaoa_descriptor, aws_device, - shots, None, None, True, 1.) + + braket_backend = QAOAAWSQPUBackend( + qaoa_descriptor, aws_device, shots, None, None, True, 1.0 + ) braket_backend.expectation(variate_params) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_qpu_devices.py b/tests/test_qpu_devices.py index a27b96b1b..1c0fd2a24 100644 --- a/tests/test_qpu_devices.py +++ b/tests/test_qpu_devices.py @@ -19,76 +19,78 @@ class TestingDeviceQiskit(unittest.TestCase): For any tests using provided credentials, the tests will only pass if those details provided are correct/valid with IBMQ. - Please ensure that the provided api token, hub, group and project in the + Please ensure that the provided api token, hub, group and project in the crendentials.json are correct. All of these can be found in your IBMQ Account Page. """ + @pytest.mark.api def setUp(self): - self.HUB = 'ibm-q' - self.GROUP = 'open' - self.PROJECT = 'main' - + self.HUB = "ibm-q" + self.GROUP = "open" + self.PROJECT = "main" + @pytest.mark.api def test_changing_provider(self): - + """ - This test checks that the specified hub,group and project in the + This test checks that the specified hub,group and project in the initialisation of DeviceQiskit changes the provider to the appropriate destination. """ - - device_obj = DeviceQiskit(device_name='ibmq_manila') + + device_obj = DeviceQiskit(device_name="ibmq_manila") device_obj.check_connection() - + self.assertEqual(device_obj.provider.credentials.hub, self.HUB) self.assertEqual(device_obj.provider.credentials.group, self.GROUP) self.assertEqual(device_obj.provider.credentials.project, self.PROJECT) - - device_obj2 = DeviceQiskit(device_name='ibmq_manila', - hub='ibm-q-startup') + + device_obj2 = DeviceQiskit(device_name="ibmq_manila", hub="ibm-q-startup") device_obj2.check_connection() - self.assertEqual(device_obj2.provider.credentials.hub, 'ibm-q-startup') - + self.assertEqual(device_obj2.provider.credentials.hub, "ibm-q-startup") + @pytest.mark.api def test_check_connection_provider_no_backend_wrong_hub_group_project(self): - + """ - If the wrong hub, group or project is specified, check_connection should + If the wrong hub, group or project is specified, check_connection should return False. The provider_connected attribute should be updated to False. Since the API Token is loaded from save_account, the api token will be checked by Qiskit. """ - - for each_combi in itertools.product(['invalid_hub', None], - ['invalid_group', None], - ['invalid_project', None]): - + + for each_combi in itertools.product( + ["invalid_hub", None], ["invalid_group", None], ["invalid_project", None] + ): + if each_combi != (None, None, None): - - device_obj = DeviceQiskit(device_name='', - hub=each_combi[0], - group=each_combi[1], - project=each_combi[2]) - + + device_obj = DeviceQiskit( + device_name="", + hub=each_combi[0], + group=each_combi[1], + project=each_combi[2], + ) + self.assertEqual(device_obj.check_connection(), False) self.assertEqual(device_obj.provider_connected, False) self.assertEqual(device_obj.qpu_connected, None) @pytest.mark.api def test_check_connection_provider_no_backend_provided_credentials(self): - + """ If no information about the device name, but the credentials used are correct, check_connection should return True. The provider_connected attribute should be updated to True. """ - device_obj = DeviceQiskit(device_name='', - hub=self.HUB, group=self.GROUP, - project=self.PROJECT) + device_obj = DeviceQiskit( + device_name="", hub=self.HUB, group=self.GROUP, project=self.PROJECT + ) self.assertEqual(device_obj.check_connection(), True) self.assertEqual(device_obj.provider_connected, True) @@ -96,7 +98,7 @@ def test_check_connection_provider_no_backend_provided_credentials(self): @pytest.mark.api def test_check_connection_provider_right_backend_provided_credentials(self): - + """ If the correct device name is provided and the credentials used are correct, check_connection should return True. @@ -104,16 +106,19 @@ def test_check_connection_provider_right_backend_provided_credentials(self): The qpu_connected attribute should be updated to True. """ - device_obj = DeviceQiskit(device_name='', - hub=self.HUB, group=self.GROUP, - project=self.PROJECT) + device_obj = DeviceQiskit( + device_name="", hub=self.HUB, group=self.GROUP, project=self.PROJECT + ) device_obj.check_connection() valid_qpu_name = device_obj.available_qpus[0] - device_obj = DeviceQiskit(device_name=valid_qpu_name, - hub=self.HUB, group=self.GROUP, - project=self.PROJECT) + device_obj = DeviceQiskit( + device_name=valid_qpu_name, + hub=self.HUB, + group=self.GROUP, + project=self.PROJECT, + ) self.assertEqual(device_obj.check_connection(), True) self.assertEqual(device_obj.provider_connected, True) @@ -121,7 +126,7 @@ def test_check_connection_provider_right_backend_provided_credentials(self): @pytest.mark.api def test_check_connection_provider_wrong_backend_provided_credentials(self): - + """ If device name provided is incorrect, and not empty, and the credentials used are correct, check_connection should return False. @@ -129,9 +134,12 @@ def test_check_connection_provider_wrong_backend_provided_credentials(self): The qpu_connected attribute should be updated to False. """ - device_obj = DeviceQiskit(device_name='random_invalid_backend', - hub=self.HUB, group=self.GROUP, - project=self.PROJECT) + device_obj = DeviceQiskit( + device_name="random_invalid_backend", + hub=self.HUB, + group=self.GROUP, + project=self.PROJECT, + ) self.assertEqual(device_obj.check_connection(), False) self.assertEqual(device_obj.provider_connected, True) @@ -139,81 +147,88 @@ def test_check_connection_provider_wrong_backend_provided_credentials(self): class TestingDeviceLocal(unittest.TestCase): - + """ This tests check that the Device Object created for local devices have the appropriate behaviour. """ - + def test_supported_device_names(self): - + for each_device_name in SUPPORTED_LOCAL_SIMULATORS: device_obj = DeviceLocal(each_device_name) - + self.assertEqual(device_obj.check_connection(), True) - + def test_unsupported_device_names(self): - - device_obj = DeviceLocal('unsupported_device') - + + device_obj = DeviceLocal("unsupported_device") + self.assertEqual(device_obj.check_connection(), False) class TestingDeviceAWS(unittest.TestCase): - - """These tests check the Object used to access AWS Braket and their + + """These tests check the Object used to access AWS Braket and their available QPUs can be established. For any tests using provided credentials, the tests will only pass if those details provided are correct/valid with AWS Braket. """ - + @pytest.mark.api def test_changing_aws_region(self): - - device_obj = DeviceAWS(device_name='arn:aws:braket:::device/quantum-simulator/amazon/sv1') - + + device_obj = DeviceAWS( + device_name="arn:aws:braket:::device/quantum-simulator/amazon/sv1" + ) + device_obj.check_connection() default_region = device_obj.aws_region - - self.assertEqual('us-east-1', default_region) - - device_obj = DeviceAWS(device_name='arn:aws:braket:::device/quantum-simulator/amazon/sv1', aws_region='us-west-1') - + + self.assertEqual("us-east-1", default_region) + + device_obj = DeviceAWS( + device_name="arn:aws:braket:::device/quantum-simulator/amazon/sv1", + aws_region="us-west-1", + ) + device_obj.check_connection() custom_region = device_obj.aws_region - - self.assertEqual('us-west-1', custom_region) - + + self.assertEqual("us-west-1", custom_region) + @pytest.mark.api def test_changing_s3_bucket_names(self): - - device_obj = DeviceAWS(device_name='arn:aws:braket:::device/quantum-simulator/amazon/sv1', s3_bucket_name='random_new_name') - + + device_obj = DeviceAWS( + device_name="arn:aws:braket:::device/quantum-simulator/amazon/sv1", + s3_bucket_name="random_new_name", + ) + device_obj.check_connection() custom_bucket = device_obj.s3_bucket_name - - self.assertEqual('random_new_name', custom_bucket) - - @pytest.mark.api + + self.assertEqual("random_new_name", custom_bucket) + + @pytest.mark.api def test_check_connection_provider_no_backend_provided_credentials(self): - + """ If no information about the device name, but the credentials used are correct, check_connection should return True. The provider_connected attribute should be updated to True. """ - device_obj = DeviceAWS(device_name='') + device_obj = DeviceAWS(device_name="") self.assertEqual(device_obj.check_connection(), True) self.assertEqual(device_obj.provider_connected, True) self.assertEqual(device_obj.qpu_connected, None) - @pytest.mark.api def test_check_connection_provider_right_backend_provided_credentials(self): - + """ If the correct device name is provided and the credentials used are correct, check_connection should return True. @@ -221,7 +236,7 @@ def test_check_connection_provider_right_backend_provided_credentials(self): The qpu_connected attribute should be updated to True. """ - device_obj = DeviceAWS(device_name='') + device_obj = DeviceAWS(device_name="") device_obj.check_connection() valid_qpu_name = device_obj.available_qpus[0] @@ -232,10 +247,9 @@ def test_check_connection_provider_right_backend_provided_credentials(self): self.assertEqual(device_obj.provider_connected, True) self.assertEqual(device_obj.qpu_connected, True) - @pytest.mark.api def test_check_connection_provider_wrong_backend_provided_credentials(self): - + """ If device name provided is incorrect, and not empty, and the credentials used are correct, check_connection should return False. @@ -243,80 +257,88 @@ def test_check_connection_provider_wrong_backend_provided_credentials(self): The qpu_connected attribute should be updated to False. """ - device_obj = DeviceAWS(device_name='random_invalid_backend') + device_obj = DeviceAWS(device_name="random_invalid_backend") self.assertEqual(device_obj.check_connection(), False) self.assertEqual(device_obj.provider_connected, True) self.assertEqual(device_obj.qpu_connected, False) - + class TestingDeviceAzure(unittest.TestCase): - - """These tests check the Object used to access Azure and their + + """These tests check the Object used to access Azure and their available QPUs can be established. For any tests using provided credentials, the tests will only pass if those details provided are correct/valid with Azure. """ - + @pytest.mark.api def setUp(self): - + bashCommand = "az resource list" process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE) output, error = process.communicate() - + if error is not None: print(error) - raise Exception('You must have the Azure CLI installed and must be logged in to use the Azure Quantum Backends') + raise Exception( + "You must have the Azure CLI installed and must be logged in to use the Azure Quantum Backends" + ) else: output_json = json.loads(output) - output_json_s = [each_json for each_json in output_json if each_json['name'] == 'TestingOpenQAOA'][0] - self.RESOURCE_ID = output_json_s['id'] - self.AZ_LOCATION = output_json_s['location'] - + output_json_s = [ + each_json + for each_json in output_json + if each_json["name"] == "TestingOpenQAOA" + ][0] + self.RESOURCE_ID = output_json_s["id"] + self.AZ_LOCATION = output_json_s["location"] + @pytest.mark.api def test_check_connection_provider_no_resource_id(self): - + """ If no information about about the workspace is provided, the resource id or az location, check_connection and provider_connected should return False. """ - - for resource_id, az_location in itertools.product(['', self.RESOURCE_ID], - ['', self.AZ_LOCATION]): - - if not (resource_id == self.RESOURCE_ID and az_location == self.AZ_LOCATION): - - device_obj = DeviceAzure(device_name='', - resource_id=resource_id, - az_location=az_location) + + for resource_id, az_location in itertools.product( + ["", self.RESOURCE_ID], ["", self.AZ_LOCATION] + ): + + if not ( + resource_id == self.RESOURCE_ID and az_location == self.AZ_LOCATION + ): + + device_obj = DeviceAzure( + device_name="", resource_id=resource_id, az_location=az_location + ) self.assertEqual(device_obj.check_connection(), False) self.assertEqual(device_obj.provider_connected, False) self.assertEqual(device_obj.qpu_connected, None) - - - @pytest.mark.api + + @pytest.mark.api def test_check_connection_provider_no_backend_provided_credentials(self): - + """ If no information about the device name, but the credentials used are correct, check_connection should return True. The provider_connected attribute should be updated to True. """ - device_obj = DeviceAzure(device_name='', resource_id=self.RESOURCE_ID, - az_location=self.AZ_LOCATION) + device_obj = DeviceAzure( + device_name="", resource_id=self.RESOURCE_ID, az_location=self.AZ_LOCATION + ) self.assertEqual(device_obj.check_connection(), True) self.assertEqual(device_obj.provider_connected, True) self.assertEqual(device_obj.qpu_connected, None) - @pytest.mark.api def test_check_connection_provider_right_backend_provided_credentials(self): - + """ If the correct device name is provided and the credentials used are correct, check_connection should return True. @@ -324,23 +346,26 @@ def test_check_connection_provider_right_backend_provided_credentials(self): The qpu_connected attribute should be updated to True. """ - device_obj = DeviceAzure(device_name='', resource_id=self.RESOURCE_ID, - az_location=self.AZ_LOCATION) + device_obj = DeviceAzure( + device_name="", resource_id=self.RESOURCE_ID, az_location=self.AZ_LOCATION + ) device_obj.check_connection() valid_qpu_name = device_obj.available_qpus[0] - device_obj = DeviceAzure(device_name=valid_qpu_name, resource_id=self.RESOURCE_ID, - az_location=self.AZ_LOCATION) + device_obj = DeviceAzure( + device_name=valid_qpu_name, + resource_id=self.RESOURCE_ID, + az_location=self.AZ_LOCATION, + ) self.assertEqual(device_obj.check_connection(), True) self.assertEqual(device_obj.provider_connected, True) self.assertEqual(device_obj.qpu_connected, True) - @pytest.mark.api def test_check_connection_provider_wrong_backend_provided_credentials(self): - + """ If device name provided is incorrect, and not empty, and the credentials used are correct, check_connection should return False. @@ -348,12 +373,16 @@ def test_check_connection_provider_wrong_backend_provided_credentials(self): The qpu_connected attribute should be updated to False. """ - device_obj = DeviceAzure(device_name='invalid_backend', resource_id=self.RESOURCE_ID, - az_location=self.AZ_LOCATION) + device_obj = DeviceAzure( + device_name="invalid_backend", + resource_id=self.RESOURCE_ID, + az_location=self.AZ_LOCATION, + ) self.assertEqual(device_obj.check_connection(), False) self.assertEqual(device_obj.provider_connected, True) self.assertEqual(device_obj.qpu_connected, False) -if __name__ == '__main__': + +if __name__ == "__main__": unittest.main() diff --git a/tests/test_qpu_qiskit.py b/tests/test_qpu_qiskit.py index 2948c424e..5c3a237fb 100644 --- a/tests/test_qpu_qiskit.py +++ b/tests/test_qpu_qiskit.py @@ -5,11 +5,20 @@ import pytest from qiskit import QuantumCircuit - -from openqaoa.qaoa_components import (create_qaoa_variational_params, PauliOp, - Hamiltonian, QAOADescriptor, QAOAVariationalStandardParams) -from openqaoa_qiskit.backends import (DeviceQiskit, QAOAQiskitQPUBackend, - QAOAQiskitBackendStatevecSimulator) +from qiskit.quantum_info import Operator + +from openqaoa.qaoa_components import ( + create_qaoa_variational_params, + PauliOp, + Hamiltonian, + QAOADescriptor, + QAOAVariationalStandardParams, +) +from openqaoa_qiskit.backends import ( + DeviceQiskit, + QAOAQiskitQPUBackend, + QAOAQiskitBackendStatevecSimulator, +) from openqaoa.utilities import X_mixer_hamiltonian from openqaoa.problems import NumberPartition @@ -22,16 +31,16 @@ class TestingQAOAQiskitQPUBackend(unittest.TestCase): For all of these tests, credentials.json MUST be filled with the appropriate credentials. If unsure about to correctness of the current input credentials - , please run test_qpu_devices.py. + , please run test_qpu_devices.py. """ - + @pytest.mark.qpu def setUp(self): - self.HUB = 'ibm-q' - self.GROUP = 'open' - self.PROJECT = 'main' - + self.HUB = "ibm-q" + self.GROUP = "open" + self.PROJECT = "main" + @pytest.mark.qpu def test_circuit_angle_assignment_qpu_backend(self): """ @@ -43,56 +52,60 @@ def test_circuit_angle_assignment_qpu_backend(self): nqubits = 3 p = 2 weights = [1, 1, 1] - gammas = [0, 1/8*np.pi] - betas = [1/2*np.pi, 3/8*np.pi] + gammas = [0, 1 / 8 * np.pi] + betas = [1 / 2 * np.pi, 3 / 8 * np.pi] shots = 10000 - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) - qiskit_device = DeviceQiskit('ibmq_qasm_simulator', - self.HUB, self.GROUP, - self.PROJECT) + qiskit_device = DeviceQiskit( + "ibmq_qasm_simulator", self.HUB, self.GROUP, self.PROJECT + ) - qiskit_backend = QAOAQiskitQPUBackend(qaoa_descriptor, qiskit_device, - shots, None, - None, False) + qiskit_backend = QAOAQiskitQPUBackend( + qaoa_descriptor, qiskit_device, shots, None, None, False + ) qpu_circuit = qiskit_backend.qaoa_circuit(variate_params) # Standard Decomposition main_circuit = QuantumCircuit(3) main_circuit.cx(0, 1) - main_circuit.rz(2*gammas[0], 1) + main_circuit.rz(2 * gammas[0], 1) main_circuit.cx(0, 1) main_circuit.cx(1, 2) - main_circuit.rz(2*gammas[0], 2) + main_circuit.rz(2 * gammas[0], 2) main_circuit.cx(1, 2) main_circuit.cx(0, 2) - main_circuit.rz(2*gammas[0], 2) + main_circuit.rz(2 * gammas[0], 2) main_circuit.cx(0, 2) - main_circuit.rx(-2*betas[0], 0) - main_circuit.rx(-2*betas[0], 1) - main_circuit.rx(-2*betas[0], 2) + main_circuit.rx(-2 * betas[0], 0) + main_circuit.rx(-2 * betas[0], 1) + main_circuit.rx(-2 * betas[0], 2) main_circuit.cx(0, 1) - main_circuit.rz(2*gammas[1], 1) + main_circuit.rz(2 * gammas[1], 1) main_circuit.cx(0, 1) main_circuit.cx(1, 2) - main_circuit.rz(2*gammas[1], 2) + main_circuit.rz(2 * gammas[1], 2) main_circuit.cx(1, 2) main_circuit.cx(0, 2) - main_circuit.rz(2*gammas[1], 2) + main_circuit.rz(2 * gammas[1], 2) main_circuit.cx(0, 2) - main_circuit.rx(-2*betas[1], 0) - main_circuit.rx(-2*betas[1], 1) - main_circuit.rx(-2*betas[1], 2) - main_circuit.measure_all() + main_circuit.rx(-2 * betas[1], 0) + main_circuit.rx(-2 * betas[1], 1) + main_circuit.rx(-2 * betas[1], 2) - self.assertEqual(main_circuit.to_instruction().definition, - qpu_circuit.to_instruction().definition) + qpu_circuit.remove_final_measurements(inplace=True) + qpu_circuit_operator = Operator(qpu_circuit) + main_circuit_operator = Operator(main_circuit) + + assert qpu_circuit_operator.equiv(main_circuit_operator) @pytest.mark.qpu def test_circuit_angle_assignment_qpu_backend_w_hadamard(self): @@ -103,57 +116,61 @@ def test_circuit_angle_assignment_qpu_backend_w_hadamard(self): nqubits = 3 p = 2 weights = [1, 1, 1] - gammas = [0, 1/8*np.pi] - betas = [1/2*np.pi, 3/8*np.pi] + gammas = [0, 1 / 8 * np.pi] + betas = [1 / 2 * np.pi, 3 / 8 * np.pi] shots = 10000 - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) - qiskit_device = DeviceQiskit('ibmq_qasm_simulator', - self.HUB, self.GROUP, - self.PROJECT) + qiskit_device = DeviceQiskit( + "ibmq_qasm_simulator", self.HUB, self.GROUP, self.PROJECT + ) - qiskit_backend = QAOAQiskitQPUBackend(qaoa_descriptor, qiskit_device, - shots, None, - None, True) + qiskit_backend = QAOAQiskitQPUBackend( + qaoa_descriptor, qiskit_device, shots, None, None, True + ) qpu_circuit = qiskit_backend.qaoa_circuit(variate_params) # Standard Decomposition main_circuit = QuantumCircuit(3) main_circuit.h([0, 1, 2]) main_circuit.cx(0, 1) - main_circuit.rz(2*gammas[0], 1) + main_circuit.rz(2 * gammas[0], 1) main_circuit.cx(0, 1) main_circuit.cx(1, 2) - main_circuit.rz(2*gammas[0], 2) + main_circuit.rz(2 * gammas[0], 2) main_circuit.cx(1, 2) main_circuit.cx(0, 2) - main_circuit.rz(2*gammas[0], 2) + main_circuit.rz(2 * gammas[0], 2) main_circuit.cx(0, 2) - main_circuit.rx(-2*betas[0], 0) - main_circuit.rx(-2*betas[0], 1) - main_circuit.rx(-2*betas[0], 2) + main_circuit.rx(-2 * betas[0], 0) + main_circuit.rx(-2 * betas[0], 1) + main_circuit.rx(-2 * betas[0], 2) main_circuit.cx(0, 1) - main_circuit.rz(2*gammas[1], 1) + main_circuit.rz(2 * gammas[1], 1) main_circuit.cx(0, 1) main_circuit.cx(1, 2) - main_circuit.rz(2*gammas[1], 2) + main_circuit.rz(2 * gammas[1], 2) main_circuit.cx(1, 2) main_circuit.cx(0, 2) - main_circuit.rz(2*gammas[1], 2) + main_circuit.rz(2 * gammas[1], 2) main_circuit.cx(0, 2) - main_circuit.rx(-2*betas[1], 0) - main_circuit.rx(-2*betas[1], 1) - main_circuit.rx(-2*betas[1], 2) - main_circuit.measure_all() + main_circuit.rx(-2 * betas[1], 0) + main_circuit.rx(-2 * betas[1], 1) + main_circuit.rx(-2 * betas[1], 2) + + qpu_circuit.remove_final_measurements(inplace=True) + qpu_circuit_operator = Operator(qpu_circuit) + main_circuit_operator = Operator(main_circuit) - self.assertEqual(main_circuit.to_instruction().definition, - qpu_circuit.to_instruction().definition) + assert qpu_circuit_operator.equiv(main_circuit_operator) @pytest.mark.qpu def test_prepend_circuit(self): @@ -164,28 +181,30 @@ def test_prepend_circuit(self): nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 10000 # Prepended Circuit prepend_circuit = QuantumCircuit(3) prepend_circuit.x([0, 1, 2]) - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) - qiskit_device = DeviceQiskit('ibmq_qasm_simulator', - self.HUB, self.GROUP, - self.PROJECT) + qiskit_device = DeviceQiskit( + "ibmq_qasm_simulator", self.HUB, self.GROUP, self.PROJECT + ) - qiskit_backend = QAOAQiskitQPUBackend(qaoa_descriptor, qiskit_device, - shots, prepend_circuit, - None, True) + qiskit_backend = QAOAQiskitQPUBackend( + qaoa_descriptor, qiskit_device, shots, prepend_circuit, None, True + ) qpu_circuit = qiskit_backend.qaoa_circuit(variate_params) # Standard Decomposition @@ -193,21 +212,23 @@ def test_prepend_circuit(self): main_circuit.x([0, 1, 2]) main_circuit.h([0, 1, 2]) main_circuit.cx(0, 1) - main_circuit.rz(2*gammas[0], 1) + main_circuit.rz(2 * gammas[0], 1) main_circuit.cx(0, 1) main_circuit.cx(1, 2) - main_circuit.rz(2*gammas[0], 2) + main_circuit.rz(2 * gammas[0], 2) main_circuit.cx(1, 2) main_circuit.cx(0, 2) - main_circuit.rz(2*gammas[0], 2) + main_circuit.rz(2 * gammas[0], 2) main_circuit.cx(0, 2) - main_circuit.rx(-2*betas[0], 0) - main_circuit.rx(-2*betas[0], 1) - main_circuit.rx(-2*betas[0], 2) - main_circuit.measure_all() + main_circuit.rx(-2 * betas[0], 0) + main_circuit.rx(-2 * betas[0], 1) + main_circuit.rx(-2 * betas[0], 2) + + qpu_circuit.remove_final_measurements(inplace=True) + qpu_circuit_operator = Operator(qpu_circuit) + main_circuit_operator = Operator(main_circuit) - self.assertEqual(main_circuit.to_instruction().definition, - qpu_circuit.to_instruction().definition) + assert qpu_circuit_operator.equiv(main_circuit_operator) @pytest.mark.qpu def test_append_circuit(self): @@ -219,107 +240,127 @@ def test_append_circuit(self): nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 10000 # Appended Circuit append_circuit = QuantumCircuit(3) append_circuit.x([0, 1, 2]) - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) - qiskit_device = DeviceQiskit('ibmq_qasm_simulator', - self.HUB, self.GROUP, - self.PROJECT) + qiskit_device = DeviceQiskit( + "ibmq_qasm_simulator", self.HUB, self.GROUP, self.PROJECT + ) - qiskit_backend = QAOAQiskitQPUBackend(qaoa_descriptor, qiskit_device, - shots, None, - append_circuit, True) + qiskit_backend = QAOAQiskitQPUBackend( + qaoa_descriptor, qiskit_device, shots, None, append_circuit, True + ) qpu_circuit = qiskit_backend.qaoa_circuit(variate_params) # Standard Decomposition main_circuit = QuantumCircuit(3) main_circuit.h([0, 1, 2]) main_circuit.cx(0, 1) - main_circuit.rz(2*gammas[0], 1) + main_circuit.rz(2 * gammas[0], 1) main_circuit.cx(0, 1) main_circuit.cx(1, 2) - main_circuit.rz(2*gammas[0], 2) + main_circuit.rz(2 * gammas[0], 2) main_circuit.cx(1, 2) main_circuit.cx(0, 2) - main_circuit.rz(2*gammas[0], 2) + main_circuit.rz(2 * gammas[0], 2) main_circuit.cx(0, 2) - main_circuit.rx(-2*betas[0], 0) - main_circuit.rx(-2*betas[0], 1) - main_circuit.rx(-2*betas[0], 2) + main_circuit.rx(-2 * betas[0], 0) + main_circuit.rx(-2 * betas[0], 1) + main_circuit.rx(-2 * betas[0], 2) main_circuit.x([0, 1, 2]) - main_circuit.measure_all() - self.assertEqual(main_circuit.to_instruction().definition, - qpu_circuit.to_instruction().definition) + qpu_circuit.remove_final_measurements(inplace=True) + qpu_circuit_operator = Operator(qpu_circuit) + main_circuit_operator = Operator(main_circuit) + + assert qpu_circuit_operator.equiv(main_circuit_operator) @pytest.mark.qpu def test_expectations_in_init(self): - + """ Testing the Exceptions in the init function of the QiskitQPUShotBasedBackend """ - + nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 10000 - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) - + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) + # We mock the potential Exception that could occur in the Device class - qiskit_device = DeviceQiskit('', '', '', '') + qiskit_device = DeviceQiskit("", "", "", "") qiskit_device._check_provider_connection = Mock(return_value=False) - + try: - QAOAQiskitQPUBackend(qaoa_descriptor, qiskit_device, - shots, None, None, True) + QAOAQiskitQPUBackend( + qaoa_descriptor, qiskit_device, shots, None, None, True + ) except Exception as e: - self.assertEqual(str(e), 'Error connecting to IBMQ.') - - - self.assertRaises(Exception, QAOAQiskitQPUBackend, (qaoa_descriptor, - qiskit_device, - shots, None, None, - True)) - - - qiskit_device = DeviceQiskit(device_name='', - hub=self.HUB, group=self.GROUP, - project=self.PROJECT, - ) - + self.assertEqual(str(e), "Error connecting to IBMQ.") + + self.assertRaises( + Exception, + QAOAQiskitQPUBackend, + (qaoa_descriptor, qiskit_device, shots, None, None, True), + ) + + qiskit_device = DeviceQiskit( + device_name="", + hub=self.HUB, + group=self.GROUP, + project=self.PROJECT, + ) + try: - QAOAQiskitQPUBackend(qaoa_descriptor, qiskit_device, - shots, None, None, True) + QAOAQiskitQPUBackend( + qaoa_descriptor, qiskit_device, shots, None, None, True + ) except Exception as e: - self.assertEqual(str(e), 'Connection to IBMQ was made. Error connecting to the specified backend.') - - self.assertRaises(Exception, QAOAQiskitQPUBackend, qaoa_descriptor, - qiskit_device, shots, None, None, True) + self.assertEqual( + str(e), + "Connection to IBMQ was made. Error connecting to the specified backend.", + ) + + self.assertRaises( + Exception, + QAOAQiskitQPUBackend, + qaoa_descriptor, + qiskit_device, + shots, + None, + None, + True, + ) @pytest.mark.qpu def test_remote_integration_sim_run(self): """ - Checks if Remote IBM QASM Simulator is similar/close to Local IBM + Checks if Remote IBM QASM Simulator is similar/close to Local IBM Statevector Simulator. This test also serves as an integration test for the IBMQPU Backend. @@ -329,65 +370,76 @@ def test_remote_integration_sim_run(self): nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [[0], [1/8*np.pi], [0], [1/8*np.pi]] - betas = [[0], [0], [1/8*np.pi], [1/8*np.pi]] + gammas = [[0], [1 / 8 * np.pi], [0], [1 / 8 * np.pi]] + betas = [[0], [0], [1 / 8 * np.pi], [1 / 8 * np.pi]] shots = 10000 for i in range(4): - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas[i], - gammas[i]) - - qiskit_device = DeviceQiskit('ibmq_qasm_simulator', - self.HUB, self.GROUP, - self.PROJECT) - - qiskit_backend = QAOAQiskitQPUBackend(qaoa_descriptor, qiskit_device, - shots, None, None, False) + variate_params = QAOAVariationalStandardParams( + qaoa_descriptor, betas[i], gammas[i] + ) + + qiskit_device = DeviceQiskit( + "ibmq_qasm_simulator", self.HUB, self.GROUP, self.PROJECT + ) + + qiskit_backend = QAOAQiskitQPUBackend( + qaoa_descriptor, qiskit_device, shots, None, None, False + ) qiskit_expectation = qiskit_backend.expectation(variate_params) - qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - None, - None, - False) + qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, None, None, False + ) qiskit_statevec_expectation = qiskit_statevec_backend.expectation( - variate_params) + variate_params + ) - acceptable_delta = 0.05*qiskit_statevec_expectation + acceptable_delta = 0.05 * qiskit_statevec_expectation self.assertAlmostEqual( - qiskit_expectation, qiskit_statevec_expectation, delta=acceptable_delta) - + qiskit_expectation, qiskit_statevec_expectation, delta=acceptable_delta + ) + @pytest.mark.qpu def test_remote_qubit_overflow(self): - + """ If the user creates a circuit that is larger than the maximum circuit size - that is supported by the QPU. An Exception should be raised with the + that is supported by the QPU. An Exception should be raised with the appropriate error message alerting the user to the error. """ - + shots = 100 - + set_of_numbers = np.random.randint(1, 10, 6).tolist() qubo = NumberPartition(set_of_numbers).qubo mixer_hamil = X_mixer_hamiltonian(n_qubits=6) qaoa_descriptor = QAOADescriptor(qubo.hamiltonian, mixer_hamil, p=1) - variate_params = create_qaoa_variational_params(qaoa_descriptor, 'standard', 'rand') + variate_params = create_qaoa_variational_params( + qaoa_descriptor, "standard", "rand" + ) + + qiskit_device = DeviceQiskit("ibmq_manila", self.HUB, self.GROUP, self.PROJECT) - qiskit_device = DeviceQiskit('ibmq_manila', self.HUB, - self.GROUP, self.PROJECT) - try: - QAOAQiskitQPUBackend(qaoa_descriptor, qiskit_device, - shots, None, None, True) + QAOAQiskitQPUBackend( + qaoa_descriptor, qiskit_device, shots, None, None, True + ) except Exception as e: - self.assertEqual(str(e), 'There are lesser qubits on the device than the number of qubits required for the circuit.') + self.assertEqual( + str(e), + "There are lesser qubits on the device than the number of qubits required for the circuit.", + ) + # def test_remote_integration_qpu_run(self): # """ @@ -419,5 +471,5 @@ def test_remote_qubit_overflow(self): # self.assertEqual(type(qiskit_expectation.item()), float) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_result_object.py b/tests/test_result_object.py index 2573c8f96..75c70d61a 100644 --- a/tests/test_result_object.py +++ b/tests/test_result_object.py @@ -12,6 +12,7 @@ from openqaoa.problems.converters import FromDocplex2IsingModel from openqaoa.backends import create_device + class TestingLoggerClass(unittest.TestCase): def test_attribute_existence(self): """ @@ -118,11 +119,11 @@ def test_plot_probabilities(self): # Create the problem g = nx.circulant_graph(6, [1]) - vc = MinimumVertexCover(g, field =1.0, penalty=10).qubo + vc = MinimumVertexCover(g, field=1.0, penalty=10).qubo # first for state-vector based simulator: q_sv = QAOA() - q_sv.set_circuit_properties(p=3, init_type='ramp') + q_sv.set_circuit_properties(p=3, init_type="ramp") q_sv.compile(vc) q_sv.optimize() @@ -131,7 +132,7 @@ def test_plot_probabilities(self): # then for shot based simulator: q_shot = QAOA() - q_shot_dev = create_device(location='local',name='qiskit.shot_simulator') + q_shot_dev = create_device(location="local", name="qiskit.shot_simulator") q_shot.set_device(q_shot_dev) q_shot.compile(vc) @@ -145,10 +146,19 @@ def test_plot_n_shots(self): g = nx.circulant_graph(6, [1]) vc = MinimumVertexCover(g, field=1.0, penalty=10).qubo - for method in ['cans', 'icans']: + for method in ["cans", "icans"]: q = QAOA() - q.set_classical_optimizer(method=method, maxiter=50, jac='finite_difference', - optimizer_options = {'stepsize': 0.01, 'n_shots_min':5, 'n_shots_max':50, 'n_shots_budget':1000}) + q.set_classical_optimizer( + method=method, + maxiter=50, + jac="finite_difference", + optimizer_options={ + "stepsize": 0.01, + "n_shots_min": 5, + "n_shots_max": 50, + "n_shots_budget": 1000, + }, + ) q.compile(vc, verbose=False) q.optimize() @@ -156,23 +166,59 @@ def test_plot_n_shots(self): # all combinations to check test_dict = { - 'none': (None, {'label': [None, ['t1', 't2']], 'linestyle':["-", ["--", "-"]], 'color': [None, ['red', 'green']]}), - 'int': (0, {'label': [None, 't1', ['t2']], 'linestyle':["-", ["--"]], 'color': [None, ['red'], 'green']}), - 'list_one': (1, {'label': [None, 't1', ['t2']], 'linestyle':["-", ["--"]], 'color': [None, ['red'], 'green']}), - 'list_two': ([0,1], {'label': [None, ['t1', 't2']], 'linestyle':["-", ["--", "-"]], 'color': [None, ['red', 'green']]}), + "none": ( + None, + { + "label": [None, ["t1", "t2"]], + "linestyle": ["-", ["--", "-"]], + "color": [None, ["red", "green"]], + }, + ), + "int": ( + 0, + { + "label": [None, "t1", ["t2"]], + "linestyle": ["-", ["--"]], + "color": [None, ["red"], "green"], + }, + ), + "list_one": ( + 1, + { + "label": [None, "t1", ["t2"]], + "linestyle": ["-", ["--"]], + "color": [None, ["red"], "green"], + }, + ), + "list_two": ( + [0, 1], + { + "label": [None, ["t1", "t2"]], + "linestyle": ["-", ["--", "-"]], + "color": [None, ["red", "green"]], + }, + ), } # using the test_dict we plot with different options for value in test_dict.values(): - for label, line, color in zip(value[1]['label'], value[1]['linestyle'], value[1]['color']): - q.result.plot_n_shots(param_to_plot=value[0], label=label, linestyle=line, color=color, title=f"method: {method}, param_to_plot: {value[0]}, label: {label}, linestyle: {line}, color: {color}") + for label, line, color in zip( + value[1]["label"], value[1]["linestyle"], value[1]["color"] + ): + q.result.plot_n_shots( + param_to_plot=value[0], + label=label, + linestyle=line, + color=color, + title=f"method: {method}, param_to_plot: {value[0]}, label: {label}, linestyle: {line}, color: {color}", + ) plt.close() - # function to test that errors are raised, when trying to plot with incorrect inputs - def test_incorrect_arguments(argument:str, inputs_to_try:list): + # function to test that errors are raised, when trying to plot with incorrect inputs + def test_incorrect_arguments(argument: str, inputs_to_try: list): for x in inputs_to_try: error = False - try: - q.result.plot_n_shots(**{argument:x}) + try: + q.result.plot_n_shots(**{argument: x}) except Exception as e: assert len(str(e)) > 0, "No error message was raised" error = True @@ -180,10 +226,19 @@ def test_incorrect_arguments(argument:str, inputs_to_try:list): plt.close() # check that errors are raised, when trying to plot with incorrect inputs - test_incorrect_arguments(argument='param_to_plot', inputs_to_try=["0", 2, [0,1,2]]) - test_incorrect_arguments(argument='linestyle', inputs_to_try=[0, ["one", "two", "three"], [1, "two"]]) - test_incorrect_arguments(argument='label', inputs_to_try=[0, ["one", "two", "three"], [1, "two"]]) - test_incorrect_arguments(argument='color', inputs_to_try=[0, ["b", "c", "g"], [1, "g"]]) + test_incorrect_arguments( + argument="param_to_plot", inputs_to_try=["0", 2, [0, 1, 2]] + ) + test_incorrect_arguments( + argument="linestyle", + inputs_to_try=[0, ["one", "two", "three"], [1, "two"]], + ) + test_incorrect_arguments( + argument="label", inputs_to_try=[0, ["one", "two", "three"], [1, "two"]] + ) + test_incorrect_arguments( + argument="color", inputs_to_try=[0, ["b", "c", "g"], [1, "g"]] + ) def test_get_counts(self): @@ -232,7 +287,9 @@ def test_get_counts(self): assert optimized_measurement_outcomes_shot == QAOAResult.get_counts( optimized_measurement_outcomes_shot ) - assert counts_from_sv == QAOAResult.get_counts(optimized_measurement_outcomes_sv) + assert counts_from_sv == QAOAResult.get_counts( + optimized_measurement_outcomes_sv + ) def test_best_result(self): """Test lowest_cost_bitstring attribute and FromDocplex2IsingModel model generation""" diff --git a/tests/test_results.py b/tests/test_results.py index d79951fc7..078d98624 100644 --- a/tests/test_results.py +++ b/tests/test_results.py @@ -5,8 +5,10 @@ from openqaoa import QAOA, RQAOA from openqaoa.algorithms import QAOAResult, RQAOAResult -from openqaoa.backends.qaoa_backend import (DEVICE_NAME_TO_OBJECT_MAPPER, - DEVICE_ACCESS_OBJECT_MAPPER) +from openqaoa.backends.qaoa_backend import ( + DEVICE_NAME_TO_OBJECT_MAPPER, + DEVICE_ACCESS_OBJECT_MAPPER, +) from openqaoa.backends import create_device from openqaoa.backends.basebackend import QAOABaseBackendStatevector from openqaoa.backends.devices_core import SUPPORTED_LOCAL_SIMULATORS @@ -21,26 +23,53 @@ def _compare_qaoa_results(dict_old, dict_new, bool_cmplx_str): for key in dict_old.keys(): if key == "cost_hamiltonian": ## CHECK WHAT DO WITH THIS pass - elif key == "_QAOAResult__type_backend": + elif key == "_QAOAResult__type_backend": if issubclass(dict_old[key], QAOABaseBackendStatevector): - assert dict_new[key] == QAOABaseBackendStatevector, "Type of backend is not correct, complex_to_string = {}".format(bool_cmplx_str) + assert ( + dict_new[key] == QAOABaseBackendStatevector + ), "Type of backend is not correct, complex_to_string = {}".format( + bool_cmplx_str + ) else: - assert dict_new[key] == "", "Type of backend should be empty string, complex_to_string = {}".format(bool_cmplx_str) + assert ( + dict_new[key] == "" + ), "Type of backend should be empty string, complex_to_string = {}".format( + bool_cmplx_str + ) elif key == "optimized": for key2 in dict_old[key].keys(): if key2 == "measurement_outcomes": - assert np.all(dict_old[key][key2] == dict_new[key][key2]), "Optimized params are not the same, complex_to_string = {}".format(bool_cmplx_str) + assert np.all( + dict_old[key][key2] == dict_new[key][key2] + ), "Optimized params are not the same, complex_to_string = {}".format( + bool_cmplx_str + ) else: - assert dict_old[key][key2] == dict_new[key][key2], "Optimized params are not the same, complex_to_string = {}".format(bool_cmplx_str) + assert ( + dict_old[key][key2] == dict_new[key][key2] + ), "Optimized params are not the same, complex_to_string = {}".format( + bool_cmplx_str + ) elif key == "intermediate": for key2 in dict_old[key].keys(): if key2 == "measurement_outcomes": for step in range(len(dict_old[key][key2])): - assert np.all(dict_old[key][key2][step] == dict_new[key][key2][step]), "Intermediate params are not the same, complex_to_string = {}".format(bool_cmplx_str) + assert np.all( + dict_old[key][key2][step] == dict_new[key][key2][step] + ), "Intermediate params are not the same, complex_to_string = {}".format( + bool_cmplx_str + ) else: - assert dict_old[key][key2] == dict_new[key][key2], "Intermediate params are not the same, complex_to_string = {}".format(bool_cmplx_str) + assert ( + dict_old[key][key2] == dict_new[key][key2] + ), "Intermediate params are not the same, complex_to_string = {}".format( + bool_cmplx_str + ) else: - assert dict_old[key] == dict_new[key], f"{key} is not the same, complex_to_string = {bool_cmplx_str}" + assert ( + dict_old[key] == dict_new[key] + ), f"{key} is not the same, complex_to_string = {bool_cmplx_str}" + def _test_keys_in_dict(obj, expected_keys): """ @@ -49,7 +78,8 @@ def _test_keys_in_dict(obj, expected_keys): if isinstance(obj, dict): for key in obj: - if key in expected_keys.keys(): expected_keys[key] = True + if key in expected_keys.keys(): + expected_keys[key] = True if isinstance(obj[key], dict): _test_keys_in_dict(obj[key], expected_keys) @@ -68,39 +98,50 @@ class TestingResultOutputs(unittest.TestCase): """ def test_flags_result_outputs_workflow(self): - + """ Run an optimization problem for 5 iterations. - Should expect certain fields of the results output to be filled based + Should expect certain fields of the results output to be filled based on some of the users inputs. (Default settings) Can be checked for cobyla. - + Check for all available supported local backends. """ - + g = nw.circulant_graph(3, [1]) - vc = MinimumVertexCover(g, field =1.0, penalty=10).qubo - - choice_combination = list(itertools.product([True, False], [True, False], [True, False])) + vc = MinimumVertexCover(g, field=1.0, penalty=10).qubo + + choice_combination = list( + itertools.product([True, False], [True, False], [True, False]) + ) recorded_evals = [0, 5] - + for device_name in ALLOWED_LOCAL_SIMUALTORS: - + for each_choice in choice_combination: - + q = QAOA() - q.set_classical_optimizer(method = 'cobyla', - parameter_log = each_choice[0], - cost_progress = each_choice[1], - optimization_progress = each_choice[2], - maxiter = 5) - device = create_device('local', device_name) + q.set_classical_optimizer( + method="cobyla", + parameter_log=each_choice[0], + cost_progress=each_choice[1], + optimization_progress=each_choice[2], + maxiter=5, + ) + device = create_device("local", device_name) q.set_device(device) q.compile(vc) q.optimize() - self.assertEqual(recorded_evals[each_choice[0]], len(q.result.intermediate['angles'])) - self.assertEqual(recorded_evals[each_choice[1]], len(q.result.intermediate['cost'])) - self.assertEqual(recorded_evals[each_choice[2]], len(q.result.intermediate['measurement_outcomes'])) + self.assertEqual( + recorded_evals[each_choice[0]], len(q.result.intermediate["angles"]) + ) + self.assertEqual( + recorded_evals[each_choice[1]], len(q.result.intermediate["cost"]) + ) + self.assertEqual( + recorded_evals[each_choice[2]], + len(q.result.intermediate["measurement_outcomes"]), + ) def test_qaoa_result_asdict(self): """ @@ -109,68 +150,123 @@ def test_qaoa_result_asdict(self): # run the QAOA qaoa = QAOA() - qaoa.compile(problem = QUBO.random_instance(n=8)) + qaoa.compile(problem=QUBO.random_instance(n=8)) qaoa.optimize() - + # get dict results_dict = qaoa.result.asdict() # list of expected keys - expected_keys = ['method', 'cost_hamiltonian', 'n_qubits', 'terms', 'qubit_indices', 'pauli_str', 'phase', 'coeffs', 'constant', 'qubits_pairs', 'qubits_singles', 'single_qubit_coeffs', 'pair_qubit_coeffs', 'evals', 'number_of_evals', 'jac_evals', 'qfim_evals', 'most_probable_states', 'solutions_bitstrings', 'bitstring_energy', 'intermediate', 'angles', 'cost', 'measurement_outcomes', 'job_id', 'optimized', 'angles', 'cost', 'measurement_outcomes', 'job_id'] - - #we append all the keys that we find in rqaoa.results, so if we introduce a new key, we will know that we need to update the result.asdict method + expected_keys = [ + "method", + "cost_hamiltonian", + "n_qubits", + "terms", + "qubit_indices", + "pauli_str", + "phase", + "coeffs", + "constant", + "qubits_pairs", + "qubits_singles", + "single_qubit_coeffs", + "pair_qubit_coeffs", + "evals", + "number_of_evals", + "jac_evals", + "qfim_evals", + "most_probable_states", + "solutions_bitstrings", + "bitstring_energy", + "intermediate", + "angles", + "cost", + "measurement_outcomes", + "job_id", + "optimized", + "angles", + "cost", + "measurement_outcomes", + "job_id", + ] + + # we append all the keys that we find in rqaoa.results, so if we introduce a new key, we will know that we need to update the result.asdict method for key in vars(qaoa.result).keys(): - if not key in expected_keys and not '_QAOAResult__' in key: expected_keys.append(key) + if not key in expected_keys and not "_QAOAResult__" in key: + expected_keys.append(key) - #create a dictionary with all the expected keys and set them to False + # create a dictionary with all the expected keys and set them to False expected_keys_dict = {item: False for item in expected_keys} - #test the keys, it will set the keys to True if they are found + # test the keys, it will set the keys to True if they are found _test_keys_in_dict(results_dict, expected_keys_dict) - # Check if the dictionary has all the expected keys + # Check if the dictionary has all the expected keys for key, value in expected_keys_dict.items(): - assert value==True, f'Key {key} was not found in the dictionary of the QAOA Result class.' - + assert ( + value == True + ), f"Key {key} was not found in the dictionary of the QAOA Result class." ## now we repeat the same test but we do not include the cost hamiltonian - #get dict without cost hamiltonian - results_dict = qaoa.result.asdict(keep_cost_hamiltonian = False) + # get dict without cost hamiltonian + results_dict = qaoa.result.asdict(keep_cost_hamiltonian=False) - #expected keys - expected_keys_dict = {item: False for item in expected_keys} - expected_keys_not_in_dict = ['cost_hamiltonian', 'n_qubits', 'terms', 'qubit_indices', 'pauli_str', 'phase', 'coeffs', 'constant', 'qubits_pairs', 'qubits_singles', 'single_qubit_coeffs', 'pair_qubit_coeffs'] - - #test the keys, it will set the keys to True if they are found, except the ones that were not included which should be those in expected_keys_not_in_dict - _test_keys_in_dict(results_dict, expected_keys_dict) + # expected keys + expected_keys_dict = {item: False for item in expected_keys} + expected_keys_not_in_dict = [ + "cost_hamiltonian", + "n_qubits", + "terms", + "qubit_indices", + "pauli_str", + "phase", + "coeffs", + "constant", + "qubits_pairs", + "qubits_singles", + "single_qubit_coeffs", + "pair_qubit_coeffs", + ] + + # test the keys, it will set the keys to True if they are found, except the ones that were not included which should be those in expected_keys_not_in_dict + _test_keys_in_dict(results_dict, expected_keys_dict) # Check if the dictionary has all the expected keys except the ones that were not included for key, value in expected_keys_dict.items(): if not key in expected_keys_not_in_dict: - assert value==True, f'Key {key} was not found in the dictionary of the RQAOAResult class.' + assert ( + value == True + ), f"Key {key} was not found in the dictionary of the RQAOAResult class." else: - assert value==False, f'Key {key} was found in the dictionary of the RQAOAResult class, but it should not have been.' - + assert ( + value == False + ), f"Key {key} was found in the dictionary of the RQAOAResult class, but it should not have been." ## now we repeat the same test but we do not include some keys - #get dict without some values - results_dict = qaoa.result.asdict(exclude_keys = ['solutions_bitstrings', 'method']) + # get dict without some values + results_dict = qaoa.result.asdict( + exclude_keys=["solutions_bitstrings", "method"] + ) - #expected keys + # expected keys expected_keys_dict = {item: False for item in expected_keys} - expected_keys_not_in_dict = ['solutions_bitstrings', 'method'] + expected_keys_not_in_dict = ["solutions_bitstrings", "method"] - #test the keys, it will set the keys to True if they are found, except the ones that were not included which should be those in expected_keys_not_in_dict + # test the keys, it will set the keys to True if they are found, except the ones that were not included which should be those in expected_keys_not_in_dict _test_keys_in_dict(results_dict, expected_keys_dict) # Check if the dictionary has all the expected keys except the ones that were not included for key, value in expected_keys_dict.items(): if not key in expected_keys_not_in_dict: - assert value==True, f'Key {key} was not found in the dictionary of the RQAOAResult class.' + assert ( + value == True + ), f"Key {key} was not found in the dictionary of the RQAOAResult class." else: - assert value==False, f'Key {key} was found in the dictionary of the RQAOAResult class, but it should not have been.' + assert ( + value == False + ), f"Key {key} was found in the dictionary of the RQAOAResult class, but it should not have been." """ to get the list of expected keys, run the following code: @@ -194,21 +290,32 @@ def get_keys(obj, list_keys): print(expected_keys) """ - #test eval_number + # test eval_number def test_qaoa_result_eval_number(self): """ Test the eval_number method for the QAOA result class """ - for method in ['cobyla', 'spsa', 'vgd', 'newton', 'natural_grad_descent']: + for method in ["cobyla", "spsa", "vgd", "newton", "natural_grad_descent"]: # run the QAOA and get the results q = QAOA() - q.set_classical_optimizer(maxiter=15, method=method, jac='finite_difference', hess='finite_difference') - q.compile(problem = QUBO.random_instance(n=8)) + q.set_classical_optimizer( + maxiter=15, + method=method, + jac="finite_difference", + hess="finite_difference", + ) + q.compile(problem=QUBO.random_instance(n=8)) q.optimize() # test the eval_number method - assert q.result.intermediate['cost'].index(min(q.result.intermediate['cost'])) + 1 == q.result.optimized['eval_number'], 'optimized eval_number does not return the correct number of the optimized evaluation, when using {} method'.format(method) + assert ( + q.result.intermediate["cost"].index(min(q.result.intermediate["cost"])) + + 1 + == q.result.optimized["eval_number"] + ), "optimized eval_number does not return the correct number of the optimized evaluation, when using {} method".format( + method + ) def test_qaoa_results_from_dict(self): """ @@ -217,43 +324,64 @@ def test_qaoa_results_from_dict(self): """ # problem - maxcut_qubo = MaximumCut(nw.generators.fast_gnp_random_graph(n=6,p=0.6, seed=42)).qubo - + maxcut_qubo = MaximumCut( + nw.generators.fast_gnp_random_graph(n=6, p=0.6, seed=42) + ).qubo - # run qaoa with different devices, and save the objcets in a list + # run qaoa with different devices, and save the objcets in a list qaoas = [] - for device in [create_device(location='local', name='qiskit.shot_simulator'), create_device(location='local', name='vectorized')]: + for device in [ + create_device(location="local", name="qiskit.shot_simulator"), + create_device(location="local", name="vectorized"), + ]: q = QAOA() q.set_device(device) - q.set_circuit_properties(p=1, param_type='extended', init_type='rand', mixer_hamiltonian='x') + q.set_circuit_properties( + p=1, param_type="extended", init_type="rand", mixer_hamiltonian="x" + ) q.set_backend_properties(prepend_state=None, append_state=None) q.set_classical_optimizer(maxiter=10, optimization_progress=True) - q.compile(maxcut_qubo) + q.compile(maxcut_qubo) - q.optimize() + q.optimize() qaoas.append(q) for q in qaoas: results = q.result for bool_cmplx_str in [True, False]: - results_from_dict = QAOAResult.from_dict(results.asdict(complex_to_string=bool_cmplx_str)) + results_from_dict = QAOAResult.from_dict( + results.asdict(complex_to_string=bool_cmplx_str) + ) # assert that results_from_dict is intance of Result - assert isinstance(results_from_dict, QAOAResult), 'results_from_dict is not an instance of Result' - - _compare_qaoa_results(results.__dict__, results_from_dict.__dict__, bool_cmplx_str) + assert isinstance( + results_from_dict, QAOAResult + ), "results_from_dict is not an instance of Result" + _compare_qaoa_results( + results.__dict__, results_from_dict.__dict__, bool_cmplx_str + ) class TestingRQAOAResultOutputs(unittest.TestCase): """ Test the Results Output after a full RQAOA loop - """ + """ - def __run_rqaoa(self, type='custom', eliminations=1, p=1, param_type='standard', mixer='x', method='cobyla', maxiter=15, name_device='qiskit.statevector_simulator'): + def __run_rqaoa( + self, + type="custom", + eliminations=1, + p=1, + param_type="standard", + mixer="x", + method="cobyla", + maxiter=15, + name_device="qiskit.statevector_simulator", + ): """ private function to run the RQAOA """ @@ -261,23 +389,33 @@ def __run_rqaoa(self, type='custom', eliminations=1, p=1, param_type='standard', n_qubits = 6 n_cutoff = 3 g = nw.circulant_graph(n_qubits, [1]) - problem = MinimumVertexCover(g, field =1.0, penalty=10).qubo + problem = MinimumVertexCover(g, field=1.0, penalty=10).qubo r = RQAOA() - qiskit_device = create_device(location='local', name=name_device) + qiskit_device = create_device(location="local", name=name_device) r.set_device(qiskit_device) - if type == 'adaptive': - r.set_rqaoa_parameters(n_cutoff = n_cutoff, n_max=eliminations, rqaoa_type=type) + if type == "adaptive": + r.set_rqaoa_parameters( + n_cutoff=n_cutoff, n_max=eliminations, rqaoa_type=type + ) else: - r.set_rqaoa_parameters(n_cutoff = n_cutoff, steps=eliminations, rqaoa_type=type) + r.set_rqaoa_parameters( + n_cutoff=n_cutoff, steps=eliminations, rqaoa_type=type + ) r.set_circuit_properties(p=p, param_type=param_type, mixer_hamiltonian=mixer) r.set_backend_properties(prepend_state=None, append_state=None) - r.set_classical_optimizer(method=method, maxiter=maxiter, optimization_progress=True, cost_progress=True, parameter_log=True) + r.set_classical_optimizer( + method=method, + maxiter=maxiter, + optimization_progress=True, + cost_progress=True, + parameter_log=True, + ) r.compile(problem) r.optimize() return r.result - + def test_rqaoa_result_outputs(self): """ Test the result outputs for the RQAOA class @@ -288,42 +426,69 @@ def test_rqaoa_result_outputs(self): # Test for the standard RQAOA results = self.__run_rqaoa() - assert isinstance(results, RQAOAResult), 'Results of RQAOA are not of type RQAOAResult' - for key in results['solution'].keys(): - assert len(key) == n_qubits, 'Number of qubits solution is not correct' - assert isinstance(results['classical_output']['minimum_energy'], float) - assert isinstance(results['classical_output']['optimal_states'], list) - for rule_list in results['elimination_rules']: + assert isinstance( + results, RQAOAResult + ), "Results of RQAOA are not of type RQAOAResult" + for key in results["solution"].keys(): + assert len(key) == n_qubits, "Number of qubits solution is not correct" + assert isinstance(results["classical_output"]["minimum_energy"], float) + assert isinstance(results["classical_output"]["optimal_states"], list) + for rule_list in results["elimination_rules"]: for rule in rule_list: - assert isinstance(rule, dict), 'Elimination rule item is not a dictionary' - assert isinstance(results['schedule'], list), 'Schedule is not a list' - assert sum(results['schedule']) + n_cutoff == n_qubits, 'Schedule is not correct' - for step in results['intermediate_steps']: - assert isinstance(step['problem'], QUBO), 'problem is not of type QUBO' - assert isinstance(step['qaoa_results'], QAOAResult), 'QAOA_results is not of type QAOA Results' - assert isinstance(step['exp_vals_z'], np.ndarray), 'exp_vals_z is not of type numpy array' - assert isinstance(step['corr_matrix'], np.ndarray), 'corr_matrix is not of type numpy array' - assert isinstance(results['number_steps'], int), 'Number of steps is not an integer' - + assert isinstance( + rule, dict + ), "Elimination rule item is not a dictionary" + assert isinstance(results["schedule"], list), "Schedule is not a list" + assert ( + sum(results["schedule"]) + n_cutoff == n_qubits + ), "Schedule is not correct" + for step in results["intermediate_steps"]: + assert isinstance(step["problem"], QUBO), "problem is not of type QUBO" + assert isinstance( + step["qaoa_results"], QAOAResult + ), "QAOA_results is not of type QAOA Results" + assert isinstance( + step["exp_vals_z"], np.ndarray + ), "exp_vals_z is not of type numpy array" + assert isinstance( + step["corr_matrix"], np.ndarray + ), "corr_matrix is not of type numpy array" + assert isinstance( + results["number_steps"], int + ), "Number of steps is not an integer" + # Test for the adaptive RQAOA - results = self.__run_rqaoa(type='adaptive') - assert isinstance(results, RQAOAResult), 'Results of RQAOA are not of type RQAOAResult' - for key in results['solution'].keys(): - assert len(key) == n_qubits, 'Number of qubits solution is not correct' - assert isinstance(results['classical_output']['minimum_energy'], float) - assert isinstance(results['classical_output']['optimal_states'], list) - for rule_list in results['elimination_rules']: + results = self.__run_rqaoa(type="adaptive") + assert isinstance( + results, RQAOAResult + ), "Results of RQAOA are not of type RQAOAResult" + for key in results["solution"].keys(): + assert len(key) == n_qubits, "Number of qubits solution is not correct" + assert isinstance(results["classical_output"]["minimum_energy"], float) + assert isinstance(results["classical_output"]["optimal_states"], list) + for rule_list in results["elimination_rules"]: for rule in rule_list: - assert isinstance(rule, dict), 'Elimination rule item is not a dictionary' - assert isinstance(results['schedule'], list), 'Schedule is not a list' - assert sum(results['schedule']) + n_cutoff == n_qubits, 'Schedule is not correct' - for step in results['intermediate_steps']: - assert isinstance(step['problem'], QUBO), 'QUBO is not of type QUBO' - assert isinstance(step['qaoa_results'], QAOAResult), 'QAOA_results is not of type QAOA Results' - assert isinstance(step['exp_vals_z'], np.ndarray), 'exp_vals_z is not of type numpy array' - assert isinstance(step['corr_matrix'], np.ndarray), 'corr_matrix is not of type numpy array' - assert isinstance(results['number_steps'], int), 'Number of steps is not an integer' - + assert isinstance( + rule, dict + ), "Elimination rule item is not a dictionary" + assert isinstance(results["schedule"], list), "Schedule is not a list" + assert ( + sum(results["schedule"]) + n_cutoff == n_qubits + ), "Schedule is not correct" + for step in results["intermediate_steps"]: + assert isinstance(step["problem"], QUBO), "QUBO is not of type QUBO" + assert isinstance( + step["qaoa_results"], QAOAResult + ), "QAOA_results is not of type QAOA Results" + assert isinstance( + step["exp_vals_z"], np.ndarray + ), "exp_vals_z is not of type numpy array" + assert isinstance( + step["corr_matrix"], np.ndarray + ), "corr_matrix is not of type numpy array" + assert isinstance( + results["number_steps"], int + ), "Number of steps is not an integer" def test_rqaoa_result_methods_steps(self): """ @@ -334,22 +499,40 @@ def test_rqaoa_result_methods_steps(self): results = self.__run_rqaoa() # test the solution method - assert results.get_solution() == results['solution'], 'get_solution method is not correct' - - # test the methods for the intermediate steps - for i in range(results['number_steps']): - - #methods for intermediate qaao results - assert results.get_qaoa_results(i) == results['intermediate_steps'][i]['qaoa_results'], 'get_qaoa_results method is not correct' - assert results.get_qaoa_optimized_angles(i) == results.get_qaoa_results(i).optimized['angles'], 'get_qaoa_optimized_angles method is not correct' - - #methods for intermediate qubo - assert results.get_problem(i) == results['intermediate_steps'][i]['problem'], 'get_qubo method is not correct' - assert isinstance(results.get_hamiltonian(i), Hamiltonian), 'get_hamiltonian method is not correct' - - #methods for intermediate exp_vals_z and corr_matrix - assert results.get_exp_vals_z(i) is results['intermediate_steps'][i]['exp_vals_z'], 'get_exp_vals_z method is not correct' - assert results.get_corr_matrix(i) is results['intermediate_steps'][i]['corr_matrix'], 'get_corr_matrix method is not correct' + assert ( + results.get_solution() == results["solution"] + ), "get_solution method is not correct" + + # test the methods for the intermediate steps + for i in range(results["number_steps"]): + + # methods for intermediate qaao results + assert ( + results.get_qaoa_results(i) + == results["intermediate_steps"][i]["qaoa_results"] + ), "get_qaoa_results method is not correct" + assert ( + results.get_qaoa_optimized_angles(i) + == results.get_qaoa_results(i).optimized["angles"] + ), "get_qaoa_optimized_angles method is not correct" + + # methods for intermediate qubo + assert ( + results.get_problem(i) == results["intermediate_steps"][i]["problem"] + ), "get_qubo method is not correct" + assert isinstance( + results.get_hamiltonian(i), Hamiltonian + ), "get_hamiltonian method is not correct" + + # methods for intermediate exp_vals_z and corr_matrix + assert ( + results.get_exp_vals_z(i) + is results["intermediate_steps"][i]["exp_vals_z"] + ), "get_exp_vals_z method is not correct" + assert ( + results.get_corr_matrix(i) + is results["intermediate_steps"][i]["corr_matrix"] + ), "get_corr_matrix method is not correct" def test_rqaoa_result_plot_corr_matrix(self): """ @@ -360,7 +543,7 @@ def test_rqaoa_result_plot_corr_matrix(self): results = self.__run_rqaoa() # test the plot_corr_matrix method - for i in range(results['number_steps']): + for i in range(results["number_steps"]): results.plot_corr_matrix(step=i) def test_rqaoa_result_asdict(self): @@ -370,48 +553,104 @@ def test_rqaoa_result_asdict(self): # run the RQAOA results = self.__run_rqaoa() - + # get dict results_dict = results.asdict() - #create a list of expected keys - expected_keys = ['solution', 'classical_output', 'minimum_energy', 'optimal_states', 'elimination_rules', 'singlet', 'bias', 'pair', 'correlation', 'schedule', 'intermediate_steps', 'problem', 'terms', 'weights', 'constant', 'n', 'qaoa_results', 'method', 'cost_hamiltonian', 'n_qubits', 'qubit_indices', 'pauli_str', 'phase', 'coeffs', 'qubits_pairs', 'qubits_singles', 'single_qubit_coeffs', 'pair_qubit_coeffs', 'evals', 'number_of_evals', 'jac_evals', 'qfim_evals', 'most_probable_states', 'solutions_bitstrings', 'bitstring_energy', 'intermediate', 'angles', 'cost', 'measurement_outcomes', 'job_id', 'optimized', 'angles', 'cost', 'measurement_outcomes', 'job_id', 'exp_vals_z', 'corr_matrix', 'number_steps'] - - #we append all the keys that we find in rqaoa.results, so if we introduce a new key, we will know that we need to update the result.asdict method + # create a list of expected keys + expected_keys = [ + "solution", + "classical_output", + "minimum_energy", + "optimal_states", + "elimination_rules", + "singlet", + "bias", + "pair", + "correlation", + "schedule", + "intermediate_steps", + "problem", + "terms", + "weights", + "constant", + "n", + "qaoa_results", + "method", + "cost_hamiltonian", + "n_qubits", + "qubit_indices", + "pauli_str", + "phase", + "coeffs", + "qubits_pairs", + "qubits_singles", + "single_qubit_coeffs", + "pair_qubit_coeffs", + "evals", + "number_of_evals", + "jac_evals", + "qfim_evals", + "most_probable_states", + "solutions_bitstrings", + "bitstring_energy", + "intermediate", + "angles", + "cost", + "measurement_outcomes", + "job_id", + "optimized", + "angles", + "cost", + "measurement_outcomes", + "job_id", + "exp_vals_z", + "corr_matrix", + "number_steps", + ] + + # we append all the keys that we find in rqaoa.results, so if we introduce a new key, we will know that we need to update the result.asdict method for key in results.keys(): - if not key in expected_keys: expected_keys.append(key) - for key in results['intermediate_steps'][0].keys(): - if not key in expected_keys: expected_keys.append(key) + if not key in expected_keys: + expected_keys.append(key) + for key in results["intermediate_steps"][0].keys(): + if not key in expected_keys: + expected_keys.append(key) # dictionary with all the expected keys and set them to False expected_keys = {item: False for item in expected_keys} - #test the keys, it will set the keys to True if they are found + # test the keys, it will set the keys to True if they are found _test_keys_in_dict(results_dict, expected_keys) # Check if the dictionary has all the expected keys except the ones that were not included for key, value in expected_keys.items(): - assert value==True, f'Key {key} was not found in the dictionary of the RQAOAResult class.' - + assert ( + value == True + ), f"Key {key} was not found in the dictionary of the RQAOAResult class." ## now we repeat the same test but we do not include some keys - #get dict without some values - results_dict = results.asdict(exclude_keys = ['solutions_bitstrings', 'method']) + # get dict without some values + results_dict = results.asdict(exclude_keys=["solutions_bitstrings", "method"]) - #expected keys + # expected keys expected_keys_dict = {item: False for item in expected_keys} - expected_keys_not_in_dict = ['solutions_bitstrings', 'method'] + expected_keys_not_in_dict = ["solutions_bitstrings", "method"] - #test the keys, it will set the keys to True if they are found, except the ones that were not included which should be those in expected_keys_not_in_dict + # test the keys, it will set the keys to True if they are found, except the ones that were not included which should be those in expected_keys_not_in_dict _test_keys_in_dict(results_dict, expected_keys_dict) # Check if the dictionary has all the expected keys except the ones that were not included for key, value in expected_keys_dict.items(): if not key in expected_keys_not_in_dict: - assert value==True, f'Key {key} was not found in the dictionary of the RQAOAResult class.' + assert ( + value == True + ), f"Key {key} was not found in the dictionary of the RQAOAResult class." else: - assert value==False, f'Key {key} was found in the dictionary of the RQAOAResult class, but it should not have been.' + assert ( + value == False + ), f"Key {key} was found in the dictionary of the RQAOAResult class, but it should not have been." """ to get the list of expected keys, run the following code: @@ -442,22 +681,28 @@ def test_rqaoa_results_from_dict(self): """ # problem - maxcut_qubo = MaximumCut(nw.generators.fast_gnp_random_graph(n=6,p=0.6, seed=42)).qubo - + maxcut_qubo = MaximumCut( + nw.generators.fast_gnp_random_graph(n=6, p=0.6, seed=42) + ).qubo - # run rqaoa with different devices, and save the objcets in a list + # run rqaoa with different devices, and save the objcets in a list rqaoas = [] - for device in [create_device(location='local', name='qiskit.shot_simulator'), create_device(location='local', name='vectorized')]: + for device in [ + create_device(location="local", name="qiskit.shot_simulator"), + create_device(location="local", name="vectorized"), + ]: r = RQAOA() r.set_device(device) - r.set_circuit_properties(p=1, param_type='extended', init_type='rand', mixer_hamiltonian='x') + r.set_circuit_properties( + p=1, param_type="extended", init_type="rand", mixer_hamiltonian="x" + ) r.set_backend_properties(prepend_state=None, append_state=None) r.set_classical_optimizer(maxiter=10, optimization_progress=True) - r.compile(maxcut_qubo) + r.compile(maxcut_qubo) - r.optimize() + r.optimize() rqaoas.append(r) @@ -467,22 +712,36 @@ def test_rqaoa_results_from_dict(self): new_results = RQAOAResult.from_dict(r.result.asdict()) old_results = r.result - #assert that new_results is an instance of RQAOAResult - assert isinstance(new_results, RQAOAResult), "new_results is not an instance of RQAOAResult" + # assert that new_results is an instance of RQAOAResult + assert isinstance( + new_results, RQAOAResult + ), "new_results is not an instance of RQAOAResult" for key in old_results: if key == "intermediate_steps": for i in range(len(old_results[key])): for key2 in old_results[key][i]: if key2 == "problem": - assert old_results[key][i][key2].asdict() == new_results[key][i][key2].asdict(), f"{key2} is not the same" + assert ( + old_results[key][i][key2].asdict() + == new_results[key][i][key2].asdict() + ), f"{key2} is not the same" elif key2 == "qaoa_results": - _compare_qaoa_results(old_results[key][i][key2].asdict(), new_results[key][i][key2].asdict(), None) + _compare_qaoa_results( + old_results[key][i][key2].asdict(), + new_results[key][i][key2].asdict(), + None, + ) else: - assert np.all(old_results[key][i][key2] == new_results[key][i][key2]), f"{key2} is not the same" + assert np.all( + old_results[key][i][key2] + == new_results[key][i][key2] + ), f"{key2} is not the same" else: - assert old_results[key] == new_results[key], f"{key} is not the same" + assert ( + old_results[key] == new_results[key] + ), f"{key} is not the same" + if __name__ == "__main__": - unittest.main() - \ No newline at end of file + unittest.main() diff --git a/tests/test_sample_from_wavefunction.py b/tests/test_sample_from_wavefunction.py index 353b9edce..d1e082971 100644 --- a/tests/test_sample_from_wavefunction.py +++ b/tests/test_sample_from_wavefunction.py @@ -2,20 +2,24 @@ import numpy as np from openqaoa.backends.qaoa_backend import get_qaoa_backend -from openqaoa.qaoa_components import QAOADescriptor, QAOAVariationalStandardParams, Hamiltonian +from openqaoa.qaoa_components import ( + QAOADescriptor, + QAOAVariationalStandardParams, + Hamiltonian, +) from openqaoa.utilities import random_classical_hamiltonian, X_mixer_hamiltonian from openqaoa.backends import DeviceLocal class TestGetSamplesMethod(unittest.TestCase): """ - Test the `get_samples` method in `cost_function.py` + Test the `get_samples` method in `cost_function.py` -> Test whether it produces the right results while sampling the wavefunction """ def test_samples_with_one_string(self): """ - This function generates samples for a wavefunction that has + This function generates samples for a wavefunction that has unit probability for one a basis state and zero for others. In other words, the final wavefunction is a product state in the computational basis. @@ -24,27 +28,30 @@ def test_samples_with_one_string(self): reg = [0, 1, 2, 3, 4, 5] solution = bin(0)[2:].zfill(len(reg)) terms = [(i,) for i in reg] - weights = [1]*len(terms) + weights = [1] * len(terms) p = 1 - betas, gammas = [np.pi/4], [-np.pi/4] + betas, gammas = [np.pi / 4], [-np.pi / 4] - cost_hamiltonian = Hamiltonian.classical_hamiltonian( - terms, weights, constant=0) + cost_hamiltonian = Hamiltonian.classical_hamiltonian(terms, weights, constant=0) mixer_hamiltonian = X_mixer_hamiltonian(len(reg)) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) variational_params_std = QAOAVariationalStandardParams( - qaoa_descriptor, betas, gammas) + qaoa_descriptor, betas, gammas + ) backend_vectorized = get_qaoa_backend( - qaoa_descriptor, DeviceLocal('vectorized')) + qaoa_descriptor, DeviceLocal("vectorized") + ) backend_qiskit_statevec = get_qaoa_backend( - qaoa_descriptor, DeviceLocal('qiskit.statevector_simulator')) + qaoa_descriptor, DeviceLocal("qiskit.statevector_simulator") + ) shot_results_vec = backend_vectorized.sample_from_wavefunction( - variational_params_std, n_samples=15) + variational_params_std, n_samples=15 + ) shot_results_qiskit = backend_qiskit_statevec.sample_from_wavefunction( - variational_params_std, n_samples=15) + variational_params_std, n_samples=15 + ) bool_list_vec = [x == solution for x in shot_results_vec] bool_list_qiskit = [x == solution for x in shot_results_qiskit] @@ -54,7 +61,7 @@ def test_samples_with_one_string(self): def test_samples_limiting_case(self): """ - Check whether sample distribution approximates the probability vector in the limit of + Check whether sample distribution approximates the probability vector in the limit of large number of shots NOTE: if the assertion error still keeps failing for no apparent reason, try changing @@ -72,49 +79,59 @@ def test_samples_limiting_case(self): cost_hamiltonian = random_classical_hamiltonian(reg) n_qubits = cost_hamiltonian.n_qubits mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) variational_params_std = QAOAVariationalStandardParams( - qaoa_descriptor, betas, gammas) + qaoa_descriptor, betas, gammas + ) backend_vectorized = get_qaoa_backend( - qaoa_descriptor, DeviceLocal('vectorized')) + qaoa_descriptor, DeviceLocal("vectorized") + ) backend_qiskit_statevec = get_qaoa_backend( - qaoa_descriptor, DeviceLocal('qiskit.statevector_simulator')) + qaoa_descriptor, DeviceLocal("qiskit.statevector_simulator") + ) # wf_vec = backend_vectorized.wavefunction(variational_params_std) - prob_wf_vec = np.array(list(backend_vectorized.probability_dict( - variational_params_std).values()), dtype=float) + prob_wf_vec = np.array( + list(backend_vectorized.probability_dict(variational_params_std).values()), + dtype=float, + ) # wf_qiskit = backend_qiskit_statevec.wavefunction(variational_params_std) - prob_wf_qiskit = np.array(list(backend_qiskit_statevec.probability_dict( - variational_params_std).values()), dtype=float) + prob_wf_qiskit = np.array( + list( + backend_qiskit_statevec.probability_dict( + variational_params_std + ).values() + ), + dtype=float, + ) samples_vec = backend_vectorized.sample_from_wavefunction( - variational_params_std, n_samples=nshots) + variational_params_std, n_samples=nshots + ) samples_qiskit = backend_qiskit_statevec.sample_from_wavefunction( - variational_params_std, n_samples=nshots) + variational_params_std, n_samples=nshots + ) - samples_dict_vec = {bin(x)[2:].zfill( - n_qubits): 0 for x in range(2**n_qubits)} - samples_dict_qiskit = {bin(x)[2:].zfill( - n_qubits): 0 for x in range(2**n_qubits)} + samples_dict_vec = {bin(x)[2:].zfill(n_qubits): 0 for x in range(2**n_qubits)} + samples_dict_qiskit = { + bin(x)[2:].zfill(n_qubits): 0 for x in range(2**n_qubits) + } for shot_result in samples_vec: - samples_dict_vec[shot_result] += 1/nshots + samples_dict_vec[shot_result] += 1 / nshots for shot_result in samples_qiskit: - samples_dict_qiskit[shot_result] += 1/nshots + samples_dict_qiskit[shot_result] += 1 / nshots - samples_prob_vec = np.array( - list(samples_dict_vec.values()), dtype=float) - samples_prob_qiskit = np.array( - list(samples_dict_qiskit.values()), dtype=float) + samples_prob_vec = np.array(list(samples_dict_vec.values()), dtype=float) + samples_prob_qiskit = np.array(list(samples_dict_qiskit.values()), dtype=float) + np.testing.assert_array_almost_equal(prob_wf_vec, samples_prob_vec, decimal=3) np.testing.assert_array_almost_equal( - prob_wf_vec, samples_prob_vec, decimal=3) - np.testing.assert_array_almost_equal( - prob_wf_qiskit, samples_prob_qiskit, decimal=3) + prob_wf_qiskit, samples_prob_qiskit, decimal=3 + ) # def testing_w_init_prog(self): # """ diff --git a/tests/test_sim_qiskit.py b/tests/test_sim_qiskit.py index 234c1f50a..df4984d52 100644 --- a/tests/test_sim_qiskit.py +++ b/tests/test_sim_qiskit.py @@ -3,432 +3,512 @@ from qiskit import QuantumCircuit -from openqaoa.qaoa_components import (PauliOp, Hamiltonian, QAOADescriptor, - QAOAVariationalExtendedParams, QAOAVariationalStandardParams) -from openqaoa_qiskit.backends import QAOAQiskitBackendStatevecSimulator, QAOAQiskitBackendShotBasedSimulator +from openqaoa.qaoa_components import ( + PauliOp, + Hamiltonian, + QAOADescriptor, + QAOAVariationalExtendedParams, + QAOAVariationalStandardParams, +) +from openqaoa_qiskit.backends import ( + QAOAQiskitBackendStatevecSimulator, + QAOAQiskitBackendShotBasedSimulator, +) from openqaoa.backends import QAOAvectorizedBackendSimulator from openqaoa.utilities import X_mixer_hamiltonian, ring_of_disagrees class TestingQAOAQiskitSimulatorBackend(unittest.TestCase): - - """This Object tests the QAOA Qiskit Simulator Backend objects, which is - tasked with the creation and execution of a QAOA circuit for the qiskit + + """This Object tests the QAOA Qiskit Simulator Backend objects, which is + tasked with the creation and execution of a QAOA circuit for the qiskit library and its local backends. - """ - + """ + def test_circuit_angle_assignment_statevec_backend(self): - + """ A tests that checks if the circuit created by the Qiskit Backend has the appropriate angles assigned before the circuit is executed. Checks the circuit created on IBM Simulator Backends. """ - + ntrials = 10 - + nqubits = 3 p = 2 - weights = [[np.random.rand(), np.random.rand(), np.random.rand()] for i in range(ntrials)] + weights = [ + [np.random.rand(), np.random.rand(), np.random.rand()] + for i in range(ntrials) + ] init_hadamards = [np.random.choice([True, False]) for i in range(ntrials)] constants = [np.random.rand() for i in range(ntrials)] - + for i in range(ntrials): - - gammas = [np.random.rand()*np.pi for i in range(p)] - betas = [np.random.rand()*np.pi for i in range(p)] - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights[i], constants[i]) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) + + gammas = [np.random.rand() * np.pi for i in range(p)] + betas = [np.random.rand() * np.pi for i in range(p)] + + print(gammas) + print(betas) + + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights[i], + constants[i], + ) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams( + qaoa_descriptor, betas, gammas + ) - qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - None, - None, - False) + qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, None, None, False + ) statevec_circuit = qiskit_statevec_backend.qaoa_circuit(variate_params) # Trivial Decomposition main_circuit = QuantumCircuit(3) - main_circuit.rzz(2*weights[i][0]*gammas[0], 0, 1) - main_circuit.rzz(2*weights[i][1]*gammas[0], 1, 2) - main_circuit.rzz(2*weights[i][2]*gammas[0], 0, 2) - main_circuit.rx(-2*betas[0], 0) - main_circuit.rx(-2*betas[0], 1) - main_circuit.rx(-2*betas[0], 2) - main_circuit.rzz(2*weights[i][0]*gammas[1], 0, 1) - main_circuit.rzz(2*weights[i][1]*gammas[1], 1, 2) - main_circuit.rzz(2*weights[i][2]*gammas[1], 0, 2) - main_circuit.rx(-2*betas[1], 0) - main_circuit.rx(-2*betas[1], 1) - main_circuit.rx(-2*betas[1], 2) - - self.assertEqual(main_circuit.to_instruction().definition, statevec_circuit.to_instruction().definition) - + main_circuit.rzz(2 * weights[i][0] * gammas[0], 0, 1) + main_circuit.rzz(2 * weights[i][1] * gammas[0], 1, 2) + main_circuit.rzz(2 * weights[i][2] * gammas[0], 0, 2) + main_circuit.rx(-2 * betas[0], 0) + main_circuit.rx(-2 * betas[0], 1) + main_circuit.rx(-2 * betas[0], 2) + main_circuit.rzz(2 * weights[i][0] * gammas[1], 0, 1) + main_circuit.rzz(2 * weights[i][1] * gammas[1], 1, 2) + main_circuit.rzz(2 * weights[i][2] * gammas[1], 0, 2) + main_circuit.rx(-2 * betas[1], 0) + main_circuit.rx(-2 * betas[1], 1) + main_circuit.rx(-2 * betas[1], 2) + + self.assertEqual( + main_circuit.to_instruction().definition, + statevec_circuit.to_instruction().definition, + ) + def test_circuit_angle_assignment_statevec_backend_w_hadamard(self): - + """ Checks for consistent if init_hadamard is set to True. """ - + ntrials = 10 - + nqubits = 3 p = 2 - weights = [[np.random.rand(), np.random.rand(), np.random.rand()] for i in range(ntrials)] + weights = [ + [np.random.rand(), np.random.rand(), np.random.rand()] + for i in range(ntrials) + ] init_hadamards = [np.random.choice([True, False]) for i in range(ntrials)] constants = [np.random.rand() for i in range(ntrials)] - + for i in range(ntrials): - - gammas = [np.random.rand()*np.pi for i in range(p)] - betas = [np.random.rand()*np.pi for i in range(p)] - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights[i], constants[i]) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) + + gammas = [np.random.rand() * np.pi for i in range(p)] + betas = [np.random.rand() * np.pi for i in range(p)] + + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights[i], + constants[i], + ) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + variate_params = QAOAVariationalStandardParams( + qaoa_descriptor, betas, gammas + ) - qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - None, - None, - True) + qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, None, None, True + ) statevec_circuit = qiskit_statevec_backend.qaoa_circuit(variate_params) # Trivial Decomposition main_circuit = QuantumCircuit(3) main_circuit.h([0, 1, 2]) - main_circuit.rzz(2*weights[i][0]*gammas[0], 0, 1) - main_circuit.rzz(2*weights[i][1]*gammas[0], 1, 2) - main_circuit.rzz(2*weights[i][2]*gammas[0], 0, 2) - main_circuit.rx(-2*betas[0], 0) - main_circuit.rx(-2*betas[0], 1) - main_circuit.rx(-2*betas[0], 2) - main_circuit.rzz(2*weights[i][0]*gammas[1], 0, 1) - main_circuit.rzz(2*weights[i][1]*gammas[1], 1, 2) - main_circuit.rzz(2*weights[i][2]*gammas[1], 0, 2) - main_circuit.rx(-2*betas[1], 0) - main_circuit.rx(-2*betas[1], 1) - main_circuit.rx(-2*betas[1], 2) - - self.assertEqual(main_circuit.to_instruction().definition, statevec_circuit.to_instruction().definition) - + main_circuit.rzz(2 * weights[i][0] * gammas[0], 0, 1) + main_circuit.rzz(2 * weights[i][1] * gammas[0], 1, 2) + main_circuit.rzz(2 * weights[i][2] * gammas[0], 0, 2) + main_circuit.rx(-2 * betas[0], 0) + main_circuit.rx(-2 * betas[0], 1) + main_circuit.rx(-2 * betas[0], 2) + main_circuit.rzz(2 * weights[i][0] * gammas[1], 0, 1) + main_circuit.rzz(2 * weights[i][1] * gammas[1], 1, 2) + main_circuit.rzz(2 * weights[i][2] * gammas[1], 0, 2) + main_circuit.rx(-2 * betas[1], 0) + main_circuit.rx(-2 * betas[1], 1) + main_circuit.rx(-2 * betas[1], 2) + + self.assertEqual( + main_circuit.to_instruction().definition, + statevec_circuit.to_instruction().definition, + ) + def test_prepend_circuit(self): - + """ Checks if prepended circuit has been prepended correctly. """ - + nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] - shots = 10000 - + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] + shots = 10000 + # Prepended Circuit prepend_circuit = QuantumCircuit(3) prepend_circuit.x([0, 1, 2]) - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) + + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) - - qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - prepend_circuit, - None, - True) - qiskit_shot_backend = QAOAQiskitBackendShotBasedSimulator(qaoa_descriptor, - shots, - prepend_circuit, - None, - True, 1.0) - + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) + + qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, prepend_circuit, None, True + ) + qiskit_shot_backend = QAOAQiskitBackendShotBasedSimulator( + qaoa_descriptor, shots, prepend_circuit, None, True, 1.0 + ) + statevec_circuit = qiskit_statevec_backend.qaoa_circuit(variate_params) shot_circuit = qiskit_shot_backend.qaoa_circuit(variate_params) shot_circuit.remove_final_measurements() - + # Trivial Decomposition main_circuit = QuantumCircuit(3) main_circuit.x([0, 1, 2]) main_circuit.h([0, 1, 2]) - main_circuit.rzz(2*gammas[0], 0, 1) - main_circuit.rzz(2*gammas[0], 1, 2) - main_circuit.rzz(2*gammas[0], 0, 2) - main_circuit.rx(-2*betas[0], 0) - main_circuit.rx(-2*betas[0], 1) - main_circuit.rx(-2*betas[0], 2) - - self.assertEqual(main_circuit.to_instruction().definition, statevec_circuit.to_instruction().definition) - self.assertEqual(main_circuit.to_instruction().definition, shot_circuit.to_instruction().definition) - + main_circuit.rzz(2 * gammas[0], 0, 1) + main_circuit.rzz(2 * gammas[0], 1, 2) + main_circuit.rzz(2 * gammas[0], 0, 2) + main_circuit.rx(-2 * betas[0], 0) + main_circuit.rx(-2 * betas[0], 1) + main_circuit.rx(-2 * betas[0], 2) + + self.assertEqual( + main_circuit.to_instruction().definition, + statevec_circuit.to_instruction().definition, + ) + self.assertEqual( + main_circuit.to_instruction().definition, + shot_circuit.to_instruction().definition, + ) + def test_append_circuit(self): - + """ Checks if appended circuit is appropriately appended to the back of the QAOA Circuit. """ - + nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 10000 - + # Appended Circuit append_circuit = QuantumCircuit(3) append_circuit.x([0, 1, 2]) - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) + + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) - - qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - None, - append_circuit, - True) - qiskit_shot_backend = QAOAQiskitBackendShotBasedSimulator(qaoa_descriptor, - shots, - None, - append_circuit, - True, 1.0) - + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) + + qiskit_statevec_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, None, append_circuit, True + ) + qiskit_shot_backend = QAOAQiskitBackendShotBasedSimulator( + qaoa_descriptor, shots, None, append_circuit, True, 1.0 + ) + statevec_circuit = qiskit_statevec_backend.qaoa_circuit(variate_params) shot_circuit = qiskit_shot_backend.qaoa_circuit(variate_params) shot_circuit.remove_final_measurements() - + # Standard Decomposition main_circuit = QuantumCircuit(3) main_circuit.h([0, 1, 2]) - main_circuit.rzz(2*gammas[0], 0, 1) - main_circuit.rzz(2*gammas[0], 1, 2) - main_circuit.rzz(2*gammas[0], 0, 2) - main_circuit.rx(-2*betas[0], 0) - main_circuit.rx(-2*betas[0], 1) - main_circuit.rx(-2*betas[0], 2) + main_circuit.rzz(2 * gammas[0], 0, 1) + main_circuit.rzz(2 * gammas[0], 1, 2) + main_circuit.rzz(2 * gammas[0], 0, 2) + main_circuit.rx(-2 * betas[0], 0) + main_circuit.rx(-2 * betas[0], 1) + main_circuit.rx(-2 * betas[0], 2) main_circuit.x([0, 1, 2]) - - self.assertEqual(main_circuit.to_instruction().definition, statevec_circuit.to_instruction().definition) - self.assertEqual(main_circuit.to_instruction().definition, shot_circuit.to_instruction().definition) - + + self.assertEqual( + main_circuit.to_instruction().definition, + statevec_circuit.to_instruction().definition, + ) + self.assertEqual( + main_circuit.to_instruction().definition, + shot_circuit.to_instruction().definition, + ) + def test_qaoa_circuit_wavefunction_expectation_equivalence_1(self): - + """ - The following tests with a similar naming scheme check for consistency - between the outputs of the qiskit statevector simulator and the + The following tests with a similar naming scheme check for consistency + between the outputs of the qiskit statevector simulator and the vectorized backend. - We compare both the wavefunctions returned by the Backends and the + We compare both the wavefunctions returned by the Backends and the expectation values. """ - + nqubits = 3 p = 1 - weights = [1,2,3] + weights = [1, 2, 3] gammas = [[3], [2]] - betas = [[1], [1/8]] - + betas = [[1], [1 / 8]] + for i in range(2): - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) + + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas[i], - gammas[i]) + variate_params = QAOAVariationalStandardParams( + qaoa_descriptor, betas[i], gammas[i] + ) - qiskit_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - None, - None, - True) + qiskit_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, None, None, True + ) qiskit_wavefunction = qiskit_backend.wavefunction(variate_params) qiskit_expectation = qiskit_backend.expectation(variate_params) - vector_backend = QAOAvectorizedBackendSimulator(qaoa_descriptor, - None, - None, - True) + vector_backend = QAOAvectorizedBackendSimulator( + qaoa_descriptor, None, None, True + ) vector_wavefunction = vector_backend.wavefunction(variate_params) vector_expectation = vector_backend.expectation(variate_params) - + self.assertAlmostEqual(qiskit_expectation, vector_expectation) - + for j in range(2**nqubits): - self.assertAlmostEqual(qiskit_wavefunction[j].real, - vector_wavefunction[j].real) - self.assertAlmostEqual(qiskit_wavefunction[j].imag, - vector_wavefunction[j].imag) - - + self.assertAlmostEqual( + qiskit_wavefunction[j].real, vector_wavefunction[j].real + ) + self.assertAlmostEqual( + qiskit_wavefunction[j].imag, vector_wavefunction[j].imag + ) + def test_qaoa_circuit_wavefunction_expectation_equivalence_2(self): - - """Due to the difference in the constructions of the statevector simulators, + + """Due to the difference in the constructions of the statevector simulators, there is a global phase difference between the results obtained from qiskit's statevector simulator and OpenQAOA's vectorised simulator. In order to - show the equivalence between the wavefunctions produced, the expectation + show the equivalence between the wavefunctions produced, the expectation of a random operator is computed. """ - + nqubits = 3 p = 1 - weights = [1,2,3] - gammas = [[1/8 * np.pi], [1/8 * np.pi]] - betas = [[1], [1/8 * np.pi]] - + weights = [1, 2, 3] + gammas = [[1 / 8 * np.pi], [1 / 8 * np.pi]] + betas = [[1], [1 / 8 * np.pi]] + for i in range(2): - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) - + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) + + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) + qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas[i], - gammas[i]) + variate_params = QAOAVariationalStandardParams( + qaoa_descriptor, betas[i], gammas[i] + ) - qiskit_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - None, - None, - True) + qiskit_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, None, None, True + ) qiskit_wavefunction = qiskit_backend.wavefunction(variate_params) qiskit_expectation = qiskit_backend.expectation(variate_params) - - vector_backend = QAOAvectorizedBackendSimulator(qaoa_descriptor, - None, - None, - True) + + vector_backend = QAOAvectorizedBackendSimulator( + qaoa_descriptor, None, None, True + ) vector_wavefunction = vector_backend.wavefunction(variate_params) vector_expectation = vector_backend.expectation(variate_params) - - random_operator = np.random.rand(2**nqubits, 2**nqubits) + np.random.rand(2**nqubits, 2**nqubits)*1j + + random_operator = ( + np.random.rand(2**nqubits, 2**nqubits) + + np.random.rand(2**nqubits, 2**nqubits) * 1j + ) random_herm = random_operator + random_operator.conj().T - expect_qiskit = np.matmul(np.array(qiskit_wavefunction).T.conjugate(), np.matmul(random_herm, np.array(qiskit_wavefunction))) - expect_vector = np.matmul(np.array(vector_wavefunction).T.conjugate(), np.matmul(random_herm, np.array(vector_wavefunction))) + expect_qiskit = np.matmul( + np.array(qiskit_wavefunction).T.conjugate(), + np.matmul(random_herm, np.array(qiskit_wavefunction)), + ) + expect_vector = np.matmul( + np.array(vector_wavefunction).T.conjugate(), + np.matmul(random_herm, np.array(vector_wavefunction)), + ) self.assertAlmostEqual(expect_qiskit.real, expect_vector.real) self.assertAlmostEqual(expect_qiskit.imag, expect_vector.imag) self.assertAlmostEqual(qiskit_expectation, vector_expectation) - + def test_qaoa_circuit_wavefunction_expectation_equivalence_3(self): - - """Due to the difference in the constructions of the statevector simulators, + + """Due to the difference in the constructions of the statevector simulators, there is a global phase difference between the results obtained from qiskit's statevector simulator and OpenQAOA's vectorised simulator. In order to - show the equivalence between the wavefunctions produced, the expectation + show the equivalence between the wavefunctions produced, the expectation of a random operator is computed. - + Nonuniform mixer weights. """ - + nqubits = 3 p = 1 - weights = [1,2,3] - gammas = [[1/8 * np.pi], [1/8 * np.pi]] - betas = [[1], [1/8 * np.pi]] - + weights = [1, 2, 3] + gammas = [[1 / 8 * np.pi], [1 / 8 * np.pi]] + betas = [[1], [1 / 8 * np.pi]] + for i in range(2): - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits, coeffs = [1,2,3]) - + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) + + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits, coeffs=[1, 2, 3]) + qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas[i], - gammas[i]) + variate_params = QAOAVariationalStandardParams( + qaoa_descriptor, betas[i], gammas[i] + ) - qiskit_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - None, - None, - True) + qiskit_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, None, None, True + ) qiskit_wavefunction = qiskit_backend.wavefunction(variate_params) qiskit_expectation = qiskit_backend.expectation(variate_params) - - vector_backend = QAOAvectorizedBackendSimulator(qaoa_descriptor, - None, - None, - True) + + vector_backend = QAOAvectorizedBackendSimulator( + qaoa_descriptor, None, None, True + ) vector_wavefunction = vector_backend.wavefunction(variate_params) vector_expectation = vector_backend.expectation(variate_params) - - random_operator = np.random.rand(2**nqubits, 2**nqubits) + np.random.rand(2**nqubits, 2**nqubits)*1j + + random_operator = ( + np.random.rand(2**nqubits, 2**nqubits) + + np.random.rand(2**nqubits, 2**nqubits) * 1j + ) random_herm = random_operator + random_operator.conj().T - expect_qiskit = np.matmul(np.array(qiskit_wavefunction).T.conjugate(), np.matmul(random_herm, np.array(qiskit_wavefunction))) - expect_vector = np.matmul(np.array(vector_wavefunction).T.conjugate(), np.matmul(random_herm, np.array(vector_wavefunction))) + expect_qiskit = np.matmul( + np.array(qiskit_wavefunction).T.conjugate(), + np.matmul(random_herm, np.array(qiskit_wavefunction)), + ) + expect_vector = np.matmul( + np.array(vector_wavefunction).T.conjugate(), + np.matmul(random_herm, np.array(vector_wavefunction)), + ) self.assertAlmostEqual(expect_qiskit.real, expect_vector.real) self.assertAlmostEqual(expect_qiskit.imag, expect_vector.imag) self.assertAlmostEqual(qiskit_expectation, vector_expectation) - + def test_qaoa_circuit_wavefunction_expectation_equivalence_4(self): - - """Due to the difference in the constructions of the statevector simulators, + + """Due to the difference in the constructions of the statevector simulators, there is a global phase difference between the results obtained from qiskit's statevector simulator and OpenQAOA's vectorised simulator. In order to - show the equivalence between the wavefunctions produced, the expectation + show the equivalence between the wavefunctions produced, the expectation of a random operator is computed. - + Y, YY and XX mixers with nonuniform weights. """ - + nqubits = 3 p = 1 - weights = [1,2,3] - gammas = [[1/8 * np.pi], [1/8 * np.pi]] - betas = [[1], [1/8 * np.pi]] - + weights = [1, 2, 3] + gammas = [[1 / 8 * np.pi], [1 / 8 * np.pi]] + betas = [[1], [1 / 8 * np.pi]] + for i in range(2): - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) - mixer_hamil = Hamiltonian([PauliOp('Y', (0,)), PauliOp('YY', (0,1)), PauliOp('XX', (1,2)), PauliOp('XZ', (1,2))], [1,2,3,4], 1) - + + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) + mixer_hamil = Hamiltonian( + [ + PauliOp("Y", (0,)), + PauliOp("YY", (0, 1)), + PauliOp("XX", (1, 2)), + PauliOp("XZ", (1, 2)), + ], + [1, 2, 3, 4], + 1, + ) + qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas[i], - gammas[i]) + variate_params = QAOAVariationalStandardParams( + qaoa_descriptor, betas[i], gammas[i] + ) - qiskit_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - None, - None, - True) + qiskit_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, None, None, True + ) qiskit_wavefunction = qiskit_backend.wavefunction(variate_params) qiskit_expectation = qiskit_backend.expectation(variate_params) - - vector_backend = QAOAvectorizedBackendSimulator(qaoa_descriptor, - None, - None, - True) + + vector_backend = QAOAvectorizedBackendSimulator( + qaoa_descriptor, None, None, True + ) vector_wavefunction = vector_backend.wavefunction(variate_params) vector_expectation = vector_backend.expectation(variate_params) - - random_operator = np.random.rand(2**nqubits, 2**nqubits) + np.random.rand(2**nqubits, 2**nqubits)*1j + + random_operator = ( + np.random.rand(2**nqubits, 2**nqubits) + + np.random.rand(2**nqubits, 2**nqubits) * 1j + ) random_herm = random_operator + random_operator.conj().T - expect_qiskit = np.matmul(np.array(qiskit_wavefunction).T.conjugate(), np.matmul(random_herm, np.array(qiskit_wavefunction))) - expect_vector = np.matmul(np.array(vector_wavefunction).T.conjugate(), np.matmul(random_herm, np.array(vector_wavefunction))) + expect_qiskit = np.matmul( + np.array(qiskit_wavefunction).T.conjugate(), + np.matmul(random_herm, np.array(qiskit_wavefunction)), + ) + expect_vector = np.matmul( + np.array(vector_wavefunction).T.conjugate(), + np.matmul(random_herm, np.array(vector_wavefunction)), + ) self.assertAlmostEqual(expect_qiskit.real, expect_vector.real) self.assertAlmostEqual(expect_qiskit.imag, expect_vector.imag) @@ -439,128 +519,150 @@ def test_cost_call(self): testing the __call__ method of the base class. Only for vectorized and Qiskit Local Statevector Backends. """ - + n_qubits = 8 register = range(n_qubits) p = 1 - - betas = [np.pi/8] - gammas = [np.pi/4] + + betas = [np.pi / 8] + gammas = [np.pi / 4] cost_hamiltonian = ring_of_disagrees(register) mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) + variational_params_std = QAOAVariationalStandardParams( + qaoa_descriptor, betas, gammas + ) + + backend_qiskit_statevec = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) - backend_qiskit_statevec = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor,prepend_state=None, - append_state=None,init_hadamard=True) + exp_qiskit_statevec = backend_qiskit_statevec.expectation( + (variational_params_std) + ) - exp_qiskit_statevec = backend_qiskit_statevec.expectation((variational_params_std)) - assert np.isclose(exp_qiskit_statevec, -6) def test_get_wavefunction(self): - + n_qubits = 3 terms = [[0, 1], [0, 2], [0]] weights = [1, 1, -0.5] p = 1 - - betas_singles = [np.pi,0,0] + + betas_singles = [np.pi, 0, 0] betas_pairs = [] gammas_singles = [np.pi] - gammas_pairs = [[1/2*np.pi]*2] - - cost_hamiltonian = Hamiltonian.classical_hamiltonian(terms=terms, coeffs=weights, constant=0) + gammas_pairs = [[1 / 2 * np.pi] * 2] + + cost_hamiltonian = Hamiltonian.classical_hamiltonian( + terms=terms, coeffs=weights, constant=0 + ) mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalExtendedParams(qaoa_descriptor, - betas_singles=betas_singles, - betas_pairs=betas_pairs, - gammas_singles=gammas_singles, - gammas_pairs=gammas_pairs) - - backend_qiskit_statevec = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor,prepend_state=None, - append_state=None,init_hadamard=True) - - wf_qiskit_statevec = backend_qiskit_statevec.wavefunction((variational_params_std)) - expected_wf = 1j*np.array([-1,1,1,-1,1,-1,-1,1])/(2*np.sqrt(2)) - + variational_params_std = QAOAVariationalExtendedParams( + qaoa_descriptor, + betas_singles=betas_singles, + betas_pairs=betas_pairs, + gammas_singles=gammas_singles, + gammas_pairs=gammas_pairs, + ) + + backend_qiskit_statevec = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) + + wf_qiskit_statevec = backend_qiskit_statevec.wavefunction( + (variational_params_std) + ) + expected_wf = 1j * np.array([-1, 1, 1, -1, 1, -1, -1, 1]) / (2 * np.sqrt(2)) + try: assert np.allclose(wf_qiskit_statevec, expected_wf) except AssertionError: - assert np.allclose(np.real(np.conjugate(wf_qiskit_statevec)*wf_qiskit_statevec), - np.conjugate(expected_wf)*expected_wf) - + assert np.allclose( + np.real(np.conjugate(wf_qiskit_statevec) * wf_qiskit_statevec), + np.conjugate(expected_wf) * expected_wf, + ) + def test_exact_solution(self): """ NOTE:Since the implementation of exact solution is backend agnostic - Checking it once should be okay. + Checking it once should be okay. Nevertheless, for the sake of completeness it will be tested for all backend instances. """ - + n_qubits = 8 register = range(n_qubits) p = 1 - correct_energy = -8 - correct_config = [0,1,0,1,0,1,0,1] - + correct_energy = -8 + correct_config = [0, 1, 0, 1, 0, 1, 0, 1] + # The tests pass regardless of the value of betas and gammas is this correct? - betas = [np.pi/8] - gammas = [np.pi/4] + betas = [np.pi / 8] + gammas = [np.pi / 4] cost_hamiltonian = ring_of_disagrees(register) mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) - - backend_qiskit_statevec = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor,prepend_state=None, - append_state=None,init_hadamard=True) + variational_params_std = QAOAVariationalStandardParams( + qaoa_descriptor, betas, gammas + ) - #exact solution is defined as the property of the cost function + backend_qiskit_statevec = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) + + # exact solution is defined as the property of the cost function energy_qiskit, config_qiskit = backend_qiskit_statevec.exact_solution - + assert np.isclose(energy_qiskit, correct_energy) config_qiskit = [config.tolist() for config in config_qiskit] assert correct_config in config_qiskit - + def test_expectation_w_uncertainty(self): - + """ Test the standard deviation equality. Expectation w uncertainty. """ - + n_qubits = 8 register = range(n_qubits) p = 1 - - betas = [np.pi/8] - gammas = [np.pi/4] + + betas = [np.pi / 8] + gammas = [np.pi / 4] cost_hamiltonian = ring_of_disagrees(register) mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) + variational_params_std = QAOAVariationalStandardParams( + qaoa_descriptor, betas, gammas + ) + + backend_qiskit_statevec = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) - backend_qiskit_statevec = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor,prepend_state=None, - append_state=None,init_hadamard=True) + ( + exp_qiskit_statevec, + exp_unc_qiskit_statevec, + ) = backend_qiskit_statevec.expectation_w_uncertainty(variational_params_std) - exp_qiskit_statevec, exp_unc_qiskit_statevec = backend_qiskit_statevec.expectation_w_uncertainty(variational_params_std) - assert np.isclose(exp_qiskit_statevec, -6) - - terms = [(register[i],register[(i+1)%n_qubits]) for i in range(n_qubits)] - weights = [0.5]*len(terms) - + + terms = [(register[i], register[(i + 1) % n_qubits]) for i in range(n_qubits)] + weights = [0.5] * len(terms) + # Check standard deviation - # Get the matrix form of the Hamiltonian (note we just keep the diagonal + # Get the matrix form of the Hamiltonian (note we just keep the diagonal # part) and square it - ham_matrix = np.zeros((2**len(register))) + ham_matrix = np.zeros((2 ** len(register))) for i, term in enumerate(terms): out = np.real(weights[i]) for qubit in register: @@ -569,126 +671,133 @@ def test_expectation_w_uncertainty(self): else: out = np.kron([1, 1], out) ham_matrix += out - + ham_matrix_sq = np.square(ham_matrix) - + # Get the wavefunction wf = backend_qiskit_statevec.wavefunction(variational_params_std) - + # Get the probabilities - probs = np.real(np.conjugate(wf)*wf) - + probs = np.real(np.conjugate(wf) * wf) + # Standard deviation - exp_2 = np.dot(probs,ham_matrix) - std_dev2 = np.sqrt(np.dot(probs,ham_matrix_sq) - exp_2**2) - + exp_2 = np.dot(probs, ham_matrix) + std_dev2 = np.sqrt(np.dot(probs, ham_matrix_sq) - exp_2**2) + assert np.isclose(exp_unc_qiskit_statevec, std_dev2) - + def test_expectation_w_randomizing_variables(self): - + """ - Run ntrials sets of randomized input parameters and compares the - expectation value output between the qiskit statevector simulator and + Run ntrials sets of randomized input parameters and compares the + expectation value output between the qiskit statevector simulator and vectorized simulator. """ - + ntrials = 100 - + nqubits = 3 p = [np.random.randint(1, 4) for i in range(ntrials)] - weights = [[np.random.rand(), np.random.rand(), np.random.rand(), np.random.rand()] for i in range(ntrials)] + weights = [ + [np.random.rand(), np.random.rand(), np.random.rand(), np.random.rand()] + for i in range(ntrials) + ] init_hadamards = [np.random.choice([True, False]) for i in range(ntrials)] constants = [np.random.rand() for i in range(ntrials)] - + for i in range(ntrials): - - gammas = [np.random.rand()*np.pi for i in range(p[i])] - betas = [np.random.rand()*np.pi for i in range(p[i])] - - cost_hamil = Hamiltonian([PauliOp('Z', (0, )), PauliOp('ZZ', (0, 1)), - PauliOp('ZZ', (1, 2)), PauliOp('ZZ', (0, 2))], - weights[i], constants[i]) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) + + gammas = [np.random.rand() * np.pi for i in range(p[i])] + betas = [np.random.rand() * np.pi for i in range(p[i])] + + cost_hamil = Hamiltonian( + [ + PauliOp("Z", (0,)), + PauliOp("ZZ", (0, 1)), + PauliOp("ZZ", (1, 2)), + PauliOp("ZZ", (0, 2)), + ], + weights[i], + constants[i], + ) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p[i]) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, - gammas) + variate_params = QAOAVariationalStandardParams( + qaoa_descriptor, betas, gammas + ) - qiskit_backend = QAOAQiskitBackendStatevecSimulator(qaoa_descriptor, - None, - None, - init_hadamards[i]) + qiskit_backend = QAOAQiskitBackendStatevecSimulator( + qaoa_descriptor, None, None, init_hadamards[i] + ) qiskit_expectation = qiskit_backend.expectation(variate_params) - vector_backend = QAOAvectorizedBackendSimulator(qaoa_descriptor, - None, - None, - init_hadamards[i]) + vector_backend = QAOAvectorizedBackendSimulator( + qaoa_descriptor, None, None, init_hadamards[i] + ) vector_expectation = vector_backend.expectation(variate_params) - + self.assertAlmostEqual(qiskit_expectation, vector_expectation) - + def test_shot_based_simulator(self): - + """ Test get_counts in shot-based qiskit simulator. """ - + nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 10000 - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) + + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) - - qiskit_shot_backend = QAOAQiskitBackendShotBasedSimulator(qaoa_descriptor, - shots, - None, - None, - True, 1.0) - + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) + + qiskit_shot_backend = QAOAQiskitBackendShotBasedSimulator( + qaoa_descriptor, shots, None, None, True, 1.0 + ) + shot_result = qiskit_shot_backend.get_counts(variate_params) - + self.assertEqual(type(shot_result), dict) - + def test_cvar_alpha_expectation(self): - + """ Test computing the expectation value by changing the alpha of the cvar. """ - + nqubits = 3 p = 1 weights = [1, -1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 10000 - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('ZZ', (1, 2)), - PauliOp('ZZ', (0, 2))], weights, 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) + + cost_hamil = Hamiltonian( + [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))], + weights, + 1, + ) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) - - qiskit_shot_backend = QAOAQiskitBackendShotBasedSimulator(qaoa_descriptor, - shots, - None, - None, - True, 1.0, - seed_simulator=1234) - + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) + + qiskit_shot_backend = QAOAQiskitBackendShotBasedSimulator( + qaoa_descriptor, shots, None, None, True, 1.0, seed_simulator=1234 + ) + expectation_value_100 = qiskit_shot_backend.expectation(variate_params) self.assertEqual(type(float(expectation_value_100)), float) - + # cvar_alpha = 0.5, 0.75 qiskit_shot_backend.cvar_alpha = 0.5 expectation_value_05 = qiskit_shot_backend.expectation(variate_params) @@ -697,40 +806,50 @@ def test_cvar_alpha_expectation(self): self.assertNotEqual(expectation_value_05, expectation_value_075) self.assertEqual(type(float(expectation_value_05)), float) self.assertEqual(type(float(expectation_value_075)), float) - + def test_standard_decomposition_branch_in_circuit_construction(self): - + """ XY Pauli is not an implemented low level gate. Produces NotImplementedError as the standard decomposition for the XY PauliGate doesnt exist. """ - + nqubits = 3 p = 1 weights = [1, 1, 1] - gammas = [1/8*np.pi] - betas = [1/8*np.pi] + gammas = [1 / 8 * np.pi] + betas = [1 / 8 * np.pi] shots = 10000 - - cost_hamil = Hamiltonian([PauliOp('XY', (0, 1)), PauliOp('XY', (1, 2)), - PauliOp('XY', (0, 2))], weights, 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nqubits) + + cost_hamil = Hamiltonian( + [PauliOp("XY", (0, 1)), PauliOp("XY", (1, 2)), PauliOp("XY", (0, 2))], + weights, + 1, + ) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nqubits) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=p) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) - - self.assertRaises(NotImplementedError, QAOAQiskitBackendShotBasedSimulator, - qaoa_descriptor, - shots, - None, - None, - True, 1.0) - - self.assertRaises(NotImplementedError, QAOAQiskitBackendStatevecSimulator, - qaoa_descriptor, - None, - None, - True) - -if __name__ == '__main__': - unittest.main() \ No newline at end of file + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, betas, gammas) + + self.assertRaises( + NotImplementedError, + QAOAQiskitBackendShotBasedSimulator, + qaoa_descriptor, + shots, + None, + None, + True, + 1.0, + ) + + self.assertRaises( + NotImplementedError, + QAOAQiskitBackendStatevecSimulator, + qaoa_descriptor, + None, + None, + True, + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_simulators.py b/tests/test_simulators.py index bd9797f08..84f19addd 100644 --- a/tests/test_simulators.py +++ b/tests/test_simulators.py @@ -7,23 +7,22 @@ class TestSimulators(unittest.TestCase): - def test_job_ids(self): """ Test if correct job ids are generated and returned for all simulators """ - #define problem + # define problem problem = QUBO.random_instance(3) - #loop over all simulators + # loop over all simulators for n in SUPPORTED_LOCAL_SIMULATORS: # initialize q = QAOA() # device - device = create_device(location='local', name=n) + device = create_device(location="local", name=n) q.set_device(device) # classical optimizer only 3 iterations @@ -36,14 +35,16 @@ def test_job_ids(self): q.optimize() # check if we have job ids - opt_id = q.result.optimized['job_id'] - assert len(opt_id) == 36 and isinstance(opt_id, str), f'simulator {n}: job id is not a string of length 36, but {opt_id}' + opt_id = q.result.optimized["job_id"] + assert len(opt_id) == 36 and isinstance( + opt_id, str + ), f"simulator {n}: job id is not a string of length 36, but {opt_id}" - inter_id = q.result.intermediate['job_id'] + inter_id = q.result.intermediate["job_id"] for id in inter_id: - assert len(id) == 36 and isinstance(id, str), f'simulator {n}: on intermediate job id is not a string of length 36, but {id}' - - + assert len(id) == 36 and isinstance( + id, str + ), f"simulator {n}: on intermediate job id is not a string of length 36, but {id}" if __name__ == "__main__": diff --git a/tests/test_utilities.py b/tests/test_utilities.py index ab2a981de..b5d399562 100644 --- a/tests/test_utilities.py +++ b/tests/test_utilities.py @@ -2,10 +2,16 @@ import numpy as np import itertools import unittest +import datetime from openqaoa.backends import DeviceLocal from openqaoa.utilities import * -from openqaoa.qaoa_components import PauliOp, Hamiltonian, QAOADescriptor, create_qaoa_variational_params +from openqaoa.qaoa_components import ( + PauliOp, + Hamiltonian, + QAOADescriptor, + create_qaoa_variational_params, +) from openqaoa.backends.qaoa_backend import get_qaoa_backend from openqaoa.optimizers.qaoa_optimizer import get_optimizer from openqaoa.problems import MinimumVertexCover @@ -14,8 +20,8 @@ Unit test based testing of the utility functions """ -class TestingUtilities(unittest.TestCase): +class TestingUtilities(unittest.TestCase): def test_X_mixer_hamiltonian(self): """ Tests the function that generates X mixer Hamiltonian. @@ -24,31 +30,37 @@ def test_X_mixer_hamiltonian(self): """ # Set of sizes - sizes = range(1,10) - + sizes = range(1, 10) + # Test for different sizes for n_qubits in sizes: - + # Define input coefficients input_coefficients = [-1 for _ in range(n_qubits)] # Define mixer Hamiltonian - mixer_hamiltonian = X_mixer_hamiltonian(n_qubits,input_coefficients) + mixer_hamiltonian = X_mixer_hamiltonian(n_qubits, input_coefficients) # Extract mixer Hamiltonian attributes terms = mixer_hamiltonian.terms coefficients = mixer_hamiltonian.coeffs constant = mixer_hamiltonian.constant - + # Correct mixer hamiltonian attributes - correct_terms = [PauliOp('X',(i,)) for i in range(n_qubits)] + correct_terms = [PauliOp("X", (i,)) for i in range(n_qubits)] correct_coefficients = [-1 for _ in range(n_qubits)] correct_constant = 0 # Test that the mixer Hamiltonian was correctly generated - assert terms == correct_terms, f'The terms in the X mixer Hamiltonian were not generated correctly' - assert np.allclose(coefficients,correct_coefficients), f'The coefficients in the X mixer Hamiltonian were not generated correctly' - assert np.allclose(constant,correct_constant), f'The constant in the X mixer Hamiltonian was not generated correctly' + assert ( + terms == correct_terms + ), f"The terms in the X mixer Hamiltonian were not generated correctly" + assert np.allclose( + coefficients, correct_coefficients + ), f"The coefficients in the X mixer Hamiltonian were not generated correctly" + assert np.allclose( + constant, correct_constant + ), f"The constant in the X mixer Hamiltonian was not generated correctly" def test_XY_mixer_hamiltonian(self): """ @@ -59,20 +71,20 @@ def test_XY_mixer_hamiltonian(self): """ # Set of sizes - sizes = range(2,10) + sizes = range(2, 10) # Set of default connectivities - connectivities = ['full','chain','star'] + connectivities = ["full", "chain", "star"] # String of Pauli objects contained in the XY mixer Hamiltonian - terms_strings = ['XX','YY'] + terms_strings = ["XX", "YY"] # Set of uses - input_type = ['string','custom'] - + input_type = ["string", "custom"] + # Test for different sizes for n_qubits in sizes: - + # Test for different connectivities for connectivity in connectivities: @@ -80,55 +92,73 @@ def test_XY_mixer_hamiltonian(self): for input in input_type: # Define connectivity explicit indexing - if connectivity == 'full': - terms_indices = list(itertools.combinations(range(n_qubits),2)) + if connectivity == "full": + terms_indices = list(itertools.combinations(range(n_qubits), 2)) - elif connectivity == 'chain': - terms_indices = [(i,i+1) for i in range(n_qubits-1)] + elif connectivity == "chain": + terms_indices = [(i, i + 1) for i in range(n_qubits - 1)] else: - terms_indices = [(0,i) for i in range(1,n_qubits)] - + terms_indices = [(0, i) for i in range(1, n_qubits)] + # Define input coefficients, account for two terms per connection (XX + YY) - input_coefficients = 2*[1 for _ in range(len(terms_indices))] + input_coefficients = 2 * [1 for _ in range(len(terms_indices))] # Define mixer Hamiltonian - if input == 'string': - mixer_hamiltonian = XY_mixer_hamiltonian(n_qubits,connectivity,input_coefficients) + if input == "string": + mixer_hamiltonian = XY_mixer_hamiltonian( + n_qubits, connectivity, input_coefficients + ) else: - mixer_hamiltonian = XY_mixer_hamiltonian(n_qubits,terms_indices,input_coefficients) + mixer_hamiltonian = XY_mixer_hamiltonian( + n_qubits, terms_indices, input_coefficients + ) # Extract mixer Hamiltonian attributes terms = mixer_hamiltonian.terms coefficients = mixer_hamiltonian.coeffs constant = mixer_hamiltonian.constant - + # Correct mixer hamiltonian attributes - correct_terms = [PauliOp(string,indices) for indices in terms_indices for string in terms_strings] + correct_terms = [ + PauliOp(string, indices) + for indices in terms_indices + for string in terms_strings + ] correct_coefficients = [1 for _ in range(len(correct_terms))] correct_constant = 0 - + # Test that the mixer Hamiltonian was correctly generated - assert terms == correct_terms, f'The terms in the XY mixer Hamiltonian were not generated correctly for {input} input' - assert np.allclose(coefficients,correct_coefficients), f'The coefficients in the XY mixer Hamiltonian were not generated correctly for {input} input' - assert np.allclose(constant,correct_constant), f'The constant in the XY mixer Hamiltonian was not generated correctly for {input} input' + assert ( + terms == correct_terms + ), f"The terms in the XY mixer Hamiltonian were not generated correctly for {input} input" + assert np.allclose( + coefficients, correct_coefficients + ), f"The coefficients in the XY mixer Hamiltonian were not generated correctly for {input} input" + assert np.allclose( + constant, correct_constant + ), f"The constant in the XY mixer Hamiltonian was not generated correctly for {input} input" - # Exception case - Insert an connectivity input name that is not supported # Supported connectivities - supported_connectivities = ['full','chain','star'] + supported_connectivities = ["full", "chain", "star"] # Choose a wrong connectivity - connectivity = 'bubbletea' + connectivity = "bubbletea" - # Attempt construction of Pauli operator + # Attempt construction of Pauli operator with self.assertRaises(ValueError) as context: - mixer_hamiltonian = XY_mixer_hamiltonian(n_qubits,connectivity,input_coefficients) + mixer_hamiltonian = XY_mixer_hamiltonian( + n_qubits, connectivity, input_coefficients + ) # Check exception message - self.assertEqual(f"Please choose connection topology from {supported_connectivities}", str(context.exception)) + self.assertEqual( + f"Please choose connection topology from {supported_connectivities}", + str(context.exception), + ) def test_get_mixer_hamiltonian(self): """ @@ -141,49 +171,59 @@ def test_get_mixer_hamiltonian(self): n_qubits = 10 # Define a qubit connectivity for X, and a connectivity for XY mixers - connectivities = [None,'star','full','chain'] + connectivities = [None, "star", "full", "chain"] for connectivity in connectivities: # Define connectivity explicit indexing - if connectivity == 'full': - terms_indices = list(itertools.combinations(range(n_qubits),2)) - input_coefficients = 2*[1 for _ in range(len(terms_indices))] - mixer_type = 'xy' + if connectivity == "full": + terms_indices = list(itertools.combinations(range(n_qubits), 2)) + input_coefficients = 2 * [1 for _ in range(len(terms_indices))] + mixer_type = "xy" - elif connectivity == 'chain': - terms_indices = [(i,i+1) for i in range(n_qubits-1)] - input_coefficients = 2*[1 for _ in range(len(terms_indices))] - mixer_type = 'xy' + elif connectivity == "chain": + terms_indices = [(i, i + 1) for i in range(n_qubits - 1)] + input_coefficients = 2 * [1 for _ in range(len(terms_indices))] + mixer_type = "xy" - elif connectivity == 'star': - terms_indices = [(0,i) for i in range(1,n_qubits)] - input_coefficients = 2*[1 for _ in range(len(terms_indices))] - mixer_type = 'xy' + elif connectivity == "star": + terms_indices = [(0, i) for i in range(1, n_qubits)] + input_coefficients = 2 * [1 for _ in range(len(terms_indices))] + mixer_type = "xy" else: input_coefficients = [1 for _ in range(n_qubits)] - mixer_type = 'x' + mixer_type = "x" # Retrieve Hamiltonian and attributes - mixer_hamiltonian = get_mixer_hamiltonian(n_qubits,mixer_type,connectivity,input_coefficients) + mixer_hamiltonian = get_mixer_hamiltonian( + n_qubits, mixer_type, connectivity, input_coefficients + ) terms = mixer_hamiltonian.terms coefficients = mixer_hamiltonian.coeffs # Generate correct Hamiltonian and attributes - if mixer_type == 'xy': - correct_mixer_hamiltonian = XY_mixer_hamiltonian(n_qubits,connectivity,input_coefficients) + if mixer_type == "xy": + correct_mixer_hamiltonian = XY_mixer_hamiltonian( + n_qubits, connectivity, input_coefficients + ) else: - correct_mixer_hamiltonian = X_mixer_hamiltonian(n_qubits,input_coefficients) - + correct_mixer_hamiltonian = X_mixer_hamiltonian( + n_qubits, input_coefficients + ) + correct_terms = correct_mixer_hamiltonian.terms correct_coefficients = correct_mixer_hamiltonian.coeffs # Test that the mixer Hamiltonian was correctly generated - assert terms == correct_terms, f'The terms in the mixer Hamiltonian were not generated correctly for {connectivity} connectivity' - assert np.allclose(coefficients,correct_coefficients), f'The coefficients in the mixer Hamiltonian were not generated correctly for {connectivity} connectivity' - + assert ( + terms == correct_terms + ), f"The terms in the mixer Hamiltonian were not generated correctly for {connectivity} connectivity" + assert np.allclose( + coefficients, correct_coefficients + ), f"The coefficients in the mixer Hamiltonian were not generated correctly for {connectivity} connectivity" + def test_graph_from_hamiltonian(self): """ Tests the function that extracts the underlying graph from a Hamiltonian. @@ -195,36 +235,60 @@ def test_graph_from_hamiltonian(self): n_qubits = 10 # Define hamiltonian - terms = [PauliOp('ZZ',(i,j)) for j in range(n_qubits) for i in range(j)] + [PauliOp('Z',(i,)) for i in range(n_qubits)] - coefficients = [0.5 for j in range(n_qubits) for _ in range(j)] + [-1 for _ in range(n_qubits)] + terms = [PauliOp("ZZ", (i, j)) for j in range(n_qubits) for i in range(j)] + [ + PauliOp("Z", (i,)) for i in range(n_qubits) + ] + coefficients = [0.5 for j in range(n_qubits) for _ in range(j)] + [ + -1 for _ in range(n_qubits) + ] constant = 0 - hamiltonian = Hamiltonian(terms,coefficients,constant) + hamiltonian = Hamiltonian(terms, coefficients, constant) # Extract graph attributes from hamiltonian graph = graph_from_hamiltonian(hamiltonian) - singlet_edges = list({(node,):graph.nodes[node]['weight'] for node in graph.nodes if graph.nodes[node].get('weight') is not None}.keys()) - pair_edges = list(nx.get_edge_attributes(graph, 'weight').keys()) + singlet_edges = list( + { + (node,): graph.nodes[node]["weight"] + for node in graph.nodes + if graph.nodes[node].get("weight") is not None + }.keys() + ) + pair_edges = list(nx.get_edge_attributes(graph, "weight").keys()) edges = singlet_edges + pair_edges - pair_weights = list(nx.get_edge_attributes(graph, 'weight').values()) - singlet_weights = list({(node,):graph.nodes[node]['weight'] for node in graph.nodes if graph.nodes[node].get('weight') is not None}.values()) + pair_weights = list(nx.get_edge_attributes(graph, "weight").values()) + singlet_weights = list( + { + (node,): graph.nodes[node]["weight"] + for node in graph.nodes + if graph.nodes[node].get("weight") is not None + }.values() + ) weights = singlet_weights + pair_weights - graph_dict = {edge:weight for edge,weight in zip(edges,weights)} + graph_dict = {edge: weight for edge, weight in zip(edges, weights)} # Correct graph attributes correct_edges = [term.qubit_indices for term in terms] - correct_weights = [0.5 for _ in range(int(n_qubits*(n_qubits-1)/2))] + [-1 for _ in range(n_qubits)] + correct_weights = [0.5 for _ in range(int(n_qubits * (n_qubits - 1) / 2))] + [ + -1 for _ in range(n_qubits) + ] - correct_graph_dict = {edge:weight for edge,weight in zip(correct_edges,correct_weights)} + correct_graph_dict = { + edge: weight for edge, weight in zip(correct_edges, correct_weights) + } # Test that the graph contains the correct number of edges - assert len(graph_dict) == len(correct_graph_dict), f'An incorrect number of edges was generated' + assert len(graph_dict) == len( + correct_graph_dict + ), f"An incorrect number of edges was generated" # Test that graph attributes were obtained correctly for edge in graph_dict.keys(): - assert np.allclose(graph_dict[edge], correct_graph_dict[edge]), f'Weights were not obtained correctly' + assert np.allclose( + graph_dict[edge], correct_graph_dict[edge] + ), f"Weights were not obtained correctly" def test_hamiltonian_from_graph(self): """ @@ -237,7 +301,7 @@ def test_hamiltonian_from_graph(self): n_qubits = 10 # Define graph - pair_edges = [(i,j) for j in range(n_qubits) for i in range(j)] + pair_edges = [(i, j) for j in range(n_qubits) for i in range(j)] singlet_edges = [(i,) for i in range(n_qubits)] edges = singlet_edges + pair_edges @@ -245,11 +309,11 @@ def test_hamiltonian_from_graph(self): # Populate the graph with weighted nodes and weighted edges for edge in edges: - + # Weighted node if len(edge) == 1: - graph.add_node(edge[0],weight = -1) - + graph.add_node(edge[0], weight=-1) + # Weighted edge else: graph.add_edge(edge[0], edge[1], weight=0.5) @@ -257,17 +321,31 @@ def test_hamiltonian_from_graph(self): # Generate Hamiltonian and extract attributes hamiltonian = hamiltonian_from_graph(graph) - hamiltonian_dict = {term.qubit_indices:coeff for term,coeff in zip(hamiltonian.terms,hamiltonian.coeffs)} + hamiltonian_dict = { + term.qubit_indices: coeff + for term, coeff in zip(hamiltonian.terms, hamiltonian.coeffs) + } constant = hamiltonian.constant # Correct Hamiltonian attributes - correct_terms = [PauliOp('Z',(i,)) for i in range(n_qubits)] + [PauliOp('ZZ',(i,j)) for j in range(n_qubits) for i in range(j)] - correct_coefficients = [-1 for _ in range(n_qubits)] + [0.5 for j in range(n_qubits) for _ in range(j)] - correct_hamiltonian_dict = {term.qubit_indices:coeff for term,coeff in zip(correct_terms,correct_coefficients)} + correct_terms = [PauliOp("Z", (i,)) for i in range(n_qubits)] + [ + PauliOp("ZZ", (i, j)) for j in range(n_qubits) for i in range(j) + ] + correct_coefficients = [-1 for _ in range(n_qubits)] + [ + 0.5 for j in range(n_qubits) for _ in range(j) + ] + correct_hamiltonian_dict = { + term.qubit_indices: coeff + for term, coeff in zip(correct_terms, correct_coefficients) + } correct_constant = 0 - assert hamiltonian_dict == correct_hamiltonian_dict, f'The terms and coefficients were not correctly generated' - assert np.allclose(constant,correct_constant), f'The constant was not correctly generated' + assert ( + hamiltonian_dict == correct_hamiltonian_dict + ), f"The terms and coefficients were not correctly generated" + assert np.allclose( + constant, correct_constant + ), f"The constant was not correctly generated" def test_random_k_regular_graph(self): """ @@ -280,49 +358,58 @@ def test_random_k_regular_graph(self): n_nodes = 6 # Set of degrees - degrees = [2,3,4,5] + degrees = [2, 3, 4, 5] # Check for every degree for degree in degrees: # Check for weighted and unweighted - for weighted in [False,True]: + for weighted in [False, True]: - for biases in [False,True]: + for biases in [False, True]: # Generate graph - graph = random_k_regular_graph(degree,list(range(n_nodes)), weighted = weighted, biases = biases) + graph = random_k_regular_graph( + degree, list(range(n_nodes)), weighted=weighted, biases=biases + ) # Test it has the correct number of edges for a regular graph - assert np.allclose(len(list(graph.edges)), degree*n_nodes/2), f'The number of edges is not correct' + assert np.allclose( + len(list(graph.edges)), degree * n_nodes / 2 + ), f"The number of edges is not correct" # Test graph is properly unweighted if weighted is False: - assert np.allclose(list(nx.get_edge_attributes(graph, 'weight').values()),[1 for _ in range(int(degree*n_nodes/2))]), f'Graph is not unweighted' + assert np.allclose( + list(nx.get_edge_attributes(graph, "weight").values()), + [1 for _ in range(int(degree * n_nodes / 2))], + ), f"Graph is not unweighted" def test_random_classical_hamiltonian(self): - """" + """ " Tests the function that generates a random classical Hamiltonian. - + The test consists in checking that the generated Hamiltonian is indeed classical (containing only 'Z' type pauils). """ # Number of qubits - sizes = list(range(2,10)) + sizes = list(range(2, 10)) # Test for different qubit numbers for n_qubits in sizes: - hamiltonian = random_classical_hamiltonian(reg = list(range(n_qubits))) + hamiltonian = random_classical_hamiltonian(reg=list(range(n_qubits))) # Test the hamiltonian is a Hamiltonian object - assert isinstance(hamiltonian,Hamiltonian), f'The object is not Hamiltonian object' + assert isinstance( + hamiltonian, Hamiltonian + ), f"The object is not Hamiltonian object" # Check all terms are combination of 'Z' Paulis terms = hamiltonian.terms for term in terms: - assert term.pauli_str in ('Z','ZZ'), f'Found non-classical term' + assert term.pauli_str in ("Z", "ZZ"), f"Found non-classical term" def test_ground_state_hamiltonian(self): """ @@ -331,50 +418,57 @@ def test_ground_state_hamiltonian(self): The test consists in computing the ground state and minimum energy for given examples. """ # Number of variables/qubits - n_qubits = 10 + n_qubits = 10 # Terms and weights of the graph - edges = [(i,i+1) for i in range(n_qubits-1)] + [(0,n_qubits-1)] # Ring structure - weights = [1 for _ in range(len(edges))] # All weights equal to 1 + edges = [(i, i + 1) for i in range(n_qubits - 1)] + [ + (0, n_qubits - 1) + ] # Ring structure + weights = [1 for _ in range(len(edges))] # All weights equal to 1 # Define Hamiltonian - hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant = 0) + hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant=0) ## Testing # Correct solutions to the problem correct_energy = -10 - correct_states = ['1010101010','0101010101'] + correct_states = ["1010101010", "0101010101"] # Obtain solution from function energy, states = ground_state_hamiltonian(hamiltonian) - + # Test function result - assert np.allclose(energy,correct_energy), f'Computed solutions are incorrect' - assert states == correct_states , f'Computed solutions are incorrect' - - # Exception case - Insert a number that is too high + assert np.allclose(energy, correct_energy), f"Computed solutions are incorrect" + assert states == correct_states, f"Computed solutions are incorrect" + + # Exception case - Insert a number that is too high # Number of variables/qubits - n_qubits = 30 + n_qubits = 30 # Terms and weights of the graph - edges = [(i,i+1) for i in range(n_qubits-1)] + [(0,n_qubits-1)] # Ring structure - weights = [1 for _ in range(len(edges))] # All weights equal to 1 + edges = [(i, i + 1) for i in range(n_qubits - 1)] + [ + (0, n_qubits - 1) + ] # Ring structure + weights = [1 for _ in range(len(edges))] # All weights equal to 1 # Define Hamiltonian - hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant = 0) + hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant=0) # Attempt solving the system with self.assertRaises(ValueError) as context: energy, states = ground_state_hamiltonian(hamiltonian) # Check exception message - self.assertEqual("The number of qubits is too high, computation could take a long time. If still want to proceed set argument `bounded` to False",str(context.exception)) + self.assertEqual( + "The number of qubits is too high, computation could take a long time. If still want to proceed set argument `bounded` to False", + str(context.exception), + ) def test_bitstring_energy(self): """ - Test the function that computes the energy of a given string for a specificied + Test the function that computes the energy of a given string for a specificied cost Hamiltonian. The test consists in computing the energy of a few strings given a specific Hamiltonian. @@ -384,14 +478,14 @@ def test_bitstring_energy(self): n_qubits = 10 # Edges and weights defining the problem graph - edges = [(i,i+1) for i in range(n_qubits-1)] + [(0,n_qubits-1)] + edges = [(i, i + 1) for i in range(n_qubits - 1)] + [(0, n_qubits - 1)] weights = [1 for _ in range(len(edges))] # Hamiltonian - hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant = 0) + hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant=0) # Input states - states = ['0101010101',[1,0,1,0,1,0,1,0,1,0]] + states = ["0101010101", [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]] # Correct energies correct_energy = -10 @@ -400,10 +494,10 @@ def test_bitstring_energy(self): for state in states: # Compute energies for the given trial states - energy = bitstring_energy(hamiltonian,state) - + energy = bitstring_energy(hamiltonian, state) + # Test computed solution is correcrt - assert np.allclose(correct_energy,energy), f'Computed energy is incorrect' + assert np.allclose(correct_energy, energy), f"Computed energy is incorrect" def test_energy_expectation(self): """ @@ -418,24 +512,32 @@ def test_energy_expectation(self): n_qubits = 10 # Define edges and weights determining the problem graph - edges = [(i,i+1) for i in range(n_qubits-1)] + [(0,n_qubits-1)] + edges = [(i, i + 1) for i in range(n_qubits - 1)] + [(0, n_qubits - 1)] weights = [1 for _ in range(len(edges))] - + # Hamiltonian - hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant = 0) + hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant=0) # Input measurement counts dictionary - input_measurement_counts = {'0101010101':10,'1010101010':10,'0000000000':10,'1111111111':10,'1111111110':10} + input_measurement_counts = { + "0101010101": 10, + "1010101010": 10, + "0000000000": 10, + "1111111111": 10, + "1111111110": 10, + } # Obtain energy expectation value - energy = energy_expectation(hamiltonian,input_measurement_counts) - + energy = energy_expectation(hamiltonian, input_measurement_counts) + # Correct energy correct_energy = 1.2 - + # Test energy was computed correctly - assert np.allclose(energy,correct_energy), f'The energy expectation value was not computed correctly' - + assert np.allclose( + energy, correct_energy + ), f"The energy expectation value was not computed correctly" + def test_energy_spectrum_hamiltonian(self): """ Tests the function that computes the exact energy spectrum from a given classical Hamiltonian. @@ -447,7 +549,7 @@ def test_energy_spectrum_hamiltonian(self): n_qubits = 3 # Edges and weights defining the classical Hamiltonian - edges = [(i,i+1) for i in range(n_qubits-1)] + [(0,n_qubits-1)] + edges = [(i, i + 1) for i in range(n_qubits - 1)] + [(0, n_qubits - 1)] weights = [1 for _ in range(len(edges))] constant = 10 @@ -458,10 +560,12 @@ def test_energy_spectrum_hamiltonian(self): energies = energy_spectrum_hamiltonian(hamiltonian) energies.sort() # Correct energies - correct_energies = [9,9,9,9,9,9,13,13] + correct_energies = [9, 9, 9, 9, 9, 9, 13, 13] # Test computed energies are correct - assert np.allclose(energies,correct_energies), f'Energy spectrum was not computed correctly' + assert np.allclose( + energies, correct_energies + ), f"Energy spectrum was not computed correctly" def test_low_energy_states(self): """ @@ -473,56 +577,75 @@ def test_low_energy_states(self): """ # Define threshold - threshold_percentage = 3/10 + threshold_percentage = 3 / 10 # Define Hamiltonian - terms = [PauliOp('ZZ',(0,1)),PauliOp('ZZ',(1,2)),PauliOp('ZZ',(0,2))] - coeffs = [1,2,3] + terms = [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))] + coeffs = [1, 2, 3] constant = 0 - hamiltonian = Hamiltonian(terms,coeffs,constant) + hamiltonian = Hamiltonian(terms, coeffs, constant) # Obtain low energy states and the low energy threshold - low_energy_threshold,states = low_energy_states(hamiltonian,threshold_percentage) + low_energy_threshold, states = low_energy_states( + hamiltonian, threshold_percentage + ) # Correct low energy state and low energy threshold correct_low_energy_threshold = -1 - correct_states = ['100','011','001','110'] + correct_states = ["100", "011", "001", "110"] # Test that low energy threshold and states were correctly retrieved - assert np.allclose(low_energy_threshold,correct_low_energy_threshold), f'Low energy threshold was not computed correctly' - assert set(states) == set(correct_states), f'Low energy states were not computed correctly' + assert np.allclose( + low_energy_threshold, correct_low_energy_threshold + ), f"Low energy threshold was not computed correctly" + assert set(states) == set( + correct_states + ), f"Low energy states were not computed correctly" def test_low_energy_states_overlap(self): """ Test the function that computes the overlap between the low energy states, defined by a threshold percentage from the gound state energy, and a given input state, expressed in terms of a probability dictionary. - + The test consists in computing the overlap for a given Hamiltonian and a given input state. """ # Define threshold - threshold_percentage = 3/10 + threshold_percentage = 3 / 10 # Define Hamiltonian - terms = [PauliOp('ZZ',(0,1)),PauliOp('ZZ',(1,2)),PauliOp('ZZ',(0,2))] - coeffs = [1,2,3] + terms = [PauliOp("ZZ", (0, 1)), PauliOp("ZZ", (1, 2)), PauliOp("ZZ", (0, 2))] + coeffs = [1, 2, 3] constant = 0 - hamiltonian = Hamiltonian(terms,coeffs,constant) + hamiltonian = Hamiltonian(terms, coeffs, constant) # Input state probability dictionary - prob_dict = {'000':20,'001':10,'010':10,'100':10,'011':20,'101':10,'110':10,'111':10} + prob_dict = { + "000": 20, + "001": 10, + "010": 10, + "100": 10, + "011": 20, + "101": 10, + "110": 10, + "111": 10, + } # Obtain low energy states overlap - overlap = low_energy_states_overlap(hamiltonian,threshold_percentage,prob_dict) + overlap = low_energy_states_overlap( + hamiltonian, threshold_percentage, prob_dict + ) # Correct overlap correct_overlap = 0.5 # Test overlap has been generated correctly - assert np.allclose(overlap,correct_overlap), f'The overlap was not computed correctly' + assert np.allclose( + overlap, correct_overlap + ), f"The overlap was not computed correctly" def test_ring_of_disagrees(self): """ @@ -532,27 +655,35 @@ def test_ring_of_disagrees(self): """ # Set of sizes - sizes = range(3,10) + sizes = range(3, 10) # Uniform case for n_qubits in sizes: - + # Generate ring of disagrees and extract attributes - rod_hamiltonian = ring_of_disagrees(reg = list(range(n_qubits))) + rod_hamiltonian = ring_of_disagrees(reg=list(range(n_qubits))) rod_terms = rod_hamiltonian.terms rod_coefficients = rod_hamiltonian.coeffs rod_constant = rod_hamiltonian.constant # Correct ring of disagrees hamiltonian - correct_rod_terms = [PauliOp('ZZ',(i,i+1)) for i in range(n_qubits-1)] + [PauliOp('ZZ',(0,n_qubits-1))] + correct_rod_terms = [ + PauliOp("ZZ", (i, i + 1)) for i in range(n_qubits - 1) + ] + [PauliOp("ZZ", (0, n_qubits - 1))] correct_rod_coefficients = [0.5 for _ in range(len(correct_rod_terms))] - correct_rod_constant = -n_qubits*0.5 + correct_rod_constant = -n_qubits * 0.5 # Test the ring of disagrees Hamiltonian was properly generated - assert rod_terms == correct_rod_terms, f'The terms in the uniform ROD Hamiltonian were not generated correctly' - assert np.allclose(rod_coefficients,correct_rod_coefficients), f'The coefficients in the uniform ROD Hamiltonian were not generated correctly' - assert np.allclose(rod_constant,correct_rod_constant), f'The constant in the uniform ROD Hamiltonian was not generated correctly' + assert ( + rod_terms == correct_rod_terms + ), f"The terms in the uniform ROD Hamiltonian were not generated correctly" + assert np.allclose( + rod_coefficients, correct_rod_coefficients + ), f"The coefficients in the uniform ROD Hamiltonian were not generated correctly" + assert np.allclose( + rod_constant, correct_rod_constant + ), f"The constant in the uniform ROD Hamiltonian was not generated correctly" def test_exp_val_hamiltonian_termwise_analytical(self): """ @@ -560,12 +691,12 @@ def test_exp_val_hamiltonian_termwise_analytical(self): analytically for p = 1 and the function computing the full set of expectation values when analytical results can be obtained (p=1). - NOTE: Correlations in the exp_val_pair_analytical() and exp_val_pair() functions are computed - as average value , meaning it includes the contribution. + NOTE: Correlations in the exp_val_pair_analytical() and exp_val_pair() functions are computed + as average value , meaning it includes the contribution. This is subtracted by default in the exp_val_hamiltonian_termwise() function. - The tests consist in: computing expectation values for some example cases for the - first function, and a full set of expectation values for a given example. + The tests consist in: computing expectation values for some example cases for the + first function, and a full set of expectation values for a given example. """ ## Problem definition @@ -574,76 +705,101 @@ def test_exp_val_hamiltonian_termwise_analytical(self): n_qubits = 4 # Edges and weights of the graph - pair_edges = [(i,i+1) for i in range(n_qubits-1)] + [(0,n_qubits-1)] + pair_edges = [(i, i + 1) for i in range(n_qubits - 1)] + [(0, n_qubits - 1)] self_edges = [(i,) for i in range(n_qubits)] - pair_weights = [1 for _ in range(len(pair_edges))] # All weights equal to 1 - self_weights = [(-1)**j for j in range(len(self_edges))] + pair_weights = [1 for _ in range(len(pair_edges))] # All weights equal to 1 + self_weights = [(-1) ** j for j in range(len(self_edges))] edges = pair_edges + self_edges weights = pair_weights + self_weights # Hamiltonian - hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant = 0) + hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant=0) ## Testing # Spin and pair whose expectation values are computed spin = 0 - pair = (0,1) - + pair = (0, 1) + # Correct solution - qaoa_angles_cases = {(0,0):(0,0),(np.pi,0):(0,0),(np.pi/4,np.pi/4):(0,0),\ - (np.pi/4,np.pi/8):(-np.sqrt(2)/4,-0.25),(np.pi/8,0):(0,0)} # (beta,gamma):(exp_val,corr) + qaoa_angles_cases = { + (0, 0): (0, 0), + (np.pi, 0): (0, 0), + (np.pi / 4, np.pi / 4): (0, 0), + (np.pi / 4, np.pi / 8): (-np.sqrt(2) / 4, -0.25), + (np.pi / 8, 0): (0, 0), + } # (beta,gamma):(exp_val,corr) # Compute singlet expectation values and correlations for each set of angles for qaoa_angles in qaoa_angles_cases.keys(): - + # Extract correct solution - exp_val = np.round(qaoa_angles_cases[qaoa_angles][0],16) - corr = np.round(qaoa_angles_cases[qaoa_angles][1],16) - + exp_val = np.round(qaoa_angles_cases[qaoa_angles][0], 16) + corr = np.round(qaoa_angles_cases[qaoa_angles][1], 16) + # Compute expectation values and correlations - comp_exp_val = np.round(exp_val_single_analytical(spin,hamiltonian,qaoa_angles),16) - comp_corr = np.round(exp_val_pair_analytical(pair,hamiltonian,qaoa_angles),16) + comp_exp_val = np.round( + exp_val_single_analytical(spin, hamiltonian, qaoa_angles), 16 + ) + comp_corr = np.round( + exp_val_pair_analytical(pair, hamiltonian, qaoa_angles), 16 + ) # Test if computed results are correct - assert np.allclose(exp_val,comp_exp_val), f'Incorrectly computed singlet expectation value' - assert np.allclose(corr,comp_corr), f'Incorrectly computed correlation term' + assert np.allclose( + exp_val, comp_exp_val + ), f"Incorrectly computed singlet expectation value" + assert np.allclose( + corr, comp_corr + ), f"Incorrectly computed correlation term" # Fix a set of angles for testing full set of expectation values and correlations - fixed_angles = [np.pi/4,np.pi/8] + fixed_angles = [np.pi / 4, np.pi / 8] # Correct solutions - exp_val_list = np.array([-np.sqrt(2)/4,np.sqrt(2)/4,-np.sqrt(2)/4,np.sqrt(2)/4]) - corr_matrix = np.array([[0.0,-1/4,0,-1/4],\ - [0.0,0.0,-1/4,0],\ - [0.0,0.0,0.0,-1/4],\ - [0.0,0.0,0.0,0.0]]) - - corr_matrix -= np.outer(exp_val_list,exp_val_list) + exp_val_list = np.array( + [-np.sqrt(2) / 4, np.sqrt(2) / 4, -np.sqrt(2) / 4, np.sqrt(2) / 4] + ) + corr_matrix = np.array( + [ + [0.0, -1 / 4, 0, -1 / 4], + [0.0, 0.0, -1 / 4, 0], + [0.0, 0.0, 0.0, -1 / 4], + [0.0, 0.0, 0.0, 0.0], + ] + ) + + corr_matrix -= np.outer(exp_val_list, exp_val_list) # Compute list of expectation values and correlation matrix - comp_exp_val_list, comp_corr_matrix = exp_val_hamiltonian_termwise(variational_params = None, - qaoa_backend = None, - hamiltonian = hamiltonian, - p = 1, - mixer_type='x', - qaoa_optimized_angles = fixed_angles, - analytical=True) + comp_exp_val_list, comp_corr_matrix = exp_val_hamiltonian_termwise( + variational_params=None, + qaoa_backend=None, + hamiltonian=hamiltonian, + p=1, + mixer_type="x", + qaoa_optimized_angles=fixed_angles, + analytical=True, + ) # Test if computed results are correct - assert np.allclose(exp_val_list,comp_exp_val_list), f'Computed set of singlet expectation values is incorrect' + assert np.allclose( + exp_val_list, comp_exp_val_list + ), f"Computed set of singlet expectation values is incorrect" for j in range(len(comp_corr_matrix)): - assert np.allclose(corr_matrix[j],comp_corr_matrix[j]), f'Computed correlation matrix is incorrect' - + assert np.allclose( + corr_matrix[j], comp_corr_matrix[j] + ), f"Computed correlation matrix is incorrect" + def test_exp_val_hamiltonian_termwise(self): """ Test of the function that computes singlet expectation values and correlations numerically through the QAOA output distribution of states. The test consist of computing the singlet expectation values and correlations for a given problem. - The result is constrasted with the analytical result, whose implementation is tested in + The result is constrasted with the analytical result, whose implementation is tested in test_exp_val_hamiltonian_termwise_analytical(). """ @@ -656,43 +812,72 @@ def test_exp_val_hamiltonian_termwise(self): p = 1 # Terms and weights of the graph - edges = [(i,i+1) for i in range(n_qubits-1)] + [(0,n_qubits-1)] + edges = [(i, i + 1) for i in range(n_qubits - 1)] + [(0, n_qubits - 1)] weights = [10 for _ in range(len(edges))] # Hyperparameters - hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant = 10) + hamiltonian = Hamiltonian.classical_hamiltonian(edges, weights, constant=10) # Mixer Hamiltonian mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) # Define circuit and variational parameters - qaoa_descriptor = QAOADescriptor(hamiltonian,mixer_hamiltonian, p = p) - variational_params = create_qaoa_variational_params(qaoa_descriptor, params_type = 'standard', init_type = 'ramp') + qaoa_descriptor = QAOADescriptor(hamiltonian, mixer_hamiltonian, p=p) + variational_params = create_qaoa_variational_params( + qaoa_descriptor, params_type="standard", init_type="ramp" + ) ## Testing # Perform QAOA and obtain expectation values numerically - qaoa_backend = get_qaoa_backend(qaoa_descriptor, device = DeviceLocal('vectorized')) - optimizer = get_optimizer(qaoa_backend, variational_params, optimizer_dict = {'method':'cobyla','maxiter':200}) + qaoa_backend = get_qaoa_backend( + qaoa_descriptor, device=DeviceLocal("vectorized") + ) + optimizer = get_optimizer( + qaoa_backend, + variational_params, + optimizer_dict={"method": "cobyla", "maxiter": 200}, + ) optimizer() qaoa_results = optimizer.qaoa_result - - qaoa_results_optimized = qaoa_results.optimized - qaoa_optimized_angles = qaoa_results_optimized['angles'] - qaoa_optimized_counts = qaoa_results.get_counts(qaoa_results_optimized['measurement_outcomes']) - num_exp_vals_z, num_corr_matrix = exp_val_hamiltonian_termwise(variational_params, - qaoa_backend, hamiltonian, 'x', p, qaoa_optimized_angles, qaoa_optimized_counts, analytical=False) - # Analytical expectation values - exp_vals_z, corr_matrix = exp_val_hamiltonian_termwise(variational_params, - qaoa_backend, hamiltonian, 'x', p, qaoa_optimized_angles, qaoa_optimized_counts, analytical=True) + qaoa_results_optimized = qaoa_results.optimized + qaoa_optimized_angles = qaoa_results_optimized["angles"] + qaoa_optimized_counts = qaoa_results.get_counts( + qaoa_results_optimized["measurement_outcomes"] + ) + num_exp_vals_z, num_corr_matrix = exp_val_hamiltonian_termwise( + variational_params, + qaoa_backend, + hamiltonian, + "x", + p, + qaoa_optimized_angles, + qaoa_optimized_counts, + analytical=False, + ) + # Analytical expectation values + exp_vals_z, corr_matrix = exp_val_hamiltonian_termwise( + variational_params, + qaoa_backend, + hamiltonian, + "x", + p, + qaoa_optimized_angles, + qaoa_optimized_counts, + analytical=True, + ) # Test if computed results are correct - assert np.allclose(exp_vals_z,num_exp_vals_z), f'Computed singlet expectation values are incorrect' + assert np.allclose( + exp_vals_z, num_exp_vals_z + ), f"Computed singlet expectation values are incorrect" for j in range(len(num_corr_matrix)): - assert np.allclose(corr_matrix[j],num_corr_matrix[j]), f'Computed correlation matrix is incorrect' + assert np.allclose( + corr_matrix[j], num_corr_matrix[j] + ), f"Computed correlation matrix is incorrect" def test_energy_expectation_analytical(self): """ @@ -707,7 +892,7 @@ def test_energy_expectation_analytical(self): n_qubits = 6 # Edges of the graph - edges = [(i,i+1) for i in range(n_qubits-1)] + [(0,n_qubits-1)] + edges = [(i, i + 1) for i in range(n_qubits - 1)] + [(0, n_qubits - 1)] # Define graph and add edges G = nx.Graph() @@ -719,22 +904,38 @@ def test_energy_expectation_analytical(self): mvc = MinimumVertexCover(G, field=field, penalty=penalty).qubo # Minimum Vertex Cover Hamiltonian - hamiltonian = Hamiltonian.classical_hamiltonian(mvc.terms, mvc.weights, mvc.constant) + hamiltonian = Hamiltonian.classical_hamiltonian( + mvc.terms, mvc.weights, mvc.constant + ) # Set of angles on which to compute the energy - angle_set = [(0,0),(np.pi/4,0),(2*np.pi,np.pi),(np.pi/8,np.pi/2)] + angle_set = [(0, 0), (np.pi / 4, 0), (2 * np.pi, np.pi), (np.pi / 8, np.pi / 2)] # Test correct and computed energies for angles in angle_set: - b,g = angles - - correct_energy = n_qubits*(-np.sin(2*b)*np.sin(2*g*field)*np.cos(g*penalty/2) + \ - (1/2)*np.sin(2*b)**2*np.cos(g*penalty/2)**2*(1 - np.cos(2*g*field)) - \ - np.sin(4*b)*np.cos(g*field)*np.sin(g*penalty/2)*np.cos(g*penalty/2) ) + mvc.constant - - energy = energy_expectation_analytical(angles,hamiltonian) - - assert energy == correct_energy, f'Computed energy {energy} is not equal to correct value {correct_energy} for (beta,gamma) = {(b,g)}' + b, g = angles + + correct_energy = ( + n_qubits + * ( + -np.sin(2 * b) * np.sin(2 * g * field) * np.cos(g * penalty / 2) + + (1 / 2) + * np.sin(2 * b) ** 2 + * np.cos(g * penalty / 2) ** 2 + * (1 - np.cos(2 * g * field)) + - np.sin(4 * b) + * np.cos(g * field) + * np.sin(g * penalty / 2) + * np.cos(g * penalty / 2) + ) + + mvc.constant + ) + + energy = energy_expectation_analytical(angles, hamiltonian) + + assert ( + energy == correct_energy + ), f"Computed energy {energy} is not equal to correct value {correct_energy} for (beta,gamma) = {(b,g)}" def test_flip_counts(self): """ @@ -742,22 +943,47 @@ def test_flip_counts(self): The test consists in flipping the keys for a given set of examples dictionaries. """ - + # Input dictionaries - input_dicts = [{'0':2/3, '1':1/3}, {'00':0,'01':0,'10':1/2,'11':1/2}, - {'000':0,'001':1/3,'010':0,'100':0,'011':1/3,'101':0,'110':1/3,'111':0}] + input_dicts = [ + {"0": 2 / 3, "1": 1 / 3}, + {"00": 0, "01": 0, "10": 1 / 2, "11": 1 / 2}, + { + "000": 0, + "001": 1 / 3, + "010": 0, + "100": 0, + "011": 1 / 3, + "101": 0, + "110": 1 / 3, + "111": 0, + }, + ] # Flip the keys of the dictionaries dicts = [flip_counts(input) for input in input_dicts] # Correct dictionaries - correct_dicts = [{'0':2/3, '1':1/3}, {'00':0,'01':1/2,'10':0,'11':1/2}, - {'000':0,'001':0,'010':0,'100':1/3,'011':1/3,'101':0,'110':1/3,'111':0}] - + correct_dicts = [ + {"0": 2 / 3, "1": 1 / 3}, + {"00": 0, "01": 1 / 2, "10": 0, "11": 1 / 2}, + { + "000": 0, + "001": 0, + "010": 0, + "100": 1 / 3, + "011": 1 / 3, + "101": 0, + "110": 1 / 3, + "111": 0, + }, + ] # Test that fictionary keys have been flipped correctly - assert dicts == correct_dicts, f'Dictionary key flipping has not been performed correctly' - + assert ( + dicts == correct_dicts + ), f"Dictionary key flipping has not been performed correctly" + def test_qaoa_probabilities(self): """ Tests the function that generates a qiskit-style probability dictionary from a statevector. @@ -766,23 +992,39 @@ def test_qaoa_probabilities(self): """ # State vectors - state_vecs = [np.array(([np.sqrt(2)/np.sqrt(3),-1j/np.sqrt(3)]),dtype = complex), - np.array(([-1/2,-1/2,1j/2,-1j/2]),dtype = complex), - np.array(([1,0,0,0,0,0,0,0]),dtype = complex)] + state_vecs = [ + np.array(([np.sqrt(2) / np.sqrt(3), -1j / np.sqrt(3)]), dtype=complex), + np.array(([-1 / 2, -1 / 2, 1j / 2, -1j / 2]), dtype=complex), + np.array(([1, 0, 0, 0, 0, 0, 0, 0]), dtype=complex), + ] # Compute probability dictionaries prob_dicts = [qaoa_probabilities(state_vec) for state_vec in state_vecs] - + # Correct probability dictionaries - correct_prob_dicts = [{'0':2/3, '1':1/3}, {'00':1/4,'01':1/4,'10':1/4,'11':1/4}, - {'000':1,'001':0,'010':0,'100':0,'011':0,'101':0,'110':0,'111':0}] + correct_prob_dicts = [ + {"0": 2 / 3, "1": 1 / 3}, + {"00": 1 / 4, "01": 1 / 4, "10": 1 / 4, "11": 1 / 4}, + { + "000": 1, + "001": 0, + "010": 0, + "100": 0, + "011": 0, + "101": 0, + "110": 0, + "111": 0, + }, + ] # Test that each probability dictionary has been generated correctly - for idx,prob_dict in enumerate(prob_dicts): - + for idx, prob_dict in enumerate(prob_dicts): + # Check each string has the same probability associated for string in prob_dict.keys(): - assert np.allclose(prob_dicts[idx][string],correct_prob_dicts[idx][string]), f'Probablity have not been generated correctly' + assert np.allclose( + prob_dicts[idx][string], correct_prob_dicts[idx][string] + ), f"Probablity have not been generated correctly" def test_delete_keys_from_dict(self): """ @@ -790,23 +1032,54 @@ def test_delete_keys_from_dict(self): """ # Input dictionaries - input_dicts = [{'0':2/3, '1':1/3}, {'00':0,'01':0,'10':1/2,'11':1/2}, - {'000':0,'001':1/3,'010':0,'100':0,'011':1/3,'101':0,'110':1/3,'111':0}, - [{'list_0':1/3, 'list_1':1/3}, {'list_0':1/3, 'list_1':1/3}, {'list_0':1/3, 'list_1':1/3, 'list_2':1/3, 'list_3':1/3}]] + input_dicts = [ + {"0": 2 / 3, "1": 1 / 3}, + {"00": 0, "01": 0, "10": 1 / 2, "11": 1 / 2}, + { + "000": 0, + "001": 1 / 3, + "010": 0, + "100": 0, + "011": 1 / 3, + "101": 0, + "110": 1 / 3, + "111": 0, + }, + [ + {"list_0": 1 / 3, "list_1": 1 / 3}, + {"list_0": 1 / 3, "list_1": 1 / 3}, + {"list_0": 1 / 3, "list_1": 1 / 3, "list_2": 1 / 3, "list_3": 1 / 3}, + ], + ] # Keys to be deleted - keys = ['0','00','000', 'list_0'] + keys = ["0", "00", "000", "list_0"] # Delete keys from dictionaries - output_dicts = delete_keys_from_dict(input_dicts,keys) + output_dicts = delete_keys_from_dict(input_dicts, keys) # expected output dictionaries - expected_dicts = [{'1':1/3}, {'01':0,'10':1/2,'11':1/2}, - {'001':1/3,'010':0,'100':0,'011':1/3,'101':0,'110':1/3,'111':0}, - [{'list_1':1/3}, {'list_1':1/3}, {'list_1':1/3, 'list_2':1/3, 'list_3':1/3}]] + expected_dicts = [ + {"1": 1 / 3}, + {"01": 0, "10": 1 / 2, "11": 1 / 2}, + { + "001": 1 / 3, + "010": 0, + "100": 0, + "011": 1 / 3, + "101": 0, + "110": 1 / 3, + "111": 0, + }, + [ + {"list_1": 1 / 3}, + {"list_1": 1 / 3}, + {"list_1": 1 / 3, "list_2": 1 / 3, "list_3": 1 / 3}, + ], + ] # Test that each dictionary has been generated correctly - assert output_dicts == expected_dicts, f'Keys have not been deleted correctly' + assert output_dicts == expected_dicts, f"Keys have not been deleted correctly" def test_convert2serialize(self): """ @@ -826,23 +1099,26 @@ def __init__(self, a, b): self.b = b def _ast(self): - return {'a':self.a,'b':self.b} + return {"a": self.a, "b": self.b} # Create an instance of the class - test_instance = TestClass(a = 1, b = 2) + test_instance = TestClass(a=1, b=2) # Convert the instance into a serializable dictionary serialized_dict = convert2serialize(test_instance) # Expected dictionary - expected_dict = {'a': 1, 'b': 2} + expected_dict = {"a": 1, "b": 2} # Test that the dictionary has been generated correctly - assert serialized_dict == expected_dict, f'Object has not been converted correctly' + assert ( + serialized_dict == expected_dict + ), f"Object has not been converted correctly" # now test with a list of instances, with attributes being list, dictionaries, complex numbers and numpy arrays test_instance_list = [ - TestClass(a = [1,2,3], b = {'x':1,'y':2}), TestClass2(a = np.array([1,2,3]), b = 1+1j) + TestClass(a=[1, 2, 3], b={"x": 1, "y": 2}), + TestClass2(a=np.array([1, 2, 3]), b=1 + 1j), ] # Convert the instance into a serializable dictionary @@ -850,11 +1126,14 @@ def _ast(self): # Expected dictionary expected_dict = [ - {'a': [1,2,3], 'b': {'x':1,'y':2}}, {'a': [1,2,3], 'b': '(1+1j)'} + {"a": [1, 2, 3], "b": {"x": 1, "y": 2}}, + {"a": [1, 2, 3], "b": "(1+1j)"}, ] # Test that the dictionary has been generated correctly - assert serialized_dict == expected_dict, f'Object has not been converted correctly' + assert ( + serialized_dict == expected_dict + ), f"Object has not been converted correctly" def test_function_is_valid_uuid(self): """ @@ -862,8 +1141,12 @@ def test_function_is_valid_uuid(self): """ # Test that the function correctly identifies valid uuids - assert is_valid_uuid('123e4567-e89b-12d3-a456-426655440000'), f'UUID has not been identified correctly' - assert is_valid_uuid('not_a_uuid') == False, f'wrong UUID has not been identified correctly' + assert is_valid_uuid( + "123e4567-e89b-12d3-a456-426655440000" + ), f"UUID has not been identified correctly" + assert ( + is_valid_uuid("not_a_uuid") == False + ), f"wrong UUID has not been identified correctly" def test_generate_uuid(self): """ @@ -874,8 +1157,29 @@ def test_generate_uuid(self): generated_uuid = generate_uuid() # Test that the uuid has been generated correctly - assert is_valid_uuid(generated_uuid), f'UUID has not been generated correctly' + assert is_valid_uuid(generated_uuid), f"UUID has not been generated correctly" + + def test_generate_timestamp(self): + """ + Tests the function that generates a timestamp: generate_timestamp. + It checks if the reutned string is a valid timestamp of format YYYY-MM-DDTHH:MM:SS. + """ + + def is_valid_timestamp(s): + try: + datetime.datetime.strptime(s, "%Y-%m-%dT%H:%M:%S") + return True + except ValueError: + return False + + # Generate a timestamp + generated_timestamp = generate_timestamp() + + # Test that the timestamp has been generated correctly + assert is_valid_timestamp( + generated_timestamp + ), f"Timestamp has not been generated correctly" + - if __name__ == "__main__": - unittest.main() + unittest.main() diff --git a/tests/test_vectorised.py b/tests/test_vectorised.py deleted file mode 100644 index 211abb3d5..000000000 --- a/tests/test_vectorised.py +++ /dev/null @@ -1,694 +0,0 @@ -import unittest -import numpy as np -from scipy.linalg import expm -from scipy.sparse import csc_matrix, kron, diags - -# RX and CHPHASE are never used -from openqaoa.backends.qaoa_vectorized import ( - QAOAvectorizedBackendSimulator, - _permute_qubits, _get_perm, RX -) -from openqaoa.utilities import X_mixer_hamiltonian, ring_of_disagrees -from openqaoa.qaoa_components import ( - QAOAVariationalExtendedParams, - QAOAVariationalStandardParams, Hamiltonian, - PauliOp, QAOADescriptor, create_qaoa_variational_params -) - -###################################################### -# TESTS OF SIMPLE PERMUTATION AND RESHAPING OPERATIONS -###################################################### - - -def Disagrees_SetUp(n_qubits): - """ - Helper function for the tests below - """ - - register = range(n_qubits) - p = 1 - cost_hamil = ring_of_disagrees(register) - mixer_hamil = X_mixer_hamiltonian(n_qubits) - - betas = [np.pi/8] - gammas = [np.pi/4] - - qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p) - variational_params_std = QAOAVariationalStandardParams(qaoa_descriptor, - betas, - gammas) - # Get the part of the Hamiltonian proportional to the identity - - return register, cost_hamil, qaoa_descriptor, variational_params_std - -def pauli_matrix_SetUp(): - """ - Helper function for apply_gate tests. - """ - - constI = csc_matrix(np.eye(2)).toarray() - constX = csc_matrix(np.array([[0,1], [1,0]])).toarray() - constY = csc_matrix(np.array([[0, -1j], [1j, 0]])).toarray() - constZ = csc_matrix(np.array([[1,0], [0,-1]])).toarray() - - return constI, constX, constY, constZ - -def apply_gate_problem_SetUp(): - """ - Helper function for apply_gate tests. - """ - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('Z', (2,))], [1,1], 0) - mixer_hamil = Hamiltonian([PauliOp('X', (0,)), PauliOp('X', (1,)), - PauliOp('X', (2,))], [1,1,1], 0) - theta = 0 # Don't apply mixer and driver unitaries - qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - theta, - theta) - vector_backend = QAOAvectorizedBackendSimulator(qaoa_descriptor, - None, - None, - True) - return cost_hamil.n_qubits, vector_backend - - -class TestingQAOAvectorizedBackend(unittest.TestCase): - """ - Unittest based testing of QAOACostVector - """ - - def test_permute(self): - - nqubits = 3 - - arr = np.arange(2**nqubits) - arr.shape = [2]*nqubits - #reshaped_arr = backend._reshape_qubits(nqubits, arr) - perm = [2, 0, 1] - permuted_arr = _permute_qubits(arr, perm) - - expected_arr = np.array([[[0, 2], [4, 6]], [[1, 3], [5, 7]]]) - - assert np.array_equal(permuted_arr, expected_arr) - - def test_get_perm(self): - - nqubits = 4 - - perm1, perminv1 = _get_perm(nqubits, [1, 3]) - perm2, perminv2 = _get_perm(nqubits, [0, 2]) - - perm1_expected = np.array([2, 0, 1, 3]) - perminv1_expected = np.array([1, 2, 0, 3]) - - perm2_expected = np.array([3, 1, 0, 2]) - perminv2_expected = np.array([2, 1, 3, 0]) - - assert np.array_equal(perm1, perm1_expected) - assert np.array_equal(perminv1, perminv1_expected) - assert np.array_equal(perm2, perm2_expected) - assert np.array_equal(perminv2, perminv2_expected) - - - ########################################################## - # TESTS OF BASIC CIRCUIT OPERATIONS (SAME AS FOR PROJECTQ) - ########################################################## - - def test_qaoa_circuit(self): - - # Test circuit with p = 1 on 3 qubits - # Performs a round of ZZ rotations through pi, and a round of X mixer rotations through pi - nqubits = 3 - register = [i for i in range(nqubits)] - p = 1 - bias_qubits = [] - bias_angles = [] - pairs = [[0, 1], [0, 2], [1, 2]] - weights = [1, 1, 1] - pairs_angles = [np.pi] # [[np.pi]*len(pairs)] - mixer_angles = [np.pi] # [[np.pi]*nqubits] - - cost_hamiltonian = Hamiltonian.classical_hamiltonian( - pairs, weights, constant=0) - mixer_hamiltonian = X_mixer_hamiltonian(nqubits) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalStandardParams(qaoa_descriptor, - mixer_angles, - pairs_angles) - - backend_vectorized = QAOAvectorizedBackendSimulator( - qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True) - - backend_vectorized.qaoa_circuit(variational_params_std) - wf = backend_vectorized.wavefn - wf.shape = 2**nqubits - wf = wf/wf[0] - - expected_wf = np.array([1, 1, 1, 1, 1, 1, 1, 1]) - - assert np.allclose(wf, expected_wf) - - def test_wavefunction_single_terms(self): - - # Test wavefunction and expectation values with hamiltonian object, without 2-qubit terms - cost_hamil = Hamiltonian( - [PauliOp('Z', (0,)), PauliOp('Z', (1,))], [1, 1], 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits=2) - qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - variate_params = create_qaoa_variational_params( - qaoa_descriptor, 'standard', 'ramp') - backend_obj = QAOAvectorizedBackendSimulator( - qaoa_descriptor, None, None, True) - - args = [np.pi/4, np.pi/4] # beta, gamma - variate_params.update_from_raw(args) - - assert np.allclose(backend_obj.wavefunction( - variate_params), [0, 0, 0, 1j]) - assert np.isclose(backend_obj.expectation(variate_params), -1) - - def test_wavefunction(self): - - nqubits = 3 - - # Test circuit with p = 1 on 3 qubits - terms = [[0, 1], [0, 2], [0]] - weights = [1, 1, -0.5] - register = [0, 1, 2] - p = 1 - - betas_singles = [np.pi, 0, 0] - betas_pairs = [] - gammas_singles = [np.pi] - gammas_pairs = [[np.pi/2]*2] - - cost_hamiltonian = Hamiltonian.classical_hamiltonian( - terms, weights, constant=0) - mixer_hamiltonian = X_mixer_hamiltonian(nqubits) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) - variational_params_ext = QAOAVariationalExtendedParams(qaoa_descriptor, - betas_singles, - betas_pairs, - gammas_singles, - gammas_pairs) - - backend_vectorized = QAOAvectorizedBackendSimulator(qaoa_descriptor, prepend_state=None, - append_state=None, init_hadamard=True) - - wf = backend_vectorized.wavefunction(variational_params_ext) - - cost_op1 = diags([-1, 1, 1, -1, -1, 1, 1, -1], 0, format='csc') - cost_op2 = diags([-1, 1, -1, 1, 1, -1, 1, -1], 0, format='csc') - cost_op3 = -1j*diags([-1, 1, -1, 1, -1, 1, -1, 1], 0, format='csc') - - # Factors of 2 needed to produce a rotation for total - mixer = kron(RX(0), kron(RX(0), RX(-2*np.pi))) - # time of pi (pi-pulse) on the Bloch sphere - - input_wf = np.ones(2**nqubits)/np.sqrt(2**nqubits) - direct_wf = -mixer @ cost_op3 @ cost_op2 @ cost_op1 @ input_wf - - expected_wf = -1j*np.array([-1, 1, 1, -1, 1, -1, -1, 1])/(2*np.sqrt(2)) - - assert np.allclose(wf, direct_wf) - assert np.allclose(wf, expected_wf) - - def test_execute_exp_val(self): - - n_qubits = 8 - register, cost_hamil, qaoa_descriptor, variate_params = Disagrees_SetUp( - n_qubits) - - backend_vectorized = QAOAvectorizedBackendSimulator(qaoa_descriptor, prepend_state=None, - append_state=None, init_hadamard=True) - exp_val, std_dev1 = backend_vectorized.expectation_w_uncertainty( - variate_params) - - # Check correct expecation value - assert np.isclose(exp_val, -6) - - # Check standard deviation - # Get the matrix form of the Hamiltonian (note we just keep the diagonal part) and square it - ham_matrix = np.zeros((2**len(register))) - for i, term in enumerate(cost_hamil.terms): - out = np.real(cost_hamil.coeffs[i]) - for qubit in register: - if qubit in term.qubit_indices: - out = np.kron([1, -1], out) - else: - out = np.kron([1, 1], out) - ham_matrix += out - ham_matrix += cost_hamil.constant - - ham_matrix_sq = np.square(ham_matrix) - - # Get the wavefunction - wf = backend_vectorized.wavefunction(variate_params) - - # Get the probabilities - probs = [np.abs(el)**2 for el in wf] - - # Standard deviation - exp_2 = np.dot(probs, ham_matrix) - std_dev2 = np.sqrt(np.dot(probs, ham_matrix_sq) - exp_2**2) - - assert np.isclose(std_dev1, std_dev2) - - def test_cost_call(self): - """ - testing the __call__ method of the base class. - Only for vectorized and Qiskit Local Statevector Backends. - """ - - n_qubits = 8 - register = range(n_qubits) - p = 1 - - betas = [np.pi/8] - gammas = [np.pi/4] - cost_hamiltonian = ring_of_disagrees(register) - mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalStandardParams( - qaoa_descriptor, betas, gammas) - - backend_vectorized = QAOAvectorizedBackendSimulator(qaoa_descriptor, prepend_state=None, - append_state=None, init_hadamard=True) - - exp_vec = backend_vectorized.expectation(variational_params_std) - - assert np.isclose(exp_vec, -6) - - def test_get_wavefunction(self): - - n_qubits = 3 - terms = [[0, 1], [0, 2], [0]] - weights = [1, 1, -0.5] - p = 1 - - betas_singles = [np.pi,0,0] - betas_pairs = [] - gammas_singles = [np.pi] - gammas_pairs = [[1/2*np.pi]*2] - - cost_hamiltonian = Hamiltonian.classical_hamiltonian(terms=terms, coeffs=weights, constant=0) - mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) - qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalExtendedParams(qaoa_descriptor, - betas_singles=betas_singles, - betas_pairs=betas_pairs, - gammas_singles=gammas_singles, - gammas_pairs=gammas_pairs) - - backend_vectorised_statevec = QAOAvectorizedBackendSimulator(qaoa_descriptor,prepend_state=None, - append_state=None,init_hadamard=True) - - wf_vectorised_statevec = backend_vectorised_statevec.wavefunction((variational_params_std)) - expected_wf = 1j*np.array([-1,1,1,-1,1,-1,-1,1])/(2*np.sqrt(2)) - - try: - assert np.allclose(wf_vectorised_statevec, expected_wf) - except AssertionError: - assert np.allclose(np.real(np.conjugate(wf_vectorised_statevec)*wf_vectorised_statevec), - np.conjugate(expected_wf)*expected_wf) - - def test_exact_solution(self): - """ - NOTE:Since the implementation of exact solution is backend agnostic - Checking it once should be okay. - - Nevertheless, for the sake of completeness it will be tested for all backend - instances. - - """ - - n_qubits = 8 - register = range(n_qubits) - p = 1 - - correct_energy = -8 - correct_config = [0, 1, 0, 1, 0, 1, 0, 1] - - # The tests pass regardless of the value of betas and gammas is this correct? - betas = [np.pi/8] - gammas = [np.pi/4] - - cost_hamiltonian = ring_of_disagrees(register) - mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) - - backend_vectorized = QAOAvectorizedBackendSimulator(qaoa_descriptor, prepend_state=None, - append_state=None, init_hadamard=True) - # exact solution is defined as the property of the cost function - energy_vec, config_vec = backend_vectorized.exact_solution - - assert np.isclose(energy_vec, correct_energy) - - config_vec = [config.tolist() for config in config_vec] - - assert correct_config in config_vec - - def test_afunction_throws_exception(self): - # Make sure that exception is raised when Hamiltonian contains nonclassical (non-Z or ZZ terms) - - def test_nonclassical_hamiltonian_error(): - - cost_hamil = Hamiltonian( - [PauliOp('Y', (0,)), PauliOp('Z', (1,))], [1, 1], 1) - mixer_hamil = X_mixer_hamiltonian(n_qubits=2) - qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - variate_params = create_qaoa_variational_params( - qaoa_descriptor, 'standard', 'ramp') - backend_obj = QAOAvectorizedBackendSimulator( - qaoa_descriptor, None, None, True) - - self.assertRaises(Exception, test_nonclassical_hamiltonian_error) - - ########################################################## - # TESTS OF APPLY GATE METHODS - ########################################################## - - def test_apply_rx(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_rx method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_rx(0, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constI, constX)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_ry(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_ry method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_ry(0, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constI, constY)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_rz(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_rz method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_rz(0, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constI, constZ)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_rxx(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_rxx method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_rxx(0, 1, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constX, constX)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_ryy(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_ryy method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_ryy(0, 1, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constY, constY)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_rzz(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_rzz method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_rzz(0, 1, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constZ, constZ)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_rzx(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_rzx method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_rzx(0, 1, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constX, constZ)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_rxz(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_rxz method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_rzx(1, 0, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constZ, constX)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_rxy(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_rxy method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_rxy(0, 1, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constY, constX)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_ryx(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_ryx method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_rxy(1, 0, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constX, constY)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_ryz(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_ryz method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_ryz(0, 1, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constZ, constY)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - def test_apply_rzy(self): - - constI, constX, constY, constZ = pauli_matrix_SetUp() - - # Result from apply_ryz method - angles = [0.1, np.pi/2, np.pi/4] - - for angle in angles: - n_qubits, vector_backend = apply_gate_problem_SetUp() - vector_backend.apply_ryz(1, 0, angle) - - # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constY, constZ)).toarray()*angle*1j/2) - res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - - # ADD TESTS FOR PREPEND AND APPEND STATES BELOW - # def test_with_init_prog_A(self): - - # """ - # Checks the trivial case that when we use a given set of params (params_std) as the - # init_prog followed by a circuit whose angles are zero (new_params), we should get the same as - # if we run the program with no init_prog, but where the angles are given by params_std - # """ - - # n_qubits = 8 - # _,_,_, params_std = Disagrees_SetUp(n_qubits) - - # new_params = copy(params_std) - # new_params.betas = [0] - # new_params.gammas = [0] - - # vector_cost = QAOACostVector(params_std, init_prog=params_std) - # exp_val = vector_cost.execute_exp_val(new_params) - - # # Check correct expecation value - # assert np.isclose(exp_val, -6) - - # def test_with_init_prog_B(self): - - # """ - # Set up a problem with p = 2 and solve directly - # Set up the same problem with an init_prog corresponding to the p=1 params, - # and the program to execute being the p=2 params. - # """ - - # n = 4 - # p = 2 - # register = range(n) - # terms = [[0, 1], [0, 2], [0, 3], [3, 0], [1, 3]] - # weights = [0.1, 1, -0.5, 0.3, 3] - - # # Direct way for p=2 - # hyperparams = HyperParams(terms,weights,p=p) - # stand_params = StandardParams.linear_ramp_from_hamiltonian(hyperparams) - # vector_cost = QAOACostVector(stand_params) - # wf_direct = vector_cost.wavefunction(stand_params) - - # # Indirect way - # init_hyperparams = HyperParams(terms,weights,p=1) - # init_betas = stand_params.betas[0] - # init_gammas = stand_params.gammas[0] - # init_prog = StandardParams(init_hyperparams, (init_betas, init_gammas)) - - # betas_step2 = stand_params.betas[1] - # gammas_step2 = stand_params.gammas[1] - # params_step2 = StandardParams(init_hyperparams,(betas_step2, gammas_step2)) - # vector_cost = QAOACostVector(params_step2, init_prog = init_prog) - # wf_indirect = vector_cost.wavefunction(params_step2) - - # assert np.allclose(wf_direct, wf_indirect) - - # def test_with_init_prog_C(self): - - # """ - # Similar to above, but uses a random example with ExtendedParams - # """ - - # n = 8 - # p = 3 - # reg = range(n) - # terms, weights = zip(*random_hamiltonian(reg).items()) - # terms, weights = list(terms),list(weights) - # hyperparams = HyperParams(terms,weights,p=p) - # abs_params = AbstractParams(hyperparams) - # n_gammas_singles = len(abs_params.qubits_singles) - # n_gammas_pairs = len(abs_params.qubits_pairs) - - # # Direct way - # betas = np.random.rand(p,n) - # gammas_singles = np.random.rand(p,n_gammas_singles) - # gammas_pairs = np.random.rand(p,n_gammas_pairs) - # params = (betas,gammas_singles, gammas_pairs) - # ext_params = ExtendedParams.from_AbstractParameters(abs_params,params) - # vector_cost = QAOACostVector(ext_params) - # wf_direct = vector_cost.wavefunction(ext_params) - - # # Indirect way: pass in the p=2 state as the init_prog to the final step - # init_hyperparams = HyperParams(terms,weights,p=2) - # init_betas = [ext_params.betas[0], ext_params.betas[1]] - # init_gammas_singles = [ext_params.gammas_singles[0], ext_params.gammas_singles[1]] - # init_gammas_pairs = [ext_params.gammas_pairs[0], ext_params.gammas_pairs[1]] - # init_prog = ExtendedParams(init_hyperparams, (init_betas, init_gammas_singles, init_gammas_pairs)) - - # hyperparams3 = HyperParams(terms,weights,p=1) - # betas_step3 = ext_params.betas[2] - # gammas_singles_step3 = ext_params.gammas_singles[2] - # gammas_pairs_step3 = ext_params.gammas_pairs[2] - # params_step3 = ExtendedParams(hyperparams3,(betas_step3, gammas_singles_step3, gammas_pairs_step3)) - # vector_cost = QAOACostVector(params_step3, init_prog = init_prog) - # wf_indirect = vector_cost.wavefunction(params=params_step3) - - # assert np.allclose(wf_direct, wf_indirect) - - -if __name__ == "__main__": - unittest.main() \ No newline at end of file diff --git a/tests/test_vectorized.py b/tests/test_vectorized.py index 211abb3d5..2459ba56b 100644 --- a/tests/test_vectorized.py +++ b/tests/test_vectorized.py @@ -5,14 +5,19 @@ # RX and CHPHASE are never used from openqaoa.backends.qaoa_vectorized import ( - QAOAvectorizedBackendSimulator, - _permute_qubits, _get_perm, RX + QAOAvectorizedBackendSimulator, + _permute_qubits, + _get_perm, + RX, ) from openqaoa.utilities import X_mixer_hamiltonian, ring_of_disagrees from openqaoa.qaoa_components import ( - QAOAVariationalExtendedParams, - QAOAVariationalStandardParams, Hamiltonian, - PauliOp, QAOADescriptor, create_qaoa_variational_params + QAOAVariationalExtendedParams, + QAOAVariationalStandardParams, + Hamiltonian, + PauliOp, + QAOADescriptor, + create_qaoa_variational_params, ) ###################################################### @@ -30,52 +35,50 @@ def Disagrees_SetUp(n_qubits): cost_hamil = ring_of_disagrees(register) mixer_hamil = X_mixer_hamiltonian(n_qubits) - betas = [np.pi/8] - gammas = [np.pi/4] + betas = [np.pi / 8] + gammas = [np.pi / 4] qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p) - variational_params_std = QAOAVariationalStandardParams(qaoa_descriptor, - betas, - gammas) + variational_params_std = QAOAVariationalStandardParams( + qaoa_descriptor, betas, gammas + ) # Get the part of the Hamiltonian proportional to the identity return register, cost_hamil, qaoa_descriptor, variational_params_std + def pauli_matrix_SetUp(): """ Helper function for apply_gate tests. """ - + constI = csc_matrix(np.eye(2)).toarray() - constX = csc_matrix(np.array([[0,1], [1,0]])).toarray() + constX = csc_matrix(np.array([[0, 1], [1, 0]])).toarray() constY = csc_matrix(np.array([[0, -1j], [1j, 0]])).toarray() - constZ = csc_matrix(np.array([[1,0], [0,-1]])).toarray() - + constZ = csc_matrix(np.array([[1, 0], [0, -1]])).toarray() + return constI, constX, constY, constZ + def apply_gate_problem_SetUp(): """ Helper function for apply_gate tests. """ - - cost_hamil = Hamiltonian([PauliOp('ZZ', (0, 1)), PauliOp('Z', (2,))], [1,1], 0) - mixer_hamil = Hamiltonian([PauliOp('X', (0,)), PauliOp('X', (1,)), - PauliOp('X', (2,))], [1,1,1], 0) - theta = 0 # Don't apply mixer and driver unitaries + + cost_hamil = Hamiltonian([PauliOp("ZZ", (0, 1)), PauliOp("Z", (2,))], [1, 1], 0) + mixer_hamil = Hamiltonian( + [PauliOp("X", (0,)), PauliOp("X", (1,)), PauliOp("X", (2,))], [1, 1, 1], 0 + ) + theta = 0 # Don't apply mixer and driver unitaries qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) - variate_params = QAOAVariationalStandardParams(qaoa_descriptor, - theta, - theta) - vector_backend = QAOAvectorizedBackendSimulator(qaoa_descriptor, - None, - None, - True) + variate_params = QAOAVariationalStandardParams(qaoa_descriptor, theta, theta) + vector_backend = QAOAvectorizedBackendSimulator(qaoa_descriptor, None, None, True) return cost_hamil.n_qubits, vector_backend class TestingQAOAvectorizedBackend(unittest.TestCase): """ - Unittest based testing of QAOACostVector + Unittest based testing of QAOACostVector """ def test_permute(self): @@ -83,8 +86,8 @@ def test_permute(self): nqubits = 3 arr = np.arange(2**nqubits) - arr.shape = [2]*nqubits - #reshaped_arr = backend._reshape_qubits(nqubits, arr) + arr.shape = [2] * nqubits + # reshaped_arr = backend._reshape_qubits(nqubits, arr) perm = [2, 0, 1] permuted_arr = _permute_qubits(arr, perm) @@ -110,7 +113,6 @@ def test_get_perm(self): assert np.array_equal(perm2, perm2_expected) assert np.array_equal(perminv2, perminv2_expected) - ########################################################## # TESTS OF BASIC CIRCUIT OPERATIONS (SAME AS FOR PROJECTQ) ########################################################## @@ -129,22 +131,21 @@ def test_qaoa_circuit(self): pairs_angles = [np.pi] # [[np.pi]*len(pairs)] mixer_angles = [np.pi] # [[np.pi]*nqubits] - cost_hamiltonian = Hamiltonian.classical_hamiltonian( - pairs, weights, constant=0) + cost_hamiltonian = Hamiltonian.classical_hamiltonian(pairs, weights, constant=0) mixer_hamiltonian = X_mixer_hamiltonian(nqubits) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalStandardParams(qaoa_descriptor, - mixer_angles, - pairs_angles) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) + variational_params_std = QAOAVariationalStandardParams( + qaoa_descriptor, mixer_angles, pairs_angles + ) backend_vectorized = QAOAvectorizedBackendSimulator( - qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True) + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) backend_vectorized.qaoa_circuit(variational_params_std) wf = backend_vectorized.wavefn wf.shape = 2**nqubits - wf = wf/wf[0] + wf = wf / wf[0] expected_wf = np.array([1, 1, 1, 1, 1, 1, 1, 1]) @@ -153,20 +154,18 @@ def test_qaoa_circuit(self): def test_wavefunction_single_terms(self): # Test wavefunction and expectation values with hamiltonian object, without 2-qubit terms - cost_hamil = Hamiltonian( - [PauliOp('Z', (0,)), PauliOp('Z', (1,))], [1, 1], 1) + cost_hamil = Hamiltonian([PauliOp("Z", (0,)), PauliOp("Z", (1,))], [1, 1], 1) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) variate_params = create_qaoa_variational_params( - qaoa_descriptor, 'standard', 'ramp') - backend_obj = QAOAvectorizedBackendSimulator( - qaoa_descriptor, None, None, True) + qaoa_descriptor, "standard", "ramp" + ) + backend_obj = QAOAvectorizedBackendSimulator(qaoa_descriptor, None, None, True) - args = [np.pi/4, np.pi/4] # beta, gamma + args = [np.pi / 4, np.pi / 4] # beta, gamma variate_params.update_from_raw(args) - assert np.allclose(backend_obj.wavefunction( - variate_params), [0, 0, 0, 1j]) + assert np.allclose(backend_obj.wavefunction(variate_params), [0, 0, 0, 1j]) assert np.isclose(backend_obj.expectation(variate_params), -1) def test_wavefunction(self): @@ -182,57 +181,55 @@ def test_wavefunction(self): betas_singles = [np.pi, 0, 0] betas_pairs = [] gammas_singles = [np.pi] - gammas_pairs = [[np.pi/2]*2] + gammas_pairs = [[np.pi / 2] * 2] - cost_hamiltonian = Hamiltonian.classical_hamiltonian( - terms, weights, constant=0) + cost_hamiltonian = Hamiltonian.classical_hamiltonian(terms, weights, constant=0) mixer_hamiltonian = X_mixer_hamiltonian(nqubits) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) - variational_params_ext = QAOAVariationalExtendedParams(qaoa_descriptor, - betas_singles, - betas_pairs, - gammas_singles, - gammas_pairs) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) + variational_params_ext = QAOAVariationalExtendedParams( + qaoa_descriptor, betas_singles, betas_pairs, gammas_singles, gammas_pairs + ) - backend_vectorized = QAOAvectorizedBackendSimulator(qaoa_descriptor, prepend_state=None, - append_state=None, init_hadamard=True) + backend_vectorized = QAOAvectorizedBackendSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) wf = backend_vectorized.wavefunction(variational_params_ext) - cost_op1 = diags([-1, 1, 1, -1, -1, 1, 1, -1], 0, format='csc') - cost_op2 = diags([-1, 1, -1, 1, 1, -1, 1, -1], 0, format='csc') - cost_op3 = -1j*diags([-1, 1, -1, 1, -1, 1, -1, 1], 0, format='csc') + cost_op1 = diags([-1, 1, 1, -1, -1, 1, 1, -1], 0, format="csc") + cost_op2 = diags([-1, 1, -1, 1, 1, -1, 1, -1], 0, format="csc") + cost_op3 = -1j * diags([-1, 1, -1, 1, -1, 1, -1, 1], 0, format="csc") # Factors of 2 needed to produce a rotation for total - mixer = kron(RX(0), kron(RX(0), RX(-2*np.pi))) + mixer = kron(RX(0), kron(RX(0), RX(-2 * np.pi))) # time of pi (pi-pulse) on the Bloch sphere - input_wf = np.ones(2**nqubits)/np.sqrt(2**nqubits) + input_wf = np.ones(2**nqubits) / np.sqrt(2**nqubits) direct_wf = -mixer @ cost_op3 @ cost_op2 @ cost_op1 @ input_wf - - expected_wf = -1j*np.array([-1, 1, 1, -1, 1, -1, -1, 1])/(2*np.sqrt(2)) - + + expected_wf = -1j * np.array([-1, 1, 1, -1, 1, -1, -1, 1]) / (2 * np.sqrt(2)) + assert np.allclose(wf, direct_wf) assert np.allclose(wf, expected_wf) - + def test_execute_exp_val(self): n_qubits = 8 register, cost_hamil, qaoa_descriptor, variate_params = Disagrees_SetUp( - n_qubits) + n_qubits + ) - backend_vectorized = QAOAvectorizedBackendSimulator(qaoa_descriptor, prepend_state=None, - append_state=None, init_hadamard=True) - exp_val, std_dev1 = backend_vectorized.expectation_w_uncertainty( - variate_params) + backend_vectorized = QAOAvectorizedBackendSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) + exp_val, std_dev1 = backend_vectorized.expectation_w_uncertainty(variate_params) # Check correct expecation value assert np.isclose(exp_val, -6) # Check standard deviation # Get the matrix form of the Hamiltonian (note we just keep the diagonal part) and square it - ham_matrix = np.zeros((2**len(register))) + ham_matrix = np.zeros((2 ** len(register))) for i, term in enumerate(cost_hamil.terms): out = np.real(cost_hamil.coeffs[i]) for qubit in register: @@ -249,7 +246,7 @@ def test_execute_exp_val(self): wf = backend_vectorized.wavefunction(variate_params) # Get the probabilities - probs = [np.abs(el)**2 for el in wf] + probs = [np.abs(el) ** 2 for el in wf] # Standard deviation exp_2 = np.dot(probs, ham_matrix) @@ -267,59 +264,69 @@ def test_cost_call(self): register = range(n_qubits) p = 1 - betas = [np.pi/8] - gammas = [np.pi/4] + betas = [np.pi / 8] + gammas = [np.pi / 4] cost_hamiltonian = ring_of_disagrees(register) mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) variational_params_std = QAOAVariationalStandardParams( - qaoa_descriptor, betas, gammas) + qaoa_descriptor, betas, gammas + ) - backend_vectorized = QAOAvectorizedBackendSimulator(qaoa_descriptor, prepend_state=None, - append_state=None, init_hadamard=True) + backend_vectorized = QAOAvectorizedBackendSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) exp_vec = backend_vectorized.expectation(variational_params_std) assert np.isclose(exp_vec, -6) - + def test_get_wavefunction(self): - + n_qubits = 3 terms = [[0, 1], [0, 2], [0]] weights = [1, 1, -0.5] p = 1 - - betas_singles = [np.pi,0,0] + + betas_singles = [np.pi, 0, 0] betas_pairs = [] gammas_singles = [np.pi] - gammas_pairs = [[1/2*np.pi]*2] - - cost_hamiltonian = Hamiltonian.classical_hamiltonian(terms=terms, coeffs=weights, constant=0) + gammas_pairs = [[1 / 2 * np.pi] * 2] + + cost_hamiltonian = Hamiltonian.classical_hamiltonian( + terms=terms, coeffs=weights, constant=0 + ) mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalExtendedParams(qaoa_descriptor, - betas_singles=betas_singles, - betas_pairs=betas_pairs, - gammas_singles=gammas_singles, - gammas_pairs=gammas_pairs) - - backend_vectorised_statevec = QAOAvectorizedBackendSimulator(qaoa_descriptor,prepend_state=None, - append_state=None,init_hadamard=True) - - wf_vectorised_statevec = backend_vectorised_statevec.wavefunction((variational_params_std)) - expected_wf = 1j*np.array([-1,1,1,-1,1,-1,-1,1])/(2*np.sqrt(2)) - + variational_params_std = QAOAVariationalExtendedParams( + qaoa_descriptor, + betas_singles=betas_singles, + betas_pairs=betas_pairs, + gammas_singles=gammas_singles, + gammas_pairs=gammas_pairs, + ) + + backend_vectorised_statevec = QAOAvectorizedBackendSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) + + wf_vectorised_statevec = backend_vectorised_statevec.wavefunction( + (variational_params_std) + ) + expected_wf = 1j * np.array([-1, 1, 1, -1, 1, -1, -1, 1]) / (2 * np.sqrt(2)) + try: assert np.allclose(wf_vectorised_statevec, expected_wf) except AssertionError: - assert np.allclose(np.real(np.conjugate(wf_vectorised_statevec)*wf_vectorised_statevec), - np.conjugate(expected_wf)*expected_wf) - + assert np.allclose( + np.real(np.conjugate(wf_vectorised_statevec) * wf_vectorised_statevec), + np.conjugate(expected_wf) * expected_wf, + ) + def test_exact_solution(self): """ NOTE:Since the implementation of exact solution is backend agnostic - Checking it once should be okay. + Checking it once should be okay. Nevertheless, for the sake of completeness it will be tested for all backend instances. @@ -334,18 +341,19 @@ def test_exact_solution(self): correct_config = [0, 1, 0, 1, 0, 1, 0, 1] # The tests pass regardless of the value of betas and gammas is this correct? - betas = [np.pi/8] - gammas = [np.pi/4] + betas = [np.pi / 8] + gammas = [np.pi / 4] cost_hamiltonian = ring_of_disagrees(register) mixer_hamiltonian = X_mixer_hamiltonian(n_qubits) - qaoa_descriptor = QAOADescriptor( - cost_hamiltonian, mixer_hamiltonian, p) - variational_params_std = QAOAVariationalStandardParams(qaoa_descriptor, - betas, gammas) + qaoa_descriptor = QAOADescriptor(cost_hamiltonian, mixer_hamiltonian, p) + variational_params_std = QAOAVariationalStandardParams( + qaoa_descriptor, betas, gammas + ) - backend_vectorized = QAOAvectorizedBackendSimulator(qaoa_descriptor, prepend_state=None, - append_state=None, init_hadamard=True) + backend_vectorized = QAOAvectorizedBackendSimulator( + qaoa_descriptor, prepend_state=None, append_state=None, init_hadamard=True + ) # exact solution is defined as the property of the cost function energy_vec, config_vec = backend_vectorized.exact_solution @@ -354,242 +362,293 @@ def test_exact_solution(self): config_vec = [config.tolist() for config in config_vec] assert correct_config in config_vec - + def test_afunction_throws_exception(self): # Make sure that exception is raised when Hamiltonian contains nonclassical (non-Z or ZZ terms) - + def test_nonclassical_hamiltonian_error(): cost_hamil = Hamiltonian( - [PauliOp('Y', (0,)), PauliOp('Z', (1,))], [1, 1], 1) + [PauliOp("Y", (0,)), PauliOp("Z", (1,))], [1, 1], 1 + ) mixer_hamil = X_mixer_hamiltonian(n_qubits=2) qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1) variate_params = create_qaoa_variational_params( - qaoa_descriptor, 'standard', 'ramp') + qaoa_descriptor, "standard", "ramp" + ) backend_obj = QAOAvectorizedBackendSimulator( - qaoa_descriptor, None, None, True) - + qaoa_descriptor, None, None, True + ) + self.assertRaises(Exception, test_nonclassical_hamiltonian_error) - + ########################################################## # TESTS OF APPLY GATE METHODS ########################################################## def test_apply_rx(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_rx method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_rx(0, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constI, constX)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constI, constX)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_ry(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_ry method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_ry(0, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constI, constY)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constI, constY)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_rz(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_rz method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_rz(0, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constI, constZ)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constI, constZ)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_rxx(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_rxx method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_rxx(0, 1, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constX, constX)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constX, constX)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_ryy(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_ryy method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_ryy(0, 1, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constY, constY)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constY, constY)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_rzz(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_rzz method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_rzz(0, 1, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constZ, constZ)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constZ, constZ)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_rzx(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_rzx method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_rzx(0, 1, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constX, constZ)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constX, constZ)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_rxz(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_rxz method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_rzx(1, 0, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constZ, constX)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constZ, constX)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_rxy(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_rxy method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_rxy(0, 1, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constY, constX)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constY, constX)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_ryx(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_ryx method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_rxy(1, 0, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constX, constY)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constX, constY)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_ryz(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_ryz method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_ryz(0, 1, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constZ, constY)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constZ, constY)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" - + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + def test_apply_rzy(self): - + constI, constX, constY, constZ = pauli_matrix_SetUp() # Result from apply_ryz method - angles = [0.1, np.pi/2, np.pi/4] - + angles = [0.1, np.pi / 2, np.pi / 4] + for angle in angles: n_qubits, vector_backend = apply_gate_problem_SetUp() vector_backend.apply_ryz(1, 0, angle) # Result from matrix multiply exponentiated gate - wavefn = np.ones((2**n_qubits,),dtype=complex)/np.sqrt(2**n_qubits) - unitary = expm(-kron(constI, kron(constY, constZ)).toarray()*angle*1j/2) + wavefn = np.ones((2**n_qubits,), dtype=complex) / np.sqrt(2**n_qubits) + unitary = expm( + -kron(constI, kron(constY, constZ)).toarray() * angle * 1j / 2 + ) res_wfn = np.matmul(unitary, wavefn).reshape([2] * n_qubits) - assert np.allclose(vector_backend.wavefn, res_wfn), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" + assert np.allclose( + vector_backend.wavefn, res_wfn + ), f"angle = {angle} failed, {vector_backend.wavefn} != {res_wfn}" # ADD TESTS FOR PREPEND AND APPEND STATES BELOW # def test_with_init_prog_A(self): @@ -691,4 +750,4 @@ def test_apply_rzy(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/tests/test_workflows.py b/tests/test_workflows.py index c8d93e9f5..061c1df34 100644 --- a/tests/test_workflows.py +++ b/tests/test_workflows.py @@ -2,6 +2,7 @@ import unittest import networkx as nw import numpy as np +import datetime from qiskit.providers.fake_provider import FakeVigo from qiskit.providers.aer.noise import NoiseModel @@ -10,42 +11,45 @@ from openqaoa import QAOA, RQAOA from openqaoa.algorithms import QAOAResult, RQAOAResult from openqaoa.algorithms.baseworkflow import Workflow -from openqaoa.utilities import ( - X_mixer_hamiltonian, - XY_mixer_hamiltonian, - is_valid_uuid -) +from openqaoa.utilities import X_mixer_hamiltonian, XY_mixer_hamiltonian, is_valid_uuid from openqaoa.algorithms.workflow_properties import ( - BackendProperties, ClassicalOptimizer, CircuitProperties + BackendProperties, + ClassicalOptimizer, + CircuitProperties, ) from openqaoa.algorithms.rqaoa.rqaoa_workflow_properties import RqaoaParameters from openqaoa.backends import create_device, DeviceLocal from openqaoa.backends.devices_core import SUPPORTED_LOCAL_SIMULATORS from openqaoa.qaoa_components import ( - Hamiltonian, QAOADescriptor, QAOAVariationalStandardParams, - QAOAVariationalStandardWithBiasParams, QAOAVariationalExtendedParams, - QAOAVariationalFourierParams, QAOAVariationalFourierExtendedParams, - QAOAVariationalFourierWithBiasParams + Hamiltonian, + QAOADescriptor, + QAOAVariationalStandardParams, + QAOAVariationalStandardWithBiasParams, + QAOAVariationalExtendedParams, + QAOAVariationalFourierParams, + QAOAVariationalFourierExtendedParams, + QAOAVariationalFourierWithBiasParams, ) from openqaoa.backends import QAOAvectorizedBackendSimulator from openqaoa.backends.basebackend import QAOABaseBackendStatevector from openqaoa.problems import MinimumVertexCover, QUBO, MaximumCut from openqaoa.optimizers.qaoa_optimizer import available_optimizers from openqaoa.optimizers.training_vqa import ( - ScipyOptimizer, CustomScipyGradientOptimizer, - PennyLaneOptimizer + ScipyOptimizer, + CustomScipyGradientOptimizer, + PennyLaneOptimizer, ) from openqaoa_pyquil.backends import DevicePyquil from openqaoa_pyquil.backends import QAOAPyQuilWavefunctionSimulatorBackend from openqaoa_qiskit.backends import DeviceQiskit from openqaoa_qiskit.backends import ( QAOAQiskitBackendShotBasedSimulator, - QAOAQiskitBackendStatevecSimulator + QAOAQiskitBackendStatevecSimulator, ) ALLOWED_LOCAL_SIMUALTORS = SUPPORTED_LOCAL_SIMULATORS -LOCAL_DEVICES = ALLOWED_LOCAL_SIMUALTORS + ['6q-qvm', 'Aspen-11'] +LOCAL_DEVICES = ALLOWED_LOCAL_SIMUALTORS + ["6q-qvm", "Aspen-11"] def _compare_qaoa_results(dict_old, dict_new): @@ -53,26 +57,37 @@ def _compare_qaoa_results(dict_old, dict_new): for key in dict_old.keys(): if key == "cost_hamiltonian": ## CHECK WHAT DO WITH THIS pass - elif key == "_QAOAResult__type_backend": + elif key == "_QAOAResult__type_backend": if issubclass(dict_old[key], QAOABaseBackendStatevector): - assert dict_new[key] == QAOABaseBackendStatevector, "Type of backend is not correct." + assert ( + dict_new[key] == QAOABaseBackendStatevector + ), "Type of backend is not correct." else: assert dict_new[key] == "", "Type of backend should be empty string." elif key == "optimized": for key2 in dict_old[key].keys(): if key2 == "measurement_outcomes": - assert np.all(dict_old[key][key2] == dict_new[key][key2]), "Optimized params are not the same." + assert np.all( + dict_old[key][key2] == dict_new[key][key2] + ), "Optimized params are not the same." else: - assert dict_old[key][key2] == dict_new[key][key2], "Optimized params are not the same." + assert ( + dict_old[key][key2] == dict_new[key][key2] + ), "Optimized params are not the same." elif key == "intermediate": for key2 in dict_old[key].keys(): if key2 == "measurement_outcomes": for step in range(len(dict_old[key][key2])): - assert np.all(dict_old[key][key2][step] == dict_new[key][key2][step]), "Intermediate params are not the same." + assert np.all( + dict_old[key][key2][step] == dict_new[key][key2][step] + ), "Intermediate params are not the same." else: - assert dict_old[key][key2] == dict_new[key][key2], "Intermediate params are not the same." + assert ( + dict_old[key][key2] == dict_new[key][key2] + ), "Intermediate params are not the same." else: - assert dict_old[key] == dict_new[key], f"{key} is not the same" + assert dict_old[key] == dict_new[key], f"'{key}' is not the same" + def _test_keys_in_dict(obj, expected_keys): """ @@ -81,7 +96,8 @@ def _test_keys_in_dict(obj, expected_keys): if isinstance(obj, dict): for key in obj: - if key in expected_keys.keys(): expected_keys[key] = True + if key in expected_keys.keys(): + expected_keys[key] = True if isinstance(obj[key], dict): _test_keys_in_dict(obj[key], expected_keys) @@ -100,582 +116,638 @@ class TestingVanillaQAOA(unittest.TestCase): """ def test_vanilla_qaoa_default_values(self): - + q = QAOA() assert q.circuit_properties.p == 1 - assert q.circuit_properties.param_type == 'standard' - assert q.circuit_properties.init_type == 'ramp' - assert q.device.device_location == 'local' - assert q.device.device_name == 'vectorized' + assert q.circuit_properties.param_type == "standard" + assert q.circuit_properties.init_type == "ramp" + assert q.device.device_location == "local" + assert q.device.device_name == "vectorized" def test_end_to_end_vectorized(self): - + g = nw.circulant_graph(6, [1]) - vc = MinimumVertexCover(g, field =1.0, penalty=10).qubo + vc = MinimumVertexCover(g, field=1.0, penalty=10).qubo q = QAOA() - q.set_classical_optimizer(optimization_progress = True) + q.set_classical_optimizer(optimization_progress=True) q.compile(vc) q.optimize() - result = q.result.most_probable_states['solutions_bitstrings'][0] - assert '010101' == result or '101010' == result + result = q.result.most_probable_states["solutions_bitstrings"][0] + assert "010101" == result or "101010" == result def test_set_device_local(self): - """" + """ " Check that all local devices are correctly initialised """ q = QAOA() for d in q.local_simulators: - q.set_device(create_device(location='local', name=d)) + q.set_device(create_device(location="local", name=d)) assert type(q.device) == DeviceLocal assert q.device.device_name == d - assert q.device.device_location == 'local' + assert q.device.device_location == "local" def test_set_device_cloud(self): - """" + """ " Check that all QPU-provider related devices are correctly initialised """ q = QAOA() - q.set_device(create_device('qcs', - name='6q-qvm', - **{'as_qvm':True, 'execution_timeout' : 10, 'compiler_timeout':10})) + q.set_device( + create_device( + "qcs", + name="6q-qvm", + **{"as_qvm": True, "execution_timeout": 10, "compiler_timeout": 10}, + ) + ) assert type(q.device) == DevicePyquil - assert q.device.device_name == '6q-qvm' - assert q.device.device_location == 'qcs' - - - q.set_device(create_device('ibmq', - name='place_holder', - **{"hub": "***", - "group": "***", - "project": "***"})) + assert q.device.device_name == "6q-qvm" + assert q.device.device_location == "qcs" + + q.set_device( + create_device( + "ibmq", + name="place_holder", + **{"hub": "***", "group": "***", "project": "***"}, + ) + ) assert type(q.device) == DeviceQiskit - assert q.device.device_name == 'place_holder' - assert q.device.device_location == 'ibmq' + assert q.device.device_name == "place_holder" + assert q.device.device_location == "ibmq" def test_compile_before_optimise(self): """ Assert that compilation has to be called before optimisation - """ + """ g = nw.circulant_graph(6, [1]) # vc = MinimumVertexCover(g, field =1.0, penalty=10).qubo q = QAOA() - q.set_classical_optimizer(optimization_progress = True) + q.set_classical_optimizer(optimization_progress=True) self.assertRaises(ValueError, lambda: q.optimize()) - + def test_cost_hamil(self): - + g = nw.circulant_graph(6, [1]) - problem = MinimumVertexCover(g, field =1.0, penalty=10) + problem = MinimumVertexCover(g, field=1.0, penalty=10) qubo_problem = problem.qubo - - test_hamil = Hamiltonian.classical_hamiltonian(terms = qubo_problem.terms, - coeffs = qubo_problem.weights, - constant = qubo_problem.constant) + + test_hamil = Hamiltonian.classical_hamiltonian( + terms=qubo_problem.terms, + coeffs=qubo_problem.weights, + constant=qubo_problem.constant, + ) q = QAOA() - - q.compile(problem = qubo_problem) - + + q.compile(problem=qubo_problem) + self.assertEqual(q.cost_hamil.expression, test_hamil.expression) - self.assertEqual(q.qaoa_descriptor.cost_hamiltonian.expression, - test_hamil.expression) - + self.assertEqual( + q.qaoa_descriptor.cost_hamiltonian.expression, test_hamil.expression + ) + def test_set_circuit_properties_fourier_q(self): - + """ The value of q should be None if the param_type used is not fourier. Else if param_type is fourier, fourier_extended or fourier_w_bias, it should be the value of q, if it is provided. """ - - fourier_param_types = ['fourier', 'fourier_extended', 'fourier_w_bias'] - + + fourier_param_types = ["fourier", "fourier_extended", "fourier_w_bias"] + q = QAOA() - + for each_param_type in fourier_param_types: - q.set_circuit_properties(param_type = each_param_type, q = 1) + q.set_circuit_properties(param_type=each_param_type, q=1) self.assertEqual(q.circuit_properties.q, 1) - - q.set_circuit_properties(param_type = "standard", q = 1) - + + q.set_circuit_properties(param_type="standard", q=1) + self.assertEqual(q.circuit_properties.q, None) - + def test_set_circuit_properties_annealing_time_linear_ramp_time(self): - + """ - Check that linear_ramp_time and annealing_time are updated appropriately - as the value of p is changed. + Check that linear_ramp_time and annealing_time are updated appropriately + as the value of p is changed. """ - + q = QAOA() - + q.set_circuit_properties(p=3) - - self.assertEqual(q.circuit_properties.annealing_time, 0.7*3) - self.assertEqual(q.circuit_properties.linear_ramp_time, 0.7*3) - + + self.assertEqual(q.circuit_properties.annealing_time, 0.7 * 3) + self.assertEqual(q.circuit_properties.linear_ramp_time, 0.7 * 3) + q.set_circuit_properties(p=2) - - self.assertEqual(q.circuit_properties.annealing_time, 0.7*2) - self.assertEqual(q.circuit_properties.linear_ramp_time, 0.7*2) - - + + self.assertEqual(q.circuit_properties.annealing_time, 0.7 * 2) + self.assertEqual(q.circuit_properties.linear_ramp_time, 0.7 * 2) + def test_set_circuit_properties_qaoa_descriptor_mixer_x(self): - + """ Checks if the X mixer created by the X_mixer_hamiltonian method and the automated methods in workflows do the same thing. - + For each qubit, there should be 1 RXGateMap per layer of p. """ - + nodes = 6 edge_probability = 0.6 - g = nw.generators.fast_gnp_random_graph(n=nodes,p=edge_probability) - problem = MinimumVertexCover(g, field =1.0, penalty=10) + g = nw.generators.fast_gnp_random_graph(n=nodes, p=edge_probability) + problem = MinimumVertexCover(g, field=1.0, penalty=10) q = QAOA() - q.set_circuit_properties(mixer_hamiltonian = 'x', p = 2) + q.set_circuit_properties(mixer_hamiltonian="x", p=2) - q.compile(problem = problem.qubo) + q.compile(problem=problem.qubo) self.assertEqual(type(q.qaoa_descriptor), QAOADescriptor) self.assertEqual(q.qaoa_descriptor.p, 2) - mixer_hamil = X_mixer_hamiltonian(n_qubits = nodes) + mixer_hamil = X_mixer_hamiltonian(n_qubits=nodes) self.assertEqual(q.mixer_hamil.expression, mixer_hamil.expression) - + self.assertEqual(len(q.qaoa_descriptor.mixer_qubits_singles), 6) self.assertEqual(len(q.qaoa_descriptor.mixer_qubits_pairs), 0) - for each_gatemap_name in q.qaoa_descriptor.mixer_qubits_singles: - self.assertEqual(each_gatemap_name, 'RXGateMap') + for each_gatemap_name in q.qaoa_descriptor.mixer_qubits_singles: + self.assertEqual(each_gatemap_name, "RXGateMap") for j in range(2): for i in range(6): - self.assertEqual(q.qaoa_descriptor.mixer_block[j][i].qubit_1, i) + self.assertEqual(q.qaoa_descriptor.mixer_blocks[j][i].qubit_1, i) def test_set_circuit_properties_qaoa_descriptor_mixer_xy(self): - + """ Checks if the XY mixer created by the XY_mixer_hamiltonian method and the automated methods in workflows do the same thing. - + Depending on the qubit connectivity selected. (chain, full or star) For each pair of connected qubits, there should be 1 RXXGateMap and RYYGateMap per layer of p. """ - + g_c = nw.circulant_graph(6, [1]) g_f = nw.complete_graph(6) # A 5-sided star graoh requires 6 qubit. (Center Qubit of the pattern) g_s = nw.star_graph(5) - problems = [MinimumVertexCover(g_c, field =1.0, penalty=10), - MinimumVertexCover(g_f, field =1.0, penalty=10), - MinimumVertexCover(g_s, field =1.0, penalty=10)] - qubit_connectivity_name = ['chain', 'full', 'star'] - + problems = [ + MinimumVertexCover(g_c, field=1.0, penalty=10), + MinimumVertexCover(g_f, field=1.0, penalty=10), + MinimumVertexCover(g_s, field=1.0, penalty=10), + ] + qubit_connectivity_name = ["chain", "full", "star"] + for i in range(3): q = QAOA() - q.set_circuit_properties(mixer_hamiltonian = 'xy', - mixer_qubit_connectivity = qubit_connectivity_name[i], - p = 2) + q.set_circuit_properties( + mixer_hamiltonian="xy", + mixer_qubit_connectivity=qubit_connectivity_name[i], + p=2, + ) - q.compile(problem = problems[i].qubo) + q.compile(problem=problems[i].qubo) self.assertEqual(type(q.qaoa_descriptor), QAOADescriptor) self.assertEqual(q.qaoa_descriptor.p, 2) - mixer_hamil = XY_mixer_hamiltonian(n_qubits = 6, qubit_connectivity = qubit_connectivity_name[i]) - + mixer_hamil = XY_mixer_hamiltonian( + n_qubits=6, qubit_connectivity=qubit_connectivity_name[i] + ) + self.assertEqual(q.mixer_hamil.expression, mixer_hamil.expression) - + self.assertEqual(len(q.qaoa_descriptor.mixer_qubits_singles), 0) for i in range(0, len(q.qaoa_descriptor.mixer_qubits_pairs), 2): - self.assertEqual(q.qaoa_descriptor.mixer_qubits_pairs[i], 'RXXGateMap') - self.assertEqual(q.qaoa_descriptor.mixer_qubits_pairs[i+1], 'RYYGateMap') - + self.assertEqual(q.qaoa_descriptor.mixer_qubits_pairs[i], "RXXGateMap") + self.assertEqual( + q.qaoa_descriptor.mixer_qubits_pairs[i + 1], "RYYGateMap" + ) + def test_set_circuit_properties_variate_params(self): - + """ Ensure that the Varitional Parameter Object created based on the input string , param_type, is correct. - + TODO: Check if q=None is the appropriate default. """ - - param_type_names = ['standard', 'standard_w_bias', 'extended', - 'fourier', 'fourier_extended', 'fourier_w_bias'] - object_types = [QAOAVariationalStandardParams, - QAOAVariationalStandardWithBiasParams, - QAOAVariationalExtendedParams, QAOAVariationalFourierParams, - QAOAVariationalFourierExtendedParams, - QAOAVariationalFourierWithBiasParams] - + + param_type_names = [ + "standard", + "standard_w_bias", + "extended", + "fourier", + "fourier_extended", + "fourier_w_bias", + ] + object_types = [ + QAOAVariationalStandardParams, + QAOAVariationalStandardWithBiasParams, + QAOAVariationalExtendedParams, + QAOAVariationalFourierParams, + QAOAVariationalFourierExtendedParams, + QAOAVariationalFourierWithBiasParams, + ] + nodes = 6 edge_probability = 0.6 - g = nw.generators.fast_gnp_random_graph(n=nodes,p=edge_probability) - problem = MinimumVertexCover(g, field =1.0, penalty=10) - + g = nw.generators.fast_gnp_random_graph(n=nodes, p=edge_probability) + problem = MinimumVertexCover(g, field=1.0, penalty=10) + for i in range(len(object_types)): q = QAOA() - q.set_circuit_properties(param_type = param_type_names[i], q=1) + q.set_circuit_properties(param_type=param_type_names[i], q=1) + + q.compile(problem=problem.qubo) - q.compile(problem = problem.qubo) - self.assertEqual(type(q.variate_params), object_types[i]) - + def test_set_circuit_properties_change(self): - + """ Ensure that once a property has beefn changed via set_circuit_properties. - The attribute has been appropriately updated. + The attribute has been appropriately updated. Updating all attributes at the same time. """ - -# default_pairings = {'param_type': 'standard', -# 'init_type': 'ramp', -# 'qubit_register': [], -# 'p': 1, -# 'q': None, -# 'annealing_time': 0.7, -# 'linear_ramp_time': 0.7, -# 'variational_params_dict': {}, -# 'mixer_hamiltonian': 'x', -# 'mixer_qubit_connectivity': None, -# 'mixer_coeffs': None, -# 'seed': None} - + + # default_pairings = {'param_type': 'standard', + # 'init_type': 'ramp', + # 'qubit_register': [], + # 'p': 1, + # 'q': None, + # 'annealing_time': 0.7, + # 'linear_ramp_time': 0.7, + # 'variational_params_dict': {}, + # 'mixer_hamiltonian': 'x', + # 'mixer_qubit_connectivity': None, + # 'mixer_coeffs': None, + # 'seed': None} + q = QAOA() # TODO: Some weird error related to the initialisation of QAOA here -# for each_key, each_value in default_pairings.items(): -# print(each_key, getattr(q.circuit_properties, each_key), each_value) -# self.assertEqual(getattr(q.circuit_properties, each_key), each_value) - - update_pairings = {'param_type': 'fourier', - 'init_type': 'rand', - 'qubit_register': [0, 1], - 'p': 2, - 'q': 2, - 'annealing_time': 1.0, - 'linear_ramp_time': 1.0, - 'variational_params_dict': {'key': 'value'}, - 'mixer_hamiltonian': 'xy', - 'mixer_qubit_connectivity': 'chain', - 'mixer_coeffs': [0.1, 0.2], - 'seed': 45} - + # for each_key, each_value in default_pairings.items(): + # print(each_key, getattr(q.circuit_properties, each_key), each_value) + # self.assertEqual(getattr(q.circuit_properties, each_key), each_value) + + update_pairings = { + "param_type": "fourier", + "init_type": "rand", + "qubit_register": [0, 1], + "p": 2, + "q": 2, + "annealing_time": 1.0, + "linear_ramp_time": 1.0, + "variational_params_dict": {"key": "value"}, + "mixer_hamiltonian": "xy", + "mixer_qubit_connectivity": "chain", + "mixer_coeffs": [0.1, 0.2], + "seed": 45, + } + q.set_circuit_properties(**update_pairings) - + for each_key, each_value in update_pairings.items(): self.assertEqual(getattr(q.circuit_properties, each_key), each_value) - + def test_set_circuit_properties_rejected_values(self): - + """ - Some properties of CircuitProperties Object return a ValueError if the specified property has not been whitelisted in the code. + Some properties of CircuitProperties Object return a ValueError if the specified property has not been whitelisted in the code. This checks that the ValueError is raised if the argument is not whitelisted. """ - + q = QAOA() - - self.assertRaises(ValueError, lambda: q.set_circuit_properties(param_type = 'wrong name')) - self.assertRaises(ValueError, lambda: q.set_circuit_properties(init_type = 'wrong name')) - self.assertRaises(ValueError, lambda: q.set_circuit_properties(mixer_hamiltonian = 'wrong name')) - self.assertRaises(ValueError, lambda: q.set_circuit_properties(p = -1)) - + + self.assertRaises( + ValueError, lambda: q.set_circuit_properties(param_type="wrong name") + ) + self.assertRaises( + ValueError, lambda: q.set_circuit_properties(init_type="wrong name") + ) + self.assertRaises( + ValueError, lambda: q.set_circuit_properties(mixer_hamiltonian="wrong name") + ) + self.assertRaises(ValueError, lambda: q.set_circuit_properties(p=-1)) + def test_set_backend_properties_change(self): - + """ Ensure that once a property has been changed via set_backend_properties. The attribute has been appropriately updated. Updating all attributes at the same time. """ - - default_pairings = {'prepend_state': None, - 'append_state': None, - 'init_hadamard': True, - 'n_shots': 100, - 'cvar_alpha': 1.} - + + default_pairings = { + "prepend_state": None, + "append_state": None, + "init_hadamard": True, + "n_shots": 100, + "cvar_alpha": 1.0, + } + q = QAOA() - + for each_key, each_value in default_pairings.items(): self.assertEqual(getattr(q.backend_properties, each_key), each_value) - - update_pairings = {'prepend_state': [[0, 0]], - 'append_state': [[0, 0]], - 'init_hadamard': False, - 'n_shots': 10, - 'cvar_alpha': .5} - + + update_pairings = { + "prepend_state": [[0, 0]], + "append_state": [[0, 0]], + "init_hadamard": False, + "n_shots": 10, + "cvar_alpha": 0.5, + } + q.set_backend_properties(**update_pairings) - + for each_key, each_value in update_pairings.items(): self.assertEqual(getattr(q.backend_properties, each_key), each_value) - + def test_set_backend_properties_check_backend_vectorized(self): - + """ Check if the backend returned by set_backend_properties is correct Based on the input device. Also Checks if defaults from workflows are used in the backend. """ - + nodes = 6 edge_probability = 0.6 - g = nw.generators.fast_gnp_random_graph(n=nodes,p=edge_probability) - problem = MinimumVertexCover(g, field =1.0, penalty=10) + g = nw.generators.fast_gnp_random_graph(n=nodes, p=edge_probability) + problem = MinimumVertexCover(g, field=1.0, penalty=10) qubo_problem = problem.qubo - + q = QAOA() - q.set_device(create_device(location = 'local', name = 'vectorized')) - q.compile(problem = qubo_problem) - + q.set_device(create_device(location="local", name="vectorized")) + q.compile(problem=qubo_problem) + self.assertEqual(type(q.backend), QAOAvectorizedBackendSimulator) - + self.assertEqual(q.backend.init_hadamard, True) self.assertEqual(q.backend.prepend_state, None) self.assertEqual(q.backend.append_state, None) self.assertEqual(q.backend.cvar_alpha, 1) - + self.assertRaises(AttributeError, lambda: q.backend.n_shots) - + def test_set_backend_properties_check_backend_vectorized_w_custom(self): - + """ Check if the backend returned by set_backend_properties is correct Based on the input device. Uses custom values for attributes in backend_properties and checks if the backend object responds appropriately. """ - + nodes = 3 edge_probability = 0.6 - g = nw.generators.fast_gnp_random_graph(n=nodes,p=edge_probability) - problem = MinimumVertexCover(g, field =1.0, penalty=10) + g = nw.generators.fast_gnp_random_graph(n=nodes, p=edge_probability) + problem = MinimumVertexCover(g, field=1.0, penalty=10) qubo_problem = problem.qubo - + q = QAOA() - q.set_device(create_device(location = 'local', name = 'vectorized')) - + q.set_device(create_device(location="local", name="vectorized")) + prepend_state_rand = np.random.rand(2**3) append_state_rand = np.eye(2**3) - - update_pairings = {'prepend_state': prepend_state_rand, - 'append_state': append_state_rand, - 'init_hadamard': False, - 'n_shots': 10, - 'cvar_alpha': 1} - + + update_pairings = { + "prepend_state": prepend_state_rand, + "append_state": append_state_rand, + "init_hadamard": False, + "n_shots": 10, + "cvar_alpha": 1, + } + q.set_backend_properties(**update_pairings) - - q.compile(problem = qubo_problem) - + + q.compile(problem=qubo_problem) + self.assertEqual(type(q.backend), QAOAvectorizedBackendSimulator) self.assertEqual(q.backend.init_hadamard, False) self.assertEqual((q.backend.prepend_state == prepend_state_rand).all(), True) self.assertEqual((q.backend.append_state == append_state_rand).all(), True) self.assertEqual(q.backend.cvar_alpha, 1) - + self.assertRaises(AttributeError, lambda: q.backend.n_shots) - + def test_set_backend_properties_check_backend_vectorized_error_values(self): - + """ If the values provided from the workflows are incorrect, we should receive the appropriate error messages from the vectorized backend. - + Checks: Incorrect size of prepend state and append state. """ - + nodes = 3 edge_probability = 0.6 - g = nw.generators.fast_gnp_random_graph(n=nodes,p=edge_probability) - problem = MinimumVertexCover(g, field =1.0, penalty=10) + g = nw.generators.fast_gnp_random_graph(n=nodes, p=edge_probability) + problem = MinimumVertexCover(g, field=1.0, penalty=10) qubo_problem = problem.qubo - + q = QAOA() - q.set_device(create_device(location = 'local', name = 'vectorized')) - + q.set_device(create_device(location="local", name="vectorized")) + prepend_state_rand = np.random.rand(2**2) - - update_pairings = {'prepend_state': prepend_state_rand, - 'append_state': None} - + + update_pairings = {"prepend_state": prepend_state_rand, "append_state": None} + q.set_backend_properties(**update_pairings) - - self.assertRaises(ValueError, lambda : q.compile(problem = qubo_problem)) - + + self.assertRaises(ValueError, lambda: q.compile(problem=qubo_problem)) + q = QAOA() - q.set_device(create_device(location = 'local', name = 'vectorized')) - + q.set_device(create_device(location="local", name="vectorized")) + append_state_rand = np.random.rand(2**2, 2**2) - - update_pairings = {'prepend_state': None, - 'append_state': append_state_rand} - + + update_pairings = {"prepend_state": None, "append_state": append_state_rand} + q.set_backend_properties(**update_pairings) - - self.assertRaises(ValueError, lambda : q.compile(problem = qubo_problem)) - + + self.assertRaises(ValueError, lambda: q.compile(problem=qubo_problem)) + def test_set_backend_properties_check_backend_qiskit_qasm(self): - + """ Check if the backend returned by set_backend_properties is correct Based on the input device. For qiskit qasm simulator. Also Checks if defaults from workflows are used in the backend. """ - + nodes = 6 edge_probability = 0.6 - g = nw.generators.fast_gnp_random_graph(n=nodes,p=edge_probability) - problem = MinimumVertexCover(g, field =1.0, penalty=10) + g = nw.generators.fast_gnp_random_graph(n=nodes, p=edge_probability) + problem = MinimumVertexCover(g, field=1.0, penalty=10) qubo_problem = problem.qubo - + q = QAOA() - q.set_device(create_device(location = 'local', name = 'qiskit.qasm_simulator')) - q.compile(problem = qubo_problem) - + q.set_device(create_device(location="local", name="qiskit.qasm_simulator")) + q.compile(problem=qubo_problem) + self.assertEqual(type(q.backend), QAOAQiskitBackendShotBasedSimulator) - + self.assertEqual(q.backend.init_hadamard, True) self.assertEqual(q.backend.prepend_state, None) self.assertEqual(q.backend.append_state, None) self.assertEqual(q.backend.cvar_alpha, 1) self.assertEqual(q.backend.n_shots, 100) - + def test_set_backend_properties_check_backend_qiskit_statevector(self): - + """ Check if the backend returned by set_backend_properties is correct Based on the input device. For qiskit statevector simulator. Also Checks if defaults from workflows are used in the backend. """ - + nodes = 6 edge_probability = 0.6 - g = nw.generators.fast_gnp_random_graph(n=nodes,p=edge_probability) - problem = MinimumVertexCover(g, field =1.0, penalty=10) + g = nw.generators.fast_gnp_random_graph(n=nodes, p=edge_probability) + problem = MinimumVertexCover(g, field=1.0, penalty=10) qubo_problem = problem.qubo - + q = QAOA() - q.set_device(create_device(location = 'local', name = 'qiskit.statevector_simulator')) - q.compile(problem = qubo_problem) - + q.set_device( + create_device(location="local", name="qiskit.statevector_simulator") + ) + q.compile(problem=qubo_problem) + self.assertEqual(type(q.backend), QAOAQiskitBackendStatevecSimulator) - + self.assertEqual(q.backend.init_hadamard, True) self.assertEqual(q.backend.prepend_state, None) self.assertEqual(q.backend.append_state, None) self.assertEqual(q.backend.cvar_alpha, 1) - + self.assertRaises(AttributeError, lambda: q.backend.n_shots) - + def test_set_backend_properties_check_backend_pyquil_statevector(self): - + """ Check if the backend returned by set_backend_properties is correct Based on the input device. For pyquil statevector simulator. Also Checks if defaults from workflows are used in the backend. """ - + nodes = 6 edge_probability = 0.6 - g = nw.generators.fast_gnp_random_graph(n=nodes,p=edge_probability) - problem = MinimumVertexCover(g, field =1.0, penalty=10) + g = nw.generators.fast_gnp_random_graph(n=nodes, p=edge_probability) + problem = MinimumVertexCover(g, field=1.0, penalty=10) qubo_problem = problem.qubo - + q = QAOA() - q.set_device(create_device(location = 'local', name = 'pyquil.statevector_simulator')) - q.compile(problem = qubo_problem) - + q.set_device( + create_device(location="local", name="pyquil.statevector_simulator") + ) + q.compile(problem=qubo_problem) + self.assertEqual(type(q.backend), QAOAPyQuilWavefunctionSimulatorBackend) - + self.assertEqual(q.backend.init_hadamard, True) self.assertEqual(q.backend.prepend_state, None) self.assertEqual(q.backend.append_state, None) self.assertEqual(q.backend.cvar_alpha, 1) - + self.assertRaises(AttributeError, lambda: q.backend.n_shots) - + def test_set_classical_optimizer_defaults(self): - + """ Check if the fields in the default classical_optimizer dict are correct """ - - default_pairings = {'optimize': True, 'method': 'cobyla', - 'maxiter': 100, 'jac': None, 'hess': None, - 'constraints': None, 'bounds': None, 'tol': None, - 'optimizer_options': None, 'jac_options': None, - 'hess_options': None, 'optimization_progress': False, - 'cost_progress': True, 'parameter_log': True, - } - + + default_pairings = { + "optimize": True, + "method": "cobyla", + "maxiter": 100, + "jac": None, + "hess": None, + "constraints": None, + "bounds": None, + "tol": None, + "optimizer_options": None, + "jac_options": None, + "hess_options": None, + "optimization_progress": False, + "cost_progress": True, + "parameter_log": True, + } + q = QAOA() - + for each_key, each_value in default_pairings.items(): self.assertEqual(getattr(q.classical_optimizer, each_key), each_value) - + if each_value != None: self.assertEqual(q.classical_optimizer.asdict()[each_key], each_value) - + def test_set_classical_optimizer_jac_hess_casing(self): - + """ jac and hess should be in lower case if it is a string. """ - + q = QAOA() - q.set_classical_optimizer(jac = 'JaC', hess = 'HeSS') - - self.assertEqual(q.classical_optimizer.jac, 'jac') - self.assertEqual(q.classical_optimizer.hess, 'hess') - + q.set_classical_optimizer(jac="JaC", hess="HeSS") + + self.assertEqual(q.classical_optimizer.jac, "jac") + self.assertEqual(q.classical_optimizer.hess, "hess") + def test_set_classical_optimizer_method_selectors(self): - + """ Different methods would return different Optimizer classes. Check that the correct class is returned. """ - + nodes = 6 edge_probability = 0.6 - g = nw.generators.fast_gnp_random_graph(n=nodes,p=edge_probability) - problem = MinimumVertexCover(g, field =1.0, penalty=10) + g = nw.generators.fast_gnp_random_graph(n=nodes, p=edge_probability) + problem = MinimumVertexCover(g, field=1.0, penalty=10) qubo_problem = problem.qubo - - for each_method in available_optimizers()['scipy']: + + for each_method in available_optimizers()["scipy"]: q = QAOA() - q.set_classical_optimizer(method = each_method, jac='grad_spsa') - q.compile(problem = qubo_problem) - + q.set_classical_optimizer(method=each_method, jac="grad_spsa") + q.compile(problem=qubo_problem) + self.assertEqual(isinstance(q.optimizer, ScipyOptimizer), True) - self.assertEqual(isinstance(q.optimizer, CustomScipyGradientOptimizer), False) + self.assertEqual( + isinstance(q.optimizer, CustomScipyGradientOptimizer), False + ) self.assertEqual(isinstance(q.optimizer, PennyLaneOptimizer), False) - - for each_method in available_optimizers()['custom_scipy_gradient']: + + for each_method in available_optimizers()["custom_scipy_gradient"]: q = QAOA() - q.set_classical_optimizer(method = each_method, jac='grad_spsa', - hess='finite_difference') - q.compile(problem = qubo_problem) - + q.set_classical_optimizer( + method=each_method, jac="grad_spsa", hess="finite_difference" + ) + q.compile(problem=qubo_problem) + self.assertEqual(isinstance(q.optimizer, ScipyOptimizer), False) - self.assertEqual(isinstance(q.optimizer, CustomScipyGradientOptimizer), True) + self.assertEqual( + isinstance(q.optimizer, CustomScipyGradientOptimizer), True + ) self.assertEqual(isinstance(q.optimizer, PennyLaneOptimizer), False) - - for each_method in available_optimizers()['custom_scipy_pennylane']: + + for each_method in available_optimizers()["custom_scipy_pennylane"]: q = QAOA() - q.set_classical_optimizer(method = each_method, jac='grad_spsa') - q.compile(problem = qubo_problem) - + q.set_classical_optimizer(method=each_method, jac="grad_spsa") + q.compile(problem=qubo_problem) + self.assertEqual(isinstance(q.optimizer, ScipyOptimizer), False) - self.assertEqual(isinstance(q.optimizer, CustomScipyGradientOptimizer), False) + self.assertEqual( + isinstance(q.optimizer, CustomScipyGradientOptimizer), False + ) self.assertEqual(isinstance(q.optimizer, PennyLaneOptimizer), True) def test_set_header(self): @@ -684,117 +756,182 @@ def test_set_header(self): """ # create a QAOA object - qaoa:QAOA = QAOA() + qaoa: QAOA = QAOA() - #check if the header values are set to None, except for the experiment_id and algorithm + # check if the header values are set to None, except for the experiment_id and algorithm for key, value in qaoa.header.items(): - if key == 'experiment_id': - assert is_valid_uuid(qaoa.header['experiment_id']), "The experiment_id is not a valid uuid." - elif key == 'algorithm': - assert qaoa.header['algorithm']=='qaoa' + if key == "experiment_id": + assert is_valid_uuid( + qaoa.header["experiment_id"] + ), "The experiment_id is not a valid uuid." + elif key == "algorithm": + assert qaoa.header["algorithm"] == "qaoa" else: - assert value == None, "The value of the key {} (of the dictionary qaoa.header) is not None, when it should be.".format(key) + assert ( + value == None + ), "The value of the key {} (of the dictionary qaoa.header) is not None, when it should be.".format( + key + ) # save the experiment_id - experiment_id = qaoa.header['experiment_id'] + experiment_id = qaoa.header["experiment_id"] # set the header qaoa.set_header( - project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", - name="test", - run_by="raul", - provider="-", - target="-", - cloud="local", - client="-", - qubit_routing="-", - error_mitigation="-", - error_correction="-" - ) + project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", + description="test", + run_by="raul", + provider="-", + target="-", + cloud="local", + client="-", + ) + + # check that the experiment_id has not changed, since it is not set in the set_header method + assert ( + qaoa.header["experiment_id"] == experiment_id + ), "The experiment_id has changed when it should not have." + + # now set the experiment_id + experiment_id = experiment_id[:-2] + "00" + + # set the header + qaoa.set_header( + project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", + description="test", + run_by="raul", + provider="-", + target="-", + cloud="local", + client="-", + experiment_id=experiment_id, + ) # check if the header values are set to the correct values, except for the qubit_number, atomic_id, execution_time_start, and execution_time_end (which are set to None) dict_values = { - 'experiment_id': experiment_id, - 'project_id': '8353185c-b175-4eda-9628-b4e58cb0e41b', - 'algorithm': 'qaoa', - 'name': 'test', - 'run_by': 'raul', - 'provider': '-', - 'target': '-', - 'cloud': 'local', - 'client': '-', - 'qubit_routing': '-', - 'error_mitigation': '-', - 'error_correction': '-', - 'qubit_number': None, - 'atomic_id': None, - 'execution_time_start': None, - 'execution_time_end': None + "experiment_id": experiment_id, + "project_id": "8353185c-b175-4eda-9628-b4e58cb0e41b", + "algorithm": "qaoa", + "description": "test", + "run_by": "raul", + "provider": "-", + "target": "-", + "cloud": "local", + "client": "-", + "qubit_number": None, + "atomic_id": None, + "execution_time_start": None, + "execution_time_end": None, } for key, value in qaoa.header.items(): - assert dict_values[key] == value, "The value of the key {} (of the dictionary qaoa.header) is not correct.".format(key) + assert ( + dict_values[key] == value + ), "The value of the key {} (of the dictionary qaoa.header) is not correct.".format( + key + ) # compile the QAOA object - qaoa.compile(problem = QUBO.random_instance(n=8)) + qaoa.compile(problem=QUBO.random_instance(n=8)) - #check if the header values are still set to the correct values, except for execution_time_start, and execution_time_end (which are set to None). + # check if the header values are still set to the correct values, except for execution_time_start, and execution_time_end (which are set to None). # Now atomic_id should be set to a valid uuid. And qubit_number should be set to 8 (number of qubits of the problem) - dict_values['qubit_number'] = 8 + dict_values["qubit_number"] = 8 for key, value in qaoa.header.items(): - if key not in ['atomic_id']: - assert dict_values[key] == value, "The value of the key {} (of the dictionary qaoa.header) is not correct.".format(key) - assert is_valid_uuid(qaoa.header['atomic_id']), "The atomic_id is not a valid uuid." + if key not in ["atomic_id"]: + assert ( + dict_values[key] == value + ), "The value of the key {} (of the dictionary qaoa.header) is not correct.".format( + key + ) + assert is_valid_uuid( + qaoa.header["atomic_id"] + ), "The atomic_id is not a valid uuid." # save the atomic_id - atomic_id = qaoa.header['atomic_id'] + atomic_id = qaoa.header["atomic_id"] # optimize the QAOA object qaoa.optimize() - #check if the header values are still set to the correct values, now everything should be set to a valid value (execution_time_start and execution_time_end should be integers>1672933928) - dict_values['atomic_id'] = atomic_id + # check if the header values are still set to the correct values, now everything should be set to a valid value (execution_time_start and execution_time_end should be integers>1672933928) + dict_values["atomic_id"] = atomic_id for key, value in qaoa.header.items(): - if key not in ['execution_time_start', 'execution_time_end']: - assert dict_values[key] == value, "The value of the key {} (of the dictionary qaoa.header) is not correct.".format(key) - assert qaoa.header['execution_time_start'] > 1672933928, "The execution_time_start is not a valid integer." - assert qaoa.header['execution_time_end'] > 1672933928, "The execution_time_end is not a valid integer." - + if key not in ["execution_time_start", "execution_time_end"]: + assert ( + dict_values[key] == value + ), "The value of the key {} (of the dictionary qaoa.header) is not correct.".format( + key + ) + assert datetime.datetime.strptime( + qaoa.header["execution_time_start"], "%Y-%m-%dT%H:%M:%S" + ), "The execution_time_start is not valid." + assert datetime.datetime.strptime( + qaoa.header["execution_time_end"], "%Y-%m-%dT%H:%M:%S" + ), "The execution_time_end is not valid." # test if an error is raised when the project_id is not a valid string error = False try: - qaoa.set_header(project_id="test") + qaoa.set_header( + project_id="test", + description="test", + run_by="raul", + provider="-", + target="-", + cloud="local", + client="-", + ) except: error = True assert error, "The project_id is not valid string, but no error was raised." + # test if an error is raised when the experiment_id is not a valid string + error = False + try: + qaoa.set_header( + project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", + experiment_id="test", + description="test", + run_by="raul", + provider="-", + target="-", + cloud="local", + client="-", + ) + except: + error = True + assert error, "The experiment_id is not valid string, but no error was raised." + def test_set_exp_tags(self): """ Test the set_exp_tags method of the QAOA class. """ qaoa = QAOA() - qaoa.set_exp_tags(tags={'tag1': 'value1', 'tag2': 'value2'}) - qaoa.set_exp_tags(tags={'tag1': 'value9'}) - qaoa.compile(problem = QUBO.random_instance(n=8)) + qaoa.set_exp_tags(tags={"tag1": "value1", "tag2": "value2"}) + qaoa.set_exp_tags(tags={"tag1": "value9"}) + qaoa.compile(problem=QUBO.random_instance(n=8)) qaoa.optimize() - assert qaoa.exp_tags == {'tag1':'value9', 'tag2':'value2'}, "Experiment tags are not set correctly." + assert qaoa.exp_tags == { + "tag1": "value9", + "tag2": "value2", + }, "Experiment tags are not set correctly." error = False try: - qaoa.set_exp_tags(tags={'tag1': complex(1,2)}) + qaoa.set_exp_tags(tags={"tag1": complex(1, 2)}) except: error = True assert error, "Experiment tag values should be primitives." error = False try: - qaoa.set_exp_tags(tags={(1,2): 'test'}) + qaoa.set_exp_tags(tags={(1, 2): "test"}) except: error = True assert error, "Experiment tag keys should be strings." - + def test_qaoa_asdict_with_noise(self): "test to check that we can serialize a QAOA object with noise" device_backend = FakeVigo() @@ -803,15 +940,20 @@ def test_qaoa_asdict_with_noise(self): q_noisy_shot = QAOA() # device - qiskit_noisy_shot = create_device(location='local', name='qiskit.qasm_simulator') + qiskit_noisy_shot = create_device( + location="local", name="qiskit.qasm_simulator" + ) q_noisy_shot.set_device(qiskit_noisy_shot) # circuit properties - q_noisy_shot.set_circuit_properties(p=2, param_type='standard', init_type='rand', mixer_hamiltonian='x') + q_noisy_shot.set_circuit_properties( + p=2, param_type="standard", init_type="rand", mixer_hamiltonian="x" + ) # backend properties - q_noisy_shot.set_backend_properties(n_shots = 200, noise_model = noise_model) + q_noisy_shot.set_backend_properties(n_shots=200, noise_model=noise_model) # classical optimizer properties - q_noisy_shot.set_classical_optimizer(method='COBYLA', maxiter=200, - cost_progress=True, parameter_log=True) + q_noisy_shot.set_classical_optimizer( + method="COBYLA", maxiter=200, cost_progress=True, parameter_log=True + ) q_noisy_shot.compile(QUBO.random_instance(n=8)) q_noisy_shot.optimize() q_noisy_shot.asdict() @@ -819,64 +961,74 @@ def test_qaoa_asdict_with_noise(self): def test_qaoa_asdict_dumps(self): """Test the asdict method of the QAOA class.""" - #qaoa + # qaoa qaoa = QAOA() - qaoa.compile(problem = QUBO.random_instance(n=8)) + qaoa.compile(problem=QUBO.random_instance(n=8)) # set the header qaoa.set_header( - project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", - name="test", - run_by="raul", - provider="-", - target="-", - cloud="local", - client="-", - qubit_routing="-", - error_mitigation="-", - error_correction="-" - ) + project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", + description="test", + run_by="raul", + provider="-", + target="-", + cloud="local", + client="-", + ) qaoa.optimize() # check QAOA asdict - self.__test_expected_keys(qaoa.asdict(), method='asdict') + self.__test_expected_keys(qaoa.asdict(), method="asdict") # check QAOA asdict deleting some keys - exclude_keys = ['corr_matrix', 'number_steps'] - self.__test_expected_keys(qaoa.asdict(exclude_keys=exclude_keys), exclude_keys, method='asdict') + exclude_keys = ["corr_matrix", "number_steps"] + self.__test_expected_keys( + qaoa.asdict(exclude_keys=exclude_keys), exclude_keys, method="asdict" + ) # check QAOA dumps - self.__test_expected_keys(json.loads(qaoa.dumps()), method='dumps') + self.__test_expected_keys(json.loads(qaoa.dumps()), method="dumps") # check QAOA dumps deleting some keys - exclude_keys = ['parent_id', 'counter'] - self.__test_expected_keys(json.loads(qaoa.dumps(exclude_keys=exclude_keys)), exclude_keys, method='dumps') + exclude_keys = ["parent_id", "counter"] + self.__test_expected_keys( + json.loads(qaoa.dumps(exclude_keys=exclude_keys)), + exclude_keys, + method="dumps", + ) # check QAOA dump - file_name = 'test_dump_qaoa.json' - experiment_id, atomic_id = qaoa.header['experiment_id'], qaoa.header['atomic_id'] - full_name = f'{experiment_id}--{atomic_id}--{file_name}' + file_name = "test_dump_qaoa.json" + experiment_id, atomic_id = ( + qaoa.header["experiment_id"], + qaoa.header["atomic_id"], + ) + full_name = f"{experiment_id}--{atomic_id}--{file_name}" qaoa.dump(file_name, indent=None) - assert os.path.isfile(full_name), 'Dump file does not exist' - with open(full_name, 'r') as file: - assert file.read() == qaoa.dumps(indent=None), 'Dump file does not contain the correct data' + assert os.path.isfile(full_name), "Dump file does not exist" + with open(full_name, "r") as file: + assert file.read() == qaoa.dumps( + indent=None + ), "Dump file does not contain the correct data" os.remove(full_name) # check RQAOA dump whitout prepending the experiment_id and atomic_id - qaoa.dump(file_name, indent=None,prepend_id=False) - assert os.path.isfile(file_name), 'Dump file does not exist, when not prepending the experiment_id and atomic_id' - + qaoa.dump(file_name, indent=None, prepend_id=False) + assert os.path.isfile( + file_name + ), "Dump file does not exist, when not prepending the experiment_id and atomic_id" + # check RQAOA dump fails when the file already exists error = False try: - qaoa.dump(file_name, indent=None,prepend_id=False) + qaoa.dump(file_name, indent=None, prepend_id=False) except FileExistsError: error = True - assert error, 'Dump file does not fail when the file already exists' + assert error, "Dump file does not fail when the file already exists" # check that we can overwrite the file - qaoa.dump(file_name, indent=None,prepend_id=False, overwrite=True) - assert os.path.isfile(file_name), 'Dump file does not exist, when overwriting' + qaoa.dump(file_name, indent=None, prepend_id=False, overwrite=True) + assert os.path.isfile(file_name), "Dump file does not exist, when overwriting" os.remove(file_name) # check RQAOA dump fails when prepend_id is True and file_name is not given @@ -885,48 +1037,151 @@ def test_qaoa_asdict_dumps(self): qaoa.dump(prepend_id=False) except ValueError: error = True - assert error, 'Dump file does not fail when prepend_id is True and file_name is not given' + assert ( + error + ), "Dump file does not fail when prepend_id is True and file_name is not given" # check you can dump to a file with no arguments qaoa.dump() - assert os.path.isfile(f'{experiment_id}--{atomic_id}.json'), 'Dump file does not exist, when no name is given' - os.remove(f'{experiment_id}--{atomic_id}.json') + assert os.path.isfile( + f"{experiment_id}--{atomic_id}.json" + ), "Dump file does not exist, when no name is given" + os.remove(f"{experiment_id}--{atomic_id}.json") # check QAOA dump deleting some keys - exclude_keys = ['schedule', 'singlet'] + exclude_keys = ["schedule", "singlet"] qaoa.dump(file_name, exclude_keys=exclude_keys, indent=None) - assert os.path.isfile(full_name), 'Dump file does not exist, when deleting some keys' - with open(full_name, 'r') as file: - assert file.read() == qaoa.dumps(exclude_keys=exclude_keys, indent=None), 'Dump file does not contain the correct data, when deleting some keys' + assert os.path.isfile( + full_name + ), "Dump file does not exist, when deleting some keys" + with open(full_name, "r") as file: + assert file.read() == qaoa.dumps( + exclude_keys=exclude_keys, indent=None + ), "Dump file does not contain the correct data, when deleting some keys" os.remove(full_name) # check QAOA dump with compression qaoa.dump(file_name, compresslevel=2, indent=None) - assert os.path.isfile(full_name+'.gz'), 'Dump file does not exist, when compressing' - with gzip.open(full_name+'.gz', 'rb') as file: - assert file.read() == qaoa.dumps(indent=None).encode(), 'Dump file does not contain the correct data, when compressing' - os.remove(full_name+'.gz') - - - - def __test_expected_keys(self, obj, exclude_keys=[], method='asdict'): + assert os.path.isfile( + full_name + ".gz" + ), "Dump file does not exist, when compressing" + with gzip.open(full_name + ".gz", "rb") as file: + assert ( + file.read() == qaoa.dumps(indent=None).encode() + ), "Dump file does not contain the correct data, when compressing" + os.remove(full_name + ".gz") + + def __test_expected_keys(self, obj, exclude_keys=[], method="asdict"): """ method to test if the dictionary has all the expected keys """ - #create a dictionary with all the expected keys and set them to False - expected_keys = ['header', 'atomic_id', 'experiment_id', 'project_id', 'algorithm', 'name', 'run_by', 'provider', 'target', 'cloud', 'client', 'qubit_number', 'qubit_routing', 'error_mitigation', 'error_correction', 'execution_time_start', 'execution_time_end', 'metadata', 'problem_type', 'n_shots', 'optimizer_method', 'param_type', 'init_type', 'p', 'data', 'exp_tags', 'input_problem', 'terms', 'weights', 'constant', 'n', 'problem_instance', 'input_parameters', 'device', 'device_location', 'device_name', 'backend_properties', 'init_hadamard', 'prepend_state', 'append_state', 'cvar_alpha', 'noise_model', 'qubit_layout', 'seed_simulator', 'qiskit_simulation_method', 'active_reset', 'rewiring', 'disable_qubit_rewiring', 'classical_optimizer', 'optimize', 'method', 'maxiter', 'maxfev', 'jac', 'hess', 'constraints', 'bounds', 'tol', 'optimizer_options', 'jac_options', 'hess_options', 'parameter_log', 'optimization_progress', 'cost_progress', 'save_intermediate', 'circuit_properties', 'qubit_register', 'q', 'variational_params_dict', 'total_annealing_time', 'annealing_time', 'linear_ramp_time', 'mixer_hamiltonian', 'mixer_qubit_connectivity', 'mixer_coeffs', 'seed', 'result', 'evals', 'number_of_evals', 'jac_evals', 'qfim_evals', 'most_probable_states', 'solutions_bitstrings', 'bitstring_energy', 'intermediate', 'angles', 'cost', 'measurement_outcomes', 'job_id', 'optimized', 'eval_number'] + # create a dictionary with all the expected keys and set them to False + expected_keys = [ + "header", + "atomic_id", + "experiment_id", + "project_id", + "algorithm", + "description", + "run_by", + "provider", + "target", + "cloud", + "client", + "qubit_number", + "execution_time_start", + "execution_time_end", + "metadata", + "problem_type", + "n_shots", + "optimizer_method", + "param_type", + "init_type", + "p", + "data", + "exp_tags", + "input_problem", + "terms", + "weights", + "constant", + "n", + "problem_instance", + "input_parameters", + "device", + "device_location", + "device_name", + "backend_properties", + "init_hadamard", + "prepend_state", + "append_state", + "cvar_alpha", + "noise_model", + "initial_qubit_mapping", + "seed_simulator", + "qiskit_simulation_method", + "active_reset", + "rewiring", + "disable_qubit_rewiring", + "classical_optimizer", + "optimize", + "method", + "maxiter", + "maxfev", + "jac", + "hess", + "constraints", + "bounds", + "tol", + "optimizer_options", + "jac_options", + "hess_options", + "parameter_log", + "optimization_progress", + "cost_progress", + "save_intermediate", + "circuit_properties", + "qubit_register", + "q", + "variational_params_dict", + "total_annealing_time", + "annealing_time", + "linear_ramp_time", + "mixer_hamiltonian", + "mixer_qubit_connectivity", + "mixer_coeffs", + "seed", + "result", + "evals", + "number_of_evals", + "jac_evals", + "qfim_evals", + "most_probable_states", + "solutions_bitstrings", + "bitstring_energy", + "intermediate", + "angles", + "cost", + "measurement_outcomes", + "job_id", + "optimized", + "eval_number", + ] expected_keys = {item: False for item in expected_keys} - #test the keys, it will set the keys to True if they are found + # test the keys, it will set the keys to True if they are found _test_keys_in_dict(obj, expected_keys) # Check if the dictionary has all the expected keys except the ones that were not included for key, value in expected_keys.items(): if key not in exclude_keys: - assert value==True, f'Key {key} not found in the dictionary, when using {method} method.' + assert ( + value == True + ), f'Key "{key}" not found in the dictionary, when using "{method}" method.' else: - assert value==False, f'Key {key} was found in the dictionary, but it should not be there, when using {method} method.' + assert ( + value == False + ), f'Key "{key}" was found in the dictionary, but it should not be there, when using "{method}" method.' """ to get the list of expected keys, run the following code: @@ -950,49 +1205,53 @@ def get_keys(obj, list_keys): print(expected_keys) """ - def test_qaoa_from_dict_and_load(self): + def test_qaoa_from_dict_and_load(self): """ test loading the QAOA object from a dictionary methods: from_dict, load, loads """ # problem - maxcut_qubo = MaximumCut( - nw.generators.fast_gnp_random_graph(n=6,p=0.6, seed=42) - ).qubo + maxcut_qubo = MaximumCut( + nw.generators.fast_gnp_random_graph(n=6, p=0.6, seed=42) + ).qubo - # run rqaoa with different devices, and save the objcets in a list + # run rqaoa with different devices, and save the objcets in a list qaoas = [] - for device in [create_device(location='local', name='qiskit.shot_simulator'), create_device(location='local', name='vectorized')]: + for device in [ + create_device(location="local", name="qiskit.shot_simulator"), + create_device(location="local", name="vectorized"), + ]: q = QAOA() q.set_device(device) - q.set_circuit_properties(p=1, param_type='extended', init_type='rand', mixer_hamiltonian='x') + q.set_circuit_properties( + p=1, param_type="extended", init_type="rand", mixer_hamiltonian="x" + ) q.set_backend_properties(n_shots=50) q.set_classical_optimizer(maxiter=10, optimization_progress=True) - q.set_exp_tags({'add_tag': 'test'}) + q.set_exp_tags({"add_tag": "test"}) q.set_header( - project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", - name="test", - run_by="raul", - provider="-", - target="-", - cloud="local", - client="-", - qubit_routing="-", - error_mitigation="-", - error_correction="-" - ) + project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", + description="test", + run_by="raul", + provider="-", + target="-", + cloud="local", + client="-", + ) # test that you can convert the rqaoa object to a dictionary and then load it before optimization _ = QAOA.from_dict(q.asdict()) _.compile(maxcut_qubo) _.optimize() - assert isinstance(_, QAOA), 'The object loaded from a dictionary is not an RQAOA object.' + assert isinstance( + _, QAOA + ), "The object loaded from a dictionary is not an RQAOA object." # compile and optimize the original rqaoa object - q.compile(maxcut_qubo) - q.optimize() + q.compile(maxcut_qubo) + q.optimize() qaoas.append(q) @@ -1001,19 +1260,18 @@ def test_qaoa_from_dict_and_load(self): new_q_list = [] - #get new qaoa from dict + # get new qaoa from dict new_q_list.append(QAOA.from_dict(q.asdict())) - #get new qaoa from json string + # get new qaoa from json string new_q_list.append(QAOA.loads(q.dumps())) - #get new qaoa from json file + # get new qaoa from json file q.dump("test.json", prepend_id=False) new_q_list.append(QAOA.load("test.json")) - os.remove("test.json") #delete file test.json - #get new qaoa from compressed json file + os.remove("test.json") # delete file test.json + # get new qaoa from compressed json file q.dump("test.json", prepend_id=False, compresslevel=3) new_q_list.append(QAOA.load("test.json.gz")) - os.remove("test.json.gz") #delete file test.json - + os.remove("test.json.gz") # delete file test.json for new_q in new_q_list: @@ -1021,10 +1279,19 @@ def test_qaoa_from_dict_and_load(self): assert isinstance(new_q, QAOA), "new_r is not an RQAOA object" # check that the attributes of the new object are of the correct type - attributes_types = [ ("header", dict), ("exp_tags", dict), ("problem", QUBO), ("result", QAOAResult), - ("backend_properties", BackendProperties), ("classical_optimizer", ClassicalOptimizer), ("circuit_properties", CircuitProperties) ] + attributes_types = [ + ("header", dict), + ("exp_tags", dict), + ("problem", QUBO), + ("result", QAOAResult), + ("backend_properties", BackendProperties), + ("classical_optimizer", ClassicalOptimizer), + ("circuit_properties", CircuitProperties), + ] for attribute, type_ in attributes_types: - assert isinstance(getattr(new_q, attribute), type_), f"attribute {attribute} is not type {type_}" + assert isinstance( + getattr(new_q, attribute), type_ + ), f"attribute {attribute} is not type {type_}" # get the two objects (old and new) as dictionaries q_asdict = q.asdict() @@ -1037,14 +1304,16 @@ def test_qaoa_from_dict_and_load(self): elif key == "data": for key2, value2 in value.items(): - if key2 == "input_parameters": - #pop key device since it is not returned completely when using asdict/dump(s) + if key2 == "input_parameters": + # pop key device since it is not returned completely when using asdict/dump(s) value2.pop("device") new_q_asdict[key][key2].pop("device") if key2 == "result": _compare_qaoa_results(value2, new_q_asdict[key][key2]) else: - assert value2==new_q_asdict[key][key2], "{} not the same".format(key2) + assert ( + value2 == new_q_asdict[key][key2] + ), "{} not the same".format(key2) # compile and optimize the new qaoa, to check if everything is working new_q.compile(maxcut_qubo) @@ -1056,7 +1325,9 @@ def test_qaoa_from_dict_and_load(self): RQAOA.from_dict(q.asdict()) except Exception: error = True - assert error, "RQAOA.from_dict should raise an error when using a QAOA dictionary" + assert ( + error + ), "RQAOA.from_dict should raise an error when using a QAOA dictionary" class TestingRQAOA(unittest.TestCase): @@ -1064,23 +1335,23 @@ class TestingRQAOA(unittest.TestCase): Unit test based testing of the RQAOA workflow class """ - def _test_default_values(self, x): + def _test_default_values(self, x): """ General function to check default values of rqaoa and qaoa """ # circuit_properties cp = x.circuit_properties - assert cp.param_type == 'standard' - assert cp.init_type == 'ramp' + assert cp.param_type == "standard" + assert cp.init_type == "ramp" assert cp.p == 1 assert cp.q == None - assert cp.mixer_hamiltonian == 'x' + assert cp.mixer_hamiltonian == "x" # device - d = x.device - assert d.device_location == 'local' - assert d.device_name == 'vectorized' + d = x.device + assert d.device_location == "local" + assert d.device_name == "vectorized" def test_rqaoa_default_values(self): """ @@ -1088,7 +1359,7 @@ def test_rqaoa_default_values(self): """ r = RQAOA() - assert r.rqaoa_parameters.rqaoa_type == 'custom' + assert r.rqaoa_parameters.rqaoa_type == "custom" assert r.rqaoa_parameters.n_cutoff == 5 assert r.rqaoa_parameters.n_max == 1 assert r.rqaoa_parameters.steps == 1 @@ -1096,7 +1367,7 @@ def test_rqaoa_default_values(self): assert r.rqaoa_parameters.counter == 0 self._test_default_values(r) - + def test_rqaoa_compile_and_qoao_default_values(self): """ Test creation of the qaoa object and its default values @@ -1105,36 +1376,57 @@ def test_rqaoa_compile_and_qoao_default_values(self): r.compile(QUBO.random_instance(n=7)) self._test_default_values(r._RQAOA__q) - - def __run_rqaoa(self, type, problem=None, n_cutoff=5, eliminations=1, p=1, param_type='standard', mixer='x', method='cobyla', maxiter=15, name_device='qiskit.statevector_simulator', return_object=False): + def __run_rqaoa( + self, + type, + problem=None, + n_cutoff=5, + eliminations=1, + p=1, + param_type="standard", + mixer="x", + method="cobyla", + maxiter=15, + name_device="qiskit.statevector_simulator", + return_object=False, + ): if problem == None: - problem = QUBO.random_instance(n=8) + problem = MaximumCut.random_instance( + n_nodes=8, edge_probability=0.5, seed=2 + ).qubo r = RQAOA() - qiskit_device = create_device(location='local', name=name_device) + qiskit_device = create_device(location="local", name=name_device) r.set_device(qiskit_device) - if type == 'adaptive': - r.set_rqaoa_parameters(n_cutoff = n_cutoff, n_max=eliminations, rqaoa_type=type) + if type == "adaptive": + r.set_rqaoa_parameters( + n_cutoff=n_cutoff, n_max=eliminations, rqaoa_type=type + ) else: - r.set_rqaoa_parameters(n_cutoff = n_cutoff, steps=eliminations, rqaoa_type=type) + r.set_rqaoa_parameters( + n_cutoff=n_cutoff, steps=eliminations, rqaoa_type=type + ) r.set_circuit_properties(p=p, param_type=param_type, mixer_hamiltonian=mixer) r.set_backend_properties(prepend_state=None, append_state=None) - r.set_classical_optimizer(method=method, maxiter=maxiter, optimization_progress=True, cost_progress=True, parameter_log=True) + r.set_classical_optimizer( + method=method, + maxiter=maxiter, + optimization_progress=True, + cost_progress=True, + parameter_log=True, + ) r.set_header( - project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", - name="test", - run_by="raul", - provider="-", - target="-", - cloud="local", - client="-", - qubit_routing="-", - error_mitigation="-", - error_correction="-" - ) - r.set_exp_tags(tags={'tag1': 'value1', 'tag2': 'value2'}) + project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", + description="header", + run_by="raul", + provider="-", + target="-", + cloud="local", + client="-", + ) + r.set_exp_tags(tags={"tag1": "value1", "tag2": "value2"}) r.compile(problem) r.optimize() @@ -1153,13 +1445,12 @@ def test_rqaoa_optimize_multiple_times(self): exception = False try: r.optimize() - except: + except: exception = True - - assert exception, 'RQAOA should not be able to optimize without compilation' - - r.compile(problem) + assert exception, "RQAOA should not be able to optimize without compilation" + + r.compile(problem) r.optimize() exception = False try: @@ -1167,8 +1458,9 @@ def test_rqaoa_optimize_multiple_times(self): except: exception = True - assert exception, 'RQAOA should not be able to optimize twice without compilation' - + assert ( + exception + ), "RQAOA should not be able to optimize twice without compilation" def test_example_1_adaptive_custom(self): @@ -1176,15 +1468,15 @@ def test_example_1_adaptive_custom(self): n_qubits = 12 # Elimination schemes - Nmax = [1,2,3,4] - schedules = [1,[1,2,1,2,7]] + Nmax = [1, 2, 3, 4] + schedules = [1, [1, 2, 1, 2, 7]] n_cutoff = 5 # Edges and weights of the graph - pair_edges = [(i,i+1) for i in range(n_qubits-1)] + [(0,n_qubits-1)] + pair_edges = [(i, i + 1) for i in range(n_qubits - 1)] + [(0, n_qubits - 1)] self_edges = [(i,) for i in range(n_qubits)] - pair_weights = [1 for _ in range(len(pair_edges))] # All weights equal to 1 - self_weights = [10**(-4) for _ in range(len(self_edges))] + pair_weights = [1 for _ in range(len(pair_edges))] # All weights equal to 1 + self_weights = [10 ** (-4) for _ in range(len(self_edges))] edges = pair_edges + self_edges weights = pair_weights + self_weights @@ -1195,13 +1487,13 @@ def test_example_1_adaptive_custom(self): # run RQAOA and append solution for nmax in Nmax: - solutions.append(self.__run_rqaoa('adaptive', problem, n_cutoff, nmax)) + solutions.append(self.__run_rqaoa("adaptive", problem, n_cutoff, nmax)) for schedule in schedules: - solutions.append(self.__run_rqaoa('custom', problem, n_cutoff, schedule)) + solutions.append(self.__run_rqaoa("custom", problem, n_cutoff, schedule)) # Correct solution - exact_soutions = {'101010101010': -12, '010101010101': -12} + exact_soutions = {"101010101010": -12, "010101010101": -12} # Check computed solutions are among the correct ones for solution in solutions: @@ -1219,11 +1511,11 @@ def test_example_2_adaptive_custom(self): # run RQAOA and append solution in list solutions = [] - solutions.append(self.__run_rqaoa('adaptive', problem, n_cutoff)) - solutions.append(self.__run_rqaoa('custom', problem, n_cutoff)) + solutions.append(self.__run_rqaoa("adaptive", problem, n_cutoff)) + solutions.append(self.__run_rqaoa("custom", problem, n_cutoff)) # Correct solution - exact_soutions = {'1010101010': 5, '0101010101': 5} + exact_soutions = {"1010101010": 5, "0101010101": 5} # Check computed solutions are among the correct ones for solution in solutions: @@ -1243,12 +1535,22 @@ def test_example_3_adaptive_custom(self): # run RQAOA and append solution in list solutions = [] - solutions.append(self.__run_rqaoa('adaptive', problem, n_cutoff, nmax)) - solutions.append(self.__run_rqaoa('custom', problem, n_cutoff, step)) + solutions.append(self.__run_rqaoa("adaptive", problem, n_cutoff, nmax)) + solutions.append(self.__run_rqaoa("custom", problem, n_cutoff, step)) # Correct solution - exact_soutions = {'0111111111': 9, '1011111111': 9, '1101111111': 9, '1110111111': 9, '1111011111': 9, - '1111101111': 9, '1111110111': 9,'1111111011': 9, '1111111101': 9,'1111111110': 9} + exact_soutions = { + "0111111111": 9, + "1011111111": 9, + "1101111111": 9, + "1110111111": 9, + "1111011111": 9, + "1111101111": 9, + "1111110111": 9, + "1111111011": 9, + "1111111101": 9, + "1111111110": 9, + } # Check computed solutions are among the correct ones for solution in solutions: @@ -1261,29 +1563,282 @@ def test_example_4_adaptive_custom(self): n_qubits = 10 # Elimination schemes - Nmax = [1,2,3,4] - schedules = [1,2,3] + Nmax = [1, 2, 3, 4] + schedules = [1, 2, 3] n_cutoff = 3 # Edges and weights of the graph - edges = [(i,j) for j in range(n_qubits) for i in range(j)] + edges = [(i, j) for j in range(n_qubits) for i in range(j)] weights = [1 for _ in range(len(edges))] - problem = QUBO(n_qubits, edges, weights) + problem = QUBO(n_qubits, edges, weights) # list of solutions of rqaoa solutions = [] # run RQAOA and append solution for nmax in Nmax: - solutions.append(self.__run_rqaoa('adaptive', problem, n_cutoff, nmax)) + solutions.append(self.__run_rqaoa("adaptive", problem, n_cutoff, nmax)) for schedule in schedules: - solutions.append(self.__run_rqaoa('custom', problem, n_cutoff, schedule)) + solutions.append(self.__run_rqaoa("custom", problem, n_cutoff, schedule)) # Correct solution - exact_states = ['1111100000', '1111010000', '1110110000', '1101110000', '1011110000', '0111110000', '1111001000', '1110101000', '1101101000', '1011101000', '0111101000', '1110011000', '1101011000', '1011011000', '0111011000', '1100111000', '1010111000', '0110111000', '1001111000', '0101111000', '0011111000', '1111000100', '1110100100', '1101100100', '1011100100', '0111100100', '1110010100', '1101010100', '1011010100', '0111010100', '1100110100', '1010110100', '0110110100', '1001110100', '0101110100', '0011110100', '1110001100', '1101001100', '1011001100', '0111001100', '1100101100', '1010101100', '0110101100', '1001101100', '0101101100', '0011101100', '1100011100', '1010011100', '0110011100', '1001011100', '0101011100', '0011011100', '1000111100', '0100111100', '0010111100', '0001111100', '1111000010', '1110100010', '1101100010', '1011100010', '0111100010', '1110010010', '1101010010', '1011010010', '0111010010', '1100110010', '1010110010', '0110110010', '1001110010', '0101110010', '0011110010', '1110001010', '1101001010', '1011001010', '0111001010', '1100101010', '1010101010', '0110101010', '1001101010', '0101101010', '0011101010', '1100011010', '1010011010', '0110011010', '1001011010', '0101011010', '0011011010', '1000111010', '0100111010', '0010111010', '0001111010', '1110000110', '1101000110', '1011000110', '0111000110', '1100100110', '1010100110', '0110100110', '1001100110', '0101100110', '0011100110', '1100010110', '1010010110', '0110010110', '1001010110', '0101010110', '0011010110', '1000110110', '0100110110', '0010110110', '0001110110', '1100001110', '1010001110', '0110001110', '1001001110', '0101001110', '0011001110', '1000101110', '0100101110', '0010101110', '0001101110', '1000011110', '0100011110', '0010011110', '0001011110', '0000111110', '1111000001', '1110100001', '1101100001', '1011100001', '0111100001', '1110010001', '1101010001', '1011010001', '0111010001', '1100110001', '1010110001', '0110110001', '1001110001', '0101110001', '0011110001', '1110001001', '1101001001', '1011001001', '0111001001', '1100101001', '1010101001', '0110101001', '1001101001', '0101101001', '0011101001', '1100011001', '1010011001', '0110011001', '1001011001', '0101011001', '0011011001', '1000111001', '0100111001', '0010111001', '0001111001', '1110000101', '1101000101', '1011000101', '0111000101', '1100100101', '1010100101', '0110100101', '1001100101', '0101100101', '0011100101', '1100010101', '1010010101', '0110010101', '1001010101', '0101010101', '0011010101', '1000110101', '0100110101', '0010110101', '0001110101', '1100001101', '1010001101', '0110001101', '1001001101', '0101001101', '0011001101', '1000101101', '0100101101', '0010101101', '0001101101', '1000011101', '0100011101', '0010011101', '0001011101', '0000111101', '1110000011', '1101000011', '1011000011', '0111000011', '1100100011', '1010100011', '0110100011', '1001100011', '0101100011', '0011100011', '1100010011', '1010010011', '0110010011', '1001010011', '0101010011', '0011010011', '1000110011', '0100110011', '0010110011', '0001110011', '1100001011', '1010001011', '0110001011', '1001001011', '0101001011', '0011001011', '1000101011', '0100101011', '0010101011', '0001101011', '1000011011', '0100011011', '0010011011', '0001011011', '0000111011', '1100000111', '1010000111', '0110000111', '1001000111', '0101000111', '0011000111', '1000100111', '0100100111', '0010100111', '0001100111', '1000010111', '0100010111', '0010010111', '0001010111', '0000110111', '1000001111', '0100001111', '0010001111', '0001001111', '0000101111', '0000011111'] - exact_soutions = {state:-5 for state in exact_states} + exact_states = [ + "1111100000", + "1111010000", + "1110110000", + "1101110000", + "1011110000", + "0111110000", + "1111001000", + "1110101000", + "1101101000", + "1011101000", + "0111101000", + "1110011000", + "1101011000", + "1011011000", + "0111011000", + "1100111000", + "1010111000", + "0110111000", + "1001111000", + "0101111000", + "0011111000", + "1111000100", + "1110100100", + "1101100100", + "1011100100", + "0111100100", + "1110010100", + "1101010100", + "1011010100", + "0111010100", + "1100110100", + "1010110100", + "0110110100", + "1001110100", + "0101110100", + "0011110100", + "1110001100", + "1101001100", + "1011001100", + "0111001100", + "1100101100", + "1010101100", + "0110101100", + "1001101100", + "0101101100", + "0011101100", + "1100011100", + "1010011100", + "0110011100", + "1001011100", + "0101011100", + "0011011100", + "1000111100", + "0100111100", + "0010111100", + "0001111100", + "1111000010", + "1110100010", + "1101100010", + "1011100010", + "0111100010", + "1110010010", + "1101010010", + "1011010010", + "0111010010", + "1100110010", + "1010110010", + "0110110010", + "1001110010", + "0101110010", + "0011110010", + "1110001010", + "1101001010", + "1011001010", + "0111001010", + "1100101010", + "1010101010", + "0110101010", + "1001101010", + "0101101010", + "0011101010", + "1100011010", + "1010011010", + "0110011010", + "1001011010", + "0101011010", + "0011011010", + "1000111010", + "0100111010", + "0010111010", + "0001111010", + "1110000110", + "1101000110", + "1011000110", + "0111000110", + "1100100110", + "1010100110", + "0110100110", + "1001100110", + "0101100110", + "0011100110", + "1100010110", + "1010010110", + "0110010110", + "1001010110", + "0101010110", + "0011010110", + "1000110110", + "0100110110", + "0010110110", + "0001110110", + "1100001110", + "1010001110", + "0110001110", + "1001001110", + "0101001110", + "0011001110", + "1000101110", + "0100101110", + "0010101110", + "0001101110", + "1000011110", + "0100011110", + "0010011110", + "0001011110", + "0000111110", + "1111000001", + "1110100001", + "1101100001", + "1011100001", + "0111100001", + "1110010001", + "1101010001", + "1011010001", + "0111010001", + "1100110001", + "1010110001", + "0110110001", + "1001110001", + "0101110001", + "0011110001", + "1110001001", + "1101001001", + "1011001001", + "0111001001", + "1100101001", + "1010101001", + "0110101001", + "1001101001", + "0101101001", + "0011101001", + "1100011001", + "1010011001", + "0110011001", + "1001011001", + "0101011001", + "0011011001", + "1000111001", + "0100111001", + "0010111001", + "0001111001", + "1110000101", + "1101000101", + "1011000101", + "0111000101", + "1100100101", + "1010100101", + "0110100101", + "1001100101", + "0101100101", + "0011100101", + "1100010101", + "1010010101", + "0110010101", + "1001010101", + "0101010101", + "0011010101", + "1000110101", + "0100110101", + "0010110101", + "0001110101", + "1100001101", + "1010001101", + "0110001101", + "1001001101", + "0101001101", + "0011001101", + "1000101101", + "0100101101", + "0010101101", + "0001101101", + "1000011101", + "0100011101", + "0010011101", + "0001011101", + "0000111101", + "1110000011", + "1101000011", + "1011000011", + "0111000011", + "1100100011", + "1010100011", + "0110100011", + "1001100011", + "0101100011", + "0011100011", + "1100010011", + "1010010011", + "0110010011", + "1001010011", + "0101010011", + "0011010011", + "1000110011", + "0100110011", + "0010110011", + "0001110011", + "1100001011", + "1010001011", + "0110001011", + "1001001011", + "0101001011", + "0011001011", + "1000101011", + "0100101011", + "0010101011", + "0001101011", + "1000011011", + "0100011011", + "0010011011", + "0001011011", + "0000111011", + "1100000111", + "1010000111", + "0110000111", + "1001000111", + "0101000111", + "0011000111", + "1000100111", + "0100100111", + "0010100111", + "0001100111", + "1000010111", + "0100010111", + "0010010111", + "0001010111", + "0000110111", + "1000001111", + "0100001111", + "0010001111", + "0001001111", + "0000101111", + "0000011111", + ] + exact_soutions = {state: -5 for state in exact_states} # Check computed solutions are among the correct ones for solution in solutions: @@ -1293,49 +1848,62 @@ def test_example_4_adaptive_custom(self): def test_rqaoa_asdict_dumps(self): """Test the asdict method of the RQAOA class.""" - #rqaoa - rqaoa = self.__run_rqaoa('custom', return_object=True) + # rqaoa + rqaoa = self.__run_rqaoa("custom", return_object=True) # check RQAOA asdict - self.__test_expected_keys(rqaoa.asdict(), method='asdict') + self.__test_expected_keys(rqaoa.asdict(), method="asdict") # check RQAOA asdict deleting some keys - exclude_keys = ['corr_matrix', 'number_steps'] - self.__test_expected_keys(rqaoa.asdict(exclude_keys=exclude_keys), exclude_keys, method='asdict') + exclude_keys = ["corr_matrix", "number_steps"] + self.__test_expected_keys( + rqaoa.asdict(exclude_keys=exclude_keys), exclude_keys, method="asdict" + ) # check RQAOA dumps - self.__test_expected_keys(json.loads(rqaoa.dumps()), method='dumps') + self.__test_expected_keys(json.loads(rqaoa.dumps()), method="dumps") # check RQAOA dumps deleting some keys - exclude_keys = ['project_id', 'counter'] - self.__test_expected_keys(json.loads(rqaoa.dumps(exclude_keys=exclude_keys)), exclude_keys, method='dumps') + exclude_keys = ["project_id", "counter"] + self.__test_expected_keys( + json.loads(rqaoa.dumps(exclude_keys=exclude_keys)), + exclude_keys, + method="dumps", + ) # check RQAOA dump - file_name = 'test_dump_rqaoa.json' - experiment_id, atomic_id = rqaoa.header['experiment_id'], rqaoa.header['atomic_id'] - full_name = f'{experiment_id}--{atomic_id}--{file_name}' + file_name = "test_dump_rqaoa.json" + experiment_id, atomic_id = ( + rqaoa.header["experiment_id"], + rqaoa.header["atomic_id"], + ) + full_name = f"{experiment_id}--{atomic_id}--{file_name}" rqaoa.dump(file_name, indent=None) - assert os.path.isfile(full_name), 'Dump file does not exist' - with open(full_name, 'r') as file: - assert file.read() == rqaoa.dumps(indent=None), 'Dump file does not contain the correct data' + assert os.path.isfile(full_name), "Dump file does not exist" + with open(full_name, "r") as file: + assert file.read() == rqaoa.dumps( + indent=None + ), "Dump file does not contain the correct data" os.remove(full_name) # check RQAOA dump whitout prepending the experiment_id and atomic_id - rqaoa.dump(file_name, indent=None,prepend_id=False) - assert os.path.isfile(file_name), 'Dump file does not exist, when not prepending the experiment_id and atomic_id' - + rqaoa.dump(file_name, indent=None, prepend_id=False) + assert os.path.isfile( + file_name + ), "Dump file does not exist, when not prepending the experiment_id and atomic_id" + # check RQAOA dump fails when the file already exists error = False try: - rqaoa.dump(file_name, indent=None,prepend_id=False) + rqaoa.dump(file_name, indent=None, prepend_id=False) except FileExistsError: error = True - assert error, 'Dump file does not fail when the file already exists' + assert error, "Dump file does not fail when the file already exists" # check that we can overwrite the file - rqaoa.dump(file_name, indent=None,prepend_id=False, overwrite=True) - assert os.path.isfile(file_name), 'Dump file does not exist, when overwriting' + rqaoa.dump(file_name, indent=None, prepend_id=False, overwrite=True) + assert os.path.isfile(file_name), "Dump file does not exist, when overwriting" os.remove(file_name) # check RQAOA dump fails when prepend_id is True and file_name is not given @@ -1344,47 +1912,177 @@ def test_rqaoa_asdict_dumps(self): rqaoa.dump(prepend_id=False) except ValueError: error = True - assert error, 'Dump file does not fail when prepend_id is True and file_name is not given' + assert ( + error + ), "Dump file does not fail when prepend_id is True and file_name is not given" # check you can dump to a file with no arguments rqaoa.dump() - assert os.path.isfile(f'{experiment_id}--{atomic_id}.json'), 'Dump file does not exist, when no name is given' - os.remove(f'{experiment_id}--{atomic_id}.json') + assert os.path.isfile( + f"{experiment_id}--{atomic_id}.json" + ), "Dump file does not exist, when no name is given" + os.remove(f"{experiment_id}--{atomic_id}.json") # check RQAOA dump deleting some keys - exclude_keys = ['schedule', 'singlet'] + exclude_keys = ["schedule", "singlet"] rqaoa.dump(file_name, exclude_keys=exclude_keys, indent=None) - assert os.path.isfile(full_name), 'Dump file does not exist, when deleting some keys' - with open(full_name, 'r') as file: - assert file.read() == rqaoa.dumps(exclude_keys=exclude_keys, indent=None), 'Dump file does not contain the correct data, when deleting some keys' + assert os.path.isfile( + full_name + ), "Dump file does not exist, when deleting some keys" + with open(full_name, "r") as file: + assert file.read() == rqaoa.dumps( + exclude_keys=exclude_keys, indent=None + ), "Dump file does not contain the correct data, when deleting some keys" os.remove(full_name) # check RQAOA dump with compression rqaoa.dump(file_name, compresslevel=2, indent=None) - assert os.path.isfile(full_name+'.gz'), 'Dump file does not exist, when compressing' - with gzip.open(full_name+'.gz', 'rb') as file: - assert file.read() == rqaoa.dumps(indent=None).encode(), 'Dump file does not contain the correct data, when compressing' - os.remove(full_name+'.gz') - - - def __test_expected_keys(self, obj, exclude_keys=[], method='asdict'): + assert os.path.isfile( + full_name + ".gz" + ), "Dump file does not exist, when compressing" + with gzip.open(full_name + ".gz", "rb") as file: + assert ( + file.read() == rqaoa.dumps(indent=None).encode() + ), "Dump file does not contain the correct data, when compressing" + os.remove(full_name + ".gz") + + def __test_expected_keys(self, obj, exclude_keys=[], method="asdict"): """ method to test if the dictionary has all the expected keys """ - #create a dictionary with all the expected keys and set them to False - expected_keys = ['header', 'atomic_id', 'experiment_id', 'project_id', 'algorithm', 'name', 'run_by', 'provider', 'target', 'cloud', 'client', 'qubit_number', 'qubit_routing', 'error_mitigation', 'error_correction', 'execution_time_start', 'execution_time_end', 'metadata', 'tag1', 'tag2', 'problem_type', 'n_shots', 'optimizer_method', 'param_type', 'init_type', 'p', 'rqaoa_type', 'rqaoa_n_max', 'rqaoa_n_cutoff', 'data', 'exp_tags', 'input_problem', 'terms', 'weights', 'constant', 'n', 'problem_instance', 'input_parameters', 'device', 'device_location', 'device_name', 'backend_properties', 'init_hadamard', 'prepend_state', 'append_state', 'cvar_alpha', 'noise_model', 'qubit_layout', 'seed_simulator', 'qiskit_simulation_method', 'active_reset', 'rewiring', 'disable_qubit_rewiring', 'classical_optimizer', 'optimize', 'method', 'maxiter', 'maxfev', 'jac', 'hess', 'constraints', 'bounds', 'tol', 'optimizer_options', 'jac_options', 'hess_options', 'parameter_log', 'optimization_progress', 'cost_progress', 'save_intermediate', 'circuit_properties', 'qubit_register', 'q', 'variational_params_dict', 'total_annealing_time', 'annealing_time', 'linear_ramp_time', 'mixer_hamiltonian', 'mixer_qubit_connectivity', 'mixer_coeffs', 'seed', 'rqaoa_parameters', 'n_max', 'steps', 'n_cutoff', 'original_hamiltonian', 'counter', 'result', 'solution', 'classical_output', 'minimum_energy', 'optimal_states', 'elimination_rules', 'pair', 'correlation', 'schedule', 'number_steps', 'intermediate_steps', 'problem', 'qaoa_results', 'evals', 'number_of_evals', 'jac_evals', 'qfim_evals', 'most_probable_states', 'solutions_bitstrings', 'bitstring_energy', 'intermediate', 'angles', 'cost', 'measurement_outcomes', 'job_id', 'optimized', 'eval_number', 'exp_vals_z', 'corr_matrix', 'atomic_ids'] + # create a dictionary with all the expected keys and set them to False + expected_keys = [ + "header", + "atomic_id", + "experiment_id", + "project_id", + "algorithm", + "description", + "run_by", + "provider", + "target", + "cloud", + "client", + "qubit_number", + "execution_time_start", + "execution_time_end", + "metadata", + "tag1", + "tag2", + "problem_type", + "n_shots", + "optimizer_method", + "param_type", + "init_type", + "p", + "rqaoa_type", + "rqaoa_n_max", + "rqaoa_n_cutoff", + "data", + "exp_tags", + "input_problem", + "terms", + "weights", + "constant", + "n", + "problem_instance", + "input_parameters", + "device", + "device_location", + "device_name", + "backend_properties", + "init_hadamard", + "prepend_state", + "append_state", + "cvar_alpha", + "noise_model", + "initial_qubit_mapping", + "seed_simulator", + "qiskit_simulation_method", + "active_reset", + "rewiring", + "disable_qubit_rewiring", + "classical_optimizer", + "optimize", + "method", + "maxiter", + "maxfev", + "jac", + "hess", + "constraints", + "bounds", + "tol", + "optimizer_options", + "jac_options", + "hess_options", + "parameter_log", + "optimization_progress", + "cost_progress", + "save_intermediate", + "circuit_properties", + "qubit_register", + "q", + "variational_params_dict", + "total_annealing_time", + "annealing_time", + "linear_ramp_time", + "mixer_hamiltonian", + "mixer_qubit_connectivity", + "mixer_coeffs", + "seed", + "rqaoa_parameters", + "n_max", + "steps", + "n_cutoff", + "original_hamiltonian", + "counter", + "result", + "solution", + "classical_output", + "minimum_energy", + "optimal_states", + "elimination_rules", + "pair", + "correlation", + "schedule", + "number_steps", + "intermediate_steps", + "problem", + "qaoa_results", + "evals", + "number_of_evals", + "jac_evals", + "qfim_evals", + "most_probable_states", + "solutions_bitstrings", + "bitstring_energy", + "intermediate", + "angles", + "cost", + "measurement_outcomes", + "job_id", + "optimized", + "eval_number", + "exp_vals_z", + "corr_matrix", + "atomic_ids", + ] expected_keys = {item: False for item in expected_keys} - #test the keys, it will set the keys to True if they are found + # test the keys, it will set the keys to True if they are found _test_keys_in_dict(obj, expected_keys) # Check if the dictionary has all the expected keys except the ones that were not included for key, value in expected_keys.items(): if key not in exclude_keys: - assert value==True, f'Key {key} not found in the dictionary, when using {method} method.' + assert ( + value == True + ), f'Key "{key}" not found in the dictionary, when using "{method}" method.' else: - assert value==False, f'Key {key} was found in the dictionary, but it should not be there, when using {method} method.' + assert ( + value == False + ), f'Key "{key}" was found in the dictionary, but it should not be there, when using "{method}" method.' """ to get the list of expected keys, run the following code: @@ -1412,72 +2110,112 @@ def test_rqaoa_dumping_step_by_step(self): """ test dumping the RQAOA object step by step """ - + # define the problem problem = QUBO.random_instance(n=8) - problem.set_metadata({'metadata_key1': 'metadata_value1', 'metadata_key2': 'metadata_value2'}) + problem.set_metadata( + {"metadata_key1": "metadata_value1", "metadata_key2": "metadata_value2"} + ) # define the RQAOA object r = RQAOA() # set experimental tags - r.set_exp_tags({'tag1': 'value1', 'tag2': 'value2'}) + r.set_exp_tags({"tag1": "value1", "tag2": "value2"}) # set the classical optimizer - r.set_classical_optimizer(optimization_progress=True) + r.set_classical_optimizer(optimization_progress=True) # compile the problem r.compile(problem) # optimize the problem while dumping the data at each step - r.optimize(dump=True, dump_options={'file_name': 'test_dumping_step_by_step', 'compresslevel': 2, 'indent': None}) + r.optimize( + dump=True, + dump_options={ + "file_name": "test_dumping_step_by_step", + "compresslevel": 2, + "indent": None, + }, + ) # create list of expected file names - experiment_id, atomic_id = r.header['experiment_id'], r.header['atomic_id'] - file_names = {id: experiment_id + '--' + id + '--' + 'test_dumping_step_by_step.json.gz' for id in r.result['atomic_ids'].values()} - file_names[atomic_id] = experiment_id + '--' + atomic_id + '--' + 'test_dumping_step_by_step.json.gz' + experiment_id, atomic_id = r.header["experiment_id"], r.header["atomic_id"] + file_names = { + id: experiment_id + "--" + id + "--" + "test_dumping_step_by_step.json.gz" + for id in r.result["atomic_ids"].values() + } + file_names[atomic_id] = ( + experiment_id + + "--" + + atomic_id + + "--" + + "test_dumping_step_by_step.json.gz" + ) # check if the files exist for file_name in file_names.values(): - assert os.path.isfile(file_name), f'File {file_name} does not exist.' + assert os.path.isfile(file_name), f"File {file_name} does not exist." # put each file in a dictionary files = {} for atomic_id, file_name in file_names.items(): - with gzip.open(file_name, 'rb') as file: + with gzip.open(file_name, "rb") as file: files[atomic_id] = json.loads(file.read().decode()) rqaoa_files, qaoa_files = 0, 0 - + # check if the files have the expected keys for atomic_id, dictionary in files.items(): file_name = file_names[atomic_id] - if r.header['atomic_id'] == atomic_id: # rqaoa files + if r.header["atomic_id"] == atomic_id: # rqaoa files rqaoa_files += 1 - assert dictionary['header']['experiment_id'] == r.header['experiment_id'], f'File {file_name} has a different experiment_id than the RQAOA object.' - assert dictionary['header']['atomic_id'] == r.header['atomic_id'], f'File {file_name} has a different atomic_id than the RQAOA object.' - assert dictionary['header']['algorithm'] == 'rqaoa', f'File {file_name} has a different algorithm than rqaoa, which is the expected algorithm.' - - #check that the intermediate mesuraments are empty - for step in dictionary['data']['result']['intermediate_steps']: - assert step['qaoa_results']['intermediate']['measurement_outcomes'] == [], f'File {file_name} has intermediate mesuraments, but it should not have them.' - - else: # qaoa files + assert ( + dictionary["header"]["experiment_id"] == r.header["experiment_id"] + ), f"File {file_name} has a different experiment_id than the RQAOA object." + assert ( + dictionary["header"]["atomic_id"] == r.header["atomic_id"] + ), f"File {file_name} has a different atomic_id than the RQAOA object." + assert ( + dictionary["header"]["algorithm"] == "rqaoa" + ), f"File {file_name} has a different algorithm than rqaoa, which is the expected algorithm." + + # check that the intermediate mesuraments are empty + for step in dictionary["data"]["result"]["intermediate_steps"]: + assert ( + step["qaoa_results"]["intermediate"]["measurement_outcomes"] + == [] + ), f"File {file_name} has intermediate mesuraments, but it should not have them." + + else: # qaoa files qaoa_files += 1 - assert dictionary['header']['atomic_id'] == atomic_id, f'File {file_name} has a different atomic_id than expected.' - assert dictionary['header']['algorithm'] == 'qaoa', f'File {file_name} has a different algorithm than qaoa, which is the expected algorithm.' - - #check that the intermediate mesuraments are not empty - assert len(dictionary['data']['result']['intermediate']['measurement_outcomes']) > 0, f'File {file_name} does not have intermediate mesuraments, but it should have them.' - - assert rqaoa_files == 1, f'Expected 1 rqaoa file, but {rqaoa_files} were found.' - assert qaoa_files == len(r.result['atomic_ids']), f'Expected {len(r.result["atomic_ids"])} qaoa files, but {qaoa_files} were found.' + assert ( + dictionary["header"]["atomic_id"] == atomic_id + ), f"File {file_name} has a different atomic_id than expected." + assert ( + dictionary["header"]["algorithm"] == "qaoa" + ), f"File {file_name} has a different algorithm than qaoa, which is the expected algorithm." + + # check that the intermediate mesuraments are not empty + assert ( + len( + dictionary["data"]["result"]["intermediate"][ + "measurement_outcomes" + ] + ) + > 0 + ), f"File {file_name} does not have intermediate mesuraments, but it should have them." + + assert rqaoa_files == 1, f"Expected 1 rqaoa file, but {rqaoa_files} were found." + assert qaoa_files == len( + r.result["atomic_ids"] + ), f'Expected {len(r.result["atomic_ids"])} qaoa files, but {qaoa_files} were found.' # erease the files for file_name in file_names.values(): @@ -1490,43 +2228,47 @@ def test_rqaoa_from_dict_and_load(self): """ # problem - maxcut_qubo = MaximumCut( - nw.generators.fast_gnp_random_graph(n=6,p=0.6, seed=42) - ).qubo + maxcut_qubo = MaximumCut( + nw.generators.fast_gnp_random_graph(n=6, p=0.6, seed=42) + ).qubo # run rqaoa with different devices, and save the objcets in a list rqaoas = [] - for device in [create_device(location='local', name='qiskit.shot_simulator'), create_device(location='local', name='vectorized')]: + for device in [ + create_device(location="local", name="qiskit.shot_simulator"), + create_device(location="local", name="vectorized"), + ]: r = RQAOA() r.set_device(device) - r.set_circuit_properties(p=1, param_type='extended', init_type='rand', mixer_hamiltonian='x') + r.set_circuit_properties( + p=1, param_type="extended", init_type="rand", mixer_hamiltonian="x" + ) r.set_backend_properties(n_shots=50) r.set_classical_optimizer(maxiter=10, optimization_progress=True) - r.set_rqaoa_parameters(rqaoa_type='adaptive', n_cutoff=3) - r.set_exp_tags({'tag1': 'value1', 'tag2': 'value2'}) + r.set_rqaoa_parameters(rqaoa_type="adaptive", n_cutoff=3) + r.set_exp_tags({"tag1": "value1", "tag2": "value2"}) r.set_header( - project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", - name="test", - run_by="raul", - provider="-", - target="-", - cloud="local", - client="-", - qubit_routing="-", - error_mitigation="-", - error_correction="-" + project_id="8353185c-b175-4eda-9628-b4e58cb0e41b", + description="test", + run_by="raul", + provider="-", + target="-", + cloud="local", + client="-", ) # test that you can convert the rqaoa object to a dictionary and then load it before optimization _ = RQAOA.from_dict(r.asdict()) _.compile(maxcut_qubo) _.optimize() - assert isinstance(_, RQAOA), 'The object loaded from a dictionary is not an RQAOA object.' + assert isinstance( + _, RQAOA + ), "The object loaded from a dictionary is not an RQAOA object." # compile and optimize the original rqaoa object - r.compile(maxcut_qubo) - r.optimize() + r.compile(maxcut_qubo) + r.optimize() rqaoas.append(r) @@ -1535,18 +2277,18 @@ def test_rqaoa_from_dict_and_load(self): new_r_list = [] - #get new qaoa from dict + # get new qaoa from dict new_r_list.append(RQAOA.from_dict(r.asdict())) - #get new qaoa from json string + # get new qaoa from json string new_r_list.append(RQAOA.loads(r.dumps())) - #get new qaoa from json file + # get new qaoa from json file r.dump("test.json", prepend_id=False) new_r_list.append(RQAOA.load("test.json")) - os.remove("test.json") #delete file test.json - #get new qaoa from compressed json file + os.remove("test.json") # delete file test.json + # get new qaoa from compressed json file r.dump("test.json", prepend_id=False, compresslevel=3) new_r_list.append(RQAOA.load("test.json.gz")) - os.remove("test.json.gz") #delete file test.json + os.remove("test.json.gz") # delete file test.json for new_r in new_r_list: @@ -1554,11 +2296,20 @@ def test_rqaoa_from_dict_and_load(self): assert isinstance(new_r, RQAOA), "new_r is not an RQAOA object" # check that the attributes of the new object are of the correct type - attributes_types = [ ("header", dict), ("exp_tags", dict), ("problem", QUBO), ("result", RQAOAResult), - ("backend_properties", BackendProperties), ("classical_optimizer", ClassicalOptimizer), - ("circuit_properties", CircuitProperties), ("rqaoa_parameters", RqaoaParameters) ] + attributes_types = [ + ("header", dict), + ("exp_tags", dict), + ("problem", QUBO), + ("result", RQAOAResult), + ("backend_properties", BackendProperties), + ("classical_optimizer", ClassicalOptimizer), + ("circuit_properties", CircuitProperties), + ("rqaoa_parameters", RqaoaParameters), + ] for attribute, type_ in attributes_types: - assert isinstance(getattr(new_r, attribute), type_), f"attribute {attribute} is not type {type_}" + assert isinstance( + getattr(new_r, attribute), type_ + ), f"attribute {attribute} is not type {type_}" # get the two objects (old and new) as dictionaries r_asdict = r.asdict() @@ -1571,19 +2322,35 @@ def test_rqaoa_from_dict_and_load(self): elif key == "data": for key2, value2 in value.items(): - if key2 == "input_parameters": - #pop key device + if key2 == "input_parameters": + # pop key device value2.pop("device") new_r_asdict[key][key2].pop("device") if key2 == "result": - for step in range(len(value2['intermediate_steps'])): - for key3 in value2['intermediate_steps'][step].keys(): + for step in range(len(value2["intermediate_steps"])): + for key3 in value2["intermediate_steps"][ + step + ].keys(): if key3 == "qaoa_results": - _compare_qaoa_results(value2['intermediate_steps'][step]['qaoa_results'], new_r_asdict[key][key2]['intermediate_steps'][step]['qaoa_results']) + _compare_qaoa_results( + value2["intermediate_steps"][step][ + "qaoa_results" + ], + new_r_asdict[key][key2][ + "intermediate_steps" + ][step]["qaoa_results"], + ) else: - assert value2['intermediate_steps'][step][key3] == new_r_asdict[key][key2]['intermediate_steps'][step][key3], f"{key3} is not the same" + assert ( + value2["intermediate_steps"][step][key3] + == new_r_asdict[key][key2][ + "intermediate_steps" + ][step][key3] + ), f"{key3} is not the same" else: - assert value2==new_r_asdict[key][key2], "{} not the same".format(key2) + assert ( + value2 == new_r_asdict[key][key2] + ), "{} not the same".format(key2) # compile and optimize the new rqaoa, to check if everything is working new_r.compile(maxcut_qubo) @@ -1595,7 +2362,10 @@ def test_rqaoa_from_dict_and_load(self): Workflow.from_dict(r.asdict()) except Exception: error = True - assert error, "Optimizer.from_dict should raise an error when using a RQAOA dictionary" + assert ( + error + ), "Optimizer.from_dict should raise an error when using a RQAOA dictionary" + -if __name__ == '__main__': +if __name__ == "__main__": unittest.main()