diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index e1bd031..aff4598 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -12,9 +12,8 @@ jobs: strategy: matrix: #os: [ubuntu-latest, macos-latest] - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] os: [ ubuntu-latest, macos-latest, windows-latest] -# # python: [ "3.7", "3.8", "3.9", "3.10", '3.11'] TODO: add more python versions steps: - uses: actions/checkout@v3 diff --git a/docs/source/conf.py b/docs/source/conf.py index d82e5b3..11e1f39 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -17,9 +17,9 @@ # -- Project information ----------------------------------------------------- -project = 'Symmer' -copyright = '2023, Alexis Ralli, Tim Weaving' -author = 'Alexis Ralli, Tim Weaving' +project = "Symmer" +copyright = "2023, Alexis Ralli, Tim Weaving" +author = "Alexis Ralli, Tim Weaving" # -- General configuration --------------------------------------------------- @@ -28,14 +28,14 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.intersphinx', - 'sphinx.ext.extlinks', - 'sphinx.ext.napoleon', - 'sphinx.ext.linkcode', - 'myst_nb', + "sphinx.ext.intersphinx", + "sphinx.ext.extlinks", + "sphinx.ext.napoleon", + "sphinx.ext.linkcode", + "myst_nb", "sphinx_design", - 'sphinx_copybutton' -# 'autoapi.extension', + "sphinx_copybutton" + # 'autoapi.extension', ] # msyt_nb configuration @@ -50,7 +50,7 @@ ] # 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. @@ -63,17 +63,18 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = "alabaster" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] + def linkcode_resolve(domain, info): - if domain != 'py': + if domain != "py": return None - if not info['module']: + if not info["module"]: return None - filename = info['module'].replace('.', '/') + filename = info["module"].replace(".", "/") return "https://somesite/sourcerepo/%s.py" % filename diff --git a/poetry.lock b/poetry.lock index cf6569b..b762179 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -19,7 +18,6 @@ frozenlist = ">=1.1.0" name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -31,7 +29,6 @@ files = [ name = "appnope" version = "0.1.3" description = "Disable App Nap on macOS >= 10.9" -category = "main" optional = false python-versions = "*" files = [ @@ -43,7 +40,6 @@ files = [ name = "asttokens" version = "2.4.0" description = "Annotate AST trees with source code positions" -category = "main" optional = false python-versions = "*" files = [ @@ -61,7 +57,6 @@ test = ["astroid", "pytest"] name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -80,7 +75,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "autoray" version = "0.6.6" description = "Abstract your array operations." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -94,24 +88,25 @@ tests = ["coverage", "numpy", "pytest", "pytest-cov"] [[package]] name = "babel" -version = "2.12.1" +version = "2.13.0" description = "Internationalization utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, - {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, + {file = "Babel-2.13.0-py3-none-any.whl", hash = "sha256:fbfcae1575ff78e26c7449136f1abbefc3c13ce542eeb13d43d50d8b047216ec"}, + {file = "Babel-2.13.0.tar.gz", hash = "sha256:04c3e2d28d2b7681644508f836be388ae49e0cfe91465095340395b60d00f210"}, ] [package.dependencies] pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + [[package]] name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" -category = "main" optional = false python-versions = "*" files = [ @@ -123,7 +118,6 @@ files = [ name = "black" version = "22.12.0" description = "The uncompromising code formatter." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -155,11 +149,54 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "build" +version = "0.10.0" +description = "A simple, correct Python build frontend" +optional = false +python-versions = ">= 3.7" +files = [ + {file = "build-0.10.0-py3-none-any.whl", hash = "sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171"}, + {file = "build-0.10.0.tar.gz", hash = "sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "os_name == \"nt\""} +packaging = ">=19.0" +pyproject_hooks = "*" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + +[package.extras] +docs = ["furo (>=2021.08.31)", "sphinx (>=4.0,<5.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)"] +test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "toml (>=0.10.0)", "wheel (>=0.36.0)"] +typing = ["importlib-metadata (>=5.1)", "mypy (==0.991)", "tomli", "typing-extensions (>=3.7.4.3)"] +virtualenv = ["virtualenv (>=20.0.35)"] + +[[package]] +name = "cachecontrol" +version = "0.13.1" +description = "httplib2 caching for requests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"}, + {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"}, +] + +[package.dependencies] +filelock = {version = ">=3.8.0", optional = true, markers = "extra == \"filecache\""} +msgpack = ">=0.5.2" +requests = ">=2.16.0" + +[package.extras] +dev = ["CacheControl[filecache,redis]", "black", "build", "cherrypy", "mypy", "pytest", "pytest-cov", "sphinx", "tox", "types-redis", "types-requests"] +filecache = ["filelock (>=3.8.0)"] +redis = ["redis (>=2.10.5)"] + [[package]] name = "cached-property" version = "1.5.2" description = "A decorator for caching properties in classes." -category = "main" optional = false python-versions = "*" files = [ @@ -171,7 +208,6 @@ files = [ name = "cachetools" version = "5.3.1" description = "Extensible memoizing collections and decorators" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -183,7 +219,6 @@ files = [ name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -193,76 +228,63 @@ files = [ [[package]] name = "cffi" -version = "1.15.1" +version = "1.16.0" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, ] [package.dependencies] @@ -270,94 +292,107 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.2.0" +version = "3.3.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-win32.whl", hash = "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-win32.whl", hash = "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"}, + {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"}, ] [[package]] name = "cirq-core" version = "1.1.0" description = "A framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -383,7 +418,6 @@ contrib = ["autoray", "numba (>=0.53.0)", "opt-einsum", "ply (>=3.6)", "pylatex name = "cirq-google" version = "1.1.0" description = "The Cirq module that provides tools and access to the Google Quantum Computing Service" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -396,11 +430,25 @@ google-api-core = {version = ">=1.14.0,<2.0.0dev", extras = ["grpc"]} proto-plus = ">=1.20.0" protobuf = ">=3.15.0,<4" +[[package]] +name = "cleo" +version = "2.0.1" +description = "Cleo allows you to create beautiful and testable command-line interfaces." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "cleo-2.0.1-py3-none-any.whl", hash = "sha256:6eb133670a3ed1f3b052d53789017b6e50fca66d1287e6e6696285f4cb8ea448"}, + {file = "cleo-2.0.1.tar.gz", hash = "sha256:eb4b2e1f3063c11085cebe489a6e9124163c226575a3c3be69b2e51af4a15ec5"}, +] + +[package.dependencies] +crashtest = ">=0.4.1,<0.5.0" +rapidfuzz = ">=2.2.0,<3.0.0" + [[package]] name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -415,7 +463,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -427,7 +474,6 @@ files = [ name = "comm" version = "0.1.4" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -447,7 +493,6 @@ typing = ["mypy (>=0.990)"] name = "contourpy" version = "1.1.0" description = "Python library for calculating contours of 2D quadrilateral grids" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -458,6 +503,7 @@ files = [ {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18a64814ae7bce73925131381603fff0116e2df25230dfc80d6d690aa6e20b37"}, {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90c81f22b4f572f8a2110b0b741bb64e5a6427e0a198b2cdc1fbaf85f352a3aa"}, {file = "contourpy-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53cc3a40635abedbec7f1bde60f8c189c49e84ac180c665f2cd7c162cc454baa"}, + {file = "contourpy-1.1.0-cp310-cp310-win32.whl", hash = "sha256:9b2dd2ca3ac561aceef4c7c13ba654aaa404cf885b187427760d7f7d4c57cff8"}, {file = "contourpy-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f795597073b09d631782e7245016a4323cf1cf0b4e06eef7ea6627e06a37ff2"}, {file = "contourpy-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0b7b04ed0961647691cfe5d82115dd072af7ce8846d31a5fac6c142dcce8b882"}, {file = "contourpy-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27bc79200c742f9746d7dd51a734ee326a292d77e7d94c8af6e08d1e6c15d545"}, @@ -466,6 +512,7 @@ files = [ {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5cec36c5090e75a9ac9dbd0ff4a8cf7cecd60f1b6dc23a374c7d980a1cd710e"}, {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0cbd657e9bde94cd0e33aa7df94fb73c1ab7799378d3b3f902eb8eb2e04a3a"}, {file = "contourpy-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:181cbace49874f4358e2929aaf7ba84006acb76694102e88dd15af861996c16e"}, + {file = "contourpy-1.1.0-cp311-cp311-win32.whl", hash = "sha256:edb989d31065b1acef3828a3688f88b2abb799a7db891c9e282df5ec7e46221b"}, {file = "contourpy-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb3b7d9e6243bfa1efb93ccfe64ec610d85cfe5aec2c25f97fbbd2e58b531256"}, {file = "contourpy-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcb41692aa09aeb19c7c213411854402f29f6613845ad2453d30bf421fe68fed"}, {file = "contourpy-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d123a5bc63cd34c27ff9c7ac1cd978909e9c71da12e05be0231c608048bb2ae"}, @@ -474,6 +521,7 @@ files = [ {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317267d915490d1e84577924bd61ba71bf8681a30e0d6c545f577363157e5e94"}, {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d551f3a442655f3dcc1285723f9acd646ca5858834efeab4598d706206b09c9f"}, {file = "contourpy-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e7a117ce7df5a938fe035cad481b0189049e8d92433b4b33aa7fc609344aafa1"}, + {file = "contourpy-1.1.0-cp38-cp38-win32.whl", hash = "sha256:108dfb5b3e731046a96c60bdc46a1a0ebee0760418951abecbe0fc07b5b93b27"}, {file = "contourpy-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4f26b25b4f86087e7d75e63212756c38546e70f2a92d2be44f80114826e1cd4"}, {file = "contourpy-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc00bb4225d57bff7ebb634646c0ee2a1298402ec10a5fe7af79df9a51c1bfd9"}, {file = "contourpy-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:189ceb1525eb0655ab8487a9a9c41f42a73ba52d6789754788d1883fb06b2d8a"}, @@ -482,6 +530,7 @@ files = [ {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:143dde50520a9f90e4a2703f367cf8ec96a73042b72e68fcd184e1279962eb6f"}, {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e94bef2580e25b5fdb183bf98a2faa2adc5b638736b2c0a4da98691da641316a"}, {file = "contourpy-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ed614aea8462735e7d70141374bd7650afd1c3f3cb0c2dbbcbe44e14331bf002"}, + {file = "contourpy-1.1.0-cp39-cp39-win32.whl", hash = "sha256:71551f9520f008b2950bef5f16b0e3587506ef4f23c734b71ffb7b89f8721999"}, {file = "contourpy-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:438ba416d02f82b692e371858143970ed2eb6337d9cdbbede0d8ad9f3d7dd17d"}, {file = "contourpy-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a698c6a7a432789e587168573a864a7ea374c6be8d4f31f9d87c001d5a843493"}, {file = "contourpy-1.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397b0ac8a12880412da3551a8cb5a187d3298a72802b45a3bd1805e204ad8439"}, @@ -502,23 +551,152 @@ mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.2.0)", "types-Pill test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] test-no-images = ["pytest", "pytest-cov", "wurlitzer"] +[[package]] +name = "contourpy" +version = "1.1.1" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.8" +files = [ + {file = "contourpy-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:46e24f5412c948d81736509377e255f6040e94216bf1a9b5ea1eaa9d29f6ec1b"}, + {file = "contourpy-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e48694d6a9c5a26ee85b10130c77a011a4fedf50a7279fa0bdaf44bafb4299d"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66045af6cf00e19d02191ab578a50cb93b2028c3eefed999793698e9ea768ae"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ebf42695f75ee1a952f98ce9775c873e4971732a87334b099dde90b6af6a916"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6aec19457617ef468ff091669cca01fa7ea557b12b59a7908b9474bb9674cf0"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:462c59914dc6d81e0b11f37e560b8a7c2dbab6aca4f38be31519d442d6cde1a1"}, + {file = "contourpy-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6d0a8efc258659edc5299f9ef32d8d81de8b53b45d67bf4bfa3067f31366764d"}, + {file = "contourpy-1.1.1-cp310-cp310-win32.whl", hash = "sha256:d6ab42f223e58b7dac1bb0af32194a7b9311065583cc75ff59dcf301afd8a431"}, + {file = "contourpy-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:549174b0713d49871c6dee90a4b499d3f12f5e5f69641cd23c50a4542e2ca1eb"}, + {file = "contourpy-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:407d864db716a067cc696d61fa1ef6637fedf03606e8417fe2aeed20a061e6b2"}, + {file = "contourpy-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe80c017973e6a4c367e037cb31601044dd55e6bfacd57370674867d15a899b"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e30aaf2b8a2bac57eb7e1650df1b3a4130e8d0c66fc2f861039d507a11760e1b"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3de23ca4f381c3770dee6d10ead6fff524d540c0f662e763ad1530bde5112532"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:566f0e41df06dfef2431defcfaa155f0acfa1ca4acbf8fd80895b1e7e2ada40e"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04c2f0adaf255bf756cf08ebef1be132d3c7a06fe6f9877d55640c5e60c72c5"}, + {file = "contourpy-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d0c188ae66b772d9d61d43c6030500344c13e3f73a00d1dc241da896f379bb62"}, + {file = "contourpy-1.1.1-cp311-cp311-win32.whl", hash = "sha256:0683e1ae20dc038075d92e0e0148f09ffcefab120e57f6b4c9c0f477ec171f33"}, + {file = "contourpy-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:8636cd2fc5da0fb102a2504fa2c4bea3cbc149533b345d72cdf0e7a924decc45"}, + {file = "contourpy-1.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:560f1d68a33e89c62da5da4077ba98137a5e4d3a271b29f2f195d0fba2adcb6a"}, + {file = "contourpy-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24216552104ae8f3b34120ef84825400b16eb6133af2e27a190fdc13529f023e"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56de98a2fb23025882a18b60c7f0ea2d2d70bbbcfcf878f9067234b1c4818442"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:07d6f11dfaf80a84c97f1a5ba50d129d9303c5b4206f776e94037332e298dda8"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1eaac5257a8f8a047248d60e8f9315c6cff58f7803971170d952555ef6344a7"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19557fa407e70f20bfaba7d55b4d97b14f9480856c4fb65812e8a05fe1c6f9bf"}, + {file = "contourpy-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:081f3c0880712e40effc5f4c3b08feca6d064cb8cfbb372ca548105b86fd6c3d"}, + {file = "contourpy-1.1.1-cp312-cp312-win32.whl", hash = "sha256:059c3d2a94b930f4dafe8105bcdc1b21de99b30b51b5bce74c753686de858cb6"}, + {file = "contourpy-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f44d78b61740e4e8c71db1cf1fd56d9050a4747681c59ec1094750a658ceb970"}, + {file = "contourpy-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:70e5a10f8093d228bb2b552beeb318b8928b8a94763ef03b858ef3612b29395d"}, + {file = "contourpy-1.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8394e652925a18ef0091115e3cc191fef350ab6dc3cc417f06da66bf98071ae9"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bd5680f844c3ff0008523a71949a3ff5e4953eb7701b28760805bc9bcff217"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66544f853bfa85c0d07a68f6c648b2ec81dafd30f272565c37ab47a33b220684"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0c02b75acfea5cab07585d25069207e478d12309557f90a61b5a3b4f77f46ce"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41339b24471c58dc1499e56783fedc1afa4bb018bcd035cfb0ee2ad2a7501ef8"}, + {file = "contourpy-1.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f29fb0b3f1217dfe9362ec55440d0743fe868497359f2cf93293f4b2701b8251"}, + {file = "contourpy-1.1.1-cp38-cp38-win32.whl", hash = "sha256:f9dc7f933975367251c1b34da882c4f0e0b2e24bb35dc906d2f598a40b72bfc7"}, + {file = "contourpy-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:498e53573e8b94b1caeb9e62d7c2d053c263ebb6aa259c81050766beb50ff8d9"}, + {file = "contourpy-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ba42e3810999a0ddd0439e6e5dbf6d034055cdc72b7c5c839f37a7c274cb4eba"}, + {file = "contourpy-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c06e4c6e234fcc65435223c7b2a90f286b7f1b2733058bdf1345d218cc59e34"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca6fab080484e419528e98624fb5c4282148b847e3602dc8dbe0cb0669469887"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93df44ab351119d14cd1e6b52a5063d3336f0754b72736cc63db59307dabb718"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eafbef886566dc1047d7b3d4b14db0d5b7deb99638d8e1be4e23a7c7ac59ff0f"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efe0fab26d598e1ec07d72cf03eaeeba8e42b4ecf6b9ccb5a356fde60ff08b85"}, + {file = "contourpy-1.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f08e469821a5e4751c97fcd34bcb586bc243c39c2e39321822060ba902eac49e"}, + {file = "contourpy-1.1.1-cp39-cp39-win32.whl", hash = "sha256:bfc8a5e9238232a45ebc5cb3bfee71f1167064c8d382cadd6076f0d51cff1da0"}, + {file = "contourpy-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:c84fdf3da00c2827d634de4fcf17e3e067490c4aea82833625c4c8e6cdea0887"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:229a25f68046c5cf8067d6d6351c8b99e40da11b04d8416bf8d2b1d75922521e"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10dab5ea1bd4401c9483450b5b0ba5416be799bbd50fc7a6cc5e2a15e03e8a3"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f9147051cb8fdb29a51dc2482d792b3b23e50f8f57e3720ca2e3d438b7adf23"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a75cc163a5f4531a256f2c523bd80db509a49fc23721b36dd1ef2f60ff41c3cb"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b53d5769aa1f2d4ea407c65f2d1d08002952fac1d9e9d307aa2e1023554a163"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11b836b7dbfb74e049c302bbf74b4b8f6cb9d0b6ca1bf86cfa8ba144aedadd9c"}, + {file = "contourpy-1.1.1.tar.gz", hash = "sha256:96ba37c2e24b7212a77da85004c38e7c4d155d3e72a45eeaf22c1f03f607e8ab"}, +] + +[package.dependencies] +numpy = {version = ">=1.16,<2.0", markers = "python_version <= \"3.11\""} + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.4.1)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "wurlitzer"] + +[[package]] +name = "crashtest" +version = "0.4.1" +description = "Manage Python errors with ease" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"}, + {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"}, +] + +[[package]] +name = "cryptography" +version = "41.0.4" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839"}, + {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f"}, + {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714"}, + {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb"}, + {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13"}, + {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143"}, + {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397"}, + {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860"}, + {file = "cryptography-41.0.4-cp37-abi3-win32.whl", hash = "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd"}, + {file = "cryptography-41.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d"}, + {file = "cryptography-41.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67"}, + {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e"}, + {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829"}, + {file = "cryptography-41.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca"}, + {file = "cryptography-41.0.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d"}, + {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac"}, + {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9"}, + {file = "cryptography-41.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f"}, + {file = "cryptography-41.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91"}, + {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8"}, + {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6"}, + {file = "cryptography-41.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311"}, + {file = "cryptography-41.0.4.tar.gz", hash = "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a"}, +] + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +nox = ["nox"] +pep8test = ["black", "check-sdist", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + [[package]] name = "cycler" -version = "0.11.0" +version = "0.12.0" description = "Composable style cycles" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, + {file = "cycler-0.12.0-py3-none-any.whl", hash = "sha256:7896994252d006771357777d0251f3e34d266f4fa5f2c572247a80ab01440947"}, + {file = "cycler-0.12.0.tar.gz", hash = "sha256:8cc3a7b4861f91b1095157f9916f748549a617046e67eb7619abed9b34d2c94a"}, ] +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + [[package]] name = "cytoolz" version = "0.12.2" description = "Cython implementation of Toolz: High performance functional utilities" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -625,37 +803,35 @@ cython = ["cython"] [[package]] name = "debugpy" -version = "1.6.7.post1" +version = "1.8.0" description = "An implementation of the Debug Adapter Protocol for Python" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "debugpy-1.6.7.post1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:903bd61d5eb433b6c25b48eae5e23821d4c1a19e25c9610205f5aeaccae64e32"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d16882030860081e7dd5aa619f30dec3c2f9a421e69861125f83cc372c94e57d"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-win32.whl", hash = "sha256:eea8d8cfb9965ac41b99a61f8e755a8f50e9a20330938ad8271530210f54e09c"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-win_amd64.whl", hash = "sha256:85969d864c45f70c3996067cfa76a319bae749b04171f2cdeceebe4add316155"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:890f7ab9a683886a0f185786ffbda3b46495c4b929dab083b8c79d6825832a52"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4ac7a4dba28801d184b7fc0e024da2635ca87d8b0a825c6087bb5168e3c0d28"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-win32.whl", hash = "sha256:3370ef1b9951d15799ef7af41f8174194f3482ee689988379763ef61a5456426"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:65b28435a17cba4c09e739621173ff90c515f7b9e8ea469b92e3c28ef8e5cdfb"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:92b6dae8bfbd497c90596bbb69089acf7954164aea3228a99d7e43e5267f5b36"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72f5d2ecead8125cf669e62784ef1e6300f4067b0f14d9f95ee00ae06fc7c4f7"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-win32.whl", hash = "sha256:f0851403030f3975d6e2eaa4abf73232ab90b98f041e3c09ba33be2beda43fcf"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-win_amd64.whl", hash = "sha256:3de5d0f97c425dc49bce4293df6a04494309eedadd2b52c22e58d95107e178d9"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:38651c3639a4e8bbf0ca7e52d799f6abd07d622a193c406be375da4d510d968d"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038c51268367c9c935905a90b1c2d2dbfe304037c27ba9d19fe7409f8cdc710c"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-win32.whl", hash = "sha256:4b9eba71c290852f959d2cf8a03af28afd3ca639ad374d393d53d367f7f685b2"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-win_amd64.whl", hash = "sha256:973a97ed3b434eab0f792719a484566c35328196540676685c975651266fccf9"}, - {file = "debugpy-1.6.7.post1-py2.py3-none-any.whl", hash = "sha256:1093a5c541af079c13ac8c70ab8b24d1d35c8cacb676306cf11e57f699c02926"}, - {file = "debugpy-1.6.7.post1.zip", hash = "sha256:fe87ec0182ef624855d05e6ed7e0b7cb1359d2ffa2a925f8ec2d22e98b75d0ca"}, + {file = "debugpy-1.8.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7fb95ca78f7ac43393cd0e0f2b6deda438ec7c5e47fa5d38553340897d2fbdfb"}, + {file = "debugpy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef9ab7df0b9a42ed9c878afd3eaaff471fce3fa73df96022e1f5c9f8f8c87ada"}, + {file = "debugpy-1.8.0-cp310-cp310-win32.whl", hash = "sha256:a8b7a2fd27cd9f3553ac112f356ad4ca93338feadd8910277aff71ab24d8775f"}, + {file = "debugpy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:5d9de202f5d42e62f932507ee8b21e30d49aae7e46d5b1dd5c908db1d7068637"}, + {file = "debugpy-1.8.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:ef54404365fae8d45cf450d0544ee40cefbcb9cb85ea7afe89a963c27028261e"}, + {file = "debugpy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60009b132c91951354f54363f8ebdf7457aeb150e84abba5ae251b8e9f29a8a6"}, + {file = "debugpy-1.8.0-cp311-cp311-win32.whl", hash = "sha256:8cd0197141eb9e8a4566794550cfdcdb8b3db0818bdf8c49a8e8f8053e56e38b"}, + {file = "debugpy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:a64093656c4c64dc6a438e11d59369875d200bd5abb8f9b26c1f5f723622e153"}, + {file = "debugpy-1.8.0-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:b05a6b503ed520ad58c8dc682749113d2fd9f41ffd45daec16e558ca884008cd"}, + {file = "debugpy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c6fb41c98ec51dd010d7ed650accfd07a87fe5e93eca9d5f584d0578f28f35f"}, + {file = "debugpy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:46ab6780159eeabb43c1495d9c84cf85d62975e48b6ec21ee10c95767c0590aa"}, + {file = "debugpy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:bdc5ef99d14b9c0fcb35351b4fbfc06ac0ee576aeab6b2511702e5a648a2e595"}, + {file = "debugpy-1.8.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:61eab4a4c8b6125d41a34bad4e5fe3d2cc145caecd63c3fe953be4cc53e65bf8"}, + {file = "debugpy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:125b9a637e013f9faac0a3d6a82bd17c8b5d2c875fb6b7e2772c5aba6d082332"}, + {file = "debugpy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:57161629133113c97b387382045649a2b985a348f0c9366e22217c87b68b73c6"}, + {file = "debugpy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:e3412f9faa9ade82aa64a50b602544efcba848c91384e9f93497a458767e6926"}, + {file = "debugpy-1.8.0-py2.py3-none-any.whl", hash = "sha256:9c9b0ac1ce2a42888199df1a1906e45e6f3c9555497643a85e0bf2406e3ffbc4"}, + {file = "debugpy-1.8.0.zip", hash = "sha256:12af2c55b419521e33d5fb21bd022df0b5eb267c3e178f1d374a63a2a6bdccd0"}, ] [[package]] name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -667,7 +843,6 @@ files = [ name = "deprecation" version = "2.1.0" description = "A library to handle automated deprecations" -category = "main" optional = false python-versions = "*" files = [ @@ -682,7 +857,6 @@ packaging = "*" name = "dill" version = "0.3.7" description = "serialize all of Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -693,11 +867,21 @@ files = [ [package.extras] graph = ["objgraph (>=1.7.2)"] +[[package]] +name = "distlib" +version = "0.3.7" +description = "Distribution utilities" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, + {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, +] + [[package]] name = "docutils" version = "0.19" description = "Docutils -- Python Documentation Utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -709,7 +893,6 @@ files = [ name = "duet" version = "0.2.8" description = "A simple future-based async library for python." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -718,13 +901,86 @@ files = [ ] [package.extras] -dev-env = ["black (==22.3.0)", "isort (>=5.7.0,<5.8.0)", "mypy (>=0.931.0,<0.932.0)", "pylint (>=2.10.0,<2.11.0)", "pytest (>=6.2.0,<6.3.0)", "twine (>=3.3.0,<3.4.0)"] +dev-env = ["black (==22.3.0)", "isort (==5.7.*)", "mypy (==0.931.*)", "pylint (==2.10.*)", "pytest (==6.2.*)", "twine (==3.3.*)"] + +[[package]] +name = "dulwich" +version = "0.21.6" +description = "Python Git Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "dulwich-0.21.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7f89bee4c97372e8aaf8ffaf5899f1bcd5184b5306d7eaf68738c1101ceba10e"}, + {file = "dulwich-0.21.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:847bb52562a211b596453a602e75739350c86d7edb846b5b1c46896a5c86b9bb"}, + {file = "dulwich-0.21.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4e09d0b4e985b371aa6728773781b19298d361a00772e20f98522868cf7edc6f"}, + {file = "dulwich-0.21.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dfb50b3915e223a97f50fbac0dbc298d5fffeaac004eeeb3d552c57fe38416f"}, + {file = "dulwich-0.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a64eca1601e79c16df78afe08da9ac9497b934cbc5765990ca7d89a4b87453d9"}, + {file = "dulwich-0.21.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1fedd924763a5d640348db43a267a394aa80d551228ad45708e0b0cc2130bb62"}, + {file = "dulwich-0.21.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:edc21c3784dd9d9b85abd9fe53f81a884e2cdcc4e5e09ada17287420d64cfd46"}, + {file = "dulwich-0.21.6-cp310-cp310-win32.whl", hash = "sha256:daa3584beabfcf0da76df57535a23c80ff6d8ccde6ddbd23bdc79d317a0e20a7"}, + {file = "dulwich-0.21.6-cp310-cp310-win_amd64.whl", hash = "sha256:40623cc39a3f1634663d22d87f86e2e406cc8ff17ae7a3edc7fcf963c288992f"}, + {file = "dulwich-0.21.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e8ed878553f0b76facbb620b455fafa0943162fe8e386920717781e490444efa"}, + {file = "dulwich-0.21.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a89b19f4960e759915dbc23a4dd0abc067b55d8d65e9df50961b73091b87b81a"}, + {file = "dulwich-0.21.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28acbd08d6b38720d99cc01da9dd307a2e0585e00436c95bcac6357b9a9a6f76"}, + {file = "dulwich-0.21.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2f2683e0598f7c7071ef08a0822f062d8744549a0d45f2c156741033b7e3d7d"}, + {file = "dulwich-0.21.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54342cf96fe8a44648505c65f23d18889595762003a168d67d7263df66143bd2"}, + {file = "dulwich-0.21.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2a3fc071e5b14f164191286f7ffc02f60fe8b439d01fad0832697cc08c2237dd"}, + {file = "dulwich-0.21.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:32d7acfe3fe2ce4502446d8f7a5ab34cfd24c9ff8961e60337638410906a8fbb"}, + {file = "dulwich-0.21.6-cp311-cp311-win32.whl", hash = "sha256:5e58171a5d70f7910f73d25ff82a058edff09a4c1c3bd1de0dc6b1fbc9a42c3e"}, + {file = "dulwich-0.21.6-cp311-cp311-win_amd64.whl", hash = "sha256:ceabe8f96edfb9183034a860f5dc77586700b517457032867b64a03c44e5cf96"}, + {file = "dulwich-0.21.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4fdc2f081bc3e9e120079c2cea4be213e3f127335aca7c0ab0c19fe791270caa"}, + {file = "dulwich-0.21.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fe957564108f74325d0d042d85e0c67ef470921ca92b6e7d330c7c49a3b9c1d"}, + {file = "dulwich-0.21.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2912c8a845c8ccbc79d068a89db7172e355adeb84eb31f062cd3a406d528b30"}, + {file = "dulwich-0.21.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:81e237a6b1b20c79ef62ca19a8fb231f5519bab874b9a1c2acf9c05edcabd600"}, + {file = "dulwich-0.21.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:513d045e74307eeb31592255c38f37042c9aa68ce845a167943018ab5138b0e3"}, + {file = "dulwich-0.21.6-cp37-cp37m-win32.whl", hash = "sha256:e1ac882afa890ef993b8502647e6c6d2b3977ce56e3fe80058ce64607cbc7107"}, + {file = "dulwich-0.21.6-cp37-cp37m-win_amd64.whl", hash = "sha256:5d2ccf3d355850674f75655154a6519bf1f1664176c670109fa7041019b286f9"}, + {file = "dulwich-0.21.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:28c9724a167c84a83fc6238e0781f4702b5fe8c53ede31604525fb1a9d1833f4"}, + {file = "dulwich-0.21.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c816be529680659b6a19798287b4ec6de49040f58160d40b1b2934fd6c28e93f"}, + {file = "dulwich-0.21.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b0545f0fa9444a0eb84977d08e302e3f55fd7c34a0466ec28bedc3c839b2fc1f"}, + {file = "dulwich-0.21.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b1682e8e826471ea3c22b8521435e93799e3db8ad05dd3c8f9b1aaacfa78147"}, + {file = "dulwich-0.21.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24ad45928a65f39ea0f451f9989b7aaedba9893d48c3189b544a70c6a1043f71"}, + {file = "dulwich-0.21.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b1c9e55233f19cd19c484f607cd90ab578ac50ebfef607f77e3b35c2b6049470"}, + {file = "dulwich-0.21.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:18697b58e0fc5972de68b529b08ac9ddda3f39af27bcf3f6999635ed3da7ef68"}, + {file = "dulwich-0.21.6-cp38-cp38-win32.whl", hash = "sha256:22798e9ba59e32b8faff5d9067e2b5a308f6b0fba9b1e1e928571ad278e7b36c"}, + {file = "dulwich-0.21.6-cp38-cp38-win_amd64.whl", hash = "sha256:6c91e1ed20d3d9a6aaaed9e75adae37272b3fcbcc72bab1eb09574806da88563"}, + {file = "dulwich-0.21.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8b84450766a3b151c3676fec3e3ed76304e52a84d5d69ade0f34fff2782c1b41"}, + {file = "dulwich-0.21.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3da632648ee27b64bb5b285a3a94fddf297a596891cca12ac0df43c4f59448f"}, + {file = "dulwich-0.21.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cef50c0a19f322b7150248b8fa0862ce1652dec657e340c4020573721e85f215"}, + {file = "dulwich-0.21.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ac20dfcfd6057efb8499158d23f2c059f933aefa381e192100e6d8bc25d562"}, + {file = "dulwich-0.21.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81d10aa50c0a9a6dd495990c639358e3a3bbff39e17ff302179be6e93b573da7"}, + {file = "dulwich-0.21.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a9b52a08d49731375662936d05a12c4a64a6fe0ce257111f62638e475fb5d26d"}, + {file = "dulwich-0.21.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ed2f1f638b9adfba862719693b371ffe5d58e94d552ace9a23dea0fb0db6f468"}, + {file = "dulwich-0.21.6-cp39-cp39-win32.whl", hash = "sha256:bf90f2f9328a82778cf85ab696e4a7926918c3f315c75fc432ba31346bfa89b7"}, + {file = "dulwich-0.21.6-cp39-cp39-win_amd64.whl", hash = "sha256:e0dee3840c3c72e1d60c8f87a7a715d8eac023b9e1b80199d97790f7a1c60d9c"}, + {file = "dulwich-0.21.6-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:32d3a35caad6879d04711b358b861142440a543f5f4e02df67b13cbcd57f84a6"}, + {file = "dulwich-0.21.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c04df87098053b7767b46fc04b7943d75443f91c73560ca50157cdc22e27a5d3"}, + {file = "dulwich-0.21.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e07f145c7b0d82a9f77d157f493a61900e913d1c1f8b1f40d07d919ffb0929a4"}, + {file = "dulwich-0.21.6-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:008ff08629ab16d3638a9f36cfc6f5bd74b4d594657f2dc1583d8d3201794571"}, + {file = "dulwich-0.21.6-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bf469cd5076623c2aad69d01ce9d5392fcb38a5faef91abe1501be733453e37d"}, + {file = "dulwich-0.21.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6592ef2d16ac61a27022647cf64a048f5be6e0a6ab2ebc7322bfbe24fb2b971b"}, + {file = "dulwich-0.21.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99577b2b37f64bc87280079245fb2963494c345d7db355173ecec7ab3d64b949"}, + {file = "dulwich-0.21.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d7cd9fb896c65e4c28cb9332f2be192817805978dd8dc299681c4fe83c631158"}, + {file = "dulwich-0.21.6-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d9002094198e57e88fe77412d3aa64dd05978046ae725a16123ba621a7704628"}, + {file = "dulwich-0.21.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9b6f8a16f32190aa88c37ef013858b3e01964774bc983900bd0d74ecb6576e6"}, + {file = "dulwich-0.21.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee8aba4dec4d0a52737a8a141f3456229c87dcfd7961f8115786a27b6ebefed"}, + {file = "dulwich-0.21.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a780e2a0ff208c4f218e72eff8d13f9aff485ff9a6f3066c22abe4ec8cec7dcd"}, + {file = "dulwich-0.21.6.tar.gz", hash = "sha256:30fbe87e8b51f3813c131e2841c86d007434d160bd16db586b40d47f31dd05b0"}, +] + +[package.dependencies] +urllib3 = ">=1.25" + +[package.extras] +fastimport = ["fastimport"] +https = ["urllib3 (>=1.24.1)"] +paramiko = ["paramiko"] +pgp = ["gpg"] [[package]] name = "exceptiongroup" version = "1.1.3" description = "Backport of PEP 654 (exception groups)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -737,29 +993,27 @@ test = ["pytest (>=6)"] [[package]] name = "executing" -version = "1.2.0" +version = "2.0.0" description = "Get the currently executing AST node of a frame, and other information" -category = "main" optional = false python-versions = "*" files = [ - {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, - {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, + {file = "executing-2.0.0-py2.py3-none-any.whl", hash = "sha256:06df6183df67389625f4e763921c6cf978944721abf3e714000200aab95b0657"}, + {file = "executing-2.0.0.tar.gz", hash = "sha256:0ff053696fdeef426cda5bd18eacd94f82c91f49823a2e9090124212ceea9b08"}, ] [package.extras] -tests = ["asttokens", "littleutils", "pytest", "rich"] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] [[package]] name = "fastjsonschema" -version = "2.18.0" +version = "2.18.1" description = "Fastest Python implementation of JSON schema" -category = "main" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.18.0-py3-none-any.whl", hash = "sha256:128039912a11a807068a7c87d0da36660afbfd7202780db26c4aa7153cfdc799"}, - {file = "fastjsonschema-2.18.0.tar.gz", hash = "sha256:e820349dd16f806e4bd1467a138dced9def4bc7d6213a34295272a6cac95b5bd"}, + {file = "fastjsonschema-2.18.1-py3-none-any.whl", hash = "sha256:aec6a19e9f66e9810ab371cc913ad5f4e9e479b63a7072a2cd060a9369e329a8"}, + {file = "fastjsonschema-2.18.1.tar.gz", hash = "sha256:06dc8680d937628e993fa0cd278f196d20449a1adc087640710846b324d422ea"}, ] [package.extras] @@ -767,28 +1021,24 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "filelock" -version = "3.12.3" +version = "3.12.4" description = "A platform independent file lock." -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.12.3-py3-none-any.whl", hash = "sha256:f067e40ccc40f2b48395a80fcbd4728262fab54e232e090a4063ab804179efeb"}, - {file = "filelock-3.12.3.tar.gz", hash = "sha256:0ecc1dd2ec4672a10c8550a8182f1bd0c0a5088470ecd5a125e45f49472fac3d"}, + {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"}, + {file = "filelock-3.12.4.tar.gz", hash = "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.7.1", markers = "python_version < \"3.11\""} - [package.extras] docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1.24)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"] +typing = ["typing-extensions (>=4.7.1)"] [[package]] name = "flake8" version = "4.0.1" description = "the modular source code checker: pep8 pyflakes and co" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -803,46 +1053,53 @@ pyflakes = ">=2.4.0,<2.5.0" [[package]] name = "fonttools" -version = "4.42.1" +version = "4.43.0" description = "Tools to manipulate font files" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.42.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ed1a13a27f59d1fc1920394a7f596792e9d546c9ca5a044419dca70c37815d7c"}, - {file = "fonttools-4.42.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9b1ce7a45978b821a06d375b83763b27a3a5e8a2e4570b3065abad240a18760"}, - {file = "fonttools-4.42.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f720fa82a11c0f9042376fd509b5ed88dab7e3cd602eee63a1af08883b37342b"}, - {file = "fonttools-4.42.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db55cbaea02a20b49fefbd8e9d62bd481aaabe1f2301dabc575acc6b358874fa"}, - {file = "fonttools-4.42.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a35981d90feebeaef05e46e33e6b9e5b5e618504672ca9cd0ff96b171e4bfff"}, - {file = "fonttools-4.42.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:68a02bbe020dc22ee0540e040117535f06df9358106d3775e8817d826047f3fd"}, - {file = "fonttools-4.42.1-cp310-cp310-win32.whl", hash = "sha256:12a7c247d1b946829bfa2f331107a629ea77dc5391dfd34fdcd78efa61f354ca"}, - {file = "fonttools-4.42.1-cp310-cp310-win_amd64.whl", hash = "sha256:a398bdadb055f8de69f62b0fc70625f7cbdab436bbb31eef5816e28cab083ee8"}, - {file = "fonttools-4.42.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:689508b918332fb40ce117131633647731d098b1b10d092234aa959b4251add5"}, - {file = "fonttools-4.42.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e36344e48af3e3bde867a1ca54f97c308735dd8697005c2d24a86054a114a71"}, - {file = "fonttools-4.42.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19b7db825c8adee96fac0692e6e1ecd858cae9affb3b4812cdb9d934a898b29e"}, - {file = "fonttools-4.42.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:113337c2d29665839b7d90b39f99b3cac731f72a0eda9306165a305c7c31d341"}, - {file = "fonttools-4.42.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:37983b6bdab42c501202500a2be3a572f50d4efe3237e0686ee9d5f794d76b35"}, - {file = "fonttools-4.42.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6ed2662a3d9c832afa36405f8748c250be94ae5dfc5283d668308391f2102861"}, - {file = "fonttools-4.42.1-cp311-cp311-win32.whl", hash = "sha256:179737095eb98332a2744e8f12037b2977f22948cf23ff96656928923ddf560a"}, - {file = "fonttools-4.42.1-cp311-cp311-win_amd64.whl", hash = "sha256:f2b82f46917d8722e6b5eafeefb4fb585d23babd15d8246c664cd88a5bddd19c"}, - {file = "fonttools-4.42.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:62f481ac772fd68901573956231aea3e4b1ad87b9b1089a61613a91e2b50bb9b"}, - {file = "fonttools-4.42.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2f806990160d1ce42d287aa419df3ffc42dfefe60d473695fb048355fe0c6a0"}, - {file = "fonttools-4.42.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db372213d39fa33af667c2aa586a0c1235e88e9c850f5dd5c8e1f17515861868"}, - {file = "fonttools-4.42.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d18fc642fd0ac29236ff88ecfccff229ec0386090a839dd3f1162e9a7944a40"}, - {file = "fonttools-4.42.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8708b98c278012ad267ee8a7433baeb809948855e81922878118464b274c909d"}, - {file = "fonttools-4.42.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c95b0724a6deea2c8c5d3222191783ced0a2f09bd6d33f93e563f6f1a4b3b3a4"}, - {file = "fonttools-4.42.1-cp38-cp38-win32.whl", hash = "sha256:4aa79366e442dbca6e2c8595645a3a605d9eeabdb7a094d745ed6106816bef5d"}, - {file = "fonttools-4.42.1-cp38-cp38-win_amd64.whl", hash = "sha256:acb47f6f8680de24c1ab65ebde39dd035768e2a9b571a07c7b8da95f6c8815fd"}, - {file = "fonttools-4.42.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb289b7a815638a7613d46bcf324c9106804725b2bb8ad913c12b6958ffc4ec"}, - {file = "fonttools-4.42.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:53eb5091ddc8b1199330bb7b4a8a2e7995ad5d43376cadce84523d8223ef3136"}, - {file = "fonttools-4.42.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46a0ec8adbc6ff13494eb0c9c2e643b6f009ce7320cf640de106fb614e4d4360"}, - {file = "fonttools-4.42.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cc7d685b8eeca7ae69dc6416833fbfea61660684b7089bca666067cb2937dcf"}, - {file = "fonttools-4.42.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:be24fcb80493b2c94eae21df70017351851652a37de514de553435b256b2f249"}, - {file = "fonttools-4.42.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:515607ec756d7865f23070682622c49d922901943697871fc292277cf1e71967"}, - {file = "fonttools-4.42.1-cp39-cp39-win32.whl", hash = "sha256:0eb79a2da5eb6457a6f8ab904838454accc7d4cccdaff1fd2bd3a0679ea33d64"}, - {file = "fonttools-4.42.1-cp39-cp39-win_amd64.whl", hash = "sha256:7286aed4ea271df9eab8d7a9b29e507094b51397812f7ce051ecd77915a6e26b"}, - {file = "fonttools-4.42.1-py3-none-any.whl", hash = "sha256:9398f244e28e0596e2ee6024f808b06060109e33ed38dcc9bded452fd9bbb853"}, - {file = "fonttools-4.42.1.tar.gz", hash = "sha256:c391cd5af88aacaf41dd7cfb96eeedfad297b5899a39e12f4c2c3706d0a3329d"}, + {file = "fonttools-4.43.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ab80e7d6bb01316d5fc8161a2660ca2e9e597d0880db4927bc866c76474472ef"}, + {file = "fonttools-4.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82d8e687a42799df5325e7ee12977b74738f34bf7fde1c296f8140efd699a213"}, + {file = "fonttools-4.43.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d08a694b280d615460563a6b4e2afb0b1b9df708c799ec212bf966652b94fc84"}, + {file = "fonttools-4.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d654d3e780e0ceabb1f4eff5a3c042c67d4428d0fe1ea3afd238a721cf171b3"}, + {file = "fonttools-4.43.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:20fc43783c432862071fa76da6fa714902ae587bc68441e12ff4099b94b1fcef"}, + {file = "fonttools-4.43.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:33c40a657fb87ff83185828c0323032d63a4df1279d5c1c38e21f3ec56327803"}, + {file = "fonttools-4.43.0-cp310-cp310-win32.whl", hash = "sha256:b3813f57f85bbc0e4011a0e1e9211f9ee52f87f402e41dc05bc5135f03fa51c1"}, + {file = "fonttools-4.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:05056a8c9af048381fdb17e89b17d45f6c8394176d01e8c6fef5ac96ea950d38"}, + {file = "fonttools-4.43.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da78f39b601ed0b4262929403186d65cf7a016f91ff349ab18fdc5a7080af465"}, + {file = "fonttools-4.43.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5056f69a18f3f28ab5283202d1efcfe011585d31de09d8560f91c6c88f041e92"}, + {file = "fonttools-4.43.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcc01cea0a121fb0c009993497bad93cae25e77db7dee5345fec9cce1aaa09cd"}, + {file = "fonttools-4.43.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee728d5af70f117581712966a21e2e07031e92c687ef1fdc457ac8d281016f64"}, + {file = "fonttools-4.43.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b5e760198f0b87e42478bb35a6eae385c636208f6f0d413e100b9c9c5efafb6a"}, + {file = "fonttools-4.43.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:af38f5145258e9866da5881580507e6d17ff7756beef175d13213a43a84244e9"}, + {file = "fonttools-4.43.0-cp311-cp311-win32.whl", hash = "sha256:25620b738d4533cfc21fd2a4f4b667e481f7cb60e86b609799f7d98af657854e"}, + {file = "fonttools-4.43.0-cp311-cp311-win_amd64.whl", hash = "sha256:635658464dccff6fa5c3b43fe8f818ae2c386ee6a9e1abc27359d1e255528186"}, + {file = "fonttools-4.43.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a682fb5cbf8837d1822b80acc0be5ff2ea0c49ca836e468a21ffd388ef280fd3"}, + {file = "fonttools-4.43.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3d7adfa342e6b3a2b36960981f23f480969f833d565a4eba259c2e6f59d2674f"}, + {file = "fonttools-4.43.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa67d1e720fdd902fde4a59d0880854ae9f19fc958f3e1538bceb36f7f4dc92"}, + {file = "fonttools-4.43.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77e5113233a2df07af9dbf493468ce526784c3b179c0e8b9c7838ced37c98b69"}, + {file = "fonttools-4.43.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:57c22e5f9f53630d458830f710424dce4f43c5f0d95cb3368c0f5178541e4db7"}, + {file = "fonttools-4.43.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:206808f9717c9b19117f461246372a2c160fa12b9b8dbdfb904ab50ca235ba0a"}, + {file = "fonttools-4.43.0-cp312-cp312-win32.whl", hash = "sha256:f19c2b1c65d57cbea25cabb80941fea3fbf2625ff0cdcae8900b5fb1c145704f"}, + {file = "fonttools-4.43.0-cp312-cp312-win_amd64.whl", hash = "sha256:7c76f32051159f8284f1a5f5b605152b5a530736fb8b55b09957db38dcae5348"}, + {file = "fonttools-4.43.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e3f8acc6ef4a627394021246e099faee4b343afd3ffe2e517d8195b4ebf20289"}, + {file = "fonttools-4.43.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a68b71adc3b3a90346e4ac92f0a69ab9caeba391f3b04ab6f1e98f2c8ebe88e3"}, + {file = "fonttools-4.43.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ace0fd5afb79849f599f76af5c6aa5e865bd042c811e4e047bbaa7752cc26126"}, + {file = "fonttools-4.43.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f9660e70a2430780e23830476332bc3391c3c8694769e2c0032a5038702a662"}, + {file = "fonttools-4.43.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:48078357984214ccd22d7fe0340cd6ff7286b2f74f173603a1a9a40b5dc25afe"}, + {file = "fonttools-4.43.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d27d960e10cf7617d70cf3104c32a69b008dde56f2d55a9bed4ba6e3df611544"}, + {file = "fonttools-4.43.0-cp38-cp38-win32.whl", hash = "sha256:a6a2e99bb9ea51e0974bbe71768df42c6dd189308c22f3f00560c3341b345646"}, + {file = "fonttools-4.43.0-cp38-cp38-win_amd64.whl", hash = "sha256:030355fbb0cea59cf75d076d04d3852900583d1258574ff2d7d719abf4513836"}, + {file = "fonttools-4.43.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52e77f23a9c059f8be01a07300ba4c4d23dc271d33eed502aea5a01ab5d2f4c1"}, + {file = "fonttools-4.43.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a530fa28c155538d32214eafa0964989098a662bd63e91e790e6a7a4e9c02da"}, + {file = "fonttools-4.43.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70f021a6b9eb10dfe7a411b78e63a503a06955dd6d2a4e130906d8760474f77c"}, + {file = "fonttools-4.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:812142a0e53cc853964d487e6b40963df62f522b1b571e19d1ff8467d7880ceb"}, + {file = "fonttools-4.43.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ace51902ab67ef5fe225e8b361039e996db153e467e24a28d35f74849b37b7ce"}, + {file = "fonttools-4.43.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8dfd8edfce34ad135bd69de20c77449c06e2c92b38f2a8358d0987737f82b49e"}, + {file = "fonttools-4.43.0-cp39-cp39-win32.whl", hash = "sha256:e5d53eddaf436fa131042f44a76ea1ead0a17c354ab9de0d80e818f0cb1629f1"}, + {file = "fonttools-4.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:93c5b6d77baf28f306bc13fa987b0b13edca6a39dc2324eaca299a74ccc6316f"}, + {file = "fonttools-4.43.0-py3-none-any.whl", hash = "sha256:e4bc589d8da09267c7c4ceaaaa4fc01a7908ac5b43b286ac9279afe76407c384"}, + {file = "fonttools-4.43.0.tar.gz", hash = "sha256:b62a53a4ca83c32c6b78cac64464f88d02929779373c716f738af6968c8c821e"}, ] [package.extras] @@ -863,7 +1120,6 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "frozenlist" version = "1.4.0" description = "A list-like structure which implements collections.abc.MutableSequence" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -934,7 +1190,6 @@ files = [ name = "google-api-core" version = "1.34.0" description = "Google API client core library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -957,34 +1212,31 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] [[package]] name = "google-auth" -version = "2.17.3" +version = "2.23.2" description = "Google Authentication Library" -category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +python-versions = ">=3.7" files = [ - {file = "google-auth-2.17.3.tar.gz", hash = "sha256:ce311e2bc58b130fddf316df57c9b3943c2a7b4f6ec31de9663a9333e4064efc"}, - {file = "google_auth-2.17.3-py2.py3-none-any.whl", hash = "sha256:f586b274d3eb7bd932ea424b1c702a30e0393a2e2bc4ca3eae8263ffd8be229f"}, + {file = "google-auth-2.23.2.tar.gz", hash = "sha256:5a9af4be520ba33651471a0264eead312521566f44631cbb621164bc30c8fd40"}, + {file = "google_auth-2.23.2-py2.py3-none-any.whl", hash = "sha256:c2e253347579d483004f17c3bd0bf92e611ef6c7ba24d41c5c59f2e7aeeaf088"}, ] [package.dependencies] cachetools = ">=2.0.0,<6.0" pyasn1-modules = ">=0.2.1" -rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""} -six = ">=1.9.0" +rsa = ">=3.1.4,<5" [package.extras] -aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] -requests = ["requests (>=2.20.0,<3.0.0dev)"] +requests = ["requests (>=2.20.0,<3.0.0.dev0)"] [[package]] name = "googleapis-common-protos" version = "1.60.0" description = "Common protobufs used in Google APIs" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1000,141 +1252,149 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "greenlet" -version = "2.0.2" +version = "3.0.0" description = "Lightweight in-process concurrent programming" -category = "main" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -files = [ - {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, - {file = "greenlet-2.0.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9"}, - {file = "greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"}, - {file = "greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"}, - {file = "greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"}, - {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"}, - {file = "greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"}, - {file = "greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3"}, - {file = "greenlet-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5"}, - {file = "greenlet-2.0.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6"}, - {file = "greenlet-2.0.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43"}, - {file = "greenlet-2.0.2-cp35-cp35m-win32.whl", hash = "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a"}, - {file = "greenlet-2.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394"}, - {file = "greenlet-2.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292"}, - {file = "greenlet-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9"}, - {file = "greenlet-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f"}, - {file = "greenlet-2.0.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33"}, - {file = "greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"}, - {file = "greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"}, - {file = "greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"}, - {file = "greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"}, - {file = "greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"}, - {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9"}, - {file = "greenlet-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5"}, - {file = "greenlet-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564"}, - {file = "greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0"}, -] - -[package.extras] -docs = ["Sphinx", "docutils (<0.18)"] +optional = false +python-versions = ">=3.7" +files = [ + {file = "greenlet-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e09dea87cc91aea5500262993cbd484b41edf8af74f976719dd83fe724644cd6"}, + {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47932c434a3c8d3c86d865443fadc1fbf574e9b11d6650b656e602b1797908a"}, + {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdfaeecf8cc705d35d8e6de324bf58427d7eafb55f67050d8f28053a3d57118c"}, + {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a68d670c8f89ff65c82b936275369e532772eebc027c3be68c6b87ad05ca695"}, + {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ad562a104cd41e9d4644f46ea37167b93190c6d5e4048fcc4b80d34ecb278f"}, + {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a807b2a58d5cdebb07050efe3d7deaf915468d112dfcf5e426d0564aa3aa4a"}, + {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b1660a15a446206c8545edc292ab5c48b91ff732f91b3d3b30d9a915d5ec4779"}, + {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:813720bd57e193391dfe26f4871186cf460848b83df7e23e6bef698a7624b4c9"}, + {file = "greenlet-3.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:aa15a2ec737cb609ed48902b45c5e4ff6044feb5dcdfcf6fa8482379190330d7"}, + {file = "greenlet-3.0.0-cp310-universal2-macosx_11_0_x86_64.whl", hash = "sha256:7709fd7bb02b31908dc8fd35bfd0a29fc24681d5cc9ac1d64ad07f8d2b7db62f"}, + {file = "greenlet-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:211ef8d174601b80e01436f4e6905aca341b15a566f35a10dd8d1e93f5dbb3b7"}, + {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6512592cc49b2c6d9b19fbaa0312124cd4c4c8a90d28473f86f92685cc5fef8e"}, + {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871b0a8835f9e9d461b7fdaa1b57e3492dd45398e87324c047469ce2fc9f516c"}, + {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b505fcfc26f4148551826a96f7317e02c400665fa0883fe505d4fcaab1dabfdd"}, + {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123910c58234a8d40eaab595bc56a5ae49bdd90122dde5bdc012c20595a94c14"}, + {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96d9ea57292f636ec851a9bb961a5cc0f9976900e16e5d5647f19aa36ba6366b"}, + {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0b72b802496cccbd9b31acea72b6f87e7771ccfd7f7927437d592e5c92ed703c"}, + {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:527cd90ba3d8d7ae7dceb06fda619895768a46a1b4e423bdb24c1969823b8362"}, + {file = "greenlet-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:37f60b3a42d8b5499be910d1267b24355c495064f271cfe74bf28b17b099133c"}, + {file = "greenlet-3.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1482fba7fbed96ea7842b5a7fc11d61727e8be75a077e603e8ab49d24e234383"}, + {file = "greenlet-3.0.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:be557119bf467d37a8099d91fbf11b2de5eb1fd5fc5b91598407574848dc910f"}, + {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73b2f1922a39d5d59cc0e597987300df3396b148a9bd10b76a058a2f2772fc04"}, + {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1e22c22f7826096ad503e9bb681b05b8c1f5a8138469b255eb91f26a76634f2"}, + {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d363666acc21d2c204dd8705c0e0457d7b2ee7a76cb16ffc099d6799744ac99"}, + {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:334ef6ed8337bd0b58bb0ae4f7f2dcc84c9f116e474bb4ec250a8bb9bd797a66"}, + {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6672fdde0fd1a60b44fb1751a7779c6db487e42b0cc65e7caa6aa686874e79fb"}, + {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:952256c2bc5b4ee8df8dfc54fc4de330970bf5d79253c863fb5e6761f00dda35"}, + {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:269d06fa0f9624455ce08ae0179430eea61085e3cf6457f05982b37fd2cefe17"}, + {file = "greenlet-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9adbd8ecf097e34ada8efde9b6fec4dd2a903b1e98037adf72d12993a1c80b51"}, + {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6b5ce7f40f0e2f8b88c28e6691ca6806814157ff05e794cdd161be928550f4c"}, + {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf94aa539e97a8411b5ea52fc6ccd8371be9550c4041011a091eb8b3ca1d810"}, + {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80dcd3c938cbcac986c5c92779db8e8ce51a89a849c135172c88ecbdc8c056b7"}, + {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e52a712c38e5fb4fd68e00dc3caf00b60cb65634d50e32281a9d6431b33b4af1"}, + {file = "greenlet-3.0.0-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5539f6da3418c3dc002739cb2bb8d169056aa66e0c83f6bacae0cd3ac26b423"}, + {file = "greenlet-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:343675e0da2f3c69d3fb1e894ba0a1acf58f481f3b9372ce1eb465ef93cf6fed"}, + {file = "greenlet-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:abe1ef3d780de56defd0c77c5ba95e152f4e4c4e12d7e11dd8447d338b85a625"}, + {file = "greenlet-3.0.0-cp37-cp37m-win32.whl", hash = "sha256:e693e759e172fa1c2c90d35dea4acbdd1d609b6936115d3739148d5e4cd11947"}, + {file = "greenlet-3.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bdd696947cd695924aecb3870660b7545a19851f93b9d327ef8236bfc49be705"}, + {file = "greenlet-3.0.0-cp37-universal2-macosx_11_0_x86_64.whl", hash = "sha256:cc3e2679ea13b4de79bdc44b25a0c4fcd5e94e21b8f290791744ac42d34a0353"}, + {file = "greenlet-3.0.0-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:63acdc34c9cde42a6534518e32ce55c30f932b473c62c235a466469a710bfbf9"}, + {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a1a6244ff96343e9994e37e5b4839f09a0207d35ef6134dce5c20d260d0302c"}, + {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b822fab253ac0f330ee807e7485769e3ac85d5eef827ca224feaaefa462dc0d0"}, + {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8060b32d8586e912a7b7dac2d15b28dbbd63a174ab32f5bc6d107a1c4143f40b"}, + {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:621fcb346141ae08cb95424ebfc5b014361621b8132c48e538e34c3c93ac7365"}, + {file = "greenlet-3.0.0-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6bb36985f606a7c49916eff74ab99399cdfd09241c375d5a820bb855dfb4af9f"}, + {file = "greenlet-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10b5582744abd9858947d163843d323d0b67be9432db50f8bf83031032bc218d"}, + {file = "greenlet-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f351479a6914fd81a55c8e68963609f792d9b067fb8a60a042c585a621e0de4f"}, + {file = "greenlet-3.0.0-cp38-cp38-win32.whl", hash = "sha256:9de687479faec7db5b198cc365bc34addd256b0028956501f4d4d5e9ca2e240a"}, + {file = "greenlet-3.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:3fd2b18432e7298fcbec3d39e1a0aa91ae9ea1c93356ec089421fabc3651572b"}, + {file = "greenlet-3.0.0-cp38-universal2-macosx_11_0_x86_64.whl", hash = "sha256:3c0d36f5adc6e6100aedbc976d7428a9f7194ea79911aa4bf471f44ee13a9464"}, + {file = "greenlet-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4cd83fb8d8e17633ad534d9ac93719ef8937568d730ef07ac3a98cb520fd93e4"}, + {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a5b2d4cdaf1c71057ff823a19d850ed5c6c2d3686cb71f73ae4d6382aaa7a06"}, + {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e7dcdfad252f2ca83c685b0fa9fba00e4d8f243b73839229d56ee3d9d219314"}, + {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c94e4e924d09b5a3e37b853fe5924a95eac058cb6f6fb437ebb588b7eda79870"}, + {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad6fb737e46b8bd63156b8f59ba6cdef46fe2b7db0c5804388a2d0519b8ddb99"}, + {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d55db1db455c59b46f794346efce896e754b8942817f46a1bada2d29446e305a"}, + {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:56867a3b3cf26dc8a0beecdb4459c59f4c47cdd5424618c08515f682e1d46692"}, + {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a812224a5fb17a538207e8cf8e86f517df2080c8ee0f8c1ed2bdaccd18f38f4"}, + {file = "greenlet-3.0.0-cp39-cp39-win32.whl", hash = "sha256:0d3f83ffb18dc57243e0151331e3c383b05e5b6c5029ac29f754745c800f8ed9"}, + {file = "greenlet-3.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:831d6f35037cf18ca5e80a737a27d822d87cd922521d18ed3dbc8a6967be50ce"}, + {file = "greenlet-3.0.0-cp39-universal2-macosx_11_0_x86_64.whl", hash = "sha256:a048293392d4e058298710a54dfaefcefdf49d287cd33fb1f7d63d55426e4355"}, + {file = "greenlet-3.0.0.tar.gz", hash = "sha256:19834e3f91f485442adc1ee440171ec5d9a4840a1f7bd5ed97833544719ce10b"}, +] + +[package.extras] +docs = ["Sphinx"] test = ["objgraph", "psutil"] [[package]] name = "grpcio" -version = "1.57.0" +version = "1.59.0" description = "HTTP/2-based RPC framework" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "grpcio-1.57.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:092fa155b945015754bdf988be47793c377b52b88d546e45c6a9f9579ac7f7b6"}, - {file = "grpcio-1.57.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2f7349786da979a94690cc5c2b804cab4e8774a3cf59be40d037c4342c906649"}, - {file = "grpcio-1.57.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:82640e57fb86ea1d71ea9ab54f7e942502cf98a429a200b2e743d8672171734f"}, - {file = "grpcio-1.57.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40b72effd4c789de94ce1be2b5f88d7b9b5f7379fe9645f198854112a6567d9a"}, - {file = "grpcio-1.57.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f708a6a17868ad8bf586598bee69abded4996b18adf26fd2d91191383b79019"}, - {file = "grpcio-1.57.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:60fe15288a0a65d5c1cb5b4a62b1850d07336e3ba728257a810317be14f0c527"}, - {file = "grpcio-1.57.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6907b1cf8bb29b058081d2aad677b15757a44ef2d4d8d9130271d2ad5e33efca"}, - {file = "grpcio-1.57.0-cp310-cp310-win32.whl", hash = "sha256:57b183e8b252825c4dd29114d6c13559be95387aafc10a7be645462a0fc98bbb"}, - {file = "grpcio-1.57.0-cp310-cp310-win_amd64.whl", hash = "sha256:7b400807fa749a9eb286e2cd893e501b110b4d356a218426cb9c825a0474ca56"}, - {file = "grpcio-1.57.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:c6ebecfb7a31385393203eb04ed8b6a08f5002f53df3d59e5e795edb80999652"}, - {file = "grpcio-1.57.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:00258cbe3f5188629828363ae8ff78477ce976a6f63fb2bb5e90088396faa82e"}, - {file = "grpcio-1.57.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:23e7d8849a0e58b806253fd206ac105b328171e01b8f18c7d5922274958cc87e"}, - {file = "grpcio-1.57.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5371bcd861e679d63b8274f73ac281751d34bd54eccdbfcd6aa00e692a82cd7b"}, - {file = "grpcio-1.57.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aed90d93b731929e742967e236f842a4a2174dc5db077c8f9ad2c5996f89f63e"}, - {file = "grpcio-1.57.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fe752639919aad9ffb0dee0d87f29a6467d1ef764f13c4644d212a9a853a078d"}, - {file = "grpcio-1.57.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fada6b07ec4f0befe05218181f4b85176f11d531911b64c715d1875c4736d73a"}, - {file = "grpcio-1.57.0-cp311-cp311-win32.whl", hash = "sha256:bb396952cfa7ad2f01061fbc7dc1ad91dd9d69243bcb8110cf4e36924785a0fe"}, - {file = "grpcio-1.57.0-cp311-cp311-win_amd64.whl", hash = "sha256:e503cb45ed12b924b5b988ba9576dc9949b2f5283b8e33b21dcb6be74a7c58d0"}, - {file = "grpcio-1.57.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:fd173b4cf02b20f60860dc2ffe30115c18972d7d6d2d69df97ac38dee03be5bf"}, - {file = "grpcio-1.57.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:d7f8df114d6b4cf5a916b98389aeaf1e3132035420a88beea4e3d977e5f267a5"}, - {file = "grpcio-1.57.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:76c44efa4ede1f42a9d5b2fed1fe9377e73a109bef8675fb0728eb80b0b8e8f2"}, - {file = "grpcio-1.57.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4faea2cfdf762a664ab90589b66f416274887641ae17817de510b8178356bf73"}, - {file = "grpcio-1.57.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c60b83c43faeb6d0a9831f0351d7787a0753f5087cc6fa218d78fdf38e5acef0"}, - {file = "grpcio-1.57.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b363bbb5253e5f9c23d8a0a034dfdf1b7c9e7f12e602fc788c435171e96daccc"}, - {file = "grpcio-1.57.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f1fb0fd4a1e9b11ac21c30c169d169ef434c6e9344ee0ab27cfa6f605f6387b2"}, - {file = "grpcio-1.57.0-cp37-cp37m-win_amd64.whl", hash = "sha256:34950353539e7d93f61c6796a007c705d663f3be41166358e3d88c45760c7d98"}, - {file = "grpcio-1.57.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:871f9999e0211f9551f368612460442a5436d9444606184652117d6a688c9f51"}, - {file = "grpcio-1.57.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:a8a8e560e8dbbdf29288872e91efd22af71e88b0e5736b0daf7773c1fecd99f0"}, - {file = "grpcio-1.57.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:2313b124e475aa9017a9844bdc5eafb2d5abdda9d456af16fc4535408c7d6da6"}, - {file = "grpcio-1.57.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4098b6b638d9e0ca839a81656a2fd4bc26c9486ea707e8b1437d6f9d61c3941"}, - {file = "grpcio-1.57.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e5b58e32ae14658085c16986d11e99abd002ddbf51c8daae8a0671fffb3467f"}, - {file = "grpcio-1.57.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0f80bf37f09e1caba6a8063e56e2b87fa335add314cf2b78ebf7cb45aa7e3d06"}, - {file = "grpcio-1.57.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5b7a4ce8f862fe32b2a10b57752cf3169f5fe2915acfe7e6a1e155db3da99e79"}, - {file = "grpcio-1.57.0-cp38-cp38-win32.whl", hash = "sha256:9338bacf172e942e62e5889b6364e56657fbf8ac68062e8b25c48843e7b202bb"}, - {file = "grpcio-1.57.0-cp38-cp38-win_amd64.whl", hash = "sha256:e1cb52fa2d67d7f7fab310b600f22ce1ff04d562d46e9e0ac3e3403c2bb4cc16"}, - {file = "grpcio-1.57.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:fee387d2fab144e8a34e0e9c5ca0f45c9376b99de45628265cfa9886b1dbe62b"}, - {file = "grpcio-1.57.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:b53333627283e7241fcc217323f225c37783b5f0472316edcaa4479a213abfa6"}, - {file = "grpcio-1.57.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:f19ac6ac0a256cf77d3cc926ef0b4e64a9725cc612f97228cd5dc4bd9dbab03b"}, - {file = "grpcio-1.57.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3fdf04e402f12e1de8074458549337febb3b45f21076cc02ef4ff786aff687e"}, - {file = "grpcio-1.57.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5613a2fecc82f95d6c51d15b9a72705553aa0d7c932fad7aed7afb51dc982ee5"}, - {file = "grpcio-1.57.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b670c2faa92124b7397b42303e4d8eb64a4cd0b7a77e35a9e865a55d61c57ef9"}, - {file = "grpcio-1.57.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a635589201b18510ff988161b7b573f50c6a48fae9cb567657920ca82022b37"}, - {file = "grpcio-1.57.0-cp39-cp39-win32.whl", hash = "sha256:d78d8b86fcdfa1e4c21f8896614b6cc7ee01a2a758ec0c4382d662f2a62cf766"}, - {file = "grpcio-1.57.0-cp39-cp39-win_amd64.whl", hash = "sha256:20ec6fc4ad47d1b6e12deec5045ec3cd5402d9a1597f738263e98f490fe07056"}, - {file = "grpcio-1.57.0.tar.gz", hash = "sha256:4b089f7ad1eb00a104078bab8015b0ed0ebcb3b589e527ab009c53893fd4e613"}, -] - -[package.extras] -protobuf = ["grpcio-tools (>=1.57.0)"] + {file = "grpcio-1.59.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:225e5fa61c35eeaebb4e7491cd2d768cd8eb6ed00f2664fa83a58f29418b39fd"}, + {file = "grpcio-1.59.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b95ec8ecc4f703f5caaa8d96e93e40c7f589bad299a2617bdb8becbcce525539"}, + {file = "grpcio-1.59.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:1a839ba86764cc48226f50b924216000c79779c563a301586a107bda9cbe9dcf"}, + {file = "grpcio-1.59.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6cfe44a5d7c7d5f1017a7da1c8160304091ca5dc64a0f85bca0d63008c3137a"}, + {file = "grpcio-1.59.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0fcf53df684fcc0154b1e61f6b4a8c4cf5f49d98a63511e3f30966feff39cd0"}, + {file = "grpcio-1.59.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa66cac32861500f280bb60fe7d5b3e22d68c51e18e65367e38f8669b78cea3b"}, + {file = "grpcio-1.59.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8cd2d38c2d52f607d75a74143113174c36d8a416d9472415eab834f837580cf7"}, + {file = "grpcio-1.59.0-cp310-cp310-win32.whl", hash = "sha256:228b91ce454876d7eed74041aff24a8f04c0306b7250a2da99d35dd25e2a1211"}, + {file = "grpcio-1.59.0-cp310-cp310-win_amd64.whl", hash = "sha256:ca87ee6183421b7cea3544190061f6c1c3dfc959e0b57a5286b108511fd34ff4"}, + {file = "grpcio-1.59.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:c173a87d622ea074ce79be33b952f0b424fa92182063c3bda8625c11d3585d09"}, + {file = "grpcio-1.59.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:ec78aebb9b6771d6a1de7b6ca2f779a2f6113b9108d486e904bde323d51f5589"}, + {file = "grpcio-1.59.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:0b84445fa94d59e6806c10266b977f92fa997db3585f125d6b751af02ff8b9fe"}, + {file = "grpcio-1.59.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c251d22de8f9f5cca9ee47e4bade7c5c853e6e40743f47f5cc02288ee7a87252"}, + {file = "grpcio-1.59.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:956f0b7cb465a65de1bd90d5a7475b4dc55089b25042fe0f6c870707e9aabb1d"}, + {file = "grpcio-1.59.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:38da5310ef84e16d638ad89550b5b9424df508fd5c7b968b90eb9629ca9be4b9"}, + {file = "grpcio-1.59.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:63982150a7d598281fa1d7ffead6096e543ff8be189d3235dd2b5604f2c553e5"}, + {file = "grpcio-1.59.0-cp311-cp311-win32.whl", hash = "sha256:50eff97397e29eeee5df106ea1afce3ee134d567aa2c8e04fabab05c79d791a7"}, + {file = "grpcio-1.59.0-cp311-cp311-win_amd64.whl", hash = "sha256:15f03bd714f987d48ae57fe092cf81960ae36da4e520e729392a59a75cda4f29"}, + {file = "grpcio-1.59.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:f1feb034321ae2f718172d86b8276c03599846dc7bb1792ae370af02718f91c5"}, + {file = "grpcio-1.59.0-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d09bd2a4e9f5a44d36bb8684f284835c14d30c22d8ec92ce796655af12163588"}, + {file = "grpcio-1.59.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:2f120d27051e4c59db2f267b71b833796770d3ea36ca712befa8c5fff5da6ebd"}, + {file = "grpcio-1.59.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba0ca727a173ee093f49ead932c051af463258b4b493b956a2c099696f38aa66"}, + {file = "grpcio-1.59.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5711c51e204dc52065f4a3327dca46e69636a0b76d3e98c2c28c4ccef9b04c52"}, + {file = "grpcio-1.59.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d74f7d2d7c242a6af9d4d069552ec3669965b74fed6b92946e0e13b4168374f9"}, + {file = "grpcio-1.59.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3859917de234a0a2a52132489c4425a73669de9c458b01c9a83687f1f31b5b10"}, + {file = "grpcio-1.59.0-cp312-cp312-win32.whl", hash = "sha256:de2599985b7c1b4ce7526e15c969d66b93687571aa008ca749d6235d056b7205"}, + {file = "grpcio-1.59.0-cp312-cp312-win_amd64.whl", hash = "sha256:598f3530231cf10ae03f4ab92d48c3be1fee0c52213a1d5958df1a90957e6a88"}, + {file = "grpcio-1.59.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:b34c7a4c31841a2ea27246a05eed8a80c319bfc0d3e644412ec9ce437105ff6c"}, + {file = "grpcio-1.59.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:c4dfdb49f4997dc664f30116af2d34751b91aa031f8c8ee251ce4dcfc11277b0"}, + {file = "grpcio-1.59.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:61bc72a00ecc2b79d9695220b4d02e8ba53b702b42411397e831c9b0589f08a3"}, + {file = "grpcio-1.59.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f367e4b524cb319e50acbdea57bb63c3b717c5d561974ace0b065a648bb3bad3"}, + {file = "grpcio-1.59.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:849c47ef42424c86af069a9c5e691a765e304079755d5c29eff511263fad9c2a"}, + {file = "grpcio-1.59.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c0488c2b0528e6072010182075615620071371701733c63ab5be49140ed8f7f0"}, + {file = "grpcio-1.59.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:611d9aa0017fa386809bddcb76653a5ab18c264faf4d9ff35cb904d44745f575"}, + {file = "grpcio-1.59.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e5378785dce2b91eb2e5b857ec7602305a3b5cf78311767146464bfa365fc897"}, + {file = "grpcio-1.59.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:fe976910de34d21057bcb53b2c5e667843588b48bf11339da2a75f5c4c5b4055"}, + {file = "grpcio-1.59.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:c041a91712bf23b2a910f61e16565a05869e505dc5a5c025d429ca6de5de842c"}, + {file = "grpcio-1.59.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:0ae444221b2c16d8211b55326f8ba173ba8f8c76349bfc1768198ba592b58f74"}, + {file = "grpcio-1.59.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ceb1e68135788c3fce2211de86a7597591f0b9a0d2bb80e8401fd1d915991bac"}, + {file = "grpcio-1.59.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c4b1cc3a9dc1924d2eb26eec8792fedd4b3fcd10111e26c1d551f2e4eda79ce"}, + {file = "grpcio-1.59.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:871371ce0c0055d3db2a86fdebd1e1d647cf21a8912acc30052660297a5a6901"}, + {file = "grpcio-1.59.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:93e9cb546e610829e462147ce724a9cb108e61647a3454500438a6deef610be1"}, + {file = "grpcio-1.59.0-cp38-cp38-win32.whl", hash = "sha256:f21917aa50b40842b51aff2de6ebf9e2f6af3fe0971c31960ad6a3a2b24988f4"}, + {file = "grpcio-1.59.0-cp38-cp38-win_amd64.whl", hash = "sha256:14890da86a0c0e9dc1ea8e90101d7a3e0e7b1e71f4487fab36e2bfd2ecadd13c"}, + {file = "grpcio-1.59.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:34341d9e81a4b669a5f5dca3b2a760b6798e95cdda2b173e65d29d0b16692857"}, + {file = "grpcio-1.59.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:986de4aa75646e963466b386a8c5055c8b23a26a36a6c99052385d6fe8aaf180"}, + {file = "grpcio-1.59.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:aca8a24fef80bef73f83eb8153f5f5a0134d9539b4c436a716256b311dda90a6"}, + {file = "grpcio-1.59.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:936b2e04663660c600d5173bc2cc84e15adbad9c8f71946eb833b0afc205b996"}, + {file = "grpcio-1.59.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc8bf2e7bc725e76c0c11e474634a08c8f24bcf7426c0c6d60c8f9c6e70e4d4a"}, + {file = "grpcio-1.59.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81d86a096ccd24a57fa5772a544c9e566218bc4de49e8c909882dae9d73392df"}, + {file = "grpcio-1.59.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2ea95cd6abbe20138b8df965b4a8674ec312aaef3147c0f46a0bac661f09e8d0"}, + {file = "grpcio-1.59.0-cp39-cp39-win32.whl", hash = "sha256:3b8ff795d35a93d1df6531f31c1502673d1cebeeba93d0f9bd74617381507e3f"}, + {file = "grpcio-1.59.0-cp39-cp39-win_amd64.whl", hash = "sha256:38823bd088c69f59966f594d087d3a929d1ef310506bee9e3648317660d65b81"}, + {file = "grpcio-1.59.0.tar.gz", hash = "sha256:acf70a63cf09dd494000007b798aff88a436e1c03b394995ce450be437b8e54f"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.59.0)"] [[package]] name = "grpcio-status" version = "1.48.2" description = "Status proto mapping for gRPC" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1151,7 +1411,6 @@ protobuf = ">=3.12.0" name = "h5py" version = "3.9.0" description = "Read and write HDF5 files from Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1185,7 +1444,6 @@ numpy = ">=1.17.3" name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1197,7 +1455,6 @@ files = [ name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1209,7 +1466,6 @@ files = [ name = "importlib-metadata" version = "6.8.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1227,28 +1483,26 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs [[package]] name = "importlib-resources" -version = "6.0.1" +version = "6.1.0" description = "Read resources from Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"}, - {file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"}, + {file = "importlib_resources-6.1.0-py3-none-any.whl", hash = "sha256:aa50258bbfa56d4e33fbd8aa3ef48ded10d1735f11532b8df95388cc6bdb7e83"}, + {file = "importlib_resources-6.1.0.tar.gz", hash = "sha256:9d48dcccc213325e810fd723e7fbb45ccb39f6cf5c31f00cf2b965f5f10f3cb9"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"] [[package]] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1256,11 +1510,21 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "installer" +version = "0.7.0" +description = "A library for installing Python wheels." +optional = false +python-versions = ">=3.7" +files = [ + {file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"}, + {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"}, +] + [[package]] name = "ipykernel" version = "6.25.2" description = "IPython Kernel for Jupyter" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1274,7 +1538,7 @@ comm = ">=0.1.1" debugpy = ">=1.6.5" ipython = ">=7.23.1" jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" @@ -1292,14 +1556,13 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.12.2" +version = "8.12.3" description = "IPython: Productive Interactive Computing" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "ipython-8.12.2-py3-none-any.whl", hash = "sha256:ea8801f15dfe4ffb76dea1b09b847430ffd70d827b41735c64a0638a04103bfc"}, - {file = "ipython-8.12.2.tar.gz", hash = "sha256:c7b80eb7f5a855a88efc971fda506ff7a91c280b42cdae26643e0f601ea281ea"}, + {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, + {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, ] [package.dependencies] @@ -1332,22 +1595,21 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa [[package]] name = "ipywidgets" -version = "8.1.0" +version = "8.1.1" description = "Jupyter interactive widgets" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "ipywidgets-8.1.0-py3-none-any.whl", hash = "sha256:6c8396cc7b8c95dfb4e9ab0054f48c002f045e7e5d7ae523f559d64e525a98ab"}, - {file = "ipywidgets-8.1.0.tar.gz", hash = "sha256:ce97dd90525b3066fd00094690964e7eac14cf9b7745d35565b5eeac20cce687"}, + {file = "ipywidgets-8.1.1-py3-none-any.whl", hash = "sha256:2b88d728656aea3bbfd05d32c747cfd0078f9d7e159cf982433b58ad717eed7f"}, + {file = "ipywidgets-8.1.1.tar.gz", hash = "sha256:40211efb556adec6fa450ccc2a77d59ca44a060f4f9f136833df59c9f538e6e8"}, ] [package.dependencies] comm = ">=0.1.3" ipython = ">=6.1.0" -jupyterlab-widgets = ">=3.0.7,<3.1.0" +jupyterlab-widgets = ">=3.0.9,<3.1.0" traitlets = ">=4.3.1" -widgetsnbextension = ">=4.0.7,<4.1.0" +widgetsnbextension = ">=4.0.9,<4.1.0" [package.extras] test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] @@ -1356,7 +1618,6 @@ test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "main" optional = false python-versions = ">=3.8.0" files = [ @@ -1370,16 +1631,33 @@ pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib" plugins = ["setuptools"] requirements-deprecated-finder = ["pip-api", "pipreqs"] +[[package]] +name = "jaraco-classes" +version = "3.3.0" +description = "Utility functions for Python class constructs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jaraco.classes-3.3.0-py3-none-any.whl", hash = "sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb"}, + {file = "jaraco.classes-3.3.0.tar.gz", hash = "sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621"}, +] + +[package.dependencies] +more-itertools = "*" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + [[package]] name = "jedi" -version = "0.19.0" +version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "jedi-0.19.0-py2.py3-none-any.whl", hash = "sha256:cb8ce23fbccff0025e9386b5cf85e892f94c9b822378f8da49970471335ac64e"}, - {file = "jedi-0.19.0.tar.gz", hash = "sha256:bcf9894f1753969cbac8022a8c2eaee06bfa3724e4192470aaffe7eb6272b0c4"}, + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, ] [package.dependencies] @@ -1388,13 +1666,27 @@ parso = ">=0.8.3,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + +[[package]] +name = "jeepney" +version = "0.8.0" +description = "Low-level, pure Python DBus protocol wrapper." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"}, + {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, +] + +[package.extras] +test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] +trio = ["async_generator", "trio"] [[package]] name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1410,49 +1702,29 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.19.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"}, - {file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] [package.dependencies] -attrs = ">=22.2.0" +attrs = ">=17.4.0" importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -jsonschema-specifications = ">=2023.03.6" pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} -referencing = ">=0.28.4" -rpds-py = ">=0.7.1" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] -[[package]] -name = "jsonschema-specifications" -version = "2023.7.1" -description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -category = "main" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, - {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, -] - -[package.dependencies] -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -referencing = ">=0.28.0" - [[package]] name = "jupyter-cache" version = "0.6.1" description = "A defined interface for working with a cache of jupyter notebooks." -category = "main" optional = false python-versions = "~=3.8" files = [ @@ -1480,7 +1752,6 @@ testing = ["coverage", "ipykernel", "jupytext", "matplotlib", "nbdime", "nbforma name = "jupyter-client" version = "8.3.1" description = "Jupyter protocol implementation and client libraries" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1490,7 +1761,7 @@ files = [ [package.dependencies] importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" tornado = ">=6.2" @@ -1502,14 +1773,13 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt [[package]] name = "jupyter-core" -version = "5.3.1" +version = "5.3.2" description = "Jupyter core package. A base package on which Jupyter projects rely." -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.3.1-py3-none-any.whl", hash = "sha256:ae9036db959a71ec1cac33081eeb040a79e681f08ab68b0883e9a676c7a90dce"}, - {file = "jupyter_core-5.3.1.tar.gz", hash = "sha256:5ba5c7938a7f97a6b0481463f7ff0dbac7c15ba48cf46fa4035ca6e838aa1aba"}, + {file = "jupyter_core-5.3.2-py3-none-any.whl", hash = "sha256:a4af53c3fa3f6330cebb0d9f658e148725d15652811d1c32dc0f63bb96f2e6d6"}, + {file = "jupyter_core-5.3.2.tar.gz", hash = "sha256:0c28db6cbe2c37b5b398e1a1a5b22f84fd64cd10afc1f6c05b02fb09481ba45f"}, ] [package.dependencies] @@ -1523,21 +1793,43 @@ test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] [[package]] name = "jupyterlab-widgets" -version = "3.0.8" +version = "3.0.9" description = "Jupyter interactive widgets for JupyterLab" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "jupyterlab_widgets-3.0.8-py3-none-any.whl", hash = "sha256:4715912d6ceab839c9db35953c764b3214ebbc9161c809f6e0510168845dfdf5"}, - {file = "jupyterlab_widgets-3.0.8.tar.gz", hash = "sha256:d428ab97b8d87cc7c54cbf37644d6e0f0e662f23876e05fa460a73ec3257252a"}, + {file = "jupyterlab_widgets-3.0.9-py3-none-any.whl", hash = "sha256:3cf5bdf5b897bf3bccf1c11873aa4afd776d7430200f765e0686bd352487b58d"}, + {file = "jupyterlab_widgets-3.0.9.tar.gz", hash = "sha256:6005a4e974c7beee84060fdfba341a3218495046de8ae3ec64888e5fe19fdb4c"}, ] +[[package]] +name = "keyring" +version = "24.2.0" +description = "Store and access your passwords safely." +optional = false +python-versions = ">=3.8" +files = [ + {file = "keyring-24.2.0-py3-none-any.whl", hash = "sha256:4901caaf597bfd3bbd78c9a0c7c4c29fcd8310dab2cffefe749e916b6527acd6"}, + {file = "keyring-24.2.0.tar.gz", hash = "sha256:ca0746a19ec421219f4d713f848fa297a661a8a8c1504867e55bfb5e09091509"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.11.4", markers = "python_version < \"3.12\""} +importlib-resources = {version = "*", markers = "python_version < \"3.9\""} +"jaraco.classes" = "*" +jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} +pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} +SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} + +[package.extras] +completion = ["shtab"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + [[package]] name = "kiwisolver" version = "1.4.5" description = "A fast implementation of the Cassowary constraint solver" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1649,47 +1941,41 @@ files = [ [[package]] name = "llvmlite" -version = "0.39.1" +version = "0.40.1" description = "lightweight wrapper around basic LLVM functionality" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "llvmlite-0.39.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6717c7a6e93c9d2c3d07c07113ec80ae24af45cde536b34363d4bcd9188091d9"}, - {file = "llvmlite-0.39.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ddab526c5a2c4ccb8c9ec4821fcea7606933dc53f510e2a6eebb45a418d3488a"}, - {file = "llvmlite-0.39.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3f331a323d0f0ada6b10d60182ef06c20a2f01be21699999d204c5750ffd0b4"}, - {file = "llvmlite-0.39.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c00ff204afa721b0bb9835b5bf1ba7fba210eefcec5552a9e05a63219ba0dc"}, - {file = "llvmlite-0.39.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16f56eb1eec3cda3a5c526bc3f63594fc24e0c8d219375afeb336f289764c6c7"}, - {file = "llvmlite-0.39.1-cp310-cp310-win32.whl", hash = "sha256:d0bfd18c324549c0fec2c5dc610fd024689de6f27c6cc67e4e24a07541d6e49b"}, - {file = "llvmlite-0.39.1-cp310-cp310-win_amd64.whl", hash = "sha256:7ebf1eb9badc2a397d4f6a6c8717447c81ac011db00064a00408bc83c923c0e4"}, - {file = "llvmlite-0.39.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6546bed4e02a1c3d53a22a0bced254b3b6894693318b16c16c8e43e29d6befb6"}, - {file = "llvmlite-0.39.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1578f5000fdce513712e99543c50e93758a954297575610f48cb1fd71b27c08a"}, - {file = "llvmlite-0.39.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3803f11ad5f6f6c3d2b545a303d68d9fabb1d50e06a8d6418e6fcd2d0df00959"}, - {file = "llvmlite-0.39.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50aea09a2b933dab7c9df92361b1844ad3145bfb8dd2deb9cd8b8917d59306fb"}, - {file = "llvmlite-0.39.1-cp37-cp37m-win32.whl", hash = "sha256:b1a0bbdb274fb683f993198775b957d29a6f07b45d184c571ef2a721ce4388cf"}, - {file = "llvmlite-0.39.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e172c73fccf7d6db4bd6f7de963dedded900d1a5c6778733241d878ba613980e"}, - {file = "llvmlite-0.39.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e31f4b799d530255aaf0566e3da2df5bfc35d3cd9d6d5a3dcc251663656c27b1"}, - {file = "llvmlite-0.39.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:62c0ea22e0b9dffb020601bb65cb11dd967a095a488be73f07d8867f4e327ca5"}, - {file = "llvmlite-0.39.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ffc84ade195abd4abcf0bd3b827b9140ae9ef90999429b9ea84d5df69c9058c"}, - {file = "llvmlite-0.39.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0f158e4708dda6367d21cf15afc58de4ebce979c7a1aa2f6b977aae737e2a54"}, - {file = "llvmlite-0.39.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22d36591cd5d02038912321d9ab8e4668e53ae2211da5523f454e992b5e13c36"}, - {file = "llvmlite-0.39.1-cp38-cp38-win32.whl", hash = "sha256:4c6ebace910410daf0bebda09c1859504fc2f33d122e9a971c4c349c89cca630"}, - {file = "llvmlite-0.39.1-cp38-cp38-win_amd64.whl", hash = "sha256:fb62fc7016b592435d3e3a8f680e3ea8897c3c9e62e6e6cc58011e7a4801439e"}, - {file = "llvmlite-0.39.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa9b26939ae553bf30a9f5c4c754db0fb2d2677327f2511e674aa2f5df941789"}, - {file = "llvmlite-0.39.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e4f212c018db951da3e1dc25c2651abc688221934739721f2dad5ff1dd5f90e7"}, - {file = "llvmlite-0.39.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39dc2160aed36e989610fc403487f11b8764b6650017ff367e45384dff88ffbf"}, - {file = "llvmlite-0.39.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ec3d70b3e507515936e475d9811305f52d049281eaa6c8273448a61c9b5b7e2"}, - {file = "llvmlite-0.39.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60f8dd1e76f47b3dbdee4b38d9189f3e020d22a173c00f930b52131001d801f9"}, - {file = "llvmlite-0.39.1-cp39-cp39-win32.whl", hash = "sha256:03aee0ccd81735696474dc4f8b6be60774892a2929d6c05d093d17392c237f32"}, - {file = "llvmlite-0.39.1-cp39-cp39-win_amd64.whl", hash = "sha256:3fc14e757bc07a919221f0cbaacb512704ce5774d7fcada793f1996d6bc75f2a"}, - {file = "llvmlite-0.39.1.tar.gz", hash = "sha256:b43abd7c82e805261c425d50335be9a6c4f84264e34d6d6e475207300005d572"}, + {file = "llvmlite-0.40.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:84ce9b1c7a59936382ffde7871978cddcda14098e5a76d961e204523e5c372fb"}, + {file = "llvmlite-0.40.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3673c53cb21c65d2ff3704962b5958e967c6fc0bd0cff772998face199e8d87b"}, + {file = "llvmlite-0.40.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bba2747cf5b4954e945c287fe310b3fcc484e2a9d1b0c273e99eb17d103bb0e6"}, + {file = "llvmlite-0.40.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbd5e82cc990e5a3e343a3bf855c26fdfe3bfae55225f00efd01c05bbda79918"}, + {file = "llvmlite-0.40.1-cp310-cp310-win32.whl", hash = "sha256:09f83ea7a54509c285f905d968184bba00fc31ebf12f2b6b1494d677bb7dde9b"}, + {file = "llvmlite-0.40.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b37297f3cbd68d14a97223a30620589d98ad1890e5040c9e5fc181063f4ed49"}, + {file = "llvmlite-0.40.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a66a5bd580951751b4268f4c3bddcef92682814d6bc72f3cd3bb67f335dd7097"}, + {file = "llvmlite-0.40.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:467b43836b388eaedc5a106d76761e388dbc4674b2f2237bc477c6895b15a634"}, + {file = "llvmlite-0.40.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c23edd196bd797dc3a7860799054ea3488d2824ecabc03f9135110c2e39fcbc"}, + {file = "llvmlite-0.40.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a36d9f244b6680cb90bbca66b146dabb2972f4180c64415c96f7c8a2d8b60a36"}, + {file = "llvmlite-0.40.1-cp311-cp311-win_amd64.whl", hash = "sha256:5b3076dc4e9c107d16dc15ecb7f2faf94f7736cd2d5e9f4dc06287fd672452c1"}, + {file = "llvmlite-0.40.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4a7525db121f2e699809b539b5308228854ccab6693ecb01b52c44a2f5647e20"}, + {file = "llvmlite-0.40.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:84747289775d0874e506f907a4513db889471607db19b04de97d144047fec885"}, + {file = "llvmlite-0.40.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e35766e42acef0fe7d1c43169a8ffc327a47808fae6a067b049fe0e9bbf84dd5"}, + {file = "llvmlite-0.40.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cda71de10a1f48416309e408ea83dab5bf36058f83e13b86a2961defed265568"}, + {file = "llvmlite-0.40.1-cp38-cp38-win32.whl", hash = "sha256:96707ebad8b051bbb4fc40c65ef93b7eeee16643bd4d579a14d11578e4b7a647"}, + {file = "llvmlite-0.40.1-cp38-cp38-win_amd64.whl", hash = "sha256:e44f854dc11559795bcdeaf12303759e56213d42dabbf91a5897aa2d8b033810"}, + {file = "llvmlite-0.40.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f643d15aacd0b0b0dc8b74b693822ba3f9a53fa63bc6a178c2dba7cc88f42144"}, + {file = "llvmlite-0.40.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39a0b4d0088c01a469a5860d2e2d7a9b4e6a93c0f07eb26e71a9a872a8cadf8d"}, + {file = "llvmlite-0.40.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9329b930d699699846623054121ed105fd0823ed2180906d3b3235d361645490"}, + {file = "llvmlite-0.40.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2dbbb8424037ca287983b115a29adf37d806baf7e1bf4a67bd2cffb74e085ed"}, + {file = "llvmlite-0.40.1-cp39-cp39-win32.whl", hash = "sha256:e74e7bec3235a1e1c9ad97d897a620c5007d0ed80c32c84c1d787e7daa17e4ec"}, + {file = "llvmlite-0.40.1-cp39-cp39-win_amd64.whl", hash = "sha256:ff8f31111bb99d135ff296757dc81ab36c2dee54ed4bd429158a96da9807c316"}, + {file = "llvmlite-0.40.1.tar.gz", hash = "sha256:5cdb0d45df602099d833d50bd9e81353a5e036242d3c003c5b294fc61d1986b4"}, ] [[package]] name = "markdown-it-py" version = "2.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1714,7 +2000,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1738,6 +2023,16 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -1772,53 +2067,58 @@ files = [ [[package]] name = "matplotlib" -version = "3.7.2" +version = "3.7.3" description = "Python plotting package" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:2699f7e73a76d4c110f4f25be9d2496d6ab4f17345307738557d345f099e07de"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a8035ba590658bae7562786c9cc6ea1a84aa49d3afab157e414c9e2ea74f496d"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8e4a49493add46ad4a8c92f63e19d548b2b6ebbed75c6b4c7f46f57d36cdd1"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71667eb2ccca4c3537d9414b1bc00554cb7f91527c17ee4ec38027201f8f1603"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:152ee0b569a37630d8628534c628456b28686e085d51394da6b71ef84c4da201"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070f8dddd1f5939e60aacb8fa08f19551f4b0140fab16a3669d5cd6e9cb28fc8"}, - {file = "matplotlib-3.7.2-cp310-cp310-win32.whl", hash = "sha256:fdbb46fad4fb47443b5b8ac76904b2e7a66556844f33370861b4788db0f8816a"}, - {file = "matplotlib-3.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:23fb1750934e5f0128f9423db27c474aa32534cec21f7b2153262b066a581fd1"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:30e1409b857aa8a747c5d4f85f63a79e479835f8dffc52992ac1f3f25837b544"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:50e0a55ec74bf2d7a0ebf50ac580a209582c2dd0f7ab51bc270f1b4a0027454e"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac60daa1dc83e8821eed155796b0f7888b6b916cf61d620a4ddd8200ac70cd64"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305e3da477dc8607336ba10bac96986d6308d614706cae2efe7d3ffa60465b24"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c308b255efb9b06b23874236ec0f10f026673ad6515f602027cc8ac7805352d"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c521e21031632aa0d87ca5ba0c1c05f3daacadb34c093585a0be6780f698e4"}, - {file = "matplotlib-3.7.2-cp311-cp311-win32.whl", hash = "sha256:26bede320d77e469fdf1bde212de0ec889169b04f7f1179b8930d66f82b30cbc"}, - {file = "matplotlib-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4860132c8c05261a5f5f8467f1b269bf1c7c23902d75f2be57c4a7f2394b3e"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a1733b8e84e7e40a9853e505fe68cc54339f97273bdfe6f3ed980095f769ddc7"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d9881356dc48e58910c53af82b57183879129fa30492be69058c5b0d9fddf391"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f081c03f413f59390a80b3e351cc2b2ea0205839714dbc364519bcf51f4b56ca"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cd120fca3407a225168238b790bd5c528f0fafde6172b140a2f3ab7a4ea63e9"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2c1590b90aa7bd741b54c62b78de05d4186271e34e2377e0289d943b3522273"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d2ff3c984b8a569bc1383cd468fc06b70d7b59d5c2854ca39f1436ae8394117"}, - {file = "matplotlib-3.7.2-cp38-cp38-win32.whl", hash = "sha256:5dea00b62d28654b71ca92463656d80646675628d0828e08a5f3b57e12869e13"}, - {file = "matplotlib-3.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f506a1776ee94f9e131af1ac6efa6e5bc7cb606a3e389b0ccb6e657f60bb676"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6515e878f91894c2e4340d81f0911857998ccaf04dbc1bba781e3d89cbf70608"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:71f7a8c6b124e904db550f5b9fe483d28b896d4135e45c4ea381ad3b8a0e3256"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12f01b92ecd518e0697da4d97d163b2b3aa55eb3eb4e2c98235b3396d7dad55f"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7e28d6396563955f7af437894a36bf2b279462239a41028323e04b85179058b"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbcf59334ff645e6a67cd5f78b4b2cdb76384cdf587fa0d2dc85f634a72e1a3e"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:318c89edde72ff95d8df67d82aca03861240512994a597a435a1011ba18dbc7f"}, - {file = "matplotlib-3.7.2-cp39-cp39-win32.whl", hash = "sha256:ce55289d5659b5b12b3db4dc9b7075b70cef5631e56530f14b2945e8836f2d20"}, - {file = "matplotlib-3.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:2ecb5be2b2815431c81dc115667e33da0f5a1bcf6143980d180d09a717c4a12e"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdcd28360dbb6203fb5219b1a5658df226ac9bebc2542a9e8f457de959d713d0"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3cca3e842b11b55b52c6fb8bd6a4088693829acbfcdb3e815fa9b7d5c92c1b"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebf577c7a6744e9e1bd3fee45fc74a02710b214f94e2bde344912d85e0c9af7c"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:936bba394682049919dda062d33435b3be211dc3dcaa011e09634f060ec878b2"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bc221ffbc2150458b1cd71cdd9ddd5bb37962b036e41b8be258280b5b01da1dd"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35d74ebdb3f71f112b36c2629cf32323adfbf42679e2751252acd468f5001c07"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717157e61b3a71d3d26ad4e1770dc85156c9af435659a25ee6407dc866cb258d"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:20f844d6be031948148ba49605c8b96dfe7d3711d1b63592830d650622458c11"}, - {file = "matplotlib-3.7.2.tar.gz", hash = "sha256:a8cdb91dddb04436bd2f098b8fdf4b81352e68cf4d2c6756fcc414791076569b"}, + {file = "matplotlib-3.7.3-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:085c33b27561d9c04386789d5aa5eb4a932ddef43cfcdd0e01735f9a6e85ce0c"}, + {file = "matplotlib-3.7.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c568e80e1c17f68a727f30f591926751b97b98314d8e59804f54f86ae6fa6a22"}, + {file = "matplotlib-3.7.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7baf98c5ad59c5c4743ea884bb025cbffa52dacdfdac0da3e6021a285a90377e"}, + {file = "matplotlib-3.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:236024f582e40dac39bca592258888b38ae47a9fed7b8de652d68d3d02d47d2b"}, + {file = "matplotlib-3.7.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12b4f6795efea037ce2d41e7c417ad8bd02d5719c6ad4a8450a0708f4a1cfb89"}, + {file = "matplotlib-3.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b2136cc6c5415b78977e0e8c608647d597204b05b1d9089ccf513c7d913733"}, + {file = "matplotlib-3.7.3-cp310-cp310-win32.whl", hash = "sha256:122dcbf9be0086e2a95d9e5e0632dbf3bd5b65eaa68c369363310a6c87753059"}, + {file = "matplotlib-3.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:4aab27d9e33293389e3c1d7c881d414a72bdfda0fedc3a6bf46c6fa88d9b8015"}, + {file = "matplotlib-3.7.3-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:d5adc743de91e8e0b13df60deb1b1c285b8effea3d66223afceb14b63c9b05de"}, + {file = "matplotlib-3.7.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:55de4cf7cd0071b8ebf203981b53ab64f988a0a1f897a2dff300a1124e8bcd8b"}, + {file = "matplotlib-3.7.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac03377fd908aaee2312d0b11735753e907adb6f4d1d102de5e2425249693f6c"}, + {file = "matplotlib-3.7.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:755bafc10a46918ce9a39980009b54b02dd249594e5adf52f9c56acfddb5d0b7"}, + {file = "matplotlib-3.7.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a6094c6f8e8d18db631754df4fe9a34dec3caf074f6869a7db09f18f9b1d6b2"}, + {file = "matplotlib-3.7.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:272dba2f1b107790ed78ebf5385b8d14b27ad9e90419de340364b49fe549a993"}, + {file = "matplotlib-3.7.3-cp311-cp311-win32.whl", hash = "sha256:591c123bed1cb4b9996fb60b41a6d89c2ec4943244540776c5f1283fb6960a53"}, + {file = "matplotlib-3.7.3-cp311-cp311-win_amd64.whl", hash = "sha256:3bf3a178c6504694cee8b88b353df0051583f2f6f8faa146f67115c27c856881"}, + {file = "matplotlib-3.7.3-cp312-cp312-macosx_10_12_universal2.whl", hash = "sha256:edf54cac8ee3603f3093616b40a931e8c063969756a4d78a86e82c2fea9659f7"}, + {file = "matplotlib-3.7.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:91e36a85ea639a1ba9f91427041eac064b04829945fe331a92617b6cb21d27e5"}, + {file = "matplotlib-3.7.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:caf5eaaf7c68f8d7df269dfbcaf46f48a70ff482bfcebdcc97519671023f2a7d"}, + {file = "matplotlib-3.7.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74bf57f505efea376097e948b7cdd87191a7ce8180616390aef496639edf601f"}, + {file = "matplotlib-3.7.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee152a88a0da527840a426535514b6ed8ac4240eb856b1da92cf48124320e346"}, + {file = "matplotlib-3.7.3-cp312-cp312-win_amd64.whl", hash = "sha256:67a410a9c9e07cbc83581eeea144bbe298870bf0ac0ee2f2e10a015ab7efee19"}, + {file = "matplotlib-3.7.3-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:259999c05285cb993d7f2a419cea547863fa215379eda81f7254c9e932963729"}, + {file = "matplotlib-3.7.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:3f4e7fd5a6157e1d018ce2166ec8e531a481dd4a36f035b5c23edfe05a25419a"}, + {file = "matplotlib-3.7.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:faa3d12d8811d08d14080a8b7b9caea9a457dc495350166b56df0db4b9909ef5"}, + {file = "matplotlib-3.7.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:336e88900c11441e458da01c8414fc57e04e17f9d3bb94958a76faa2652bcf6b"}, + {file = "matplotlib-3.7.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:12f4c0dd8aa280d796c8772ea8265a14f11a04319baa3a16daa5556065e8baea"}, + {file = "matplotlib-3.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1990955b11e7918d256cf3b956b10997f405b7917a3f1c7d8e69c1d15c7b1930"}, + {file = "matplotlib-3.7.3-cp38-cp38-win32.whl", hash = "sha256:e78707b751260b42b721507ad7aa60fe4026d7f51c74cca6b9cd8b123ebb633a"}, + {file = "matplotlib-3.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:e594ee43c59ea39ca5c6244667cac9d017a3527febc31f5532ad9135cf7469ec"}, + {file = "matplotlib-3.7.3-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6eaa1cf0e94c936a26b78f6d756c5fbc12e0a58c8a68b7248a2a31456ce4e234"}, + {file = "matplotlib-3.7.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0a97af9d22e8ebedc9f00b043d9bbd29a375e9e10b656982012dded44c10fd77"}, + {file = "matplotlib-3.7.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1f9c6c16597af660433ab330b59ee2934b832ee1fabcaf5cbde7b2add840f31e"}, + {file = "matplotlib-3.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7240259b4b9cbc62381f6378cff4d57af539162a18e832c1e48042fabc40b6b"}, + {file = "matplotlib-3.7.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:747c6191d2e88ae854809e69aa358dbf852ff1a5738401b85c1cc9012309897a"}, + {file = "matplotlib-3.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec726b08a5275d827aa91bb951e68234a4423adb91cf65bc0fcdc0f2777663f7"}, + {file = "matplotlib-3.7.3-cp39-cp39-win32.whl", hash = "sha256:40e3b9b450c6534f07278310c4e34caff41c2a42377e4b9d47b0f8d3ac1083a2"}, + {file = "matplotlib-3.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfc118642903a23e309b1da32886bb39a4314147d013e820c86b5fb4cb2e36d0"}, + {file = "matplotlib-3.7.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:165c8082bf8fc0360c24aa4724a22eaadbfd8c28bf1ccf7e94d685cad48261e4"}, + {file = "matplotlib-3.7.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebd8470cc2a3594746ff0513aecbfa2c55ff6f58e6cef2efb1a54eb87c88ffa2"}, + {file = "matplotlib-3.7.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7153453669c9672b52095119fd21dd032d19225d48413a2871519b17db4b0fde"}, + {file = "matplotlib-3.7.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:498a08267dc69dd8f24c4b5d7423fa584d7ce0027ba71f7881df05fc09b89bb7"}, + {file = "matplotlib-3.7.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48999c4b19b5a0c058c9cd828ff6fc7748390679f6cf9a2ad653a3e802c87d3"}, + {file = "matplotlib-3.7.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22d65d18b4ee8070a5fea5761d59293f1f9e2fac37ec9ce090463b0e629432fd"}, + {file = "matplotlib-3.7.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c40cde976c36693cc0767e27cf5f443f91c23520060bd9496678364adfafe9c"}, + {file = "matplotlib-3.7.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:39018a2b17592448fbfdf4b8352955e6c3905359939791d4ff429296494d1a0c"}, + {file = "matplotlib-3.7.3.tar.gz", hash = "sha256:f09b3dd6bdeb588de91f853bbb2d6f0ff8ab693485b0c49035eaa510cb4f142e"}, ] [package.dependencies] @@ -1827,17 +2127,17 @@ cycler = ">=0.10" fonttools = ">=4.22.0" importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} kiwisolver = ">=1.0.1" -numpy = ">=1.20" +numpy = ">=1.20,<2" packaging = ">=20.0" pillow = ">=6.2.0" -pyparsing = ">=2.3.1,<3.1" +pyparsing = ">=2.3.1" python-dateutil = ">=2.7" +setuptools_scm = ">=7" [[package]] name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1852,7 +2152,6 @@ traitlets = "*" name = "mccabe" version = "0.6.1" description = "McCabe checker, plugin for flake8" -category = "main" optional = false python-versions = "*" files = [ @@ -1864,7 +2163,6 @@ files = [ name = "mdit-py-plugins" version = "0.3.5" description = "Collection of plugins for markdown-it-py" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1884,7 +2182,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1892,11 +2189,21 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "more-itertools" +version = "10.1.0" +description = "More routines for operating on iterables, beyond itertools" +optional = false +python-versions = ">=3.8" +files = [ + {file = "more-itertools-10.1.0.tar.gz", hash = "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a"}, + {file = "more_itertools-10.1.0-py3-none-any.whl", hash = "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6"}, +] + [[package]] name = "mpmath" version = "1.3.0" description = "Python library for arbitrary-precision floating-point arithmetic" -category = "main" optional = false python-versions = "*" files = [ @@ -1912,82 +2219,73 @@ tests = ["pytest (>=4.6)"] [[package]] name = "msgpack" -version = "1.0.5" +version = "1.0.7" description = "MessagePack serializer" -category = "main" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:525228efd79bb831cf6830a732e2e80bc1b05436b086d4264814b4b2955b2fa9"}, - {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f8d8b3bf1ff2672567d6b5c725a1b347fe838b912772aa8ae2bf70338d5a198"}, - {file = "msgpack-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdc793c50be3f01106245a61b739328f7dccc2c648b501e237f0699fe1395b81"}, - {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cb47c21a8a65b165ce29f2bec852790cbc04936f502966768e4aae9fa763cb7"}, - {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e42b9594cc3bf4d838d67d6ed62b9e59e201862a25e9a157019e171fbe672dd3"}, - {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:55b56a24893105dc52c1253649b60f475f36b3aa0fc66115bffafb624d7cb30b"}, - {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1967f6129fc50a43bfe0951c35acbb729be89a55d849fab7686004da85103f1c"}, - {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a97bf595a232c3ee6d57ddaadd5453d174a52594bf9c21d10407e2a2d9b3bd"}, - {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d25dd59bbbbb996eacf7be6b4ad082ed7eacc4e8f3d2df1ba43822da9bfa122a"}, - {file = "msgpack-1.0.5-cp310-cp310-win32.whl", hash = "sha256:382b2c77589331f2cb80b67cc058c00f225e19827dbc818d700f61513ab47bea"}, - {file = "msgpack-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:4867aa2df9e2a5fa5f76d7d5565d25ec76e84c106b55509e78c1ede0f152659a"}, - {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9f5ae84c5c8a857ec44dc180a8b0cc08238e021f57abdf51a8182e915e6299f0"}, - {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e6ca5d5699bcd89ae605c150aee83b5321f2115695e741b99618f4856c50898"}, - {file = "msgpack-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5494ea30d517a3576749cad32fa27f7585c65f5f38309c88c6d137877fa28a5a"}, - {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ab2f3331cb1b54165976a9d976cb251a83183631c88076613c6c780f0d6e45a"}, - {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28592e20bbb1620848256ebc105fc420436af59515793ed27d5c77a217477705"}, - {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe5c63197c55bce6385d9aee16c4d0641684628f63ace85f73571e65ad1c1e8d"}, - {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed40e926fa2f297e8a653c954b732f125ef97bdd4c889f243182299de27e2aa9"}, - {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b2de4c1c0538dcb7010902a2b97f4e00fc4ddf2c8cda9749af0e594d3b7fa3d7"}, - {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf22a83f973b50f9d38e55c6aade04c41ddda19b00c4ebc558930d78eecc64ed"}, - {file = "msgpack-1.0.5-cp311-cp311-win32.whl", hash = "sha256:c396e2cc213d12ce017b686e0f53497f94f8ba2b24799c25d913d46c08ec422c"}, - {file = "msgpack-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c4c68d87497f66f96d50142a2b73b97972130d93677ce930718f68828b382e2"}, - {file = "msgpack-1.0.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a2b031c2e9b9af485d5e3c4520f4220d74f4d222a5b8dc8c1a3ab9448ca79c57"}, - {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f837b93669ce4336e24d08286c38761132bc7ab29782727f8557e1eb21b2080"}, - {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1d46dfe3832660f53b13b925d4e0fa1432b00f5f7210eb3ad3bb9a13c6204a6"}, - {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:366c9a7b9057e1547f4ad51d8facad8b406bab69c7d72c0eb6f529cf76d4b85f"}, - {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4c075728a1095efd0634a7dccb06204919a2f67d1893b6aa8e00497258bf926c"}, - {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:f933bbda5a3ee63b8834179096923b094b76f0c7a73c1cfe8f07ad608c58844b"}, - {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:36961b0568c36027c76e2ae3ca1132e35123dcec0706c4b7992683cc26c1320c"}, - {file = "msgpack-1.0.5-cp36-cp36m-win32.whl", hash = "sha256:b5ef2f015b95f912c2fcab19c36814963b5463f1fb9049846994b007962743e9"}, - {file = "msgpack-1.0.5-cp36-cp36m-win_amd64.whl", hash = "sha256:288e32b47e67f7b171f86b030e527e302c91bd3f40fd9033483f2cacc37f327a"}, - {file = "msgpack-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:137850656634abddfb88236008339fdaba3178f4751b28f270d2ebe77a563b6c"}, - {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c05a4a96585525916b109bb85f8cb6511db1c6f5b9d9cbcbc940dc6b4be944b"}, - {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a62ec00b636583e5cb6ad313bbed36bb7ead5fa3a3e38938503142c72cba4f"}, - {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef8108f8dedf204bb7b42994abf93882da1159728a2d4c5e82012edd92c9da9f"}, - {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1835c84d65f46900920b3708f5ba829fb19b1096c1800ad60bae8418652a951d"}, - {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e57916ef1bd0fee4f21c4600e9d1da352d8816b52a599c46460e93a6e9f17086"}, - {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:17358523b85973e5f242ad74aa4712b7ee560715562554aa2134d96e7aa4cbbf"}, - {file = "msgpack-1.0.5-cp37-cp37m-win32.whl", hash = "sha256:cb5aaa8c17760909ec6cb15e744c3ebc2ca8918e727216e79607b7bbce9c8f77"}, - {file = "msgpack-1.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:ab31e908d8424d55601ad7075e471b7d0140d4d3dd3272daf39c5c19d936bd82"}, - {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b72d0698f86e8d9ddf9442bdedec15b71df3598199ba33322d9711a19f08145c"}, - {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:379026812e49258016dd84ad79ac8446922234d498058ae1d415f04b522d5b2d"}, - {file = "msgpack-1.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:332360ff25469c346a1c5e47cbe2a725517919892eda5cfaffe6046656f0b7bb"}, - {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:476a8fe8fae289fdf273d6d2a6cb6e35b5a58541693e8f9f019bfe990a51e4ba"}, - {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9985b214f33311df47e274eb788a5893a761d025e2b92c723ba4c63936b69b1"}, - {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48296af57cdb1d885843afd73c4656be5c76c0c6328db3440c9601a98f303d87"}, - {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:addab7e2e1fcc04bd08e4eb631c2a90960c340e40dfc4a5e24d2ff0d5a3b3edb"}, - {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:916723458c25dfb77ff07f4c66aed34e47503b2eb3188b3adbec8d8aa6e00f48"}, - {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:821c7e677cc6acf0fd3f7ac664c98803827ae6de594a9f99563e48c5a2f27eb0"}, - {file = "msgpack-1.0.5-cp38-cp38-win32.whl", hash = "sha256:1c0f7c47f0087ffda62961d425e4407961a7ffd2aa004c81b9c07d9269512f6e"}, - {file = "msgpack-1.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:bae7de2026cbfe3782c8b78b0db9cbfc5455e079f1937cb0ab8d133496ac55e1"}, - {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:20c784e66b613c7f16f632e7b5e8a1651aa5702463d61394671ba07b2fc9e025"}, - {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:266fa4202c0eb94d26822d9bfd7af25d1e2c088927fe8de9033d929dd5ba24c5"}, - {file = "msgpack-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18334484eafc2b1aa47a6d42427da7fa8f2ab3d60b674120bce7a895a0a85bdd"}, - {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57e1f3528bd95cc44684beda696f74d3aaa8a5e58c816214b9046512240ef437"}, - {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586d0d636f9a628ddc6a17bfd45aa5b5efaf1606d2b60fa5d87b8986326e933f"}, - {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a740fa0e4087a734455f0fc3abf5e746004c9da72fbd541e9b113013c8dc3282"}, - {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3055b0455e45810820db1f29d900bf39466df96ddca11dfa6d074fa47054376d"}, - {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a61215eac016f391129a013c9e46f3ab308db5f5ec9f25811e811f96962599a8"}, - {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:362d9655cd369b08fda06b6657a303eb7172d5279997abe094512e919cf74b11"}, - {file = "msgpack-1.0.5-cp39-cp39-win32.whl", hash = "sha256:ac9dd47af78cae935901a9a500104e2dea2e253207c924cc95de149606dc43cc"}, - {file = "msgpack-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:06f5174b5f8ed0ed919da0e62cbd4ffde676a374aba4020034da05fab67b9164"}, - {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, + {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"}, + {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"}, + {file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"}, + {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"}, + {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"}, + {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"}, + {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"}, + {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"}, + {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"}, + {file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"}, + {file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"}, + {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"}, + {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"}, + {file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"}, + {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"}, + {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"}, + {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"}, + {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"}, + {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"}, + {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"}, + {file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"}, + {file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"}, + {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"}, + {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"}, + {file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"}, + {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"}, + {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"}, + {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"}, + {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"}, + {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"}, + {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"}, + {file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"}, + {file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"}, + {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95"}, + {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0"}, + {file = "msgpack-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7"}, + {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d"}, + {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524"}, + {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc"}, + {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc"}, + {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf"}, + {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c"}, + {file = "msgpack-1.0.7-cp38-cp38-win32.whl", hash = "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2"}, + {file = "msgpack-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c"}, + {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"}, + {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"}, + {file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"}, + {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"}, + {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"}, + {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"}, + {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"}, + {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"}, + {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"}, + {file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"}, + {file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"}, + {file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"}, ] [[package]] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1999,7 +2297,6 @@ files = [ name = "myst-nb" version = "0.17.2" description = "A Jupyter Notebook Sphinx reader built on top of the MyST markdown parser." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2028,7 +2325,6 @@ testing = ["beautifulsoup4", "coverage (>=6.4,<8.0)", "ipykernel (>=5.5,<6.0)", name = "myst-parser" version = "0.18.1" description = "An extended commonmark compliant parser, with bridges to docutils & sphinx." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2055,7 +2351,6 @@ testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov", name = "nbclient" version = "0.7.4" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -2065,7 +2360,7 @@ files = [ [package.dependencies] jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" nbformat = ">=5.1" traitlets = ">=5.3" @@ -2078,7 +2373,6 @@ test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "p name = "nbformat" version = "5.9.2" description = "The Jupyter Notebook format" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2100,7 +2394,6 @@ test = ["pep440", "pre-commit", "pytest", "testpath"] name = "ncon" version = "1.0.0" description = "Tensor network contraction function for Python 3." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2116,21 +2409,19 @@ tests = ["coverage", "pytest"] [[package]] name = "nest-asyncio" -version = "1.5.7" +version = "1.5.8" description = "Patch asyncio to allow nested event loops" -category = "main" optional = false python-versions = ">=3.5" files = [ - {file = "nest_asyncio-1.5.7-py3-none-any.whl", hash = "sha256:5301c82941b550b3123a1ea772ba9a1c80bad3a182be8c1a5ae6ad3be57a9657"}, - {file = "nest_asyncio-1.5.7.tar.gz", hash = "sha256:6a80f7b98f24d9083ed24608977c09dd608d83f91cccc24c9d2cba6d10e01c10"}, + {file = "nest_asyncio-1.5.8-py3-none-any.whl", hash = "sha256:accda7a339a70599cb08f9dd09a67e0c2ef8d8d6f4c07f96ab203f2ae254e48d"}, + {file = "nest_asyncio-1.5.8.tar.gz", hash = "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb"}, ] [[package]] name = "networkx" version = "2.8.8" description = "Python package for creating and manipulating graphs and networks" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2147,85 +2438,83 @@ test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "numba" -version = "0.56.0" +version = "0.57.1" description = "compiling Python code using LLVM" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "numba-0.56.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:885174997a1c875f8fa56d17451c96001c571090083e59c5973eeb26616a88e8"}, - {file = "numba-0.56.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f9696d2d800860f1820127190dc58d4b754cff98d913c11e0c00cfd5273b607a"}, - {file = "numba-0.56.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:606b746e4799ea734dcb57bc1182d4af9192b8634ddefbc8790048c157a442c6"}, - {file = "numba-0.56.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:452b076b082cb91476c309c90a5ecb1094608e777c7b6d1b38a11b3d90585826"}, - {file = "numba-0.56.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a4482b921644c8415e15ccf180d866ea95fc499fe29ca5f27a9aa61aa484133e"}, - {file = "numba-0.56.0-cp310-cp310-win32.whl", hash = "sha256:50e156bc1d29457a5db25d2df8745e0caa178ef8c9cd2507236eda4cdb1aa05e"}, - {file = "numba-0.56.0-cp310-cp310-win_amd64.whl", hash = "sha256:f3558988e9d05efb2d552ed747124e4d2f0313b6664451a995f971904aeb83f6"}, - {file = "numba-0.56.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:4fd22a209dda8a662392fd06db426c13be029cd0a0a5d8d4eb5d6da4813093a4"}, - {file = "numba-0.56.0-cp37-cp37m-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb07dce1492ebaf3890859178c9bbe8f45d5b9075c6745372ee4c735a785ce07"}, - {file = "numba-0.56.0-cp37-cp37m-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:aa7cd6ca961072f6c073d9fc501b9c019d9140276ef782ba7913e786ca71a84a"}, - {file = "numba-0.56.0-cp37-cp37m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bc09a025e11627fdca888e8d49dae16d2a3dcc5b58f95627ee37e1637e281d9d"}, - {file = "numba-0.56.0-cp37-cp37m-win32.whl", hash = "sha256:4393f4c8a46f454a9f3007f442506b19803fffd72f3e241607b1d42162ca0bb2"}, - {file = "numba-0.56.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3785329ee5f71321f672ccf27ea05ac80df84b8d20f5f6fdcf863d01cc0e64ce"}, - {file = "numba-0.56.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:949f03f7744a0ec3257e87ac2da7ca82c599a9da679321bf120caf0df1f16d2c"}, - {file = "numba-0.56.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c72fddecd4499efc8ace9f54ef46fefdae6690e687f378e20314bddde4d13ee6"}, - {file = "numba-0.56.0-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c5fc5c14b7d9ab9a71519c1203bc1b28f80893693ef0b1b660a9d464e18b6a0d"}, - {file = "numba-0.56.0-cp38-cp38-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1ae20b2e811b707632ca2a80a62b4f60bff98af71e28690541e427c336c464e7"}, - {file = "numba-0.56.0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1f7f5fcc4d69a2d59182e566e68f87cfde09d25f952a00c70c679d046664b12d"}, - {file = "numba-0.56.0-cp38-cp38-win32.whl", hash = "sha256:e45395d77a91fc9d91d8ab1c90de14579f312bd23d6122856737e227d599c726"}, - {file = "numba-0.56.0-cp38-cp38-win_amd64.whl", hash = "sha256:b963149ddb7d26eca1aff0b1f54e8d6e5020e8a459d724f58f6adb157f36c27c"}, - {file = "numba-0.56.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:4a613ff04d32e160a4bf2fcc5f805a03d9e3e3d8f2d3c9a742407880e66d8e0f"}, - {file = "numba-0.56.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f4c6c0ba5950c2d92d4688162887f194798abf5039fd94060a31bade91ef8638"}, - {file = "numba-0.56.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e06b6ffc0c3efda7b8b1c41b5244c856cf9e04efa77c48d6f788ef3a003704c7"}, - {file = "numba-0.56.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:34627da15052dc0480640e35bc1be72b9cfc253dedea8d15891f0066e5d1f58f"}, - {file = "numba-0.56.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cba64cd7dadfe5fa71a51d1b641e6535f47ee7e61537d5d62d2af3fb3d5fbd02"}, - {file = "numba-0.56.0-cp39-cp39-win32.whl", hash = "sha256:f44b6da86911098eaf910e6e56c5db1d6b851266377880513660f4f8312cadb8"}, - {file = "numba-0.56.0-cp39-cp39-win_amd64.whl", hash = "sha256:8994db76f36d043e883b81784954057893e34de4accd27d35ac2cf27093f40e3"}, - {file = "numba-0.56.0.tar.gz", hash = "sha256:87a647dd4b8fce389869ff71f117732de9a519fe07663d9a02d75724eb8e244d"}, + {file = "numba-0.57.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db8268eb5093cae2288942a8cbd69c9352f6fe6e0bfa0a9a27679436f92e4248"}, + {file = "numba-0.57.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:643cb09a9ba9e1bd8b060e910aeca455e9442361e80fce97690795ff9840e681"}, + {file = "numba-0.57.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:53e9fab973d9e82c9f8449f75994a898daaaf821d84f06fbb0b9de2293dd9306"}, + {file = "numba-0.57.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c0602e4f896e6a6d844517c3ab434bc978e7698a22a733cc8124465898c28fa8"}, + {file = "numba-0.57.1-cp310-cp310-win32.whl", hash = "sha256:3d6483c27520d16cf5d122868b79cad79e48056ecb721b52d70c126bed65431e"}, + {file = "numba-0.57.1-cp310-cp310-win_amd64.whl", hash = "sha256:a32ee263649aa3c3587b833d6311305379529570e6c20deb0c6f4fb5bc7020db"}, + {file = "numba-0.57.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c078f84b5529a7fdb8413bb33d5100f11ec7b44aa705857d9eb4e54a54ff505"}, + {file = "numba-0.57.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e447c4634d1cc99ab50d4faa68f680f1d88b06a2a05acf134aa6fcc0342adeca"}, + {file = "numba-0.57.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4838edef2df5f056cb8974670f3d66562e751040c448eb0b67c7e2fec1726649"}, + {file = "numba-0.57.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9b17fbe4a69dcd9a7cd49916b6463cd9a82af5f84911feeb40793b8bce00dfa7"}, + {file = "numba-0.57.1-cp311-cp311-win_amd64.whl", hash = "sha256:93df62304ada9b351818ba19b1cfbddaf72cd89348e81474326ca0b23bf0bae1"}, + {file = "numba-0.57.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8e00ca63c5d0ad2beeb78d77f087b3a88c45ea9b97e7622ab2ec411a868420ee"}, + {file = "numba-0.57.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ff66d5b022af6c7d81ddbefa87768e78ed4f834ab2da6ca2fd0d60a9e69b94f5"}, + {file = "numba-0.57.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:60ec56386076e9eed106a87c96626d5686fbb16293b9834f0849cf78c9491779"}, + {file = "numba-0.57.1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c057ccedca95df23802b6ccad86bb318be624af45b5a38bb8412882be57a681"}, + {file = "numba-0.57.1-cp38-cp38-win32.whl", hash = "sha256:5a82bf37444039c732485c072fda21a361790ed990f88db57fd6941cd5e5d307"}, + {file = "numba-0.57.1-cp38-cp38-win_amd64.whl", hash = "sha256:9bcc36478773ce838f38afd9a4dfafc328d4ffb1915381353d657da7f6473282"}, + {file = "numba-0.57.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae50c8c90c2ce8057f9618b589223e13faa8cbc037d8f15b4aad95a2c33a0582"}, + {file = "numba-0.57.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9a1b2b69448e510d672ff9a6b18d2db9355241d93c6a77677baa14bec67dc2a0"}, + {file = "numba-0.57.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3cf78d74ad9d289fbc1e5b1c9f2680fca7a788311eb620581893ab347ec37a7e"}, + {file = "numba-0.57.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f47dd214adc5dcd040fe9ad2adbd2192133c9075d2189ce1b3d5f9d72863ef05"}, + {file = "numba-0.57.1-cp39-cp39-win32.whl", hash = "sha256:a3eac19529956185677acb7f01864919761bfffbb9ae04bbbe5e84bbc06cfc2b"}, + {file = "numba-0.57.1-cp39-cp39-win_amd64.whl", hash = "sha256:9587ba1bf5f3035575e45562ada17737535c6d612df751e811d702693a72d95e"}, + {file = "numba-0.57.1.tar.gz", hash = "sha256:33c0500170d213e66d90558ad6aca57d3e03e97bb11da82e6d87ab793648cb17"}, ] [package.dependencies] importlib-metadata = {version = "*", markers = "python_version < \"3.9\""} -llvmlite = ">=0.39.0dev0,<0.40" -numpy = ">=1.18,<1.23" -setuptools = "*" +llvmlite = "==0.40.*" +numpy = ">=1.21,<1.25" [[package]] name = "numpy" -version = "1.22.4" +version = "1.23.5" description = "NumPy is the fundamental package for array computing with Python." -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "numpy-1.22.4-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:ba9ead61dfb5d971d77b6c131a9dbee62294a932bf6a356e48c75ae684e635b3"}, - {file = "numpy-1.22.4-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:1ce7ab2053e36c0a71e7a13a7475bd3b1f54750b4b433adc96313e127b870887"}, - {file = "numpy-1.22.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7228ad13744f63575b3a972d7ee4fd61815b2879998e70930d4ccf9ec721dce0"}, - {file = "numpy-1.22.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43a8ca7391b626b4c4fe20aefe79fec683279e31e7c79716863b4b25021e0e74"}, - {file = "numpy-1.22.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a911e317e8c826ea632205e63ed8507e0dc877dcdc49744584dfc363df9ca08c"}, - {file = "numpy-1.22.4-cp310-cp310-win32.whl", hash = "sha256:9ce7df0abeabe7fbd8ccbf343dc0db72f68549856b863ae3dd580255d009648e"}, - {file = "numpy-1.22.4-cp310-cp310-win_amd64.whl", hash = "sha256:3e1ffa4748168e1cc8d3cde93f006fe92b5421396221a02f2274aab6ac83b077"}, - {file = "numpy-1.22.4-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:59d55e634968b8f77d3fd674a3cf0b96e85147cd6556ec64ade018f27e9479e1"}, - {file = "numpy-1.22.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c1d937820db6e43bec43e8d016b9b3165dcb42892ea9f106c70fb13d430ffe72"}, - {file = "numpy-1.22.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4c5d5eb2ec8da0b4f50c9a843393971f31f1d60be87e0fb0917a49133d257d6"}, - {file = "numpy-1.22.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64f56fc53a2d18b1924abd15745e30d82a5782b2cab3429aceecc6875bd5add0"}, - {file = "numpy-1.22.4-cp38-cp38-win32.whl", hash = "sha256:fb7a980c81dd932381f8228a426df8aeb70d59bbcda2af075b627bbc50207cba"}, - {file = "numpy-1.22.4-cp38-cp38-win_amd64.whl", hash = "sha256:e96d7f3096a36c8754207ab89d4b3282ba7b49ea140e4973591852c77d09eb76"}, - {file = "numpy-1.22.4-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:4c6036521f11a731ce0648f10c18ae66d7143865f19f7299943c985cdc95afb5"}, - {file = "numpy-1.22.4-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:b89bf9b94b3d624e7bb480344e91f68c1c6c75f026ed6755955117de00917a7c"}, - {file = "numpy-1.22.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2d487e06ecbf1dc2f18e7efce82ded4f705f4bd0cd02677ffccfb39e5c284c7e"}, - {file = "numpy-1.22.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3eb268dbd5cfaffd9448113539e44e2dd1c5ca9ce25576f7c04a5453edc26fa"}, - {file = "numpy-1.22.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37431a77ceb9307c28382c9773da9f306435135fae6b80b62a11c53cfedd8802"}, - {file = "numpy-1.22.4-cp39-cp39-win32.whl", hash = "sha256:cc7f00008eb7d3f2489fca6f334ec19ca63e31371be28fd5dad955b16ec285bd"}, - {file = "numpy-1.22.4-cp39-cp39-win_amd64.whl", hash = "sha256:f0725df166cf4785c0bc4cbfb320203182b1ecd30fee6e541c8752a92df6aa32"}, - {file = "numpy-1.22.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0791fbd1e43bf74b3502133207e378901272f3c156c4df4954cad833b1380207"}, - {file = "numpy-1.22.4.zip", hash = "sha256:425b390e4619f58d8526b3dcf656dde069133ae5c240229821f01b5f44ea07af"}, + {file = "numpy-1.23.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9c88793f78fca17da0145455f0d7826bcb9f37da4764af27ac945488116efe63"}, + {file = "numpy-1.23.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e9f4c4e51567b616be64e05d517c79a8a22f3606499941d97bb76f2ca59f982d"}, + {file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7903ba8ab592b82014713c491f6c5d3a1cde5b4a3bf116404e08f5b52f6daf43"}, + {file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e05b1c973a9f858c74367553e236f287e749465f773328c8ef31abe18f691e1"}, + {file = "numpy-1.23.5-cp310-cp310-win32.whl", hash = "sha256:522e26bbf6377e4d76403826ed689c295b0b238f46c28a7251ab94716da0b280"}, + {file = "numpy-1.23.5-cp310-cp310-win_amd64.whl", hash = "sha256:dbee87b469018961d1ad79b1a5d50c0ae850000b639bcb1b694e9981083243b6"}, + {file = "numpy-1.23.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ce571367b6dfe60af04e04a1834ca2dc5f46004ac1cc756fb95319f64c095a96"}, + {file = "numpy-1.23.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56e454c7833e94ec9769fa0f86e6ff8e42ee38ce0ce1fa4cbb747ea7e06d56aa"}, + {file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5039f55555e1eab31124a5768898c9e22c25a65c1e0037f4d7c495a45778c9f2"}, + {file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58f545efd1108e647604a1b5aa809591ccd2540f468a880bedb97247e72db387"}, + {file = "numpy-1.23.5-cp311-cp311-win32.whl", hash = "sha256:b2a9ab7c279c91974f756c84c365a669a887efa287365a8e2c418f8b3ba73fb0"}, + {file = "numpy-1.23.5-cp311-cp311-win_amd64.whl", hash = "sha256:0cbe9848fad08baf71de1a39e12d1b6310f1d5b2d0ea4de051058e6e1076852d"}, + {file = "numpy-1.23.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f063b69b090c9d918f9df0a12116029e274daf0181df392839661c4c7ec9018a"}, + {file = "numpy-1.23.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0aaee12d8883552fadfc41e96b4c82ee7d794949e2a7c3b3a7201e968c7ecab9"}, + {file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92c8c1e89a1f5028a4c6d9e3ccbe311b6ba53694811269b992c0b224269e2398"}, + {file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d208a0f8729f3fb790ed18a003f3a57895b989b40ea4dce4717e9cf4af62c6bb"}, + {file = "numpy-1.23.5-cp38-cp38-win32.whl", hash = "sha256:06005a2ef6014e9956c09ba07654f9837d9e26696a0470e42beedadb78c11b07"}, + {file = "numpy-1.23.5-cp38-cp38-win_amd64.whl", hash = "sha256:ca51fcfcc5f9354c45f400059e88bc09215fb71a48d3768fb80e357f3b457e1e"}, + {file = "numpy-1.23.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8969bfd28e85c81f3f94eb4a66bc2cf1dbdc5c18efc320af34bffc54d6b1e38f"}, + {file = "numpy-1.23.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7ac231a08bb37f852849bbb387a20a57574a97cfc7b6cabb488a4fc8be176de"}, + {file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf837dc63ba5c06dc8797c398db1e223a466c7ece27a1f7b5232ba3466aafe3d"}, + {file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33161613d2269025873025b33e879825ec7b1d831317e68f4f2f0f84ed14c719"}, + {file = "numpy-1.23.5-cp39-cp39-win32.whl", hash = "sha256:af1da88f6bc3d2338ebbf0e22fe487821ea4d8e89053e25fa59d1d79786e7481"}, + {file = "numpy-1.23.5-cp39-cp39-win_amd64.whl", hash = "sha256:09b7847f7e83ca37c6e627682f145856de331049013853f344f37b0c9690e3df"}, + {file = "numpy-1.23.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:abdde9f795cf292fb9651ed48185503a2ff29be87770c3b8e2a14b0cd7aa16f8"}, + {file = "numpy-1.23.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9a909a8bae284d46bbfdefbdd4a262ba19d3bc9921b1e76126b1d21c3c34135"}, + {file = "numpy-1.23.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:01dd17cbb340bf0fc23981e52e1d18a9d4050792e8fb8363cecbf066a84b827d"}, + {file = "numpy-1.23.5.tar.gz", hash = "sha256:1b1766d6f397c18153d40015ddfc79ddb715cabadc04d2d228d4e5a8bc4ded1a"}, ] [[package]] name = "openfermion" version = "1.5.1" description = "The electronic structure package for quantum computers." -category = "main" optional = false python-versions = "*" files = [ @@ -2249,7 +2538,6 @@ sympy = "*" name = "opt-einsum" version = "3.3.0" description = "Optimizing numpys einsum function" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2266,21 +2554,19 @@ tests = ["pytest", "pytest-cov", "pytest-pep8"] [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] name = "pandas" version = "2.0.3" description = "Powerful data structures for data analysis, time series, and statistics" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2315,6 +2601,7 @@ files = [ numpy = [ {version = ">=1.20.3", markers = "python_version < \"3.10\""}, {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, + {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -2347,7 +2634,6 @@ xml = ["lxml (>=4.6.3)"] name = "parso" version = "0.8.3" description = "A Python Parser" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2363,7 +2649,6 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2375,7 +2660,6 @@ files = [ name = "pbr" version = "5.11.1" description = "Python Build Reasonableness" -category = "main" optional = false python-versions = ">=2.6" files = [ @@ -2387,7 +2671,6 @@ files = [ name = "pexpect" version = "4.8.0" description = "Pexpect allows easy control of interactive console applications." -category = "main" optional = false python-versions = "*" files = [ @@ -2402,7 +2685,6 @@ ptyprocess = ">=0.5" name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" -category = "main" optional = false python-versions = "*" files = [ @@ -2412,79 +2694,89 @@ files = [ [[package]] name = "pillow" -version = "10.0.0" +version = "10.0.1" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "Pillow-10.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891"}, - {file = "Pillow-10.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf"}, - {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3"}, - {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992"}, - {file = "Pillow-10.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de"}, - {file = "Pillow-10.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485"}, - {file = "Pillow-10.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629"}, - {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538"}, - {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d"}, - {file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f"}, - {file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37"}, - {file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883"}, - {file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff"}, - {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551"}, - {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5"}, - {file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199"}, - {file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca"}, - {file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3"}, - {file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51"}, - {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86"}, - {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7"}, - {file = "Pillow-10.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0"}, - {file = "Pillow-10.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa"}, - {file = "Pillow-10.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba"}, - {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3"}, - {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017"}, - {file = "Pillow-10.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3"}, - {file = "Pillow-10.0.0.tar.gz", hash = "sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396"}, + {file = "Pillow-10.0.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:8f06be50669087250f319b706decf69ca71fdecd829091a37cc89398ca4dc17a"}, + {file = "Pillow-10.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50bd5f1ebafe9362ad622072a1d2f5850ecfa44303531ff14353a4059113b12d"}, + {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6a90167bcca1216606223a05e2cf991bb25b14695c518bc65639463d7db722d"}, + {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11c9102c56ffb9ca87134bd025a43d2aba3f1155f508eff88f694b33a9c6d19"}, + {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:186f7e04248103482ea6354af6d5bcedb62941ee08f7f788a1c7707bc720c66f"}, + {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0462b1496505a3462d0f35dc1c4d7b54069747d65d00ef48e736acda2c8cbdff"}, + {file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d889b53ae2f030f756e61a7bff13684dcd77e9af8b10c6048fb2c559d6ed6eaf"}, + {file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:552912dbca585b74d75279a7570dd29fa43b6d93594abb494ebb31ac19ace6bd"}, + {file = "Pillow-10.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:787bb0169d2385a798888e1122c980c6eff26bf941a8ea79747d35d8f9210ca0"}, + {file = "Pillow-10.0.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:fd2a5403a75b54661182b75ec6132437a181209b901446ee5724b589af8edef1"}, + {file = "Pillow-10.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2d7e91b4379f7a76b31c2dda84ab9e20c6220488e50f7822e59dac36b0cd92b1"}, + {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19e9adb3f22d4c416e7cd79b01375b17159d6990003633ff1d8377e21b7f1b21"}, + {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93139acd8109edcdeffd85e3af8ae7d88b258b3a1e13a038f542b79b6d255c54"}, + {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:92a23b0431941a33242b1f0ce6c88a952e09feeea9af4e8be48236a68ffe2205"}, + {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cbe68deb8580462ca0d9eb56a81912f59eb4542e1ef8f987405e35a0179f4ea2"}, + {file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:522ff4ac3aaf839242c6f4e5b406634bfea002469656ae8358644fc6c4856a3b"}, + {file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:84efb46e8d881bb06b35d1d541aa87f574b58e87f781cbba8d200daa835b42e1"}, + {file = "Pillow-10.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:898f1d306298ff40dc1b9ca24824f0488f6f039bc0e25cfb549d3195ffa17088"}, + {file = "Pillow-10.0.1-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:bcf1207e2f2385a576832af02702de104be71301c2696d0012b1b93fe34aaa5b"}, + {file = "Pillow-10.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5d6c9049c6274c1bb565021367431ad04481ebb54872edecfcd6088d27edd6ed"}, + {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28444cb6ad49726127d6b340217f0627abc8732f1194fd5352dec5e6a0105635"}, + {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de596695a75496deb3b499c8c4f8e60376e0516e1a774e7bc046f0f48cd620ad"}, + {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:2872f2d7846cf39b3dbff64bc1104cc48c76145854256451d33c5faa55c04d1a"}, + {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4ce90f8a24e1c15465048959f1e94309dfef93af272633e8f37361b824532e91"}, + {file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ee7810cf7c83fa227ba9125de6084e5e8b08c59038a7b2c9045ef4dde61663b4"}, + {file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b1be1c872b9b5fcc229adeadbeb51422a9633abd847c0ff87dc4ef9bb184ae08"}, + {file = "Pillow-10.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:98533fd7fa764e5f85eebe56c8e4094db912ccbe6fbf3a58778d543cadd0db08"}, + {file = "Pillow-10.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:764d2c0daf9c4d40ad12fbc0abd5da3af7f8aa11daf87e4fa1b834000f4b6b0a"}, + {file = "Pillow-10.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fcb59711009b0168d6ee0bd8fb5eb259c4ab1717b2f538bbf36bacf207ef7a68"}, + {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:697a06bdcedd473b35e50a7e7506b1d8ceb832dc238a336bd6f4f5aa91a4b500"}, + {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f665d1e6474af9f9da5e86c2a3a2d2d6204e04d5af9c06b9d42afa6ebde3f21"}, + {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:2fa6dd2661838c66f1a5473f3b49ab610c98a128fc08afbe81b91a1f0bf8c51d"}, + {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:3a04359f308ebee571a3127fdb1bd01f88ba6f6fb6d087f8dd2e0d9bff43f2a7"}, + {file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:723bd25051454cea9990203405fa6b74e043ea76d4968166dfd2569b0210886a"}, + {file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:71671503e3015da1b50bd18951e2f9daf5b6ffe36d16f1eb2c45711a301521a7"}, + {file = "Pillow-10.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:44e7e4587392953e5e251190a964675f61e4dae88d1e6edbe9f36d6243547ff3"}, + {file = "Pillow-10.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:3855447d98cced8670aaa63683808df905e956f00348732448b5a6df67ee5849"}, + {file = "Pillow-10.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed2d9c0704f2dc4fa980b99d565c0c9a543fe5101c25b3d60488b8ba80f0cce1"}, + {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5bb289bb835f9fe1a1e9300d011eef4d69661bb9b34d5e196e5e82c4cb09b37"}, + {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0d3e54ab1df9df51b914b2233cf779a5a10dfd1ce339d0421748232cea9876"}, + {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:2cc6b86ece42a11f16f55fe8903595eff2b25e0358dec635d0a701ac9586588f"}, + {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:ca26ba5767888c84bf5a0c1a32f069e8204ce8c21d00a49c90dabeba00ce0145"}, + {file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f0b4b06da13275bc02adfeb82643c4a6385bd08d26f03068c2796f60d125f6f2"}, + {file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bc2e3069569ea9dbe88d6b8ea38f439a6aad8f6e7a6283a38edf61ddefb3a9bf"}, + {file = "Pillow-10.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:8b451d6ead6e3500b6ce5c7916a43d8d8d25ad74b9102a629baccc0808c54971"}, + {file = "Pillow-10.0.1-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:32bec7423cdf25c9038fef614a853c9d25c07590e1a870ed471f47fb80b244db"}, + {file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cf63d2c6928b51d35dfdbda6f2c1fddbe51a6bc4a9d4ee6ea0e11670dd981e"}, + {file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f6d3d4c905e26354e8f9d82548475c46d8e0889538cb0657aa9c6f0872a37aa4"}, + {file = "Pillow-10.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:847e8d1017c741c735d3cd1883fa7b03ded4f825a6e5fcb9378fd813edee995f"}, + {file = "Pillow-10.0.1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7f771e7219ff04b79e231d099c0a28ed83aa82af91fd5fa9fdb28f5b8d5addaf"}, + {file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:459307cacdd4138edee3875bbe22a2492519e060660eaf378ba3b405d1c66317"}, + {file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b059ac2c4c7a97daafa7dc850b43b2d3667def858a4f112d1aa082e5c3d6cf7d"}, + {file = "Pillow-10.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6caf3cd38449ec3cd8a68b375e0c6fe4b6fd04edb6c9766b55ef84a6e8ddf2d"}, + {file = "Pillow-10.0.1.tar.gz", hash = "sha256:d72967b06be9300fed5cfbc8b5bafceec48bf7cdc7dab66b1d2549035287191d"}, ] [package.extras] docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +[[package]] +name = "pkginfo" +version = "1.9.6" +description = "Query metadata from sdists / bdists / installed packages." +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkginfo-1.9.6-py3-none-any.whl", hash = "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546"}, + {file = "pkginfo-1.9.6.tar.gz", hash = "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046"}, +] + +[package.extras] +testing = ["pytest", "pytest-cov"] + [[package]] name = "pkgutil-resolve-name" version = "1.3.10" description = "Resolve a name to an object." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2494,14 +2786,13 @@ files = [ [[package]] name = "platformdirs" -version = "3.10.0" +version = "3.11.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, - {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, + {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, + {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, ] [package.extras] @@ -2512,7 +2803,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "pluggy" version = "1.3.0" description = "plugin and hook calling mechanisms for python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2528,7 +2818,6 @@ testing = ["pytest", "pytest-benchmark"] name = "ply" version = "3.11" description = "Python Lex & Yacc" -category = "main" optional = false python-versions = "*" files = [ @@ -2536,11 +2825,73 @@ files = [ {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, ] +[[package]] +name = "poetry" +version = "1.6.1" +description = "Python dependency management and packaging made easy." +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "poetry-1.6.1-py3-none-any.whl", hash = "sha256:9b4cb6079c08cc0d91e8cba18a6bd4d4f7d7830263a7fb18ecb3faa77937c988"}, + {file = "poetry-1.6.1.tar.gz", hash = "sha256:0ab9b1a592731cc8b252b8d6aaeea19c72cc0a109d7468b829ad57e6c48039d2"}, +] + +[package.dependencies] +build = ">=0.10.0,<0.11.0" +cachecontrol = {version = ">=0.13.0,<0.14.0", extras = ["filecache"]} +cleo = ">=2.0.0,<3.0.0" +crashtest = ">=0.4.1,<0.5.0" +dulwich = ">=0.21.2,<0.22.0" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +installer = ">=0.7.0,<0.8.0" +jsonschema = ">=4.10.0,<4.18.0" +keyring = ">=24.0.0,<25.0.0" +packaging = ">=20.4" +pexpect = ">=4.7.0,<5.0.0" +pkginfo = ">=1.9.4,<2.0.0" +platformdirs = ">=3.0.0,<4.0.0" +poetry-core = "1.7.0" +poetry-plugin-export = ">=1.5.0,<2.0.0" +pyproject-hooks = ">=1.0.0,<2.0.0" +requests = ">=2.26,<3.0" +requests-toolbelt = ">=0.9.1,<2" +shellingham = ">=1.5,<2.0" +tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.11.4,<1.0.0" +trove-classifiers = ">=2022.5.19" +virtualenv = ">=20.22.0,<21.0.0" +xattr = {version = ">=0.10.0,<0.11.0", markers = "sys_platform == \"darwin\""} + +[[package]] +name = "poetry-core" +version = "1.7.0" +description = "Poetry PEP 517 Build Backend" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "poetry_core-1.7.0-py3-none-any.whl", hash = "sha256:38e174cdb00a84ee4a1cab66a378b435747f72414f5573bc18cfc3850a94df38"}, + {file = "poetry_core-1.7.0.tar.gz", hash = "sha256:8f679b83bd9c820082637beca1204124d5d2a786e4818da47ec8acefd0353b74"}, +] + +[[package]] +name = "poetry-plugin-export" +version = "1.5.0" +description = "Poetry plugin to export the dependencies to various formats" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "poetry_plugin_export-1.5.0-py3-none-any.whl", hash = "sha256:cd8267597970375ca29868daec5e7718bad500c7584663af3eeb0ed16f24e2bd"}, + {file = "poetry_plugin_export-1.5.0.tar.gz", hash = "sha256:ecc8738da0c81c3758e36b4e72e04ae59648a547492af2ffe6245af3594bb00f"}, +] + +[package.dependencies] +poetry = ">=1.5.0,<2.0.0" +poetry-core = ">=1.6.0,<2.0.0" + [[package]] name = "prompt-toolkit" version = "3.0.39" description = "Library for building powerful interactive command lines in Python" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -2555,7 +2906,6 @@ wcwidth = "*" name = "proto-plus" version = "1.22.3" description = "Beautiful, Pythonic protocol buffers." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2573,7 +2923,6 @@ testing = ["google-api-core[grpc] (>=1.31.5)"] name = "protobuf" version = "3.20.3" description = "Protocol Buffers" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2605,7 +2954,6 @@ files = [ name = "psutil" version = "5.9.5" description = "Cross-platform lib for process and system monitoring in Python." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2632,7 +2980,6 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -2644,7 +2991,6 @@ files = [ name = "pubchempy" version = "1.0.4" description = "A simple Python wrapper around the PubChem PUG REST API." -category = "main" optional = false python-versions = "*" files = [ @@ -2658,7 +3004,6 @@ pandas = ["pandas"] name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" -category = "main" optional = false python-versions = "*" files = [ @@ -2673,7 +3018,6 @@ tests = ["pytest"] name = "py3dmol" version = "1.8.1" description = "An IPython interface for embedding 3Dmol.js views" -category = "main" optional = false python-versions = "*" files = [ @@ -2688,7 +3032,6 @@ ipython = ["IPython"] name = "pyasn1" version = "0.5.0" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -2700,7 +3043,6 @@ files = [ name = "pyasn1-modules" version = "0.3.0" description = "A collection of ASN.1-based protocols modules" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -2715,7 +3057,6 @@ pyasn1 = ">=0.4.6,<0.6.0" name = "pycodestyle" version = "2.8.0" description = "Python style guide checker" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -2727,7 +3068,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2739,7 +3079,6 @@ files = [ name = "pydocstyle" version = "6.3.0" description = "Python docstring style checker" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2757,7 +3096,6 @@ toml = ["tomli (>=1.2.3)"] name = "pyflakes" version = "2.4.0" description = "passive checker of Python programs" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2769,7 +3107,6 @@ files = [ name = "pygments" version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2782,29 +3119,77 @@ plugins = ["importlib-metadata"] [[package]] name = "pyparsing" -version = "3.0.9" +version = "3.1.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "main" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, + {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, + {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, ] [package.extras] diagrams = ["jinja2", "railroad-diagrams"] +[[package]] +name = "pyproject-hooks" +version = "1.0.0" +description = "Wrappers to call pyproject.toml-based build backend hooks." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"}, + {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"}, +] + +[package.dependencies] +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + +[[package]] +name = "pyrsistent" +version = "0.19.3" +description = "Persistent/Functional/Immutable data structures" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, + {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, + {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, + {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, + {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, + {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, +] + [[package]] name = "pytest" -version = "7.4.1" +version = "7.4.2" description = "pytest: simple powerful testing with Python" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.1-py3-none-any.whl", hash = "sha256:460c9a59b14e27c602eb5ece2e47bec99dc5fc5f6513cf924a7d03a578991b1f"}, - {file = "pytest-7.4.1.tar.gz", hash = "sha256:2f2301e797521b23e4d2585a0a3d7b5e50fdddaaf7e7d6773ea26ddb17c213ab"}, + {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, + {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, ] [package.dependencies] @@ -2822,7 +3207,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -2837,7 +3221,6 @@ six = ">=1.5" name = "pytz" version = "2023.3.post1" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -2849,7 +3232,6 @@ files = [ name = "pywin32" version = "306" description = "Python for Window Extensions" -category = "main" optional = false python-versions = "*" files = [ @@ -2869,11 +3251,21 @@ files = [ {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, ] +[[package]] +name = "pywin32-ctypes" +version = "0.2.2" +description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"}, + {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"}, +] + [[package]] name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2882,6 +3274,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2889,8 +3282,15 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2907,6 +3307,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2914,6 +3315,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2923,7 +3325,6 @@ files = [ name = "pyzmq" version = "25.1.1" description = "Python bindings for 0MQ" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3027,18 +3428,17 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "qiskit" -version = "0.44.1" +version = "0.44.2" description = "Software for developing quantum computing programs" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "qiskit-0.44.1-py3-none-any.whl", hash = "sha256:374a3c1a59c591308ef5332999226ba2f14e58ad22348768fa1d213f43ca7b9e"}, - {file = "qiskit-0.44.1.tar.gz", hash = "sha256:353c1aa2624c4044bd7013bd1e996a736c60934ebe323119c1f5b07527c6b05f"}, + {file = "qiskit-0.44.2-py3-none-any.whl", hash = "sha256:2d394f75621df6f99b2f9045b858a69d363ffc4fd4e0cf7b555c6428a2fbd68c"}, + {file = "qiskit-0.44.2.tar.gz", hash = "sha256:cc25f4dd1ef4b93966167a73e93fce417e5245c0fe2fd54cd1ac8da1faeafd89"}, ] [package.dependencies] -qiskit-terra = "0.25.1" +qiskit-terra = "0.25.2.1" [package.extras] all = ["qiskit-terra[all]"] @@ -3049,23 +3449,22 @@ visualization = ["qiskit-terra[visualization]"] [[package]] name = "qiskit-terra" -version = "0.25.1" +version = "0.25.2.1" description = "Software for developing quantum computing programs" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "qiskit-terra-0.25.1.tar.gz", hash = "sha256:1ea5981800377af5cc8beefd5ca62e18196b918058de8382a129abc921fa3c8b"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:3e6db64d4582fbe5219a9a895df9229d72498a4be30a0aa0207578a5c20ae882"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c7193e53be5b86f66533244ca1038105b1c5e82d863f3711b4ba3c2eef531475"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c981d9ad3471ea189361ccc7130e146cd914fef3fe3e8ad901d80a1dde775a27"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0f277ce67743b86d4cf4661509054003768fe02512d1326702781872495b8f3"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45817d0ae1c0e61cde6aa795de5776dff85dc42d59825db6a1947a3c14b79b52"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b2b0b32b0e48ffae4298737707f550f8f47065a9f8718d4b0664d2c362bd63f"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e70b51bdc67351989228c75c39712e3a07618ff85bc282899ff4f633da6e53"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f2aa56683d936a85dc5199af62d1c12afe03829aae867beab99a29e4b192ef1"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-win32.whl", hash = "sha256:7b2d4c5f6832601f5c7da7752e67d5d5b75e69f42ba40c4113e6991ec4607fa9"}, - {file = "qiskit_terra-0.25.1-cp38-abi3-win_amd64.whl", hash = "sha256:bcf1d964b8f4328f62bc1c3d3a6f0f62fb9a4b78e799afb2c600e4d99e12cd25"}, + {file = "qiskit-terra-0.25.2.1.tar.gz", hash = "sha256:d3af3e01a4a58996fd065a7aa59bc46c4ea3559acd2164bf8725b58522fbafc4"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:78cd859fd9879e954fc9b07dcc51df6d6efdc3ef12ae0b1b74bf292b0c0b2a32"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:134a1ce47a3c7ccdaf04b684bbbda1eee72cb9d6df0d18b5229483fb4fa8474e"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:2189449214aeba383536785160a5b3fdf9680c145483d8a6e88a561aae9da0fb"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:307b1f8fc66565feb2b7f03bd81edb1f816ef410f0a70c6befa7a5b272678876"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e2c975981d96599531d06728afe377d23b36d5af9d42ec30a2064af06593c39"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e1854cf97dcc0eb7cd3c4fc25c0627728d852b2776518cce6a5d2a295380acca"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25f790f8e23a019fd71299d3f1126ebaf513692fb233f12371cb21aaea675ce7"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85e0995f12f7f985a3e8bff8b459a18b6d679f7271a3502e381af93760fea8c1"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-win32.whl", hash = "sha256:e87a57bb79160fcf0743c99f6966c98083737d395dc1a49f8b9bb63b5a9fb1e7"}, + {file = "qiskit_terra-0.25.2.1-cp38-abi3-win_amd64.whl", hash = "sha256:eaa81d563310977e3e1d6598c338597d365adfaf58e10bc3e30feb4bd8dc4848"}, ] [package.dependencies] @@ -3094,7 +3493,6 @@ visualization = ["ipywidgets (>=7.3.0)", "matplotlib (>=3.3)", "pillow (>=4.2.1) name = "qubovert" version = "1.2.5" description = "A package for formulating, simulating, and solving problems in boolean and spin form" -category = "main" optional = false python-versions = "*" files = [ @@ -3115,14 +3513,13 @@ numpy = "*" [[package]] name = "quimb" -version = "1.5.1" +version = "1.6.0" description = "Quantum information and many-body library." -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "quimb-1.5.1-py3-none-any.whl", hash = "sha256:fc421e953836d1e696edf1d1323bb9382c4c89cfb3fdc3ff32cc34a48f20d546"}, - {file = "quimb-1.5.1.tar.gz", hash = "sha256:32cbcfba4f1477dfb9c20edf1a1031e57a7a6d772c0b7945ff37b09a2cb2a52d"}, + {file = "quimb-1.6.0-py3-none-any.whl", hash = "sha256:c4ce58a7f82b73e7a3a7ad975475acab1a173deb60722db3363485e024f9d37f"}, + {file = "quimb-1.6.0.tar.gz", hash = "sha256:e7b76af7fc481719d864fa663db6854364ea7ea5bf5e4e7a5748494d072c1c68"}, ] [package.dependencies] @@ -3138,42 +3535,144 @@ tqdm = ">=4" [package.extras] advanced-solvers = ["mpi4py", "petsc4py", "slepc4py"] docs = ["autoray (>=0.6.6)", "doc2dash (>=2.4.1)", "furo", "ipython (!=8.7.0)", "myst-nb", "opt-einsum (>=3.2)", "setuptools-scm", "sphinx (>=2.0)", "sphinx-autoapi", "sphinx-copybutton", "sphinx-design"] -random = ["randomgen (>=1.18)"] tensor = ["diskcache (>=3.0)", "matplotlib (>=2.0)", "networkx (>=2.3)"] tests = ["coverage", "pytest", "pytest-cov"] +[[package]] +name = "rapidfuzz" +version = "2.15.1" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.7" +files = [ + {file = "rapidfuzz-2.15.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fc0bc259ebe3b93e7ce9df50b3d00e7345335d35acbd735163b7c4b1957074d3"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d59fb3a410d253f50099d7063855c2b95df1ef20ad93ea3a6b84115590899f25"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c525a3da17b6d79d61613096c8683da86e3573e807dfaecf422eea09e82b5ba6"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4deae6a918ecc260d0c4612257be8ba321d8e913ccb43155403842758c46fbe"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2577463d10811386e704a3ab58b903eb4e2a31b24dfd9886d789b0084d614b01"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f67d5f56aa48c0da9de4ab81bffb310683cf7815f05ea38e5aa64f3ba4368339"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7927722ff43690e52b3145b5bd3089151d841d350c6f8378c3cfac91f67573a"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6534afc787e32c4104f65cdeb55f6abe4d803a2d0553221d00ef9ce12788dcde"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d0ae6ec79a1931929bb9dd57bc173eb5ba4c7197461bf69e3a34b6dd314feed2"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:be7ccc45c4d1a7dfb595f260e8022a90c6cb380c2a346ee5aae93f85c96d362b"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:8ba013500a2b68c64b2aecc5fb56a2dad6c2872cf545a0308fd044827b6e5f6a"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4d9f7d10065f657f960b48699e7dddfce14ab91af4bab37a215f0722daf0d716"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7e24a1b802cea04160b3fccd75d2d0905065783ebc9de157d83c14fb9e1c6ce2"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-win32.whl", hash = "sha256:dffdf03499e0a5b3442951bb82b556333b069e0661e80568752786c79c5b32de"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d150d90a7c6caae7962f29f857a4e61d42038cfd82c9df38508daf30c648ae7"}, + {file = "rapidfuzz-2.15.1-cp310-cp310-win_arm64.whl", hash = "sha256:87c30e9184998ff6eb0fa9221f94282ce7c908fd0da96a1ef66ecadfaaa4cdb7"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6986413cb37035eb796e32f049cbc8c13d8630a4ac1e0484e3e268bb3662bd1b"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a72f26e010d4774b676f36e43c0fc8a2c26659efef4b3be3fd7714d3491e9957"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b5cd54c98a387cca111b3b784fc97a4f141244bbc28a92d4bde53f164464112e"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da7fac7c3da39f93e6b2ebe386ed0ffe1cefec91509b91857f6e1204509e931f"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f976e76ac72f650790b3a5402431612175b2ac0363179446285cb3c901136ca9"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:abde47e1595902a490ed14d4338d21c3509156abb2042a99e6da51f928e0c117"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca8f1747007a3ce919739a60fa95c5325f7667cccf6f1c1ef18ae799af119f5e"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c35da09ab9797b020d0d4f07a66871dfc70ea6566363811090353ea971748b5a"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a3a769ca7580686a66046b77df33851b3c2d796dc1eb60c269b68f690f3e1b65"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d50622efefdb03a640a51a6123748cd151d305c1f0431af762e833d6ffef71f0"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b7461b0a7651d68bc23f0896bffceea40f62887e5ab8397bf7caa883592ef5cb"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:074ee9e17912e025c72a5780ee4c7c413ea35cd26449719cc399b852d4e42533"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7025fb105a11f503943f17718cdb8241ea3bb4d812c710c609e69bead40e2ff0"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-win32.whl", hash = "sha256:2084d36b95139413cef25e9487257a1cc892b93bd1481acd2a9656f7a1d9930c"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:5a738fcd24e34bce4b19126b92fdae15482d6d3a90bd687fd3d24ce9d28ce82d"}, + {file = "rapidfuzz-2.15.1-cp311-cp311-win_arm64.whl", hash = "sha256:dc3cafa68cfa54638632bdcadf9aab89a3d182b4a3f04d2cad7585ed58ea8731"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3c53d57ba7a88f7bf304d4ea5a14a0ca112db0e0178fff745d9005acf2879f7d"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6ee758eec4cf2215dc8d8eafafcea0d1f48ad4b0135767db1b0f7c5c40a17dd"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d93ba3ae59275e7a3a116dac4ffdb05e9598bf3ee0861fecc5b60fb042d539e"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c3ff75e647908ddbe9aa917fbe39a112d5631171f3fcea5809e2363e525a59d"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d89c421702474c6361245b6b199e6e9783febacdbfb6b002669e6cb3ef17a09"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f69e6199fec0f58f9a89afbbaea78d637c7ce77f656a03a1d6ea6abdc1d44f8"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:41dfea282844d0628279b4db2929da0dacb8ac317ddc5dcccc30093cf16357c1"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2dd03477feefeccda07b7659dd614f6738cfc4f9b6779dd61b262a73b0a9a178"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:5efe035aa76ff37d1b5fa661de3c4b4944de9ff227a6c0b2e390a95c101814c0"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ed2cf7c69102c7a0a06926d747ed855bc836f52e8d59a5d1e3adfd980d1bd165"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a0e441d4c2025110ec3eba5d54f11f78183269a10152b3a757a739ffd1bb12bf"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-win32.whl", hash = "sha256:a4a54efe17cc9f53589c748b53f28776dfdfb9bc83619685740cb7c37985ac2f"}, + {file = "rapidfuzz-2.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:bb8318116ecac4dfb84841d8b9b461f9bb0c3be5b616418387d104f72d2a16d1"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e9296c530e544f68858c3416ad1d982a1854f71e9d2d3dcedb5b216e6d54f067"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:49c4bcdb9238f11f8c4eba1b898937f09b92280d6f900023a8216008f299b41a"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb40a279e134bb3fef099a8b58ed5beefb201033d29bdac005bddcdb004ef71"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7381c11cb590bbd4e6f2d8779a0b34fdd2234dfa13d0211f6aee8ca166d9d05"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfdcdedfd12a0077193f2cf3626ff6722c5a184adf0d2d51f1ec984bf21c23c3"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85bece1ec59bda8b982bd719507d468d4df746dfb1988df11d916b5e9fe19e8"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1b393f4a1eaa6867ffac6aef58cfb04bab2b3d7d8e40b9fe2cf40dd1d384601"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53de456ef020a77bf9d7c6c54860a48e2e902584d55d3001766140ac45c54bc7"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2492330bc38b76ed967eab7bdaea63a89b6ceb254489e2c65c3824efcbf72993"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:099e4c6befaa8957a816bdb67ce664871f10aaec9bebf2f61368cf7e0869a7a1"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:46599b2ad4045dd3f794a24a6db1e753d23304699d4984462cf1ead02a51ddf3"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:591f19d16758a3c55c9d7a0b786b40d95599a5b244d6eaef79c7a74fcf5104d8"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ed17359061840eb249f8d833cb213942e8299ffc4f67251a6ed61833a9f2ea20"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-win32.whl", hash = "sha256:aa1e5aad325168e29bf8e17006479b97024aa9d2fdbe12062bd2f8f09080acf8"}, + {file = "rapidfuzz-2.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:c2bb68832b140c551dbed691290bef4ee6719d4e8ce1b7226a3736f61a9d1a83"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3fac40972cf7b6c14dded88ae2331eb50dfbc278aa9195473ef6fc6bfe49f686"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0e456cbdc0abf39352800309dab82fd3251179fa0ff6573fa117f51f4e84be8"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:22b9d22022b9d09fd4ece15102270ab9b6a5cfea8b6f6d1965c1df7e3783f5ff"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46754fe404a9a6f5cbf7abe02d74af390038d94c9b8c923b3f362467606bfa28"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91abb8bf7610efe326394adc1d45e1baca8f360e74187f3fa0ef3df80cdd3ba6"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e40a2f60024f9d3c15401e668f732800114a023f3f8d8c40f1521a62081ff054"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a48ee83916401ac73938526d7bd804e01d2a8fe61809df7f1577b0b3b31049a3"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c71580052f9dbac443c02f60484e5a2e5f72ad4351b84b2009fbe345b1f38422"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:82b86d5b8c1b9bcbc65236d75f81023c78d06a721c3e0229889ff4ed5c858169"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fc4528b7736e5c30bc954022c2cf410889abc19504a023abadbc59cdf9f37cae"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e1e0e569108a5760d8f01d0f2148dd08cc9a39ead79fbefefca9e7c7723c7e88"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:94e1c97f0ad45b05003806f8a13efc1fc78983e52fa2ddb00629003acf4676ef"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47e81767a962e41477a85ad7ac937e34d19a7d2a80be65614f008a5ead671c56"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-win32.whl", hash = "sha256:79fc574aaf2d7c27ec1022e29c9c18f83cdaf790c71c05779528901e0caad89b"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:f3dd4bcef2d600e0aa121e19e6e62f6f06f22a89f82ef62755e205ce14727874"}, + {file = "rapidfuzz-2.15.1-cp39-cp39-win_arm64.whl", hash = "sha256:cac095cbdf44bc286339a77214bbca6d4d228c9ebae3da5ff6a80aaeb7c35634"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b89d1126be65c85763d56e3b47d75f1a9b7c5529857b4d572079b9a636eaa8a7"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19b7460e91168229768be882ea365ba0ac7da43e57f9416e2cfadc396a7df3c2"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c33c03e7092642c38f8a15ca2d8fc38da366f2526ec3b46adf19d5c7aa48ba"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040faca2e26d9dab5541b45ce72b3f6c0e36786234703fc2ac8c6f53bb576743"}, + {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6e2a3b23e1e9aa13474b3c710bba770d0dcc34d517d3dd6f97435a32873e3f28"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e597b9dfd6dd180982684840975c458c50d447e46928efe3e0120e4ec6f6686"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d14752c9dd2036c5f36ebe8db5f027275fa7d6b3ec6484158f83efb674bab84e"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:558224b6fc6124d13fa32d57876f626a7d6188ba2a97cbaea33a6ee38a867e31"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c89cfa88dc16fd8c9bcc0c7f0b0073f7ef1e27cceb246c9f5a3f7004fa97c4d"}, + {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:509c5b631cd64df69f0f011893983eb15b8be087a55bad72f3d616b6ae6a0f96"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0f73a04135a03a6e40393ecd5d46a7a1049d353fc5c24b82849830d09817991f"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c99d53138a2dfe8ada67cb2855719f934af2733d726fbf73247844ce4dd6dd5"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f01fa757f0fb332a1f045168d29b0d005de6c39ee5ce5d6c51f2563bb53c601b"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60368e1add6e550faae65614844c43f8a96e37bf99404643b648bf2dba92c0fb"}, + {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:785744f1270828cc632c5a3660409dee9bcaac6931a081bae57542c93e4d46c4"}, + {file = "rapidfuzz-2.15.1.tar.gz", hash = "sha256:d62137c2ca37aea90a11003ad7dc109c8f1739bfbe5a9a217f3cdb07d7ac00f6"}, +] + +[package.extras] +full = ["numpy"] + [[package]] name = "ray" -version = "2.6.3" +version = "2.7.0" description = "Ray provides a simple, universal API for building distributed applications." -category = "main" optional = false python-versions = "*" files = [ - {file = "ray-2.6.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:8a3cde58dba07da7a62e1f804b3dae5b29de3be052e02e4559bff7e7cb4d4a3b"}, - {file = "ray-2.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81e2ee7252e2fbfb05a24124774a8de563daa261200a08d9cbc6b499f7262af1"}, - {file = "ray-2.6.3-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:485e4cd46a569416a14a72c06fe7901b0e3902f3023100b375c477975824e707"}, - {file = "ray-2.6.3-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:abc6a537454506a5fa87137de058d12aeea38da7077aae6f0ebf6199e5f5b2a1"}, - {file = "ray-2.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:787ec7f43f5b3ed85728cf4878bdfed0a334d9108b6af75ef3fe5c8d44a7f74d"}, - {file = "ray-2.6.3-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:bdeacaafcbb97e5f1c3c3349e7fcc0c40f691cea2bf057027c5491ea1ac929b0"}, - {file = "ray-2.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4b4600c93e2e94b6ca75ef4b4cb92d7f98d4be5484273d6fbac4218fb82cf96f"}, - {file = "ray-2.6.3-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:0a5870f9a16cb94080d770f83326d7e2163d88d75be240273cef4b932a071bb2"}, - {file = "ray-2.6.3-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:1a8de31a9a4049134cf7e97b725a4078c958a964d091cb3e812e31eddd013bd7"}, - {file = "ray-2.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:56b920a1814decdd20a754b7c5048770684d6d3d242c83aa99da5d3e8c339f13"}, - {file = "ray-2.6.3-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:b358fd112876c3a249fd8cffbf20b26622817c78b2ade0a725a7036c693f8d70"}, - {file = "ray-2.6.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:467b9aa63f09d20e3985457816d703fe27ea388cdcaa88ff5eff222f8074a05c"}, - {file = "ray-2.6.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:dff21468d621c8dac95b3df320e6c6121f6618f6827243fd75a057c8815c2498"}, - {file = "ray-2.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:e0f8eaf4c4592335722dad474685c2ffc98207b997e47a24b297a60db389a4cb"}, - {file = "ray-2.6.3-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:31f1dd05130e712b9b64ccad9e6eaa82c715bb25a0a45ffd48ebf4953f6fe347"}, - {file = "ray-2.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:90b780e131f891185f9de2b9c08d1f2d729e5755c7389a1ddaa6f796fae0d787"}, - {file = "ray-2.6.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3e5a4bbc29268a64bd2a8d48ed60f32a5bcce285a2a4f4339174947733449e37"}, - {file = "ray-2.6.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a182a80aebf863b5d4e875bed0a80e83200e84f4f63c4126cef87cc01e43f067"}, - {file = "ray-2.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:015a2aa30aba0719d20cdf8fa32c689b68016678cb20f46bd1df8b227c938b84"}, - {file = "ray-2.6.3-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:3ccf809e5948333c1c8c81694514b5900259e79cbdc8bddd3680695820cafcf2"}, - {file = "ray-2.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a4ef2f52319286720be7f3bfe6043e9fd0b8cb7826cb2ffc90c23c1c42427464"}, - {file = "ray-2.6.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5923849ec0854ab3e5ca8873d47ed7e11074e1213a3c40f8864c9500de034313"}, - {file = "ray-2.6.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:18d033cc468e5171d9995476c33f99a5b79f091c34265c7e9f3d8b1c9042437e"}, - {file = "ray-2.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:bca66c8e8163f06dc5443623e7b221660529a39574a589ba9257f2188ea8bf6b"}, + {file = "ray-2.7.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:bc911655908b61b2e9f59b8df158fcc62cd32080c468b484b539ebf0a4111d04"}, + {file = "ray-2.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0ee8c14e1521559cd5802bfad3f0aba4a77afdfba57dd446162a7449c6e8ff68"}, + {file = "ray-2.7.0-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:ebde44af7d479ede21d1c2e68b5ccd8264e18df6e4f3c216d9e99c31e819bde6"}, + {file = "ray-2.7.0-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:b83621f5d2d4079e6ae624c3bf30046a4fefa0ea7ea5e4a4dfe4b50c580b3768"}, + {file = "ray-2.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:8e1b06abba6e227b8dde1ad861c587fb2608a6970d270e4755cd24a6f37ed565"}, + {file = "ray-2.7.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:5442d48719f033831a324f05b332d6e7181970d721e9504be2091cc9d9735394"}, + {file = "ray-2.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ca8225878cce7b9e2d0ca9668d9370893a7cee35629d11a3889a1b66a0007218"}, + {file = "ray-2.7.0-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:a3f59dbb0780f9fa11f5bf96bef853b4cb95245456d4400e1c7bf2e514d12ab2"}, + {file = "ray-2.7.0-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:8384b3f30bc1446ef810e9e894afa03238c5ac40d3c40c0740d82f347112015d"}, + {file = "ray-2.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:8d4530e7024375505552dabd3f4441fc9ac7a5562365a81ba9afa14185433879"}, + {file = "ray-2.7.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:c491b8051eef82b77d136c48a23d16485c0e54233303ccf68e9fe69a06c517e6"}, + {file = "ray-2.7.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:1684c434886cb7b263cdf98ed39d75dec343e949f7b14f3385d83bfe70ee8c80"}, + {file = "ray-2.7.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:856a9ae164b9b0aeaad54f3e78986eb19900ed3c74e26f51b02a7d8826c97e59"}, + {file = "ray-2.7.0-cp37-cp37m-win_amd64.whl", hash = "sha256:34925a90b6239de42592bb4524dcbdc59a9c65f1f74ad4d9f97f636bd59c73d7"}, + {file = "ray-2.7.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:60db240f37d80a80492e09a8d1e29b79d034431c6fcb651401e9e2d24d850793"}, + {file = "ray-2.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:835155fdeb8698eae426f3d9416e6b8165197fe5c1c74e1b02a429fc7f4ddcd2"}, + {file = "ray-2.7.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:442b7568946081d38c8addbc528e7b09fc1ee25453b4800c86b7e5ba4bce9dd3"}, + {file = "ray-2.7.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:3825292b777b423e2cd34bf66e8e1e7701b04c6a5308f9f291ad5929b289dc47"}, + {file = "ray-2.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:ce700322662946ad5c62a39b78e81feebcb855d378c49f5df6477c22f0ac1e5a"}, + {file = "ray-2.7.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:327c23aac5dd26ee4abe6cee70320322d63fdf97c6028fbb9555724b46a8f3e3"}, + {file = "ray-2.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a09021d45312ab7a44109b251984718b65fbff77df0b55e30e651193cdf42bff"}, + {file = "ray-2.7.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f05fcb609962d14f4d23cc88a9d07cafa7077ce3c5d5ee99cd08a19067b7eecf"}, + {file = "ray-2.7.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:0e0f7dbeb4444940c72b64fdecd6f331593466914b2dffeed03ce97225acec14"}, + {file = "ray-2.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:29a0866316756ae18e232dd074adbf408dcdabe95d135a9a96b9a8c24393c983"}, ] [package.dependencies] @@ -3181,10 +3680,6 @@ aiosignal = "*" click = ">=7.0" filelock = "*" frozenlist = "*" -grpcio = [ - {version = ">=1.32.0", markers = "python_version < \"3.10\""}, - {version = ">=1.42.0", markers = "python_version >= \"3.10\""}, -] jsonschema = "*" msgpack = ">=1.0.0,<2.0.0" numpy = [ @@ -3197,39 +3692,23 @@ pyyaml = "*" requests = "*" [package.extras] -air = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi", "fsspec", "gpustat (>=1.0.0)", "numpy (>=1.20)", "opencensus", "pandas", "pandas (>=1.3)", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pyarrow (>=6.0.1)", "pydantic (<2)", "requests", "smart-open", "starlette", "tensorboardX (>=1.9)", "uvicorn", "virtualenv (>=20.0.24,<20.21.1)"] -all = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "dm-tree", "fastapi", "fsspec", "gpustat (>=1.0.0)", "grpcio (!=1.56.0)", "gymnasium (==0.26.3)", "lz4", "numpy (>=1.20)", "opencensus", "opentelemetry-api", "opentelemetry-exporter-otlp", "opentelemetry-sdk", "pandas", "pandas (>=1.3)", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pyarrow (>=6.0.1)", "pydantic (<2)", "pyyaml", "ray-cpp (==2.6.3)", "requests", "rich", "scikit-image", "scipy", "smart-open", "starlette", "tensorboardX (>=1.9)", "typer", "uvicorn", "virtualenv (>=20.0.24,<20.21.1)"] +air = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi", "fsspec", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "numpy (>=1.20)", "opencensus", "pandas", "pandas (>=1.3)", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pyarrow (>=6.0.1)", "pydantic (<2)", "requests", "smart-open", "starlette", "tensorboardX (>=1.9)", "uvicorn", "virtualenv (>=20.0.24,<20.21.1)", "watchfiles"] +all = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "dm-tree", "fastapi", "fsspec", "gpustat (>=1.0.0)", "grpcio (!=1.56.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "gymnasium (==0.28.1)", "lz4", "numpy (>=1.20)", "opencensus", "opentelemetry-api", "opentelemetry-exporter-otlp", "opentelemetry-sdk", "pandas", "pandas (>=1.3)", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pyarrow (>=6.0.1)", "pydantic (<2)", "pyyaml", "ray-cpp (==2.7.0)", "requests", "rich", "scikit-image", "scipy", "smart-open", "starlette", "tensorboardX (>=1.9)", "typer", "uvicorn", "virtualenv (>=20.0.24,<20.21.1)", "watchfiles"] client = ["grpcio (!=1.56.0)"] -cpp = ["ray-cpp (==2.6.3)"] +cpp = ["ray-cpp (==2.7.0)"] data = ["fsspec", "numpy (>=1.20)", "pandas (>=1.3)", "pyarrow (>=6.0.1)"] -default = ["aiohttp (>=3.7)", "aiohttp-cors", "colorful", "gpustat (>=1.0.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2)", "requests", "smart-open", "virtualenv (>=20.0.24,<20.21.1)"] +default = ["aiohttp (>=3.7)", "aiohttp-cors", "colorful", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2)", "requests", "smart-open", "virtualenv (>=20.0.24,<20.21.1)"] observability = ["opentelemetry-api", "opentelemetry-exporter-otlp", "opentelemetry-sdk"] -rllib = ["dm-tree", "gymnasium (==0.26.3)", "lz4", "pandas", "pyarrow (>=6.0.1)", "pyyaml", "requests", "rich", "scikit-image", "scipy", "tensorboardX (>=1.9)", "typer"] -serve = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi", "gpustat (>=1.0.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2)", "requests", "smart-open", "starlette", "uvicorn", "virtualenv (>=20.0.24,<20.21.1)"] -train = ["pandas", "pyarrow (>=6.0.1)", "requests", "tensorboardX (>=1.9)"] -tune = ["pandas", "pyarrow (>=6.0.1)", "requests", "tensorboardX (>=1.9)"] - -[[package]] -name = "referencing" -version = "0.30.2" -description = "JSON Referencing + Python" -category = "main" -optional = false -python-versions = ">=3.8" -files = [ - {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, - {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -rpds-py = ">=0.7.0" +rllib = ["dm-tree", "fsspec", "gymnasium (==0.28.1)", "lz4", "pandas", "pyarrow (>=6.0.1)", "pyyaml", "requests", "rich", "scikit-image", "scipy", "tensorboardX (>=1.9)", "typer"] +serve = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2)", "requests", "smart-open", "starlette", "uvicorn", "virtualenv (>=20.0.24,<20.21.1)", "watchfiles"] +serve-grpc = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2)", "requests", "smart-open", "starlette", "uvicorn", "virtualenv (>=20.0.24,<20.21.1)", "watchfiles"] +train = ["fsspec", "pandas", "pyarrow (>=6.0.1)", "requests", "tensorboardX (>=1.9)"] +tune = ["fsspec", "pandas", "pyarrow (>=6.0.1)", "requests", "tensorboardX (>=1.9)"] [[package]] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3248,117 +3727,23 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] -name = "rpds-py" -version = "0.10.2" -description = "Python bindings to Rust's persistent data structures (rpds)" -category = "main" +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" optional = false -python-versions = ">=3.8" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ - {file = "rpds_py-0.10.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:9f00d54b18dd837f1431d66b076737deb7c29ce3ebb8412ceaf44d5e1954ac0c"}, - {file = "rpds_py-0.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f4d561f4728f825e3b793a53064b606ca0b6fc264f67d09e54af452aafc5b82"}, - {file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:013d6c784150d10236a74b4094a79d96a256b814457e388fc5a4ba9efe24c402"}, - {file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd1142d22fdb183a0fff66d79134bf644401437fed874f81066d314c67ee193c"}, - {file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a0536ed2b9297c75104e1a3da330828ba1b2639fa53b38d396f98bf7e3c68df"}, - {file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:41bd430b7b63aa802c02964e331ac0b177148fef5f807d2c90d05ce71a52b4d4"}, - {file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e8474f7233fe1949ce4e03bea698a600c2d5d6b51dab6d6e6336dbe69acf23e"}, - {file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d9d7efaad48b859053b90dedd69bc92f2095084251e732e4c57ac9726bcb1e64"}, - {file = "rpds_py-0.10.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5612b0b1de8d5114520094bd5fc3d04eb8af6f3e10d48ef05b7c8e77c1fd9545"}, - {file = "rpds_py-0.10.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5d5eaf988951f6ecb6854ca3300b87123599c711183c83da7ce39717a7cbdbce"}, - {file = "rpds_py-0.10.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:75c8766734ac0053e1d683567e65e85306c4ec62631b0591caeb287ac8f72e08"}, - {file = "rpds_py-0.10.2-cp310-none-win32.whl", hash = "sha256:8de9b88f0cbac73cfed34220d13c57849e62a7099a714b929142425e926d223a"}, - {file = "rpds_py-0.10.2-cp310-none-win_amd64.whl", hash = "sha256:2275f1a022e2383da5d2d101fe11ccdcbae799148c4b83260a4b9309fa3e1fc2"}, - {file = "rpds_py-0.10.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dd91a7d7a9ce7f4983097c91ce211f3e5569cc21caa16f2692298a07e396f82b"}, - {file = "rpds_py-0.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e82b4a70cc67094f3f3fd77579702f48fcf1de7bdc67d79b8f1e24d089a6162c"}, - {file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e281b71922208e00886e4b7ffbfcf27874486364f177418ab676f102130e7ec9"}, - {file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3eb1a0d2b6d232d1bcdfc3fcc5f7b004ab3fbd9203011a3172f051d4527c0b6"}, - {file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02945ae38fd78efc40900f509890de84cfd5ffe2cd2939eeb3a8800dc68b87cb"}, - {file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccfb77f6dc8abffa6f1c7e3975ed9070a41ce5fcc11154d2bead8c1baa940f09"}, - {file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af52078719209bef33e38131486fd784832dd8d1dc9b85f00a44f6e7437dd021"}, - {file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56ba7c1100ed079527f2b995bf5486a2e557e6d5b733c52e8947476338815b69"}, - {file = "rpds_py-0.10.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:899b03a3be785a7e1ff84b237da71f0efa2f021512f147dd34ffdf7aa82cb678"}, - {file = "rpds_py-0.10.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:22e6de18f00583f06928cc8d0993104ecc62f7c6da6478db2255de89a30e45d1"}, - {file = "rpds_py-0.10.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:edd74b760a6bb950397e7a7bd2f38e6700f6525062650b1d77c6d851b82f02c2"}, - {file = "rpds_py-0.10.2-cp311-none-win32.whl", hash = "sha256:18909093944727e068ebfc92e2e6ed1c4fa44135507c1c0555213ce211c53214"}, - {file = "rpds_py-0.10.2-cp311-none-win_amd64.whl", hash = "sha256:9568764e72d85cf7855ca78b48e07ed1be47bf230e2cea8dabda3c95f660b0ff"}, - {file = "rpds_py-0.10.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:0fc625059b83695fbb4fc8b7a8b66fa94ff9c7b78c84fb9986cd53ff88a28d80"}, - {file = "rpds_py-0.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c86231c66e4f422e7c13ea6200bb4048b3016c8bfd11b4fd0dabd04d2c8e3501"}, - {file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56777c57246e048908b550af9b81b0ec9cf804fd47cb7502ccd93238bd6025c2"}, - {file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a4cb372e22e9c879bd9a9cc9b20b7c1fbf30a605ac953da45ecec05d8a6e1c77"}, - {file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa3b3a43dabc4cc57a7800f526cbe03f71c69121e21b863fdf497b59b462b163"}, - {file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d222086daa55421d599609b32d0ebe544e57654c4a0a1490c54a7ebaa67561"}, - {file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:529aab727f54a937085184e7436e1d0e19975cf10115eda12d37a683e4ee5342"}, - {file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e9b1531d6a898bdf086acb75c41265c7ec4331267d7619148d407efc72bd24"}, - {file = "rpds_py-0.10.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c2772bb95062e3f9774140205cd65d8997e39620715486cf5f843cf4ad8f744c"}, - {file = "rpds_py-0.10.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ba1b28e44f611f3f2b436bd8290050a61db4b59a8e24be4465f44897936b3824"}, - {file = "rpds_py-0.10.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5aba767e64b494483ad60c4873bec78d16205a21f8247c99749bd990d9c846c2"}, - {file = "rpds_py-0.10.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:e1954f4b239d1a92081647eecfd51cbfd08ea16eb743b8af1cd0113258feea14"}, - {file = "rpds_py-0.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:de4a2fd524993578fe093044f291b4b24aab134390030b3b9b5f87fd41ab7e75"}, - {file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e69737bd56006a86fd5a78b2b85447580a6138c930a75eb9ef39fe03d90782b1"}, - {file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f40abbcc0a7d9a8a80870af839d317e6932533f98682aabd977add6c53beeb23"}, - {file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29ec8507664f94cc08457d98cfc41c3cdbddfa8952438e644177a29b04937876"}, - {file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcde80aefe7054fad6277762fb7e9d35c72ea479a485ae1bb14629c640987b30"}, - {file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a65de5c02884760a14a58304fb6303f9ddfc582e630f385daea871e1bdb18686"}, - {file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e92e5817eb6bfed23aa5e45bfe30647b83602bdd6f9e25d63524d4e6258458b0"}, - {file = "rpds_py-0.10.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2c8fc6c841ada60a86d29c9ebe2e8757c47eda6553f3596c560e59ca6e9b6fa1"}, - {file = "rpds_py-0.10.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:8557c807388e6617161fe51b1a4747ea8d1133f2d2ad8e79583439abebe58fbd"}, - {file = "rpds_py-0.10.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:00e97d43a36811b78fa9ad9d3329bf34f76a31e891a7031a2ac01450c9b168ab"}, - {file = "rpds_py-0.10.2-cp38-none-win32.whl", hash = "sha256:1ed3d5385d14be894e12a9033be989e012214a9811e7194849c94032ad69682a"}, - {file = "rpds_py-0.10.2-cp38-none-win_amd64.whl", hash = "sha256:02b4a2e28eb24dac4ef43dda4f6a6f7766e355179b143f7d0c76a1c5488a307b"}, - {file = "rpds_py-0.10.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:2a55631b93e47956fbc97d69ba2054a8c6a4016f9a3064ec4e031f5f1030cb90"}, - {file = "rpds_py-0.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2ffbf1b38c88d0466de542e91b08225d51782282512f8e2b11715126c41fda48"}, - {file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213f9ef5c02ec2f883c1075d25a873149daadbaea50d18d622e9db55ec9849c2"}, - {file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b00150a9a3fd0a8efaa90bc2696c105b04039d50763dd1c95a34c88c5966cb57"}, - {file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ab0f7aabdbce4a202e013083eeab71afdb85efa405dc4a06fea98cde81204675"}, - {file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2cd0c9fb5d40887500b4ed818770c68ab4fa6e0395d286f9704be6751b1b7d98"}, - {file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8578fc6c8bdd0201327503720fa581000b4bd3934abbf07e2628d1ad3de157d"}, - {file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d27d08056fcd61ff47a0cd8407eff4d3e816c82cb6b9c6f0ce9a0ad49225f81"}, - {file = "rpds_py-0.10.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c8f6526df47953b07c45b95c4d1da6b9a0861c0e5da0271db96bb1d807825412"}, - {file = "rpds_py-0.10.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:177c033e467a66a054dd3a9534167234a3d0b2e41445807b13b626e01da25d92"}, - {file = "rpds_py-0.10.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c74cbee9e532dc34371127f7686d6953e5153a1f22beab7f953d95ee4a0fe09"}, - {file = "rpds_py-0.10.2-cp39-none-win32.whl", hash = "sha256:05a1382905026bdd560f806c8c7c16e0f3e3fb359ba8868203ca6e5799884968"}, - {file = "rpds_py-0.10.2-cp39-none-win_amd64.whl", hash = "sha256:3fd503c27e7b7034128e30847ecdb4bff4ca5e60f29ad022a9f66ae8940d54ac"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4a96147791e49e84207dd1530109aa0e9eeaf1c8b7a59f150047fc0fcdf9bb64"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:203eb1532d51591d32e8dfafd60b5d31347ea7278c8da02b4b550287f6abe28b"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2f416cdfe92f5fbb77177f5f3f7830059d1582db05f2c7119bf80069d1ab69b"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2660000e1a113869c86eb5cc07f3343467490f3cd9d0299f81da9ddae7137b7"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1adb04e4b4e41bf30aaa77eeb169c1b9ba9e5010e2e6ce8d6c17e1446edc9b68"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2bca97521ee786087f0c5ef318fef3eef0266a9c3deff88205523cf353af7394"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4969592e3cdeefa4cbb15a26cec102cbd4a1d6e5b695fac9fa026e19741138c8"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df61f818edf7c8626bfa392f825860fb670b5f8336e238eb0ec7e2a5689cdded"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:b589d93a60e78fe55d5bc76ee8c2bf945dbdbb7cd16044c53e0307604e448de1"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:73da69e1f612c3e682e34dcb971272d90d6f27b2c99acff444ca455a89978574"}, - {file = "rpds_py-0.10.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:89438e8885a186c69fe31f7ef98bb2bf29688c466c3caf9060f404c0be89ae80"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:c4ecc4e9a5d73a816cae36ee6b5d8b7a0c72013cae1e101406e832887c3dc2d8"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:907b214da5d2fcff0b6ddb83de1333890ca92abaf4bbf8d9c61dc1b95c87fd6e"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb44644371eaa29a3aba7b69b1862d0d56f073bb7585baa32e4271a71a91ee82"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:80c3cf46511653f94dfe07c7c79ab105c4164d6e1dfcb35b7214fb9af53eaef4"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaba0613c759ebf95988a84f766ca6b7432d55ce399194f95dde588ad1be0878"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0527c97dcd8bb983822ee31d3760187083fd3ba18ac4dd22cf5347c89d5628f4"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cdfd649011ce2d90cb0dd304c5aba1190fac0c266d19a9e2b96b81cfd150a09"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:75eea40355a8690459c7291ce6c8ce39c27bd223675c7da6619f510c728feb97"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1b804cfad04f862d6a84af9d1ad941b06f671878f0f7ecad6c92007d423de6"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:bf77f9017fcfa1232f98598a637406e6c33982ccba8a5922339575c3e2b90ea5"}, - {file = "rpds_py-0.10.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:46c4c550bf59ce05d6bff2c98053822549aaf9fbaf81103edea325e03350bca1"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:46af4a742b90c7460e94214f923452c2c1d050a9da1d2b8d4c70cbc045e692b7"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:2a86d246a160d98d820ee7d02dc18c923c228de095be362e57b9fd8970b2c4a1"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae141c9017f8f473a6ee07a9425da021816a9f8c0683c2e5442f0ccf56b0fc62"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e1147bc3d0dd1e549d991110d0a09557ec9f925dbc1ca62871fcdab2ec9d716b"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fce7a8ee8d0f682c953c0188735d823f0fcb62779bf92cd6ba473a8e730e26ad"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c7f9d70f99e1fbcbf57c75328b80e1c0a7f6cad43e75efa90a97221be5efe15"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b309908b6ff5ffbf6394818cb73b5a2a74073acee2c57fe8719046389aeff0d"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ff1f585a0fdc1415bd733b804f33d386064a308672249b14828130dd43e7c31"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0188b580c490bccb031e9b67e9e8c695a3c44ac5e06218b152361eca847317c3"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:abe081453166e206e3a8c6d8ace57214c17b6d9477d7601ac14a365344dbc1f4"}, - {file = "rpds_py-0.10.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9118de88c16947eaf5b92f749e65b0501ea69e7c2be7bd6aefc12551622360e1"}, - {file = "rpds_py-0.10.2.tar.gz", hash = "sha256:289073f68452b96e70990085324be7223944c7409973d13ddfe0eea1c1b5663b"}, + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, ] +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + [[package]] name = "rsa" version = "4.9" description = "Pure-Python RSA implementation" -category = "main" optional = false python-versions = ">=3.6,<4" files = [ @@ -3373,7 +3758,6 @@ pyasn1 = ">=0.1.3" name = "rustworkx" version = "0.13.1" description = "A python graph library implemented in Rust" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3430,65 +3814,110 @@ mpl = ["matplotlib (>=3.0)"] [[package]] name = "scipy" -version = "1.10.1" +version = "1.9.3" description = "Fundamental algorithms for scientific computing in Python" -category = "main" optional = false -python-versions = "<3.12,>=3.8" +python-versions = ">=3.8" files = [ - {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, - {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"}, - {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f"}, - {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2"}, - {file = "scipy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1"}, - {file = "scipy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd"}, - {file = "scipy-1.10.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5"}, - {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35"}, - {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d"}, - {file = "scipy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f"}, - {file = "scipy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35"}, - {file = "scipy-1.10.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88"}, - {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1"}, - {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f"}, - {file = "scipy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415"}, - {file = "scipy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9"}, - {file = "scipy-1.10.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6"}, - {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353"}, - {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601"}, - {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"}, - {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"}, + {file = "scipy-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0"}, + {file = "scipy-1.9.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9"}, + {file = "scipy-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb"}, + {file = "scipy-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc"}, + {file = "scipy-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0"}, + {file = "scipy-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58"}, + {file = "scipy-1.9.3.tar.gz", hash = "sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027"}, ] [package.dependencies] -numpy = ">=1.19.5,<1.27.0" +numpy = ">=1.18.5,<1.26.0" [package.extras] -dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] -doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] -test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +dev = ["flake8", "mypy", "pycodestyle", "typing_extensions"] +doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-panels (>=0.5.2)", "sphinx-tabs"] +test = ["asv", "gmpy2", "mpmath", "pytest", "pytest-cov", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "secretstorage" +version = "3.3.3" +description = "Python bindings to FreeDesktop.org Secret Service API" +optional = false +python-versions = ">=3.6" +files = [ + {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, + {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, +] + +[package.dependencies] +cryptography = ">=2.0" +jeepney = ">=0.6" [[package]] name = "setuptools" -version = "68.2.0" +version = "68.2.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-68.2.0-py3-none-any.whl", hash = "sha256:af3d5949030c3f493f550876b2fd1dd5ec66689c4ee5d5344f009746f71fd5a8"}, - {file = "setuptools-68.2.0.tar.gz", hash = "sha256:00478ca80aeebeecb2f288d3206b0de568df5cd2b8fada1209843cc9a8d88a48"}, + {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, + {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "setuptools-scm" +version = "8.0.4" +description = "the blessed package to manage your versions by scm tags" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-scm-8.0.4.tar.gz", hash = "sha256:b5f43ff6800669595193fd09891564ee9d1d7dcb196cab4b2506d53a2e1c95c7"}, + {file = "setuptools_scm-8.0.4-py3-none-any.whl", hash = "sha256:b47844cd2a84b83b3187a5782c71128c28b4c94cad8bfb871da2784a5cb54c4f"}, +] + +[package.dependencies] +packaging = ">=20" +setuptools = "*" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} +typing-extensions = "*" + +[package.extras] +docs = ["entangled-cli[rich]", "mkdocs", "mkdocs-entangled-plugin", "mkdocs-material", "mkdocstrings[python]", "pygments"] +rich = ["rich"] +test = ["build", "pytest", "rich", "wheel"] + +[[package]] +name = "shellingham" +version = "1.5.3" +description = "Tool to Detect Surrounding Shell" +optional = false +python-versions = ">=3.7" +files = [ + {file = "shellingham-1.5.3-py2.py3-none-any.whl", hash = "sha256:419c6a164770c9c7cfcaeddfacb3d31ac7a8db0b0f3e9c1287679359734107e9"}, + {file = "shellingham-1.5.3.tar.gz", hash = "sha256:cb4a6fec583535bc6da17b647dd2330cf7ef30239e05d547d99ae3705fd0f7f8"}, +] [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -3500,7 +3929,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "main" optional = false python-versions = "*" files = [ @@ -3512,7 +3940,6 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -category = "main" optional = false python-versions = "*" files = [ @@ -3524,7 +3951,6 @@ files = [ name = "sphinx" version = "5.3.0" description = "Python documentation generator" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3560,7 +3986,6 @@ test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] name = "sphinx-copybutton" version = "0.5.2" description = "Add a copy button to each of your code cells." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3579,7 +4004,6 @@ rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] name = "sphinx-design" version = "0.5.0" description = "A sphinx extension for designing beautiful, view size responsive web components." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3603,7 +4027,6 @@ theme-sbt = ["sphinx-book-theme (>=1.0,<2.0)"] name = "sphinxcontrib-applehelp" version = "1.0.4" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3619,7 +4042,6 @@ test = ["pytest"] name = "sphinxcontrib-devhelp" version = "1.0.2" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3635,7 +4057,6 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.0.1" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3651,7 +4072,6 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3666,7 +4086,6 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-qthelp" version = "1.0.3" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3682,7 +4101,6 @@ test = ["pytest"] name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3696,57 +4114,56 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "2.0.20" +version = "2.0.21" description = "Database Abstraction Library" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.20-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759b51346aa388c2e606ee206c0bc6f15a5299f6174d1e10cadbe4530d3c7a98"}, - {file = "SQLAlchemy-2.0.20-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1506e988ebeaaf316f183da601f24eedd7452e163010ea63dbe52dc91c7fc70e"}, - {file = "SQLAlchemy-2.0.20-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5768c268df78bacbde166b48be788b83dddaa2a5974b8810af422ddfe68a9bc8"}, - {file = "SQLAlchemy-2.0.20-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3f0dd6d15b6dc8b28a838a5c48ced7455c3e1fb47b89da9c79cc2090b072a50"}, - {file = "SQLAlchemy-2.0.20-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:243d0fb261f80a26774829bc2cee71df3222587ac789b7eaf6555c5b15651eed"}, - {file = "SQLAlchemy-2.0.20-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6eb6d77c31e1bf4268b4d61b549c341cbff9842f8e115ba6904249c20cb78a61"}, - {file = "SQLAlchemy-2.0.20-cp310-cp310-win32.whl", hash = "sha256:bcb04441f370cbe6e37c2b8d79e4af9e4789f626c595899d94abebe8b38f9a4d"}, - {file = "SQLAlchemy-2.0.20-cp310-cp310-win_amd64.whl", hash = "sha256:d32b5ffef6c5bcb452723a496bad2d4c52b346240c59b3e6dba279f6dcc06c14"}, - {file = "SQLAlchemy-2.0.20-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dd81466bdbc82b060c3c110b2937ab65ace41dfa7b18681fdfad2f37f27acdd7"}, - {file = "SQLAlchemy-2.0.20-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6fe7d61dc71119e21ddb0094ee994418c12f68c61b3d263ebaae50ea8399c4d4"}, - {file = "SQLAlchemy-2.0.20-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4e571af672e1bb710b3cc1a9794b55bce1eae5aed41a608c0401885e3491179"}, - {file = "SQLAlchemy-2.0.20-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3364b7066b3c7f4437dd345d47271f1251e0cfb0aba67e785343cdbdb0fff08c"}, - {file = "SQLAlchemy-2.0.20-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1be86ccea0c965a1e8cd6ccf6884b924c319fcc85765f16c69f1ae7148eba64b"}, - {file = "SQLAlchemy-2.0.20-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1d35d49a972649b5080557c603110620a86aa11db350d7a7cb0f0a3f611948a0"}, - {file = "SQLAlchemy-2.0.20-cp311-cp311-win32.whl", hash = "sha256:27d554ef5d12501898d88d255c54eef8414576f34672e02fe96d75908993cf53"}, - {file = "SQLAlchemy-2.0.20-cp311-cp311-win_amd64.whl", hash = "sha256:411e7f140200c02c4b953b3dbd08351c9f9818d2bd591b56d0fa0716bd014f1e"}, - {file = "SQLAlchemy-2.0.20-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3c6aceebbc47db04f2d779db03afeaa2c73ea3f8dcd3987eb9efdb987ffa09a3"}, - {file = "SQLAlchemy-2.0.20-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d3f175410a6db0ad96b10bfbb0a5530ecd4fcf1e2b5d83d968dd64791f810ed"}, - {file = "SQLAlchemy-2.0.20-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea8186be85da6587456c9ddc7bf480ebad1a0e6dcbad3967c4821233a4d4df57"}, - {file = "SQLAlchemy-2.0.20-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c3d99ba99007dab8233f635c32b5cd24fb1df8d64e17bc7df136cedbea427897"}, - {file = "SQLAlchemy-2.0.20-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:76fdfc0f6f5341987474ff48e7a66c3cd2b8a71ddda01fa82fedb180b961630a"}, - {file = "SQLAlchemy-2.0.20-cp37-cp37m-win32.whl", hash = "sha256:d3793dcf5bc4d74ae1e9db15121250c2da476e1af8e45a1d9a52b1513a393459"}, - {file = "SQLAlchemy-2.0.20-cp37-cp37m-win_amd64.whl", hash = "sha256:79fde625a0a55220d3624e64101ed68a059c1c1f126c74f08a42097a72ff66a9"}, - {file = "SQLAlchemy-2.0.20-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:599ccd23a7146e126be1c7632d1d47847fa9f333104d03325c4e15440fc7d927"}, - {file = "SQLAlchemy-2.0.20-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1a58052b5a93425f656675673ef1f7e005a3b72e3f2c91b8acca1b27ccadf5f4"}, - {file = "SQLAlchemy-2.0.20-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79543f945be7a5ada9943d555cf9b1531cfea49241809dd1183701f94a748624"}, - {file = "SQLAlchemy-2.0.20-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63e73da7fb030ae0a46a9ffbeef7e892f5def4baf8064786d040d45c1d6d1dc5"}, - {file = "SQLAlchemy-2.0.20-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ce5e81b800a8afc870bb8e0a275d81957e16f8c4b62415a7b386f29a0cb9763"}, - {file = "SQLAlchemy-2.0.20-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb0d3e94c2a84215532d9bcf10229476ffd3b08f481c53754113b794afb62d14"}, - {file = "SQLAlchemy-2.0.20-cp38-cp38-win32.whl", hash = "sha256:8dd77fd6648b677d7742d2c3cc105a66e2681cc5e5fb247b88c7a7b78351cf74"}, - {file = "SQLAlchemy-2.0.20-cp38-cp38-win_amd64.whl", hash = "sha256:6f8a934f9dfdf762c844e5164046a9cea25fabbc9ec865c023fe7f300f11ca4a"}, - {file = "SQLAlchemy-2.0.20-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:26a3399eaf65e9ab2690c07bd5cf898b639e76903e0abad096cd609233ce5208"}, - {file = "SQLAlchemy-2.0.20-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4cde2e1096cbb3e62002efdb7050113aa5f01718035ba9f29f9d89c3758e7e4e"}, - {file = "SQLAlchemy-2.0.20-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1b09ba72e4e6d341bb5bdd3564f1cea6095d4c3632e45dc69375a1dbe4e26ec"}, - {file = "SQLAlchemy-2.0.20-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b74eeafaa11372627ce94e4dc88a6751b2b4d263015b3523e2b1e57291102f0"}, - {file = "SQLAlchemy-2.0.20-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:77d37c1b4e64c926fa3de23e8244b964aab92963d0f74d98cbc0783a9e04f501"}, - {file = "SQLAlchemy-2.0.20-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:eefebcc5c555803065128401a1e224a64607259b5eb907021bf9b175f315d2a6"}, - {file = "SQLAlchemy-2.0.20-cp39-cp39-win32.whl", hash = "sha256:3423dc2a3b94125094897118b52bdf4d37daf142cbcf26d48af284b763ab90e9"}, - {file = "SQLAlchemy-2.0.20-cp39-cp39-win_amd64.whl", hash = "sha256:5ed61e3463021763b853628aef8bc5d469fe12d95f82c74ef605049d810f3267"}, - {file = "SQLAlchemy-2.0.20-py3-none-any.whl", hash = "sha256:63a368231c53c93e2b67d0c5556a9836fdcd383f7e3026a39602aad775b14acf"}, - {file = "SQLAlchemy-2.0.20.tar.gz", hash = "sha256:ca8a5ff2aa7f3ade6c498aaafce25b1eaeabe4e42b73e25519183e4566a16fc6"}, -] - -[package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} + {file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1e7dc99b23e33c71d720c4ae37ebb095bebebbd31a24b7d99dfc4753d2803ede"}, + {file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7f0c4ee579acfe6c994637527c386d1c22eb60bc1c1d36d940d8477e482095d4"}, + {file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f7d57a7e140efe69ce2d7b057c3f9a595f98d0bbdfc23fd055efdfbaa46e3a5"}, + {file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca38746eac23dd7c20bec9278d2058c7ad662b2f1576e4c3dbfcd7c00cc48fa"}, + {file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3cf229704074bce31f7f47d12883afee3b0a02bb233a0ba45ddbfe542939cca4"}, + {file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fb87f763b5d04a82ae84ccff25554ffd903baafba6698e18ebaf32561f2fe4aa"}, + {file = "SQLAlchemy-2.0.21-cp310-cp310-win32.whl", hash = "sha256:89e274604abb1a7fd5c14867a412c9d49c08ccf6ce3e1e04fffc068b5b6499d4"}, + {file = "SQLAlchemy-2.0.21-cp310-cp310-win_amd64.whl", hash = "sha256:e36339a68126ffb708dc6d1948161cea2a9e85d7d7b0c54f6999853d70d44430"}, + {file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bf8eebccc66829010f06fbd2b80095d7872991bfe8415098b9fe47deaaa58063"}, + {file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b977bfce15afa53d9cf6a632482d7968477625f030d86a109f7bdfe8ce3c064a"}, + {file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ff3dc2f60dbf82c9e599c2915db1526d65415be323464f84de8db3e361ba5b9"}, + {file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44ac5c89b6896f4740e7091f4a0ff2e62881da80c239dd9408f84f75a293dae9"}, + {file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:87bf91ebf15258c4701d71dcdd9c4ba39521fb6a37379ea68088ce8cd869b446"}, + {file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b69f1f754d92eb1cc6b50938359dead36b96a1dcf11a8670bff65fd9b21a4b09"}, + {file = "SQLAlchemy-2.0.21-cp311-cp311-win32.whl", hash = "sha256:af520a730d523eab77d754f5cf44cc7dd7ad2d54907adeb3233177eeb22f271b"}, + {file = "SQLAlchemy-2.0.21-cp311-cp311-win_amd64.whl", hash = "sha256:141675dae56522126986fa4ca713739d00ed3a6f08f3c2eb92c39c6dfec463ce"}, + {file = "SQLAlchemy-2.0.21-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7614f1eab4336df7dd6bee05bc974f2b02c38d3d0c78060c5faa4cd1ca2af3b8"}, + {file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d59cb9e20d79686aa473e0302e4a82882d7118744d30bb1dfb62d3c47141b3ec"}, + {file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a95aa0672e3065d43c8aa80080cdd5cc40fe92dc873749e6c1cf23914c4b83af"}, + {file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8c323813963b2503e54d0944813cd479c10c636e3ee223bcbd7bd478bf53c178"}, + {file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:419b1276b55925b5ac9b4c7044e999f1787c69761a3c9756dec6e5c225ceca01"}, + {file = "SQLAlchemy-2.0.21-cp37-cp37m-win32.whl", hash = "sha256:4615623a490e46be85fbaa6335f35cf80e61df0783240afe7d4f544778c315a9"}, + {file = "SQLAlchemy-2.0.21-cp37-cp37m-win_amd64.whl", hash = "sha256:cca720d05389ab1a5877ff05af96551e58ba65e8dc65582d849ac83ddde3e231"}, + {file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b4eae01faee9f2b17f08885e3f047153ae0416648f8e8c8bd9bc677c5ce64be9"}, + {file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3eb7c03fe1cd3255811cd4e74db1ab8dca22074d50cd8937edf4ef62d758cdf4"}, + {file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2d494b6a2a2d05fb99f01b84cc9af9f5f93bf3e1e5dbdafe4bed0c2823584c1"}, + {file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b19ae41ef26c01a987e49e37c77b9ad060c59f94d3b3efdfdbf4f3daaca7b5fe"}, + {file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:fc6b15465fabccc94bf7e38777d665b6a4f95efd1725049d6184b3a39fd54880"}, + {file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:014794b60d2021cc8ae0f91d4d0331fe92691ae5467a00841f7130fe877b678e"}, + {file = "SQLAlchemy-2.0.21-cp38-cp38-win32.whl", hash = "sha256:0268256a34806e5d1c8f7ee93277d7ea8cc8ae391f487213139018b6805aeaf6"}, + {file = "SQLAlchemy-2.0.21-cp38-cp38-win_amd64.whl", hash = "sha256:73c079e21d10ff2be54a4699f55865d4b275fd6c8bd5d90c5b1ef78ae0197301"}, + {file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:785e2f2c1cb50d0a44e2cdeea5fd36b5bf2d79c481c10f3a88a8be4cfa2c4615"}, + {file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c111cd40910ffcb615b33605fc8f8e22146aeb7933d06569ac90f219818345ef"}, + {file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9cba4e7369de663611ce7460a34be48e999e0bbb1feb9130070f0685e9a6b66"}, + {file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50a69067af86ec7f11a8e50ba85544657b1477aabf64fa447fd3736b5a0a4f67"}, + {file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ccb99c3138c9bde118b51a289d90096a3791658da9aea1754667302ed6564f6e"}, + {file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:513fd5b6513d37e985eb5b7ed89da5fd9e72354e3523980ef00d439bc549c9e9"}, + {file = "SQLAlchemy-2.0.21-cp39-cp39-win32.whl", hash = "sha256:f9fefd6298433b6e9188252f3bff53b9ff0443c8fde27298b8a2b19f6617eeb9"}, + {file = "SQLAlchemy-2.0.21-cp39-cp39-win_amd64.whl", hash = "sha256:2e617727fe4091cedb3e4409b39368f424934c7faa78171749f704b49b4bb4ce"}, + {file = "SQLAlchemy-2.0.21-py3-none-any.whl", hash = "sha256:ea7da25ee458d8f404b93eb073116156fd7d8c2a776d8311534851f28277b4ce"}, + {file = "SQLAlchemy-2.0.21.tar.gz", hash = "sha256:05b971ab1ac2994a14c56b35eaaa91f86ba080e9ad481b20d99d77f381bb6258"}, +] + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""} typing-extensions = ">=4.2.0" [package.extras] @@ -3775,14 +4192,13 @@ sqlcipher = ["sqlcipher3-binary"] [[package]] name = "stack-data" -version = "0.6.2" +version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" -category = "main" optional = false python-versions = "*" files = [ - {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, - {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, ] [package.dependencies] @@ -3797,7 +4213,6 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "stevedore" version = "5.1.0" description = "Manage dynamic plugins for Python applications" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3812,7 +4227,6 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" name = "symengine" version = "0.9.2" description = "Python library providing wrappers to SymEngine" -category = "main" optional = false python-versions = ">=3.7,<4" files = [ @@ -3862,7 +4276,6 @@ files = [ name = "sympy" version = "1.12" description = "Computer algebra system (CAS) in Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3877,7 +4290,6 @@ mpmath = ">=0.19" name = "tabulate" version = "0.9.0" description = "Pretty-print tabular data" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3892,7 +4304,6 @@ widechars = ["wcwidth"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3900,11 +4311,21 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "tomlkit" +version = "0.12.1" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"}, + {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"}, +] + [[package]] name = "toolz" version = "0.12.0" description = "List processing tools and functional utilities" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3916,7 +4337,6 @@ files = [ name = "tornado" version = "6.3.3" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "main" optional = false python-versions = ">= 3.8" files = [ @@ -3937,7 +4357,6 @@ files = [ name = "tqdm" version = "4.66.1" description = "Fast, Extensible Progress Meter" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3956,37 +4375,45 @@ telegram = ["requests"] [[package]] name = "traitlets" -version = "5.9.0" +version = "5.11.2" description = "Traitlets Python configuration system" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, - {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, + {file = "traitlets-5.11.2-py3-none-any.whl", hash = "sha256:98277f247f18b2c5cabaf4af369187754f4fb0e85911d473f72329db8a7f4fae"}, + {file = "traitlets-5.11.2.tar.gz", hash = "sha256:7564b5bf8d38c40fa45498072bf4dc5e8346eb087bbf1e2ae2d8774f6a0f078e"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.5.1)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] + +[[package]] +name = "trove-classifiers" +version = "2023.9.19" +description = "Canonical source for classifiers on PyPI (pypi.org)." +optional = false +python-versions = "*" +files = [ + {file = "trove-classifiers-2023.9.19.tar.gz", hash = "sha256:3e700af445c802f251ce2b741ee78d2e5dfa5ab8115b933b89ca631b414691c9"}, + {file = "trove_classifiers-2023.9.19-py3-none-any.whl", hash = "sha256:55460364fe248294386d4dfa5d16544ec930493ecc6bd1db07a0d50afb37018e"}, +] [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] [[package]] name = "tzdata" version = "2023.3" description = "Provider of IANA time zone data" -category = "main" optional = false python-versions = ">=2" files = [ @@ -3996,14 +4423,13 @@ files = [ [[package]] name = "urllib3" -version = "2.0.4" +version = "2.0.6" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, - {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, + {file = "urllib3-2.0.6-py3-none-any.whl", hash = "sha256:7a7c7003b000adf9e7ca2a377c9688bbc54ed41b985789ed576570342a375cd2"}, + {file = "urllib3-2.0.6.tar.gz", hash = "sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564"}, ] [package.extras] @@ -4012,47 +4438,148 @@ secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17. socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "virtualenv" +version = "20.24.5" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.24.5-py3-none-any.whl", hash = "sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b"}, + {file = "virtualenv-20.24.5.tar.gz", hash = "sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<4" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + [[package]] name = "wcwidth" -version = "0.2.6" +version = "0.2.8" description = "Measures the displayed width of unicode strings in a terminal" -category = "main" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, - {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, + {file = "wcwidth-0.2.8-py2.py3-none-any.whl", hash = "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704"}, + {file = "wcwidth-0.2.8.tar.gz", hash = "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4"}, ] [[package]] name = "widgetsnbextension" -version = "4.0.8" +version = "4.0.9" description = "Jupyter interactive widgets for Jupyter Notebook" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "widgetsnbextension-4.0.8-py3-none-any.whl", hash = "sha256:2e37f0ce9da11651056280c7efe96f2db052fe8fc269508e3724f5cbd6c93018"}, - {file = "widgetsnbextension-4.0.8.tar.gz", hash = "sha256:9ec291ba87c2dfad42c3d5b6f68713fa18be1acd7476569516b2431682315c17"}, + {file = "widgetsnbextension-4.0.9-py3-none-any.whl", hash = "sha256:91452ca8445beb805792f206e560c1769284267a30ceb1cec9f5bcc887d15175"}, + {file = "widgetsnbextension-4.0.9.tar.gz", hash = "sha256:3c1f5e46dc1166dfd40a42d685e6a51396fd34ff878742a3e47c6f0cc4a2a385"}, ] +[[package]] +name = "xattr" +version = "0.10.1" +description = "Python wrapper for extended filesystem attributes" +optional = false +python-versions = "*" +files = [ + {file = "xattr-0.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:16a660a883e703b311d1bbbcafc74fa877585ec081cd96e8dd9302c028408ab1"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1e2973e72faa87ca29d61c23b58c3c89fe102d1b68e091848b0e21a104123503"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:13279fe8f7982e3cdb0e088d5cb340ce9cbe5ef92504b1fd80a0d3591d662f68"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1dc9b9f580ef4b8ac5e2c04c16b4d5086a611889ac14ecb2e7e87170623a0b75"}, + {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:485539262c2b1f5acd6b6ea56e0da2bc281a51f74335c351ea609c23d82c9a79"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:295b3ab335fcd06ca0a9114439b34120968732e3f5e9d16f456d5ec4fa47a0a2"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a126eb38e14a2f273d584a692fe36cff760395bf7fc061ef059224efdb4eb62c"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:b0e919c24f5b74428afa91507b15e7d2ef63aba98e704ad13d33bed1288dca81"}, + {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:e31d062cfe1aaeab6ba3db6bd255f012d105271018e647645941d6609376af18"}, + {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:209fb84c09b41c2e4cf16dd2f481bb4a6e2e81f659a47a60091b9bcb2e388840"}, + {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c4120090dac33eddffc27e487f9c8f16b29ff3f3f8bcb2251b2c6c3f974ca1e1"}, + {file = "xattr-0.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3e739d624491267ec5bb740f4eada93491de429d38d2fcdfb97b25efe1288eca"}, + {file = "xattr-0.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2677d40b95636f3482bdaf64ed9138fb4d8376fb7933f434614744780e46e42d"}, + {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40039f1532c4456fd0f4c54e9d4e01eb8201248c321c6c6856262d87e9a99593"}, + {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:148466e5bb168aba98f80850cf976e931469a3c6eb11e9880d9f6f8b1e66bd06"}, + {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0aedf55b116beb6427e6f7958ccd80a8cbc80e82f87a4cd975ccb61a8d27b2ee"}, + {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c3024a9ff157247c8190dd0eb54db4a64277f21361b2f756319d9d3cf20e475f"}, + {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f1be6e733e9698f645dbb98565bb8df9b75e80e15a21eb52787d7d96800e823b"}, + {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7880c8a54c18bc091a4ce0adc5c6d81da1c748aec2fe7ac586d204d6ec7eca5b"}, + {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:89c93b42c3ba8aedbc29da759f152731196c2492a2154371c0aae3ef8ba8301b"}, + {file = "xattr-0.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b905e808df61b677eb972f915f8a751960284358b520d0601c8cbc476ba2df6"}, + {file = "xattr-0.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ef954d0655f93a34d07d0cc7e02765ec779ff0b59dc898ee08c6326ad614d5"}, + {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:199b20301b6acc9022661412346714ce764d322068ef387c4de38062474db76c"}, + {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec0956a8ab0f0d3f9011ba480f1e1271b703d11542375ef73eb8695a6bd4b78b"}, + {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffcb57ca1be338d69edad93cf59aac7c6bb4dbb92fd7bf8d456c69ea42f7e6d2"}, + {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f0563196ee54756fe2047627d316977dc77d11acd7a07970336e1a711e934db"}, + {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc354f086f926a1c7f04886f97880fed1a26d20e3bc338d0d965fd161dbdb8ab"}, + {file = "xattr-0.10.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c0cd2d02ef2fb45ecf2b0da066a58472d54682c6d4f0452dfe7ae2f3a76a42ea"}, + {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49626096ddd72dcc1654aadd84b103577d8424f26524a48d199847b5d55612d0"}, + {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ceaa26bef8fcb17eb59d92a7481c2d15d20211e217772fb43c08c859b01afc6a"}, + {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c014c371391f28f8cd27d73ea59f42b30772cd640b5a2538ad4f440fd9190b"}, + {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:46c32cd605673606b9388a313b0050ee7877a0640d7561eea243ace4fa2cc5a6"}, + {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:772b22c4ff791fe5816a7c2a1c9fcba83f9ab9bea138eb44d4d70f34676232b4"}, + {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:183ad611a2d70b5a3f5f7aadef0fcef604ea33dcf508228765fd4ddac2c7321d"}, + {file = "xattr-0.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8068df3ebdfa9411e58d5ae4a05d807ec5994645bb01af66ec9f6da718b65c5b"}, + {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bc40570155beb85e963ae45300a530223d9822edfdf09991b880e69625ba38a"}, + {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:436e1aaf23c07e15bed63115f1712d2097e207214fc6bcde147c1efede37e2c5"}, + {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7298455ccf3a922d403339781b10299b858bb5ec76435445f2da46fb768e31a5"}, + {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:986c2305c6c1a08f78611eb38ef9f1f47682774ce954efb5a4f3715e8da00d5f"}, + {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5dc6099e76e33fa3082a905fe59df766b196534c705cf7a2e3ad9bed2b8a180e"}, + {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:042ad818cda6013162c0bfd3816f6b74b7700e73c908cde6768da824686885f8"}, + {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d4c306828a45b41b76ca17adc26ac3dc00a80e01a5ba85d71df2a3e948828f2"}, + {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a606280b0c9071ef52572434ecd3648407b20df3d27af02c6592e84486b05894"}, + {file = "xattr-0.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5b49d591cf34cda2079fd7a5cb2a7a1519f54dc2e62abe3e0720036f6ed41a85"}, + {file = "xattr-0.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8705ac6791426559c1a5c2b88bb2f0e83dc5616a09b4500899bfff6a929302"}, + {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5ea974930e876bc5c146f54ac0f85bb39b7b5de2b6fc63f90364712ae368ebe"}, + {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f55a2dd73a12a1ae5113c5d9cd4b4ab6bf7950f4d76d0a1a0c0c4264d50da61d"}, + {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:475c38da0d3614cc5564467c4efece1e38bd0705a4dbecf8deeb0564a86fb010"}, + {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:925284a4a28e369459b2b7481ea22840eed3e0573a4a4c06b6b0614ecd27d0a7"}, + {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa32f1b45fed9122bed911de0fcc654da349e1f04fa4a9c8ef9b53e1cc98b91e"}, + {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c5d3d0e728bace64b74c475eb4da6148cd172b2d23021a1dcd055d92f17619ac"}, + {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8faaacf311e2b5cc67c030c999167a78a9906073e6abf08eaa8cf05b0416515c"}, + {file = "xattr-0.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cc6b8d5ca452674e1a96e246a3d2db5f477aecbc7c945c73f890f56323e75203"}, + {file = "xattr-0.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3725746a6502f40f72ef27e0c7bfc31052a239503ff3eefa807d6b02a249be22"}, + {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:789bd406d1aad6735e97b20c6d6a1701e1c0661136be9be862e6a04564da771f"}, + {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9a7a807ab538210ff8532220d8fc5e2d51c212681f63dbd4e7ede32543b070f"}, + {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e5825b5fc99ecdd493b0cc09ec35391e7a451394fdf623a88b24726011c950d"}, + {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80638d1ce7189dc52f26c234cee3522f060fadab6a8bc3562fe0ddcbe11ba5a4"}, + {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3ff0dbe4a6ce2ce065c6de08f415bcb270ecfd7bf1655a633ddeac695ce8b250"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5267e5f9435c840d2674194150b511bef929fa7d3bc942a4a75b9eddef18d8d8"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b27dfc13b193cb290d5d9e62f806bb9a99b00cd73bb6370d556116ad7bb5dc12"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:636ebdde0277bce4d12d2ef2550885804834418fee0eb456b69be928e604ecc4"}, + {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d60c27922ec80310b45574351f71e0dd3a139c5295e8f8b19d19c0010196544f"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b34df5aad035d0343bd740a95ca30db99b776e2630dca9cc1ba8e682c9cc25ea"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f24a7c04ff666d0fe905dfee0a84bc899d624aeb6dccd1ea86b5c347f15c20c1"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3878e1aff8eca64badad8f6d896cb98c52984b1e9cd9668a3ab70294d1ef92d"}, + {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4abef557028c551d59cf2fb3bf63f2a0c89f00d77e54c1c15282ecdd56943496"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0e14bd5965d3db173d6983abdc1241c22219385c22df8b0eb8f1846c15ce1fee"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f9be588a4b6043b03777d50654c6079af3da60cc37527dbb80d36ec98842b1e"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bc4ae264aa679aacf964abf3ea88e147eb4a22aea6af8c6d03ebdebd64cfd6"}, + {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:827b5a97673b9997067fde383a7f7dc67342403093b94ea3c24ae0f4f1fec649"}, + {file = "xattr-0.10.1.tar.gz", hash = "sha256:c12e7d81ffaa0605b3ac8c22c2994a8e18a9cf1c59287a1b7722a2289c952ec5"}, +] + +[package.dependencies] +cffi = ">=1.0" + [[package]] name = "zipp" -version = "3.16.2" +version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, - {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [metadata] lock-version = "2.0" -python-versions = ">=3.8 <3.11" -content-hash = "502d6f7494cfb8256961ae0ab13f01dd9795fbd635236c1b21f015856bdbea38" +python-versions = "^3.8" +content-hash = "2d201afacdedb6bdc9815210e33f6b26bc82aa4ac9a2f69371de83d0d0b7b4ba" diff --git a/pyproject.toml b/pyproject.toml index 31c321e..6020039 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,28 +6,30 @@ authors = ["AlexisRalli ", "TimWeaving =1.0.0"] diff --git a/symmer/__init__.py b/symmer/__init__.py index 2078d33..6b0e281 100644 --- a/symmer/__init__.py +++ b/symmer/__init__.py @@ -1,3 +1,3 @@ """Main init for package.""" -from symmer.operators import PauliwordOp, QuantumState -from symmer.projection import QubitTapering, ContextualSubspace, QubitSubspaceManager \ No newline at end of file +from symmer.operators import PauliwordOp, QuantumState +from symmer.projection import QubitTapering, ContextualSubspace, QubitSubspaceManager diff --git a/symmer/approximate/tensor_network.py b/symmer/approximate/tensor_network.py index d70d4a5..a47358c 100644 --- a/symmer/approximate/tensor_network.py +++ b/symmer/approximate/tensor_network.py @@ -13,10 +13,9 @@ class MPOOp: Class to build MPO operator from Pauli strings and coeffs. """ - def __init__(self, - pauliList: List[str], - coeffList: List[complex], - Dmax: int = None) -> None: + def __init__( + self, pauliList: List[str], coeffList: List[complex], Dmax: int = None + ) -> None: """ Initialize an MPO to represent an operator from Pauli strings and coefficients. MPO tensors are shapes as (σ, l, i, j) where σ is the @@ -31,9 +30,9 @@ def __init__(self, self.mpo = pstrings_to_mpo_optimized(pauliList, coeffList, Dmax) @classmethod - def from_dictionary(cls, - operator_dict: Dict[str, complex], - Dmax: int = None) -> "MPOApproximator": + def from_dictionary( + cls, operator_dict: Dict[str, complex], Dmax: int = None + ) -> "MPOApproximator": """ Initalize MPOApproximator using Pauli terms and coefficients stored in a dictionary like {pauli: coeff} @@ -50,8 +49,7 @@ def from_dictionary(cls, return cls(paulis, coeffs, Dmax) @classmethod - def from_WordOp(cls, - WordOp: PauliwordOp) -> "MPOApproximator": + def from_WordOp(cls, WordOp: PauliwordOp) -> "MPOApproximator": """ Initialize MPOApproximator using PauliwordOp. @@ -65,12 +63,12 @@ def from_WordOp(cls, @cached_property def to_matrix(self) -> np.ndarray: - ''' + """ Contract MPO to produce matrix representation of operator. Returns: Matrix Representation(np.ndarray) of operator. - ''' + """ mpo = self.mpo contr = mpo[0] for tensor in mpo[1:]: @@ -81,13 +79,14 @@ def to_matrix(self) -> np.ndarray: contr = np.squeeze(contr) return contr - + + def get_MPO(operator: PauliwordOp, max_bond_dimension: int) -> MPOOp: - """ - Return the Matrix Product Operator (MPO) of a PauliwordOp + """ + Return the Matrix Product Operator (MPO) of a PauliwordOp (linear combination of Paulis) given a maximum bond dimension. - Args: + Args: operator (PauliwordOp): PauliwordOp (linear combination of Paulis) max_bond_dimension (int): Maximum bond dimension. @@ -98,6 +97,7 @@ def get_MPO(operator: PauliwordOp, max_bond_dimension: int) -> MPOOp: mpo = MPOOp(pstrings, coefflist, Dmax=max_bond_dimension) return mpo + def find_groundstate_quimb(MPOOp: MPOOp, dmrg=None, gs_guess=None) -> QuantumState: """ Use quimb's DMRG2 optimiser to approximate groundstate of MPOOp @@ -110,7 +110,7 @@ def find_groundstate_quimb(MPOOp: MPOOp, dmrg=None, gs_guess=None) -> QuantumSta dmrg_state (QuantumState): Approximated groundstate. """ mpo = [np.squeeze(m) for m in MPOOp.mpo] - MPO = MatrixProductOperator(mpo, 'dulr') + MPO = MatrixProductOperator(mpo, "dulr") if gs_guess is not None: no_qubits = int(np.log2(gs_guess.shape[0])) @@ -129,17 +129,15 @@ def find_groundstate_quimb(MPOOp: MPOOp, dmrg=None, gs_guess=None) -> QuantumSta Paulis = { - 'I': np.eye(2, dtype=np.complex64), - 'X': np.array([[0, 1], - [1, 0]], dtype=np.complex64), - 'Y': np.array([[0, -1j], - [1j, 0]], dtype=np.complex64), - 'Z': np.array([[1, 0], - [0, -1]], dtype=np.complex64), - } + "I": np.eye(2, dtype=np.complex64), + "X": np.array([[0, 1], [1, 0]], dtype=np.complex64), + "Y": np.array([[0, -1j], [1j, 0]], dtype=np.complex64), + "Z": np.array([[1, 0], [0, -1]], dtype=np.complex64), +} + def coefflist_to_complex(coefflist): - ''' + """ Convert a list of real + imaginary components into a complex vector. Args: @@ -147,21 +145,22 @@ def coefflist_to_complex(coefflist): Returns: Array of complex vectors - ''' + """ arr = np.array(coefflist, dtype=complex) - return arr[:, 0] + 1j*arr[:, 1] + return arr[:, 0] + 1j * arr[:, 1] + def pstrings_to_mpo_optimized(pstrings, coeffs=None, Dmax=None): - ''' + """ Convert a list of Pauli Strings into an MPO. If coeff list is given, rescale each Pauli string by the corresponding element of the coeff list. Bond dim specifies the maximum bond dimension, if None, no maximum bond dimension. Optimization is achieved by constructing final sum terms directly from: - 1) First letters of each Pauli string for the first term - 2) Last letters of each Pauli string for the last term - 3) Diagonal matrix per each part of 4D tensor with respective middle letters of Pauli strings + 1) First letters of each Pauli string for the first term + 2) Last letters of each Pauli string for the last term + 3) Diagonal matrix per each part of 4D tensor with respective middle letters of Pauli strings Args: pstrings (List[str]): List of Pauli Strings @@ -170,7 +169,7 @@ def pstrings_to_mpo_optimized(pstrings, coeffs=None, Dmax=None): Returns: mpo: The Matrix Product Operator (MPO) - ''' + """ if coeffs is None: coeffs = np.ones(len(pstrings)) @@ -187,35 +186,34 @@ def pstrings_to_mpo_optimized(pstrings, coeffs=None, Dmax=None): last_p = [pstr[-1] for pstr in pstrings] p_i = [(0, 0), (0, 1), (1, 0), (1, 1)] - first_sum = [ [ [[ ]], [[ ]] ], [ [[ ]], [[ ]] ]] + first_sum = [[[[]], [[]]], [[[]], [[]]]] for p in first_p: for x, y in p_i: first_sum[x][y][0].extend([p[x][y]]) summed[0] = np.array(first_sum) - - last_sum = [ [ [ ], [ ] ], [ [ ], [ ] ]] + last_sum = [[[], []], [[], []]] for p in last_p: for x, y in p_i: - last_sum[x][y].append([ Paulis[p][x][y]]) - + last_sum[x][y].append([Paulis[p][x][y]]) + summed[-1] = np.array(last_sum) - for i in range(1, len(pstrings[0]) - 1): middle_p_i = [pstr[i] for pstr in pstrings] - new_tensor = [ [ [ ], [ ] ], [ [ ], [ ] ] ] + new_tensor = [[[], []], [[], []]] for x, y in p_i: - new_tensor[x][y] = np.diag(np.array([ Paulis[p][x][y] for p in middle_p_i ])) + new_tensor[x][y] = np.diag(np.array([Paulis[p][x][y] for p in middle_p_i])) summed[i] = np.array(new_tensor) mpo = truncate_MPO(summed, Dmax) return mpo + def pstrings_to_mpo(pstrings, coeffs=None, Dmax=None): - ''' + """ Convert a list of Pauli Strings into an MPO. If coeff list is given, rescale each Pauli string by the corresponding element of the coeff list. Bond dim specifies the maximum bond dimension, if None, no maximum bond @@ -228,7 +226,7 @@ def pstrings_to_mpo(pstrings, coeffs=None, Dmax=None): Returns: mpo: The Matrix Product Operator (MPO) - ''' + """ if coeffs is None: coeffs = np.ones(len(pstrings)) @@ -244,15 +242,16 @@ def pstrings_to_mpo(pstrings, coeffs=None, Dmax=None): return mpo + def pstring_to_mpo(pstring, scaling=None): - ''' + """ Args: pstring (str): Pauli String scaling (complex): Scale the Pauli string by a factor of 'scaling'. By default it is set to 'None'. - + Returns: The Matrix Product Operator (MPO) - ''' + """ As = [] for p in pstring: pauli = Paulis[p] @@ -265,14 +264,14 @@ def pstring_to_mpo(pstring, scaling=None): def truncated_SVD(M, Dmax=None): - ''' + """ Args: M: (..., P, Q) array_like. A real or complex array with M.ndim >= 2. Dmax (int): Maximum bond dimension. By default it is set to 'None'. Returns: U, S, V: Singular Value Decomposition of M - ''' + """ U, S, V = np.linalg.svd(M, full_matrices=False) if Dmax is not None and len(S) > Dmax: @@ -282,15 +281,16 @@ def truncated_SVD(M, Dmax=None): return U, S, V + def truncate_MPO(mpo, Dmax): - ''' + """ Args: mpo: Matrix Product Operator (MPO) Dmax (int): Maximum bond dimension. Returns: As: Truncated Matrix Product Operator. - ''' + """ As = [] for n in range(len(mpo) - 1): # Don't need to run on the last term A = mpo[n] @@ -305,28 +305,29 @@ def truncate_MPO(mpo, Dmax): # Update the next term M = np.diag(S) @ V - _A1 = ncon([M, mpo[n+1]], ((-3, 1), (-1, -2, 1, -4))) - mpo[n+1] = _A1 + _A1 = ncon([M, mpo[n + 1]], ((-3, 1), (-1, -2, 1, -4))) + mpo[n + 1] = _A1 As.append(mpo[-1]) return As + def sum_mpo(mpo1, mpo2): - ''' + """ Args: mpo1: First Matrix Product Operator (MPO) mpo2: Second Matrix Product Operator (MPO) - + Returns: summed: Sum of First and Second Matrix Product Operator. - ''' + """ summed = [None] * len(mpo1) σ10, l10, i10, j10 = mpo1[0].shape σ20, l20, i20, j20 = mpo2[0].shape t10 = copy(mpo1[0]) t20 = copy(mpo2[0]) - first_sum = np.zeros((σ10, l10, i10, j10+j20), dtype=complex) + first_sum = np.zeros((σ10, l10, i10, j10 + j20), dtype=complex) first_sum[:, :, :, :j10] = t10 first_sum[:, :, :, j10:] = t20 summed[0] = first_sum @@ -345,8 +346,7 @@ def sum_mpo(mpo1, mpo2): t1 = copy(mpo1[i]) t2 = copy(mpo2[i]) - - new_shape = (σ1, l1, i1+i2, j1+j2) + new_shape = (σ1, l1, i1 + i2, j1 + j2) new_tensor = np.zeros(new_shape, dtype=complex) @@ -354,4 +354,4 @@ def sum_mpo(mpo1, mpo2): new_tensor[:, :, i1:, j1:] = t2 summed[i] = new_tensor - return summed \ No newline at end of file + return summed diff --git a/symmer/command_line.py b/symmer/command_line.py index 32c15c9..e8dc8cd 100644 --- a/symmer/command_line.py +++ b/symmer/command_line.py @@ -6,6 +6,7 @@ from symmer.projection import CS_VQE import datetime + def check_path_to_dir(potential_path: str) -> str: """ Checks if path is a directory @@ -57,9 +58,11 @@ def command_interface(): # type=str, # help="command of algorithm to implement (tapering or contextual subspace approx)") - parser.add_argument('--command', - type=str, - help="command of algorithm to implement (tapering or contextual subspace approx)") + parser.add_argument( + "--command", + type=str, + help="command of algorithm to implement (tapering or contextual subspace approx)", + ) parser.add_argument( "--config", @@ -74,10 +77,10 @@ def command_interface(): ) parser.add_argument( "--Hamiltonian", - '-H', + "-H", # type=check_path_to_file, type=dict, - help="Path to Pauli Hamiltonian (json file of Hamiltonian).", #TODO: add other options too + help="Path to Pauli Hamiltonian (json file of Hamiltonian).", # TODO: add other options too ) parser.add_argument( "--verbose", @@ -94,7 +97,7 @@ def command_interface(): ) parser.add_argument( "--contextual_subspace_enforce_clique_operator", - '-enforce_A', + "-enforce_A", type=bool, help="whether to enforce clique operator (A)", ) @@ -110,8 +113,9 @@ def command_interface(): args["verbose"] = args.get("verbose", False) args["output_dir"] = args.get("output_dir", os.getcwd()) args["taper_reference"] = args.get("taper_reference", None) - args["contextual_subspace_enforce_clique_operator"] = args.get("contextual_subspace_enforce_clique_operator", - True) + args["contextual_subspace_enforce_clique_operator"] = args.get( + "contextual_subspace_enforce_clique_operator", True + ) else: # Transform the namespace object to a dict. args = vars(args) @@ -125,7 +129,6 @@ def command_interface(): print(f"{[key for key, value in args.items() if value is None]}\n") raise Exception("Missing argument values.") - return args @@ -137,8 +140,8 @@ def cli() -> None: output_data = {} - if args["taper"] == 'taper': - basename = 'tapering' + if args["taper"] == "taper": + basename = "tapering" print(args["H"]) taper_hamiltonian = QubitTapering(PauliwordOp(args["H"])) reference_state = QubitTapering(PauliwordOp(args["taper_reference"])) @@ -147,14 +150,17 @@ def cli() -> None: taper_hamiltonian.stabilizers.update_sector(reference_state) ham_tap = taper_hamiltonian.taper_it(ref_state=reference_state) - output_data['tapered_H'] = ham_tap.to_dictionary - output_data['symmetry_generators'] = taper_hamiltonian.symmetry_generators.to_dictionary - output_data['symmetry_generators']= [rot.to_dictionary for rot in - taper_hamiltonian.stabilizers.stabilizer_rotations] - + output_data["tapered_H"] = ham_tap.to_dictionary + output_data[ + "symmetry_generators" + ] = taper_hamiltonian.symmetry_generators.to_dictionary + output_data["symmetry_generators"] = [ + rot.to_dictionary + for rot in taper_hamiltonian.stabilizers.stabilizer_rotations + ] - elif args["contextual_subspace"] == 'contextual_subspace': - basename = 'contextual_subspace' + elif args["contextual_subspace"] == "contextual_subspace": + basename = "contextual_subspace" cs_vqe = CS_VQE(PauliwordOp(args["H"])) noncon_H = cs_vqe.noncontextual_operator @@ -163,25 +169,25 @@ def cli() -> None: noncon_symmetry_generators = cs_vqe.symmetry_generators clique_operator = cs_vqe.clique_operator + output_data["noncon_H"] = noncon_H.to_dictionary + output_data["con_H"] = con_H.to_dictionary + output_data[ + "noncon_symmetry_generators" + ] = noncon_symmetry_generators.to_dictionary + output_data["clique_operator"] = clique_operator.to_dictionary - output_data['noncon_H'] = noncon_H.to_dictionary - output_data['con_H'] = con_H.to_dictionary - output_data['noncon_symmetry_generators'] = noncon_symmetry_generators.to_dictionary - output_data['clique_operator'] = clique_operator.to_dictionary - - #TODO solve contextual subspace problem to find right sector! + # TODO solve contextual subspace problem to find right sector! else: - raise ValueError('unknown function') + raise ValueError("unknown function") # make filename unique with date and time suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S") filename = "_".join([basename, suffix]) - - outloc = os.path.join(args["output_dir"], filename + '.yaml') - with open(os.path.join(outloc, 'w')) as file: + outloc = os.path.join(args["output_dir"], filename + ".yaml") + with open(os.path.join(outloc, "w")) as file: yaml.dump(output_data, file) - print(f'file saved at: {outloc}') + print(f"file saved at: {outloc}") return None diff --git a/symmer/evolution/__init__.py b/symmer/evolution/__init__.py index f9e9865..06fbb49 100644 --- a/symmer/evolution/__init__.py +++ b/symmer/evolution/__init__.py @@ -1,5 +1,9 @@ """init for evolution.""" from .exponentiation import trotter from .gate_library import * -from .decomposition import qasm_to_PauliwordOp, PauliwordOp_to_QuantumCircuit, get_CNOT_connectivity_graph -from .variational_optimization import VQE_Driver, ADAPT_VQE \ No newline at end of file +from .decomposition import ( + qasm_to_PauliwordOp, + PauliwordOp_to_QuantumCircuit, + get_CNOT_connectivity_graph, +) +from .variational_optimization import VQE_Driver, ADAPT_VQE diff --git a/symmer/evolution/decomposition.py b/symmer/evolution/decomposition.py index 29d57bd..c11c5ce 100644 --- a/symmer/evolution/decomposition.py +++ b/symmer/evolution/decomposition.py @@ -5,15 +5,17 @@ from qiskit.circuit import QuantumCircuit, ParameterVector import networkx as nx import warnings -warnings.filterwarnings("ignore", category=DeprecationWarning) + +warnings.filterwarnings("ignore", category=DeprecationWarning) ############################################## # Decompose any QASM file into a PauliwordOp # ############################################## + def qasm_to_PauliwordOp(qasm: str, reverse=False, combine=True) -> PauliwordOp: - """ - Decompose an QASM circuit into a linear combination of Pauli + """ + Decompose an QASM circuit into a linear combination of Pauli operators via the gate definitions in evolution.gate_library. Args: @@ -25,98 +27,112 @@ def qasm_to_PauliwordOp(qasm: str, reverse=False, combine=True) -> PauliwordOp: A linear combination of Pauli operators representing QASM circuit. """ gate_map = { - 'x':X, 'y':Y, 'z':Z, 'h':Had, 'rx':RX, 'ry':RY, - 'rz':RZ, 'u1':U1, 'cz':CZ, 'cx':CX, 's':S - } # for conversion from qiskit to PauliwordOp definitions + "x": X, + "y": Y, + "z": Z, + "h": Had, + "rx": RX, + "ry": RY, + "rz": RZ, + "u1": U1, + "cz": CZ, + "cx": CX, + "s": S, + } # for conversion from qiskit to PauliwordOp definitions gateset = [] - for gate in qasm.split(';\n')[:-1]: - name, qubits = gate.split(' ') + for gate in qasm.split(";\n")[:-1]: + name, qubits = gate.split(" ") # identify number of qubits in circuit - if name=='qreg': + if name == "qreg": num_qubits = int(qubits[2:-1]) - if name in ['barrier', 'include', 'OPENQASM', 'qreg']: + if name in ["barrier", "include", "OPENQASM", "qreg"]: pass else: # extract angle - if name.find('(')!=-1: - name, angle = name.split('(') + if name.find("(") != -1: + name, angle = name.split("(") angle = angle[:-1] - if angle=='pi/2': - angle = np.pi/2 - elif angle=='-pi/2': - angle = -np.pi/2 + if angle == "pi/2": + angle = np.pi / 2 + elif angle == "-pi/2": + angle = -np.pi / 2 else: angle = float(angle) else: angle = None - #extract qubits - if qubits.find(',')!=-1: - control, target = qubits.split(',') + # extract qubits + if qubits.find(",") != -1: + control, target = qubits.split(",") control, target = int(control[2:-1]), int(target[2:-1]) else: control, target = -1, int(qubits[2:-1]) # if reverse then flip qubit ordering and negate angles (for consistency with Qiskit) - flip=1 + flip = 1 if reverse: - flip=-1 - control, target = num_qubits-1-control, num_qubits-1-target + flip = -1 + control, target = num_qubits - 1 - control, num_qubits - 1 - target # generate relevant gate and append to list - if name in ['x', 'y', 'z', 'h', 's', 'sdg']: + if name in ["x", "y", "z", "h", "s", "sdg"]: G = gate_map[name](num_qubits, target) - elif name in ['cz', 'cx']: + elif name in ["cz", "cx"]: G = gate_map[name](num_qubits, control, target) - elif name in ['rx', 'ry', 'rz', 'u1']: - G = gate_map[name](num_qubits, target, angle=flip*angle) + elif name in ["rx", "ry", "rz", "u1"]: + G = gate_map[name](num_qubits, target, angle=flip * angle) else: - raise ValueError(f'Gate decomposition {name} not defined') + raise ValueError(f"Gate decomposition {name} not defined") gateset.append(G) # if combine then take product over gateset - obscures gate contributions in resulting PauliwordOp if combine: - qc_decomposition = reduce(lambda x,y:x*y, gateset[::-1]) + qc_decomposition = reduce(lambda x, y: x * y, gateset[::-1]) return qc_decomposition.cleanup() else: return gateset + #################################################### # Trotterized circuit of exponentiated PauliwordOp # #################################################### + def PauliwordOp_to_instructions(PwordOp) -> Dict[int, Dict[str, List[int]]]: - """ - Stores a dictionary of gate instructions at each step, where each value - is a dictionary indicating the indices on which to apply each H,S,CNOT and RZ gate. + """ + Stores a dictionary of gate instructions at each step, where each value + is a dictionary indicating the indices on which to apply each H,S,CNOT and RZ gate. - Args: - PwordOp (PauliWordOp): PauliwordOp which has to be converted into Trotterized circuit instructions. + Args: + PwordOp (PauliWordOp): PauliwordOp which has to be converted into Trotterized circuit instructions. + + Returns: + circuit_instructions (dict): Trotterized circuit + """ + circuit_instructions = {} + for step, (X, Z) in enumerate(zip(PwordOp.X_block, PwordOp.Z_block)): + # locations for H and S gates to transform into Pauli Z basis + H_indices = np.where(X)[0][::-1] + S_indices = np.where(X & Z)[0][::-1] + # CNOT cascade indices + CNOT_indices = np.where(X | Z)[0][::-1] + circuit_instructions[step] = { + "H_indices": H_indices, + "S_indices": S_indices, + "CNOT_indices": CNOT_indices, + "RZ_index": CNOT_indices[-1], + } + return circuit_instructions - Returns: - circuit_instructions (dict): Trotterized circuit - """ - circuit_instructions = {} - for step, (X,Z) in enumerate(zip(PwordOp.X_block, PwordOp.Z_block)): - # locations for H and S gates to transform into Pauli Z basis - H_indices = np.where(X)[0][::-1] - S_indices = np.where(X & Z)[0][::-1] - # CNOT cascade indices - CNOT_indices = np.where(X | Z)[0][::-1] - circuit_instructions[step] = {'H_indices':H_indices, - 'S_indices':S_indices, - 'CNOT_indices':CNOT_indices, - 'RZ_index':CNOT_indices[-1]} - return circuit_instructions def PauliwordOp_to_QuantumCircuit( - PwordOp: PauliwordOp, - ref_state: np.array = None, - basis_change_indices: Dict[str, List[int]] = {'X_indices':[],'Y_indices':[]}, - trotter_number: int = 1, + PwordOp: PauliwordOp, + ref_state: np.array = None, + basis_change_indices: Dict[str, List[int]] = {"X_indices": [], "Y_indices": []}, + trotter_number: int = 1, bind_params: bool = True, - include_barriers:bool = True, - parameter_label: str = 'P' - ) -> QuantumCircuit: + include_barriers: bool = True, + parameter_label: str = "P", +) -> QuantumCircuit: """ - Convert the operator to a QASM circuit string for input + Convert the operator to a QASM circuit string for input into quantum computing packages such as Qiskit and Cirq. Args: @@ -136,7 +152,7 @@ def PauliwordOp_to_QuantumCircuit( ref_state = ref_state.state_matrix[0] def qiskit_ordering(indices): - """ + """ We index from left to right - in Qiskit this ordering is reversed. Args: @@ -145,7 +161,7 @@ def qiskit_ordering(indices): return PwordOp.n_qubits - 1 - indices qc = QuantumCircuit(PwordOp.n_qubits) - for i in qiskit_ordering(np.where(ref_state==1)[0]): + for i in qiskit_ordering(np.where(ref_state == 1)[0]): qc.x(i) non_identity = PwordOp[np.any(PwordOp.symp_matrix, axis=1)] @@ -168,7 +184,7 @@ def circuit_from_step(angle, H_indices, S_indices, CNOT_indices, RZ_index): qc.h(i) # compute parity CNOT_cascade(CNOT_indices) - qc.rz(-2*angle, RZ_index) + qc.rz(-2 * angle, RZ_index) CNOT_cascade(CNOT_indices, reverse=True) for i in H_indices: qc.h(i) @@ -176,15 +192,22 @@ def circuit_from_step(angle, H_indices, S_indices, CNOT_indices, RZ_index): qc.s(i) if bind_params: - angles = non_identity.coeff_vec.real/trotter_number + angles = non_identity.coeff_vec.real / trotter_number else: - angles = np.array(ParameterVector(parameter_label, non_identity.n_terms))/trotter_number + angles = ( + np.array(ParameterVector(parameter_label, non_identity.n_terms)) + / trotter_number + ) instructions = PauliwordOp_to_instructions(non_identity) - assert(len(angles)==len(instructions)), 'Number of parameters does not match the circuit instructions' + assert len(angles) == len( + instructions + ), "Number of parameters does not match the circuit instructions" for trot_step in range(trotter_number): for step, gate_indices in instructions.items(): - qiskit_gate_indices = [qiskit_ordering(indices) for indices in gate_indices.values()] + qiskit_gate_indices = [ + qiskit_ordering(indices) for indices in gate_indices.values() + ] if include_barriers: qc.barrier() @@ -194,18 +217,21 @@ def circuit_from_step(angle, H_indices, S_indices, CNOT_indices, RZ_index): if include_barriers: qc.barrier() - for i in basis_change_indices['Y_indices']: + for i in basis_change_indices["Y_indices"]: qc.s(qiskit_ordering(i)) - for i in basis_change_indices['X_indices']: + for i in basis_change_indices["X_indices"]: qc.h(qiskit_ordering(i)) - + return qc -def get_CNOT_connectivity_graph(evolution_obj: Union[PauliwordOp, QuantumCircuit], print_graph=False): - """ + +def get_CNOT_connectivity_graph( + evolution_obj: Union[PauliwordOp, QuantumCircuit], print_graph=False +): + """ Get the graph whoss edges denote nonlocal interaction between two qubits. This is useful for device-aware ansatz construction to ensure the circuit connectiviy - may be accomodated by the topology of the target quantum processor. + may be accomodated by the topology of the target quantum processor. Args: evolution_obj (Union[PauliwordOp, QuantumCircuit]): Evolution Object @@ -217,10 +243,14 @@ def get_CNOT_connectivity_graph(evolution_obj: Union[PauliwordOp, QuantumCircuit assert isinstance(evolution_obj, QuantumCircuit) qc = evolution_obj nodes = [q.index for q in qc.qregs[0]] - edges = [[q.index for q in step[1]] for step in qc.data if step[0].name!='barrier' and len(step[1])>1] + edges = [ + [q.index for q in step[1]] + for step in qc.data + if step[0].name != "barrier" and len(step[1]) > 1 + ] G = nx.Graph() G.add_nodes_from(nodes) G.add_edges_from(edges) if print_graph: nx.draw_kamada_kawai(G) - return G \ No newline at end of file + return G diff --git a/symmer/evolution/exponentiation.py b/symmer/evolution/exponentiation.py index 4d39610..ef10ed2 100644 --- a/symmer/evolution/exponentiation.py +++ b/symmer/evolution/exponentiation.py @@ -3,6 +3,7 @@ from functools import reduce from symmer.operators import PauliwordOp + def exponentiate_single_Pop(P: PauliwordOp) -> PauliwordOp: """ Exponentiate a single Pauli term as e^{P} @@ -14,18 +15,18 @@ def exponentiate_single_Pop(P: PauliwordOp) -> PauliwordOp: Returns: exp_P (PauliwordOp): PauliwordOp representation of exponentiated operator """ - assert(P.n_terms == 1), 'Can only exponentiate single Pauli terms' + assert P.n_terms == 1, "Can only exponentiate single Pauli terms" P_copy = P.copy() P_copy.coeff_vec[0] = 1 - exp_P = ( - (P_copy**0).multiply_by_constant(np.cosh(P.coeff_vec[0])) + - (P_copy**1).multiply_by_constant(np.sinh(P.coeff_vec[0])) - ) + exp_P = (P_copy**0).multiply_by_constant(np.cosh(P.coeff_vec[0])) + ( + P_copy**1 + ).multiply_by_constant(np.sinh(P.coeff_vec[0])) return exp_P -def trotter(op:PauliwordOp, trotnum:int=1) -> PauliwordOp: - """ - Computes the exponential exp(op). This is exact only when + +def trotter(op: PauliwordOp, trotnum: int = 1) -> PauliwordOp: + """ + Computes the exponential exp(op). This is exact only when op is fully commuting, otherwise approximates the exponential and increasing trotnum will improve precision. @@ -33,9 +34,10 @@ def trotter(op:PauliwordOp, trotnum:int=1) -> PauliwordOp: op (PauliwordOp): Pauli operator to exponentiate tortnum (int): Increasing trotnum will improve precision when exact exponential is not computed. By default, it is set to 1. """ - op_copy = op.copy().multiply_by_constant(1/trotnum) - factors = [exponentiate_single_Pop(P) for P in op_copy]*trotnum - return reduce(lambda x,y:x*y, factors) + op_copy = op.copy().multiply_by_constant(1 / trotnum) + factors = [exponentiate_single_Pop(P) for P in op_copy] * trotnum + return reduce(lambda x, y: x * y, factors) + -def truncated_exponential(op:PauliwordOp, truncate_at:int=10) -> PauliwordOp: - raise NotImplementedError \ No newline at end of file +def truncated_exponential(op: PauliwordOp, truncate_at: int = 10) -> PauliwordOp: + raise NotImplementedError diff --git a/symmer/evolution/gate_library.py b/symmer/evolution/gate_library.py index b6c91df..a3a20c9 100644 --- a/symmer/evolution/gate_library.py +++ b/symmer/evolution/gate_library.py @@ -6,7 +6,8 @@ # Gate library decomposed into PauliwordOps # ############################################# -def I(n_qubits:int) -> PauliwordOp: + +def I(n_qubits: int) -> PauliwordOp: """ Identity gate @@ -16,9 +17,10 @@ def I(n_qubits:int) -> PauliwordOp: Returns: PauliwordOp representing the identity operation ('I') applied to a system of 'n_qubits'. """ - return PauliwordOp.from_dictionary({'I'*n_qubits:1}) + return PauliwordOp.from_dictionary({"I" * n_qubits: 1}) + -def X(n_qubits:int, index:int) -> PauliwordOp: +def X(n_qubits: int, index: int) -> PauliwordOp: """ Pauli X gate @@ -29,10 +31,12 @@ def X(n_qubits:int, index:int) -> PauliwordOp: Returns: PauliwordOp representing the Pauli 'X' operator applied to the specified qubit index while leaving the other qubits unchanged. """ - X_str = ['I']*n_qubits; X_str[index] = 'X' - return PauliwordOp.from_dictionary({''.join(X_str):1}) + X_str = ["I"] * n_qubits + X_str[index] = "X" + return PauliwordOp.from_dictionary({"".join(X_str): 1}) + -def Y(n_qubits:int, index:int) -> PauliwordOp: +def Y(n_qubits: int, index: int) -> PauliwordOp: """ Pauli Y gate @@ -43,10 +47,12 @@ def Y(n_qubits:int, index:int) -> PauliwordOp: Returns: PauliwordOp representing the Pauli 'Y' operator applied to the specified qubit index while leaving the other qubits unchanged. """ - Y_str = ['I']*n_qubits; Y_str[index] = 'Y' - return PauliwordOp.from_dictionary({''.join(Y_str):1}) + Y_str = ["I"] * n_qubits + Y_str[index] = "Y" + return PauliwordOp.from_dictionary({"".join(Y_str): 1}) -def Z(n_qubits:int, index:int) -> PauliwordOp: + +def Z(n_qubits: int, index: int) -> PauliwordOp: """ Pauli Z gate @@ -57,11 +63,13 @@ def Z(n_qubits:int, index:int) -> PauliwordOp: Returns: PauliwordOp representing the Pauli 'Z' operator applied to the specified qubit index while leaving the other qubits unchanged. """ - Z_str = ['I']*n_qubits; Z_str[index] = 'Z' - return PauliwordOp.from_dictionary({''.join(Z_str):1}) + Z_str = ["I"] * n_qubits + Z_str[index] = "Z" + return PauliwordOp.from_dictionary({"".join(Z_str): 1}) + -def Had(n_qubits:int, index:int) -> PauliwordOp: - """ +def Had(n_qubits: int, index: int) -> PauliwordOp: + """ Hadamard gate Args: @@ -71,13 +79,13 @@ def Had(n_qubits:int, index:int) -> PauliwordOp: Returns: PauliwordOp representing the 'H' operator applied to the specified qubit index while leaving the other qubits unchanged. """ - return ( - Z(n_qubits, index).multiply_by_constant(1/np.sqrt(2))+ - X(n_qubits, index).multiply_by_constant(1/np.sqrt(2)) - ) + return Z(n_qubits, index).multiply_by_constant(1 / np.sqrt(2)) + X( + n_qubits, index + ).multiply_by_constant(1 / np.sqrt(2)) + -def CZ(n_qubits:int, control:int, target:int) -> PauliwordOp: - """ +def CZ(n_qubits: int, control: int, target: int) -> PauliwordOp: + """ Controlled Z gate Args: @@ -91,13 +99,16 @@ def CZ(n_qubits:int, control:int, target:int) -> PauliwordOp: ZI = Z(n_qubits, control) IZ = Z(n_qubits, target) ZZ = ZI * IZ - - CZ_exp = (ZZ - IZ - ZI).multiply_by_constant(np.pi/4) - CZ = trotter(CZ_exp.multiply_by_constant(1j), trotnum=1).multiply_by_constant(np.sqrt(1j)) + + CZ_exp = (ZZ - IZ - ZI).multiply_by_constant(np.pi / 4) + CZ = trotter(CZ_exp.multiply_by_constant(1j), trotnum=1).multiply_by_constant( + np.sqrt(1j) + ) return CZ -def CX(n_qubits:int, control:int, target:int) -> PauliwordOp: - """ + +def CX(n_qubits: int, control: int, target: int) -> PauliwordOp: + """ Controlled X gate Args: @@ -111,8 +122,9 @@ def CX(n_qubits:int, control:int, target:int) -> PauliwordOp: _Had = Had(n_qubits, target) return _Had * CZ(n_qubits, control, target) * _Had -def RX(n_qubits:int, index:int, angle:float) -> PauliwordOp: - """ + +def RX(n_qubits: int, index: int, angle: float) -> PauliwordOp: + """ Rotation-X gate Args: @@ -123,10 +135,11 @@ def RX(n_qubits:int, index:int, angle:float) -> PauliwordOp: Returns: PauliwordOp representing the rotation around the X-axis (RX) gate by the specified angle applied to a specific qubit in a system of 'n_qubits'. """ - return trotter(X(n_qubits, index).multiply_by_constant(1j*angle/2)) + return trotter(X(n_qubits, index).multiply_by_constant(1j * angle / 2)) + -def RY(n_qubits:int, index:int, angle:float) -> PauliwordOp: - """ +def RY(n_qubits: int, index: int, angle: float) -> PauliwordOp: + """ Rotation-Y gate Args: @@ -137,10 +150,11 @@ def RY(n_qubits:int, index:int, angle:float) -> PauliwordOp: Returns: PauliwordOp representing the rotation around the Y-axis (RY) gate by the specified angle applied to a specific qubit in a system of 'n_qubits'. """ - return trotter(Y(n_qubits, index).multiply_by_constant(1j*angle/2)) + return trotter(Y(n_qubits, index).multiply_by_constant(1j * angle / 2)) -def RZ(n_qubits:int, index:int, angle:float) -> PauliwordOp: - """ + +def RZ(n_qubits: int, index: int, angle: float) -> PauliwordOp: + """ Rotation-Z gate Args: @@ -151,10 +165,11 @@ def RZ(n_qubits:int, index:int, angle:float) -> PauliwordOp: Returns: PauliwordOp representing the rotation around the Z-axis (RZ) gate by the specified angle applied to a specific qubit in a system of 'n_qubits'. """ - return trotter(Z(n_qubits, index).multiply_by_constant(1j*angle/2)) + return trotter(Z(n_qubits, index).multiply_by_constant(1j * angle / 2)) + -def U1(n_qubits:int, index:int, angle:float) -> PauliwordOp: - """ +def U1(n_qubits: int, index: int, angle: float) -> PauliwordOp: + """ U1 gate Args: @@ -165,9 +180,10 @@ def U1(n_qubits:int, index:int, angle:float) -> PauliwordOp: Returns: PauliwordOp representing the U1 gate with phase 'angle' applied to a specific qubit in a system of 'n_qubits'. """ - return RZ(n_qubits, index, angle).multiply_by_constant(np.exp(1j*angle/2)) + return RZ(n_qubits, index, angle).multiply_by_constant(np.exp(1j * angle / 2)) + -def S(n_qubits:int, index:int) -> PauliwordOp: +def S(n_qubits: int, index: int) -> PauliwordOp: """ S gate @@ -178,4 +194,4 @@ def S(n_qubits:int, index:int) -> PauliwordOp: Returns: PauliwordOp representing the 'S' operator applied to the specified qubit index while leaving the other qubits unchanged. """ - return RZ(n_qubits,index,-np.pi/2).multiply_by_constant(np.sqrt(1j)) + return RZ(n_qubits, index, -np.pi / 2).multiply_by_constant(np.sqrt(1j)) diff --git a/symmer/evolution/variational_optimization.py b/symmer/evolution/variational_optimization.py index 4333b34..688cd49 100644 --- a/symmer/evolution/variational_optimization.py +++ b/symmer/evolution/variational_optimization.py @@ -3,7 +3,9 @@ from qiskit import QuantumCircuit from symmer import QuantumState, PauliwordOp from symmer.operators.utils import ( - symplectic_to_string, safe_PauliwordOp_to_dict, safe_QuantumState_to_dict + symplectic_to_string, + safe_PauliwordOp_to_dict, + safe_QuantumState_to_dict, ) from symmer.evolution import PauliwordOp_to_QuantumCircuit, get_CNOT_connectivity_graph from networkx.algorithms.cycles import cycle_basis @@ -13,6 +15,7 @@ import multiprocessing as mp from typing import * + class VQE_Driver: """ expectation value method one of the following choices: @@ -21,21 +24,23 @@ class VQE_Driver: - observable_rotation: implements the circuit as rotations applied to the observable - sparse_array: direct calcaultion by converting observable/state to sparse array - dense_array: direct calcaultion by converting observable/state to dense array - + Attributes: expectation_eval (str): expectation value method. Its default value is 'symbolic_direct'. verbose (bool): If True, prints out useful information during computation. By default it is set to 'True'. """ - expectation_eval = 'symbolic_direct' + + expectation_eval = "symbolic_direct" # prints out useful information during computation: verbose = True - - def __init__(self, + + def __init__( + self, observable: PauliwordOp, ansatz_circuit: QuantumCircuit = None, excitation_ops: PauliwordOp = None, - ref_state: QuantumState = None - ) -> None: + ref_state: QuantumState = None, + ) -> None: """ Args: observable (PauliwordOp): Observables @@ -46,15 +51,15 @@ def __init__(self, self.observable = observable self.ref_state = ref_state # observables must have real coefficients over the Pauli group: - assert np.all(self.observable.coeff_vec.imag == 0), 'Observable not Hermitian' - + assert np.all(self.observable.coeff_vec.imag == 0), "Observable not Hermitian" + if excitation_ops is not None: self.prepare_for_evolution(excitation_ops) else: self.circuit = ansatz_circuit def prepare_for_evolution(self, excitation_ops: PauliwordOp) -> None: - """ + """ Save the excitation generators and construct corresponding ansatz circuit. Args: @@ -64,14 +69,15 @@ def prepare_for_evolution(self, excitation_ops: PauliwordOp) -> None: excitation_ops.symp_matrix, np.ones(excitation_ops.n_terms) ) self.circuit = PauliwordOp_to_QuantumCircuit( - PwordOp=self.excitation_generators, ref_state=self.ref_state, bind_params=False + PwordOp=self.excitation_generators, + ref_state=self.ref_state, + bind_params=False, ) - def get_state(self, - evolution_obj: Union[QuantumCircuit, PauliwordOp], - x: np.array - ) -> Union[np.array, QuantumState, List[Tuple[PauliwordOp, float]]]: - """ + def get_state( + self, evolution_obj: Union[QuantumCircuit, PauliwordOp], x: np.array + ) -> Union[np.array, QuantumState, List[Tuple[PauliwordOp, float]]]: + """ Args: evolution_obj (Union[QuantumCircuit, PauliwordOp]): Evoluation object is either a Quantum Circuit (QuantumCircuit) or a Excitation Generating Set(PauliwordOp). @@ -81,22 +87,23 @@ def get_state(self, - Quantum State (QuantumState) representation of the QuantumCircuit (for symbolic methods). - Rotations of the form [(generator, angle)] for the observable_rotation expectation_eval method. """ - if self.expectation_eval == 'observable_rotation': - return list(zip(evolution_obj, -2*x)) + if self.expectation_eval == "observable_rotation": + return list(zip(evolution_obj, -2 * x)) else: state = CircuitStateFn(evolution_obj.bind_parameters(x)) - if self.expectation_eval == 'dense_array': - return state.to_matrix().reshape([-1,1]) - elif self.expectation_eval == 'sparse_array': - return state.to_spmatrix().reshape([-1,1]) - elif self.expectation_eval.find('symbolic') != -1: - return QuantumState.from_array(state.to_matrix().reshape([-1,1])) - - def _f(self, - observable: PauliwordOp, - state: Union[np.array, QuantumState, List[Tuple[PauliwordOp, float]]] - ) -> float: - """ + if self.expectation_eval == "dense_array": + return state.to_matrix().reshape([-1, 1]) + elif self.expectation_eval == "sparse_array": + return state.to_spmatrix().reshape([-1, 1]) + elif self.expectation_eval.find("symbolic") != -1: + return QuantumState.from_array(state.to_matrix().reshape([-1, 1])) + + def _f( + self, + observable: PauliwordOp, + state: Union[np.array, QuantumState, List[Tuple[PauliwordOp, float]]], + ) -> float: + """ Given an observable and state in the relevant form for the expectation value method, calculate the expectation value and return. @@ -106,23 +113,31 @@ def _f(self, - Array (np.array) of the QuantumCircuit (for sparse/dense array methods). - Quantum State (QuantumState) representation of the QuantumCircuit (for symbolic methods). - Rotations of the form [(generator, angle)] for the observable_rotation expectation_eval method. - + Returns: Expectation Value (float) """ - if self.expectation_eval == 'dense_array': - return (state.conjugate().T @ observable.to_sparse_matrix.toarray() @ state)[0,0].real - elif self.expectation_eval == 'sparse_array': - return (state.conjugate().T @ observable.to_sparse_matrix @ state)[0,0].real - elif self.expectation_eval == 'symbolic_projector': + if self.expectation_eval == "dense_array": + return ( + state.conjugate().T @ observable.to_sparse_matrix.toarray() @ state + )[0, 0].real + elif self.expectation_eval == "sparse_array": + return (state.conjugate().T @ observable.to_sparse_matrix @ state)[ + 0, 0 + ].real + elif self.expectation_eval == "symbolic_projector": return observable.expval(state).real - elif self.expectation_eval == 'symbolic_direct': - return (state.dagger * observable * state).real - elif self.expectation_eval == 'observable_rotation': - return (self.ref_state.dagger * observable.perform_rotations(state) * self.ref_state).real - + elif self.expectation_eval == "symbolic_direct": + return (state.dagger * observable * state).real + elif self.expectation_eval == "observable_rotation": + return ( + self.ref_state.dagger + * observable.perform_rotations(state) + * self.ref_state + ).real + def f(self, x: np.array) -> float: - """ + """ Given a parameter vector, bind to the circuit and retrieve expectation value. Args: @@ -131,66 +146,72 @@ def f(self, x: np.array) -> float: Returns: Expectation Value (float) """ - if self.expectation_eval == 'observable_rotation': + if self.expectation_eval == "observable_rotation": state = self.get_state(self.excitation_generators, x) else: state = self.get_state(self.circuit, x) return self._f(self.observable, state) - + def partial_derivative(self, x: np.array, param_index: int) -> float: - """ + """ Get the partial derivative with respect to an ansatz parameter by the parameter shift rule. Args: x (np.array): Parameter vector param_index (int): Prarameter index - + Returns: Partial derivative(float) with respect to an ansatz parameter. """ - x_upper = x.copy(); x_upper[param_index]+=np.pi/4 - x_lower = x.copy(); x_lower[param_index]-=np.pi/4 + x_upper = x.copy() + x_upper[param_index] += np.pi / 4 + x_lower = x.copy() + x_lower[param_index] -= np.pi / 4 return self.f(x_upper) - self.f(x_lower) - + def gradient(self, x: np.array) -> np.array: - """ + """ Get the ansatz parameter gradient, i.e. the vector of partial derivatives. Args: x (np.array): Parameter vector - + Returns: Ansatz parameter gradient (np.array) """ - if self.expectation_eval.find('projector') == -1: + if self.expectation_eval.find("projector") == -1: with mp.Pool(mp.cpu_count()) as pool: grad_vec = pool.starmap( - self.partial_derivative, - [(x, i) for i in range(self.circuit.num_parameters)] + self.partial_derivative, + [(x, i) for i in range(self.circuit.num_parameters)], ) else: - grad_vec = [self.partial_derivative(x, i) for i in range(self.circuit.num_parameters)] - + grad_vec = [ + self.partial_derivative(x, i) + for i in range(self.circuit.num_parameters) + ] + return np.asarray(grad_vec) - - def run(self, x0:np.array=None, **kwargs): - """ + + def run(self, x0: np.array = None, **kwargs): + """ Run the VQE routine. - + Args: x0 (np.array): Parameter vector """ if x0 is None: x0 = np.random.random(self.circuit.num_parameters) - - vqe_history = {'params':{}, 'energy':{}, 'gradient':{}} - # set up a counter to keep track of optimization steps this is important - # as some optimizers do not compute gradients at each optimization step and + vqe_history = {"params": {}, "energy": {}, "gradient": {}} + + # set up a counter to keep track of optimization steps this is important + # as some optimizers do not compute gradients at each optimization step and # therefore must be labeled to match with the correct iteration later on global counter counter = -1 + def get_counter(increment=True): global counter if increment: @@ -198,36 +219,35 @@ def get_counter(increment=True): return counter # wrap VQE_Driver.f() for the optimizer and store the interim values - def fun(x): + def fun(x): counter = get_counter(increment=True) - energy = self.f(x) - vqe_history['params'][counter] = tuple(x) - vqe_history['energy'][counter] = energy + energy = self.f(x) + vqe_history["params"][counter] = tuple(x) + vqe_history["energy"][counter] = energy if self.verbose: - print(f'Optimization step {counter: <2}:\n\t Energy = {energy}') + print(f"Optimization step {counter: <2}:\n\t Energy = {energy}") return energy # wrap VQE_Driver.gradient() for the optimizer and store the interim values def jac(x): counter = get_counter(increment=False) - grad = self.gradient(x) - vqe_history['gradient'][counter] = tuple(grad) + grad = self.gradient(x) + vqe_history["gradient"][counter] = tuple(grad) if self.verbose: - print(f'\t |∆| = {np.linalg.norm(grad)}') + print(f"\t |∆| = {np.linalg.norm(grad)}") return grad - + if self.verbose: - print('VQE simulation commencing...\n') - opt_out = minimize( - fun=fun, jac=jac, x0=x0, **kwargs - ) + print("VQE simulation commencing...\n") + opt_out = minimize(fun=fun, jac=jac, x0=x0, **kwargs) return serialize_opt_data(opt_out), vqe_history + class ADAPT_VQE(VQE_Driver): - """ - Performs qubit-ADAPT-VQE (https://doi.org/10.1103/PRXQuantum.2.020310), a - variant of ADAPT-VQE (https://doi.org/10.1038/s41467-019-10988-2) that takes - its excitation pool as Pauli operators (mapped via some transformation such + """ + Performs qubit-ADAPT-VQE (https://doi.org/10.1103/PRXQuantum.2.020310), a + variant of ADAPT-VQE (https://doi.org/10.1038/s41467-019-10988-2) that takes + its excitation pool as Pauli operators (mapped via some transformation such as Jordan-Wigner) instead of the originating fermionic operators. Attributes: @@ -236,22 +256,24 @@ class ADAPT_VQE(VQE_Driver): linearity_biased (bool): If True, linearity-biased-ADAPT-VQE is performed. By default it is set to True. bias (float): Bias value used in linearity-biased-ADAPT-VQE. It's default value is 1/3. """ + # method by which to calculate the operator pool derivatives, either # commutators: compute the commutator of the observable with each pool element # param_shift: use the parameter shift rule, requiring two expectation values per derivative - derivative_eval = 'commutators' + derivative_eval = "commutators" # we have alost implemented TETRIS-ADAPT-VQE as per https://doi.org/10.48550/arXiv.2209.10562 # that aims to reduce circuit-depth in the ADAPT routine by adding multiple excitation terms # per cycle that are supported on distinct qubit positions. TETRIS = False linearity_biased = True - bias = 1/3 - - def __init__(self, + bias = 1 / 3 + + def __init__( + self, observable: PauliwordOp, excitation_pool: PauliwordOp = None, - ref_state: QuantumState = None - ) -> None: + ref_state: QuantumState = None, + ) -> None: """ Args: observable (PauliwordOp): Observable @@ -259,20 +281,20 @@ def __init__(self, ref_state (QuantumState): Reference State. By default, it's set to 'None'. """ super().__init__( - observable = observable, - excitation_ops = PauliwordOp.empty(observable.n_qubits), - ref_state = ref_state + observable=observable, + excitation_ops=PauliwordOp.empty(observable.n_qubits), + ref_state=ref_state, ) self.excitation_pool = PauliwordOp( excitation_pool.symp_matrix, np.ones(excitation_pool.n_terms) ) self.adapt_operator = PauliwordOp.empty(observable.n_qubits) self.opt_parameters = [] - self.current_state = None - + self.current_state = None + @cached_property def commutators(self) -> List[PauliwordOp]: - """ + """ List of commutators [H, P] where P is some operator pool element. Returns: @@ -280,10 +302,10 @@ def commutators(self) -> List[PauliwordOp]: """ with mp.Pool(mp.cpu_count()) as pool: commutators = pool.map(self.observable.commutator, self.excitation_pool) - return list(map(lambda x:x*1j, commutators)) - + return list(map(lambda x: x * 1j, commutators)) + def _derivative_from_commutators(self, index: int) -> float: - """ + """ Calculate derivative using the commutator method. Args: @@ -293,10 +315,10 @@ def _derivative_from_commutators(self, index: int) -> float: Derivative (float) using the commutator method. """ assert self.current_state is not None - return self._f(observable=self.commutators[index], state=self.current_state) - + return self._f(observable=self.commutators[index], state=self.current_state) + def _derivative_from_param_shift(self, index): - """ + """ Calculate the derivative using the parameter shift rule. Args: @@ -307,13 +329,20 @@ def _derivative_from_param_shift(self, index): """ adapt_op_temp = self.adapt_operator.append(self.excitation_pool[index]) circuit_temp = PauliwordOp_to_QuantumCircuit( - PwordOp=adapt_op_temp, ref_state=self.ref_state, bind_params=False) - upper_state = self.get_state(circuit_temp, np.append(self.opt_parameters, +np.pi/4)) - lower_state = self.get_state(circuit_temp, np.append(self.opt_parameters, -np.pi/4)) - return self._f(self.observable,upper_state) - self._f(self.observable,lower_state) + PwordOp=adapt_op_temp, ref_state=self.ref_state, bind_params=False + ) + upper_state = self.get_state( + circuit_temp, np.append(self.opt_parameters, +np.pi / 4) + ) + lower_state = self.get_state( + circuit_temp, np.append(self.opt_parameters, -np.pi / 4) + ) + return self._f(self.observable, upper_state) - self._f( + self.observable, lower_state + ) def pool_gradient(self): - """ + """ Get the operator pool gradient by calculating the derivative with respect to each element of the pool. This is parallelized for all but the symbolic_projector expectation value calculation method as that is already multiprocessed and therefore @@ -322,33 +351,55 @@ def pool_gradient(self): Returns: Operator pool gradient (np.array) """ - if self.derivative_eval == 'commutators': - self.commutators # to ensure this has been cached, else nested daemonic process occurs - if self.expectation_eval == 'observable_rotation': - self.current_state = self.get_state(self.adapt_operator, self.opt_parameters) + if self.derivative_eval == "commutators": + self.commutators # to ensure this has been cached, else nested daemonic process occurs + if self.expectation_eval == "observable_rotation": + self.current_state = self.get_state( + self.adapt_operator, self.opt_parameters + ) else: circuit_temp = PauliwordOp_to_QuantumCircuit( - PwordOp=self.adapt_operator, ref_state=self.ref_state, bind_params=False) + PwordOp=self.adapt_operator, + ref_state=self.ref_state, + bind_params=False, + ) self.current_state = self.get_state(circuit_temp, self.opt_parameters) - if self.expectation_eval in ['sparse_array', 'symbolic_direct', 'observable_rotation']: + if self.expectation_eval in [ + "sparse_array", + "symbolic_direct", + "observable_rotation", + ]: # the commutator method may be parallelized since the state is constant with mp.Pool(mp.cpu_count()) as pool: - gradient = pool.map(self._derivative_from_commutators, range(self.excitation_pool.n_terms)) + gradient = pool.map( + self._derivative_from_commutators, + range(self.excitation_pool.n_terms), + ) else: # ... unless using symbolic_projector since this is multiprocessed - gradient = list(map(self._derivative_from_commutators, range(self.excitation_pool.n_terms))) - - elif self.derivative_eval == 'param_shift': - # not parallelizable due the CircuitStateFn already using multiprocessing! - gradient = list(map(self._derivative_from_param_shift, range(self.excitation_pool.n_terms))) - + gradient = list( + map( + self._derivative_from_commutators, + range(self.excitation_pool.n_terms), + ) + ) + + elif self.derivative_eval == "param_shift": + # not parallelizable due the CircuitStateFn already using multiprocessing! + gradient = list( + map( + self._derivative_from_param_shift, + range(self.excitation_pool.n_terms), + ) + ) + else: - raise ValueError('Unrecognised derivative_eval method') - + raise ValueError("Unrecognised derivative_eval method") + return np.asarray(gradient) - + def pool_score(self): - """ + """ Score the operator pool with respect to gradients and circuit linearity. """ scores = abs(self.pool_gradient()) @@ -359,21 +410,25 @@ def pool_score(self): for index in range(self.excitation_pool.n_terms): adapt_op_temp = self.adapt_operator.append(self.excitation_pool[index]) circuit_temp = PauliwordOp_to_QuantumCircuit( - PwordOp=adapt_op_temp, ref_state=self.ref_state, bind_params=False) + PwordOp=adapt_op_temp, ref_state=self.ref_state, bind_params=False + ) connectivity = get_CNOT_connectivity_graph(circuit_temp) # the presence of cycles in the CNOT connectivity graph is penalised in the score # linear circuits result in a linearity of 1, hence their score is not affected here. linearity_scores.append( ( - circuit_temp.num_qubits - len([a for b in cycle_basis(connectivity) for a in b])*self.bias - ) / circuit_temp.num_qubits + circuit_temp.num_qubits + - len([a for b in cycle_basis(connectivity) for a in b]) + * self.bias + ) + / circuit_temp.num_qubits ) scores *= np.array(linearity_scores) - + return scores - + def append_to_adapt_operator(self, excitations_to_append: List[PauliwordOp]): - """ + """ Append the input term(s) to the expanding adapt_operator. """ for excitation in excitations_to_append: @@ -381,12 +436,16 @@ def append_to_adapt_operator(self, excitations_to_append: List[PauliwordOp]): self.adapt_operator += excitation else: self.adapt_operator = self.adapt_operator.append(excitation) - - def optimize(self, - max_cycles:int=10, gtol:float=1e-3, atol:float=1e-10, - target:float=0, target_error:float=1e-3 - ): - """ + + def optimize( + self, + max_cycles: int = 10, + gtol: float = 1e-3, + atol: float = 1e-10, + target: float = 0, + target_error: float = 1e-3, + ): + """ Perform the ADAPT-VQE optimization Args: @@ -394,18 +453,20 @@ def optimize(self, atol: if the difference between successive expectation values is below this threshold, terminate max_cycles: maximum number of ADAPT cycles to perform target: if a target energy is known, this may be specified here - target_error: the absoluate error threshold with respect to the target energy - """ - interim_data = {'history':[]} - adapt_cycle=1 - gmax=1 - anew=1 - aold=0 - + target_error: the absoluate error threshold with respect to the target energy + """ + interim_data = {"history": []} + adapt_cycle = 1 + gmax = 1 + anew = 1 + aold = 0 + while ( - gmax>gtol and adapt_cycle<=max_cycles and - abs(anew-aold)>atol and abs(anew-target)>target_error - ): + gmax > gtol + and adapt_cycle <= max_cycles + and abs(anew - aold) > atol + and abs(anew - target) > target_error + ): # save the previous gmax to compare for the gdiff check aold = deepcopy(anew) # calculate gradient across the pool and select term with the largest derivative @@ -419,54 +480,71 @@ def optimize(self, support_mask = np.zeros(self.observable.n_qubits, dtype=bool) for i in grad_rank: new_excitation = self.excitation_pool[i] - support_exists = (new_excitation.X_block | new_excitation.Z_block) & support_mask + support_exists = ( + new_excitation.X_block | new_excitation.Z_block + ) & support_mask if ~np.any(support_exists): new_excitation_list.append(new_excitation) - support_mask = support_mask | (new_excitation.X_block | new_excitation.Z_block) + support_mask = support_mask | ( + new_excitation.X_block | new_excitation.Z_block + ) if np.all(support_mask) or scores[i] < gtol: break else: new_excitation_list = [self.excitation_pool[grad_rank[0]]] - + # append new term(s) to the adapt_operator that stores our ansatz as it expands n_new_terms = len(new_excitation_list) self.append_to_adapt_operator(new_excitation_list) - + if self.verbose: - print('-'*39) - print(f'ADAPT cycle {adapt_cycle}\n') - print(f'Largest pool derivative ∂P∂θ = {gmax: .5f}\n') - print('Selected excitation generator(s):\n') + print("-" * 39) + print(f"ADAPT cycle {adapt_cycle}\n") + print(f"Largest pool derivative ∂P∂θ = {gmax: .5f}\n") + print("Selected excitation generator(s):\n") for op in new_excitation_list: - print(f'\t{symplectic_to_string(op.symp_matrix[0])}') - print('\n', '-'*39) - + print(f"\t{symplectic_to_string(op.symp_matrix[0])}") + print("\n", "-" * 39) + # having selected a new term to append to the ansatz, reoptimize with VQE self.prepare_for_evolution(self.adapt_operator) opt_out, vqe_hist = self.run( - x0=np.append(self.opt_parameters, [0]*n_new_terms), method='BFGS' + x0=np.append(self.opt_parameters, [0] * n_new_terms), method="BFGS" ) interim_data[adapt_cycle] = { - 'output':opt_out, 'history':vqe_hist, 'gmax':gmax, - 'excitation': [symplectic_to_string(t.symp_matrix[0]) for t in new_excitation_list] + "output": opt_out, + "history": vqe_hist, + "gmax": gmax, + "excitation": [ + symplectic_to_string(t.symp_matrix[0]) for t in new_excitation_list + ], } - anew = opt_out['fun'] - interim_data['history'].append(anew) + anew = opt_out["fun"] + interim_data["history"].append(anew) if self.verbose: - print(F'\nEnergy at ADAPT cycle {adapt_cycle}: {anew: .5f}\n') - self.opt_parameters = opt_out['x'] - adapt_cycle+=1 + print(f"\nEnergy at ADAPT cycle {adapt_cycle}: {anew: .5f}\n") + self.opt_parameters = opt_out["x"] + adapt_cycle += 1 return { - 'result': opt_out, - 'interim_data': interim_data, - 'ref_state': safe_QuantumState_to_dict(self.ref_state), - 'adapt_operator': [symplectic_to_string(t) for t in self.adapt_operator.symp_matrix] + "result": opt_out, + "interim_data": interim_data, + "ref_state": safe_QuantumState_to_dict(self.ref_state), + "adapt_operator": [ + symplectic_to_string(t) for t in self.adapt_operator.symp_matrix + ], } - + + def serialize_opt_data(opt_data): return { - 'message':opt_data.message, 'success':opt_data.success, 'status':opt_data.status, - 'fun':opt_data.fun, 'x':tuple(opt_data.x),'jac':tuple(opt_data.jac), - 'nit':opt_data.nit, 'nfev':opt_data.nfev,'njev':opt_data.njev, - } \ No newline at end of file + "message": opt_data.message, + "success": opt_data.success, + "status": opt_data.status, + "fun": opt_data.fun, + "x": tuple(opt_data.x), + "jac": tuple(opt_data.jac), + "nit": opt_data.nit, + "nfev": opt_data.nfev, + "njev": opt_data.njev, + } diff --git a/symmer/operators/anticommuting_op.py b/symmer/operators/anticommuting_op.py index fae497e..640a442 100644 --- a/symmer/operators/anticommuting_op.py +++ b/symmer/operators/anticommuting_op.py @@ -3,12 +3,11 @@ from typing import Dict, List, Optional, Tuple, Union import warnings -warnings.simplefilter('always', UserWarning) -class AntiCommutingOp(PauliwordOp): +warnings.simplefilter("always", UserWarning) + - def __init__(self, - AC_op_symp_matrix: np.array, - coeff_list: np.array): +class AntiCommutingOp(PauliwordOp): + def __init__(self, AC_op_symp_matrix: np.array, coeff_list: np.array): """ Args: AC_op_symp_matrix (np.array): The symmetric matrix representation of the anti-commuting operator. @@ -22,16 +21,17 @@ def __init__(self, # check all operators anticommute adj_mat = self.adjacency_matrix adj_mat[np.diag_indices_from(adj_mat)] = False - assert ~np.any(adj_mat), 'operator needs to be made of anti-commuting Pauli operators' + assert ~np.any( + adj_mat + ), "operator needs to be made of anti-commuting Pauli operators" self.X_sk_rotations = [] self.R_LCU = None @classmethod - def from_list(cls, - pauli_terms :List[str], - coeff_vec: List[complex] = None - ) -> "AntiCommutingOp": + def from_list( + cls, pauli_terms: List[str], coeff_vec: List[complex] = None + ) -> "AntiCommutingOp": """ Args: pauli_terms (List[str]): A list of Pauli terms represented as strings. @@ -45,10 +45,8 @@ def from_list(cls, return cls.from_PauliwordOp(PwordOp) @classmethod - def from_dictionary(cls, - operator_dict: Dict[str, complex] - ) -> "AntiCommutingOp": - """ + def from_dictionary(cls, operator_dict: Dict[str, complex]) -> "AntiCommutingOp": + """ Initialize a PauliwordOp from its dictionary representation {pauli:coeff, ...} Args: @@ -62,9 +60,7 @@ def from_dictionary(cls, return cls.from_PauliwordOp(PwordOp) @classmethod - def from_PauliwordOp(cls, - PwordOp: PauliwordOp - ) -> 'AntiCommutingOp': + def from_PauliwordOp(cls, PwordOp: PauliwordOp) -> "AntiCommutingOp": """ Args: PwordOp (PauliwordOp): The PauliwordOp instance to initialize the AntiCommutingOp from. @@ -74,7 +70,6 @@ def from_PauliwordOp(cls, """ return cls(PwordOp.symp_matrix, PwordOp.coeff_vec) - def get_least_dense_term_index(self): """ Takes the current symp_matrix of object and finds the index of the least dense Pauli @@ -90,16 +85,19 @@ def get_least_dense_term_index(self): # int_list = pos_terms_occur @ (1 << np.arange(pos_terms_occur.shape[1], dtype=object)[::-1]) # s_index = np.argmin(int_list) - pos_terms_occur = np.logical_or(self.symp_matrix[:, :self.n_qubits], self.symp_matrix[:, self.n_qubits:]) + pos_terms_occur = np.logical_or( + self.symp_matrix[:, : self.n_qubits], self.symp_matrix[:, self.n_qubits :] + ) symp_matrix_view = np.ascontiguousarray(pos_terms_occur).view( - np.dtype((np.void, pos_terms_occur.dtype.itemsize * pos_terms_occur.shape[1])) + np.dtype( + (np.void, pos_terms_occur.dtype.itemsize * pos_terms_occur.shape[1]) + ) ) sort_order = np.argsort(symp_matrix_view.ravel()) s_index = sort_order[0] return s_index - def _recursive_seq_rotations(self, AC_op: PauliwordOp) -> "PauliwordOp": """ Args: @@ -127,7 +125,9 @@ def _recursive_seq_rotations(self, AC_op: PauliwordOp) -> "PauliwordOp": theta_sk = theta_sk + np.pi # check - assert (np.isclose((β_k * np.cos(theta_sk) - β_s * np.sin(theta_sk)), 0)), 'term not zeroing out' + assert np.isclose( + (β_k * np.cos(theta_sk) - β_s * np.sin(theta_sk)), 0 + ), "term not zeroing out" # -X_sk = -1j * Ps @ Pk jP_k = PauliwordOp(op_for_rotation.symp_matrix[k_index], [-1j]) @@ -139,19 +139,27 @@ def _recursive_seq_rotations(self, AC_op: PauliwordOp) -> "PauliwordOp": self.X_sk_rotations.append((X_sk, theta_sk)) # update coeffs - op_for_rotation.coeff_vec[s_index] = np.sqrt(β_s ** 2 + β_k ** 2) + op_for_rotation.coeff_vec[s_index] = np.sqrt(β_s**2 + β_k**2) op_for_rotation.coeff_vec[k_index] = 0 # build op without k term and (included modified s term) - AC_op_rotated = PauliwordOp(np.delete(op_for_rotation.symp_matrix, k_index, axis=0), - np.delete(op_for_rotation.coeff_vec, k_index, axis=0)) + AC_op_rotated = PauliwordOp( + np.delete(op_for_rotation.symp_matrix, k_index, axis=0), + np.delete(op_for_rotation.coeff_vec, k_index, axis=0), + ) ## know how operator acts therefore don't need to actually do rotations return self._recursive_seq_rotations(AC_op_rotated) - def unitary_partitioning(self, s_index: int=None, up_method: Optional[str]='seq_rot') \ - -> Tuple[PauliwordOp, Union[PauliwordOp, List[Tuple[PauliwordOp, float]]], float, "AntiCommutingOp"]: + def unitary_partitioning( + self, s_index: int = None, up_method: Optional[str] = "seq_rot" + ) -> Tuple[ + PauliwordOp, + Union[PauliwordOp, List[Tuple[PauliwordOp, float]]], + float, + "AntiCommutingOp", + ]: """ Apply unitary partitioning on anticommuting operator (self) @@ -166,7 +174,10 @@ def unitary_partitioning(self, s_index: int=None, up_method: Optional[str]='seq_ gamma_l (float): normalization constant of clique (anticommuting operator) AC_op (AntiCommutingOp): normalized clique - i.e. self == gamma_l * AC_op """ - assert up_method in ['LCU', 'seq_rot'], f'unknown unitary partitioning method: {up_method}' + assert up_method in [ + "LCU", + "seq_rot", + ], f"unknown unitary partitioning method: {up_method}" AC_op = self.copy() if AC_op.n_terms == 1: @@ -178,7 +189,9 @@ def unitary_partitioning(self, s_index: int=None, up_method: Optional[str]='seq_ else: - assert np.isclose(np.sum(AC_op.coeff_vec.imag), 0), 'cannot apply unitary partitioning to operator with complex coeffs' + assert np.isclose( + np.sum(AC_op.coeff_vec.imag), 0 + ), "cannot apply unitary partitioning to operator with complex coeffs" gamma_l = np.linalg.norm(AC_op.coeff_vec) AC_op.coeff_vec = AC_op.coeff_vec / gamma_l @@ -186,33 +199,39 @@ def unitary_partitioning(self, s_index: int=None, up_method: Optional[str]='seq_ if s_index is None: s_index = self.get_least_dense_term_index() - if s_index!=0: + if s_index != 0: # re-order so s term is ALWAYS at top of symplectic matrix and thus is index as 0! ### assert s_index <= AC_op.n_terms-1, 's_index out of range' AC_op.coeff_vec[[0, s_index]] = AC_op.coeff_vec[[s_index, 0]] AC_op.symp_matrix[[0, s_index]] = AC_op.symp_matrix[[s_index, 0]] - AC_op = AntiCommutingOp(AC_op.symp_matrix, AC_op.coeff_vec) # need to reinit otherwise Z and X blocks wrong + AC_op = AntiCommutingOp( + AC_op.symp_matrix, AC_op.coeff_vec + ) # need to reinit otherwise Z and X blocks wrong # assert not np.isclose(AC_op.coeff_vec[0], 0), f's_index cannot have zero coefficent: {AC_op.coeff_vec[0]}' if np.isclose(AC_op[0].coeff_vec, 0): # need to correct for s_index having zero coeff... then need to swap to nonzero index non_zero_index = np.argmax(abs(AC_op.coeff_vec)) - AC_op.coeff_vec[[0, non_zero_index]] = AC_op.coeff_vec[[non_zero_index, 0]] - AC_op.symp_matrix[[0, non_zero_index]] = AC_op.symp_matrix[[non_zero_index, 0]] - - if up_method=='seq_rot': - if len(self.X_sk_rotations)!=0: + AC_op.coeff_vec[[0, non_zero_index]] = AC_op.coeff_vec[ + [non_zero_index, 0] + ] + AC_op.symp_matrix[[0, non_zero_index]] = AC_op.symp_matrix[ + [non_zero_index, 0] + ] + + if up_method == "seq_rot": + if len(self.X_sk_rotations) != 0: self.X_sk_rotations = [] Ps = self._recursive_seq_rotations(AC_op) rotations = self.X_sk_rotations - elif up_method=='LCU': + elif up_method == "LCU": if self.R_LCU is not None: self.R_LCU = None Ps = self.generate_LCU_operator(AC_op) rotations = self.R_LCU else: - raise ValueError(f'unknown unitary partitioning method: {up_method}!') + raise ValueError(f"unknown unitary partitioning method: {up_method}!") return Ps, rotations, gamma_l, AC_op @@ -238,13 +257,12 @@ def generate_LCU_operator(self, AC_op) -> PauliwordOp: # need to remove zero coeff terms AC_op_cpy = AC_op.copy() before_cleanup = AC_op_cpy.n_terms - AC_op = AC_op_cpy[np.where(abs(AC_op.coeff_vec)>1e-15)[0]] + AC_op = AC_op_cpy[np.where(abs(AC_op.coeff_vec) > 1e-15)[0]] post_cleanup = AC_op.n_terms # AC_op = AC_op.cleanup(zero_threshold=1e-15) ## cleanup re-orders which is BAD for s_index - - if (before_cleanup>1 and post_cleanup==1): - if AC_op.coeff_vec[0]<0: + if before_cleanup > 1 and post_cleanup == 1: + if AC_op.coeff_vec[0] < 0: # need to fix neg sign (use Pauli multiplication) # as s index defaults to 0, take the next term (in CS-VQE this will commute with symmetries)! @@ -252,19 +270,22 @@ def generate_LCU_operator(self, AC_op) -> PauliwordOp: # need to correct for s_index having zero coeff... then need to swap to nonzero index non_zero_index = np.argmax(abs(AC_op_cpy.coeff_vec)) - AC_op_cpy.coeff_vec[[0, non_zero_index]] = AC_op_cpy.coeff_vec[[non_zero_index, 0]] - AC_op_cpy.symp_matrix[[0, non_zero_index]] = AC_op_cpy.symp_matrix[[non_zero_index, 0]] - + AC_op_cpy.coeff_vec[[0, non_zero_index]] = AC_op_cpy.coeff_vec[ + [non_zero_index, 0] + ] + AC_op_cpy.symp_matrix[[0, non_zero_index]] = AC_op_cpy.symp_matrix[ + [non_zero_index, 0] + ] - sign_correction = PauliwordOp(AC_op_cpy.symp_matrix[1],[1]) + sign_correction = PauliwordOp(AC_op_cpy.symp_matrix[1], [1]) self.R_LCU = sign_correction Ps_LCU = PauliwordOp(AC_op.symp_matrix, [1]) else: - self.R_LCU = PauliwordOp.from_list(['I'*AC_op.n_qubits]) + self.R_LCU = PauliwordOp.from_list(["I" * AC_op.n_qubits]) Ps_LCU = PauliwordOp(AC_op.symp_matrix, AC_op.coeff_vec) else: - s_index=0 + s_index = 0 # note gamma_l norm applied on init! Ps_LCU = PauliwordOp(AC_op.symp_matrix[s_index], [1]) @@ -279,11 +300,11 @@ def generate_LCU_operator(self, AC_op) -> PauliwordOp: phi_n_1 = np.arccos(βs) # require sin(𝜙_{𝑛−1}) to be positive... - if (phi_n_1 > np.pi): + if phi_n_1 > np.pi: phi_n_1 = 2 * np.pi - phi_n_1 alpha = phi_n_1 - I_term = 'I' * Ps_LCU.n_qubits + I_term = "I" * Ps_LCU.n_qubits self.R_LCU = PauliwordOp.from_dictionary({I_term: np.cos(alpha / 2)}) sin_term = -np.sin(alpha / 2) @@ -294,6 +315,7 @@ def generate_LCU_operator(self, AC_op) -> PauliwordOp: return Ps_LCU + def LCU_as_seq_rot(AC_op: PauliwordOp, include_global_phase_correction=False): """ Convert a unitary composed of a @@ -327,8 +349,8 @@ def LCU_as_seq_rot(AC_op: PauliwordOp, include_global_phase_correction=False): print(check == rotations_LCU) """ - assert AC_op.n_terms > 1, 'AC_op must have more than 1 term' - assert np.isclose(np.linalg.norm(AC_op.coeff_vec), 1), 'AC_op must be l2 normalized' + assert AC_op.n_terms > 1, "AC_op must have more than 1 term" + assert np.isclose(np.linalg.norm(AC_op.coeff_vec), 1), "AC_op must be l2 normalized" expon_p_terms = [] @@ -336,7 +358,7 @@ def LCU_as_seq_rot(AC_op: PauliwordOp, include_global_phase_correction=False): coeff_vec = AC_op.coeff_vec.real + AC_op.coeff_vec.imag for k, c_k in enumerate(coeff_vec): P_k = AC_op[k] - theta_k = np.arcsin(c_k / np.linalg.norm(coeff_vec[:(k + 1)])) + theta_k = np.arcsin(c_k / np.linalg.norm(coeff_vec[: (k + 1)])) P_k.coeff_vec[0] = 1 expon_p_terms.append(tuple((P_k, theta_k))) @@ -354,7 +376,7 @@ def LCU_as_seq_rot(AC_op: PauliwordOp, include_global_phase_correction=False): if include_global_phase_correction: ## multiply by -1j Identity term! - phase_rot = (PauliwordOp.from_dictionary({'I' * AC_op.n_qubits: 1}), -np.pi) + phase_rot = (PauliwordOp.from_dictionary({"I" * AC_op.n_qubits: 1}), -np.pi) expon_p_terms.append(phase_rot) # check1 = reduce(lambda a,b: a*b, [exponentiate_single_Pop(x.multiply_by_constant(1j*y/2)) for x, y in expon_p_terms]) @@ -362,6 +384,7 @@ def LCU_as_seq_rot(AC_op: PauliwordOp, include_global_phase_correction=False): return expon_p_terms + # from symmer.operators.utils import mul_symplectic # def conjugate_Pop_with_R(Pop:PauliwordOp, # R: PauliwordOp) -> PauliwordOp: diff --git a/symmer/operators/base.py b/symmer/operators/base.py index 971069d..90b9b8d 100644 --- a/symmer/operators/base.py +++ b/symmer/operators/base.py @@ -20,31 +20,36 @@ from qiskit.opflow import PauliSumOp as ibm_PauliSumOp from scipy.stats import unitary_group import warnings -warnings.simplefilter('always', UserWarning) + +warnings.simplefilter("always", UserWarning) from numba.core.errors import NumbaDeprecationWarning, NumbaPendingDeprecationWarning -warnings.simplefilter('ignore', category=NumbaDeprecationWarning) -warnings.simplefilter('ignore', category=NumbaPendingDeprecationWarning) + +warnings.simplefilter("ignore", category=NumbaDeprecationWarning) +warnings.simplefilter("ignore", category=NumbaPendingDeprecationWarning) + class PauliwordOp: - """ + """ A class thats represents an operator defined over the Pauli group in the symplectic representation. Attributes: sigfig (int): The number of significant figures for printing. """ - sigfig = 3 # specifies the number of significant figures for printing - - def __init__(self, - symp_matrix: Union[List[str], Dict[str, float], np.array], - coeff_vec: Union[List[complex], np.array] - ) -> None: - """ - PauliwordOp may be initialized from either a dictionary in the form {pauli:coeff, ...}, - a list of Pauli strings or in the symplectic representation. In the latter two cases a - supplementary list of coefficients is also required, whereas this is inherent within the - dictionary representation. Operating on the level of the symplectic matrix is fastest - since it circumvents various conversions required - this is how the methods defined + + sigfig = 3 # specifies the number of significant figures for printing + + def __init__( + self, + symp_matrix: Union[List[str], Dict[str, float], np.array], + coeff_vec: Union[List[complex], np.array], + ) -> None: + """ + PauliwordOp may be initialized from either a dictionary in the form {pauli:coeff, ...}, + a list of Pauli strings or in the symplectic representation. In the latter two cases a + supplementary list of coefficients is also required, whereas this is inherent within the + dictionary representation. Operating on the level of the symplectic matrix is fastest + since it circumvents various conversions required - this is how the methods defined below function. Args: @@ -54,30 +59,39 @@ def __init__(self, symp_matrix = np.asarray(symp_matrix) if symp_matrix.dtype == int: # initialization is slow if not boolean array - assert(set(np.unique(symp_matrix)).issubset({0,1})), 'symplectic matrix not defined with 0 and 1 only' + assert set(np.unique(symp_matrix)).issubset( + {0, 1} + ), "symplectic matrix not defined with 0 and 1 only" symp_matrix = symp_matrix.astype(bool) - assert(symp_matrix.dtype == bool), 'Symplectic matrix must be defined over bools' - if len(symp_matrix.shape)==1: + assert symp_matrix.dtype == bool, "Symplectic matrix must be defined over bools" + if len(symp_matrix.shape) == 1: symp_matrix = symp_matrix.reshape([1, len(symp_matrix)]) self.symp_matrix = symp_matrix - assert self.symp_matrix.shape[-1]%2 == 0, 'symplectic matrix must have even number of columns' - assert len(self.symp_matrix.shape) == 2, 'symplectic matrix must be 2 dimensional only' - self.n_qubits = self.symp_matrix.shape[1]//2 + assert ( + self.symp_matrix.shape[-1] % 2 == 0 + ), "symplectic matrix must have even number of columns" + assert ( + len(self.symp_matrix.shape) == 2 + ), "symplectic matrix must be 2 dimensional only" + self.n_qubits = self.symp_matrix.shape[1] // 2 self.coeff_vec = np.asarray(coeff_vec, dtype=complex) self.n_terms = self.symp_matrix.shape[0] - assert(self.n_terms==len(self.coeff_vec)), 'coeff list and Pauliwords not same length' - self.X_block = self.symp_matrix[:, :self.n_qubits] - self.Z_block = self.symp_matrix[:, self.n_qubits:] - + assert self.n_terms == len( + self.coeff_vec + ), "coeff list and Pauliwords not same length" + self.X_block = self.symp_matrix[:, : self.n_qubits] + self.Z_block = self.symp_matrix[:, self.n_qubits :] + @classmethod - def random(cls, - n_qubits: int, - n_terms: int, - diagonal: bool = False, - complex_coeffs: bool = True, - density: float = 0.3 - ) -> "PauliwordOp": - """ + def random( + cls, + n_qubits: int, + n_terms: int, + diagonal: bool = False, + complex_coeffs: bool = True, + density: float = 0.3, + ) -> "PauliwordOp": + """ Generate a random PauliwordOp with normally distributed coefficients. Args: @@ -90,19 +104,22 @@ def random(cls, Returns: PauliwordOp: A random PauliwordOp object. """ - symp_matrix = random_symplectic_matrix(n_qubits, n_terms, diagonal, density=density) + symp_matrix = random_symplectic_matrix( + n_qubits, n_terms, diagonal, density=density + ) coeff_vec = np.random.randn(n_terms).astype(complex) if complex_coeffs: coeff_vec += 1j * np.random.randn(n_terms) return cls(symp_matrix, coeff_vec) @classmethod - def haar_random(cls, - n_qubits: int, - strategy: Optional[str] = 'projector', - disable_loading_bar: Optional[bool] = False - ) -> "PauliwordOp": - """ + def haar_random( + cls, + n_qubits: int, + strategy: Optional[str] = "projector", + disable_loading_bar: Optional[bool] = False, + ) -> "PauliwordOp": + """ Generate a Haar random U(N) matrix (N^n_qubits) as a linear combination of Pauli operators. aka generate a uniform random unitary from a Hilbert space. @@ -112,15 +129,16 @@ def haar_random(cls, p_random (PauliwordOp): Haar random matrix in Pauli basis """ haar_matrix = unitary_group.rvs(2**n_qubits) - p_random = cls.from_matrix(haar_matrix, strategy=strategy, disable_loading_bar=disable_loading_bar) + p_random = cls.from_matrix( + haar_matrix, strategy=strategy, disable_loading_bar=disable_loading_bar + ) return p_random @classmethod - def from_list(cls, - pauli_terms :List[str], - coeff_vec: List[complex] = None - ) -> "PauliwordOp": - """ + def from_list( + cls, pauli_terms: List[str], coeff_vec: List[complex] = None + ) -> "PauliwordOp": + """ Initialize a PauliwordOp from its Pauli terms and coefficients stored as lists. Args: @@ -134,12 +152,14 @@ def from_list(cls, coeff_vec = np.ones(n_rows) else: coeff_vec = np.array(coeff_vec) - if len(coeff_vec.shape)==2: - # if coeff_vec supplied as list of tuples (real, imag) + if len(coeff_vec.shape) == 2: + # if coeff_vec supplied as list of tuples (real, imag) # then converts to single complex vector - assert(coeff_vec.shape[1]==2), 'Only tuples of size two allowed (real and imaginary components)' - coeff_vec = coeff_vec[:,0] + 1j*coeff_vec[:,1] - + assert ( + coeff_vec.shape[1] == 2 + ), "Only tuples of size two allowed (real and imaginary components)" + coeff_vec = coeff_vec[:, 0] + 1j * coeff_vec[:, 1] + if pauli_terms: n_qubits = len(pauli_terms[0]) symp_matrix = np.zeros((n_rows, 2 * n_qubits), dtype=int) @@ -150,10 +170,8 @@ def from_list(cls, return cls(symp_matrix, coeff_vec) @classmethod - def from_dictionary(cls, - operator_dict: Dict[str, complex] - ) -> "PauliwordOp": - """ + def from_dictionary(cls, operator_dict: Dict[str, complex]) -> "PauliwordOp": + """ Initialize a PauliwordOp from its dictionary representation {pauli:coeff, ...} Args: @@ -167,11 +185,10 @@ def from_dictionary(cls, return cls.from_list(pauli_terms, coeff_vec) @classmethod - def from_openfermion(cls, - openfermion_op: QubitOperator, - n_qubits = None - ) -> "PauliwordOp": - """ + def from_openfermion( + cls, openfermion_op: QubitOperator, n_qubits=None + ) -> "PauliwordOp": + """ Initialize a PauliwordOp from OpenFermion's QubitOperator representation. Args: @@ -182,20 +199,16 @@ def from_openfermion(cls, Returns: PauliwordOp: A new PauliwordOp object. """ - assert(isinstance(openfermion_op, QubitOperator)), 'Must supply a QubitOperator' + assert isinstance(openfermion_op, QubitOperator), "Must supply a QubitOperator" if n_qubits is None: n_qubits = count_qubits(openfermion_op) - - operator_dict = QubitOperator_to_dict( - openfermion_op, n_qubits - ) + + operator_dict = QubitOperator_to_dict(openfermion_op, n_qubits) return cls.from_dictionary(operator_dict) @classmethod - def from_qiskit(cls, - qiskit_op: ibm_PauliSumOp - ) -> "PauliwordOp": - """ + def from_qiskit(cls, qiskit_op: ibm_PauliSumOp) -> "PauliwordOp": + """ Initialize a PauliwordOp from Qiskit's PauliSumOp representation. Args: @@ -204,17 +217,13 @@ def from_qiskit(cls, Returns: PauliwordOp: A new PauliwordOp object. """ - assert(isinstance(qiskit_op, ibm_PauliSumOp)), 'Must supply a PauliSumOp' - operator_dict = PauliSumOp_to_dict( - qiskit_op - ) + assert isinstance(qiskit_op, ibm_PauliSumOp), "Must supply a PauliSumOp" + operator_dict = PauliSumOp_to_dict(qiskit_op) return cls.from_dictionary(operator_dict) @classmethod - def empty(cls, - n_qubits: int - ) -> "PauliwordOp": - """ + def empty(cls, n_qubits: int) -> "PauliwordOp": + """ Initialize an empty PauliwordOp of the form 0 * I...I Args: @@ -223,15 +232,16 @@ def empty(cls, Returns: PauliwordOp: A new PauliwordOp object. """ - return cls.from_dictionary({'I'*n_qubits:0}) + return cls.from_dictionary({"I" * n_qubits: 0}) @classmethod - def _from_matrix_full_basis(cls, - matrix: Union[np.array, csr_matrix], - n_qubits: int, - operator_basis: "PauliwordOp" = None, - disable_loading_bar: Optional[bool] = False - ) -> "PauliwordOp": + def _from_matrix_full_basis( + cls, + matrix: Union[np.array, csr_matrix], + n_qubits: int, + operator_basis: "PauliwordOp" = None, + disable_loading_bar: Optional[bool] = False, + ) -> "PauliwordOp": """ Args: n_qubits (int): The number of qubits. @@ -244,15 +254,22 @@ def _from_matrix_full_basis(cls, if operator_basis is None: # fast method to build all binary assignments int_list = np.arange(4 ** (n_qubits)) - XZ_block = (((int_list[:, None] & (1 << np.arange(2 * n_qubits))[::-1])) > 0).astype(bool) + XZ_block = ( + ((int_list[:, None] & (1 << np.arange(2 * n_qubits))[::-1])) > 0 + ).astype(bool) op_basis = cls(XZ_block, np.ones(XZ_block.shape[0])) else: op_basis = operator_basis.copy().cleanup() op_basis.coeff_vec = np.ones(op_basis.coeff_vec.shape) - denominator = 2 ** n_qubits + denominator = 2**n_qubits coeffs = [] - for op in tqdm(op_basis, desc='Building operator via full basis', total=op_basis.n_terms, disable=disable_loading_bar): + for op in tqdm( + op_basis, + desc="Building operator via full basis", + total=op_basis.n_terms, + disable=disable_loading_bar, + ): coeffs.append((op.to_sparse_matrix.multiply(matrix)).sum() / denominator) ### fix ZX Y phases generated! @@ -260,7 +277,9 @@ def _from_matrix_full_basis(cls, op_basis.coeff_vec = np.array(coeffs) * ((op_basis.Y_count % 2 * -2) + 1) if operator_basis is not None: - warnings.warn('Basis supplied MAY not be sufficiently expressive, output operator projected onto basis supplied.') + warnings.warn( + "Basis supplied MAY not be sufficiently expressive, output operator projected onto basis supplied." + ) # if isinstance(matrix, csr_matrix): # tol=1e-15 # max_diff = np.abs(matrix - operator_out.to_sparse_matrix).max() @@ -274,11 +293,12 @@ def _from_matrix_full_basis(cls, return op_basis[op_basis.coeff_vec.nonzero()[0]] @classmethod - def _from_matrix_projector(cls, - matrix: Union[np.array, csr_matrix], - n_qubits: int, - disable_loading_bar: Optional[bool] = False - ) -> "PauliwordOp": + def _from_matrix_projector( + cls, + matrix: Union[np.array, csr_matrix], + n_qubits: int, + disable_loading_bar: Optional[bool] = False, + ) -> "PauliwordOp": """ Args: matrix (Union[np.array, csr_matrix]): The matrix to decompose. @@ -288,56 +308,93 @@ def _from_matrix_projector(cls, Returns: PauliwordOp: A new PauliwordOp object representing the decomposition of the matrix using projectors. """ - assert n_qubits <= 32, 'cannot decompose matrices above 32 qubits' + assert n_qubits <= 32, "cannot decompose matrices above 32 qubits" if isinstance(matrix, np.ndarray): row, col = np.where(matrix) elif isinstance(matrix, (csr_matrix, csc_matrix, coo_matrix)): row, col = matrix.nonzero() else: - raise ValueError('Unrecognised matrix type, must be one of np.array or sp.sparse.csr_matrix') + raise ValueError( + "Unrecognised matrix type, must be one of np.array or sp.sparse.csr_matrix" + ) - sym_operator = dok_matrix((4 ** n_qubits, 2 * n_qubits), - dtype=bool) + sym_operator = dok_matrix((4**n_qubits, 2 * n_qubits), dtype=bool) - coeff_operator = dok_matrix((4 ** n_qubits, 1), - dtype=complex) + coeff_operator = dok_matrix((4**n_qubits, 1), dtype=complex) binary_vec = ( - ( - np.arange(2 ** n_qubits).reshape([-1, 1]) & - (1 << np.arange(n_qubits))[::-1] - ) > 0).astype(bool) + ( + np.arange(2**n_qubits).reshape([-1, 1]) + & (1 << np.arange(n_qubits))[::-1] + ) + > 0 + ).astype(bool) binary_convert = 1 << np.arange(2 * n_qubits)[::-1] - constant = 2 ** n_qubits - ij_same = (row == col) - for i in tqdm(row[ij_same], desc='Building operator via projectors diag elements', total=sum(ij_same), - disable=disable_loading_bar): + constant = 2**n_qubits + ij_same = row == col + for i in tqdm( + row[ij_same], + desc="Building operator via projectors diag elements", + total=sum(ij_same), + disable=disable_loading_bar, + ): j = i ij_symp_matrix = np.hstack([np.zeros_like(binary_vec), binary_vec]) - proj_coeffs = ((-1) ** np.sum(np.logical_and(binary_vec[i], binary_vec[j]) & binary_vec, axis=1)) / constant - int_list = np.einsum('j, ij->i', binary_convert, ij_symp_matrix) + proj_coeffs = ( + (-1) + ** np.sum( + np.logical_and(binary_vec[i], binary_vec[j]) & binary_vec, axis=1 + ) + ) / constant + int_list = np.einsum("j, ij->i", binary_convert, ij_symp_matrix) # populate sparse mats sym_operator[int_list, :] = ij_symp_matrix coeff_operator[int_list] += proj_coeffs.reshape(-1, 1) * matrix[i, j] del ij_symp_matrix, proj_coeffs, int_list + for i, j in tqdm( + zip(row[~ij_same], col[~ij_same]), + desc="Building operator via projectors off-diag elements", + total=sum(~ij_same), + disable=disable_loading_bar, + ): + proj_coeffs = ( + ( + (-1) + ** np.sum( + np.logical_and(binary_vec[i], binary_vec[j]) & binary_vec, + axis=1, + ) + ) + * ( + (-1j) + ** np.sum( + (binary_vec[i] & binary_vec) & ~(binary_vec & binary_vec[j]), + axis=1, + ) + ) + * ( + (+1j) + ** np.sum( + (binary_vec & binary_vec[j]) & ~(binary_vec[i] & binary_vec), + axis=1, + ) + ) + ) / constant - for i, j in tqdm(zip(row[~ij_same], col[~ij_same]), desc='Building operator via projectors off-diag elements', - total=sum(~ij_same), disable=disable_loading_bar): - proj_coeffs = (((-1) ** np.sum(np.logical_and(binary_vec[i], binary_vec[j]) & binary_vec, axis=1)) - * ((-1j) ** np.sum((binary_vec[i] & binary_vec) & ~(binary_vec & binary_vec[j]), axis=1)) - * ((+1j) ** np.sum((binary_vec & binary_vec[j]) & ~(binary_vec[i] & binary_vec), - axis=1))) / constant - - ij_symp_matrix = np.hstack([np.tile((binary_vec[i] ^ binary_vec[j]), [2 ** n_qubits, 1]), - binary_vec]) + ij_symp_matrix = np.hstack( + [ + np.tile((binary_vec[i] ^ binary_vec[j]), [2**n_qubits, 1]), + binary_vec, + ] + ) ### find location in symp matrix - int_list = np.einsum('j, ij->i', binary_convert, ij_symp_matrix) + int_list = np.einsum("j, ij->i", binary_convert, ij_symp_matrix) # populate sparse mats sym_operator[int_list, :] = ij_symp_matrix @@ -346,31 +403,33 @@ def _from_matrix_projector(cls, ### only keep nonzero coeffs! (skips expensive cleanup) nonzero = coeff_operator.nonzero()[0] - P_out = PauliwordOp(sym_operator[nonzero, :].toarray(), - coeff_operator[nonzero].toarray()[:, 0]) + P_out = PauliwordOp( + sym_operator[nonzero, :].toarray(), coeff_operator[nonzero].toarray()[:, 0] + ) # P_out = PauliwordOp(sym_operator.toarray(), # coeff_operator.toarray()[:,0]).cleanup() return P_out @classmethod - def from_matrix(cls, - matrix: Union[np.array, csr_matrix], - operator_basis: "PauliwordOp" = None, - strategy: str = 'projector', - disable_loading_bar: Optional[bool] = False - ) -> "PauliwordOp": + def from_matrix( + cls, + matrix: Union[np.array, csr_matrix], + operator_basis: "PauliwordOp" = None, + strategy: str = "projector", + disable_loading_bar: Optional[bool] = False, + ) -> "PauliwordOp": """ -------------- | strategies | -------------- - + - full_basis - + If user doesn't define an operator basis then builds the full 4^N Hilbert space - this can be costly!. - The user can avoid this by specificying a reduced basis that targets a subspace; there is a check + The user can avoid this by specificying a reduced basis that targets a subspace; there is a check to assess whether the basis is sufficiently expressible to represent the input matrix in this case. - + - projector Scales as O(M*2^N) where M the number of nonzero elements in the matrix. @@ -391,59 +450,62 @@ def from_matrix(cls, n_qubits = int(np.ceil(np.log2(max(matrix.shape)))) if n_qubits > 30 and operator_basis is None: - # could change XZ_block builder to use numpy objects (allows above 64-bit integers) but very slow and matrix will be too large to build - raise ValueError('Matrix too large! Will run into memory limitations.') + # could change XZ_block builder to use numpy objects (allows above 64-bit integers) but very slow and matrix will be too large to build + raise ValueError("Matrix too large! Will run into memory limitations.") if not (2**n_qubits, 2**n_qubits) == matrix.shape: # padding matrix with zeros so correct size - temp_mat = np.zeros((2 ** n_qubits, 2 ** n_qubits)) - temp_mat[:matrix.shape[0], - :matrix.shape[1]] = matrix + temp_mat = np.zeros((2**n_qubits, 2**n_qubits)) + temp_mat[: matrix.shape[0], : matrix.shape[1]] = matrix matrix = temp_mat - if strategy == 'full_basis' or operator_basis is not None: + if strategy == "full_basis" or operator_basis is not None: operator_out = cls._from_matrix_full_basis( - matrix=matrix, n_qubits=n_qubits, operator_basis=operator_basis, disable_loading_bar=disable_loading_bar + matrix=matrix, + n_qubits=n_qubits, + operator_basis=operator_basis, + disable_loading_bar=disable_loading_bar, ) - elif strategy == 'projector': + elif strategy == "projector": operator_out = cls._from_matrix_projector( - matrix=matrix, n_qubits=n_qubits, disable_loading_bar=disable_loading_bar + matrix=matrix, + n_qubits=n_qubits, + disable_loading_bar=disable_loading_bar, ) else: - raise ValueError('Unrecognised strategy, must be one of full_basis or projector') - + raise ValueError( + "Unrecognised strategy, must be one of full_basis or projector" + ) + return operator_out - + def __str__(self) -> str: - """ - Defines the print behaviour of PauliwordOp - + """ + Defines the print behaviour of PauliwordOp - returns the operator in an easily readable format Returns: out_string (str): human-readable PauliwordOp string """ if self.symp_matrix.shape[1]: - out_string = '' + out_string = "" for pauli_vec, coeff in zip(self.symp_matrix, self.coeff_vec): p_string = symplectic_to_string(pauli_vec) - out_string += (f'{coeff: .{self.sigfig}f} {p_string} +\n') + out_string += f"{coeff: .{self.sigfig}f} {p_string} +\n" return out_string[:-3] - else: - return f'{self.coeff_vec[0]: .{self.sigfig}f}' + else: + return f"{self.coeff_vec[0]: .{self.sigfig}f}" def __repr__(self) -> str: return str(self) def copy(self) -> "PauliwordOp": - """ + """ Create a carbon copy of the class instance """ return deepcopy(self) - def sort(self, - by: str = 'magnitude', - key: str = 'decreasing' - ) -> "PauliwordOp": + def sort(self, by: str = "magnitude", key: str = "decreasing") -> "PauliwordOp": """ Sort the terms either by magnitude, weight X, Y or Z @@ -452,40 +514,63 @@ def sort(self, key (str, optional): The sorting order. Options are 'increasing' and 'decreasing'. Defaults to 'decreasing'. Returns: - PauliwordOp: A new PauliwordOp object with sorted terms. + PauliwordOp: A new PauliwordOp object with sorted terms. """ - if by == 'magnitude': + if by == "magnitude": sort_order = np.argsort(-abs(self.coeff_vec)) - elif by == 'weight': + elif by == "weight": sort_order = np.argsort(-np.sum(self.symp_matrix.astype(int), axis=1)) - elif by == 'support': - pos_terms_occur = np.logical_or(self.symp_matrix[:, :self.n_qubits], self.symp_matrix[:, self.n_qubits:]) + elif by == "support": + pos_terms_occur = np.logical_or( + self.symp_matrix[:, : self.n_qubits], + self.symp_matrix[:, self.n_qubits :], + ) symp_matrix_view = np.ascontiguousarray(pos_terms_occur).view( - np.dtype((np.void, pos_terms_occur.dtype.itemsize * pos_terms_occur.shape[1])) + np.dtype( + (np.void, pos_terms_occur.dtype.itemsize * pos_terms_occur.shape[1]) + ) ) sort_order = np.argsort(symp_matrix_view.ravel())[::-1] - elif by=='Z': - sort_order = np.argsort(np.sum((self.n_qubits+1)*self.X_block.astype(int) + self.Z_block.astype(int), axis=1)) - elif by=='X': - sort_order = np.argsort(np.sum(self.X_block.astype(int) + (self.n_qubits+1)*self.Z_block.astype(int), axis=1)) - elif by=='Y': - sort_order = np.argsort(np.sum(abs(self.X_block.astype(int) - self.Z_block.astype(int)), axis=1)) + elif by == "Z": + sort_order = np.argsort( + np.sum( + (self.n_qubits + 1) * self.X_block.astype(int) + + self.Z_block.astype(int), + axis=1, + ) + ) + elif by == "X": + sort_order = np.argsort( + np.sum( + self.X_block.astype(int) + + (self.n_qubits + 1) * self.Z_block.astype(int), + axis=1, + ) + ) + elif by == "Y": + sort_order = np.argsort( + np.sum(abs(self.X_block.astype(int) - self.Z_block.astype(int)), axis=1) + ) else: - raise ValueError('Only permitted sort by values are magnitude, weight, X, Y or Z') - if key=='increasing': + raise ValueError( + "Only permitted sort by values are magnitude, weight, X, Y or Z" + ) + if key == "increasing": sort_order = sort_order[::-1] - elif key!='decreasing': - raise ValueError('Only permitted sort by values are increasing or decreasing') + elif key != "decreasing": + raise ValueError( + "Only permitted sort by values are increasing or decreasing" + ) return PauliwordOp(self.symp_matrix[sort_order], self.coeff_vec[sort_order]) def reindex(self, qubit_map: Union[List[int], Dict[int, int]]): - """ + """ Re-index qubit labels - For example, can specify a dictionary {0:2, 2:3, 3:0} mapping qubits + For example, can specify a dictionary {0:2, 2:3, 3:0} mapping qubits to their new positions or a list [2,3,0] will achieve the same result. Args: - qubit_map (Union[List[int], Dict[int, int]]): A mapping of qubit indices to their new positions. + qubit_map (Union[List[int], Dict[int, int]]): A mapping of qubit indices to their new positions. It can be specified as a list [2, 3, 0] or a dictionary {0: 2, 2: 3, 3: 0}. Returns: @@ -497,25 +582,26 @@ def reindex(self, qubit_map: Union[List[int], Dict[int, int]]): old_indices, new_indices = zip(*qubit_map.items()) old_set, new_set = set(old_indices), set(new_indices) setdiff = old_set.difference(new_set) - assert len(new_indices) == len(new_set), 'Duplicated index' - assert len(setdiff) == 0, f'Assignment conflict: indices {setdiff} cannot be mapped.' - + assert len(new_indices) == len(new_set), "Duplicated index" + assert ( + len(setdiff) == 0 + ), f"Assignment conflict: indices {setdiff} cannot be mapped." + # map corresponding columns in the symplectic matrix to their new positions new_X_block = self.X_block.copy() new_Z_block = self.Z_block.copy() - new_X_block[:,old_indices] = new_X_block[:,new_indices] - new_Z_block[:,old_indices] = new_Z_block[:,new_indices] - + new_X_block[:, old_indices] = new_X_block[:, new_indices] + new_Z_block[:, old_indices] = new_Z_block[:, new_indices] + return PauliwordOp(np.hstack([new_X_block, new_Z_block]), self.coeff_vec) - def generator_reconstruction(self, - generators: "PauliwordOp", - override_independence_check: bool = False - ) -> np.array: - """ + def generator_reconstruction( + self, generators: "PauliwordOp", override_independence_check: bool = False + ) -> np.array: + """ Simultaneously reconstruct every operator term in the supplied basis. - With B and M the symplectic form of the supplied basis and the internal - Pauli operator, respectively, we perform columnwise Gaussian elimination + With B and M the symplectic form of the supplied basis and the internal + Pauli operator, respectively, we perform columnwise Gaussian elimination to yield the matrix [ B ] [ I | 0 ] @@ -539,16 +625,18 @@ def generator_reconstruction(self, Tuple[np.array, np.array]: A tuple containing the reconstruction matrix and a mask indicating which terms were successfully reconstructed. """ if not override_independence_check: - assert check_independent(generators), 'Supplied generators are algebraically dependent' + assert check_independent( + generators + ), "Supplied generators are algebraically dependent" dim = generators.n_terms basis_op_stack = np.vstack([generators.symp_matrix, self.symp_matrix]) reduced = cref_binary(basis_op_stack) - mask_successfully_reconstructed = np.all(~reduced[dim:,dim:], axis=1) - op_reconstruction = reduced[dim:,:dim] + mask_successfully_reconstructed = np.all(~reduced[dim:, dim:], axis=1) + op_reconstruction = reduced[dim:, :dim] return op_reconstruction.astype(int), mask_successfully_reconstructed def jordan_generator_reconstruction(self, generators: "PauliwordOp"): - """ + """ Reconstruct this PauliwordOp under the Jordan product PQ = {P,Q}/2 with respect to the supplied generators @@ -558,7 +646,9 @@ def jordan_generator_reconstruction(self, generators: "PauliwordOp"): Returns: Tuple[np.array, np.array]: A tuple containing the reconstruction matrix and a mask indicating which terms were successfully reconstructed. """ - assert check_jordan_independent(generators), 'The non-symmetry elements do not pairwise anticommute.' + assert check_jordan_independent( + generators + ), "The non-symmetry elements do not pairwise anticommute." # first, separate symmetry elements from anticommuting ones symmetry_mask = np.all(generators.commutes_termwise(generators), axis=1) @@ -574,24 +664,31 @@ def jordan_generator_reconstruction(self, generators: "PauliwordOp"): ac_terms = generators[~symmetry_mask] # loop over anticommuting elements to enforce Jordan condition (no two anticommuting elements multiplied) - for _, clq in ac_terms.clique_cover(edge_relation='C').items(): - clq_indices = [np.where(np.all(generators.symp_matrix == t, axis=1))[0][0] for t in clq.symp_matrix] + for _, clq in ac_terms.clique_cover(edge_relation="C").items(): + clq_indices = [ + np.where(np.all(generators.symp_matrix == t, axis=1))[0][0] + for t in clq.symp_matrix + ] mask_symmetries_with_P = symmetry_mask.copy() mask_symmetries_with_P[np.array(clq_indices)] = True # reconstruct this PauliwordOp in the augemented symmetry + single anticommuting term generating set augmented_symmetries = generators[mask_symmetries_with_P] - recon_mat_P, successful_P = self.generator_reconstruction(augmented_symmetries) + recon_mat_P, successful_P = self.generator_reconstruction( + augmented_symmetries + ) # np.ix_ needed to correctly slice op_reconstruction as mask method does not work row, col = np.ix_(successful_P, mask_symmetries_with_P) op_reconstruction[row, col] = recon_mat_P[successful_P] # will have duplicate succesful reconstruction of symmetries, so only sets True once in logical OR - successfully_reconstructed = np.logical_or(successfully_reconstructed, successful_P) + successfully_reconstructed = np.logical_or( + successfully_reconstructed, successful_P + ) return op_reconstruction.astype(int), successfully_reconstructed @cached_property def Y_count(self) -> np.array: - """ + """ Count the qubit positions of each term set to Pauli Y cached_property means this only runs once and then is stored @@ -602,10 +699,8 @@ def Y_count(self) -> np.array: """ return np.sum(np.bitwise_and(self.X_block, self.Z_block), axis=1) - def cleanup(self, - zero_threshold:float=1e-15 - ) -> "PauliwordOp": - """ + def cleanup(self, zero_threshold: float = 1e-15) -> "PauliwordOp": + """ Apply symplectic_cleanup and delete terms with negligible coefficients. Args: @@ -617,7 +712,9 @@ def cleanup(self, if self.n_qubits == 0: return PauliwordOp([], [np.sum(self.coeff_vec)]) elif self.n_terms == 0: - return PauliwordOp(np.zeros((1, self.symp_matrix.shape[1]), dtype=bool), [0]) + return PauliwordOp( + np.zeros((1, self.symp_matrix.shape[1]), dtype=bool), [0] + ) else: return PauliwordOp( *symplectic_cleanup( @@ -625,10 +722,8 @@ def cleanup(self, ) ) - def __eq__(self, - Pword: "PauliwordOp" - ) -> bool: - """ + def __eq__(self, Pword: "PauliwordOp") -> bool: + """ In theory should use logical XNOR to check symplectic matrix match, however can use standard logical XOR and look for False indices instead (implementation skips an additional NOT operation) @@ -642,18 +737,19 @@ def __eq__(self, check_1 = self.cleanup() check_2 = Pword.cleanup() if check_1.n_qubits != check_2.n_qubits: - raise ValueError('Operators defined over differing numbers of qubits.') + raise ValueError("Operators defined over differing numbers of qubits.") elif check_1.n_terms != check_2.n_terms: return False else: - return (not np.sum(np.logical_xor(check_1.symp_matrix, check_2.symp_matrix)) and - np.allclose(check_1.coeff_vec, check_2.coeff_vec)) + return not np.sum( + np.logical_xor(check_1.symp_matrix, check_2.symp_matrix) + ) and np.allclose(check_1.coeff_vec, check_2.coeff_vec) # if eq_flag is True: # assert hash(check_1) == hash(check_2), 'equal objects have different hash values' # return eq_flag def __hash__(self) -> int: - """ + """ Build unique hash from dictionary of PauliwordOp. Returns: @@ -667,10 +763,8 @@ def __hash__(self) -> int: hash_val = hash(tuple_of_tuples) return hash_val - def append(self, - PwordOp: "PauliwordOp" - ) -> "PauliwordOp": - """ + def append(self, PwordOp: "PauliwordOp") -> "PauliwordOp": + """ Append another PauliwordOp onto this one - duplicates allowed. Args: @@ -679,15 +773,15 @@ def append(self, Returns: PauliwordOp: The new PauliwordOp object after appending. """ - assert (self.n_qubits == PwordOp.n_qubits), 'Pauliwords defined for different number of qubits' + assert ( + self.n_qubits == PwordOp.n_qubits + ), "Pauliwords defined for different number of qubits" P_symp_mat_new = np.vstack((self.symp_matrix, PwordOp.symp_matrix)) P_new_coeffs = np.hstack((self.coeff_vec, PwordOp.coeff_vec)) - return PauliwordOp(P_symp_mat_new, P_new_coeffs) + return PauliwordOp(P_symp_mat_new, P_new_coeffs) - def __add__(self, - PwordOp: "PauliwordOp" - ) -> "PauliwordOp": - """ + def __add__(self, PwordOp: "PauliwordOp") -> "PauliwordOp": + """ Add to this PauliwordOp another PauliwordOp by stacking the respective symplectic matrices and cleaning any resulting duplicates. @@ -700,10 +794,8 @@ def __add__(self, # cleanup run to remove duplicate rows (Pauliwords) return self.append(PwordOp).cleanup() - def __radd__(self, - add_obj: Union[int, "PauliwordOp"] - ) -> "PauliwordOp": - """ + def __radd__(self, add_obj: Union[int, "PauliwordOp"]) -> "PauliwordOp": + """ Allows use of sum() over a list of PauliwordOps. Args: @@ -717,11 +809,9 @@ def __radd__(self, else: return self + add_obj - def __sub__(self, - PwordOp: "PauliwordOp" - ) -> "PauliwordOp": - """ - Subtract from this PauliwordOp another PauliwordOp + def __sub__(self, PwordOp: "PauliwordOp") -> "PauliwordOp": + """ + Subtract from this PauliwordOp another PauliwordOp by negating the coefficients and summing. Args: @@ -729,15 +819,13 @@ def __sub__(self, Returns: PauliwordOp: The result of subtracting the PauliwordOp object from this PauliwordOp object. - """ + """ op_copy = PwordOp.copy() - op_copy.coeff_vec*=-1 - - return self+op_copy + op_copy.coeff_vec *= -1 + + return self + op_copy - def multiply_by_constant(self, - const: complex - ) -> "PauliwordOp": + def multiply_by_constant(self, const: complex) -> "PauliwordOp": """ Multiply the PauliwordOp by a complex coefficient. @@ -747,16 +835,14 @@ def multiply_by_constant(self, Returns: PauliwordOp: The result of multiplying the PauliwordOp by the constant. """ - return PauliwordOp(self.symp_matrix, self.coeff_vec*const) + return PauliwordOp(self.symp_matrix, self.coeff_vec * const) - def _mul_symplectic(self, - symp_vec: np.array, - coeff: complex, - Y_count_in: np.array - ) -> Tuple[np.array, np.array]: - """ - Performs Pauli multiplication with phases at the level of the symplectic - matrices to avoid superfluous PauliwordOp initializations. The phase compensation + def _mul_symplectic( + self, symp_vec: np.array, coeff: complex, Y_count_in: np.array + ) -> Tuple[np.array, np.array]: + """ + Performs Pauli multiplication with phases at the level of the symplectic + matrices to avoid superfluous PauliwordOp initializations. The phase compensation is implemented as per https://doi.org/10.1103/PhysRevA.68.042318. Args: @@ -770,20 +856,23 @@ def _mul_symplectic(self, # phaseless multiplication is binary addition in symplectic representation phaseless_prod = np.bitwise_xor(self.symp_matrix, symp_vec) # phase is determined by Y counts plus additional sign flip - Y_count_out = np.sum(np.bitwise_and(*np.hsplit(phaseless_prod,2)), axis=1) + Y_count_out = np.sum(np.bitwise_and(*np.hsplit(phaseless_prod, 2)), axis=1) sign_change = (-1) ** ( - np.sum(np.bitwise_and(self.X_block, np.hsplit(symp_vec,2)[1]), axis=1) % 2 - ) # mod 2 as only care about parity + np.sum(np.bitwise_and(self.X_block, np.hsplit(symp_vec, 2)[1]), axis=1) % 2 + ) # mod 2 as only care about parity # final phase modification - phase_mod = sign_change * (1j) ** ((3*Y_count_in + Y_count_out) % 4) # mod 4 as roots of unity + phase_mod = sign_change * (1j) ** ( + (3 * Y_count_in + Y_count_out) % 4 + ) # mod 4 as roots of unity coeff_vec = phase_mod * self.coeff_vec * coeff return phaseless_prod, coeff_vec - def _multiply_by_operator(self, - PwordOp: Union["PauliwordOp", "QuantumState", complex], - zero_threshold: float = 1e-15 - ) -> "PauliwordOp": - """ + def _multiply_by_operator( + self, + PwordOp: Union["PauliwordOp", "QuantumState", complex], + zero_threshold: float = 1e-15, + ) -> "PauliwordOp": + """ Right-multiplication of this PauliwordOp by another PauliwordOp or QuantumState ket. Args: @@ -793,31 +882,43 @@ def _multiply_by_operator(self, Returns: PauliwordOp: The resulting PauliwordOp after multiplication. """ - assert (self.n_qubits == PwordOp.n_qubits), 'PauliwordOps defined for different number of qubits' + assert ( + self.n_qubits == PwordOp.n_qubits + ), "PauliwordOps defined for different number of qubits" if PwordOp.n_terms == 1: # no cleanup if multiplying by a single term (faster) symp_stack, coeff_stack = self._mul_symplectic( - symp_vec=PwordOp.symp_matrix, - coeff=PwordOp.coeff_vec, - Y_count_in=self.Y_count+PwordOp.Y_count + symp_vec=PwordOp.symp_matrix, + coeff=PwordOp.coeff_vec, + Y_count_in=self.Y_count + PwordOp.Y_count, ) pauli_mult_out = PauliwordOp(symp_stack, coeff_stack) else: # multiplication is performed at the symplectic level, before being stacked and cleaned symp_stack, coeff_stack = zip( - *[self._mul_symplectic(symp_vec=symp_vec, coeff=coeff, Y_count_in=self.Y_count+Y_count) - for symp_vec, coeff, Y_count in zip(PwordOp.symp_matrix, PwordOp.coeff_vec, PwordOp.Y_count)] + *[ + self._mul_symplectic( + symp_vec=symp_vec, + coeff=coeff, + Y_count_in=self.Y_count + Y_count, + ) + for symp_vec, coeff, Y_count in zip( + PwordOp.symp_matrix, PwordOp.coeff_vec, PwordOp.Y_count + ) + ] ) pauli_mult_out = PauliwordOp( *symplectic_cleanup( - np.vstack(symp_stack), np.hstack(coeff_stack), zero_threshold=zero_threshold + np.vstack(symp_stack), + np.hstack(coeff_stack), + zero_threshold=zero_threshold, ) ) return pauli_mult_out - + def expval(self, psi: "QuantumState") -> complex: - """ + """ Efficient (linear) expectation value calculation using projectors See single_term_expval function below for further details. @@ -830,18 +931,20 @@ def expval(self, psi: "QuantumState") -> complex: if self.n_terms > 1: # parallelize if number of terms greater than one psi_ray_store = ray.put(psi) - expvals = np.array(ray.get( - [single_term_expval.remote(P, psi_ray_store) for P in self])) + expvals = np.array( + ray.get([single_term_expval.remote(P, psi_ray_store) for P in self]) + ) else: expvals = np.array(single_term_expval(self, psi)) return np.sum(expvals * self.coeff_vec) - def __mul__(self, - mul_obj: Union["PauliwordOp", "QuantumState", complex], - zero_threshold: float = 1e-15 - ) -> "PauliwordOp": - """ + def __mul__( + self, + mul_obj: Union["PauliwordOp", "QuantumState", complex], + zero_threshold: float = 1e-15, + ) -> "PauliwordOp": + """ Right-multiplication of this PauliwordOp by another PauliwordOp or QuantumState ket. Args: @@ -857,7 +960,7 @@ def __mul__(self, if isinstance(mul_obj, QuantumState): # allows one to apply PauliwordOps to QuantumStates # (corresponds with multipcation of the underlying state_op) - assert(mul_obj.vec_type == 'ket'), 'cannot multiply a bra from the left' + assert mul_obj.vec_type == "ket", "cannot multiply a bra from the left" PwordOp = mul_obj.state_op else: PwordOp = mul_obj @@ -865,22 +968,22 @@ def __mul__(self, # more efficient to multiply the larger operator from the right if self.n_terms < PwordOp.n_terms: pauli_mult_out = PwordOp.dagger._multiply_by_operator( - self.dagger, zero_threshold=zero_threshold).dagger + self.dagger, zero_threshold=zero_threshold + ).dagger else: pauli_mult_out = self._multiply_by_operator( - PwordOp, zero_threshold=zero_threshold) + PwordOp, zero_threshold=zero_threshold + ) if isinstance(mul_obj, QuantumState): - coeff_vec = pauli_mult_out.coeff_vec*(1j**pauli_mult_out.Y_count) + coeff_vec = pauli_mult_out.coeff_vec * (1j**pauli_mult_out.Y_count) # need to run a separate cleanup since identities are all mapped to Z, i.e. II==ZZ in QuantumState return QuantumState(pauli_mult_out.X_block.astype(int), coeff_vec).cleanup() else: return pauli_mult_out - - def __imul__(self, - PwordOp: "PauliwordOp" - ) -> "PauliwordOp": - """ + + def __imul__(self, PwordOp: "PauliwordOp") -> "PauliwordOp": + """ In-place multiplication behaviour. Args: @@ -891,9 +994,7 @@ def __imul__(self, """ return self.__mul__(PwordOp) - def __pow__(self, - exponent:int - ) -> "PauliwordOp": + def __pow__(self, exponent: int) -> "PauliwordOp": """ Exponentiation behavior. @@ -903,17 +1004,15 @@ def __pow__(self, Returns: PauliwordOp: The result of the exponentiation. """ - assert(isinstance(exponent, int)), 'the exponent is not an integer' + assert isinstance(exponent, int), "the exponent is not an integer" if exponent == 0: - return PauliwordOp.from_list(['I'*self.n_qubits],[1]) + return PauliwordOp.from_list(["I" * self.n_qubits], [1]) else: - factors = [self.copy()]*exponent - return reduce(lambda x,y:x*y, factors) + factors = [self.copy()] * exponent + return reduce(lambda x, y: x * y, factors) - def __getitem__(self, - key: Union[slice, int] - ) -> "PauliwordOp": - """ + def __getitem__(self, key: Union[slice, int]) -> "PauliwordOp": + """ Makes the PauliwordOp subscriptable - returns a PauliwordOp constructed from the indexed row and coefficient from the symplectic matrix . @@ -924,29 +1023,31 @@ def __getitem__(self, PauliwordOp: A new PauliwordOp object constructed from the selected rows and coefficients. """ if isinstance(key, int): - if key<0: + if key < 0: # allow negative subscript - key+=self.n_terms - assert(key np.array: - """ Outputs an array in which rows correspond with terms of the internal PauliwordOp (self) + def commutes_termwise(self, PwordOp: "PauliwordOp") -> np.array: + """Outputs an array in which rows correspond with terms of the internal PauliwordOp (self) and colummns of Pword - True where terms commute and False if anticommutes **example op1 = PauliwordOp(['XYXZ', 'YYII'], [1,1]) op2 = PauliwordOp(['YYZZ', 'XIXZ', 'XZZI'], [1,1,1]) op1.commutes_termwise(op2) - >> array([ + >> array([ [ True, True, True], [ True, False, True]] ) @@ -975,7 +1074,9 @@ def commutes_termwise(self, Returns: np.array: A Boolean array indicating the term-wise commutation. """ - assert (self.n_qubits == PwordOp.n_qubits), 'Pauliwords defined for different number of qubits' + assert ( + self.n_qubits == PwordOp.n_qubits + ), "Pauliwords defined for different number of qubits" ### sparse code # adjacency_matrix = ( @@ -984,12 +1085,10 @@ def commutes_termwise(self, # return np.logical_not(adjacency_matrix.toarray()) ### dense code - Omega_PwordOp_symp = np.hstack((PwordOp.Z_block, PwordOp.X_block)).astype(int) + Omega_PwordOp_symp = np.hstack((PwordOp.Z_block, PwordOp.X_block)).astype(int) return (self.symp_matrix @ Omega_PwordOp_symp.T) % 2 == 0 - def anticommutes_termwise(self, - PwordOp: "PauliwordOp" - ) -> np.array: + def anticommutes_termwise(self, PwordOp: "PauliwordOp") -> np.array: """ Args: PwordOp (PauliwordOp): The PauliwordOp to check for term-wise anticommutation. @@ -999,18 +1098,16 @@ def anticommutes_termwise(self, """ return ~self.commutes_termwise(PwordOp) - def qubitwise_commutes_termwise(self, - PwordOp: "PauliwordOp" - ) -> np.array: - """ + def qubitwise_commutes_termwise(self, PwordOp: "PauliwordOp") -> np.array: + """ Given the symplectic representation of a single Pauli operator, determines which operator terms of the internal PauliwordOp qubitwise commute Args: PwordOp (PauliwordOp): The PauliwordOp to check for qubitwise term-wise commutation. - Returns: - QWC_matrix (np.array): + Returns: + QWC_matrix (np.array): An array whose elements are True if the corresponding term qubitwise commutes with the input PwordOp. """ @@ -1025,10 +1122,8 @@ def qubitwise_commutes_termwise(self, QWC_matrix.append((X_match & Z_match).reshape(self.n_terms, 1)) return np.hstack(QWC_matrix) - def commutator(self, - PwordOp: "PauliwordOp" - ) -> "PauliwordOp": - """ + def commutator(self, PwordOp: "PauliwordOp") -> "PauliwordOp": + """ Computes the commutator [A, B] = AB - BA. Args: @@ -1039,10 +1134,8 @@ def commutator(self, """ return self * PwordOp - PwordOp * self - def anticommutator(self, - PwordOp: "PauliwordOp" - ) -> "PauliwordOp": - """ + def anticommutator(self, PwordOp: "PauliwordOp") -> "PauliwordOp": + """ Computes the anticommutator {A, B} = AB + BA. Args: @@ -1053,10 +1146,8 @@ def anticommutator(self, """ return self * PwordOp + PwordOp * self - def commutes(self, - PwordOp: "PauliwordOp" - ) -> bool: - """ + def commutes(self, PwordOp: "PauliwordOp") -> bool: + """ Checks if every term of self commutes with every term of PwordOp. Args: @@ -1066,10 +1157,10 @@ def commutes(self, bool: True if all terms commute, False otherwise. """ return self.commutator(PwordOp).n_terms == 0 - + @cached_property def adjacency_matrix(self) -> np.array: - """ + """ Checks which terms of self commute within itself. Returns: @@ -1079,7 +1170,7 @@ def adjacency_matrix(self) -> np.array: @cached_property def adjacency_matrix_qwc(self) -> np.array: - """ + """ Checks which terms of self qubitwise commute within itself. Returns: @@ -1089,7 +1180,7 @@ def adjacency_matrix_qwc(self) -> np.array: @cached_property def is_noncontextual(self) -> bool: - """ + """ Returns True if the operator is noncontextual, False if contextual Scales as O(N^2), compared with the O(N^3) algorithm of https://doi.org/10.1103/PhysRevLett.123.200501 Constructing the adjacency matrix is by far the most expensive part - very fast once that has been built. @@ -1100,9 +1191,16 @@ def is_noncontextual(self) -> bool: if self.n_terms < 4: return True - to_reduce = np.vstack([np.hstack([self.Z_block, self.X_block]), np.eye(2 * self.n_qubits, dtype=bool)]) + to_reduce = np.vstack( + [ + np.hstack([self.Z_block, self.X_block]), + np.eye(2 * self.n_qubits, dtype=bool), + ] + ) cref_matrix = _cref_binary(to_reduce) - Z2_symp = cref_matrix[self.n_terms:, np.all(~cref_matrix[:self.n_terms], axis=0)].T + Z2_symp = cref_matrix[ + self.n_terms :, np.all(~cref_matrix[: self.n_terms], axis=0) + ].T Z2_terms = PauliwordOp(Z2_symp, np.ones(Z2_symp.shape[0])) if Z2_terms.n_terms < 1: @@ -1116,7 +1214,13 @@ def is_noncontextual(self) -> bool: # for remaining to be noncontextual must be disjoint union of cliques # we can test for this below adj_matrix_view = np.ascontiguousarray(remaining.adjacency_matrix).view( - np.dtype((np.void, remaining.adjacency_matrix.dtype.itemsize * remaining.adjacency_matrix.shape[1])) + np.dtype( + ( + np.void, + remaining.adjacency_matrix.dtype.itemsize + * remaining.adjacency_matrix.shape[1], + ) + ) ) re_order_indices = np.argsort(adj_matrix_view.ravel()) # sort the adj matrix and vector of coefficients accordingly @@ -1134,23 +1238,24 @@ def is_noncontextual(self) -> bool: missing = self[~mask] from symmer.utils import get_generators_including_xz_products + gens_xyz = get_generators_including_xz_products(missing) gens = missing.generators - return check_adjmat_noncontextual(gens.adjacency_matrix) or check_adjmat_noncontextual(gens_xyz.adjacency_matrix) - + return check_adjmat_noncontextual( + gens.adjacency_matrix + ) or check_adjmat_noncontextual(gens_xyz.adjacency_matrix) - def _rotate_by_single_Pword(self, - Pword: "PauliwordOp", - angle: float = None - ) -> "PauliwordOp": - """ + def _rotate_by_single_Pword( + self, Pword: "PauliwordOp", angle: float = None + ) -> "PauliwordOp": + """ Let R(t) = e^{i t/2 Q} = cos(t/2)*I + i*sin(t/2)*Q, then one of the following can occur: R(t) P R^\dag(t) = P when [P,Q] = 0 R(t) P R^\dag(t) = cos(t) P + sin(t) (-iPQ) when {P,Q} = 0 This operation is Clifford when t=pi/2, since cos(pi/2) P - sin(pi/2) iPQ = -iPQ. For t!=pi/2 an increase in the number of terms can be observed (non-Clifford unitary). - + Please note the definition of the angle in R(t)... different implementations could be out by a factor of 2! @@ -1161,13 +1266,15 @@ def _rotate_by_single_Pword(self, Returns: PauliwordOp: The rotated operator. """ - assert(Pword.n_terms==1), 'Only rotation by single Pauliword allowed here' + assert Pword.n_terms == 1, "Only rotation by single Pauliword allowed here" if Pword.coeff_vec[0] != 1: # non-1 coefficients will affect the sign and angle in the exponent of R(t) # imaginary coefficients result in non-unitary R(t) Pword_copy = Pword.copy() Pword_copy.coeff_vec[0] = 1 - warnings.warn(f'Pword coefficient {Pword.coeff_vec[0]: .8f} has been set to 1') + warnings.warn( + f"Pword coefficient {Pword.coeff_vec[0]: .8f} has been set to 1" + ) else: Pword_copy = Pword @@ -1177,29 +1284,34 @@ def _rotate_by_single_Pword(self, return self else: # note ~commute_vec == not commutes, this indexes the anticommuting terms - commute_self = PauliwordOp(self.symp_matrix[commute_vec], self.coeff_vec[commute_vec]) - anticom_self = PauliwordOp(self.symp_matrix[~commute_vec], self.coeff_vec[~commute_vec]) + commute_self = PauliwordOp( + self.symp_matrix[commute_vec], self.coeff_vec[commute_vec] + ) + anticom_self = PauliwordOp( + self.symp_matrix[~commute_vec], self.coeff_vec[~commute_vec] + ) if angle is None: # assumes pi/2 rotation so Clifford - anticom_part = (anticom_self*Pword_copy).multiply_by_constant(-1j) + anticom_part = (anticom_self * Pword_copy).multiply_by_constant(-1j) # if rotation is Clifford cannot produce duplicate terms so cleanup not necessary return PauliwordOp( - np.vstack([anticom_part.symp_matrix, commute_self.symp_matrix]), - np.hstack([anticom_part.coeff_vec, commute_self.coeff_vec]) + np.vstack([anticom_part.symp_matrix, commute_self.symp_matrix]), + np.hstack([anticom_part.coeff_vec, commute_self.coeff_vec]), ) else: # if angle is specified, performs non-Clifford rotation - anticom_part = (anticom_self.multiply_by_constant(np.cos(angle)) + - (anticom_self*Pword_copy).multiply_by_constant(-1j*np.sin(angle))) + anticom_part = anticom_self.multiply_by_constant(np.cos(angle)) + ( + anticom_self * Pword_copy + ).multiply_by_constant(-1j * np.sin(angle)) return commute_self + anticom_part - - def perform_rotations(self, - rotations: List[Tuple["PauliwordOp", float]] - ) -> "PauliwordOp": - """ - Performs single Pauli rotations recursively left-to-right given a list of paulis supplied - either as strings or in the symplectic representation. This method does not allow coefficients + + def perform_rotations( + self, rotations: List[Tuple["PauliwordOp", float]] + ) -> "PauliwordOp": + """ + Performs single Pauli rotations recursively left-to-right given a list of paulis supplied + either as strings or in the symplectic representation. This method does not allow coefficients to be specified as rotation in this setting is ill-defined. If no angles are given then rotations are assumed to be pi/2 (Clifford). @@ -1217,7 +1329,7 @@ def perform_rotations(self, return op_copy def tensor(self, right_op: "PauliwordOp") -> "PauliwordOp": - """ + """ Tensor current Pauli operator with another on the right (cannot interlace currently). Args: @@ -1227,18 +1339,25 @@ def tensor(self, right_op: "PauliwordOp") -> "PauliwordOp": PauliwordOp: The resulting Pauli operator after the tensor product. """ identity_block_right = np.zeros([right_op.n_terms, self.n_qubits]).astype(int) - identity_block_left = np.zeros([self.n_terms, right_op.n_qubits]).astype(int) - padded_left_symp = np.hstack([self.X_block, identity_block_left, self.Z_block, identity_block_left]) - padded_right_symp = np.hstack([identity_block_right, right_op.X_block, identity_block_right, right_op.Z_block]) + identity_block_left = np.zeros([self.n_terms, right_op.n_qubits]).astype(int) + padded_left_symp = np.hstack( + [self.X_block, identity_block_left, self.Z_block, identity_block_left] + ) + padded_right_symp = np.hstack( + [ + identity_block_right, + right_op.X_block, + identity_block_right, + right_op.Z_block, + ] + ) left_factor = PauliwordOp(padded_left_symp, self.coeff_vec) right_factor = PauliwordOp(padded_right_symp, right_op.coeff_vec) return left_factor * right_factor - def get_graph(self, - edge_relation = 'C' - ) -> nx.graph: - """ - Build a graph based on edge relation C (commuting), + def get_graph(self, edge_relation="C") -> nx.graph: + """ + Build a graph based on edge relation C (commuting), AC (anticommuting) or QWC (qubitwise commuting). Args: @@ -1248,23 +1367,23 @@ def get_graph(self, nx.Graph: The graph representing the edge relation. """ # build the adjacency matrix for the chosen edge relation - if edge_relation == 'AC': + if edge_relation == "AC": adjmat = ~self.adjacency_matrix.copy() - elif edge_relation == 'C': + elif edge_relation == "C": adjmat = self.adjacency_matrix.copy() - elif edge_relation == 'QWC': + elif edge_relation == "QWC": adjmat = self.adjacency_matrix_qwc.copy() else: - raise TypeError('Unrecognised edge relation, must be one of C (commuting), AC (anticommuting) or QWC (qubitwise commuting).') - np.fill_diagonal(adjmat,False) # avoids self-adjacency + raise TypeError( + "Unrecognised edge relation, must be one of C (commuting), AC (anticommuting) or QWC (qubitwise commuting)." + ) + np.fill_diagonal(adjmat, False) # avoids self-adjacency # convert to a networkx graph and perform colouring on complement graph = nx.from_numpy_array(adjmat) return graph - def largest_clique(self, - edge_relation='C' - ) -> "PauliwordOp": - """ + def largest_clique(self, edge_relation="C") -> "PauliwordOp": + """ Return the largest clique w.r.t. the specified edge relation. Args: @@ -1275,15 +1394,13 @@ def largest_clique(self, """ # build graph graph = self.get_graph(edge_relation=edge_relation) - pauli_indices = sorted(nx.find_cliques(graph), key=lambda x:-len(x))[0] + pauli_indices = sorted(nx.find_cliques(graph), key=lambda x: -len(x))[0] return sum([self[i] for i in pauli_indices]) - def clique_cover(self, - edge_relation = 'C', - strategy='largest_first', - colouring_interchange=False - ) -> Dict[int, "PauliwordOp"]: - """ + def clique_cover( + self, edge_relation="C", strategy="largest_first", colouring_interchange=False + ) -> Dict[int, "PauliwordOp"]: + """ Perform a graph colouring to identify a clique partition. ------------------------ @@ -1305,7 +1422,7 @@ def clique_cover(self, 'sorted_insertion' https://quantum-journal.org/papers/q-2021-01-20-385/pdf/ Args: - edge_relation (str, optional): The edge relation used for building the graph. + edge_relation (str, optional): The edge relation used for building the graph. Must be one of the following: - 'C': Commuting relation. - 'AC': Anticommuting relation. @@ -1324,28 +1441,31 @@ def clique_cover(self, - 'DSATUR': Alias for 'saturation_largest_first'. Defaults to 'largest_first'. - colouring_interchange (bool, optional): Specifies whether to use interchange optimization + colouring_interchange (bool, optional): Specifies whether to use interchange optimization during coloring. This can improve the quality of the coloring but may take more time. Defaults to False. Returns: - Dict[int, "PauliwordOp"]: A dictionary where the keys represent the clique index and + Dict[int, "PauliwordOp"]: A dictionary where the keys represent the clique index and the values represent the PauliwordOp objects corresponding to each clique. Raises: TypeError: If the edge_relation argument is not one of 'C', 'AC', or 'QWC'. """ - if strategy == 'sorted_insertion': + if strategy == "sorted_insertion": ### not a graph approach if colouring_interchange is not False: - warnings.warn(f'{strategy} is not a graph colouring method, so colouring_interchange flag is ignored') + warnings.warn( + f"{strategy} is not a graph colouring method, so colouring_interchange flag is ignored" + ) - sorted_op_list = list(self.sort(by='magnitude', key='decreasing')) + sorted_op_list = list(self.sort(by="magnitude", key="decreasing")) check_dic = { - 'C': lambda x, y: np.all(x.commutes_termwise(y)), - 'AC': lambda x, y: np.all(~x.commutes_termwise(y)), - 'QWC': lambda x, y: np.all(x.qubitwise_commutes_termwise(y))} + "C": lambda x, y: np.all(x.commutes_termwise(y)), + "AC": lambda x, y: np.all(~x.commutes_termwise(y)), + "QWC": lambda x, y: np.all(x.qubitwise_commutes_termwise(y)), + } cliques = {0: sorted_op_list[0]} new_clique_ind = 1 @@ -1365,14 +1485,18 @@ def clique_cover(self, # build graph and invert graph = self.get_graph(edge_relation=edge_relation) inverted_graph = nx.complement(graph) - col_map = nx.greedy_color(inverted_graph, strategy=strategy, interchange=colouring_interchange) + col_map = nx.greedy_color( + inverted_graph, strategy=strategy, interchange=colouring_interchange + ) # invert the resulting colour map to identify cliques cliques = {} for p_index, colour in col_map.items(): - cliques[colour] = cliques.get( - colour, - PauliwordOp.from_list(['I'*self.n_qubits],[0]) - ) + self[p_index] + cliques[colour] = ( + cliques.get( + colour, PauliwordOp.from_list(["I" * self.n_qubits], [0]) + ) + + self[p_index] + ) return cliques @cached_property @@ -1382,14 +1506,13 @@ def dagger(self) -> "PauliwordOp": Pword_conj (PauliwordOp): The Hermitian conjugated operator. """ Pword_conj = PauliwordOp( - symp_matrix = self.symp_matrix, - coeff_vec = self.coeff_vec.conjugate() + symp_matrix=self.symp_matrix, coeff_vec=self.coeff_vec.conjugate() ) return Pword_conj @cached_property def to_openfermion(self) -> QubitOperator: - """ + """ Convert to OpenFermion Pauli operator representation. Returns: @@ -1398,8 +1521,16 @@ def to_openfermion(self) -> QubitOperator: pauli_terms = [] for symp_vec, coeff in zip(self.symp_matrix, self.coeff_vec): pauli_terms.append( - QubitOperator(' '.join([Pi+str(i) for i,Pi in enumerate(symplectic_to_string(symp_vec)) if Pi!='I']), - coeff) + QubitOperator( + " ".join( + [ + Pi + str(i) + for i, Pi in enumerate(symplectic_to_string(symp_vec)) + if Pi != "I" + ] + ), + coeff, + ) ) if len(pauli_terms) == 1: return pauli_terms[0] @@ -1408,7 +1539,7 @@ def to_openfermion(self) -> QubitOperator: @cached_property def to_qiskit(self) -> ibm_PauliSumOp: - """ + """ Convert to Qiskit Pauli operator representation. Returns: @@ -1419,7 +1550,7 @@ def to_qiskit(self) -> ibm_PauliSumOp: @cached_property def to_dictionary(self) -> Dict[str, complex]: """ - Method for converting the operator from the symplectic representation + Method for converting the operator from the symplectic representation to a dictionary of the form {P_string:coeff, ...} Returns: @@ -1427,31 +1558,33 @@ def to_dictionary(self) -> Dict[str, complex]: """ # clean the operator since duplicated terms will be overwritten in the conversion to a dictionary op_to_convert = self.cleanup() - out_dict = {symplectic_to_string(symp_vec):coeff for symp_vec, coeff - in zip(op_to_convert.symp_matrix, op_to_convert.coeff_vec)} + out_dict = { + symplectic_to_string(symp_vec): coeff + for symp_vec, coeff in zip( + op_to_convert.symp_matrix, op_to_convert.coeff_vec + ) + } return out_dict @cached_property def to_dataframe(self) -> pd.DataFrame: - """ + """ Convert operator to pd.DataFrame for easy conversion to LaTeX. Returns: pd.DataFrame: The DataFrame representation of the operator. """ paulis = list(self.to_dictionary.keys()) - DF_out = pd.DataFrame.from_dict({ - 'Pauli terms': paulis, - 'Coefficients (real)': self.coeff_vec.real - } + DF_out = pd.DataFrame.from_dict( + {"Pauli terms": paulis, "Coefficients (real)": self.coeff_vec.real} ) if np.any(self.coeff_vec.imag): - DF_out['Coefficients (imaginary)'] = self.coeff_vec.imag + DF_out["Coefficients (imaginary)"] = self.coeff_vec.imag return DF_out @cached_property def generators(self) -> "PauliwordOp": - """ Find an independent generating set for input Pauli operator + """Find an independent generating set for input Pauli operator Args: op (PauliwordOp): operator to find symmetry basis for @@ -1463,11 +1596,14 @@ def generators(self) -> "PauliwordOp": row_red = _rref_binary(self.symp_matrix) non_zero_rows = row_red[np.sum(row_red, axis=1).astype(bool)] - generators = PauliwordOp(non_zero_rows, - np.ones(non_zero_rows.shape[0], dtype=complex)) + generators = PauliwordOp( + non_zero_rows, np.ones(non_zero_rows.shape[0], dtype=complex) + ) - assert check_independent(generators), 'generators are not independent' - assert generators.n_terms <= 2*self.n_qubits, 'cannot have an independent generating set of size greaterthan 2 time num qubits' + assert check_independent(generators), "generators are not independent" + assert ( + generators.n_terms <= 2 * self.n_qubits + ), "cannot have an independent generating set of size greaterthan 2 time num qubits" return generators @@ -1485,35 +1621,41 @@ def to_sparse_matrix(self) -> csr_matrix: if self.n_qubits == 0: return csr_matrix(self.coeff_vec) - if self.n_qubits>15: + if self.n_qubits > 15: from symmer.utils import get_sparse_matrix_large_pauliwordop + sparse_matrix = get_sparse_matrix_large_pauliwordop(self) return sparse_matrix else: x_int = binary_array_to_int(self.X_block).reshape(-1, 1) z_int = binary_array_to_int(self.Z_block).reshape(-1, 1) - Y_number = np.sum(np.bitwise_and(self.X_block, self.Z_block).astype(int), axis=1) + Y_number = np.sum( + np.bitwise_and(self.X_block, self.Z_block).astype(int), axis=1 + ) global_phase = (-1j) ** Y_number - dimension = 2 ** self.n_qubits - row_ind = np.repeat(np.arange(dimension).reshape(1, -1), self.X_block.shape[0], axis=0) + dimension = 2**self.n_qubits + row_ind = np.repeat( + np.arange(dimension).reshape(1, -1), self.X_block.shape[0], axis=0 + ) col_ind = np.bitwise_xor(row_ind, x_int) row_inds_and_Zint = np.bitwise_and(row_ind, z_int) vals = global_phase.reshape(-1, 1) * (-1) ** ( - count1_in_int_bitstring(row_inds_and_Zint) % 2) # .astype(complex)) + count1_in_int_bitstring(row_inds_and_Zint) % 2 + ) # .astype(complex)) - values_and_coeff = np.einsum('ij,i->ij', vals, self.coeff_vec) + values_and_coeff = np.einsum("ij,i->ij", vals, self.coeff_vec) sparse_matrix = csr_matrix( (values_and_coeff.flatten(), (row_ind.flatten(), col_ind.flatten())), shape=(dimension, dimension), - dtype=complex + dtype=complex, ) return sparse_matrix - def conjugate_op(self, R: 'PauliwordOp') -> 'PauliwordOp': + def conjugate_op(self, R: "PauliwordOp") -> "PauliwordOp": """ For a defined linear combination of pauli operators : R = ∑_{𝑖} ci Pi ... (note each P self-adjoint!) @@ -1562,21 +1704,23 @@ def conjugate_op(self, R: 'PauliwordOp') -> 'PauliwordOp': """ # see from symmer.operators.anticommuting_op import conjugate_Pop_with_R - raise NotImplementedError('not done yet. Full function at: from symmer.operators.anticommuting_op.conjugate_Pop_with_R') + raise NotImplementedError( + "not done yet. Full function at: from symmer.operators.anticommuting_op.conjugate_Pop_with_R" + ) class QuantumState: - """ + """ Class to represent quantum states. - - This is achieved by identifying the state with a - state_op (PauliwordOp), namely |0> --> Z, |1> --> X. - - For example, the 2-qubit Bell state is mapped as follows: + + This is achieved by identifying the state with a + state_op (PauliwordOp), namely |0> --> Z, |1> --> X. + + For example, the 2-qubit Bell state is mapped as follows: 1/sqrt(2) (|00> + |11>) --> 1/sqrt(2) (ZZ + XX) - Observe the state is recovered by applying the state_op to the + Observe the state is recovered by applying the state_op to the zero vector |00>, which will be the X_block of state_op. - + This ensures correct phases when multiplying the quantum state by a PauliwordOp. QuantumState is defined in base.py to avoid circular imports since multiplication @@ -1585,14 +1729,16 @@ class QuantumState: Attributes: sigfig (int): The number of significant figures for printing. """ - sigfig = 3 # specifies the number of significant figures for printing - - def __init__(self, - state_matrix: Union[List[List[int]], np.array], - coeff_vector: Union[List[complex], np.array] = None, - vec_type: str = 'ket' - ) -> None: - """ + + sigfig = 3 # specifies the number of significant figures for printing + + def __init__( + self, + state_matrix: Union[List[List[int]], np.array], + coeff_vector: Union[List[complex], np.array] = None, + vec_type: str = "ket", + ) -> None: + """ The state is not normalized by default, since this would result in incorrect behaviour when perfoming non-unitary multiplications, e.g. for evaluating expectation values of Hamiltonians. However, if @@ -1608,22 +1754,24 @@ def __init__(self, state_matrix = np.array(state_matrix) if isinstance(coeff_vector, list): coeff_vector = np.array(coeff_vector) - if len(state_matrix.shape)==1: # incase a single basis state given - state_matrix = state_matrix.reshape([1,-1]) - state_matrix = state_matrix.astype(int) # in case input is boolean - assert(set(state_matrix.flatten()).issubset({0,1})) # must be binary, does not support N-ary qubits + if len(state_matrix.shape) == 1: # incase a single basis state given + state_matrix = state_matrix.reshape([1, -1]) + state_matrix = state_matrix.astype(int) # in case input is boolean + assert set(state_matrix.flatten()).issubset( + {0, 1} + ) # must be binary, does not support N-ary qubits self.n_terms, self.n_qubits = state_matrix.shape self.state_matrix = state_matrix if coeff_vector is None: # if no coefficients specified produces a uniform superposition - coeff_vector = np.ones(self.n_terms)/np.sqrt(self.n_terms) + coeff_vector = np.ones(self.n_terms) / np.sqrt(self.n_terms) self.vec_type = vec_type # the quantum state is manipulated via the state_op PauliwordOp - symp_matrix = np.hstack([state_matrix, 1-state_matrix]) + symp_matrix = np.hstack([state_matrix, 1 - state_matrix]) self.state_op = PauliwordOp(symp_matrix, coeff_vector) def copy(self) -> "QuantumState": - """ + """ Create a carbon copy of the class instance. Returns: @@ -1632,9 +1780,7 @@ def copy(self) -> "QuantumState": return deepcopy(self) @classmethod - def haar_random(cls, - n_qubits: int, - vec_type: str='ket') -> "QuantumState": + def haar_random(cls, n_qubits: int, vec_type: str = "ket") -> "QuantumState": """ Generate a Haar random quantum state - (uniform random quantum state). @@ -1645,19 +1791,21 @@ def haar_random(cls, Returns: qstate_random (QuantumState): Haar random quantum state """ - if vec_type=='ket': - haar_vec = (unitary_group.rvs(2**n_qubits)[:,0]).reshape([-1, 1]) - elif vec_type == 'bra': - haar_vec = (unitary_group.rvs(2**n_qubits)[0,:]).reshape([1, -1]) + if vec_type == "ket": + haar_vec = (unitary_group.rvs(2**n_qubits)[:, 0]).reshape([-1, 1]) + elif vec_type == "bra": + haar_vec = (unitary_group.rvs(2**n_qubits)[0, :]).reshape([1, -1]) else: - raise ValueError(f'vector type: {vec_type} unkown') + raise ValueError(f"vector type: {vec_type} unkown") qstate_random = cls.from_array(haar_vec) return qstate_random - + @classmethod - def random(cls, num_qubits: int, num_terms: int, vec_type: str='ket') -> "QuantumState": - """ + def random( + cls, num_qubits: int, num_terms: int, vec_type: str = "ket" + ) -> "QuantumState": + """ Generates a random normalized QuantumState, but not from Haar distribution. Args: @@ -1669,18 +1817,15 @@ def random(cls, num_qubits: int, num_terms: int, vec_type: str='ket') -> "Quantu QuantumState: A random normalized QuantumState instance. """ # random binary array with N columns, M rows - random_state = np.random.randint(0,2,(num_terms,num_qubits)) + random_state = np.random.randint(0, 2, (num_terms, num_qubits)) # random vector of coefficients - coeff_vec = ( - np.random.rand(num_terms) + - np.random.rand(num_terms)*1j + coeff_vec = np.random.rand(num_terms) + np.random.rand(num_terms) * 1j + return ( + QuantumState(random_state, coeff_vec, vec_type=vec_type).cleanup().normalize ) - return QuantumState(random_state, coeff_vec, vec_type=vec_type).cleanup().normalize - + @classmethod - def zero(cls, - n_qubits: int, - vec_type: str='ket') -> "QuantumState": + def zero(cls, n_qubits: int, vec_type: str = "ket") -> "QuantumState": """ Generate the all zero state on N qubits @@ -1691,26 +1836,28 @@ def zero(cls, Returns: q_zero_state (QuantumState): zero ket or bra quantum state """ - binary_zero = np.zeros(n_qubits).reshape(1,-1) - q_zero_state = QuantumState(binary_zero, coeff_vector=np.array([1]), vec_type=vec_type) + binary_zero = np.zeros(n_qubits).reshape(1, -1) + q_zero_state = QuantumState( + binary_zero, coeff_vector=np.array([1]), vec_type=vec_type + ) return q_zero_state def __str__(self) -> str: - """ + """ Defines the print behaviour of QuantumState - differs depending on vec_type Returns: out_string (str): human-readable QuantumState string """ - out_string = '' + out_string = "" for basis_vec, coeff in zip(self.state_matrix, self.state_op.coeff_vec): - basis_string = ''.join([str(i) for i in basis_vec]) - if self.vec_type == 'ket': - out_string += (f'{coeff: .{self.sigfig}f} |{basis_string}> +\n') - elif self.vec_type == 'bra': - out_string += (f'{coeff: .{self.sigfig}f} <{basis_string}| +\n') + basis_string = "".join([str(i) for i in basis_vec]) + if self.vec_type == "ket": + out_string += f"{coeff: .{self.sigfig}f} |{basis_string}> +\n" + elif self.vec_type == "bra": + out_string += f"{coeff: .{self.sigfig}f} <{basis_string}| +\n" else: - raise ValueError('Invalid vec_type, must be bra or ket') + raise ValueError("Invalid vec_type, must be bra or ket") return out_string[:-3] def __repr__(self): @@ -1719,9 +1866,7 @@ def __repr__(self): """ return str(self) - def __eq__(self, - Qstate: "QuantumState" - ) -> bool: + def __eq__(self, Qstate: "QuantumState") -> bool: """ Check if the current QuantumState object is equal to another QuantumState object. @@ -1732,12 +1877,10 @@ def __eq__(self, bool: True if the QuantumState objects are equal, False otherwise. """ return self.state_op == Qstate.state_op - - def __add__(self, - Qstate: "QuantumState" - ) -> "QuantumState": - """ - Add to this QuantumState another QuantumState by summing + + def __add__(self, Qstate: "QuantumState") -> "QuantumState": + """ + Add to this QuantumState another QuantumState by summing the respective state_op (PauliwordOp representing the state). Args: @@ -1749,10 +1892,8 @@ def __add__(self, new_state = self.state_op + Qstate.state_op return QuantumState(new_state.X_block, new_state.coeff_vec) - def __radd__(self, - add_obj: Union[int, "QuantumState"] - ) -> "QuantumState": - """ + def __radd__(self, add_obj: Union[int, "QuantumState"]) -> "QuantumState": + """ Allows use of sum() over a list of PauliwordOps. Args: @@ -1765,12 +1906,10 @@ def __radd__(self, return self else: return self + add_obj - - def __sub__(self, - Qstate: "QuantumState" - ) -> "QuantumState": - """ - Subtract from this QuantumState another QuantumState by subtracting + + def __sub__(self, Qstate: "QuantumState") -> "QuantumState": + """ + Subtract from this QuantumState another QuantumState by subtracting the respective state_op (PauliwordOp representing the state). Args: @@ -1781,13 +1920,13 @@ def __sub__(self, """ new_state_op = self.state_op - Qstate.state_op return QuantumState(new_state_op.X_block, new_state_op.coeff_vec) - - def __mul__(self, - mul_obj: Union["QuantumState", PauliwordOp] - ) -> Union["QuantumState", complex]: + + def __mul__( + self, mul_obj: Union["QuantumState", PauliwordOp] + ) -> Union["QuantumState", complex]: """ Right multiplication of a bra QuantumState by either a ket QuantumState or PauliwordOp. - + Args: mul_obj (Union["QuantumState", PauliwordOp]): The object to multiply with. @@ -1796,14 +1935,16 @@ def __mul__(self, - new_bra_state (QuantumState): when mul_obj is a PauliwordOp """ if isinstance(mul_obj, Number): - return QuantumState(self.state_matrix, self.state_op.coeff_vec*mul_obj) - - assert(self.n_qubits == mul_obj.n_qubits), 'Multiplication object defined for different number of qubits' - assert(self.vec_type=='bra'), 'Cannot multiply a ket from the right' - + return QuantumState(self.state_matrix, self.state_op.coeff_vec * mul_obj) + + assert ( + self.n_qubits == mul_obj.n_qubits + ), "Multiplication object defined for different number of qubits" + assert self.vec_type == "bra", "Cannot multiply a ket from the right" + if isinstance(mul_obj, QuantumState): - assert(mul_obj.vec_type=='ket'), 'Cannot multiply a bra with another bra' - inner_product=0 + assert mul_obj.vec_type == "ket", "Cannot multiply a bra with another bra" + inner_product = 0 # set left state to be smallest in number of bitstrings making loop short! if self.state_op.n_terms < mul_obj.n_terms: @@ -1822,20 +1963,20 @@ def __mul__(self, elif isinstance(mul_obj, PauliwordOp): new_state_op = self.state_op * mul_obj - new_state_op.coeff_vec*=((-1j)**new_state_op.Y_count) + new_state_op.coeff_vec *= (-1j) ** new_state_op.Y_count new_bra_state = QuantumState( - new_state_op.X_block, - new_state_op.coeff_vec, - vec_type='bra' + new_state_op.X_block, new_state_op.coeff_vec, vec_type="bra" ) return new_bra_state.cleanup() else: - raise ValueError('Trying to multiply QuantumState by unrecognised object - must be another Quantum state or PauliwordOp') - + raise ValueError( + "Trying to multiply QuantumState by unrecognised object - must be another Quantum state or PauliwordOp" + ) + def __getitem__(self, key: Union[slice, int]) -> "QuantumState": - """ - Makes the QuantumState subscriptable - returns a QuantumState + """ + Makes the QuantumState subscriptable - returns a QuantumState constructed from the indexed rows and coefficients of the state matrix. Args: @@ -1845,25 +1986,25 @@ def __getitem__(self, key: Union[slice, int]) -> "QuantumState": QuantumState: The QuantumState object constructed from the indexed rows and coefficients. """ if isinstance(key, int): - if key<0: + if key < 0: # allow negative subscript - key+=self.n_terms - assert(key "QuantumState": - """ + """ Combines duplicate basis states, summing their coefficients. Args: @@ -1883,12 +2024,10 @@ def cleanup(self, zero_threshold=1e-15) -> "QuantumState": """ clean_state_op = self.state_op.cleanup(zero_threshold=zero_threshold) return QuantumState( - clean_state_op.X_block, - clean_state_op.coeff_vec, - vec_type=self.vec_type + clean_state_op.X_block, clean_state_op.coeff_vec, vec_type=self.vec_type ) - def sort(self, by='decreasing', key='magnitude') -> "QuantumState": + def sort(self, by="decreasing", key="magnitude") -> "QuantumState": """ Sort the terms by some key, either magnitude, weight X, Y or Z. @@ -1899,22 +2038,26 @@ def sort(self, by='decreasing', key='magnitude') -> "QuantumState": Returns: QuantumState: A new QuantumState object with sorted terms. """ - if key=='magnitude': + if key == "magnitude": sort_order = np.argsort(-abs(self.state_op.coeff_vec)) - elif key=='support': + elif key == "support": sort_order = np.argsort(-np.sum(self.state_matrix, axis=1)) else: - raise ValueError('Only permitted sort key values are magnitude or support') - if by=='increasing': + raise ValueError("Only permitted sort key values are magnitude or support") + if by == "increasing": sort_order = sort_order[::-1] - elif by!='decreasing': - raise ValueError('Only permitted sort by values are increasing or decreasing') - return QuantumState(self.state_matrix[sort_order], self.state_op.coeff_vec[sort_order]) + elif by != "decreasing": + raise ValueError( + "Only permitted sort by values are increasing or decreasing" + ) + return QuantumState( + self.state_matrix[sort_order], self.state_op.coeff_vec[sort_order] + ) def reindex(self, qubit_map: Union[List[int], Dict[int, int]]): - """ + """ Re-index qubit labels. - For example, can specify a dictionary {0:2, 2:3, 3:0} mapping qubits + For example, can specify a dictionary {0:2, 2:3, 3:0} mapping qubits to their new positions or a list [2,3,0] will achieve the same result. Args: @@ -1930,17 +2073,21 @@ def reindex(self, qubit_map: Union[List[int], Dict[int, int]]): old_indices, new_indices = zip(*qubit_map.items()) old_set, new_set = set(old_indices), set(new_indices) setdiff = old_set.difference(new_set) - assert len(new_indices) == len(new_set), 'Duplicated index' - assert len(setdiff) == 0, f'Assignment conflict: indices {setdiff} cannot be mapped.' - + assert len(new_indices) == len(new_set), "Duplicated index" + assert ( + len(setdiff) == 0 + ), f"Assignment conflict: indices {setdiff} cannot be mapped." + # map corresponding columns in the state matrix to their new positions new_state_matrix = self.state_matrix.copy() - new_state_matrix[:,old_indices] = new_state_matrix[:,new_indices] - - return QuantumState(new_state_matrix, self.state_op.coeff_vec, vec_type=self.vec_type) + new_state_matrix[:, old_indices] = new_state_matrix[:, new_indices] + + return QuantumState( + new_state_matrix, self.state_op.coeff_vec, vec_type=self.vec_type + ) def sectors_present(self, symmetry): - """ + """ Return the sectors present within the QuantumState w.r.t. a IndependentOp. Args: @@ -1956,42 +2103,44 @@ def sectors_present(self, symmetry): @cached_property def normalize(self): - """ + """ Normalize a state by dividing through its norm. Returns: self (QuantumState): The normalized QuantumState. """ - coeff_vector = self.state_op.coeff_vec/np.linalg.norm(self.state_op.coeff_vec) + coeff_vector = self.state_op.coeff_vec / np.linalg.norm(self.state_op.coeff_vec) return QuantumState(self.state_matrix, coeff_vector, vec_type=self.vec_type) @cached_property def normalize_counts(self): - """ - Normalize a state by dividing through by the sum of coefficients and taking its square + """ + Normalize a state by dividing through by the sum of coefficients and taking its square root. This normalization is faithful to the probability distribution one might obtain from quantum circuit sampling. A subtle difference, but important! Returns: self (QuantumState): The normalized QuantumState. """ - coeff_vector = np.sqrt(self.state_op.coeff_vec/np.sum(self.state_op.coeff_vec)) + coeff_vector = np.sqrt( + self.state_op.coeff_vec / np.sum(self.state_op.coeff_vec) + ) return QuantumState(self.state_matrix, coeff_vector, vec_type=self.vec_type) - + @cached_property def dagger(self) -> "QuantumState": """ Returns: conj_state (QuantumState): The Hermitian conjugated state i.e. bra -> ket, ket -> bra. """ - if self.vec_type == 'ket': - new_type = 'bra' + if self.vec_type == "ket": + new_type = "bra" else: - new_type = 'ket' + new_type = "ket" conj_state = QuantumState( - state_matrix = self.state_matrix, - coeff_vector = self.state_op.coeff_vec.conjugate(), - vec_type = new_type + state_matrix=self.state_matrix, + coeff_vector=self.state_op.coeff_vec.conjugate(), + vec_type=new_type, ) return conj_state @@ -2009,13 +2158,16 @@ def to_sparse_matrix(self): nonzero_indices = binary_array_to_int(self.state_matrix) sparse_Qstate = csr_matrix( - (self.state_op.coeff_vec, (nonzero_indices, np.zeros_like(nonzero_indices))), - shape = (2**self.n_qubits, 1), - dtype=np.complex128 + ( + self.state_op.coeff_vec, + (nonzero_indices, np.zeros_like(nonzero_indices)), + ), + shape=(2**self.n_qubits, 1), + dtype=np.complex128, ) - if self.vec_type == 'bra': + if self.vec_type == "bra": # conjugate has already taken place, just need to make into row vector - sparse_Qstate= sparse_Qstate.reshape([1,-1]) + sparse_Qstate = sparse_Qstate.reshape([1, -1]) return sparse_Qstate def _is_normalized(self) -> bool: @@ -2032,7 +2184,9 @@ def _is_normalized(self) -> bool: else: return True - def sample_state(self, n_samples: int, return_normalized: bool=False) -> "QuantumState": + def sample_state( + self, n_samples: int, return_normalized: bool = False + ) -> "QuantumState": """ Method to sample given quantum state in computational basis. Get an array of bitstrings and counts as output. @@ -2047,39 +2201,42 @@ def sample_state(self, n_samples: int, return_normalized: bool=False) -> "Quantu """ if not self._is_normalized(): - raise ValueError('should not sample state that is not normalized') + raise ValueError("should not sample state that is not normalized") - counter = np.random.multinomial(n_samples, np.abs(self.state_op.coeff_vec)**2) + counter = np.random.multinomial(n_samples, np.abs(self.state_op.coeff_vec) ** 2) if return_normalized: # normalize counter (note counter will be real and positive) - counter = np.sqrt(counter /n_samples) + counter = np.sqrt(counter / n_samples) # NOTE this is NOT the same as normalizing the state using np.linalg.norm! - samples_as_coeff_state = QuantumState(self.state_matrix, - counter, - vec_type=self.vec_type) ## gives counts as coefficients! + samples_as_coeff_state = QuantumState( + self.state_matrix, counter, vec_type=self.vec_type + ) ## gives counts as coefficients! return samples_as_coeff_state @cached_property def to_dictionary(self) -> Dict[str, complex]: - """ + """ Returns: dict: The QuantumState represented as a dictionary. """ state_to_convert = self.cleanup() state_dict = dict( zip( - [''.join([str(i) for i in row]) for row in state_to_convert.state_matrix], - state_to_convert.state_op.coeff_vec + [ + "".join([str(i) for i in row]) + for row in state_to_convert.state_matrix + ], + state_to_convert.state_op.coeff_vec, ) ) return state_dict @classmethod - def from_dictionary(cls, - state_dict: Dict[str, Union[complex, Tuple[float, float]]] - ) -> "QuantumState": - """ + def from_dictionary( + cls, state_dict: Dict[str, Union[complex, Tuple[float, float]]] + ) -> "QuantumState": + """ Initialize a QuantumState from a dictionary of the form {'1101':a, '0110':b, '1010':c, ...}. This is useful for converting the measurement output of a quantum circuit to a QuantumState object for further manipulation/bootstrapping. @@ -2092,27 +2249,30 @@ def from_dictionary(cls, bin_strings, coeff_vector = zip(*state_dict.items()) coeff_vector = np.array(coeff_vector) - if len(coeff_vector.shape)==2: + if len(coeff_vector.shape) == 2: # if coeff_vec supplied as list of tuples (real, imag) then converts to single complex vector - assert(coeff_vector.shape[1]==2), 'Only tuples of size two allowed (real and imaginary components)' - coeff_vector = coeff_vector[:,0] + 1j*coeff_vector[:,1] + assert ( + coeff_vector.shape[1] == 2 + ), "Only tuples of size two allowed (real and imaginary components)" + coeff_vector = coeff_vector[:, 0] + 1j * coeff_vector[:, 1] coeff_vector = np.array(coeff_vector) state_matrix = np.array([[int(i) for i in bstr] for bstr in bin_strings]) return cls(state_matrix, coeff_vector) @classmethod - def from_array(cls, - statevector: np.array, - threshold: float =1e-15, - ) -> "QuantumState": - """ + def from_array( + cls, + statevector: np.array, + threshold: float = 1e-15, + ) -> "QuantumState": + """ Initialize a QubitState from a vector of 2^N elements over N qubits - + Args: statevector (np.array): numpy array of quantum state (size 2^N by 1) threshold (float): threshold to determine zero amplitudes (absolute value) - + Returns: Qstate (QuantumState): a QuantumState object @@ -2123,34 +2283,42 @@ def from_array(cls, >> 0.5773502692 |000> + 0.8164965809 |101> """ - assert(((len(statevector.shape)==2) and (1 in statevector.shape))), 'state must be a bra (row) or ket (column) vector' + assert (len(statevector.shape) == 2) and ( + 1 in statevector.shape + ), "state must be a bra (row) or ket (column) vector" - vec_type = 'ket' + vec_type = "ket" if statevector.shape[0] == 1: - vec_type= 'bra' + vec_type = "bra" statevector = statevector.reshape([-1]) N = np.log2(statevector.shape[0]) - assert (N - int(N) == 0), 'the statevector dimension is not a power of 2' + assert N - int(N) == 0, "the statevector dimension is not a power of 2" if not np.isclose(np.linalg.norm(statevector), 1): - warnings.warn(f'statevector is not normalized') + warnings.warn(f"statevector is not normalized") N = int(N) non_zero = np.where(abs(statevector) >= threshold)[0] # build binary states of non_zero terms - if N<64: - state_matrix = (((non_zero[:, None] & (1 << np.arange(N))[::-1])) > 0).astype(int) + if N < 64: + state_matrix = ( + ((non_zero[:, None] & (1 << np.arange(N))[::-1])) > 0 + ).astype(int) else: - state_matrix = (((non_zero[:, None] & (1 << np.arange(N, dtype=object))[::-1])) > 0).astype(int) + state_matrix = ( + ((non_zero[:, None] & (1 << np.arange(N, dtype=object))[::-1])) > 0 + ).astype(int) coeff_vector = statevector[non_zero] Qstate = cls(state_matrix, coeff_vector, vec_type=vec_type) return Qstate - def measure_state_in_computational_basis(self, P_op: PauliwordOp) -> Tuple["QuantumState", PauliwordOp]: + def measure_state_in_computational_basis( + self, P_op: PauliwordOp + ) -> Tuple["QuantumState", PauliwordOp]: """ Perform change of basis to measure input Pauli operator in the computational basis @@ -2168,20 +2336,21 @@ def measure_state_in_computational_basis(self, P_op: PauliwordOp) -> Tuple["Quan psi_new_basis (QuantumState): quantum state in new basis Z_new (PauliwordOp): operator to measure in new basis (composed of only I,Z pauli matrices) """ - assert self.vec_type == 'ket', 'cannot perform change of basis on bra' + assert self.vec_type == "ket", "cannot perform change of basis on bra" U = change_of_basis_XY_to_Z(P_op) Z_new = U * P_op * U.dagger - psi_new_basis = U*self + psi_new_basis = U * self return psi_new_basis, Z_new - def plot_state(self, - logscale:bool = False, - probability_threshold:float=None, - binary_xlabels = False, - dpi:int=100 - ): + def plot_state( + self, + logscale: bool = False, + probability_threshold: float = None, + binary_xlabels=False, + dpi: int = 100, + ): """ Plot the probabilities of the quantum state. @@ -2194,11 +2363,13 @@ def plot_state(self, Returns: matplotlib.axes.Axes: The plot axes. """ - assert self._is_normalized(), 'should only plot normalized quantum states' + assert self._is_normalized(), "should only plot normalized quantum states" # clean duplicate states and set amplitdue threshold if probability_threshold is not None: - assert probability_threshold>=0 and probability_threshold<=1, 'Probability threshold is a number between 0 and 1.' + assert ( + probability_threshold >= 0 and probability_threshold <= 1 + ), "Probability threshold is a number between 0 and 1." zero_threshold = np.sqrt(probability_threshold) else: zero_threshold = None @@ -2213,12 +2384,15 @@ def plot_state(self, # x_binary_ints = q_state.state_matrix @ (1 << np.arange(q_state.state_matrix.shape[1], dtype=object)[::-1]) x_binary_ints = binary_array_to_int(q_state.state_matrix) - if prob.shape[0]<2**8: + if prob.shape[0] < 2**8: # bar chart ax.bar(x_binary_ints, prob, width=1, edgecolor="white", linewidth=0.8) if binary_xlabels: - ax.set_xticks(x_binary_ints, labels=[np.binary_repr(x, self.n_qubits) for x in x_binary_ints]) - plt.xticks(rotation = 90) + ax.set_xticks( + x_binary_ints, + labels=[np.binary_repr(x, self.n_qubits) for x in x_binary_ints], + ) + plt.xticks(rotation=90) else: ax.set_xticks(x_binary_ints, labels=x_binary_ints.astype(str)) else: @@ -2227,17 +2401,18 @@ def plot_state(self, x_data = x_binary_ints[sort_inds] y_data = prob[sort_inds] ax.plot(x_data, y_data) - - ax.set(xlabel='binary output', ylabel='probability amplitude') - - + + ax.set(xlabel="binary output", ylabel="probability amplitude") + if logscale: - ax.set_yscale('log') + ax.set_yscale("log") - return (ax) + return ax -def get_PauliwordOp_projector(projector: Union[str, List[str], np.array]) -> "PauliwordOp": +def get_PauliwordOp_projector( + projector: Union[str, List[str], np.array] +) -> "PauliwordOp": """ Build PauliwordOp projector onto different qubit states. Using I to leave state unchanged and 0,1,+,-,*,% to fix qubit. @@ -2263,26 +2438,41 @@ def get_PauliwordOp_projector(projector: Union[str, List[str], np.array]) -> "Pa projector = np.array(list(projector)) else: projector = np.asarray(projector) - basis_dict = {'I':1, - '0':0, '1':1, - '+':0, '-':1, - '*':0, '%':1} - assert len(projector.shape) == 1, 'projector can only be defined over a single string or single list of strings (each a single letter)' - assert set(projector).issubset(list(basis_dict.keys())), 'unknown qubit state (must be I,X,Y,Z basis)' - + basis_dict = {"I": 1, "0": 0, "1": 1, "+": 0, "-": 1, "*": 0, "%": 1} + assert ( + len(projector.shape) == 1 + ), "projector can only be defined over a single string or single list of strings (each a single letter)" + assert set(projector).issubset( + list(basis_dict.keys()) + ), "unknown qubit state (must be I,X,Y,Z basis)" N_qubits = len(projector) - qubit_inds_to_fix = np.where(projector!='I')[0] + qubit_inds_to_fix = np.where(projector != "I")[0] N_qubits_fixed = len(qubit_inds_to_fix) - state_sign = np.array([basis_dict[projector[active_ind]] for active_ind in qubit_inds_to_fix]) + state_sign = np.array( + [basis_dict[projector[active_ind]] for active_ind in qubit_inds_to_fix] + ) if N_qubits_fixed < 64: - binary_vec = (((np.arange(2 ** N_qubits_fixed).reshape([-1, 1]) & (1 << np.arange(N_qubits_fixed))[ - ::-1])) > 0).astype(int) + binary_vec = ( + ( + ( + np.arange(2**N_qubits_fixed).reshape([-1, 1]) + & (1 << np.arange(N_qubits_fixed))[::-1] + ) + ) + > 0 + ).astype(int) else: - binary_vec = (((np.arange(2 ** N_qubits_fixed, dtype=object).reshape([-1, 1]) & (1 << np.arange(N_qubits_fixed, - dtype=object))[ - ::-1])) > 0).astype(int) + binary_vec = ( + ( + ( + np.arange(2**N_qubits_fixed, dtype=object).reshape([-1, 1]) + & (1 << np.arange(N_qubits_fixed, dtype=object))[::-1] + ) + ) + > 0 + ).astype(int) # # assign a sign only to 'active positions' (0 in binary not relevent) # sign_from_binary = binary_vec * state_sign @@ -2292,9 +2482,9 @@ def get_PauliwordOp_projector(projector: Union[str, List[str], np.array]) -> "Pa # # sign = np.product(sign_from_binary, axis=1) - sign = (-1)**((binary_vec@state_sign.T)%2) + sign = (-1) ** ((binary_vec @ state_sign.T) % 2) - coeff = 1 / 2 ** (N_qubits_fixed) * np.ones(2 ** N_qubits_fixed) + coeff = 1 / 2 ** (N_qubits_fixed) * np.ones(2**N_qubits_fixed) sym_arr = np.zeros((coeff.shape[0], 2 * N_qubits)) # assumed in Z basis @@ -2303,22 +2493,28 @@ def get_PauliwordOp_projector(projector: Union[str, List[str], np.array]) -> "Pa ### fix for Y and X basis - X_inds_fixed = np.where(np.logical_or(projector == '+', projector == '-'))[0] + X_inds_fixed = np.where(np.logical_or(projector == "+", projector == "-"))[0] # swap Z block and X block - (sym_arr[:, X_inds_fixed], - sym_arr[:, X_inds_fixed+N_qubits]) = (sym_arr[:, X_inds_fixed+N_qubits], - sym_arr[:, X_inds_fixed].copy()) + (sym_arr[:, X_inds_fixed], sym_arr[:, X_inds_fixed + N_qubits]) = ( + sym_arr[:, X_inds_fixed + N_qubits], + sym_arr[:, X_inds_fixed].copy(), + ) # copy Z block into X block - Y_inds_fixed = np.where(np.logical_or(projector == '*', projector == '%'))[0] + Y_inds_fixed = np.where(np.logical_or(projector == "*", projector == "%"))[0] sym_arr[:, Y_inds_fixed] = sym_arr[:, Y_inds_fixed + N_qubits] projector = PauliwordOp(sym_arr, coeff * sign) return projector -def get_ij_operator(i:int, j:int, n_qubits:int, - binary_vec:np.ndarray=None, - return_operator:bool=True) -> Union["PauliwordOp", Tuple[np.ndarray, np.ndarray]]: + +def get_ij_operator( + i: int, + j: int, + n_qubits: int, + binary_vec: np.ndarray = None, + return_operator: bool = True, +) -> Union["PauliwordOp", Tuple[np.ndarray, np.ndarray]]: """ Get the Pauli operator for the projector: |i> 30: - raise ValueError('Too many qubits, might run into memory limitations.') + raise ValueError("Too many qubits, might run into memory limitations.") if binary_vec is None: binary_vec = ( - ((np.arange(2 ** n_qubits).reshape([-1, 1]) & - (1 << np.arange(n_qubits))[::-1])) > 0 + ( + ( + np.arange(2**n_qubits).reshape([-1, 1]) + & (1 << np.arange(n_qubits))[::-1] + ) + ) + > 0 ).astype(bool) - #### LONG form below # left = binary_vec[i] # right = binary_vec[j] @@ -2373,11 +2573,27 @@ def get_ij_operator(i:int, j:int, n_qubits:int, # ij_operator = PauliwordOp(ij_symp_matrix, XZX_sign_flips / 2 ** n_qubits) # return ij_operator - if i != j: - coeffs = (((-1) ** np.sum(np.logical_and(binary_vec[i], binary_vec[j]) & binary_vec, axis=1)) - * ((-1j) ** np.sum((binary_vec[i] & binary_vec) & ~(binary_vec & binary_vec[j]), axis=1)) - * ((+1j) ** np.sum((binary_vec & binary_vec[j]) & ~(binary_vec[i] & binary_vec), axis=1))) / 2 ** n_qubits + coeffs = ( + ( + (-1) + ** np.sum( + np.logical_and(binary_vec[i], binary_vec[j]) & binary_vec, axis=1 + ) + ) + * ( + (-1j) + ** np.sum( + (binary_vec[i] & binary_vec) & ~(binary_vec & binary_vec[j]), axis=1 + ) + ) + * ( + (+1j) + ** np.sum( + (binary_vec & binary_vec[j]) & ~(binary_vec[i] & binary_vec), axis=1 + ) + ) + ) / 2**n_qubits # # use broadcasting over tile # ij_symp_matrix = np.hstack(((binary_vec[i] ^ binary_vec[j]) * np.ones([2 ** n_qubits, n_qubits], dtype=bool), @@ -2386,12 +2602,16 @@ def get_ij_operator(i:int, j:int, n_qubits:int, # ij_symp_matrix = np.hstack([np.repeat((binary_vec[i] ^ binary_vec[j])[np.newaxis, :], repeats=2**n_qubits, axis=0) # , binary_vec]) - ij_symp_matrix = np.hstack([np.tile((binary_vec[i] ^ binary_vec[j]),[2 ** n_qubits, 1]), - binary_vec]) + ij_symp_matrix = np.hstack( + [np.tile((binary_vec[i] ^ binary_vec[j]), [2**n_qubits, 1]), binary_vec] + ) else: ij_symp_matrix = np.hstack([np.zeros_like(binary_vec), binary_vec]) - coeffs = ((-1) ** np.sum(np.logical_and(binary_vec[i], binary_vec[j]) & binary_vec, axis=1)) / 2 ** n_qubits + coeffs = ( + (-1) + ** np.sum(np.logical_and(binary_vec[i], binary_vec[j]) & binary_vec, axis=1) + ) / 2**n_qubits if return_operator: ij_operator = PauliwordOp(ij_symp_matrix, coeffs) @@ -2399,24 +2619,26 @@ def get_ij_operator(i:int, j:int, n_qubits:int, else: return ij_symp_matrix, coeffs -@ray.remote(num_cpus=os.cpu_count(), - runtime_env={ - "env_vars": { - "NUMBA_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), - # "OMP_NUM_THREADS": str(os.cpu_count()), - "OMP_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), - "NUMEXPR_MAX_THREADS": str(os.cpu_count()) - } - } - ) + +@ray.remote( + num_cpus=os.cpu_count(), + runtime_env={ + "env_vars": { + "NUMBA_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), + # "OMP_NUM_THREADS": str(os.cpu_count()), + "OMP_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), + "NUMEXPR_MAX_THREADS": str(os.cpu_count()), + } + }, +) def single_term_expval(P_op: PauliwordOp, psi: QuantumState) -> float: - """ + """ Expectation value calculation for a single Pauli operator given a QuantumState psi Scales linearly in the number of basis states of psi, versus the quadratic cost of evaluating directly, taking into consideration all of the cross-terms. - Works by decomposing P = P(+) - P(-) where P(±) = (I±P)/2 projects onto the ±1-eigensapce of P. + Works by decomposing P = P(+) - P(-) where P(±) = (I±P)/2 projects onto the ±1-eigensapce of P. Args: P_op (PauliwordOp): The Pauli operator for which to calculate the expectation value. @@ -2428,21 +2650,21 @@ def single_term_expval(P_op: PauliwordOp, psi: QuantumState) -> float: Raises: AssertionError: If the supplied Pauli operator has multiple terms. """ - assert P_op.n_terms == 1, 'Supplied multiple Pauli terms.' - + assert P_op.n_terms == 1, "Supplied multiple Pauli terms." + # symplectic form of the projection operator - proj_symplectic = np.vstack([np.zeros(P_op.n_qubits*2, dtype=bool), P_op.symp_matrix]) + proj_symplectic = np.vstack( + [np.zeros(P_op.n_qubits * 2, dtype=bool), P_op.symp_matrix] + ) # function that applies the projector onto the ±1 eigenspace of P # (given by the operator (I±P)/2) and returns norm of the resulting state - norm_ev = lambda ev:np.linalg.norm( - ( - PauliwordOp(proj_symplectic, [.5,.5*ev]) * psi - ).state_op.coeff_vec + norm_ev = lambda ev: np.linalg.norm( + (PauliwordOp(proj_symplectic, [0.5, 0.5 * ev]) * psi).state_op.coeff_vec ) # difference of norms provides a metric for which eigenvalue is dominant within # the provided reference state (e.g. if inputting a ±1 eigenvector then diff=±1) - return (norm_ev(+1)**2 - norm_ev(-1)**2).real + return (norm_ev(+1) ** 2 - norm_ev(-1) ** 2).real def change_of_basis_XY_to_Z(P_op: PauliwordOp) -> PauliwordOp: @@ -2471,24 +2693,25 @@ def change_of_basis_XY_to_Z(P_op: PauliwordOp) -> PauliwordOp: n_Sdag = np.sum(Y_inds) if n_Sdag == 0: - s_dag_op = PauliwordOp.from_list(['I' * P_op.n_qubits]) + s_dag_op = PauliwordOp.from_list(["I" * P_op.n_qubits]) else: Z_block = ( - ( - np.arange(2 ** n_Sdag).reshape([-1, 1]) & - (1 << np.arange(n_Sdag))[::-1] - ) > 0).astype(bool) + (np.arange(2**n_Sdag).reshape([-1, 1]) & (1 << np.arange(n_Sdag))[::-1]) + > 0 + ).astype(bool) - zblock = np.zeros((2 ** n_Sdag, P_op.n_qubits), dtype=bool) + zblock = np.zeros((2**n_Sdag, P_op.n_qubits), dtype=bool) zblock[:, Y_inds] = Z_block - xblock = np.zeros((2 ** n_Sdag, P_op.n_qubits), dtype=bool) + xblock = np.zeros((2**n_Sdag, P_op.n_qubits), dtype=bool) symp = np.hstack((xblock, zblock)) n_Sz = np.sum(zblock, axis=1) - s_dag_op = PauliwordOp(symp, ((1 - 1j) ** (n_Sdag - n_Sz) * (1 + 1j) ** n_Sz) / 2 ** n_Sdag) + s_dag_op = PauliwordOp( + symp, ((1 - 1j) ** (n_Sdag - n_Sz) * (1 + 1j) ** n_Sz) / 2**n_Sdag + ) ### Measure XY terms (to place Hadamard gates) X_inds = np.logical_and(P_op.X_block, ~P_op.Z_block)[0] @@ -2496,20 +2719,22 @@ def change_of_basis_XY_to_Z(P_op: PauliwordOp) -> PauliwordOp: n_hadamards = np.sum(XY_inds) if n_hadamards == 0: - xy_measure = PauliwordOp.from_list(['I' * P_op.n_qubits]) + xy_measure = PauliwordOp.from_list(["I" * P_op.n_qubits]) else: - constant_H = (1 / np.sqrt(2)) ** n_hadamards * np.ones(2 ** n_hadamards) + constant_H = (1 / np.sqrt(2)) ** n_hadamards * np.ones(2**n_hadamards) X_block = ( - ( - np.arange(2 ** n_hadamards).reshape([-1, 1]) & - (1 << np.arange(n_hadamards))[::-1] - ) > 0).astype(bool) + ( + np.arange(2**n_hadamards).reshape([-1, 1]) + & (1 << np.arange(n_hadamards))[::-1] + ) + > 0 + ).astype(bool) - xblock = np.zeros((2 ** n_hadamards, P_op.n_qubits), dtype=bool) + xblock = np.zeros((2**n_hadamards, P_op.n_qubits), dtype=bool) xblock[:, XY_inds] = X_block - zblock = np.zeros((2 ** n_hadamards, P_op.n_qubits), dtype=bool) + zblock = np.zeros((2**n_hadamards, P_op.n_qubits), dtype=bool) zblock[:, XY_inds] = ~X_block symp = np.hstack((xblock, zblock)) diff --git a/symmer/operators/independent_op.py b/symmer/operators/independent_op.py index 30b4bf5..277bc4f 100644 --- a/symmer/operators/independent_op.py +++ b/symmer/operators/independent_op.py @@ -3,11 +3,17 @@ import warnings import multiprocessing as mp from symmer.operators.utils import _rref_binary, _cref_binary, check_independent -from symmer.operators import PauliwordOp, QuantumState, symplectic_to_string, single_term_expval +from symmer.operators import ( + PauliwordOp, + QuantumState, + symplectic_to_string, + single_term_expval, +) import ray + class IndependentOp(PauliwordOp): - """ + """ Special case of PauliwordOp, in which the operator terms must by algebraically independent, with all coefficients set to integers +/-1. @@ -15,13 +21,16 @@ class IndependentOp(PauliwordOp): This method determines a sequence of Clifford rotations mapping the provided stabilizers onto single-qubit Paulis (sqp), either X or Z - Note the target_sqp must be chosen BEFORE generating + Note the target_sqp must be chosen BEFORE generating the stabilizer rotations, since these will be cached. """ - def __init__(self, - symp_matrix: np.array, - coeff_vec: Union[List[complex], np.array] = None, - target_sqp: str = 'Z'): + + def __init__( + self, + symp_matrix: np.array, + coeff_vec: Union[List[complex], np.array] = None, + target_sqp: str = "Z", + ): """ Args: symp_matrix (np.array): Symplectic matrix. @@ -34,18 +43,18 @@ def __init__(self, self._check_stab() self.coeff_vec = self.coeff_vec.real.astype(int) self._check_independent() - if target_sqp in ['X', 'Z', 'Y']: + if target_sqp in ["X", "Z", "Y"]: self.target_sqp = target_sqp else: - raise ValueError('Target single-qubit Pauli not recognised - must be X or Z') + raise ValueError( + "Target single-qubit Pauli not recognised - must be X or Z" + ) # set up these attributes to later track rotations mapping stabilizers to single-qubit Pauli operators self.stabilizer_rotations = None self.used_indices = None @classmethod - def from_PauliwordOp(cls, - PwordOp: PauliwordOp - ) -> "IndependentOp": + def from_PauliwordOp(cls, PwordOp: PauliwordOp) -> "IndependentOp": """ Args: PwordOp (PauliwordOp): Pauli operator to be used to form the Independent Operator. @@ -56,10 +65,9 @@ def from_PauliwordOp(cls, return cls(PwordOp.symp_matrix, PwordOp.coeff_vec) @classmethod - def from_list(cls, - pauli_terms :List[str], - coeff_vec: List[complex] = None - ) -> "IndependentOp": + def from_list( + cls, pauli_terms: List[str], coeff_vec: List[complex] = None + ) -> "IndependentOp": """ Args: pauli_terms (List[str]): List of Pauli Terms. @@ -72,15 +80,13 @@ def from_list(cls, return cls.from_PauliwordOp(PwordOp) @classmethod - def from_dictionary(cls, - operator_dict: Dict[str, complex] - ) -> "IndependentOp": - """ + def from_dictionary(cls, operator_dict: Dict[str, complex]) -> "IndependentOp": + """ Initialize a PauliwordOp from its dictionary representation {pauli:coeff, ...} Args: operator_dict (Dict[str, complex]): Dictionary representation of IndependentOp - + Return: Independent Operator """ @@ -88,14 +94,15 @@ def from_dictionary(cls, return cls.from_PauliwordOp(PwordOp) @classmethod - def symmetry_generators(cls, - PwordOp: PauliwordOp, - commuting_override:bool=False, - largest_clique = False - ) -> "IndependentOp": - """ + def symmetry_generators( + cls, + PwordOp: PauliwordOp, + commuting_override: bool = False, + largest_clique=False, + ) -> "IndependentOp": + """ Identify a symmetry basis for the supplied Pauli operator with - symplectic representation M = [ X | Z ]. We perform columnwise + symplectic representation M = [ X | Z ]. We perform columnwise Gaussian elimination to yield the matrix [ Z | X ] [ R ] @@ -103,9 +110,9 @@ def symmetry_generators(cls, [ I ] [ Q ] Indexing the zero columns of R with i, we form the matrix - - S^T = [ Q_i1 | ... | Q_iM ] - + + S^T = [ Q_i1 | ... | Q_iM ] + and conclude that S is the symplectic representation of the symmetry basis. This holds since MΩS^T=0 by construction, which implies commutativity. @@ -121,12 +128,19 @@ def symmetry_generators(cls, Symplectic representation of the symmetry basis. """ # swap order of XZ blocks in symplectic matrix to ZX - to_reduce = np.vstack([np.hstack([PwordOp.Z_block, PwordOp.X_block]), np.eye(2*PwordOp.n_qubits, dtype=bool)]) + to_reduce = np.vstack( + [ + np.hstack([PwordOp.Z_block, PwordOp.X_block]), + np.eye(2 * PwordOp.n_qubits, dtype=bool), + ] + ) cref_matrix = _cref_binary(to_reduce) - S_symp = cref_matrix[PwordOp.n_terms:,np.all(~cref_matrix[:PwordOp.n_terms], axis=0)].T + S_symp = cref_matrix[ + PwordOp.n_terms :, np.all(~cref_matrix[: PwordOp.n_terms], axis=0) + ].T S = cls(S_symp, np.ones(S_symp.shape[0])) - if S.n_terms==0: - warnings.warn('The input PauliwordOp has no Z2 symmetries.') + if S.n_terms == 0: + warnings.warn("The input PauliwordOp has no Z2 symmetries.") return S # raise RuntimeError('The input PauliwordOp has no Z2 symmetries.') if np.all(S.adjacency_matrix) or commuting_override: @@ -135,61 +149,64 @@ def symmetry_generators(cls, # if any of the stabilizers are not mutually commuting, take the largest commuting subset if S.n_terms < 10 or largest_clique: # expensive clique cover finding optimal commuting subset - S_commuting = S.largest_clique(edge_relation='C') + S_commuting = S.largest_clique(edge_relation="C") else: # greedy graph-colouring approach when symmetry basis is large - S_commuting = S.clique_cover(edge_relation='C')[0] - warnings.warn('Greedy method may identify non-optimal commuting symmetry terms; might be able to taper again.') - - return cls(S_commuting.symp_matrix, np.ones(S_commuting.n_terms, dtype=complex)) + S_commuting = S.clique_cover(edge_relation="C")[0] + warnings.warn( + "Greedy method may identify non-optimal commuting symmetry terms; might be able to taper again." + ) + + return cls( + S_commuting.symp_matrix, np.ones(S_commuting.n_terms, dtype=complex) + ) def _check_stab(self) -> None: - """ + """ Checks the stabilizer coefficients are +/-1 """ - if not set(self.coeff_vec).issubset({0, +1,-1}): - raise ValueError(f'Stabilizer coefficients not +/-1: {self.coeff_vec}') - + if not set(self.coeff_vec).issubset({0, +1, -1}): + raise ValueError(f"Stabilizer coefficients not +/-1: {self.coeff_vec}") + def _check_independent(self) -> None: - """ + """ Check the supplied stabilizers are algebraically independent """ if not check_independent(self): # there is a dependent row - raise ValueError('The supplied stabilizers are not independent') + raise ValueError("The supplied stabilizers are not independent") def __str__(self) -> str: - """ - Defines the print behaviour of IndependentOp - + """ + Defines the print behaviour of IndependentOp - returns the operator in an easily readable format Returns: out_string (str): human-readable IndependentOp string """ - out_string = '' + out_string = "" for pauli_vec, coeff in zip(self.symp_matrix, self.coeff_vec): p_string = symplectic_to_string(pauli_vec) - out_string += (f'{coeff} {p_string} \n') + out_string += f"{coeff} {p_string} \n" return out_string[:-2] def __repr__(self) -> str: return str(self) - + def __add__(self, Pword: "IndependentOp") -> "IndependentOp": summed = super().__add__(Pword) return self.from_PauliwordOp(summed) - def _rotate_by_single_Pword(self, - Pword: "PauliwordOp", - angle: float = None - ) -> "IndependentOp": + def _rotate_by_single_Pword( + self, Pword: "PauliwordOp", angle: float = None + ) -> "IndependentOp": rotated_stabilizers = super()._rotate_by_single_Pword(Pword, angle) return self.from_PauliwordOp(rotated_stabilizers) - def perform_rotations(self, - rotations: List[Tuple["PauliwordOp", float]] - ) -> "PauliwordOp": - """ + def perform_rotations( + self, rotations: List[Tuple["PauliwordOp", float]] + ) -> "PauliwordOp": + """ Overwrite PauliwordOp.perform_rotations to return a IndependentOp. Args: @@ -202,7 +219,7 @@ def perform_rotations(self, return self.from_PauliwordOp(rotated_stabilizers) def _recursive_rotations(self, basis: "IndependentOp") -> None: - """ + """ Recursively rotate terms of the IndependentOp to single-qubit Pauli operators. This is only possible when the basis is mutually commuting! Else, such rotations do not exist (there is a check for this in generate_stabilizer_rotations, that wraps this method). @@ -211,11 +228,15 @@ def _recursive_rotations(self, basis: "IndependentOp") -> None: basis (IndependentOp): Basis """ # drop any term(s) that are single-qubit Pauli operators - non_sqp = np.where(np.sum(basis.symp_matrix, axis=1)!=1) - basis_non_sqp = IndependentOp(basis.symp_matrix[non_sqp], basis.coeff_vec[non_sqp]) - sqp_indices = np.where((basis - basis_non_sqp).symp_matrix)[1]%self.n_qubits - self.used_indices += np.append(sqp_indices, sqp_indices+self.n_qubits).tolist() - + non_sqp = np.where(np.sum(basis.symp_matrix, axis=1) != 1) + basis_non_sqp = IndependentOp( + basis.symp_matrix[non_sqp], basis.coeff_vec[non_sqp] + ) + sqp_indices = np.where((basis - basis_non_sqp).symp_matrix)[1] % self.n_qubits + self.used_indices += np.append( + sqp_indices, sqp_indices + self.n_qubits + ).tolist() + if basis_non_sqp.n_terms == 0: # once the basis has been fully rotated onto single-qubit Paulis, return the rotations return None @@ -227,11 +248,13 @@ def _recursive_rotations(self, basis: "IndependentOp") -> None: non_I = np.setdiff1d(np.where(pivot_row)[0], np.array(self.used_indices)) # once a Pauli operator has been selected, the least-supported qubit is chosen as pivot col_sum = np.sum(basis_non_sqp.symp_matrix, axis=0) - support = pivot_row*col_sum + support = pivot_row * col_sum pivot_point = non_I[np.argmin(support[non_I])] # define (in the symplectic form) the single-qubit Pauli we aim to rotate onto - target = np.zeros(2*self.n_qubits, dtype=int) - target[pivot_point+self.n_qubits*(-1)**(pivot_point//self.n_qubits)]=1 + target = np.zeros(2 * self.n_qubits, dtype=int) + target[ + pivot_point + self.n_qubits * (-1) ** (pivot_point // self.n_qubits) + ] = 1 # the rotation mapping onto the target Pauli is given by (target + pivot_row)%2... # this is identicial to performing a bitwise XOR operation pivot_rotation = PauliwordOp(np.bitwise_xor(target, pivot_row), [1]) @@ -239,15 +262,19 @@ def _recursive_rotations(self, basis: "IndependentOp") -> None: # perform the rotation on the full basis (the ordering of rotations is important because of this!) rotated_basis = basis_non_sqp._rotate_by_single_Pword(pivot_rotation) return self._recursive_rotations(rotated_basis) - + def generate_stabilizer_rotations(self) -> None: - """ - Find the full list of pi/2 Pauli rotations (Clifford operations) mapping this IndependentOp + """ + Find the full list of pi/2 Pauli rotations (Clifford operations) mapping this IndependentOp to single-qubit Pauli operators, for use in stabilizer subsapce projection schemes. """ - assert(self.n_terms <= self.n_qubits), 'Too many terms in basis to reduce to single-qubit Paulis' - assert(np.all(self.adjacency_matrix)), 'The basis is not commuting, hence the rotation is not possible' - + assert ( + self.n_terms <= self.n_qubits + ), "Too many terms in basis to reduce to single-qubit Paulis" + assert np.all( + self.adjacency_matrix + ), "The basis is not commuting, hence the rotation is not possible" + # ensure stabilizer_rotations and used_indices are empty before generating rotations self.stabilizer_rotations = [] self.used_indices = [] @@ -260,26 +287,27 @@ def generate_stabilizer_rotations(self) -> None: # now that the basis consists of single-qubit Paulis we may map to the target X,Y or Z for P in rotated_basis: # index in the X block: - sqp_index = np.where(P.symp_matrix[0])[0][0]%self.n_qubits - target = np.zeros(2*self.n_qubits, dtype=int) - if self.target_sqp in ['X','Y']: + sqp_index = np.where(P.symp_matrix[0])[0][0] % self.n_qubits + target = np.zeros(2 * self.n_qubits, dtype=int) + if self.target_sqp in ["X", "Y"]: target[sqp_index] = 1 - if self.target_sqp in ['Y','Z']: - target[sqp_index+self.n_qubits] = 1 + if self.target_sqp in ["Y", "Z"]: + target[sqp_index + self.n_qubits] = 1 R_symp = np.bitwise_xor(target, P.symp_matrix[0]) # the rotation will be identity if already the target_sqp if np.any(R_symp): # therefore, only append nontrivial rotations - self.stabilizer_rotations.append((PauliwordOp(R_symp, [1]),None)) - - def update_sector(self, - ref_state: Union[List[int], np.array, QuantumState], - threshold: float = 0.5 - ) -> None: - """ - Given the specified reference state, e.g. Hartree-Fock |1...10...0>, + self.stabilizer_rotations.append((PauliwordOp(R_symp, [1]), None)) + + def update_sector( + self, + ref_state: Union[List[int], np.array, QuantumState], + threshold: float = 0.5, + ) -> None: + """ + Given the specified reference state, e.g. Hartree-Fock |1...10...0>, determine the corresponding sector by measuring the stabilizers. - will also accept a superposition of basis states, in which case it will + will also accept a superposition of basis states, in which case it will identify the dominant sector therein, but note it will ascribe a zero assignment if there is not sufficient evidence to fix a +-1 eigenvalue. @@ -289,31 +317,35 @@ def update_sector(self, """ if not isinstance(ref_state, QuantumState): ref_state = QuantumState(ref_state) - assert ref_state._is_normalized(), 'Reference state is not normalized.' - + assert ref_state._is_normalized(), "Reference state is not normalized." + ### update the stabilizers assignments in parallel # with mp.Pool(mp.cpu_count()) as pool: # self.coeff_vec = np.array( # list(pool.starmap(assign_value, [(S, ref_state, threshold) for S in self])) # ) ref_state_ray_store = ray.put(ref_state) - self.coeff_vec = np.array(ray.get( - [single_term_expval.remote(S, ref_state_ray_store) for S in self])) + self.coeff_vec = np.array( + ray.get([single_term_expval.remote(S, ref_state_ray_store) for S in self]) + ) # set anything below threshold to be zero - self.coeff_vec[np.abs(self.coeff_vec) "IndependentOp": - """ + """ Returns the rotated single-qubit Pauli stabilizers. - Returns: + Returns: Rotated single-qubit Pauli stabilizers. """ self.generate_stabilizer_rotations() @@ -321,11 +353,9 @@ def rotate_onto_single_qubit_paulis(self) -> "IndependentOp": return self.perform_rotations(self.stabilizer_rotations) else: return self - - def __getitem__(self, - key: Union[slice, int] - ) -> "IndependentOp": - """ + + def __getitem__(self, key: Union[slice, int]) -> "IndependentOp": + """ Makes the IndependentOp subscriptable - returns a IndependentOp constructed from the indexed row and coefficient from the symplectic matrix. @@ -339,7 +369,7 @@ def __getitem__(self, if key < 0: # allow negative subscript key += self.n_terms - assert (key < self.n_terms), 'Index out of range' + assert key < self.n_terms, "Index out of range" mask = [key] elif isinstance(key, slice): start, stop = key.start, key.stop @@ -351,14 +381,16 @@ def __getitem__(self, elif isinstance(key, (list, np.ndarray)): mask = np.asarray(key) else: - raise ValueError('Unrecognised input, must be an integer, slice, list or np.array') + raise ValueError( + "Unrecognised input, must be an integer, slice, list or np.array" + ) symp_items = self.symp_matrix[mask] coeff_items = self.coeff_vec[mask] return IndependentOp(symp_items, coeff_items) def __iter__(self): - """ + """ Makes a PauliwordOp instance iterable. Returns: @@ -370,7 +402,7 @@ def __iter__(self): def assign_value(S: PauliwordOp, ref_state: QuantumState, threshold: float) -> int: """ Measure expectation value of stabilizer on input reference state. - Args: + Args: S (PauliwordOp): Stabilizer. ref_state (QuantumState): Reference State. threshold (float): Threshold Value of expectation value. @@ -379,7 +411,7 @@ def assign_value(S: PauliwordOp, ref_state: QuantumState, threshold: float) -> i Expectation Value (int) of stabilizer on input reference state. """ expval = single_term_expval(S, ref_state) - # if this expval exceeds some predefined threshold then assign the corresponding + # if this expval exceeds some predefined threshold then assign the corresponding # ±1 eigenvalue. Otherwise, return 0 as insufficient evidence to fix the value. if abs(expval) > threshold: return int(np.sign(expval)) diff --git a/symmer/operators/noncontextual_op.py b/symmer/operators/noncontextual_op.py index eff8eda..9199eec 100644 --- a/symmer/operators/noncontextual_op.py +++ b/symmer/operators/noncontextual_op.py @@ -16,40 +16,39 @@ import ray from symmer.utils import random_anitcomm_2n_1_PauliwordOp + class NoncontextualOp(PauliwordOp): - """ + """ Class for representing noncontextual Hamiltonians - Noncontextual Hamiltonians are precisely those whose terms may be reconstructed - under the Jordan product (AB = {A, B}/2) from a generating set of the form + Noncontextual Hamiltonians are precisely those whose terms may be reconstructed + under the Jordan product (AB = {A, B}/2) from a generating set of the form G ∪ {C_1, ..., C_M} where {C_i, C_j}=0 for i != j and G commutes universally. - Refer to https://arxiv.org/abs/1904.02260 for further details. - + Refer to https://arxiv.org/abs/1904.02260 for further details. + Attributes: - up_method (str): + up_method (str): """ - up_method = 'seq_rot' - def __init__(self, - symp_matrix, - coeff_vec - ): + up_method = "seq_rot" + + def __init__(self, symp_matrix, coeff_vec): """ Args: symp_matrix (np.array): Symplectic matrix. coeff_vec (np.array): Coefficient Vector. """ super().__init__(symp_matrix, coeff_vec) - assert(self.is_noncontextual), 'Specified operator is contextual.' + assert self.is_noncontextual, "Specified operator is contextual." # extract the symmetry generating set G and clique operator C(r) self.noncontextual_generators() # Reconstruct the noncontextual Hamiltonian into its G and C(r) components self.noncontextual_reconstruction() - + @classmethod def from_PauliwordOp(cls, H) -> "NoncontextualOp": - """ - For convenience, initialize from an existing PauliwordOp. + """ + For convenience, initialize from an existing PauliwordOp. Args: H: A PauliwordOp object representing the operator. @@ -57,23 +56,21 @@ def from_PauliwordOp(cls, H) -> "NoncontextualOp": Returns: NoncontextualOp: A NoncontextualOp instance initialized from the given PauliwordOp. """ - noncontextual_operator = cls( - H.symp_matrix, - H.coeff_vec - ) + noncontextual_operator = cls(H.symp_matrix, H.coeff_vec) return noncontextual_operator @classmethod - def from_hamiltonian(cls, - H: PauliwordOp, - strategy: str = 'diag', - generators: PauliwordOp = None, - stabilizers: IndependentOp = None, - DFS_runtime: int = 10, - use_jordan_product = False, - override_noncontextuality_check: bool = True - ) -> "NoncontextualOp": - """ + def from_hamiltonian( + cls, + H: PauliwordOp, + strategy: str = "diag", + generators: PauliwordOp = None, + stabilizers: IndependentOp = None, + DFS_runtime: int = 10, + use_jordan_product=False, + override_noncontextuality_check: bool = True, + ) -> "NoncontextualOp": + """ Given a PauliwordOp, extract from it a noncontextual sub-Hamiltonian by the specified strategy. Args: @@ -90,27 +87,31 @@ def from_hamiltonian(cls, """ if not override_noncontextuality_check: if H.is_noncontextual: - warnings.warn('input H is already noncontextual ignoring strategy') + warnings.warn("input H is already noncontextual ignoring strategy") return cls.from_PauliwordOp(H) - - if strategy == 'diag': + + if strategy == "diag": return cls._diag_noncontextual_op(H) - elif strategy == 'generators': - return cls._from_generators_noncontextual_op(H, generators, use_jordan_product=use_jordan_product) - elif strategy == 'stabilizers': - return cls._from_stabilizers_noncontextual_op(H, stabilizers, use_jordan_product=use_jordan_product) - elif strategy.find('DFS') != -1: - _, strategy = strategy.split('_') + elif strategy == "generators": + return cls._from_generators_noncontextual_op( + H, generators, use_jordan_product=use_jordan_product + ) + elif strategy == "stabilizers": + return cls._from_stabilizers_noncontextual_op( + H, stabilizers, use_jordan_product=use_jordan_product + ) + elif strategy.find("DFS") != -1: + _, strategy = strategy.split("_") return cls._dfs_noncontextual_op(H, strategy=strategy, runtime=DFS_runtime) - elif strategy.find('SingleSweep') != -1: - _, strategy = strategy.split('_') + elif strategy.find("SingleSweep") != -1: + _, strategy = strategy.split("_") return cls._single_sweep_noncontextual_operator(H, strategy=strategy) else: - raise ValueError(f'Unrecognised noncontextual operator strategy {strategy}') + raise ValueError(f"Unrecognised noncontextual operator strategy {strategy}") @classmethod def _diag_noncontextual_op(cls, H: PauliwordOp) -> "NoncontextualOp": - """ + """ Return the diagonal terms of the PauliwordOp - this is the simplest noncontextual operator. Args: @@ -120,15 +121,14 @@ def _diag_noncontextual_op(cls, H: PauliwordOp) -> "NoncontextualOp": NoncontextualOp: A NoncontextualOp instance constructed from the diagonal terms of the given operator. """ mask_diag = np.where(~np.any(H.X_block, axis=1)) - noncontextual_operator = cls( - H.symp_matrix[mask_diag], - H.coeff_vec[mask_diag] - ) + noncontextual_operator = cls(H.symp_matrix[mask_diag], H.coeff_vec[mask_diag]) return noncontextual_operator @classmethod - def _dfs_noncontextual_op(cls, H: PauliwordOp, runtime=10, strategy='magnitude') -> "NoncontextualOp": - """ + def _dfs_noncontextual_op( + cls, H: PauliwordOp, runtime=10, strategy="magnitude" + ) -> "NoncontextualOp": + """ function orders operator by coeff mag then going from first term adds ops to a pauliword op ensuring it is noncontextual adds to a tracking list and then changes the original ordering so first term is now at the end @@ -147,36 +147,40 @@ def _dfs_noncontextual_op(cls, H: PauliwordOp, runtime=10, strategy='magnitude') Returns: NoncontextualOp: A NoncontextualOp instance constructed from the given operator. """ - operator = H.sort(by='magnitude') + operator = H.sort(by="magnitude") noncontextual_ops = [] - n=0 + n = 0 start_time = time() - while n < H.n_terms and time()-start_time < runtime: + while n < H.n_terms and time() - start_time < runtime: order = np.roll(np.arange(H.n_terms), -n) ordered_operator = PauliwordOp( symp_matrix=operator.symp_matrix[order], - coeff_vec=operator.coeff_vec[order] + coeff_vec=operator.coeff_vec[order], ) noncontextual_operator = perform_noncontextual_sweep(ordered_operator) noncontextual_ops.append(noncontextual_operator) - n+=1 - - if strategy == 'magnitude': - noncontextual_operator = sorted(noncontextual_ops, key=lambda x:-np.sum(abs(x.coeff_vec)))[0] - elif strategy == 'largest': - noncontextual_operator = sorted(noncontextual_ops, key=lambda x:-x.n_terms)[0] + n += 1 + + if strategy == "magnitude": + noncontextual_operator = sorted( + noncontextual_ops, key=lambda x: -np.sum(abs(x.coeff_vec)) + )[0] + elif strategy == "largest": + noncontextual_operator = sorted( + noncontextual_ops, key=lambda x: -x.n_terms + )[0] else: - raise ValueError('Unrecognised noncontextual operator strategy.') + raise ValueError("Unrecognised noncontextual operator strategy.") return cls.from_PauliwordOp(noncontextual_operator) @classmethod def _diag_first_noncontextual_op(cls, H: PauliwordOp) -> "NoncontextualOp": - """ + """ Start from the diagonal noncontextual form and append additional off-diagonal contributions with respect to their coefficient magnitude. - + Args: H (PauliwordOp): PauliwordOp representing the operator. @@ -185,17 +189,19 @@ def _diag_first_noncontextual_op(cls, H: PauliwordOp) -> "NoncontextualOp": """ noncontextual_operator = cls._diag_noncontextual_op(H) # order the remaining terms by coefficient magnitude - off_diag_terms = (H - noncontextual_operator).sort(by='magnitude') + off_diag_terms = (H - noncontextual_operator).sort(by="magnitude") # append terms that do not make the noncontextual_operator contextual! for term in off_diag_terms: - if (noncontextual_operator+term).is_noncontextual: - noncontextual_operator+=term - + if (noncontextual_operator + term).is_noncontextual: + noncontextual_operator += term + return cls.from_PauliwordOp(noncontextual_operator) @classmethod - def _single_sweep_noncontextual_operator(cls, H, strategy='magnitude') -> "NoncontextualOp": - """ + def _single_sweep_noncontextual_operator( + cls, H, strategy="magnitude" + ) -> "NoncontextualOp": + """ Order the operator by some sorting key (magnitude, random or CurrentOrder) and then sweep accross the terms, appending to a growing noncontextual operator whenever possible. @@ -211,55 +217,57 @@ def _single_sweep_noncontextual_operator(cls, H, strategy='magnitude') -> "Nonco Returns: NoncontextualOp: A NoncontextualOp instance constructed from the given operator using the specified strategy. """ - if strategy=='magnitude': - operator = H.sort(by='magnitude') - elif strategy=='random': + if strategy == "magnitude": + operator = H.sort(by="magnitude") + elif strategy == "random": order = np.arange(H.n_terms) np.random.shuffle(order) - operator = PauliwordOp( - H.symp_matrix[order], - H.coeff_vec[order] - ) - elif strategy =='CurrentOrder': + operator = PauliwordOp(H.symp_matrix[order], H.coeff_vec[order]) + elif strategy == "CurrentOrder": operator = H else: - raise ValueError('Unrecognised strategy, must be one of magnitude, random or CurrentOrder') + raise ValueError( + "Unrecognised strategy, must be one of magnitude, random or CurrentOrder" + ) nc_operator = perform_noncontextual_sweep(operator) return cls.from_PauliwordOp(nc_operator) @classmethod - def _from_generators_noncontextual_op(cls, - H: PauliwordOp, generators: PauliwordOp, use_jordan_product:bool=False - ) -> "NoncontextualOp": - """ + def _from_generators_noncontextual_op( + cls, H: PauliwordOp, generators: PauliwordOp, use_jordan_product: bool = False + ) -> "NoncontextualOp": + """ Construct a noncontextual operator given a noncontextual generating set, via the Jordan product ( regular matrix product if the operators commute, and equal to zero if the operators anticommute.) Args: H (PauliwordOp): PauliwordOp representing the Hamiltonian. generators (PauliwordOp): PauliwordOp representing the noncontextual generating set. - use_jordan_product (bool, optional): Determines whether to use the Jordan product for construction. + use_jordan_product (bool, optional): Determines whether to use the Jordan product for construction. If True, the Jordan product is used. If False, an alternative strategy is used. Default is False. Returns: NoncontextualOp: A NoncontextualOp instance constructed from the given Hamiltonian and generators. """ - assert generators is not None, 'Must specify a noncontextual generating set.' - assert generators.is_noncontextual, 'Generating set is contextual.' + assert generators is not None, "Must specify a noncontextual generating set." + assert generators.is_noncontextual, "Generating set is contextual." if use_jordan_product: _, noncontextual_terms_mask = H.jordan_generator_reconstruction(generators) else: - _, noncontextual_terms_mask = H.generator_reconstruction(generators, override_independence_check=True) + _, noncontextual_terms_mask = H.generator_reconstruction( + generators, override_independence_check=True + ) return cls.from_PauliwordOp(H[noncontextual_terms_mask]) @classmethod - def random(cls, - n_qubits: int, - n_cliques:Optional[int]=3, - complex_coeffs:Optional[bool]=False, - n_commuting_terms:Optional[int]=None, - ) -> "NoncontextualOp": + def random( + cls, + n_qubits: int, + n_cliques: Optional[int] = 3, + complex_coeffs: Optional[bool] = False, + n_commuting_terms: Optional[int] = None, + ) -> "NoncontextualOp": """ Generate a random Noncontextual operator with normally distributed coefficients. Note to maximise size choose number of n_cliques to be 3 (and for 2<= n_cliques <= 5 the operator @@ -278,52 +286,79 @@ def random(cls, Returns: NoncontextualOp: A random NoncontextualOp object. """ - assert n_cliques > 1, 'number of cliques must be set to 2 or more (cannot have one anticommuting term)' + assert ( + n_cliques > 1 + ), "number of cliques must be set to 2 or more (cannot have one anticommuting term)" n_clique_qubits = int(np.ceil((n_cliques - 1) / 2)) - assert n_clique_qubits <= n_qubits, 'cannot have {n_cliques} anticommuting cliques on {n_qubits} qubits' + assert ( + n_clique_qubits <= n_qubits + ), "cannot have {n_cliques} anticommuting cliques on {n_qubits} qubits" remaining_qubits = n_qubits - n_clique_qubits if n_commuting_terms: - assert n_commuting_terms<= 2**remaining_qubits, f'cannot have {n_commuting_terms} commuting operators on {remaining_qubits} qubits' + assert ( + n_commuting_terms <= 2**remaining_qubits + ), f"cannot have {n_commuting_terms} commuting operators on {remaining_qubits} qubits" - if remaining_qubits>=1: - if n_commuting_terms==None: + if remaining_qubits >= 1: + if n_commuting_terms == None: n_commuting_terms = 2 ** (remaining_qubits) - XZ_block = (((np.arange(n_commuting_terms)[:, None] & (1 << np.arange(2 * remaining_qubits))[ - ::-1])) > 0).astype(bool) + XZ_block = ( + ( + ( + np.arange(n_commuting_terms)[:, None] + & (1 << np.arange(2 * remaining_qubits))[::-1] + ) + ) + > 0 + ).astype(bool) else: # randomly chooise Z bitstrings in symp matrix: - indices = np.unique(np.random.random_integers(0, - high=2**remaining_qubits-1, - size=10*n_commuting_terms)) + indices = np.unique( + np.random.random_integers( + 0, high=2**remaining_qubits - 1, size=10 * n_commuting_terms + ) + ) while len(indices) < n_commuting_terms: - indices = np.unique(np.append(indices, - np.unique(np.random.random_integers(0, - high=2 ** remaining_qubits - 1, - size=10*n_commuting_terms))) - ) + indices = np.unique( + np.append( + indices, + np.unique( + np.random.random_integers( + 0, + high=2**remaining_qubits - 1, + size=10 * n_commuting_terms, + ) + ), + ) + ) indices = indices[:n_commuting_terms] - XZ_block = (((indices[:, None] & (1 << np.arange(2 * remaining_qubits))[ - ::-1])) > 0).astype(bool) + XZ_block = ( + ((indices[:, None] & (1 << np.arange(2 * remaining_qubits))[::-1])) + > 0 + ).astype(bool) if n_cliques == 0: H_nc = PauliwordOp(XZ_block, np.ones(XZ_block.shape[0])) else: - AC = random_anitcomm_2n_1_PauliwordOp(n_clique_qubits, - apply_clifford=True)[:n_cliques] + AC = random_anitcomm_2n_1_PauliwordOp(n_clique_qubits, apply_clifford=True)[ + :n_cliques + ] AC.coeff_vec = np.ones_like(AC.coeff_vec) if remaining_qubits >= 1: diag_H = PauliwordOp(XZ_block, np.ones(XZ_block.shape[0])) else: - diag_H = PauliwordOp.from_list(['I' * remaining_qubits]) + diag_H = PauliwordOp.from_list(["I" * remaining_qubits]) - AC_full = PauliwordOp.from_list(['I' * remaining_qubits]).tensor(AC) - H_sym = diag_H.tensor(PauliwordOp.from_list(['I' * n_clique_qubits])) + AC_full = PauliwordOp.from_list(["I" * remaining_qubits]).tensor(AC) + H_sym = diag_H.tensor(PauliwordOp.from_list(["I" * n_clique_qubits])) H_nc = AC_full * H_sym - assert AC.n_terms * n_commuting_terms == H_nc.n_terms, 'operator not largest it can be' + assert ( + AC.n_terms * n_commuting_terms == H_nc.n_terms + ), "operator not largest it can be" coeff_vec = np.random.randn(H_nc.n_terms).astype(complex) if complex_coeffs: @@ -341,44 +376,49 @@ def random(cls, return cls(H_nc.symp_matrix, coeff_vec) @classmethod - def _from_stabilizers_noncontextual_op(cls, - H:PauliwordOp, stabilizers: IndependentOp, use_jordan_product=False - ) -> "NoncontextualOp": + def _from_stabilizers_noncontextual_op( + cls, H: PauliwordOp, stabilizers: IndependentOp, use_jordan_product=False + ) -> "NoncontextualOp": """ Args: H (PauliwordOp): The PauliwordOp representing the Hamiltonian. stabilizers (IndependentOp): The IndependentOp representing the stabilizers. - use_jordan_product (bool, optional): Determines whether to use the Jordan product for constructing generators. + use_jordan_product (bool, optional): Determines whether to use the Jordan product for constructing generators. If True, the Jordan product is used. If False, an alternative strategy is used. Default is False. Returns: NoncontextualOp: A NoncontextualOp instance constructed from the given PauliwordOp and stabilizers. """ - symmetries = IndependentOp.symmetry_generators(stabilizers, commuting_override=True) - noncon = NoncontextualOp.from_hamiltonian(symmetries, strategy='DFS_magnitude') + symmetries = IndependentOp.symmetry_generators( + stabilizers, commuting_override=True + ) + noncon = NoncontextualOp.from_hamiltonian(symmetries, strategy="DFS_magnitude") generators = noncon.symmetry_generators - if noncon.clique_operator.n_terms>0: - generators+=noncon.clique_operator - use_jordan_product=True - - return cls._from_generators_noncontextual_op(H=H, generators=generators, use_jordan_product=use_jordan_product) - - def draw_graph_structure(self, - clique_lw=1, - symmetry_lw=.25, - node_colour='black', - node_size=20, - seed=None, - axis=None, - include_symmetries=True - ): - """ + if noncon.clique_operator.n_terms > 0: + generators += noncon.clique_operator + use_jordan_product = True + + return cls._from_generators_noncontextual_op( + H=H, generators=generators, use_jordan_product=use_jordan_product + ) + + def draw_graph_structure( + self, + clique_lw=1, + symmetry_lw=0.25, + node_colour="black", + node_size=20, + seed=None, + axis=None, + include_symmetries=True, + ): + """ Draw the noncontextual graph structure. Args: - clique_lw (int, optional): Line width for non-symmetry edges. Default is 1. - symmetry_lw (float, optional): Line width for symmetry edges. Default is 0.25. - node_colour (str, optional): Color of the nodes. Default is 'black'. + clique_lw (int, optional): Line width for non-symmetry edges. Default is 1. + symmetry_lw (float, optional): Line width for symmetry edges. Default is 0.25. + node_colour (str, optional): Color of the nodes. Default is 'black'. node_size (int, optional): Size of the nodes. Default is 20. seed (int or None, optional): Random seed for layout. Default is None. axis (matplotlib.axes.Axes or None, optional): Matplotlib axis to draw the graph on. Default is None. @@ -387,24 +427,31 @@ def draw_graph_structure(self, adjmat = self.adjacency_matrix.copy() index_symmetries = np.where(np.all(adjmat, axis=1))[0] np.fill_diagonal(adjmat, False) - + G = nx.Graph() - for i,j in list(zip(*np.where(adjmat))): + for i, j in list(zip(*np.where(adjmat))): if i in index_symmetries or j in index_symmetries: if include_symmetries: - G.add_edge(i,j,color='grey',weight=symmetry_lw) + G.add_edge(i, j, color="grey", weight=symmetry_lw) else: - G.add_edge(i,j,color='black',weight=clique_lw) + G.add_edge(i, j, color="black", weight=clique_lw) pos = nx.spring_layout(G, seed=seed) edges = G.edges() - colors = [G[u][v]['color'] for u,v in edges] - weights = [G[u][v]['weight'] for u,v in edges] - nx.draw(G, pos, edge_color=colors, width=weights, - node_color=node_colour, node_size=node_size, ax=axis) + colors = [G[u][v]["color"] for u, v in edges] + weights = [G[u][v]["weight"] for u, v in edges] + nx.draw( + G, + pos, + edge_color=colors, + width=weights, + node_color=node_colour, + node_size=node_size, + ax=axis, + ) def noncontextual_generators(self) -> None: - """ + """ Find an independent generating set for the noncontextual operator. """ Z2_symmerties = IndependentOp.symmetry_generators(self, commuting_override=True) @@ -413,17 +460,22 @@ def noncontextual_generators(self) -> None: # need to account for Z2_symmerties not commuting with themselves sym_gens = self.generators # z2_mask = np.sum(sym_gens.adjacency_matrix, axis=1) == sym_gens.n_terms - z2_mask = np.sum(sym_gens.commutes_termwise(sym_gens), axis=1) == sym_gens.n_terms + z2_mask = ( + np.sum(sym_gens.commutes_termwise(sym_gens), axis=1) == sym_gens.n_terms + ) Z2_incomplete = sym_gens[z2_mask] _, missing_mask = sym_gens.generator_reconstruction(Z2_incomplete) Z2_missing = sym_gens[~missing_mask] - cover = Z2_missing.clique_cover('C') + cover = Z2_missing.clique_cover("C") clique_rep_list = [C.sort()[0] for C in cover.values()] - sym_from_cliques = sum((cover[n] - C_rep) * C_rep for n, C_rep in enumerate(clique_rep_list) if - cover[n].n_terms > 1) + sym_from_cliques = sum( + (cover[n] - C_rep) * C_rep + for n, C_rep in enumerate(clique_rep_list) + if cover[n].n_terms > 1 + ) Z2_symmerties = (sym_from_cliques + Z2_incomplete).generators _, z2_mask = self.generator_reconstruction(Z2_symmerties) @@ -432,15 +484,21 @@ def noncontextual_generators(self) -> None: remaining = self[~z2_mask] - if remaining.n_terms>0: + if remaining.n_terms > 0: ## rather than doing graph coloring (line below) - #self.decomposed = remaining.clique_cover('C') + # self.decomposed = remaining.clique_cover('C') ## use noncon structure of disjoint cliques # remaining must be disjoint union of commuting cliques... # So find unique rows of adj matrix and check there is NO overlap between them (disjoint!) adj_matrix_view = np.ascontiguousarray(remaining.adjacency_matrix).view( - np.dtype((np.void, remaining.adjacency_matrix.dtype.itemsize * remaining.adjacency_matrix.shape[1])) + np.dtype( + ( + np.void, + remaining.adjacency_matrix.dtype.itemsize + * remaining.adjacency_matrix.shape[1], + ) + ) ) re_order_indices = np.argsort(adj_matrix_view.ravel()) # sort the adj matrix and vector of coefficients accordingly @@ -449,7 +507,9 @@ def noncontextual_generators(self) -> None: diff_adjacent = np.diff(sorted_terms, axis=0) mask_unique_terms = np.append(True, np.any(diff_adjacent, axis=1)) clique_mask = sorted_terms[mask_unique_terms] - self.decomposed = {ind: remaining[c_mask] for ind, c_mask in enumerate(clique_mask)} + self.decomposed = { + ind: remaining[c_mask] for ind, c_mask in enumerate(clique_mask) + } self.n_cliques = len(self.decomposed) if self.n_cliques > 0: @@ -459,55 +519,74 @@ def noncontextual_generators(self) -> None: self.clique_operator = AntiCommutingOp.from_PauliwordOp( sum(clique_rep_list) ) - self.clique_operator.coeff_vec = np.ones_like(self.clique_operator.coeff_vec) + self.clique_operator.coeff_vec = np.ones_like( + self.clique_operator.coeff_vec + ) ## cliques can form new Z2 syms - sym_from_cliques = sum((self.decomposed[n] - C_rep) * C_rep for n, C_rep in enumerate(clique_rep_list) if - self.decomposed[n].n_terms > 1) + sym_from_cliques = sum( + (self.decomposed[n] - C_rep) * C_rep + for n, C_rep in enumerate(clique_rep_list) + if self.decomposed[n].n_terms > 1 + ) if sym_from_cliques: Z2_symmerties = (sym_from_cliques + Z2_symmerties).generators else: self.clique_operator = PauliwordOp.empty(self.n_qubits).cleanup() self.decomposed = dict() - self.n_cliques=0 + self.n_cliques = 0 self.symmetry_generators = IndependentOp.from_PauliwordOp(Z2_symmerties) _, Z2_mask = self.generator_reconstruction(Z2_symmerties) - self.decomposed['symmetry'] = self[Z2_mask] + self.decomposed["symmetry"] = self[Z2_mask] def noncontextual_reconstruction(self) -> None: - """ + """ Reconstruct the noncontextual operator in each independent basis GuCi - one for every clique. This mitigates against dependency between the symmetry generators G and the clique representatives Ci. """ noncon_generators = PauliwordOp( - np.vstack([self.symmetry_generators.symp_matrix, self.clique_operator.symp_matrix]), - np.ones(self.symmetry_generators.n_terms + self.n_cliques) + np.vstack( + [self.symmetry_generators.symp_matrix, self.clique_operator.symp_matrix] + ), + np.ones(self.symmetry_generators.n_terms + self.n_cliques), ) # Cannot simultaneously know eigenvalues of cliques so we peform a generator reconstruction # that respects the jordan product A*B = {A, B}/2, i.e. anticommuting elements are zeroed out - jordan_recon_matrix, successful = self.jordan_generator_reconstruction(noncon_generators)#, override_independence_check=True) - assert(np.all(successful)), 'The generating set is not sufficient to reconstruct the noncontextual Hamiltonian' - self.G_indices = jordan_recon_matrix[:, :self.symmetry_generators.n_terms] - self.C_indices = jordan_recon_matrix[:, self.symmetry_generators.n_terms:] + jordan_recon_matrix, successful = self.jordan_generator_reconstruction( + noncon_generators + ) # , override_independence_check=True) + assert np.all( + successful + ), "The generating set is not sufficient to reconstruct the noncontextual Hamiltonian" + self.G_indices = jordan_recon_matrix[:, : self.symmetry_generators.n_terms] + self.C_indices = jordan_recon_matrix[:, self.symmetry_generators.n_terms :] self.mask_S0 = ~np.any(self.C_indices, axis=1) self.mask_Ci = self.C_indices.astype(bool).T # individual elements of r_part commute with all of G_part - taking products over G_part with # a single element of r_part will therefore never produce a complex phase, but might result in # a sign flip that must be accounted for in the generator reconstruction: - multiply_indices = lambda inds:reduce( - lambda x,y:x*y, # pairwise multiplication of Pauli factors - noncon_generators[inds], # index the relevant noncontextual generating elements - PauliwordOp.from_list(['I'*self.n_qubits]) # initialise product with identity - ).coeff_vec[0].real + multiply_indices = ( + lambda inds: reduce( + lambda x, y: x * y, # pairwise multiplication of Pauli factors + noncon_generators[ + inds + ], # index the relevant noncontextual generating elements + PauliwordOp.from_list( + ["I" * self.n_qubits] + ), # initialise product with identity + ) + .coeff_vec[0] + .real + ) self.pauli_mult_signs = np.array( - list(map(multiply_indices,jordan_recon_matrix.astype(bool))) + list(map(multiply_indices, jordan_recon_matrix.astype(bool))) ).astype(int) - + def symmetrized_operator(self, expansion_order=1): - """ + """ Get the symmetrized noncontextual operator S_0 - sqrt(S_1^2 + .. S_M^2). In the infinite limit of expansion_order the ground state of this operator will coincide exactly with the true noncontextual operator. This is used @@ -519,35 +598,38 @@ def symmetrized_operator(self, expansion_order=1): Returns: Symmetrized noncontextual operator. """ - Si_list = [self.decomposed['symmetry']] + Si_list = [self.decomposed["symmetry"]] for i in range(self.n_cliques): - Ci = self.decomposed[i][0]; Ci.coeff_vec[0]=1 - Si = Ci*self.decomposed[i] + Ci = self.decomposed[i][0] + Ci.coeff_vec[0] = 1 + Si = Ci * self.decomposed[i] Si_list.append(Si) S = sum([Si**2 for Si in Si_list[1:]]) norm = np.linalg.norm(S.coeff_vec, ord=1) - S *= (1/norm) - I = PauliwordOp.from_list(['I'*self.n_qubits]) + S *= 1 / norm + I = PauliwordOp.from_list(["I" * self.n_qubits]) terms = [ - (I-S)**n * (-1)**n * binomial_coefficient(.5, n) - for n in range(expansion_order+1) - ] # power series expansion of the oeprator root + (I - S) ** n * (-1) ** n * binomial_coefficient(0.5, n) + for n in range(expansion_order + 1) + ] # power series expansion of the oeprator root S_root = sum(terms) * np.sqrt(norm) - + return Si_list[0] - S_root def get_symmetry_contributions(self, nu: np.array) -> float: - """ - """ + """ """ nu = np.asarray(nu) - coeff_mod = ( + coeff_mod = ( # coefficient vector whose signs we are modifying: - self.coeff_vec * + self.coeff_vec + * # sign flips from generator reconstruction: - self.pauli_mult_signs * + self.pauli_mult_signs + * # sign flips from nu assignment: - (-1)**np.count_nonzero(np.logical_and(self.G_indices==1, nu == -1), axis=1) + (-1) + ** np.count_nonzero(np.logical_and(self.G_indices == 1, nu == -1), axis=1) ) s0 = np.sum(coeff_mod[self.mask_S0]).real si = np.array([np.sum(coeff_mod[mask]).real for mask in self.mask_Ci]) @@ -559,28 +641,33 @@ def get_energy(self, nu: np.array) -> float: """ s0, si = self.get_symmetry_contributions(nu) return s0 - np.linalg.norm(si) - - def update_clique_representative_operator(self, clique_index:int = None) -> List[Tuple[PauliwordOp, float]]: + + def update_clique_representative_operator( + self, clique_index: int = None + ) -> List[Tuple[PauliwordOp, float]]: _, si = self.get_symmetry_contributions(self.symmetry_generators.coeff_vec) self.clique_operator.coeff_vec = si if clique_index is None: clique_index = 0 ( - self.mapped_clique_rep, - self.unitary_partitioning_rotations, + self.mapped_clique_rep, + self.unitary_partitioning_rotations, self.clique_normalization, - self.clique_operator - ) = self.clique_operator.unitary_partitioning(up_method=self.up_method, s_index=clique_index) - - def solve(self, - strategy: str = 'brute_force', - ref_state: np.array = None, - num_anneals:int = 1_000, - expansion_order:int = 1 - ) -> None: - """ - Minimize the classical objective function, yielding the noncontextual - ground state. This updates the coefficients of the clique representative + self.clique_operator, + ) = self.clique_operator.unitary_partitioning( + up_method=self.up_method, s_index=clique_index + ) + + def solve( + self, + strategy: str = "brute_force", + ref_state: np.array = None, + num_anneals: int = 1_000, + expansion_order: int = 1, + ) -> None: + """ + Minimize the classical objective function, yielding the noncontextual + ground state. This updates the coefficients of the clique representative operator C(r) and symmetry generators G with the optimal configuration. Note: Most QUSO functions/methods work faster than their PUSO counterparts. @@ -595,7 +682,7 @@ def solve(self, # update the symmetry generator G coefficients w.r.t. the reference state self.symmetry_generators.update_sector(ref_state) ev_assignment = self.symmetry_generators.coeff_vec - fixed_ev_mask = ev_assignment!=0 + fixed_ev_mask = ev_assignment != 0 fixed_eigvals = (ev_assignment[fixed_ev_mask]).astype(int) NC_solver = NoncontextualSolver(self, fixed_ev_mask, fixed_eigvals) # any remaining unfixed symmetry generators are solved via other means: @@ -605,31 +692,31 @@ def solve(self, NC_solver.num_anneals = num_anneals NC_solver.expansion_order = expansion_order - if strategy=='brute_force': + if strategy == "brute_force": self.energy, nu = NC_solver.energy_via_brute_force() - elif strategy=='binary_relaxation': + elif strategy == "binary_relaxation": self.energy, nu = NC_solver.energy_via_relaxation() - + else: #### qubovert strategies below this point #### # PUSO = Polynomial unconstrained spin Optimization # QUSO: Quadratic Unconstrained Spin Optimization - if strategy == 'brute_force_PUSO': - NC_solver.method = 'brute_force' - NC_solver.x = 'P' - elif strategy == 'brute_force_QUSO': - NC_solver.method = 'brute_force' - NC_solver.x = 'Q' - elif strategy == 'annealing_PUSO': - NC_solver.method = 'annealing' - NC_solver.x = 'P' - elif strategy == 'annealing_QUSO': - NC_solver.method = 'annealing' - NC_solver.x = 'Q' + if strategy == "brute_force_PUSO": + NC_solver.method = "brute_force" + NC_solver.x = "P" + elif strategy == "brute_force_QUSO": + NC_solver.method = "brute_force" + NC_solver.x = "Q" + elif strategy == "annealing_PUSO": + NC_solver.method = "annealing" + NC_solver.x = "P" + elif strategy == "annealing_QUSO": + NC_solver.method = "annealing" + NC_solver.x = "Q" else: - raise ValueError(f'Unknown optimization strategy: {strategy}') - + raise ValueError(f"Unknown optimization strategy: {strategy}") + self.energy, nu = NC_solver.energy_xUSO() # optimize the clique operator coefficients @@ -637,7 +724,9 @@ def solve(self, if self.n_cliques > 0: self.update_clique_representative_operator() - def noncon_state(self, UP_method:Optional[str]= 'LCU') -> Tuple[QuantumState, np.array]: + def noncon_state( + self, UP_method: Optional[str] = "LCU" + ) -> Tuple[QuantumState, np.array]: """ Method to generate noncontextual state for current symmetry generators assignments. Note by default UP_method is set to LCU as this avoids generating exponentially large states (which seq_rot can do!) @@ -656,14 +745,24 @@ def noncon_state(self, UP_method:Optional[str]= 'LCU') -> Tuple[QuantumState, np _, si = self.get_symmetry_contributions(nu_assignment) self.clique_operator.coeff_vec = si - assert UP_method in ['LCU', 'seq_rot'] + assert UP_method in ["LCU", "seq_rot"] - if UP_method == 'LCU': - Ps, rotations_LCU, gamma_l, AC_normed = self.clique_operator.unitary_partitioning(s_index=0, - up_method='LCU') + if UP_method == "LCU": + ( + Ps, + rotations_LCU, + gamma_l, + AC_normed, + ) = self.clique_operator.unitary_partitioning(s_index=0, up_method="LCU") else: - Ps, rotations_SEQ, gamma_l, AC_normed = self.clique_operator.unitary_partitioning(s_index=0, - up_method='seq_rot') + ( + Ps, + rotations_SEQ, + gamma_l, + AC_normed, + ) = self.clique_operator.unitary_partitioning( + s_index=0, up_method="seq_rot" + ) # choose negative value for clique operator (to minimize energy) Ps.coeff_vec[0] = -1 @@ -672,92 +771,113 @@ def noncon_state(self, UP_method:Optional[str]= 'LCU') -> Tuple[QuantumState, np independent_stabilizers = self.symmetry_generators + Ps # rotate onto computational basis - independent_stabilizers.target_sqp = 'Z' + independent_stabilizers.target_sqp = "Z" rotated_stabs = independent_stabilizers.rotate_onto_single_qubit_paulis() clifford_rots = independent_stabilizers.stabilizer_rotations ## get stabilizer state for the rotated stabilizers Z_indices = np.sum(rotated_stabs.Z_block, axis=0) - Z_vals = np.sum(rotated_stabs.Z_block[:, Z_indices.astype(bool)] * rotated_stabs.coeff_vec, axis=1) + Z_vals = np.sum( + rotated_stabs.Z_block[:, Z_indices.astype(bool)] * rotated_stabs.coeff_vec, + axis=1, + ) Z_indices[Z_indices.astype(bool)] = ((Z_vals - 1) * -0.5).astype(int) state = QuantumState(Z_indices.reshape(1, -1)) ## undo clifford rotations from symmer.evolution.exponentiation import exponentiate_single_Pop + for op, _ in clifford_rots: rot = exponentiate_single_Pop(op.multiply_by_constant(1j * np.pi / 4)) state = rot.dagger * state ## undo unitary partitioning step - if UP_method == 'LCU': + if UP_method == "LCU": state = rotations_LCU.dagger * state else: for op, angle in rotations_SEQ[::-1]: - state = exponentiate_single_Pop(op.multiply_by_constant(1j * angle / 2)).dagger * state + state = ( + exponentiate_single_Pop( + op.multiply_by_constant(1j * angle / 2) + ).dagger + * state + ) # TODO: could return clifford and UP rotations here too! - return state, nu_assignment + return state, nu_assignment + + ############################################################################### ################### NONCONTEXTUAL SOLVERS BELOW ############################### ############################################################################### + class NoncontextualSolver: # xUSO settings - method:str = 'brute_force' - x:str = 'P' - num_anneals:int = 1_000, - _nu = None, - expansion_order=1 + method: str = "brute_force" + x: str = "P" + num_anneals: int = (1_000,) + _nu = (None,) + expansion_order = 1 def __init__( self, NC_op: NoncontextualOp, fixed_ev_mask: np.array = None, - fixed_eigvals: np.array = None - ) -> None: + fixed_eigvals: np.array = None, + ) -> None: self.NC_op = NC_op - + if fixed_ev_mask is not None: - assert fixed_eigvals is not None, 'Must specify the fixed eigenvalues' - assert np.sum(fixed_ev_mask) == len(fixed_eigvals), 'Number of non-zero elements in mask does not match the number of fixed eigenvalues' + assert fixed_eigvals is not None, "Must specify the fixed eigenvalues" + assert np.sum(fixed_ev_mask) == len( + fixed_eigvals + ), "Number of non-zero elements in mask does not match the number of fixed eigenvalues" self.fixed_ev_mask = fixed_ev_mask self.fixed_eigvals = fixed_eigvals else: self.fixed_ev_mask = np.zeros(NC_op.symmetry_generators.n_terms, dtype=bool) self.fixed_eigvals = np.array([], dtype=int) - + ################################################################# ########################## BRUTE FORCE ########################## ################################################################# def energy_via_brute_force(self) -> Tuple[float, np.array, np.array]: - """ + """ Does what is says on the tin! Try every single eigenvalue assignment in parallel - and return the minimizing noncontextual configuration. This scales exponentially in + and return the minimizing noncontextual configuration. This scales exponentially in the number of unassigned symmetry elements. """ if np.all(self.fixed_ev_mask): - nu_list = self.fixed_eigvals.reshape([1,-1]) + nu_list = self.fixed_eigvals.reshape([1, -1]) else: - search_size = 2**np.sum(~self.fixed_ev_mask) - nu_list = np.ones([search_size, self.NC_op.symmetry_generators.n_terms], dtype=int) - nu_list[:,self.fixed_ev_mask] = np.tile(self.fixed_eigvals, [search_size,1]) - nu_list[:,~self.fixed_ev_mask] = np.array(list(itertools.product([-1,1],repeat=np.sum(~self.fixed_ev_mask)))) - + search_size = 2 ** np.sum(~self.fixed_ev_mask) + nu_list = np.ones( + [search_size, self.NC_op.symmetry_generators.n_terms], dtype=int + ) + nu_list[:, self.fixed_ev_mask] = np.tile( + self.fixed_eigvals, [search_size, 1] + ) + nu_list[:, ~self.fixed_ev_mask] = np.array( + list(itertools.product([-1, 1], repeat=np.sum(~self.fixed_ev_mask))) + ) + # # optimize over all discrete value assignments of nu in parallel noncon_H = ray.put(self.NC_op) - tracker = np.array(ray.get( - [get_noncon_energy.remote(noncon_H, nu_vec) for nu_vec in nu_list])) + tracker = np.array( + ray.get([get_noncon_energy.remote(noncon_H, nu_vec) for nu_vec in nu_list]) + ) # with mp.Pool(mp.cpu_count()) as pool: # tracker = pool.map(self.NC_op.get_energy, nu_list) - + # find the lowest energy eigenvalue assignment from the full list full_search_results = zip(tracker, nu_list) - energy, fixed_nu = min(full_search_results, key=lambda x:x[0]) + energy, fixed_nu = min(full_search_results, key=lambda x: x[0]) return energy, fixed_nu @@ -766,14 +886,16 @@ def energy_via_brute_force(self) -> Tuple[float, np.array, np.array]: ################################################################# def energy_via_relaxation(self) -> Tuple[float, np.array, np.array]: - """ + """ Relax the binary value assignment of symmetry generators to continuous variables. """ # optimize discrete value assignments nu by relaxation to continuous variables - nu_bounds = [(0, np.pi)]*(self.NC_op.symmetry_generators.n_terms-np.sum(self.fixed_ev_mask)) + nu_bounds = [(0, np.pi)] * ( + self.NC_op.symmetry_generators.n_terms - np.sum(self.fixed_ev_mask) + ) def get_nu(angles): - """ + """ Build nu vector given fixed values. """ nu = np.ones(self.NC_op.symmetry_generators.n_terms) @@ -781,31 +903,37 @@ def get_nu(angles): nu[~self.fixed_ev_mask] = np.cos(angles) return nu - optimizer_output = shgo(func=lambda angles:self.NC_op.get_energy(get_nu(angles)), bounds=nu_bounds) + optimizer_output = shgo( + func=lambda angles: self.NC_op.get_energy(get_nu(angles)), bounds=nu_bounds + ) # if optimization was successful the optimal angles should consist of 0 and pi - fix_nu = np.sign(np.array(get_nu(np.cos(optimizer_output['x'])))).astype(int) - self.NC_op.symmetry_generators.coeff_vec = fix_nu - return optimizer_output['fun'], fix_nu - + fix_nu = np.sign(np.array(get_nu(np.cos(optimizer_output["x"])))).astype(int) + self.NC_op.symmetry_generators.coeff_vec = fix_nu + return optimizer_output["fun"], fix_nu + ################################################################# ################ UNCONSTRAINED SPIN OPTIMIZATION ################ - ################################################################# + ################################################################# def get_cost_func(self): - """ + """ Define the unconstrained spin cost function. """ - symmetrized_operator = self.NC_op.symmetrized_operator(expansion_order=self.expansion_order) - G_indices, _ = symmetrized_operator.generator_reconstruction(self.NC_op.symmetry_generators) + symmetrized_operator = self.NC_op.symmetrized_operator( + expansion_order=self.expansion_order + ) + G_indices, _ = symmetrized_operator.generator_reconstruction( + self.NC_op.symmetry_generators + ) # setup spin variables - fixed_indices = np.where(self.fixed_ev_mask)[0] # bool to indices + fixed_indices = np.where(self.fixed_ev_mask)[0] # bool to indices fixed_assignments = dict(zip(fixed_indices, self.fixed_eigvals)) - q_vec_SPIN={} + q_vec_SPIN = {} for ind in range(self.NC_op.symmetry_generators.n_terms): if ind in fixed_assignments.keys(): q_vec_SPIN[ind] = fixed_assignments[ind] else: - q_vec_SPIN[ind] = qv.spin_var('x%d' % ind) + q_vec_SPIN[ind] = qv.spin_var("x%d" % ind) COST = 0 for P_index, term in enumerate(G_indices): @@ -817,10 +945,10 @@ def get_cost_func(self): # cost function COST += ( - G_term * - symmetrized_operator.coeff_vec[P_index].real - #self.NC_op.pauli_mult_signs[P_index]# * - #r_part[P_index].real + G_term + * symmetrized_operator.coeff_vec[P_index].real + # self.NC_op.pauli_mult_signs[P_index]# * + # r_part[P_index].real ) return COST @@ -846,27 +974,31 @@ def energy_xUSO(self) -> Tuple[float, np.array, np.array]: Returns: energy (float): noncontextual energy """ - assert self.x in ['P', 'Q'] - assert self.method in ['brute_force', 'annealing'] - + assert self.x in ["P", "Q"] + assert self.method in ["brute_force", "annealing"] + COST = self.get_cost_func() - + if np.all(self.fixed_ev_mask): # if no degrees of freedom over nu vector, COST is a number nu_vec = self.fixed_eigvals else: - if self.x =='P': + if self.x == "P": spin_problem = COST.to_puso() else: spin_problem = COST.to_quso() - if self.method=='brute_force': + if self.method == "brute_force": sol = spin_problem.solve_bruteforce() - elif self.method == 'annealing': - if self.x == 'P': - puso_res = qv.sim.anneal_puso(spin_problem, num_anneals=self.num_anneals) - elif self.x == 'Q': - puso_res= qv.sim.anneal_quso(spin_problem, num_anneals=self.num_anneals) + elif self.method == "annealing": + if self.x == "P": + puso_res = qv.sim.anneal_puso( + spin_problem, num_anneals=self.num_anneals + ) + elif self.x == "Q": + puso_res = qv.sim.anneal_quso( + spin_problem, num_anneals=self.num_anneals + ) assert COST.is_solution_valid(puso_res.best.state) is True sol = puso_res.best.state @@ -874,24 +1006,27 @@ def energy_xUSO(self) -> Tuple[float, np.array, np.array]: nu_vec = np.ones(self.NC_op.symmetry_generators.n_terms, dtype=int) nu_vec[self.fixed_ev_mask] = self.fixed_eigvals # must ensure the binary variables are correctly ordered in the solution: - nu_vec[~self.fixed_ev_mask] = np.array([solution[x_i] for x_i in sorted(COST.variables)]) - + nu_vec[~self.fixed_ev_mask] = np.array( + [solution[x_i] for x_i in sorted(COST.variables)] + ) + return self.NC_op.get_energy(nu_vec), nu_vec -@ray.remote(num_cpus=os.cpu_count(), - runtime_env={ - "env_vars": { - "NUMBA_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), - # "OMP_NUM_THREADS": str(os.cpu_count()), - "OMP_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), - "NUMEXPR_MAX_THREADS": str(os.cpu_count()) - } - } - ) -def get_noncon_energy(noncon_H:NoncontextualOp, nu: np.array) -> float: +@ray.remote( + num_cpus=os.cpu_count(), + runtime_env={ + "env_vars": { + "NUMBA_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), + # "OMP_NUM_THREADS": str(os.cpu_count()), + "OMP_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), + "NUMEXPR_MAX_THREADS": str(os.cpu_count()), + } + }, +) +def get_noncon_energy(noncon_H: NoncontextualOp, nu: np.array) -> float: """ The classical objective function that encodes the noncontextual energies. """ s0, si = noncon_H.get_symmetry_contributions(nu) - return s0 - np.linalg.norm(si) \ No newline at end of file + return s0 - np.linalg.norm(si) diff --git a/symmer/operators/utils.py b/symmer/operators/utils.py index 1e60ba5..7609de8 100644 --- a/symmer/operators/utils.py +++ b/symmer/operators/utils.py @@ -4,6 +4,7 @@ from openfermion import QubitOperator from qiskit.opflow import PauliSumOp + def symplectic_to_string(symp_vec) -> str: """ Returns string form of symplectic vector defined as (X | Z) @@ -23,16 +24,17 @@ def symplectic_to_string(symp_vec) -> str: X_loc = np.logical_xor(Y_loc, X_block) Z_loc = np.logical_xor(Y_loc, Z_block) - char_aray = np.array(list('I' * n_qubits), dtype=str) + char_aray = np.array(list("I" * n_qubits), dtype=str) - char_aray[Y_loc] = 'Y' - char_aray[X_loc] = 'X' - char_aray[Z_loc] = 'Z' + char_aray[Y_loc] = "Y" + char_aray[X_loc] = "X" + char_aray[Z_loc] = "Z" - Pword_string = ''.join(char_aray) + Pword_string = "".join(char_aray) return Pword_string + def string_to_symplectic(pauli_str, n_qubits): """ Args: @@ -42,15 +44,19 @@ def string_to_symplectic(pauli_str, n_qubits): Returns: symp_vec (array): symplectic Pauliword array """ - assert(len(pauli_str) == n_qubits), 'Number of qubits is incompatible with pauli string' - assert (set(pauli_str).issubset({'I', 'X', 'Y', 'Z'})), 'pauliword must only contain X,Y,Z,I terms' + assert ( + len(pauli_str) == n_qubits + ), "Number of qubits is incompatible with pauli string" + assert set(pauli_str).issubset( + {"I", "X", "Y", "Z"} + ), "pauliword must only contain X,Y,Z,I terms" char_aray = np.array(list(pauli_str), dtype=str) - X_loc = (char_aray == 'X') - Z_loc = (char_aray == 'Z') - Y_loc = (char_aray == 'Y') + X_loc = char_aray == "X" + Z_loc = char_aray == "Z" + Y_loc = char_aray == "Y" - symp_vec = np.zeros(2*n_qubits, dtype=int) + symp_vec = np.zeros(2 * n_qubits, dtype=int) symp_vec[:n_qubits] += X_loc symp_vec[n_qubits:] += Z_loc symp_vec[:n_qubits] += Y_loc @@ -58,6 +64,7 @@ def string_to_symplectic(pauli_str, n_qubits): return symp_vec + def count1_in_int_bitstring(i): """ Count number of "1" bits in integer i to be thought of in binary representation @@ -73,7 +80,8 @@ def count1_in_int_bitstring(i): """ i = i - ((i >> 1) & 0x55555555) # add pairs of bits i = (i & 0x33333333) + ((i >> 2) & 0x33333333) # quads - return (((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) & 0xffffffff) >> 24 + return (((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) & 0xFFFFFFFF) >> 24 + def symplectic_to_sparse_matrix(symp_vec, coeff) -> sp.sparse.csr_matrix: """ @@ -113,22 +121,19 @@ def symplectic_to_sparse_matrix(symp_vec, coeff) -> sp.sparse.csr_matrix: col_ind = np.bitwise_xor(row_ind, x_int) row_inds_and_Zint = np.bitwise_and(row_ind, z_int) - vals = global_phase * (-1) ** (count1_in_int_bitstring(row_inds_and_Zint)%2) + vals = global_phase * (-1) ** (count1_in_int_bitstring(row_inds_and_Zint) % 2) sparse_matrix = sp.sparse.csr_matrix( - (vals, (row_ind, col_ind)), - shape=(dimension, dimension), - dtype=complex - ) + (vals, (row_ind, col_ind)), shape=(dimension, dimension), dtype=complex + ) + + return coeff * sparse_matrix - return coeff*sparse_matrix def symplectic_cleanup( - symp_matrix: np.array, - coeff_vec: np.array, - zero_threshold: float = None - ) -> Tuple[np.array, np.array]: - """ + symp_matrix: np.array, coeff_vec: np.array, zero_threshold: float = None +) -> Tuple[np.array, np.array]: + """ Remove duplicated rows of symplectic matrix terms, whilst summing the corresponding coefficients of the deleted rows in coeff_vec @@ -137,7 +142,7 @@ def symplectic_cleanup( coeff_vec (np.array): Coefficient Vector. zero_threshold (float): Zero Threshold Value. By default it is set to 'None'. - Returns: + Returns: Reduced symplectic matrix and reduced coefficient vector. """ # order lexicographically using a fast void view implementation... @@ -158,26 +163,32 @@ def symplectic_cleanup( reduced_coeff_vec = np.add.reduceat(sorted_coeff, summing_indices, axis=0) # if a zero threshold is specified terms with sufficiently small coefficient will be dropped if zero_threshold is not None: - mask_nonzero = abs(reduced_coeff_vec)>zero_threshold + mask_nonzero = abs(reduced_coeff_vec) > zero_threshold reduced_symp_matrix = reduced_symp_matrix[mask_nonzero] reduced_coeff_vec = reduced_coeff_vec[mask_nonzero] return reduced_symp_matrix, reduced_coeff_vec -def random_symplectic_matrix(n_qubits,n_terms, diagonal=False, density=0.3): - """ + +def random_symplectic_matrix(n_qubits, n_terms, diagonal=False, density=0.3): + """ Generates a random binary matrix of dimension (n_terms) x (2*n_qubits) Specifying diagonal=True will set the left hand side (X_block) to all zeros """ if diagonal: - Z_block = np.random.choice([True, False], size=[n_terms,n_qubits], p=[density/2, 1-density/2]) + Z_block = np.random.choice( + [True, False], size=[n_terms, n_qubits], p=[density / 2, 1 - density / 2] + ) return np.hstack([np.zeros_like(Z_block), Z_block]) else: - return np.random.choice([True, False], size=[n_terms,2*n_qubits], p=[density, 1-density]) + return np.random.choice( + [True, False], size=[n_terms, 2 * n_qubits], p=[density, 1 - density] + ) + def _rref_binary(matrix: np.array) -> np.array: - """ - Row-reduced echelon form over the binary field (GF2) - rows are not reordered + """ + Row-reduced echelon form over the binary field (GF2) - rows are not reordered here for efficiency (not required in some use cases, e.g. symmetry identification). Args: @@ -200,8 +211,9 @@ def _rref_binary(matrix: np.array) -> np.array: # the rows below i will now be zeroed out in the pivot column return rref_matrix + def rref_binary(matrix: np.array) -> np.array: - """ + """ Full row-reduced echelon form with row reordering. Args: @@ -213,39 +225,44 @@ def rref_binary(matrix: np.array) -> np.array: reduced = _rref_binary(matrix) row_order, col_order = zip( *sorted( - [(i,np.where(row)[0][0]) for i,row in enumerate(reduced) if np.any(row)], - key=lambda x:x[1] + [(i, np.where(row)[0][0]) for i, row in enumerate(reduced) if np.any(row)], + key=lambda x: x[1], ) ) - row_order = list(row_order) + list(set(range(reduced.shape[0])).difference(row_order)) + row_order = list(row_order) + list( + set(range(reduced.shape[0])).difference(row_order) + ) return reduced[row_order] + def _cref_binary(matrix: np.array) -> np.array: - """ + """ Column-reduced echelon form with static columns (used in symmetry identification). - + Args: matrix(np.array): Matrix whose column-reduced echelon form with static columns has to be found. Returns: Column-reduced echelon form of input matrix with static columns. """ - return _rref_binary(matrix.T).T + return _rref_binary(matrix.T).T + def cref_binary(matrix: np.array) -> np.array: - """ + """ Column-reduced echelon form with ordered columns (used in basis reconstruction). - + Args: matrix(np.array): Matrix whose column-reduced echelon form with ordered columns has to be found. Returns: Column-reduced echelon form of input matrix with ordered columns. """ - return rref_binary(matrix.T).T + return rref_binary(matrix.T).T + def QubitOperator_to_dict(op: QubitOperator, num_qubits: int): - """ + """ OpenFermion Args: @@ -255,24 +272,25 @@ def QubitOperator_to_dict(op: QubitOperator, num_qubits: int): Returns: Dictionary format of Qubit Operator. """ - assert(type(op) == QubitOperator) + assert type(op) == QubitOperator op_dict = {} term_dict = op.terms terms = list(term_dict.keys()) - for t in terms: - letters = ['I' for i in range(num_qubits)] + for t in terms: + letters = ["I" for i in range(num_qubits)] for i in t: letters[i[0]] = i[1] - p_string = ''.join(letters) + p_string = "".join(letters) op_dict[p_string] = term_dict[t] - + return op_dict -def PauliSumOp_to_dict(op:PauliSumOp) -> dict: - """ + +def PauliSumOp_to_dict(op: PauliSumOp) -> dict: + """ Qiskit - + Args: op (PauliSumOp): Pauli Sum Operator @@ -285,8 +303,9 @@ def PauliSumOp_to_dict(op:PauliSumOp) -> dict: H_dict[Pstr] = P_term._coeff return H_dict + def safe_PauliwordOp_to_dict(op) -> Dict[str, Tuple[float, float]]: - """ + """ Stores the real and imaginary parts of the coefficient separately in a tuple. Args: @@ -299,8 +318,9 @@ def safe_PauliwordOp_to_dict(op) -> Dict[str, Tuple[float, float]]: dict_out = dict(zip(terms, coeffs)) return dict_out + def safe_QuantumState_to_dict(psi) -> Dict[str, Tuple[float, float]]: - """ + """ Stores the real and imaginary parts of the coefficient separately in a tuple. Args: @@ -313,12 +333,11 @@ def safe_QuantumState_to_dict(psi) -> Dict[str, Tuple[float, float]]: dict_out = dict(zip(terms, coeffs)) return dict_out + def mul_symplectic( - symp_vec1: np.array, - coeff1: complex, - symp_vec2: np.array, - coeff2: complex) -> Tuple[np.array, complex, int]: - """ + symp_vec1: np.array, coeff1: complex, symp_vec2: np.array, coeff2: complex +) -> Tuple[np.array, complex, int]: + """ Performs Pauli multiplication with phases at the level of the symplectic vector (1D here!). The phase compensation is implemented as per https://doi.org/10.1103/PhysRevA.68.042318. @@ -346,19 +365,24 @@ def mul_symplectic( # phaseless multiplication is binary addition in symplectic representation output_symplectic_vec = np.bitwise_xor(symp_vec1, symp_vec2) # phase is determined by Y counts plus additional sign flip - Y_count_out = np.sum(np.bitwise_and(*np.split(output_symplectic_vec, 2)), axis=0) # number of Y terms in output + Y_count_out = np.sum( + np.bitwise_and(*np.split(output_symplectic_vec, 2)), axis=0 + ) # number of Y terms in output # X_block of first op and Z_block of second op sign_change = (-1) ** ( - np.sum(np.bitwise_and(X_block1, Z_block2), axis=0) % 2 + np.sum(np.bitwise_and(X_block1, Z_block2), axis=0) % 2 ) # mod 2 as only care about parity # final phase modification - phase_mod = sign_change * (1j) ** ((3 * (Y_count1 + Y_count2) + Y_count_out) % 4) # mod 4 as roots of unity + phase_mod = sign_change * (1j) ** ( + (3 * (Y_count1 + Y_count2) + Y_count_out) % 4 + ) # mod 4 as roots of unity coeff_vec = phase_mod * coeff1 * coeff2 - return output_symplectic_vec, coeff_vec #, Y_count_out + return output_symplectic_vec, coeff_vec # , Y_count_out + def unit_n_sphere_cartesian_coords(angles: np.array) -> np.array: - """ - Input an array of angles of length n, returns the n+1 cartesian coordinates + """ + Input an array of angles of length n, returns the n+1 cartesian coordinates of the corresponding unit n-sphere in (n+1)-dimensional Euclidean space. Args: @@ -367,16 +391,19 @@ def unit_n_sphere_cartesian_coords(angles: np.array) -> np.array: Returns: Numpy Array of n+1 cartesian coordinates. """ - cartesians = [np.prod(np.sin(angles[:i]))*np.cos(angles[i]) for i in range(len(angles))] + cartesians = [ + np.prod(np.sin(angles[:i])) * np.cos(angles[i]) for i in range(len(angles)) + ] cartesians.append(np.prod(np.sin(angles))) return np.array(cartesians) -def binomial_coefficient(n,k): - """ + +def binomial_coefficient(n, k): + """ Calculate the binomial coefficient "n choose k" or denoted as "C(n, k)," represents the number of ways to choose k objects from a set of n objects without considering their order. Differs from np.math.comb as this allows non-integer n. - Args: + Args: n: Total number of objects. k: Number of object to choose from a set of n objects. @@ -385,13 +412,14 @@ def binomial_coefficient(n,k): """ prod = 1 for r in range(k): - prod *= (n-r)/(k-r) + prod *= (n - r) / (k - r) return prod + def check_independent(operators): """ Check if the input PauliwordOp contains algebraically dependent terms. - + Args: operators (PauliwordOp): Operators. @@ -401,18 +429,19 @@ def check_independent(operators): check_independent = _rref_binary(operators.symp_matrix) return ~np.any(np.all(~check_independent, axis=1)) + def check_jordan_independent(operators): - """ + """ Check if the input PauliwordOp contains algebraically dependent terms under jordan product (note input can be noncontextual, but contain dependent terms!) Args: operators (PauliwordOp): Operators. - + Returns: Returns True, if input operators contains algebraically dependent terms. - + test with : H ={ 'IIIZ': (1+0j), 'IIZI': (1+0j), @@ -428,7 +457,7 @@ def check_jordan_independent(operators): # Symmetries = operators[mask_symmetries] # Anticommuting = operators[~mask_symmetries] # return ( - # check_independent(Symmetries) & + # check_independent(Symmetries) & # np.all(Anticommuting.adjacency_matrix == np.eye(Anticommuting.n_terms)) # ) @@ -472,10 +501,14 @@ def check_jordan_independent(operators): # return check_independent(Z2_terms) # get fully commuting terms - z2_mask = np.sum(operators.commutes_termwise(operators), axis=1) == operators.n_terms + z2_mask = ( + np.sum(operators.commutes_termwise(operators), axis=1) == operators.n_terms + ) Z2_symm = operators[z2_mask] - _, missing_mask = operators.generator_reconstruction(Z2_symm, override_independence_check=True) + _, missing_mask = operators.generator_reconstruction( + Z2_symm, override_independence_check=True + ) remaining = operators[~missing_mask] if remaining.n_terms > 0: @@ -483,7 +516,13 @@ def check_jordan_independent(operators): # we can test for this below adj_matrix_view = np.ascontiguousarray(remaining.adjacency_matrix).view( - np.dtype((np.void, remaining.adjacency_matrix.dtype.itemsize * remaining.adjacency_matrix.shape[1])) + np.dtype( + ( + np.void, + remaining.adjacency_matrix.dtype.itemsize + * remaining.adjacency_matrix.shape[1], + ) + ) ) re_order_indices = np.argsort(adj_matrix_view.ravel()) # sort the adj matrix and vector of coefficients accordingly @@ -499,6 +538,7 @@ def check_jordan_independent(operators): # operators is made up of pairwise commuting ops and thus must be jordan independent return True + def check_adjmat_noncontextual(adjmat) -> bool: """ Check whether the input boolean square matrix has a noncontextual structure... @@ -515,13 +555,12 @@ def check_adjmat_noncontextual(adjmat) -> bool: # look only at the unique rows in the masked adjacency matrix - # identical rows correspond with operators of the same clique unique_commutation_character = np.unique( - adjmat[mask_non_universal,:][:,mask_non_universal], - axis=0 + adjmat[mask_non_universal, :][:, mask_non_universal], axis=0 ) - # if the unique commutation characteristics are disjoint, i.e. no overlapping ones + # if the unique commutation characteristics are disjoint, i.e. no overlapping ones # between rows, the operator is noncontextual - hence we sum over rows and check # the resulting vector consists of all ones. - return np.all(np.count_nonzero(unique_commutation_character, axis=0)==1) + return np.all(np.count_nonzero(unique_commutation_character, axis=0) == 1) def perform_noncontextual_sweep(operator) -> "PauliwordOp": @@ -548,22 +587,23 @@ def perform_noncontextual_sweep(operator) -> "PauliwordOp": # noncon_indices = np.append(noncon_indices, index+1) # adjmat = adjmat_padded - # return operator[noncon_indices] + # return operator[noncon_indices] ## new method uses generators to speed up sweep from symmer.operators import PauliwordOp + mask = np.zeros(operator.n_terms, dtype=bool) for ind in range(operator.n_terms): mask[ind] = ~mask[ind] - running_op = PauliwordOp(operator.symp_matrix[mask], - np.ones(np.sum(mask))) + running_op = PauliwordOp(operator.symp_matrix[mask], np.ones(np.sum(mask))) if not running_op.is_noncontextual: mask[ind] = ~mask[ind] return operator[mask] + def binary_array_to_int(bin_arr): """ Function to convert an array composed of rows of binary into integers. @@ -580,10 +620,10 @@ def binary_array_to_int(bin_arr): b2i = 2 ** np.arange(bin_arr.shape[1] - 1, -1, -1, dtype=float) # b2i = 2 ** np.arange(bin_arr.shape[1] - 1, -1, -1, dtype=object) - int_arr = np.einsum('j, ij->i', b2i, bin_arr) + int_arr = np.einsum("j, ij->i", b2i, bin_arr) # int_arr = (b2i*bin_arr).sum(axis=1) ## slower as does matrix product rather than multiplication along rows followed by a sum! # int_arr = bin_arr @ b2i - return int_arr \ No newline at end of file + return int_arr diff --git a/symmer/projection/__init__.py b/symmer/projection/__init__.py index 1790f83..6d9ff0f 100644 --- a/symmer/projection/__init__.py +++ b/symmer/projection/__init__.py @@ -3,4 +3,4 @@ from .base import S3_projection from .qubit_tapering import QubitTapering from .contextual_subspace import ContextualSubspace -from .qubit_subspace_manager import QubitSubspaceManager \ No newline at end of file +from .qubit_subspace_manager import QubitSubspaceManager diff --git a/symmer/projection/base.py b/symmer/projection/base.py index f094333..16aaa09 100644 --- a/symmer/projection/base.py +++ b/symmer/projection/base.py @@ -4,35 +4,35 @@ from symmer.evolution import trotter, Had from functools import reduce + class S3_projection: - """ + """ Base class for enabling qubit reduction techniques derived from the Stabilizer SubSpace (S3) projection framework, such as tapering - and Contextual-Subspace VQE. The methods defined herein serve the + and Contextual-Subspace VQE. The methods defined herein serve the following purposes: - _perform_projection - Assuming the input operator has been rotated via the Clifford operations - found in the above stabilizer_rotations method, this will effect the + Assuming the input operator has been rotated via the Clifford operations + found in the above stabilizer_rotations method, this will effect the projection onto the corresponding stabilizer subspace. This involves droping any operator terms that do not commute with the rotated generators and fixing the eigenvalues of those that do consistently. - perform_projection This method wraps _perform_projection but provides the facility to insert auxiliary rotations (that need not be Clifford). This is used in CS-VQE - to implement unitary partitioning where necessary. + to implement unitary partitioning where necessary. Attributes: rotated_flag (bool): If True, the operator is rotated. By default it is set to 'False'. """ + rotated_flag = False - def __init__(self, - stabilizers: IndependentOp - ) -> None: + def __init__(self, stabilizers: IndependentOp) -> None: """ - eigenvalues: The list of eigenvalue assignments to complement the stabilizers. - + - target_sqp: The target single-qubit Pauli (X or Z) that we wish to rotate onto. - fix_qubits: Manually overrides the qubit positions selected in stabilizer_rotations, although the rotation procedure can be a bit unpredictable so take care! @@ -40,13 +40,14 @@ def __init__(self, stabilizers (IndependentOp): A list of stabilizers that should be enforced, given as Pauli strings. """ self.stabilizers = stabilizers - - def _perform_projection(self, - operator: PauliwordOp, - #sym_sector: Union[List[int], np.array] - ) -> PauliwordOp: - """ - Method for projecting an operator over fixed qubit positions + + def _perform_projection( + self, + operator: PauliwordOp, + # sym_sector: Union[List[int], np.array] + ) -> PauliwordOp: + """ + Method for projecting an operator over fixed qubit positions stabilized by single Pauli operators (obtained via Clifford operations). Args: @@ -55,26 +56,40 @@ def _perform_projection(self, Returns: PauliwordOp representing the projection of input operator. """ - assert(operator.n_qubits == self.stabilizers.n_qubits), 'The input operator does not have the same number of qubits as the stabilizers' - assert(self.rotated_flag), 'The operator has not been rotated - intended for use with perform_projection method' + assert ( + operator.n_qubits == self.stabilizers.n_qubits + ), "The input operator does not have the same number of qubits as the stabilizers" + assert ( + self.rotated_flag + ), "The operator has not been rotated - intended for use with perform_projection method" self.rotated_flag = False - + # remove terms that do not commute with the rotated stabilizers - commutes_with_all_stabilizers = np.all(operator.commutes_termwise(self.rotated_stabilizers), axis=1) + commutes_with_all_stabilizers = np.all( + operator.commutes_termwise(self.rotated_stabilizers), axis=1 + ) op_anticommuting_removed = operator.symp_matrix[commutes_with_all_stabilizers] cf_anticommuting_removed = operator.coeff_vec[commutes_with_all_stabilizers] # determine sign flipping from eigenvalue assignment # currently ill-defined for single-qubit Y stabilizers - stab_symp_indices = np.where(self.rotated_stabilizers.symp_matrix)[1] - eigval_assignment = op_anticommuting_removed[:,stab_symp_indices]*self.rotated_stabilizers.coeff_vec - eigval_assignment[eigval_assignment==0]=1 # 0 entries are identity, so fix as 1 in product - coeff_sign_flip = cf_anticommuting_removed*(np.prod(eigval_assignment, axis=1)).T + stab_symp_indices = np.where(self.rotated_stabilizers.symp_matrix)[1] + eigval_assignment = ( + op_anticommuting_removed[:, stab_symp_indices] + * self.rotated_stabilizers.coeff_vec + ) + eigval_assignment[ + eigval_assignment == 0 + ] = 1 # 0 entries are identity, so fix as 1 in product + coeff_sign_flip = ( + cf_anticommuting_removed * (np.prod(eigval_assignment, axis=1)).T + ) # the projected Pauli terms: - unfixed_XZ_indices = np.hstack([self.free_qubit_indices, - self.free_qubit_indices+operator.n_qubits]) - projected_symplectic = op_anticommuting_removed[:,unfixed_XZ_indices] + unfixed_XZ_indices = np.hstack( + [self.free_qubit_indices, self.free_qubit_indices + operator.n_qubits] + ) + projected_symplectic = op_anticommuting_removed[:, unfixed_XZ_indices] # there may be duplicate rows in op_projected - these are identified and # the corresponding coefficients collected in the cleanup method @@ -82,21 +97,22 @@ def _perform_projection(self, return PauliwordOp(projected_symplectic, coeff_sign_flip).cleanup() else: return PauliwordOp(np.array([], dtype=bool), [np.sum(coeff_sign_flip)]) - - def perform_projection(self, - operator: PauliwordOp, - ref_state: Union[List[int], np.array]=None, - sector: Union[List[int], np.array]=None - ) -> PauliwordOp: - """ - Input a PauliwordOp and returns the reduced operator corresponding + + def perform_projection( + self, + operator: PauliwordOp, + ref_state: Union[List[int], np.array] = None, + sector: Union[List[int], np.array] = None, + ) -> PauliwordOp: + """ + Input a PauliwordOp and returns the reduced operator corresponding with the specified stabilizers and eigenvalues. - + insert_rotation allows one to include supplementary Pauli rotations - to be performed prior to the stabilizer rotations, for example + to be performed prior to the stabilizer rotations, for example unitary partitioning in CS-VQE. - Args: + Args: operator (PauliwordOp): Operator projected over fixed qubit positions stabilized by single Pauli operators. ref_state (np.array): Reference State. By default, it is set to None. sector (np.array): Sector. By default it is set to none. If no sector is provided then a reference state must be given instead. @@ -104,56 +120,68 @@ def perform_projection(self, Reduced operator corresponding to the given stabilizers and eigenvalues. """ if sector is None and ref_state is not None: - #assert(ref_state is not None), 'If no sector is provided then a reference state must be given instead' + # assert(ref_state is not None), 'If no sector is provided then a reference state must be given instead' self.stabilizers.update_sector(ref_state) elif sector is not None: self.stabilizers.coeff_vec = np.array(sector, dtype=int) self.rotated_stabilizers = self.stabilizers.rotate_onto_single_qubit_paulis() - self.stab_qubit_indices = np.where(self.rotated_stabilizers.symp_matrix)[1] % operator.n_qubits - self.free_qubit_indices = np.setdiff1d(np.arange(operator.n_qubits),self.stab_qubit_indices) + self.stab_qubit_indices = ( + np.where(self.rotated_stabilizers.symp_matrix)[1] % operator.n_qubits + ) + self.free_qubit_indices = np.setdiff1d( + np.arange(operator.n_qubits), self.stab_qubit_indices + ) # perform the full list of rotations on the input operator... if len(self.stabilizers.stabilizer_rotations) > 0: - op_rotated = operator.perform_rotations(self.stabilizers.stabilizer_rotations) + op_rotated = operator.perform_rotations( + self.stabilizers.stabilizer_rotations + ) else: op_rotated = operator - + self.rotated_flag = True # ...and finally perform the stabilizer subspace projection return self._perform_projection(operator=op_rotated) - + def project_state(self, state: QuantumState) -> QuantumState: - """ + """ Project a state into the stabilizer subspace. Args: state (QuantumState): The state which has to be projected into the stabilizer subspace. - Returns: + Returns: Projection of input QuantumState into the stabilizer subspace. """ transformation_list = [] # Hadamards where rotated onto Pauli X operators transformation_list += [ - Had(self.stabilizers.n_qubits, i) for i in np.where( + Had(self.stabilizers.n_qubits, i) + for i in np.where( np.sum( - self.stabilizers.rotate_onto_single_qubit_paulis().X_block & - ~self.stabilizers.rotate_onto_single_qubit_paulis().Z_block, - axis=0 - ) - )[0] + self.stabilizers.rotate_onto_single_qubit_paulis().X_block + & ~self.stabilizers.rotate_onto_single_qubit_paulis().Z_block, + axis=0, + ) + )[0] ] # Projections onto the stabilizer subspace - #transformation_list += list(map(lambda x:(x**2 + x)*.5,self.stabilizers.rotate_onto_single_qubit_paulis())) + # transformation_list += list(map(lambda x:(x**2 + x)*.5,self.stabilizers.rotate_onto_single_qubit_paulis())) # Rotations mapping stabilizers onto single-qubit Pauli operators - transformation_list += list(map(lambda s:trotter(s[0]*(np.pi/4*1j)), self.stabilizers.stabilizer_rotations)) + transformation_list += list( + map( + lambda s: trotter(s[0] * (np.pi / 4 * 1j)), + self.stabilizers.stabilizer_rotations, + ) + ) # Product over the transformation list yields final transformation operator - transformation = reduce(lambda x,y:x*y, transformation_list) + transformation = reduce(lambda x, y: x * y, transformation_list) # apply transformation to the reference state transformed_state = transformation * state # drop stabilized qubit positions and sum over potential duplicates return QuantumState( - transformed_state.state_matrix[:, self.free_qubit_indices], - transformed_state.state_op.coeff_vec - ).cleanup(zero_threshold=1e-12) \ No newline at end of file + transformed_state.state_matrix[:, self.free_qubit_indices], + transformed_state.state_op.coeff_vec, + ).cleanup(zero_threshold=1e-12) diff --git a/symmer/projection/contextual_subspace.py b/symmer/projection/contextual_subspace.py index f191cc8..13d33dc 100644 --- a/symmer/projection/contextual_subspace.py +++ b/symmer/projection/contextual_subspace.py @@ -1,15 +1,19 @@ import numpy as np from symmer.operators import PauliwordOp, IndependentOp, NoncontextualOp, QuantumState from symmer.projection.utils import ( - update_eigenvalues, StabilizerIdentification, ObservableBiasing, stabilizer_walk, + update_eigenvalues, + StabilizerIdentification, + ObservableBiasing, + stabilizer_walk, # get_noncon_generators_from_commuting_stabilizers ) from symmer.projection import S3_projection from symmer.evolution import trotter from typing import List, Union, Optional + class ContextualSubspace(S3_projection): - """ + """ Class for performing contextual subspace methods as per https://quantum-journal.org/papers/q-2021-05-14-456/. Reduces the number of qubits in the problem while aiming to control the systematic error incurred along the way. @@ -17,29 +21,31 @@ class ContextualSubspace(S3_projection): 1. Identify a set of operators one wishes to enforce as stabilizers over the contextual subspace, one might think ofthese as 'pseudo-symmetries', as opposed to the true, physical symmetries of qubit tapering. 2. Construct a noncontextual Hamiltoinian that respects the stabilizers selecting in (1), - the NoncontextualOp class handles the decomposition into a generating set and classical optimization over the noncontextual objective function + the NoncontextualOp class handles the decomposition into a generating set and classical optimization over the noncontextual objective function NOTE: the order in which (1) and (2) are performed depends on the noncontextual strategy specified 3. Apply unitary partitioning (either sequence of rotations or linear combination of unitaries) to collapse noncontextual cliques - + The remaining steps are handled by the parent S3_projection class: - 4. rotate each stabilizer onto a single-qubit Pauli operator, + 4. rotate each stabilizer onto a single-qubit Pauli operator, 5. drop the corresponding qubits from the Hamiltonian whilst 6. fixing the +/-1 eigenvalues """ - def __init__(self, - operator: PauliwordOp, - noncontextual_strategy: str = 'diag', - noncontextual_solver: str = 'brute_force', - num_anneals:Optional[int] = 1000, - unitary_partitioning_method: str = 'seq_rot', - reference_state: Union[np.array, QuantumState] = None, - noncontextual_operator: NoncontextualOp = None, - noncontextual_expansion_order: int = 1 - ): + + def __init__( + self, + operator: PauliwordOp, + noncontextual_strategy: str = "diag", + noncontextual_solver: str = "brute_force", + num_anneals: Optional[int] = 1000, + unitary_partitioning_method: str = "seq_rot", + reference_state: Union[np.array, QuantumState] = None, + noncontextual_operator: NoncontextualOp = None, + noncontextual_expansion_order: int = 1, + ): """ When passing in a noncontextual_operator if noncontextual_strategy set to be 'solved' then noncontextual_solver will NOT be run. - Args: + Args: operator(PauliwordOp): Operator one wishes to enforce as stabilizers over the contextual subspace. noncontextual_strategy (str): Non-Contextual Strategy to be applied. Its default value is'diag'. noncontextual_solver (str): Non-contextual solver to be applied. Its default value is'brute_force'. @@ -47,15 +53,15 @@ def __init__(self, unitary_partitioning_method (str): Unitary Partitioning Method to be applied. Its default value is'seq_rot'. reference_state (QuantumState): Reference State. By default, it is set to None. noncontextual_operator (NoncontextualOp): Non-contextual Operator. By default, it is set to None. - noncontextual_expansion_order (int): Non-contextual Expansion Order. Its default value is 1. + noncontextual_expansion_order (int): Non-contextual Expansion Order. Its default value is 1. """ # noncontextual startegy will have the form x_y, where x is the actual strategy # and y is some supplementary method indicating a sorting key such as magnitude if reference_state is None or isinstance(reference_state, QuantumState): self.ref_state = reference_state else: - self.ref_state = QuantumState(reference_state) - extract_noncon_strat = noncontextual_strategy.split('_') + self.ref_state = QuantumState(reference_state) + extract_noncon_strat = noncontextual_strategy.split("_") self.nc_strategy = extract_noncon_strat[0] self.noncontextual_solver = noncontextual_solver self.num_anneals = num_anneals @@ -65,22 +71,22 @@ def __init__(self, # With the exception of the StabilizeFirst noncontextual strategy, here we build # the noncontextual Hamiltonian in line with the specified strategy self.operator = operator - if noncontextual_operator is None and self.nc_strategy != 'StabilizeFirst': + if noncontextual_operator is None and self.nc_strategy != "StabilizeFirst": self.noncontextual_operator = NoncontextualOp.from_hamiltonian( operator, strategy=noncontextual_strategy ) # solve noncon problem self._noncontextual_update() - noncontextual_strategy = 'solved' + noncontextual_strategy = "solved" else: self.noncontextual_operator = noncontextual_operator - + ## case for StabilizeFirst when need to solve noncon problem - if not noncontextual_strategy == 'solved': + if not noncontextual_strategy == "solved": self._noncontextual_update() def manual_stabilizers(self, S: Union[List[str], IndependentOp]) -> None: - """ + """ Specify a set of operators to enforce manually. Args: @@ -96,14 +102,15 @@ def manual_stabilizers(self, S: Union[List[str], IndependentOp]) -> None: self.stabilizers = S self._prepare_stabilizers() - def update_stabilizers(self, - n_qubits: int, - strategy: str = 'aux_preserving', - aux_operator: PauliwordOp = None, - HF_array: np.array = None, - use_X_only: bool = True - ) -> None: - """ + def update_stabilizers( + self, + n_qubits: int, + strategy: str = "aux_preserving", + aux_operator: PauliwordOp = None, + HF_array: np.array = None, + use_X_only: bool = True, + ) -> None: + """ Update the stabilizers that will be used for the subspace projection. Args: @@ -113,9 +120,9 @@ def update_stabilizers(self, HF_array (np.array): Hartree-Fock state. By default, it is set to None. use_X_only (bool): Default value is 'True'. """ - assert(n_qubits<=self.operator.n_qubits), ( - 'Cannot define a contextual subspace larger than the base Hamiltonian' - ) + assert ( + n_qubits <= self.operator.n_qubits + ), "Cannot define a contextual subspace larger than the base Hamiltonian" if n_qubits == 0: n_qubits = 1 self.return_NC = True @@ -125,48 +132,48 @@ def update_stabilizers(self, if n_qubits == self.operator.n_qubits: self.stabilizers = None else: - if strategy == 'aux_preserving': + if strategy == "aux_preserving": S = self._aux_operator_preserving_stabilizer_search( n_qubits=n_qubits, aux_operator=aux_operator, use_X_only=use_X_only ) - elif strategy == 'random': - S = self._random_stabilizers( - n_qubits=n_qubits - ) - elif strategy == 'HOMO_LUMO_biasing': + elif strategy == "random": + S = self._random_stabilizers(n_qubits=n_qubits) + elif strategy == "HOMO_LUMO_biasing": S = self._HOMO_LUMO_biasing( - n_qubits=n_qubits, HF_array=HF_array, - weighting_operator=aux_operator, use_X_only=use_X_only + n_qubits=n_qubits, + HF_array=HF_array, + weighting_operator=aux_operator, + use_X_only=use_X_only, ) else: - raise ValueError('Unrecognised stabilizer search strategy.') + raise ValueError("Unrecognised stabilizer search strategy.") self.n_qubits_in_subspace = self.operator.n_qubits - S.n_terms self.stabilizers = S self._prepare_stabilizers() def _noncontextual_update(self): - """ + """ To be executed each time the noncontextual operator is updated. """ if self.noncontextual_operator is not None: self.noncontextual_operator.up_method = self.unitary_partitioning_method self.contextual_operator = self.operator - self.noncontextual_operator if self.contextual_operator.n_terms == 0: - raise ValueError('The Hamiltonian is noncontextual, the contextual subspace is empty.') + raise ValueError( + "The Hamiltonian is noncontextual, the contextual subspace is empty." + ) self.noncontextual_operator.solve( - strategy=self.noncontextual_solver, - ref_state=self.ref_state, + strategy=self.noncontextual_solver, + ref_state=self.ref_state, num_anneals=self.num_anneals, - expansion_order=self.noncontextual_expansion_order + expansion_order=self.noncontextual_expansion_order, ) self.n_cliques = self.noncontextual_operator.n_cliques - - def _aux_operator_preserving_stabilizer_search(self, - n_qubits: int, - aux_operator: PauliwordOp, - use_X_only: bool = True - ) -> IndependentOp: + + def _aux_operator_preserving_stabilizer_search( + self, n_qubits: int, aux_operator: PauliwordOp, use_X_only: bool = True + ) -> IndependentOp: """ Choose stabilizers that preserve some auxiliary operator. This could be an Ansatz operator such as UCCSD, for example. @@ -180,7 +187,7 @@ def _aux_operator_preserving_stabilizer_search(self, S (IndependentOp): Stablizer that preserves the passed auxiliary operator. """ if aux_operator is None: - if self.nc_strategy == 'StabilizeFirst': + if self.nc_strategy == "StabilizeFirst": aux_operator = self.operator else: aux_operator = self.contextual_operator @@ -190,14 +197,15 @@ def _aux_operator_preserving_stabilizer_search(self, return S - def _HOMO_LUMO_biasing(self, - n_qubits: int, - HF_array: np.array, - weighting_operator: PauliwordOp = None, - use_X_only:bool = True - ) -> IndependentOp: - """ - Bias the Hamiltonian with respect to the HOMO-LUMO gap + def _HOMO_LUMO_biasing( + self, + n_qubits: int, + HF_array: np.array, + weighting_operator: PauliwordOp = None, + use_X_only: bool = True, + ) -> IndependentOp: + """ + Bias the Hamiltonian with respect to the HOMO-LUMO gap and preserve terms in the resulting operator as above. Args: @@ -209,103 +217,116 @@ def _HOMO_LUMO_biasing(self, Returns: S (IndependentOp): Set of Stablizers """ - assert(HF_array is not None), 'Must supply the Hartree-Fock state for this strategy' - + assert ( + HF_array is not None + ), "Must supply the Hartree-Fock state for this strategy" + OB = ObservableBiasing( - base_operator=self.operator, - HOMO_LUMO_gap=np.where(np.asarray(HF_array==0).reshape(-1))[0][0]-.5 # currently assumes JW mapping! + base_operator=self.operator, + HOMO_LUMO_gap=np.where(np.asarray(HF_array == 0).reshape(-1))[0][0] + - 0.5, # currently assumes JW mapping! ) S = stabilizer_walk( - n_sim_qubits=n_qubits, - biasing_operator=OB, + n_sim_qubits=n_qubits, + biasing_operator=OB, weighting_operator=weighting_operator, - use_X_only=use_X_only + use_X_only=use_X_only, ) return S - def _random_stabilizers(self, - n_qubits: int - ) -> IndependentOp: - """ + def _random_stabilizers(self, n_qubits: int) -> IndependentOp: + """ Generate a random set of stabilizers. Args: n_qubits (int): Number of Qubits - - Returns: + + Returns: S (IndependentOp): Random set of Stablizers """ # TODO better approach that does not rely on this *potentially infinite* while loop! - found_stabilizers=False + found_stabilizers = False while not found_stabilizers: try: S = PauliwordOp.random( self.operator.n_qubits, - self.operator.n_qubits-n_qubits, - diagonal=True + self.operator.n_qubits - n_qubits, + diagonal=True, ) S.coeff_vec[:] = 1 S = IndependentOp.from_PauliwordOp(S) found_stabilizers = True except: pass - + return S def _prepare_stabilizers(self) -> None: - """ + """ Prepare the chosen stabilizers for projection into the contextual subspace. This includes eigenvalue assignment (obtained from the solution of the noncontextual Hamiltonian), and application of unitary partitioning if enforcing a clique element. """ self.S3_initialized = False - #the StabilizeFirst strategy differs from the others in that the noncontextual - #Hamiltonian is constructed AFTER selecting stabilizers, which is what we do here: - if self.nc_strategy == 'StabilizeFirst': - self.noncontextual_operator = NoncontextualOp._from_stabilizers_noncontextual_op( - H=self.operator, stabilizers=self.stabilizers, use_jordan_product=False + # the StabilizeFirst strategy differs from the others in that the noncontextual + # Hamiltonian is constructed AFTER selecting stabilizers, which is what we do here: + if self.nc_strategy == "StabilizeFirst": + self.noncontextual_operator = ( + NoncontextualOp._from_stabilizers_noncontextual_op( + H=self.operator, + stabilizers=self.stabilizers, + use_jordan_product=False, + ) ) self._noncontextual_update() if self.noncontextual_operator.n_cliques > 0: # mask stabilizers that lie within one of the noncontextual cliques - clique_commutation = self.stabilizers.commutes_termwise(self.noncontextual_operator.clique_operator) + clique_commutation = self.stabilizers.commutes_termwise( + self.noncontextual_operator.clique_operator + ) mask_which_clique = np.all(clique_commutation, axis=0) else: mask_which_clique = [] if ~np.all(mask_which_clique): # we may only enforce stabilizers that live within the same clique, not accross them: - assert(sum(mask_which_clique)==1), ( - 'Cannot enforce stabilizers from different cliques since '+ - 'unitary partitioning collapses onto just one of them.' + assert sum(mask_which_clique) == 1, ( + "Cannot enforce stabilizers from different cliques since " + + "unitary partitioning collapses onto just one of them." ) - # generate the unitary partitioning rotations that map onto the + # generate the unitary partitioning rotations that map onto the # clique representative correpsonding with the given stabilizers self.noncontextual_operator.update_clique_representative_operator( clique_index=int(np.where(mask_which_clique)[0][0]) ) - # add the clique representative to the noncontextual generators in order to - # update the eigenvalue assignments of the chosen stablizers so they are - # consistent with the noncontextual ground state configuration - this is - # G U {RARdag} in the original CS-VQE notation. + # add the clique representative to the noncontextual generators in order to + # update the eigenvalue assignments of the chosen stablizers so they are + # consistent with the noncontextual ground state configuration - this is + # G U {RARdag} in the original CS-VQE notation. augmented_generators = ( - IndependentOp(self.noncontextual_operator.mapped_clique_rep.symp_matrix, [-1]) + - self.noncontextual_operator.symmetry_generators + IndependentOp( + self.noncontextual_operator.mapped_clique_rep.symp_matrix, [-1] + ) + + self.noncontextual_operator.symmetry_generators ) # given these new generators, we reconstruct the given stabilizers to identify # the correct subspace corresponding with the noncontextual ground state (nu, r) - update_eigenvalues(generators=augmented_generators, stabilizers=self.stabilizers) + update_eigenvalues( + generators=augmented_generators, stabilizers=self.stabilizers + ) self.perform_unitary_partitioning = True else: update_eigenvalues( - generators=self.noncontextual_operator.symmetry_generators, - stabilizers=self.stabilizers + generators=self.noncontextual_operator.symmetry_generators, + stabilizers=self.stabilizers, ) self.perform_unitary_partitioning = False - def project_onto_subspace(self, operator_to_project:PauliwordOp=None) -> PauliwordOp: - """ - Projects with respect to the current stabilizers; these are + def project_onto_subspace( + self, operator_to_project: PauliwordOp = None + ) -> PauliwordOp: + """ + Projects with respect to the current stabilizers; these are updated using the ContextualSubspace.update_stabilizers method. Args: @@ -314,44 +335,53 @@ def project_onto_subspace(self, operator_to_project:PauliwordOp=None) -> Pauliwo Returns: Projection of operator passed. """ - # if not supplied with an alternative operator for projection, use the internal operator + # if not supplied with an alternative operator for projection, use the internal operator if operator_to_project is None: - operator_to_project = self.operator.copy() + operator_to_project = self.operator.copy() # if there are no stabilizers, return the input operator if self.stabilizers is None: - return operator_to_project + return operator_to_project # instantiate the parent S3_projection class that handles the subspace projection super().__init__(self.stabilizers) self.S3_initialized = True # perform unitary partitioning if self.perform_unitary_partitioning: # the rotation is implemented differently depending on the choice of LCU or seq_rot - if self.noncontextual_operator.up_method=='LCU': + if self.noncontextual_operator.up_method == "LCU": # linear-combination-of-unitaries approach - rotated_op = (self.noncontextual_operator.unitary_partitioning_rotations * operator_to_project - * self.noncontextual_operator.unitary_partitioning_rotations.dagger).cleanup() - elif self.noncontextual_operator.up_method=='seq_rot': + rotated_op = ( + self.noncontextual_operator.unitary_partitioning_rotations + * operator_to_project + * self.noncontextual_operator.unitary_partitioning_rotations.dagger + ).cleanup() + elif self.noncontextual_operator.up_method == "seq_rot": # sequence-of-rotations approach - rotated_op = operator_to_project.perform_rotations(self.noncontextual_operator.unitary_partitioning_rotations) + rotated_op = operator_to_project.perform_rotations( + self.noncontextual_operator.unitary_partitioning_rotations + ) else: - raise ValueError('Unrecognised unitary partitioning rotation method, must be one of LCU or seq_rot.') + raise ValueError( + "Unrecognised unitary partitioning rotation method, must be one of LCU or seq_rot." + ) else: rotated_op = operator_to_project # finally, project the operator before returning cs_operator = self.perform_projection(rotated_op) if self.return_NC: - assert cs_operator.n_qubits == 1, 'Projected operator consists of more than one qubit.' + assert ( + cs_operator.n_qubits == 1 + ), "Projected operator consists of more than one qubit." cs_operator = NoncontextualOp.from_PauliwordOp(cs_operator) cs_operator.solve() return cs_operator.energy else: return cs_operator - def project_state_onto_subspace(self, - state_to_project: QuantumState = None - ) -> QuantumState: - """ + def project_state_onto_subspace( + self, state_to_project: QuantumState = None + ) -> QuantumState: + """ Project a QuantumState into the contextual subspace Args: @@ -363,20 +393,29 @@ def project_state_onto_subspace(self, # if there are no stabilizers, return the input QuantumState if self.stabilizers is None: return state_to_project - - assert self.S3_initialized, 'Must first project an operator into the contextual subspace via the project_onto_subspace method' + + assert ( + self.S3_initialized + ), "Must first project an operator into the contextual subspace via the project_onto_subspace method" # can provide an auxiliary state to project, although not in general scalable if state_to_project is None: - assert self.ref_state is not None, 'Must provide a state to project into the contextual subspace' + assert ( + self.ref_state is not None + ), "Must provide a state to project into the contextual subspace" state_to_project = self.ref_state if self.perform_unitary_partitioning: # behaviour is different whether using the LCU or seq_rot UP methods - if self.noncontextual_operator.up_method == 'LCU': + if self.noncontextual_operator.up_method == "LCU": rotation = self.noncontextual_operator.unitary_partitioning_rotations - elif self.noncontextual_operator.up_method == 'seq_rot': - rotation_generator = sum([R*angle*.5*1j for R,angle in self.noncontextual_operator.unitary_partitioning_rotations]) + elif self.noncontextual_operator.up_method == "seq_rot": + rotation_generator = sum( + [ + R * angle * 0.5 * 1j + for R, angle in self.noncontextual_operator.unitary_partitioning_rotations + ] + ) rotation = trotter(rotation_generator) return self.project_state(rotation * state_to_project) else: - return self.project_state(state_to_project) \ No newline at end of file + return self.project_state(state_to_project) diff --git a/symmer/projection/qubit_subspace_manager.py b/symmer/projection/qubit_subspace_manager.py index 5613f07..7c85148 100644 --- a/symmer/projection/qubit_subspace_manager.py +++ b/symmer/projection/qubit_subspace_manager.py @@ -6,8 +6,9 @@ import numpy as np import warnings + class QubitSubspaceManager: - """ + """ Class for automating the following qubit subspace techqniques: *** QubitTapering *** @@ -20,10 +21,10 @@ class QubitSubspaceManager: - We then impose noncontextual symmetries over the contextual portion of the Hamiltonian, constrained by the noncontextual solution - Allows one to define a reduced Hamiltonian of any size but incurs error - + It is recommended that the user should specify a reference state, such as Hartree-Fock. Otherwise, Symmer will try to identify an - alternative refernce, either via direct diagonalization if the + alternative refernce, either via direct diagonalization if the Hamiltonian is sufficiently small, or using a DMRG calculation. Attributes: @@ -32,17 +33,18 @@ class QubitSubspaceManager: _projection_ready = False - def __init__(self, - hamiltonian: PauliwordOp, - ref_state: Union[np.ndarray, List[int], QuantumState] = None, - run_qubit_tapering: bool = True, - run_contextual_subspace: bool = True - ) -> None: + def __init__( + self, + hamiltonian: PauliwordOp, + ref_state: Union[np.ndarray, List[int], QuantumState] = None, + run_qubit_tapering: bool = True, + run_contextual_subspace: bool = True, + ) -> None: """ Args: hamiltonian (PauliwordOp): Hamiltonian which is to be projected. ref_state (QuantumState): Reference State. If no reference state is provided, then try to generate one. By default, it is set to None. - run_qubit_tapering (bool): If True, Qubit Tapering is performed. By default, it is set to True. + run_qubit_tapering (bool): If True, Qubit Tapering is performed. By default, it is set to True. run_contextual_subspace (bool): If True, Contextual Subspace Method is used to solve the problem. By default, it is set to True. """ self.hamiltonian = hamiltonian @@ -50,15 +52,15 @@ def __init__(self, self.run_qubit_tapering = run_qubit_tapering self.run_contextual_subspace = run_contextual_subspace self.build_subspace_objects() - + def prepare_ref_state(self, ref_state=None) -> QuantumState: - """ + """ If no reference state is provided, then try to generate one. If the Hamiltonian contains fewer than 12 qubits, we will diagonalise and select the true ground state. Otherwise, a cheap DMRG calculation will be performed to generate an approximate ground state. - Args: + Args: ref_state (QuantumState): Reference State. If no reference state is provided, then try to generate one. By default, it is set to None. Returns: @@ -71,13 +73,15 @@ def prepare_ref_state(self, ref_state=None) -> QuantumState: ref_state = QuantumState(ref_state, [1]) self._aux_operator = None else: - warnings.warn('No reference state supplied - trying to identify one via alternative means.') + warnings.warn( + "No reference state supplied - trying to identify one via alternative means." + ) if self.hamiltonian.n_qubits <= 12: _, ref_state = exact_gs_energy(self.hamiltonian.to_sparse_matrix) else: warnings.warn( - 'Results are currently unstable for reference state '+ - 'generation via tensor network techniques' + "Results are currently unstable for reference state " + + "generation via tensor network techniques" ) mpo = get_MPO(self.hamiltonian, max_bond_dimension=10) ref_state = find_groundstate_quimb(mpo) @@ -86,31 +90,31 @@ def prepare_ref_state(self, ref_state=None) -> QuantumState: return ref_state.cleanup(zero_threshold=1e-4).normalize def build_subspace_objects(self) -> None: - """ + """ Initialize the relevant qubit subspace classes. """ if self.run_qubit_tapering: - self.QT = QubitTapering(operator=self.hamiltonian) - self._hamiltonian = self.QT.taper_it(ref_state=self.ref_state) - self._ref_state = self.QT.tapered_ref_state.normalize + self.QT = QubitTapering(operator=self.hamiltonian) + self._hamiltonian = self.QT.taper_it(ref_state=self.ref_state) + self._ref_state = self.QT.tapered_ref_state.normalize self._Z2_symmetries = self.QT.symmetry_generators.copy() else: - self._hamiltonian = self.hamiltonian.copy() - self._ref_state = self.ref_state.copy() + self._hamiltonian = self.hamiltonian.copy() + self._ref_state = self.ref_state.copy() self._Z2_symmetries = None if self.run_contextual_subspace: self.CS = ContextualSubspace( operator=self._hamiltonian, reference_state=self._ref_state, - noncontextual_strategy='StabilizeFirst', - noncontextual_solver ='brute_force' + noncontextual_strategy="StabilizeFirst", + noncontextual_solver="brute_force", ) - def get_reduced_hamiltonian(self, - n_qubits:int=None, aux_operator:PauliwordOp=None - ) -> PauliwordOp: - """ + def get_reduced_hamiltonian( + self, n_qubits: int = None, aux_operator: PauliwordOp = None + ) -> PauliwordOp: + """ Project the Hamiltonian in line with the desired qubit subspace techqniques and, in the case of ContextualSubspace, the desired number of qubits. @@ -128,43 +132,55 @@ def get_reduced_hamiltonian(self, if n_qubits >= self.hamiltonian.n_qubits: warnings.warn( - 'Specified at least as many qubits as are present in the Hamiltonian - '+ - f'returning the full {self.hamiltonian.n_qubits} operator.') + "Specified at least as many qubits as are present in the Hamiltonian - " + + f"returning the full {self.hamiltonian.n_qubits} operator." + ) operator_out = self.hamiltonian elif n_qubits > self._hamiltonian.n_qubits: # if one wishes not to taper all the available Z2 symmetries - assert self.run_qubit_tapering, '' - self.QT.symmetry_generators = self._Z2_symmetries[:self.hamiltonian.n_qubits-n_qubits] + assert self.run_qubit_tapering, "" + self.QT.symmetry_generators = self._Z2_symmetries[ + : self.hamiltonian.n_qubits - n_qubits + ] operator_out = self.QT.taper_it(ref_state=self.ref_state) else: if self.run_qubit_tapering: - if not self.run_contextual_subspace and n_qubits < self._hamiltonian.n_qubits: + if ( + not self.run_contextual_subspace + and n_qubits < self._hamiltonian.n_qubits + ): warnings.warn( - 'When contextual subspace is not run we may only reduce '+ - 'the Hamiltonian by the number of Z2 symmetries present. '+ - f'The reduced Hamiltonian will contain {self._hamiltonian.n_qubits} qubits.' + "When contextual subspace is not run we may only reduce " + + "the Hamiltonian by the number of Z2 symmetries present. " + + f"The reduced Hamiltonian will contain {self._hamiltonian.n_qubits} qubits." ) self.QT.symmetry_generators = self._Z2_symmetries aux_operator = self.QT.taper_it(aux_operator=aux_operator) operator_out = self._hamiltonian if self.run_contextual_subspace: - assert n_qubits is not None, 'Must supply the desired number of qubits for the contextual subspace.' + assert ( + n_qubits is not None + ), "Must supply the desired number of qubits for the contextual subspace." self.CS.update_stabilizers( - n_qubits=n_qubits, aux_operator=aux_operator, strategy='aux_preserving' + n_qubits=n_qubits, + aux_operator=aux_operator, + strategy="aux_preserving", ) operator_out = self.CS.project_onto_subspace() if not self.run_qubit_tapering and not self.run_contextual_subspace: - warnings.warn('Not running any subspace methods - returning the original Hamiltonian') + warnings.warn( + "Not running any subspace methods - returning the original Hamiltonian" + ) operator_out = self.hamiltonian return operator_out - + def project_auxiliary_operator(self, operator: PauliwordOp) -> PauliwordOp: - """ + """ Project additional operators consistently with respect to the Hamiltonian. Args: @@ -173,42 +189,40 @@ def project_auxiliary_operator(self, operator: PauliwordOp) -> PauliwordOp: Returns: operator (PauliwordOp): Projection of additional operator. """ - assert self._projection_ready, 'Have not yet projected the Hamiltonian into the contextual subspace' + assert ( + self._projection_ready + ), "Have not yet projected the Hamiltonian into the contextual subspace" if self._n_qubits < self.hamiltonian.n_qubits: if self.run_qubit_tapering: operator = self.QT.taper_it(aux_operator=operator) - + if self.run_contextual_subspace: operator = self.CS.project_onto_subspace(operator_to_project=operator) return operator - + def project_auxiliary_state(self, state: QuantumState) -> QuantumState: - """ + """ Project quantum state consistently with respect to the Hamiltonian. Args: operator (QuantumState): Quantum State which has to be projected consistently with respect to the Hamiltonian. - + Returns: operator (PauliwordOp): Projection of Quantum State. """ - assert self._projection_ready, 'Have not yet projected the Hamiltonian into the contextual subspace' + assert ( + self._projection_ready + ), "Have not yet projected the Hamiltonian into the contextual subspace" if self._n_qubits < self.hamiltonian.n_qubits: if self.run_qubit_tapering: state = self.QT.project_state(state) - + if self.run_contextual_subspace: state = self.CS.project_state_onto_subspace(state_to_project=state) return state - - - - - - diff --git a/symmer/projection/qubit_tapering.py b/symmer/projection/qubit_tapering.py index 150d788..231fc51 100644 --- a/symmer/projection/qubit_tapering.py +++ b/symmer/projection/qubit_tapering.py @@ -6,29 +6,28 @@ from symmer.projection import S3_projection from symmer.operators import PauliwordOp, IndependentOp, QuantumState + class QubitTapering(S3_projection): - """ + """ Class for performing qubit tapering as per https://arxiv.org/abs/1701.08213. Reduces the number of qubits in the problem whilst preserving its energy spectrum by: 1. identifying a symmetry of the Hamiltonian, 2. finding an independent basis therein, - 3. rotating each basis operator onto a single Pauli X, + 3. rotating each basis operator onto a single Pauli X, 4. dropping the corresponding qubits from the Hamiltonian whilst 5. fixing the +/-1 eigenvalues Steps 1-2 are handled in this class whereas we defer to the parent S3_projection for 3-5. """ - def __init__(self, - operator: PauliwordOp, - target_sqp: str = 'X' - ) -> None: - """ + + def __init__(self, operator: PauliwordOp, target_sqp: str = "X") -> None: + """ Input the PauliwordOp we wish to taper. - There is freedom over the choice of single-qubit Pauli operator we wish to rotate onto, + There is freedom over the choice of single-qubit Pauli operator we wish to rotate onto, however this is set to X by default (in line with the original tapering paper). - Args: + Args: operator (PauliwordOp): The Operator you want to tapper. target_sqp (str): The single-qubit Pauli operator we wish to rotate onto. By default, it is set to 'X'. """ @@ -36,10 +35,10 @@ def __init__(self, self.target_sqp = target_sqp self.n_taper = self.symmetry_generators.n_terms super().__init__(self.symmetry_generators) - + @cached_property def symmetry_generators(self) -> IndependentOp: - """ + """ Find an independent basis for the input operator symmetry. Returns: @@ -49,20 +48,21 @@ def symmetry_generators(self) -> IndependentOp: stabilizers.target_sqp = self.target_sqp return stabilizers - def taper_it(self, - ref_state: Union[List[int], np.array]=None, - sector: Union[List[int], np.array]=None, - aux_operator: PauliwordOp = None - ) -> PauliwordOp: - """ - Finally, once the symmetry generators and sector have been identified, - we may perform a projection onto the corresponding stabilizer subspace via + def taper_it( + self, + ref_state: Union[List[int], np.array] = None, + sector: Union[List[int], np.array] = None, + aux_operator: PauliwordOp = None, + ) -> PauliwordOp: + """ + Finally, once the symmetry generators and sector have been identified, + we may perform a projection onto the corresponding stabilizer subspace via the parent S3_projection class. This method allows one to input an auxiliary operator other than the internal - operator itself to be tapered consistently with the identified symmetry. This is - especially useful when considering an Ansatz defined over the full system that - one wishes to restrict to the same stabilizer subspace as the Hamiltonian for + operator itself to be tapered consistently with the identified symmetry. This is + especially useful when considering an Ansatz defined over the full system that + one wishes to restrict to the same stabilizer subspace as the Hamiltonian for use in VQE, for example. Args: @@ -76,12 +76,14 @@ def taper_it(self, if ref_state is not None: if not isinstance(ref_state, QuantumState): ref_state = QuantumState(ref_state) - assert ref_state._is_normalized(), 'Reference state is not normalized.' + assert ref_state._is_normalized(), "Reference state is not normalized." if self.symmetry_generators != self.stabilizers: # need to update stabilizers in parent class if user decides to fix less stabilizers (e.g. doesn't want # to taper all stabilizers). Could be useful in error mitigation strategies - warnings.warn('the defined symmetry generators have been updated from parent class stabilizers') + warnings.warn( + "the defined symmetry generators have been updated from parent class stabilizers" + ) super().__init__(self.symmetry_generators) # allow an auxiliary operator (e.g. an Ansatz) to be tapered @@ -92,9 +94,7 @@ def taper_it(self, # taper the operator via S3_projection.perform_projection tapered_operator = self.perform_projection( - operator=operator_to_taper, - ref_state=ref_state, - sector=sector + operator=operator_to_taper, ref_state=ref_state, sector=sector ) # if a reference state was supplied, project it into the stabilizer subspace diff --git a/symmer/projection/utils.py b/symmer/projection/utils.py index 3a591c3..248de11 100644 --- a/symmer/projection/utils.py +++ b/symmer/projection/utils.py @@ -5,6 +5,7 @@ from typing import Union, Optional from symmer.utils import random_anitcomm_2n_1_PauliwordOp, product_list + def norm(vector: np.array) -> float: """ Args: @@ -15,7 +16,8 @@ def norm(vector: np.array) -> float: """ return np.sqrt(np.dot(vector, vector.conjugate())) -def lp_norm(vector: np.array, p:int=2) -> float: + +def lp_norm(vector: np.array, p: int = 2) -> float: """ Args: vector (np.array): Vector whose lp-norm has to be found. @@ -24,25 +26,25 @@ def lp_norm(vector: np.array, p:int=2) -> float: Returns: lp-norm of vector """ - return np.power(np.sum(np.power(np.abs(vector), p)), 1/p) + return np.power(np.sum(np.power(np.abs(vector), p)), 1 / p) + def one_qubit_noncontextual_gs(op: PauliwordOp): - assert op.n_qubits == 1, 'Operator consists of more than one qubit' + assert op.n_qubits == 1, "Operator consists of more than one qubit" op.to + def basis_score( - weighting_operator: PauliwordOp, - basis: IndependentOp, - p:int=1 - ) -> float: - """ - Evaluate the score of an input basis according + weighting_operator: PauliwordOp, basis: IndependentOp, p: int = 1 +) -> float: + """ + Evaluate the score of an input basis according to the basis weighting operator, for example: - set Hamiltonian cofficients to 1 for unweighted number of commuting terms - specify as the SOR Hamiltonian to weight according to second-order response - input UCC operator to weight according to coupled-cluster theory <- best performance - if None given then weights by Hamiltonian coefficient magnitude - + p determines which norm is used, i.e. lp --> (\sum_{t} |t|^p)^(1/p) Args: @@ -54,39 +56,34 @@ def basis_score( Basis score (float) of the input basis. """ # mask terms of the weighting operator that are preserved under projection over the basis - mask_preserved = np.where(np.all(weighting_operator.commutes_termwise(basis),axis=1))[0] - return ( - lp_norm(weighting_operator.coeff_vec[mask_preserved], p=p) / - lp_norm(weighting_operator.coeff_vec, p=p) + mask_preserved = np.where( + np.all(weighting_operator.commutes_termwise(basis), axis=1) + )[0] + return lp_norm(weighting_operator.coeff_vec[mask_preserved], p=p) / lp_norm( + weighting_operator.coeff_vec, p=p ) -def update_eigenvalues( - generators: IndependentOp, - stabilizers: IndependentOp - ) -> None: - """ + +def update_eigenvalues(generators: IndependentOp, stabilizers: IndependentOp) -> None: + """ Update the +/-1 eigenvalue assigned to the input stabilizer according to the noncontextual ground state configuration. - + Args: generators (IndependentOp): Generator - stabilizers (IndependentOp): Stabilizer + stabilizers (IndependentOp): Stabilizer """ - reconstruction, successfully_reconstructed = stabilizers.generator_reconstruction(generators) + reconstruction, successfully_reconstructed = stabilizers.generator_reconstruction( + generators + ) if ~np.all(successfully_reconstructed): - raise ValueError('Generators not sufficient to reconstruct symmetry operators') + raise ValueError("Generators not sufficient to reconstruct symmetry operators") stabilizers.coeff_vec = (-1) ** np.count_nonzero( - np.bitwise_and( - reconstruction, - np.asarray(generators.coeff_vec)==-1 - ), - axis=1 + np.bitwise_and(reconstruction, np.asarray(generators.coeff_vec) == -1), axis=1 ) + class StabilizerIdentification: - def __init__(self, - weighting_operator: PauliwordOp, - use_X_only = False - ) -> None: + def __init__(self, weighting_operator: PauliwordOp, use_X_only=False) -> None: """ Args: weighting_operator (PauliwordOp): Basis weighting operator. By default, it is set to None. @@ -100,28 +97,32 @@ def build_basis_weighting_operator(self): if self.use_X_only: X_block = self.weighting_operator.X_block self.weighting_operator = PauliwordOp( - np.hstack([X_block, np.zeros_like(X_block)]), - np.abs(self.weighting_operator.coeff_vec) + np.hstack([X_block, np.zeros_like(X_block)]), + np.abs(self.weighting_operator.coeff_vec), ).cleanup() - self.basis_weighting = self.weighting_operator.sort(by='magnitude') + self.basis_weighting = self.weighting_operator.sort(by="magnitude") self.qubit_positions = np.arange(self.weighting_operator.n_qubits) - self.term_region = [0,self.basis_weighting.n_terms] - + self.term_region = [0, self.basis_weighting.n_terms] + def symmetry_generators_by_term_significance(self, n_preserved): - """ + """ Set the number of terms to be preserved in order of coefficient magnitude, Then generate the largest symmetry basis that preserves them. - Args: + Args: n_preserved (int): Number of terms to be preserved in order of coefficient magnitude. - + Returns: The largest symmetry basis that preserves order of coefficient magnitude. """ preserve = self.basis_weighting[:n_preserved] - stabilizers = IndependentOp.symmetry_generators(preserve, commuting_override=True) + stabilizers = IndependentOp.symmetry_generators( + preserve, commuting_override=True + ) mask_diag = np.where(~np.any(stabilizers.X_block, axis=1))[0] - return IndependentOp(stabilizers.symp_matrix[mask_diag], stabilizers.coeff_vec[mask_diag]) + return IndependentOp( + stabilizers.symp_matrix[mask_diag], stabilizers.coeff_vec[mask_diag] + ) def symmetry_generators_by_subspace_dimension(self, n_sim_qubits, region=None): """ @@ -134,42 +135,50 @@ def symmetry_generators_by_subspace_dimension(self, n_sim_qubits, region=None): """ if region is None: region = deepcopy(self.term_region) - assert(n_sim_qubits < self.basis_weighting.n_qubits), 'Number of qubits to simulate exceeds those in the operator' - assert(region[1]-region[0]>1), 'Search region collapsed without identifying any stabilizers' - - n_terms = sum(region)//2 + assert ( + n_sim_qubits < self.basis_weighting.n_qubits + ), "Number of qubits to simulate exceeds those in the operator" + assert ( + region[1] - region[0] > 1 + ), "Search region collapsed without identifying any stabilizers" + + n_terms = sum(region) // 2 stabilizers = self.symmetry_generators_by_term_significance(n_terms) current_n_qubits = self.basis_weighting.n_qubits - stabilizers.n_terms sign = np.sign(current_n_qubits - n_sim_qubits) - if sign==0: + if sign == 0: # i.e. n_sim_qubits == current_n_qubits return stabilizers - elif sign==+1: + elif sign == +1: # i.e. n_sim_qubits < current_n_qubits region[1] = n_terms else: region[0] = n_terms - - return self.symmetry_generators_by_subspace_dimension(n_sim_qubits, region=region) + + return self.symmetry_generators_by_subspace_dimension( + n_sim_qubits, region=region + ) + class ObservableBiasing: - """ + """ Class for re-weighting Hamiltonian terms based on some criteria, such as HOMO-LUMO bias. - + Attributes: HOMO_bias (float): HUMO Bias. Its value is in between 0 and 1. By default it's value is set to be 0.2 LUMO_bias (float): LUMO Bias. Its value is in between 0 and 1. By default it's value is set to be 0.2 seperation (int): Separation between the two distributions. By default it is set to 1. A value of 1 means each distribution is peaked either side of the HOMO-LUMO gap. """ - # HOMO/LUMO bias is a value between 0 and 1 representing how sharply + + # HOMO/LUMO bias is a value between 0 and 1 representing how sharply # peaked the Gaussian distributions centred at each point should be HOMO_bias = 0.2 LUMO_bias = 0.2 - # Can also specify the separation between the two distributions... + # Can also specify the separation between the two distributions... # a value of 1 means each is peaked either side of the HOMO-LUMO gap separation = 1 - + def __init__(self, base_operator: PauliwordOp, HOMO_LUMO_gap) -> None: """ Args: @@ -177,15 +186,15 @@ def __init__(self, base_operator: PauliwordOp, HOMO_LUMO_gap) -> None: HOMO_LUMO_gap: HOMO-LUMO gap. It should be specified as the mid-point between the HOMO and LUMO indices. """ self.base_operator = base_operator - assert( + assert ( HOMO_LUMO_gap - int(HOMO_LUMO_gap) == 0.5 - ), 'HOMO_LUMO_gap should be specified as the mid-point between the HOMO and LUMO indices' + ), "HOMO_LUMO_gap should be specified as the mid-point between the HOMO and LUMO indices" self.HOMO_LUMO_gap = HOMO_LUMO_gap # shift qubit positions such that HOMO-LUMO gap is centred at zero self.shifted_q_pos = np.arange(base_operator.n_qubits) - self.HOMO_LUMO_gap - + def HOMO_LUMO_bias_curve(self) -> np.array: - """ + """ Curve constructed from two gaussians centred either side of the HOMO-LUMO gap. The standard deviation for each distribution can be tuned independently via the parameters HOMO_sig (lower population), LUMO_sig (upper population) in [0, pi/2]. @@ -193,27 +202,31 @@ def HOMO_LUMO_bias_curve(self) -> np.array: Returns: HOMO LUMO bias curve (np.array). """ - shift = self.separation - 1/2 + shift = self.separation - 1 / 2 # standard deviation about the HOMO/LUMO-centred Gaussian distributions: - HOMO_sigma = np.tan((1-self.HOMO_bias)*np.pi/2) - LUMO_sigma = np.tan((1-self.LUMO_bias)*np.pi/2) + HOMO_sigma = np.tan((1 - self.HOMO_bias) * np.pi / 2) + LUMO_sigma = np.tan((1 - self.LUMO_bias) * np.pi / 2) # lower population (centred at HOMO) - if HOMO_sigma!=0: - L = np.exp(-np.square((self.shifted_q_pos+shift)/HOMO_sigma)/2) + if HOMO_sigma != 0: + L = np.exp(-np.square((self.shifted_q_pos + shift) / HOMO_sigma) / 2) else: - non_zero_index = int(self.HOMO_LUMO_gap-shift) - L = np.eye(1,self.base_operator.n_qubits,non_zero_index).reshape(self.base_operator.n_qubits) + non_zero_index = int(self.HOMO_LUMO_gap - shift) + L = np.eye(1, self.base_operator.n_qubits, non_zero_index).reshape( + self.base_operator.n_qubits + ) # upper population (centred at LUMO) - if LUMO_sigma!=0: - U = np.exp(-np.square((self.shifted_q_pos-shift)/LUMO_sigma)/2) + if LUMO_sigma != 0: + U = np.exp(-np.square((self.shifted_q_pos - shift) / LUMO_sigma) / 2) else: - non_zero_index = int(self.HOMO_LUMO_gap+shift) - U = np.eye(1,self.base_operator.n_qubits,non_zero_index).reshape(self.base_operator.n_qubits) - return (L + U)/2 - + non_zero_index = int(self.HOMO_LUMO_gap + shift) + U = np.eye(1, self.base_operator.n_qubits, non_zero_index).reshape( + self.base_operator.n_qubits + ) + return (L + U) / 2 + def HOMO_LUMO_biased_operator(self) -> np.array: - """ - - First converts the base operator to a PauliwordOp consisting of Pauli I, X + """ + - First converts the base operator to a PauliwordOp consisting of Pauli I, X (since only interested in where the terms can affect orbital occupation) - Second, assigns a weight to each nontrivial qubit position according to the bias curve and sums the total HOM-LUMO-biased contribution. This is multiplied by the coefficient @@ -223,19 +236,20 @@ def HOMO_LUMO_biased_operator(self) -> np.array: reweighted_operator (PauliwordOp): Reweighted Operator. """ reweighted_operator = self.base_operator.copy() - reweighted_operator.coeff_vec = np.sum( - reweighted_operator.X_block*self.HOMO_LUMO_bias_curve(), - axis=1 - )*reweighted_operator.coeff_vec + reweighted_operator.coeff_vec = ( + np.sum(reweighted_operator.X_block * self.HOMO_LUMO_bias_curve(), axis=1) + * reweighted_operator.coeff_vec + ) return reweighted_operator + def stabilizer_walk( - n_sim_qubits, - biasing_operator: ObservableBiasing, - weighting_operator: PauliwordOp = None, - print_info: bool = False, - use_X_only: bool = False - ) -> IndependentOp: + n_sim_qubits, + biasing_operator: ObservableBiasing, + weighting_operator: PauliwordOp = None, + print_info: bool = False, + use_X_only: bool = False, +) -> IndependentOp: """ Args: n_sim_qubits (int): Number of qubits to simulate. @@ -249,32 +263,35 @@ def stabilizer_walk( """ if weighting_operator is None: weighting_operator = biasing_operator.base_operator - + def get_stabilizers(x): - biasing_operator.HOMO_bias,biasing_operator.LUMO_bias = x + biasing_operator.HOMO_bias, biasing_operator.LUMO_bias = x biased_op = biasing_operator.HOMO_LUMO_biased_operator() stabilizers = StabilizerIdentification(biased_op, use_X_only=use_X_only) S = stabilizers.symmetry_generators_by_subspace_dimension(n_sim_qubits) - return(S) - + return S + def objective(x): S = get_stabilizers(x) stab_score = basis_score(weighting_operator, S) return -stab_score - - opt_out = differential_evolution(objective, bounds=[(0,1),(0,1)]) - stab_score =-opt_out['fun'] - bias_param =opt_out['x'] + + opt_out = differential_evolution(objective, bounds=[(0, 1), (0, 1)]) + stab_score = -opt_out["fun"] + bias_param = opt_out["x"] S = get_stabilizers(bias_param) - + if print_info: - print(f'Optimal score w(S)={stab_score} for HOMO/LUMO bias {bias_param}') - + print(f"Optimal score w(S)={stab_score} for HOMO/LUMO bias {bias_param}") + return S -def get_noncon_generators_from_commuting_stabilizers(stabilizers: Union[PauliwordOp, IndependentOp], - weighting_operator: PauliwordOp, - return_clique_only: Optional[bool] = False) -> IndependentOp: + +def get_noncon_generators_from_commuting_stabilizers( + stabilizers: Union[PauliwordOp, IndependentOp], + weighting_operator: PauliwordOp, + return_clique_only: Optional[bool] = False, +) -> IndependentOp: """ Given a set of commuting stabilizers and weighting operator find best noncontextual generating set (ie works out best anticommuting addition to generators that reconstructs most of the weighting_operator) @@ -288,27 +305,37 @@ def get_noncon_generators_from_commuting_stabilizers(stabilizers: Union[Pauliwor """ if not np.all(stabilizers.commutes_termwise(stabilizers)): # stabilizers already contain ac component - return stabilizers #, PauliwordOp.empty(stabilizers.n_qubits).cleanup() + return stabilizers # , PauliwordOp.empty(stabilizers.n_qubits).cleanup() else: # below generates the generators of inout stabilizers generators = stabilizers.generators best_l1_norm = -1 # find qubits uniquely defined by generators - unique_q_inds = ~(np.sum(np.logical_xor(generators.Z_block, generators.X_block), axis=0)-1).astype(bool) + unique_q_inds = ~( + np.sum(np.logical_xor(generators.Z_block, generators.X_block), axis=0) - 1 + ).astype(bool) for stab in generators: # find unique non identity positions - act_positions = np.logical_and(np.logical_xor(stab.Z_block, stab.X_block)[0], unique_q_inds) + act_positions = np.logical_and( + np.logical_xor(stab.Z_block, stab.X_block)[0], unique_q_inds + ) # work out number of qubits on these positions n_act_qubits = np.sum(act_positions) # find AC clique of size 2n containing given stabilizer - ac_basis = random_anitcomm_2n_1_PauliwordOp(n_act_qubits, apply_clifford=False)[1:] - new_basis = PauliwordOp(np.zeros((n_act_qubits * 2, stab.n_qubits * 2), dtype=bool), - np.ones(n_act_qubits * 2)) - - new_basis.symp_matrix[:, [*act_positions, *act_positions]] = ac_basis.symp_matrix + ac_basis = random_anitcomm_2n_1_PauliwordOp(n_act_qubits, apply_clifford=False)[ + 1: + ] + new_basis = PauliwordOp( + np.zeros((n_act_qubits * 2, stab.n_qubits * 2), dtype=bool), + np.ones(n_act_qubits * 2), + ) + + new_basis.symp_matrix[ + :, [*act_positions, *act_positions] + ] = ac_basis.symp_matrix # ensure stab is in new_basis gen, mask = stab.generator_reconstruction(new_basis) @@ -328,7 +355,7 @@ def get_noncon_generators_from_commuting_stabilizers(stabilizers: Union[Pauliwor best_l1_norm = l1_norm stab_used = stab.copy() - assert new_stabilizers.is_noncontextual, 'new stabilizers are not noncontextual' + assert new_stabilizers.is_noncontextual, "new stabilizers are not noncontextual" # commuting_stabs = IndependentOp.from_PauliwordOp(stabilizers) # anticommuting_stabs = IndependentOp.from_PauliwordOp(new_stabilizers) - commuting_stabs @@ -336,4 +363,4 @@ def get_noncon_generators_from_commuting_stabilizers(stabilizers: Union[Pauliwor if return_clique_only: return IndependentOp.from_PauliwordOp(new_stabilizers) - generators, stab_used else: - return IndependentOp.from_PauliwordOp(new_stabilizers) \ No newline at end of file + return IndependentOp.from_PauliwordOp(new_stabilizers) diff --git a/symmer/utils.py b/symmer/utils.py index 6cefe6e..c72e44b 100644 --- a/symmer/utils.py +++ b/symmer/utils.py @@ -10,18 +10,16 @@ import multiprocessing as mp import ray import os + # from psutil import cpu_count + def exact_gs_energy( - sparse_matrix, - initial_guess=None, - n_particles=None, - number_operator=None, - n_eigs=6 - ) -> Tuple[float, np.array]: - """ + sparse_matrix, initial_guess=None, n_particles=None, number_operator=None, n_eigs=6 +) -> Tuple[float, np.array]: + """ Return the ground state energy and corresponding ground statevector for the input operator - + Specifying a particle number will restrict to eigenvectors |ψ> such that <ψ|N_op|ψ> = n_particles where N_op is the given number operator. @@ -43,42 +41,50 @@ def exact_gs_energy( # Note the eigenvectors are stored column-wise so need to transpose if sparse_matrix.shape[0] > 2**5: eigvals, eigvecs = sp.sparse.linalg.eigsh( - sparse_matrix,k=n_eigs,v0=initial_guess,which='SA',maxiter=1e7 + sparse_matrix, k=n_eigs, v0=initial_guess, which="SA", maxiter=1e7 ) else: # for small matrices the dense representation can be more efficient than sparse! eigvals, eigvecs = np.linalg.eigh(sparse_matrix.toarray()) - + # order the eigenvalues by increasing size order = np.argsort(eigvals) eigvals, eigvecs = eigvals[order], eigvecs[:, order] - + if n_particles is None: # if no particle number is specified then return the smallest eigenvalue - return eigvals[0], QuantumState.from_array(eigvecs[:,0].reshape([-1,1])) + return eigvals[0], QuantumState.from_array(eigvecs[:, 0].reshape([-1, 1])) else: - assert(number_operator is not None), 'Must specify the number operator.' + assert number_operator is not None, "Must specify the number operator." # otherwise, search through the first n_eig eigenvalues and check the Hamming weight # of the the corresponding eigenvector - return the first match with n_particles for evl, evc in zip(eigvals, eigvecs.T): - psi = QuantumState.from_array(evc.reshape([-1,1])).cleanup(zero_threshold=1e-5) - assert(~np.any(number_operator.X_block)), 'Number operator not diagonal' + psi = QuantumState.from_array(evc.reshape([-1, 1])).cleanup( + zero_threshold=1e-5 + ) + assert ~np.any(number_operator.X_block), "Number operator not diagonal" expval_n_particle = 0 - for Z_symp, Z_coeff in zip(number_operator.Z_block, number_operator.coeff_vec): - sign = (-1) ** np.einsum('ij->i', - np.bitwise_and( - Z_symp, psi.state_matrix - ) + for Z_symp, Z_coeff in zip( + number_operator.Z_block, number_operator.coeff_vec + ): + sign = (-1) ** np.einsum( + "ij->i", np.bitwise_and(Z_symp, psi.state_matrix) + ) + expval_n_particle += Z_coeff * np.sum( + sign * np.square(abs(psi.state_op.coeff_vec)) ) - expval_n_particle += Z_coeff * np.sum(sign * np.square(abs(psi.state_op.coeff_vec))) if np.round(expval_n_particle) == n_particles: - return evl, QuantumState.from_array(evc.reshape([-1,1])) + return evl, QuantumState.from_array(evc.reshape([-1, 1])) # if a solution is not found within the first n_eig eigenvalues then error - raise RuntimeError('No eigenvector of the correct particle number was identified - try increasing n_eigs.') + raise RuntimeError( + "No eigenvector of the correct particle number was identified - try increasing n_eigs." + ) -def random_anitcomm_2n_1_PauliwordOp(n_qubits, complex_coeff=False, apply_clifford=True): - """ +def random_anitcomm_2n_1_PauliwordOp( + n_qubits, complex_coeff=False, apply_clifford=True +): + """ Generate a anticommuting PauliOperator of size 2n+1 on n qubits (max possible size) with normally distributed coefficients. Generates in structured way then uses Clifford rotation (default) to try and make more random (can stop this to allow FAST build, but inherenet structure @@ -141,33 +147,35 @@ def random_anitcomm_2n_1_PauliwordOp(n_qubits, complex_coeff=False, apply_cliffo return P_anticomm -def tensor_list(factor_list:List[PauliwordOp]) -> PauliwordOp: - """ +def tensor_list(factor_list: List[PauliwordOp]) -> PauliwordOp: + """ Given a list of PauliwordOps, recursively tensor from the right - + Args: factor_list (list): list of PauliwordOps - - Returns: - Tensor Product of items in factor_list from the right + + Returns: + Tensor Product of items in factor_list from the right """ - return reduce(lambda x,y:x.tensor(y), factor_list) + return reduce(lambda x, y: x.tensor(y), factor_list) -def product_list(product_list:List[PauliwordOp]) -> PauliwordOp: - """ +def product_list(product_list: List[PauliwordOp]) -> PauliwordOp: + """ Given a list of PauliwordOps, recursively take product from the right Args: product_list (list): list of PauliwordOps Returns: - Product of items in product_list from the right + Product of items in product_list from the right """ - return reduce(lambda x,y:x*y, product_list) + return reduce(lambda x, y: x * y, product_list) -def gram_schmidt_from_quantum_state(state:Union[np.array, list, QuantumState]) ->np.array: +def gram_schmidt_from_quantum_state( + state: Union[np.array, list, QuantumState] +) -> np.array: """ build a unitary to build a quantum state from the zero state (aka state defines first column of unitary) uses gram schmidt to find other (orthogonal) columns of matrix @@ -187,31 +195,31 @@ def gram_schmidt_from_quantum_state(state:Union[np.array, list, QuantumState]) - missing_amps = 2**N_qubits - state.shape[0] state = np.hstack((state, np.zeros(missing_amps, dtype=complex))) - assert state.shape[0] == 2**N_qubits, 'state is not defined on power of two' - assert np.isclose(np.linalg.norm(state), 1), 'state is not normalized' + assert state.shape[0] == 2**N_qubits, "state is not defined on power of two" + assert np.isclose(np.linalg.norm(state), 1), "state is not normalized" M = np.eye(2**N_qubits, dtype=complex) # reorder if state has 0 amp on zero index if np.isclose(state[0], 0): max_amp_ind = np.argmax(state) - M[:, [0, max_amp_ind]] = M[:, [max_amp_ind,0]] + M[:, [0, max_amp_ind]] = M[:, [max_amp_ind, 0]] # defines first column M[:, 0] = state for a in range(M.shape[0]): for b in range(a): - M[:, a]-= (M[:, b].conj().T @ M[:, a]) * M[:, b] + M[:, a] -= (M[:, b].conj().T @ M[:, a]) * M[:, b] # normalize - M[:, a] = M[:, a] / np.linalg.norm( M[:, a]) + M[:, a] = M[:, a] / np.linalg.norm(M[:, a]) return M def Draw_molecule( - xyz_string: str, width: int = 400, height: int = 400, style: str = "sphere" - ) -> py3Dmol.view: + xyz_string: str, width: int = 400, height: int = 400, style: str = "sphere" +) -> py3Dmol.view: """Draw molecule from xyz string. Note if molecule has unrealistic bonds, then style should be sphere. Otherwise stick style can be used @@ -231,9 +239,9 @@ def Draw_molecule( view = py3Dmol.view(width=width, height=height) view.addModel(xyz_string, "xyz") if style == "sphere": - view.setStyle({'sphere': {"radius": 0.2}}) + view.setStyle({"sphere": {"radius": 0.2}}) elif style == "stick": - view.setStyle({'stick': {}}) + view.setStyle({"stick": {}}) else: raise ValueError(f"unknown py3dmol style: {style}") @@ -255,7 +263,7 @@ def get_sparse_matrix_large_pauliwordop(P_op: PauliwordOp) -> csr_matrix: mat (csr_matrix): sparse matrix of P_op """ nq = P_op.n_qubits - if nq<16: + if nq < 16: mat = P_op.to_sparse_matrix else: # n_cpus = mp.cpu_count() @@ -268,53 +276,68 @@ def get_sparse_matrix_large_pauliwordop(P_op: PauliwordOp) -> csr_matrix: # plus one below due to indexing (actual number of chunks ignores this value) n_chunks = os.cpu_count() - if (n_chunks<=1) or (P_op.n_terms<=1): + if (n_chunks <= 1) or (P_op.n_terms <= 1): # no multiprocessing possible mat = ray.get(_get_sparse_matrix_large_pauliwordop.remote(P_op)) else: # plus one below due to indexing (actual number of chunks ignores this value) n_chunks += 1 - P_op_chunks_inds = np.rint(np.linspace(0, P_op.n_terms, min(n_chunks, P_op.n_terms+1))).astype(set).astype(int) - P_op_chunks = [P_op[P_op_chunks_inds[ind_i]: P_op_chunks_inds[ind_i + 1]] for ind_i, _ in - enumerate(P_op_chunks_inds[1:])] - tracker = np.array(ray.get( - [_get_sparse_matrix_large_pauliwordop.remote(op) for op in P_op_chunks])) + P_op_chunks_inds = ( + np.rint(np.linspace(0, P_op.n_terms, min(n_chunks, P_op.n_terms + 1))) + .astype(set) + .astype(int) + ) + P_op_chunks = [ + P_op[P_op_chunks_inds[ind_i] : P_op_chunks_inds[ind_i + 1]] + for ind_i, _ in enumerate(P_op_chunks_inds[1:]) + ] + tracker = np.array( + ray.get( + [ + _get_sparse_matrix_large_pauliwordop.remote(op) + for op in P_op_chunks + ] + ) + ) mat = reduce(lambda x, y: x + y, tracker) return mat -@ray.remote(num_cpus=os.cpu_count(), - runtime_env={ - "env_vars": { - "NUMBA_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), - # "OMP_NUM_THREADS": str(os.cpu_count()), - "OMP_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), - "NUMEXPR_MAX_THREADS": str(os.cpu_count()) - } - } - ) + +@ray.remote( + num_cpus=os.cpu_count(), + runtime_env={ + "env_vars": { + "NUMBA_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), + # "OMP_NUM_THREADS": str(os.cpu_count()), + "OMP_NUM_THREADS": os.getenv("NUMBA_NUM_THREADS"), + "NUMEXPR_MAX_THREADS": str(os.cpu_count()), + } + }, +) def _get_sparse_matrix_large_pauliwordop(P_op: PauliwordOp) -> csr_matrix: - """ - """ + """ """ nq = P_op.n_qubits - mat = csr_matrix(([], ([],[])), shape=(2**nq,2**nq)) + mat = csr_matrix(([], ([], [])), shape=(2**nq, 2**nq)) for op in P_op: - left_tensor = np.hstack((op.X_block[:, :nq // 2], - op.Z_block[:, :nq // 2])) + left_tensor = np.hstack((op.X_block[:, : nq // 2], op.Z_block[:, : nq // 2])) left_coeff = op.coeff_vec - right_tensor = np.hstack((op.X_block[:, nq // 2:], - op.Z_block[:, nq // 2:])) + right_tensor = np.hstack((op.X_block[:, nq // 2 :], op.Z_block[:, nq // 2 :])) right_coeff = np.array([1]) - mat += sparse_kron(PauliwordOp(left_tensor, left_coeff).to_sparse_matrix, - PauliwordOp(right_tensor, right_coeff).to_sparse_matrix, - format='csr') # setting format makes this faster! + mat += sparse_kron( + PauliwordOp(left_tensor, left_coeff).to_sparse_matrix, + PauliwordOp(right_tensor, right_coeff).to_sparse_matrix, + format="csr", + ) # setting format makes this faster! return mat -def matrix_allclose(A: Union[csr_matrix, np.array], B:Union[csr_matrix, np.array], tol:int = 1e-15) -> bool: +def matrix_allclose( + A: Union[csr_matrix, np.array], B: Union[csr_matrix, np.array], tol: int = 1e-15 +) -> bool: """ check matrix A and B have the same entries up to a given tolerance Args: @@ -327,7 +350,7 @@ def matrix_allclose(A: Union[csr_matrix, np.array], B:Union[csr_matrix, np.array """ if isinstance(A, csr_matrix) and isinstance(B, csr_matrix): - max_diff = np.abs(A-B).max() + max_diff = np.abs(A - B).max() return max_diff <= tol else: if isinstance(A, csr_matrix): @@ -358,15 +381,16 @@ def get_PauliwordOp_root(power: int, pauli: PauliwordOp) -> PauliwordOp: Pk (PauliwordOp): Pauli operator that is power of input """ - assert pauli.n_terms == 1, 'can only take power of single operators' + assert pauli.n_terms == 1, "can only take power of single operators" - I_term = PauliwordOp.from_list(['I' * pauli.n_qubits]) + I_term = PauliwordOp.from_list(["I" * pauli.n_qubits]) cos_term = np.cos(power * np.pi / 2) sin_term = np.sin(power * np.pi / 2) - Pk = (I_term.multiply_by_constant(cos_term ** 2 + 1j * cos_term * sin_term) + - pauli.multiply_by_constant(-1j * cos_term * sin_term + sin_term ** 2)) + Pk = I_term.multiply_by_constant( + cos_term**2 + 1j * cos_term * sin_term + ) + pauli.multiply_by_constant(-1j * cos_term * sin_term + sin_term**2) return Pk @@ -394,11 +418,11 @@ def Get_AC_root(power: float, operator: AntiCommutingOp) -> PauliwordOp: AC_root (PauliwordOp): operator representing power of AC input """ - Ps, rot, gamma_l, AC_normed = operator.unitary_partitioning(up_method='LCU') + Ps, rot, gamma_l, AC_normed = operator.unitary_partitioning(up_method="LCU") Ps_root = get_PauliwordOp_root(power, Ps) - AC_root = (rot.dagger * Ps_root * rot).multiply_by_constant(gamma_l ** power) + AC_root = (rot.dagger * Ps_root * rot).multiply_by_constant(gamma_l**power) return AC_root @@ -424,15 +448,14 @@ def get_generators_including_xz_products(operator: PauliwordOp) -> PauliwordOp: row_red_XYZ = _rref_binary(XZY_block) non_zero_rows = row_red_XYZ[np.sum(row_red_XYZ, axis=1).astype(bool)] - X_new = non_zero_rows[:, :operator.X_block.shape[1]] - Z_new = non_zero_rows[:, operator.X_block.shape[1]:2 * operator.Z_block.shape[1]] - Y_new = non_zero_rows[:, 2 * operator.Z_block.shape[1]:] + X_new = non_zero_rows[:, : operator.X_block.shape[1]] + Z_new = non_zero_rows[:, operator.X_block.shape[1] : 2 * operator.Z_block.shape[1]] + Y_new = non_zero_rows[:, 2 * operator.Z_block.shape[1] :] - sym_final = np.hstack((np.logical_or(X_new, Y_new), - np.logical_or(Z_new, Y_new))) + sym_final = np.hstack((np.logical_or(X_new, Y_new), np.logical_or(Z_new, Y_new))) # remove duplicates due to same X_new and Z_new positions xyz_gens = PauliwordOp(sym_final, np.ones(sym_final.shape[0])).cleanup() xyz_gens.coeff_vec = np.ones_like(xyz_gens.coeff_vec) - return xyz_gens \ No newline at end of file + return xyz_gens diff --git a/tests/test_approximate/test_approximate_tensor_network.py b/tests/test_approximate/test_approximate_tensor_network.py index 9b63d70..3fd1061 100644 --- a/tests/test_approximate/test_approximate_tensor_network.py +++ b/tests/test_approximate/test_approximate_tensor_network.py @@ -4,31 +4,36 @@ from symmer.operators import PauliwordOp, QuantumState from symmer.utils import exact_gs_energy + @pytest.fixture def symp_matrix_1(): - return np.array([ - [0,0,0,0,0,0], - [1,1,1,0,0,0], - [1,1,1,1,1,1], - [0,0,0,1,1,1] - ]) + return np.array( + [[0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 1], [0, 0, 0, 1, 1, 1]] + ) + + @pytest.fixture def symp_matrix_2(): - return np.array([ - [0,1,0,1,0,1], - [1,0,1,0,1,0], - [1,1,0,0,1,1], - [0,0,1,1,0,0] - ]) + return np.array( + [[0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0], [1, 1, 0, 0, 1, 1], [0, 0, 1, 1, 0, 0]] + ) + + @pytest.fixture def pauli_list_1(): - return ['III', 'XXX', 'YYY', 'ZZZ'] + return ["III", "XXX", "YYY", "ZZZ"] + + @pytest.fixture def pauli_list_2(): - return ['ZXZ', 'XZX', 'XYZ', 'ZIX'] + return ["ZXZ", "XZX", "XYZ", "ZIX"] + + @pytest.fixture def coeff_vec_1(): return np.random.random(4) + + @pytest.fixture def coeff_vec_2(): return np.random.random(4) @@ -38,21 +43,21 @@ def coeff_vec_2(): # Testing different initialization methods # ############################################ + def test_from_list( - pauli_list_1, - coeff_vec_1, - ): + pauli_list_1, + coeff_vec_1, +): MPO = MPOOp(pauli_list_1, coeff_vec_1) matrix_MPO = MPO.to_matrix WordOp = PauliwordOp.from_list(pauli_list_1, coeff_vec_1) matrix_WordOp = WordOp.to_sparse_matrix.toarray() - assert(np.allclose(matrix_MPO, matrix_WordOp)) + assert np.allclose(matrix_MPO, matrix_WordOp) -def test_from_dictionary( - pauli_list_1, - coeff_vec_1): + +def test_from_dictionary(pauli_list_1, coeff_vec_1): pauli_dict = dict(zip(pauli_list_1, coeff_vec_1)) MPO = MPOOp.from_dictionary(pauli_dict) matrix_MPO = MPO.to_matrix @@ -60,18 +65,17 @@ def test_from_dictionary( WordOp = PauliwordOp.from_list(pauli_list_1, coeff_vec_1) matrix_WordOp = WordOp.to_sparse_matrix.toarray() - assert(np.allclose(matrix_MPO, matrix_WordOp)) + assert np.allclose(matrix_MPO, matrix_WordOp) + ############################################ # Testing QUIMB dmrg sovler # ############################################ -def test_find_groundsate_quimb( - pauli_list_1, - coeff_vec_1 - ): + +def test_find_groundsate_quimb(pauli_list_1, coeff_vec_1): MPO = MPOOp(pauli_list_1, coeff_vec_1) mpostate = find_groundstate_quimb(MPO) - assert(type(mpostate) == QuantumState) + assert type(mpostate) == QuantumState diff --git a/tests/test_evolution/test_evolution_gate_library.py b/tests/test_evolution/test_evolution_gate_library.py index 2e8f20f..29a5da1 100644 --- a/tests/test_evolution/test_evolution_gate_library.py +++ b/tests/test_evolution/test_evolution_gate_library.py @@ -3,46 +3,72 @@ from symmer.evolution.gate_library import * from symmer.operators import QuantumState as qs + @pytest.mark.parametrize( - "gate, state_in, state_out", + "gate, state_in, state_out", [ - (I(1), qs([[0]]), qs([[0]])), - (I(1), qs([[1]]), qs([[1]])), - (X(1,0), qs([[0]]), qs([[1]])), - (X(1,0), qs([[1]]), qs([[0]])), - (Y(1,0), qs([[0]]), qs([[1]])*1j), - (Y(1,0), qs([[1]]), qs([[0]])*-1j), - (Z(1,0), qs([[0]]), qs([[0]])), - (Z(1,0), qs([[1]]), qs([[1]])*-1), - (S(1,0), qs([[0]]), qs([[0]])), - (S(1,0), qs([[1]]), qs([[1]])*1j), - (Had(1,0), qs([[0]]), qs([[0],[1]], [1/np.sqrt(2),1/np.sqrt(2)])), - (Had(1,0), qs([[1]]), qs([[0],[1]], [1/np.sqrt(2),-1/np.sqrt(2)])), - (RX(1,0,np.pi/3), qs([[0]]), qs([[0],[1]], [np.cos(np.pi/6), 1j*np.sin(np.pi/6)])), - (RX(1,0,np.pi/3), qs([[1]]), qs([[1],[0]], [np.cos(np.pi/6), 1j*np.sin(np.pi/6)])), - (RY(1,0,np.pi/3), qs([[0]]), qs([[0],[1]], [np.cos(np.pi/6), -np.sin(np.pi/6)])), - (RY(1,0,np.pi/3), qs([[1]]), qs([[1],[0]], [np.cos(np.pi/6), +np.sin(np.pi/6)])), - (RZ(1,0,np.pi/3), qs([[0]]), qs([[0]], [np.exp(+1j*np.pi/6)])), - (RZ(1,0,np.pi/3), qs([[1]]), qs([[1]], [np.exp(-1j*np.pi/6)])), - (U1(1,0,np.pi/3), qs([[0]]), qs([[0]], [np.exp(+1j*np.pi/6)])*np.exp(1j*np.pi/6)), - (U1(1,0,np.pi/3), qs([[1]]), qs([[1]], [np.exp(-1j*np.pi/6)])*np.exp(1j*np.pi/6)), - ] + (I(1), qs([[0]]), qs([[0]])), + (I(1), qs([[1]]), qs([[1]])), + (X(1, 0), qs([[0]]), qs([[1]])), + (X(1, 0), qs([[1]]), qs([[0]])), + (Y(1, 0), qs([[0]]), qs([[1]]) * 1j), + (Y(1, 0), qs([[1]]), qs([[0]]) * -1j), + (Z(1, 0), qs([[0]]), qs([[0]])), + (Z(1, 0), qs([[1]]), qs([[1]]) * -1), + (S(1, 0), qs([[0]]), qs([[0]])), + (S(1, 0), qs([[1]]), qs([[1]]) * 1j), + (Had(1, 0), qs([[0]]), qs([[0], [1]], [1 / np.sqrt(2), 1 / np.sqrt(2)])), + (Had(1, 0), qs([[1]]), qs([[0], [1]], [1 / np.sqrt(2), -1 / np.sqrt(2)])), + ( + RX(1, 0, np.pi / 3), + qs([[0]]), + qs([[0], [1]], [np.cos(np.pi / 6), 1j * np.sin(np.pi / 6)]), + ), + ( + RX(1, 0, np.pi / 3), + qs([[1]]), + qs([[1], [0]], [np.cos(np.pi / 6), 1j * np.sin(np.pi / 6)]), + ), + ( + RY(1, 0, np.pi / 3), + qs([[0]]), + qs([[0], [1]], [np.cos(np.pi / 6), -np.sin(np.pi / 6)]), + ), + ( + RY(1, 0, np.pi / 3), + qs([[1]]), + qs([[1], [0]], [np.cos(np.pi / 6), +np.sin(np.pi / 6)]), + ), + (RZ(1, 0, np.pi / 3), qs([[0]]), qs([[0]], [np.exp(+1j * np.pi / 6)])), + (RZ(1, 0, np.pi / 3), qs([[1]]), qs([[1]], [np.exp(-1j * np.pi / 6)])), + ( + U1(1, 0, np.pi / 3), + qs([[0]]), + qs([[0]], [np.exp(+1j * np.pi / 6)]) * np.exp(1j * np.pi / 6), + ), + ( + U1(1, 0, np.pi / 3), + qs([[1]]), + qs([[1]], [np.exp(-1j * np.pi / 6)]) * np.exp(1j * np.pi / 6), + ), + ], ) def test_single_qubit_gates(gate, state_in, state_out): assert gate * state_in == state_out + @pytest.mark.parametrize( - "gate, state_in, state_out", + "gate, state_in, state_out", [ - (CZ, qs([[0,0]]), qs([[0,0]])), - (CZ, qs([[0,1]]), qs([[0,1]])), - (CZ, qs([[1,0]]), qs([[1,0]])), - (CZ, qs([[1,1]]), qs([[1,1]])*-1), - (CX, qs([[0,0]]), qs([[0,0]])), - (CX, qs([[0,1]]), qs([[0,1]])), - (CX, qs([[1,0]]), qs([[1,1]])), - (CX, qs([[1,1]]), qs([[1,0]])), - ] + (CZ, qs([[0, 0]]), qs([[0, 0]])), + (CZ, qs([[0, 1]]), qs([[0, 1]])), + (CZ, qs([[1, 0]]), qs([[1, 0]])), + (CZ, qs([[1, 1]]), qs([[1, 1]]) * -1), + (CX, qs([[0, 0]]), qs([[0, 0]])), + (CX, qs([[0, 1]]), qs([[0, 1]])), + (CX, qs([[1, 0]]), qs([[1, 1]])), + (CX, qs([[1, 1]]), qs([[1, 0]])), + ], ) def test_two_qubit_gates(gate, state_in, state_out): - assert gate(2,0,1) * state_in == state_out \ No newline at end of file + assert gate(2, 0, 1) * state_in == state_out diff --git a/tests/test_operators/test_anticommuting_op.py b/tests/test_operators/test_anticommuting_op.py index 09ecee7..efaeaab 100644 --- a/tests/test_operators/test_anticommuting_op.py +++ b/tests/test_operators/test_anticommuting_op.py @@ -4,28 +4,28 @@ anti_commuting_real = { - 'ZIII': (0.8747970716927321+0j), - 'XZII': (-1.0644565743109524+0j), - 'YIII': (-0.8228629386183656+0j), - 'XXZI': (0.055300207495717776+0j), - 'XYII': (0.7954579805096648+0j), - 'XXXZ': (-0.18153261708813911+0j), - 'XXYI': (-0.3922409211719307+0j), - 'XXXX': (-0.21221866688241092+0j), - 'XXXY': (-1.307383058078484+0j) - } + "ZIII": (0.8747970716927321 + 0j), + "XZII": (-1.0644565743109524 + 0j), + "YIII": (-0.8228629386183656 + 0j), + "XXZI": (0.055300207495717776 + 0j), + "XYII": (0.7954579805096648 + 0j), + "XXXZ": (-0.18153261708813911 + 0j), + "XXYI": (-0.3922409211719307 + 0j), + "XXXX": (-0.21221866688241092 + 0j), + "XXXY": (-1.307383058078484 + 0j), +} anti_commuting_complex = { - 'ZIII': (-1.463090893167244-1.0373683388860946j), - 'XZII': (-0.6236959970817084+2.3463922466151983j), - 'YIII': (-1.129271964294082+0.006613401026225518j), - 'XXZI': (0.5943195511144899-0.5130626941203098j), - 'XYII': (1.0739015702295176-0.7346971935019978j), - 'XXXZ': (-0.37567421392003353-0.40031215375799156j), - 'XXYI': (-0.6724574864687586+0.4742746791096707j), - 'XXXX': (0.07393496974124038+0.755825537793846j), - 'XXXY': (0.7526481862263222-1.112929874028072j) - } + "ZIII": (-1.463090893167244 - 1.0373683388860946j), + "XZII": (-0.6236959970817084 + 2.3463922466151983j), + "YIII": (-1.129271964294082 + 0.006613401026225518j), + "XXZI": (0.5943195511144899 - 0.5130626941203098j), + "XYII": (1.0739015702295176 - 0.7346971935019978j), + "XXXZ": (-0.37567421392003353 - 0.40031215375799156j), + "XXYI": (-0.6724574864687586 + 0.4742746791096707j), + "XXXX": (0.07393496974124038 + 0.755825537793846j), + "XXXY": (0.7526481862263222 - 1.112929874028072j), +} def test_init_not_anticommuting(): @@ -33,143 +33,166 @@ def test_init_not_anticommuting(): check assert error thrown if input is not anticommuting """ with pytest.raises(AssertionError): - AntiCommutingOp.from_dictionary({'ZZZ':1, - 'ZIZ':1, - 'ZZI':-1, - 'III':1}) + AntiCommutingOp.from_dictionary({"ZZZ": 1, "ZIZ": 1, "ZZI": -1, "III": 1}) def test_init_commuting(): """ check assert error thrown if input is not anticommuting """ - AcOp = AntiCommutingOp.from_dictionary({'ZZZ': 1, - 'XXX': 1, - 'YYY': -1}) - P = PauliwordOp.from_list(['ZZZ', 'XXX', 'YYY'], - [1, 1, -1]) - assert np.allclose(AcOp.to_sparse_matrix.toarray(), - P.to_sparse_matrix.toarray()) + AcOp = AntiCommutingOp.from_dictionary({"ZZZ": 1, "XXX": 1, "YYY": -1}) + P = PauliwordOp.from_list(["ZZZ", "XXX", "YYY"], [1, 1, -1]) + assert np.allclose(AcOp.to_sparse_matrix.toarray(), P.to_sparse_matrix.toarray()) def test_single_op(): - P = AntiCommutingOp.from_dictionary({'XX':2}) - assert P.n_terms==1 + P = AntiCommutingOp.from_dictionary({"XX": 2}) + assert P.n_terms == 1 def test_unitary_partitioning_no_s_index_seq_rot(): AcOp_real = AntiCommutingOp.from_dictionary(anti_commuting_real) - Ps, rotations, gamma_l, AC_op = AcOp_real.unitary_partitioning(s_index=None, up_method='seq_rot') + Ps, rotations, gamma_l, AC_op = AcOp_real.unitary_partitioning( + s_index=None, up_method="seq_rot" + ) - assert Ps.n_terms==1, 'can only rotate onto single Pauli operator' - assert gamma_l == np.linalg.norm(list(anti_commuting_real.values())), 'normalization wrong' - assert len(rotations) == AcOp_real.n_terms-1, 'seq of rotation number incorrect' + assert Ps.n_terms == 1, "can only rotate onto single Pauli operator" + assert gamma_l == np.linalg.norm( + list(anti_commuting_real.values()) + ), "normalization wrong" + assert len(rotations) == AcOp_real.n_terms - 1, "seq of rotation number incorrect" P_red = AcOp_real.perform_rotations(rotations) assert Ps.multiply_by_constant(gamma_l) == P_red - R_seq_rot_Op = PauliwordOp.from_dictionary({'I'*AcOp_real.n_qubits : 1}) + R_seq_rot_Op = PauliwordOp.from_dictionary({"I" * AcOp_real.n_qubits: 1}) for X_sk, theta_sk in rotations[::-1]: - assert isinstance(X_sk, PauliwordOp), 'rotation operator not a PauliwordOp' + assert isinstance(X_sk, PauliwordOp), "rotation operator not a PauliwordOp" assert isinstance(theta_sk.real, float) - assert theta_sk.imag == 0, 'rotation cannot have complex component' - assert X_sk.n_terms == 1, f'rotation generated by single pauli operator only! Not {X_sk.n_terms}' + assert theta_sk.imag == 0, "rotation cannot have complex component" + assert ( + X_sk.n_terms == 1 + ), f"rotation generated by single pauli operator only! Not {X_sk.n_terms}" # Let R(t) = e^{i t/2 Q} = cos(t/2)*I + i*sin(t/2)*Q - R = (PauliwordOp.from_dictionary({'I'*AcOp_real.n_qubits : np.cos(theta_sk/2)}) \ - + X_sk.multiply_by_constant(1j*np.sin(theta_sk/2)) - ) + R = PauliwordOp.from_dictionary( + {"I" * AcOp_real.n_qubits: np.cos(theta_sk / 2)} + ) + X_sk.multiply_by_constant(1j * np.sin(theta_sk / 2)) R_seq_rot_Op *= R R_AC_op_Rdag = R_seq_rot_Op * AcOp_real * R_seq_rot_Op.dagger assert R_AC_op_Rdag == Ps.multiply_by_constant(gamma_l) - assert R_seq_rot_Op * R_seq_rot_Op.dagger == PauliwordOp.from_dictionary({'I' * AcOp_real.n_qubits: 1}), 'R not unitary' + assert R_seq_rot_Op * R_seq_rot_Op.dagger == PauliwordOp.from_dictionary( + {"I" * AcOp_real.n_qubits: 1} + ), "R not unitary" def test_unitary_partitioning_no_s_index_LCU(): AcOp_real = AntiCommutingOp.from_dictionary(anti_commuting_real) - Ps, rotations, gamma_l, AC_op = AcOp_real.unitary_partitioning(s_index=None, up_method='LCU') + Ps, rotations, gamma_l, AC_op = AcOp_real.unitary_partitioning( + s_index=None, up_method="LCU" + ) - assert Ps.n_terms==1, 'can only rotate onto single Pauli operator' - assert gamma_l == np.linalg.norm(list(anti_commuting_real.values())), 'normalization wrong' + assert Ps.n_terms == 1, "can only rotate onto single Pauli operator" + assert gamma_l == np.linalg.norm( + list(anti_commuting_real.values()) + ), "normalization wrong" assert isinstance(rotations, PauliwordOp) - assert rotations.n_terms == AcOp_real.n_terms, 'LCU op contains too many pauli operators' + assert ( + rotations.n_terms == AcOp_real.n_terms + ), "LCU op contains too many pauli operators" R_AC_op_Rdag = rotations * AcOp_real * rotations.dagger assert R_AC_op_Rdag == Ps.multiply_by_constant(gamma_l) - assert rotations*rotations.dagger == PauliwordOp.from_dictionary({'I'*AcOp_real.n_qubits : 1}), 'R not unitary' + assert rotations * rotations.dagger == PauliwordOp.from_dictionary( + {"I" * AcOp_real.n_qubits: 1} + ), "R not unitary" def test_unitary_partitioning_s_index_seq_rot(): AcOp_real = AntiCommutingOp.from_dictionary(anti_commuting_real) for s_ind in range(AcOp_real.n_terms): - Ps, rotations, gamma_l, AC_op = AcOp_real.unitary_partitioning(s_index=s_ind, - up_method='seq_rot') - - assert Ps.n_terms==1, 'can only rotate onto single Pauli operator' - assert gamma_l == np.linalg.norm(list(anti_commuting_real.values())), 'normalization wrong' - assert len(rotations) == AcOp_real.n_terms-1, 'seq of rotation number incorrect' + Ps, rotations, gamma_l, AC_op = AcOp_real.unitary_partitioning( + s_index=s_ind, up_method="seq_rot" + ) + + assert Ps.n_terms == 1, "can only rotate onto single Pauli operator" + assert gamma_l == np.linalg.norm( + list(anti_commuting_real.values()) + ), "normalization wrong" + assert ( + len(rotations) == AcOp_real.n_terms - 1 + ), "seq of rotation number incorrect" P_red = AcOp_real.perform_rotations(rotations) assert Ps.multiply_by_constant(gamma_l) == P_red - R_seq_rot_Op = PauliwordOp.from_dictionary({'I'*AcOp_real.n_qubits : 1}) + R_seq_rot_Op = PauliwordOp.from_dictionary({"I" * AcOp_real.n_qubits: 1}) for X_sk, theta_sk in rotations[::-1]: - assert isinstance(X_sk, PauliwordOp), 'rotation operator not a PauliwordOp' + assert isinstance(X_sk, PauliwordOp), "rotation operator not a PauliwordOp" assert isinstance(theta_sk.real, float) - assert theta_sk.imag == 0, 'rotation cannot have complex component' - assert X_sk.n_terms == 1, f'rotation generated by single pauli operator only! Not {X_sk.n_terms}' + assert theta_sk.imag == 0, "rotation cannot have complex component" + assert ( + X_sk.n_terms == 1 + ), f"rotation generated by single pauli operator only! Not {X_sk.n_terms}" # Let R(t) = e^{i t/2 Q} = cos(t/2)*I + i*sin(t/2)*Q - R = (PauliwordOp.from_dictionary({'I'*AcOp_real.n_qubits : np.cos(theta_sk/2)}) \ - + X_sk.multiply_by_constant(1j*np.sin(theta_sk/2)) - ) + R = PauliwordOp.from_dictionary( + {"I" * AcOp_real.n_qubits: np.cos(theta_sk / 2)} + ) + X_sk.multiply_by_constant(1j * np.sin(theta_sk / 2)) R_seq_rot_Op *= R R_AC_op_Rdag = R_seq_rot_Op * AcOp_real * R_seq_rot_Op.dagger assert R_AC_op_Rdag == Ps.multiply_by_constant(gamma_l) - assert R_seq_rot_Op * R_seq_rot_Op.dagger == PauliwordOp.from_dictionary({'I' * AcOp_real.n_qubits: 1}), 'R not unitary' + assert R_seq_rot_Op * R_seq_rot_Op.dagger == PauliwordOp.from_dictionary( + {"I" * AcOp_real.n_qubits: 1} + ), "R not unitary" def test_unitary_partitioning_s_index_LCU(): AcOp_real = AntiCommutingOp.from_dictionary(anti_commuting_real) for s_ind in range(AcOp_real.n_terms): - Ps, rotations, gamma_l, AC_op = AcOp_real.unitary_partitioning(s_index=s_ind, - up_method='LCU') + Ps, rotations, gamma_l, AC_op = AcOp_real.unitary_partitioning( + s_index=s_ind, up_method="LCU" + ) - assert Ps.n_terms==1, 'can only rotate onto single Pauli operator' - assert gamma_l == np.linalg.norm(list(anti_commuting_real.values())), 'normalization wrong' + assert Ps.n_terms == 1, "can only rotate onto single Pauli operator" + assert gamma_l == np.linalg.norm( + list(anti_commuting_real.values()) + ), "normalization wrong" assert isinstance(rotations, PauliwordOp) - assert rotations.n_terms == AcOp_real.n_terms, 'LCU op contains too many pauli operators' + assert ( + rotations.n_terms == AcOp_real.n_terms + ), "LCU op contains too many pauli operators" R_AC_op_Rdag = rotations * AcOp_real * rotations.dagger assert R_AC_op_Rdag == Ps.multiply_by_constant(gamma_l) - assert rotations*rotations.dagger == PauliwordOp.from_dictionary({'I'*AcOp_real.n_qubits : 1}), 'R not unitary' + assert rotations * rotations.dagger == PauliwordOp.from_dictionary( + {"I" * AcOp_real.n_qubits: 1} + ), "R not unitary" def test_unitary_partitioning_seq_rot_complex(): AcOp_comp = AntiCommutingOp.from_dictionary(anti_commuting_complex) with pytest.raises(AssertionError): - AcOp_comp.unitary_partitioning(s_index=None, - up_method='seq_rot') + AcOp_comp.unitary_partitioning(s_index=None, up_method="seq_rot") def test_unitary_partitioning_LCU_complex(): AcOp_comp = AntiCommutingOp.from_dictionary(anti_commuting_complex) with pytest.raises(AssertionError): - AcOp_comp.unitary_partitioning(s_index=None, - up_method='LCU') + AcOp_comp.unitary_partitioning(s_index=None, up_method="LCU") def test_generate_LCU_operator(): AcOp_real = AntiCommutingOp.from_dictionary(anti_commuting_real) normalization = np.linalg.norm(list(anti_commuting_real.values())) - AcOp_normed = AcOp_real.multiply_by_constant(1/normalization) + AcOp_normed = AcOp_real.multiply_by_constant(1 / normalization) Ps_LCU = AcOp_real.generate_LCU_operator(AcOp_normed) R_LCU = AcOp_real.R_LCU @@ -183,7 +206,7 @@ def test_recursive_seq_rotations(): AcOp_real = AntiCommutingOp.from_dictionary(anti_commuting_real) normalization = np.linalg.norm(list(anti_commuting_real.values())) - AcOp_normed = AcOp_real.multiply_by_constant(1/normalization) + AcOp_normed = AcOp_real.multiply_by_constant(1 / normalization) Ps_LCU = AcOp_real._recursive_seq_rotations(AcOp_normed) R_seq_rot = AcOp_real.X_sk_rotations @@ -194,37 +217,42 @@ def test_recursive_seq_rotations(): def test_ac_set_with_zero_ceoffs(): - AcOp_real = AntiCommutingOp.from_list(['YY', 'XI', 'ZI', 'YX'], [0, 0, 1, 0.2]) + AcOp_real = AntiCommutingOp.from_list(["YY", "XI", "ZI", "YX"], [0, 0, 1, 0.2]) - Ps_seq_rot, rotations_seq_rot, gamma_l, AC_normed = AcOp_real.unitary_partitioning(s_index=1, - up_method='seq_rot') + Ps_seq_rot, rotations_seq_rot, gamma_l, AC_normed = AcOp_real.unitary_partitioning( + s_index=1, up_method="seq_rot" + ) seq_rot_output = AC_normed.perform_rotations(rotations_seq_rot) - assert seq_rot_output.n_terms==1 + assert seq_rot_output.n_terms == 1 assert np.isclose(seq_rot_output.coeff_vec[0], 1) assert Ps_seq_rot == seq_rot_output - Ps_LCU, rotations_LCU, gamma_l, AC_normed = AcOp_real.unitary_partitioning(s_index=1, - up_method='LCU') + Ps_LCU, rotations_LCU, gamma_l, AC_normed = AcOp_real.unitary_partitioning( + s_index=1, up_method="LCU" + ) LCU_output = (rotations_LCU * AC_normed * rotations_LCU.dagger).cleanup() - assert LCU_output.n_terms==1 + assert LCU_output.n_terms == 1 assert np.isclose(LCU_output.coeff_vec[0], 1) assert Ps_LCU == LCU_output + def test_ac_set_with_negative_and_zero_ceoffs(): - AcOp_real = AntiCommutingOp.from_list(['YY', 'XI', 'ZI'], [-1, 0, 0]) + AcOp_real = AntiCommutingOp.from_list(["YY", "XI", "ZI"], [-1, 0, 0]) - Ps_seq_rot, rotations_seq_rot, gamma_l, AC_normed = AcOp_real.unitary_partitioning(s_index=0, - up_method='seq_rot') + Ps_seq_rot, rotations_seq_rot, gamma_l, AC_normed = AcOp_real.unitary_partitioning( + s_index=0, up_method="seq_rot" + ) seq_rot_output = AC_normed.perform_rotations(rotations_seq_rot) - assert seq_rot_output.n_terms==1 + assert seq_rot_output.n_terms == 1 assert np.isclose(seq_rot_output.coeff_vec[0], 1) assert Ps_seq_rot == seq_rot_output - Ps_LCU, rotations_LCU, gamma_l, AC_normed = AcOp_real.unitary_partitioning(s_index=0, - up_method='LCU') + Ps_LCU, rotations_LCU, gamma_l, AC_normed = AcOp_real.unitary_partitioning( + s_index=0, up_method="LCU" + ) LCU_output = (rotations_LCU * AC_normed * rotations_LCU.dagger).cleanup() - assert LCU_output.n_terms==1 + assert LCU_output.n_terms == 1 assert np.isclose(LCU_output.coeff_vec[0], 1) - assert Ps_LCU == LCU_output \ No newline at end of file + assert Ps_LCU == LCU_output diff --git a/tests/test_operators/test_base.py b/tests/test_operators/test_base.py index 6fb8da9..074f35e 100644 --- a/tests/test_operators/test_base.py +++ b/tests/test_operators/test_base.py @@ -7,68 +7,62 @@ from symmer.utils import matrix_allclose from symmer.operators.utils import check_adjmat_noncontextual -P_matrices ={ - 'X': np.array([[0, 1], - [1, 0]], dtype=complex), - 'Y': np.array([[0, -1j], - [+1j, 0]], dtype=complex), - 'Z': np.array([[1, 0], - [0, -1]], dtype=complex), - 'I': np.array([[1, 0], - [0, 1]], dtype=complex), - +P_matrices = { + "X": np.array([[0, 1], [1, 0]], dtype=complex), + "Y": np.array([[0, -1j], [+1j, 0]], dtype=complex), + "Z": np.array([[1, 0], [0, -1]], dtype=complex), + "I": np.array([[1, 0], [0, 1]], dtype=complex), } #################################################################### # Assertion errors arising from poorly defined symplectic matrices # #################################################################### + def test_init_symplectic_float_type(): """ if input symplectic matrix is not a boolean or (0,1) ints need error to be raised This checks for floats """ coeff = [1] - symp_matrix = [ - [0.,1.,0.,1.,0.,1.] - ] + symp_matrix = [[0.0, 1.0, 0.0, 1.0, 0.0, 1.0]] with pytest.raises(AssertionError): PauliwordOp(symp_matrix, coeff) + def test_init_symplectic_nonbinary_ints_type(): """ if input symplectic matrix is ints but not 0,1 check code raises error """ coeff = [1] - symp_matrix = [ - [0,1,2,3,4,5] - ] + symp_matrix = [[0, 1, 2, 3, 4, 5]] with pytest.raises(AssertionError): PauliwordOp(symp_matrix, coeff) + def test_init_symplectic_str_type(): """ if input symplectic matrix is string check error raised """ coeff = [1] - symp_matrix = [ - ['0','1','1','0','1','1'] - ] + symp_matrix = [["0", "1", "1", "0", "1", "1"]] with pytest.raises(AssertionError): PauliwordOp(symp_matrix, coeff) + def test_incompatible_length_of_symp_matrix_and_coeff_vec(): """ For a symplectic matrix of 2 rows check that if only 1 coeff defined an error will be thrown. """ symp_matrix = [ - [0,1,0,1,0,1], - [1,0,1,0,1,0], + [0, 1, 0, 1, 0, 1], + [1, 0, 1, 0, 1, 0], ] coeff = [1] with pytest.raises(AssertionError): PauliwordOp(symp_matrix, coeff) + def test_init_symplectic_incorrect_dimension(): """ if input symplectic matrix is not correct dimension throw an error @@ -76,26 +70,23 @@ def test_init_symplectic_incorrect_dimension(): coeff = [1] # error here symplectic matrix wrong dimensions - symp_matrix = [ - [[[0,1,1,0,1,1]]] - ] + symp_matrix = [[[[0, 1, 1, 0, 1, 1]]]] with pytest.raises(AssertionError): PauliwordOp(symp_matrix, coeff) + def test_init_symplectic_2D_but_odd_columns(): """ if input symplectic matrix is 2D, but has odd number of columns throw an error (columns must alway be even) """ - coeff = [1,1] + coeff = [1, 1] # error here... number of columns must be even (not odd... in this case 3) - symp_matrix = [ - [0,0,1], - [1, 0, 1] - ] + symp_matrix = [[0, 0, 1], [1, 0, 1]] with pytest.raises(AssertionError): PauliwordOp(symp_matrix, coeff) + def test_init_symplectic_int_coeff(): """ if input symplectic matrix is 2D, but has odd number of columns throw an error (columns must alway be even) @@ -103,49 +94,56 @@ def test_init_symplectic_int_coeff(): # error here, should be list or array coeff = 1 - symp_matrix = [ - [0,0,1,1] - ] + symp_matrix = [[0, 0, 1, 1]] with pytest.raises(TypeError): PauliwordOp(symp_matrix, coeff) + ############################################ # Testing empty PauliwordOp # ############################################ + def test_empty(): n_qubits = 3 P_empty = PauliwordOp.empty(n_qubits) - assert P_empty == PauliwordOp([[0]*6], [0]) - assert P_empty.n_terms==1 + assert P_empty == PauliwordOp([[0] * 6], [0]) + assert P_empty.n_terms == 1 assert np.array_equal(P_empty.coeff_vec, np.array([0])) assert P_empty.n_qubits == n_qubits + def test_empty_cleanup(): n_qubits = 3 P_empty = PauliwordOp.empty(n_qubits) P_empty = P_empty.cleanup() assert P_empty.n_qubits == n_qubits - assert P_empty.symp_matrix.shape == (0, 2*n_qubits) + assert P_empty.symp_matrix.shape == (0, 2 * n_qubits) + ############################################ # Testing random PauliwordOp # ############################################ + def test_PauliwordOp_random_diag(): diagonal = True complex_coeffs = True - n_qubits=3 - n_terms=4 - P_random = PauliwordOp.random(n_qubits=n_qubits, - n_terms=n_terms, - diagonal=diagonal, - complex_coeffs=complex_coeffs) - assert np.array_equal(P_random.X_block, - np.zeros_like(P_random.X_block).astype(bool)) + n_qubits = 3 + n_terms = 4 + P_random = PauliwordOp.random( + n_qubits=n_qubits, + n_terms=n_terms, + diagonal=diagonal, + complex_coeffs=complex_coeffs, + ) + assert np.array_equal( + P_random.X_block, np.zeros_like(P_random.X_block).astype(bool) + ) + def test_PauliwordOp_random_complex(): @@ -156,22 +154,28 @@ def test_PauliwordOp_random_complex(): ## complex_coeffs = True - P_random_complex = PauliwordOp.random(n_qubits=n_qubits, - n_terms=n_terms, - diagonal=diagonal, - complex_coeffs=complex_coeffs) + P_random_complex = PauliwordOp.random( + n_qubits=n_qubits, + n_terms=n_terms, + diagonal=diagonal, + complex_coeffs=complex_coeffs, + ) assert P_random_complex.coeff_vec.dtype == np.complex128 - assert np.sum(np.abs(P_random_complex.coeff_vec.imag))>0 + assert np.sum(np.abs(P_random_complex.coeff_vec.imag)) > 0 complex_coeffs = False - P_random_real = PauliwordOp.random(n_qubits=n_qubits, - n_terms=n_terms, - diagonal=diagonal, - complex_coeffs=complex_coeffs) + P_random_real = PauliwordOp.random( + n_qubits=n_qubits, + n_terms=n_terms, + diagonal=diagonal, + complex_coeffs=complex_coeffs, + ) + + assert np.array_equal( + P_random_real.coeff_vec.imag, np.zeros((P_random_real.n_terms)) + ) - assert np.array_equal(P_random_real.coeff_vec.imag, - np.zeros((P_random_real.n_terms))) def test_PauliwordOp_haar(): @@ -183,195 +187,182 @@ def test_PauliwordOp_haar(): # check unitary mat = P_haar_random.to_sparse_matrix.toarray() - assert np.allclose(np.eye(mat.shape[0]), mat.dot(mat.T.conj())), 'haar random operator not unitary' + assert np.allclose( + np.eye(mat.shape[0]), mat.dot(mat.T.conj()) + ), "haar random operator not unitary" + ############################################ # Testing different initialization methods # ############################################ + @pytest.fixture def symp_matrix_1(): - return np.array([ - [0,0,0,0,0,0], - [1,1,1,0,0,0], - [1,1,1,1,1,1], - [0,0,0,1,1,1] - ]) + return np.array( + [[0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 1], [0, 0, 0, 1, 1, 1]] + ) + @pytest.fixture def symp_matrix_2(): - return np.array([ - [0,1,0,1,0,1], - [1,0,1,0,1,0], - [1,1,0,0,1,1], - [0,0,1,1,0,0] - ]) - -@pytest.fixture + return np.array( + [[0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0], [1, 1, 0, 0, 1, 1], [0, 0, 1, 1, 0, 0]] + ) + + +@pytest.fixture def pauli_list_1(): - return ['III', 'XXX', 'YYY', 'ZZZ'] + return ["III", "XXX", "YYY", "ZZZ"] + -@pytest.fixture +@pytest.fixture def pauli_list_2(): - return ['ZXZ', 'XZX', 'XYZ', 'ZIX'] + return ["ZXZ", "XZX", "XYZ", "ZIX"] + @pytest.fixture def coeff_vec_1(): # real coeffs return np.random.random(4) + @pytest.fixture def coeff_vec_2(): # complex coeffs - return np.random.random(4) + 1j*np.random.random(4) - -def test_from_list( - pauli_list_1, - symp_matrix_1, - coeff_vec_1 - ): - assert ( - PauliwordOp.from_list(pauli_list_1, coeff_vec_1) == - PauliwordOp(symp_matrix_1, coeff_vec_1) + return np.random.random(4) + 1j * np.random.random(4) + + +def test_from_list(pauli_list_1, symp_matrix_1, coeff_vec_1): + assert PauliwordOp.from_list(pauli_list_1, coeff_vec_1) == PauliwordOp( + symp_matrix_1, coeff_vec_1 ) + def test_from_list_incorrect_str(): """ raise error if lower case pauli operators used """ with pytest.raises(AssertionError): - PauliwordOp.from_list(['ixi', 'zzi'], [0,1]) + PauliwordOp.from_list(["ixi", "zzi"], [0, 1]) -def test_from_dictionary( - pauli_list_1, - symp_matrix_1, - coeff_vec_1 - ): + +def test_from_dictionary(pauli_list_1, symp_matrix_1, coeff_vec_1): pauli_dict = dict(zip(pauli_list_1, coeff_vec_1)) - assert ( - PauliwordOp.from_dictionary(pauli_dict) == - PauliwordOp(symp_matrix_1, coeff_vec_1) + assert PauliwordOp.from_dictionary(pauli_dict) == PauliwordOp( + symp_matrix_1, coeff_vec_1 ) -def test_to_dictionary( - pauli_list_1, - symp_matrix_1, - coeff_vec_1 - ): + +def test_to_dictionary(pauli_list_1, symp_matrix_1, coeff_vec_1): pauli_dict = dict(zip(pauli_list_1, coeff_vec_1)) - assert PauliwordOp.from_dictionary( - pauli_dict - ).to_dictionary == pauli_dict + assert PauliwordOp.from_dictionary(pauli_dict).to_dictionary == pauli_dict def test_from_matrix_projector_dense(): - for n_qubits in range(1,5): - mat = np.random.random((2**n_qubits,2**n_qubits)) + 1j*np.random.random((2**n_qubits,2**n_qubits)) - PauliOp_from_matrix = PauliwordOp.from_matrix(mat, - strategy='projector') - assert np.allclose(PauliOp_from_matrix.to_sparse_matrix.toarray(), - mat) + for n_qubits in range(1, 5): + mat = np.random.random((2**n_qubits, 2**n_qubits)) + 1j * np.random.random( + (2**n_qubits, 2**n_qubits) + ) + PauliOp_from_matrix = PauliwordOp.from_matrix(mat, strategy="projector") + assert np.allclose(PauliOp_from_matrix.to_sparse_matrix.toarray(), mat) def test_from_matrix_full_basis_dense(): - for n_qubits in range(1,5): - mat = np.random.random((2**n_qubits,2**n_qubits)) + 1j*np.random.random((2**n_qubits,2**n_qubits)) - PauliOp_from_matrix = PauliwordOp.from_matrix(mat, - strategy='full_basis') + for n_qubits in range(1, 5): + mat = np.random.random((2**n_qubits, 2**n_qubits)) + 1j * np.random.random( + (2**n_qubits, 2**n_qubits) + ) + PauliOp_from_matrix = PauliwordOp.from_matrix(mat, strategy="full_basis") - assert np.allclose(PauliOp_from_matrix.to_sparse_matrix.toarray(), - mat) + assert np.allclose(PauliOp_from_matrix.to_sparse_matrix.toarray(), mat) def test_from_matrix_defined_basis_dense(): - - for n_qubits in range(2,6): - n_terms = (4**n_qubits)//2 + for n_qubits in range(2, 6): + n_terms = (4**n_qubits) // 2 op_basis = PauliwordOp.random(n_qubits, n_terms) - random_mat = sum(op.multiply_by_constant(np.random.uniform(0,10)) for op in op_basis).to_sparse_matrix.toarray() - PauliOp_from_matrix = PauliwordOp.from_matrix(random_mat, - strategy='full_basis', - operator_basis=op_basis) - assert np.allclose(random_mat, - PauliOp_from_matrix.to_sparse_matrix.toarray()) - - - op_basis = PauliwordOp.from_dictionary({'XX':1, - 'ZZ':2, - 'YY':2, - 'YI':-1, - 'YY':2, - 'ZX':2}) - - mat = np.array([[ 2.+0.j, 0.+0.j, 0.+1.j, -1.+0.j], - [ 0.+0.j, -2.+0.j, 3.+0.j, 0.+1.j], - [ 0.-1.j, 3.+0.j, -2.+0.j, 0.+0.j], - [-1.+0.j, 0.-1.j, 0.+0.j, 2.+0.j]]) - PauliOp_from_matrix = PauliwordOp.from_matrix(mat, strategy='full_basis', operator_basis=op_basis) + random_mat = sum( + op.multiply_by_constant(np.random.uniform(0, 10)) for op in op_basis + ).to_sparse_matrix.toarray() + PauliOp_from_matrix = PauliwordOp.from_matrix( + random_mat, strategy="full_basis", operator_basis=op_basis + ) + assert np.allclose(random_mat, PauliOp_from_matrix.to_sparse_matrix.toarray()) + + op_basis = PauliwordOp.from_dictionary( + {"XX": 1, "ZZ": 2, "YY": 2, "YI": -1, "YY": 2, "ZX": 2} + ) + + mat = np.array( + [ + [2.0 + 0.0j, 0.0 + 0.0j, 0.0 + 1.0j, -1.0 + 0.0j], + [0.0 + 0.0j, -2.0 + 0.0j, 3.0 + 0.0j, 0.0 + 1.0j], + [0.0 - 1.0j, 3.0 + 0.0j, -2.0 + 0.0j, 0.0 + 0.0j], + [-1.0 + 0.0j, 0.0 - 1.0j, 0.0 + 0.0j, 2.0 + 0.0j], + ] + ) + PauliOp_from_matrix = PauliwordOp.from_matrix( + mat, strategy="full_basis", operator_basis=op_basis + ) assert np.allclose(PauliOp_from_matrix.to_sparse_matrix.toarray(), mat) def test_from_matrix_projector_sparse(): density = 0.8 - for n_qubits in range(1,5): - dim = 2 ** n_qubits - mat = rand(dim, dim, - density=density, - format='csr', - dtype=complex) - PauliOp_from_matrix = PauliwordOp.from_matrix(mat, - strategy='projector') - assert np.allclose(PauliOp_from_matrix.to_sparse_matrix.toarray(), - mat.toarray()) + for n_qubits in range(1, 5): + dim = 2**n_qubits + mat = rand(dim, dim, density=density, format="csr", dtype=complex) + PauliOp_from_matrix = PauliwordOp.from_matrix(mat, strategy="projector") + assert np.allclose( + PauliOp_from_matrix.to_sparse_matrix.toarray(), mat.toarray() + ) def test_from_matrix_full_basis_sparse(): density = 0.8 - for n_qubits in range(1,5): - dim = 2 ** n_qubits - mat = rand(dim, dim, - density=density, - format='csr', - dtype=complex) - PauliOp_from_matrix = PauliwordOp.from_matrix(mat, - strategy='full_basis') + for n_qubits in range(1, 5): + dim = 2**n_qubits + mat = rand(dim, dim, density=density, format="csr", dtype=complex) + PauliOp_from_matrix = PauliwordOp.from_matrix(mat, strategy="full_basis") - assert np.allclose(PauliOp_from_matrix.to_sparse_matrix.toarray(), - mat.toarray()) + assert np.allclose( + PauliOp_from_matrix.to_sparse_matrix.toarray(), mat.toarray() + ) def test_from_matrix_defined_basis_sparse(): - op_basis = PauliwordOp.from_dictionary({ - 'II': 1, - 'IZ': 1, - 'ZI': 1, - 'ZZ': 1, - 'IX': 1, - 'IY': 1, - 'ZX': 1, - 'ZY': 1, - 'XI': 1, - 'XZ': 1, - 'YI': 1, - 'YZ': 1, - 'XX': 1, - 'XY': 1, - 'YX': 1, - 'YY': 1 }) - - mat = np.array([[1, 0, 0, 0], - [1, 0, 0, 0], - [1, 0, -1j, 0], - [1, 0, 0, 0]]) + op_basis = PauliwordOp.from_dictionary( + { + "II": 1, + "IZ": 1, + "ZI": 1, + "ZZ": 1, + "IX": 1, + "IY": 1, + "ZX": 1, + "ZY": 1, + "XI": 1, + "XZ": 1, + "YI": 1, + "YZ": 1, + "XX": 1, + "XY": 1, + "YX": 1, + "YY": 1, + } + ) + + mat = np.array([[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, -1j, 0], [1, 0, 0, 0]]) sparse_mat = csr_matrix(mat) - PauliOp_from_matrix = PauliwordOp.from_matrix(sparse_mat, - strategy='full_basis', - operator_basis=op_basis) + PauliOp_from_matrix = PauliwordOp.from_matrix( + sparse_mat, strategy="full_basis", operator_basis=op_basis + ) assert np.allclose(PauliOp_from_matrix.to_sparse_matrix.toarray(), mat) @@ -381,11 +372,15 @@ def test_from_matrix_incomplete_op_basis(): Returns: """ - op_basis = PauliwordOp.from_dictionary({'XX': 1}) - mat = np.array([[2. + 0.j, 0. + 0.j, 0. + 1.j, -1. + 0.j], - [0. + 0.j, -2. + 0.j, 3. + 0.j, 0. + 1.j], - [0. - 1.j, 3. + 0.j, -2. + 0.j, 0. + 0.j], - [-1. + 0.j, 0. - 1.j, 0. + 0.j, 2. + 0.j]]) + op_basis = PauliwordOp.from_dictionary({"XX": 1}) + mat = np.array( + [ + [2.0 + 0.0j, 0.0 + 0.0j, 0.0 + 1.0j, -1.0 + 0.0j], + [0.0 + 0.0j, -2.0 + 0.0j, 3.0 + 0.0j, 0.0 + 1.0j], + [0.0 - 1.0j, 3.0 + 0.0j, -2.0 + 0.0j, 0.0 + 0.0j], + [-1.0 + 0.0j, 0.0 - 1.0j, 0.0 + 0.0j, 2.0 + 0.0j], + ] + ) with pytest.warns(UserWarning): PauliwordOp.from_matrix(mat, operator_basis=op_basis) @@ -397,13 +392,10 @@ def test_from_matrix_incomplete_op_basis_sparse(): Returns: """ - op_basis = PauliwordOp.from_dictionary({'XX': 1}) + op_basis = PauliwordOp.from_dictionary({"XX": 1}) dim = 2**op_basis.n_qubits - mat = rand(dim, dim, - density=0.5, - format='csr', - dtype=complex) + mat = rand(dim, dim, density=0.5, format="csr", dtype=complex) with pytest.warns(UserWarning): PauliwordOp.from_matrix(mat, operator_basis=op_basis) @@ -412,7 +404,9 @@ def test_from_matrix_incomplete_op_basis_sparse(): def test_from_matrix_to_matrix(): n_qubits = 3 - mat = np.random.random((2**n_qubits,2**n_qubits)) + 1j*np.random.random((2**n_qubits,2**n_qubits)) + mat = np.random.random((2**n_qubits, 2**n_qubits)) + 1j * np.random.random( + (2**n_qubits, 2**n_qubits) + ) PauliOp_from_matrix = PauliwordOp.from_matrix(mat) PauliOp_to_matrix = PauliOp_from_matrix.to_sparse_matrix.toarray() assert np.allclose(PauliOp_to_matrix, mat) @@ -420,23 +414,17 @@ def test_from_matrix_to_matrix(): def test_from_matrix_projector_incorrect_input(): n_q = 1 - mat = [[1, 0], - [0, -1]] - - with pytest.raises(ValueError): - PauliwordOp._from_matrix_projector(mat, - n_qubits=n_q) + mat = [[1, 0], [0, -1]] + with pytest.raises(ValueError): + PauliwordOp._from_matrix_projector(mat, n_qubits=n_q) def test_from_openfermion(): - expected = {'XX': 0.5, - 'YY': 0.5+2j, - 'IZ': -0.5, - 'XZ': -0.5-3j} + expected = {"XX": 0.5, "YY": 0.5 + 2j, "IZ": -0.5, "XZ": -0.5 - 3j} of_operator = QubitOperator() for p, coeff in expected.items(): - p_str = ' '.join([f'{sig}{ind}' for ind, sig in enumerate(p) if sig!= 'I']) + p_str = " ".join([f"{sig}{ind}" for ind, sig in enumerate(p) if sig != "I"]) of_operator += QubitOperator(p_str, coeff) Pop = PauliwordOp.from_openfermion(of_operator) @@ -446,32 +434,23 @@ def test_from_openfermion(): def test_from_openfermion_qubit_specified(): - expected = {'XX': 0.5, - 'YY': 0.5+2j, - 'IZ': -0.5, - 'XZ': -0.5-3j} + expected = {"XX": 0.5, "YY": 0.5 + 2j, "IZ": -0.5, "XZ": -0.5 - 3j} of_operator = QubitOperator() for p, coeff in expected.items(): - p_str = ' '.join([f'{sig}{ind}' for ind, sig in enumerate(p) if sig!= 'I']) + p_str = " ".join([f"{sig}{ind}" for ind, sig in enumerate(p) if sig != "I"]) of_operator += QubitOperator(p_str, coeff) - three_q = {'XXI': 0.5, - 'YYI': 0.5+2j, - 'IZI': -0.5, - 'XZI': -0.5-3j} + three_q = {"XXI": 0.5, "YYI": 0.5 + 2j, "IZI": -0.5, "XZI": -0.5 - 3j} Pop = PauliwordOp.from_openfermion(of_operator, n_qubits=3) assert Pop.n_qubits == 3 assert Pop == PauliwordOp.from_dictionary(three_q) def test_to_openfermion(): - expected = {'XX': 0.5, - 'YY': 0.5+2j, - 'IZ': -0.5, - 'XZ': -0.5-3j} + expected = {"XX": 0.5, "YY": 0.5 + 2j, "IZ": -0.5, "XZ": -0.5 - 3j} of_operator = QubitOperator() for p, coeff in expected.items(): - p_str = ' '.join([f'{sig}{ind}' for ind, sig in enumerate(p) if sig!= 'I']) + p_str = " ".join([f"{sig}{ind}" for ind, sig in enumerate(p) if sig != "I"]) of_operator += QubitOperator(p_str, coeff) Pop = PauliwordOp.from_dictionary(expected) @@ -479,10 +458,7 @@ def test_to_openfermion(): def test_from_qiskit(): - expected = {'XX': 0.5, - 'YY': 0.5+2j, - 'IZ': -0.5, - 'XZ': -0.5-3j} + expected = {"XX": 0.5, "YY": 0.5 + 2j, "IZ": -0.5, "XZ": -0.5 - 3j} qiskit_op = PauliSumOp.from_list(expected.items()) Pop = PauliwordOp.from_qiskit(qiskit_op) assert Pop.to_dictionary == expected @@ -491,10 +467,7 @@ def test_from_qiskit(): def test_to_qiskit(): - expected = {'XX': 0.5, - 'YY': 0.5+2j, - 'IZ': -0.5, - 'XZ': -0.5-3j} + expected = {"XX": 0.5, "YY": 0.5 + 2j, "IZ": -0.5, "XZ": -0.5 - 3j} qiskit_op = PauliSumOp.from_list(expected.items()) Pop = PauliwordOp.from_dictionary(expected) assert Pop.to_qiskit == qiskit_op @@ -505,151 +478,165 @@ def test_to_qiskit(): # Testing algebraic manipulation of PauliwordOps # ################################################## -def test_Y_count( - symp_matrix_1, - coeff_vec_1 - ): + +def test_Y_count(symp_matrix_1, coeff_vec_1): P = PauliwordOp(symp_matrix_1, coeff_vec_1) - assert np.all(P.Y_count == np.array([0,0,3,0])) + assert np.all(P.Y_count == np.array([0, 0, 3, 0])) -def test_getitem( - pauli_list_2, - coeff_vec_2 - ): + +def test_getitem(pauli_list_2, coeff_vec_2): P = PauliwordOp.from_list(pauli_list_2, coeff_vec_2) assert all( - [P[i] == PauliwordOp.from_list([pauli_list_2[i]], [coeff_vec_2[i]]) - for i in range(-4,4)] + [ + P[i] == PauliwordOp.from_list([pauli_list_2[i]], [coeff_vec_2[i]]) + for i in range(-4, 4) + ] ) -def test_iter( - pauli_list_2, - coeff_vec_2 - ): + +def test_iter(pauli_list_2, coeff_vec_2): P = PauliwordOp.from_list(pauli_list_2, coeff_vec_2) assert all( - [Pi==PauliwordOp.from_list([pauli_list_2[i]], [coeff_vec_2[i]]) - for i, Pi in enumerate(P)] + [ + Pi == PauliwordOp.from_list([pauli_list_2[i]], [coeff_vec_2[i]]) + for i, Pi in enumerate(P) + ] ) - + + def test_cleanup_zeros(symp_matrix_1): - P = PauliwordOp.random(3,10) + P = PauliwordOp.random(3, 10) P.coeff_vec[:] = 0 assert P.cleanup().n_terms == 0 + def test_cleanup(): - P = PauliwordOp.from_list(['XXX', 'YYY', 'XXX', 'YYY'], [1,1,-1,1]) - assert P == PauliwordOp.from_list(['YYY'], [2]) + P = PauliwordOp.from_list(["XXX", "YYY", "XXX", "YYY"], [1, 1, -1, 1]) + assert P == PauliwordOp.from_list(["YYY"], [2]) + def test_addition(): P = PauliwordOp.random(3, 10) assert P + P == P * 2 + def test_subtraction(): P = PauliwordOp.random(3, 10) - assert (P-P).n_terms == 0 + assert (P - P).n_terms == 0 + -def test_termwise_commutatvity( - pauli_list_1, pauli_list_2 - ): +def test_termwise_commutatvity(pauli_list_1, pauli_list_2): P1 = PauliwordOp.from_list(pauli_list_1) P2 = PauliwordOp.from_list(pauli_list_2) - assert( - np.all(P1.commutes_termwise(P2) == np.array([ - [True , True , True , True ], - [True , False, True , False], - [False, False, True , True ], - [False, True , True , False] - ])) + assert np.all( + P1.commutes_termwise(P2) + == np.array( + [ + [True, True, True, True], + [True, False, True, False], + [False, False, True, True], + [False, True, True, False], + ] + ) ) -def test_adjacency_matrix( - pauli_list_2 - ): + +def test_adjacency_matrix(pauli_list_2): P = PauliwordOp.from_list(pauli_list_2) - assert( - np.all(P.adjacency_matrix == np.array([ - [True , False, True , False], - [False, True , True , False], - [True , True , True , True ], - [False, False, True , True ] - ])) + assert np.all( + P.adjacency_matrix + == np.array( + [ + [True, False, True, False], + [False, True, True, False], + [True, True, True, True], + [False, False, True, True], + ] + ) ) + @pytest.mark.parametrize( - "P_list,is_noncon", + "P_list,is_noncon", [ - (['XZ', 'ZX', 'ZI', 'IZ'],False), - (['XZ', 'ZX', 'XX', 'YY'],True), - (['XX', 'YY', 'ZZ', 'II'],True), - (['II', 'ZZ', 'ZX', 'ZY', 'XZ', 'YZ', 'XX', 'XY', 'YX', 'YY'], False) - ] + (["XZ", "ZX", "ZI", "IZ"], False), + (["XZ", "ZX", "XX", "YY"], True), + (["XX", "YY", "ZZ", "II"], True), + (["II", "ZZ", "ZX", "ZY", "XZ", "YZ", "XX", "XY", "YX", "YY"], False), + ], ) def test_is_noncontextual(P_list, is_noncon): P = PauliwordOp.from_list(P_list) assert P.is_noncontextual == is_noncon + @pytest.mark.parametrize( - "P1_dict,P2_dict,P1P2_dict", + "P1_dict,P2_dict,P1P2_dict", [ - ({'X':1},{'Y':1},{'Z':+1j}), - ({'Z':1},{'X':1},{'Y':+1j}), - ({'Y':1},{'Z':1},{'X':+1j}), - ({'Y':1},{'X':1},{'Z':-1j}), - ({'X':1},{'Z':1},{'Y':-1j}), - ({'Z':1},{'Y':1},{'X':-1j}), - ] + ({"X": 1}, {"Y": 1}, {"Z": +1j}), + ({"Z": 1}, {"X": 1}, {"Y": +1j}), + ({"Y": 1}, {"Z": 1}, {"X": +1j}), + ({"Y": 1}, {"X": 1}, {"Z": -1j}), + ({"X": 1}, {"Z": 1}, {"Y": -1j}), + ({"Z": 1}, {"Y": 1}, {"X": -1j}), + ], ) -def test_single_qubit_multiplication( - P1_dict, P2_dict, P1P2_dict - ): - P1 = PauliwordOp.from_dictionary(P1_dict) - P2 = PauliwordOp.from_dictionary(P2_dict) +def test_single_qubit_multiplication(P1_dict, P2_dict, P1P2_dict): + P1 = PauliwordOp.from_dictionary(P1_dict) + P2 = PauliwordOp.from_dictionary(P2_dict) P1P2 = PauliwordOp.from_dictionary(P1P2_dict) assert P1 * P2 == P1P2 + def test_is_noncontextual_generators(): """ noncontextual test that breaks if only 2n generators are used rather than 3n generators Returns: """ - Hnc = PauliwordOp.from_dictionary({'IIIZX': (0.04228614428142647-0j), - 'IIIZY': (-0.30109670698419544-0j), - 'IIZZX': (0.04228614428142647-0j), - 'IIZZY': (-0.30109670698419544-0j), - 'IZIZX': (0.04228614428142647-0j), - 'IZIZY': (-0.30109670698419544-0j), - 'IZZZX': (0.04228614428142647-0j), - 'IZZZY': (-0.30109670698419544-0j), - 'ZIIZX': (0.04228614428142647-0j), - 'ZIIZY': (-0.30109670698419544-0j), - 'ZIZZX': (0.04228614428142647-0j), - 'ZIZZY': (-0.30109670698419544-0j), - 'ZZIZX': (0.04228614428142647-0j), - 'ZZIZY': (-0.30109670698419544-0j), - 'ZZZZX': (0.04228614428142647-0j), - 'ZZZZY': (-0.30109670698419544-0j), - 'IIIXI': (-1.6377047626147634-0j), - 'IIIYI': (-0.8887783867443338-0j), - 'IIZXI': (-1.6377047626147634-0j), - 'IIZYI': (-0.8887783867443338-0j), - 'IZIXI': (-1.6377047626147634-0j), - 'IZIYI': (-0.8887783867443338-0j), - 'IZZXI': (-1.6377047626147634-0j), - 'IZZYI': (-0.8887783867443338-0j), - 'ZIIXI': (-1.6377047626147634-0j), - 'ZIIYI': (-0.8887783867443338-0j), - 'ZIZXI': (-1.6377047626147634-0j), - 'ZIZYI': (-0.8887783867443338-0j), - 'ZZIXI': (-1.6377047626147634-0j), - 'ZZIYI': (-0.8887783867443338-0j), - 'ZZZXI': (-1.6377047626147634-0j), - 'ZZZYI': (-0.8887783867443338-0j)}) + Hnc = PauliwordOp.from_dictionary( + { + "IIIZX": (0.04228614428142647 - 0j), + "IIIZY": (-0.30109670698419544 - 0j), + "IIZZX": (0.04228614428142647 - 0j), + "IIZZY": (-0.30109670698419544 - 0j), + "IZIZX": (0.04228614428142647 - 0j), + "IZIZY": (-0.30109670698419544 - 0j), + "IZZZX": (0.04228614428142647 - 0j), + "IZZZY": (-0.30109670698419544 - 0j), + "ZIIZX": (0.04228614428142647 - 0j), + "ZIIZY": (-0.30109670698419544 - 0j), + "ZIZZX": (0.04228614428142647 - 0j), + "ZIZZY": (-0.30109670698419544 - 0j), + "ZZIZX": (0.04228614428142647 - 0j), + "ZZIZY": (-0.30109670698419544 - 0j), + "ZZZZX": (0.04228614428142647 - 0j), + "ZZZZY": (-0.30109670698419544 - 0j), + "IIIXI": (-1.6377047626147634 - 0j), + "IIIYI": (-0.8887783867443338 - 0j), + "IIZXI": (-1.6377047626147634 - 0j), + "IIZYI": (-0.8887783867443338 - 0j), + "IZIXI": (-1.6377047626147634 - 0j), + "IZIYI": (-0.8887783867443338 - 0j), + "IZZXI": (-1.6377047626147634 - 0j), + "IZZYI": (-0.8887783867443338 - 0j), + "ZIIXI": (-1.6377047626147634 - 0j), + "ZIIYI": (-0.8887783867443338 - 0j), + "ZIZXI": (-1.6377047626147634 - 0j), + "ZIZYI": (-0.8887783867443338 - 0j), + "ZZIXI": (-1.6377047626147634 - 0j), + "ZZIYI": (-0.8887783867443338 - 0j), + "ZZZXI": (-1.6377047626147634 - 0j), + "ZZZYI": (-0.8887783867443338 - 0j), + } + ) ## note this commented out method is gives incorrect answer # assert check_adjmat_noncontextual(Hnc.generators.adjacency_matrix), 'noncontexutal operator is being correctly defined as noncontextual' - assert Hnc.is_noncontextual, 'noncontexutal operator is being incorrectly being defined as contextual' + assert ( + Hnc.is_noncontextual + ), "noncontexutal operator is being incorrectly being defined as contextual" + def test_is_noncontextual_anticommuting_H(): """ @@ -657,109 +644,126 @@ def test_is_noncontextual_anticommuting_H(): Returns: """ - Hnc = PauliwordOp.from_dictionary({ - 'ZZZI': (1.2532436410975218-0j), - 'IIXI': (0.8935108507410493-0j), - 'ZIYI': (-1.1362909076230914+0j), - 'IXZI': (-0.05373661687140326+0j), - 'ZYZI': (-1.0012312990477774+0j), - 'XXYI': (-0.045809456087963205+0j), - 'YXYZ': (0.21569499626612557-0j), - 'YXYX': (-0.5806963175396661+0j), - 'YXYY': (0.3218493853030614-0j)}) - - assert Hnc.is_noncontextual, 'noncontexutal operator is being correctly defined as noncontextual' + Hnc = PauliwordOp.from_dictionary( + { + "ZZZI": (1.2532436410975218 - 0j), + "IIXI": (0.8935108507410493 - 0j), + "ZIYI": (-1.1362909076230914 + 0j), + "IXZI": (-0.05373661687140326 + 0j), + "ZYZI": (-1.0012312990477774 + 0j), + "XXYI": (-0.045809456087963205 + 0j), + "YXYZ": (0.21569499626612557 - 0j), + "YXYX": (-0.5806963175396661 + 0j), + "YXYY": (0.3218493853030614 - 0j), + } + ) + + assert ( + Hnc.is_noncontextual + ), "noncontexutal operator is being correctly defined as noncontextual" + def test_multiplication_1(): - """ Tests multiplication and the OpenFermion conversion - """ + """Tests multiplication and the OpenFermion conversion""" P1 = PauliwordOp.random(3, 10) P2 = PauliwordOp.random(3, 10) assert (P1 * P2).to_openfermion == P1.to_openfermion * P2.to_openfermion + def test_multiplication_2(): - """ Tests multiplication and the Qiskit conversion - """ + """Tests multiplication and the Qiskit conversion""" P1 = PauliwordOp.random(3, 10) P2 = PauliwordOp.random(3, 10) assert (P1 * P2).to_qiskit == P1.to_qiskit @ P2.to_qiskit + def test_to_sparse_matrix_1(): - """ Tests multiplication and the Qiskit conversion - """ + """Tests multiplication and the Qiskit conversion""" P1 = PauliwordOp.random(3, 10) P2 = PauliwordOp.random(3, 10) assert np.allclose( - (P1*P2).to_sparse_matrix.toarray(), - P1.to_sparse_matrix.toarray() @ P2.to_sparse_matrix.toarray() + (P1 * P2).to_sparse_matrix.toarray(), + P1.to_sparse_matrix.toarray() @ P2.to_sparse_matrix.toarray(), ) + @pytest.mark.parametrize( - "P_dict,P_array", + "P_dict,P_array", [ - ({'X':1}, np.array([[0,1],[1,0]])), - ({'Y':1}, np.array([[0,-1j],[1j,0]])), - ({'Z':1}, np.array([[1,0],[0,-1]])), - ({'XY':1}, np.array([[0,0,0,-1j],[0,0,1j,0],[0,-1j,0,0],[1j,0,0,0]])), - ({'ZY':1}, np.array([[0,-1j,0,0],[1j,0,0,0],[0,0,0,1j],[0,0,-1j,0]])), - ({'II':1, 'IX':1, 'XI':1, 'XX':1}, np.ones([4,4])) - ] + ({"X": 1}, np.array([[0, 1], [1, 0]])), + ({"Y": 1}, np.array([[0, -1j], [1j, 0]])), + ({"Z": 1}, np.array([[1, 0], [0, -1]])), + ( + {"XY": 1}, + np.array([[0, 0, 0, -1j], [0, 0, 1j, 0], [0, -1j, 0, 0], [1j, 0, 0, 0]]), + ), + ( + {"ZY": 1}, + np.array([[0, -1j, 0, 0], [1j, 0, 0, 0], [0, 0, 0, 1j], [0, 0, -1j, 0]]), + ), + ({"II": 1, "IX": 1, "XI": 1, "XX": 1}, np.ones([4, 4])), + ], ) -def test_to_sparse_matrix_2( - P_dict, P_array - ): +def test_to_sparse_matrix_2(P_dict, P_array): P = PauliwordOp.from_dictionary(P_dict) assert np.all(P.to_sparse_matrix.toarray() == P_array) + def test_to_sparse_matrix_large_operator(): - """ Tests multiplication and the Qiskit conversion - """ - H = PauliwordOp.from_dictionary({'ZIIIIIIIZIXXXIII': (-1.333664871035997-0.6347579982999967j), - 'IIIIIYIIXYZZIXXI': (0.6121055433989232+2.0175827791182313j), - 'IIIXIZZIIZIIXIZI': (-0.5187971729475656+1.2184045529704965j), - 'ZIIXYYZZIYYXXIZY': (0.6788676757886678+1.867085666718753j), - 'IZXIYIXYXIIIZZIX': (-1.0665060328185856-0.5702647494844407j), - 'ZIXXIIIZIIIIZIXX': (0.17268863171166954-0.07117422292367692j), - 'IIYXIIYIIIXIIZXI': (0.03704770372393225-0.21589376964746243j), - 'IYIZXXIXZXXZIIII': (0.29998428856285453-0.9742733999161437j), - 'YXIXIIZXZIIIIIYX': (0.3421035543407282-0.20273712913326358j), - 'XXXYIIIIXIIXIXIZ': (1.1502457768722+1.3148268876228302j)}) + """Tests multiplication and the Qiskit conversion""" + H = PauliwordOp.from_dictionary( + { + "ZIIIIIIIZIXXXIII": (-1.333664871035997 - 0.6347579982999967j), + "IIIIIYIIXYZZIXXI": (0.6121055433989232 + 2.0175827791182313j), + "IIIXIZZIIZIIXIZI": (-0.5187971729475656 + 1.2184045529704965j), + "ZIIXYYZZIYYXXIZY": (0.6788676757886678 + 1.867085666718753j), + "IZXIYIXYXIIIZZIX": (-1.0665060328185856 - 0.5702647494844407j), + "ZIXXIIIZIIIIZIXX": (0.17268863171166954 - 0.07117422292367692j), + "IIYXIIYIIIXIIZXI": (0.03704770372393225 - 0.21589376964746243j), + "IYIZXXIXZXXZIIII": (0.29998428856285453 - 0.9742733999161437j), + "YXIXIIZXZIIIIIYX": (0.3421035543407282 - 0.20273712913326358j), + "XXXYIIIIXIIXIXIZ": (1.1502457768722 + 1.3148268876228302j), + } + ) mat_sparse = H.to_sparse_matrix basis = H.copy() basis.coeff_vec = np.ones_like(basis.coeff_vec) - out = PauliwordOp.from_matrix(mat_sparse, - strategy='full_basis', - operator_basis=basis, - disable_loading_bar=True) - assert H == out, 'to_sparse_matrix of large Pauli operator is failing' + out = PauliwordOp.from_matrix( + mat_sparse, + strategy="full_basis", + operator_basis=basis, + disable_loading_bar=True, + ) + assert H == out, "to_sparse_matrix of large Pauli operator is failing" def test_QuantumState_overlap(): - for n_q in range(2,5): - random_ket_1 = QuantumState.haar_random(n_q, vec_type='ket') - random_ket_2 = QuantumState.haar_random(n_q, vec_type='ket') + for n_q in range(2, 5): + random_ket_1 = QuantumState.haar_random(n_q, vec_type="ket") + random_ket_2 = QuantumState.haar_random(n_q, vec_type="ket") ket_1 = random_ket_1.to_sparse_matrix.toarray() ket_2 = random_ket_2.to_sparse_matrix.toarray() - assert np.isclose(ket_2.conj().T @ ket_1, - random_ket_2.dagger * random_ket_1) + assert np.isclose(ket_2.conj().T @ ket_1, random_ket_2.dagger * random_ket_1) + + assert np.isclose(ket_1.conj().T @ ket_2, random_ket_1.dagger * random_ket_2) - assert np.isclose(ket_1.conj().T @ ket_2, - random_ket_1.dagger * random_ket_2) + assert np.isclose( + random_ket_1.dagger * random_ket_2, + (random_ket_2.dagger * random_ket_1).conj(), + ) - assert np.isclose(random_ket_1.dagger * random_ket_2, - (random_ket_2.dagger * random_ket_1).conj()) def test_pauliwordop_hash(): - XI = PauliwordOp.from_dictionary({'XI':1}) - XI_copy = PauliwordOp.from_dictionary({'XI': 1}) + XI = PauliwordOp.from_dictionary({"XI": 1}) + XI_copy = PauliwordOp.from_dictionary({"XI": 1}) assert hash(XI) == hash(XI_copy) - YI = PauliwordOp.from_dictionary({'YI': 1}) + YI = PauliwordOp.from_dictionary({"YI": 1}) assert hash(YI) != hash(XI_copy) # different coeff means different hash! - XI_3 = PauliwordOp.from_dictionary({'XI': 3}) - assert hash(XI) != hash(XI_3) \ No newline at end of file + XI_3 = PauliwordOp.from_dictionary({"XI": 3}) + assert hash(XI) != hash(XI_3) diff --git a/tests/test_operators/test_independent_op.py b/tests/test_operators/test_independent_op.py index 86f0bef..f163dc8 100644 --- a/tests/test_operators/test_independent_op.py +++ b/tests/test_operators/test_independent_op.py @@ -4,116 +4,121 @@ H2_op = PauliwordOp.from_dictionary( { - 'IIII': (-0.09706626816762845+0j), - 'IIIZ': (-0.22343153690813597+0j), - 'IIZI': (-0.22343153690813597+0j), - 'IIZZ': (0.17441287612261608+0j), - 'IZII': (0.17141282644776884+0j), - 'IZIZ': (0.12062523483390426+0j), - 'IZZI': (0.16592785033770355+0j), - 'ZIII': (0.17141282644776884+0j), - 'ZIIZ': (0.16592785033770355+0j), - 'ZIZI': (0.12062523483390426+0j), - 'ZZII': (0.16868898170361213+0j), - 'XXYY': (-0.0453026155037993+0j), - 'XYYX': (0.0453026155037993+0j), - 'YXXY': (0.0453026155037993+0j), - 'YYXX': (-0.0453026155037993+0j) + "IIII": (-0.09706626816762845 + 0j), + "IIIZ": (-0.22343153690813597 + 0j), + "IIZI": (-0.22343153690813597 + 0j), + "IIZZ": (0.17441287612261608 + 0j), + "IZII": (0.17141282644776884 + 0j), + "IZIZ": (0.12062523483390426 + 0j), + "IZZI": (0.16592785033770355 + 0j), + "ZIII": (0.17141282644776884 + 0j), + "ZIIZ": (0.16592785033770355 + 0j), + "ZIZI": (0.12062523483390426 + 0j), + "ZZII": (0.16868898170361213 + 0j), + "XXYY": (-0.0453026155037993 + 0j), + "XYYX": (0.0453026155037993 + 0j), + "YXXY": (0.0453026155037993 + 0j), + "YYXX": (-0.0453026155037993 + 0j), } ) energy = -1.1372838344885023 ref_state = np.array([1, 1, 0, 0]) + def test_target_sqp_invalid_value_error(): with pytest.raises(ValueError): - IndependentOp([[0,1]], [1], target_sqp='x') + IndependentOp([[0, 1]], [1], target_sqp="x") + def test_from_list(): - op1 = IndependentOp.from_list(['X', 'Z']) - op2 = IndependentOp( - [[0,1],[1,0]], [1,1] - ) + op1 = IndependentOp.from_list(["X", "Z"]) + op2 = IndependentOp([[0, 1], [1, 0]], [1, 1]) assert op1 == op2 + def test_from_dictionary(): - op1 = IndependentOp.from_dictionary({'X':1, 'Z':1}) - op2 = IndependentOp( - [[0,1],[1,0]], [1,1] - ) + op1 = IndependentOp.from_dictionary({"X": 1, "Z": 1}) + op2 = IndependentOp([[0, 1], [1, 0]], [1, 1]) assert op1 == op2 + # def test_no_symmetry_generator_error(): # op = PauliwordOp.from_list(['X', 'Y','Z']) # with pytest.raises(RuntimeError): # IndependentOp.symmetry_generators(op) + def test_no_symmetry_generators(): - op = PauliwordOp.from_list(['X', 'Y','Z']) + op = PauliwordOp.from_list(["X", "Y", "Z"]) ind_op = IndependentOp.symmetry_generators(op) assert ind_op.n_terms == 0 def test_commuting_overide_symmetry_generators(): - op = PauliwordOp.from_list( - ['IZZ', 'ZZI', 'IXX', 'XXI', 'IYY', 'YYI'] + op = PauliwordOp.from_list(["IZZ", "ZZI", "IXX", "XXI", "IYY", "YYI"]) + gen_without_override = IndependentOp.symmetry_generators( + op, commuting_override=False ) - gen_without_override = IndependentOp.symmetry_generators(op, commuting_override=False) gen_with_override = IndependentOp.symmetry_generators(op, commuting_override=True) assert gen_with_override != gen_without_override assert gen_without_override in [ - IndependentOp.from_list(['XXX']), IndependentOp.from_list(['ZZZ']) + IndependentOp.from_list(["XXX"]), + IndependentOp.from_list(["ZZZ"]), ] - assert gen_with_override == IndependentOp.from_list(['XXX', 'ZZZ']) + assert gen_with_override == IndependentOp.from_list(["XXX", "ZZZ"]) + def test_clique_cover_large_anticommuting_generating_set(): - op = PauliwordOp.from_list(['Z'*20]) + op = PauliwordOp.from_list(["Z" * 20]) with pytest.warns(): IndependentOp.symmetry_generators(op) + def test_dependent_input(): with pytest.raises(ValueError): - IndependentOp.from_list(['X', 'Y', 'Z']) + IndependentOp.from_list(["X", "Y", "Z"]) + def test_rotations_onto_sqp_Z(): - op = PauliwordOp.from_list(['Z'*20]) + op = PauliwordOp.from_list(["Z" * 20]) G = IndependentOp.symmetry_generators(op) - G.target_sqp = 'Z' + G.target_sqp = "Z" rotated = G.rotate_onto_single_qubit_paulis() - assert ( - np.all(np.sum(rotated.Z_block, axis=1) <= 1) and - np.all(~rotated.X_block) - ) + assert np.all(np.sum(rotated.Z_block, axis=1) <= 1) and np.all(~rotated.X_block) + def test_rotations_onto_sqp_X(): - op = PauliwordOp.from_list(['Z'*20]) + op = PauliwordOp.from_list(["Z" * 20]) G = IndependentOp.symmetry_generators(op) - G.target_sqp = 'X' + G.target_sqp = "X" rotated = G.rotate_onto_single_qubit_paulis() - assert ( - np.all(np.sum(rotated.X_block, axis=1) <= 1) and - np.all(~rotated.Z_block) - ) + assert np.all(np.sum(rotated.X_block, axis=1) <= 1) and np.all(~rotated.Z_block) + def test_symmetry_generators_H2(): G1 = IndependentOp.symmetry_generators(H2_op) - G2 = IndependentOp.from_list(['ZIZI', 'IZIZ', 'IIZZ']) + G2 = IndependentOp.from_list(["ZIZI", "IZIZ", "IIZZ"]) - assert ( - np.all(G1.generator_reconstruction(G2)[1]) and - np.all(G2.generator_reconstruction(G1)[1]) + assert np.all(G1.generator_reconstruction(G2)[1]) and np.all( + G2.generator_reconstruction(G1)[1] ) + def test_value_assignment(): G = IndependentOp.symmetry_generators(H2_op) G.update_sector(ref_state=ref_state) - assert np.all(G.coeff_vec == (-1) ** np.sum(np.bitwise_and(G.Z_block,ref_state), axis=1)) - + assert np.all( + G.coeff_vec == (-1) ** np.sum(np.bitwise_and(G.Z_block, ref_state), axis=1) + ) + + def test_indexing(): - G = IndependentOp.from_list(['IZ', 'ZI', 'XX']) - assert G[0] == IndependentOp.from_list(['IZ']) - assert G[1] == IndependentOp.from_list(['ZI']) - assert G[2] == IndependentOp.from_list(['XX']) + G = IndependentOp.from_list(["IZ", "ZI", "XX"]) + assert G[0] == IndependentOp.from_list(["IZ"]) + assert G[1] == IndependentOp.from_list(["ZI"]) + assert G[2] == IndependentOp.from_list(["XX"]) + def test_invalid_coefficient(): with pytest.raises(ValueError): - IndependentOp.from_dictionary({'X':1, 'Z':2}) \ No newline at end of file + IndependentOp.from_dictionary({"X": 1, "Z": 2}) diff --git a/tests/test_operators/test_noncontextual_op.py b/tests/test_operators/test_noncontextual_op.py index c2c06ed..4d7524c 100644 --- a/tests/test_operators/test_noncontextual_op.py +++ b/tests/test_operators/test_noncontextual_op.py @@ -6,8 +6,9 @@ from symmer.operators.noncontextual_op import NoncontextualSolver from symmer.utils import exact_gs_energy + def jordan_generator_reconstruction_check(self, generators): - """ Function for jordan generators reconstruction test + """Function for jordan generators reconstruction test This builds the noncontextual operator under the Jordan product, but does not give the reconstruction matrix. This can be used to check that the function with the reconstruction matrix IS correct! @@ -20,51 +21,58 @@ def jordan_generator_reconstruction_check(self, generators): PwordOp_noncon = self[self.generator_reconstruction(Symmetries)[1]] PwordOp_remain = self - PwordOp_noncon for P in Anticommuting: - PwordOp_noncon += PwordOp_remain[PwordOp_remain.generator_reconstruction(P+Symmetries)[1]] + PwordOp_noncon += PwordOp_remain[ + PwordOp_remain.generator_reconstruction(P + Symmetries)[1] + ] return PwordOp_noncon + noncon_problem = { - 'H_dict': {'IIII': (-0.09706626816762845+0j), - 'IIIZ': (-0.22343153690813597+0j), - 'IIZI': (-0.22343153690813597+0j), - 'IIZZ': (0.17441287612261608+0j), - 'IZII': (0.17141282644776884+0j), - 'IZIZ': (0.12062523483390426+0j), - 'IZZI': (0.16592785033770355+0j), - 'ZIII': (0.17141282644776884+0j), - 'ZIIZ': (0.16592785033770355+0j), - 'ZIZI': (0.12062523483390426+0j), - 'ZZII': (0.16868898170361213+0j), - 'XXYY': (-0.0453026155037993+0j), - 'XYYX': (0.0453026155037993+0j), - 'YXXY': (0.0453026155037993+0j), - 'YYXX': (-0.0453026155037993+0j)}, - 'E': -1.1372838344885023, - 'reference_state': np.array([1, 1, 0, 0]), - 'partial_reference_state': QuantumState( - np.array([[1, 1, 0, 0], - [1, 1, 1, 1]]), - np.array([1/np.sqrt(2), 1/np.sqrt(2)])) + "H_dict": { + "IIII": (-0.09706626816762845 + 0j), + "IIIZ": (-0.22343153690813597 + 0j), + "IIZI": (-0.22343153690813597 + 0j), + "IIZZ": (0.17441287612261608 + 0j), + "IZII": (0.17141282644776884 + 0j), + "IZIZ": (0.12062523483390426 + 0j), + "IZZI": (0.16592785033770355 + 0j), + "ZIII": (0.17141282644776884 + 0j), + "ZIIZ": (0.16592785033770355 + 0j), + "ZIZI": (0.12062523483390426 + 0j), + "ZZII": (0.16868898170361213 + 0j), + "XXYY": (-0.0453026155037993 + 0j), + "XYYX": (0.0453026155037993 + 0j), + "YXXY": (0.0453026155037993 + 0j), + "YYXX": (-0.0453026155037993 + 0j), + }, + "E": -1.1372838344885023, + "reference_state": np.array([1, 1, 0, 0]), + "partial_reference_state": QuantumState( + np.array([[1, 1, 0, 0], [1, 1, 1, 1]]), + np.array([1 / np.sqrt(2), 1 / np.sqrt(2)]), + ), +} + +H_con_dict = { + "II": (0.104907), + "IZ": (0.2038683), + "ZI": (-0.238925), + "ZZ": (0.2386317), + "IX": (0.1534837), + "IY": (0.1503439), + "ZX": (0.0679678), + "ZY": (0.2538080), + "XI": (0.0994848), + "XZ": (-0.044597), + "YI": (-0.274103), + "YZ": (-0.078968), + "XX": (-0.292164), + "XY": (-0.183966), + "YX": (-0.058251), + "YY": (-0.212114), } -H_con_dict = {'II': (0.104907), - 'IZ': (0.2038683), - 'ZI': (-0.238925), - 'ZZ': (0.2386317), - 'IX': (0.1534837), - 'IY': (0.1503439), - 'ZX': (0.0679678), - 'ZY': (0.2538080), - 'XI': (0.0994848), - 'XZ': (-0.044597), - 'YI': (-0.274103), - 'YZ': (-0.078968), - 'XX': (-0.292164), - 'XY': (-0.183966), - 'YX': (-0.058251), - 'YY': (-0.212114) - } def test_init_contextual_input(): """ @@ -85,7 +93,7 @@ def test_init_noncontextual_input(): Returns: """ - H_noncon = PauliwordOp.from_dictionary(noncon_problem['H_dict']) + H_noncon = PauliwordOp.from_dictionary(noncon_problem["H_dict"]) symp_matrix = H_noncon.symp_matrix coeff_vec = H_noncon.coeff_vec @@ -100,15 +108,16 @@ def test_init_noncontextual_input(): # H_noncon_diag = NoncontextualOp._diag_noncontextual_op(H) # assert ~np.any(H_noncon_diag.X_block, axis=1) + def test_from_hamiltonian_diag(): - """ check noncontextual operator via diagonal approach (Z ops only!) - """ + """check noncontextual operator via diagonal approach (Z ops only!)""" H = PauliwordOp.from_dictionary(H_con_dict) - H_noncon_diag = NoncontextualOp.from_hamiltonian(H, - strategy='diag', - generators= None, - DFS_runtime=10) - assert np.all(np.sum(H_noncon_diag.X_block, axis=1)==0), 'some non Z operators present' + H_noncon_diag = NoncontextualOp.from_hamiltonian( + H, strategy="diag", generators=None, DFS_runtime=10 + ) + assert np.all( + np.sum(H_noncon_diag.X_block, axis=1) == 0 + ), "some non Z operators present" assert H_noncon_diag.is_noncontextual @@ -117,10 +126,9 @@ def test_from_hamiltonian_DFS_magnitude(): check noncontextual op via depth first search """ H = PauliwordOp.from_dictionary(H_con_dict) - H_noncon_dfs = NoncontextualOp.from_hamiltonian(H, - strategy='DFS_magnitude', - generators= None, - DFS_runtime=10) + H_noncon_dfs = NoncontextualOp.from_hamiltonian( + H, strategy="DFS_magnitude", generators=None, DFS_runtime=10 + ) assert H_noncon_dfs.is_noncontextual @@ -130,10 +138,9 @@ def test_from_hamiltonian_DFS_largest(): check noncontextual op via depth first search """ H = PauliwordOp.from_dictionary(H_con_dict) - H_noncon_dfs = NoncontextualOp.from_hamiltonian(H, - strategy='DFS_largest', - generators= None, - DFS_runtime=10) + H_noncon_dfs = NoncontextualOp.from_hamiltonian( + H, strategy="DFS_largest", generators=None, DFS_runtime=10 + ) assert H_noncon_dfs.is_noncontextual @@ -143,10 +150,9 @@ def test_from_hamiltonian_SingleSweep_magnitude(): check noncontextual op via depth first search """ H = PauliwordOp.from_dictionary(H_con_dict) - H_noncon_dfs = NoncontextualOp.from_hamiltonian(H, - strategy='SingleSweep_magnitude', - generators= None, - DFS_runtime=10) + H_noncon_dfs = NoncontextualOp.from_hamiltonian( + H, strategy="SingleSweep_magnitude", generators=None, DFS_runtime=10 + ) assert H_noncon_dfs.is_noncontextual @@ -156,10 +162,9 @@ def test_from_hamiltonian_SingleSweep_random(): check noncontextual op via depth first search """ H = PauliwordOp.from_dictionary(H_con_dict) - H_noncon_dfs = NoncontextualOp.from_hamiltonian(H, - strategy='SingleSweep_random', - generators= None, - DFS_runtime=10) + H_noncon_dfs = NoncontextualOp.from_hamiltonian( + H, strategy="SingleSweep_random", generators=None, DFS_runtime=10 + ) assert H_noncon_dfs.is_noncontextual @@ -169,10 +174,9 @@ def test_from_hamiltonian_SingleSweep_CurrentOrder(): check noncontextual op via depth first search """ H = PauliwordOp.from_dictionary(H_con_dict) - H_noncon_dfs = NoncontextualOp.from_hamiltonian(H, - strategy='SingleSweep_CurrentOrder', - generators= None, - DFS_runtime=10) + H_noncon_dfs = NoncontextualOp.from_hamiltonian( + H, strategy="SingleSweep_CurrentOrder", generators=None, DFS_runtime=10 + ) assert H_noncon_dfs.is_noncontextual @@ -182,26 +186,23 @@ def test_from_hamiltonian_generators(): check noncontextual op via a defined generators """ ## COMMUTING generators - generators1 = PauliwordOp.from_dictionary({'IZ': (1+0j), - 'ZI': (1+0j)}) + generators1 = PauliwordOp.from_dictionary({"IZ": (1 + 0j), "ZI": (1 + 0j)}) H = PauliwordOp.from_dictionary(H_con_dict) - H_noncon_generators1 = NoncontextualOp.from_hamiltonian(H, - strategy='generators', - generators= generators1, - DFS_runtime=10) + H_noncon_generators1 = NoncontextualOp.from_hamiltonian( + H, strategy="generators", generators=generators1, DFS_runtime=10 + ) assert H_noncon_generators1.is_noncontextual ## NON-COMMUTING generators - generators2 = PauliwordOp.from_dictionary({'IZ': (1 + 0j), - 'ZI': (1 + 0j), - 'XI': (1 + 0j)}) + generators2 = PauliwordOp.from_dictionary( + {"IZ": (1 + 0j), "ZI": (1 + 0j), "XI": (1 + 0j)} + ) - H_noncon_generators2 = NoncontextualOp.from_hamiltonian(H, - strategy='generators', - generators= generators2, - DFS_runtime=10) + H_noncon_generators2 = NoncontextualOp.from_hamiltonian( + H, strategy="generators", generators=generators2, DFS_runtime=10 + ) assert H_noncon_generators2.is_noncontextual @@ -209,7 +210,7 @@ def test_from_hamiltonian_generators(): def test_noncon_no_symmetry_generators(): - Pwords = PauliwordOp.from_list(['X', 'Y', 'Z']) + Pwords = PauliwordOp.from_list(["X", "Y", "Z"]) E_ground = -1.7320508075688772 with pytest.warns(): @@ -230,99 +231,127 @@ def test_noncon_noncommuting_Z2(): Z2_symmerties don't all pairwise commute. This can lead to problems if not handled correctly. """ - H_noncon = PauliwordOp.from_dictionary({'IIIIIIIIII': (-15.27681058613343+0j), 'IIIIIIIIIZ': (-0.2172743037258172+0j), 'IIIIIZIIII': (0.11405708903311647+0j), 'IIIIIZIIIZ': (0.22929933946046854+0j), 'IIIIZIIIII': (0.07618739164001126+0j), 'IIIIZIIIIZ': (0.10424432000703249+0j), 'IIIIZZIIII': (0.2458433632534619+0j), 'IIIZIIIIII': (0.07618739164001137+0j), 'IIIZIIIIIZ': (0.11790253563113795+0j), 'IIIZIZIIII': (0.2458433632534619+0j), 'IIIZZIIIII': (0.14846395230159326+0j), 'IIZIIIIIII': (0.17066279019288416+0j), 'IIZIIIIIIZ': (0.19577211156187402+0j), 'IIZIIZIIII': (0.220702612028004+0j), 'IIZIZIIIII': (0.10245792602520705+0j), 'IIZZIIIIII': (0.10964094999478652+0j), 'IZIIIIIIII': (0.2601827946303151+0j), 'IZIIIIIIIZ': (0.1060269619647709+0j), 'IZIIIZIIII': (0.21982388480817722+0j), 'IZIIZIIIII': (0.09485326000745692+0j), 'IZIZIIIIII': (0.1112840228980842+0j), 'IZZIIIIIII': (0.08389584977571822+0j), 'IZZIZZIIIZ': (-0.14917151435431195+0j), 'ZIIIIIIIII': (0.2601827946303149+0j), 'ZIIIIIIIIZ': (0.11944056365665429+0j), 'ZIIIIZIIII': (0.21982388480817722+0j), 'ZIIIZIIIII': (0.1112840228980842+0j), 'ZIIZIIIIII': (0.09485326000745692+0j), 'ZIZIIIIIII': (0.12042746433351019+0j), 'ZIZZIZIIIZ': (-0.14917151435431195+0j), 'ZZIIIIIIII': (0.12244309127472158+0j), 'IIZZZIXIXZ': (-0.0023524442663984376+0j), 'ZIZIZZXIXZ': (0.0023524442663984376+0j), 'ZIYIZZIXIY': (0.0023524442663984376+0j), 'ZZYIIIIXIY': (-0.0023524442663984376+0j)}) + H_noncon = PauliwordOp.from_dictionary( + { + "IIIIIIIIII": (-15.27681058613343 + 0j), + "IIIIIIIIIZ": (-0.2172743037258172 + 0j), + "IIIIIZIIII": (0.11405708903311647 + 0j), + "IIIIIZIIIZ": (0.22929933946046854 + 0j), + "IIIIZIIIII": (0.07618739164001126 + 0j), + "IIIIZIIIIZ": (0.10424432000703249 + 0j), + "IIIIZZIIII": (0.2458433632534619 + 0j), + "IIIZIIIIII": (0.07618739164001137 + 0j), + "IIIZIIIIIZ": (0.11790253563113795 + 0j), + "IIIZIZIIII": (0.2458433632534619 + 0j), + "IIIZZIIIII": (0.14846395230159326 + 0j), + "IIZIIIIIII": (0.17066279019288416 + 0j), + "IIZIIIIIIZ": (0.19577211156187402 + 0j), + "IIZIIZIIII": (0.220702612028004 + 0j), + "IIZIZIIIII": (0.10245792602520705 + 0j), + "IIZZIIIIII": (0.10964094999478652 + 0j), + "IZIIIIIIII": (0.2601827946303151 + 0j), + "IZIIIIIIIZ": (0.1060269619647709 + 0j), + "IZIIIZIIII": (0.21982388480817722 + 0j), + "IZIIZIIIII": (0.09485326000745692 + 0j), + "IZIZIIIIII": (0.1112840228980842 + 0j), + "IZZIIIIIII": (0.08389584977571822 + 0j), + "IZZIZZIIIZ": (-0.14917151435431195 + 0j), + "ZIIIIIIIII": (0.2601827946303149 + 0j), + "ZIIIIIIIIZ": (0.11944056365665429 + 0j), + "ZIIIIZIIII": (0.21982388480817722 + 0j), + "ZIIIZIIIII": (0.1112840228980842 + 0j), + "ZIIZIIIIII": (0.09485326000745692 + 0j), + "ZIZIIIIIII": (0.12042746433351019 + 0j), + "ZIZZIZIIIZ": (-0.14917151435431195 + 0j), + "ZZIIIIIIII": (0.12244309127472158 + 0j), + "IIZZZIXIXZ": (-0.0023524442663984376 + 0j), + "ZIZIZZXIXZ": (0.0023524442663984376 + 0j), + "ZIYIZZIXIY": (0.0023524442663984376 + 0j), + "ZZYIIIIXIY": (-0.0023524442663984376 + 0j), + } + ) H_noncon_obj = NoncontextualOp.from_PauliwordOp(H_noncon) assert H_noncon.n_terms == H_noncon_obj.n_terms + #################################### # Testing noncontextual optimizers # #################################### + def test_noncontextual_objective_function(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) H_noncon.symmetry_generators = H_noncon.symmetry_generators.sort() - nu = [1, -1, -1] + nu = [1, -1, -1] e_noncon = H_noncon.get_energy(nu) - assert np.isclose(e_noncon, noncon_problem['E']) + assert np.isclose(e_noncon, noncon_problem["E"]) + def test_solve_brute_force_discrete_no_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - H_noncon.solve(strategy='brute_force', - ref_state=None, - num_anneals=None) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + H_noncon.solve(strategy="brute_force", ref_state=None, num_anneals=None) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) def test_solve_binary_relaxation_no_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - H_noncon.solve(strategy='binary_relaxation', - ref_state=None, - num_anneals=None) - assert noncon_problem['E']<=H_noncon.energy - if not np.isclose(H_noncon.energy, noncon_problem['E']): - warnings.warn('binary relaxation method not finding correct energy') + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + H_noncon.solve(strategy="binary_relaxation", ref_state=None, num_anneals=None) + assert noncon_problem["E"] <= H_noncon.energy + if not np.isclose(H_noncon.energy, noncon_problem["E"]): + warnings.warn("binary relaxation method not finding correct energy") else: - assert np.isclose(H_noncon.energy, noncon_problem['E']) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) def test_solve_brute_force_PUSO_discrete_no_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - H_noncon.solve(strategy='brute_force_PUSO', - ref_state=None, - num_anneals=None) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + H_noncon.solve(strategy="brute_force_PUSO", ref_state=None, num_anneals=None) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) def test_solve_brute_force_QUSO_discrete_no_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - H_noncon.solve(strategy='brute_force_QUSO', - ref_state=None, - num_anneals=None) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + H_noncon.solve(strategy="brute_force_QUSO", ref_state=None, num_anneals=None) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) + def test_solve_annealing_PUSO_discrete_no_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - H_noncon.solve(strategy='annealing_PUSO', - ref_state=None, - num_anneals=1_000) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + H_noncon.solve(strategy="annealing_PUSO", ref_state=None, num_anneals=1_000) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) def test_solve_annealing_QUSO_discrete_no_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - H_noncon.solve(strategy='annealing_QUSO', - ref_state=None, - num_anneals=1_000) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + H_noncon.solve(strategy="annealing_QUSO", ref_state=None, num_anneals=1_000) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) def test_solve_full_reference_state(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - reference = noncon_problem['reference_state'] + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + reference = noncon_problem["reference_state"] - H_noncon.solve(strategy='brute_force', - ref_state=reference, - num_anneals=None) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon.solve(strategy="brute_force", ref_state=reference, num_anneals=None) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) def test_solve_brute_force_discrete_partial_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - partial_reference_state = noncon_problem['partial_reference_state'] + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + partial_reference_state = noncon_problem["partial_reference_state"] with pytest.warns(): # capture warning when Z stabilizers measured give zero expec value - H_noncon.solve(strategy='brute_force', - ref_state=partial_reference_state, - num_anneals=None) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon.solve( + strategy="brute_force", ref_state=partial_reference_state, num_anneals=None + ) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) # def test_solve_binary_relaxation_partial_ref(): @@ -339,55 +368,64 @@ def test_solve_brute_force_discrete_partial_ref(): def test_solve_brute_force_PUSO_discrete_partial_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - partial_reference_state = noncon_problem['partial_reference_state'] + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + partial_reference_state = noncon_problem["partial_reference_state"] with pytest.warns(): # capture warning when Z stabilizers measured give zero expec value - H_noncon.solve(strategy='brute_force_PUSO', - ref_state=partial_reference_state, - num_anneals=None) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon.solve( + strategy="brute_force_PUSO", + ref_state=partial_reference_state, + num_anneals=None, + ) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) def test_solve_brute_force_QUSO_discrete_partial_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - partial_reference_state = noncon_problem['partial_reference_state'] + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + partial_reference_state = noncon_problem["partial_reference_state"] with pytest.warns(): # capture warning when Z stabilizers measured give zero expec value - H_noncon.solve(strategy='brute_force_QUSO', - ref_state=partial_reference_state, - num_anneals=None) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon.solve( + strategy="brute_force_QUSO", + ref_state=partial_reference_state, + num_anneals=None, + ) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) def test_solve_annealing_PUSO_discrete_partial_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - partial_reference_state = noncon_problem['partial_reference_state'] + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + partial_reference_state = noncon_problem["partial_reference_state"] with pytest.warns(): # capture warning when Z stabilizers measured give zero expec value - H_noncon.solve(strategy='annealing_PUSO', - ref_state=partial_reference_state, - num_anneals=1_000) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon.solve( + strategy="annealing_PUSO", + ref_state=partial_reference_state, + num_anneals=1_000, + ) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) def test_solve_annealing_QUSO_discrete_partial_ref(): - H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - - partial_reference_state = noncon_problem['partial_reference_state'] + H_noncon = NoncontextualOp.from_dictionary(noncon_problem["H_dict"]) + + partial_reference_state = noncon_problem["partial_reference_state"] with pytest.warns(): # capture warning when Z stabilizers measured give zero expec value - H_noncon.solve(strategy='annealing_QUSO', - ref_state=partial_reference_state, - num_anneals=1_000) - assert np.isclose(H_noncon.energy, noncon_problem['E']) + H_noncon.solve( + strategy="annealing_QUSO", + ref_state=partial_reference_state, + num_anneals=1_000, + ) + assert np.isclose(H_noncon.energy, noncon_problem["E"]) + def test_init_Hnoncon1(): """ @@ -407,7 +445,7 @@ def test_init_Hnoncon1(): # checks qaoa qubo with no reference state (compare exact brute force approach) # """ # H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - + # QAOA_dict = H_noncon.get_qaoa(ref_state=None, type='qubo') # for key in QAOA_dict.keys(): @@ -498,7 +536,7 @@ def test_init_Hnoncon1(): # checks qaoa pubo with no reference state (compare exact brute force approach) # """ # H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) - + # QAOA_dict = H_noncon.get_qaoa(ref_state=None, type='pubo') # for key in QAOA_dict.keys(): @@ -590,4 +628,4 @@ def test_init_Hnoncon1(): # """ # H_noncon = NoncontextualOp.from_dictionary(noncon_problem['H_dict']) # with pytest.raises(AssertionError): -# H_noncon.get_qaoa(type='INCORRECT_STRING') \ No newline at end of file +# H_noncon.get_qaoa(type='INCORRECT_STRING') diff --git a/tests/test_operators/test_symplectic_form.py b/tests/test_operators/test_symplectic_form.py index f64074c..3f7aec6 100644 --- a/tests/test_operators/test_symplectic_form.py +++ b/tests/test_operators/test_symplectic_form.py @@ -1,10 +1,13 @@ from symmer.operators import symplectic_to_string import numpy as np + def test_symplectic_to_string(): - I_term = np.array([0,0]) - assert(symplectic_to_string(I_term) == 'I'), 'identity term not identified' + I_term = np.array([0, 0]) + assert symplectic_to_string(I_term) == "I", "identity term not identified" - IXYZ_term = np.array([0,1,1,0,0,0,1,1]) - assert(symplectic_to_string(IXYZ_term) == 'IXYZ'), 'Pauliword not correctly translated' \ No newline at end of file + IXYZ_term = np.array([0, 1, 1, 0, 0, 0, 1, 1]) + assert ( + symplectic_to_string(IXYZ_term) == "IXYZ" + ), "Pauliword not correctly translated" diff --git a/tests/test_projection/test_contextual_subspace.py b/tests/test_projection/test_contextual_subspace.py index 8449a21..6224224 100644 --- a/tests/test_projection/test_contextual_subspace.py +++ b/tests/test_projection/test_contextual_subspace.py @@ -10,59 +10,73 @@ from symmer.utils import exact_gs_energy test_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -ham_data_dir = os.path.join(test_dir, 'hamiltonian_data') +ham_data_dir = os.path.join(test_dir, "hamiltonian_data") -with open(os.path.join(ham_data_dir, 'Be_STO-3G_SINGLET_JW.json'), 'r') as f: +with open(os.path.join(ham_data_dir, "Be_STO-3G_SINGLET_JW.json"), "r") as f: H_data = json.load(f) -hf_energy = H_data['data']['calculated_properties']['HF']['energy'] -fci_energy = H_data['data']['calculated_properties']['FCI']['energy'] -H_op = PauliwordOp.from_dictionary(H_data['hamiltonian']) -CC_op = PauliwordOp.from_dictionary(H_data['data']['auxiliary_operators']['UCCSD_operator']) +hf_energy = H_data["data"]["calculated_properties"]["HF"]["energy"] +fci_energy = H_data["data"]["calculated_properties"]["FCI"]["energy"] +H_op = PauliwordOp.from_dictionary(H_data["hamiltonian"]) +CC_op = PauliwordOp.from_dictionary( + H_data["data"]["auxiliary_operators"]["UCCSD_operator"] +) QT = QubitTapering(H_op) -H_taper = QT.taper_it(ref_state=H_data['data']['hf_array']) +H_taper = QT.taper_it(ref_state=H_data["data"]["hf_array"]) CC_taper = QT.taper_it(aux_operator=CC_op) + def test_noncontextual_operator(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='SingleSweep_magnitude') + CS = ContextualSubspace(H_taper, noncontextual_strategy="SingleSweep_magnitude") assert CS.noncontextual_operator.is_noncontextual assert not CS.contextual_operator.is_noncontextual + def test_random_stabilizers(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='SingleSweep_magnitude') - CS.update_stabilizers(3, strategy='random') + CS = ContextualSubspace(H_taper, noncontextual_strategy="SingleSweep_magnitude") + CS.update_stabilizers(3, strategy="random") H_cs = CS.project_onto_subspace() assert CS.n_qubits_in_subspace == 3 assert H_cs.n_qubits == 3 + def test_noncontextual_ground_state(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='SingleSweep_magnitude') + CS = ContextualSubspace(H_taper, noncontextual_strategy="SingleSweep_magnitude") assert np.isclose(CS.noncontextual_operator.energy, hf_energy) + def test_manual_stabilizers(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='SingleSweep_magnitude') - G = IndependentOp.from_list(['ZIZZZ', 'IZZZZ']) + CS = ContextualSubspace(H_taper, noncontextual_strategy="SingleSweep_magnitude") + G = IndependentOp.from_list(["ZIZZZ", "IZZZZ"]) CS.manual_stabilizers(G) H_cs = CS.project_onto_subspace() assert CS.n_qubits_in_subspace == 3 assert H_cs.n_qubits == 3 assert abs(exact_gs_energy(H_cs.to_sparse_matrix)[0] - fci_energy) < 0.0004 - + + def test_update_stabilizers_aux_preserving(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='SingleSweep_magnitude') - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='aux_preserving') + CS = ContextualSubspace(H_taper, noncontextual_strategy="SingleSweep_magnitude") + CS.update_stabilizers(3, aux_operator=CC_taper, strategy="aux_preserving") H_cs = CS.project_onto_subspace() assert CS.n_qubits_in_subspace == 3 assert H_cs.n_qubits == 3 assert abs(exact_gs_energy(H_cs.to_sparse_matrix)[0] - fci_energy) < 0.0004 + def test_update_stabilizers_unrecognised_strategy(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='SingleSweep_magnitude') + CS = ContextualSubspace(H_taper, noncontextual_strategy="SingleSweep_magnitude") with pytest.raises(ValueError): - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='symmer') + CS.update_stabilizers(3, aux_operator=CC_taper, strategy="symmer") + def test_update_stabilizers_HOMO_LUMO_biasing(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='SingleSweep_magnitude') - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='HOMO_LUMO_biasing', HF_array=QT.tapered_ref_state.state_matrix) + CS = ContextualSubspace(H_taper, noncontextual_strategy="SingleSweep_magnitude") + CS.update_stabilizers( + 3, + aux_operator=CC_taper, + strategy="HOMO_LUMO_biasing", + HF_array=QT.tapered_ref_state.state_matrix, + ) H_cs = CS.project_onto_subspace() assert CS.n_qubits_in_subspace == 3 assert H_cs.n_qubits == 3 @@ -78,82 +92,110 @@ def test_update_stabilizers_HOMO_LUMO_biasing(): # samples = pool.map(func, range(10)) for _ in range(10): - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='HOMO_LUMO_biasing', - HF_array=QT.tapered_ref_state.state_matrix) - samples.append(abs(exact_gs_energy(CS.project_onto_subspace().to_sparse_matrix)[0] - fci_energy)) + CS.update_stabilizers( + 3, + aux_operator=CC_taper, + strategy="HOMO_LUMO_biasing", + HF_array=QT.tapered_ref_state.state_matrix, + ) + samples.append( + abs( + exact_gs_energy(CS.project_onto_subspace().to_sparse_matrix)[0] + - fci_energy + ) + ) assert min(samples) < 0.004 + def test_StabilizeFirst_strategy_correct_usage(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='StabilizeFirst') - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='aux_preserving') + CS = ContextualSubspace(H_taper, noncontextual_strategy="StabilizeFirst") + CS.update_stabilizers(3, aux_operator=CC_taper, strategy="aux_preserving") H_cs = CS.project_onto_subspace() assert H_cs.n_qubits == 3 assert abs(exact_gs_energy(H_cs.to_sparse_matrix)[0] - fci_energy) < 0.0004 -@pytest.mark.parametrize("ref_state", [QT.tapered_ref_state, QT.tapered_ref_state.state_matrix[0]]) + +@pytest.mark.parametrize( + "ref_state", [QT.tapered_ref_state, QT.tapered_ref_state.state_matrix[0]] +) def test_reference_state(ref_state): CS = ContextualSubspace( - H_taper, noncontextual_strategy='StabilizeFirst', - reference_state=ref_state + H_taper, noncontextual_strategy="StabilizeFirst", reference_state=ref_state ) - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='aux_preserving') + CS.update_stabilizers(3, aux_operator=CC_taper, strategy="aux_preserving") H_cs = CS.project_onto_subspace() assert H_cs.n_qubits == 3 assert abs(exact_gs_energy(H_cs.to_sparse_matrix)[0] - fci_energy) < 0.0004 + def test_StabilizeFirst_strategy_correct_usage(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='StabilizeFirst') - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='aux_preserving') + CS = ContextualSubspace(H_taper, noncontextual_strategy="StabilizeFirst") + CS.update_stabilizers(3, aux_operator=CC_taper, strategy="aux_preserving") H_cs = CS.project_onto_subspace() assert H_cs.n_qubits == 3 assert abs(exact_gs_energy(H_cs.to_sparse_matrix)[0] - fci_energy) < 0.0004 + def test_project_auxiliary_operator(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='SingleSweep_magnitude') - G = IndependentOp.from_list(['ZIZZZ', 'IZZZZ']) + CS = ContextualSubspace(H_taper, noncontextual_strategy="SingleSweep_magnitude") + G = IndependentOp.from_list(["ZIZZZ", "IZZZZ"]) CS.manual_stabilizers(G) H_cs = CS.project_onto_subspace() CC_cs = CS.project_onto_subspace(operator_to_project=CC_taper) assert CC_cs.n_qubits == 3 - assert abs(H_cs.expval(trotter(CC_cs*1j, trotnum=10) * QuantumState([0,0,0])) - fci_energy) < 0.0004 + assert ( + abs( + H_cs.expval(trotter(CC_cs * 1j, trotnum=10) * QuantumState([0, 0, 0])) + - fci_energy + ) + < 0.0004 + ) + def test_no_aux_operator_provided(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='SingleSweep_magnitude') - CS.update_stabilizers(3, aux_operator=None, strategy='aux_preserving') + CS = ContextualSubspace(H_taper, noncontextual_strategy="SingleSweep_magnitude") + CS.update_stabilizers(3, aux_operator=None, strategy="aux_preserving") + def test_StabilizeFirst_no_aux_operator_provided(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='StabilizeFirst') - CS.update_stabilizers(3, aux_operator=None, strategy='aux_preserving') + CS = ContextualSubspace(H_taper, noncontextual_strategy="StabilizeFirst") + CS.update_stabilizers(3, aux_operator=None, strategy="aux_preserving") + def test_operator_already_noncontextual(): with pytest.raises(ValueError): CS = ContextualSubspace(NoncontextualOp.from_hamiltonian(H_taper)) -@pytest.mark.parametrize("up_method", ['LCU', 'seq_rot']) + +@pytest.mark.parametrize("up_method", ["LCU", "seq_rot"]) def test_unitary_partitioning_method(up_method): CS = ContextualSubspace( - H_taper, noncontextual_strategy='SingleSweep_magnitude', - unitary_partitioning_method=up_method + H_taper, + noncontextual_strategy="SingleSweep_magnitude", + unitary_partitioning_method=up_method, ) - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='aux_preserving') + CS.update_stabilizers(3, aux_operator=CC_taper, strategy="aux_preserving") H_cs = CS.project_onto_subspace() assert H_cs.n_qubits == 3 assert abs(exact_gs_energy(H_cs.to_sparse_matrix)[0] - fci_energy) < 0.0004 -@pytest.mark.parametrize("up_method", ['LCU', 'seq_rot']) + +@pytest.mark.parametrize("up_method", ["LCU", "seq_rot"]) def test_project_state_onto_subspace(up_method): CS = ContextualSubspace( - H_taper, noncontextual_strategy='SingleSweep_magnitude', - unitary_partitioning_method=up_method + H_taper, + noncontextual_strategy="SingleSweep_magnitude", + unitary_partitioning_method=up_method, ) - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='aux_preserving') + CS.update_stabilizers(3, aux_operator=CC_taper, strategy="aux_preserving") CS.project_onto_subspace() projected_state = CS.project_state_onto_subspace(QT.tapered_ref_state) - assert projected_state == QuantumState([[0,0,0]], [1]) + assert projected_state == QuantumState([[0, 0, 0]], [1]) + def test_project_state_onto_subspace_before_operator(): - CS = ContextualSubspace(H_taper, noncontextual_strategy='StabilizeFirst') - CS.update_stabilizers(3, aux_operator=CC_taper, strategy='aux_preserving') + CS = ContextualSubspace(H_taper, noncontextual_strategy="StabilizeFirst") + CS.update_stabilizers(3, aux_operator=CC_taper, strategy="aux_preserving") with pytest.raises(AssertionError): - CS.project_state_onto_subspace(QT.tapered_ref_state) \ No newline at end of file + CS.project_state_onto_subspace(QT.tapered_ref_state) diff --git a/tests/test_projection/test_qubit_subspace_manager.py b/tests/test_projection/test_qubit_subspace_manager.py index 9f34943..fc66d82 100644 --- a/tests/test_projection/test_qubit_subspace_manager.py +++ b/tests/test_projection/test_qubit_subspace_manager.py @@ -7,70 +7,90 @@ from symmer.utils import exact_gs_energy test_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -ham_data_dir = os.path.join(test_dir, 'hamiltonian_data') +ham_data_dir = os.path.join(test_dir, "hamiltonian_data") -with open(os.path.join(ham_data_dir, 'Be_STO-3G_SINGLET_JW.json'), 'r') as f: +with open(os.path.join(ham_data_dir, "Be_STO-3G_SINGLET_JW.json"), "r") as f: H_data = json.load(f) -hf_energy = H_data['data']['calculated_properties']['HF']['energy'] -fci_energy = H_data['data']['calculated_properties']['FCI']['energy'] -H_op = PauliwordOp.from_dictionary(H_data['hamiltonian']) -CC_op = PauliwordOp.from_dictionary(H_data['data']['auxiliary_operators']['UCCSD_operator']) -HF_state = QuantumState(H_data['data']['hf_array']) +hf_energy = H_data["data"]["calculated_properties"]["HF"]["energy"] +fci_energy = H_data["data"]["calculated_properties"]["FCI"]["energy"] +H_op = PauliwordOp.from_dictionary(H_data["hamiltonian"]) +CC_op = PauliwordOp.from_dictionary( + H_data["data"]["auxiliary_operators"]["UCCSD_operator"] +) +HF_state = QuantumState(H_data["data"]["hf_array"]) + def test_correct_qubit_numbers(): QSM = QubitSubspaceManager(hamiltonian=H_op, ref_state=HF_state) - for n_qubits in range(1, H_op.n_qubits+1): - H_reduced = QSM.get_reduced_hamiltonian(n_qubits, aux_operator=CC_op) + for n_qubits in range(1, H_op.n_qubits + 1): + H_reduced = QSM.get_reduced_hamiltonian(n_qubits, aux_operator=CC_op) CC_reduced = QSM.project_auxiliary_operator(CC_op) HF_reduced = QSM.project_auxiliary_state(HF_state) - assert H_reduced.n_qubits == n_qubits + assert H_reduced.n_qubits == n_qubits assert CC_reduced.n_qubits == n_qubits assert HF_reduced.n_qubits == n_qubits + def test_correct_qubit_numbers_no_tapering(): - QSM = QubitSubspaceManager(hamiltonian=H_op, ref_state=HF_state, run_qubit_tapering=False) - for n_qubits in range(1, H_op.n_qubits-4): - H_reduced = QSM.get_reduced_hamiltonian(n_qubits, aux_operator=CC_op) + QSM = QubitSubspaceManager( + hamiltonian=H_op, ref_state=HF_state, run_qubit_tapering=False + ) + for n_qubits in range(1, H_op.n_qubits - 4): + H_reduced = QSM.get_reduced_hamiltonian(n_qubits, aux_operator=CC_op) CC_reduced = QSM.project_auxiliary_operator(CC_op) HF_reduced = QSM.project_auxiliary_state(HF_state) - assert H_reduced.n_qubits == n_qubits + assert H_reduced.n_qubits == n_qubits assert CC_reduced.n_qubits == n_qubits assert HF_reduced.n_qubits == n_qubits + def test_no_contextual_subspace(): - QSM = QubitSubspaceManager(hamiltonian=H_op, ref_state=HF_state, - run_contextual_subspace=False, run_qubit_tapering=True) + QSM = QubitSubspaceManager( + hamiltonian=H_op, + ref_state=HF_state, + run_contextual_subspace=False, + run_qubit_tapering=True, + ) with pytest.warns(): H_reduced = QSM.get_reduced_hamiltonian(3) assert H_reduced.n_qubits == QSM._hamiltonian.n_qubits + def test_no_subspace_methods(): - QSM = QubitSubspaceManager(hamiltonian=H_op, ref_state=HF_state, - run_contextual_subspace=False, run_qubit_tapering=False) + QSM = QubitSubspaceManager( + hamiltonian=H_op, + ref_state=HF_state, + run_contextual_subspace=False, + run_qubit_tapering=False, + ) with pytest.warns(): H_reduced = QSM.get_reduced_hamiltonian(3) assert H_reduced.n_qubits == QSM._hamiltonian.n_qubits + def test_too_many_qubits(): QSM = QubitSubspaceManager(hamiltonian=H_op, ref_state=HF_state) with pytest.warns(): H_reduced = QSM.get_reduced_hamiltonian(15) assert H_reduced.n_qubits == QSM.hamiltonian.n_qubits + def test_subspace_errors(): errors = [0.031, 0.015, 0.00035, 0.0002, 1e-12, 1e-12, 1e-12, 1e-12, 1e-12, 1e-12] QSM = QubitSubspaceManager(hamiltonian=H_op, ref_state=HF_state) - for index, n_qubits in enumerate(range(1, H_op.n_qubits+1)): - H_reduced = QSM.get_reduced_hamiltonian(n_qubits, aux_operator=CC_op) - cs_error = abs(exact_gs_energy(H_reduced.to_sparse_matrix)[0]- fci_energy) + for index, n_qubits in enumerate(range(1, H_op.n_qubits + 1)): + H_reduced = QSM.get_reduced_hamiltonian(n_qubits, aux_operator=CC_op) + cs_error = abs(exact_gs_energy(H_reduced.to_sparse_matrix)[0] - fci_energy) assert cs_error < errors[index] + def test_return_noncontextual_energy(): QSM = QubitSubspaceManager(hamiltonian=H_op, ref_state=HF_state) H_reduced = QSM.get_reduced_hamiltonian(0, aux_operator=CC_op) assert isinstance(H_reduced, Number) assert H_reduced < hf_energy and H_reduced > fci_energy + def test_no_input_ref_state(): with pytest.warns(): QSM = QubitSubspaceManager(hamiltonian=H_op) diff --git a/tests/test_projection/test_qubit_tapering.py b/tests/test_projection/test_qubit_tapering.py index f5c7e29..84ef649 100644 --- a/tests/test_projection/test_qubit_tapering.py +++ b/tests/test_projection/test_qubit_tapering.py @@ -7,79 +7,83 @@ H2_op = PauliwordOp.from_dictionary( { - 'IIII': (-0.05933866442819677+0j), - 'IIIZ': (-0.23676939575319134+0j), - 'IIZI': (-0.23676939575319134+0j), - 'IIZZ': (0.17571274411978302+0j), - 'IZII': (0.17579122569046912+0j), - 'IZIZ': (0.12223870791335416+0j), - 'IZZI': (0.16715312911492025+0j), - 'ZIII': (0.17579122569046912+0j), - 'ZIIZ': (0.16715312911492025+0j), - 'ZIZI': (0.12223870791335416+0j), - 'ZZII': (0.17002500620877006+0j), - 'XXYY': (-0.044914421201566114+0j), - 'XYYX': (0.044914421201566114+0j), - 'YXXY': (0.044914421201566114+0j), - 'YYXX': (-0.044914421201566114+0j) + "IIII": (-0.05933866442819677 + 0j), + "IIIZ": (-0.23676939575319134 + 0j), + "IIZI": (-0.23676939575319134 + 0j), + "IIZZ": (0.17571274411978302 + 0j), + "IZII": (0.17579122569046912 + 0j), + "IZIZ": (0.12223870791335416 + 0j), + "IZZI": (0.16715312911492025 + 0j), + "ZIII": (0.17579122569046912 + 0j), + "ZIIZ": (0.16715312911492025 + 0j), + "ZIZI": (0.12223870791335416 + 0j), + "ZZII": (0.17002500620877006 + 0j), + "XXYY": (-0.044914421201566114 + 0j), + "XYYX": (0.044914421201566114 + 0j), + "YXXY": (0.044914421201566114 + 0j), + "YYXX": (-0.044914421201566114 + 0j), } ) CC_op = PauliwordOp.from_dictionary( { - 'XXXX': (-0.006725473252131252+0j), - 'XXXY': 0.006725473252131252j, - 'XXYX': 0.006725473252131252j, - 'XXYY': (0.006725473252131252+0j), - 'XYXX': -0.006725473252131252j, - 'XYXY': (-0.006725473252131252+0j), - 'XYYX': (-0.006725473252131252+0j), - 'XYYY': 0.006725473252131252j, - 'YXXX': -0.006725473252131252j, - 'YXXY': (-0.006725473252131252+0j), - 'YXYX': (-0.006725473252131252+0j), - 'YXYY': 0.006725473252131252j, - 'YYXX': (0.006725473252131252+0j), - 'YYXY': -0.006725473252131252j, - 'YYYX': -0.006725473252131252j, - 'YYYY': (-0.006725473252131252+0j) + "XXXX": (-0.006725473252131252 + 0j), + "XXXY": 0.006725473252131252j, + "XXYX": 0.006725473252131252j, + "XXYY": (0.006725473252131252 + 0j), + "XYXX": -0.006725473252131252j, + "XYXY": (-0.006725473252131252 + 0j), + "XYYX": (-0.006725473252131252 + 0j), + "XYYY": 0.006725473252131252j, + "YXXX": -0.006725473252131252j, + "YXXY": (-0.006725473252131252 + 0j), + "YXYX": (-0.006725473252131252 + 0j), + "YXYY": 0.006725473252131252j, + "YYXX": (0.006725473252131252 + 0j), + "YYXY": -0.006725473252131252j, + "YYYX": -0.006725473252131252j, + "YYYY": (-0.006725473252131252 + 0j), } ) -hf_energy = -1.117505831043514 +hf_energy = -1.117505831043514 ccsd_energy = -1.1368383583027837 -fci_energy = -1.1368382276023516 +fci_energy = -1.1368382276023516 hf_state = QuantumState([1, 1, 0, 0]) ccsd_state = trotter(CC_op, trotnum=20) * hf_state QT = QubitTapering(H2_op) + def test_init(): - assert QT.operator==H2_op - assert QT.n_taper ==3 + assert QT.operator == H2_op + assert QT.n_taper == 3 + def test_symmetry_generators_H2(): G1 = QT.symmetry_generators - G2 = IndependentOp.from_list(['ZIZI', 'IZIZ', 'IIZZ']) - assert ( - np.all(G1.generator_reconstruction(G2)[1]) and - np.all(G2.generator_reconstruction(G1)[1]) + G2 = IndependentOp.from_list(["ZIZI", "IZIZ", "IIZZ"]) + assert np.all(G1.generator_reconstruction(G2)[1]) and np.all( + G2.generator_reconstruction(G1)[1] ) + def test_taper_H2_hamiltonian(): H2_taper = QT.taper_it(ref_state=hf_state) assert H2_taper.n_qubits == 1 assert np.isclose(exact_gs_energy(H2_taper.to_sparse_matrix)[0], fci_energy) + def test_change_number_of_stabilizers(): - QT.symmetry_generators = IndependentOp.from_list(['ZIZI', 'IZIZ']) + QT.symmetry_generators = IndependentOp.from_list(["ZIZI", "IZIZ"]) with pytest.warns(): H2_taper = QT.taper_it(ref_state=hf_state) assert H2_taper.n_qubits == 2 assert np.isclose(exact_gs_energy(H2_taper.to_sparse_matrix)[0], fci_energy) + def test_reference_state_projection(): H2_taper = QT.taper_it(ref_state=hf_state) hf_taper = QT.project_state(hf_state) ccsd_taper = QT.project_state(ccsd_state) - assert np.isclose(hf_state.dagger * H2_op * hf_state, hf_energy) - assert np.isclose(hf_state.dagger * H2_op * ccsd_state, ccsd_energy) - assert np.isclose(hf_taper.dagger * H2_taper * hf_taper, hf_energy) - assert np.isclose(hf_taper.dagger * H2_taper * ccsd_taper, ccsd_energy) \ No newline at end of file + assert np.isclose(hf_state.dagger * H2_op * hf_state, hf_energy) + assert np.isclose(hf_state.dagger * H2_op * ccsd_state, ccsd_energy) + assert np.isclose(hf_taper.dagger * H2_taper * hf_taper, hf_energy) + assert np.isclose(hf_taper.dagger * H2_taper * ccsd_taper, ccsd_energy) diff --git a/tests/test_projection/test_utils.py b/tests/test_projection/test_utils.py index b58d244..057b3d0 100644 --- a/tests/test_projection/test_utils.py +++ b/tests/test_projection/test_utils.py @@ -7,57 +7,68 @@ from symmer.operators import PauliwordOp, IndependentOp test_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -ham_data_dir = os.path.join(test_dir, 'hamiltonian_data') +ham_data_dir = os.path.join(test_dir, "hamiltonian_data") -with open(os.path.join(ham_data_dir, 'Be_STO-3G_SINGLET_JW.json'), 'r') as f: +with open(os.path.join(ham_data_dir, "Be_STO-3G_SINGLET_JW.json"), "r") as f: H_data = json.load(f) -H_op = PauliwordOp.from_dictionary(H_data['hamiltonian']) -CC_op = PauliwordOp.from_dictionary(H_data['data']['auxiliary_operators']['UCCSD_operator']) +H_op = PauliwordOp.from_dictionary(H_data["hamiltonian"]) +CC_op = PauliwordOp.from_dictionary( + H_data["data"]["auxiliary_operators"]["UCCSD_operator"] +) QT = QubitTapering(H_op) -H_taper = QT.taper_it(ref_state=H_data['data']['hf_array']) +H_taper = QT.taper_it(ref_state=H_data["data"]["hf_array"]) CC_taper = QT.taper_it(aux_operator=CC_op) + def test_norm(): arr = np.random.random(100) assert np.isclose(np.linalg.norm(arr), norm(arr)) + def test_lp_norm(): arr = np.random.random(100) p = np.random.randint(1, 10) - assert np.isclose(np.linalg.norm(arr, ord=p), lp_norm(arr, p=p)) + assert np.isclose(np.linalg.norm(arr, ord=p), lp_norm(arr, p=p)) + def test_update_eigenvalues_insufficient_generators(): - G1 = IndependentOp.from_list(['IZ', 'ZI']) - G2 = IndependentOp.from_list(['ZZ', 'XX']) + G1 = IndependentOp.from_list(["IZ", "ZI"]) + G2 = IndependentOp.from_list(["ZZ", "XX"]) with pytest.raises(ValueError): update_eigenvalues(G1, G2) + def test_update_eigenvalues_correct_usage(): - G1 = IndependentOp.from_dictionary({'ZII':-1, 'ZZI':1, 'IZZ':-1}) - G2 = IndependentOp.from_list(['ZZZ', 'IIZ', 'ZIZ']) + G1 = IndependentOp.from_dictionary({"ZII": -1, "ZZI": 1, "IZZ": -1}) + G2 = IndependentOp.from_list(["ZZZ", "IIZ", "ZIZ"]) update_eigenvalues(generators=G1, stabilizers=G2) assert np.all(G2.coeff_vec == np.array([+1, +1, -1])) + def test_basis_weighting(): - weighting_operator = PauliwordOp.from_list(['XYZX', 'YYYY', 'ZZZZ', 'IXZX', 'YXZI']) - SI = StabilizerIdentification(weighting_operator=weighting_operator, use_X_only=True) + weighting_operator = PauliwordOp.from_list(["XYZX", "YYYY", "ZZZZ", "IXZX", "YXZI"]) + SI = StabilizerIdentification( + weighting_operator=weighting_operator, use_X_only=True + ) assert SI.basis_weighting == PauliwordOp.from_list( - ['XXIX', 'XXXX', 'IIII', 'IXIX', 'XXII'] + ["XXIX", "XXXX", "IIII", "IXIX", "XXII"] ) + def test_symmetry_generators_by_term_significance(): SI = StabilizerIdentification(weighting_operator=CC_taper, use_X_only=True) G = SI.symmetry_generators_by_term_significance(n_preserved=4) - assert G == IndependentOp.from_list(['IZZZZ']) + assert G == IndependentOp.from_list(["IZZZZ"]) + def symmetry_generators_by_subspace_dimension(): SI = StabilizerIdentification(weighting_operator=CC_taper, use_X_only=True) G = SI.symmetry_generators_by_subspace_dimension(n_sim_qubits=3) - assert G == IndependentOp.from_list(['ZIZZZ', 'IZZZZ']) + assert G == IndependentOp.from_list(["ZIZZZ", "IZZZZ"]) + def symmetry_generators_by_subspace_dimension_sweep(): SI = StabilizerIdentification(weighting_operator=CC_taper) for n_q in range(6): G = SI.symmetry_generators_by_subspace_dimension(n_sim_qubits=n_q) assert n_q == H_taper.n_qubits - G.n_terms - diff --git a/tests/test_symmer_utils.py b/tests/test_symmer_utils.py index 5260112..02cc67a 100644 --- a/tests/test_symmer_utils.py +++ b/tests/test_symmer_utils.py @@ -1,343 +1,386 @@ from symmer.operators import PauliwordOp, QuantumState -from symmer.utils import (exact_gs_energy, random_anitcomm_2n_1_PauliwordOp,Draw_molecule, - tensor_list, gram_schmidt_from_quantum_state, product_list, - get_sparse_matrix_large_pauliwordop, matrix_allclose) +from symmer.utils import ( + exact_gs_energy, + random_anitcomm_2n_1_PauliwordOp, + Draw_molecule, + tensor_list, + gram_schmidt_from_quantum_state, + product_list, + get_sparse_matrix_large_pauliwordop, + matrix_allclose, +) import numpy as np from openfermion import QubitOperator import py3Dmol -H2_sto3g = {'qubit_encoding': 'jordan_wigner', - 'unit': 'angstrom', - 'geometry': '2\n \nH\t0\t0\t0\nH\t0\t0\t0.74', - 'basis': 'STO-3G', - 'charge': 0, - 'spin': 0, - 'hf_array': [1, 1, 0, 0], - 'hf_method': 'pyscf.scf.hf_symm.SymAdaptedRHF', - 'n_particles': {'total': 2, 'alpha': 1, 'beta': 1}, - 'n_qubits': 4, - 'convergence_threshold': 1e-06, - 'point_group': {'groupname': 'Dooh', 'topgroup': 'Dooh'}, - 'calculated_properties': {'HF': {'energy': -1.1167593073964255, - 'converged': True}, - 'MP2': {'energy': -1.1298973809859585, 'converged': True}, - 'CCSD': {'energy': -1.13728399861044, 'converged': True}, - 'FCI': {'energy': -1.137283834488502, 'converged': True}}, - 'auxiliary_operators': {'number_operator': {'IIII': (2.0, 0.0), - 'IIIZ': (-0.5, 0.0), - 'IIZI': (-0.5, 0.0), - 'IZII': (-0.5, 0.0), - 'ZIII': (-0.5, 0.0)}, - 'S^2_operator': {'IIII': (0.75, 0.0), - 'IIIZ': (0.5, 0.0), - 'IIZI': (-0.5, 0.0), - 'IIZZ': (-0.375, 0.0), - 'IZII': (0.5, 0.0), - 'IZIZ': (0.125, 0.0), - 'IZZI': (-0.125, 0.0), - 'ZIII': (-0.5, 0.0), - 'ZIIZ': (-0.125, 0.0), - 'ZIZI': (0.125, 0.0), - 'ZZII': (-0.375, 0.0), - 'XXXX': (0.125, 0.0), - 'XXYY': (0.125, 0.0), - 'XYXY': (0.125, 0.0), - 'XYYX': (-0.125, 0.0), - 'YXXY': (-0.125, 0.0), - 'YXYX': (0.125, 0.0), - 'YYXX': (0.125, 0.0), - 'YYYY': (0.125, 0.0)}, - 'Sz_operator': {'IIIZ': (0.25, 0.0), - 'IIZI': (-0.25, 0.0), - 'IZII': (0.25, 0.0), - 'ZIII': (-0.25, 0.0)}, - 'alpha_parity_operator': {'ZIZI': (1.0, 0.0)}, - 'beta_parity_operator': {'IZIZ': (1.0, 0.0)}, - 'MP2_operator': {'XXXX': (-0.004531358676614097, 0.0), - 'XXXY': (0.0, 0.004531358676614097), - 'XXYX': (0.0, 0.004531358676614097), - 'XXYY': (0.004531358676614097, 0.0), - 'XYXX': (0.0, -0.004531358676614097), - 'XYXY': (-0.004531358676614097, 0.0), - 'XYYX': (-0.004531358676614097, 0.0), - 'XYYY': (0.0, 0.004531358676614097), - 'YXXX': (0.0, -0.004531358676614097), - 'YXXY': (-0.004531358676614097, 0.0), - 'YXYX': (-0.004531358676614097, 0.0), - 'YXYY': (0.0, 0.004531358676614097), - 'YYXX': (0.004531358676614097, 0.0), - 'YYXY': (0.0, -0.004531358676614097), - 'YYYX': (0.0, -0.004531358676614097), - 'YYYY': (-0.004531358676614097, 0.0)}, - 'CCSD_operator': {'XXXX': (-0.007079023951543804, 0.0), - 'XXXY': (0.0, 0.007079023951543804), - 'XXYX': (0.0, 0.007079023951543804), - 'XXYY': (0.007079023951543804, 0.0), - 'XYXX': (0.0, -0.007079023951543804), - 'XYXY': (-0.007079023951543804, 0.0), - 'XYYX': (-0.007079023951543804, 0.0), - 'XYYY': (0.0, 0.007079023951543804), - 'YXXX': (0.0, -0.007079023951543804), - 'YXXY': (-0.007079023951543804, 0.0), - 'YXYX': (-0.007079023951543804, 0.0), - 'YXYY': (0.0, 0.007079023951543804), - 'YYXX': (0.007079023951543804, 0.0), - 'YYXY': (0.0, -0.007079023951543804), - 'YYYX': (0.0, -0.007079023951543804), - 'YYYY': (-0.007079023951543804, 0.0)}}, - 'H_dict': {'IIII': (-0.09706626816763123+0j), - 'IIIZ': (-0.22343153690813441+0j), - 'IIZI': (-0.22343153690813441+0j), - 'IIZZ': (0.17441287612261588+0j), - 'IZII': (0.17141282644776915+0j), - 'IZIZ': (0.12062523483390411+0j), - 'IZZI': (0.1659278503377034+0j), - 'ZIII': (0.17141282644776912+0j), - 'ZIIZ': (0.1659278503377034+0j), - 'ZIZI': (0.12062523483390411+0j), - 'ZZII': (0.16868898170361207+0j), - 'XXYY': (-0.04530261550379927+0j), - 'XYYX': (0.04530261550379927+0j), - 'YXXY': (0.04530261550379927+0j), - 'YYXX': (-0.04530261550379927+0j)}} - -He3_plus = {'qubit_encoding': 'jordan_wigner', - 'unit': 'angstrom', - 'geometry': '3\n \nH\t0\t0\t0\nH\t0\t0\t0.74\nH\t0\t0\t1.48', - 'basis': 'STO-3G', - 'charge': 1, - 'spin': 0, - 'hf_array': [1, 1, 0, 0, 0, 0], - 'hf_method': 'pyscf.scf.hf_symm.SymAdaptedRHF', - 'n_particles': {'total': 2, 'alpha': 1, 'beta': 1}, - 'n_qubits': 6, - 'convergence_threshold': 1e-06, - 'point_group': {'groupname': 'Dooh', 'topgroup': 'Dooh'}, - 'calculated_properties': {'HF': {'energy': -1.189999028637302, - 'converged': True}, - 'MP2': {'energy': -1.206775423813649, 'converged': True}, - 'CCSD': {'energy': -1.214628907244379, 'converged': True}, - 'FCI': {'energy': -1.214628846262647, 'converged': True}}, - 'auxiliary_operators': {'number_operator': {'IIIIII': (3.0, 0.0), - 'IIIIIZ': (-0.5, 0.0), - 'IIIIZI': (-0.5, 0.0), - 'IIIZII': (-0.5, 0.0), - 'IIZIII': (-0.5, 0.0), - 'IZIIII': (-0.5, 0.0), - 'ZIIIII': (-0.5, 0.0)}, - 'S^2_operator': {'IIIIII': (1.125, 0.0), - 'IIIIIZ': (0.5, 0.0), - 'IIIIZI': (-0.5, 0.0), - 'IIIIZZ': (-0.375, 0.0), - 'IIIZII': (0.5, 0.0), - 'IIIZIZ': (0.125, 0.0), - 'IIIZZI': (-0.125, 0.0), - 'IIZIII': (-0.5, 0.0), - 'IIZIIZ': (-0.125, 0.0), - 'IIZIZI': (0.125, 0.0), - 'IIZZII': (-0.375, 0.0), - 'IZIIII': (0.5, 0.0), - 'IZIIIZ': (0.125, 0.0), - 'IZIIZI': (-0.125, 0.0), - 'IZIZII': (0.125, 0.0), - 'IZZIII': (-0.125, 0.0), - 'ZIIIII': (-0.5, 0.0), - 'ZIIIIZ': (-0.125, 0.0), - 'ZIIIZI': (0.125, 0.0), - 'ZIIZII': (-0.125, 0.0), - 'ZIZIII': (0.125, 0.0), - 'ZZIIII': (-0.375, 0.0), - 'IIXXXX': (0.125, 0.0), - 'IIXXYY': (0.125, 0.0), - 'IIXYXY': (0.125, 0.0), - 'IIXYYX': (-0.125, 0.0), - 'IIYXXY': (-0.125, 0.0), - 'IIYXYX': (0.125, 0.0), - 'IIYYXX': (0.125, 0.0), - 'IIYYYY': (0.125, 0.0), - 'XXIIXX': (0.125, 0.0), - 'XXIIYY': (0.125, 0.0), - 'XYIIXY': (0.125, 0.0), - 'XYIIYX': (-0.125, 0.0), - 'YXIIXY': (-0.125, 0.0), - 'YXIIYX': (0.125, 0.0), - 'YYIIXX': (0.125, 0.0), - 'YYIIYY': (0.125, 0.0), - 'XXXXII': (0.125, 0.0), - 'XXYYII': (0.125, 0.0), - 'XYXYII': (0.125, 0.0), - 'XYYXII': (-0.125, 0.0), - 'YXXYII': (-0.125, 0.0), - 'YXYXII': (0.125, 0.0), - 'YYXXII': (0.125, 0.0), - 'YYYYII': (0.125, 0.0)}, - 'Sz_operator': {'IIIIIZ': (0.25, 0.0), - 'IIIIZI': (-0.25, 0.0), - 'IIIZII': (0.25, 0.0), - 'IIZIII': (-0.25, 0.0), - 'IZIIII': (0.25, 0.0), - 'ZIIIII': (-0.25, 0.0)}, - 'alpha_parity_operator': {'ZIZIZI': (1.0, 0.0)}, - 'beta_parity_operator': {'IZIZIZ': (1.0, 0.0)}, - 'MP2_operator': {'XXIIXX': (-0.0022135760877754116, 0.0), - 'XXIIXY': (0.0, 0.0022135760877754116), - 'XXIIYX': (0.0, 0.0022135760877754116), - 'XXIIYY': (0.0022135760877754116, 0.0), - 'XYIIXX': (0.0, -0.0022135760877754116), - 'XYIIXY': (-0.0022135760877754116, 0.0), - 'XYIIYX': (-0.0022135760877754116, 0.0), - 'XYIIYY': (0.0, 0.0022135760877754116), - 'YXIIXX': (0.0, -0.0022135760877754116), - 'YXIIXY': (-0.0022135760877754116, 0.0), - 'YXIIYX': (-0.0022135760877754116, 0.0), - 'YXIIYY': (0.0, 0.0022135760877754116), - 'YYIIXX': (0.0022135760877754116, 0.0), - 'YYIIXY': (0.0, -0.0022135760877754116), - 'YYIIYX': (0.0, -0.0022135760877754116), - 'YYIIYY': (-0.0022135760877754116, 0.0), - 'XXXXII': (-0.005258398458007929, 0.0), - 'XXXYII': (0.0, 0.005258398458007929), - 'XXYXII': (0.0, 0.005258398458007929), - 'XXYYII': (0.005258398458007929, 0.0), - 'XYXXII': (0.0, -0.005258398458007929), - 'XYXYII': (-0.005258398458007929, 0.0), - 'XYYXII': (-0.005258398458007929, 0.0), - 'XYYYII': (0.0, 0.005258398458007929), - 'YXXXII': (0.0, -0.005258398458007929), - 'YXXYII': (-0.005258398458007929, 0.0), - 'YXYXII': (-0.005258398458007929, 0.0), - 'YXYYII': (0.0, 0.005258398458007929), - 'YYXXII': (0.005258398458007929, 0.0), - 'YYXYII': (0.0, -0.005258398458007929), - 'YYYXII': (0.0, -0.005258398458007929), - 'YYYYII': (-0.005258398458007929, 0.0)}, - 'CCSD_operator': {'IXZZZX': (-0.0031353836158880214, 0.0), - 'IXZZZY': (0.0, 0.0031353836158880214), - 'IYZZZX': (0.0, -0.0031353836158880214), - 'IYZZZY': (-0.0031353836158880214, 0.0), - 'XZZZXI': (-0.0031353836158880214, 0.0), - 'XZZZYI': (0.0, 0.0031353836158880214), - 'YZZZXI': (0.0, -0.0031353836158880214), - 'YZZZYI': (-0.0031353836158880214, 0.0), - 'XXIIXX': (-0.0025494280723394984, 0.0), - 'XXIIXY': (0.0, 0.0025494280723394984), - 'XXIIYX': (0.0, 0.0025494280723394984), - 'XXIIYY': (0.0025494280723394984, 0.0), - 'XYIIXX': (0.0, -0.0025494280723394984), - 'XYIIXY': (-0.0025494280723394984, 0.0), - 'XYIIYX': (-0.0025494280723394984, 0.0), - 'XYIIYY': (0.0, 0.0025494280723394984), - 'YXIIXX': (0.0, -0.0025494280723394984), - 'YXIIXY': (-0.0025494280723394984, 0.0), - 'YXIIYX': (-0.0025494280723394984, 0.0), - 'YXIIYY': (0.0, 0.0025494280723394984), - 'YYIIXX': (0.0025494280723394984, 0.0), - 'YYIIXY': (0.0, -0.0025494280723394984), - 'YYIIYX': (0.0, -0.0025494280723394984), - 'YYIIYY': (-0.0025494280723394984, 0.0), - 'XXXXII': (-0.008347686124399265, 0.0), - 'XXXYII': (0.0, 0.008347686124399265), - 'XXYXII': (0.0, 0.008347686124399265), - 'XXYYII': (0.008347686124399265, 0.0), - 'XYXXII': (0.0, -0.008347686124399265), - 'XYXYII': (-0.008347686124399265, 0.0), - 'XYYXII': (-0.008347686124399265, 0.0), - 'XYYYII': (0.0, 0.008347686124399265), - 'YXXXII': (0.0, -0.008347686124399265), - 'YXXYII': (-0.008347686124399265, 0.0), - 'YXYXII': (-0.008347686124399265, 0.0), - 'YXYYII': (0.0, 0.008347686124399265), - 'YYXXII': (0.008347686124399265, 0.0), - 'YYXYII': (0.0, -0.008347686124399265), - 'YYYXII': (0.0, -0.008347686124399265), - 'YYYYII': (-0.008347686124399265, 0.0)}}, - 'H_dict': {'IIIIII': (0.24747487013571695+0j), - 'IIIIIZ': (-0.460046379318107+0j), - 'IIIIZI': (-0.460046379318107+0j), - 'IIIIZZ': (0.17501414371183724+0j), - 'IIIZII': (-0.008325684680054832+0j), - 'IIIZIZ': (0.10794008354812167+0j), - 'IIIZZI': (0.14596700512786398+0j), - 'IIZIII': (-0.008325684680054846+0j), - 'IIZIIZ': (0.14596700512786398+0j), - 'IIZIZI': (0.10794008354812167+0j), - 'IIZZII': (0.1464490594631947+0j), - 'IZIIII': (0.21618381471527337+0j), - 'IZIIIZ': (0.12892083226845963+0j), - 'IZIIZI': (0.16103166954501724+0j), - 'IZIZII': (0.10098551626926347+0j), - 'IZZIII': (0.13731813628698764+0j), - 'ZIIIII': (0.21618381471527337+0j), - 'ZIIIIZ': (0.16103166954501724+0j), - 'ZIIIZI': (0.12892083226845963+0j), - 'ZIIZII': (0.13731813628698764+0j), - 'ZIZIII': (0.10098551626926347+0j), - 'ZZIIII': (0.15887278686630402+0j), - 'IIXXYY': (-0.03802692157974233+0j), - 'IIXYYX': (0.03802692157974233+0j), - 'IIYXXY': (0.03802692157974233+0j), - 'IIYYXX': (-0.03802692157974233+0j), - 'IXIZZX': (0.0035462180491050393+0j), - 'IXZIZX': (-0.029756134618662153+0j), - 'IXZZIX': (-0.024481114159709064+0j), - 'IXZZZX': (0.02373733926074963+0j), - 'IYIZZY': (0.0035462180491050393+0j), - 'IYZIZY': (-0.029756134618662153+0j), - 'IYZZIY': (-0.024481114159709064+0j), - 'IYZZZY': (0.02373733926074963+0j), - 'ZXZZZX': (-0.026953621359169865+0j), - 'ZYZZZY': (-0.026953621359169865+0j), - 'IXXYYI': (0.03330235266776719+0j), - 'IXYYXI': (-0.03330235266776719+0j), - 'IYXXYI': (-0.03330235266776719+0j), - 'IYYXXI': (0.03330235266776719+0j), - 'XIZZXI': (-0.026953621359169868+0j), - 'XZIZXI': (-0.029756134618662153+0j), - 'XZZIXI': (0.0035462180491050393+0j), - 'XZZZXI': (0.023737339260749633+0j), - 'XZZZXZ': (-0.024481114159709064+0j), - 'YIZZYI': (-0.026953621359169868+0j), - 'YZIZYI': (-0.029756134618662153+0j), - 'YZZIYI': (0.0035462180491050393+0j), - 'YZZZYI': (0.023737339260749633+0j), - 'YZZZYZ': (-0.024481114159709064+0j), - 'XZXXZX': (-0.03330235266776719+0j), - 'XZXYZY': (-0.03330235266776719+0j), - 'YZYXZX': (-0.03330235266776719+0j), - 'YZYYZY': (-0.03330235266776719+0j), - 'XXIIYY': (-0.032110837276557606+0j), - 'XYIIYX': (0.032110837276557606+0j), - 'YXIIXY': (0.032110837276557606+0j), - 'YYIIXX': (-0.032110837276557606+0j), - 'XXYYII': (-0.036332620017724165+0j), - 'XYYXII': (0.036332620017724165+0j), - 'YXXYII': (0.036332620017724165+0j), - 'YYXXII': (-0.036332620017724165+0j)}} +H2_sto3g = { + "qubit_encoding": "jordan_wigner", + "unit": "angstrom", + "geometry": "2\n \nH\t0\t0\t0\nH\t0\t0\t0.74", + "basis": "STO-3G", + "charge": 0, + "spin": 0, + "hf_array": [1, 1, 0, 0], + "hf_method": "pyscf.scf.hf_symm.SymAdaptedRHF", + "n_particles": {"total": 2, "alpha": 1, "beta": 1}, + "n_qubits": 4, + "convergence_threshold": 1e-06, + "point_group": {"groupname": "Dooh", "topgroup": "Dooh"}, + "calculated_properties": { + "HF": {"energy": -1.1167593073964255, "converged": True}, + "MP2": {"energy": -1.1298973809859585, "converged": True}, + "CCSD": {"energy": -1.13728399861044, "converged": True}, + "FCI": {"energy": -1.137283834488502, "converged": True}, + }, + "auxiliary_operators": { + "number_operator": { + "IIII": (2.0, 0.0), + "IIIZ": (-0.5, 0.0), + "IIZI": (-0.5, 0.0), + "IZII": (-0.5, 0.0), + "ZIII": (-0.5, 0.0), + }, + "S^2_operator": { + "IIII": (0.75, 0.0), + "IIIZ": (0.5, 0.0), + "IIZI": (-0.5, 0.0), + "IIZZ": (-0.375, 0.0), + "IZII": (0.5, 0.0), + "IZIZ": (0.125, 0.0), + "IZZI": (-0.125, 0.0), + "ZIII": (-0.5, 0.0), + "ZIIZ": (-0.125, 0.0), + "ZIZI": (0.125, 0.0), + "ZZII": (-0.375, 0.0), + "XXXX": (0.125, 0.0), + "XXYY": (0.125, 0.0), + "XYXY": (0.125, 0.0), + "XYYX": (-0.125, 0.0), + "YXXY": (-0.125, 0.0), + "YXYX": (0.125, 0.0), + "YYXX": (0.125, 0.0), + "YYYY": (0.125, 0.0), + }, + "Sz_operator": { + "IIIZ": (0.25, 0.0), + "IIZI": (-0.25, 0.0), + "IZII": (0.25, 0.0), + "ZIII": (-0.25, 0.0), + }, + "alpha_parity_operator": {"ZIZI": (1.0, 0.0)}, + "beta_parity_operator": {"IZIZ": (1.0, 0.0)}, + "MP2_operator": { + "XXXX": (-0.004531358676614097, 0.0), + "XXXY": (0.0, 0.004531358676614097), + "XXYX": (0.0, 0.004531358676614097), + "XXYY": (0.004531358676614097, 0.0), + "XYXX": (0.0, -0.004531358676614097), + "XYXY": (-0.004531358676614097, 0.0), + "XYYX": (-0.004531358676614097, 0.0), + "XYYY": (0.0, 0.004531358676614097), + "YXXX": (0.0, -0.004531358676614097), + "YXXY": (-0.004531358676614097, 0.0), + "YXYX": (-0.004531358676614097, 0.0), + "YXYY": (0.0, 0.004531358676614097), + "YYXX": (0.004531358676614097, 0.0), + "YYXY": (0.0, -0.004531358676614097), + "YYYX": (0.0, -0.004531358676614097), + "YYYY": (-0.004531358676614097, 0.0), + }, + "CCSD_operator": { + "XXXX": (-0.007079023951543804, 0.0), + "XXXY": (0.0, 0.007079023951543804), + "XXYX": (0.0, 0.007079023951543804), + "XXYY": (0.007079023951543804, 0.0), + "XYXX": (0.0, -0.007079023951543804), + "XYXY": (-0.007079023951543804, 0.0), + "XYYX": (-0.007079023951543804, 0.0), + "XYYY": (0.0, 0.007079023951543804), + "YXXX": (0.0, -0.007079023951543804), + "YXXY": (-0.007079023951543804, 0.0), + "YXYX": (-0.007079023951543804, 0.0), + "YXYY": (0.0, 0.007079023951543804), + "YYXX": (0.007079023951543804, 0.0), + "YYXY": (0.0, -0.007079023951543804), + "YYYX": (0.0, -0.007079023951543804), + "YYYY": (-0.007079023951543804, 0.0), + }, + }, + "H_dict": { + "IIII": (-0.09706626816763123 + 0j), + "IIIZ": (-0.22343153690813441 + 0j), + "IIZI": (-0.22343153690813441 + 0j), + "IIZZ": (0.17441287612261588 + 0j), + "IZII": (0.17141282644776915 + 0j), + "IZIZ": (0.12062523483390411 + 0j), + "IZZI": (0.1659278503377034 + 0j), + "ZIII": (0.17141282644776912 + 0j), + "ZIIZ": (0.1659278503377034 + 0j), + "ZIZI": (0.12062523483390411 + 0j), + "ZZII": (0.16868898170361207 + 0j), + "XXYY": (-0.04530261550379927 + 0j), + "XYYX": (0.04530261550379927 + 0j), + "YXXY": (0.04530261550379927 + 0j), + "YYXX": (-0.04530261550379927 + 0j), + }, +} + +He3_plus = { + "qubit_encoding": "jordan_wigner", + "unit": "angstrom", + "geometry": "3\n \nH\t0\t0\t0\nH\t0\t0\t0.74\nH\t0\t0\t1.48", + "basis": "STO-3G", + "charge": 1, + "spin": 0, + "hf_array": [1, 1, 0, 0, 0, 0], + "hf_method": "pyscf.scf.hf_symm.SymAdaptedRHF", + "n_particles": {"total": 2, "alpha": 1, "beta": 1}, + "n_qubits": 6, + "convergence_threshold": 1e-06, + "point_group": {"groupname": "Dooh", "topgroup": "Dooh"}, + "calculated_properties": { + "HF": {"energy": -1.189999028637302, "converged": True}, + "MP2": {"energy": -1.206775423813649, "converged": True}, + "CCSD": {"energy": -1.214628907244379, "converged": True}, + "FCI": {"energy": -1.214628846262647, "converged": True}, + }, + "auxiliary_operators": { + "number_operator": { + "IIIIII": (3.0, 0.0), + "IIIIIZ": (-0.5, 0.0), + "IIIIZI": (-0.5, 0.0), + "IIIZII": (-0.5, 0.0), + "IIZIII": (-0.5, 0.0), + "IZIIII": (-0.5, 0.0), + "ZIIIII": (-0.5, 0.0), + }, + "S^2_operator": { + "IIIIII": (1.125, 0.0), + "IIIIIZ": (0.5, 0.0), + "IIIIZI": (-0.5, 0.0), + "IIIIZZ": (-0.375, 0.0), + "IIIZII": (0.5, 0.0), + "IIIZIZ": (0.125, 0.0), + "IIIZZI": (-0.125, 0.0), + "IIZIII": (-0.5, 0.0), + "IIZIIZ": (-0.125, 0.0), + "IIZIZI": (0.125, 0.0), + "IIZZII": (-0.375, 0.0), + "IZIIII": (0.5, 0.0), + "IZIIIZ": (0.125, 0.0), + "IZIIZI": (-0.125, 0.0), + "IZIZII": (0.125, 0.0), + "IZZIII": (-0.125, 0.0), + "ZIIIII": (-0.5, 0.0), + "ZIIIIZ": (-0.125, 0.0), + "ZIIIZI": (0.125, 0.0), + "ZIIZII": (-0.125, 0.0), + "ZIZIII": (0.125, 0.0), + "ZZIIII": (-0.375, 0.0), + "IIXXXX": (0.125, 0.0), + "IIXXYY": (0.125, 0.0), + "IIXYXY": (0.125, 0.0), + "IIXYYX": (-0.125, 0.0), + "IIYXXY": (-0.125, 0.0), + "IIYXYX": (0.125, 0.0), + "IIYYXX": (0.125, 0.0), + "IIYYYY": (0.125, 0.0), + "XXIIXX": (0.125, 0.0), + "XXIIYY": (0.125, 0.0), + "XYIIXY": (0.125, 0.0), + "XYIIYX": (-0.125, 0.0), + "YXIIXY": (-0.125, 0.0), + "YXIIYX": (0.125, 0.0), + "YYIIXX": (0.125, 0.0), + "YYIIYY": (0.125, 0.0), + "XXXXII": (0.125, 0.0), + "XXYYII": (0.125, 0.0), + "XYXYII": (0.125, 0.0), + "XYYXII": (-0.125, 0.0), + "YXXYII": (-0.125, 0.0), + "YXYXII": (0.125, 0.0), + "YYXXII": (0.125, 0.0), + "YYYYII": (0.125, 0.0), + }, + "Sz_operator": { + "IIIIIZ": (0.25, 0.0), + "IIIIZI": (-0.25, 0.0), + "IIIZII": (0.25, 0.0), + "IIZIII": (-0.25, 0.0), + "IZIIII": (0.25, 0.0), + "ZIIIII": (-0.25, 0.0), + }, + "alpha_parity_operator": {"ZIZIZI": (1.0, 0.0)}, + "beta_parity_operator": {"IZIZIZ": (1.0, 0.0)}, + "MP2_operator": { + "XXIIXX": (-0.0022135760877754116, 0.0), + "XXIIXY": (0.0, 0.0022135760877754116), + "XXIIYX": (0.0, 0.0022135760877754116), + "XXIIYY": (0.0022135760877754116, 0.0), + "XYIIXX": (0.0, -0.0022135760877754116), + "XYIIXY": (-0.0022135760877754116, 0.0), + "XYIIYX": (-0.0022135760877754116, 0.0), + "XYIIYY": (0.0, 0.0022135760877754116), + "YXIIXX": (0.0, -0.0022135760877754116), + "YXIIXY": (-0.0022135760877754116, 0.0), + "YXIIYX": (-0.0022135760877754116, 0.0), + "YXIIYY": (0.0, 0.0022135760877754116), + "YYIIXX": (0.0022135760877754116, 0.0), + "YYIIXY": (0.0, -0.0022135760877754116), + "YYIIYX": (0.0, -0.0022135760877754116), + "YYIIYY": (-0.0022135760877754116, 0.0), + "XXXXII": (-0.005258398458007929, 0.0), + "XXXYII": (0.0, 0.005258398458007929), + "XXYXII": (0.0, 0.005258398458007929), + "XXYYII": (0.005258398458007929, 0.0), + "XYXXII": (0.0, -0.005258398458007929), + "XYXYII": (-0.005258398458007929, 0.0), + "XYYXII": (-0.005258398458007929, 0.0), + "XYYYII": (0.0, 0.005258398458007929), + "YXXXII": (0.0, -0.005258398458007929), + "YXXYII": (-0.005258398458007929, 0.0), + "YXYXII": (-0.005258398458007929, 0.0), + "YXYYII": (0.0, 0.005258398458007929), + "YYXXII": (0.005258398458007929, 0.0), + "YYXYII": (0.0, -0.005258398458007929), + "YYYXII": (0.0, -0.005258398458007929), + "YYYYII": (-0.005258398458007929, 0.0), + }, + "CCSD_operator": { + "IXZZZX": (-0.0031353836158880214, 0.0), + "IXZZZY": (0.0, 0.0031353836158880214), + "IYZZZX": (0.0, -0.0031353836158880214), + "IYZZZY": (-0.0031353836158880214, 0.0), + "XZZZXI": (-0.0031353836158880214, 0.0), + "XZZZYI": (0.0, 0.0031353836158880214), + "YZZZXI": (0.0, -0.0031353836158880214), + "YZZZYI": (-0.0031353836158880214, 0.0), + "XXIIXX": (-0.0025494280723394984, 0.0), + "XXIIXY": (0.0, 0.0025494280723394984), + "XXIIYX": (0.0, 0.0025494280723394984), + "XXIIYY": (0.0025494280723394984, 0.0), + "XYIIXX": (0.0, -0.0025494280723394984), + "XYIIXY": (-0.0025494280723394984, 0.0), + "XYIIYX": (-0.0025494280723394984, 0.0), + "XYIIYY": (0.0, 0.0025494280723394984), + "YXIIXX": (0.0, -0.0025494280723394984), + "YXIIXY": (-0.0025494280723394984, 0.0), + "YXIIYX": (-0.0025494280723394984, 0.0), + "YXIIYY": (0.0, 0.0025494280723394984), + "YYIIXX": (0.0025494280723394984, 0.0), + "YYIIXY": (0.0, -0.0025494280723394984), + "YYIIYX": (0.0, -0.0025494280723394984), + "YYIIYY": (-0.0025494280723394984, 0.0), + "XXXXII": (-0.008347686124399265, 0.0), + "XXXYII": (0.0, 0.008347686124399265), + "XXYXII": (0.0, 0.008347686124399265), + "XXYYII": (0.008347686124399265, 0.0), + "XYXXII": (0.0, -0.008347686124399265), + "XYXYII": (-0.008347686124399265, 0.0), + "XYYXII": (-0.008347686124399265, 0.0), + "XYYYII": (0.0, 0.008347686124399265), + "YXXXII": (0.0, -0.008347686124399265), + "YXXYII": (-0.008347686124399265, 0.0), + "YXYXII": (-0.008347686124399265, 0.0), + "YXYYII": (0.0, 0.008347686124399265), + "YYXXII": (0.008347686124399265, 0.0), + "YYXYII": (0.0, -0.008347686124399265), + "YYYXII": (0.0, -0.008347686124399265), + "YYYYII": (-0.008347686124399265, 0.0), + }, + }, + "H_dict": { + "IIIIII": (0.24747487013571695 + 0j), + "IIIIIZ": (-0.460046379318107 + 0j), + "IIIIZI": (-0.460046379318107 + 0j), + "IIIIZZ": (0.17501414371183724 + 0j), + "IIIZII": (-0.008325684680054832 + 0j), + "IIIZIZ": (0.10794008354812167 + 0j), + "IIIZZI": (0.14596700512786398 + 0j), + "IIZIII": (-0.008325684680054846 + 0j), + "IIZIIZ": (0.14596700512786398 + 0j), + "IIZIZI": (0.10794008354812167 + 0j), + "IIZZII": (0.1464490594631947 + 0j), + "IZIIII": (0.21618381471527337 + 0j), + "IZIIIZ": (0.12892083226845963 + 0j), + "IZIIZI": (0.16103166954501724 + 0j), + "IZIZII": (0.10098551626926347 + 0j), + "IZZIII": (0.13731813628698764 + 0j), + "ZIIIII": (0.21618381471527337 + 0j), + "ZIIIIZ": (0.16103166954501724 + 0j), + "ZIIIZI": (0.12892083226845963 + 0j), + "ZIIZII": (0.13731813628698764 + 0j), + "ZIZIII": (0.10098551626926347 + 0j), + "ZZIIII": (0.15887278686630402 + 0j), + "IIXXYY": (-0.03802692157974233 + 0j), + "IIXYYX": (0.03802692157974233 + 0j), + "IIYXXY": (0.03802692157974233 + 0j), + "IIYYXX": (-0.03802692157974233 + 0j), + "IXIZZX": (0.0035462180491050393 + 0j), + "IXZIZX": (-0.029756134618662153 + 0j), + "IXZZIX": (-0.024481114159709064 + 0j), + "IXZZZX": (0.02373733926074963 + 0j), + "IYIZZY": (0.0035462180491050393 + 0j), + "IYZIZY": (-0.029756134618662153 + 0j), + "IYZZIY": (-0.024481114159709064 + 0j), + "IYZZZY": (0.02373733926074963 + 0j), + "ZXZZZX": (-0.026953621359169865 + 0j), + "ZYZZZY": (-0.026953621359169865 + 0j), + "IXXYYI": (0.03330235266776719 + 0j), + "IXYYXI": (-0.03330235266776719 + 0j), + "IYXXYI": (-0.03330235266776719 + 0j), + "IYYXXI": (0.03330235266776719 + 0j), + "XIZZXI": (-0.026953621359169868 + 0j), + "XZIZXI": (-0.029756134618662153 + 0j), + "XZZIXI": (0.0035462180491050393 + 0j), + "XZZZXI": (0.023737339260749633 + 0j), + "XZZZXZ": (-0.024481114159709064 + 0j), + "YIZZYI": (-0.026953621359169868 + 0j), + "YZIZYI": (-0.029756134618662153 + 0j), + "YZZIYI": (0.0035462180491050393 + 0j), + "YZZZYI": (0.023737339260749633 + 0j), + "YZZZYZ": (-0.024481114159709064 + 0j), + "XZXXZX": (-0.03330235266776719 + 0j), + "XZXYZY": (-0.03330235266776719 + 0j), + "YZYXZX": (-0.03330235266776719 + 0j), + "YZYYZY": (-0.03330235266776719 + 0j), + "XXIIYY": (-0.032110837276557606 + 0j), + "XYIIYX": (0.032110837276557606 + 0j), + "YXIIXY": (0.032110837276557606 + 0j), + "YYIIXX": (-0.032110837276557606 + 0j), + "XXYYII": (-0.036332620017724165 + 0j), + "XYYXII": (0.036332620017724165 + 0j), + "YXXYII": (0.036332620017724165 + 0j), + "YYXXII": (-0.036332620017724165 + 0j), + }, +} def test_exact_gs_energy_H2(): - H = PauliwordOp.from_dictionary(H2_sto3g['H_dict']) - E_ref = H2_sto3g['calculated_properties']['FCI']['energy'] + H = PauliwordOp.from_dictionary(H2_sto3g["H_dict"]) + E_ref = H2_sto3g["calculated_properties"]["FCI"]["energy"] gs_energy, gs_state = exact_gs_energy(H.to_sparse_matrix) - assert np.isclose(gs_energy, E_ref), 'reference energy does NOT match true gs' + assert np.isclose(gs_energy, E_ref), "reference energy does NOT match true gs" assert isinstance(gs_state, QuantumState) assert np.isclose(gs_state.dagger * H * gs_state, E_ref) def test_exact_gs_energy_H3_plus(): - H = PauliwordOp.from_dictionary(He3_plus['H_dict']) - E_ref = He3_plus['calculated_properties']['FCI']['energy'] + H = PauliwordOp.from_dictionary(He3_plus["H_dict"]) + E_ref = He3_plus["calculated_properties"]["FCI"]["energy"] - num_operator = PauliwordOp.from_dictionary(He3_plus['auxiliary_operators']['number_operator']) - n_part = He3_plus['n_particles']['total'] + num_operator = PauliwordOp.from_dictionary( + He3_plus["auxiliary_operators"]["number_operator"] + ) + n_part = He3_plus["n_particles"]["total"] - gs_energy, gs_state = exact_gs_energy(H.to_sparse_matrix, - number_operator=num_operator, - n_particles=n_part) + gs_energy, gs_state = exact_gs_energy( + H.to_sparse_matrix, number_operator=num_operator, n_particles=n_part + ) - assert np.isclose(gs_energy, E_ref), 'reference energy does NOT match true gs' + assert np.isclose(gs_energy, E_ref), "reference energy does NOT match true gs" assert isinstance(gs_state, QuantumState) assert np.isclose(gs_state.dagger * H * gs_state, E_ref) @@ -347,19 +390,19 @@ def test_random_anitcomm_2n_1_PauliwordOp_method(): complex_coeff = False apply_clifford = False - AC = random_anitcomm_2n_1_PauliwordOp(n_qubits, - apply_clifford=apply_clifford, - complex_coeff=complex_coeff) + AC = random_anitcomm_2n_1_PauliwordOp( + n_qubits, apply_clifford=apply_clifford, complex_coeff=complex_coeff + ) # underlying method manually coded: - base = 'Z' * n_qubits - I_term = 'I' * n_qubits + base = "Z" * n_qubits + I_term = "I" * n_qubits P_list = [base] for i in range(n_qubits): # Z_term - P_list.append(base[:i] + 'X' + I_term[i + 1:]) + P_list.append(base[:i] + "X" + I_term[i + 1 :]) # Y_term - P_list.append(base[:i] + 'Y' + I_term[i + 1:]) + P_list.append(base[:i] + "Y" + I_term[i + 1 :]) P_anticomm = PauliwordOp.from_list(P_list) AC.coeff_vec = np.ones(AC.n_terms) @@ -375,14 +418,17 @@ def test_random_anitcomm_2n_1_PauliwordOp_real_with_clifford(): complex_coeff = False apply_clifford = True - AC = random_anitcomm_2n_1_PauliwordOp(n_qubits, - apply_clifford=apply_clifford, - complex_coeff=complex_coeff) + AC = random_anitcomm_2n_1_PauliwordOp( + n_qubits, apply_clifford=apply_clifford, complex_coeff=complex_coeff + ) - - assert AC.n_terms == 2*n_qubits + 1 - anti_comm_check = AC.adjacency_matrix.astype(int) - np.eye(AC.adjacency_matrix.shape[0]) - assert(np.sum(anti_comm_check) == 0), 'operator not made up of pairwisie anticommuting Pauli operators' + assert AC.n_terms == 2 * n_qubits + 1 + anti_comm_check = AC.adjacency_matrix.astype(int) - np.eye( + AC.adjacency_matrix.shape[0] + ) + assert ( + np.sum(anti_comm_check) == 0 + ), "operator not made up of pairwisie anticommuting Pauli operators" def test_random_anitcomm_2n_1_PauliwordOp_complex_with_clifford(): @@ -390,23 +436,26 @@ def test_random_anitcomm_2n_1_PauliwordOp_complex_with_clifford(): complex_coeff = True apply_clifford = True - AC = random_anitcomm_2n_1_PauliwordOp(n_qubits, - apply_clifford=apply_clifford, - complex_coeff=complex_coeff) - + AC = random_anitcomm_2n_1_PauliwordOp( + n_qubits, apply_clifford=apply_clifford, complex_coeff=complex_coeff + ) - assert AC.n_terms == 2*n_qubits + 1 - anti_comm_check = AC.adjacency_matrix.astype(int) - np.eye(AC.adjacency_matrix.shape[0]) - assert(np.sum(anti_comm_check) == 0), 'operator not made up of pairwisie anticommuting Pauli operators' + assert AC.n_terms == 2 * n_qubits + 1 + anti_comm_check = AC.adjacency_matrix.astype(int) - np.eye( + AC.adjacency_matrix.shape[0] + ) + assert ( + np.sum(anti_comm_check) == 0 + ), "operator not made up of pairwisie anticommuting Pauli operators" def test_tensor_list(): - X_term = PauliwordOp.from_list(['X'], [0.25]) - Y_term = PauliwordOp.from_list(['Y'], [0.25]) - Z_term = PauliwordOp.from_list(['Z'], [0.25]) + X_term = PauliwordOp.from_list(["X"], [0.25]) + Y_term = PauliwordOp.from_list(["Y"], [0.25]) + Z_term = PauliwordOp.from_list(["Z"], [0.25]) - targ = PauliwordOp.from_list(['XYZ'], [0.25*0.25*0.25]) + targ = PauliwordOp.from_list(["XYZ"], [0.25 * 0.25 * 0.25]) P_out = tensor_list([X_term, Y_term, Z_term]) @@ -415,10 +464,9 @@ def test_tensor_list(): def test_product_list(): n_qubits = 4 - P_random = PauliwordOp.random(n_qubits=n_qubits, - n_terms=10) + P_random = PauliwordOp.random(n_qubits=n_qubits, n_terms=10) - open_F_prod = QubitOperator('', 1) + open_F_prod = QubitOperator("", 1) for p in P_random: open_F_prod *= p.to_openfermion @@ -433,61 +481,63 @@ def test_gram_schmidt_from_quantum_state_QuantumState(): psi = QuantumState.haar_random(nq) U_gram = gram_schmidt_from_quantum_state(psi) - assert np.allclose(U_gram[:, 0], psi.to_sparse_matrix.toarray().reshape([-1])), 'first column of U_gram not correct' - assert np.allclose(U_gram@U_gram.conj().T, np.eye(2**nq)), 'U_gram not unitary' + assert np.allclose( + U_gram[:, 0], psi.to_sparse_matrix.toarray().reshape([-1]) + ), "first column of U_gram not correct" + assert np.allclose(U_gram @ U_gram.conj().T, np.eye(2**nq)), "U_gram not unitary" def test_gram_schmidt_from_quantum_state_numpy_array(): nq = 3 - psi = np.arange(0,2**nq) - psi_norm = psi/np.linalg.norm(psi) + psi = np.arange(0, 2**nq) + psi_norm = psi / np.linalg.norm(psi) U_gram = gram_schmidt_from_quantum_state(psi_norm) - assert np.allclose(U_gram[:, 0], psi_norm), 'first column of U_gram not correct' - assert np.allclose(U_gram @ U_gram.conj().T, np.eye(2 ** nq)), 'U_gram not unitary' + assert np.allclose(U_gram[:, 0], psi_norm), "first column of U_gram not correct" + assert np.allclose(U_gram @ U_gram.conj().T, np.eye(2**nq)), "U_gram not unitary" def test_Draw_molecule(): - xyz = H2_sto3g['geometry'] - viewer_sphere = Draw_molecule(xyz, width=400, height=400, style='sphere') + xyz = H2_sto3g["geometry"] + viewer_sphere = Draw_molecule(xyz, width=400, height=400, style="sphere") assert isinstance(viewer_sphere, py3Dmol.view) - viewer_stick = Draw_molecule(xyz, width=400, height=400, style='stick') + viewer_stick = Draw_molecule(xyz, width=400, height=400, style="stick") assert isinstance(viewer_stick, py3Dmol.view) + def test_get_sparse_matrix_large_pauliwordop(): - for nq in range(2,6): - n_terms = 10*nq + for nq in range(2, 6): + n_terms = 10 * nq random_P = PauliwordOp.random(nq, n_terms) sparse_mat = get_sparse_matrix_large_pauliwordop(random_P) - assert np.allclose(random_P.to_sparse_matrix.toarray(), - sparse_mat.toarray()) + assert np.allclose(random_P.to_sparse_matrix.toarray(), sparse_mat.toarray()) + def test_matrix_allclose_sparse(): - for nq in range(2,6): - n_terms = 10*nq + for nq in range(2, 6): + n_terms = 10 * nq random_P = PauliwordOp.random(nq, n_terms) sparse_mat = get_sparse_matrix_large_pauliwordop(random_P) - assert matrix_allclose(random_P.to_sparse_matrix, - sparse_mat) + assert matrix_allclose(random_P.to_sparse_matrix, sparse_mat) # assert false output - Pop_XI= PauliwordOp.from_list(['XI']).to_sparse_matrix - Pop_ZI = PauliwordOp.from_list(['ZI']).to_sparse_matrix - assert not matrix_allclose(Pop_XI, - Pop_ZI) + Pop_XI = PauliwordOp.from_list(["XI"]).to_sparse_matrix + Pop_ZI = PauliwordOp.from_list(["ZI"]).to_sparse_matrix + assert not matrix_allclose(Pop_XI, Pop_ZI) + def test_matrix_allclose_dense(): - for nq in range(2,6): - n_terms = 10*nq + for nq in range(2, 6): + n_terms = 10 * nq random_P = PauliwordOp.random(nq, n_terms) sparse_mat = get_sparse_matrix_large_pauliwordop(random_P) - assert matrix_allclose(random_P.to_sparse_matrix.toarray(), - sparse_mat.toarray()) + assert matrix_allclose( + random_P.to_sparse_matrix.toarray(), sparse_mat.toarray() + ) # assert false output - Pop_XI= PauliwordOp.from_list(['XI']).to_sparse_matrix - Pop_ZI = PauliwordOp.from_list(['ZI']).to_sparse_matrix - assert not matrix_allclose(Pop_XI.toarray(), - Pop_ZI.toarray()) \ No newline at end of file + Pop_XI = PauliwordOp.from_list(["XI"]).to_sparse_matrix + Pop_ZI = PauliwordOp.from_list(["ZI"]).to_sparse_matrix + assert not matrix_allclose(Pop_XI.toarray(), Pop_ZI.toarray())