diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 12f6a982d..16064a59f 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -36,6 +36,8 @@ RUN sh -c "$(wget -nv -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/mast # upgrade pip and install package manager RUN python -m pip install --no-cache-dir --upgrade pip +RUN pip install --no-cache-dir poetry==1.4.0 +RUN poetry config virtualenvs.create false ### TEAR DOWN IMAGE SETUP ### # switch back to dialog for any ad-hoc use of apt-get diff --git a/.devcontainer/post-install.sh b/.devcontainer/post-install.sh index c7cbf8aab..53bc587fa 100755 --- a/.devcontainer/post-install.sh +++ b/.devcontainer/post-install.sh @@ -1,8 +1,3 @@ #! /bin/zsh -pip install --no-cache-dir -r requirements.txt -pip install --no-cache-dir -r requirements-dev.txt -pip install --no-cache-dir -r doc/requirements.txt -pip install ray -pip install pylint -pip install -e . +poetry install --all-extras --with dev,doc diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 733a05e45..e137e8b9d 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -1,3 +1,115 @@ +# Release 0.5.0 + +### New features + +* Optimization callback functionalities has been improved. A dedicated `Callback` class is added which + is able to access the optimizer, the cost function, the parameters as well as gradients, during the + optimization. In addition, multiple callbacks can be specified. This opens up the endless possiblities + of customizing the the optimization progress with schedulers, trackers, heuristics, tricks, etc. + [(#219)](https://github.com/XanaduAI/MrMustard/pull/219) + +* Tensorboard-based optimization tracking is added as a builtin `Callback` class: `TensorboardCallback`. + It can automatically track costs as well as all trainable parameters during optimization in realtime. + Tensorboard can be most conveniently viewed from VScode. + [(#219)](https://github.com/XanaduAI/MrMustard/pull/219) + + ```python + import numpy as np + from mrmustard.training import Optimizer, TensorboardCallback + + def cost_fn(): + ... + + def as_dB(cost): + delta = np.sqrt(np.log(1 / (abs(cost) ** 2)) / (2 * np.pi)) + cost_dB = -10 * np.log10(delta**2) + return cost_dB + + tb_cb = TensorboardCallback(cost_converter=as_dB, track_grads=True) + + opt = Optimizer(euclidean_lr = 0.001); + opt.minimize(cost_fn, max_steps=200, by_optimizing=[...], callbacks=tb_cb) + + # Logs will be stored in `tb_cb.logdir` which defaults to `./tb_logdir/...` but can be customized. + # VScode can be used to open the Tensorboard frontend for live monitoring. + # Or, in command line: `tensorboard --logdir={tb_cb.logdir}` and open link in browser. + ``` + +* Gaussian states support a `bargmann` method for returning the bargmann representation. + [(#235)](https://github.com/XanaduAI/MrMustard/pull/235) + +* The `ket` method of `State` now supports new keyword arguments `max_prob` and `max_photons`. + Use them to speed-up the filling of a ket array up to a certain probability or *total* photon number. + [(#235)](https://github.com/XanaduAI/MrMustard/pull/235) + + ```python + from mrmustard.lab import Gaussian + + # Fills the ket array up to 99% probability or up to the |0,3>, |1,2>, |2,1>, |3,0> subspace, whichever is reached first. + # The array has the autocutoff shape, unless the cutoffs are specified explicitly. + ket = Gaussian(2).ket(max_prob=0.99, max_photons=3) + ``` + +* Gaussian transformations support a `bargmann` method for returning the bargmann representation. + [(#239)](https://github.com/XanaduAI/MrMustard/pull/239) + +* BSGate.U now supports method='vanilla' (default) and 'schwinger' (slower, but stable to any cutoff) + [(#248)](https://github.com/XanaduAI/MrMustard/pull/248) + +### Breaking Changes + +* The previous `callback` argument to `Optimizer.minimize` is now `callbacks` since we can now pass + multiple callbacks to it. + [(#219)](https://github.com/XanaduAI/MrMustard/pull/219) + +* The `opt_history` attribute of `Optimizer` does not have the placeholder at the beginning anymore. + [(#235)](https://github.com/XanaduAI/MrMustard/pull/235) + +### Improvements + +* The math module now has a submodule `lattice` for constructing recurrence relation strategies in the Fock lattice. + There are a few predefined strategies in `mrmustard.math.lattice.strategies`. + [(#235)](https://github.com/XanaduAI/MrMustard/pull/235) + +* Gradients in the Fock lattice are now computed using the vector-jacobian product. + This saves a lot of memory and speeds up the optimization process by roughly 4x. + [(#235)](https://github.com/XanaduAI/MrMustard/pull/235) + +* Tests of the compact_fock module now use hypothesis. + [(#235)](https://github.com/XanaduAI/MrMustard/pull/235) + +* Faster implementation of the fock representation of `BSgate`, `Sgate` and `SqueezedVacuum`, ranging from 5x to 50x. + [(#239)](https://github.com/XanaduAI/MrMustard/pull/239) + +* More robust implementation of cutoffs for States. +[(#239)](https://github.com/XanaduAI/MrMustard/pull/239) + +* Dependencies and versioning are now managed using Poetry. +[(#257)](https://github.com/XanaduAI/MrMustard/pull/257) + +### Bug fixes + +* Fixed a bug that would make two progress bars appear during an optimization + [(#235)](https://github.com/XanaduAI/MrMustard/pull/235) + +* The displacement of the dual of an operation had the wrong sign + [(#239)](https://github.com/XanaduAI/MrMustard/pull/239) + +* When projecting a Gaussian state onto a Fock state, the upper limit of the autocutoff now respect the Fock projection. + [(#246)](https://github.com/XanaduAI/MrMustard/pull/246) + +* Fixed a bug for the algorithms that allow faster PNR sampling from Gaussian circuits using density matrices. When the +cutoff of the first detector is equal to 1, the resulting density matrix is now correct. + +### Documentation + +### Contributors +[Filippo Miatto](https://github.com/ziofil), [Zeyue Niu](https://github.com/zeyueN), +[Robbe De Prins](https://github.com/rdprins), [Gabriele Gullì](https://github.com/ggulli), +[Richard A. Wolf](https://github.com/ryk-wolf) + +--- + # Release 0.4.1 ### New features @@ -23,8 +135,9 @@ ### Contributors [Filippo Miatto](https://github.com/ziofil), [Sebastian Duque Mesa](https://github.com/sduquemesa) +--- -# Release 0.4.0 +# Release 0.4.0 (current release) ### New features diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index f92a611a9..90887d6ab 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -1,4 +1,4 @@ -name: builds +name: Build package on: push: branches: @@ -12,37 +12,37 @@ jobs: runs-on: ubuntu-latest env: HYPOTHESIS_PROFILE: ci - strategy: fail-fast: false matrix: python-version: ['3.9', '3.10'] + concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.python-version }} + cancel-in-progress: true steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.11.0 - with: - access_token: ${{ github.token }} - - - uses: actions/checkout@v3 + - name: Checkout repo + uses: actions/checkout@v3 - - name: Set up Python + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Build and install Mr Mustard run: | - python -m pip install --upgrade pip wheel - python setup.py bdist_wheel + python -m pip install --no-cache-dir --upgrade pip + pip install --no-cache-dir poetry==1.4.0 + poetry config virtualenvs.create false + poetry build pip install dist/mrmustard*.whl + # Move to 'src' to properly test only installed package + # https://docs.pytest.org/en/7.1.x/explanation/goodpractices.html#tests-outside-application-code + mkdir src + mv mrmustard src - - name: Install test dependencies - run: | - pip install -r requirements.txt - pip install -r requirements-dev.txt - pip install wheel pytest pytest-cov pytest-mock hypothesis --upgrade + - name: Install only test dependencies + run: poetry install --no-root --extras "ray" --with dev - name: Run tests - run: | - python -m pytest tests -p no:warnings --tb=native + run: python -m pytest tests -p no:warnings --tb=native diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b081aae43..ad0ff8caf 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,35 +4,38 @@ on: branches: - develop pull_request: + paths: + - '.github/workflows/tests.yml' + - 'mrmustard/**' + - 'tests/**' + - 'pyproject.toml' + - 'poetry.lock' + - 'pytest.ini' jobs: pytest: runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true env: HYPOTHESIS_PROFILE: ci steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.11.0 - with: - access_token: ${{ github.token }} - - - uses: actions/checkout@v3 + - name: Checkout repo + uses: actions/checkout@v3 - - name: Setup python ${{ matrix.python-version }} + - name: Setup python uses: actions/setup-python@v4 with: python-version: '3.9' - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r requirements-dev.txt - pip install wheel pytest pytest-cov --upgrade - pip install .[ray] - # python setup.py bdist_wheel - # pip install dist/*.whl + python -m pip install --no-cache-dir --upgrade pip + pip install --no-cache-dir poetry==1.4.0 + poetry config virtualenvs.create false + poetry install --extras "ray" --with dev - name: Run tests run: python -m pytest tests --cov=mrmustard --cov-report=term-missing --cov-report=xml -p no:warnings --tb=native diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml index e52e7ba79..2545e285c 100644 --- a/.github/workflows/upload.yml +++ b/.github/workflows/upload.yml @@ -10,7 +10,8 @@ jobs: HYPOTHESIS_PROFILE: ci steps: - - uses: actions/checkout@v3 + - name: Checkout repo + uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 @@ -19,21 +20,24 @@ jobs: - name: Build and install Mr Mustard run: | - python -m pip install --upgrade pip wheel - python setup.py bdist_wheel + python -m pip install --no-cache-dir --upgrade pip + pip install --no-cache-dir poetry==1.4.0 + poetry config virtualenvs.create false + poetry build pip install dist/mrmustard*.whl + # Move to 'src' to properly test only installed package + # https://docs.pytest.org/en/7.1.x/explanation/goodpractices.html#tests-outside-application-code + mkdir src + mv mrmustard src - - name: Install test dependencies - run: | - pip install -r requirements.txt - pip install wheel pytest pytest-cov pytest-mock hypothesis --upgrade + - name: Install only test dependencies + run: poetry install --no-root --extras "ray" --with dev - name: Run tests - run: | - python -m pytest tests -p no:warnings --tb=native + run: python -m pytest tests -p no:warnings --tb=native - name: Publish - uses: pypa/gh-action-pypi-publish@master + uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PIPY_TOKEN }} diff --git a/.readthedocs.yml b/.readthedocs.yml index 195e00930..a7dbfa275 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -6,6 +6,11 @@ build: os: ubuntu-22.04 tools: python: "3.9" + jobs: + post_install: + - pip install --no-cache-dir poetry==1.4.0 + - poetry config virtualenvs.create false + - poetry install --with doc # Build documentation in the docs/ directory with Sphinx sphinx: @@ -16,9 +21,5 @@ sphinx: # - pdf # Optionally declare the Python requirements required to build your docs -python: - install: - - requirements: doc/requirements.txt - - method: pip - path: . - system_packages: true +# python: +# install: diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index cf329f62f..000000000 --- a/Dockerfile +++ /dev/null @@ -1,50 +0,0 @@ -FROM python:3.10 - -# Configure apt for setup -ENV DEBIAN_FRONTEND=noninteractive - -WORKDIR /mrmustard -COPY . . - -RUN apt-get update && \ - apt-get -y install --no-install-recommends sudo \ - zsh \ - less \ - curl \ - wget \ - graphviz \ - fonts-powerline \ - locales \ - git \ - && apt-get clean && rm -rf /var/lib/apt/lists/* - -### GIT GLOBAL SETUP ### - -RUN git config --global core.excludesfile /.globalgitignore -RUN touch /.globalgitignore -RUN echo ".notebooks" >> /.globalgitignore -RUN echo "nohup.out" >> /.globalgitignore - -### ZSH TERMINAL SETUP ### - -# generate locale for zsh terminal agnoster theme -RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && /usr/sbin/locale-gen -RUN locale-gen en_US.UTF-8 -# set term to be bash instead of sh -ENV TERM xterm -ENV SHELL /bin/zsh -# install oh-my-zsh -RUN sh -c "$(wget -nv -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" - -### PYTHON DEPENDENCIES INTALLATION ### - -# upgrade pip and install package manager -RUN python -m pip install --no-cache-dir --upgrade pip -RUN pip install --no-cache-dir -r requirements.txt -RUN pip install --no-cache-dir -r requirements-dev.txt -RUN pip install --no-cache-dir ray -RUN pip install --no-cache-dir -e . - -### TEAR DOWN IMAGE SETUP ### -# switch back to dialog for any ad-hoc use of apt-get -ENV DEBIAN_FRONTEND=dialog diff --git a/Makefile b/Makefile index d20cad652..fcd55052a 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ COVERAGE := --cov=mrmustard --cov-report=html:coverage_html_report --cov-append help: @echo "Please use \`make ' where is one of" @echo " install to install Mr Mustard" + @echo " install-all to install Mr Mustard with all extras and optional dependencies" @echo " dist to package the source distribution" @echo " clean to delete all temporary, cache, and build files" @echo " clean-docs to delete all built documentation" @@ -18,11 +19,18 @@ install: ifndef PYTHON3 @echo "To install Mr Mustard you need to have Python 3 installed" endif - $(PYTHON) setup.py install + poetry install + +.PHONY: install-all +install-all: +ifndef PYTHON3 + @echo "To install Mr Mustard you need to have Python 3 installed" +endif + poetry install --all-extras --with dev,doc .PHONY: dist dist: - $(PYTHON) setup.py sdist + poetry build .PHONY : clean clean: diff --git a/doc/code/training.rst b/doc/code/training.rst index 1ab03e1c2..d65fb613a 100644 --- a/doc/code/training.rst +++ b/doc/code/training.rst @@ -8,6 +8,7 @@ mrmustard.training training/parameter training/parametrized training/trainer + training/callbacks .. currentmodule:: mrmustard.training diff --git a/doc/code/training/callbacks.rst b/doc/code/training/callbacks.rst new file mode 100644 index 000000000..ae216849f --- /dev/null +++ b/doc/code/training/callbacks.rst @@ -0,0 +1,7 @@ +callbacks +============ + +.. currentmodule:: mrmustard.training.callbacks + +.. automodapi:: mrmustard.training.callbacks + :no-heading: diff --git a/doc/development/development_guide.rst b/doc/development/development_guide.rst index b7ffbf419..9711859c9 100644 --- a/doc/development/development_guide.rst +++ b/doc/development/development_guide.rst @@ -66,11 +66,11 @@ Development environment ----------------------- Mr Mustard uses a ``pytest`` suite for testing and ``black`` for formatting. These -dependencies can be installed via ``pip``: +dependencies can be installed via ``poetry``: .. code-block:: bash - pip install -r requirements-dev.txt + poetry install --with dev Software tests -------------- @@ -175,11 +175,11 @@ Documentation ------------- Additional packages are required to build the documentation, as specified in -``doc/requirements.txt``. These packages can be installed using: +``pyproject.toml`` under the group ``doc``. These packages can be installed using: .. code-block:: bash - pip install -r doc/requirements.txt + poetry install --with doc from within the top-level directory. To then build the HTML documentation, run diff --git a/doc/requirements.txt b/doc/requirements.txt deleted file mode 100644 index 8ea6a7332..000000000 --- a/doc/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -sphinx -docutils -m2r2 -sphinx-autodoc-typehints -sphinx-copybutton -sphinx-automodapi -sphinxcontrib-bibtex -mistune==0.8.4 -xanadu-sphinx-theme==0.1.0 diff --git a/mrmustard/__init__.py b/mrmustard/__init__.py index a6556e73f..f8ed18e69 100644 --- a/mrmustard/__init__.py +++ b/mrmustard/__init__.py @@ -40,7 +40,7 @@ def __init__(self): self.AUTOCUTOFF_MIN_CUTOFF = 1 self.CIRCUIT_DECIMALS = 3 # use cutoff=5 for each mode when determining if two transformations in fock repr are equal - self.EQ_TRANSFORMATION_CUTOFF = 5 + self.EQ_TRANSFORMATION_CUTOFF = 3 # 3 is enough to include a full step of the rec relations self.EQ_TRANSFORMATION_RTOL_FOCK = 1e-3 self.EQ_TRANSFORMATION_RTOL_GAUSS = 1e-6 # for the detectors @@ -50,6 +50,7 @@ def __init__(self): self.PROGRESSBAR = True self._seed = np.random.randint(0, 2**31 - 1) self.rng = np.random.default_rng(self._seed) + self.DEFAULT_BS_METHOD = "vanilla" # can be 'vanilla' or 'schwinger' @property def SEED(self): diff --git a/mrmustard/_version.py b/mrmustard/_version.py index 4e4fa30c3..c9955a3aa 100644 --- a/mrmustard/_version.py +++ b/mrmustard/_version.py @@ -13,7 +13,22 @@ # limitations under the License. """Version information. - Version number (major.minor.patch[-label]) + +Version number retrieved from pyproject.toml file """ +from pathlib import Path +import tomli + + +def _get_project_root(): + """Compute and return root dir""" + return Path(__file__).parent.parent + + +def _get_project_version(): + """Parse 'pyproject.toml' and return current version""" + with open(f"{_get_project_root()}/pyproject.toml", mode="rb") as pyproject: + return tomli.load(pyproject)["tool"]["poetry"]["version"] + -__version__ = "0.4.1" +__version__ = str(_get_project_version()) diff --git a/mrmustard/lab/abstract/state.py b/mrmustard/lab/abstract/state.py index cc2945e30..8eb8c0e01 100644 --- a/mrmustard/lab/abstract/state.py +++ b/mrmustard/lab/abstract/state.py @@ -31,12 +31,14 @@ from mrmustard import settings from mrmustard.math import Math -from mrmustard.physics import fock, gaussian +from mrmustard.physics import bargmann, fock, gaussian from mrmustard.typing import ( + ComplexMatrix, + ComplexTensor, + ComplexVector, RealMatrix, - RealVector, RealTensor, - ComplexTensor, + RealVector, ) from mrmustard.utils import graphics @@ -47,7 +49,7 @@ # pylint: disable=too-many-instance-attributes -class State: +class State: # pylint: disable=too-many-public-methods r"""Base class for quantum states.""" def __init__( @@ -92,12 +94,15 @@ def __init__( self._norm = _norm if cov is not None and means is not None: self.is_gaussian = True + self.is_hilbert_vector = np.allclose(gaussian.purity(self.cov, settings.HBAR), 1.0) self.num_modes = cov.shape[-1] // 2 elif eigenvalues is not None and symplectic is not None: self.is_gaussian = True + self.is_hilbert_vector = np.allclose(eigenvalues, 2.0 / settings.HBAR) self.num_modes = symplectic.shape[-1] // 2 elif ket is not None or dm is not None: self.is_gaussian = False + self.is_hilbert_vector = ket is not None self.num_modes = len(ket.shape) if ket is not None else len(dm.shape) // 2 self._purity = 1.0 if ket is not None else None else: @@ -148,7 +153,7 @@ def is_mixed(self): @property def is_pure(self): r"""Returns ``True`` if the state is pure and ``False`` otherwise.""" - return True if self._ket is not None else np.isclose(self.purity, 1.0, atol=1e-6) + return np.isclose(self.purity, 1.0, atol=1e-6) @property def means(self) -> Optional[RealVector]: @@ -172,14 +177,22 @@ def number_stdev(self) -> RealVector: @property def cutoffs(self) -> List[int]: - r"""Returns the cutoff dimensions for each mode.""" - if self._cutoffs is not None: - return self._cutoffs # TODO: allow self._cutoffs = [N, None] - if self._ket is None and self._dm is None: - return fock.autocutoffs(self.cov, self.means, settings.AUTOCUTOFF_PROBABILITY) - return list( - self.fock.shape[: self.num_modes] - ) # NOTE: triggered only if the fock representation already exists + r"""Returns the Hilbert space dimension of each mode.""" + if self._cutoffs is None: + if self._ket is None and self._dm is None: + self._cutoffs = fock.autocutoffs( + self.cov, self.means, settings.AUTOCUTOFF_PROBABILITY + ) + else: + self._cutoffs = [ + int(c) + for c in ( + self._ket.shape + if self._ket is not None + else self._dm.shape[: self.num_modes] + ) + ] + return self._cutoffs @property def shape(self) -> List[int]: @@ -189,14 +202,14 @@ def shape(self) -> List[int]: the first two moments of the number operator. """ # NOTE: if we initialize State(dm=pure_dm), self.fock returns the dm, which does not have shape self.cutoffs - return self.cutoffs if self.is_pure else self.cutoffs + self.cutoffs + return self.cutoffs if self.is_hilbert_vector else self.cutoffs + self.cutoffs @property def fock(self) -> ComplexTensor: r"""Returns the Fock representation of the state.""" if self._dm is None and self._ket is None: _fock = fock.wigner_to_fock_state( - self.cov, self.means, shape=self.shape, return_dm=self.is_mixed + self.cov, self.means, shape=self.shape, return_dm=not self.is_hilbert_vector ) if self.is_mixed: self._dm = _fock @@ -227,7 +240,7 @@ def norm(self) -> float: r"""Returns the norm of the state.""" if self.is_gaussian: return self._norm - return fock.norm(self.fock, self._dm is not None) + return fock.norm(self.fock, not self.is_hilbert_vector) @property def probability(self) -> float: @@ -237,12 +250,21 @@ def probability(self) -> float: return norm**2 return norm - def ket(self, cutoffs: List[int] = None) -> Optional[ComplexTensor]: + def ket( + self, + cutoffs: List[int] = None, + max_prob: float = 1.0, + max_photons: int = None, + ) -> Optional[ComplexTensor]: r"""Returns the ket of the state in Fock representation or ``None`` if the state is mixed. Args: cutoffs List[int or None]: The cutoff dimensions for each mode. If a mode cutoff is ``None``, it's guessed automatically. + max_prob (float): The maximum probability of the state. Defaults to 1.0. + (used to stop the calculation of the amplitudes early) + max_photons (int): The maximum number of photons in the state, summing over all modes + (used to stop the calculation of the amplitudes early) Returns: Tensor: the ket @@ -255,16 +277,22 @@ def ket(self, cutoffs: List[int] = None) -> Optional[ComplexTensor]: else: cutoffs = [c if c is not None else self.cutoffs[i] for i, c in enumerate(cutoffs)] + # TODO: shouldn't we check if trainable instead? that's when we want to recompute fock if self.is_gaussian: self._ket = fock.wigner_to_fock_state( - self.cov, self.means, shape=cutoffs, return_dm=False + self.cov, + self.means, + shape=cutoffs, + return_dm=False, + max_prob=max_prob, + max_photons=max_photons, ) else: # only fock representation is available if self._ket is None: # if state is pure and has a density matrix, calculate the ket if self.is_pure: self._ket = fock.dm_to_ket(self._dm) - current_cutoffs = list(self._ket.shape[: self.num_modes]) + current_cutoffs = [int(s) for s in self._ket.shape] if cutoffs != current_cutoffs: paddings = [(0, max(0, new - old)) for new, old in zip(cutoffs, current_cutoffs)] if any(p != (0, 0) for p in paddings): @@ -295,7 +323,7 @@ def dm(self, cutoffs: Optional[List[int]] = None) -> ComplexTensor: else: if self.is_gaussian: self._dm = fock.wigner_to_fock_state( - self.cov, self.means, shape=cutoffs * 2, return_dm=True + self.cov, self.means, shape=cutoffs + cutoffs, return_dm=True ) elif cutoffs != (current_cutoffs := list(self._dm.shape[: self.num_modes])): paddings = [(0, max(0, new - old)) for new, old in zip(cutoffs, current_cutoffs)] @@ -498,6 +526,21 @@ def __getitem__(self, item) -> State: self._modes = item return self + def bargmann(self, numpy=False) -> Optional[tuple[ComplexMatrix, ComplexVector, complex]]: + r"""Returns the Bargmann representation of the state. + If numpy=True, returns the numpy arrays instead of the backend arrays. + """ + if self.is_gaussian: + if self.is_pure: + A, B, C = bargmann.wigner_to_bargmann_psi(self.cov, self.means) + else: + A, B, C = bargmann.wigner_to_bargmann_rho(self.cov, self.means) + else: + return None + if numpy: + return math.asnumpy(A), math.asnumpy(B), math.asnumpy(C) + return A, B, C + def get_modes(self, item) -> State: r"""Returns the state on the given modes.""" if isinstance(item, int): @@ -524,7 +567,7 @@ def get_modes(self, item) -> State: return State(dm=fock_partitioned, modes=item) # TODO: refactor - def __eq__(self, other) -> bool: + def __eq__(self, other) -> bool: # pylint: disable=too-many-return-statements r"""Returns whether the states are equal.""" if self.num_modes != other.num_modes: return False @@ -576,7 +619,9 @@ def __rmul__(self, other): warnings.warn( "scalar multiplication forces conversion to fock representation", UserWarning ) - return self.fock # trigger creation of fock representation + if self.is_pure: + return State(ket=self.ket() * other) + return State(dm=self.dm() * other) if self._dm is not None: return State(dm=self.dm() * other, modes=self.modes) if self._ket is not None: @@ -590,8 +635,9 @@ def __truediv__(self, other): """ if self.is_gaussian: warnings.warn("scalar division forces conversion to fock representation", UserWarning) - return self.fock - + if self.is_pure: + return State(ket=self.ket() / other) + return State(dm=self.dm() / other) if self._dm is not None: return State(dm=self.dm() / other, modes=self.modes) if self._ket is not None: diff --git a/mrmustard/lab/abstract/transformation.py b/mrmustard/lab/abstract/transformation.py index f8a1456dc..281791937 100644 --- a/mrmustard/lab/abstract/transformation.py +++ b/mrmustard/lab/abstract/transformation.py @@ -19,21 +19,13 @@ from __future__ import annotations -from typing import ( - Callable, - Iterable, - List, - Optional, - Sequence, - Tuple, - Union, -) +from typing import Callable, Iterable, List, Optional, Sequence, Tuple, Union import numpy as np from mrmustard import settings from mrmustard.math import Math -from mrmustard.physics import fock, gaussian +from mrmustard.physics import bargmann, fock, gaussian from mrmustard.training.parameter import Parameter from mrmustard.typing import RealMatrix, RealVector @@ -46,6 +38,23 @@ class Transformation: r"""Base class for all Transformations.""" is_unitary = True # whether the transformation is unitary (True by default) + def bargmann(self, numpy=False): + X, Y, d = self.XYd(allow_none=False) + if self.is_unitary: + A, B, C = bargmann.wigner_to_bargmann_U( + X if X is not None else math.identity(d.shape[-1], dtype=d.dtype), + d if d is not None else math.zeros(X.shape[-1], dtype=X.dtype), + ) + else: + A, B, C = bargmann.wigner_to_bargmann_Choi( + X if X is not None else math.identity(d.shape[-1], dtype=d.dtype), + Y if Y is not None else math.zeros((d.shape[-1], d.shape[-1]), dtype=d.dtype), + d if d is not None else math.zeros(X.shape[-1], dtype=X.dtype), + ) + if numpy: + return math.asnumpy(A), math.asnumpy(B), math.asnumpy(C) + return A, B, C + def primal(self, state: State) -> State: r"""Applies ``self`` (a ``Transformation``) to other (a ``State``) and returns the transformed state. @@ -86,7 +95,7 @@ def transform_gaussian(self, state: State, dual: bool) -> State: Returns: State: the transformed state """ - X, Y, d = self.XYd if not dual else self.XYd_dual + X, Y, d = self.XYd(allow_none=False) if not dual else self.XYd_dual(allow_none=False) cov, means = gaussian.CPTP(state.cov, state.means, X, Y, d, state.modes, self.modes) new_state = State( cov=cov, means=means, modes=state.modes, _norm=state.norm @@ -105,13 +114,15 @@ def transform_fock(self, state: State, dual: bool) -> State: """ op_idx = [state.modes.index(m) for m in self.modes] if self.is_unitary: - U = self.U(cutoffs=[state.cutoffs[i] for i in op_idx]) + # until we have output autocutoff we use the same input cutoff list + U = self.U(cutoffs=[state.cutoffs[i] for i in op_idx] * 2) U = math.dagger(U) if dual else U if state.is_pure: return State(ket=fock.apply_kraus_to_ket(U, state.ket(), op_idx), modes=state.modes) return State(dm=fock.apply_kraus_to_dm(U, state.dm(), op_idx), modes=state.modes) else: - choi = self.choi(cutoffs=[state.cutoffs[i] for i in op_idx]) + # until we have output autocutoff we use the same input cutoff list + choi = self.choi(cutoffs=[state.cutoffs[i] for i in op_idx] * 4) n = state.num_modes N0 = list(range(0, n)) N1 = list(range(n, 2 * n)) @@ -130,7 +141,7 @@ def transform_fock(self, state: State, dual: bool) -> State: def modes(self) -> Sequence[int]: """Returns the list of modes on which the transformation acts on.""" if self._modes in (None, []): - for elem in self.XYd: + for elem in self.XYd(allow_none=True): if elem is not None: self._modes = list(range(elem.shape[-1] // 2)) break @@ -181,59 +192,70 @@ def d_vector_dual(self) -> Optional[RealVector]: if (d := self.d_vector) is None: return None if (Xdual := self.X_matrix_dual) is None: - return d - return math.matmul(Xdual, d) + return -d + return -math.matmul(Xdual, d) - @property - def XYd(self) -> Tuple[Optional[RealMatrix], Optional[RealMatrix], Optional[RealVector]]: + def XYd( + self, allow_none: bool = True + ) -> Tuple[Optional[RealMatrix], Optional[RealMatrix], Optional[RealVector]]: r"""Returns the ```(X, Y, d)``` triple. Override in subclasses if computing ``X``, ``Y`` and ``d`` together is more efficient. """ - return self.X_matrix, self.Y_matrix, self.d_vector - - @property - def XYd_dual(self) -> Tuple[Optional[RealMatrix], Optional[RealMatrix], Optional[RealVector]]: + if allow_none: + return self.X_matrix, self.Y_matrix, self.d_vector + X = math.eye(2 * self.num_modes) if self.X_matrix is None else self.X_matrix + Y = math.zeros_like(X) if self.Y_matrix is None else self.Y_matrix + d = math.zeros_like(X[:, 0]) if self.d_vector is None else self.d_vector + return X, Y, d + + def XYd_dual( + self, allow_none: bool = True + ) -> tuple[Optional[RealMatrix], Optional[RealMatrix], Optional[RealVector]]: r"""Returns the ```(X, Y, d)``` triple of the dual of the current transformation. Override in subclasses if computing ``Xdual``, ``Ydual`` and ``ddual`` together is more efficient. """ - return self.X_matrix_dual, self.Y_matrix_dual, self.d_vector_dual - - @property - def is_phase_covariant(self) -> bool: - X, Y, d = self.XYd - if d is not None: - return False - if X is not None and not math.allclose(self.X, math.diag(math.diag_part(self.X))): - return False - if Y is not None and not math.allclose(self.Y, math.diag(math.diag_part(self.Y))): - return False - return True + if allow_none: + return self.X_matrix_dual, self.Y_matrix_dual, self.d_vector_dual + Xdual = math.eye(2 * self.num_modes) if self.X_matrix_dual is None else self.X_matrix_dual + Ydual = math.zeros_like(Xdual) if self.Y_matrix_dual is None else self.Y_matrix_dual + ddual = math.zeros_like(Xdual[:, 0]) if self.d_vector_dual is None else self.d_vector_dual + return Xdual, Ydual, ddual def U(self, cutoffs: Sequence[int]): r"""Returns the unitary representation of the transformation.""" if not self.is_unitary: return None - X, _, d = self.XYd - return fock.wigner_to_fock_U( - X if X is not None else math.eye(2 * self.num_modes), - d if d is not None else math.zeros((2 * self.num_modes,)), - shape=cutoffs * 2 if len(cutoffs) == self.num_modes else cutoffs, - ) + X, _, d = self.XYd(allow_none=False) + if len(cutoffs) == self.num_modes: + shape = tuple(cutoffs) * 2 + elif len(cutoffs) == 2 * self.num_modes: + shape = tuple(cutoffs) + + else: + raise ValueError( + f"Invalid number of cutoffs: {len(cutoffs)} (expected {self.num_modes} or {2*self.num_modes})" + ) + return fock.wigner_to_fock_U(X, d, shape=shape) def choi(self, cutoffs: Sequence[int]): r"""Returns the Choi representation of the transformation.""" + if len(cutoffs) == self.num_modes: + shape = tuple(cutoffs) * 4 + elif len(cutoffs) == 4 * self.num_modes: + shape = tuple(cutoffs) + else: + raise ValueError( + f"Invalid number of cutoffs: {len(cutoffs)} (expected {self.num_modes} or {4*self.num_modes})" + ) if self.is_unitary: - U = self.U(cutoffs) - return fock.U_to_choi(U) - X, Y, d = self.XYd - return fock.wigner_to_fock_Choi( - X if X is not None else math.eye(2 * self.num_modes), - Y if Y is not None else math.zeros((2 * self.num_modes, 2 * self.num_modes)), - d if d is not None else math.zeros((2 * self.num_modes,)), - shape=cutoffs * 4 if len(cutoffs) == self.num_modes else cutoffs, - ) + U = self.U(shape[: self.num_modes]) + Udual = self.U(shape[self.num_modes :]) + return fock.U_to_choi(U, Udual) + X, Y, d = self.XYd(allow_none=False) + + return fock.wigner_to_fock_Choi(X, Y, d, shape=shape) def __getitem__(self, items) -> Callable: r"""Sets the modes on which the transformation acts. @@ -300,7 +322,9 @@ def __lshift__(self, other: Union[State, Transformation]): return self.dual(other) if isinstance(other, Transformation): return self >> other # so that the dual is self.dual(other.dual(x)) - raise ValueError(f"{other} is not a valid state or transformation.") + raise ValueError( + f"{other} of type {other.__class__} is not a valid state or transformation." + ) # pylint: disable=too-many-branches,too-many-return-statements def __eq__(self, other): @@ -309,59 +333,14 @@ def __eq__(self, other): return False if not (self.is_gaussian and other.is_gaussian): return np.allclose( - self.choi(cutoffs=[settings.EQ_TRANSFORMATION_CUTOFF] * self.num_modes), - other.choi(cutoffs=[settings.EQ_TRANSFORMATION_CUTOFF] * self.num_modes), + self.choi(cutoffs=[settings.EQ_TRANSFORMATION_CUTOFF] * 4 * self.num_modes), + other.choi(cutoffs=[settings.EQ_TRANSFORMATION_CUTOFF] * 4 * self.num_modes), rtol=settings.EQ_TRANSFORMATION_RTOL_FOCK, ) - sX, sY, sd = self.XYd - oX, oY, od = other.XYd - if sX is None: - if oX is not None: - if not np.allclose( - oX, np.eye(oX.shape[0]), rtol=settings.EQ_TRANSFORMATION_RTOL_GAUSS - ): - return False - if oX is None: - if sX is not None: - if not np.allclose( - sX, np.eye(sX.shape[0]), rtol=settings.EQ_TRANSFORMATION_RTOL_GAUSS - ): - return False - if sX is not None and oX is not None: - if not np.allclose(sX, oX): - return False - if sY is None: - if oY is not None: - if not np.allclose( - oY, np.zeros_like(oY), rtol=settings.EQ_TRANSFORMATION_RTOL_GAUSS - ): - return False - if oY is None: - if sY is not None: - if not np.allclose( - sY, np.zeros_like(sY), rtol=settings.EQ_TRANSFORMATION_RTOL_GAUSS - ): - return False - if sY is not None and oY is not None: - if not np.allclose(sY, oY): - return False - if sd is None: - if od is not None: - if not np.allclose( - sd, np.zeros_like(sd), rtol=settings.EQ_TRANSFORMATION_RTOL_GAUSS - ): - return False - if od is None: - if sd is not None: - if not np.allclose( - sd, np.zeros_like(sd), rtol=settings.EQ_TRANSFORMATION_RTOL_GAUSS - ): - return False - if sd is not None and od is not None: - if not np.allclose(sd, od): - return False - return True + sX, sY, sd = self.XYd(allow_none=False) + oX, oY, od = other.XYd(allow_none=False) + return np.allclose(sX, oX) and np.allclose(sY, oY) and np.allclose(sd, od) def __repr__(self): class_name = self.__class__.__name__ diff --git a/mrmustard/lab/circuit.py b/mrmustard/lab/circuit.py index dc34d2708..3b1c2040b 100644 --- a/mrmustard/lab/circuit.py +++ b/mrmustard/lab/circuit.py @@ -20,12 +20,12 @@ __all__ = ["Circuit"] -from mrmustard.typing import RealMatrix, RealVector from typing import List, Optional, Tuple from mrmustard import settings from mrmustard.lab.abstract import State, Transformation from mrmustard.training import Parametrized +from mrmustard.typing import RealMatrix, RealVector from mrmustard.utils.circdrawer import circuit_text from mrmustard.utils.xptensor import XPMatrix, XPVector @@ -62,9 +62,9 @@ def dual(self, state: State) -> State: state = op.dual(state) return state - @property def XYd( self, + allow_none: bool = True, ) -> Tuple[ RealMatrix, RealMatrix, RealVector ]: # NOTE: Overriding Transformation.XYd for efficiency @@ -72,7 +72,7 @@ def XYd( Y = XPMatrix(like_0=True) d = XPVector() for op in self._ops: - opx, opy, opd = op.XYd + opx, opy, opd = op.XYd(allow_none) opX = XPMatrix.from_xxpp(opx, modes=(op.modes, op.modes), like_1=True) opY = XPMatrix.from_xxpp(opy, modes=(op.modes, op.modes), like_0=True) opd = XPVector.from_xxpp(opd, modes=op.modes) diff --git a/mrmustard/lab/detectors.py b/mrmustard/lab/detectors.py index f6fb600ae..578f30d1d 100644 --- a/mrmustard/lab/detectors.py +++ b/mrmustard/lab/detectors.py @@ -16,8 +16,7 @@ This module implements the set of detector classes that perform measurements on quantum circuits. """ -from typing import List, Tuple, Union, Optional, Iterable - +from typing import Iterable, List, Optional, Tuple, Union from mrmustard import settings from mrmustard.math import Math diff --git a/mrmustard/lab/gates.py b/mrmustard/lab/gates.py index 586ce3fc8..f497e663c 100644 --- a/mrmustard/lab/gates.py +++ b/mrmustard/lab/gates.py @@ -18,13 +18,14 @@ This module defines gates and operations that can be applied to quantum modes to construct a quantum circuit. """ -from typing import Union, Optional, List, Tuple, Sequence -from mrmustard.typing import RealMatrix, ComplexMatrix +from typing import List, Optional, Sequence, Tuple, Union + from mrmustard import settings from mrmustard.lab.abstract import Transformation from mrmustard.math import Math -from mrmustard.physics import gaussian, fock +from mrmustard.physics import fock, gaussian from mrmustard.training import Parametrized +from mrmustard.typing import ComplexMatrix, RealMatrix math = Math() @@ -94,28 +95,45 @@ def d_vector(self): return gaussian.displacement(self.x.value, self.y.value, settings.HBAR) def U(self, cutoffs: Sequence[int]): - """Returns the unitary representation of the Displacement gate using the Laguerre - polynomials.""" + r"""Returns the unitary representation of the Displacement gate using + the Laguerre polynomials. + + Arguments: + cutoffs (Sequence[int]): the Hilbert space dimension cutoff for each mode + + Returns: + Raises: + ValueError: if the length of the cutoffs array is different from N and 2N + """ N = self.num_modes x = self.x.value * math.ones(N, dtype=self.x.value.dtype) y = self.y.value * math.ones(N, dtype=self.y.value.dtype) - r = math.sqrt(x * x + y * y) - phi = math.atan2(y, x) - - # calculate displacement unitary for each mode and concatenate with outer product - Ud = None - for idx, cutoff in enumerate(cutoffs): - if Ud is None: - Ud = fock.displacement(r[idx], phi[idx], cutoff) - else: - U_next = fock.displacement(r[idx], phi[idx], cutoff) - Ud = math.outer(Ud, U_next) + if len(cutoffs) == N: + shape = tuple(cutoffs) * 2 + elif len(cutoffs) == 2 * N: + shape = tuple(cutoffs) + else: + raise ValueError( + "len(cutoffs) should be either equal to the number of modes or twice the number of modes (for output-input)." + ) - return math.transpose( - Ud, - list(range(0, 2 * N, 2)) + list(range(1, 2 * N, 2)), - ) + if N > 1: + # calculate displacement unitary for each mode and concatenate with outer product + Ud = None + for idx, out_in in enumerate(zip(shape[:N], shape[N:])): + if Ud is None: + Ud = fock.displacement(x[idx], y[idx], shape=out_in) + else: + U_next = fock.displacement(x[idx], y[idx], shape=out_in) + Ud = math.outer(Ud, U_next) + + return math.transpose( + Ud, + list(range(0, 2 * N, 2)) + list(range(1, 2 * N, 2)), + ) + else: + return fock.displacement(x[0], y[0], shape=shape) class Sgate(Parametrized, Transformation): @@ -160,6 +178,43 @@ def __init__( self.is_gaussian = True self.short_name = "S" + def U(self, cutoffs: Sequence[int]): + r"""Returns the unitary representation of the Squeezing gate. + Args: + cutoffs (Sequence[int]): the Hilbert space dimension cutoff for each mode + + Returns: + array[complex]: the unitary matrix + """ + N = self.num_modes + if len(cutoffs) == N: + shape = tuple(cutoffs) * 2 + elif len(cutoffs) == 2 * N: + shape = tuple(cutoffs) + else: + raise ValueError( + "len(cutoffs) should be either equal to the number of modes or twice the number of modes (for output-input)." + ) + # this works both or scalar r/phi and vector r/phi: + r = self.r.value * math.ones(N, dtype=self.r.value.dtype) + phi = self.phi.value * math.ones(N, dtype=self.phi.value.dtype) + + if N > 1: + # calculate squeezing unitary for each mode and concatenate with outer product + Us = None + for idx, single_shape in enumerate(zip(shape[:N], shape[N:])): + if Us is None: + Us = fock.squeezer(r[idx], phi[idx], shape=single_shape) + else: + U_next = fock.squeezer(r[idx], phi[idx], shape=single_shape) + Us = math.outer(Us, U_next) + return math.transpose( + Us, + list(range(0, 2 * N, 2)) + list(range(1, 2 * N, 2)), + ) + else: + return fock.squeezer(r[0], phi[0], shape=shape) + @property def X_matrix(self): return gaussian.squeezing_symplectic(self.r.value, self.phi.value) @@ -203,13 +258,32 @@ def __init__( def X_matrix(self): return gaussian.rotation_symplectic(self.angle.value) - def U(self, cutoffs: Sequence[int]): + def U(self, cutoffs: Sequence[int], diag_only=False): + r"""Returns the unitary representation of the Rotation gate. + + Args: + cutoffs (Sequence[int]): cutoff dimension for each mode. + diag_only (bool): if True, only return the diagonal of the unitary matrix. + + Returns: + array[complex]: the unitary matrix + """ + if diag_only: + raise NotImplementedError("Rgate does not support diag_only=True yet") + N = self.num_modes + if len(cutoffs) == N: + shape = tuple(cutoffs) * 2 + elif len(cutoffs) == 2 * N: + shape = tuple(cutoffs) + else: + raise ValueError( + "len(cutoffs) should be either equal to the number of modes or twice the number of modes (for output-input)." + ) angles = self.angle.value * math.ones(self.num_modes, dtype=self.angle.value.dtype) - num_modes = len(cutoffs) # calculate rotation unitary for each mode and concatenate with outer product Ur = None - for idx, cutoff in enumerate(cutoffs): + for idx, cutoff in enumerate(shape[: self.num_modes]): theta = math.arange(cutoff) * angles[idx] if Ur is None: Ur = math.diag(math.make_complex(math.cos(theta), math.sin(theta))) @@ -220,7 +294,7 @@ def U(self, cutoffs: Sequence[int]): # return total unitary with indexes reordered according to MM convention return math.transpose( Ur, - list(range(0, 2 * num_modes, 2)) + list(range(1, 2 * num_modes, 2)), + list(range(0, 2 * self.num_modes, 2)) + list(range(1, 2 * self.num_modes, 2)), ) @@ -367,6 +441,33 @@ def __init__( self.is_gaussian = True self.short_name = "BS" + def U(self, cutoffs: Optional[List[int]], method=None): + r"""Returns the symplectic transformation matrix for the beam splitter. + + Args: + cutoffs (List[int]): the list of cutoff dimensions for each mode + in the order (out_0, out_1, in_0, in_1). + method (str): the method used to compute the unitary matrix. Options are: + * 'vanilla': uses the standard method + * 'schwinger': slower, but numerically stable + default is set in settings.DEFAULT_BS_METHOD (with 'vanilla' by default) + + Returns: + array[complex]: the unitary tensor of the beamsplitter + """ + if len(cutoffs) == 4: + shape = tuple(cutoffs) + elif len(cutoffs) == 2: + shape = tuple(cutoffs) + tuple(cutoffs) + else: + raise ValueError(f"Invalid len(cutoffs): {len(cutoffs)} (should be 2 or 4).") + return fock.beamsplitter( + self.theta.value, + self.phi.value, + shape=shape, + method=method or settings.DEFAULT_BS_METHOD, + ) + @property def X_matrix(self): return gaussian.beam_splitter_symplectic(self.theta.value, self.phi.value) diff --git a/mrmustard/lab/states.py b/mrmustard/lab/states.py index 7d08ff140..ea10e1d73 100644 --- a/mrmustard/lab/states.py +++ b/mrmustard/lab/states.py @@ -486,22 +486,29 @@ def __init__( def _preferred_projection(self, other: State, mode_indices: Sequence[int]): r"""Preferred method to perform a projection onto this state (rather than the default one). - E.g. ``ket << Fock(1, modes=[3])`` is equivalent to ``ket[:,:,:,1]`` if ``ket`` has 4 modes - E.g. ``dm << Fock(1, modes=[1])`` is equivalent to ``dm[:,1,:,1]`` if ``dm`` has 2 modes + E.g. ``ket << Fock([1], modes=[3])`` is equivalent to ``ket[:,:,:,1]`` if ``ket`` has 4 modes + E.g. ``dm << Fock([1], modes=[1])`` is equivalent to ``dm[:,1,:,1]`` if ``dm`` has 2 modes Args: other: the state to project onto this state mode_indices: the indices of the modes of other that we want to project onto self """ getitem = [] + cutoffs = [] used = 0 for i, _ in enumerate(other.modes): if i in mode_indices: getitem.append(self._n[used]) + cutoffs.append(self._n[used] + 1) used += 1 else: getitem.append(slice(None)) - output = other.fock[tuple(getitem)] if other.is_pure else other.fock[tuple(getitem) * 2] + cutoffs.append(other.cutoffs[i]) + output = ( + other.ket(cutoffs)[tuple(getitem)] + if other.is_hilbert_vector + else other.dm(cutoffs)[tuple(getitem) * 2] + ) if self._normalize: return fock.normalize(output, is_dm=other.is_mixed) return output diff --git a/mrmustard/math/lattice/__init__.py b/mrmustard/math/lattice/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/mrmustard/math/lattice/neighbors.py b/mrmustard/math/lattice/neighbors.py new file mode 100644 index 000000000..b9fe131dc --- /dev/null +++ b/mrmustard/math/lattice/neighbors.py @@ -0,0 +1,74 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""neighbours functions""" + +from typing import Iterator + +from numba import njit +from numba.cpython.unsafe.tuple import tuple_setitem + +################################################################################# +## All neighbours means all the indices that differ from the given pivot by ±1 ## +################################################################################# + + +@njit +def all_neighbors(pivot: tuple[int, ...]) -> Iterator[tuple[int, tuple[int, ...]]]: + r"""yields the indices of all the neighbours of the given index.""" + for j in range(len(pivot)): # pylint: disable=consider-using-enumerate + yield j, tuple_setitem(pivot, j, pivot[j] - 1) + yield j, tuple_setitem(pivot, j, pivot[j] + 1) + + +#################################################################################### +## Lower neighbours means all the indices that differ from the given index by -1 ## +#################################################################################### + + +@njit +def lower_neighbors(pivot: tuple[int, ...]) -> Iterator[tuple[int, tuple[int, ...]]]: + r"""yields the indices of the lower neighbours of the given index.""" + for j in range(len(pivot)): # pylint: disable=consider-using-enumerate + yield j, tuple_setitem(pivot, j, pivot[j] - 1) + + +#################################################################################### +## Upper neighbours means all the indices that differ from the given index by +1 ## +#################################################################################### + + +@njit +def upper_neighbors(pivot: tuple[int, ...]) -> Iterator[tuple[int, tuple[int, ...]]]: + r"""yields the indices of the lower neighbours of the given index.""" + for j in range(len(pivot)): + yield j, tuple_setitem(pivot, j, pivot[j] + 1) + + +#################################################################################################### +## bitstring neighbours are indices that differ from the given index by ±1 according to a bitstring +#################################################################################################### + + +@njit +def bitstring_neighbors( + pivot: tuple[int, ...], bitstring: tuple[int, ...] +) -> Iterator[tuple[int, tuple[int, ...]]]: + r"yields the indices of the bitstring neighbours of the given index" + for i, b in enumerate(bitstring): + if b: # b == 1 -> lower + yield i, tuple_setitem(pivot, i, pivot[i] - 1) + else: # b == 0 -> upper + yield i, tuple_setitem(pivot, i, pivot[i] + 1) diff --git a/mrmustard/math/lattice/paths.py b/mrmustard/math/lattice/paths.py new file mode 100644 index 000000000..4f3169a30 --- /dev/null +++ b/mrmustard/math/lattice/paths.py @@ -0,0 +1,81 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Path functions""" + +from numba import njit, typed, typeof, types +from numba.cpython.unsafe.tuple import tuple_setitem + +BINOMIAL_PATHS_PYTHON = {} + + +@njit +def _binomial_subspace_basis( + cutoffs: tuple[int, ...], + weight: int, + mode: int, + basis_element: tuple[int, ...], + basis: typed.List[tuple[int, ...]], +): + r"""Step of the recursive function to generate all indices + of a tensor with equal weight. + If cutoffs is an empty tuple, the the basis element is appended to the list. + Otherwise it loops over the values of the given mode, and it calls itself recursively + to construct the rest of the basis elements. + + Arguments: + cutoffs (tuple[int, ...]): the cutoffs of the tensor + weight (int): the weight of the subspace + mode (int): the mode to loop over + basis_element (tuple[int, ...]): the current basis element to construct + basis (list[tuple[int, ...]]): the list of basis elements to eventually append to + """ + if mode == len(cutoffs): + if weight == 0: # ran out of photons to distribute + basis.append(basis_element) + return + + for photons in range(cutoffs[mode]): # could be prange? + if weight - photons >= 0: + basis_element = tuple_setitem(basis_element, mode, photons) + _binomial_subspace_basis(cutoffs, weight - photons, mode + 1, basis_element, basis) + + +@njit +def binomial_subspace_basis(cutoffs: tuple[int, ...], weight: int): + r"""Returns all indices of a tensor with given weight. + + Arguments: + cutoffs (tuple[int, ...]): the cutoffs of the tensor + weight (int): the weight of the subspace + + Returns: + list[tuple[int, ...]]: the list of basis elements of the subspace + """ + basis = typed.List( + [cutoffs] + ) # this is just so that numba can infer the type, then we remove it + _binomial_subspace_basis(cutoffs, weight, 0, cutoffs, basis) + return basis[1:] # remove the dummy element + + +def BINOMIAL_PATHS_NUMBA_n(modes): + r"Creates a numba dictionary to store the paths and effectively cache them." + return typed.Dict.empty( + key_type=typeof(((0,) * modes, 0)), + value_type=types.ListType(typeof((0,) * modes)), + ) + + +BINOMIAL_PATHS_NUMBA = {modes: BINOMIAL_PATHS_NUMBA_n(modes) for modes in range(1, 100)} diff --git a/mrmustard/math/lattice/pivots.py b/mrmustard/math/lattice/pivots.py new file mode 100644 index 000000000..bc564f614 --- /dev/null +++ b/mrmustard/math/lattice/pivots.py @@ -0,0 +1,55 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from numba import njit +from numba.cpython.unsafe.tuple import tuple_setitem + + +@njit +def first_available_pivot(index: tuple[int, ...]) -> tuple[int, tuple[int, ...]]: + r"""returns the first available pivot for the given index. A pivot is a nearest neighbor + of the index. Here we pick the first available pivot. + + Arguments: + index: the index to get the first available pivot of. + + Returns: + the index that was decremented and the pivot + """ + for i, v in enumerate(index): + if v > 0: + return i, tuple_setitem(index, i, v - 1) + raise ValueError("Index is zero") + + +@njit +def smallest_pivot(index: tuple[int, ...]) -> tuple[int, tuple[int, ...]]: + r"""returns the pivot closest to a zero index. A pivot is a nearest neighbor + of the index. Here we pick the pivot with the smallest non-zero element. + + Arguments: + index: the index to get the smallest pivot of. + + Returns: + (int, tuple) the index of the element that was decremented and the pivot + """ + min_ = 2**64 - 1 + for i, v in enumerate(index): + if 0 < v < min_: + min_ = v + min_i = i + if min_ == 2**64 - 1: + raise ValueError("Index is zero") + return min_i, tuple_setitem(index, min_i, min_ - 1) diff --git a/mrmustard/math/lattice/steps.py b/mrmustard/math/lattice/steps.py new file mode 100644 index 000000000..573e04e5a --- /dev/null +++ b/mrmustard/math/lattice/steps.py @@ -0,0 +1,223 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Recurrencies for Fock-Bargmann amplitudes put together a strategy for +# enumerating the indices in a specific order and functions for calculating +# which neighbours to use in the calculation of the amplitude at a given index. +# In summary, they return the value of the amplitude at the given index by following +# a recipe made of two parts. The function to recompute A and b is determined by +# which neighbours are used. + +"""Fock-Bargmann recurrence relation steps for Gaussian states.""" + +import numpy as np +from numba import njit, prange, types +from numba.cpython.unsafe.tuple import tuple_setitem + +from mrmustard.math.lattice.neighbors import lower_neighbors +from mrmustard.math.lattice.pivots import first_available_pivot +from mrmustard.typing import ComplexMatrix, ComplexTensor, ComplexVector + +SQRT = np.sqrt(np.arange(100000)) + + +@njit +def vanilla_step( + G: ComplexTensor, + A: ComplexMatrix, + b: ComplexVector, + index: tuple[int, ...], +) -> complex: + r"""Fock-Bargmann recurrence relation step, vanilla version. + This function returns the amplitude of the Gaussian tensor G + at G[index]. It does not modify G. + The necessary pivot and neighbours must have already been computed, + as this step will read those values from G. + + Args: + G (array or dict): fock amplitudes data store that supports getitem[tuple[int, ...]] + A (array): A matrix of the Fock-Bargmann representation + b (array): B vector of the Fock-Bargmann representation + index (Sequence): index of the amplitude to calculate + Returns: + complex: the value of the amplitude at the given index + """ + # get pivot + i, pivot = first_available_pivot(index) + + # pivot contribution + value_at_index = b[i] * G[pivot] + + # neighbors contribution + for j, neighbor in lower_neighbors(pivot): + value_at_index += A[i, j] * SQRT[pivot[j]] * G[neighbor] + + return value_at_index / SQRT[index[i]] + + +@njit +def vanilla_step_jacobian( + G: ComplexTensor, + A: ComplexMatrix, + b: ComplexVector, + index: tuple[int, ...], + dGdA: ComplexTensor, + dGdB: ComplexTensor, +) -> tuple[ComplexTensor, ComplexTensor]: + r"""Jacobian contribution of a single Fock-Bargmann recurrence relation step, vanilla version. + It updates the dGdB and dGdA tensors at the given index. + + Args: + G (array or dict): fully computed store that supports __getitem__(index: tuple[int, ...]) + A (array): A matrix of the Fock-Bargmann representation + b (array): B vector of the Fock-Bargmann representation + c (complex): vacuum amplitude + index (Sequence): index at which to compute the jacobian + dGdB (array): gradient of G with respect to b (partially computed) + dGdA (array): gradient of G with respect to A (partially computed) + Returns: + tuple[array, array]: the dGdB and dGdA tensors updated at the given index + """ + # index -> pivot + i, pivot = first_available_pivot(index) + + # pivot contribution + dGdB[index] += b[i] * dGdB[pivot] / SQRT[index[i]] + dGdB[index + (i,)] += G[pivot] / SQRT[index[i]] + dGdA[index] += b[i] * dGdA[pivot] / SQRT[index[i]] + + # neighbors contribution + for j, neighbor in lower_neighbors(pivot): + dGdB[index] += A[i, j] * dGdB[neighbor] * SQRT[pivot[j]] / SQRT[index[i]] + dGdA[index] += A[i, j] * dGdA[neighbor] * SQRT[pivot[j]] / SQRT[index[i]] + dGdA[index + (i, j)] += G[neighbor] * SQRT[pivot[j]] / SQRT[index[i]] + + return dGdA, dGdB + + +@njit +def vanilla_step_grad( + G: ComplexTensor, + index: tuple[int, ...], + dA: ComplexMatrix, + db: ComplexVector, +) -> tuple[ComplexMatrix, ComplexVector]: + r"""Gradient with respect to A and b of a single Fock-Bargmann recurrence relation step, + vanilla version. dA and db can be used to update the dGdB and dGdA tensors at `index`, + or as part of the contraction with the gradient of the Gaussian tensor G. + Note that the gradient depends only on G and not on the values of A and b. + + Args: + G (array or dict): fully computed store that supports __getitem__(index: tuple[int, ...]) + index (Sequence): index of the amplitude to calculate the gradient of + dA (array): empty array to store the gradient of G[index] with respect to A + db (array): empty array to store the gradient of G[index] with respect to B + Returns: + tuple[array, array]: the updated dGdB and dGdA tensors + """ + for i in range(len(db)): # pylint: disable=consider-using-enumerate + pivot_i = tuple_setitem(index, i, index[i] - 1) + db[i] = SQRT[index[i]] * G[pivot_i] + dA[i, i] = 0.5 * SQRT[index[i] * pivot_i[i]] * G[tuple_setitem(pivot_i, i, pivot_i[i] - 1)] + for j in range(i + 1, len(db)): + dA[i, j] = SQRT[index[i] * pivot_i[j]] * G[tuple_setitem(pivot_i, j, pivot_i[j] - 1)] + + return dA, db + + +@njit +def vanilla_step_dict( + data: types.DictType, A: ComplexMatrix, b: ComplexVector, index: tuple[int, ...] +) -> complex: + r"""Fock-Bargmann recurrence relation step, vanilla version with numba dict. + This function calculates the index `index` of the Gaussian tensor `G`. + The appropriate pivot and neighbours must exist. + + Args: + data: dict(tuple[int,...], complex): fock amplitudes numba dict + A (array): A matrix of the Fock-Bargmann representation + b (array): b vector of the Fock-Bargmann representation + index (Sequence): index of the amplitude to calculate + Returns: + complex: the value of the amplitude at the given index + """ + # index -> pivot + i, pivot = first_available_pivot(index) + + # calculate value at index: pivot contribution + denom = SQRT[pivot[i] + 1] + value_at_index = b[i] / denom * data[pivot] + + # neighbors contribution + for j, neighbor in lower_neighbors(pivot): + value_at_index += A[i, j] / denom * SQRT[pivot[j]] * data.get(neighbor, 0.0 + 0.0j) + + return value_at_index + + +@njit +def binomial_step( + G: ComplexTensor, A: ComplexMatrix, b: ComplexVector, subspace_indices: list[tuple[int, ...]] +) -> tuple[ComplexTensor, float]: + r"""Computes a whole subspace of the ``G`` tensor at the indices in + ``subspace_indices`` (a subspace is such that `sum(index) = const`). + It updates the tensor ``G``. + It returns the updated tensor and the probability of the subspace. + + Args: + G (np.ndarray): Tensor filled up to the previous subspace + A (np.ndarray): A matrix of the Fock-Bargmann representation + b (np.ndarray): B vector of the Fock-Bargmann representation + subspace_indices (list[tuple[int, ...]]): list of indices to be updated + + Returns: + tuple[np.ndarray, float]: updated tensor and probability of the subspace + """ + norm = 0.0 + + for i in prange(len(subspace_indices)): + value = vanilla_step(G, A, b, subspace_indices[i]) + G[subspace_indices[i]] = value + norm = norm + np.abs(value) ** 2 + + return G, norm + + +@njit +def binomial_step_dict( + G: types.DictType, A: ComplexMatrix, b: ComplexVector, subspace_indices: list[tuple[int, ...]] +) -> tuple[types.DictType, float]: + r"""Computes a whole subspace of the ``G`` dict at the indices in + ``subspace_indices`` (a subspace is such that `sum(index) = const`). + It updates the dict ``G``. It returns the updated G dict + and the total probability of the subspace. + + Args: + G (types.DictType): Dictionary filled up to the previous subspace + A (np.ndarray): A matrix of the Fock-Bargmann representation + b (np.ndarray): B vector of the Fock-Bargmann representation + subspace_indices (list[tuple[int, ...]]): list of indices to be updated + + Returns: + tuple[types.DictType, float]: updated dictionary and probability of the subspace + """ + prob = 0.0 + + for i in prange(len(subspace_indices)): + value = vanilla_step_dict(G, A, b, subspace_indices[i]) + G[subspace_indices[i]] = value + prob = prob + np.abs(value) ** 2 + + return G, prob diff --git a/mrmustard/math/lattice/strategies/__init__.py b/mrmustard/math/lattice/strategies/__init__.py new file mode 100644 index 000000000..66a96b326 --- /dev/null +++ b/mrmustard/math/lattice/strategies/__init__.py @@ -0,0 +1,19 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from .beamsplitter import * +from .binomial import * +from .displacement import * +from .squeezer import * +from .vanilla import * diff --git a/mrmustard/math/lattice/strategies/beamsplitter.py b/mrmustard/math/lattice/strategies/beamsplitter.py new file mode 100644 index 000000000..285ff9901 --- /dev/null +++ b/mrmustard/math/lattice/strategies/beamsplitter.py @@ -0,0 +1,204 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Recurrencies for Fock-Bargmann amplitudes put together a strategy for +# enumerating the indices in a specific order and functions for calculating +# which neighbours to use in the calculation of the amplitude at a given index. +# In summary, they return the value of the amplitude at the given index by following +# a recipe made of two parts. The function to recompute A and b is determined by +# which neighbours are used. + +"""Fock-Bargmann recurrence relation steps optimized for beamsplitter.""" + +import numpy as np +from numba import njit + +from mrmustard.math.lattice import steps +from mrmustard.typing import ComplexMatrix, ComplexTensor, ComplexVector + +SQRT = np.sqrt(np.arange(100000)) + +__all__ = ["beamsplitter", "beamsplitter_vjp", "beamsplitter_schwinger"] + + +@njit +def beamsplitter( + shape: tuple[int, int, int, int], theta: float, phi: float, dtype=np.complex128 +) -> ComplexTensor: # pragma: no cover + r"""Calculates the Fock representation of the beamsplitter. + It takes advantage of input-output particle conservation (m+n=p+q) + to avoid one for loop. Inspired from the original implementation in + the walrus by @ziofil. Here is how the parameters are used in the + code (see eq. 73-75 in https://arxiv.org/abs/2004.11002): + + A = [[0,V],[v^T,0]] # BS bargmann matrix + V = [[ct, -st expm], # BS unitary + [st exp, ct]] + + Args: + shape (tuple[int, int, int, int]): shape of the Fock representation + theta (float): beamsplitter angle + phi (float): beamsplitter phase + dtype (np.dtype): data type of the Fock representation + + Returns: + array (ComplexTensor): The Fock representation of the gate + """ + ct = np.cos(theta) + st = np.sin(theta) * np.exp(1j * phi) + stc = np.conj(st) + + M, N, P, Q = shape + G = np.zeros(shape, dtype=dtype) + G[0, 0, 0, 0] = 1.0 + + # rank 3 + for m in range(M): + for n in range(N - m): + p = m + n + if 0 < p < P: + G[m, n, p, 0] = ( + ct * SQRT[m] / SQRT[p] * G[m - 1, n, p - 1, 0] + + st * SQRT[n] / SQRT[p] * G[m, n - 1, p - 1, 0] + ) + + # rank 4 + for m in range(M): + for n in range(N): + for p in range(P): + q = m + n - p + if 0 < q < Q: + G[m, n, p, q] = ( + -stc * SQRT[m] / SQRT[q] * G[m - 1, n, p, q - 1] + + ct * SQRT[n] / SQRT[q] * G[m, n - 1, p, q - 1] + ) + return G + + +@njit +def beamsplitter_vjp( + G: ComplexTensor, + dLdG: ComplexTensor, + theta: float, + phi: float, +) -> tuple[ComplexMatrix, ComplexVector, complex]: # pragma: no cover + r"""Beamsplitter gradients with respect to theta and phi. + This function could return dL/dA, dL/db, dL/dc like its vanilla counterpart, + but it is more efficient to include this chain rule step in the numba function, + since we can. + + We use these derivatives of the BS unitary: + + dVdt = [[-st, -ct exp], + [ct exp, -st]] + dVdphi = [[0, -i ct expm], + [i ct exp, 0]] + + Args: + G (np.ndarray): Tensor result of the forward pass + dLdG (np.ndarray): gradient of the loss with respect to the output tensor + theta (float): beamsplitter angle + phi (float): beamsplitter phase + + Returns: + tuple[float, float]: dL/dtheta, dL/dphi + """ + M, N, P, Q = G.shape + + # init gradients + dA = np.zeros((4, 4), dtype=np.complex128) + db = np.zeros(4, dtype=np.complex128) + dLdA = np.zeros_like(dA) + dLdb = np.zeros_like(db) + + # rank 3 + for m in range(M): + for n in range(N - m): + p = m + n + if 0 < p < P: + dA, db = steps.vanilla_step_grad(G, (m, n, p, 0), dA, db) + dLdA += dA * dLdG[m, n, p, 0] + dLdb += db * dLdG[m, n, p, 0] + + # rank 4 + for m in range(M): + for n in range(N): + for p in range(P): + q = m + n - p + if 0 < q < Q: + dA, db = steps.vanilla_step_grad(G, (m, n, p, q), dA, db) + dLdA += dA * dLdG[m, n, p, q] + dLdb += db * dLdG[m, n, p, q] + + st = np.sin(theta) + ct = np.cos(theta) + e = np.exp(1j * phi) + em = np.exp(-1j * phi) + + # omitting bottom-left block because dLdA should be zero there + dLdtheta = 2 * np.real( + -st * dLdA[0, 2] - ct * em * dLdA[0, 3] + ct * e * dLdA[1, 2] - st * dLdA[1, 3] + ) + dLdphi = 2 * np.real(1j * st * em * dLdA[0, 3] + 1j * st * e * dLdA[1, 2]) + + return dLdtheta, dLdphi + + +def beamsplitter_schwinger(shape, theta, phi, max_N=None): + r"""Returns the Fock representation of the beamsplitter up to + the given cutoff for each of the two modes. + + This implementation is in pure python (so it's slower than the numba version), + but it's numerically stable up to arbitrary cutoffs. + + In this implementation we split the two-mode Fock basis into finite subsets spanned + by |m,n> with m+n=const, i.e. {|0,0>}, {|1,0>,|0,1>}, {|2,0>, |1,1>, |0,2>}, etc... + A beamsplitter acts unitariliy in each of these subspaces without mixing them with each other, + i.e. in this basis the beamsplitter would be a block-diagonal matrix. + This means we can construct the BS matrix by first calculating the BS unitaries + in each of these subspaces. + This can be done using the matrix exponential, which is numerically stable. + We couldn't do this in the original basis because it was infinite-dimensional + and we had to truncate it at some point. + + Arguments: + shape (int, int, int, int): The shape of the output tensor. Only shapes of the form (i,k,i,k) are supported. + theta (float): The angle of the beamsplitter. + phi (float): The phase of the beamsplitter. + max_N (int): The maximum total photon number to include in the calculation. + + Returns: + np.ndarray: The beamsplitter in the Fock basis. + """ + c1, c2, c3, c4 = shape + if c1 != c3 or c2 != c4: + raise ValueError("The Schwinger method only supports shapes of the form (i,k,i,k).") + # create output tensor + U = np.zeros(shape, dtype="complex128") + + # loop over subspaces of constant photon number N up to max_N + if max_N is None or max_N > c1 + c2 - 2: + max_N = c1 + c2 - 2 + for N in range(max_N + 1): + # construct the N+1 x N+1 unitary for this subspace + diag = np.exp(1j * phi) * np.sqrt(np.arange(N, 0, -1) * np.arange(1, N + 1, 1)) + iJy = np.diag(diag, k=-1) - np.diag(np.conj(diag), k=1) + E, V = np.linalg.eig(theta * iJy) + block = V @ np.diag(np.exp(E)) @ np.conj(V.T) + # insert the elements of the block into the output tensor + for i in range(max(0, N + 1 - c1), min(N + 1, c1)): + for j in range(max(0, N + 1 - c1), min(N + 1, c2)): + U[N - i, i, N - j, j] = block[i, j] + return U diff --git a/mrmustard/math/lattice/strategies/binomial.py b/mrmustard/math/lattice/strategies/binomial.py new file mode 100644 index 000000000..771675d1a --- /dev/null +++ b/mrmustard/math/lattice/strategies/binomial.py @@ -0,0 +1,160 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +" This module contains binomial strategies " + +from typing import Optional + +import numpy as np +from numba import njit, typed, types + +from mrmustard.math.lattice import paths, steps +from mrmustard.typing import ComplexMatrix, ComplexTensor, ComplexVector + +SQRT = np.sqrt(np.arange(100000)) + +__all__ = ["binomial", "binomial_dict", "binomial_numba"] + + +def binomial( + local_cutoffs: tuple[int, ...], + A: ComplexMatrix, + b: ComplexVector, + c: complex, + max_l2: float, + global_cutoff: int, +) -> ComplexTensor: + r"""Binomial strategy (fill ket by weight), python version with numba function/loop. + + Args: + local_cutoffs (tuple[int, ...]): local cutoffs of the tensor (used at least as shape) + A (np.ndarray): A matrix of the Fock-Bargmann representation + b (np.ndarray): B vector of the Fock-Bargmann representation + c (complex): vacuum amplitude + max_l2 (float): max L2 norm. If reached, the computation is stopped early. + global_cutoff (Optional[int]): global cutoff (max total photon number considered + 1). + + Returns: + G, prob (np.ndarray, float): Fock representation of the Gaussian tensor with shape ``shape`` and L2 norm + """ + # init output tensor + G = np.zeros(local_cutoffs, dtype=np.complex128) + + # write vacuum amplitude + G.flat[0] = c + norm = np.abs(c) ** 2 + + # iterate over subspaces by weight and stop if norm is large enough. Caches indices. + for photons in range(1, global_cutoff): + try: + indices = paths.BINOMIAL_PATHS_PYTHON[(local_cutoffs, photons)] + except KeyError: + indices = paths.binomial_subspace_basis(local_cutoffs, photons) + paths.BINOMIAL_PATHS_PYTHON[(local_cutoffs, photons)] = indices + G, subspace_norm = steps.binomial_step(G, A, b, indices) # numba parallelized function + norm += subspace_norm + try: + if norm > max_l2: + break + except TypeError: # max_l2 is None + pass + return G, norm + + +def binomial_dict( + local_cutoffs: tuple[int, ...], + A: ComplexMatrix, + b: ComplexVector, + c: complex, + max_prob: Optional[float] = None, + global_cutoff: Optional[int] = None, +) -> dict[tuple[int, ...], complex]: + r"""Factorial speedup strategy (fill ket by weight), python version with numba function/loop. + Uses a dictionary to store the output. + + Args: + local_cutoffs (tuple[int, ...]): local cutoffs of the tensor (used at least as shape) + A (np.ndarray): A matrix of the Fock-Bargmann representation + b (np.ndarray): B vector of the Fock-Bargmann representation + c (complex): vacuum amplitude + max_prob (float): max L2 norm. If reached, the computation is stopped early. + global_cutoff (Optional[int]): global cutoff (max total photon number considered). + If not given it is calculated from the local cutoffs. + + Returns: + dict[tuple[int, ...], complex]: Fock representation of the Gaussian tensor. + """ + if global_cutoff is None: + global_cutoff = sum(local_cutoffs) - len(local_cutoffs) + + # init numba output dict + G = typed.Dict.empty( + key_type=types.UniTuple(types.int64, len(local_cutoffs)), + value_type=types.complex128, + ) + + # write vacuum amplitude + G[(0,) * len(local_cutoffs)] = c + prob = np.abs(c) ** 2 + + # iterate over subspaces by weight and stop if norm is large enough. Caches indices. + for photons in range(1, global_cutoff): + try: + indices = paths.BINOMIAL_PATHS_PYTHON[(local_cutoffs, photons)] + except KeyError: + indices = paths.binomial_subspace_basis(local_cutoffs, photons) + paths.BINOMIAL_PATHS_PYTHON[(local_cutoffs, photons)] = indices + G, prob_subspace = steps.binomial_step_dict(G, A, b, indices) # numba parallelized function + prob += prob_subspace + try: + if prob > max_prob: + break + except TypeError: + pass + return G + + +@njit +def binomial_numba( + local_cutoffs: tuple[int, ...], + A: ComplexMatrix, + b: ComplexVector, + c: complex, + FP: dict[tuple[tuple[int, ...], int], list[tuple[int, ...]]], + max_prob: float = 0.999, + global_cutoff: Optional[int] = None, +) -> ComplexTensor: # pragma: no cover + r"""Binomial strategy (fill by weight), fully numba version.""" + if global_cutoff is None: + global_cutoff = sum(local_cutoffs) - len(local_cutoffs) + + # init output tensor + G = np.zeros(local_cutoffs, dtype=np.complex128) + + # write vacuum amplitude + G.flat[0] = c + prob = np.abs(c) ** 2 + + # iterate over all other indices in parallel and stop if norm is large enough + for photons in range(1, global_cutoff): + try: + indices = FP[(local_cutoffs, photons)] + except Exception: # pylint: disable=broad-except + indices = paths.binomial_subspace_basis(local_cutoffs, photons) + FP[(local_cutoffs, photons)] = indices + G, prob_subspace = steps.binomial_step(G, A, b, indices) + prob += prob_subspace + if prob > max_prob: + break + return G diff --git a/mrmustard/math/lattice/strategies/displacement.py b/mrmustard/math/lattice/strategies/displacement.py new file mode 100644 index 000000000..79c3568f8 --- /dev/null +++ b/mrmustard/math/lattice/strategies/displacement.py @@ -0,0 +1,139 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +" This module contains strategies for calculating the matrix elements of the displacement gate. " + +import numpy as np +from numba import jit + +__all__ = ["displacement", "laguerre", "grad_displacement", "jacobian_displacement"] + + +@jit(nopython=True) +def displacement(cutoffs, alpha, dtype=np.complex128): # pragma: no cover + r"""Calculates the matrix elements of the displacement gate using a recurrence relation. + Uses the log of the matrix elements to avoid numerical issues and then takes the exponential. + + Args: + alpha (complex): displacement magnitude and angle + cutoffs (tuple[int, int]): Fock ladder output-input cutoffs + dtype (data type): Specifies the data type used for the calculation + + Returns: + array[complex]: matrix representing the displacement operation. + """ + r = np.abs(alpha) + phi = np.angle(alpha) + N, M = cutoffs + flipped = False + if N < M: + N, M = M, N + flipped = True + + D = np.zeros((N, M), dtype=dtype) + rng = np.arange(max(*cutoffs)) + rng[0] = 1 + log_k_fac = np.cumsum(np.log(rng)) + for n_minus_m in range(N): + m_max = min(M, N - n_minus_m) + logL = np.log(laguerre(r**2.0, m_max, n_minus_m)) + for m in range(m_max): + n = n_minus_m + m + sign = 2 * (not (flipped and n > m and n_minus_m % 2)) - 1 + conj = 2 * (not (flipped and n > m)) - 1 + D[n, m] = sign * np.exp( + +0.5 * (log_k_fac[m] - log_k_fac[n]) + + n_minus_m * np.log(r) + - (r**2.0) / 2.0 + + conj * 1j * phi * n_minus_m + + logL[m] + ) + if n < M: + D[m, n] = (-1.0) ** n_minus_m * np.conj(D[n, m]) + return D if not flipped else np.transpose(D) + + +@jit(nopython=True, cache=True) +def laguerre(x, N, alpha, dtype=np.complex128): # pragma: no cover + r"""Returns the N first generalized Laguerre polynomials evaluated at x. + + Args: + x (float): point at which to evaluate the polynomials + N (int): maximum Laguerre polynomial to calculate + alpha (float): continuous parameter for the generalized Laguerre polynomials + """ + L = np.zeros(N, dtype=dtype) + L[0] = 1.0 + if N > 1: + for m in range(0, N - 1): + L[m + 1] = ((2 * m + 1 + alpha - x) * L[m] - (m + alpha) * L[m - 1]) / (m + 1) + return L + + +@jit(nopython=True) +def grad_displacement(T, r, phi): # pragma: no cover + r"""Calculates the gradient of the displacement gate with respect to the magnitude and angle of the displacement. + + Args: + T (array[complex]): array representing the gate + r (float): displacement magnitude + phi (float): displacement angle + + Returns: + tuple[array[complex], array[complex]]: The gradient of the displacement gate with respect to r and phi + """ + cutoff = T.shape[0] + dtype = T.dtype + ei = np.exp(1j * phi) + eic = np.exp(-1j * phi) + alpha = r * ei + alphac = r * eic + sqrt = np.sqrt(np.arange(cutoff, dtype=dtype)) + grad_r = np.zeros((cutoff, cutoff), dtype=dtype) + grad_phi = np.zeros((cutoff, cutoff), dtype=dtype) + + for m in range(cutoff): + for n in range(cutoff): + grad_r[m, n] = -r * T[m, n] + sqrt[m] * ei * T[m - 1, n] - sqrt[n] * eic * T[m, n - 1] + grad_phi[m, n] = ( + sqrt[m] * 1j * alpha * T[m - 1, n] + sqrt[n] * 1j * alphac * T[m, n - 1] + ) + + return grad_r, grad_phi + + +@jit(nopython=True) +def jacobian_displacement(D, alpha): # pragma: no cover + r"""Calculates the jacobian of the displacement gate with respect to the complex displacement + alpha and its conjugate. Both are needed for backprop, as the displacement gate is not a + holomorphic function, as the Fock amplitudes depend on both alpha and on its conjugate. + Each jacobian in this case has the same shape as the array D, as the displacement is a scalar. + + Args: + D (array[complex]): the D(alpha) gate in Fock representation. Batch dimensions are allowed. + alpha (complex): parameter of D(alpha) + + Returns: + 2 array[complex]: The jacobian of the displacement gate with respect to alpha and alphaconj + """ + shape = D.shape[-2:] + alphac = np.conj(alpha) + sqrt = np.sqrt(np.arange(shape[0] + shape[1], dtype=D.dtype)) + jac_alpha = np.zeros(D.shape, dtype=D.dtype) # i.e. dD_dalpha for all m,n + jac_alphac = np.zeros(D.shape, dtype=D.dtype) # i.e. dD_dalphac for all m,n + for m in range(shape[0]): + for n in range(shape[1]): + jac_alpha[m, n] = -0.5 * alphac * D[m, n] + sqrt[m] * D[m - 1, n] + jac_alphac[m, n] = -0.5 * alpha * D[m, n] - sqrt[n] * D[m, n - 1] + return jac_alpha, jac_alphac diff --git a/mrmustard/math/lattice/strategies/squeezer.py b/mrmustard/math/lattice/strategies/squeezer.py new file mode 100644 index 000000000..a39a7e649 --- /dev/null +++ b/mrmustard/math/lattice/strategies/squeezer.py @@ -0,0 +1,188 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +" This module contains strategies for calculating the matrix elements of the squeezing gate. " + +import numpy as np +from numba import njit + +from mrmustard.math.lattice import steps +from mrmustard.typing import ComplexTensor + +SQRT = np.sqrt(np.arange(100000)) + +__all__ = ["squeezer", "squeezer_vjp", "squeezed", "squeezed_vjp"] + + +@njit +def squeezer( + shape: tuple[int, int], r: float, theta: float, dtype=np.complex128 +): # pragma: no cover + r"""Calculates the matrix elements of the squeezing gate using a recurrence relation. + (See eq. 50-52 in https://arxiv.org/abs/2004.11002) + Args: + shape (tuple[int, int]): Fock cutoffs for the output and input indices. + r (float): squeezing magnitude + theta (float): squeezing angle + dtype (data type): data type used for the calculation. + + Returns: + array (ComplexMatrix): matrix representing the squeezing gate. + """ + M, N = shape + S = np.zeros(shape, dtype=dtype) + + eitheta_tanhr = np.exp(1j * theta) * np.tanh(r) + eitheta_tanhr_conj = np.conj(eitheta_tanhr) + sechr = 1.0 / np.cosh(r) + + S[0, 0] = np.sqrt(sechr) + for m in range(2, M, 2): + S[m, 0] = -SQRT[m - 1] / SQRT[m] * eitheta_tanhr * S[m - 2, 0] + + for m in range(M): + for n in range(2 - (m % 2), N, 2): + # for n in range(1, N): + if (m + n) % 2 == 0: + S[m, n] = ( + SQRT[n - 1] / SQRT[n] * eitheta_tanhr_conj * S[m, n - 2] + + SQRT[m] / SQRT[n] * sechr * S[m - 1, n - 1] + ) + return S + + +@njit +def squeezer_vjp( + G: ComplexTensor, + dLdG: ComplexTensor, + r: float, + phi: float, +) -> tuple[float, float]: # pragma: no cover + r"""Squeezing gradients with respect to r and theta. + This function could return dL/dA, dL/db, dL/dc like its vanilla counterpart, + but it is more efficient to include this chain rule step in the numba function, since we can. + + Args: + G (np.ndarray): Tensor result of the forward pass + dLdG (np.ndarray): gradient of the loss with respect to the output tensor + r (float): squeezing magnitude + phi (float): squeezing angle + + Returns: + tuple[float, float]: dL/dr, dL/phi + """ + M, N = G.shape + + # init gradients + dA = np.zeros((2, 2), dtype=np.complex128) # dGdA at an index (of G) + _ = np.zeros(2, dtype=np.complex128) + dLdA = np.zeros_like(dA) + + # first column + for m in range(2, M, 2): + dA, _ = steps.vanilla_step_grad(G, (m, 0), dA, _) + dLdA += dA * dLdG[m, 0] + + # rest of the matrix + for m in range(M): + for n in range(1, N): + if (m + n) % 2 == 0: + dA, _ = steps.vanilla_step_grad(G, (m, n), dA, _) + dLdA += dA * dLdG[m, n] + + dLdC = np.sum(G * dLdG) # np.sqrt(np.cosh(r)) cancels out with 1 / np.sqrt(np.cosh(r)) later + # chain rule + d_sech = -np.tanh(r) / np.cosh(r) + d_tanh = 1.0 / np.cosh(r) ** 2 + tanh = np.tanh(r) + exp = np.exp(1j * phi) + exp_conj = np.exp(-1j * phi) + + dLdr = 2 * np.real( + -dLdA[0, 0] * exp * d_tanh + + dLdA[0, 1] * d_sech + + dLdA[1, 1] * exp_conj * d_tanh + - np.conj(dLdC) * 0.5 * tanh # / np.sqrt(np.cosh(r)) + ) + dLdphi = 2 * np.real(-dLdA[0, 0] * 1j * exp * tanh - dLdA[1, 1] * 1j * exp_conj * tanh) + + return dLdr, dLdphi + + +@njit +def squeezed(cutoff: int, r: float, theta: float, dtype=np.complex128): # pragma: no cover + r"""Calculates the matrix elements of the single-mode squeezed state using recurrence relations. + + Args: + cutoff (int): Fock cutoff for the ket + r (float): squeezing magnitude + theta (float): squeezing angle + dtype (data type): data type used for the calculation. + + Returns: + array (ComplexMatrix): matrix representing the squeezing gate. + """ + S = np.zeros(cutoff, dtype=dtype) + eitheta_tanhr = np.exp(1j * theta) * np.tanh(r) + S[0] = np.sqrt(1.0 / np.cosh(r)) + + for m in range(2, cutoff, 2): + S[m] = SQRT[m - 1] / SQRT[m] * eitheta_tanhr * S[m - 2] + + return S + + +@njit +def squeezed_vjp( + G: ComplexTensor, + dLdG: ComplexTensor, + r: float, + phi: float, +) -> tuple[float, float]: # pragma: no cover + r"""Squeezed state gradients with respect to r and theta. + This function could return dL/dA, dL/db, dL/dc like its vanilla counterpart, + but it is more efficient to include this chain rule step in the numba function, since we can. + + Args: + G (np.ndarray): Tensor result of the forward pass + dLdG (np.ndarray): gradient of the loss with respect to the output tensor + r (float): squeezing magnitude + phi (float): squeezing angle + + Returns: + tuple[float, float]: dL/dr, dL/phi + """ + M = G.shape[0] + + # init gradients + dA = np.zeros((1, 1), dtype=np.complex128) + _ = np.zeros(1, dtype=np.complex128) + dLdA = np.zeros_like(dA) + + # first column + for m in range(2, M, 2): + dA, _ = steps.vanilla_step_grad(G, (m,), dA, _) + dLdA += dA * dLdG[m] + + # chain rule + tanh = np.tanh(r) + d_tanh = 1.0 / np.cosh(r) ** 2 + exp = np.exp(1j * phi) + + dLdC = np.sum(G * dLdG) # np.sqrt(np.cosh(r)) cancels out with 1 / np.sqrt(np.cosh(r)) later + + dLdr = 2 * np.real(-dLdA[0, 0] * exp * d_tanh - np.conj(dLdC) * 0.5 * tanh) + dLdphi = 2 * np.real(-dLdA[0, 0] * 1j * exp * tanh) + + return dLdr, dLdphi diff --git a/mrmustard/math/lattice/strategies/vanilla.py b/mrmustard/math/lattice/strategies/vanilla.py new file mode 100644 index 000000000..6943f98cf --- /dev/null +++ b/mrmustard/math/lattice/strategies/vanilla.py @@ -0,0 +1,117 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +from numba import njit + +from mrmustard.math.lattice import paths, steps +from mrmustard.typing import ComplexMatrix, ComplexTensor, ComplexVector + +SQRT = np.sqrt(np.arange(100000)) + +__all__ = ["vanilla", "vanilla_jacobian", "vanilla_vjp"] + + +@njit +def vanilla(shape: tuple[int, ...], A, b, c) -> ComplexTensor: # pragma: no cover + r"""Vanilla Fock-Bargmann strategy. Fills the tensor by iterating over all indices + in ndindex order. + + Args: + shape (tuple[int, ...]): shape of the output tensor + A (np.ndarray): A matrix of the Fock-Bargmann representation + b (np.ndarray): B vector of the Fock-Bargmann representation + c (complex): vacuum amplitude + + Returns: + np.ndarray: Fock representation of the Gaussian tensor with shape ``shape`` + """ + + # init output tensor + G = np.zeros(shape, dtype=np.complex128) + + # initialize path iterator + path = np.ndindex(shape) + + # write vacuum amplitude + G[next(path)] = c + + # iterate over the rest of the indices + for index in path: + G[index] = steps.vanilla_step(G, A, b, index) + return G + + +@njit +def vanilla_jacobian( + G, A, b, c +) -> tuple[ComplexTensor, ComplexTensor, ComplexTensor]: # pragma: no cover + r"""Vanilla Fock-Bargmann strategy gradient. Returns dG/dA, dG/db, dG/dc. + Notice that G is a holomorphic function of A, b, c. This means that there is only + one gradient to care about for each parameter (i.e. not dG/dA.conj() etc). + """ + + # init output tensors + dGdA = np.zeros(G.shape + A.shape, dtype=np.complex128) + dGdb = np.zeros(G.shape + b.shape, dtype=np.complex128) + dGdc = G / c + + # initialize path iterator + path = paths.ndindex_path(G.shape) + + # skip first index + next(path) + + # iterate over the rest of the indices + for index in path: + dGdA, dGdb = steps.vanilla_step_jacobian(G, A, b, index, dGdA, dGdb) + + return dGdA, dGdb, dGdc + + +@njit +def vanilla_vjp(G, c, dLdG) -> tuple[ComplexMatrix, ComplexVector, complex]: # pragma: no cover + r"""Vanilla Fock-Bargmann strategy gradient. Returns dL/dA, dL/db, dL/dc. + + Args: + G (np.ndarray): Tensor result of the forward pass + c (complex): vacuum amplitude + dLdG (np.ndarray): gradient of the loss with respect to the output tensor + + Returns: + tuple[np.ndarray, np.ndarray, complex]: dL/dA, dL/db, dL/dc + """ + D = G.ndim + + # init gradients + dA = np.zeros((D, D), dtype=np.complex128) # component of dL/dA + db = np.zeros(D, dtype=np.complex128) # component of dL/db + dLdA = np.zeros_like(dA) + dLdb = np.zeros_like(db) + + # initialize path iterator + path = np.ndindex(G.shape) + + # skip first index + next(path) + + # iterate over the rest of the indices + for index in path: + dA, db = steps.vanilla_step_grad(G, index, dA, db) + dLdA += dA * dLdG[index] + dLdb += db * dLdG[index] + + dLdc = np.sum(G * dLdG) / c + + return dLdA, dLdb, dLdc diff --git a/mrmustard/math/math_interface.py b/mrmustard/math/math_interface.py index fb074c009..986c9171b 100644 --- a/mrmustard/math/math_interface.py +++ b/mrmustard/math/math_interface.py @@ -15,19 +15,21 @@ """This module contains the :class:`Math` interface that every backend has to implement.""" from abc import ABC, abstractmethod -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple from functools import lru_cache from itertools import product +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple + import numpy as np from scipy.special import binom -from scipy.stats import unitary_group, ortho_group +from scipy.stats import ortho_group, unitary_group + from mrmustard import settings from mrmustard.typing import ( - Tensor, Matrix, Scalar, - Vector, + Tensor, Trainable, + Vector, ) diff --git a/mrmustard/math/numba/compactFock_1leftoverMode_amps.py b/mrmustard/math/numba/compactFock_1leftoverMode_amps.py index f6751f30a..959ef5466 100644 --- a/mrmustard/math/numba/compactFock_1leftoverMode_amps.py +++ b/mrmustard/math/numba/compactFock_1leftoverMode_amps.py @@ -3,21 +3,22 @@ This is done by applying the recursion relation in a selective manner. """ -import numpy as np import numba -from numba import njit, int64 +import numpy as np +from numba import int64, njit from numba.cpython.unsafe.tuple import tuple_setitem + from mrmustard.math.numba.compactFock_helperFunctions import ( SQRT, - repeat_twice, construct_dict_params, + repeat_twice, ) @njit def write_block( i, arr_write, write, arr_read_pivot, read_GB, G_in, GB, A, K_i, cutoff_leftoverMode -): +): # pragma: no cover """ Apply the recurrence relation to blocks of Fock amplitudes (of shape cutoff_leftoverMode x cutoff_leftoverMode) This is the coarse-grained version of applying the recurrence relation of mrmustard.math.numba.compactFock_diagonal_amps once. @@ -62,7 +63,9 @@ def write_block( @njit -def read_block(arr_write, idx_write, arr_read, idx_read_tail, cutoff_leftoverMode): +def read_block( + arr_write, idx_write, arr_read, idx_read_tail, cutoff_leftoverMode +): # pragma: no cover """ Read the blocks of Fock amplitudes (of shape cutoff_leftoverMode x cutoff_leftoverMode) that are required to apply the recurrence relation and write them to G_in @@ -258,7 +261,7 @@ def fock_representation_1leftoverMode_amps_NUMBA( for sum_params in range(sum(cutoffs_tail)): for params in dict_params[sum_params]: # diagonal pivots: aa,bb,cc,dd,... - if params[0] < cutoffs_tail[0] - 1: + if (cutoffs_tail[0] == 1) or (params[0] < cutoffs_tail[0] - 1): arr1 = use_diag_pivot( A, B, M - 1, cutoff_leftoverMode, cutoffs_tail, params, arr0, arr1 ) diff --git a/mrmustard/math/numba/compactFock_1leftoverMode_grad.py b/mrmustard/math/numba/compactFock_1leftoverMode_grad.py index 0bb14c6c5..d94db1a4e 100644 --- a/mrmustard/math/numba/compactFock_1leftoverMode_grad.py +++ b/mrmustard/math/numba/compactFock_1leftoverMode_grad.py @@ -655,7 +655,7 @@ def fock_representation_1leftoverMode_grad_NUMBA( for sum_params in range(sum(cutoffs_tail)): for params in dict_params[sum_params]: # diagonal pivots: aa,bb,cc,dd,... - if params[0] < cutoffs_tail[0] - 1: + if (cutoffs_tail[0] == 1) or (params[0] < cutoffs_tail[0] - 1): arr1_dA, arr1_dB = use_diag_pivot_grad( A, B, diff --git a/mrmustard/math/numba/compactFock_diagonal_amps.py b/mrmustard/math/numba/compactFock_diagonal_amps.py index d65e4ca58..d78df379a 100644 --- a/mrmustard/math/numba/compactFock_diagonal_amps.py +++ b/mrmustard/math/numba/compactFock_diagonal_amps.py @@ -142,7 +142,7 @@ def fock_representation_diagonal_amps_NUMBA( for sum_params in range(sum(cutoffs)): for params in dict_params[sum_params]: # diagonal pivots: aa,bb,cc,dd,... - if params[0] < cutoffs[0] - 1: + if (cutoffs[0] == 1) or (params[0] < cutoffs[0] - 1): arr1 = use_diag_pivot(A, B, M, cutoffs, params, arr0, arr1) # off-diagonal pivots: d=0: (a+1)a,bb,cc,dd,... | d=1: 00,(b+1)b,cc,dd | 00,00,(c+1)c,dd | ... for d in range(M): diff --git a/mrmustard/math/numba/compactFock_diagonal_grad.py b/mrmustard/math/numba/compactFock_diagonal_grad.py index 6b767b182..b3aab8fcd 100644 --- a/mrmustard/math/numba/compactFock_diagonal_grad.py +++ b/mrmustard/math/numba/compactFock_diagonal_grad.py @@ -254,7 +254,7 @@ def fock_representation_diagonal_grad_NUMBA( for sum_params in range(sum(cutoffs)): for params in dict_params[sum_params]: # diagonal pivots: aa,bb,cc,dd,... - if params[0] < cutoffs[0] - 1: + if (cutoffs[0] == 1) or (params[0] < cutoffs[0] - 1): arr1_dA, arr1_dB = use_diag_pivot_grad( A, B, M, cutoffs, params, arr0, arr1, arr0_dA, arr1_dA, arr0_dB, arr1_dB ) diff --git a/mrmustard/math/tensorflow.py b/mrmustard/math/tensorflow.py index 99caf41cd..5be6eba03 100644 --- a/mrmustard/math/tensorflow.py +++ b/mrmustard/math/tensorflow.py @@ -14,25 +14,23 @@ """This module contains the Tensorflow implementation of the :class:`Math` interface.""" -from typing import Callable, List, Sequence, Tuple, Union, Optional +from typing import Callable, List, Optional, Sequence, Tuple, Union import numpy as np import tensorflow as tf import tensorflow_probability as tfp -from thewalrus import hermite_multidimensional, grad_hermite_multidimensional - +from mrmustard import settings +from mrmustard.math.autocast import Autocast +from mrmustard.math.lattice import strategies from mrmustard.math.numba.compactFock_inputValidation import ( - hermite_multidimensional_diagonal, + grad_hermite_multidimensional_1leftoverMode, grad_hermite_multidimensional_diagonal, -) -from mrmustard.math.numba.compactFock_inputValidation import ( hermite_multidimensional_1leftoverMode, - grad_hermite_multidimensional_1leftoverMode, + hermite_multidimensional_diagonal, ) - -from mrmustard.math.autocast import Autocast from mrmustard.typing import Tensor, Trainable + from .math_interface import MathInterface @@ -364,10 +362,11 @@ def value_and_gradients( @tf.custom_gradient def hermite_renormalized( self, A: tf.Tensor, B: tf.Tensor, C: tf.Tensor, shape: Tuple[int] - ) -> tf.Tensor: # TODO this is not ready + ) -> tf.Tensor: r"""Renormalized multidimensional Hermite polynomial given by the "exponential" Taylor - series of :math:`exp(C + Bx - Ax^2)` at zero, where the series has :math:`sqrt(n!)` at the - denominator rather than :math:`n!`. Note the minus sign in front of ``A``. + series of :math:`exp(C + Bx + 1/2*Ax^2)` at zero, where the series has :math:`sqrt(n!)` + at the denominator rather than :math:`n!`. It computes all the amplitudes within the + tensor of given shape. Args: A: The A matrix. @@ -378,31 +377,62 @@ def hermite_renormalized( Returns: The renormalized Hermite polynomial of given shape. """ - if isinstance(shape, List) and len(shape) == 1: - shape = shape[0] + _A, _B, _C = self.asnumpy(A), self.asnumpy(B), self.asnumpy(C) + G = strategies.vanilla(tuple(shape), _A, _B, _C) + + def grad(dLdGconj): + dLdA, dLdB, dLdC = strategies.vanilla_vjp(G, _C, np.conj(dLdGconj)) + return self.conj(dLdA), self.conj(dLdB), self.conj(dLdC) - poly = hermite_multidimensional( - self.asnumpy(A), shape, self.asnumpy(B), self.asnumpy(C), True, True, True + return G, grad + + @tf.custom_gradient + def hermite_renormalized_binomial( + self, + A: tf.Tensor, + B: tf.Tensor, + C: tf.Tensor, + shape: Tuple[int], + max_l2: Optional[float], + global_cutoff: Optional[int], + ) -> tf.Tensor: + r"""Renormalized multidimensional Hermite polynomial given by the "exponential" Taylor + series of :math:`exp(C + Bx + 1/2*Ax^2)` at zero, where the series has :math:`sqrt(n!)` + at the denominator rather than :math:`n!`. The computation fills a tensor of given shape + up to a given L2 norm or global cutoff, whichever applies first. The max_l2 value, if + not provided, is set to the default value of the AUTOCUTOFF_PROBABILITY setting. + + Args: + A: The A matrix. + B: The B vector. + C: The C scalar. + shape: The shape of the final tensor (local cutoffs). + max_l2 (float): The maximum squared L2 norm of the tensor. + global_cutoff (optional int): The global cutoff. + + Returns: + The renormalized Hermite polynomial of given shape. + """ + _A, _B, _C = self.asnumpy(A), self.asnumpy(B), self.asnumpy(C) + G, _ = strategies.binomial( + tuple(shape), + _A, + _B, + _C, + max_l2=max_l2 or settings.AUTOCUTOFF_PROBABILITY, + global_cutoff=global_cutoff or sum(shape) - len(shape) + 1, ) - def grad(dLdpoly): - dpoly_dC, dpoly_dA, dpoly_dB = tf.numpy_function( - grad_hermite_multidimensional, [poly, A, B, C], [poly.dtype] * 3 - ) - ax = tuple(range(dLdpoly.ndim)) - dLdA = self.sum(dLdpoly[..., None, None] * self.conj(dpoly_dA), axes=ax) - dLdB = self.sum(dLdpoly[..., None] * self.conj(dpoly_dB), axes=ax) - dLdC = self.sum(dLdpoly * self.conj(dpoly_dC), axes=ax) - return dLdA, dLdB, dLdC + def grad(dLdGconj): + dLdA, dLdB, dLdC = strategies.vanilla_vjp(G, _C, np.conj(dLdGconj)) + return self.conj(dLdA), self.conj(dLdB), self.conj(dLdC) - return poly, grad + return G, grad def reorder_AB_bargmann(self, A: tf.Tensor, B: tf.Tensor) -> Tuple[tf.Tensor, tf.Tensor]: r"""In mrmustard.math.numba.compactFock~ dimensions of the Fock representation are ordered like [mode0,mode0,mode1,mode1,...] while in mrmustard.physics.bargmann the ordering is [mode0,mode1,...,mode0,mode1,...]. Here we reorder A and B. - Moreover, the recurrence relation in mrmustard.math.numba.compactFock~ is defined such that A = -A compared to mrmustard.physics.bargmann. """ - A = -A ordering = np.arange(2 * A.shape[0] // 2).reshape(2, -1).T.flatten() A = tf.gather(A, ordering, axis=1) A = tf.gather(A, ordering) @@ -543,9 +573,9 @@ def boolean_mask(tensor: tf.Tensor, mask: tf.Tensor) -> Tensor: return tf.boolean_mask(tensor, mask) @staticmethod - def custom_gradient(func): + def custom_gradient(func, *args, **kwargs): """Decorator to define a function with a custom gradient.""" - return tf.custom_gradient(func) + return tf.custom_gradient(func, *args, **kwargs) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Extras (not in the Interface) diff --git a/mrmustard/physics/bargmann.py b/mrmustard/physics/bargmann.py index 43b7738cb..f9513fe8f 100644 --- a/mrmustard/physics/bargmann.py +++ b/mrmustard/physics/bargmann.py @@ -18,9 +18,10 @@ This module contains functions for transforming to the Bargmann representation. """ import numpy as np -from mrmustard.physics.husimi import wigner_to_husimi, pq_to_aadag + from mrmustard import settings from mrmustard.math import Math +from mrmustard.physics.husimi import pq_to_aadag, wigner_to_husimi math = Math() @@ -51,10 +52,10 @@ def wigner_to_bargmann_rho(cov, means): here we define it as `A = [[A_11, A_10], [A_01, A_00]]`. For `B` we have `B = [B_0, B_1] -> B = [B_1, B_0]`. """ N = cov.shape[-1] // 2 - Q, beta = wigner_to_husimi(cov, means) A = math.matmul( cayley(pq_to_aadag(cov), c=0.5), math.Xmat(N) ) # X on the right, so the index order will be rho_{left,right}: + Q, beta = wigner_to_husimi(cov, means) B = math.solve(Q, beta) # no conjugate, so that the index order will be rho_{left,right} C = math.exp(-0.5 * math.sum(math.conj(beta) * B)) / math.sqrt(math.det(Q)) return A, B, C diff --git a/mrmustard/physics/fock.py b/mrmustard/physics/fock.py index 3eaa6f1c6..9fd1e049c 100644 --- a/mrmustard/physics/fock.py +++ b/mrmustard/physics/fock.py @@ -22,11 +22,11 @@ from typing import List, Optional, Sequence, Tuple import numpy as np -from numba import jit from mrmustard import settings from mrmustard.math import Math from mrmustard.math.caching import tensor_int_cache +from mrmustard.math.lattice import strategies from mrmustard.math.mmtensor import MMTensor from mrmustard.math.numba.compactFock_diagonal_amps import fock_representation_diagonal_amps from mrmustard.physics.bargmann import ( @@ -35,7 +35,7 @@ wigner_to_bargmann_rho, wigner_to_bargmann_U, ) -from mrmustard.typing import Matrix, Scalar, Tensor, Vector +from mrmustard.typing import ComplexTensor, Matrix, Scalar, Tensor, Vector math = Math() SQRT = np.sqrt(np.arange(1e6)) @@ -93,21 +93,27 @@ def wigner_to_fock_state( cov: Matrix, means: Vector, shape: Sequence[int], + max_prob: float = 1.0, + max_photons: Optional[int] = None, return_dm: bool = True, ) -> Tensor: r"""Returns the Fock representation of a Gaussian state. Use with caution: if the cov matrix is that of a mixed state, setting return_dm to False will produce nonsense. + If return_dm=False, we can apply max_prob and max_photons to stop the + computation of the Fock representation early, when those conditions are met. * If the state is pure it can return the state vector (ket) or the density matrix. - The index order is going to be ket_i where i is the only multimode index. + The index ordering is going to be [i's] in ket_i * If the state is mixed it can return the density matrix. - The index order is going to be dm_ij where j is the right multimode index and i is the left one. + The index order is going to be [i's,j's] in dm_ij Args: cov: the Wigner covariance matrix means: the Wigner means vector shape: the shape of the tensor + max_prob: the maximum probability of a the state (applies only if the ket is returned) + max_photons: the maximum number of photons in the state (applies only if the ket is returned) return_dm: whether to return the density matrix (otherwise it returns the ket) Returns: @@ -115,10 +121,16 @@ def wigner_to_fock_state( """ if return_dm: A, B, C = wigner_to_bargmann_rho(cov, means) - return math.hermite_renormalized(-A, B, C, shape=shape) - else: + return math.hermite_renormalized(A, B, C, shape=shape) + else: # here we can apply max prob and max photons A, B, C = wigner_to_bargmann_psi(cov, means) - return math.hermite_renormalized(-A, B, C, shape=shape) + if max_photons is None: + max_photons = sum(shape) - len(shape) + if max_prob < 1.0 or max_photons < sum(shape) - len(shape): + return math.hermite_renormalized_binomial( + A, B, C, shape=shape, max_l2=max_prob, global_cutoff=max_photons + 1 + ) + return math.hermite_renormalized(A, B, C, shape=tuple(shape)) def wigner_to_fock_U(X, d, shape): @@ -135,7 +147,7 @@ def wigner_to_fock_U(X, d, shape): Tensor: the fock representation of the unitary transformation """ A, B, C = wigner_to_bargmann_U(X, d) - return math.hermite_renormalized(-A, B, C, shape=shape) + return math.hermite_renormalized(A, B, C, shape=tuple(shape)) def wigner_to_fock_Choi(X, Y, d, shape): @@ -153,7 +165,7 @@ def wigner_to_fock_Choi(X, Y, d, shape): Tensor: the fock representation of the Choi matrix """ A, B, C = wigner_to_bargmann_Choi(X, Y, d) - return math.hermite_renormalized(-A, B, C, shape=shape) + return math.hermite_renormalized(A, B, C, shape=tuple(shape)) def ket_to_dm(ket: Tensor) -> Tensor: @@ -225,17 +237,18 @@ def dm_to_probs(dm: Tensor) -> Tensor: return math.all_diagonals(dm, real=True) -def U_to_choi(U: Tensor) -> Tensor: +def U_to_choi(U: Tensor, Udual: Optional[Tensor] = None) -> Tensor: r"""Converts a unitary transformation to a Choi tensor. Args: U: the unitary transformation + Udual: the dual unitary transformation (optional, will use conj U if not provided) Returns: Tensor: the Choi tensor. The index order is going to be :math:`[\mathrm{out}_l, \mathrm{in}_l, \mathrm{out}_r, \mathrm{in}_r]` where :math:`\mathrm{in}_l` and :math:`\mathrm{in}_r` are to be contracted with the left and right indices of the density matrix. """ - return math.outer(U, math.conj(U)) + return math.outer(U, Udual or math.conj(U)) def fidelity(state_a, state_b, a_ket: bool, b_ket: bool) -> Scalar: @@ -370,10 +383,11 @@ def apply_kraus_to_ket(kraus, ket, kraus_in_idx, kraus_out_idx=None): # check that there are no repeated indices in kraus_in_idx and kraus_out_idx (separately) validate_contraction_indices(kraus_in_idx, kraus_out_idx, ket.ndim, "kraus") - ket = MMTensor(ket, axis_labels=[f"left_{i}" for i in range(ket.ndim)]) + ket = MMTensor(ket, axis_labels=[f"in_left_{i}" for i in range(ket.ndim)]) kraus = MMTensor( kraus, - axis_labels=[f"out_left_{i}" for i in kraus_out_idx] + [f"left_{i}" for i in kraus_in_idx], + axis_labels=[f"out_left_{i}" for i in kraus_out_idx] + + [f"in_left_{i}" for i in kraus_in_idx], ) # contract the operator with the ket. @@ -440,42 +454,46 @@ def apply_kraus_to_dm(kraus, dm, kraus_in_idx, kraus_out_idx=None): return k_dm_k.transpose(left + right).tensor -def apply_choi_to_dm(choi, dm, choi_in_idx, choi_out_idx=None): +def apply_choi_to_dm( + choi: ComplexTensor, + dm: ComplexTensor, + choi_in_modes: Sequence[int], + choi_out_modes: Sequence[int] = None, +): r"""Applies a choi operator to a density matrix. It assumes that the density matrix is indexed as left_1, ..., left_n, right_1, ..., right_n. - The choi operator has indices that contract with the density matrix (choi_in_idx) and indices that are left over (choi_out_idx). - `choi` will contract choi_in_idx from the left and from the right with the density matrix. + The choi operator has indices that contract with the density matrix (choi_in_modes) and indices that are left over (choi_out_modes). + `choi` will contract choi_in_modes from the left and from the right with the density matrix. Args: choi (array): the choi operator to be applied dm (array): the density matrix to which the choi operator is applied - choi_in_idx (list of ints): the indices of the choi operator that contract with the density matrix - choi_out_idx (list of ints): the indices of the choi operator that re leftover + choi_in_modes (list of ints): the input modes of the choi operator that contract with the density matrix + choi_out_modes (list of ints): the output modes of the choi operator Returns: array: the resulting density matrix """ - if choi_out_idx is None: - choi_out_idx = choi_in_idx - - if not set(choi_in_idx).issubset(range(dm.ndim // 2)): + if choi_out_modes is None: + choi_out_modes = choi_in_modes + if not set(choi_in_modes).issubset(range(dm.ndim // 2)): raise ValueError("choi_in_idx should be a subset of the density matrix indices.") # check that there are no repeated indices in kraus_in_idx and kraus_out_idx (separately) - validate_contraction_indices(choi_in_idx, choi_out_idx, dm.ndim // 2, "choi") + validate_contraction_indices(choi_in_modes, choi_out_modes, dm.ndim // 2, "choi") dm = MMTensor( dm, - axis_labels=[f"left_{i}" for i in range(dm.ndim // 2)] - + [f"right_{i}" for i in range(dm.ndim // 2)], + axis_labels=[f"in_left_{i}" for i in range(dm.ndim // 2)] + + [f"in_right_{i}" for i in range(dm.ndim // 2)], ) choi = MMTensor( choi, - axis_labels=[f"out_left_{i}" for i in choi_out_idx] - + [f"left_{i}" for i in choi_in_idx] - + [f"out_right_{i}" for i in choi_out_idx] - + [f"right_{i}" for i in choi_in_idx], + axis_labels=[f"out_left_{i}" for i in choi_out_modes] + + [f"in_left_{i}" for i in choi_in_modes] + + [f"out_right_{i}" for i in choi_out_modes] + + [f"in_right_{i}" for i in choi_in_modes], ) # contract the choi matrix with the density matrix. @@ -670,10 +688,12 @@ def oscillator_eigenstate(q: Vector, cutoff: int) -> Tensor: prefactor = (omega_over_hbar / np.pi) ** (1 / 4) * math.sqrt(2 ** (-math.arange(0, cutoff))) # Renormalized physicist hermite polys: Hn / sqrt(n!) - R = np.array([[2 + 0j]]) # to get the physicist polys + R = -np.array([[2 + 0j]]) # to get the physicist polys def f_hermite_polys(xi): - poly = math.hermite_renormalized(R, 2 * math.astensor([xi], "complex128"), 1 + 0j, cutoff) + poly = math.hermite_renormalized( + R, 2 * math.astensor([xi], "complex128"), 1 + 0j, (cutoff,) + ) return math.cast(poly, "float64") hermite_polys = math.map_fn(f_hermite_polys, x_tensor) @@ -838,101 +858,87 @@ def sample_homodyne( return homodyne_sample, probability_sample -@jit(nopython=True) -def _displacement(r, phi, cutoff, dtype=np.complex128): # pragma: no cover - r"""Calculates the matrix elements of the displacement gate using a recurrence relation. - Uses the log of the matrix elements to avoid numerical issues and then takes the exponential. +@math.custom_gradient +def displacement(x, y, shape, tol=1e-15): + r"""creates a single mode displacement matrix""" + alpha = math.asnumpy(x) + 1j * math.asnumpy(y) - Args: - r (float): displacement magnitude - phi (float): displacement angle - cutoff (int): Fock ladder cutoff - dtype (data type): Specifies the data type used for the calculation + if np.sqrt(x * x + y * y) > tol: + gate = strategies.displacement(tuple(shape), alpha) + else: + gate = math.eye(max(shape), dtype="complex128")[: shape[0], : shape[1]] - Returns: - array[complex]: matrix representing the displacement operation. - """ - D = np.zeros((cutoff, cutoff), dtype=dtype) - rng = np.arange(cutoff) - rng[0] = 1 - log_k_fac = np.cumsum(np.log(rng)) - for n_minus_m in range(cutoff): - m_max = cutoff - n_minus_m - logL = np.log(_laguerre(r**2.0, m_max, n_minus_m)) - for m in range(m_max): - n = n_minus_m + m - D[n, m] = np.exp( - 0.5 * (log_k_fac[m] - log_k_fac[n]) - + n_minus_m * np.log(r) - - (r**2.0) / 2.0 - + 1j * phi * n_minus_m - + logL[m] - ) - D[m, n] = (-1.0) ** (n_minus_m) * np.conj(D[n, m]) - return D + def grad(dL_dDc): + dD_da, dD_dac = strategies.jacobian_displacement(math.asnumpy(gate), alpha) + dL_dac = np.sum(np.conj(dL_dDc) * dD_dac + dL_dDc * np.conj(dD_da)) + dLdx = 2 * np.real(dL_dac) + dLdy = 2 * np.imag(dL_dac) + return math.astensor(dLdx, dtype=x.dtype), math.astensor(dLdy, dtype=y.dtype) + return math.astensor(gate, dtype=gate.dtype.name), grad -@jit(nopython=True, cache=True) -def _laguerre(x, N, alpha, dtype=np.complex128): # pragma: no cover - r"""Returns the N first generalized Laguerre polynomials evaluated at x. + +@math.custom_gradient +def beamsplitter(theta: float, phi: float, shape: Sequence[int], method: str): + r"""Creates a beamsplitter tensor with given cutoffs using a numba-based fock lattice strategy. Args: - x (float): point at which to evaluate the polynomials - N (int): maximum Laguerre polynomial to calculate - alpha (float): continuous parameter for the generalized Laguerre polynomials + theta (float): transmittivity angle of the beamsplitter + phi (float): phase angle of the beamsplitter + cutoffs (int,int): cutoff dimensions of the two modes """ - L = np.zeros(N, dtype=dtype) - L[0] = 1.0 - if N > 1: - for m in range(0, N - 1): - L[m + 1] = ((2 * m + 1 + alpha - x) * L[m] - (m + alpha) * L[m - 1]) / (m + 1) - return L + if method == "vanilla": + bs_unitary = strategies.beamsplitter(shape, math.asnumpy(theta), math.asnumpy(phi)) + elif method == "schwinger": + bs_unitary = strategies.beamsplitter_schwinger( + shape, math.asnumpy(theta), math.asnumpy(phi) + ) + else: + raise ValueError( + f"Unknown beamsplitter method {method}. Options are 'vanilla' and 'schwinger'." + ) + def vjp(dLdGc): + dtheta, dphi = strategies.beamsplitter_vjp( + math.asnumpy(bs_unitary), + math.asnumpy(math.conj(dLdGc)), + math.asnumpy(theta), + math.asnumpy(phi), + ) + return math.astensor(dtheta, dtype=theta.dtype), math.astensor(dphi, dtype=phi.dtype) -@jit(nopython=True) -def _grad_displacement(T, r, phi): # pragma: no cover - r"""Calculates the gradients of the displacement gate with respect to the displacement magnitude and angle. + return math.astensor(bs_unitary, dtype=bs_unitary.dtype.name), vjp - Args: - T (array[complex]): array representing the gate - r (float): displacement magnitude - phi (float): displacement angle - Returns: - tuple[array[complex], array[complex]]: The gradient of the displacement gate with respect to r and phi - """ - cutoff = T.shape[0] - dtype = T.dtype - ei = np.exp(1j * phi) - eic = np.exp(-1j * phi) - alpha = r * ei - alphac = r * eic - sqrt = np.sqrt(np.arange(cutoff, dtype=dtype)) - grad_r = np.zeros((cutoff, cutoff), dtype=dtype) - grad_phi = np.zeros((cutoff, cutoff), dtype=dtype) - - for m in range(cutoff): - for n in range(cutoff): - grad_r[m, n] = -r * T[m, n] + sqrt[m] * ei * T[m - 1, n] - sqrt[n] * eic * T[m, n - 1] - grad_phi[m, n] = ( - sqrt[m] * 1j * alpha * T[m - 1, n] + sqrt[n] * 1j * alphac * T[m, n - 1] - ) +@math.custom_gradient +def squeezer(r, phi, shape): + r"""creates a single mode squeezer matrix using a numba-based fock lattice strategy""" + sq_unitary = strategies.squeezer(shape, math.asnumpy(r), math.asnumpy(phi)) + + def vjp(dLdGc): + dr, dphi = strategies.squeezer_vjp( + math.asnumpy(sq_unitary), + math.asnumpy(math.conj(dLdGc)), + math.asnumpy(r), + math.asnumpy(phi), + ) + return math.astensor(dr, dtype=r.dtype), math.astensor(dphi, phi.dtype) - return grad_r, grad_phi + return math.astensor(sq_unitary, dtype=sq_unitary.dtype.name), vjp @math.custom_gradient -def displacement(r, phi, cutoff, tol=1e-15): - """creates a single mode displacement matrix""" - if r > tol: - gate = _displacement(math.asnumpy(r), math.asnumpy(phi), cutoff) - else: - gate = math.eye(cutoff, dtype="complex128") - - def grad(dy): # pragma: no cover - Dr, Dphi = _grad_displacement(math.asnumpy(gate), math.asnumpy(r), math.asnumpy(phi)) - grad_r = math.real(math.sum(dy * math.conj(Dr))) - grad_phi = math.real(math.sum(dy * math.conj(Dphi))) - return grad_r, grad_phi, None +def squeezed(r, phi, shape): + r"""creates a single mode squeezed state using a numba-based fock lattice strategy""" + sq_ket = strategies.squeezed(shape, math.asnumpy(r), math.asnumpy(phi)) + + def vjp(dLdGc): + dr, dphi = strategies.squeezed_vjp( + math.asnumpy(sq_ket), + math.asnumpy(math.conj(dLdGc)), + math.asnumpy(r), + math.asnumpy(phi), + ) + return math.astensor(dr, dtype=r.dtype), math.astensor(dphi, phi.dtype) - return gate, grad + return math.astensor(sq_ket, dtype=sq_ket.dtype.name), vjp diff --git a/mrmustard/training/__init__.py b/mrmustard/training/__init__.py index b6492b490..8f13cda51 100644 --- a/mrmustard/training/__init__.py +++ b/mrmustard/training/__init__.py @@ -68,3 +68,4 @@ def cost_fn(): from .parametrized import Parametrized from .optimizer import Optimizer +from .callbacks import TensorboardCallback diff --git a/mrmustard/training/callbacks.py b/mrmustard/training/callbacks.py new file mode 100644 index 000000000..1c47c7ffd --- /dev/null +++ b/mrmustard/training/callbacks.py @@ -0,0 +1,286 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""This module contains the implementation of callback functionalities for optimizations. + +Callbacks allow users to have finer control over the optimization process by executing +predefined routines as optimization progresses. Even though the :meth:`Optimizer.minimize` accepts +`Callable` functions directly, the :class:`Callback` class modularizes the logic and makes it +easier for users to inherit from it and come up with their own custom callbacks. + +Things you can do with callbacks: + +* Logging custom metrics. +* Tracking parameters and costs with Tensorboard. +* Scheduling learning rates. +* Modifying the gradient update that gets applied. +* Updating cost_fn to alter the optimization landscape in our favour. +* Adding some RL into the optimizer. +* ... + +Builtin callbacks: + +* :class:`Callback`: The base class, to be used for building custom callbacks. +* :class:`TensorboardCallback`: Tracks costs, parameter values and gradients in Tensorboard. + +Examples: +========= + +.. code-block:: + + import numpy as np + from mrmustard.training import Optimizer, TensorboardCallback + + def cost_fn(): + ... + + def as_dB(cost): + delta = np.sqrt(np.log(1 / (abs(cost) ** 2)) / (2 * np.pi)) + cost_dB = -10 * np.log10(delta**2) + return cost_dB + + tb_cb = TensorboardCallback(cost_converter=as_dB, track_grads=True) + + def rolling_cost_cb(optimizer, cost, **kwargs): + return { + 'rolling_cost': np.mean(optimizer.opt_history[-10:] + [cost]), + } + + opt = Optimizer(euclidean_lr = 0.001); + opt.minimize(cost_fn, max_steps=200, by_optimizing=[...], callbacks=[tb_cb, rolling_cost_cb]) + + # VScode can be used to open the Tensorboard frontend for live monitoring. + + opt.callback_history['TensorboardCallback'] + opt.callback_history['rolling_cost_cb'] + +""" + +from dataclasses import dataclass +from datetime import datetime +import hashlib +from pathlib import Path +from typing import Callable, Optional, Mapping, Sequence, Union +import numpy as np +import tensorflow as tf +from mrmustard.math import Math + +math = Math() + + +@dataclass +class Callback: + """Base callback class for optimizers. Users can inherit from this class and define the + following custom logic: + + * `.trigger`: + Custom triggering condition, other than the regular schedule set by `step_per_call`. + * `.call`: + The main routine to be customized. + * `.update_cost_fn`: + The custom cost_fn updater, which is expected to return a new cost_fn callable to + replace the original one passed to the optimizer. + * `.update_grads`: + The custom grads modifyer, which is expected to return a list of parameter gradients + after modification, to be applied to the parameters. + * `.update_optimizer`: + The custom optimizer updater, which is expected to modify the optimizer inplace for + things like scheduling learning rates. + + """ + + #: Custom tag for a callback instance to be used as keys in `Optimizer.callback_history`. + #: Defaults to the class name. + tag: str = None + + #: Sets calling frequency of this callback. Defaults to once per optimization step. + #: Use higher values to reduce overhead. + steps_per_call: int = 1 + + def __post_init__(self): + self.tag = self.tag or self.__class__.__name__ + self.optimizer_step: int = 0 + self.callback_step: int = 0 + + def get_opt_step(self, optimizer, **kwargs): # pylint: disable=unused-argument + """Gets current step from optimizer.""" + self.optimizer_step = len(optimizer.opt_history) + return self.optimizer_step + + def _should_call(self, **kwargs) -> bool: + return (self.get_opt_step(**kwargs) % self.steps_per_call == 0) or self.trigger(**kwargs) + + def trigger(self, **kwargs) -> bool: # pylint: disable=unused-argument + """User implemented custom trigger conditions.""" + + def call(self, **kwargs) -> Optional[Mapping]: # pylint: disable=unused-argument + """User implemented main callback logic.""" + + def update_cost_fn(self, **kwargs) -> Optional[Callable]: # pylint: disable=unused-argument + """User implemented cost_fn modifier.""" + + def update_grads(self, **kwargs) -> Optional[Sequence]: # pylint: disable=unused-argument + """User implemented gradient modifier.""" + + def update_optimizer(self, optimizer, **kwargs): # pylint: disable=unused-argument + """User implemented optimizer update scheduler.""" + + def __call__( + self, + **kwargs, + ): + if self._should_call(**kwargs): + self.callback_step += 1 + callback_result = { + "optimizer_step": self.optimizer_step, + "callback_step": self.callback_step, + } + + callback_result.update(self.call(**kwargs) or {}) + + new_cost_fn = self.update_cost_fn(callback_result=callback_result, **kwargs) + if callable(new_cost_fn): + callback_result["cost_fn"] = new_cost_fn + + new_grads = self.update_grads(callback_result=callback_result, **kwargs) + if new_grads is not None: + callback_result["grads"] = new_grads + + # Modifies the optimizer inplace, e.g. its learning rates. + self.update_optimizer(callback_result=callback_result, **kwargs) + + return callback_result + return {} + + +@dataclass +class TensorboardCallback(Callback): # pylint: disable=too-many-instance-attributes + """Callback for enabling Tensorboard tracking of optimization progresses. + + Things tracked: + + * the cost + * the transformed cost, if a `cost_converter` is provided + * trainable parameter values + * trainable parameter gradients (if `track_grads` is `True`) + + To start the Tensorboard frontend, either: + + * use VSCode: F1 -> Tensorboard -> select your `root_logdir/experiment_tag`. + * use command line: `tensorboard --logdir=root_logdir/experiment_tag` and open link in browser. + + + """ + + #: The root logdir for tensorboard logging. + root_logdir: Union[str, Path] = "./tb_logdir" + + #: The tag for experiment subfolder to group similar optimizations together for easy comparisons. + #: Defaults to the hash of all trainable variables' names. + experiment_tag: Optional[str] = None + + #: Extra prefix to name the optimization experiment. + prefix: Optional[str] = None + + #: Transformation on cost for the purpose of better interpretation. + cost_converter: Optional[Callable] = None + + #: Whether to track gradients as well as the values for trainable parameters. + track_grads: bool = False + + #: Whether to return objectives in the callback results to be stored. + log_objectives: bool = True + + #: Whether to return parameter values in the callback results to be stored. + log_trainables: bool = False + + def __post_init__(self): + super().__post_init__() + self.root_logdir = Path(self.root_logdir) + + # Initialize only when first called to use optimization time rather than init time: + self.logdir = None + self.writter_logdir = None + self.tb_writer = None + + def init_writer(self, trainables): + """Initializes tb logdir folders and writer.""" + if (self.writter_logdir is None) or (self.optimizer_step <= self.steps_per_call): + trainable_key_hash = hashlib.sha256( + ",".join(trainables.keys()).encode("utf-8") + ).hexdigest() + self.experiment_tag = self.experiment_tag or f"experiment-{trainable_key_hash[:7]}" + self.logdir = self.root_logdir / self.experiment_tag + self.prefix = self.prefix or "optim" + existing_exp = [path for path in self.logdir.glob("*") if path.is_dir()] + optim_timestamp = datetime.now().strftime("%Y%m%d-%H%M%S") + + self.writter_logdir = self.logdir / ( + f"{self.prefix}-{len(existing_exp):03d}-{optim_timestamp}" + ) + self.tb_writer = tf.summary.create_file_writer(str(self.writter_logdir)) + self.tb_writer.set_as_default() + + def call( + self, + optimizer, + cost, + trainables, + **kwargs, + ): # pylint: disable=unused-argument,arguments-differ + """Logs costs and parameters to Tensorboard.""" + + self.init_writer(trainables=trainables) + obj_tag = "objectives" + + cost = np.array(cost).item() + + obj_scalars = { + f"{obj_tag}/cost": cost, + } + if self.cost_converter is not None: + obj_scalars[f"{obj_tag}/{self.cost_converter.__name__}(cost)"] = self.cost_converter( + cost + ) + + if "orig_cost" in optimizer.callback_history: + orig_cost = np.array(optimizer.callback_history["orig_cost"][-1]).item() + obj_scalars[f"{obj_tag}/orig_cost"] = orig_cost + if self.cost_converter is not None: + obj_scalars[ + f"{obj_tag}/{self.cost_converter.__name__}(orig_cost)" + ] = self.cost_converter(orig_cost) + + for k, v in obj_scalars.items(): + tf.summary.scalar(k, data=v, step=self.optimizer_step) + + for k, (x, dx) in trainables.items(): + x = np.array(x.value) + if self.track_grads: + dx = np.array(dx) + + tag = k if np.size(x) <= 1 else None + for ind, val in np.ndenumerate(x): + tag = tag or k + str(list(ind)).replace(" ", "") + tf.summary.scalar(tag + ":value", data=val, step=self.optimizer_step) + if self.track_grads: + tf.summary.scalar(tag + ":grad", data=dx[ind], step=self.optimizer_step) + tag = None + + result = obj_scalars if self.log_objectives else {} + + if self.log_trainables: + result.update(trainables) + + return result diff --git a/mrmustard/training/optimizer.py b/mrmustard/training/optimizer.py index 8ee5e0d19..4a49fc847 100644 --- a/mrmustard/training/optimizer.py +++ b/mrmustard/training/optimizer.py @@ -17,7 +17,8 @@ """ from itertools import chain, groupby -from typing import List, Callable, Sequence +from typing import List, Callable, Sequence, Union, Mapping, Dict +from mrmustard.training.callbacks import Callback from mrmustard.utils import graphics from mrmustard.logger import create_logger from mrmustard.math import Math @@ -55,7 +56,7 @@ def __init__( "orthogonal": orthogonal_lr, } self.opt_history: List[float] = [0] - self.callback_history: List = [] + self.callback_history: Dict[str, List] = {} self.log = create_logger(__name__) def minimize( @@ -63,7 +64,7 @@ def minimize( cost_fn: Callable, by_optimizing: Sequence[Trainable], max_steps: int = 1000, - callback: Callable = None, + callbacks: Union[Callable, Sequence[Callable], Mapping[str, Callable]] = None, ): r"""Minimizes the given cost function by optimizing circuits and/or detectors. @@ -74,32 +75,55 @@ def minimize( contain the parameters to optimize max_steps (int): the minimization keeps going until the loss is stable or max_steps are reached (if ``max_steps=0`` it will only stop when the loss is stable) - callback (Callable): a function that will be executed at each step of the optimization, which - takes as arguments the training step (int), the cost and the trainable parameters. - The return value is stored in self.callback_history. + callbacks (:class:`Callback`, `Callable`, or List/Dict of them): callback functions that + will be executed at each step of the optimization after backprop but before gradient + gets applied. It takes as arguments the optimizer itself, training step (int), the + cost value, the cost function, and the trainable parameters (values & grads) dict. + The optional returned dict for each step is stored in self.callback_history which + is a callback-name-keyed dict with each value a list of such callback result dicts. + Learn more about how to use callbacks to have finer control of the optimization + process in the :mod:`.callbacks` module. """ + callbacks = self._coerce_callbacks(callbacks) + try: - self._minimize(cost_fn, by_optimizing, max_steps, callback) + self._minimize(cost_fn, by_optimizing, max_steps, callbacks) except KeyboardInterrupt: # graceful exit self.log.info("Optimizer execution halted due to keyboard interruption.") raise self.OptimizerInterruptedError() from None - def _minimize(self, cost_fn, by_optimizing, max_steps, callback): + def _minimize(self, cost_fn, by_optimizing, max_steps, callbacks): # finding out which parameters are trainable from the ops trainable_params = self._get_trainable_params(by_optimizing) + cost_fn_modified = False + orig_cost_fn = cost_fn bar = graphics.Progressbar(max_steps) with bar: while not self.should_stop(max_steps): - cost, grads = self.compute_loss_and_gradients(cost_fn, trainable_params) - self.apply_gradients(trainable_params, grads) + cost, grads = self.compute_loss_and_gradients(cost_fn, trainable_params.values()) + + trainables = {tag: (x, dx) for (tag, x), dx in zip(trainable_params.items(), grads)} + + if cost_fn_modified: + self.callback_history["orig_cost"].append(orig_cost_fn()) + new_cost_fn, new_grads = self._run_callbacks( + callbacks=callbacks, + cost_fn=cost_fn, + cost=cost, + trainables=trainables, + ) + + self.apply_gradients(trainable_params.values(), new_grads or grads) self.opt_history.append(cost) bar.step(math.asnumpy(cost)) - if callback is not None: - self.callback_history.append( - callback(len(self.opt_history) - 1, cost, trainable_params) - ) + + if callable(new_cost_fn): + cost_fn = new_cost_fn + if not cost_fn_modified: + cost_fn_modified = True + self.callback_history["orig_cost"] = self.opt_history.copy() def apply_gradients(self, trainable_params, grads): """Apply gradients to variables. @@ -120,20 +144,33 @@ def apply_gradients(self, trainable_params, grads): update_method(grads_and_vars, param_lr) @staticmethod - def _get_trainable_params(trainable_items): - """Returns a list of trainable parameters from instances of Parametrized or - items that belong to the backend and are trainable + def _get_trainable_params(trainable_items, root_tag: str = "optimized"): + """Traverses all instances of Parametrized or trainable items that belong to the backend + and return a dict of trainables of the form `{tags: trainable_parameters}` where the `tags` + are traversal paths of collecting all parent tags for reaching each parameter. """ trainables = [] - for item in trainable_items: + for i, item in enumerate(trainable_items): + owner_tag = f"{root_tag}[{i}]" if isinstance(item, Parametrized): - trainables.append(item.trainable_parameters) + tag = f"{owner_tag}:{item.__class__.__qualname__}" + trainables.append(item.traverse_trainables(owner_tag=tag).items()) elif math.from_backend(item) and math.is_trainable(item): # the created parameter is wrapped into a list because the case above # returns a list, hence ensuring we have a list of lists - trainables.append([create_parameter(item, name="from_backend", is_trainable=True)]) - - return list(chain(*trainables)) + tag = f"{owner_tag}:{math.__class__.__name__}/{getattr(item, 'name', item.__class__.__name__)}" + trainables.append( + [ + ( + tag, + create_parameter( + item, name="from_backend", is_trainable=True, owner=tag + ), + ) + ] + ) + + return dict(chain(*trainables)) @staticmethod def _group_vars_and_grads_by_type(trainable_params, grads): @@ -186,6 +223,62 @@ def should_stop(self, max_steps: int) -> bool: return True return False + @staticmethod + def _coerce_callbacks(callbacks): + r"""Coerce callbacks into dict and validate them.""" + if callbacks is None: + callbacks = {} + elif callable(callbacks): + callbacks = { + callbacks.tag if isinstance(callbacks, Callback) else callbacks.__name__: callbacks + } + elif isinstance(callbacks, Sequence): + callbacks = { + cb.tag if isinstance(cb, Callback) else cb.__name__: cb for cb in callbacks + } + elif not isinstance(callbacks, Mapping): + raise TypeError( + f"Argument `callbacks` expected to be a callable or a list/dict of callables, got {type(callbacks)}." + ) + + if any(not callable(cb) for cb in callbacks.values()): + raise TypeError("Not all provided callbacks is callable.") + + return callbacks + + def _run_callbacks(self, callbacks, cost_fn, cost, trainables): + """Iteratively calls all callbacks and applies the necessary updates.""" + new_cost_fn, new_grads = None, None + + for cb_tag, cb in callbacks.items(): + if cb_tag not in self.callback_history: + self.callback_history[cb_tag] = [] + + cb_result = cb( + optimizer=self, + cost_fn=cost_fn if new_cost_fn is None else new_cost_fn, + cost=cost, + trainables=trainables, + ) + + if not isinstance(cb_result, (Mapping, type(None))): + raise TypeError( + f"The expected return type of callback functions is dict, got {type(cb_result)}." + ) + + new_cost_fn = cb_result.pop("cost_fn", None) + + if "grads" in cb_result: + new_grads = cb_result["grads"] + trainables = { + tag: (x, dx) for (tag, (x, _)), dx in zip(trainables.items(), new_grads) + } + + if cb_result is not None and cb_result: + self.callback_history[cb_tag].append(cb_result) + + return new_cost_fn, new_grads + class OptimizerInterruptedError(Exception): """A helper class to quietly stop execution without printing a traceback.""" diff --git a/mrmustard/training/parametrized.py b/mrmustard/training/parametrized.py index 176863243..e2a05578c 100644 --- a/mrmustard/training/parametrized.py +++ b/mrmustard/training/parametrized.py @@ -18,7 +18,7 @@ class constructor generate a backend Tensor and are assigned to fields of the class. """ -from typing import Any, Generator, List, Sequence, Tuple +from typing import Any, Generator, List, Sequence, Tuple, Mapping import numpy as np @@ -103,28 +103,82 @@ def trainable_parameters(self) -> Sequence[Trainable]: """Return a list of trainable parameters within the Parametrized object by recursively traversing the object's fields """ - return list(_traverse_parametrized(self.__dict__.values(), Trainable)) + return list(_traverse_parametrized(self.__dict__, Trainable)) @property def constant_parameters(self) -> List[Constant]: """Return a list of constant parameters within the Parametrized object by recursively traversing the object's fields """ - return list(_traverse_parametrized(self.__dict__.values(), Constant)) + return list(_traverse_parametrized(self.__dict__, Constant)) + + def traverse_trainables(self, owner_tag=None) -> Mapping[str, Trainable]: + """Return a dict of trainable parameters within the Parametrized object + by recursively traversing the object's fields. The key for each parameter + will be the path of tags for reaching it from the top level Parametrized. + """ + owner_tag = owner_tag or f"{self.__class__.__qualname__}" + return dict(_traverse_parametrized(self.__dict__, Trainable, owner_tag)) + + def traverse_constants(self, owner_tag=None) -> Mapping[str, Constant]: + """Return a dict of constant parameters within the Parametrized object + by recursively traversing the object's fields. The key for each parameter + will be the path of tags for reaching it from the top level Parametrized. + """ + owner_tag = owner_tag or f"{self.__class__.__qualname__}" + return dict(_traverse_parametrized(self.__dict__, Constant, owner_tag)) -def _traverse_parametrized(object_: Any, extract_type: Parameter) -> Generator: +def _traverse_parametrized_untagged(object_: Sequence, extract_type: Parameter) -> Generator: """This private method traverses recursively all the object's attributes for objects present in ``iterable`` which are instances of ``parameter_type`` or ``Parametrized`` returning a generator with objects of type ``extract_type``. """ - for obj in object_: if isinstance( - obj, (List, Tuple) + obj, (List, Tuple, Mapping) ): # pylint: disable=isinstance-second-argument-not-valid-type yield from _traverse_parametrized(obj, extract_type) elif isinstance(obj, Parametrized): yield from _traverse_parametrized(obj.__dict__.values(), extract_type) elif isinstance(obj, extract_type): yield obj + + +def _traverse_parametrized_tagged( + object_: Mapping, extract_type: Parameter, owner_tag: str = None +) -> Generator: + """This private method traverses recursively, while accumulating tags, all the object's + attributes for objects present in ``iterable`` which are instances of ``parameter_type`` + or ``Parametrized`` returning a generator of 2-tuples of the form (str, ``extract_type``). + """ + + delim = "/" + for k, obj in object_.items(): + obj_tag = f"{owner_tag}[{k}]" if isinstance(k, int) else f"{owner_tag}{delim}{k}" + if isinstance(obj, (Mapping, List, Tuple)): + yield from _traverse_parametrized(obj, extract_type, owner_tag=obj_tag) + elif isinstance(obj, Parametrized): + yield from _traverse_parametrized(obj.__dict__, extract_type, owner_tag=obj_tag) + elif isinstance(obj, extract_type): + yield obj_tag, obj + + +def _traverse_parametrized( + object_: Any, extract_type: Parameter, owner_tag: str = None +) -> Generator: + """The recursive parameter traversal to be used for both tagged and untagged collection + Depending on if the argument `owner_tag` is provided. + """ + + if owner_tag: + yield from _traverse_parametrized_tagged( + object_=dict(enumerate(object_)) if isinstance(object_, Sequence) else object_, + extract_type=extract_type, + owner_tag=owner_tag, + ) + else: + yield from _traverse_parametrized_untagged( + object_=list(object_.values()) if isinstance(object_, Mapping) else object_, + extract_type=extract_type, + ) diff --git a/mrmustard/typing.py b/mrmustard/typing.py index 6f374ff8a..9a8508a0f 100644 --- a/mrmustard/typing.py +++ b/mrmustard/typing.py @@ -33,7 +33,14 @@ "Tensor", "Trainable", ] -from typing import Iterator, Protocol, Tuple, TypeVar, Union, runtime_checkable +from typing import ( + Iterator, + Protocol, + Tuple, + TypeVar, + Union, + runtime_checkable, +) import numpy as np diff --git a/mrmustard/utils/wigner.py b/mrmustard/utils/wigner.py index f6162536a..4941b6d0b 100644 --- a/mrmustard/utils/wigner.py +++ b/mrmustard/utils/wigner.py @@ -14,8 +14,9 @@ """This module contains the calculation of the Wigner function.""" -from numba import njit import numpy as np +from numba import njit + from mrmustard import settings @@ -27,7 +28,7 @@ def wigner_discretized(rho, qvec, pvec, hbar=settings.HBAR): Args: rho (complex array): the density matrix of the state in Fock representation - xvec (array): array of discretized :math:`x` quadrature values + qvec (array): array of discretized :math:`q` quadrature values pvec (array): array of discretized :math:`p` quadrature values hbar (optional float): the value of `\hbar`, defaults to ``settings.HBAR``. @@ -40,7 +41,7 @@ def wigner_discretized(rho, qvec, pvec, hbar=settings.HBAR): P = np.outer(np.ones_like(qvec), pvec) cutoff = rho.shape[-1] - A = (Q + P * 1.0j) / (2 * np.sqrt(hbar / 2)) + A = (Q + P * 1.0j) / np.sqrt(2 * hbar) Wmat = np.zeros((2, cutoff) + A.shape, dtype=np.complex128) diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 000000000..df4e08254 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,3445 @@ +# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. + +[[package]] +name = "absl-py" +version = "1.4.0" +description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "absl-py-1.4.0.tar.gz", hash = "sha256:d2c244d01048ba476e7c080bd2c6df5e141d211de80223460d5b3b8a2a58433d"}, + {file = "absl_py-1.4.0-py3-none-any.whl", hash = "sha256:0d3fe606adfa4f7db64792dd4c7aee4ee0c38ab75dfd353b7a83ed3e957fcb47"}, +] + +[[package]] +name = "aiosignal" +version = "1.3.1" +description = "aiosignal: a list of registered asynchronous callbacks" +category = "main" +optional = true +python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" + +[[package]] +name = "alabaster" +version = "0.7.13" +description = "A configurable sidebar-enabled Sphinx theme" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, + {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, +] + +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] + +[[package]] +name = "astroid" +version = "2.7.3" +description = "An abstract syntax tree for Python with inference support." +category = "dev" +optional = false +python-versions = "~=3.6" +files = [ + {file = "astroid-2.7.3-py3-none-any.whl", hash = "sha256:dc1e8b28427d6bbef6b8842b18765ab58f558c42bb80540bd7648c98412af25e"}, + {file = "astroid-2.7.3.tar.gz", hash = "sha256:3b680ce0419b8a771aba6190139a3998d14b413852506d99aff8dc2bf65ee67c"}, +] + +[package.dependencies] +lazy-object-proxy = ">=1.4.0" +setuptools = ">=20.0" +wrapt = ">=1.11,<1.13" + +[[package]] +name = "astunparse" +version = "1.6.3" +description = "An AST unparser for Python" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, + {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, +] + +[package.dependencies] +six = ">=1.6.1,<2.0" +wheel = ">=0.23.0,<1.0" + +[[package]] +name = "atomicwrites" +version = "1.4.1" +description = "Atomic file writes." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, +] + +[[package]] +name = "attrs" +version = "23.1.0" +description = "Classes Without Boilerplate" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] + +[[package]] +name = "babel" +version = "2.12.1" +description = "Internationalization utilities" +category = "dev" +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"}, +] + +[[package]] +name = "black" +version = "23.7.0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"}, + {file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"}, + {file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"}, + {file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"}, + {file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"}, + {file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"}, + {file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"}, + {file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"}, + {file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"}, + {file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"}, + {file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"}, + {file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"}, + {file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "cachetools" +version = "5.3.1" +description = "Extensible memoizing collections and decorators" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.3.1-py3-none-any.whl", hash = "sha256:95ef631eeaea14ba2e36f06437f36463aac3a096799e876ee55e5cdccb102590"}, + {file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"}, +] + +[[package]] +name = "certifi" +version = "2023.5.7" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.2.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"}, +] + +[[package]] +name = "click" +version = "8.1.4" +description = "Composable command line interface toolkit" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.4-py3-none-any.whl", hash = "sha256:2739815aaa5d2c986a88f1e9230c55e17f0caad3d958a5e13ad0797c166db9e3"}, + {file = "click-8.1.4.tar.gz", hash = "sha256:b97d0c74955da062a7d4ef92fadb583806a585b2ea81958a81bd72726cbb8e37"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "cloudpickle" +version = "2.2.1" +description = "Extended pickling support for Python objects" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "cloudpickle-2.2.1-py3-none-any.whl", hash = "sha256:61f594d1f4c295fa5cd9014ceb3a1fc4a70b0de1164b94fbc2d854ccba056f9f"}, + {file = "cloudpickle-2.2.1.tar.gz", hash = "sha256:d89684b8de9e34a2a43b3460fbca07d09d6e25ce858df4d5a44240403b6178f5"}, +] + +[[package]] +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 = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "commonmark" +version = "0.9.1" +description = "Python parser for the CommonMark Markdown spec" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, + {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, +] + +[package.extras] +test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] + +[[package]] +name = "coverage" +version = "7.2.7" +description = "Code coverage measurement for Python" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, + {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, + {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, + {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, + {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, + {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, + {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, + {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, + {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, + {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, + {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, + {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, + {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, + {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, + {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, + {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, + {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, + {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, + {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, + {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, + {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, + {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, + {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, + {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "cycler" +version = "0.11.0" +description = "Composable style cycles" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, + {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, +] + +[[package]] +name = "dask" +version = "2023.7.0" +description = "Parallel PyData with Task Scheduling" +category = "main" +optional = false +python-versions = ">=3.9" +files = [ + {file = "dask-2023.7.0-py3-none-any.whl", hash = "sha256:ceb10a806a8a6dca2d4623868687f9e166b4302f9a079e5a297e0780a2cd750d"}, + {file = "dask-2023.7.0.tar.gz", hash = "sha256:83212f085e9f59d6c724f32d4ce1dc1fed5405e868f5bfff701cc54912424c3d"}, +] + +[package.dependencies] +click = ">=8.0" +cloudpickle = ">=1.5.0" +fsspec = ">=2021.09.0" +importlib-metadata = ">=4.13.0" +packaging = ">=20.0" +partd = ">=1.2.0" +pyyaml = ">=5.3.1" +toolz = ">=0.10.0" + +[package.extras] +array = ["numpy (>=1.21)"] +complete = ["dask[array,dataframe,diagnostics,distributed]", "lz4 (>=4.3.2)", "pyarrow (>=7.0)"] +dataframe = ["numpy (>=1.21)", "pandas (>=1.3)"] +diagnostics = ["bokeh (>=2.4.2)", "jinja2 (>=2.10.3)"] +distributed = ["distributed (==2023.7.0)"] +test = ["pandas[test]", "pre-commit", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist"] + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "dm-tree" +version = "0.1.8" +description = "Tree is a library for working with nested data structures." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "dm-tree-0.1.8.tar.gz", hash = "sha256:0fcaabbb14e7980377439e7140bd05552739ca5e515ecb3119f234acee4b9430"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:35cc164a79336bfcfafb47e5f297898359123bbd3330c1967f0c4994f9cf9f60"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39070ba268c0491af9fe7a58644d99e8b4f2cde6e5884ba3380bddc84ed43d5f"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2869228d9c619074de501a3c10dc7f07c75422f8fab36ecdcb859b6f1b1ec3ef"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d20f2faa3672b52e5013f4077117bfb99c4cfc0b445d3bde1584c34032b57436"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5483dca4d7eb1a0d65fe86d3b6a53ae717face83c1f17e0887b1a4a64ae5c410"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d7c26e431fc93cc7e0cba867eb000db6a05f6f2b25af11ac4e9dada88fc5bca"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d714371bb08839e4e5e29024fc95832d9affe129825ef38836b143028bd144"}, + {file = "dm_tree-0.1.8-cp310-cp310-win_amd64.whl", hash = "sha256:d40fa4106ca6edc66760246a08f500ec0c85ef55c762fb4a363f6ee739ba02ee"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad16ceba90a56ec47cf45b21856d14962ac314787975ef786efb5e6e9ca75ec7"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:803bfc53b4659f447ac694dbd04235f94a73ef7c1fd1e0df7c84ac41e0bc963b"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:378cc8ad93c5fe3590f405a309980721f021c790ca1bdf9b15bb1d59daec57f5"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1607ce49aa42f010d1e5e616d92ce899d66835d4d8bea49679582435285515de"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343a4a4ebaa127451ff971254a4be4084eb4bdc0b2513c32b46f6f728fd03f9e"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa42a605d099ee7d41ba2b5fb75e21423951fd26e5d50583a00471238fb3021d"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b7764de0d855338abefc6e3ee9fe40d301668310aa3baea3f778ff051f4393"}, + {file = "dm_tree-0.1.8-cp311-cp311-win_amd64.whl", hash = "sha256:a5d819c38c03f0bb5b3b3703c60e4b170355a0fc6b5819325bf3d4ceb3ae7e80"}, + {file = "dm_tree-0.1.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8c60a7eadab64c2278861f56bca320b2720f163dca9d7558103c3b77f2416571"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af4b3d372f2477dcd89a6e717e4a575ca35ccc20cc4454a8a4b6f8838a00672d"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de287fabc464b8734be251e46e06aa9aa1001f34198da2b6ce07bd197172b9cb"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:054b461f8176f4bce7a21f7b1870f873a1ced3bdbe1282c816c550bb43c71fa6"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f7915660f59c09068e428613c480150180df1060561fd0d1470684ae7007bd1"}, + {file = "dm_tree-0.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:b9f89a454e98806b44fe9d40ec9eee61f848388f7e79ac2371a55679bd5a3ac6"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0e9620ccf06393eb6b613b5e366469304622d4ea96ae6540b28a33840e6c89cf"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b095ba4f8ca1ba19350fd53cf1f8f3eb0bd406aa28af64a6dfc86707b32a810a"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b9bd9b9ccb59409d33d51d84b7668010c04c2af7d4a371632874c1ca356cff3d"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d3172394079a86c3a759179c65f64c48d1a42b89495fcf38976d11cc3bb952c"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1612fcaecd79023dbc6a6ae48d51a80beb5c385d6f3f6d71688e57bc8d07de8"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5c8c12e3fda754ef6af94161bacdaeda816d941995fac415d6855c6c386af68"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:694c3654cfd2a81552c08ec66bb5c4a3d48fa292b9a181880fb081c36c5b9134"}, + {file = "dm_tree-0.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:bb2d109f42190225112da899b9f3d46d0d5f26aef501c61e43529fe9322530b5"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d16e1f2a073604cfcc09f7131ae8d534674f43c3aef4c25742eae295bc60d04f"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:250b692fb75f45f02e2f58fbef9ab338904ef334b90557565621fa251df267cf"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81fce77f22a302d7a5968aebdf4efafef4def7ce96528719a354e6990dcd49c7"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7ac31b9aecccb2c6e1ab29706f6ded3eba0c2c69c770322c9c685929c3d6afb"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fe962015b2fe1282892b28ebe962faed53c7f98d942da9a4625cbf27baef913"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c52cbf4f8b3dbd0beaedf44f69fa85eec5e9dede612e08035e06ada6ec9426"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:181c35521d480d0365f39300542cb6cd7fd2b77351bb43d7acfda15aef63b317"}, + {file = "dm_tree-0.1.8-cp39-cp39-win_amd64.whl", hash = "sha256:8ed3564abed97c806db122c2d3e1a2b64c74a63debe9903aad795167cc301368"}, +] + +[[package]] +name = "docutils" +version = "0.20.1" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, +] + +[[package]] +name = "filelock" +version = "3.12.2" +description = "A platform independent file lock." +category = "main" +optional = true +python-versions = ">=3.7" +files = [ + {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, + {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, +] + +[package.extras] +docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] + +[[package]] +name = "flatbuffers" +version = "23.5.26" +description = "The FlatBuffers serialization format for Python" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "flatbuffers-23.5.26-py2.py3-none-any.whl", hash = "sha256:c0ff356da363087b915fde4b8b45bdda73432fc17cddb3c8157472eab1422ad1"}, + {file = "flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89"}, +] + +[[package]] +name = "fonttools" +version = "4.40.0" +description = "Tools to manipulate font files" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.40.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b802dcbf9bcff74672f292b2466f6589ab8736ce4dcf36f48eb994c2847c4b30"}, + {file = "fonttools-4.40.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f6e3fa3da923063c286320e728ba2270e49c73386e3a711aa680f4b0747d692"}, + {file = "fonttools-4.40.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fdf60f8a5c6bcce7d024a33f7e4bc7921f5b74e8ea13bccd204f2c8b86f3470"}, + {file = "fonttools-4.40.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91784e21a1a085fac07c6a407564f4a77feb471b5954c9ee55a4f9165151f6c1"}, + {file = "fonttools-4.40.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:05171f3c546f64d78569f10adc0de72561882352cac39ec7439af12304d8d8c0"}, + {file = "fonttools-4.40.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7449e5e306f3a930a8944c85d0cbc8429cba13503372a1a40f23124d6fb09b58"}, + {file = "fonttools-4.40.0-cp310-cp310-win32.whl", hash = "sha256:bae8c13abbc2511e9a855d2142c0ab01178dd66b1a665798f357da0d06253e0d"}, + {file = "fonttools-4.40.0-cp310-cp310-win_amd64.whl", hash = "sha256:425b74a608427499b0e45e433c34ddc350820b6f25b7c8761963a08145157a66"}, + {file = "fonttools-4.40.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:00ab569b2a3e591e00425023ade87e8fef90380c1dde61be7691cb524ca5f743"}, + {file = "fonttools-4.40.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:18ea64ac43e94c9e0c23d7a9475f1026be0e25b10dda8f236fc956188761df97"}, + {file = "fonttools-4.40.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:022c4a16b412293e7f1ce21b8bab7a6f9d12c4ffdf171fdc67122baddb973069"}, + {file = "fonttools-4.40.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:530c5d35109f3e0cea2535742d6a3bc99c0786cf0cbd7bb2dc9212387f0d908c"}, + {file = "fonttools-4.40.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5e00334c66f4e83535384cb5339526d01d02d77f142c23b2f97bd6a4f585497a"}, + {file = "fonttools-4.40.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb52c10fda31159c22c7ed85074e05f8b97da8773ea461706c273e31bcbea836"}, + {file = "fonttools-4.40.0-cp311-cp311-win32.whl", hash = "sha256:6a8d71b9a5c884c72741868e845c0e563c5d83dcaf10bb0ceeec3b4b2eb14c67"}, + {file = "fonttools-4.40.0-cp311-cp311-win_amd64.whl", hash = "sha256:15abb3d055c1b2dff9ce376b6c3db10777cb74b37b52b78f61657634fd348a0d"}, + {file = "fonttools-4.40.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14037c31138fbd21847ad5e5441dfdde003e0a8f3feb5812a1a21fd1c255ffbd"}, + {file = "fonttools-4.40.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:94c915f6716589f78bc00fbc14c5b8de65cfd11ee335d32504f1ef234524cb24"}, + {file = "fonttools-4.40.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37467cee0f32cada2ec08bc16c9c31f9b53ea54b2f5604bf25a1246b5f50593a"}, + {file = "fonttools-4.40.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56d4d85f5374b45b08d2f928517d1e313ea71b4847240398decd0ab3ebbca885"}, + {file = "fonttools-4.40.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8c4305b171b61040b1ee75d18f9baafe58bd3b798d1670078efe2c92436bfb63"}, + {file = "fonttools-4.40.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a954b90d1473c85a22ecf305761d9fd89da93bbd31dae86e7dea436ad2cb5dc9"}, + {file = "fonttools-4.40.0-cp38-cp38-win32.whl", hash = "sha256:1bc4c5b147be8dbc5df9cc8ac5e93ee914ad030fe2a201cc8f02f499db71011d"}, + {file = "fonttools-4.40.0-cp38-cp38-win_amd64.whl", hash = "sha256:8a917828dbfdb1cbe50cf40eeae6fbf9c41aef9e535649ed8f4982b2ef65c091"}, + {file = "fonttools-4.40.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:882983279bf39afe4e945109772c2ffad2be2c90983d6559af8b75c19845a80a"}, + {file = "fonttools-4.40.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c55f1b4109dbc3aeb496677b3e636d55ef46dc078c2a5e3f3db4e90f1c6d2907"}, + {file = "fonttools-4.40.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec468c022d09f1817c691cf884feb1030ef6f1e93e3ea6831b0d8144c06480d1"}, + {file = "fonttools-4.40.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d5adf4ba114f028fc3f5317a221fd8b0f4ef7a2e5524a2b1e0fd891b093791a"}, + {file = "fonttools-4.40.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa83b3f151bc63970f39b2b42a06097c5a22fd7ed9f7ba008e618de4503d3895"}, + {file = "fonttools-4.40.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97d95b8301b62bdece1af943b88bcb3680fd385f88346a4a899ee145913b414a"}, + {file = "fonttools-4.40.0-cp39-cp39-win32.whl", hash = "sha256:1a003608400dd1cca3e089e8c94973c6b51a4fb1ef00ff6d7641617b9242e637"}, + {file = "fonttools-4.40.0-cp39-cp39-win_amd64.whl", hash = "sha256:7961575221e3da0841c75da53833272c520000d76f7f71274dbf43370f8a1065"}, + {file = "fonttools-4.40.0-py3-none-any.whl", hash = "sha256:200729d12461e2038700d31f0d49ad5a7b55855dec7525074979a06b46f88505"}, + {file = "fonttools-4.40.0.tar.gz", hash = "sha256:337b6e83d7ee73c40ea62407f2ce03b07c3459e213b6f332b94a69923b9e1cb9"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "scipy"] +lxml = ["lxml (>=4.0,<5)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.0.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + +[[package]] +name = "frozenlist" +version = "1.3.3" +description = "A list-like structure which implements collections.abc.MutableSequence" +category = "main" +optional = true +python-versions = ">=3.7" +files = [ + {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"}, + {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0"}, + {file = "frozenlist-1.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd"}, + {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f"}, + {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420"}, + {file = "frozenlist-1.3.3-cp310-cp310-win32.whl", hash = "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642"}, + {file = "frozenlist-1.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678"}, + {file = "frozenlist-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b"}, + {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4"}, + {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81"}, + {file = "frozenlist-1.3.3-cp311-cp311-win32.whl", hash = "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8"}, + {file = "frozenlist-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32"}, + {file = "frozenlist-1.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d"}, + {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb"}, + {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401"}, + {file = "frozenlist-1.3.3-cp37-cp37m-win32.whl", hash = "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a"}, + {file = "frozenlist-1.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5"}, + {file = "frozenlist-1.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2"}, + {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13"}, + {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3"}, + {file = "frozenlist-1.3.3-cp38-cp38-win32.whl", hash = "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b"}, + {file = "frozenlist-1.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1"}, + {file = "frozenlist-1.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b"}, + {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab"}, + {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1"}, + {file = "frozenlist-1.3.3-cp39-cp39-win32.whl", hash = "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38"}, + {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, + {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, +] + +[[package]] +name = "fsspec" +version = "2023.6.0" +description = "File-system specification" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fsspec-2023.6.0-py3-none-any.whl", hash = "sha256:1cbad1faef3e391fba6dc005ae9b5bdcbf43005c9167ce78c915549c352c869a"}, + {file = "fsspec-2023.6.0.tar.gz", hash = "sha256:d0b2f935446169753e7a5c5c55681c54ea91996cc67be93c39a154fb3a2742af"}, +] + +[package.extras] +abfs = ["adlfs"] +adl = ["adlfs"] +arrow = ["pyarrow (>=1)"] +dask = ["dask", "distributed"] +devel = ["pytest", "pytest-cov"] +dropbox = ["dropbox", "dropboxdrivefs", "requests"] +full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] +fuse = ["fusepy"] +gcs = ["gcsfs"] +git = ["pygit2"] +github = ["requests"] +gs = ["gcsfs"] +gui = ["panel"] +hdfs = ["pyarrow (>=1)"] +http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "requests"] +libarchive = ["libarchive-c"] +oci = ["ocifs"] +s3 = ["s3fs"] +sftp = ["paramiko"] +smb = ["smbprotocol"] +ssh = ["paramiko"] +tqdm = ["tqdm"] + +[[package]] +name = "gast" +version = "0.4.0" +description = "Python AST that abstracts the underlying Python version" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "gast-0.4.0-py3-none-any.whl", hash = "sha256:b7adcdd5adbebf1adf17378da5ba3f543684dbec47b1cda1f3997e573cd542c4"}, + {file = "gast-0.4.0.tar.gz", hash = "sha256:40feb7b8b8434785585ab224d1568b857edb18297e5a3047f1ba012bc83b42c1"}, +] + +[[package]] +name = "google-auth" +version = "2.17.3" +description = "Google Authentication Library" +category = "main" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +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"}, +] + +[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" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] +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)"] + +[[package]] +name = "google-auth-oauthlib" +version = "0.4.6" +description = "Google Authentication Library" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "google-auth-oauthlib-0.4.6.tar.gz", hash = "sha256:a90a072f6993f2c327067bf65270046384cda5a8ecb20b94ea9a687f1f233a7a"}, + {file = "google_auth_oauthlib-0.4.6-py2.py3-none-any.whl", hash = "sha256:3f2a6e802eebbb6fb736a370fbf3b055edcb6b52878bf2f26330b5e041316c73"}, +] + +[package.dependencies] +google-auth = ">=1.0.0" +requests-oauthlib = ">=0.7.0" + +[package.extras] +tool = ["click (>=6.0.0)"] + +[[package]] +name = "google-pasta" +version = "0.2.0" +description = "pasta is an AST-based Python refactoring library" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "google-pasta-0.2.0.tar.gz", hash = "sha256:c9f2c8dfc8f96d0d5808299920721be30c9eec37f2389f28904f454565c8a16e"}, + {file = "google_pasta-0.2.0-py2-none-any.whl", hash = "sha256:4612951da876b1a10fe3960d7226f0c7682cf901e16ac06e473b267a5afa8954"}, + {file = "google_pasta-0.2.0-py3-none-any.whl", hash = "sha256:b32482794a366b5366a32c92a9a9201b107821889935a02b3e51f6b432ea84ed"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "grpcio" +version = "1.49.1" +description = "HTTP/2-based RPC framework" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "grpcio-1.49.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:fd86040232e805b8e6378b2348c928490ee595b058ce9aaa27ed8e4b0f172b20"}, + {file = "grpcio-1.49.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6fd0c9cede9552bf00f8c5791d257d5bf3790d7057b26c59df08be5e7a1e021d"}, + {file = "grpcio-1.49.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:d0d402e158d4e84e49c158cb5204119d55e1baf363ee98d6cb5dce321c3a065d"}, + {file = "grpcio-1.49.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ceec743d42a627e64ea266059a62d214c5a3cdfcd0d7fe2b7a8e4e82527c7"}, + {file = "grpcio-1.49.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2106d9c16527f0a85e2eea6e6b91a74fc99579c60dd810d8690843ea02bc0f5f"}, + {file = "grpcio-1.49.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:52dd02b7e7868233c571b49bc38ebd347c3bb1ff8907bb0cb74cb5f00c790afc"}, + {file = "grpcio-1.49.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:120fecba2ec5d14b5a15d11063b39783fda8dc8d24addd83196acb6582cabd9b"}, + {file = "grpcio-1.49.1-cp310-cp310-win32.whl", hash = "sha256:f1a3b88e3c53c1a6e6bed635ec1bbb92201bb6a1f2db186179f7f3f244829788"}, + {file = "grpcio-1.49.1-cp310-cp310-win_amd64.whl", hash = "sha256:a7d0017b92d3850abea87c1bdec6ea41104e71c77bca44c3e17f175c6700af62"}, + {file = "grpcio-1.49.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:9fb17ff8c0d56099ac6ebfa84f670c5a62228d6b5c695cf21c02160c2ac1446b"}, + {file = "grpcio-1.49.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:075f2d06e3db6b48a2157a1bcd52d6cbdca980dd18988fe6afdb41795d51625f"}, + {file = "grpcio-1.49.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46d93a1b4572b461a227f1db6b8d35a88952db1c47e5fadcf8b8a2f0e1dd9201"}, + {file = "grpcio-1.49.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc79b2b37d779ac42341ddef40ad5bf0966a64af412c89fc2b062e3ddabb093f"}, + {file = "grpcio-1.49.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5f8b3a971c7820ea9878f3fd70086240a36aeee15d1b7e9ecbc2743b0e785568"}, + {file = "grpcio-1.49.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49b301740cf5bc8fed4fee4c877570189ae3951432d79fa8e524b09353659811"}, + {file = "grpcio-1.49.1-cp311-cp311-win32.whl", hash = "sha256:1c66a25afc6c71d357867b341da594a5587db5849b48f4b7d5908d236bb62ede"}, + {file = "grpcio-1.49.1-cp311-cp311-win_amd64.whl", hash = "sha256:6b6c3a95d27846f4145d6967899b3ab25fffc6ae99544415e1adcacef84842d2"}, + {file = "grpcio-1.49.1-cp37-cp37m-linux_armv7l.whl", hash = "sha256:1cc400c8a2173d1c042997d98a9563e12d9bb3fb6ad36b7f355bc77c7663b8af"}, + {file = "grpcio-1.49.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:34f736bd4d0deae90015c0e383885b431444fe6b6c591dea288173df20603146"}, + {file = "grpcio-1.49.1-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:196082b9c89ebf0961dcd77cb114bed8171964c8e3063b9da2fb33536a6938ed"}, + {file = "grpcio-1.49.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c9f89c42749890618cd3c2464e1fbf88446e3d2f67f1e334c8e5db2f3272bbd"}, + {file = "grpcio-1.49.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64419cb8a5b612cdb1550c2fd4acbb7d4fb263556cf4625f25522337e461509e"}, + {file = "grpcio-1.49.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8a5272061826e6164f96e3255405ef6f73b88fd3e8bef464c7d061af8585ac62"}, + {file = "grpcio-1.49.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ea9d0172445241ad7cb49577314e39d0af2c5267395b3561d7ced5d70458a9f3"}, + {file = "grpcio-1.49.1-cp37-cp37m-win32.whl", hash = "sha256:2070e87d95991473244c72d96d13596c751cb35558e11f5df5414981e7ed2492"}, + {file = "grpcio-1.49.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fcedcab49baaa9db4a2d240ac81f2d57eb0052b1c6a9501b46b8ae912720fbf"}, + {file = "grpcio-1.49.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:afbb3475cf7f4f7d380c2ca37ee826e51974f3e2665613996a91d6a58583a534"}, + {file = "grpcio-1.49.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a4f9ba141380abde6c3adc1727f21529137a2552002243fa87c41a07e528245c"}, + {file = "grpcio-1.49.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:cf0a1fb18a7204b9c44623dfbd1465b363236ce70c7a4ed30402f9f60d8b743b"}, + {file = "grpcio-1.49.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17bb6fe72784b630728c6cff9c9d10ccc3b6d04e85da6e0a7b27fb1d135fac62"}, + {file = "grpcio-1.49.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18305d5a082d1593b005a895c10041f833b16788e88b02bb81061f5ebcc465df"}, + {file = "grpcio-1.49.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b6a1b39e59ac5a3067794a0e498911cf2e37e4b19ee9e9977dc5e7051714f13f"}, + {file = "grpcio-1.49.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0e20d59aafc086b1cc68400463bddda6e41d3e5ed30851d1e2e0f6a2e7e342d3"}, + {file = "grpcio-1.49.1-cp38-cp38-win32.whl", hash = "sha256:e1e83233d4680863a421f3ee4a7a9b80d33cd27ee9ed7593bc93f6128302d3f2"}, + {file = "grpcio-1.49.1-cp38-cp38-win_amd64.whl", hash = "sha256:221d42c654d2a41fa31323216279c73ed17d92f533bc140a3390cc1bd78bf63c"}, + {file = "grpcio-1.49.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:fa9e6e61391e99708ac87fc3436f6b7b9c6b845dc4639b406e5e61901e1aacde"}, + {file = "grpcio-1.49.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9b449e966ef518ce9c860d21f8afe0b0f055220d95bc710301752ac1db96dd6a"}, + {file = "grpcio-1.49.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:aa34d2ad9f24e47fa9a3172801c676e4037d862247e39030165fe83821a7aafd"}, + {file = "grpcio-1.49.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5207f4eed1b775d264fcfe379d8541e1c43b878f2b63c0698f8f5c56c40f3d68"}, + {file = "grpcio-1.49.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b24a74651438d45619ac67004638856f76cc13d78b7478f2457754cbcb1c8ad"}, + {file = "grpcio-1.49.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fe763781669790dc8b9618e7e677c839c87eae6cf28b655ee1fa69ae04eea03f"}, + {file = "grpcio-1.49.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2f2ff7ba0f8f431f32d4b4bc3a3713426949d3533b08466c4ff1b2b475932ca8"}, + {file = "grpcio-1.49.1-cp39-cp39-win32.whl", hash = "sha256:08ff74aec8ff457a89b97152d36cb811dcc1d17cd5a92a65933524e363327394"}, + {file = "grpcio-1.49.1-cp39-cp39-win_amd64.whl", hash = "sha256:274ffbb39717918c514b35176510ae9be06e1d93121e84d50b350861dcb9a705"}, + {file = "grpcio-1.49.1.tar.gz", hash = "sha256:d4725fc9ec8e8822906ae26bb26f5546891aa7fbc3443de970cc556d43a5c99f"}, +] + +[package.dependencies] +six = ">=1.5.2" + +[package.extras] +protobuf = ["grpcio-tools (>=1.49.1)"] + +[[package]] +name = "grpcio" +version = "1.51.3" +description = "HTTP/2-based RPC framework" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "grpcio-1.51.3-cp310-cp310-linux_armv7l.whl", hash = "sha256:f601aaeae18dab81930fb8d4f916b0da21e89bb4b5f7367ef793f46b4a76b7b0"}, + {file = "grpcio-1.51.3-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:eef0450a4b5ed11feab639bf3eb1b6e23d0efa9b911bf7b06fb60e14f5f8a585"}, + {file = "grpcio-1.51.3-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:82b0ad8ac825d4bb31bff9f638557c045f4a6d824d84b21e893968286f88246b"}, + {file = "grpcio-1.51.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3667c06e37d6cd461afdd51cefe6537702f3d1dc5ff4cac07e88d8b4795dc16f"}, + {file = "grpcio-1.51.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3709048fe0aa23dda09b3e69849a12055790171dab9e399a72ea8f9dfbf9ac80"}, + {file = "grpcio-1.51.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:200d69857f9910f7458b39b9bcf83ee4a180591b40146ba9e49314e3a7419313"}, + {file = "grpcio-1.51.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cd9a5e68e79c5f031500e67793048a90209711e0854a9ddee8a3ce51728de4e5"}, + {file = "grpcio-1.51.3-cp310-cp310-win32.whl", hash = "sha256:6604f614016127ae10969176bbf12eb0e03d2fb3d643f050b3b69e160d144fb4"}, + {file = "grpcio-1.51.3-cp310-cp310-win_amd64.whl", hash = "sha256:e95c7ccd4c5807adef1602005513bf7c7d14e5a41daebcf9d8d30d8bf51b8f81"}, + {file = "grpcio-1.51.3-cp311-cp311-linux_armv7l.whl", hash = "sha256:5e77ee138100f0bb55cbd147840f87ee6241dbd25f09ea7cd8afe7efff323449"}, + {file = "grpcio-1.51.3-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:68a7514b754e38e8de9075f7bb4dee919919515ec68628c43a894027e40ddec4"}, + {file = "grpcio-1.51.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c1b9f8afa62ff265d86a4747a2990ec5a96e4efce5d5888f245a682d66eca47"}, + {file = "grpcio-1.51.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8de30f0b417744288cec65ec8cf84b8a57995cf7f1e84ccad2704d93f05d0aae"}, + {file = "grpcio-1.51.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b69c7adc7ed60da1cb1b502853db61f453fc745f940cbcc25eb97c99965d8f41"}, + {file = "grpcio-1.51.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d81528ffe0e973dc840ec73a4132fd18b8203ad129d7410155d951a0a7e4f5d0"}, + {file = "grpcio-1.51.3-cp311-cp311-win32.whl", hash = "sha256:040eb421613b57c696063abde405916dd830203c184c9000fc8c3b3b3c950325"}, + {file = "grpcio-1.51.3-cp311-cp311-win_amd64.whl", hash = "sha256:2a8e17286c4240137d933b8ca506465472248b4ce0fe46f3404459e708b65b68"}, + {file = "grpcio-1.51.3-cp37-cp37m-linux_armv7l.whl", hash = "sha256:d5cd1389669a847555df54177b911d9ff6f17345b2a6f19388707b7a9f724c88"}, + {file = "grpcio-1.51.3-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:be1bf35ce82cdbcac14e39d5102d8de4079a1c1a6a06b68e41fcd9ef64f9dd28"}, + {file = "grpcio-1.51.3-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:5eed34994c095e2bf7194ffac7381c6068b057ef1e69f8f08db77771350a7566"}, + {file = "grpcio-1.51.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f9a7d88082b2a17ae7bd3c2354d13bab0453899e0851733f6afa6918373f476"}, + {file = "grpcio-1.51.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c8abbc5f837111e7bd619612eedc223c290b0903b952ce0c7b00840ea70f14"}, + {file = "grpcio-1.51.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:165b05af77e6aecb4210ae7663e25acf234ba78a7c1c157fa5f2efeb0d6ec53c"}, + {file = "grpcio-1.51.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:54e36c2ee304ff15f2bfbdc43d2b56c63331c52d818c364e5b5214e5bc2ad9f6"}, + {file = "grpcio-1.51.3-cp37-cp37m-win32.whl", hash = "sha256:cd0daac21d9ef5e033a5100c1d3aa055bbed28bfcf070b12d8058045c4e821b1"}, + {file = "grpcio-1.51.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2fdd6333ce96435408565a9dbbd446212cd5d62e4d26f6a3c0feb1e3c35f1cc8"}, + {file = "grpcio-1.51.3-cp38-cp38-linux_armv7l.whl", hash = "sha256:54b0c29bdd9a3b1e1b61443ab152f060fc719f1c083127ab08d03fac5efd51be"}, + {file = "grpcio-1.51.3-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:ffaaf7e93fcb437356b5a4b23bf36e8a3d0221399ff77fd057e4bc77776a24be"}, + {file = "grpcio-1.51.3-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:eafbe7501a3268d05f2e450e1ddaffb950d842a8620c13ec328b501d25d2e2c3"}, + {file = "grpcio-1.51.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881ecb34feabf31c6b3b9bbbddd1a5b57e69f805041e5a2c6c562a28574f71c4"}, + {file = "grpcio-1.51.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e860a3222139b41d430939bbec2ec9c3f6c740938bf7a04471a9a8caaa965a2e"}, + {file = "grpcio-1.51.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:49ede0528e9dac7e8a9fe30b16c73b630ddd9a576bf4b675eb6b0c53ee5ca00f"}, + {file = "grpcio-1.51.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6972b009638b40a448d10e1bc18e2223143b8a7aa20d7def0d78dd4af4126d12"}, + {file = "grpcio-1.51.3-cp38-cp38-win32.whl", hash = "sha256:5694448256e3cdfe5bd358f1574a3f2f51afa20cc834713c4b9788d60b7cc646"}, + {file = "grpcio-1.51.3-cp38-cp38-win_amd64.whl", hash = "sha256:3ea4341efe603b049e8c9a5f13c696ca37fcdf8a23ca35f650428ad3606381d9"}, + {file = "grpcio-1.51.3-cp39-cp39-linux_armv7l.whl", hash = "sha256:6c677581ce129f5fa228b8f418cee10bd28dd449f3a544ea73c8ba590ee49d0b"}, + {file = "grpcio-1.51.3-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:30e09b5e0531685e176f49679b6a3b190762cc225f4565e55a899f5e14b3aa62"}, + {file = "grpcio-1.51.3-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:c831f31336e81243f85b6daff3e5e8a123302ce0ea1f2726ad752fd7a59f3aee"}, + {file = "grpcio-1.51.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2cd2e4cefb724cab1ba2df4b7535a9980531b9ec51b4dbb5f137a1f3a3754ef0"}, + {file = "grpcio-1.51.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a0d0bf44438869d307f85a54f25a896ad6b4b0ca12370f76892ad732928d87"}, + {file = "grpcio-1.51.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c02abd55409bfb293371554adf6a4401197ec2133dd97727c01180889014ba4d"}, + {file = "grpcio-1.51.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2f8ff75e61e1227ba7a3f16b2eadbcc11d0a54096d52ab75a6b88cfbe56f55d1"}, + {file = "grpcio-1.51.3-cp39-cp39-win32.whl", hash = "sha256:6c99a73a6260bdf844b2e5ddad02dcd530310f80e1fa72c300fa19c1c7496962"}, + {file = "grpcio-1.51.3-cp39-cp39-win_amd64.whl", hash = "sha256:22bdfac4f7f27acdd4da359b5e7e1973dc74bf1ed406729b07d0759fde2f064b"}, + {file = "grpcio-1.51.3.tar.gz", hash = "sha256:be7b2265b7527bb12109a7727581e274170766d5b3c9258d4e466f4872522d7a"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.51.3)"] + +[[package]] +name = "h5py" +version = "3.9.0" +description = "Read and write HDF5 files from Python" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "h5py-3.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb7bdd5e601dd1739698af383be03f3dad0465fe67184ebd5afca770f50df9d6"}, + {file = "h5py-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:78e44686334cbbf2dd21d9df15823bc38663f27a3061f6a032c68a3e30c47bf7"}, + {file = "h5py-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f68b41efd110ce9af1cbe6fa8af9f4dcbadace6db972d30828b911949e28fadd"}, + {file = "h5py-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12aa556d540f11a2cae53ea7cfb94017353bd271fb3962e1296b342f6550d1b8"}, + {file = "h5py-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:d97409e17915798029e297a84124705c8080da901307ea58f29234e09b073ddc"}, + {file = "h5py-3.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:551e358db05a874a0f827b22e95b30092f2303edc4b91bb62ad2f10e0236e1a0"}, + {file = "h5py-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6822a814b9d8b8363ff102f76ea8d026f0ca25850bb579d85376029ee3e73b93"}, + {file = "h5py-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f01202cdea754ab4227dd27014bdbd561a4bbe4b631424fd812f7c2ce9c6ac"}, + {file = "h5py-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64acceaf6aff92af091a4b83f6dee3cf8d3061f924a6bb3a33eb6c4658a8348b"}, + {file = "h5py-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:804c7fb42a34c8ab3a3001901c977a5c24d2e9c586a0f3e7c0a389130b4276fc"}, + {file = "h5py-3.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8d9492391ff5c3c80ec30ae2fe82a3f0efd1e750833739c25b0d090e3be1b095"}, + {file = "h5py-3.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9da9e7e63376c32704e37ad4cea2dceae6964cee0d8515185b3ab9cbd6b947bc"}, + {file = "h5py-3.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4e20897c88759cbcbd38fb45b507adc91af3e0f67722aa302d71f02dd44d286"}, + {file = "h5py-3.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf5225543ca35ce9f61c950b73899a82be7ba60d58340e76d0bd42bf659235a"}, + {file = "h5py-3.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:36408f8c62f50007d14e000f9f3acf77e103b9e932c114cbe52a3089e50ebf94"}, + {file = "h5py-3.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:23e74b878bbe1653ab34ca49b83cac85529cd0b36b9d625516c5830cc5ca2eac"}, + {file = "h5py-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3f457089c5d524b7998e3649bc63240679b8fb0a3859ea53bbb06841f3d755f1"}, + {file = "h5py-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6284061f3214335e1eec883a6ee497dbe7a79f19e6a57fed2dd1f03acd5a8cb"}, + {file = "h5py-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7a745efd0d56076999b52e8da5fad5d30823bac98b59c68ae75588d09991a"}, + {file = "h5py-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:79bbca34696c6f9eeeb36a91776070c49a060b2879828e2c8fa6c58b8ed10dd1"}, + {file = "h5py-3.9.0.tar.gz", hash = "sha256:e604db6521c1e367c6bd7fad239c847f53cc46646f2d2651372d05ae5e95f817"}, +] + +[package.dependencies] +numpy = ">=1.17.3" + +[[package]] +name = "hypothesis" +version = "6.31.6" +description = "A library for property-based testing" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "hypothesis-6.31.6-py3-none-any.whl", hash = "sha256:fbd31da5174f3da8d062017302071967b239a1b397d0e3181a44d43346bc6def"}, + {file = "hypothesis-6.31.6.tar.gz", hash = "sha256:d54be6a80b160ad5ea4209b01a0d72e31d910510ed7142fa9907861911800771"}, +] + +[package.dependencies] +attrs = ">=19.2.0" +sortedcontainers = ">=2.1.0,<3.0.0" + +[package.extras] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "django (>=2.2)", "dpcontracts (>=0.4)", "importlib-metadata (>=3.6)", "importlib-resources (>=3.3.0)", "lark-parser (>=0.6.5)", "libcst (>=0.3.16)", "numpy (>=1.9.0)", "pandas (>=0.25)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2021.5)"] +cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] +codemods = ["libcst (>=0.3.16)"] +dateutil = ["python-dateutil (>=1.4)"] +django = ["django (>=2.2)"] +dpcontracts = ["dpcontracts (>=0.4)"] +ghostwriter = ["black (>=19.10b0)"] +lark = ["lark-parser (>=0.6.5)"] +numpy = ["numpy (>=1.9.0)"] +pandas = ["pandas (>=0.25)"] +pytest = ["pytest (>=4.6)"] +pytz = ["pytz (>=2014.1)"] +redis = ["redis (>=3.0.0)"] +zoneinfo = ["backports.zoneinfo (>=0.2.1)", "importlib-resources (>=3.3.0)", "tzdata (>=2021.5)"] + +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] + +[[package]] +name = "importlib-metadata" +version = "6.8.0" +description = "Read metadata from Python packages" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isort" +version = "5.12.0" +description = "A Python utility / library to sort Python imports." +category = "dev" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] + +[package.extras] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "joblib" +version = "1.3.1" +description = "Lightweight pipelining with Python functions" +category = "main" +optional = true +python-versions = ">=3.7" +files = [ + {file = "joblib-1.3.1-py3-none-any.whl", hash = "sha256:89cf0529520e01b3de7ac7b74a8102c90d16d54c64b5dd98cafcd14307fdf915"}, + {file = "joblib-1.3.1.tar.gz", hash = "sha256:1f937906df65329ba98013dc9692fe22a4c5e4a648112de500508b18a21b41e3"}, +] + +[[package]] +name = "jsonschema" +version = "4.18.2" +description = "An implementation of JSON Schema validation for Python" +category = "main" +optional = true +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.18.2-py3-none-any.whl", hash = "sha256:159fdff1443b4c5ed900d4eeac6b928a3485f4aff5fba6edd1e25cd66bb46b39"}, + {file = "jsonschema-4.18.2.tar.gz", hash = "sha256:af3855bfa30e83b2200a5fe12ab5eb92460e4d3b8e4efd34094aa637f7272a87"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[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.6.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +category = "main" +optional = true +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.6.1-py3-none-any.whl", hash = "sha256:3d2b82663aff01815f744bb5c7887e2121a63399b49b104a3c96145474d091d7"}, + {file = "jsonschema_specifications-2023.6.1.tar.gz", hash = "sha256:ca1c4dd059a9e7b34101cf5b3ab7ff1d18b139f35950d598d629837ef66e8f28"}, +] + +[package.dependencies] +referencing = ">=0.28.0" + +[[package]] +name = "keras" +version = "2.10.0" +description = "Deep learning for humans." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "keras-2.10.0-py2.py3-none-any.whl", hash = "sha256:26a6e2c2522e7468ddea22710a99b3290493768fc08a39e75d1173a0e3452fdf"}, +] + +[[package]] +name = "keras-preprocessing" +version = "1.1.2" +description = "Easy data preprocessing and data augmentation for deep learning models" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "Keras_Preprocessing-1.1.2-py2.py3-none-any.whl", hash = "sha256:7b82029b130ff61cc99b55f3bd27427df4838576838c5b2f65940e4fcec99a7b"}, + {file = "Keras_Preprocessing-1.1.2.tar.gz", hash = "sha256:add82567c50c8bc648c14195bf544a5ce7c1f76761536956c3d2978970179ef3"}, +] + +[package.dependencies] +numpy = ">=1.9.1" +six = ">=1.9.0" + +[package.extras] +image = ["Pillow (>=5.2.0)", "scipy (>=0.14)"] +pep8 = ["flake8"] +tests = ["Pillow", "keras", "pandas", "pytest", "pytest-cov", "pytest-xdist", "tensorflow"] + +[[package]] +name = "kiwisolver" +version = "1.4.4" +description = "A fast implementation of the Cassowary constraint solver" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, + {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, +] + +[[package]] +name = "latexcodec" +version = "2.0.1" +description = "A lexer and codec to work with LaTeX code in Python." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "latexcodec-2.0.1-py2.py3-none-any.whl", hash = "sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271"}, + {file = "latexcodec-2.0.1.tar.gz", hash = "sha256:2aa2551c373261cefe2ad3a8953a6d6533e68238d180eb4bb91d7964adb3fe9a"}, +] + +[package.dependencies] +six = ">=1.4.1" + +[[package]] +name = "lazy-object-proxy" +version = "1.9.0" +description = "A fast and thorough lazy object proxy." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, +] + +[[package]] +name = "libclang" +version = "16.0.0" +description = "Clang Python Bindings, mirrored from the official LLVM repo: https://github.com/llvm/llvm-project/tree/main/clang/bindings/python, to make the installation process easier." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "libclang-16.0.0-py2.py3-none-macosx_10_9_x86_64.whl", hash = "sha256:65258a6bb3e7dc31dc9b26f8d42f53c9d3b959643ade291fcd1aef4855303ca6"}, + {file = "libclang-16.0.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:af55a4aa86fdfe6b2ec68bc8cfe5fdac6c448d591ca7648be86ca17099b41ca8"}, + {file = "libclang-16.0.0-py2.py3-none-manylinux2010_x86_64.whl", hash = "sha256:a043138caaf2cb076ebb060c6281ec95612926645d425c691991fc9df00e8a24"}, + {file = "libclang-16.0.0-py2.py3-none-manylinux2014_aarch64.whl", hash = "sha256:eb59652cb0559c0e71784ff4c8ba24c14644becc907b1446563ecfaa622d523b"}, + {file = "libclang-16.0.0-py2.py3-none-manylinux2014_armv7l.whl", hash = "sha256:7b6686b67a0daa84b4c614bcc119578329fc4fbb52b919565b7376b507c4793b"}, + {file = "libclang-16.0.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:2adce42ae652f312245b8f4eda6f30b4076fb61f7619f2dfd0a0c31dee4c32b9"}, + {file = "libclang-16.0.0-py2.py3-none-win_amd64.whl", hash = "sha256:ee20bf93e3dd330f71fc50cdbf13b92ced0aec8e540be64251db53502a9b33f7"}, + {file = "libclang-16.0.0-py2.py3-none-win_arm64.whl", hash = "sha256:bf4628fc4da7a1dd06a244f9b8e121c5ec68076a763c59d6b13cbb103acc935b"}, +] + +[[package]] +name = "llvmlite" +version = "0.39.1" +description = "lightweight wrapper around basic LLVM functionality" +category = "main" +optional = false +python-versions = ">=3.7" +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"}, +] + +[[package]] +name = "locket" +version = "1.0.0" +description = "File-based locks for Python on Linux and Windows" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "locket-1.0.0-py2.py3-none-any.whl", hash = "sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3"}, + {file = "locket-1.0.0.tar.gz", hash = "sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632"}, +] + +[[package]] +name = "m2r2" +version = "0.3.3.post2" +description = "Markdown and reStructuredText in a single file." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "m2r2-0.3.3.post2-py3-none-any.whl", hash = "sha256:86157721eb6eabcd54d4eea7195890cc58fa6188b8d0abea633383cfbb5e11e3"}, + {file = "m2r2-0.3.3.post2.tar.gz", hash = "sha256:e62bcb0e74b3ce19cda0737a0556b04cf4a43b785072fcef474558f2c1482ca8"}, +] + +[package.dependencies] +docutils = ">=0.19" +mistune = "0.8.4" + +[[package]] +name = "markdown" +version = "3.4.3" +description = "Python implementation of John Gruber's Markdown." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Markdown-3.4.3-py3-none-any.whl", hash = "sha256:065fd4df22da73a625f14890dd77eb8040edcbd68794bcd35943be14490608b2"}, + {file = "Markdown-3.4.3.tar.gz", hash = "sha256:8bf101198e004dc93e84a12a7395e31aac6a9c9942848ae1d99b9d72cf9b3520"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {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-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"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + +[[package]] +name = "matplotlib" +version = "3.5.0" +description = "Python plotting package" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "matplotlib-3.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4b018ea6f26424a0852eb60eb406420d9f0d34f65736ea7bbfbb104946a66d86"}, + {file = "matplotlib-3.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a07ff2565da72a7b384a9e000b15b6b8270d81370af8a3531a16f6fbcee023cc"}, + {file = "matplotlib-3.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2eea16883aa7724c95eea0eb473ab585c6cf66f0e28f7f13e63deb38f4fd6d0f"}, + {file = "matplotlib-3.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e020a42f3338823a393dd2f80e39a2c07b9f941dfe2c778eb104eeb33d60bb5"}, + {file = "matplotlib-3.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bac8eb1eccef540d7f4e844b6313d9f7722efd48c07e1b4bfec1056132127fd"}, + {file = "matplotlib-3.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a7cb59ebd63a8ac4542ec1c61dd08724f82ec3aa7bb6b4b9e212d43c611ce3d"}, + {file = "matplotlib-3.5.0-cp310-cp310-win32.whl", hash = "sha256:6e0e6b2111165522ad336705499b1f968c34a9e84d05d498ee5af0b5697d1efe"}, + {file = "matplotlib-3.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:ff5d9fe518ad2de14ce82ab906b6ab5c2b0c7f4f984400ff8a7a905daa580a0a"}, + {file = "matplotlib-3.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:66b172610db0ececebebb09d146f54205f87c7b841454e408fba854764f91bdd"}, + {file = "matplotlib-3.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee3d9ff16d749a9aa521bd7d86f0dbf256b2d2ac8ce31b19e4d2c86d2f2ff0b6"}, + {file = "matplotlib-3.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970aa97297537540369d05fe0fd1bb952593f9ab696c9b427c06990a83e2418b"}, + {file = "matplotlib-3.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:153a0cf6a6ff4f406a0600d2034710c49988bacc6313d193b32716f98a697580"}, + {file = "matplotlib-3.5.0-cp37-cp37m-win32.whl", hash = "sha256:6db02c5605f063b67780f4d5753476b6a4944343284aa4e93c5e8ff6e9ec7f76"}, + {file = "matplotlib-3.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:df0042cab69f4d246f4cb8fc297770ac4ae6ec2983f61836b04a117722037dcd"}, + {file = "matplotlib-3.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a7bf8b05c214d32fb7ca7c001fde70b9b426378e897b0adbf77b85ea3569d56a"}, + {file = "matplotlib-3.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0abf8b51cc6d3ba34d1b15b26e329f23879848a0cf1216954c1f432ffc7e1af7"}, + {file = "matplotlib-3.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:13930a0c9bec0fd25f43c448b047a21af1353328b946f044a8fc3be077c6b1a8"}, + {file = "matplotlib-3.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18f6e52386300db5cc4d1e9019ad9da2e80658bab018834d963ebb0aa5355095"}, + {file = "matplotlib-3.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba107add08e12600b072cf3c47aaa1ab85dd4d3c48107a5d3377d1bf80f8b235"}, + {file = "matplotlib-3.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2089b9014792dcc87bb1d620cde847913338abf7d957ef05587382b0cb76d44e"}, + {file = "matplotlib-3.5.0-cp38-cp38-win32.whl", hash = "sha256:f23fbf70d2e80f4e03a83fc1206a8306d9bc50482fee4239f10676ce7e470c83"}, + {file = "matplotlib-3.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:71a1851111f23f82fc43d2b6b2bfdd3f760579a664ebc939576fe21cc6133d01"}, + {file = "matplotlib-3.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d092b7ba63182d2dd427904e3eb58dd5c46ec67c5968de14a4b5007010a3a4cc"}, + {file = "matplotlib-3.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ac17a7e7b06ee426a4989f0b7f24ab1a592e39cdf56353a90f4e998bc0bf44d6"}, + {file = "matplotlib-3.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a5b62d1805cc83d755972033c05cea78a1e177a159fc84da5c9c4ab6303ccbd9"}, + {file = "matplotlib-3.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:666d717a4798eb9c5d3ae83fe80c7bc6ed696b93e879cb01cb24a74155c73612"}, + {file = "matplotlib-3.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65f877882b7ddede7090c7d87be27a0f4720fe7fc6fddd4409c06e1aa0f1ae8d"}, + {file = "matplotlib-3.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7baf23adb698d8c6ca7339c9dde00931bc47b2dd82fa912827fef9f93db77f5e"}, + {file = "matplotlib-3.5.0-cp39-cp39-win32.whl", hash = "sha256:b3b687e905da32e5f2e5f16efa713f5d1fcd9fb8b8c697895de35c91fedeb086"}, + {file = "matplotlib-3.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6cef5b31e27c31253c0f852b629a38d550ae66ec6850129c49d872f9ee428cb"}, + {file = "matplotlib-3.5.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a0dcaf5648cecddc328e81a0421821a1f65a1d517b20746c94a1f0f5c36fb51a"}, + {file = "matplotlib-3.5.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b5e439d9e55d645f2a4dca63e2f66d68fe974c405053b132d61c7e98c25dfeb2"}, + {file = "matplotlib-3.5.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dc8c5c23e7056e126275dbf29efba817b3d94196690930d0968873ac3a94ab82"}, + {file = "matplotlib-3.5.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:a0ea10faa3bab0714d3a19c7e0921279a68d57552414d6eceaea99f97d7735db"}, + {file = "matplotlib-3.5.0.tar.gz", hash = "sha256:38892a254420d95594285077276162a5e9e9c30b6da08bdc2a4d53331ad9a6fa"}, +] + +[package.dependencies] +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.0.1" +numpy = ">=1.17" +packaging = ">=20.0" +pillow = ">=6.2.0" +pyparsing = ">=2.2.1" +python-dateutil = ">=2.7" +setuptools-scm = ">=4" + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] + +[[package]] +name = "mistune" +version = "0.8.4" +description = "The fastest markdown parser in pure Python" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, + {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +description = "Python library for arbitrary-precision floating-point arithmetic" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, + {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, +] + +[package.extras] +develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] +docs = ["sphinx"] +gmpy = ["gmpy2 (>=2.1.0a4)"] +tests = ["pytest (>=4.6)"] + +[[package]] +name = "msgpack" +version = "1.0.5" +description = "MessagePack serializer" +category = "main" +optional = true +python-versions = "*" +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"}, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "numba" +version = "0.56.4" +description = "compiling Python code using LLVM" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "numba-0.56.4-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:9f62672145f8669ec08762895fe85f4cf0ead08ce3164667f2b94b2f62ab23c3"}, + {file = "numba-0.56.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c602d015478b7958408d788ba00a50272649c5186ea8baa6cf71d4a1c761bba1"}, + {file = "numba-0.56.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:85dbaed7a05ff96492b69a8900c5ba605551afb9b27774f7f10511095451137c"}, + {file = "numba-0.56.4-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f4cfc3a19d1e26448032049c79fc60331b104f694cf570a9e94f4e2c9d0932bb"}, + {file = "numba-0.56.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4e08e203b163ace08bad500b0c16f6092b1eb34fd1fce4feaf31a67a3a5ecf3b"}, + {file = "numba-0.56.4-cp310-cp310-win32.whl", hash = "sha256:0611e6d3eebe4cb903f1a836ffdb2bda8d18482bcd0a0dcc56e79e2aa3fefef5"}, + {file = "numba-0.56.4-cp310-cp310-win_amd64.whl", hash = "sha256:fbfb45e7b297749029cb28694abf437a78695a100e7c2033983d69f0ba2698d4"}, + {file = "numba-0.56.4-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:3cb1a07a082a61df80a468f232e452d818f5ae254b40c26390054e4e868556e0"}, + {file = "numba-0.56.4-cp37-cp37m-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d69ad934e13c15684e7887100a8f5f0f61d7a8e57e0fd29d9993210089a5b531"}, + {file = "numba-0.56.4-cp37-cp37m-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:dbcc847bac2d225265d054993a7f910fda66e73d6662fe7156452cac0325b073"}, + {file = "numba-0.56.4-cp37-cp37m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8a95ca9cc77ea4571081f6594e08bd272b66060634b8324e99cd1843020364f9"}, + {file = "numba-0.56.4-cp37-cp37m-win32.whl", hash = "sha256:fcdf84ba3ed8124eb7234adfbb8792f311991cbf8aed1cad4b1b1a7ee08380c1"}, + {file = "numba-0.56.4-cp37-cp37m-win_amd64.whl", hash = "sha256:42f9e1be942b215df7e6cc9948cf9c15bb8170acc8286c063a9e57994ef82fd1"}, + {file = "numba-0.56.4-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:553da2ce74e8862e18a72a209ed3b6d2924403bdd0fb341fa891c6455545ba7c"}, + {file = "numba-0.56.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4373da9757049db7c90591e9ec55a2e97b2b36ba7ae3bf9c956a513374077470"}, + {file = "numba-0.56.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3a993349b90569518739009d8f4b523dfedd7e0049e6838c0e17435c3e70dcc4"}, + {file = "numba-0.56.4-cp38-cp38-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:720886b852a2d62619ae3900fe71f1852c62db4f287d0c275a60219e1643fc04"}, + {file = "numba-0.56.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e64d338b504c9394a4a34942df4627e1e6cb07396ee3b49fe7b8d6420aa5104f"}, + {file = "numba-0.56.4-cp38-cp38-win32.whl", hash = "sha256:03fe94cd31e96185cce2fae005334a8cc712fc2ba7756e52dff8c9400718173f"}, + {file = "numba-0.56.4-cp38-cp38-win_amd64.whl", hash = "sha256:91f021145a8081f881996818474ef737800bcc613ffb1e618a655725a0f9e246"}, + {file = "numba-0.56.4-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:d0ae9270a7a5cc0ede63cd234b4ff1ce166c7a749b91dbbf45e0000c56d3eade"}, + {file = "numba-0.56.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c75e8a5f810ce80a0cfad6e74ee94f9fde9b40c81312949bf356b7304ef20740"}, + {file = "numba-0.56.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a12ef323c0f2101529d455cfde7f4135eaa147bad17afe10b48634f796d96abd"}, + {file = "numba-0.56.4-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:03634579d10a6129181129de293dd6b5eaabee86881369d24d63f8fe352dd6cb"}, + {file = "numba-0.56.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0240f9026b015e336069329839208ebd70ec34ae5bfbf402e4fcc8e06197528e"}, + {file = "numba-0.56.4-cp39-cp39-win32.whl", hash = "sha256:14dbbabf6ffcd96ee2ac827389afa59a70ffa9f089576500434c34abf9b054a4"}, + {file = "numba-0.56.4-cp39-cp39-win_amd64.whl", hash = "sha256:0da583c532cd72feefd8e551435747e0e0fbb3c0530357e6845fcc11e38d6aea"}, + {file = "numba-0.56.4.tar.gz", hash = "sha256:32d9fef412c81483d7efe0ceb6cf4d3310fde8b624a9cecca00f790573ac96ee"}, +] + +[package.dependencies] +llvmlite = ">=0.39.0dev0,<0.40" +numpy = ">=1.18,<1.24" +setuptools = "*" + +[[package]] +name = "numpy" +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.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 = "oauthlib" +version = "3.2.2" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, + {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, +] + +[package.extras] +rsa = ["cryptography (>=3.0.0)"] +signals = ["blinker (>=1.4.0)"] +signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] + +[[package]] +name = "opt-einsum" +version = "3.3.0" +description = "Optimizing numpys einsum function" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "opt_einsum-3.3.0-py3-none-any.whl", hash = "sha256:2455e59e3947d3c275477df7f5205b30635e266fe6dc300e3d9f9646bfcea147"}, + {file = "opt_einsum-3.3.0.tar.gz", hash = "sha256:59f6475f77bbc37dcf7cd748519c0ec60722e91e63ca114e68821c0c54a46549"}, +] + +[package.dependencies] +numpy = ">=1.7" + +[package.extras] +docs = ["numpydoc", "sphinx (==1.2.3)", "sphinx-rtd-theme", "sphinxcontrib-napoleon"] +tests = ["pytest", "pytest-cov", "pytest-pep8"] + +[[package]] +name = "packaging" +version = "23.1" +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"}, +] + +[[package]] +name = "pandas" +version = "2.0.3" +description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" +optional = true +python-versions = ">=3.8" +files = [ + {file = "pandas-2.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c7c9f27a4185304c7caf96dc7d91bc60bc162221152de697c98eb0b2648dd8"}, + {file = "pandas-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f167beed68918d62bffb6ec64f2e1d8a7d297a038f86d4aed056b9493fca407f"}, + {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce0c6f76a0f1ba361551f3e6dceaff06bde7514a374aa43e33b588ec10420183"}, + {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba619e410a21d8c387a1ea6e8a0e49bb42216474436245718d7f2e88a2f8d7c0"}, + {file = "pandas-2.0.3-cp310-cp310-win32.whl", hash = "sha256:3ef285093b4fe5058eefd756100a367f27029913760773c8bf1d2d8bebe5d210"}, + {file = "pandas-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:9ee1a69328d5c36c98d8e74db06f4ad518a1840e8ccb94a4ba86920986bb617e"}, + {file = "pandas-2.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b084b91d8d66ab19f5bb3256cbd5ea661848338301940e17f4492b2ce0801fe8"}, + {file = "pandas-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37673e3bdf1551b95bf5d4ce372b37770f9529743d2498032439371fc7b7eb26"}, + {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9cb1e14fdb546396b7e1b923ffaeeac24e4cedd14266c3497216dd4448e4f2d"}, + {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9cd88488cceb7635aebb84809d087468eb33551097d600c6dad13602029c2df"}, + {file = "pandas-2.0.3-cp311-cp311-win32.whl", hash = "sha256:694888a81198786f0e164ee3a581df7d505024fbb1f15202fc7db88a71d84ebd"}, + {file = "pandas-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6a21ab5c89dcbd57f78d0ae16630b090eec626360085a4148693def5452d8a6b"}, + {file = "pandas-2.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4da0d45e7f34c069fe4d522359df7d23badf83abc1d1cef398895822d11061"}, + {file = "pandas-2.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:32fca2ee1b0d93dd71d979726b12b61faa06aeb93cf77468776287f41ff8fdc5"}, + {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:258d3624b3ae734490e4d63c430256e716f488c4fcb7c8e9bde2d3aa46c29089"}, + {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eae3dc34fa1aa7772dd3fc60270d13ced7346fcbcfee017d3132ec625e23bb0"}, + {file = "pandas-2.0.3-cp38-cp38-win32.whl", hash = "sha256:f3421a7afb1a43f7e38e82e844e2bca9a6d793d66c1a7f9f0ff39a795bbc5e02"}, + {file = "pandas-2.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:69d7f3884c95da3a31ef82b7618af5710dba95bb885ffab339aad925c3e8ce78"}, + {file = "pandas-2.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5247fb1ba347c1261cbbf0fcfba4a3121fbb4029d95d9ef4dc45406620b25c8b"}, + {file = "pandas-2.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81af086f4543c9d8bb128328b5d32e9986e0c84d3ee673a2ac6fb57fd14f755e"}, + {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1994c789bf12a7c5098277fb43836ce090f1073858c10f9220998ac74f37c69b"}, + {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ec591c48e29226bcbb316e0c1e9423622bc7a4eaf1ef7c3c9fa1a3981f89641"}, + {file = "pandas-2.0.3-cp39-cp39-win32.whl", hash = "sha256:04dbdbaf2e4d46ca8da896e1805bc04eb85caa9a82e259e8eed00254d5e0c682"}, + {file = "pandas-2.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:1168574b036cd8b93abc746171c9b4f1b83467438a5e45909fed645cf8692dbc"}, + {file = "pandas-2.0.3.tar.gz", hash = "sha256:c02f372a88e0d17f36d3093a644c73cfc1788e876a7c4bcb4020a77512e2043c"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.20.3", markers = "python_version < \"3.10\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.1" + +[package.extras] +all = ["PyQt5 (>=5.15.1)", "SQLAlchemy (>=1.4.16)", "beautifulsoup4 (>=4.9.3)", "bottleneck (>=1.3.2)", "brotlipy (>=0.7.0)", "fastparquet (>=0.6.3)", "fsspec (>=2021.07.0)", "gcsfs (>=2021.07.0)", "html5lib (>=1.1)", "hypothesis (>=6.34.2)", "jinja2 (>=3.0.0)", "lxml (>=4.6.3)", "matplotlib (>=3.6.1)", "numba (>=0.53.1)", "numexpr (>=2.7.3)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pandas-gbq (>=0.15.0)", "psycopg2 (>=2.8.6)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "python-snappy (>=0.6.0)", "pyxlsb (>=1.0.8)", "qtpy (>=2.2.0)", "s3fs (>=2021.08.0)", "scipy (>=1.7.1)", "tables (>=3.6.1)", "tabulate (>=0.8.9)", "xarray (>=0.21.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)", "zstandard (>=0.15.2)"] +aws = ["s3fs (>=2021.08.0)"] +clipboard = ["PyQt5 (>=5.15.1)", "qtpy (>=2.2.0)"] +compression = ["brotlipy (>=0.7.0)", "python-snappy (>=0.6.0)", "zstandard (>=0.15.2)"] +computation = ["scipy (>=1.7.1)", "xarray (>=0.21.0)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pyxlsb (>=1.0.8)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)"] +feather = ["pyarrow (>=7.0.0)"] +fss = ["fsspec (>=2021.07.0)"] +gcp = ["gcsfs (>=2021.07.0)", "pandas-gbq (>=0.15.0)"] +hdf5 = ["tables (>=3.6.1)"] +html = ["beautifulsoup4 (>=4.9.3)", "html5lib (>=1.1)", "lxml (>=4.6.3)"] +mysql = ["SQLAlchemy (>=1.4.16)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.0.0)", "tabulate (>=0.8.9)"] +parquet = ["pyarrow (>=7.0.0)"] +performance = ["bottleneck (>=1.3.2)", "numba (>=0.53.1)", "numexpr (>=2.7.1)"] +plot = ["matplotlib (>=3.6.1)"] +postgresql = ["SQLAlchemy (>=1.4.16)", "psycopg2 (>=2.8.6)"] +spss = ["pyreadstat (>=1.1.2)"] +sql-other = ["SQLAlchemy (>=1.4.16)"] +test = ["hypothesis (>=6.34.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.6.3)"] + +[[package]] +name = "partd" +version = "1.4.0" +description = "Appendable key-value storage" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "partd-1.4.0-py3-none-any.whl", hash = "sha256:7a63529348cf0dff14b986db641cd1b83c16b5cb9fc647c2851779db03282ef8"}, + {file = "partd-1.4.0.tar.gz", hash = "sha256:aa0ff35dbbcc807ae374db56332f4c1b39b46f67bf2975f5151e0b4186aed0d5"}, +] + +[package.dependencies] +locket = "*" +toolz = "*" + +[package.extras] +complete = ["blosc", "numpy (>=1.9.0)", "pandas (>=0.19.0)", "pyzmq"] + +[[package]] +name = "pathspec" +version = "0.11.1" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, + {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, +] + +[[package]] +name = "pillow" +version = "10.0.0" +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"}, +] + +[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 = "platformdirs" +version = "3.8.1" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.8.1-py3-none-any.whl", hash = "sha256:cec7b889196b9144d088e4c57d9ceef7374f6c39694ad1577a0aab50d27ea28c"}, + {file = "platformdirs-3.8.1.tar.gz", hash = "sha256:f87ca4fcff7d2b0f81c6a748a77973d7af0f4d526f98f308477c3c436c74d528"}, +] + +[package.extras] +docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] + +[[package]] +name = "pluggy" +version = "1.2.0" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "protobuf" +version = "3.19.6" +description = "Protocol Buffers" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "protobuf-3.19.6-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:010be24d5a44be7b0613750ab40bc8b8cedc796db468eae6c779b395f50d1fa1"}, + {file = "protobuf-3.19.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11478547958c2dfea921920617eb457bc26867b0d1aa065ab05f35080c5d9eb6"}, + {file = "protobuf-3.19.6-cp310-cp310-win32.whl", hash = "sha256:559670e006e3173308c9254d63facb2c03865818f22204037ab76f7a0ff70b5f"}, + {file = "protobuf-3.19.6-cp310-cp310-win_amd64.whl", hash = "sha256:347b393d4dd06fb93a77620781e11c058b3b0a5289262f094379ada2920a3730"}, + {file = "protobuf-3.19.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a8ce5ae0de28b51dff886fb922012dad885e66176663950cb2344c0439ecb473"}, + {file = "protobuf-3.19.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90b0d02163c4e67279ddb6dc25e063db0130fc299aefabb5d481053509fae5c8"}, + {file = "protobuf-3.19.6-cp36-cp36m-win32.whl", hash = "sha256:30f5370d50295b246eaa0296533403961f7e64b03ea12265d6dfce3a391d8992"}, + {file = "protobuf-3.19.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0c0714b025ec057b5a7600cb66ce7c693815f897cfda6d6efb58201c472e3437"}, + {file = "protobuf-3.19.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5057c64052a1f1dd7d4450e9aac25af6bf36cfbfb3a1cd89d16393a036c49157"}, + {file = "protobuf-3.19.6-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bb6776bd18f01ffe9920e78e03a8676530a5d6c5911934c6a1ac6eb78973ecb6"}, + {file = "protobuf-3.19.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a04134866861b11556a82dd91ea6daf1f4925746b992f277b84013a7cc1229"}, + {file = "protobuf-3.19.6-cp37-cp37m-win32.whl", hash = "sha256:4bc98de3cdccfb5cd769620d5785b92c662b6bfad03a202b83799b6ed3fa1fa7"}, + {file = "protobuf-3.19.6-cp37-cp37m-win_amd64.whl", hash = "sha256:aa3b82ca1f24ab5326dcf4ea00fcbda703e986b22f3d27541654f749564d778b"}, + {file = "protobuf-3.19.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2b2d2913bcda0e0ec9a784d194bc490f5dc3d9d71d322d070b11a0ade32ff6ba"}, + {file = "protobuf-3.19.6-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:d0b635cefebd7a8a0f92020562dead912f81f401af7e71f16bf9506ff3bdbb38"}, + {file = "protobuf-3.19.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a552af4dc34793803f4e735aabe97ffc45962dfd3a237bdde242bff5a3de684"}, + {file = "protobuf-3.19.6-cp38-cp38-win32.whl", hash = "sha256:0469bc66160180165e4e29de7f445e57a34ab68f49357392c5b2f54c656ab25e"}, + {file = "protobuf-3.19.6-cp38-cp38-win_amd64.whl", hash = "sha256:91d5f1e139ff92c37e0ff07f391101df77e55ebb97f46bbc1535298d72019462"}, + {file = "protobuf-3.19.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c0ccd3f940fe7f3b35a261b1dd1b4fc850c8fde9f74207015431f174be5976b3"}, + {file = "protobuf-3.19.6-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:30a15015d86b9c3b8d6bf78d5b8c7749f2512c29f168ca259c9d7727604d0e39"}, + {file = "protobuf-3.19.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:878b4cd080a21ddda6ac6d1e163403ec6eea2e206cf225982ae04567d39be7b0"}, + {file = "protobuf-3.19.6-cp39-cp39-win32.whl", hash = "sha256:5a0d7539a1b1fb7e76bf5faa0b44b30f812758e989e59c40f77a7dab320e79b9"}, + {file = "protobuf-3.19.6-cp39-cp39-win_amd64.whl", hash = "sha256:bbf5cea5048272e1c60d235c7bd12ce1b14b8a16e76917f371c718bd3005f045"}, + {file = "protobuf-3.19.6-py2.py3-none-any.whl", hash = "sha256:14082457dc02be946f60b15aad35e9f5c69e738f80ebbc0900a19bc83734a5a4"}, + {file = "protobuf-3.19.6.tar.gz", hash = "sha256:5f5540d57a43042389e87661c6eaa50f47c19c6176e8cf1c4f287aeefeccb5c4"}, +] + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] + +[[package]] +name = "pyaml" +version = "23.7.0" +description = "PyYAML-based module to produce a bit more pretty and readable YAML-serialized data" +category = "main" +optional = true +python-versions = ">=3.8" +files = [ + {file = "pyaml-23.7.0-py3-none-any.whl", hash = "sha256:0a37018282545ccc31faecbe138fda4d89e236af04d691cfb5af00cd60089345"}, + {file = "pyaml-23.7.0.tar.gz", hash = "sha256:0c510bbb8938309400e0b1e47ac16fd90e56d652805a93417128786718f33546"}, +] + +[package.dependencies] +PyYAML = "*" + +[package.extras] +anchors = ["unidecode"] + +[[package]] +name = "pyarrow" +version = "12.0.1" +description = "Python library for Apache Arrow" +category = "main" +optional = true +python-versions = ">=3.7" +files = [ + {file = "pyarrow-12.0.1-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:6d288029a94a9bb5407ceebdd7110ba398a00412c5b0155ee9813a40d246c5df"}, + {file = "pyarrow-12.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345e1828efdbd9aa4d4de7d5676778aba384a2c3add896d995b23d368e60e5af"}, + {file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d6009fdf8986332b2169314da482baed47ac053311c8934ac6651e614deacd6"}, + {file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d3c4cbbf81e6dd23fe921bc91dc4619ea3b79bc58ef10bce0f49bdafb103daf"}, + {file = "pyarrow-12.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:cdacf515ec276709ac8042c7d9bd5be83b4f5f39c6c037a17a60d7ebfd92c890"}, + {file = "pyarrow-12.0.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:749be7fd2ff260683f9cc739cb862fb11be376de965a2a8ccbf2693b098db6c7"}, + {file = "pyarrow-12.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6895b5fb74289d055c43db3af0de6e16b07586c45763cb5e558d38b86a91e3a7"}, + {file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1887bdae17ec3b4c046fcf19951e71b6a619f39fa674f9881216173566c8f718"}, + {file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2c9cb8eeabbadf5fcfc3d1ddea616c7ce893db2ce4dcef0ac13b099ad7ca082"}, + {file = "pyarrow-12.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:ce4aebdf412bd0eeb800d8e47db854f9f9f7e2f5a0220440acf219ddfddd4f63"}, + {file = "pyarrow-12.0.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:e0d8730c7f6e893f6db5d5b86eda42c0a130842d101992b581e2138e4d5663d3"}, + {file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43364daec02f69fec89d2315f7fbfbeec956e0d991cbbef471681bd77875c40f"}, + {file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:051f9f5ccf585f12d7de836e50965b3c235542cc896959320d9776ab93f3b33d"}, + {file = "pyarrow-12.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:be2757e9275875d2a9c6e6052ac7957fbbfc7bc7370e4a036a9b893e96fedaba"}, + {file = "pyarrow-12.0.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:cf812306d66f40f69e684300f7af5111c11f6e0d89d6b733e05a3de44961529d"}, + {file = "pyarrow-12.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:459a1c0ed2d68671188b2118c63bac91eaef6fc150c77ddd8a583e3c795737bf"}, + {file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e705e33eaf666bbe508a16fd5ba27ca061e177916b7a317ba5a51bee43384c"}, + {file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9120c3eb2b1f6f516a3b7a9714ed860882d9ef98c4b17edcdc91d95b7528db60"}, + {file = "pyarrow-12.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c780f4dc40460015d80fcd6a6140de80b615349ed68ef9adb653fe351778c9b3"}, + {file = "pyarrow-12.0.1-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:a3c63124fc26bf5f95f508f5d04e1ece8cc23a8b0af2a1e6ab2b1ec3fdc91b24"}, + {file = "pyarrow-12.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b13329f79fa4472324f8d32dc1b1216616d09bd1e77cfb13104dec5463632c36"}, + {file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb656150d3d12ec1396f6dde542db1675a95c0cc8366d507347b0beed96e87ca"}, + {file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6251e38470da97a5b2e00de5c6a049149f7b2bd62f12fa5dbb9ac674119ba71a"}, + {file = "pyarrow-12.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:3de26da901216149ce086920547dfff5cd22818c9eab67ebc41e863a5883bac7"}, + {file = "pyarrow-12.0.1.tar.gz", hash = "sha256:cce317fc96e5b71107bf1f9f184d5e54e2bd14bbf3f9a3d62819961f0af86fec"}, +] + +[package.dependencies] +numpy = ">=1.16.6" + +[[package]] +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 = [ + {file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"}, + {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"}, +] + +[[package]] +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 = [ + {file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"}, + {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"}, +] + +[package.dependencies] +pyasn1 = ">=0.4.6,<0.6.0" + +[[package]] +name = "pybtex" +version = "0.24.0" +description = "A BibTeX-compatible bibliography processor in Python" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" +files = [ + {file = "pybtex-0.24.0-py2.py3-none-any.whl", hash = "sha256:e1e0c8c69998452fea90e9179aa2a98ab103f3eed894405b7264e517cc2fcc0f"}, + {file = "pybtex-0.24.0.tar.gz", hash = "sha256:818eae35b61733e5c007c3fcd2cfb75ed1bc8b4173c1f70b56cc4c0802d34755"}, +] + +[package.dependencies] +latexcodec = ">=1.0.4" +PyYAML = ">=3.01" +six = "*" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "pybtex-docutils" +version = "1.0.2" +description = "A docutils backend for pybtex." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pybtex-docutils-1.0.2.tar.gz", hash = "sha256:43aa353b6d498fd5ac30f0073a98e332d061d34fe619d3d50d1761f8fd4aa016"}, + {file = "pybtex_docutils-1.0.2-py3-none-any.whl", hash = "sha256:6f9e3c25a37bcaac8c4f69513272706ec6253bb708a93d8b4b173f43915ba239"}, +] + +[package.dependencies] +docutils = ">=0.8" +pybtex = ">=0.16" + +[[package]] +name = "pygments" +version = "2.15.1" +description = "Pygments is a syntax highlighting package written in Python." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, + {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, +] + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pylint" +version = "2.10.0" +description = "python code static checker" +category = "dev" +optional = false +python-versions = "~=3.6" +files = [ + {file = "pylint-2.10.0-py3-none-any.whl", hash = "sha256:2d01c6de5ea20443e3f7ed8ae285f75b2d4da92e840f10118ddb7da18a1e09df"}, + {file = "pylint-2.10.0.tar.gz", hash = "sha256:dcf4a5dd7bc98c68790323f783d792423c1946e7a4a195e44d7b2c2d386f457d"}, +] + +[package.dependencies] +appdirs = ">=1.4.0" +astroid = ">=2.7.2,<2.8" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.7" +toml = ">=0.7.1" + +[[package]] +name = "pyparsing" +version = "3.1.0" +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.1.0-py3-none-any.whl", hash = "sha256:d554a96d1a7d3ddaf7183104485bc19fd80543ad6ac5bdb6426719d766fb06c1"}, + {file = "pyparsing-3.1.0.tar.gz", hash = "sha256:edb662d6fe322d6e990b1594b5feaeadf806803359e3d4d42f11e295e588f0ea"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pytest" +version = "6.2.5" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, +] + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +toml = "*" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "3.0.0" +description = "Pytest plugin for measuring coverage." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, + {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[[package]] +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 = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2023.3" +description = "World timezone definitions, modern and historical" +category = "main" +optional = true +python-versions = "*" +files = [ + {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, + {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, +] + +[[package]] +name = "pyyaml" +version = "6.0" +description = "YAML parser and emitter for Python" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, + {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, +] + +[[package]] +name = "ray" +version = "2.5.0" +description = "Ray provides a simple, universal API for building distributed applications." +category = "main" +optional = true +python-versions = "*" +files = [ + {file = "ray-2.5.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:d1bebc874e896880c1215f4c1a11697ada49fa1595d6d99d7c5b4dc03030df36"}, + {file = "ray-2.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0285df2d24cacc36ca64b7852178a9bf37e3fc88545752fc2b46c27396965c1"}, + {file = "ray-2.5.0-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:38935d46c2597c1d1f113e1c8f88e2716c67052c480de5b2a0265e0a1a5ce88f"}, + {file = "ray-2.5.0-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:d53a07c9a9dbc134945a26980f557e9ff0f591bf8cabed1a6ebf921768d1c8bd"}, + {file = "ray-2.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:ef26ba24461dad98365b48ef01e27e70bc9737f4cf4734115804153d7d9195dc"}, + {file = "ray-2.5.0-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d714175a5000ca91f82646a9b72521118bb6d2db5568e1b7ae9ceb64769716b6"}, + {file = "ray-2.5.0-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:0cde929e63497ed5f1c8626e5ccf7595ef6acaf1e7e270ad7c12f8e1c7695244"}, + {file = "ray-2.5.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:7e5512abf62c05c9ff90b1c89a4e0f2e45ee00e73f816eb8265e3ebd92fe4064"}, + {file = "ray-2.5.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3bf36beb213f89c0eb1ec5ac6ffddc8f53e616be745167f00ca017abd8672a2d"}, + {file = "ray-2.5.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:59c2448b07f45d9a9d8e594bb5337bd35a5fea04e42cb4211a3346c2c0d066b0"}, + {file = "ray-2.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:63008dd659d9ef25b0e20f0e1a285e8266e0af68b1178bca1b6ae43e49a68104"}, + {file = "ray-2.5.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:e9464e93d6b72e0da69b9c5ab0501cc40f2db14801e22c6b97fa4e8039647892"}, + {file = "ray-2.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7dc00fac119bfa1c2f8ac456d50a728346d6f2722fb7a21bf70841fc7476c285"}, + {file = "ray-2.5.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:d76051519bd4ae39fda4a87536978cafdebf2843c1c29a9f734c503d8ea676cd"}, + {file = "ray-2.5.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:9a8e06dc5d4201129c28b6768a971c474b82a23935b2e40461ffc7f1c2f4942a"}, + {file = "ray-2.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:849014b62ca50ff106b7a5d41430346e2762b1c4c803673af076209925b8f912"}, + {file = "ray-2.5.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:a1b52c12a3349d8e37357df31438b6f1b12c7719ef41bdf5089fc7e78e8ab212"}, + {file = "ray-2.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:25f3d50c27c4c4756259d093d152381c6604bb96684a0cf43c55ddcc2eb73f79"}, + {file = "ray-2.5.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:1cb4f6ef9cfdb69d2ae582f357e977527944390e2f5cbbf51efd8252ed4c9a11"}, + {file = "ray-2.5.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:662cff303c086369a29283badcd7445b7f911874d8407b2c589b1ccbf6028d2e"}, + {file = "ray-2.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:a2cea10981dad7cfd187edf5e225a667eb114269afc5f2321b52113ef2d86123"}, +] + +[package.dependencies] +aiosignal = "*" +attrs = "*" +click = ">=7.0" +filelock = "*" +frozenlist = "*" +grpcio = [ + {version = ">=1.32.0,<=1.51.3", markers = "python_version < \"3.10\" and sys_platform != \"darwin\""}, + {version = ">=1.32.0,<=1.49.1", markers = "python_version < \"3.10\" and sys_platform == \"darwin\""}, + {version = ">=1.42.0,<=1.51.3", markers = "python_version >= \"3.10\" and sys_platform != \"darwin\""}, + {version = ">=1.42.0,<=1.49.1", markers = "python_version >= \"3.10\" and sys_platform == \"darwin\""}, +] +jsonschema = "*" +msgpack = ">=1.0.0,<2.0.0" +numpy = {version = ">=1.19.3", markers = "python_version >= \"3.9\""} +packaging = "*" +pandas = {version = "*", optional = true, markers = "extra == \"tune\""} +protobuf = ">=3.15.3,<3.19.5 || >3.19.5" +pyarrow = {version = ">=6.0.1", optional = true, markers = "extra == \"tune\""} +pyyaml = "*" +requests = "*" +tensorboardX = {version = ">=1.9", optional = true, markers = "extra == \"tune\""} + +[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", "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)", "gymnasium (==0.26.3)", "kubernetes", "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", "pyyaml", "ray-cpp (==2.5.0)", "requests", "rich", "scikit-image", "scipy", "smart-open", "starlette", "tensorboardX (>=1.9)", "typer", "urllib3", "uvicorn", "virtualenv (>=20.0.24,<20.21.1)"] +cpp = ["ray-cpp (==2.5.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", "requests", "smart-open", "virtualenv (>=20.0.24,<20.21.1)"] +k8s = ["kubernetes", "urllib3"] +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", "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.29.1" +description = "JSON Referencing + Python" +category = "main" +optional = true +python-versions = ">=3.8" +files = [ + {file = "referencing-0.29.1-py3-none-any.whl", hash = "sha256:d3c8f323ee1480095da44d55917cfb8278d73d6b4d5f677e3e40eb21314ac67f"}, + {file = "referencing-0.29.1.tar.gz", hash = "sha256:90cb53782d550ba28d2166ef3f55731f38397def8832baac5d45235f1995e35e"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-oauthlib" +version = "1.3.1" +description = "OAuthlib authentication support for Requests." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, + {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, +] + +[package.dependencies] +oauthlib = ">=3.0.0" +requests = ">=2.0.0" + +[package.extras] +rsa = ["oauthlib[signedtoken] (>=3.0.0)"] + +[[package]] +name = "rich" +version = "10.15.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "main" +optional = false +python-versions = ">=3.6.2,<4.0.0" +files = [ + {file = "rich-10.15.1-py3-none-any.whl", hash = "sha256:a59fb2721c52c5061ac65f318c0afb709e098b1ab6ce5813ea38982654c4b6ee"}, + {file = "rich-10.15.1.tar.gz", hash = "sha256:93d0ea3c35ecfd8703dbe52b76885e224ad8d68c7766c921c726b14b22a57b7d"}, +] + +[package.dependencies] +colorama = ">=0.4.0,<0.5.0" +commonmark = ">=0.9.0,<0.10.0" +pygments = ">=2.6.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] + +[[package]] +name = "rpds-py" +version = "0.8.10" +description = "Python bindings to Rust's persistent data structures (rpds)" +category = "main" +optional = true +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.8.10-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:93d06cccae15b3836247319eee7b6f1fdcd6c10dabb4e6d350d27bd0bdca2711"}, + {file = "rpds_py-0.8.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3816a890a6a9e9f1de250afa12ca71c9a7a62f2b715a29af6aaee3aea112c181"}, + {file = "rpds_py-0.8.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7c6304b894546b5a6bdc0fe15761fa53fe87d28527a7142dae8de3c663853e1"}, + {file = "rpds_py-0.8.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ad3bfb44c8840fb4be719dc58e229f435e227fbfbe133dc33f34981ff622a8f8"}, + {file = "rpds_py-0.8.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:14f1c356712f66653b777ecd8819804781b23dbbac4eade4366b94944c9e78ad"}, + {file = "rpds_py-0.8.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82bb361cae4d0a627006dadd69dc2f36b7ad5dc1367af9d02e296ec565248b5b"}, + {file = "rpds_py-0.8.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2e3c4f2a8e3da47f850d7ea0d7d56720f0f091d66add889056098c4b2fd576c"}, + {file = "rpds_py-0.8.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15a90d0ac11b4499171067ae40a220d1ca3cb685ec0acc356d8f3800e07e4cb8"}, + {file = "rpds_py-0.8.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:70bb9c8004b97b4ef7ae56a2aa56dfaa74734a0987c78e7e85f00004ab9bf2d0"}, + {file = "rpds_py-0.8.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d64f9f88d5203274a002b54442cafc9c7a1abff2a238f3e767b70aadf919b451"}, + {file = "rpds_py-0.8.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ccbbd276642788c4376fbe8d4e6c50f0fb4972ce09ecb051509062915891cbf0"}, + {file = "rpds_py-0.8.10-cp310-none-win32.whl", hash = "sha256:fafc0049add8043ad07ab5382ee80d80ed7e3699847f26c9a5cf4d3714d96a84"}, + {file = "rpds_py-0.8.10-cp310-none-win_amd64.whl", hash = "sha256:915031002c86a5add7c6fd4beb601b2415e8a1c956590a5f91d825858e92fe6e"}, + {file = "rpds_py-0.8.10-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:84eb541a44f7a18f07a6bfc48b95240739e93defe1fdfb4f2a295f37837945d7"}, + {file = "rpds_py-0.8.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f59996d0550894affaad8743e97b9b9c98f638b221fac12909210ec3d9294786"}, + {file = "rpds_py-0.8.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9adb5664b78fcfcd830000416c8cc69853ef43cb084d645b3f1f0296edd9bae"}, + {file = "rpds_py-0.8.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f96f3f98fbff7af29e9edf9a6584f3c1382e7788783d07ba3721790625caa43e"}, + {file = "rpds_py-0.8.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:376b8de737401050bd12810003d207e824380be58810c031f10ec563ff6aef3d"}, + {file = "rpds_py-0.8.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d1c2bc319428d50b3e0fa6b673ab8cc7fa2755a92898db3a594cbc4eeb6d1f7"}, + {file = "rpds_py-0.8.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73a1e48430f418f0ac3dfd87860e4cc0d33ad6c0f589099a298cb53724db1169"}, + {file = "rpds_py-0.8.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:134ec8f14ca7dbc6d9ae34dac632cdd60939fe3734b5d287a69683c037c51acb"}, + {file = "rpds_py-0.8.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4b519bac7c09444dd85280fd60f28c6dde4389c88dddf4279ba9b630aca3bbbe"}, + {file = "rpds_py-0.8.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9cd57981d9fab04fc74438d82460f057a2419974d69a96b06a440822d693b3c0"}, + {file = "rpds_py-0.8.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:69d089c026f6a8b9d64a06ff67dc3be196707b699d7f6ca930c25f00cf5e30d8"}, + {file = "rpds_py-0.8.10-cp311-none-win32.whl", hash = "sha256:220bdcad2d2936f674650d304e20ac480a3ce88a40fe56cd084b5780f1d104d9"}, + {file = "rpds_py-0.8.10-cp311-none-win_amd64.whl", hash = "sha256:6c6a0225b8501d881b32ebf3f5807a08ad3685b5eb5f0a6bfffd3a6e039b2055"}, + {file = "rpds_py-0.8.10-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:e3d0cd3dff0e7638a7b5390f3a53057c4e347f4ef122ee84ed93fc2fb7ea4aa2"}, + {file = "rpds_py-0.8.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d77dff3a5aa5eedcc3da0ebd10ff8e4969bc9541aa3333a8d41715b429e99f47"}, + {file = "rpds_py-0.8.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41c89a366eae49ad9e65ed443a8f94aee762931a1e3723749d72aeac80f5ef2f"}, + {file = "rpds_py-0.8.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3793c21494bad1373da517001d0849eea322e9a049a0e4789e50d8d1329df8e7"}, + {file = "rpds_py-0.8.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:805a5f3f05d186c5d50de2e26f765ba7896d0cc1ac5b14ffc36fae36df5d2f10"}, + {file = "rpds_py-0.8.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b01b39ad5411563031ea3977bbbc7324d82b088e802339e6296f082f78f6115c"}, + {file = "rpds_py-0.8.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3f1e860be21f3e83011116a65e7310486300e08d9a3028e73e8d13bb6c77292"}, + {file = "rpds_py-0.8.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a13c8e56c46474cd5958d525ce6a9996727a83d9335684e41f5192c83deb6c58"}, + {file = "rpds_py-0.8.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:93d99f957a300d7a4ced41615c45aeb0343bb8f067c42b770b505de67a132346"}, + {file = "rpds_py-0.8.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:148b0b38d719c0760e31ce9285a9872972bdd7774969a4154f40c980e5beaca7"}, + {file = "rpds_py-0.8.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3cc5e5b5514796f45f03a568981971b12a3570f3de2e76114f7dc18d4b60a3c4"}, + {file = "rpds_py-0.8.10-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:e8e24b210a4deb5a7744971f8f77393005bae7f873568e37dfd9effe808be7f7"}, + {file = "rpds_py-0.8.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b41941583adce4242af003d2a8337b066ba6148ca435f295f31ac6d9e4ea2722"}, + {file = "rpds_py-0.8.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c490204e16bca4f835dba8467869fe7295cdeaa096e4c5a7af97f3454a97991"}, + {file = "rpds_py-0.8.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ee45cd1d84beed6cbebc839fd85c2e70a3a1325c8cfd16b62c96e2ffb565eca"}, + {file = "rpds_py-0.8.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a8ca409f1252e1220bf09c57290b76cae2f14723746215a1e0506472ebd7bdf"}, + {file = "rpds_py-0.8.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96b293c0498c70162effb13100624c5863797d99df75f2f647438bd10cbf73e4"}, + {file = "rpds_py-0.8.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4627520a02fccbd324b33c7a83e5d7906ec746e1083a9ac93c41ac7d15548c7"}, + {file = "rpds_py-0.8.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e39d7ab0c18ac99955b36cd19f43926450baba21e3250f053e0704d6ffd76873"}, + {file = "rpds_py-0.8.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ba9f1d1ebe4b63801977cec7401f2d41e888128ae40b5441270d43140efcad52"}, + {file = "rpds_py-0.8.10-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:802f42200d8caf7f25bbb2a6464cbd83e69d600151b7e3b49f49a47fa56b0a38"}, + {file = "rpds_py-0.8.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d19db6ba816e7f59fc806c690918da80a7d186f00247048cd833acdab9b4847b"}, + {file = "rpds_py-0.8.10-cp38-none-win32.whl", hash = "sha256:7947e6e2c2ad68b1c12ee797d15e5f8d0db36331200b0346871492784083b0c6"}, + {file = "rpds_py-0.8.10-cp38-none-win_amd64.whl", hash = "sha256:fa326b3505d5784436d9433b7980171ab2375535d93dd63fbcd20af2b5ca1bb6"}, + {file = "rpds_py-0.8.10-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7b38a9ac96eeb6613e7f312cd0014de64c3f07000e8bf0004ad6ec153bac46f8"}, + {file = "rpds_py-0.8.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c4d42e83ddbf3445e6514f0aff96dca511421ed0392d9977d3990d9f1ba6753c"}, + {file = "rpds_py-0.8.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b21575031478609db6dbd1f0465e739fe0e7f424a8e7e87610a6c7f68b4eb16"}, + {file = "rpds_py-0.8.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:574868858a7ff6011192c023a5289158ed20e3f3b94b54f97210a773f2f22921"}, + {file = "rpds_py-0.8.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae40f4a70a1f40939d66ecbaf8e7edc144fded190c4a45898a8cfe19d8fc85ea"}, + {file = "rpds_py-0.8.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37f7ee4dc86db7af3bac6d2a2cedbecb8e57ce4ed081f6464510e537589f8b1e"}, + {file = "rpds_py-0.8.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:695f642a3a5dbd4ad2ffbbacf784716ecd87f1b7a460843b9ddf965ccaeafff4"}, + {file = "rpds_py-0.8.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f43ab4cb04bde6109eb2555528a64dfd8a265cc6a9920a67dcbde13ef53a46c8"}, + {file = "rpds_py-0.8.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a11ab0d97be374efd04f640c04fe5c2d3dabc6dfb998954ea946ee3aec97056d"}, + {file = "rpds_py-0.8.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:92cf5b3ee60eef41f41e1a2cabca466846fb22f37fc580ffbcb934d1bcab225a"}, + {file = "rpds_py-0.8.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ceaac0c603bf5ac2f505a78b2dcab78d3e6b706be6596c8364b64cc613d208d2"}, + {file = "rpds_py-0.8.10-cp39-none-win32.whl", hash = "sha256:dd4f16e57c12c0ae17606c53d1b57d8d1c8792efe3f065a37cb3341340599d49"}, + {file = "rpds_py-0.8.10-cp39-none-win_amd64.whl", hash = "sha256:c03a435d26c3999c2a8642cecad5d1c4d10c961817536af52035f6f4ee2f5dd0"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0da53292edafecba5e1d8c1218f99babf2ed0bf1c791d83c0ab5c29b57223068"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d20a8ed227683401cc508e7be58cba90cc97f784ea8b039c8cd01111e6043e0"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97cab733d303252f7c2f7052bf021a3469d764fc2b65e6dbef5af3cbf89d4892"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8c398fda6df361a30935ab4c4bccb7f7a3daef2964ca237f607c90e9f3fdf66f"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2eb4b08c45f8f8d8254cdbfacd3fc5d6b415d64487fb30d7380b0d0569837bf1"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7dfb1cbb895810fa2b892b68153c17716c6abaa22c7dc2b2f6dcf3364932a1c"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89c92b74e8bf6f53a6f4995fd52f4bd510c12f103ee62c99e22bc9e05d45583c"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e9c0683cb35a9b5881b41bc01d5568ffc667910d9dbc632a1fba4e7d59e98773"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0eeb2731708207d0fe2619afe6c4dc8cb9798f7de052da891de5f19c0006c315"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:7495010b658ec5b52835f21d8c8b1a7e52e194c50f095d4223c0b96c3da704b1"}, + {file = "rpds_py-0.8.10-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c72ebc22e70e04126158c46ba56b85372bc4d54d00d296be060b0db1671638a4"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:2cd3045e7f6375dda64ed7db1c5136826facb0159ea982f77d9cf6125025bd34"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:2418cf17d653d24ffb8b75e81f9f60b7ba1b009a23298a433a4720b2a0a17017"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a2edf8173ac0c7a19da21bc68818be1321998528b5e3f748d6ee90c0ba2a1fd"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f29b8c55fd3a2bc48e485e37c4e2df3317f43b5cc6c4b6631c33726f52ffbb3"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a7d20c1cf8d7b3960c5072c265ec47b3f72a0c608a9a6ee0103189b4f28d531"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:521fc8861a86ae54359edf53a15a05fabc10593cea7b3357574132f8427a5e5a"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5c191713e98e7c28800233f039a32a42c1a4f9a001a8a0f2448b07391881036"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:083df0fafe199371206111583c686c985dddaf95ab3ee8e7b24f1fda54515d09"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ed41f3f49507936a6fe7003985ea2574daccfef999775525d79eb67344e23767"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:2614c2732bf45de5c7f9e9e54e18bc78693fa2f635ae58d2895b7965e470378c"}, + {file = "rpds_py-0.8.10-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c60528671d9d467009a6ec284582179f6b88651e83367d0ab54cb739021cd7de"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ee744fca8d1ea822480a2a4e7c5f2e1950745477143668f0b523769426060f29"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a38b9f526d0d6cbdaa37808c400e3d9f9473ac4ff64d33d9163fd05d243dbd9b"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60e0e86e870350e03b3e25f9b1dd2c6cc72d2b5f24e070249418320a6f9097b7"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f53f55a8852f0e49b0fc76f2412045d6ad9d5772251dea8f55ea45021616e7d5"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c493365d3fad241d52f096e4995475a60a80f4eba4d3ff89b713bc65c2ca9615"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:300eb606e6b94a7a26f11c8cc8ee59e295c6649bd927f91e1dbd37a4c89430b6"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a665f6f1a87614d1c3039baf44109094926dedf785e346d8b0a728e9cabd27a"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:927d784648211447201d4c6f1babddb7971abad922b32257ab74de2f2750fad0"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:c200b30dd573afa83847bed7e3041aa36a8145221bf0cfdfaa62d974d720805c"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:08166467258fd0240a1256fce272f689f2360227ee41c72aeea103e9e4f63d2b"}, + {file = "rpds_py-0.8.10-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:996cc95830de9bc22b183661d95559ec6b3cd900ad7bc9154c4cbf5be0c9b734"}, + {file = "rpds_py-0.8.10.tar.gz", hash = "sha256:13e643ce8ad502a0263397362fb887594b49cf84bf518d6038c16f235f2bcea4"}, +] + +[[package]] +name = "rsa" +version = "4.9" +description = "Pure-Python RSA implementation" +category = "main" +optional = false +python-versions = ">=3.6,<4" +files = [ + {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, + {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, +] + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +name = "scikit-learn" +version = "1.3.0" +description = "A set of python modules for machine learning and data mining" +category = "main" +optional = true +python-versions = ">=3.8" +files = [ + {file = "scikit-learn-1.3.0.tar.gz", hash = "sha256:8be549886f5eda46436b6e555b0e4873b4f10aa21c07df45c4bc1735afbccd7a"}, + {file = "scikit_learn-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:981287869e576d42c682cf7ca96af0c6ac544ed9316328fd0d9292795c742cf5"}, + {file = "scikit_learn-1.3.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:436aaaae2c916ad16631142488e4c82f4296af2404f480e031d866863425d2a2"}, + {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7e28d8fa47a0b30ae1bd7a079519dd852764e31708a7804da6cb6f8b36e3630"}, + {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae80c08834a473d08a204d966982a62e11c976228d306a2648c575e3ead12111"}, + {file = "scikit_learn-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:552fd1b6ee22900cf1780d7386a554bb96949e9a359999177cf30211e6b20df6"}, + {file = "scikit_learn-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79970a6d759eb00a62266a31e2637d07d2d28446fca8079cf9afa7c07b0427f8"}, + {file = "scikit_learn-1.3.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:850a00b559e636b23901aabbe79b73dc604b4e4248ba9e2d6e72f95063765603"}, + {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee04835fb016e8062ee9fe9074aef9b82e430504e420bff51e3e5fffe72750ca"}, + {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d953531f5d9f00c90c34fa3b7d7cfb43ecff4c605dac9e4255a20b114a27369"}, + {file = "scikit_learn-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:151ac2bf65ccf363664a689b8beafc9e6aae36263db114b4ca06fbbbf827444a"}, + {file = "scikit_learn-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a885a9edc9c0a341cab27ec4f8a6c58b35f3d449c9d2503a6fd23e06bbd4f6a"}, + {file = "scikit_learn-1.3.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:9877af9c6d1b15486e18a94101b742e9d0d2f343d35a634e337411ddb57783f3"}, + {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c470f53cea065ff3d588050955c492793bb50c19a92923490d18fcb637f6383a"}, + {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6e2d7389542eae01077a1ee0318c4fec20c66c957f45c7aac0c6eb0fe3c612"}, + {file = "scikit_learn-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:3a11936adbc379a6061ea32fa03338d4ca7248d86dd507c81e13af428a5bc1db"}, + {file = "scikit_learn-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:998d38fcec96584deee1e79cd127469b3ad6fefd1ea6c2dfc54e8db367eb396b"}, + {file = "scikit_learn-1.3.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ded35e810438a527e17623ac6deae3b360134345b7c598175ab7741720d7ffa7"}, + {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e8102d5036e28d08ab47166b48c8d5e5810704daecf3a476a4282d562be9a28"}, + {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7617164951c422747e7c32be4afa15d75ad8044f42e7d70d3e2e0429a50e6718"}, + {file = "scikit_learn-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:1d54fb9e6038284548072df22fd34777e434153f7ffac72c8596f2d6987110dd"}, +] + +[package.dependencies] +joblib = ">=1.1.1" +numpy = ">=1.17.3" +scipy = ">=1.5.0" +threadpoolctl = ">=2.0.0" + +[package.extras] +benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.10.1)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] +tests = ["black (>=23.3.0)", "matplotlib (>=3.1.3)", "mypy (>=1.3)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.0.272)", "scikit-image (>=0.16.2)"] + +[[package]] +name = "scikit-optimize" +version = "0.9.0" +description = "Sequential model-based optimization toolbox." +category = "main" +optional = true +python-versions = "*" +files = [ + {file = "scikit-optimize-0.9.0.tar.gz", hash = "sha256:77d8c9e64947fc9f5cc05bbc6aed7b8a9907871ae26fe11997fd67be90f26008"}, + {file = "scikit_optimize-0.9.0-py2.py3-none-any.whl", hash = "sha256:5a439a18232381fad4bda78e914b616416720708e67f123498d14bd2842d861a"}, +] + +[package.dependencies] +joblib = ">=0.11" +numpy = ">=1.13.3" +pyaml = ">=16.9" +scikit-learn = ">=0.20.0" +scipy = ">=0.19.1" + +[package.extras] +plots = ["matplotlib (>=2.0.0)"] + +[[package]] +name = "scipy" +version = "1.8.0" +description = "SciPy: Scientific Library for Python" +category = "main" +optional = false +python-versions = ">=3.8,<3.11" +files = [ + {file = "scipy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:87b01c7d5761e8a266a0fbdb9d88dcba0910d63c1c671bdb4d99d29f469e9e03"}, + {file = "scipy-1.8.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ae3e327da323d82e918e593460e23babdce40d7ab21490ddf9fc06dec6b91a18"}, + {file = "scipy-1.8.0-cp310-cp310-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:16e09ef68b352d73befa8bcaf3ebe25d3941fe1a58c82909d5589856e6bc8174"}, + {file = "scipy-1.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c17a1878d00a5dd2797ccd73623ceca9d02375328f6218ee6d921e1325e61aff"}, + {file = "scipy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937d28722f13302febde29847bbe554b89073fbb924a30475e5ed7b028898b5f"}, + {file = "scipy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:8f4d059a97b29c91afad46b1737274cb282357a305a80bdd9e8adf3b0ca6a3f0"}, + {file = "scipy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:38aa39b6724cb65271e469013aeb6f2ce66fd44f093e241c28a9c6bc64fd79ed"}, + {file = "scipy-1.8.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:559a8a4c03a5ba9fe3232f39ed24f86457e4f3f6c0abbeae1fb945029f092720"}, + {file = "scipy-1.8.0-cp38-cp38-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:f4a6d3b9f9797eb2d43938ac2c5d96d02aed17ef170c8b38f11798717523ddba"}, + {file = "scipy-1.8.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b2c2af4183ed09afb595709a8ef5783b2baf7f41e26ece24e1329c109691a7"}, + {file = "scipy-1.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a279e27c7f4566ef18bab1b1e2c37d168e365080974758d107e7d237d3f0f484"}, + {file = "scipy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad5be4039147c808e64f99c0e8a9641eb5d2fa079ff5894dcd8240e94e347af4"}, + {file = "scipy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:3d9dd6c8b93a22bf9a3a52d1327aca7e092b1299fb3afc4f89e8eba381be7b59"}, + {file = "scipy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:5e73343c5e0d413c1f937302b2e04fb07872f5843041bcfd50699aef6e95e399"}, + {file = "scipy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:de2e80ee1d925984c2504812a310841c241791c5279352be4707cdcd7c255039"}, + {file = "scipy-1.8.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:c2bae431d127bf0b1da81fc24e4bba0a84d058e3a96b9dd6475dfcb3c5e8761e"}, + {file = "scipy-1.8.0-cp39-cp39-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:723b9f878095ed994756fa4ee3060c450e2db0139c5ba248ee3f9628bd64e735"}, + {file = "scipy-1.8.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:011d4386b53b933142f58a652aa0f149c9b9242abd4f900b9f4ea5fbafc86b89"}, + {file = "scipy-1.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6f0cd9c0bd374ef834ee1e0f0999678d49dcc400ea6209113d81528958f97c7"}, + {file = "scipy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3720d0124aced49f6f2198a6900304411dbbeed12f56951d7c66ebef05e3df6"}, + {file = "scipy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:3d573228c10a3a8c32b9037be982e6440e411b443a6267b067cac72f690b8d56"}, + {file = "scipy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb7088e89cd751acf66195d2f00cf009a1ea113f3019664032d9075b1e727b6c"}, + {file = "scipy-1.8.0.tar.gz", hash = "sha256:31d4f2d6b724bc9a98e527b5849b8a7e589bf1ea630c33aa563eda912c9ff0bd"}, +] + +[package.dependencies] +numpy = ">=1.17.3,<1.25.0" + +[[package]] +name = "setuptools" +version = "68.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, + {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "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 (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "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)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "setuptools-scm" +version = "7.1.0" +description = "the blessed package to manage your versions by scm tags" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "setuptools_scm-7.1.0-py3-none-any.whl", hash = "sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e"}, + {file = "setuptools_scm-7.1.0.tar.gz", hash = "sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27"}, +] + +[package.dependencies] +packaging = ">=20.0" +setuptools = "*" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +typing-extensions = "*" + +[package.extras] +test = ["pytest (>=6.2)", "virtualenv (>20)"] +toml = ["setuptools (>=42)"] + +[[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 = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] + +[[package]] +name = "sortedcontainers" +version = "2.4.0" +description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, + {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, +] + +[[package]] +name = "sphinx" +version = "7.0.1" +description = "Python documentation generator" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "Sphinx-7.0.1.tar.gz", hash = "sha256:61e025f788c5977d9412587e733733a289e2b9fdc2fef8868ddfbfc4ccfe881d"}, + {file = "sphinx-7.0.1-py3-none-any.whl", hash = "sha256:60c5e04756c1709a98845ed27a2eed7a556af3993afb66e77fec48189f742616"}, +] + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.18.1,<0.21" +imagesize = ">=1.3" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.13" +requests = ">=2.25.0" +snowballstemmer = ">=2.0" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.5" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] +test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"] + +[[package]] +name = "sphinx-autodoc-typehints" +version = "1.23.3" +description = "Type hints (PEP 484) support for the Sphinx autodoc extension" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sphinx_autodoc_typehints-1.23.3-py3-none-any.whl", hash = "sha256:ec913d93e915b4dae6a8758cd95baecc70ed77fcdfe050601fc6b12afd0fc059"}, + {file = "sphinx_autodoc_typehints-1.23.3.tar.gz", hash = "sha256:8fb8dfc4b010505c850f4ef395fc80222ebfd8fd1b40149f8862f2396f623760"}, +] + +[package.dependencies] +sphinx = ">=7.0.1" + +[package.extras] +docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)"] +numpy = ["nptyping (>=2.5)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "sphobjinv (>=2.3.1)", "typing-extensions (>=4.6.3)"] +type-comment = ["typed-ast (>=1.5.4)"] + +[[package]] +name = "sphinx-automodapi" +version = "0.15.0" +description = "Sphinx extension for auto-generating API documentation for entire modules" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sphinx-automodapi-0.15.0.tar.gz", hash = "sha256:fd5871e054df7f3e299dde959afffa849f4d01c6eac274c366b06472afcb06aa"}, + {file = "sphinx_automodapi-0.15.0-py3-none-any.whl", hash = "sha256:06848f261fb127b25d35f27c2c4fddb041e76498733da064504f8077cbd27bec"}, +] + +[package.dependencies] +sphinx = ">=2" + +[package.extras] +test = ["codecov", "coverage", "cython", "pytest", "pytest-cov"] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +description = "Add a copy button to each of your code cells." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"}, + {file = "sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"}, +] + +[package.dependencies] +sphinx = ">=1.8" + +[package.extras] +code-style = ["pre-commit (==2.12.1)"] +rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] + +[[package]] +name = "sphinx-gallery" +version = "0.13.0" +description = "A `Sphinx `_ extension that builds an HTML gallery of examples from any set of Python scripts." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sphinx-gallery-0.13.0.tar.gz", hash = "sha256:4756f92e079128b08cbc7a57922cc904b3d442b1abfa73ec6471ad24f3c5b4b2"}, + {file = "sphinx_gallery-0.13.0-py3-none-any.whl", hash = "sha256:5bedfa4998b4158d5affc7d1df6796e4b1e834b16680001dac992af1304d8ed9"}, +] + +[package.dependencies] +sphinx = ">=4" + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.4" +description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, + {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-bibtex" +version = "2.5.0" +description = "Sphinx extension for BibTeX style citations." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "sphinxcontrib-bibtex-2.5.0.tar.gz", hash = "sha256:71b42e5db0e2e284f243875326bf9936aa9a763282277d75048826fef5b00eaa"}, + {file = "sphinxcontrib_bibtex-2.5.0-py3-none-any.whl", hash = "sha256:748f726eaca6efff7731012103417ef130ecdcc09501b4d0c54283bf5f059f76"}, +] + +[package.dependencies] +docutils = ">=0.8" +importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} +pybtex = ">=0.24" +pybtex-docutils = ">=1.0.0" +Sphinx = ">=2.1" + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.1" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, + {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] + +[package.extras] +test = ["flake8", "mypy", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sympy" +version = "1.12" +description = "Computer algebra system (CAS) in Python" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"}, + {file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"}, +] + +[package.dependencies] +mpmath = ">=0.19" + +[[package]] +name = "tensorboard" +version = "2.10.1" +description = "TensorBoard lets you watch Tensors Flow" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "tensorboard-2.10.1-py3-none-any.whl", hash = "sha256:fb9222c1750e2fa35ef170d998a1e229f626eeced3004494a8849c88c15d8c1c"}, +] + +[package.dependencies] +absl-py = ">=0.4" +google-auth = ">=1.6.3,<3" +google-auth-oauthlib = ">=0.4.1,<0.5" +grpcio = ">=1.24.3" +markdown = ">=2.6.8" +numpy = ">=1.12.0" +protobuf = ">=3.9.2,<3.20" +requests = ">=2.21.0,<3" +setuptools = ">=41.0.0" +tensorboard-data-server = ">=0.6.0,<0.7.0" +tensorboard-plugin-wit = ">=1.6.0" +werkzeug = ">=1.0.1" +wheel = ">=0.26" + +[[package]] +name = "tensorboard-data-server" +version = "0.6.1" +description = "Fast data loading for TensorBoard" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "tensorboard_data_server-0.6.1-py3-none-any.whl", hash = "sha256:809fe9887682d35c1f7d1f54f0f40f98bb1f771b14265b453ca051e2ce58fca7"}, + {file = "tensorboard_data_server-0.6.1-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:fa8cef9be4fcae2f2363c88176638baf2da19c5ec90addb49b1cde05c95c88ee"}, + {file = "tensorboard_data_server-0.6.1-py3-none-manylinux2010_x86_64.whl", hash = "sha256:d8237580755e58eff68d1f3abefb5b1e39ae5c8b127cc40920f9c4fb33f4b98a"}, +] + +[[package]] +name = "tensorboard-plugin-wit" +version = "1.8.1" +description = "What-If Tool TensorBoard plugin." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "tensorboard_plugin_wit-1.8.1-py3-none-any.whl", hash = "sha256:ff26bdd583d155aa951ee3b152b3d0cffae8005dc697f72b44a8e8c2a77a8cbe"}, +] + +[[package]] +name = "tensorboardx" +version = "2.6" +description = "TensorBoardX lets you watch Tensors Flow without Tensorflow" +category = "main" +optional = true +python-versions = "*" +files = [ + {file = "tensorboardX-2.6-py2.py3-none-any.whl", hash = "sha256:24a7cd076488de1e9d15ef25371b8ebf90c4f8f622af2477c611198f03f4a606"}, + {file = "tensorboardX-2.6.tar.gz", hash = "sha256:d4c036964dd2deb075a1909832b276daa383eab3f9db519ad90b99f5aea06b0c"}, +] + +[package.dependencies] +numpy = "*" +packaging = "*" +protobuf = ">=3.8.0,<4" + +[[package]] +name = "tensorflow" +version = "2.10.0" +description = "TensorFlow is an open source machine learning framework for everyone." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tensorflow-2.10.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:60d5b4fbbb7a1304d96352372fa032e861e98bb3f23aced7ce53bc475a2df97d"}, + {file = "tensorflow-2.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1e898bc1df521af9a8bfe0e511124379a6414083234ec67c6ab212ad12b2f"}, + {file = "tensorflow-2.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e129114dc529e63af9c419b5917b3407d0d26a4c8b73e114f601a175a7eb0477"}, + {file = "tensorflow-2.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:0a3b58d90fadb5bdf81a964bea73bb89019a9d1e9ac12de75375c8f65e0d7570"}, + {file = "tensorflow-2.10.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:0701da16a3d6d34763cd9ced6467cee24c02c9abf0d1a48ba59ea5a8d0421cec"}, + {file = "tensorflow-2.10.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64cc999ae83ddd891083141d3e5d718e3d799501a1b56c544f2ca648a8396c3e"}, + {file = "tensorflow-2.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9f711c5ff04333355c83eb96ca2e1db57c9663c6fa01d68b5953a040a602a3c"}, + {file = "tensorflow-2.10.0-cp37-cp37m-win_amd64.whl", hash = "sha256:9f4677e9ab7104e73710a94ff5d2ed4b335378dcd2ac7402a68c31802a680911"}, + {file = "tensorflow-2.10.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8773858cbf37aaad444b07605d29f5b2d8f7cd1ecbf1cce2777931b96884589c"}, + {file = "tensorflow-2.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5806d4645bce5eb415863d757b5f056364b9d1cfa2c34f711f69d46cac605eee"}, + {file = "tensorflow-2.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e85f89bc23c62d4243fad70bac902f00a234b33da8b91e2967eeef0f4b75b1e3"}, + {file = "tensorflow-2.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:d9b19b5120c0b393d9e2fc72561cfa3a454ef7f1ac649d8ad0dcc98817a086a4"}, + {file = "tensorflow-2.10.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:4b542af76d93c43e9d24dcb69888793831e434dc781c9533ee07f928fce84a15"}, + {file = "tensorflow-2.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588a1f34d9db51ea856aff07da9aa877c1d1d109336eee2c3bbb16dabd3f605"}, + {file = "tensorflow-2.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:487918f4074685e213ba247387faab34933df76939134008441cb9d3e2c95cab"}, + {file = "tensorflow-2.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:741a74278f471dc21991a6c7dc802d454d42fd39515900c6363b8c38a898fb0f"}, +] + +[package.dependencies] +absl-py = ">=1.0.0" +astunparse = ">=1.6.0" +flatbuffers = ">=2.0" +gast = ">=0.2.1,<=0.4.0" +google-pasta = ">=0.1.1" +grpcio = ">=1.24.3,<2.0" +h5py = ">=2.9.0" +keras = ">=2.10.0,<2.11" +keras-preprocessing = ">=1.1.1" +libclang = ">=13.0.0" +numpy = ">=1.20" +opt-einsum = ">=2.3.2" +packaging = "*" +protobuf = ">=3.9.2,<3.20" +setuptools = "*" +six = ">=1.12.0" +tensorboard = ">=2.10,<2.11" +tensorflow-estimator = ">=2.10.0,<2.11" +tensorflow-io-gcs-filesystem = ">=0.23.1" +termcolor = ">=1.1.0" +typing-extensions = ">=3.6.6" +wrapt = ">=1.11.0" + +[[package]] +name = "tensorflow-cpu-aws" +version = "2.10.0" +description = "TensorFlow is an open source machine learning framework for everyone." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tensorflow_cpu_aws-2.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b11a7004e078b17d1a472cd5a091a0efd14672294d98ab76b851ddc15faee92c"}, + {file = "tensorflow_cpu_aws-2.10.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c8e76c48e75d0b353239fcb039c3abbfa8ee6fe2660badb6b094c59e222714e"}, + {file = "tensorflow_cpu_aws-2.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fe56d8506dae3891af6b62f26f16597e8416f9c6b788fe5dd98b602136f6cf6"}, + {file = "tensorflow_cpu_aws-2.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:112fa013271dc3282f7c821b138126f2504892703d85d5686198eb348fa6f6d2"}, +] + +[package.dependencies] +absl-py = ">=1.0.0" +astunparse = ">=1.6.0" +flatbuffers = ">=2.0" +gast = ">=0.2.1,<=0.4.0" +google-pasta = ">=0.1.1" +grpcio = ">=1.24.3,<2.0" +h5py = ">=2.9.0" +keras = ">=2.10.0,<2.11" +keras-preprocessing = ">=1.1.1" +libclang = ">=13.0.0" +numpy = ">=1.20" +opt-einsum = ">=2.3.2" +packaging = "*" +protobuf = ">=3.9.2,<3.20" +setuptools = "*" +six = ">=1.12.0" +tensorboard = ">=2.10,<2.11" +tensorflow-estimator = ">=2.10.0,<2.11" +tensorflow-io-gcs-filesystem = ">=0.23.1" +termcolor = ">=1.1.0" +typing-extensions = ">=3.6.6" +wrapt = ">=1.11.0" + +[[package]] +name = "tensorflow-estimator" +version = "2.10.0" +description = "TensorFlow Estimator." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tensorflow_estimator-2.10.0-py2.py3-none-any.whl", hash = "sha256:f324ea17cd57f16e33bf188711d5077e6b2e5f5a12c328d6e01a07b23888edcd"}, +] + +[[package]] +name = "tensorflow-io-gcs-filesystem" +version = "0.32.0" +description = "TensorFlow IO" +category = "main" +optional = false +python-versions = ">=3.7, <3.12" +files = [ + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:74a7e25e83d4117a7ebb09a3f247553a5497393ab48c3ee0cf0d17b405026817"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:045d51bba586390d0545fcd8a18727d62b175eb142f6f4c6d719d39de40774cd"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db682e9a510c27dd35710ba5a2c62c371e25b727741b2fe3a920355fa501e947"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:7f15fd22e592661b10de317be2f42a0f84be7bfc5e6a565fcfcb04b60d625b78"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:336d9b3fe6b55aea149c4f6aa1fd6ffaf27d4e5c37e55a182340b47caba38846"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:842f5f09cd756bdb3b4d0b5571b3a6f72fd534d42da938b9acf0ef462995eada"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:1ce80e1555d6ee88dda67feddf366cc8b30252b5837a7a17303df7b06a71fc2e"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05e65d3cb6c93a7929b384d86c6369c63cbbab8a770440a3d95e094878403f9f"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:21de7dcc06eb1e7de3c022b0072d90ba35ef886578149663437aa7a6fb5bf6b3"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:79fdd02103b8ae9f8b89af41f744c013fa1caaea709de19833917795e3063857"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5635df0bbe40f971dc1b946e3372744b0bdfda45c38ffcd28ef53a32bb8da4da"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:122be149e5f6a030f5c2901be0cc3cb07619232f7b03889e2cdf3da1c0d4f92f"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8214cdf85bea694160f9035ff395221c1e25e119784ccb4c104919b1f5dec84e"}, + {file = "tensorflow_io_gcs_filesystem-0.32.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28202492d904a6e280cf27560791e87ac1c7566000db82065d63a70c27008af2"}, +] + +[package.extras] +tensorflow = ["tensorflow (>=2.12.0,<2.13.0)"] +tensorflow-aarch64 = ["tensorflow-aarch64 (>=2.12.0,<2.13.0)"] +tensorflow-cpu = ["tensorflow-cpu (>=2.12.0,<2.13.0)"] +tensorflow-gpu = ["tensorflow-gpu (>=2.12.0,<2.13.0)"] +tensorflow-rocm = ["tensorflow-rocm (>=2.12.0,<2.13.0)"] + +[[package]] +name = "tensorflow-probability" +version = "0.18.0" +description = "Probabilistic modeling and statistical inference in TensorFlow" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "tensorflow_probability-0.18.0-py2.py3-none-any.whl", hash = "sha256:80d57e7792c78586f12255ab4a7c359b7e86bc06d487fd629119d9e650624a18"}, +] + +[package.dependencies] +absl-py = "*" +cloudpickle = ">=1.3" +decorator = "*" +dm-tree = "*" +gast = ">=0.3.2" +numpy = ">=1.13.3" +six = ">=1.10.0" + +[package.extras] +jax = ["jax", "jaxlib"] +tfds = ["tensorflow-datasets (>=2.2.0)"] + +[[package]] +name = "termcolor" +version = "2.3.0" +description = "ANSI color formatting for output in terminal" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "termcolor-2.3.0-py3-none-any.whl", hash = "sha256:3afb05607b89aed0ffe25202399ee0867ad4d3cb4180d98aaf8eefa6a5f7d475"}, + {file = "termcolor-2.3.0.tar.gz", hash = "sha256:b5b08f68937f138fe92f6c089b99f1e2da0ae56c52b78bf7075fd95420fd9a5a"}, +] + +[package.extras] +tests = ["pytest", "pytest-cov"] + +[[package]] +name = "thewalrus" +version = "0.19.0" +description = "Open source library for hafnian calculation" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "thewalrus-0.19.0-py3-none-any.whl", hash = "sha256:07b6e2969bf5405a2df736c442b1500857438bbd2afc2053b8b600b8b0c67f97"}, + {file = "thewalrus-0.19.0.tar.gz", hash = "sha256:06ff07a14cd8cd4650d9c82b8bb8301ef9a58dcdd4bafb14841768ccf80c98b9"}, +] + +[package.dependencies] +dask = {version = "*", extras = ["delayed"]} +numba = ">=0.49.1" +numpy = ">=1.19.2" +scipy = ">=1.2.1" +sympy = ">=1.5.1" + +[[package]] +name = "threadpoolctl" +version = "3.1.0" +description = "threadpoolctl" +category = "main" +optional = true +python-versions = ">=3.6" +files = [ + {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, + {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, +] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "toolz" +version = "0.12.0" +description = "List processing tools and functional utilities" +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "toolz-0.12.0-py3-none-any.whl", hash = "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f"}, + {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, +] + +[[package]] +name = "tqdm" +version = "4.65.0" +description = "Fast, Extensible Progress Meter" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, + {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "typing-extensions" +version = "4.7.1" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" +optional = false +python-versions = ">=3.7" +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"}, +] + +[[package]] +name = "tzdata" +version = "2023.3" +description = "Provider of IANA time zone data" +category = "main" +optional = true +python-versions = ">=2" +files = [ + {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, + {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, +] + +[[package]] +name = "urllib3" +version = "2.0.3" +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.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"}, + {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "werkzeug" +version = "2.3.6" +description = "The comprehensive WSGI web application library." +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "Werkzeug-2.3.6-py3-none-any.whl", hash = "sha256:935539fa1413afbb9195b24880778422ed620c0fc09670945185cce4d91a8890"}, + {file = "Werkzeug-2.3.6.tar.gz", hash = "sha256:98c774df2f91b05550078891dee5f0eb0cb797a522c757a2452b9cee5b202330"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[[package]] +name = "wheel" +version = "0.40.0" +description = "A built-package format for Python" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "wheel-0.40.0-py3-none-any.whl", hash = "sha256:d236b20e7cb522daf2390fa84c55eea81c5c30190f90f29ae2ca1ad8355bf247"}, + {file = "wheel-0.40.0.tar.gz", hash = "sha256:cd1196f3faee2b31968d626e1731c94f99cbdb67cf5a46e4f5656cbee7738873"}, +] + +[package.extras] +test = ["pytest (>=6.0.0)"] + +[[package]] +name = "wrapt" +version = "1.12.1" +description = "Module for decorators, wrappers and monkey patching." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"}, +] + +[[package]] +name = "xanadu-sphinx-theme" +version = "0.1.0" +description = "Sphinx theme for Xanadu open-source Python packages" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "xanadu-sphinx-theme-0.1.0.tar.gz", hash = "sha256:ce3c825cebf4b52a025330a907e95ab1a452e71f91c904fab7e38eccbe0d3eda"}, + {file = "xanadu_sphinx_theme-0.1.0-py3-none-any.whl", hash = "sha256:fedba15959e5abcdbf8f4ea34370ebf3bef32498eede9a7e7f14cc4ce0560b5b"}, +] + +[package.dependencies] +pillow = "*" +sphinx = "*" +sphinx-gallery = "*" + +[[package]] +name = "zipp" +version = "3.16.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.16.0-py3-none-any.whl", hash = "sha256:5dadc3ad0a1f825fe42ce1bce0f2fc5a13af2e6b2d386af5b0ff295bc0a287d3"}, + {file = "zipp-3.16.0.tar.gz", hash = "sha256:1876cb065531855bbe83b6c489dcf69ecc28f1068d8e95959fe8bbc77774c941"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "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-mypy (>=0.9.1)", "pytest-ruff"] + +[extras] +ray = ["ray", "scikit-optimize"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.9,<3.11" +content-hash = "4bc682389a785eeb023c5eae11a3800b7e79cc3405421797fcf1bc5d6b19ef89" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..1262f969a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,71 @@ +[tool.poetry] +name = "mrmustard" +version = "0.5.0" +description = "Differentiable quantum Gaussian circuits" +authors = ["Xanadu "] +license = "Apache License 2.0" +readme = "README.md" +include = ["pyproject.toml"] +classifiers = [ + "Development Status :: 4 - Beta", + "Environment :: Console", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Natural Language :: English", + "Operating System :: POSIX", + "Operating System :: MacOS :: MacOS X", + "Operating System :: POSIX :: Linux", + "Operating System :: Microsoft :: Windows", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Scientific/Engineering :: Physics", +] + +[tool.poetry.dependencies] +python = ">=3.9,<3.11" +numpy = "1.23.5" +scipy = "1.8.0" +numba = "0.56.4" +thewalrus = "0.19.0" +tensorflow = "<=2.10.1" +tensorflow-cpu-aws = { version = "2.10.0", markers = "platform_machine == 'aarch64' or platform_machine == 'arm64'" } +tensorflow-probability = "0.18.0" +rich = "10.15.1" +matplotlib = "3.5.0" +tqdm = "^4.65.0" +ray = { version = "2.5.0", extras = ["tune"], optional = true } +scikit-optimize = { version = "^0.9.0", optional = true } + +[tool.poetry.extras] +ray = ["ray", "scikit-optimize"] + +[tool.poetry.group.dev] +optional = true + +[tool.poetry.group.dev.dependencies] +pytest = "6.2.5" +pytest-cov ="3.0.0" +hypothesis = "6.31.6" +pylint = "2.10.0" +black = ">=22.1.0" + +[tool.poetry.group.doc] +optional = true + +[tool.poetry.group.doc.dependencies] +sphinx = "^7.0.1" +docutils = "^0.20.1" +m2r2 = "^0.3.3.post2" +sphinx-autodoc-typehints = "^1.23.3" +sphinx-copybutton = "^0.5.2" +sphinx-automodapi = "^0.15.0" +sphinxcontrib-bibtex = "^2.5.0" +mistune = "0.8.4" +xanadu-sphinx-theme = "0.1.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index 5ec2222b6..000000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,5 +0,0 @@ -pytest==6.2.5 -pytest-cov==3.0.0 -hypothesis==6.31.6 -pylint==2.10.0 -black>=22.1.0 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 46cd82df7..000000000 --- a/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -numpy==1.23.5 -scipy==1.8.0 -numba==0.56.4 -thewalrus==0.19.0 -tensorflow==2.10.1; sys_platform != "darwin" -tensorflow_macos==2.10.0; sys_platform == "darwin" -tensorflow-probability==0.18.0 -rich==10.15.1 -matplotlib==3.5.0 diff --git a/setup.py b/setup.py deleted file mode 100644 index 77ae75209..000000000 --- a/setup.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2021 Xanadu Quantum Technologies Inc. - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import platform - -from setuptools import find_packages, setup - -with open("mrmustard/_version.py") as f: - version = f.readlines()[-1].split()[-1].strip("\"'") - -requirements = [ - "numpy", - "scipy", - "numba", - "thewalrus>=0.17.0", - "tensorflow<=2.10.1" if platform.system() != "Darwin" else "tensorflow_macos<=2.10.0", - "tensorflow-probability<=0.18.0", - "rich", - "tqdm", - "matplotlib", -] - -extra_requirements = { - "ray": ["ray[tune]", "scikit-optimize"], -} - -info = { - "name": "mrmustard", - "version": version, - "description": "Differentiable quantum Gaussian circuits", - "url": "https://github.com/XanaduAI/mrmustard", - "author": "Xanadu", - "author_email": "filippo@xanadu.ai", - "license": "Apache License 2.0", - "packages": find_packages(where="."), - "install_requires": requirements, - "extras_require": extra_requirements, - "long_description": open("README.md", encoding="utf-8").read(), - "long_description_content_type": "text/markdown", -} - -classifiers = [ - "Development Status :: 4 - Beta", - "Environment :: Console", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: Apache Software License", - "Natural Language :: English", - "Operating System :: POSIX", - "Operating System :: MacOS :: MacOS X", - "Operating System :: POSIX :: Linux", - "Operating System :: Microsoft :: Windows", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Scientific/Engineering :: Physics", -] - -setup(classifiers=classifiers, **(info)) diff --git a/tests/test_lab/test_circuit.py b/tests/test_lab/test_circuit.py index b8e9954db..c88068e38 100644 --- a/tests/test_lab/test_circuit.py +++ b/tests/test_lab/test_circuit.py @@ -12,14 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import numpy as np -import pytest -from hypothesis import given, strategies as st, assume -from hypothesis.extra.numpy import arrays -from mrmustard.physics import gaussian + +from hypothesis import given + from mrmustard.lab import * -from mrmustard import settings -from tests import random +from tests.random import angle, medium_float, n_mode_pure_state, r def test_circuit_placement_SD(): @@ -53,3 +50,12 @@ def test_is_unitary(): assert Ggate(1).is_unitary assert (Ggate(1) >> Ggate(1)).is_unitary assert not (Ggate(2) >> Attenuator([0.1, 0.2])).is_unitary + + +@given( + r=r, phi1=angle, phi2=angle, x=medium_float, y=medium_float, G=n_mode_pure_state(num_modes=1) +) +def test_shift(r, phi1, phi2, x, y, G): + "test that the leftshift/rightshift operator works as expected" + circ = Sgate(r, phi1) >> Dgate(x, y) >> Rgate(phi2) + assert G == (circ << G) >> circ diff --git a/tests/test_lab/test_gates_fock.py b/tests/test_lab/test_gates_fock.py index 663732bdf..d9799ed73 100644 --- a/tests/test_lab/test_gates_fock.py +++ b/tests/test_lab/test_gates_fock.py @@ -17,6 +17,7 @@ from hypothesis import given from thewalrus.fock_gradients import ( beamsplitter, + displacement, mzgate, squeezing, two_mode_squeezing, @@ -35,6 +36,8 @@ Sgate, ) from mrmustard.lab.states import TMSV, Fock, SqueezedVacuum, State +from mrmustard.math import Math +from mrmustard.math.lattice import strategies from mrmustard.physics import fock from tests.random import ( angle, @@ -47,6 +50,8 @@ two_mode_unitary_gate, ) +math = Math() + @given(state=n_mode_pure_state(num_modes=1), x=medium_float, y=medium_float) def test_Dgate_1mode(state, x, y): @@ -97,7 +102,7 @@ def test_single_mode_fock_equals_gaussian_ket(gate): def test_single_mode_fock_equals_gaussian_ket_dm(gate): """Test same state is obtained via fock representation or phase space for single mode circuits.""" - cutoffs = [70] + cutoffs = (70,) gaussian_state = SqueezedVacuum(-0.1) fock_state = State(ket=gaussian_state.ket(cutoffs)) @@ -110,7 +115,7 @@ def test_single_mode_fock_equals_gaussian_ket_dm(gate): def test_two_mode_fock_equals_gaussian(gate): """Test same state is obtained via fock representation or phase space for two modes circuits.""" - cutoffs = [20, 20] + cutoffs = (20, 20) gaussian_state = TMSV(0.1) >> BSgate(np.pi / 2) >> Attenuator(0.5) fock_state = State(dm=gaussian_state.dm(cutoffs)) @@ -122,12 +127,12 @@ def test_two_mode_fock_equals_gaussian(gate): @pytest.mark.parametrize( "cutoffs,x,y", [ - [[5], 0.3, 0.5], - [[5], 0.0, 0.0], - [[2, 2], [0.1, 0.1], [0.25, -0.2]], - [[3, 3], [0.0, 0.0], [0.0, 0.0]], - [[2, 5, 1], [0.1, 5.0, 1.0], [-0.3, 0.1, 0.0]], - [[3, 3, 3, 3], [0.1, 0.2, 0.3, 0.4], [-0.5, -4, 3.1, 4.2]], + [[5, 5], 0.3, 0.5], + [[5, 5], 0.0, 0.0], + [[2, 2, 2, 2], [0.1, 0.1], [0.25, -0.2]], + [[3, 3, 3, 3], [0.0, 0.0], [0.0, 0.0]], + [[2, 5, 1, 2, 5, 1], [0.1, 5.0, 1.0], [-0.3, 0.1, 0.0]], + [[3, 3, 3, 3, 3, 3, 3, 3], [0.1, 0.2, 0.3, 0.4], [-0.5, -4, 3.1, 4.2]], ], ) def test_fock_representation_displacement(cutoffs, x, y): @@ -139,8 +144,80 @@ def test_fock_representation_displacement(cutoffs, x, y): # compare with the standard way of calculating # transformation unitaries using the Choi isomorphism - X = np.eye(2 * len(cutoffs)) - expected_Ud = fock.wigner_to_fock_U(X, dgate.XYd[-1], cutoffs * 2) + X, _, d = dgate.XYd(allow_none=False) + expected_Ud = fock.wigner_to_fock_U(X, d, cutoffs) + + assert np.allclose(Ud, expected_Ud, atol=1e-5) + + +@given(x1=medium_float, x2=medium_float, y1=medium_float, y2=medium_float) +def test_parallel_displacement(x1, x2, y1, y2): + """Tests that parallel Dgate returns the correct unitary.""" + U12 = Dgate([x1, x2], [y1, y2]).U([2, 7, 2, 7]) + U1 = Dgate(x1, y1).U([2, 2]) + U2 = Dgate(x2, y2).U([7, 7]) + assert np.allclose(U12, np.transpose(np.tensordot(U1, U2, [[], []]), [0, 2, 1, 3])) + + +def test_squeezer_grad_against_finite_differences(): + """tests fock squeezer gradient against finite differences""" + cutoffs = (5, 5) + r = math.new_variable(0.5, None, "r") + phi = math.new_variable(0.1, None, "phi") + delta = 1e-6 + dUdr = (Sgate(r + delta, phi).U(cutoffs) - Sgate(r - delta, phi).U(cutoffs)) / (2 * delta) + dUdphi = (Sgate(r, phi + delta).U(cutoffs) - Sgate(r, phi - delta).U(cutoffs)) / (2 * delta) + _, (gradr, gradphi) = math.value_and_gradients( + lambda: fock.squeezer(r, phi, shape=cutoffs), [r, phi] + ) + assert np.allclose(gradr, 2 * np.real(np.sum(dUdr))) + assert np.allclose(gradphi, 2 * np.real(np.sum(dUdphi))) + + +def test_displacement_grad(): + """tests fock displacement gradient against finite differences""" + cutoffs = [5, 5] + x = math.new_variable(0.1, None, "x") + y = math.new_variable(0.1, None, "y") + alpha = math.make_complex(x, y).numpy() + delta = 1e-6 + dUdx = (fock.displacement(x + delta, y, cutoffs) - fock.displacement(x - delta, y, cutoffs)) / ( + 2 * delta + ) + dUdy = (fock.displacement(x, y + delta, cutoffs) - fock.displacement(x, y - delta, cutoffs)) / ( + 2 * delta + ) + + D = fock.displacement(x, y, shape=cutoffs) + dD_da, dD_dac = strategies.jacobian_displacement(math.asnumpy(D), alpha) + assert np.allclose(dD_da + dD_dac, dUdx) + assert np.allclose(1j * (dD_da - dD_dac), dUdy) + + +def test_fock_representation_displacement_rectangular(): + """Tests that DGate returns the correct unitary.""" + x, y = 0.3, 0.5 + cutoffs = 5, 10 + # apply gate + dgate = Dgate(x, y) + Ud = dgate.U(cutoffs) + + # compare with tw implementation + expected_Ud = displacement(np.sqrt(x * x + y * y), np.arctan2(y, x), 10)[:5, :10] + + assert np.allclose(Ud, expected_Ud, atol=1e-5) + + +def test_fock_representation_displacement_rectangular2(): + """Tests that DGate returns the correct unitary.""" + x, y = 0.3, 0.5 + cutoffs = 10, 5 + # apply gate + dgate = Dgate(x, y) + Ud = dgate.U(cutoffs) + + # compare with tw implementation + expected_Ud = displacement(np.sqrt(x * x + y * y), np.arctan2(y, x), 10)[:10, :5] assert np.allclose(Ud, expected_Ud, atol=1e-5) @@ -149,28 +226,37 @@ def test_fock_representation_displacement(cutoffs, x, y): def test_fock_representation_squeezing(r, phi): S = Sgate(r=r, phi=phi) expected = squeezing(r=r, theta=phi, cutoff=20) - assert np.allclose(expected, S.U(cutoffs=[20]), atol=1e-5) + assert np.allclose(expected, S.U(cutoffs=[20, 20]), atol=1e-5) + + +@given(r1=r, phi1=angle, r2=r, phi2=angle) +def test_parallel_squeezing(r1, phi1, r2, phi2): + """Tests that two parallel squeezers return the correct unitary.""" + U12 = Sgate([r1, r2], [phi1, phi2]).U([5, 7, 5, 7]) + U1 = Sgate(r1, phi1).U([5, 5]) + U2 = Sgate(r2, phi2).U([7, 7]) + assert np.allclose(U12, np.transpose(np.tensordot(U1, U2, [[], []]), [0, 2, 1, 3])) @given(theta=angle, phi=angle) def test_fock_representation_beamsplitter(theta, phi): BS = BSgate(theta=theta, phi=phi) - expected = beamsplitter(theta=theta, phi=phi, cutoff=20) - assert np.allclose(expected, BS.U(cutoffs=[20, 20]), atol=1e-5) + expected = beamsplitter(theta=theta, phi=phi, cutoff=10) + assert np.allclose(expected, BS.U(cutoffs=[10, 10, 10, 10]), atol=1e-5) @given(r=r, phi=angle) def test_fock_representation_two_mode_squeezing(r, phi): S2 = S2gate(r=r, phi=phi) - expected = two_mode_squeezing(r=r, theta=phi, cutoff=20) - assert np.allclose(expected, S2.U(cutoffs=[20, 20]), atol=1e-5) + expected = two_mode_squeezing(r=r, theta=phi, cutoff=10) + assert np.allclose(expected, S2.U(cutoffs=[10, 10, 10, 10]), atol=1e-5) @given(phi_a=angle, phi_b=angle) def test_fock_representation_mzgate(phi_a, phi_b): MZ = MZgate(phi_a=phi_a, phi_b=phi_b, internal=False) - expected = mzgate(theta=phi_b, phi=phi_a, cutoff=20) - assert np.allclose(expected, MZ.U(cutoffs=[20, 20]), atol=1e-5) + expected = mzgate(theta=phi_b, phi=phi_a, cutoff=10) + assert np.allclose(expected, MZ.U(cutoffs=[10, 10, 10, 10]), atol=1e-5) @pytest.mark.parametrize( @@ -190,8 +276,8 @@ def test_fock_representation_rgate(cutoffs, angles, modes): # compare with the standard way of calculating # transformation unitaries using the Choi isomorphism - d = np.zeros(2 * len(cutoffs)) - expected_R = fock.wigner_to_fock_U(rgate.XYd[0], d, cutoffs * 2) + d = np.zeros(len(cutoffs) * 2) + expected_R = fock.wigner_to_fock_U(rgate.X_matrix, d, tuple(cutoffs + cutoffs)) assert np.allclose(R, expected_R, atol=1e-5) @@ -213,3 +299,30 @@ def test_raise_interferometer_error(): def test_choi_cutoffs(): output = State(dm=Coherent([1.0, 1.0]).dm([5, 8])) >> Attenuator(0.5, modes=[1]) assert output.cutoffs == [5, 8] # cutoffs are respected by the gate + + +def test_measure_with_fock(): + "tests that the autocutoff respects the fock projection cutoff" + cov = np.array( + [ + [1.08341848, 0.26536937, 0.0, 0.0], + [0.26536937, 1.05564949, 0.0, 0.0], + [0.0, 0.0, 0.98356475, -0.24724869], + [0.0, 0.0, -0.24724869, 1.00943755], + ] + ) + + state = State(means=np.zeros(4), cov=cov) + + n_detect = 2 + state_out = state << Fock([n_detect], modes=[1]) + assert np.allclose(state_out.ket(), np.array([0.00757899, 0.0])) + + +@given(theta=angle, phi=angle) +def test_schwinger_bs_equals_vanilla_bs_for_small_cutoffs(theta, phi): + """Tests that the Schwinger boson BS gate is equivalent to the vanilla BS gate for low cutoffs.""" + U_vanilla = BSgate(theta, phi).U([10, 10, 10, 10], method="vanilla") + U_schwinger = BSgate(theta, phi).U([10, 10, 10, 10], method="schwinger") + + assert np.allclose(U_vanilla, U_schwinger, atol=1e-6) diff --git a/tests/test_lab/test_state.py b/tests/test_lab/test_state.py new file mode 100644 index 000000000..47aeb6356 --- /dev/null +++ b/tests/test_lab/test_state.py @@ -0,0 +1,49 @@ +import numpy as np + +from mrmustard.lab import Attenuator, Gaussian + + +def test_addition(): + """Test that addition of Gaussians is correct""" + G0 = Gaussian(1, cutoffs=[10]) + G1 = Gaussian(1, cutoffs=[10]) + + mixed = G0 + G1 + + assert np.allclose(mixed.dm([10]), G0.dm([10]) + G1.dm([10])) + + +def test_multiplication_ket(): + """Test that multiplication of Gaussians is correct""" + G = Gaussian(1, cutoffs=[10]) + + scaled = 42.0 * G + + assert np.allclose(scaled.ket(G.shape), 42.0 * G.ket()) + + +def test_multiplication_dm(): + """Test that multiplication of Gaussians is correct""" + G = Gaussian(1) >> Attenuator(0.9) + + scaled = 42.0 * G + + assert np.allclose(scaled.dm(), 42.0 * G.dm()) + + +def test_division_ket(): + """Test that division of Gaussians is correct""" + G = Gaussian(1, cutoffs=[10]) + + scaled = G / 42.0 + + assert np.allclose(scaled.ket([10]), G.ket([10]) / 42.0) + + +def test_division_dm(): + """Test that division of Gaussians is correct""" + G = Gaussian(1) >> Attenuator(0.9) + + scaled = G / 42.0 + + assert np.allclose(scaled.dm(G.cutoffs), G.dm() / 42.0) diff --git a/tests/test_math/test_compactFock.py b/tests/test_math/test_compactFock.py index 2d9b0d828..26a11ce0c 100644 --- a/tests/test_math/test_compactFock.py +++ b/tests/test_math/test_compactFock.py @@ -15,6 +15,15 @@ math = Math() # use methods in math if you want them to be differentiable +def allowed_cutoffs(max_cutoffs): + r"""Generate all cutoffs from (1,)*M to max_cutoffs""" + res = [] + for idx in np.ndindex(max_cutoffs): + cutoffs = np.array(idx) + 1 + res.append(tuple(cutoffs)) + return res + + @st.composite def random_ABC(draw, M): r""" @@ -29,48 +38,50 @@ def random_ABC(draw, M): @given(random_ABC(M=3)) def test_compactFock_diagonal(A_B_G0): """Test getting Fock amplitudes if all modes are detected (math.hermite_renormalized_diagonal)""" - cutoffs = [7, 4, 8] - A, B, G0 = A_B_G0 # Create random state (M mode Gaussian state with displacement) - - # Vanilla MM - G_ref = math.hermite_renormalized( - math.conj(-A), math.conj(B), math.conj(G0), shape=list(cutoffs) * 2 - ).numpy() # note: shape=[C1,C2,C3,...,C1,C2,C3,...] - - # Extract diagonal amplitudes from vanilla MM - ref_diag = np.zeros(cutoffs, dtype=np.complex128) - for inds in np.ndindex(*cutoffs): - inds_expanded = list(inds) + list(inds) # a,b,c,a,b,c - ref_diag[inds] = G_ref[tuple(inds_expanded)] - - # New MM - G_diag = math.hermite_renormalized_diagonal(math.conj(-A), math.conj(B), math.conj(G0), cutoffs) - assert np.allclose(ref_diag, G_diag) + for cutoffs in allowed_cutoffs((7, 7, 7)): + A, B, G0 = A_B_G0 # Create random state (M mode Gaussian state with displacement) + + # Vanilla MM + G_ref = math.hermite_renormalized( + math.conj(-A), math.conj(B), math.conj(G0), shape=list(cutoffs) * 2 + ).numpy() # note: shape=[C1,C2,C3,...,C1,C2,C3,...] + + # Extract diagonal amplitudes from vanilla MM + ref_diag = np.zeros(cutoffs, dtype=np.complex128) + for inds in np.ndindex(*cutoffs): + inds_expanded = list(inds) + list(inds) # a,b,c,a,b,c + ref_diag[inds] = G_ref[tuple(inds_expanded)] + + # New MM + G_diag = math.hermite_renormalized_diagonal( + math.conj(-A), math.conj(B), math.conj(G0), cutoffs + ) + assert np.allclose(ref_diag, G_diag) @given(random_ABC(M=3)) def test_compactFock_1leftover(A_B_G0): """Test getting Fock amplitudes if all but the first mode are detected (math.hermite_renormalized_1leftoverMode)""" - cutoffs = [7, 4, 8] - A, B, G0 = A_B_G0 # Create random state (M mode Gaussian state with displacement) - - # New algorithm - G_leftover = math.hermite_renormalized_1leftoverMode( - math.conj(-A), math.conj(B), math.conj(G0), cutoffs - ) - - # Vanilla MM - G_ref = math.hermite_renormalized( - math.conj(-A), math.conj(B), math.conj(G0), shape=list(cutoffs) * 2 - ).numpy() # note: shape=[C1,C2,C3,...,C1,C2,C3,...] - - # Extract amplitudes of leftover mode from vanilla MM - ref_leftover = np.zeros([cutoffs[0]] * 2 + list(cutoffs)[1:], dtype=np.complex128) - for inds in np.ndindex(*cutoffs[1:]): - ref_leftover[tuple([slice(cutoffs[0]), slice(cutoffs[0])] + list(inds))] = G_ref[ - tuple([slice(cutoffs[0])] + list(inds) + [slice(cutoffs[0])] + list(inds)) - ] - assert np.allclose(ref_leftover, G_leftover) + for cutoffs in allowed_cutoffs((7, 7, 7)): + A, B, G0 = A_B_G0 # Create random state (M mode Gaussian state with displacement) + + # New algorithm + G_leftover = math.hermite_renormalized_1leftoverMode( + math.conj(-A), math.conj(B), math.conj(G0), cutoffs + ) + + # Vanilla MM + G_ref = math.hermite_renormalized( + math.conj(-A), math.conj(B), math.conj(G0), shape=list(cutoffs) * 2 + ).numpy() # note: shape=[C1,C2,C3,...,C1,C2,C3,...] + + # Extract amplitudes of leftover mode from vanilla MM + ref_leftover = np.zeros([cutoffs[0]] * 2 + list(cutoffs)[1:], dtype=np.complex128) + for inds in np.ndindex(*cutoffs[1:]): + ref_leftover[tuple([slice(cutoffs[0]), slice(cutoffs[0])] + list(inds))] = G_ref[ + tuple([slice(cutoffs[0])] + list(inds) + [slice(cutoffs[0])] + list(inds)) + ] + assert np.allclose(ref_leftover, G_leftover) def test_compactFock_diagonal_gradients(): diff --git a/tests/test_math/test_interface.py b/tests/test_math/test_interface.py index ad463f616..c3fbd63e4 100644 --- a/tests/test_math/test_interface.py +++ b/tests/test_math/test_interface.py @@ -16,9 +16,11 @@ Unit tests for the :class:`Math`. """ +import numpy as np import pytest -from mrmustard.math import Math + from mrmustard import settings +from mrmustard.math import Math try: import torch @@ -50,7 +52,14 @@ def test_error_for_wrong_backend(): backend = settings.BACKEND with pytest.raises(ValueError) as exception_info: settings.BACKEND = "unexisting_backend" - assert exception_info.value.args[0] == f"Backend must be either 'tensorflow' or 'torch'" + assert exception_info.value.args[0] == "Backend must be either 'tensorflow' or 'torch'" # set back to initial value to avoid side effects settings.BACKEND = backend + + +def test_hash_tensor(): + """Test hash of a tensor""" + math = Math() + tensor = math.astensor([1, 2, 3]) + assert np.allclose(*[math.hash_tensor(tensor) for _ in range(3)]) diff --git a/tests/test_math/test_lattice.py b/tests/test_math/test_lattice.py new file mode 100644 index 000000000..f7cb43a1f --- /dev/null +++ b/tests/test_math/test_lattice.py @@ -0,0 +1,29 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests for the lattice module""" + +import numpy as np + +from mrmustard.lab import Gaussian + + +def test_vanilla_vs_binomial(): + """Test that the vanilla and binomial methods give the same result""" + G = Gaussian(2) + + ket_vanilla = G.ket(cutoffs=[10, 10])[:5, :5] + ket_binomial = G.ket(max_photons=10)[:5, :5] + + assert np.allclose(ket_vanilla, ket_binomial) diff --git a/tests/test_math/test_special.py b/tests/test_math/test_special.py index 6f08d450a..04916d3b8 100644 --- a/tests/test_math/test_special.py +++ b/tests/test_math/test_special.py @@ -16,6 +16,7 @@ import numpy as np from scipy.special import eval_hermite, factorial + from mrmustard.math import Math math = Math() @@ -26,9 +27,12 @@ def test_reduction_to_renorm_physicists_polys(): x = np.arange(-1, 1, 0.1) init = 1 n_max = 5 - A = np.ones([init, init], dtype=complex) + A = -np.ones([init, init], dtype=complex) vals = np.array( - [math.hermite_renormalized(2 * A, 2 * np.array([x0], dtype=complex), 1, n_max) for x0 in x] + [ + math.hermite_renormalized(2 * A, 2 * np.array([x0], dtype=complex), 1, (n_max,)) + for x0 in x + ] ).T expected = np.array([eval_hermite(i, x) / np.sqrt(factorial(i)) for i in range(len(vals))]) assert np.allclose(vals, expected) diff --git a/tests/test_physics/test_bargmann.py b/tests/test_physics/test_bargmann.py new file mode 100644 index 000000000..229536b96 --- /dev/null +++ b/tests/test_physics/test_bargmann.py @@ -0,0 +1,53 @@ +import numpy as np + +from mrmustard.lab import Attenuator, Dgate, Gaussian, Ggate +from mrmustard.physics.bargmann import ( + wigner_to_bargmann_Choi, + wigner_to_bargmann_psi, + wigner_to_bargmann_rho, + wigner_to_bargmann_U, +) + + +def test_wigner_to_bargmann_psi(): + """Test that the Bargmann representation of a ket is correct""" + G = Gaussian(2) >> Dgate(0.1, 0.2) + + for x, y in zip(G.bargmann(), wigner_to_bargmann_psi(G.cov, G.means)): + assert np.allclose(x, y) + + +def test_wigner_to_bargmann_rho(): + """Test that the Bargmann representation of a dm is correct""" + G = Gaussian(2) >> Dgate(0.1, 0.2) >> Attenuator(0.9) + + for x, y in zip(G.bargmann(), wigner_to_bargmann_rho(G.cov, G.means)): + assert np.allclose(x, y) + + +def test_wigner_to_bargmann_U(): + """Test that the Bargmann representation of a unitary is correct""" + G = Ggate(2) >> Dgate(0.1, 0.2) + X, _, d = G.XYd(allow_none=False) + for x, y in zip(G.bargmann(), wigner_to_bargmann_U(X, d)): + assert np.allclose(x, y) + + +def test_wigner_to_bargmann_choi(): + """Test that the Bargmann representation of a Choi matrix is correct""" + G = Ggate(2) >> Dgate(0.1, 0.2) >> Attenuator(0.9) + X, Y, d = G.XYd(allow_none=False) + for x, y in zip(G.bargmann(), wigner_to_bargmann_Choi(X, Y, d)): + assert np.allclose(x, y) + + +def test_bargmann_numpy_state(): + """Tests that the numpy option of the bargmann method of State works correctly""" + state = Gaussian(1) + assert all(isinstance(thing, np.ndarray) for thing in state.bargmann(numpy=True)) + + +def test_bargmann_numpy_transformation(): + """Tests that the numpy option of the bargmann method of State works correctly""" + transformation = Ggate(1) + assert all(isinstance(thing, np.ndarray) for thing in transformation.bargmann(numpy=True)) diff --git a/tests/test_physics/test_fock/test_fock.py b/tests/test_physics/test_fock/test_fock.py index 70e465653..8c673aee8 100644 --- a/tests/test_physics/test_fock/test_fock.py +++ b/tests/test_physics/test_fock/test_fock.py @@ -12,42 +12,30 @@ # See the License for the specific language governing permissions and # limitations under the License. -from hypothesis import settings, given, strategies as st -import pytest - import numpy as np +import pytest +from hypothesis import given +from hypothesis import strategies as st from scipy.special import factorial from thewalrus.quantum import total_photon_number_distribution + from mrmustard.lab import ( + TMSV, + Attenuator, + BSgate, Circuit, - Vacuum, + Coherent, + Fock, + Gaussian, + Ggate, S2gate, - BSgate, Sgate, - Rgate, - Dgate, - Ggate, - Interferometer, SqueezedVacuum, - TMSV, State, - Attenuator, - Fock, - Coherent, - Gaussian, -) -from mrmustard.physics.fock import ( - dm_to_ket, - ket_to_dm, - trace, - apply_choi_to_dm, - apply_choi_to_ket, - apply_kraus_to_dm, - apply_kraus_to_ket, - _grad_displacement, - _displacement, + Vacuum, ) - +from mrmustard.math.lattice.strategies import displacement, grad_displacement +from mrmustard.physics import fock # helper strategies st_angle = st.floats(min_value=0, max_value=2 * np.pi) @@ -176,30 +164,30 @@ def test_density_matrix(num_modes): [ Vacuum(num_modes=2), Fock([4, 3], modes=[0, 1]), - Coherent(x=[0.1, 0.2], y=[-0.4, 0.4], cutoffs=[25]), - Gaussian(num_modes=2, cutoffs=[35]), + Coherent(x=[0.1, 0.2], y=[-0.4, 0.4], cutoffs=[10, 10]), + Gaussian(num_modes=2, cutoffs=[35, 35]), ], ) def test_dm_to_ket(state): """Tests pure state density matrix conversion to ket""" dm = state.dm() - ket = dm_to_ket(dm) + ket = fock.dm_to_ket(dm) # check if ket is normalized - assert np.allclose(np.linalg.norm(ket), 1) + assert np.allclose(np.linalg.norm(ket), 1, atol=1e-4) # check kets are equivalent - assert np.allclose(ket, state.ket()) + assert np.allclose(ket, state.ket(), atol=1e-4) - dm_reconstructed = ket_to_dm(ket) + dm_reconstructed = fock.ket_to_dm(ket) # check ket leads to same dm assert np.allclose(dm, dm_reconstructed, atol=1e-15) def test_dm_to_ket_error(): - """Test dm_to_ket raises an error when state is mixed""" + """Test fock.dm_to_ket raises an error when state is mixed""" state = Coherent(x=0.1, y=-0.4, cutoffs=[15]) >> Attenuator(0.5) with pytest.raises(ValueError): - dm_to_ket(state) + fock.dm_to_ket(state) def test_fock_trace_mode1_dm(): @@ -238,30 +226,29 @@ def test_fock_trace_function(): """tests that the Fock state is correctly traced""" state = Vacuum(2) >> Ggate(2) >> Attenuator([0.1, 0.1]) dm = state.dm([3, 20]) - dm_traced = trace(dm, keep=[0]) + dm_traced = fock.trace(dm, keep=[0]) assert np.allclose(dm_traced, State(dm=dm).get_modes(0).dm(), atol=1e-5) def test_dm_choi(): """tests that choi op is correctly applied to a dm""" circ = Ggate(1) >> Attenuator([0.1]) - dm_out = apply_choi_to_dm(circ.choi([10]), Vacuum(1).dm([10]), [0], [0]) + dm_out = fock.apply_choi_to_dm(circ.choi([10, 10, 10, 10]), Vacuum(1).dm([10]), [0], [0]) dm_expected = (Vacuum(1) >> circ).dm([10]) assert np.allclose(dm_out, dm_expected, atol=1e-5) def test_single_mode_choi_application_order(): """Test dual operations output the correct mode ordering""" - s = Attenuator(1.0) << State(dm=SqueezedVacuum(1.0, np.pi / 2).dm([40])) - assert np.allclose(s.dm([10])[:10, :10], SqueezedVacuum(1.0, np.pi / 2).dm([10])) - # NOTE: the [:10,:10] part is not necessary once PR #184 is merged + s = Attenuator(1.0) << State(dm=SqueezedVacuum(1.0, np.pi / 2).dm([40])) # apply identity gate + assert np.allclose(s.dm([10]), SqueezedVacuum(1.0, np.pi / 2).dm([10])) def test_apply_kraus_to_ket_1mode(): """Test that Kraus operators are applied to a ket on the correct indices""" ket = np.random.normal(size=(2, 3, 4)) kraus = np.random.normal(size=(5, 3)) - ket_out = apply_kraus_to_ket(kraus, ket, [1], [1]) + ket_out = fock.apply_kraus_to_ket(kraus, ket, [1], [1]) assert ket_out.shape == (2, 5, 4) @@ -269,7 +256,7 @@ def test_apply_kraus_to_ket_2mode(): """Test that Kraus operators are applied to a ket on the correct indices""" ket = np.random.normal(size=(2, 3, 4)) kraus = np.random.normal(size=(5, 3, 4)) - ket_out = apply_kraus_to_ket(kraus, ket, [1, 2], [1]) + ket_out = fock.apply_kraus_to_ket(kraus, ket, [1, 2], [1]) assert ket_out.shape == (2, 5) @@ -277,7 +264,7 @@ def test_apply_kraus_to_ket_2mode_2(): """Test that Kraus operators are applied to a ket on the correct indices""" ket = np.random.normal(size=(2, 3)) kraus = np.random.normal(size=(5, 4, 3)) - ket_out = apply_kraus_to_ket(kraus, ket, [1], [1, 2]) + ket_out = fock.apply_kraus_to_ket(kraus, ket, [1], [1, 2]) assert ket_out.shape == (2, 5, 4) @@ -285,7 +272,7 @@ def test_apply_kraus_to_dm_1mode(): """Test that Kraus operators are applied to a dm on the correct indices""" dm = np.random.normal(size=(2, 3, 2, 3)) kraus = np.random.normal(size=(5, 3)) - dm_out = apply_kraus_to_dm(kraus, dm, [1], [1]) + dm_out = fock.apply_kraus_to_dm(kraus, dm, [1], [1]) assert dm_out.shape == (2, 5, 2, 5) @@ -293,7 +280,7 @@ def test_apply_kraus_to_dm_2mode(): """Test that Kraus operators are applied to a dm on the correct indices""" dm = np.random.normal(size=(2, 3, 4, 2, 3, 4)) kraus = np.random.normal(size=(5, 3, 4)) - dm_out = apply_kraus_to_dm(kraus, dm, [1, 2], [1]) + dm_out = fock.apply_kraus_to_dm(kraus, dm, [1, 2], [1]) assert dm_out.shape == (2, 5, 2, 5) @@ -301,7 +288,7 @@ def test_apply_kraus_to_dm_2mode_2(): """Test that Kraus operators are applied to a dm on the correct indices""" dm = np.random.normal(size=(2, 3, 4, 2, 3, 4)) kraus = np.random.normal(size=(5, 6, 3)) - dm_out = apply_kraus_to_dm(kraus, dm, [1], [3, 1]) + dm_out = fock.apply_kraus_to_dm(kraus, dm, [1], [3, 1]) assert dm_out.shape == (2, 6, 4, 5, 2, 6, 4, 5) @@ -309,7 +296,7 @@ def test_apply_choi_to_ket_1mode(): """Test that choi operators are applied to a ket on the correct indices""" ket = np.random.normal(size=(3, 5)) choi = np.random.normal(size=(4, 3, 4, 3)) # [out_l, in_l, out_r, in_r] - ket_out = apply_choi_to_ket(choi, ket, [0], [0]) + ket_out = fock.apply_choi_to_ket(choi, ket, [0], [0]) assert ket_out.shape == (4, 5, 4, 5) @@ -317,7 +304,7 @@ def test_apply_choi_to_ket_2mode(): """Test that choi operators are applied to a ket on the correct indices""" ket = np.random.normal(size=(3, 5)) choi = np.random.normal(size=(2, 3, 5, 2, 3, 5)) # [out_l, in_l, out_r, in_r] - ket_out = apply_choi_to_ket(choi, ket, [0, 1], [0]) + ket_out = fock.apply_choi_to_ket(choi, ket, [0, 1], [0]) assert ket_out.shape == (2, 2) @@ -325,82 +312,104 @@ def test_apply_choi_to_dm_1mode(): """Test that choi operators are applied to a dm on the correct indices""" dm = np.random.normal(size=(3, 5, 3, 5)) choi = np.random.normal(size=(4, 3, 4, 3)) # [out_l, in_l, out_r, in_r] - dm_out = apply_choi_to_dm(choi, dm, [0], [0]) + dm_out = fock.apply_choi_to_dm(choi, dm, [0], [0]) assert dm_out.shape == (4, 5, 4, 5) def test_apply_choi_to_dm_2mode(): """Test that choi operators are applied to a dm on the correct indices""" dm = np.random.normal(size=(4, 5, 4, 5)) - choi = np.random.normal(size=(2, 3, 5, 2, 3, 5)) # [out_l, in_l, out_r, in_r] - dm_out = apply_choi_to_dm(choi, dm, [1], [1, 2]) + choi = np.random.normal(size=(2, 3, 5, 2, 3, 5)) # [out_l_1,2, in_l_1, out_r_1,2, in_r_1] + dm_out = fock.apply_choi_to_dm(choi, dm, [1], [1, 2]) assert dm_out.shape == (4, 2, 3, 4, 2, 3) -class TestDisplacement: - def test_grad_displacement(self): - """Tests the value of the analytic gradient for the Dgate against finite differences""" - cutoff = 4 - r = 1.0 - theta = np.pi / 8 - T = _displacement(r, theta, cutoff) - Dr, Dtheta = _grad_displacement(T, r, theta) - - dr = 0.001 - dtheta = 0.001 - Drp = _displacement(r + dr, theta, cutoff) - Drm = _displacement(r - dr, theta, cutoff) - Dthetap = _displacement(r, theta + dtheta, cutoff) - Dthetam = _displacement(r, theta - dtheta, cutoff) - Drapprox = (Drp - Drm) / (2 * dr) - Dthetaapprox = (Dthetap - Dthetam) / (2 * dtheta) - assert np.allclose(Dr, Drapprox, atol=1e-5, rtol=0) - assert np.allclose(Dtheta, Dthetaapprox, atol=1e-5, rtol=0) - - def test_displacement_values(self): - """Tests the correct construction of the single mode displacement operation""" - cutoff = 5 - alpha = 0.3 + 0.5 * 1j - # This data is obtained by using qutip - # np.array(displace(40,alpha).data.todense())[0:5,0:5] - expected = np.array( +def test_displacement_grad(): + """Tests the value of the analytic gradient for the Dgate against finite differences""" + cutoff = 4 + r = 2.0 + theta = np.pi / 8 + T = displacement((cutoff, cutoff), r * np.exp(1j * theta)) + Dr, Dtheta = grad_displacement(T, r, theta) + + dr = 0.001 + dtheta = 0.001 + Drp = displacement((cutoff, cutoff), (r + dr) * np.exp(1j * theta)) + Drm = displacement((cutoff, cutoff), (r - dr) * np.exp(1j * theta)) + Dthetap = displacement((cutoff, cutoff), r * np.exp(1j * (theta + dtheta))) + Dthetam = displacement((cutoff, cutoff), r * np.exp(1j * (theta - dtheta))) + Drapprox = (Drp - Drm) / (2 * dr) + Dthetaapprox = (Dthetap - Dthetam) / (2 * dtheta) + assert np.allclose(Dr, Drapprox, atol=1e-5, rtol=0) + assert np.allclose(Dtheta, Dthetaapprox, atol=1e-5, rtol=0) + + +def test_displacement_values(): + """Tests the correct construction of the single mode displacement operation""" + cutoff = 5 + alpha = 0.3 + 0.5 * 1j + # This data is obtained by using qutip + # np.array(displace(40,alpha).data.todense())[0:5,0:5] + expected = np.array( + [ [ - [ - 0.84366482 + 0.00000000e00j, - -0.25309944 + 4.21832408e-01j, - -0.09544978 - 1.78968334e-01j, - 0.06819609 + 3.44424719e-03j, - -0.01109048 + 1.65323865e-02j, - ], - [ - 0.25309944 + 4.21832408e-01j, - 0.55681878 + 0.00000000e00j, - -0.29708743 + 4.95145724e-01j, - -0.14658716 - 2.74850926e-01j, - 0.12479885 + 6.30297236e-03j, - ], - [ - -0.09544978 + 1.78968334e-01j, - 0.29708743 + 4.95145724e-01j, - 0.31873657 + 0.00000000e00j, - -0.29777767 + 4.96296112e-01j, - -0.18306015 - 3.43237787e-01j, - ], - [ - -0.06819609 + 3.44424719e-03j, - -0.14658716 + 2.74850926e-01j, - 0.29777767 + 4.96296112e-01j, - 0.12389162 + 1.10385981e-17j, - -0.27646677 + 4.60777945e-01j, - ], - [ - -0.01109048 - 1.65323865e-02j, - -0.12479885 + 6.30297236e-03j, - -0.18306015 + 3.43237787e-01j, - 0.27646677 + 4.60777945e-01j, - -0.03277289 + 1.88440656e-17j, - ], - ] - ) - T = _displacement(np.abs(alpha), np.angle(alpha), cutoff) - assert np.allclose(T, expected, atol=1e-5, rtol=0) + 0.84366482 + 0.00000000e00j, + -0.25309944 + 4.21832408e-01j, + -0.09544978 - 1.78968334e-01j, + 0.06819609 + 3.44424719e-03j, + -0.01109048 + 1.65323865e-02j, + ], + [ + 0.25309944 + 4.21832408e-01j, + 0.55681878 + 0.00000000e00j, + -0.29708743 + 4.95145724e-01j, + -0.14658716 - 2.74850926e-01j, + 0.12479885 + 6.30297236e-03j, + ], + [ + -0.09544978 + 1.78968334e-01j, + 0.29708743 + 4.95145724e-01j, + 0.31873657 + 0.00000000e00j, + -0.29777767 + 4.96296112e-01j, + -0.18306015 - 3.43237787e-01j, + ], + [ + -0.06819609 + 3.44424719e-03j, + -0.14658716 + 2.74850926e-01j, + 0.29777767 + 4.96296112e-01j, + 0.12389162 + 1.10385981e-17j, + -0.27646677 + 4.60777945e-01j, + ], + [ + -0.01109048 - 1.65323865e-02j, + -0.12479885 + 6.30297236e-03j, + -0.18306015 + 3.43237787e-01j, + 0.27646677 + 4.60777945e-01j, + -0.03277289 + 1.88440656e-17j, + ], + ] + ) + D = displacement((cutoff, cutoff), alpha) + assert np.allclose(D, expected, atol=1e-5, rtol=0) + + +@given(x=st.floats(-1, 1), y=st.floats(-1, 1)) +def test_number_means(x, y): + assert np.allclose(State(ket=Coherent(x, y).ket([80])).number_means, x * x + y * y) + assert np.allclose(State(dm=Coherent(x, y).dm([80])).number_means, x * x + y * y) + + +@given(x=st.floats(-1, 1), y=st.floats(-1, 1)) +def test_number_variances_coh(x, y): + assert np.allclose(fock.number_variances(Coherent(x, y).ket([80]), False)[0], x * x + y * y) + assert np.allclose(fock.number_variances(Coherent(x, y).dm([80]), True)[0], x * x + y * y) + + +def test_number_variances_fock(): + assert np.allclose(fock.number_variances(Fock(n=1).ket(), False), 0) + assert np.allclose(fock.number_variances(Fock(n=1).dm(), True), 0) + + +def test_normalize_dm(): + dm = np.array([[0.2, 0], [0, 0.2]]) + assert np.allclose(fock.normalize(dm, True), np.array([[0.5, 0], [0, 0.5]])) diff --git a/tests/test_physics/test_gaussian/test_gaussian_utils.py b/tests/test_physics/test_gaussian/test_gaussian_utils.py index 1698f48a9..9b87c64c4 100644 --- a/tests/test_physics/test_gaussian/test_gaussian_utils.py +++ b/tests/test_physics/test_gaussian/test_gaussian_utils.py @@ -13,7 +13,7 @@ # limitations under the License. import numpy as np -from hypothesis import given, strategies as st + from mrmustard import * from mrmustard.physics import gaussian as gp @@ -53,10 +53,30 @@ def test_partition_cov_2modes(): def test_partition_cov_3modes(): pass # TODO - # arr = np.array([[1,2,3,4,5,6], - # [7,8,9,10,11,12], - # [13,14,15,16,17,18], - # [19,20,21,22,23,24], - # [25,26,27,28,29,30], - # [31,32,33,34,35,36]]) - # A,B,AB = gp.partition_cov(gp.math.astensor(arr), Amodes=[0,2]) + +def test_CPTP_with_none_X(): + cov, means = gp.CPTP( + cov=np.eye(2), + means=np.zeros(2), + X=None, + Y=np.zeros((2, 2)), + d=np.zeros(2), + state_modes=[0], + transf_modes=[0], + ) + assert np.allclose(cov, np.eye(2)) + assert np.allclose(means, np.zeros(2)) + + +def test_CPTP_with_none_XYd(): + cov, means = gp.CPTP( + cov=np.eye(2), + means=np.zeros(2), + X=None, + Y=None, + d=None, + state_modes=[0], + transf_modes=[0], + ) + assert np.allclose(cov, np.eye(2)) + assert np.allclose(means, np.zeros(2)) diff --git a/tests/test_physics/test_gaussian/test_symplectics.py b/tests/test_physics/test_gaussian/test_symplectics.py index 09fa2dff2..832f89cc3 100644 --- a/tests/test_physics/test_gaussian/test_symplectics.py +++ b/tests/test_physics/test_gaussian/test_symplectics.py @@ -12,28 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pytest -from hypothesis import given, strategies as st - -from thewalrus.symplectic import two_mode_squeezing, squeezing, rotation, beam_splitter, expand import numpy as np +from hypothesis import given +from hypothesis import strategies as st +from thewalrus.symplectic import beam_splitter, expand, rotation, squeezing, two_mode_squeezing -from mrmustard import settings -from mrmustard.lab.gates import ( - Sgate, +from mrmustard.lab import ( + Amplifier, + Attenuator, BSgate, - S2gate, - Rgate, - MZgate, - Pgate, + Coherent, CXgate, CZgate, Dgate, - Amplifier, - Attenuator, + MZgate, + Pgate, + Rgate, + S2gate, + Sgate, ) -from mrmustard.lab.states import Vacuum, TMSV, Thermal -from mrmustard.physics.gaussian import quadratic_phase, controlled_Z, controlled_X +from mrmustard.lab.states import TMSV, Thermal, Vacuum +from mrmustard.physics.gaussian import controlled_X, controlled_Z @given(r=st.floats(0, 2)) @@ -135,7 +134,7 @@ def test_BSgate(theta, phi): @given(r=st.floats(0, 1), phi=st.floats(0, 2 * np.pi)) def test_S2gate(r, phi): """Tests the S2gate is implemented correctly by applying it on one half of a maximally entangled state""" - r_choi = settings.CHOI_R + r_choi = np.arcsinh(1.0) S2 = S2gate(r=r, phi=phi) bell = (TMSV(r_choi) & TMSV(r_choi)).get_modes([0, 2, 1, 3]) cov = (bell[0, 1, 2, 3] >> S2[0, 1]).cov @@ -150,7 +149,7 @@ def test_S2gate(r, phi): @given(phi_ex=st.floats(0, 2 * np.pi), phi_in=st.floats(0, 2 * np.pi)) def test_MZgate_external_tms(phi_ex, phi_in): """Tests the MZgate is implemented correctly by applying it on one half of a maximally entangled state""" - r_choi = settings.CHOI_R + r_choi = np.arcsinh(1.0) bell = (TMSV(r_choi) & TMSV(r_choi)).get_modes([0, 2, 1, 3]) MZ = MZgate(phi_a=phi_ex, phi_b=phi_in, internal=False) cov = (bell[0, 1, 2, 3] >> MZ[0, 1]).cov @@ -173,7 +172,7 @@ def test_MZgate_external_tms(phi_ex, phi_in): @given(phi_a=st.floats(0, 2 * np.pi), phi_b=st.floats(0, 2 * np.pi)) def test_MZgate_internal_tms(phi_a, phi_b): """Tests the MZgate is implemented correctly by applying it on one half of a maximally entangled state""" - r_choi = settings.CHOI_R + r_choi = np.arcsinh(1.0) bell = (TMSV(r_choi) & TMSV(r_choi)).get_modes([0, 2, 1, 3]) MZ = MZgate(phi_a=phi_a, phi_b=phi_b, internal=True) cov = (bell[0, 1, 2, 3] >> MZ[0, 1]).cov @@ -207,3 +206,9 @@ def test_amplifier_attenuator_on_coherent_coherent(eta, x, y): assert Vacuum(1) >> Dgate(x, y) >> Amplifier(1 / eta) >> Attenuator(eta) == Thermal( ((1 / eta) - 1) * eta ) >> Dgate(x, y) + + +@given(x=st.floats(-2, 2), y=st.floats(-2, 2)) +def test_number_means(x, y): + """Tests that the number means of a displaced state are correct""" + assert np.allclose(Coherent(x, y).number_means, x * x + y * y) diff --git a/tests/test_training/test_callbacks.py b/tests/test_training/test_callbacks.py new file mode 100644 index 000000000..0091b9ff5 --- /dev/null +++ b/tests/test_training/test_callbacks.py @@ -0,0 +1,72 @@ +# Copyright 2022 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""callbacks tests""" + +import numpy as np +import tensorflow as tf + +from mrmustard import settings +from mrmustard.lab.circuit import Circuit +from mrmustard.lab.gates import ( + BSgate, + S2gate, +) +from mrmustard.lab.states import Vacuum +from mrmustard.math import Math +from mrmustard.training import Optimizer, TensorboardCallback + +math = Math() + + +def test_tensorboard_callback(tmp_path): + """Tests tensorboard callbacks on hong-ou-mandel optimization.""" + settings.SEED = 42 + i, k = 2, 3 + r = np.arcsinh(1.0) + s2_0, s2_1, bs = ( + S2gate(r=r, phi=0.0, phi_trainable=True)[0, 1], + S2gate(r=r, phi=0.0, phi_trainable=True)[2, 3], + BSgate( + theta=np.arccos(np.sqrt(k / (i + k))) + 0.1 * settings.rng.normal(), + phi=settings.rng.normal(), + theta_trainable=True, + phi_trainable=True, + )[1, 2], + ) + circ = Circuit([s2_0, s2_1, bs]) + state_in = Vacuum(num_modes=4) + cutoff = 1 + i + k + + free_var = math.new_variable([1.1, -0.2], None, "free_var") + + def cost_fn(): + return tf.abs( + (state_in >> circ).ket(cutoffs=[cutoff] * 4)[i, 1, i + k - 1, k] + ) ** 2 + tf.reduce_sum(free_var**2) + + tbcb = TensorboardCallback( + steps_per_call=2, + root_logdir=tmp_path, + cost_converter=np.log10, + track_grads=True, + ) + + opt = Optimizer(euclidean_lr=0.01) + opt.minimize(cost_fn, by_optimizing=[circ, free_var], max_steps=300, callbacks={"tb": tbcb}) + + assert np.allclose(np.cos(bs.theta.value) ** 2, k / (i + k), atol=1e-2) + assert tbcb.logdir.exists() + assert len(list(tbcb.writter_logdir.glob("events*"))) > 0 + assert len(opt.callback_history["tb"]) == (len(opt.opt_history) - 1) // tbcb.steps_per_call diff --git a/tests/test_training/test_opt.py b/tests/test_training/test_opt.py index 48b4bfbf9..9db5b0797 100644 --- a/tests/test_training/test_opt.py +++ b/tests/test_training/test_opt.py @@ -31,11 +31,12 @@ S2gate, Sgate, ) -from mrmustard.lab.states import DisplacedSqueezed, SqueezedVacuum, Vacuum +from mrmustard.lab.states import DisplacedSqueezed, Fock, Gaussian, SqueezedVacuum, Vacuum from mrmustard.math import Math from mrmustard.physics import fidelity from mrmustard.physics.gaussian import trace, von_neumann_entropy from mrmustard.training import Optimizer, Parametrized +from mrmustard.training.callbacks import Callback math = Math() @@ -43,7 +44,7 @@ @given(n=st.integers(0, 3)) def test_S2gate_coincidence_prob(n): """Testing the optimal probability of obtaining |n,n> from a two mode squeezed vacuum""" - settings.SEED = 42 + settings.SEED = 40 S = S2gate( r=abs(settings.rng.normal(loc=1.0, scale=0.1)), r_trainable=True, @@ -52,12 +53,24 @@ def test_S2gate_coincidence_prob(n): def cost_fn(): return -math.abs((Vacuum(2) >> S[0, 1]).ket(cutoffs=[n + 1, n + 1])[n, n]) ** 2 + def cb(optimizer, cost, trainables, **kwargs): # pylint: disable=unused-argument + return { + "cost": cost, + "lr": optimizer.learning_rate["euclidean"], + "num_trainables": len(trainables), + } + opt = Optimizer(euclidean_lr=0.01) - opt.minimize(cost_fn, by_optimizing=[S], max_steps=300) + opt.minimize(cost_fn, by_optimizing=[S], max_steps=300, callbacks=cb) expected = 1 / (n + 1) * (n / (n + 1)) ** n assert np.allclose(-cost_fn(), expected, atol=1e-5) + cb_result = opt.callback_history.get("cb") + assert {res["num_trainables"] for res in cb_result} == {1} + assert {res["lr"] for res in cb_result} == {0.01} + assert [res["cost"] for res in cb_result] == opt.opt_history[1:] + @given(i=st.integers(1, 5), k=st.integers(1, 5)) def test_hong_ou_mandel_optimizer(i, k): @@ -86,8 +99,15 @@ def cost_fn(): return math.abs((state_in >> circ).ket(cutoffs=[cutoff] * 4)[i, 1, i + k - 1, k]) ** 2 opt = Optimizer(euclidean_lr=0.01) - opt.minimize(cost_fn, by_optimizing=[circ], max_steps=300) + opt.minimize( + cost_fn, + by_optimizing=[circ], + max_steps=300, + callbacks=[Callback(tag="null_cb", steps_per_call=3)], + ) assert np.allclose(np.cos(bs.theta.value) ** 2, k / (i + k), atol=1e-2) + assert "null_cb" in opt.callback_history + assert len(opt.callback_history["null_cb"]) == (len(opt.opt_history) - 1) // 3 def test_learning_two_mode_squeezing(): @@ -95,8 +115,8 @@ def test_learning_two_mode_squeezing(): settings.SEED = 42 ops = [ Sgate( - r=abs(settings.rng.normal(size=(2))), - phi=settings.rng.normal(size=(2)), + r=abs(settings.rng.normal(size=2)), + phi=settings.rng.normal(size=2), r_trainable=True, phi_trainable=True, ), @@ -126,7 +146,7 @@ def test_learning_two_mode_Ggate(): G = Ggate(num_modes=2, symplectic_trainable=True) def cost_fn(): - amps = (Vacuum(2) >> G).ket(cutoffs=[2, 2]) + amps = (Vacuum(2) >> G).ket(cutoffs=[2, 2], max_prob=0.9999) return -math.abs(amps[1, 1]) ** 2 + math.abs(amps[0, 1]) ** 2 opt = Optimizer(symplectic_lr=0.5, euclidean_lr=0.01) @@ -140,8 +160,8 @@ def test_learning_two_mode_Interferometer(): settings.SEED = 42 ops = [ Sgate( - r=settings.rng.normal(size=(2)) ** 2, - phi=settings.rng.normal(size=(2)), + r=settings.rng.normal(size=2) ** 2, + phi=settings.rng.normal(size=2), r_trainable=True, phi_trainable=True, ), @@ -165,8 +185,8 @@ def test_learning_two_mode_RealInterferometer(): settings.SEED = 2 ops = [ Sgate( - r=settings.rng.normal(size=(2)) ** 2, - phi=settings.rng.normal(size=(2)), + r=settings.rng.normal(size=2) ** 2, + phi=settings.rng.normal(size=2), r_trainable=True, phi_trainable=True, ), @@ -223,7 +243,7 @@ def test_learning_four_mode_Interferometer(): >> BSgate(settings.rng.normal(scale=0.01), modes=[1, 2]) >> BSgate(settings.rng.normal(scale=0.01), modes=[0, 3]) ) - X = math.cast(perturbed.XYd[0], "complex128") + X = math.cast(perturbed.XYd()[0], "complex128") perturbed_U = X[:4, :4] + 1j * X[4:, :4] ops = [ @@ -263,7 +283,7 @@ def test_learning_four_mode_RealInterferometer(): >> BSgate(settings.rng.normal(scale=0.01), modes=[1, 2]) >> BSgate(settings.rng.normal(scale=0.01), modes=[0, 3]) ) - perturbed_O = pertubed.XYd[0][:4, :4] + perturbed_O = pertubed.XYd()[0][:4, :4] ops = [ Sgate( @@ -386,12 +406,87 @@ def test_dgate_optimization(): settings.SEED = 24 dgate = Dgate(x_trainable=True, y_trainable=True) - target_state = DisplacedSqueezed(r=0.0, x=1.0, y=1.0) + target_state = DisplacedSqueezed(r=0.0, x=0.1, y=0.2).ket(cutoffs=[40]) def cost_fn(): state_out = Vacuum(1) >> dgate - - return 1 - fidelity(state_out, target_state) + return -math.abs(math.sum(math.conj(state_out.ket([40])) * target_state)) ** 2 opt = Optimizer() opt.minimize(cost_fn, by_optimizing=[dgate]) + + assert np.allclose(dgate.x.value, 0.1, atol=0.01) + assert np.allclose(dgate.y.value, 0.2, atol=0.01) + + +def test_sgate_optimization(): + """Test that Sgate is optimized correctly.""" + settings.SEED = 25 + + sgate = Sgate(r=0.2, phi=0.1, r_trainable=True, phi_trainable=True) + target_state = SqueezedVacuum(r=0.1, phi=0.2).ket(cutoffs=[40]) + + def cost_fn(): + state_out = Vacuum(1) >> sgate + + return -math.abs(math.sum(math.conj(state_out.ket([40])) * target_state)) ** 2 + + opt = Optimizer() + opt.minimize(cost_fn, by_optimizing=[sgate]) + + assert np.allclose(sgate.r.value, 0.1, atol=0.01) + assert np.allclose(sgate.phi.value, 0.2, atol=0.01) + + +def test_bsgate_optimization(): + """Test that Sgate is optimized correctly.""" + settings.SEED = 25 + + G = Gaussian(2) + + bsgate = BSgate(0.05, 0.1, theta_trainable=True, phi_trainable=True) + target_state = (G >> BSgate(0.1, 0.2)).ket(cutoffs=[40, 40]) + + def cost_fn(): + state_out = G >> bsgate + + return -math.abs(math.sum(math.conj(state_out.ket([40, 40])) * target_state)) ** 2 + + opt = Optimizer() + opt.minimize(cost_fn, by_optimizing=[bsgate]) + + assert np.allclose(bsgate.theta.value, 0.1, atol=0.01) + assert np.allclose(bsgate.phi.value, 0.2, atol=0.01) + + +def test_squeezing_grad_from_fock(): + """Test that the gradient of a squeezing gate is computed from the fock representation.""" + squeezing = Sgate(r=1, r_trainable=True) + + def cost_fn(): + return -(Fock(2) >> squeezing << Vacuum(1)) + + opt = Optimizer(euclidean_lr=0.05) + opt.minimize(cost_fn, by_optimizing=[squeezing], max_steps=100) + + +def test_displacement_grad_from_fock(): + """Test that the gradient of a displacement gate is computed from the fock representation.""" + disp = Dgate(x=1.0, y=1.0, x_trainable=True, y_trainable=True) + + def cost_fn(): + return -(Fock(2) >> disp << Vacuum(1)) + + opt = Optimizer(euclidean_lr=0.05) + opt.minimize(cost_fn, by_optimizing=[disp], max_steps=100) + + +def test_bsgate_grad_from_fock(): + """Test that the gradient of a beamsplitter gate is computed from the fock representation.""" + sq = SqueezedVacuum(r=1.0, r_trainable=True) + + def cost_fn(): + return -((sq & Fock(1)) >> BSgate(0.5) << (Vacuum(1) & Fock(1))) + + opt = Optimizer(euclidean_lr=0.05) + opt.minimize(cost_fn, by_optimizing=[sq], max_steps=100) diff --git a/tests/test_training/test_parametrized.py b/tests/test_training/test_parametrized.py index 171dc4685..55ca3f7b4 100644 --- a/tests/test_training/test_parametrized.py +++ b/tests/test_training/test_parametrized.py @@ -115,6 +115,18 @@ def test_get_parameters(): assert len(constant_params) == 2 assert all(isinstance(param, Constant) for param in constant_params) + trainable_params = parametrized.traverse_trainables(owner_tag="foo") + assert len(trainable_params) == 4 + assert all(isinstance(param, Trainable) for param in trainable_params.values()) + assert all(tag.startswith("foo") for tag in trainable_params) + assert all(tag.split("/")[1] in kwargs for tag in trainable_params) + + constant_params = parametrized.traverse_constants() + assert len(constant_params) == 2 + assert all(isinstance(param, Constant) for param in constant_params.values()) + assert all(tag.startswith("Parametrized") for tag in constant_params) + assert all(tag.split("/")[1] in kwargs for tag in constant_params) + def test_get_nested_parameters(): """Test that nested Parametrized objects (e.g. a circuit) return all the trainable @@ -137,3 +149,13 @@ def test_get_nested_parameters(): assert (s2.phi in trainables) and (bs.theta in trainables) assert (s2.r in constants) and (bs.phi in constants) + + trainables = circ.traverse_trainables() + constants = circ.traverse_constants("Device") + assert len(trainables) == 2 + assert len(constants) == 2 + assert all(tag.startswith("Circuit/_ops[") for tag in trainables) + assert all(tag.startswith("Device/_ops[") for tag in constants) + + assert (s2.phi in trainables.values()) and (bs.theta in trainables.values()) + assert (s2.r in constants.values()) and (bs.phi in constants.values()) diff --git a/tests/test_utils/test_wigner.py b/tests/test_utils/test_wigner.py index 8ade9e656..60395d3b8 100644 --- a/tests/test_utils/test_wigner.py +++ b/tests/test_utils/test_wigner.py @@ -14,20 +14,21 @@ """This module contains test for the calculation of the discretized Wigner function.""" -import pytest import numpy as np +import pytest from scipy.stats import multivariate_normal -from mrmustard.utils.wigner import wigner_discretized + +from mrmustard import settings from mrmustard.lab import ( - Vacuum, Coherent, - SqueezedVacuum, - Thermal, DisplacedSqueezed, - Gaussian, Fock, + Gaussian, + SqueezedVacuum, + Thermal, + Vacuum, ) -from mrmustard import settings +from mrmustard.utils.wigner import wigner_discretized def multivariate_normal_pdf(qvec, pvec, means, cov):