From 8a3cf5ddf5b2d419d6d028f45f95879b71dc705b Mon Sep 17 00:00:00 2001 From: IraitzM Date: Thu, 6 Feb 2025 18:03:30 +0100 Subject: [PATCH 01/10] fix(uv): Adding uv and pdm projects structure --- .gitignore | 15 +- .pre-commit-config.yaml | 34 + .python-version | 1 + .vscode/settings.json | 4 - README.md | 27 +- __init__.py | 0 build/lib/quask/__init__.py | 3 - build/lib/quask/core/__init__.py | 5 - build/lib/quask/core/ansatz.py | 168 -- build/lib/quask/core/kernel.py | 133 -- build/lib/quask/core/kernel_factory.py | 50 - build/lib/quask/core/kernel_type.py | 21 - build/lib/quask/core/operation.py | 53 - .../lib/quask/core_implementation/__init__.py | 4 - .../core_implementation/braket_kernel.py | 32 - .../core_implementation/pennylane_kernel.py | 113 - .../quask/core_implementation/qibo_kernel.py | 5 - .../core_implementation/qiskit_kernel.py | 118 - build/lib/quask/evaluator/__init__.py | 10 - .../centered_kernel_alignment_evaluator.py | 38 - .../evaluator/covering_number_evaluator.py | 24 - .../ess_model_complexity_evaluator.py | 72 - .../geometric_difference_evaluator.py | 67 - build/lib/quask/evaluator/haar_evaluator.py | 73 - .../evaluator/kernel_alignment_evaluator.py | 36 - build/lib/quask/evaluator/kernel_evaluator.py | 21 - .../lib/quask/evaluator/lie_rank_evaluator.py | 116 - .../ridge_generalization_evaluator.py | 34 - .../evaluator/spectral_bias_evaluator.py | 102 - build/lib/quask/optimizer/__init__.py | 6 - .../quask/optimizer/base_kernel_optimizer.py | 32 - .../lib/quask/optimizer/bayesian_optimizer.py | 73 - build/lib/quask/optimizer/greedy_optimizer.py | 50 - .../optimizer/metaheuristic_optimizer.py | 122 -- .../reinforcement_learning_optimizer.py | 82 - .../optimizer/wide_kernel_environment.py | 153 -- build/lib/quask/tests/__init__.py | 0 build/lib/quask/tests/kernel_test.py | 59 - dist/quask-1.0.2-py3-none-any.whl | Bin 36668 -> 0 bytes dist/quask-1.0.2.tar.gz | Bin 29442 -> 0 bytes dist/quask-2.0.0a1-py3-none-any.whl | Bin 37494 -> 0 bytes dist/quask-2.0.0a1.tar.gz | Bin 28739 -> 0 bytes dist/quask-2.0.1a2-py3-none-any.whl | Bin 38910 -> 0 bytes dist/quask-2.0.1a2.tar.gz | Bin 29900 -> 0 bytes pyproject.toml | 141 ++ requirements.txt | 423 ++++ setup.cfg | 36 - setup.py | 10 - src/quask.egg-info/PKG-INFO | 139 -- src/quask.egg-info/SOURCES.txt | 43 - src/quask.egg-info/dependency_links.txt | 1 - src/quask.egg-info/not-zip-safe | 1 - src/quask.egg-info/requires.txt | 15 - src/quask.egg-info/top_level.txt | 1 - src/quask/__version__.py | 3 + src/quask/core/__init__.py | 10 +- src/quask/core/ansatz.py | 163 +- src/quask/core/kernel.py | 119 +- src/quask/core/kernel_factory.py | 36 +- src/quask/core/kernel_type.py | 11 +- src/quask/core/operation.py | 39 +- src/quask/core_implementation/__init__.py | 8 +- .../core_implementation/braket_kernel.py | 34 +- .../core_implementation/pennylane_kernel.py | 63 +- src/quask/core_implementation/qibo_kernel.py | 4 +- .../core_implementation/qiskit_kernel.py | 170 +- src/quask/evaluator/__init__.py | 34 +- .../centered_kernel_alignment_evaluator.py | 18 +- .../evaluator/covering_number_evaluator.py | 13 +- .../ess_model_complexity_evaluator.py | 43 +- .../geometric_difference_evaluator.py | 30 +- src/quask/evaluator/haar_evaluator.py | 42 +- .../evaluator/kernel_alignment_evaluator.py | 14 +- src/quask/evaluator/kernel_evaluator.py | 12 +- src/quask/evaluator/lie_rank_evaluator.py | 69 +- .../ridge_generalization_evaluator.py | 17 +- .../evaluator/spectral_bias_evaluator.py | 38 +- src/quask/optimizer/base_kernel_optimizer.py | 23 +- src/quask/optimizer/bayesian_optimizer.py | 42 +- .../optimizer/metaheuristic_optimizer.py | 72 +- .../reinforcement_learning_optimizer.py | 78 +- .../optimizer/wide_kernel_environment.py | 81 +- src/quask/tests/__init__.py | 0 src/quask/tests/kernel_test.py | 59 - tests/kernel_test.py | 21 +- tests/test_example.py | 10 +- tests/test_pennylane_kernel.py | 119 +- tox.ini | 21 + uv.lock | 1943 +++++++++++++++++ 89 files changed, 3482 insertions(+), 2743 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 .python-version delete mode 100644 .vscode/settings.json delete mode 100644 __init__.py delete mode 100644 build/lib/quask/__init__.py delete mode 100644 build/lib/quask/core/__init__.py delete mode 100644 build/lib/quask/core/ansatz.py delete mode 100644 build/lib/quask/core/kernel.py delete mode 100644 build/lib/quask/core/kernel_factory.py delete mode 100644 build/lib/quask/core/kernel_type.py delete mode 100644 build/lib/quask/core/operation.py delete mode 100644 build/lib/quask/core_implementation/__init__.py delete mode 100644 build/lib/quask/core_implementation/braket_kernel.py delete mode 100644 build/lib/quask/core_implementation/pennylane_kernel.py delete mode 100644 build/lib/quask/core_implementation/qibo_kernel.py delete mode 100644 build/lib/quask/core_implementation/qiskit_kernel.py delete mode 100644 build/lib/quask/evaluator/__init__.py delete mode 100644 build/lib/quask/evaluator/centered_kernel_alignment_evaluator.py delete mode 100644 build/lib/quask/evaluator/covering_number_evaluator.py delete mode 100644 build/lib/quask/evaluator/ess_model_complexity_evaluator.py delete mode 100644 build/lib/quask/evaluator/geometric_difference_evaluator.py delete mode 100644 build/lib/quask/evaluator/haar_evaluator.py delete mode 100644 build/lib/quask/evaluator/kernel_alignment_evaluator.py delete mode 100644 build/lib/quask/evaluator/kernel_evaluator.py delete mode 100644 build/lib/quask/evaluator/lie_rank_evaluator.py delete mode 100644 build/lib/quask/evaluator/ridge_generalization_evaluator.py delete mode 100644 build/lib/quask/evaluator/spectral_bias_evaluator.py delete mode 100644 build/lib/quask/optimizer/__init__.py delete mode 100644 build/lib/quask/optimizer/base_kernel_optimizer.py delete mode 100644 build/lib/quask/optimizer/bayesian_optimizer.py delete mode 100644 build/lib/quask/optimizer/greedy_optimizer.py delete mode 100644 build/lib/quask/optimizer/metaheuristic_optimizer.py delete mode 100644 build/lib/quask/optimizer/reinforcement_learning_optimizer.py delete mode 100644 build/lib/quask/optimizer/wide_kernel_environment.py delete mode 100644 build/lib/quask/tests/__init__.py delete mode 100644 build/lib/quask/tests/kernel_test.py delete mode 100644 dist/quask-1.0.2-py3-none-any.whl delete mode 100644 dist/quask-1.0.2.tar.gz delete mode 100644 dist/quask-2.0.0a1-py3-none-any.whl delete mode 100644 dist/quask-2.0.0a1.tar.gz delete mode 100644 dist/quask-2.0.1a2-py3-none-any.whl delete mode 100644 dist/quask-2.0.1a2.tar.gz create mode 100644 pyproject.toml create mode 100644 requirements.txt delete mode 100644 setup.cfg delete mode 100644 setup.py delete mode 100644 src/quask.egg-info/PKG-INFO delete mode 100644 src/quask.egg-info/SOURCES.txt delete mode 100644 src/quask.egg-info/dependency_links.txt delete mode 100644 src/quask.egg-info/not-zip-safe delete mode 100644 src/quask.egg-info/requires.txt delete mode 100644 src/quask.egg-info/top_level.txt create mode 100644 src/quask/__version__.py delete mode 100644 src/quask/tests/__init__.py delete mode 100644 src/quask/tests/kernel_test.py create mode 100644 tox.ini create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore index b7e3a84..37f7fd0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +# Artifacts and local files *.pyc dist/* build/* @@ -10,4 +11,16 @@ src/quask/evaluator/__pycache__/* src/quask/optimizer/__pycache__/* .ipynb_checkpoints/* .vs_code/* -.vscode/* \ No newline at end of file +.vscode/* + +# Virtual environment +.venv + +# Ruff +.ruff_cache + +# Tox +.tox + +# PDM +.pdm-build diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..33b5bb6 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,34 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.2.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files +- repo: https://github.com/asottile/pyupgrade + rev: v1.25.0 + hooks: + - id: pyupgrade + args: [--py36-plus] +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.9.3 + hooks: + # Run the linter. + - id: ruff + args: [ --fix, --preview ] + # Run the formatter. + - id: ruff-format +- repo: https://github.com/astral-sh/uv-pre-commit + # uv version. + rev: 0.5.24 + hooks: + - id: uv-lock +- repo: https://github.com/astral-sh/uv-pre-commit + # uv version. + rev: 0.5.24 + hooks: + - id: uv-export --no-hashes -o requirements.txt diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 215e639..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "esbonio.sphinx.confDir": "", - "restructuredtext.syntaxHighlighting.disabled": true -} \ No newline at end of file diff --git a/README.md b/README.md index bd7d57e..e7b44cd 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,11 @@ It is designed to simplify the process of choosing a quantum kernel, automate th QuASK promotes the use of reusable code and is available as a library that can be seamlessly integrated into existing code bases. It is written in Python 3, can be easily installed using pip, and is accessible on PyPI. - *Homepage*: [quask.web.cern.ch](https://quask.web.cern.ch/) *Documentation*: [quask.readthedocs.io](https://quask.readthedocs.io/en/latest/) -## Installation +## Installation The easiest way to use *quask* is by installing it in your Python3 environment (version >= 3.10) via the *pip* packet manager, @@ -24,23 +23,23 @@ You also need any quantum SDK installed on your system. For example, we can inst python3 -m pip install qiskit_ibm_runtime --upgrade python3 -m pip install qiskit-aer -See the [Installation section](https://quask.readthedocs.io/en/latest/installation.html) +See the [Installation section](https://quask.readthedocs.io/en/latest/installation.html) of our documentation page for more information. ## Examples The fastest way to start developing using _quask_ is via our [Getting started](https://quask.readthedocs.io/en/latest/getting_started.html) guide. -If you are not familiar with the concept of kernel methods in classical machine learning, we have developed a [series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_classical/index.html) on the topic. +If you are not familiar with the concept of kernel methods in classical machine learning, we have developed a [series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_classical/index.html) on the topic. -If you are not familiar with the concept of quantum kernels, we have developed a [series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_quantum/index.html) on the topic, which is also used to showcase the basic functionalities of _quask_. +If you are not familiar with the concept of quantum kernels, we have developed a [series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_quantum/index.html) on the topic, which is also used to showcase the basic functionalities of _quask_. Then [advanced features of _quask_](https://quask.readthedocs.io/en/latest/tutorials_quask/index.html) are shown, including the use of different backends, the criteria to evaluate a quantum kernel, and the automatic optimization approach. -Finally, [look here for some applications](https://quask.readthedocs.io/en/latest/tutorials_applications/index.html). +Finally, [look here for some applications](https://quask.readthedocs.io/en/latest/tutorials_applications/index.html). -## Source +## Source ### Deployment to PyPI @@ -49,7 +48,7 @@ The software is uploaded to [PyPI](https://pypi.org/project/quask/). ### Test -The suite of test for _quask_ is currently under development.To run the available tests, type +The suite of test for _quask_ is currently under development.To run the available tests, type pytest @@ -58,7 +57,7 @@ You can also specify specific test scripts. pytest tests/test_example.py - _quask_ has been developed and tested with the following versions of the quantum frameworks: + _quask_ has been developed and tested with the following versions of the quantum frameworks: * PennyLane==0.32.0 * PennyLane-Lightning==0.32.0 @@ -67,9 +66,9 @@ You can also specify specific test scripts. * qiskit-ibm-runtime==0.14.0 -## Documentation +## Documentation -The documentation is available at our [Read the Docs](https://quask.readthedocs.io/en/latest/) domain. +The documentation is available at our [Read the Docs](https://quask.readthedocs.io/en/latest/) domain. ### Generate the documentation @@ -93,7 +92,7 @@ The Sphinx configuration file (`conf.py`) has the following, non-standard option ### Generate the UML diagrams -Currently, the pages generated from the Python notebooks has to be compiled to RST format manually. We could use in the future the [nbsphinx extension](https://docs.readthedocs.io/en/stable/guides/jupyter.html) to automatize this process. This has the advantage that the documentation is always up to date, the disadvantage is that the process is much slower. +Currently, the pages generated from the Python notebooks has to be compiled to RST format manually. We could use in the future the [nbsphinx extension](https://docs.readthedocs.io/en/stable/guides/jupyter.html) to automatize this process. This has the advantage that the documentation is always up to date, the disadvantage is that the process is much slower. ### Generate the UML diagrams @@ -102,7 +101,7 @@ The UML diagrams in the [Platform overview](https://quask.readthedocs.io/en/late sudo apt-get install graphviz python3 -m pip install pylint -The UML diagrams are created via: +The UML diagrams are created via: cd src/quask pyreverse -o png -p QUASK . @@ -110,7 +109,7 @@ The UML diagrams are created via: ## Acknowledgements -The platform has been developed with the contribution of [Massimiliano Incudini](https://incud.github.io), Francesco Di Marcantonio, Davide Tezza, Roman Wixinger, Sofia Vallecorsa, and [Michele Grossi](https://scholar.google.com/citations?user=cnfcO7cAAAAJ&hl=en). +The platform has been developed with the contribution of [Massimiliano Incudini](https://incud.github.io), Francesco Di Marcantonio, Davide Tezza, Roman Wixinger, Sofia Vallecorsa, and [Michele Grossi](https://scholar.google.com/citations?user=cnfcO7cAAAAJ&hl=en). If you have used _quask_ for your project, please consider citing us. diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib/quask/__init__.py b/build/lib/quask/__init__.py deleted file mode 100644 index c76089e..0000000 --- a/build/lib/quask/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from . import datasets -from . import metrics -from . import kernels diff --git a/build/lib/quask/core/__init__.py b/build/lib/quask/core/__init__.py deleted file mode 100644 index a73d91a..0000000 --- a/build/lib/quask/core/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .operation import Operation -from .ansatz import Ansatz -from .kernel_type import KernelType -from .kernel_factory import KernelFactory -from .kernel import Kernel diff --git a/build/lib/quask/core/ansatz.py b/build/lib/quask/core/ansatz.py deleted file mode 100644 index b4b5f22..0000000 --- a/build/lib/quask/core/ansatz.py +++ /dev/null @@ -1,168 +0,0 @@ -import numpy as np -from typing import List -from . import Operation - - -class Ansatz: - """ - Class representing the Ansatz as list of Operations - """ - - def __init__(self, n_features: int, n_qubits: int, n_operations: int, allow_midcircuit_measurement=False): - """ - Initialization - :param n_features: number of feature that can be used to parametrize the operation - :param n_qubits: number of qubits of the circuit - :param n_operations: number of operations - :param allow_midcircuit_measurement: True if mid-circuit measurement are allowed - """ - assert n_qubits >= 2, "This ansatz is specified for >= 2 qubits" - assert n_features > 0, "Cannot have zero or negative number of features" - assert n_operations > 0, "Cannot have zero or negative number or operations" - self.n_features: int = n_features - self.n_qubits: int = n_qubits - self.n_operations: int = n_operations - self.operation_list: List[Operation] = [None] * n_operations - self.allow_midcircuit_measurement: bool = allow_midcircuit_measurement - - def change_operation(self, operation_index: int, new_feature: int, new_wires: List[int], new_generator: str, new_bandwidth: float): - """ - Overwrite the operation at the given index with a whole new set of data - :param operation_index: index of the operation - :param new_feature: feature parameterizing the operation - :param new_wires: wires on which the operation is applied - :param new_generator: generator of the operation - :param new_bandwidth: bandwidth of the operation - :return: None - """ - self.change_feature(operation_index, new_feature) - self.change_wires(operation_index, new_wires) - self.change_generators(operation_index, new_generator) - self.change_bandwidth(operation_index, new_bandwidth) - - def change_bandwidth(self, operation_index: int, new_bandwidth: float): - """ - Overwrite the operation at the given index with a new bandwidth - :param operation_index: index of the operation - :param new_bandwidth: bandwidth of the operation - :return: None - """ - assert 0 <= operation_index < self.n_operations, "Operation index out of bounds" - self.operation_list[operation_index].bandwidth = new_bandwidth - - def change_generators(self, operation_index: int, new_generator: str): - """ - Overwrite the operation at the given index with a new generator - :param operation_index: index of the operation - :param new_generator: generator of the operation - :return: None - """ - assert 0 <= operation_index < self.n_operations, "Operation index out of bounds" - assert new_generator in Operation.OPERATIONS, f"Unknown generator {new_generator}" - if not self.allow_midcircuit_measurement: - assert new_generator not in Operation.MEASUREMENT_OPERATIONS, "Mid-circuit measurement not allowed" - self.operation_list[operation_index].generator = new_generator - - def change_feature(self, operation_index: int, new_feature: int): - """ - Overwrite the operation at the given index with a new feature - :param operation_index: index of the operation - :param new_feature: feature parameterizing the operation - :return: None - """ - assert 0 <= operation_index < self.n_operations, "Operation index out of bounds" - assert 0 <= new_feature <= self.n_features, f"Feature index out of bounds ({new_feature=})" - self.operation_list[operation_index].feature = new_feature - - def change_wires(self, operation_index: int, new_wires: List[int]): - """ - Overwrite the operation at the given index with a new pair of wires - :param operation_index: index of the operation - :param new_wires: wires on which the operation is applied - :return: None - """ - assert 0 <= operation_index < self.n_operations, "Operation index out of bounds" - assert len(new_wires) == 2, "The location is a list of two integers, not less no more" - assert 0 <= new_wires[0] < self.n_qubits, f"First wire index out of bounds ({new_wires=})" - assert 0 <= new_wires[1] < self.n_qubits, f"Second wire index out of bounds ({new_wires=})" - assert new_wires[0] != new_wires[1], f"Cannot specify the same wire twice ({new_wires=})" - self.operation_list[operation_index].wires = new_wires - - def get_allowed_operations(self): - """ - Get the list of allowed operation for the ansatz, either only the PAULI_GENERATORS or any operation including measurements - :return: list of allowed operations - """ - if self.allow_midcircuit_measurement: - return Operation.OPERATIONS - else: - return Operation.PAULI_GENERATORS - - def initialize_to_identity(self): - """ - Initialize the ansatz to the identity circuit - :return: None - """ - self.operation_list = [None] * self.n_operations - for i in range(self.n_operations): - self.operation_list[i] = Operation("II", [0, 1], -1, 1) - - def initialize_to_random_circuit(self): - """ - Initialize the ansatz to a random circuit - :return: None - """ - for i in range(self.n_operations): - generator = np.random.choice(self.get_allowed_operations()) - wires = np.random.choice(list(range(self.n_qubits)), 2, replace=False) - feature = np.random.choice(list(range(self.n_features + 1))) - bandwidth = np.random.uniform(0.0, 1.0) - self.operation_list[i] = Operation(generator, wires, feature, bandwidth) - - def initialize_to_known_ansatz(self, ansatz): - """ - Initialize the ansatz form an already given element - :param ansatz: Given ansatz - :return: None - """ - self.initialize_to_identity() - for i in range(self.n_operations): - op: Operation = ansatz.operation_list[i] - self.change_operation(i, op.feature, op.wires, op.generator, op.bandwidth) - - def to_numpy(self): - """ - Serialize the ansatz to a numpy array - :return: numpy array - """ - return np.array([op.to_numpy() for op in self.operation_list]).ravel() - - @staticmethod - def from_numpy(array, n_features, n_qubits, n_operations, allow_midcircuit_measurement, shift_second_wire=False): - """ - Deserialize the ansatz from a numpy array - :param array: numpy array - :param n_features: number of feature that can be used to parametrize the operation - :param n_qubits: number of qubits of the circuit - :param n_operations: number of operations - :param allow_midcircuit_measurement: True if mid-circuit measurement are allowed - :return: Ansatz deserialized - """ - ans = Ansatz(n_features, n_qubits, n_operations, allow_midcircuit_measurement) - ans.initialize_to_identity() - for i in range(n_operations): - # feature -> wires -> generator -> bandwidth - generator = np.rint(array[i * 5]).astype(int) - wires = [np.rint(array[i * 5 + 1]).astype(int), np.rint(array[i * 5 + 2]).astype(int)] - feature = np.rint(array[i * 5 + 3]).astype(int) - bandwidth = np.round(array[i * 5 + 4], decimals=4) - if shift_second_wire and wires[1] >= wires[0]: - wires[1] += 1 - ans.change_operation(i, feature, wires, Operation.OPERATIONS[generator], bandwidth) - return ans - - def __str__(self): - return str(self.operation_list) - - def __repr__(self): - return self.__str__() \ No newline at end of file diff --git a/build/lib/quask/core/kernel.py b/build/lib/quask/core/kernel.py deleted file mode 100644 index aa30ef1..0000000 --- a/build/lib/quask/core/kernel.py +++ /dev/null @@ -1,133 +0,0 @@ -import numpy as np -from scipy.spatial.distance import cdist -from abc import ABC, abstractmethod -from . import Ansatz, KernelType, KernelFactory - - -class Kernel(ABC): - """ - Abstract class representing a kernel object - """ - - PAULIS = ['I', 'X', 'Y', 'Z'] - - def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType): - """ - Initialization. - - :param ansatz: Ansatz object representing the unitary transformation - :param measurement: Pauli string representing the measurement - :param type: type of kernel, fidelity or observable - """ - assert ansatz.n_qubits == len(measurement), "Measurement qubits and number of ansatz qubits do not match" - assert len(set(measurement).difference(Kernel.PAULIS)) == 0, "Unknown Pauli in measurement" - self.ansatz = ansatz - self.measurement = measurement - self.type = type - self.last_probabilities = None - - def get_last_probabilities(self): - """ - Get the last kernel value calculated. - - :return: last probability array - """ - return np.array(self.last_probabilities) - - @abstractmethod - def kappa(self, x1, x2) -> float: - """ - Calculate the kernel given two datapoints. - - :param x1: first data point - :param x2: second data point - :return: Kernel similarity between the two data points - """ - pass - - @abstractmethod - def phi(self, x) -> float: - """ - Calculate the feature map of a data point. - - :param x: data point - :return: feature map of the datapoint as numpy array - """ - pass - - def get_allowed_operations(self): - """ - Get the list of allowed operations. - - :return: list of generators allowed (the information is saved in the ansatz) - """ - return self.ansatz.get_allowed_operations() - - def build_kernel(self, X1: np.ndarray, X2: np.ndarray) -> np.ndarray: - """ - Build a kernel. - - :param X1: a single datapoint or a list of datapoints - :param X2: a single datapoint or a list of datapoints - :return: a single or a matrix of kernel inner products - """ - # if you gave me only one sample - if len(X1.shape) == 1 and len(X2.shape) == 1: - if self.type in [KernelType.FIDELITY, KernelType.SWAP_TEST]: - return self.kappa(X1, X2) - else: - return self.phi(X1) * self.phi(X2) - - # if you gave me multiple samples - assert self.ansatz.n_features == X1.shape[1], "Number of features and X1.shape[1] do not match" - assert self.ansatz.n_features == X2.shape[1], "Number of features and X2.shape[1] do not match" - if self.type in [KernelType.FIDELITY, KernelType.SWAP_TEST]: - return cdist(X1, X2, metric=self.kappa) - else: - n = X1.shape[0] - m = X2.shape[0] - Phi1 = np.array([self.phi(x) for x in X1]).reshape((n, 1)) - Phi2 = np.array([self.phi(x) for x in X2]).reshape((m, 1)) - return Phi1.dot(Phi2.T) - - def to_numpy(self): - """ - Serialize the kernel object as a numpy array. - - :return: numpy array - """ - ansatz_numpy = self.ansatz.to_numpy() - measurement_numpy = np.array([Kernel.PAULIS.index(p) for p in self.measurement]) - type_numpy = np.array([self.type.value]) - return np.concatenate([ansatz_numpy, measurement_numpy, type_numpy], dtype=object).ravel() - - @staticmethod - def from_numpy(array, n_features, n_qubits, n_operations, allow_midcircuit_measurement, shift_second_wire=False): - """ - Deserialize the object from a numpy array. - - :param array: numpy array - :param n_features: number of feature that can be used to parametrize the operation - :param n_qubits: number of qubits of the circuit - :param n_operations: number of operations - :param allow_midcircuit_measurement: True if mid-circuit measurement are allowed - :return: Kernel object (created using default instance in KernelFactory) - """ - assert len(array) == 5 * n_operations + n_qubits + 1, f"Size of the array is {len(array)} instead of {5 * n_operations + n_qubits + 1}" - ansatz_numpy = array[:n_operations*5] - measurement_numpy = array[n_operations*5:-1] - type_numpy = array[-1] - ansatz = Ansatz.from_numpy(ansatz_numpy, n_features, n_qubits, n_operations, allow_midcircuit_measurement, shift_second_wire) - measurement = "".join(Kernel.PAULIS[np.rint(i).astype(int)] for i in measurement_numpy) - the_type = KernelType.convert(type_numpy) - kernel = KernelFactory.create_kernel(ansatz, measurement, the_type) - return kernel - - def __str__(self): - return str(self.ansatz) + " -> " + self.measurement - - def __repr__(self): - return self.__str__() - - def __copy__(self): - return Kernel.from_numpy(self.to_numpy(), self.ansatz.n_features, self.ansatz.n_qubits, self.ansatz.n_operations, self.ansatz.allow_midcircuit_measurement) diff --git a/build/lib/quask/core/kernel_factory.py b/build/lib/quask/core/kernel_factory.py deleted file mode 100644 index 573aec9..0000000 --- a/build/lib/quask/core/kernel_factory.py +++ /dev/null @@ -1,50 +0,0 @@ -from . import Ansatz, KernelType - - -class KernelFactory: - """ - Instantiate the concrete object from classes that inherit from (abstract class) Kernel. - Implement the self-registering factory pattern - """ - - __implementations = {} - """Dictionary containing pairs (name, function to create the kernel).""" - - __current_implementation: str = "" - """Name of the implementation to use right now to create the kernels""" - - @staticmethod - def add_implementation(name, fn): - """ - Add the current closure function as one of the possible implementations available - - :param name: name of the implementation - :param fn: function that creates the quantum kernel - """ - if name in KernelFactory.__implementations: - raise ValueError("This name is already present in the register of available implementations") - if fn.__code__.co_argcount != 3: - raise ValueError("The function must have these three arguments, 'ansatz', 'measurement', and 'type': the number of argument does not match") - if fn.__code__.co_varnames != ('ansatz', 'measurement', 'type'): - raise ValueError("The function must have these three arguments, 'ansatz', 'measurement', and 'type': the name of some argument does not match") - KernelFactory.__implementations[name] = fn - - - @staticmethod - def set_current_implementation(name): - if name not in KernelFactory.__implementations: - raise ValueError("This name is not present in the register of available implementations") - KernelFactory.__current_implementation = name - - @staticmethod - def create_kernel(ansatz: Ansatz, measurement: str, type: KernelType): - """ - Create a kernel object using the default class chosen. - - :param ansatz: Ansatz object representing the unitary transformation - :param measurement: Pauli string representing the measurement - :param type: type of kernel, fidelity, swap test or observable - :return: kernel object of the default concrete class - """ - fn = KernelFactory.__implementations[KernelFactory.__current_implementation] - return fn(ansatz, measurement, type) \ No newline at end of file diff --git a/build/lib/quask/core/kernel_type.py b/build/lib/quask/core/kernel_type.py deleted file mode 100644 index 655f14c..0000000 --- a/build/lib/quask/core/kernel_type.py +++ /dev/null @@ -1,21 +0,0 @@ -from enum import Enum - - -class KernelType(Enum): - """ - Possible types of kernel - """ - FIDELITY = 0 - OBSERVABLE = 1 - SWAP_TEST = 2 - - @staticmethod - def convert(item): - if isinstance(item, KernelType): - return item - elif item < 0.5: - return KernelType.FIDELITY - elif 0.5 <= item < 1.5: - return KernelType.OBSERVABLE - else: - return KernelType.SWAP_TEST diff --git a/build/lib/quask/core/operation.py b/build/lib/quask/core/operation.py deleted file mode 100644 index 54caaf3..0000000 --- a/build/lib/quask/core/operation.py +++ /dev/null @@ -1,53 +0,0 @@ -import numpy as np -from typing import List -import itertools - - -class Operation: - """ - Class representing a 2-qubit rotational quantum gates $exp(-i \theta \sigma_1 \otimes \sigma_2)$ - """ - - PAULI_GENERATORS = list(a + b for a, b in itertools.product(["I", "X", "Y", "Z"], repeat=2)) - MEASUREMENT_OPERATIONS = ["IM", "MI"] - OPERATIONS = PAULI_GENERATORS + MEASUREMENT_OPERATIONS - - def __init__(self, generator: str, wires: List[int], feature: int, bandwidth: float): - """ - Operation initializer - :param generator: one of the elements of Operation.OPERATIONS - :param wires: pair of integers - :param feature: index of the feature parameterizing the element (can be -1 for constant feature '1') - :param bandwidth: bandwidth parameter in range [0,1] - """ - self.generator: str = generator - self.wires: List[int] = wires - self.feature: int = feature - self.bandwidth: float = bandwidth - - def to_numpy(self): - """ - Serialize the Operation object to a numpy array format - :return: numpy array representing the operation - """ - return np.array([Operation.OPERATIONS.index(self.generator), self.wires[0], self.wires[1], self.feature, self.bandwidth]) - - @staticmethod - def from_numpy(array): - """ - Deserialize the operation object given its numpy array description - :param array: numpy array - :return: Operation object - """ - op = Operation(None, None, None, None) - op.generator = Operation.OPERATIONS[int(array[0])] - op.wires = [int(array[1]), int(array[2])] - op.feature = int(array[3]) - op.bandwidth = float(array[4]) - return op - - def __str__(self): - return f"-i {self.bandwidth:0.2f} * x[{self.feature}] {self.generator}^({self.wires[0]},{self.wires[1]})" - - def __repr__(self): - return self.__str__() \ No newline at end of file diff --git a/build/lib/quask/core_implementation/__init__.py b/build/lib/quask/core_implementation/__init__.py deleted file mode 100644 index 3eafad0..0000000 --- a/build/lib/quask/core_implementation/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .pennylane_kernel import PennylaneKernel -from .qiskit_kernel import QiskitKernel -from .braket_kernel import BraketKernel -from .qibo_kernel import QiboKernel diff --git a/build/lib/quask/core_implementation/braket_kernel.py b/build/lib/quask/core_implementation/braket_kernel.py deleted file mode 100644 index 137bd28..0000000 --- a/build/lib/quask/core_implementation/braket_kernel.py +++ /dev/null @@ -1,32 +0,0 @@ -import numpy as np -import pennylane as qml -from ..core import Ansatz, Kernel, KernelType -from .pennylane_kernel import PennylaneKernel - - -class BraketKernel(PennylaneKernel): - - def create_device(self, n_qubits): - return qml.device( - "braket.aws.qubit", - device_arn=self.device_name, - s3_destination_folder=(self.s3_bucket, self.s3_prefix), - wires=n_qubits - ) - - def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType, - device_name: str, s3_bucket: str, s3_prefix: str, n_shots: int = None): - """ - Initialization. - - :param ansatz: Ansatz object representing the unitary transformation - :param measurement: Pauli string representing the measurement - :param type: type of kernel, fidelity or observable - :param device_name: name of the device, 'default.qubit' for noiseless simulation - :param n_shots: number of shots when sampling the solution, None to have infinity - """ - - super().__init__(ansatz, measurement, type, device_name, n_shots) - self.s3_bucket = s3_bucket - self.s3_prefix = s3_prefix - diff --git a/build/lib/quask/core_implementation/pennylane_kernel.py b/build/lib/quask/core_implementation/pennylane_kernel.py deleted file mode 100644 index 8db054c..0000000 --- a/build/lib/quask/core_implementation/pennylane_kernel.py +++ /dev/null @@ -1,113 +0,0 @@ -import numpy as np -import pennylane as qml -from ..core import Ansatz, Kernel, KernelType - - -def AnsatzTemplate(ansatz: Ansatz, params: np.ndarray, wires: np.ndarray): - for operation in ansatz.operation_list: - if "M" not in operation.generator: - feature = np.pi if operation.feature == ansatz.n_features else params[operation.feature] - qml.PauliRot(operation.bandwidth * feature, operation.generator, wires=wires[operation.wires]) - elif operation.generator[0] == "M": - qml.measure(wires[operation.wires[0]]) - else: - qml.measure(wires[operation.wires[1]]) - - -def ChangeBasis(measurement: str): - for i, pauli in enumerate(measurement): - if pauli == 'X': - qml.Hadamard(wires=[i]) - elif pauli == 'Y': - qml.S(wires=[i]) - qml.Hadamard(wires=[i]) - - -class PennylaneKernel(Kernel): - - def create_device(self, n_qubits): - return qml.device(self.device_name, wires=n_qubits, shots=self.n_shots) - - def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType, device_name: str = "default.qubit", n_shots: int = None): - """ - Initialization. - - :param ansatz: Ansatz object representing the unitary transformation - :param measurement: Pauli string representing the measurement - :param type: type of kernel, fidelity or observable - :param device_name: name of the device, 'default.qubit' for noiseless simulation - :param n_shots: number of shots when sampling the solution, None to have infinity - """ - - super().__init__(ansatz, measurement, type) - self.device_name = device_name - self.n_shots = n_shots - - dev = self.create_device(self.ansatz.n_qubits) - wires = np.array(list(range(self.ansatz.n_qubits))) - measurement_wires = np.array([i for i in wires if measurement[i] != 'I']) - if len(measurement_wires) == 0: - measurement_wires = range(self.ansatz.n_qubits) - - @qml.qnode(dev) - def fidelity_kernel(x1, x2): - AnsatzTemplate(self.ansatz, x1, wires=wires) - qml.adjoint(AnsatzTemplate)(self.ansatz, x2, wires=wires) - ChangeBasis(self.measurement) - return qml.probs(wires=measurement_wires) - - self.fidelity_kernel = fidelity_kernel - - @qml.qnode(dev) - def observable_phi(x): - AnsatzTemplate(self.ansatz, x, wires=wires) - ChangeBasis(self.measurement) - return qml.probs(wires=measurement_wires) - - self.observable_phi = observable_phi - - dev_swap = self.create_device(1+2*self.ansatz.n_qubits) - n = self.ansatz.n_qubits - - @qml.qnode(dev_swap) - def swap_kernel(x1, x2): - qml.Hadamard(wires=[0]) - AnsatzTemplate(self.ansatz, x1, wires=1+wires) - AnsatzTemplate(self.ansatz, x2, wires=1+n+wires) - for j in measurement_wires: - qml.CSWAP(wires=[0, 1+j, 1+n+j]) - qml.Hadamard(wires=[0]) - return qml.probs(wires=[0]) - - self.swap_kernel = swap_kernel - - def kappa(self, x1, x2) -> float: - if self.type == KernelType.OBSERVABLE: - return self.phi(x1) * self.phi(x2) - - elif self.type == KernelType.FIDELITY: - probabilities = self.fidelity_kernel(x1, x2) - self.last_probabilities = probabilities - return probabilities[0] - - elif self.type == KernelType.SWAP_TEST: - probabilities = self.swap_kernel(x1, x2) - self.last_probabilities = probabilities - return np.max([2 * probabilities[0] - 1, 0.0]) - - def phi(self, x) -> float: - if self.type == KernelType.OBSERVABLE: - probabilities = self.observable_phi(x) - self.last_probabilities = probabilities - parity = lambda i: 1 if bin(i).count('1') % 2 == 0 else -1 - probabilities = np.array([parity(i) * probabilities[i] for i in range(len(probabilities))]) - # sum_probabilities = np.sum(probabilities) - # print(f"{sum_probabilities=} {probabilities=}") - return np.sum(probabilities) - - elif self.type in [KernelType.FIDELITY, KernelType.SWAP_TEST]: - raise ValueError("phi not available for fidelity kernels") - - else: - raise ValueError("Unknown type, possible erroneous loading from a numpy array") - diff --git a/build/lib/quask/core_implementation/qibo_kernel.py b/build/lib/quask/core_implementation/qibo_kernel.py deleted file mode 100644 index a7daae4..0000000 --- a/build/lib/quask/core_implementation/qibo_kernel.py +++ /dev/null @@ -1,5 +0,0 @@ -import numpy as np -from ..core import Ansatz, Kernel, KernelType - -class QiboKernel(Kernel): - pass diff --git a/build/lib/quask/core_implementation/qiskit_kernel.py b/build/lib/quask/core_implementation/qiskit_kernel.py deleted file mode 100644 index 3e4cd0c..0000000 --- a/build/lib/quask/core_implementation/qiskit_kernel.py +++ /dev/null @@ -1,118 +0,0 @@ -import numpy as np -from ..core import Ansatz, Kernel, KernelType - -from qiskit import Aer, BasicAer, QuantumCircuit -from qiskit.circuit import ParameterVector -from qiskit.circuit.library import PauliEvolutionGate -from qiskit_ibm_runtime import QiskitRuntimeService -from qiskit.quantum_info import SparsePauliOp -from qiskit_ibm_runtime import Sampler as IbmSampler -from qiskit_ibm_runtime import Estimator as IbmEstimator -from qiskit_ibm_runtime import Options -from qiskit_aer.primitives import Sampler as AerSampler -from qiskit_aer.primitives import Estimator as AerEstimator - -class QiskitKernel(Kernel): - - def get_estimator(self): - if self.platform == "Aer": - return AerEstimator( - backend_options={"method": "statevector"}, - run_options={"shots": self.n_shots}) - else: - options = Options() - options.optimization_level = self.optimization_level - options.resilience_level = self.resilience_level - return IbmEstimator(backend=self.backend, options=self.options) - - def get_sampler(self): - if self.platform == "Aer": - return AerSampler( - backend_options={"method": "statevector"}, - run_options={"shots": self.n_shots}) - else: - options = Options() - options.optimization_level = self.optimization_level - options.resilience_level = self.resilience_level - return IbmSampler(backend=self.backend, options=self.options) - - def get_qiskit_ansatz(self): - n_params = self.ansatz.n_features + 1 - params = ParameterVector('p', n_params) - qc = QuantumCircuit(self.ansatz.n_qubits) - qc.rx(0.0*np.prod(params), 0) # fake instruction to include all parameters in the quantum circuit - for operation in self.ansatz.operation_list: - operator = SparsePauliOp(operation.generator) - rotation = operation.bandwidth*params[operation.feature] - evo = PauliEvolutionGate(operator, time=rotation) - qc.append(evo, operation.wires) - return qc - - def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType, - platform="Aer", backend="qasm_simulator", n_shots=2048, - optimization_level=2, resilience_level=2): - """ - Initialization. - - :param ansatz: Ansatz object representing the unitary transformation - :param measurement: Pauli string representing the measurement - :param type: type of kernel, fidelity or observable - :param device_name: name of the device, 'default.qubit' for noiseless simulation - :param n_shots: number of shots when sampling the solution, None to have infinity - """ - super().__init__(ansatz, measurement, type) - assert platform in ["Aer", "QiskitRuntimeService"] - self.platform = platform - self.backend_name = backend - self.n_shots = n_shots - self.optimization_level = optimization_level - self.resilience_level = resilience_level - - - def kappa(self, x1, x2) -> float: - assert len(x1) == self.ansatz.n_features - assert len(x2) == self.ansatz.n_features - - if self.type == KernelType.OBSERVABLE: - return self.phi(x1) * self.phi(x2) - - elif self.type == KernelType.FIDELITY: - qc = QuantumCircuit(self.ansatz.n_qubits, self.ansatz.n_qubits) - qc.append(self.get_qiskit_ansatz().bind_parameters(x1.tolist() + [1.0]), range(self.ansatz.n_qubits)) - qc.append(self.get_qiskit_ansatz().bind_parameters(x2.tolist() + [1.0]).inverse(), range(self.ansatz.n_qubits)) - qc.measure(range(self.ansatz.n_qubits), range(self.ansatz.n_qubits)) - job = self.get_sampler().run(qc) - probabilities = job.result().quasi_dists[0] - return probabilities.get(0, 0.0) - - elif self.type == KernelType.SWAP_TEST: - qc = QuantumCircuit(1+2*self.ansatz.n_qubits, 1) - qc.h(0) - qc.append(self.get_qiskit_ansatz().bind_parameters(x1.tolist() + [1.0]), range(1, 1+self.ansatz.n_qubits)) - qc.append(self.get_qiskit_ansatz().bind_parameters(x2.tolist() + [1.0]), range(self.ansatz.n_qubits)) - for i in range(self.ansatz.n_qubits): - qc.cswap(0, 1+i, 1+self.ansatz.n_qubits+i) - qc.h(0) - qc.measure(0, 0) - job = self.get_sampler().run(qc) - probabilities = job.result().quasi_dists[0] - return probabilities.get(0, 0.0) - - - def phi(self, x) -> float: - if self.type == KernelType.OBSERVABLE: - - assert len(x) == self.ansatz.n_features - complete_features = x.tolist() + [1.0] - circuit = self.get_qiskit_ansatz().bind_parameters(complete_features) - observable = SparsePauliOp(self.measurement) - job = self.get_estimator().run(circuit, observable) - exp_val = job.result().values[0] - return exp_val - - elif self.type in [KernelType.FIDELITY, KernelType.SWAP_TEST]: - raise ValueError("phi not available for fidelity kernels") - - else: - raise ValueError("Unknown type, possible erroneous loading from a numpy array") - diff --git a/build/lib/quask/evaluator/__init__.py b/build/lib/quask/evaluator/__init__.py deleted file mode 100644 index 5a19973..0000000 --- a/build/lib/quask/evaluator/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from .kernel_evaluator import KernelEvaluator -from .lie_rank_evaluator import LieRankEvaluator -from .haar_evaluator import HaarEvaluator -from .covering_number_evaluator import CoveringNumberEvaluator -from .kernel_alignment_evaluator import KernelAlignmentEvaluator -from .centered_kernel_alignment_evaluator import CenteredKernelAlignmentEvaluator -from .spectral_bias_evaluator import SpectralBiasEvaluator -from .ridge_generalization_evaluator import RidgeGeneralizationEvaluator -from .geometric_difference_evaluator import GeometricDifferenceEvaluator -from .ess_model_complexity_evaluator import EssModelComplexityEvaluator diff --git a/build/lib/quask/evaluator/centered_kernel_alignment_evaluator.py b/build/lib/quask/evaluator/centered_kernel_alignment_evaluator.py deleted file mode 100644 index 48448fa..0000000 --- a/build/lib/quask/evaluator/centered_kernel_alignment_evaluator.py +++ /dev/null @@ -1,38 +0,0 @@ -import numpy as np -from ..core import Kernel -from . import KernelEvaluator, KernelAlignmentEvaluator - - -class CenteredKernelAlignmentEvaluator(KernelEvaluator): - """ - Kernel compatibility measure based on the centered kernel-target alignment - See: Cortes, Corinna, Mehryar Mohri, and Afshin Rostamizadeh. "Algorithms for learning kernels based on centered alignment." - The Journal of Machine Learning Research 13.1 (2012): 795-828. - """ - - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - if K is None: - K = kernel.build_kernel(X, X) - Kc = CenteredKernelAlignmentEvaluator.center_kernel(K) - kta = KernelAlignmentEvaluator.kta(Kc, y) - return - np.abs(kta) - - @staticmethod - def center_kernel(K): - """ - Center a kernel (subtract its mean value) - :param K: kernel matrix - :return: centered kernel - """ - m = K.shape[0] - U = np.eye(m) - (1 / m) * np.outer([1] * m, [1] * m) - Kc = U @ K @ U.T - return Kc diff --git a/build/lib/quask/evaluator/covering_number_evaluator.py b/build/lib/quask/evaluator/covering_number_evaluator.py deleted file mode 100644 index ce155b2..0000000 --- a/build/lib/quask/evaluator/covering_number_evaluator.py +++ /dev/null @@ -1,24 +0,0 @@ -import numpy as np -from ..core import Kernel -from . import KernelEvaluator - - -class CoveringNumberEvaluator(KernelEvaluator): - """ - Expressibility measure based on the covering number associated with the hypothesis class related to the current ansatz. - See: Du, Yuxuan, et al. "Efficient measure for the expressivity of variational quantum algorithms." Physical Review Letters - 128.8 (2022): 080506. - """ - - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - operations = kernel.ansatz.operation_list - trainable_operations = [op for op in operations if op.feature >= 0] - return 2 ** trainable_operations diff --git a/build/lib/quask/evaluator/ess_model_complexity_evaluator.py b/build/lib/quask/evaluator/ess_model_complexity_evaluator.py deleted file mode 100644 index 545d78c..0000000 --- a/build/lib/quask/evaluator/ess_model_complexity_evaluator.py +++ /dev/null @@ -1,72 +0,0 @@ -import numpy as np -from scipy.linalg import sqrtm -from ..core import Kernel -from . import KernelEvaluator - - -def EssModelComplexityEvaluator(KernelEvaluator): - """ - Calculate the model complexity s(K). - See Equation F1 in "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938) - """ - - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - if K is None: - K = kernel.build_kernel(X, X) - - return calculate_model_complexity(K, y) - - def calculate_model_complexity(k, y, normalization_lambda=0.001): - """ - Calculate the model complexity s(K), which is equation F1 in - "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938). - - :param k: Kernel gram matrix - :param y: Labels - :param normalization_lambda: Normalization factor - :return: model complexity of the given kernel - """ - n = k.shape[0] - k_inv = np.linalg.inv(k + normalization_lambda * np.eye(n)) - k_body = k_inv @ k @ k_inv - model_complexity = y.T @ k_body @ y - return model_complexity - - def calculate_model_complexity_training(k, y, normalization_lambda=0.001): - """ - Subprocedure of the function 'calculate_model_complexity_generalized'. - - :param k: Kernel gram matrix - :param y: Labels - :param normalization_lambda: Normalization factor - :return: model complexity of the given kernel - """ - n = k.shape[0] - k_inv = np.linalg.inv(k + normalization_lambda * np.eye(n)) - k_mid = k_inv @ k_inv # without k in the middle - model_complexity = (normalization_lambda**2) * (y.T @ k_mid @ y) - return model_complexity - - def calculate_model_complexity_generalized(k, y, normalization_lambda=0.001): - """ - Calculate the model complexity s(K), which is equation M1 in - "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938). - - :param k: Kernel gram matrix - :param y: Labels - :param normalization_lambda: Normalization factor - :return: model complexity of the given kernel - """ - n = k.shape[0] - a = np.sqrt(calculate_model_complexity_training(k, y, normalization_lambda) / n) - b = np.sqrt(calculate_model_complexity(k, y, normalization_lambda) / n) - return a + b diff --git a/build/lib/quask/evaluator/geometric_difference_evaluator.py b/build/lib/quask/evaluator/geometric_difference_evaluator.py deleted file mode 100644 index 8aca8a4..0000000 --- a/build/lib/quask/evaluator/geometric_difference_evaluator.py +++ /dev/null @@ -1,67 +0,0 @@ -import numpy as np -from scipy.linalg import sqrtm -from ..core import Kernel -from . import KernelEvaluator - - -class GeometricDifferenceEvaluator(KernelEvaluator): - """ - Calculate the geometric difference g(K_1 || K_2), and characterize - the separation between classical and quantum kernels. - See Equation F9 in "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938) - """ - - def __init__(self, list_classical_kernel_matrices, lam): - """ - Initialization. - - :param list_classical_kernel_matrices: List of kernel matrices obtained with classical kernels - :param lam: normalization constant lambda - """ - super().__init__() - self.list_classical_kernel_matrices = list_classical_kernel_matrices - self.lam = lam - - - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - if K is None: - K = kernel.build_kernel(X, X) - - geometric_differences = [GeometricDifferenceEvaluator.g(K, Kc, self.lam) - for Kc in self.list_classical_kernel_matrices] - - return -1 * np.min(geometric_differences) - - @staticmethod - def g(k_1, k_2, lam): - """ - Method to calculate the geometric difference - - :param k_1: first matrix (quantum usually) - :param k_2: second matrix (classical usually) - :param lam: normalization lambda - :return: value of g(K_1, K_2) - """ - n = k_2.shape[0] - assert k_2.shape == (n, n) - assert k_1.shape == (n, n) - # √K1 - k_1_sqrt = np.real(sqrtm(k_1)) - # √K2 - k_2_sqrt = np.real(sqrtm(k_2)) - # √(K2 + lambda I)^-2 - kc_inv = np.linalg.inv(k_2 + lam * np.eye(n)) - kc_inv = kc_inv @ kc_inv - # Equation F9 - f9_body = k_1_sqrt.dot(k_2_sqrt.dot(kc_inv.dot(k_2_sqrt.dot(k_1_sqrt)))) - f9 = np.sqrt(np.linalg.norm(f9_body, np.inf)) - return f9 diff --git a/build/lib/quask/evaluator/haar_evaluator.py b/build/lib/quask/evaluator/haar_evaluator.py deleted file mode 100644 index fc0e991..0000000 --- a/build/lib/quask/evaluator/haar_evaluator.py +++ /dev/null @@ -1,73 +0,0 @@ -import numpy as np -from ..core import Kernel -from . import KernelEvaluator - - -class HaarEvaluator(KernelEvaluator): - """ - Expressibility measure based on the comparison between the distribution of states obtained with an Haar random circuit and - the one obtained with the current ansatz. - See: Sim, Sukin, Peter D. Johnson, and Alán Aspuru-Guzik. "Expressibility and entangling capability of parameterized quantum - circuits for hybrid quantum-classical algorithms." Advanced Quantum Technologies 2.12 (2019): 1900070. - """ - - def __init__(self, n_bins: int, n_samples: int): - """ - Initialization - :param n_bins: number of discretization buckets - :param n_samples: number of samples approximating the distribution of values - """ - self.n_bins = n_bins - self.n_samples = n_samples - - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - haar_histogram = HaarEvaluator.haar_histogram(kernel, self.n_bins) - ansatz_histogram = HaarEvaluator.ansatz_histogram(kernel, self.n_bins, self.n_samples) - self.last_result = (haar_histogram, ansatz_histogram) - return np.linalg.norm(haar_histogram - ansatz_histogram) - - @staticmethod - def ansatz_histogram(kernel, n_bins, n_samples): - """ - Create a histogram of the fidelities of the ansatz - :param kernel: kernel object - :param n_bins: number of discretization buckets - :param n_samples: number of samples approximating the distribution of values - :return: histogram of the given ansatz - """ - histogram = [0] * n_bins - - for _ in range(n_samples): - theta_1 = np.random.normal(size=(kernel.ansatz.n_features,)) * np.pi - theta_2 = np.random.normal(size=(kernel.ansatz.n_features,)) * np.pi - fidelity = kernel.kappa(theta_1, theta_2) - index = int(fidelity * n_bins) - histogram[np.minimum(index, n_bins - 1)] += 1 - - return np.array(histogram) / n_samples - - @staticmethod - def haar_histogram(kernel, n_bins): - """ - Create a histogram of the Haar random fidelities - :param n_bins: number of bins - :return: histogram - """ - N = 2 ** kernel.ansatz.n_qubits - - def prob(low, high): - return (1-low) ** (N - 1) - (1 - high) ** (N - 1) - - histogram = np.array([prob(i / n_bins, (i+1) / n_bins) for i in range(n_bins)]) - return histogram - - def __str__(self): - return "A = " + self.last_result[0] + " - " + self.last_result[1] diff --git a/build/lib/quask/evaluator/kernel_alignment_evaluator.py b/build/lib/quask/evaluator/kernel_alignment_evaluator.py deleted file mode 100644 index 3abe93a..0000000 --- a/build/lib/quask/evaluator/kernel_alignment_evaluator.py +++ /dev/null @@ -1,36 +0,0 @@ -import numpy as np -from ..core import Kernel -from . import KernelEvaluator - - -class KernelAlignmentEvaluator(KernelEvaluator): - """ - Kernel compatibility measure based on the kernel-target alignment - See: Cristianini, Nello, et al. "On kernel-target alignment." Advances in neural information processing systems 14 (2001). - """ - - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - if K is None: - K = kernel.build_kernel(X, X) - the_cost = -1 * np.abs(KernelAlignmentEvaluator.kta(K, y)) - # assert not np.isnan(the_cost), f"{kernel=} {K=} {y=}" - return the_cost if not np.isnan(the_cost) else 1000 - - @staticmethod - def kta(K, y): - """ - Calculates the kernel target alignment - :param K: kernel matrix - :param y: label vector - :return: kernel target alignment - """ - Y = np.outer(y, y) - return np.sum(K * Y) / (np.linalg.norm(K) * np.linalg.norm(Y)) diff --git a/build/lib/quask/evaluator/kernel_evaluator.py b/build/lib/quask/evaluator/kernel_evaluator.py deleted file mode 100644 index 2ea922d..0000000 --- a/build/lib/quask/evaluator/kernel_evaluator.py +++ /dev/null @@ -1,21 +0,0 @@ -import numpy as np -from abc import ABC, abstractmethod -from ..core import Kernel - - -class KernelEvaluator(ABC): - - def __init__(self): - self.last_result = None - - @abstractmethod - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - pass diff --git a/build/lib/quask/evaluator/lie_rank_evaluator.py b/build/lib/quask/evaluator/lie_rank_evaluator.py deleted file mode 100644 index d8db4eb..0000000 --- a/build/lib/quask/evaluator/lie_rank_evaluator.py +++ /dev/null @@ -1,116 +0,0 @@ -import copy -import numpy as np -from typing import Set -from ..core import Kernel -from . import KernelEvaluator - - -class LieRankEvaluator(KernelEvaluator): - """ - Expressibility and 'Efficient classical simulability' measure based on the rank of the Lie algebra obtained by spanning - the generators of the circuits. - See: Larocca, Martin, et al. "Diagnosing barren plateaus with tools from quantum optimal control." Quantum 6 (2022): 824. - """ - - def __init__(self, T): - """ - Initializer - :param T: threshold T > 0 telling how is the minimum dimension of a 'hard-to-simulate' Lie algebra - """ - super().__init__() - self.T = T - - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - self.last_result = self.braket_generators(kernel, self.T) - return -len(self.last_result) - - def braket_pair(self, a: str, b: str): - """ - Calculate the commutator between two pauli matrices - :param a: first Pauli (one of the strings 'I', 'X', 'Y', 'Z') - :param b: second Pauli (one of the strings 'I', 'X', 'Y', 'Z') - :return: [a, b] - """ - assert a in ['I', 'X', 'Y', 'Z'] and b in ['I', 'X', 'Y', 'Z'] - if a == b: return 'I' - if a == 'I': return b - if b == 'I': return a - return list(set(['X', 'Y', 'Z']).difference([a, b]))[0] - - def braket_strings(self, s1: str, s2: str): - """ - Calculate the communtator between two pauli strings - :param s1: first Pauli string - :param s2: second Pauli string - :return: [s1, s2] - """ - assert len(s1) == len(s2), "Tha Pauli strings have different lengths" - return [self.braket_pair(a, b) for (a, b) in zip(s1, s2)] - - def __braket_generators(self, initial_generators: Set[str], new_generators: Set[str]): - """ - Return the set of generators obtained by commutating pairwise the elements in the given set - :param initial_generators: first set of generators - :param new_generators: second set of generators - :return: generators obtained with the pairwise commutation of the given elements (only new ones) - """ - out_generators = [] - for gen_new in new_generators: - for gen_old in initial_generators: - braket = "".join(self.braket_strings(gen_new, gen_old)) - if braket not in initial_generators and braket not in new_generators: - out_generators.append(braket) - return set(out_generators) - - def get_initial_generators(self, kernel): - """ - Create the initial generators of a kernel, i.e. for each operation apply the generator to the correct wires - and identity everywhere else - :param kernel: kernel object - :return set of initial generators corresponding to the operations of the kernel - """ - # get the generators of each operation - generators = [kernel.ansatz.operation_list[i].generator for i in range(kernel.ansatz.n_operations)] - # get the wires on which each operation acts - wires = [kernel.ansatz.operation_list[i].wires for i in range(kernel.ansatz.n_operations)] - initial_generators = [] - for i in range(kernel.ansatz.n_operations): - # initialize each generator with identity everyone, as list of char and not as string (the latter is immutable) - initial_generator = ['I'] * kernel.ansatz.n_qubits - # assign the generator to each qubit - q0, q1 = wires[i][0], wires[i][1] - g0, g1 = generators[i][0], generators[i][1] - initial_generator[q0] = g0 - initial_generator[q1] = g1 - # convert the list of char to string, now - initial_generator = "".join(initial_generator) - # print(f"{i=} {q0=} {q1=} {g0=} {g1=} {initial_generator=}") - initial_generators.append(initial_generator) - # print(f"{initial_generators}") - return set(initial_generators) - - def braket_generators(self, kernel, T): - """ - Return the basis of the lie algebra of the circuit defined by the kernel. The number of elements is truncated at T - :param kernel: kernel object - :param T: threshold - :return: basis of the lie algebra of the generators in kernel - """ - initial_generators = self.get_initial_generators(kernel) - new_generators = copy.deepcopy(initial_generators) - all_generators = copy.deepcopy(initial_generators) - while len(all_generators) < T and len(new_generators) > 0: - new_generators = self.__braket_generators(all_generators, new_generators) - all_generators = all_generators.union(new_generators) - return all_generators - - def __str__(self): - return str(self.last_result) diff --git a/build/lib/quask/evaluator/ridge_generalization_evaluator.py b/build/lib/quask/evaluator/ridge_generalization_evaluator.py deleted file mode 100644 index ba793ab..0000000 --- a/build/lib/quask/evaluator/ridge_generalization_evaluator.py +++ /dev/null @@ -1,34 +0,0 @@ -import numpy as np -from sklearn.kernel_ridge import KernelRidge -from ..core import Kernel -from . import KernelEvaluator - - -class RidgeGeneralizationEvaluator(KernelEvaluator): - """ - Evaluates the generalization error of the given kernel - """ - - def __init__(self): - """ - Initialization - """ - pass - - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - n_train = len(y) // 2 - n_test = len(y) - n_train - krr = KernelRidge(kernel=lambda X1, X2: kernel.build_kernel(X1, X2)) - krr.fit(X[:n_train], y[:n_train]) - y_pred = np.array(krr.predict(X[n_train:])) - mse = np.linalg.norm(y_pred - y[n_train:]) / n_test - return mse - diff --git a/build/lib/quask/evaluator/spectral_bias_evaluator.py b/build/lib/quask/evaluator/spectral_bias_evaluator.py deleted file mode 100644 index 7918372..0000000 --- a/build/lib/quask/evaluator/spectral_bias_evaluator.py +++ /dev/null @@ -1,102 +0,0 @@ -import numpy as np -from scipy.linalg import eigh -from ..core import Kernel -from . import KernelEvaluator - - -class SpectralBiasEvaluator(KernelEvaluator): - """ - Kernel compatibility measure based on the spectral bias framework. - See: Canatar, Abdulkadir, Blake Bordelon, and Cengiz Pehlevan. "Spectral bias and task-model alignment explain generalization - in kernel regression and infinitely wide neural networks." Nature communications 12.1 (2021): 2914. - """ - - def __init__(self, n_eigenvalues_cut): - """ - Initialization - :param n_eigenvalues_cut: number of eigenvalues contributing to the cumulative power - """ - self.n_eigenvalues_cut = n_eigenvalues_cut - - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - :param kernel: kernel object - :param K: optional kernel matrix \kappa(X, X) - :param X: datapoints - :param y: labels - :return: cost of the kernel, the lower the better - """ - if K is None: - K = kernel.build_kernel(X, X) - Lambda, Phi = SpectralBiasEvaluator.decompose_kernel(K) - w, a = SpectralBiasEvaluator.calculate_weights(Lambda, Phi, y) - C, powers = SpectralBiasEvaluator.cumulative_power_distribution(w, Lambda, self.n_eigenvalues_cut) - self.last_result = (Lambda, Phi, w, a, C, powers) - return C - - - @staticmethod - def decompose_kernel(K, eigenvalue_descending_order=True, eigenvalue_removal_threshold=1e-12): - """ - Decompose the kernel matrix K in its eigenvalues Λ and eigenvectors Φ - :param K: kernel matrix, real and symmetric - :param eigenvalue_descending_order: if True, the biggest eigenvalue is the first one - :return: Lambda vector (n elements) and Phi matrix (N*N matrix) - """ - Lambda, Phi = eigh(K) - - # set the desired order for the eigenvalues - if eigenvalue_descending_order: - Lambda = Lambda[::-1] - Phi = Phi[:, ::-1] - - # kernel matrix is positive definite, any (small) negative eigenvalue is effectively a numerical error - Lambda[Lambda < 0] = 0 - - # remove the smallest positive eigenvalues, as they are useless - Lambda[Lambda < eigenvalue_removal_threshold] = 0 - - return Lambda, Phi - - @staticmethod - def calculate_weights(Lambda, Phi, labels): - """ - Calculates the weights of a predictor given the labels and the kernel eigendecomposition, - as shown in (Canatar et al 2021, inline formula below equation 18). - :param Lambda: vectors of m nonnegative eigenvalues 'eta' - :param Phi: vectors of m nonnegative eigenvectors 'phi' - :param labels: vector of m labels corresponding to 'm' ground truth labels or predictor outputs - :return: vector w of RKHS weights, vector a of out-of-RKHS weights - """ - # get the number of training elements - m = Lambda.shape[0] - - # invert nonzero eigenvalues - inv_eigenvalues = np.reciprocal(Lambda, where=Lambda > 0) - - # weight vectors are calculated by inverting formula: y = \sum_k=1^M w_k \sqrt{lambda_k} \phi_k(x) - the_w = (1 / m) * np.diag(inv_eigenvalues ** 0.5) @ Phi.T @ labels - the_w[Lambda == 0] = 0 - - # weight vector for the components out-of-RKHS - the_a = (1 / m) * Phi.T @ labels - the_a[Lambda > 0] = 0 - return the_w, the_a - - @staticmethod - def cumulative_power_distribution(w, Lambda, n_eigenvalues): - """ - - :param w: vector of weights - :param Lambda: vector of eigenvalues - :param n_eigenvalues: number of eigenvalues contributing to the cumulative power - :return: - """ - powers = np.diag(Lambda) @ (w ** 2) - return np.sum(powers[:n_eigenvalues]) / np.sum(powers), powers - - def __str__(self): - (Lambda, Phi, w, a, C, powers) = self.last_result - return f"""{Lambda=} {Phi=} {w=} {a=} {C=} {powers=}""" - diff --git a/build/lib/quask/optimizer/__init__.py b/build/lib/quask/optimizer/__init__.py deleted file mode 100644 index 407bf28..0000000 --- a/build/lib/quask/optimizer/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from .base_kernel_optimizer import BaseKernelOptimizer -from .wide_kernel_environment import WideKernelEnvironment -from .metaheuristic_optimizer import MetaheuristicOptimizer -from .reinforcement_learning_optimizer import ReinforcementLearningOptimizer -from .greedy_optimizer import GreedyOptimizer -from .bayesian_optimizer import BayesianOptimizer diff --git a/build/lib/quask/optimizer/base_kernel_optimizer.py b/build/lib/quask/optimizer/base_kernel_optimizer.py deleted file mode 100644 index a251780..0000000 --- a/build/lib/quask/optimizer/base_kernel_optimizer.py +++ /dev/null @@ -1,32 +0,0 @@ -from abc import ABC, abstractmethod -import numpy as np -import copy -from ..core import Operation, Ansatz, Kernel, KernelFactory -from ..evaluator import KernelEvaluator - - -class BaseKernelOptimizer(ABC): - """ - Abstract class implementing a procedure to optimize the kernel - """ - - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): - """ - Initialization - :param initial_kernel: initial kernel object - :param X: datapoints - :param y: labels - :param ke: kernel evaluator object - """ - self.initial_kernel = initial_kernel - self.X = X - self.y = y - self.ke = ke - - @abstractmethod - def optimize(self): - """ - Run the optimization - :return: optimized kernel object - """ - pass diff --git a/build/lib/quask/optimizer/bayesian_optimizer.py b/build/lib/quask/optimizer/bayesian_optimizer.py deleted file mode 100644 index b24a445..0000000 --- a/build/lib/quask/optimizer/bayesian_optimizer.py +++ /dev/null @@ -1,73 +0,0 @@ -import numpy as np -from joblib import Parallel, delayed -from skopt import Optimizer -from skopt.space import Real, Categorical - -from ..core import Operation, Ansatz, Kernel, KernelFactory -from ..evaluator import KernelEvaluator -from . import BaseKernelOptimizer - - -class BayesianOptimizer(BaseKernelOptimizer): - - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): - super().__init__(initial_kernel, X, y, ke) - self.optimizer = None - - def get_sklearn_dimensions(self): - n_features = self.initial_kernel.ansatz.n_features - n_operations = self.initial_kernel.ansatz.n_operations - n_qubits = self.initial_kernel.ansatz.n_qubits - allowed_generators = self.initial_kernel.get_allowed_operations() - ansatz_dimension = [ - # generator - Categorical(list(range(len(allowed_generators)))), - # wires - Categorical(list(range(n_qubits))), - Categorical(list(range(n_qubits - 1))), - # features - Categorical(list(range(n_features))), - # bandwidth - Real(0.0, 1.0), - ] * n_operations - measurement_dimensions = [Categorical([0, 1, 2, 3])] * n_qubits - return ansatz_dimension + measurement_dimensions - - def get_kernel(self, the_array): - the_array = np.array(the_array, dtype=object) - the_kernel = Kernel.from_numpy(np.concatenate([the_array.ravel(), np.array([self.initial_kernel.type])]), - self.initial_kernel.ansatz.n_features, - self.initial_kernel.ansatz.n_qubits, - self.initial_kernel.ansatz.n_operations, - self.initial_kernel.ansatz.allow_midcircuit_measurement, - shift_second_wire=True) - return the_kernel - - def get_cost(self, the_array): - the_kernel = self.get_kernel(the_array) - the_cost = self.ke.evaluate(the_kernel, None, self.X, self.y) - return the_cost - - def optimize(self, n_epochs=20, n_points=4, n_jobs=4): - - self.optimizer = Optimizer( - dimensions=self.get_sklearn_dimensions(), - random_state=1, - base_estimator='gp', - acq_func="PI", - acq_optimizer="sampling", - acq_func_kwargs={"xi": 10000.0, "kappa": 10000.0} - ) - - for i in range(n_epochs): - x = self.optimizer.ask(n_points=n_points) # x is a list of n_points points - y = Parallel(n_jobs=n_jobs)(delayed(lambda array: self.get_cost(array))(v) for v in x) # evaluate points in parallel - self.optimizer.tell(x, y) - print(f"Epoch of training {i=}") - - min_index = np.argmin(self.optimizer.yi) - # min_cost = self.optimizer.yi[min_index] - min_solution = self.optimizer.Xi[min_index] - - best_kernel = self.get_kernel(min_solution) - return best_kernel diff --git a/build/lib/quask/optimizer/greedy_optimizer.py b/build/lib/quask/optimizer/greedy_optimizer.py deleted file mode 100644 index c552cfb..0000000 --- a/build/lib/quask/optimizer/greedy_optimizer.py +++ /dev/null @@ -1,50 +0,0 @@ -import copy - -import numpy as np -from mushroom_rl.core import Environment - -from ..core import Kernel -from ..evaluator import KernelEvaluator -from . import BaseKernelOptimizer, WideKernelEnvironment - - -class GreedyOptimizer(BaseKernelOptimizer): - - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): - super().__init__(initial_kernel, X, y, ke) - self.mdp: WideKernelEnvironment = Environment.make('WideKernelEnvironment', initial_kernel=self.initial_kernel, X=X, y=y, ke=ke) - self.rewards_history = [] - self.actions_history = [] - - def optimize(self, verbose=False): - - self.mdp.reset() - state = copy.deepcopy(self.mdp._state) - - terminated = False - n_actions = self.mdp._mdp_info.action_space.size[0] - rewards = np.zeros(shape=(n_actions,)) - - while not terminated: - # list all actions at the first depth - for action in range(n_actions): - self.mdp.reset(state) - new_state, reward, absorbed, _ = self.mdp.step((action,)) - rewards[action] = reward - _, kernel = self.mdp.deserialize_state(new_state) - if absorbed: - terminated = True - print(f"{action=:4d} {reward=:0.6f} {kernel=}") - # apply chosen action - chosen_action = np.argmax(rewards) - self.mdp.reset(state) - state, _, _, _ = self.mdp.step((chosen_action,)) - if verbose: - print(f"Chosen action: {chosen_action}") - print(f"{self.mdp.deserialize_state(state)=}") - # additional information - self.rewards_history.append(rewards) - self.actions_history.append(chosen_action) - - _, kernel = self.mdp.deserialize_state(state) - return kernel diff --git a/build/lib/quask/optimizer/metaheuristic_optimizer.py b/build/lib/quask/optimizer/metaheuristic_optimizer.py deleted file mode 100644 index e902ea7..0000000 --- a/build/lib/quask/optimizer/metaheuristic_optimizer.py +++ /dev/null @@ -1,122 +0,0 @@ -import copy -import numpy as np -from enum import Enum - -from opytimizer import Opytimizer -from opytimizer.core import Function -from opytimizer.optimizers.swarm import PSO -from opytimizer.spaces import GridSpace -from opytimizer.utils.callback import Callback -from ..core import Kernel -from ..evaluator import KernelEvaluator -from . import BaseKernelOptimizer - - -class CustomCallback(Callback): - """A CustomCallback can be created by override its parent `Callback` class - and by implementing the desired logic in its available methods. - """ - - def __init__(self): - """Initialization method for the customized callback.""" - - # You only need to override its parent class - super(CustomCallback).__init__() - - def on_task_begin(self, opt_model): - """Called at the beginning of an task.""" - print("Task begin") - - def on_task_end(self, opt_model): - """Called at the end of an task.""" - print("Task end") - - def on_iteration_begin(self, iteration, opt_model): - """Called at the beginning of an iteration.""" - print(f"Iteration {iteration} begin") - - def on_iteration_end(self, iteration, opt_model): - """Called at the end of an iteration.""" - print(f"Iteration {iteration} end") - - def on_evaluate_before(self, *evaluate_args): - """Called before the `evaluate` method.""" - print(f"Evaluate before {evaluate_args}") - - def on_evaluate_after(self, *evaluate_args): - """Called after the `evaluate` method.""" - print(f"Evaluate after {evaluate_args}") - - def on_update_before(self, *update_args): - """Called before the `update` method.""" - print(f"Update before {update_args}") - - def on_update_after(self, *update_args): - """Called after the `update` method.""" - print(f"Update after {update_args}") - - -class MetaheuristicType(Enum): - - # evolutionary - FOREST_OPTIMIZATION = 1 - GENERIC_ALGORITHM = 2 - # population - EMPEROR_PENGUIN_OPTIMIZER = 3 - # swarm - PARTICLE_SWARM_OPTIMIZATION = 0 - - -class MetaheuristicOptimizer(BaseKernelOptimizer): - - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): - super().__init__(initial_kernel, X, y, ke) - - def cost(array): - array = array.ravel() - the_array = np.concatenate([array, np.array([initial_kernel.type])]) - # create kernel - the_kernel = Kernel.from_numpy(the_array, - initial_kernel.ansatz.n_features, - initial_kernel.ansatz.n_qubits, - initial_kernel.ansatz.n_operations, - initial_kernel.ansatz.allow_midcircuit_measurement, - shift_second_wire=True) - the_cost = ke.evaluate(the_kernel, None, X, y) - print(f"MetaheuristicOptimizer.cost -> {the_cost: 5.5f} -> {array}") - return the_cost - - self.space = self.get_opytimize_space() - self.optimizer = PSO() - self.cost = cost - self.function = Function(cost) - self.opt = Opytimizer(self.space, self.optimizer, self.function, save_agents=True) - self.history = None - self.best_solution = None - self.best_cost = None - - def optimize(self, n_iterations=1000, verbose=False): - self.opt.start(n_iterations=n_iterations, callbacks=[CustomCallback()] if verbose else []) - self.history = self.opt.history - data_at_convergence = self.history.get_convergence("best_agent") - self.best_solution = data_at_convergence[0].ravel() - self.best_cost = data_at_convergence[1].ravel() - the_array = np.concatenate([self.best_solution, np.array([self.initial_kernel.type])]) - return Kernel.from_numpy(the_array, - self.initial_kernel.ansatz.n_features, - self.initial_kernel.ansatz.n_qubits, - self.initial_kernel.ansatz.n_operations, - self.initial_kernel.ansatz.allow_midcircuit_measurement, - shift_second_wire=True) - - def get_opytimize_space(self): - n_features = self.initial_kernel.ansatz.n_features - n_operations = self.initial_kernel.ansatz.n_operations - n_qubits = self.initial_kernel.ansatz.n_qubits - allowed_generators = self.initial_kernel.get_allowed_operations() - - n_variables = 5 * n_operations + n_qubits - step = [1, 1, 1, 1, 0.2] * n_operations + [1] * n_qubits - lower_bound = [0, 0, 0, 0, 0.2] * n_operations + [0] * n_qubits - upper_bound = [len(allowed_generators) - 1, n_qubits - 1, n_qubits - 2, n_features, 1.0] * n_operations + [3] * n_qubits - return GridSpace(n_variables, step, lower_bound, upper_bound) diff --git a/build/lib/quask/optimizer/reinforcement_learning_optimizer.py b/build/lib/quask/optimizer/reinforcement_learning_optimizer.py deleted file mode 100644 index 636692e..0000000 --- a/build/lib/quask/optimizer/reinforcement_learning_optimizer.py +++ /dev/null @@ -1,82 +0,0 @@ -import numpy as np -import copy -from ..core import Operation, Ansatz, Kernel, KernelFactory -from ..evaluator import KernelEvaluator -from . import BaseKernelOptimizer - - -class ReinforcementLearningOptimizer(BaseKernelOptimizer): - """ - Reinforcement learning based technique for optimize a kernel function - """ - - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): - """ - Initialization - :param initial_kernel: initial kernel object - :param X: datapoints - :param y: labels - :param ke: kernel evaluator object - """ - from mushroom_rl.core import Environment - from mushroom_rl.core import Core - from mushroom_rl.algorithms.value import SARSALambda - from mushroom_rl.policy import EpsGreedy - from mushroom_rl.utils.parameters import Parameter - from mushroom_rl.utils.dataset import compute_J - self.initial_kernel = copy.deepcopy(initial_kernel) - self.X = X - self.y = y - self.ke = ke - self.mdp = Environment.make('WideKernelEnvironment', initial_kernel=self.initial_kernel, X=X, y=y, ke=ke) - self.agent = None - self.core = None - - def optimize(self, initial_episodes=3, n_episodes=100, n_steps_per_fit=1, final_episodes=3): - """ - Optimization routine - :param initial_episodes: - :param n_steps: - :param n_steps_per_fit: - :param final_episodes: - :return: - """ - from mushroom_rl.core import Environment - from mushroom_rl.core import Core - from mushroom_rl.algorithms.value import SARSALambda - from mushroom_rl.policy import EpsGreedy - from mushroom_rl.utils.parameters import Parameter - from mushroom_rl.utils.dataset import compute_J - # Policy - epsilon = Parameter(value=1.) - pi = EpsGreedy(epsilon=epsilon) - learning_rate = Parameter(.1) - - # Agent - self.agent = SARSALambda(self.mdp.info, pi, - learning_rate=learning_rate, - lambda_coeff=.9) - - # Reinforcement learning experiment - self.core = Core(self.agent, self.mdp) - - # Visualize initial policy for 3 episodes - dataset = self.core.evaluate(n_episodes=initial_episodes, render=True) - print(f"{dataset=}") - - # Print the average objective value before learning - J = np.mean(compute_J(dataset, self.mdp.info.gamma)) - print(f'Objective function before learning: {J}') - - # Train - self.core.learn(n_episodes=n_episodes, n_steps_per_fit=n_steps_per_fit, render=True) - - # Visualize results for 3 episodes - dataset = self.core.evaluate(n_episodes=final_episodes, render=True) - - # Print the average objective value after learning - J = np.mean(compute_J(dataset, self.mdp.info.gamma)) - print(f'Objective function after learning: {J}') - - kernel = Kernel.from_numpy(self.mdp._state[1:], self.mdp.n_features, self.mdp.n_qubits, self.mdp.n_operations, self.mdp.allow_midcircuit_measurement) - return kernel diff --git a/build/lib/quask/optimizer/wide_kernel_environment.py b/build/lib/quask/optimizer/wide_kernel_environment.py deleted file mode 100644 index b6a9468..0000000 --- a/build/lib/quask/optimizer/wide_kernel_environment.py +++ /dev/null @@ -1,153 +0,0 @@ -import numpy as np -from mushroom_rl.core import Environment, MDPInfo -from mushroom_rl.utils.spaces import Discrete -from ..core import Operation, Ansatz, Kernel, KernelFactory -from ..evaluator import KernelEvaluator - - -class WideKernelEnvironment(Environment): - """ - Implementation of a Mushroom-RL Environment for our problem - """ - - @staticmethod - def setup(): - WideKernelEnvironment.register() - - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): - """ - Initialization - :param initial_kernel: initial kernel object - :param X: datapoints - :param y: labels - :param ke: kernel evaluator object - """ - self.initial_kernel = initial_kernel - self.n_operations = self.initial_kernel.ansatz.n_operations - self.n_features = self.initial_kernel.ansatz.n_features - self.n_qubits = self.initial_kernel.ansatz.n_qubits - self.allow_midcircuit_measurement = self.initial_kernel.ansatz.allow_midcircuit_measurement - self.X = X - self.y = y - self.ke = ke - self.last_reward = None - - # Create the action space. - action_space = Discrete( - len(self.initial_kernel.get_allowed_operations()) - * self.n_qubits - * (self.n_qubits - 1) - * (self.n_features + 1) - ) - - # Create the observation space. - observation_space = Discrete( - len(self.initial_kernel.get_allowed_operations()) - * self.n_qubits - * (self.n_qubits - 1) - * (self.n_features + 1) - * self.n_operations - ) - - # Create the MDPInfo structure, needed by the environment interface - mdp_info = MDPInfo(observation_space, action_space, gamma=0.99, horizon=100) - super().__init__(mdp_info) - - # Create a state class variable to store the current state - self._state = self.serialize_state(0, initial_kernel) - - # Create the viewer - self._viewer = None - - def serialize_state(self, n_operation, kernel): - """ - Pack the state of the optimization technique - :param n_operation: number of operations currently performed - :param kernel: kernel object - :return: serialized state - """ - state = np.concatenate([np.array([n_operation], dtype=int), kernel.to_numpy()], dtype=object).ravel() - return state.astype(int) - - def deserialize_state(self, array): - """ - Deserialized a previously packed state variable - :param array: serialized state - :return: tuple n_operations, kernel object - """ - kernel = Kernel.from_numpy(array[1:], self.n_features, self.n_qubits, self.n_operations, self.allow_midcircuit_measurement) - n_operations = int(array[0]) - return n_operations, kernel - - def render(self): - """ - Rendering function - we don't need that - :return: None - """ - n_op, kernel = self.deserialize_state(self._state) - print(f"{self.last_reward=:2.4f} {n_op=:2d} {kernel=}") - - def reset(self, state=None): - """ - Reset the state - :param state: optional state - :return: self._state variable - """ - if state is None: - self.initial_kernel.ansatz.initialize_to_identity() - self._state = self.serialize_state(0, self.initial_kernel) - else: - self._state = state - return self._state - - def unpack_action(self, action): - """ - Unpack an action to a operation - :param action: integer representing the action - :return: dictionary of the operation - """ - generator_index = int(action % len(self.initial_kernel.get_allowed_operations())) - action = action // len(self.initial_kernel.get_allowed_operations()) - - wires_0 = int(action % self.n_qubits) - action = action // self.n_qubits - - wires_1 = int(action % (self.n_qubits - 1)) - if wires_1 >= wires_0: - wires_1 += 1 - action = action // (self.n_qubits - 1) - - feature = int(action % (self.n_features + 1)) - action = action // (self.n_features + 1) - assert action == 0 - - return {'generator': self.initial_kernel.get_allowed_operations()[generator_index], - 'wires': [wires_0, wires_1], - 'feature': feature, - 'bandwidth': 1.0} - - def step(self, action): - - the_action = self.unpack_action(action[0]) - - # Create kernel from state - n_operations, kernel = self.deserialize_state(self._state) - - # Update kernel - kernel.ansatz.change_operation(n_operations, the_action['feature'], the_action['wires'], the_action['generator'], the_action['bandwidth']) - n_operations += 1 - - # Update state - self._state = self.serialize_state(n_operations, kernel) - - # Compute the reward as distance penalty from goal - reward = -1 * self.ke.evaluate(kernel, None, self.X, self.y) - self.last_reward = reward - - # Set the absorbing flag if goal is reached - absorbing = self.n_operations == n_operations - - # Return all the information + empty dictionary (used to pass additional information) - return self._state, reward, absorbing, {} - - diff --git a/build/lib/quask/tests/__init__.py b/build/lib/quask/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/build/lib/quask/tests/kernel_test.py b/build/lib/quask/tests/kernel_test.py deleted file mode 100644 index a265326..0000000 --- a/build/lib/quask/tests/kernel_test.py +++ /dev/null @@ -1,59 +0,0 @@ -from quask import Operation, Ansatz, KernelType, PennylaneKernel -import numpy as np - - -def test_static_single_qubit(KernelClass): - - # circuit: |0> - RX(pi) - - # |0> - ID - - ansats = Ansatz(n_features=1, n_qubits=2, n_operations=1) - ansats.initialize_to_identity() - ansats.change_generators(0, "XI") - ansats.change_feature(0, -1) - ansats.change_wires(0, [0, 1]) - ansats.change_bandwidth(0, 1) - - # measurement operation = <1|Z|1> - # probabilities: [0.0, 1.0] - # observable: 0.0 * (+1) + 1.0 * (-1) = -1.0 - kernel = KernelClass(ansats, "ZI", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0, 1])), f"Incorrect measurement: {kernel.get_last_probabilities()}" - assert np.isclose(x, -1), "Incorrect observable" - - # measurement operation = <1|X|1> = <1H|Z|H1> = <+|Z|+> - # probabilities: [0.5, 0.5] - # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 - kernel = KernelClass(ansats, "XI", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0.5, 0.5])), f"Incorrect measurement: {kernel.get_last_probabilities()}" - assert np.isclose(x, 0), "Incorrect observable" - - # measurement operation = <1|Y|1> = <1HSdag|Z|SdagH1> = <[1/sqrt(2), -i/sqrt(2)]|Z|[1/sqrt(2), -i/sqrt(2)]> - # probabilities: [0.5, 0.5] - # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 - kernel = KernelClass(ansats, "YI", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0.5, 0.5])), f"Incorrect measurement: {kernel.get_last_probabilities()}" - assert np.isclose(x, 0), "Incorrect observable" - - -def test_static_two_qubit(KernelClass): - - # circuit: |0> - XY(#0) - - # |0> - XY(#0) - - ansats = Ansatz(n_features=1, n_qubits=2, n_operations=1) - ansats.initialize_to_identity() - ansats.change_generators(0, "XY") - ansats.change_feature(0, 0) - ansats.change_wires(0, [0, 1]) - ansats.change_bandwidth(0, 1) - - kernel = KernelClass(ansats, "ZZ", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.pi / 2])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0.5, 0.0, 0.0, 0.5])), "Incorrect measurement" - assert np.isclose(x, 0), "Incorrect observable" - - -test_static_single_qubit(PennylaneKernel) -test_static_two_qubit(PennylaneKernel) diff --git a/dist/quask-1.0.2-py3-none-any.whl b/dist/quask-1.0.2-py3-none-any.whl deleted file mode 100644 index a876f5de2dd205a1df7c40f00bea3e1aaff5583a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36668 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

@2ek;Q<+3Cz5WF*l zhSI0S&zBz5)dhRubcSQCQVk&veQy05Q9v-dqOj*|&|P2HK!dFIJefrgICW+3fC>QIV2I8WJwZe+I6+uj&ZSYFRDb zs>W5e4IDJJKKH4?u8H1Kg$q?zaXwVq(A1F=8b1AYRBNU+YmY-?DZNcW4XB zDdbmmvX>~G=LY=^a>eb5Jb|w??;=$7Q%FcxK2frmL(t0p1N2{s;A?*aHtTm|-tgBs zOZa~y0!IT|V>_GwoVzcpZABfhA^7Qy{SYjKCDzukOVq-{f@sDDrTFq}CO6c96s}1Y zWYKz&a(DLh_Aobm5^ju_%z2d&3a6Nf{w_l6|GG{R zL$!p>sGYV%PSvk04$laPZku{LEZCb(`OpPHlk$n_*b6CCFp>zS{CIqu9Nr*5Esn1| zV_3-DG$I@`vhV6U69(BSRF383&b0mgdka2id1W3WS8opoa7quxsSuctzcT3BVbADE z9r+>5^{W3^(E-SeIf2Rle%Pd3lm>DGkR~*Ma=2m-F`LqAq1uk~4Cv$u7`tf&!-Ts= zyoLNJRw_)r2770J5>#N`C;&9l8fy$}r}Ej0^{pF_nuj6kK8 z*<|8+FgeKNRry*tpZfsF$C%Sk+g2=zHBMli1{|fMFKJzW25f{K1&wtiU`lxcsbUzt zC%-BA30K4Ou(~qx#$#K+k(Q)MqOF{rII+M$%WQxQ`Ya9?*Sc+PR!3JC&0iZmaVjOW zrbpw~x#|1Q=Mdr8G0lS*>?G^@30qmI4-%G?k_pMgf-WHke;(z4vqh?Hn8I6?X12Y6 zUMjb%%KLt5cn@MtFfs0~F+8e}U7qUL3^D(su49?r8LmMi9VOsS8X(yNt{`~d^Pp|& z!b-;qPa{d$bzcEcCPI*LCGG+1#nqY|NkKU+SIl)pav&ji3O$Md0?lbQc?B|HZ8C^n z+azNF)q^`4hiUtPZroG*)wmusVzT}o?RkGJ^V{s5sz-=9USypOgll$2o0Ntebal9k z5Fh6q+3=ktUt$qUBNsx$zS#_MrwdSh$6d(mG6MP0`IOE()F-@UCM0WsCYlK|0G;IX zlsGgHHmDlipO|5m(j{R7Kk($Q94@bmfPV+Ltj@Dmn~av#;!g!!e^aX?6{5bPD4TrMQj4IOQ-bGdwX_>VfdS+;lqIk1;E8y7 zSQ6#m*PDRgJ!vBlT=#ilKyjM(lCQV&hxV@64SM+=~PLt$(O7iHov^R8OM~5{a5SxW zh8>jBZD@7eCNsm%#vz;$8qC;^ihHUB+O3|mJ=qoOu!-~yVbI3bY&ffUx3EoVCM!cN z^Zfpy-hY2t)n_v`QpPb1-$pJvGhpn-QRz34xHQU@hKd$(y08R#OA)-1N!&3S{3|<+ z1%;m!s~=wT;jtmN!&pS}N&(=%4Rm&zxHv4Owbv$}MV*Ow0HCAN9?A6hp$oW9kIuoX zdO8|-)fYmh>z5R_XjJzYoE!qMlkx>VkLiNWll$X53|Q%R;%|kpPPM9}@A~rJnmumd z9p32Q(%$>)_$K+km3Aj1M*|x}YZK%DtnSTfQh$E~Qa$u_zeXbX_?E~Owr53PFf0&2 zO_VD_i6~ICPys2UOgIq>i3zK#+SzEll|@~28JBqR8E@uK4rUw~vc!$dzY-wU)39|i z1?w~amT0bT+W8`ba!;>#^)f%+yx*hvGpF(Jyq{gjVWJW#68l>61e~CwnWt5fhM4%L zMQBjCrh>b>$D`%7o^hmpf^?xP+h=}M2lk_Em{2w2DSnFml*a63HshIeQfap1^1@Ul)KBmF`yHea5Z+d!p~tSm)Rbqb`qOAUIDz@z zz-=z*kR-r`+DjBlYZd8v@n*q`uTwh?*@6L1@uXIuuV2tyY!X%)P#W9P~fQo3$Qprz2tbN4TiAw|(wV*L=kbZ=KI{ijFLd8*iGh?)lXWbe8r=&UE# zqvqoI?tBWe2emwCZrHnQ-U33l9Diwe;EdQ@ydO%FsI}brl@Nl{*}vP2Id$tr!(n6G zbDPE@dwSq+h-Rg{N@jWUhQ}M`T-AB$u|U32DdxAZEmV`d6jNp$Lxd8c7Py?&88dd5 zc}_`Q_Q90VX#0i}L0}NXnQ^&tDzI4~2T$S(J;Y;umMqURQCySBi}?m#if$+>G1t0~ z`JJOfU0?8gD_{MG5Z(|*Bz|Jkf+~L1wC`zqgt8DFdIc>jDnRjLqR=NW>?r!}N_X#- zHD|W=?sKQTCW=bw5+IgR7iAdC7Z_KmH!n*G&pp*1JVK`*&Zv=A9a7Z2ldpl;mbVx*5Yd)?zq+9%N!3%x+NA+c&d-%>bjEi?tBaCBC>>iZoQgewbL!t}UKY-J` zv=O*=5!@5k@7$gTdlpn1bCHDq6_A1)dX~EAhr0xuT{Fg~|LX56ILB2f%?2QDK@8>pO};wPub7eOf4gq-^^r)HJ1v5_`cs^M{3!BCW$))MdfOT&DWpN zAL(%+q1?jSmA$97e4&>LJCJ$KucqDpE2yvCh$g=O z4ix=}{~y)d+41*ogTZe(|IcbZtSM!8z=6~QKITW@o#2TplhuuBl!qQ8V#Ju1H=m}# z!Upj>MZ_r~mCP?Aab@`NsSxL-h-|<;tmEQHP_LpwySS@Q`rT&oxbsS9<0Ph(@(@Io zilCAp!rVlXbWJG9f^ST6K8)}A z_Y!X&X(?wegD0{KuPhzzBMUkhP)c+I?r9m-R)umuWvmfLp;%SsILCzN-sGI?nGr}i zp4fp6K}Qdv4LO}CD#vOSj+)F}VwmxeO`+c`m1;W*lE~nl7nw>_BC#NzamnjkjEGsv zGx-|@G(avWkp5$;82EmfOnrz{uti6okhQ}4wo-lacV?y6f^{`CzJ+Pq`;5(^fm~*K z*mhTlNdo#=aUwTpH!v8olnOYZsiX+HGV?O3Nrk^DjSUrM^bwI1mo@Wz(Aw+m>$d zML-=px$X}jH^D_1Qw$gM-V=R$Wi@At#LCFK`Ar68LVpTNLcCc@nPRNjWjC{9M+ol2 zJa!Ne=V#8ipCJEi_f9k`WxvQobQ$<<64UG?dRDg6VRKw<6zS*n(+!{>eAsZBQftU4 zCa-*YkNmh{iV07DR^XKK2=r&B8+(`#4ACf1v``fzxplfQr1Fw7Zn!b35{{4~Prh5) z0o8nxWjgn`l30;L?ZKi*&BtB0+vbpeIvo4rx~cO`v>=vA+>IB0SV$swFZ~WT zPZ(#W!FRCJ$wTN}r}qZxTI0V*ZSsB9!&MnJU!G(7g)3%pL4-R{Cuz&VpUWrEtGlKt$?ADYmyDU;&MW65fJH>DkMWRa#EewkJ z(uP+>sj$4lXMUx$Jps>WwhlAcd}w!C#*4o?E+gXv2q(Mg5dYSuhPWL{Y6AoWAc<1J zjG}Tc@fb9{I7n6GVGcU^<%%=L(bG|6Rwd-xCu<)su3mLPQ)NZRn?$6{bnL#rh{*}p z(-Q@f_kqWB2VYATkqKk|2hKbsTh1|^nv*6~qY$`)mY!fbmwuf~Epbfjx0*QWng#edQkLXV>j=A+;odkzyxC3(O^^=A)DqK$3jFao$^Ty-&btuK_fxy8^%Q;T`t(y?*`u0dj z1+;362SmJCzTmB&oAknta3kvPM;cWsDyeS9=VA5#&J1)W0NeDN6rYCP3K1WNR)gE6b5PkMVbtOVnF5CKrTYy6?1`g}f}9 z%(_vaSja0~!|Y;L1-!N(-$>kxSKL??Caen=*d!|wh6*VbU?W`bE*&a_D1I6 z?)|eZT*g6c2C*|q9~*&VRU+&6)yLK9&Klq8Uy!{7bG_}gl$SL#i)tsu0fgpJ&=93j zE3IMQA?nZeJNGe)x*jH_u{dBxoUvGbW`hO4-!H~46w1FF7|F^IR`)*qkhvL!lvrY>M;|522L#Vg1<$k7LfzQp8I!;cDFv-<2auhdg%0JR3_SDd$*-lwh*(Al}>xk)EX8Mm9hu*e^7;(PBkO;Oa zIi%F|S`_&T)dS_CgDLYZB_7|mdW^obcQ1OFUhGN~+u#t-<$Y#}^WLln)+6#3F(zdc zY&1)j^5!as6S}_zGfUHQ&Q09X1en`nX!!GKlXc_~IIR;o_Eza4o#lOI9pwdkV}1J; z?{k~#&D7#Eb!LN0&)KZwti8pqB4_6Y!?WRi(iFBq8i}U$Z`_b-xQCXZ5YGt5yR|7m6z|XhvgU1 z=-$L8T7SGy-(3=u)~%02{L>CSz&O@AvKglb!qvx>ZSHqaSmBMZB`K006lE zs}rVWq+_6CqBFK|a;CMgHMOIcmJkw=RTA0Kw6Vi!Mf}z!_zB?6D+8%A8I}1r@>Zno z=vYmQnV`)MaUak+*=^L_+7;KyrQ_$5i`jF%CE+@6hZ?w|NgFok;c=Y4=ljHc*Pi7-^wcLE3{eE5!`Xj$$u^5$VMo)FezW#UNdT0`zzQ@CR*%E`THiv)5w$&_wor~G^ zt?MDP{Y398Hg#KPyQ>rRL=Aoa>1lcR)7IC=g?d|iCmg;tHMy=CwNN z?P_cKGYtNbB>eSVTDwg3#nV6Znuce1mL|)ZY*W%TTb+763XmKxNr#*8Lv*Rc?vraC zi(0gl%3ygU!?fzm0o7!FGR8G%IV%2}pa>cEssgKiEkaAhi&D=B*lOfR(wkg5N{?lm z`Ke9y%f2k59=v1Ow6W2%9V>YKc>>Bjq}X!}k`s>F=&9FZl;U(P!GIJzz$aDJ(4_Y; zHISB!tE~8Ph*XMy&gk+i$s2^!c-pams19^H#t~*4Lelc+^SbUrUq%hmLglmAXqcJ{ zkr(#^Y|^q(H9wf2$5i)SRwg1+(7r^IQoK-KCI3qi3!5i_qqqkGD(giB6Q04 z#3)#?KNa@Qw>W#xo#sF$SC{!|Xk1+Qc>N3GRGS%Jq@ge(k(7s*SMOQ`?W|{Y!tu#@ z=q*|27AyRlGp>qH9BX~@owKR3Om0T#^RrpM%{5PKwqThd=bTI^b%2CjD!OCWcUgLlQ5fG;i5JF{fG}6-a$F$& z32@rIJ6uARA9T3kZR18dO!TP6q8+Z=ke>aXUy}nDs2>(u$=Hk7rz;JWz!-T61z_Yl0*N1{xQ_xEi)CTw1Gf?xsQn(#4i1jH^=JvU;W*X1PSZ7o}KRUwg$i z2JuT>M=e&sRfhXBC>ysnV%9Tg=Eqd;*P27ehHuwPY9e064c!p zd}^x=APbZu>^a~tGSL`FNbgP_`U-p>-!=VoJFcjRgcWGD{d<}&Uw;m5#Xa!Q8b=WcHms=T6GQwK0$NLxV;>Byn0t-KX`fGf(8f`UVNdvK_lH;TN@V-{I_!@|7^ zBz2-bg|uu7FnNvGD35=uHghQ0%v(HTU76-NA(o-%CPo@Z%*LrFOQ8@|ZSj||zBzM* zb0`|bO zIl400?>Q4FR%H}bq+rUqOh|lYa0H1g6l42BurzWJqTM>HmW)?%yLU4jAh^*Iz1#ro zbVjRh=4I(EL%b35%6< zXySK=vJ3vQbwe#9r9mtt`~%Q!?Ip+_cN@z`I{?XnkzI!NvL45;hs%lZkTQtVq5yv^ zc$KZed|aR=OilQn>O=SZNz|TXLT(*tH?wBtlCTjq)cAG-@khzt>`;Jr{wGW8R@HZ+%Z7W2#8$sC&{c3-_Ky78pf^hVq*+QI56IE+HjE@aB8_~Ja@n=YtGSIp@$<57*%ULl8K$ycT`QkQ$=V=rd z(M4(@UHOq03a83J7N{YC{A47-7fzPC-SLtgf9HcKvqcAGUCx@84KaI7=k>1>6?C?Yy$eNr8`39k7TN57CoNQurs92cc1!OCgD-IydT_KEyKIdY3&{Q;Z&T zxkMpny!IDTyv9=bF&5GKtwT71WR!K5M?0w)Ma+!iv@)N%g;WxeBc0vdnDP2H)Iv&$ z#j+mE)%ZhMB66Y_JG??Ac>UOF95X_O;rXHcb@U9{S=38+gz#;SzdP|btjgCSX-D_P z{$`L~iA@W{B&0Yc%9$nJ8RFN$sQ83m!)>=?tjVcL+H&d7zo#1Fg=k+gI>ors9CuUi zBS9CokAfL0?d?U_C>JA27t1o**+G|_2NJQex~~mp>31AcQLb^kYcn|uxsmZbl{H3t zl;GDYSC#}Cr}nwX=>c z-~Y%4>Wrb;9xnw|NS&JT$colmQdaj){IkI`g5S$G3Vh;s$xn=2Y3nF?5 zi{hDeScr+xUZkPB!^0|~^pax--%~3?-Cys;0p_5}79?wJSN&o;x7QN^-RWmlzF%+F z2Q!sHKPrN^hBZ|@i0db8*T|>5?Z0F{R&~}ZLl(0XVp-Lj847XTbe->Zpyms#9^mLq zLX_ATo^k8j>{jwp1pw|$+{oe4sBAa@!fLC!f-ILR3=6_*_09$>M5fPOD1sT*clD({ zZe_k3e7pK&OMgB1ye_?fciTUBo1T7K-uk>()!s?kfza+nJW=D1>Yc5n>x*dW4f4(F zucU@6#I(vV1j&4eFsoxST!ph?%8b&Y^aAlPnD2bs+L(kI>Gfpm^>kwHeZRZkI$G8t z{SVmvhV;z&VesSb{YW=DoBq5$zhCj2w#N(U;_nSO;OpY;MZDqP?CS05eq3JLQF3(- z3Lv(wt3KXv(ds zM!uOrkPzbZJY8;B)VFBns$MAeVogUm;ao5?`WbS9?BG0o3{1zbY%OXR?IDQBgnQ%+ zKG1qUXy0daQB*VUOXOL#*ye&kTN`$yO@Znivb|BKjlz(q9a^CVLD=E~h&s)_r=I zeV5#IA^!U-(O+f;CY2sA-=Gg+flSqIaNVs2$_Q!WB^k!zrLuNQo8u2cTjejv=b0f!T7f>xLCm^q)obPT}DPi?o`S<`A!H~VZ93U_*?jA zw#-g4I($UH@w{RSRi9Kb)F*QA2amALPbbL*%L>d#G| zy#y-nWky^H5Oa9Iz%$ml)(S+%Z2rI5cOW3WSnIJ>P5-o1)BGS@Tz4wzGZnBbfI) z`>Z|>Q5R#+8?2r&LJ`CeE zl^c_0^4v72()`gtvnA3M||fHK#hn|t$h%YOgciJkxG>>F$jsc|5GyZT>y$Zyi>f0{@BkIr63 zMEQ^KALT#O>KBfS;%MKsrKjoZlnGQ)t}rmWxD*NYn5)4E;`(cn3i-6n#UqNXr?#Ak zO3GJOmls!wmu{Nq8xmuEpPIfP?H`-;JDdy9d+r0c@HLD#go6-e_`16^Y~=I!3$X$7Dm5wog=M>2dAgf zIob=}nLOE)UWdM^sWGPQSiG)0tU{D*+>2&48gKmS& zh(V6Je7*MJnoQDIxylxAbfAo4rted5Bz+9j%a&zHK{Ufs()PDd2R7}(lr5<{xi!Y5~0=wAeR>xukpvZn&M%&l{$*QJgsxhr6G3scH^{*CPnw2@$6(@Pn!5A!r0ZFVUj=wX-CwMNK3 zRUC14!ja0ykv-T`N-oF>AynPOF=CW8|R>uD)Fop)V0pZ%}D36n;T&idy0-9a;A9@6znhw~Y8Pn)izw^)8 z-rZvI8u>y8?4gV}ib3emROu`BukxrKpa>YTAaYSLHK4<>Y4M(62;DB13rm1}$N?3#wMpdTq8m5JBC#YBBg5VYkBh=MoHt&5j&m z7COj)&JY4!pi8@x7zK6F8Np$xY-nXtlIQ}jotjKF*#|`={5+z6?Xk?S5pUlnmycnK z=sbwg+@dnygCEs3UncRQY>7m2)+A5%BZrYzw^y$F*cJij&H3BT zkD1sL*Qsb&9$51aFoK3dBvUIPF$y>WrZ*7a6y<7@!o-pLd&(n_IP#%`rFJ6+}^9+oex1k6tEMoxo7I{=lP1Ke%< z=Hko~jm=O;$<3Z)O;i0#NLL2a(l zv!RM=>zq2J3b7rCMiOda0Wu=D4az&IYpB90M78oy3+E)`-gCbY$5Z2c>HXs=l+{PQ zOUyEo?9!osi&P;qO`O2x@q4z}%0$=AIb)m3ai0!isk{K9Ky(67e7FF7lUQ<$h zgE{BM#KASS<(h4aqA{*8Ciy!n}$mdIsiMZ7}Mhi7u@d!p2YC+k?NV!u={o-}2mCH6G$+&MlJ29GbPLA14fc?^nV7Q<{u zlXe<`C*lN&5{Q^BtL%M)uM%blw_#w1{Sdj|-5+W>obyL_rHmj{rVSmr{!4lYn(V}1 z*g&6uzBjJHlzRP z+b3%Wf8FKRi+gFKyN&xPnEC?ta+aW~)7nf(d(Qo4ZTl!qp|Q>!0lSn1SOcyEVaJrPxz1v+YF zQ5oO>8}5HJcIHt@Jrl)@6C)}+|NUclPVlE^HUu-*I ze$f8uwC75R?q*LGKjDl!JUk_h4A+z&(mf>A)P)g|-?>5{V|*0!_bR2%l`iDmIaVPN zg&UHb?$6Go5!3QgZ9Y^$DW8OIy(cg(+$f7nl^^Ge4*EDsG4`~JyuKpPC~h&`X&RdT zp?|)>r{AM)x1HN1<@KT&8lif#&3qyQ@6lKP0Rst82p7&6y*f>|2>YC%!hrY~R^)HE zbVt5q#7mQ`Zg!l(^ipEo+HAZF%U*%|RX=$^g-5S-}DTdV2XlrSIhSllO9lL~XMQWXdQeov->yuQd zb{tIPkzI#Qhps`tZqI~hb33ea8QLeNrggHFYEzC?Q`bQKDvGeF!m5$=`dZ($BYROT zMHA!vTxKtvY4+U2A{UtzFd$}H9Ee#3vyIvF_wmJhy9K&=Yx@WLYeG@bwn=Uf%QYsx zUWAdD10e1&Nni5nzPdWBr8ydFQQ1Si``B7icx)qFn*0t94dHvMc<<_&cp2sE-(nTb ztY|auZ>~5DI6GPp*M;g#7fr7$^u-u#%Dn+U&`vU?$9d>B{Pqfes9}R7eVcgM{&kim z?DOpW-6y3sav?OOBcgN4KL@ll9aO^BUqlxQf;Zolg(*}Thjl8bd!2Hj(BLnqVulPzR(ndL`L?HH51vt-$`AS@NuVEcSyFEp(~<^ zy@n9)O|Q(%7acL{8cuZK+l)Y`kBE`Ja|#VQuq&fQa~qwm&rm+IVETWP5i8TrHt~)5 z8fb9LQ_tOM=iMCS?0IVE&qbxsRglfi44BC*7cwJ zwlE|3{r<6zN->#Sp(=_YHrk@vev66bcl^a{d- zB#Reh+nvjrY{D9Q+=w@n@ydPsDtErpCD)=?0KxzJ`2YgLxGW0Q& zD^fW6yPAjPBf$YY~=E z_>-Igb+}TsxIV!#O_jlr7U?k1AR^Ns8CgbJ>V1V< zu67WWr3S5BkZj?4_yTB0uh=5Z{;E0+HA z_vw2ftL4tpF@?L2EG7=v2jCiLcEq6hItMk|!*wxAfg9-&wX%!g#!4M@_>(9<<<+zV z_=_U{IdAy!HQ`+WL@90Xc>gE{$;U4VV)n0qz@SvuDu-(LK5yoOUXT@Y-^1M5+w*AF ztF3HGJf3io;E%^MJ6gHrX-xSnYz=gTSu*X50?Jv7AzMyl7TfWZ1BbqHj!t1hx8z(S zV1Y*m&ZgnW?U_s7mYg%G2B-$kzu>50s%$l98U|1e%tq&^?UA(yb4!zp)AJf^1GC(-66`TV{+x}BHcVjq^4{R*s@SPoa@PTb+Kpe1{ zfrEoHf0pd;=9j=(9<2>PBCw#ALlkx4LF7?h%T44}X2Ky_dHqTJ%4GambOJ;H?`v^T zilN(~*mt>rETEU;u!65`$NIms;|B5aUmTFw_3c1^abw&-UOtQstl)Fl7P#fgFi0Vm S3uLbPk|5T=pCfUscYgpzh>a!y diff --git a/dist/quask-1.0.2.tar.gz b/dist/quask-1.0.2.tar.gz deleted file mode 100644 index e3da406a90224da2e2b3796909924f2b0eb3c700..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29442 zcmaI7Q;;r9(52h9ZQIsv+qP|Ew{6?DZQJH<+qS#k`TlceBIar;o~WqEi;Aecsa(0L z2&18(?x5UEK>$u}MlLq=%nVEnEDWwj&Oq0_Hh*y?nwZx8>*p2;nhGC?_aTIUe55+U zwps`{>glEFr*@Jyz8zr&f$16*!8On&g}Znx{N^ys)tSCBa(!qsBPQI{Fo2|2hEewI zkt?QR{{ImXV{6Oa=I3##_jBznBJeQ{`N8&4e(liQ*<0Ly^rYUrV+{z^`#B-?F}FG; zU-&lYn^X8=$Tl4uxodm9y|v%7x!LXh*WvB%?%-eVcExx#j|uoNIW0ZQt`%=y-2GIv z+b`MO+hfcJ-1oLNH}`JY-`d_CJpJtatQoA|dj0y}D;&8b0B(AVzW4N}0r4b&E$!dC z?VXJst6PpNn@ND$6u(Jh&)4kQr1$fgY0%Tu( z00srx9U9H@gDW|?o;KsUJdlwo|3q2IJ5tpw9YlzZf

    h*7(lyhzg-8v`UoC>X4Q@ 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 wIn2HkV0!| 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 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a023752 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,141 @@ +[project] +name = "quask" +dynamic = ["version"] +authors = [ + {name = "Massimiliano Incudini", email = "massimiliano.incudini@univr.it"}, + {name = "Francesco Di Marcantonio", email = "massimiliano.incudini@univr.it"}, + {name = "Roman Wixinger", email = "massimiliano.incudini@univr.it"}, + {name = "Sofia Vallecorsa", email = "massimiliano.incudini@univr.it"}, + {name = "Michele Grossi", email = "massimiliano.incudini@univr.it"}, +] +requires-python = ">=3.10" +description = "Quantum Advantage Seeker with Kernels (QuASK): a software framework to speed up the research in quantum machine learning" +url = "https://quask.web.cern.ch/" +classifiers = [ + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10" +] +dependencies = [ + "pandas>=2.2.3", + "pennylane>=0.40.0", + "scikit-learn>=1.6.1", + "scipy>=1.15.1", +] + +[build-system] +requires = ["pdm-backend"] +build-backend = "pdm.backend" + +[tool.pdm.build] +includes = ["dcm/"] + +[tool.pdm.version] +source = "file" +path = "src/quask/__version__.py" + +[dependency-groups] +dev = [ + "nose2[coverage_plugin]>=0.15.1", + "tox-pdm>=0.7.2", +] +demo = [ + "ipykernel>=6.29.5", +] +docs = [ + "sphinx-rtd-theme>=3.0.2", + "sphinx>=8.1.3", + "sphinxcontrib-napoleon>=0.7", + "sphinx-autoapi>=3.4.0", +] +release = [ + "pre-commit>=4.1.0", + "python-semantic-release>=9.16.1", +] + +# Ruff +[tool.ruff] +exclude = [".venv","data", "examples"] +line-length = 79 + +# - https://docs.astral.sh/ruff/rules/ +[tool.ruff.lint] +extend-select = [ + "UP", # pyupgrade + "D", # pydocstyle + "F", # fake8 + "E", # PyCodeStyle + "I", # isort + "N", # Naming + "RUF", # Ruff + "PL", # PyLint +] +ignore = ["D102", "N802", "PLR0904"] + +[tool.ruff.lint.pydocstyle] +convention = "google" + +# SemVer +[tool.semantic_release] +assets = [] +build_command_env = [] +commit_message = "{version}\n\nAutomatically generated by python-semantic-release" +commit_parser = "angular" +logging_use_named_masks = false +major_on_zero = true +version_variables = ["arc/quask/__version__.py:__version__"] +allow_zero_version = true +no_git_verify = false +tag_format = "{version}" + +[tool.semantic_release.branches.main] +match = "(main|master)" +prerelease_token = "rc" +prerelease = false + +[tool.semantic_release.changelog] +exclude_commit_patterns = [] +mode = "update" +insertion_flag = "" +template_dir = "templates" + +[tool.semantic_release.changelog.default_templates] +changelog_file = "CHANGELOG.md" +output_format = "md" +mask_initial_release = false + +[tool.semantic_release.changelog.environment] +block_start_string = "{%" +block_end_string = "%}" +variable_start_string = "{{" +variable_end_string = "}}" +comment_start_string = "{#" +comment_end_string = "#}" +trim_blocks = false +lstrip_blocks = false +newline_sequence = "\n" +keep_trailing_newline = false +extensions = [] +autoescape = false + +[tool.semantic_release.commit_author] +env = "GIT_COMMIT_AUTHOR" +default = "semantic-release " + +[tool.semantic_release.commit_parser_options] +minor_tags = ["feat"] +patch_tags = ["fix", "perf"] +other_allowed_tags = ["enhance","build", "chore", "ci", "docs", "style", "refactor", "test"] +allowed_tags = ["feat", "fix", "perf", "build", "chore", "ci", "docs", "style", "refactor", "test"] +default_bump_level = 0 + +[tool.semantic_release.remote] +name = "origin" +type = "github" +ignore_token_for_push = false +insecure = false + +[tool.semantic_release.publish] +dist_glob_patterns = ["dist/*"] +upload_to_vcs_release = true diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..cebcefa --- /dev/null +++ b/requirements.txt @@ -0,0 +1,423 @@ +# This file was autogenerated by uv via the following command: +# uv export --frozen --output-file=requirements.txt +-e . +appdirs==1.4.4 \ + --hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41 \ + --hash=sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128 +astunparse==1.6.3 \ + --hash=sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872 \ + --hash=sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8 +autograd==1.7.0 \ + --hash=sha256:49680300f842f3a8722b060ac0d3ed7aca071d1ad4d3d38c9fdadafdcc73c30b \ + --hash=sha256:de743fd368d6df523cd37305dcd171861a9752a144493677d2c9f5a56983ff2f +autoray==0.7.0 \ + --hash=sha256:03103957df3d1b66b8068158056c2909a72095b19d1b24262261276a714a5d07 \ + --hash=sha256:7829d21258512f87e02f23ce74ae5759af4ce8998069d2cce53468f1d701a219 +cachetools==5.5.1 \ + --hash=sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95 \ + --hash=sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb +certifi==2025.1.31 \ + --hash=sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651 \ + --hash=sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe +chardet==5.2.0 \ + --hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \ + --hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 +charset-normalizer==3.4.1 \ + --hash=sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd \ + --hash=sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601 \ + --hash=sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd \ + --hash=sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d \ + --hash=sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313 \ + --hash=sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd \ + --hash=sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa \ + --hash=sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8 \ + --hash=sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1 \ + --hash=sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2 \ + --hash=sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d \ + --hash=sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b \ + --hash=sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408 \ + --hash=sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3 \ + --hash=sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f \ + --hash=sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a \ + --hash=sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146 \ + --hash=sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6 \ + --hash=sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9 \ + --hash=sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f \ + --hash=sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545 \ + --hash=sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176 \ + --hash=sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b \ + --hash=sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f \ + --hash=sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b \ + --hash=sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9 \ + --hash=sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125 \ + --hash=sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de \ + --hash=sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11 \ + --hash=sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35 \ + --hash=sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f \ + --hash=sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda \ + --hash=sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a \ + --hash=sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971 \ + --hash=sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d \ + --hash=sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f \ + --hash=sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757 \ + --hash=sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a \ + --hash=sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886 \ + --hash=sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77 \ + --hash=sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76 \ + --hash=sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247 \ + --hash=sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85 \ + --hash=sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb \ + --hash=sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7 \ + --hash=sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037 \ + --hash=sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1 \ + --hash=sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807 \ + --hash=sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407 \ + --hash=sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12 \ + --hash=sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3 \ + --hash=sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd \ + --hash=sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00 \ + --hash=sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616 +colorama==0.4.6 \ + --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ + --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 +coverage==7.6.10 \ + --hash=sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9 \ + --hash=sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273 \ + --hash=sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994 \ + --hash=sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e \ + --hash=sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50 \ + --hash=sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e \ + --hash=sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e \ + --hash=sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c \ + --hash=sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853 \ + --hash=sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8 \ + --hash=sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8 \ + --hash=sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe \ + --hash=sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165 \ + --hash=sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb \ + --hash=sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609 \ + --hash=sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098 \ + --hash=sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd \ + --hash=sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3 \ + --hash=sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43 \ + --hash=sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d \ + --hash=sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359 \ + --hash=sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78 \ + --hash=sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99 \ + --hash=sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988 \ + --hash=sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2 \ + --hash=sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0 \ + --hash=sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694 \ + --hash=sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377 \ + --hash=sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23 \ + --hash=sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312 \ + --hash=sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf \ + --hash=sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6 \ + --hash=sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b \ + --hash=sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c \ + --hash=sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690 \ + --hash=sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a \ + --hash=sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f \ + --hash=sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd \ + --hash=sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852 \ + --hash=sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0 \ + --hash=sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244 \ + --hash=sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078 \ + --hash=sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0 \ + --hash=sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132 \ + --hash=sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5 \ + --hash=sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247 \ + --hash=sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022 \ + --hash=sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b \ + --hash=sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3 \ + --hash=sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18 \ + --hash=sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5 \ + --hash=sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f +diastatic-malt==2.15.2 \ + --hash=sha256:7eb90d8c30b7ff16b4e84c3a65de2ff7f5b7b9d0f5cdea23918e747ff7fb5320 \ + --hash=sha256:85429257b356030f101c31b2c7d506c4829f21bd865aed796766f900d7908407 +distlib==0.3.9 \ + --hash=sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87 \ + --hash=sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403 +filelock==3.17.0 \ + --hash=sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338 \ + --hash=sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e +gast==0.6.0 \ + --hash=sha256:52b182313f7330389f72b069ba00f174cfe2a06411099547288839c6cbafbd54 \ + --hash=sha256:88fc5300d32c7ac6ca7b515310862f71e6fdf2c029bbec7c66c0f5dd47b6b1fb +idna==3.10 \ + --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ + --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 +joblib==1.4.2 \ + --hash=sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6 \ + --hash=sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e +networkx==3.4.2 \ + --hash=sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1 \ + --hash=sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f +nose2==0.15.1 \ + --hash=sha256:36770f519df5becd3cbfe0bee4abbfbf9b9f6b4eb4e03361d282b7efcfc4f0df \ + --hash=sha256:564450c0c4f1602dfe171902ceb4726cc56658af7a620ae1826f1ffc86b09a86 +numpy==2.0.2 \ + --hash=sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a \ + --hash=sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195 \ + --hash=sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951 \ + --hash=sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc \ + --hash=sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd \ + --hash=sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318 \ + --hash=sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448 \ + --hash=sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece \ + --hash=sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5 \ + --hash=sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57 \ + --hash=sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78 \ + --hash=sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66 \ + --hash=sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a \ + --hash=sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e \ + --hash=sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c \ + --hash=sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97 \ + --hash=sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c \ + --hash=sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9 \ + --hash=sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669 \ + --hash=sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4 \ + --hash=sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8 \ + --hash=sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c \ + --hash=sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b \ + --hash=sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692 \ + --hash=sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15 \ + --hash=sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131 \ + --hash=sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a \ + --hash=sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326 \ + --hash=sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b \ + --hash=sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded \ + --hash=sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04 +packaging==24.2 \ + --hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \ + --hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f +pandas==2.2.3 \ + --hash=sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a \ + --hash=sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d \ + --hash=sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5 \ + --hash=sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4 \ + --hash=sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0 \ + --hash=sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32 \ + --hash=sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28 \ + --hash=sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f \ + --hash=sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348 \ + --hash=sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18 \ + --hash=sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468 \ + --hash=sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5 \ + --hash=sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667 \ + --hash=sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645 \ + --hash=sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13 \ + --hash=sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3 \ + --hash=sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d \ + --hash=sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb \ + --hash=sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3 \ + --hash=sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039 \ + --hash=sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8 \ + --hash=sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd \ + --hash=sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659 \ + --hash=sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57 \ + --hash=sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4 \ + --hash=sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a \ + --hash=sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9 \ + --hash=sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42 \ + --hash=sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2 \ + --hash=sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc \ + --hash=sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698 \ + --hash=sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed \ + --hash=sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015 \ + --hash=sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24 \ + --hash=sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319 +pennylane==0.40.0 \ + --hash=sha256:c93bb48ff80833edaf424b3b91e01a56cd25b22170bc99b7e53e7168a1ad4dd1 +pennylane-lightning==0.40.0 \ + --hash=sha256:20052041abc417d74d1794506d4340a8a2298b858e2b94591704e73670d913f9 \ + --hash=sha256:2ba97b4d6aa0a6eb774413ea3272d418959b792de6df8e4196171cad450f25af \ + --hash=sha256:3a6915cc17ce99cd4f3d04dcf7d579f59cecdc2866cd4e8e1c33478d86101437 \ + --hash=sha256:3d7715c84290fc1291e315d2c0d2bf5719cbe86e3e92fb538393ab130b3f5ba2 \ + --hash=sha256:3f75b7d39d63880e9d59562d78ae5ec63d2aed936b2feee3c937dfbcd080b834 \ + --hash=sha256:4a66e8c644f634f9d1fda6b9223f5cc106acf4146334a25a23f948ec59b075c0 \ + --hash=sha256:6b89ad785e16cc3b3d155b1abd27e42fcb5854a0e2d90452f6445fc0e80b1cf4 \ + --hash=sha256:7fe9262c602b6c7f0ab893468867e24c63e9cacc7d77e19b448ac1361bb86a47 \ + --hash=sha256:8a4ff3f1d82f664e6d608d155cb019b189aac676c6c7cb40c4f92b15e0d2d485 \ + --hash=sha256:96390ce82767b3a66c4f8e0b1bcec2f4f15fb317652cffa9815e371e74458197 \ + --hash=sha256:99cf7bcfb3a2a29838cc12f0001e3e7e02d35c5c1d696ce2e5ba0c3f2995c4d9 \ + --hash=sha256:a3db3cf2c3caed80ce561b66bb4bf6b5712ecf0b08db986f24c4ff9e187e82b3 \ + --hash=sha256:a58ab1489fee0424840bc8f91e8f7e32ecc3338a714b2fe1bf68a9026a5a295a \ + --hash=sha256:b2209727b8c914c8101087da188cbbc7b332bb77ceab4b6791c7ed7b3c5a942c \ + --hash=sha256:e3152f6b53390281334257554ecad90566cd4d200187971d238d2c7691000466 \ + --hash=sha256:edc95e75ef1b4e6dba96e914893175f9448d4d1b53a6e78614cb7587a8a22f2f \ + --hash=sha256:fed88008b7d468cb1d0e5b3ef92d87f9b600d0896d21eff43655a521cc841d7b +platformdirs==4.3.6 \ + --hash=sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907 \ + --hash=sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb +pluggy==1.5.0 \ + --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ + --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 +pyproject-api==1.9.0 \ + --hash=sha256:326df9d68dea22d9d98b5243c46e3ca3161b07a1b9b18e213d1e24fd0e605766 \ + --hash=sha256:7e8a9854b2dfb49454fae421cb86af43efbb2b2454e5646ffb7623540321ae6e +python-dateutil==2.9.0.post0 \ + --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ + --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 +pytz==2025.1 \ + --hash=sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57 \ + --hash=sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e +requests==2.32.3 \ + --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ + --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 +rustworkx==0.16.0 \ + --hash=sha256:040c4368729cf502f756a3b0ff5f1c6915fc389f74dcc6afc6c3833688c97c01 \ + --hash=sha256:0db3a73bf68b3e66c08322a2fc95d3aa663d037d9b4e49c3509da4898d3529cc \ + --hash=sha256:293180b83509ee9bff4c3af7ccc1024f6528d61b65d0cb7320bd31924f10cb71 \ + --hash=sha256:476a6c67b0142acd941691943750cc6737a48372304489969c2b62d30aaf4c27 \ + --hash=sha256:4f12a13d7486234fa2a84746d5e41f436bf9df43548043e7a232f48804ff8c61 \ + --hash=sha256:89efd5c3a4653ddacc55ca39f28b261d43deec7d678f8f8fc6b76b5087f1dfea \ + --hash=sha256:905df608843c32fa45ac023687769fe13056edf7584474c801d5c50705d76e9b \ + --hash=sha256:9f0dcb83f38d5ca2c3a683eb9b6951c8aec3262fbfe5141946a7ee5ba37e0bb6 \ + --hash=sha256:bef2ef42870f806af93979b457e240f6dfa4f867ca33965c620f3a804409ed3a \ + --hash=sha256:d650e39fc1a1534335f7517358ebfc3478bb235428463cfcd7c5750d50377b33 \ + --hash=sha256:ec0c12aac8c54910ace20ac6ada4b890cd39f95f69100514715f8ad7af9041e4 +scikit-learn==1.6.1 \ + --hash=sha256:0650e730afb87402baa88afbf31c07b84c98272622aaba002559b614600ca691 \ + --hash=sha256:0c8d036eb937dbb568c6242fa598d551d88fb4399c0344d95c001980ec1c7d36 \ + --hash=sha256:1061b7c028a8663fb9a1a1baf9317b64a257fcb036dae5c8752b2abef31d136f \ + --hash=sha256:25fc636bdaf1cc2f4a124a116312d837148b5e10872147bdaf4887926b8c03d8 \ + --hash=sha256:2c2cae262064e6a9b77eee1c8e768fc46aa0b8338c6a8297b9b6759720ec0ff2 \ + --hash=sha256:2e69fab4ebfc9c9b580a7a80111b43d214ab06250f8a7ef590a4edf72464dd86 \ + --hash=sha256:2ffa1e9e25b3d93990e74a4be2c2fc61ee5af85811562f1288d5d055880c4322 \ + --hash=sha256:3f59fe08dc03ea158605170eb52b22a105f238a5d512c4470ddeca71feae8e5f \ + --hash=sha256:6a7aa5f9908f0f28f4edaa6963c0a6183f1911e63a69aa03782f0d924c830a35 \ + --hash=sha256:70b1d7e85b1c96383f872a519b3375f92f14731e279a7b4c6cfd650cf5dffc52 \ + --hash=sha256:72abc587c75234935e97d09aa4913a82f7b03ee0b74111dcc2881cba3c5a7b33 \ + --hash=sha256:775da975a471c4f6f467725dff0ced5c7ac7bda5e9316b260225b48475279a1b \ + --hash=sha256:7a1c43c8ec9fde528d664d947dc4c0789be4077a3647f232869f41d9bf50e0fb \ + --hash=sha256:8634c4bd21a2a813e0a7e3900464e6d593162a29dd35d25bdf0103b3fce60ed5 \ + --hash=sha256:8a600c31592bd7dab31e1c61b9bbd6dea1b3433e67d264d17ce1017dbdce8002 \ + --hash=sha256:926f207c804104677af4857b2c609940b743d04c4c35ce0ddc8ff4f053cddc1b \ + --hash=sha256:a17c1dea1d56dcda2fac315712f3651a1fea86565b64b48fa1bc090249cbf236 \ + --hash=sha256:b3b00cdc8f1317b5f33191df1386c0befd16625f49d979fe77a8d44cae82410d \ + --hash=sha256:b4fc2525eca2c69a59260f583c56a7557c6ccdf8deafdba6e060f94c1c59738e \ + --hash=sha256:c06beb2e839ecc641366000ca84f3cf6fa9faa1777e29cf0c04be6e4d096a348 \ + --hash=sha256:d056391530ccd1e501056160e3c9673b4da4805eb67eb2bdf4e983e1f9c9204e \ + --hash=sha256:dc4765af3386811c3ca21638f63b9cf5ecf66261cc4815c1db3f1e7dc7b79db2 \ + --hash=sha256:dc5cf3d68c5a20ad6d571584c0750ec641cc46aeef1c1507be51300e6003a7e1 \ + --hash=sha256:e8ca8cb270fee8f1f76fa9bfd5c3507d60c6438bbee5687f81042e2bb98e5a97 \ + --hash=sha256:fa909b1a36e000a03c382aade0bd2063fd5680ff8b8e501660c0f59f021a6415 +scipy==1.15.1 \ + --hash=sha256:033a75ddad1463970c96a88063a1df87ccfddd526437136b6ee81ff0312ebdf6 \ + --hash=sha256:0458839c9f873062db69a03de9a9765ae2e694352c76a16be44f93ea45c28d2b \ + --hash=sha256:070d10654f0cb6abd295bc96c12656f948e623ec5f9a4eab0ddb1466c000716e \ + --hash=sha256:09c52320c42d7f5c7748b69e9f0389266fd4f82cf34c38485c14ee976cb8cb04 \ + --hash=sha256:0ac102ce99934b162914b1e4a6b94ca7da0f4058b6d6fd65b0cef330c0f3346f \ + --hash=sha256:0fb57b30f0017d4afa5fe5f5b150b8f807618819287c21cbe51130de7ccdaed2 \ + --hash=sha256:100193bb72fbff37dbd0bf14322314fc7cbe08b7ff3137f11a34d06dc0ee6b85 \ + --hash=sha256:14eaa373c89eaf553be73c3affb11ec6c37493b7eaaf31cf9ac5dffae700c2e0 \ + --hash=sha256:2114a08daec64980e4b4cbdf5bee90935af66d750146b1d2feb0d3ac30613692 \ + --hash=sha256:21e10b1dd56ce92fba3e786007322542361984f8463c6d37f6f25935a5a6ef52 \ + --hash=sha256:2722a021a7929d21168830790202a75dbb20b468a8133c74a2c0230c72626b6c \ + --hash=sha256:395be70220d1189756068b3173853029a013d8c8dd5fd3d1361d505b2aa58fa7 \ + --hash=sha256:3fe1d95944f9cf6ba77aa28b82dd6bb2a5b52f2026beb39ecf05304b8392864b \ + --hash=sha256:491d57fe89927fa1aafbe260f4cfa5ffa20ab9f1435025045a5315006a91b8f5 \ + --hash=sha256:4b17d4220df99bacb63065c76b0d1126d82bbf00167d1730019d2a30d6ae01ea \ + --hash=sha256:4c9d8fc81d6a3b6844235e6fd175ee1d4c060163905a2becce8e74cb0d7554ce \ + --hash=sha256:55cc79ce4085c702ac31e49b1e69b27ef41111f22beafb9b49fea67142b696c4 \ + --hash=sha256:5b190b935e7db569960b48840e5bef71dc513314cc4e79a1b7d14664f57fd4ff \ + --hash=sha256:5bd8d27d44e2c13d0c1124e6a556454f52cd3f704742985f6b09e75e163d20d2 \ + --hash=sha256:5dff14e75cdbcf07cdaa1c7707db6017d130f0af9ac41f6ce443a93318d6c6e0 \ + --hash=sha256:5eb0ca35d4b08e95da99a9f9c400dc9f6c21c424298a0ba876fdc69c7afacedf \ + --hash=sha256:63b9b6cd0333d0eb1a49de6f834e8aeaefe438df8f6372352084535ad095219e \ + --hash=sha256:667f950bf8b7c3a23b4199db24cb9bf7512e27e86d0e3813f015b74ec2c6e3df \ + --hash=sha256:6b3e71893c6687fc5e29208d518900c24ea372a862854c9888368c0b267387ab \ + --hash=sha256:71ba9a76c2390eca6e359be81a3e879614af3a71dfdabb96d1d7ab33da6f2364 \ + --hash=sha256:74bb864ff7640dea310a1377d8567dc2cb7599c26a79ca852fc184cc851954ac \ + --hash=sha256:82add84e8a9fb12af5c2c1a3a3f1cb51849d27a580cb9e6bd66226195142be6e \ + --hash=sha256:837299eec3d19b7e042923448d17d95a86e43941104d33f00da7e31a0f715d3c \ + --hash=sha256:900f3fa3db87257510f011c292a5779eb627043dd89731b9c461cd16ef76ab3d \ + --hash=sha256:9f151e9fb60fbf8e52426132f473221a49362091ce7a5e72f8aa41f8e0da4f25 \ + --hash=sha256:af0b61c1de46d0565b4b39c6417373304c1d4f5220004058bdad3061c9fa8a95 \ + --hash=sha256:bc7136626261ac1ed988dca56cfc4ab5180f75e0ee52e58f1e6aa74b5f3eacd5 \ + --hash=sha256:be3deeb32844c27599347faa077b359584ba96664c5c79d71a354b80a0ad0ce0 \ + --hash=sha256:c09aa9d90f3500ea4c9b393ee96f96b0ccb27f2f350d09a47f533293c78ea776 \ + --hash=sha256:c352c1b6d7cac452534517e022f8f7b8d139cd9f27e6fbd9f3cbd0bfd39f5bef \ + --hash=sha256:c64ded12dcab08afff9e805a67ff4480f5e69993310e093434b10e85dc9d43e1 \ + --hash=sha256:cdde8414154054763b42b74fe8ce89d7f3d17a7ac5dd77204f0e142cdc9239e9 \ + --hash=sha256:ce3a000cd28b4430426db2ca44d96636f701ed12e2b3ca1f2b1dd7abdd84b39a \ + --hash=sha256:f735bc41bd1c792c96bc426dece66c8723283695f02df61dcc4d0a707a42fc54 \ + --hash=sha256:f82fcf4e5b377f819542fbc8541f7b5fbcf1c0017d0df0bc22c781bf60abc4d8 +scipy-openblas32==0.3.29.0.0 \ + --hash=sha256:02d32eafdf101f9503b99bd623e84f109a95cbe16d65492e174ed386339e2e1f \ + --hash=sha256:2ca3ee3b9143b86addccda36a741462621413766dbc09896b0b43cc223a3b051 \ + --hash=sha256:33994f0a37373ff6717fd9c948053a76c272efd516f8b33b3e51ecec786922fe \ + --hash=sha256:6b276ac72c00cc0850588663b9da4c8099d4bee8a2527557747cf6b8ed5179cb \ + --hash=sha256:768352307e56873538222526b7dbcfd3dcd8615451741d15eef9af718ac93750 \ + --hash=sha256:8b21c803bdc344a383a1d5d392d3cfe5366d9b89d2aeee963705156000cbbc7a \ + --hash=sha256:9d6301960024370f6061c71e8efd8bcb5be22c6526a529ff05c370048adb6b04 \ + --hash=sha256:dd74159091a83ae7bf7b066345c3d3e43e212cd4537c03a2fd873154e5a179f2 \ + --hash=sha256:e56c9c8e5e41d91d357b0d514fc59ca25467fbd68e5bdffa1f3dfa96f3249eb2 +six==1.17.0 \ + --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ + --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 +termcolor==2.5.0 \ + --hash=sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8 \ + --hash=sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f +threadpoolctl==3.5.0 \ + --hash=sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107 \ + --hash=sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467 +tomli==2.2.1 ; python_full_version < '3.11' \ + --hash=sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6 \ + --hash=sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd \ + --hash=sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c \ + --hash=sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b \ + --hash=sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8 \ + --hash=sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6 \ + --hash=sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77 \ + --hash=sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff \ + --hash=sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea \ + --hash=sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192 \ + --hash=sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249 \ + --hash=sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee \ + --hash=sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4 \ + --hash=sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98 \ + --hash=sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8 \ + --hash=sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4 \ + --hash=sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281 \ + --hash=sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744 \ + --hash=sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69 \ + --hash=sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13 \ + --hash=sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140 \ + --hash=sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e \ + --hash=sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e \ + --hash=sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc \ + --hash=sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff \ + --hash=sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec \ + --hash=sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2 \ + --hash=sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222 \ + --hash=sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106 \ + --hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \ + --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \ + --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7 +tomlkit==0.13.2 \ + --hash=sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde \ + --hash=sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79 +tox==4.24.1 \ + --hash=sha256:083a720adbc6166fff0b7d1df9d154f9d00bfccb9403b8abf6bc0ee435d6a62e \ + --hash=sha256:57ba7df7d199002c6df8c2db9e6484f3de6ca8f42013c083ea2d4d1e5c6bdc75 +tox-pdm==0.7.2 \ + --hash=sha256:12f6215416b7acd00a80a9e7128f3dc3e3c89308d60707f5d0a24abdf83ac104 \ + --hash=sha256:a841a7e1e942a71805624703b9a6d286663bd6af79bba6130ba756975c315308 +typing-extensions==4.12.2 \ + --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ + --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 +tzdata==2025.1 \ + --hash=sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694 \ + --hash=sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639 +urllib3==2.3.0 \ + --hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \ + --hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d +virtualenv==20.29.1 \ + --hash=sha256:4e4cb403c0b0da39e13b46b1b2476e505cb0046b25f242bee80f62bf990b2779 \ + --hash=sha256:b8b8970138d32fb606192cb97f6cd4bb644fa486be9308fb9b63f81091b5dc35 +wheel==0.45.1 \ + --hash=sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729 \ + --hash=sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index dd4827e..0000000 --- a/setup.cfg +++ /dev/null @@ -1,36 +0,0 @@ -[metadata] -name = quask -version = 2.0.0-alpha2 -author = Massimiliano Incudini, Francesco Di Marcantonio, Roman Wixinger, Sofia Vallecorsa, Michele Grossi -author_email = massimiliano.incudini@univr.it -description = Quantum Advantage Seeker with Kernels (QuASK): a software framework to speed up the research in quantum machine learning -license_files = LICENSE.txt -url = https://quask.web.cern.ch/ -classifiers = - Intended Audience :: Developers - License :: OSI Approved :: Apache Software License - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - -[options] -python_requires = >=3.8 -install_requires = - pennylane==0.33.1 - pytest>=7.4.3 - numpy>=1.23.5 - pandas>=2.1.2 - scikit-learn>=1.3.1 - scipy>=1.11.2 - -[options.packages.find] -where = src - -[options.extras_require] -demo = - jupyter -docs = - sphinx>=4.5.0 - sphinx-rtd-theme>=1.0.0 - sphinxcontrib-napoleon>=0.7 - sphinx-autoapi>=2.0.1 diff --git a/setup.py b/setup.py deleted file mode 100644 index daf9285..0000000 --- a/setup.py +++ /dev/null @@ -1,10 +0,0 @@ -from setuptools import setup - -# Read the contents of the README.md file -with open("README.md", "r", encoding="utf-8") as readme_file: - long_description = readme_file.read() - -setup( - long_description=long_description, - long_description_content_type="text/markdown", -) diff --git a/src/quask.egg-info/PKG-INFO b/src/quask.egg-info/PKG-INFO deleted file mode 100644 index 3311c8f..0000000 --- a/src/quask.egg-info/PKG-INFO +++ /dev/null @@ -1,139 +0,0 @@ -Metadata-Version: 2.1 -Name: quask -Version: 2.0.0a1 -Summary: Quantum Advantage Seeker with Kernels (QuASK): a software framework to speed up the research in quantum machine learning -Home-page: https://github.com/CERN-IT-INNOVATION/QuASK -Author: Massimiliano Incudini, Francesco Di Marcantonio, Roman Wixinger, Sofia Vallecorsa, Michele Grossi -Author-email: massimiliano.incudini@univr.it -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Requires-Python: >=3.8 -Description-Content-Type: text/markdown -Provides-Extra: demo -Provides-Extra: docs -License-File: LICENSE.txt - -# Quantum Advantage Seeker with Kernels (QuASK) - -QuASK is an actively maintained library for constructing, studying, and benchmarking quantum kernel methods. - -It is designed to simplify the process of choosing a quantum kernel, automate the machine learning pipeline at all its stages, and provide pedagogical guidance for early-stage researchers to utilize these tools to their full potential. - -QuASK promotes the use of reusable code and is available as a library that can be seamlessly integrated into existing code bases. It is written in Python 3, can be easily installed using pip, and is accessible on PyPI. - -## Installation - -The easiest way to use *quask* is by installing it in your Python3 -environment (version >= 3.10) via the *pip* packet manager, - - python3 -m pip install quask==2.0.0-alpha1 - -You also need any quantum SDK installed on your system. For example, we can install Qiskit (but we can also work with Pennylane, Braket, Qibo, and the modular nature of the software allows the creation of your own custom backends). - - python3 -m pip install qiskit qiskit_ibm_runtime - python3 -m pip install qiskit_ibm_runtime --upgrade - python3 -m pip install qiskit-aer - -See the [Installation section](https://quask.readthedocs.io/en/latest/installation.html) -of our documentation page for more information. - -## Examples - -The fastest way to start developing using _quask_ is via our [Getting started](https://quask.readthedocs.io/en/latest/getting_started.html) guide. - -If you are not familiar with the concept of kernel methods in classical machine learning, we have developed a [series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_classical/index.html) on the topic. - -If you are not familiar with the concept of quantum kernels, we have developed a [series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_quantum/index.html) on the topic, which is also used to showcase the basic functionalities of _quask_. - -Then [advanced features of _quask_](https://quask.readthedocs.io/en/latest/tutorials_quask/index.html) are shown, including the use of different backends, the criteria to evaluate a quantum kernel, and the automatic optimization approach. - -Finally, [look here for some applications](https://quask.readthedocs.io/en/latest/tutorials_applications/index.html). - - -## Source - - -### Deployment to PyPI - -The software is uploaded to [PyPI](https://pypi.org/project/quask/). - -### Test - -The suite of test for _quask_ is currently under development.To run the available tests, type - - pytest - - -You can also specify specific test scripts. - - pytest tests/test_example.py - - _quask_ has been developed and tested with the following versions of the quantum frameworks: - -* PennyLane==0.32.0 -* PennyLane-Lightning==0.32.0 -* qiskit==0.44.1 -* qiskit-aer==0.12.2 -* qiskit-ibm-runtime==0.14.0 - - -## Documentation - -The documentation is available at our [Read the Docs](https://quask.readthedocs.io/en/latest/) domain. - -### Generate the documentation - -The documentation has been generated with Sphinx (v7.2.6) and uses the Furo theme. To install it, run - - python3 -m pip install -U sphinx - python3 -m pip install furo - -To generate the documentation, run - - cd docs - make clean && make html - -The Sphinx configuration file (`conf.py`) has the following, non-standard options: - - html_theme = 'furo' - html_theme_options = { - "sidebar_hide_name": True - } - autodoc_mock_imports = ["skopt", "skopt.space", "django", "mushroom_rl", "opytimizer", "pennylane", "qiskit", "qiskit_ibm_runtime", "qiskit_aer"] - -### Generate the UML diagrams - -Currently, the pages generated from the Python notebooks has to be compiled to RST format manually. We could use in the future the [nbsphinx extension](https://docs.readthedocs.io/en/stable/guides/jupyter.html) to automatize this process. This has the advantage that the documentation is always up to date, the disadvantage is that the process is much slower. - -### Generate the UML diagrams - -The UML diagrams in the [Platform overview](https://quask.readthedocs.io/en/latest/platform_overview.html) page of the documentation are generated using pyreverse and Graphviz. They can be installed via: - - sudo apt-get install graphviz - python3 -m pip install pylint - -The UML diagrams are created via: - - cd src/quask - pyreverse -o png -p QUASK . - - -## Acknowledgements - -The platform has been developed with the contribution of [Massimiliano Incudini](https://incud.github.io), Francesco Di Marcantonio, Davide Tezza, Roman Wixinger, Sofia Vallecorsa, and [Michele Grossi](https://scholar.google.com/citations?user=cnfcO7cAAAAJ&hl=en). - -If you have used _quask_ for your project, please consider citing us. - - @article{dimarcantonio2023quask, - title={Quantum Advantage Seeker with Kernels (QuASK): a software framework to accelerate research in quantum machine learning}, - author={Di Marcantonio, Francesco and Incudini, Massimiliano and Tezza, Davide and Grossi, Michele}, - journal={Quantum Machine Intelligence}, - volume={5}, - number={1}, - pages={20}, - year={2023}, - publisher={Springer} - } diff --git a/src/quask.egg-info/SOURCES.txt b/src/quask.egg-info/SOURCES.txt deleted file mode 100644 index 8db349b..0000000 --- a/src/quask.egg-info/SOURCES.txt +++ /dev/null @@ -1,43 +0,0 @@ -LICENSE.txt -README.md -setup.cfg -setup.py -src/quask/__init__.py -src/quask.egg-info/PKG-INFO -src/quask.egg-info/SOURCES.txt -src/quask.egg-info/dependency_links.txt -src/quask.egg-info/requires.txt -src/quask.egg-info/top_level.txt -src/quask/core/__init__.py -src/quask/core/ansatz.py -src/quask/core/kernel.py -src/quask/core/kernel_factory.py -src/quask/core/kernel_type.py -src/quask/core/operation.py -src/quask/core_implementation/__init__.py -src/quask/core_implementation/braket_kernel.py -src/quask/core_implementation/pennylane_kernel.py -src/quask/core_implementation/qibo_kernel.py -src/quask/core_implementation/qiskit_kernel.py -src/quask/evaluator/__init__.py -src/quask/evaluator/centered_kernel_alignment_evaluator.py -src/quask/evaluator/covering_number_evaluator.py -src/quask/evaluator/ess_model_complexity_evaluator.py -src/quask/evaluator/geometric_difference_evaluator.py -src/quask/evaluator/haar_evaluator.py -src/quask/evaluator/kernel_alignment_evaluator.py -src/quask/evaluator/kernel_evaluator.py -src/quask/evaluator/lie_rank_evaluator.py -src/quask/evaluator/ridge_generalization_evaluator.py -src/quask/evaluator/spectral_bias_evaluator.py -src/quask/optimizer/__init__.py -src/quask/optimizer/base_kernel_optimizer.py -src/quask/optimizer/bayesian_optimizer.py -src/quask/optimizer/greedy_optimizer.py -src/quask/optimizer/metaheuristic_optimizer.py -src/quask/optimizer/reinforcement_learning_optimizer.py -src/quask/optimizer/wide_kernel_environment.py -src/quask/tests/__init__.py -src/quask/tests/kernel_test.py -tests/test_example.py -tests/test_pennylane_kernel.py \ No newline at end of file diff --git a/src/quask.egg-info/dependency_links.txt b/src/quask.egg-info/dependency_links.txt deleted file mode 100644 index 8b13789..0000000 --- a/src/quask.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/quask.egg-info/not-zip-safe b/src/quask.egg-info/not-zip-safe deleted file mode 100644 index 8b13789..0000000 --- a/src/quask.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/quask.egg-info/requires.txt b/src/quask.egg-info/requires.txt deleted file mode 100644 index 648c1b9..0000000 --- a/src/quask.egg-info/requires.txt +++ /dev/null @@ -1,15 +0,0 @@ -pennylane==0.33.1 -pytest>=7.4.3 -numpy>=1.23.5 -pandas>=2.1.2 -scikit-learn>=1.3.1 -scipy>=1.11.2 - -[demo] -jupyter - -[docs] -sphinx>=4.5.0 -sphinx-rtd-theme>=1.0.0 -sphinxcontrib-napoleon>=0.7 -sphinx-autoapi>=2.0.1 diff --git a/src/quask.egg-info/top_level.txt b/src/quask.egg-info/top_level.txt deleted file mode 100644 index ae54f2e..0000000 --- a/src/quask.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -quask diff --git a/src/quask/__version__.py b/src/quask/__version__.py new file mode 100644 index 0000000..c94203d --- /dev/null +++ b/src/quask/__version__.py @@ -0,0 +1,3 @@ +"""Version file.""" + +__version__ = "2.0.0-alpha2" diff --git a/src/quask/core/__init__.py b/src/quask/core/__init__.py index a73d91a..3982361 100644 --- a/src/quask/core/__init__.py +++ b/src/quask/core/__init__.py @@ -1,5 +1,5 @@ -from .operation import Operation -from .ansatz import Ansatz -from .kernel_type import KernelType -from .kernel_factory import KernelFactory -from .kernel import Kernel +from .ansatz import Ansatz as Ansatz +from .kernel import Kernel as Kernel +from .kernel_factory import KernelFactory as KernelFactory +from .kernel_type import KernelType as KernelType +from .operation import Operation as Operation diff --git a/src/quask/core/ansatz.py b/src/quask/core/ansatz.py index 71b18c7..9345328 100644 --- a/src/quask/core/ansatz.py +++ b/src/quask/core/ansatz.py @@ -1,33 +1,46 @@ import numpy as np -from typing import List + from . import Operation class Ansatz: - """ - Class representing the Ansatz as list of Operations - """ - - def __init__(self, n_features: int, n_qubits: int, n_operations: int, allow_midcircuit_measurement=False): - """ - Initialization + """Class representing the Ansatz as list of Operations""" + + def __init__( + self, + n_features: int, + n_qubits: int, + n_operations: int, + allow_midcircuit_measurement=False, + ): + """Initialization :param n_features: number of feature that can be used to parametrize the operation :param n_qubits: number of qubits of the circuit :param n_operations: number of operations :param allow_midcircuit_measurement: True if mid-circuit measurement are allowed """ assert n_qubits >= 2, "This ansatz is specified for >= 2 qubits" - assert n_features > 0, "Cannot have zero or negative number of features" - assert n_operations > 0, "Cannot have zero or negative number or operations" + assert n_features > 0, ( + "Cannot have zero or negative number of features" + ) + assert n_operations > 0, ( + "Cannot have zero or negative number or operations" + ) self.n_features: int = n_features self.n_qubits: int = n_qubits self.n_operations: int = n_operations - self.operation_list: List[Operation] = [None] * n_operations + self.operation_list: list[Operation] = [None] * n_operations self.allow_midcircuit_measurement: bool = allow_midcircuit_measurement - def change_operation(self, operation_index: int, new_feature: int, new_wires: List[int], new_generator: str, new_bandwidth: float): - """ - Overwrite the operation at the given index with a whole new set of data + def change_operation( + self, + operation_index: int, + new_feature: int, + new_wires: list[int], + new_generator: str, + new_bandwidth: float, + ): + """Overwrite the operation at the given index with a whole new set of data :param operation_index: index of the operation :param new_feature: feature parameterizing the operation :param new_wires: wires on which the operation is applied @@ -41,56 +54,73 @@ def change_operation(self, operation_index: int, new_feature: int, new_wires: Li self.change_bandwidth(operation_index, new_bandwidth) def change_bandwidth(self, operation_index: int, new_bandwidth: float): - """ - Overwrite the operation at the given index with a new bandwidth + """Overwrite the operation at the given index with a new bandwidth :param operation_index: index of the operation :param new_bandwidth: bandwidth of the operation :return: None """ - assert 0 <= operation_index < self.n_operations, "Operation index out of bounds" + assert 0 <= operation_index < self.n_operations, ( + "Operation index out of bounds" + ) self.operation_list[operation_index].bandwidth = new_bandwidth def change_generators(self, operation_index: int, new_generator: str): - """ - Overwrite the operation at the given index with a new generator + """Overwrite the operation at the given index with a new generator :param operation_index: index of the operation :param new_generator: generator of the operation :return: None """ - assert 0 <= operation_index < self.n_operations, "Operation index out of bounds" - assert new_generator in Operation.OPERATIONS, f"Unknown generator {new_generator}" + assert 0 <= operation_index < self.n_operations, ( + "Operation index out of bounds" + ) + assert new_generator in Operation.OPERATIONS, ( + f"Unknown generator {new_generator}" + ) if not self.allow_midcircuit_measurement: - assert new_generator not in Operation.MEASUREMENT_OPERATIONS, "Mid-circuit measurement not allowed" + assert new_generator not in Operation.MEASUREMENT_OPERATIONS, ( + "Mid-circuit measurement not allowed" + ) self.operation_list[operation_index].generator = new_generator def change_feature(self, operation_index: int, new_feature: int): - """ - Overwrite the operation at the given index with a new feature + """Overwrite the operation at the given index with a new feature :param operation_index: index of the operation :param new_feature: feature parameterizing the operation :return: None """ - assert 0 <= operation_index < self.n_operations, "Operation index out of bounds" - assert 0 <= new_feature <= self.n_features, f"Feature index out of bounds ({new_feature=})" + assert 0 <= operation_index < self.n_operations, ( + "Operation index out of bounds" + ) + assert 0 <= new_feature <= self.n_features, ( + f"Feature index out of bounds ({new_feature=})" + ) self.operation_list[operation_index].feature = new_feature - def change_wires(self, operation_index: int, new_wires: List[int]): - """ - Overwrite the operation at the given index with a new pair of wires + def change_wires(self, operation_index: int, new_wires: list[int]): + """Overwrite the operation at the given index with a new pair of wires :param operation_index: index of the operation :param new_wires: wires on which the operation is applied :return: None """ - assert 0 <= operation_index < self.n_operations, "Operation index out of bounds" - assert len(new_wires) == 2, "The location is a list of two integers, not less no more" - assert 0 <= new_wires[0] < self.n_qubits, f"First wire index out of bounds ({new_wires=})" - assert 0 <= new_wires[1] < self.n_qubits, f"Second wire index out of bounds ({new_wires=})" - assert new_wires[0] != new_wires[1], f"Cannot specify the same wire twice ({new_wires=})" + assert 0 <= operation_index < self.n_operations, ( + "Operation index out of bounds" + ) + assert len(new_wires) == 2, ( + "The location is a list of two integers, not less no more" + ) + assert 0 <= new_wires[0] < self.n_qubits, ( + f"First wire index out of bounds ({new_wires=})" + ) + assert 0 <= new_wires[1] < self.n_qubits, ( + f"Second wire index out of bounds ({new_wires=})" + ) + assert new_wires[0] != new_wires[1], ( + f"Cannot specify the same wire twice ({new_wires=})" + ) self.operation_list[operation_index].wires = new_wires def get_allowed_operations(self): - """ - Get the list of allowed operation for the ansatz, either only the PAULI_GENERATORS or any operation including measurements + """Get the list of allowed operation for the ansatz, either only the PAULI_GENERATORS or any operation including measurements :return: list of allowed operations """ if self.allow_midcircuit_measurement: @@ -99,48 +129,60 @@ def get_allowed_operations(self): return Operation.PAULI_GENERATORS def initialize_to_identity(self): - """ - Initialize the ansatz to the identity circuit + """Initialize the ansatz to the identity circuit :return: None """ self.operation_list = [None] * self.n_operations for i in range(self.n_operations): - self.operation_list[i] = Operation("II", [0, 1], self.n_features, 1.0) + self.operation_list[i] = Operation( + "II", [0, 1], self.n_features, 1.0 + ) def initialize_to_random_circuit(self): - """ - Initialize the ansatz to a random circuit + """Initialize the ansatz to a random circuit :return: None """ for i in range(self.n_operations): generator = np.random.choice(self.get_allowed_operations()) - wires = np.random.choice(list(range(self.n_qubits)), 2, replace=False) + wires = np.random.choice( + list(range(self.n_qubits)), 2, replace=False + ) feature = np.random.choice(list(range(self.n_features + 1))) bandwidth = np.random.uniform(0.0, 1.0) - self.operation_list[i] = Operation(generator, wires, feature, bandwidth) + self.operation_list[i] = Operation( + generator, wires, feature, bandwidth + ) def initialize_to_known_ansatz(self, ansatz): - """ - Initialize the ansatz form an already given element + """Initialize the ansatz form an already given element + :param ansatz: Given ansatz :return: None """ self.initialize_to_identity() for i in range(self.n_operations): op: Operation = ansatz.operation_list[i] - self.change_operation(i, op.feature, op.wires, op.generator, op.bandwidth) + self.change_operation( + i, op.feature, op.wires, op.generator, op.bandwidth + ) def to_numpy(self): - """ - Serialize the ansatz to a numpy array + """Serialize the ansatz to a numpy array :return: numpy array """ return np.array([op.to_numpy() for op in self.operation_list]).ravel() @staticmethod - def from_numpy(array, n_features, n_qubits, n_operations, allow_midcircuit_measurement, shift_second_wire=False): - """ - Deserialize the ansatz from a numpy array + def from_numpy( + array, + n_features, + n_qubits, + n_operations, + allow_midcircuit_measurement, + shift_second_wire=False, + ): + """Deserialize the ansatz from a numpy array. + :param array: numpy array :param n_features: number of feature that can be used to parametrize the operation :param n_qubits: number of qubits of the circuit @@ -148,21 +190,32 @@ def from_numpy(array, n_features, n_qubits, n_operations, allow_midcircuit_measu :param allow_midcircuit_measurement: True if mid-circuit measurement are allowed :return: Ansatz deserialized """ - ans = Ansatz(n_features, n_qubits, n_operations, allow_midcircuit_measurement) + ans = Ansatz( + n_features, n_qubits, n_operations, allow_midcircuit_measurement + ) ans.initialize_to_identity() for i in range(n_operations): # feature -> wires -> generator -> bandwidth generator = np.rint(array[i * 5]).astype(int) - wires = [np.rint(array[i * 5 + 1]).astype(int), np.rint(array[i * 5 + 2]).astype(int)] + wires = [ + np.rint(array[i * 5 + 1]).astype(int), + np.rint(array[i * 5 + 2]).astype(int), + ] feature = np.rint(array[i * 5 + 3]).astype(int) bandwidth = np.round(array[i * 5 + 4], decimals=4) if shift_second_wire and wires[1] >= wires[0]: wires[1] += 1 - ans.change_operation(i, feature, wires, Operation.OPERATIONS[generator], bandwidth) + ans.change_operation( + i, feature, wires, Operation.OPERATIONS[generator], bandwidth + ) return ans def __str__(self): + """Gets the function string. + + :return: str: _description_ + """ return str(self.operation_list) def __repr__(self): - return self.__str__() \ No newline at end of file + return self.__str__() diff --git a/src/quask/core/kernel.py b/src/quask/core/kernel.py index 2bbd9bd..45caa8a 100644 --- a/src/quask/core/kernel.py +++ b/src/quask/core/kernel.py @@ -1,34 +1,35 @@ -import numpy as np -from scipy.spatial.distance import cdist from abc import ABC, abstractmethod -from . import Ansatz, KernelType, KernelFactory + +import numpy as np + +from . import Ansatz, KernelFactory, KernelType class Kernel(ABC): - """ - Abstract class representing a kernel object - """ + """Abstract class representing a kernel object""" - PAULIS = ['I', 'X', 'Y', 'Z'] + PAULIS = ["I", "X", "Y", "Z"] def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType): - """ - Initialization. + """Initialization. :param ansatz: Ansatz object representing the unitary transformation :param measurement: Pauli string representing the measurement :param type: type of kernel, fidelity or observable """ - assert ansatz.n_qubits == len(measurement), "Measurement qubits and number of ansatz qubits do not match" - assert len(set(measurement).difference(Kernel.PAULIS)) == 0, "Unknown Pauli in measurement" + assert ansatz.n_qubits == len(measurement), ( + "Measurement qubits and number of ansatz qubits do not match" + ) + assert len(set(measurement).difference(Kernel.PAULIS)) == 0, ( + "Unknown Pauli in measurement" + ) self.ansatz = ansatz self.measurement = measurement self.type = type self.last_probabilities = None def get_last_probabilities(self): - """ - Get the last kernel value calculated. + """Get the last kernel value calculated. :return: last probability array """ @@ -36,8 +37,7 @@ def get_last_probabilities(self): @abstractmethod def kappa(self, x1, x2) -> float: - """ - Calculate the kernel given two datapoints. + """Calculate the kernel given two datapoints. :param x1: first data point :param x2: second data point @@ -47,8 +47,7 @@ def kappa(self, x1, x2) -> float: @abstractmethod def phi(self, x) -> float: - """ - Calculate the feature map of a data point. + """Calculate the feature map of a data point. :param x: data point :return: feature map of the datapoint as numpy array @@ -56,16 +55,16 @@ def phi(self, x) -> float: pass def get_allowed_operations(self): - """ - Get the list of allowed operations. + """Get the list of allowed operations. :return: list of generators allowed (the information is saved in the ansatz) """ return self.ansatz.get_allowed_operations() - def build_kernel(self, X1: np.ndarray, X2: np.ndarray, matrix: str=None) -> np.ndarray: - """ - Build a kernel. + def build_kernel( + self, X1: np.ndarray, X2: np.ndarray, matrix: str = None + ) -> np.ndarray: + """Build a kernel. :param X1: a single datapoint or a list of datapoints :param X2: a single datapoint or a list of datapoints @@ -78,10 +77,14 @@ def build_kernel(self, X1: np.ndarray, X2: np.ndarray, matrix: str=None) -> np.n return self.kappa(X1, X2) else: return self.phi(X1) * self.phi(X2) - + # if you gave me multiple samples - assert self.ansatz.n_features == X1.shape[1], "Number of features and X1.shape[1] do not match" - assert self.ansatz.n_features == X2.shape[1], "Number of features and X2.shape[1] do not match" + assert self.ansatz.n_features == X1.shape[1], ( + "Number of features and X1.shape[1] do not match" + ) + assert self.ansatz.n_features == X2.shape[1], ( + "Number of features and X2.shape[1] do not match" + ) if self.type in [KernelType.FIDELITY, KernelType.SWAP_TEST]: if matrix == "train": return self.kernel_train_matrix(X1, X2) @@ -98,39 +101,48 @@ def kernel_train_matrix(self, X1, X2): N = X1.shape[0] kernel_matrix = np.full((N, N), np.nan) for i in range(kernel_matrix.shape[0]): - for j in range(i,kernel_matrix.shape[1]): + for j in range(i, kernel_matrix.shape[1]): if i == j: - kernel_matrix[i,j] = 1 + kernel_matrix[i, j] = 1 else: - kernel_matrix[i,j] = self.kappa(X1[i], X2[j]) - kernel_matrix[j,i] = kernel_matrix[i,j] + kernel_matrix[i, j] = self.kappa(X1[i], X2[j]) + kernel_matrix[j, i] = kernel_matrix[i, j] return kernel_matrix - + def kernel_test_matrix(self, X1, X2): N_tr = X2.shape[0] N_te = X1.shape[0] kernel_matrix = np.full((N_te, N_tr), np.nan) for i in range(kernel_matrix.shape[0]): for j in range(kernel_matrix.shape[1]): - kernel_matrix[i,j] = self.kappa(X1[i],X2[j]) + kernel_matrix[i, j] = self.kappa(X1[i], X2[j]) return kernel_matrix def to_numpy(self): - """ - Serialize the kernel object as a numpy array. + """Serialize the kernel object as a numpy array. :return: numpy array """ ansatz_numpy = self.ansatz.to_numpy() - measurement_numpy = np.array([Kernel.PAULIS.index(p) for p in self.measurement]) + measurement_numpy = np.array( + [Kernel.PAULIS.index(p) for p in self.measurement] + ) type_numpy = np.array([self.type.value]) - return np.concatenate([ansatz_numpy, measurement_numpy, type_numpy], dtype=object).ravel() + return np.concatenate( + [ansatz_numpy, measurement_numpy, type_numpy], dtype=object + ).ravel() @staticmethod - def from_numpy(array, n_features, n_qubits, n_operations, allow_midcircuit_measurement, shift_second_wire=False): - """ - Deserialize the object from a numpy array. - + def from_numpy( + array, + n_features, + n_qubits, + n_operations, + allow_midcircuit_measurement, + shift_second_wire=False, + ): + """Deserialize the object from a numpy array. + :param array: numpy array :param n_features: number of feature that can be used to parametrize the operation :param n_qubits: number of qubits of the circuit @@ -138,12 +150,23 @@ def from_numpy(array, n_features, n_qubits, n_operations, allow_midcircuit_measu :param allow_midcircuit_measurement: True if mid-circuit measurement are allowed :return: Kernel object (created using default instance in KernelFactory) """ - assert len(array) == 5 * n_operations + n_qubits + 1, f"Size of the array is {len(array)} instead of {5 * n_operations + n_qubits + 1}" - ansatz_numpy = array[:n_operations*5] - measurement_numpy = array[n_operations*5:-1] + assert len(array) == 5 * n_operations + n_qubits + 1, ( + f"Size of the array is {len(array)} instead of {5 * n_operations + n_qubits + 1}" + ) + ansatz_numpy = array[: n_operations * 5] + measurement_numpy = array[n_operations * 5 : -1] type_numpy = array[-1] - ansatz = Ansatz.from_numpy(ansatz_numpy, n_features, n_qubits, n_operations, allow_midcircuit_measurement, shift_second_wire) - measurement = "".join(Kernel.PAULIS[np.rint(i).astype(int)] for i in measurement_numpy) + ansatz = Ansatz.from_numpy( + ansatz_numpy, + n_features, + n_qubits, + n_operations, + allow_midcircuit_measurement, + shift_second_wire, + ) + measurement = "".join( + Kernel.PAULIS[np.rint(i).astype(int)] for i in measurement_numpy + ) the_type = KernelType.convert(type_numpy) kernel = KernelFactory.create_kernel(ansatz, measurement, the_type) return kernel @@ -155,4 +178,10 @@ def __repr__(self): return self.__str__() def __copy__(self): - return Kernel.from_numpy(self.to_numpy(), self.ansatz.n_features, self.ansatz.n_qubits, self.ansatz.n_operations, self.ansatz.allow_midcircuit_measurement) + return Kernel.from_numpy( + self.to_numpy(), + self.ansatz.n_features, + self.ansatz.n_qubits, + self.ansatz.n_operations, + self.ansatz.allow_midcircuit_measurement, + ) diff --git a/src/quask/core/kernel_factory.py b/src/quask/core/kernel_factory.py index 2366075..3cab975 100644 --- a/src/quask/core/kernel_factory.py +++ b/src/quask/core/kernel_factory.py @@ -2,12 +2,11 @@ class KernelFactory: - """ - Instantiate the concrete object from classes that inherit from (abstract class) Kernel. + """Instantiate the concrete object from classes that inherit from (abstract class) Kernel. Implement the self-registering factory pattern """ - # to see the implementations and the current_implementation you can call it in this way: ._KernelFactory__implementations, ._KernelFactory__current_implementation + # to see the implementations and the current_implementation you can call it in this way: ._KernelFactory__implementations, ._KernelFactory__current_implementation __implementations = {} """Dictionary containing pairs (name, function to create the kernel).""" @@ -16,36 +15,43 @@ class KernelFactory: @staticmethod def add_implementation(name, fn): - """ - Add the current closure function as one of the possible implementations available + """Add the current closure function as one of the possible implementations available :param name: name of the implementation :param fn: function that creates the quantum kernel """ if name in KernelFactory.__implementations: - raise ValueError("This name is already present in the register of available implementations") + raise ValueError( + "This name is already present in the register of available implementations" + ) if fn.__code__.co_argcount != 3: - raise ValueError("The function must have these three arguments, 'ansatz', 'measurement', and 'type': the number of argument does not match") - if fn.__code__.co_varnames != ('ansatz', 'measurement', 'type'): - raise ValueError("The function must have these three arguments, 'ansatz', 'measurement', and 'type': the name of some argument does not match") + raise ValueError( + "The function must have these three arguments, 'ansatz', 'measurement', and 'type': the number of argument does not match" + ) + if fn.__code__.co_varnames != ("ansatz", "measurement", "type"): + raise ValueError( + "The function must have these three arguments, 'ansatz', 'measurement', and 'type': the name of some argument does not match" + ) KernelFactory.__implementations[name] = fn - @staticmethod def set_current_implementation(name): if name not in KernelFactory.__implementations: - raise ValueError("This name is not present in the register of available implementations") + raise ValueError( + "This name is not present in the register of available implementations" + ) KernelFactory.__current_implementation = name @staticmethod def create_kernel(ansatz: Ansatz, measurement: str, type: KernelType): - """ - Create a kernel object using the default class chosen. + """Create a kernel object using the default class chosen. :param ansatz: Ansatz object representing the unitary transformation :param measurement: Pauli string representing the measurement :param type: type of kernel, fidelity, swap test or observable :return: kernel object of the default concrete class """ - fn = KernelFactory.__implementations[KernelFactory.__current_implementation] - return fn(ansatz, measurement, type) \ No newline at end of file + fn = KernelFactory.__implementations[ + KernelFactory.__current_implementation + ] + return fn(ansatz, measurement, type) diff --git a/src/quask/core/kernel_type.py b/src/quask/core/kernel_type.py index 655f14c..a1af4f8 100644 --- a/src/quask/core/kernel_type.py +++ b/src/quask/core/kernel_type.py @@ -2,9 +2,8 @@ class KernelType(Enum): - """ - Possible types of kernel - """ + """Possible types of kernel""" + FIDELITY = 0 OBSERVABLE = 1 SWAP_TEST = 2 @@ -13,9 +12,9 @@ class KernelType(Enum): def convert(item): if isinstance(item, KernelType): return item - elif item < 0.5: + elif item < 0.5: return KernelType.FIDELITY - elif 0.5 <= item < 1.5: + elif 0.5 <= item < 1.5: return KernelType.OBSERVABLE - else: + else: return KernelType.SWAP_TEST diff --git a/src/quask/core/operation.py b/src/quask/core/operation.py index 54caaf3..4bd5081 100644 --- a/src/quask/core/operation.py +++ b/src/quask/core/operation.py @@ -1,41 +1,48 @@ -import numpy as np -from typing import List import itertools +import numpy as np + class Operation: - """ - Class representing a 2-qubit rotational quantum gates $exp(-i \theta \sigma_1 \otimes \sigma_2)$ - """ + """Class representing a 2-qubit rotational quantum gates $exp(-i \theta \\sigma_1 \\otimes \\sigma_2)$""" - PAULI_GENERATORS = list(a + b for a, b in itertools.product(["I", "X", "Y", "Z"], repeat=2)) + PAULI_GENERATORS = list( + a + b for a, b in itertools.product(["I", "X", "Y", "Z"], repeat=2) + ) MEASUREMENT_OPERATIONS = ["IM", "MI"] OPERATIONS = PAULI_GENERATORS + MEASUREMENT_OPERATIONS - def __init__(self, generator: str, wires: List[int], feature: int, bandwidth: float): - """ - Operation initializer + def __init__( + self, generator: str, wires: list[int], feature: int, bandwidth: float + ): + """Operation initializer :param generator: one of the elements of Operation.OPERATIONS :param wires: pair of integers :param feature: index of the feature parameterizing the element (can be -1 for constant feature '1') :param bandwidth: bandwidth parameter in range [0,1] """ self.generator: str = generator - self.wires: List[int] = wires + self.wires: list[int] = wires self.feature: int = feature self.bandwidth: float = bandwidth def to_numpy(self): - """ - Serialize the Operation object to a numpy array format + """Serialize the Operation object to a numpy array format :return: numpy array representing the operation """ - return np.array([Operation.OPERATIONS.index(self.generator), self.wires[0], self.wires[1], self.feature, self.bandwidth]) + return np.array( + [ + Operation.OPERATIONS.index(self.generator), + self.wires[0], + self.wires[1], + self.feature, + self.bandwidth, + ] + ) @staticmethod def from_numpy(array): - """ - Deserialize the operation object given its numpy array description + """Deserialize the operation object given its numpy array description :param array: numpy array :return: Operation object """ @@ -50,4 +57,4 @@ def __str__(self): return f"-i {self.bandwidth:0.2f} * x[{self.feature}] {self.generator}^({self.wires[0]},{self.wires[1]})" def __repr__(self): - return self.__str__() \ No newline at end of file + return self.__str__() diff --git a/src/quask/core_implementation/__init__.py b/src/quask/core_implementation/__init__.py index 3eafad0..43d3462 100644 --- a/src/quask/core_implementation/__init__.py +++ b/src/quask/core_implementation/__init__.py @@ -1,4 +1,4 @@ -from .pennylane_kernel import PennylaneKernel -from .qiskit_kernel import QiskitKernel -from .braket_kernel import BraketKernel -from .qibo_kernel import QiboKernel +from .braket_kernel import BraketKernel as BraketKernel +from .pennylane_kernel import PennylaneKernel as PennylaneKernel +from .qibo_kernel import QiboKernel as QiboKernel +from .qiskit_kernel import QiskitKernel as QiskitKernel diff --git a/src/quask/core_implementation/braket_kernel.py b/src/quask/core_implementation/braket_kernel.py index 137bd28..734fd12 100644 --- a/src/quask/core_implementation/braket_kernel.py +++ b/src/quask/core_implementation/braket_kernel.py @@ -1,23 +1,29 @@ -import numpy as np import pennylane as qml -from ..core import Ansatz, Kernel, KernelType + +from ..core import Ansatz, KernelType from .pennylane_kernel import PennylaneKernel class BraketKernel(PennylaneKernel): - - def create_device(self, n_qubits): + def create_device(self, n_qubits): return qml.device( - "braket.aws.qubit", - device_arn=self.device_name, - s3_destination_folder=(self.s3_bucket, self.s3_prefix), - wires=n_qubits + "braket.aws.qubit", + device_arn=self.device_name, + s3_destination_folder=(self.s3_bucket, self.s3_prefix), + wires=n_qubits, ) - - def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType, - device_name: str, s3_bucket: str, s3_prefix: str, n_shots: int = None): - """ - Initialization. + + def __init__( + self, + ansatz: Ansatz, + measurement: str, + type: KernelType, + device_name: str, + s3_bucket: str, + s3_prefix: str, + n_shots: int = None, + ): + """Initialization. :param ansatz: Ansatz object representing the unitary transformation :param measurement: Pauli string representing the measurement @@ -25,8 +31,6 @@ def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType, :param device_name: name of the device, 'default.qubit' for noiseless simulation :param n_shots: number of shots when sampling the solution, None to have infinity """ - super().__init__(ansatz, measurement, type, device_name, n_shots) self.s3_bucket = s3_bucket self.s3_prefix = s3_prefix - diff --git a/src/quask/core_implementation/pennylane_kernel.py b/src/quask/core_implementation/pennylane_kernel.py index 8db054c..cd0edea 100644 --- a/src/quask/core_implementation/pennylane_kernel.py +++ b/src/quask/core_implementation/pennylane_kernel.py @@ -1,13 +1,22 @@ import numpy as np import pennylane as qml + from ..core import Ansatz, Kernel, KernelType def AnsatzTemplate(ansatz: Ansatz, params: np.ndarray, wires: np.ndarray): for operation in ansatz.operation_list: if "M" not in operation.generator: - feature = np.pi if operation.feature == ansatz.n_features else params[operation.feature] - qml.PauliRot(operation.bandwidth * feature, operation.generator, wires=wires[operation.wires]) + feature = ( + np.pi + if operation.feature == ansatz.n_features + else params[operation.feature] + ) + qml.PauliRot( + operation.bandwidth * feature, + operation.generator, + wires=wires[operation.wires], + ) elif operation.generator[0] == "M": qml.measure(wires[operation.wires[0]]) else: @@ -16,21 +25,26 @@ def AnsatzTemplate(ansatz: Ansatz, params: np.ndarray, wires: np.ndarray): def ChangeBasis(measurement: str): for i, pauli in enumerate(measurement): - if pauli == 'X': + if pauli == "X": qml.Hadamard(wires=[i]) - elif pauli == 'Y': + elif pauli == "Y": qml.S(wires=[i]) qml.Hadamard(wires=[i]) class PennylaneKernel(Kernel): - - def create_device(self, n_qubits): + def create_device(self, n_qubits): return qml.device(self.device_name, wires=n_qubits, shots=self.n_shots) - - def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType, device_name: str = "default.qubit", n_shots: int = None): - """ - Initialization. + + def __init__( + self, + ansatz: Ansatz, + measurement: str, + type: KernelType, + device_name: str = "default.qubit", + n_shots: int = None, + ): + """Initialization. :param ansatz: Ansatz object representing the unitary transformation :param measurement: Pauli string representing the measurement @@ -38,14 +52,15 @@ def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType, device_na :param device_name: name of the device, 'default.qubit' for noiseless simulation :param n_shots: number of shots when sampling the solution, None to have infinity """ - super().__init__(ansatz, measurement, type) self.device_name = device_name self.n_shots = n_shots dev = self.create_device(self.ansatz.n_qubits) wires = np.array(list(range(self.ansatz.n_qubits))) - measurement_wires = np.array([i for i in wires if measurement[i] != 'I']) + measurement_wires = np.array( + [i for i in wires if measurement[i] != "I"] + ) if len(measurement_wires) == 0: measurement_wires = range(self.ansatz.n_qubits) @@ -66,16 +81,16 @@ def observable_phi(x): self.observable_phi = observable_phi - dev_swap = self.create_device(1+2*self.ansatz.n_qubits) + dev_swap = self.create_device(1 + 2 * self.ansatz.n_qubits) n = self.ansatz.n_qubits @qml.qnode(dev_swap) def swap_kernel(x1, x2): qml.Hadamard(wires=[0]) - AnsatzTemplate(self.ansatz, x1, wires=1+wires) - AnsatzTemplate(self.ansatz, x2, wires=1+n+wires) + AnsatzTemplate(self.ansatz, x1, wires=1 + wires) + AnsatzTemplate(self.ansatz, x2, wires=1 + n + wires) for j in measurement_wires: - qml.CSWAP(wires=[0, 1+j, 1+n+j]) + qml.CSWAP(wires=[0, 1 + j, 1 + n + j]) qml.Hadamard(wires=[0]) return qml.probs(wires=[0]) @@ -89,7 +104,7 @@ def kappa(self, x1, x2) -> float: probabilities = self.fidelity_kernel(x1, x2) self.last_probabilities = probabilities return probabilities[0] - + elif self.type == KernelType.SWAP_TEST: probabilities = self.swap_kernel(x1, x2) self.last_probabilities = probabilities @@ -99,8 +114,13 @@ def phi(self, x) -> float: if self.type == KernelType.OBSERVABLE: probabilities = self.observable_phi(x) self.last_probabilities = probabilities - parity = lambda i: 1 if bin(i).count('1') % 2 == 0 else -1 - probabilities = np.array([parity(i) * probabilities[i] for i in range(len(probabilities))]) + parity = lambda i: 1 if bin(i).count("1") % 2 == 0 else -1 + probabilities = np.array( + [ + parity(i) * probabilities[i] + for i in range(len(probabilities)) + ] + ) # sum_probabilities = np.sum(probabilities) # print(f"{sum_probabilities=} {probabilities=}") return np.sum(probabilities) @@ -109,5 +129,6 @@ def phi(self, x) -> float: raise ValueError("phi not available for fidelity kernels") else: - raise ValueError("Unknown type, possible erroneous loading from a numpy array") - + raise ValueError( + "Unknown type, possible erroneous loading from a numpy array" + ) diff --git a/src/quask/core_implementation/qibo_kernel.py b/src/quask/core_implementation/qibo_kernel.py index a7daae4..9adc644 100644 --- a/src/quask/core_implementation/qibo_kernel.py +++ b/src/quask/core_implementation/qibo_kernel.py @@ -1,5 +1,5 @@ -import numpy as np -from ..core import Ansatz, Kernel, KernelType +from ..core import Kernel + class QiboKernel(Kernel): pass diff --git a/src/quask/core_implementation/qiskit_kernel.py b/src/quask/core_implementation/qiskit_kernel.py index 3249b06..8c9f189 100644 --- a/src/quask/core_implementation/qiskit_kernel.py +++ b/src/quask/core_implementation/qiskit_kernel.py @@ -1,31 +1,40 @@ import numpy as np -from ..core import Ansatz, Kernel, KernelType # from qiskit import Aer, BasicAer, QuantumCircuit -from qiskit.circuit import QuantumCircuit, ParameterVector +from qiskit.circuit import ParameterVector, QuantumCircuit from qiskit.circuit.library import PauliEvolutionGate -from qiskit_ibm_runtime import QiskitRuntimeService, IBMBackend +from qiskit.primitives import StatevectorEstimator, StatevectorSampler from qiskit.quantum_info import SparsePauliOp, Statevector -from qiskit_ibm_runtime import SamplerV2 as IBMSampler +from qiskit.result import QuasiDistribution +from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager from qiskit_ibm_runtime import EstimatorV2 as IBMEstimator -from qiskit_ibm_runtime import RuntimeJobV2 +from qiskit_ibm_runtime import IBMBackend, QiskitRuntimeService, RuntimeJobV2 +from qiskit_ibm_runtime import SamplerV2 as IBMSampler +from qiskit_ibm_runtime.options import EstimatorOptions as eop + # from qiskit_ibm_runtime import Options from qiskit_ibm_runtime.options import SamplerOptions as sop -from qiskit_ibm_runtime.options import EstimatorOptions as eop -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager -from qiskit.result import QuasiDistribution -from qiskit.primitives import BackendSamplerV2 as BackendSampler -from qiskit.primitives import StatevectorSampler, StatevectorEstimator + +from ..core import Ansatz, Kernel, KernelType + # from qiskit_aer.primitives import Sampler as AerSampler # from qiskit_aer.primitives import Estimator as AerEstimator -class QiskitKernel(Kernel): - def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType, - platform: str="finite_shots", backend: IBMBackend=None, n_shots: int=2048, - options: dict=None, optimization_level: int=2, layout: list=None): - """ - Initialization. +class QiskitKernel(Kernel): + def __init__( + self, + ansatz: Ansatz, + measurement: str, + type: KernelType, + platform: str = "finite_shots", + backend: IBMBackend = None, + n_shots: int = 2048, + options: dict = None, + optimization_level: int = 2, + layout: list = None, + ): + """Initialization. :param ansatz: Ansatz object representing the unitary transformation :param measurement: Pauli string representing the measurement @@ -46,10 +55,20 @@ def __init__(self, ansatz: Ansatz, measurement: str, type: KernelType, self.optimization_level = optimization_level self.layout = layout - def get_backend(self, channel: str, ibm_token: str, group_instance: str, device: str=None): - service = QiskitRuntimeService(channel=channel, token=ibm_token, instance=group_instance) + def get_backend( + self, + channel: str, + ibm_token: str, + group_instance: str, + device: str = None, + ): + service = QiskitRuntimeService( + channel=channel, token=ibm_token, instance=group_instance + ) if device == None: - self.backend = service.least_busy(operational=True, simulator=False) + self.backend = service.least_busy( + operational=True, simulator=False + ) else: self.backend = service.backend(device) print(f"{self.backend.name} selected") @@ -57,48 +76,54 @@ def get_backend(self, channel: str, ibm_token: str, group_instance: str, device: def get_sampler_options(self): sampler_options = sop( - default_shots = self.n_shots, - dynamical_decoupling = { - "enable": bool(self.options["dynamical_decoupling"]["sequence_type"]), - "sequence_type": self.options["dynamical_decoupling"]["sequence_type"] + default_shots=self.n_shots, + dynamical_decoupling={ + "enable": bool( + self.options["dynamical_decoupling"]["sequence_type"] + ), + "sequence_type": self.options["dynamical_decoupling"][ + "sequence_type" + ], }, - twirling = { + twirling={ "enable_gates": self.options["twirling"]["enable_gates"], "enable_measure": self.options["twirling"]["enable_measure"], "num_randomizations": "auto", - "shots_per_randomization": "auto" - } + "shots_per_randomization": "auto", + }, ) return sampler_options - + def get_estimator_options(self): estimator_options = eop( - default_shots = self.n_shots, - dynamical_decoupling = { - "enable": bool(self.options["dynamical_decoupling"]["sequence_type"]), - "sequence_type": self.options["dynamical_decoupling"]["sequence_type"] + default_shots=self.n_shots, + dynamical_decoupling={ + "enable": bool( + self.options["dynamical_decoupling"]["sequence_type"] + ), + "sequence_type": self.options["dynamical_decoupling"][ + "sequence_type" + ], }, - twirling = { + twirling={ "enable_gates": self.options["twirling"]["enable_gates"], "enable_measure": self.options["twirling"]["enable_measure"], "num_randomizations": "auto", - "shots_per_randomization": "auto" - } + "shots_per_randomization": "auto", + }, ) return estimator_options - + def get_sampler(self): if self.platform == "infty_shots": return Statevector - + elif self.platform == "finite_shots": - return StatevectorSampler( - default_shots=self.n_shots - ) + return StatevectorSampler(default_shots=self.n_shots) elif self.platform == "ibm_quantum": options = self.get_sampler_options() return IBMSampler(backend=self.backend, options=options) - + def get_estimator(self): if self.platform == "infty_shots": return StatevectorEstimator @@ -112,39 +137,43 @@ def get_running_method(self, qc: QuantumCircuit): res = Statevector.from_instruction(qc).data[0].real elif self.platform == "finite_shots": qc.measure_all() - counts = ( - sampler.run([qc]).result()[0].data.meas.get_int_counts() - ) + counts = sampler.run([qc]).result()[0].data.meas.get_int_counts() dist = QuasiDistribution( - {meas: count / self.n_shots for meas, count in counts.items()}, shots=self.n_shots + {meas: count / self.n_shots for meas, count in counts.items()}, + shots=self.n_shots, ) res = dist.get(0, 0.0) elif self.platform == "ibm_quantum": qc.measure_all() logical_circuit = qc - pm = generate_preset_pass_manager(optimization_level=self.optimization_level, backend=self.backend, initial_layout=self.layout) + pm = generate_preset_pass_manager( + optimization_level=self.optimization_level, + backend=self.backend, + initial_layout=self.layout, + ) physical_circuit = pm.run(logical_circuit) job = sampler.run([physical_circuit]) print(f"Job sent to hardware. Job ID: {job.job_id()}") res = job return res - + def get_job_results(self, job: RuntimeJobV2): counts = job.result()[0].data.meas.get_int_counts() dist = QuasiDistribution( - {meas: count / self.n_shots for meas, count in counts.items()}, shots=self.n_shots + {meas: count / self.n_shots for meas, count in counts.items()}, + shots=self.n_shots, ) res = dist.get(0, 0.0) return res def get_qiskit_ansatz(self): n_params = self.ansatz.n_features - params = ParameterVector('p', n_params) + params = ParameterVector("p", n_params) qc = QuantumCircuit(self.ansatz.n_qubits) for operation in self.ansatz.operation_list: operator = SparsePauliOp(operation.generator) - rotation = operation.bandwidth*params[operation.feature]/2 + rotation = operation.bandwidth * params[operation.feature] / 2 evo = PauliEvolutionGate(operator, time=rotation) qc.append(evo, operation.wires) return qc @@ -158,30 +187,49 @@ def kappa(self, x1: np.ndarray, x2: np.ndarray) -> float: elif self.type == KernelType.FIDELITY: qc = QuantumCircuit(self.ansatz.n_qubits, self.ansatz.n_qubits) - qc.append(self.get_qiskit_ansatz().assign_parameters(x1.tolist()), range(self.ansatz.n_qubits)) - qc.append(self.get_qiskit_ansatz().assign_parameters(x2.tolist()).inverse(), range(self.ansatz.n_qubits)) + qc.append( + self.get_qiskit_ansatz().assign_parameters(x1.tolist()), + range(self.ansatz.n_qubits), + ) + qc.append( + self.get_qiskit_ansatz() + .assign_parameters(x2.tolist()) + .inverse(), + range(self.ansatz.n_qubits), + ) probabilities = self.get_running_method(qc) return probabilities - + elif self.type == KernelType.SWAP_TEST: - qc = QuantumCircuit(1+2*self.ansatz.n_qubits, 1) + qc = QuantumCircuit(1 + 2 * self.ansatz.n_qubits, 1) qc.h(0) - qc.append(self.get_qiskit_ansatz().assign_parameters(x1.tolist() + [1.0]), range(1, 1+self.ansatz.n_qubits)) - qc.append(self.get_qiskit_ansatz().assign_parameters(x2.tolist() + [1.0]), range(self.ansatz.n_qubits)) + qc.append( + self.get_qiskit_ansatz().assign_parameters( + x1.tolist() + [1.0] + ), + range(1, 1 + self.ansatz.n_qubits), + ) + qc.append( + self.get_qiskit_ansatz().assign_parameters( + x2.tolist() + [1.0] + ), + range(self.ansatz.n_qubits), + ) for i in range(self.ansatz.n_qubits): - qc.cswap(0, 1+i, 1+self.ansatz.n_qubits+i) + qc.cswap(0, 1 + i, 1 + self.ansatz.n_qubits + i) qc.h(0) qc.measure(0, 0) job = self.get_sampler().run(qc) probabilities = job.result().quasi_dists[0] return probabilities.get(0, 0.0) - + def phi(self, x: np.ndarray) -> float: if self.type == KernelType.OBSERVABLE: - assert len(x) == self.ansatz.n_features complete_features = x.tolist() + [1.0] - circuit = self.get_qiskit_ansatz().bind_parameters(complete_features) + circuit = self.get_qiskit_ansatz().bind_parameters( + complete_features + ) observable = SparsePauliOp(self.measurement) job = self.get_estimator().run(circuit, observable) exp_val = job.result().values[0] @@ -191,4 +239,6 @@ def phi(self, x: np.ndarray) -> float: raise ValueError("phi not available for fidelity kernels") else: - raise ValueError("Unknown type, possible erroneous loading from a numpy array") \ No newline at end of file + raise ValueError( + "Unknown type, possible erroneous loading from a numpy array" + ) diff --git a/src/quask/evaluator/__init__.py b/src/quask/evaluator/__init__.py index 5a19973..f016a0b 100644 --- a/src/quask/evaluator/__init__.py +++ b/src/quask/evaluator/__init__.py @@ -1,10 +1,24 @@ -from .kernel_evaluator import KernelEvaluator -from .lie_rank_evaluator import LieRankEvaluator -from .haar_evaluator import HaarEvaluator -from .covering_number_evaluator import CoveringNumberEvaluator -from .kernel_alignment_evaluator import KernelAlignmentEvaluator -from .centered_kernel_alignment_evaluator import CenteredKernelAlignmentEvaluator -from .spectral_bias_evaluator import SpectralBiasEvaluator -from .ridge_generalization_evaluator import RidgeGeneralizationEvaluator -from .geometric_difference_evaluator import GeometricDifferenceEvaluator -from .ess_model_complexity_evaluator import EssModelComplexityEvaluator +from .centered_kernel_alignment_evaluator import ( + CenteredKernelAlignmentEvaluator as CenteredKernelAlignmentEvaluator, +) +from .covering_number_evaluator import ( + CoveringNumberEvaluator as CoveringNumberEvaluator, +) +from .ess_model_complexity_evaluator import ( + EssModelComplexityEvaluator as EssModelComplexityEvaluator, +) +from .geometric_difference_evaluator import ( + GeometricDifferenceEvaluator as GeometricDifferenceEvaluator, +) +from .haar_evaluator import HaarEvaluator as HaarEvaluator +from .kernel_alignment_evaluator import ( + KernelAlignmentEvaluator as KernelAlignmentEvaluator, +) +from .kernel_evaluator import KernelEvaluator as KernelEvaluator +from .lie_rank_evaluator import LieRankEvaluator as LieRankEvaluator +from .ridge_generalization_evaluator import ( + RidgeGeneralizationEvaluator as RidgeGeneralizationEvaluator, +) +from .spectral_bias_evaluator import ( + SpectralBiasEvaluator as SpectralBiasEvaluator, +) diff --git a/src/quask/evaluator/centered_kernel_alignment_evaluator.py b/src/quask/evaluator/centered_kernel_alignment_evaluator.py index 48448fa..e997029 100644 --- a/src/quask/evaluator/centered_kernel_alignment_evaluator.py +++ b/src/quask/evaluator/centered_kernel_alignment_evaluator.py @@ -1,18 +1,19 @@ import numpy as np + from ..core import Kernel -from . import KernelEvaluator, KernelAlignmentEvaluator +from . import KernelAlignmentEvaluator, KernelEvaluator class CenteredKernelAlignmentEvaluator(KernelEvaluator): - """ - Kernel compatibility measure based on the centered kernel-target alignment + """Kernel compatibility measure based on the centered kernel-target alignment See: Cortes, Corinna, Mehryar Mohri, and Afshin Rostamizadeh. "Algorithms for learning kernels based on centered alignment." The Journal of Machine Learning Research 13.1 (2012): 795-828. """ - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -23,12 +24,11 @@ def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): K = kernel.build_kernel(X, X) Kc = CenteredKernelAlignmentEvaluator.center_kernel(K) kta = KernelAlignmentEvaluator.kta(Kc, y) - return - np.abs(kta) + return -np.abs(kta) @staticmethod def center_kernel(K): - """ - Center a kernel (subtract its mean value) + """Center a kernel (subtract its mean value) :param K: kernel matrix :return: centered kernel """ diff --git a/src/quask/evaluator/covering_number_evaluator.py b/src/quask/evaluator/covering_number_evaluator.py index ce155b2..ef9174f 100644 --- a/src/quask/evaluator/covering_number_evaluator.py +++ b/src/quask/evaluator/covering_number_evaluator.py @@ -1,18 +1,19 @@ import numpy as np + from ..core import Kernel from . import KernelEvaluator class CoveringNumberEvaluator(KernelEvaluator): - """ - Expressibility measure based on the covering number associated with the hypothesis class related to the current ansatz. + """Expressibility measure based on the covering number associated with the hypothesis class related to the current ansatz. See: Du, Yuxuan, et al. "Efficient measure for the expressivity of variational quantum algorithms." Physical Review Letters 128.8 (2022): 080506. """ - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -21,4 +22,4 @@ def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): """ operations = kernel.ansatz.operation_list trainable_operations = [op for op in operations if op.feature >= 0] - return 2 ** trainable_operations + return 2**trainable_operations diff --git a/src/quask/evaluator/ess_model_complexity_evaluator.py b/src/quask/evaluator/ess_model_complexity_evaluator.py index 4f4cdc6..a70255e 100644 --- a/src/quask/evaluator/ess_model_complexity_evaluator.py +++ b/src/quask/evaluator/ess_model_complexity_evaluator.py @@ -1,19 +1,19 @@ import numpy as np -from scipy.linalg import sqrtm + from ..core import Kernel from . import KernelEvaluator class EssModelComplexityEvaluator(KernelEvaluator): - """ - Calculate the model complexity s(K). + """Calculate the model complexity s(K). See Equation F1 in "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938) """ - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -27,8 +27,7 @@ def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): @staticmethod def calculate_model_complexity(k, y, normalization_lambda=0.001): - """ - Calculate the model complexity s(K), which is equation F1 in + """Calculate the model complexity s(K), which is equation F1 in "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938). :param k: Kernel gram matrix @@ -44,8 +43,7 @@ def calculate_model_complexity(k, y, normalization_lambda=0.001): @staticmethod def calculate_model_complexity_training(k, y, normalization_lambda=0.001): - """ - Subprocedure of the function 'calculate_model_complexity_generalized'. + """Subprocedure of the function 'calculate_model_complexity_generalized'. :param k: Kernel gram matrix :param y: Labels @@ -54,14 +52,15 @@ def calculate_model_complexity_training(k, y, normalization_lambda=0.001): """ n = k.shape[0] k_inv = np.linalg.inv(k + normalization_lambda * np.eye(n)) - k_mid = k_inv @ k_inv # without k in the middle + k_mid = k_inv @ k_inv # without k in the middle model_complexity = (normalization_lambda**2) * (y.T @ k_mid @ y) return model_complexity @staticmethod - def calculate_model_complexity_generalized(k, y, normalization_lambda=0.001): - """ - Calculate the model complexity s(K), which is equation M1 in + def calculate_model_complexity_generalized( + k, y, normalization_lambda=0.001 + ): + """Calculate the model complexity s(K), which is equation M1 in "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938). :param k: Kernel gram matrix @@ -70,6 +69,16 @@ def calculate_model_complexity_generalized(k, y, normalization_lambda=0.001): :return: model complexity of the given kernel """ n = k.shape[0] - a = np.sqrt(EssModelComplexityEvaluator.calculate_model_complexity_training(k, y, normalization_lambda) / n) - b = np.sqrt(EssModelComplexityEvaluator.calculate_model_complexity(k, y, normalization_lambda) / n) + a = np.sqrt( + EssModelComplexityEvaluator.calculate_model_complexity_training( + k, y, normalization_lambda + ) + / n + ) + b = np.sqrt( + EssModelComplexityEvaluator.calculate_model_complexity( + k, y, normalization_lambda + ) + / n + ) return a + b diff --git a/src/quask/evaluator/geometric_difference_evaluator.py b/src/quask/evaluator/geometric_difference_evaluator.py index afde588..d625ba2 100644 --- a/src/quask/evaluator/geometric_difference_evaluator.py +++ b/src/quask/evaluator/geometric_difference_evaluator.py @@ -1,19 +1,18 @@ import numpy as np from scipy.linalg import sqrtm + from ..core import Kernel from . import KernelEvaluator class GeometricDifferenceEvaluator(KernelEvaluator): - """ - Calculate the geometric difference g(K_1 || K_2), and characterize - the separation between classical and quantum kernels. + """Calculate the geometric difference g(K_1 || K_2), and characterize + the separation between classical and quantum kernels. See Equation F9 in "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938) """ def __init__(self, list_classical_kernel_matrices, lam): - """ - Initialization. + """Initialization. :param list_classical_kernel_matrices: List of kernel matrices obtained with classical kernels :param lam: normalization constant lambda @@ -22,11 +21,11 @@ def __init__(self, list_classical_kernel_matrices, lam): self.list_classical_kernel_matrices = list_classical_kernel_matrices self.lam = lam + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions - :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -36,16 +35,17 @@ def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): if K is None: K = kernel.build_kernel(X, X) - geometric_differences = [GeometricDifferenceEvaluator.g(K, Kc, self.lam) - for Kc in self.list_classical_kernel_matrices] + geometric_differences = [ + GeometricDifferenceEvaluator.g(K, Kc, self.lam) + for Kc in self.list_classical_kernel_matrices + ] # return -1 * np.min(geometric_differences) return geometric_differences @staticmethod def g(k_1, k_2, lam): - """ - Method to calculate the geometric difference + """Method to calculate the geometric difference :param k_1: first matrix (quantum usually) :param k_2: second matrix (classical usually) @@ -63,6 +63,8 @@ def g(k_1, k_2, lam): kc_inv = np.linalg.inv(k_2 + lam * np.eye(n)) kc_inv = kc_inv @ kc_inv # Equation F9 - f9_body = k_1_sqrt.dot(k_2_sqrt.dot(kc_inv.dot(k_2_sqrt.dot(k_1_sqrt)))) + f9_body = k_1_sqrt.dot( + k_2_sqrt.dot(kc_inv.dot(k_2_sqrt.dot(k_1_sqrt))) + ) f9 = np.sqrt(np.linalg.norm(f9_body, np.inf)) return f9 diff --git a/src/quask/evaluator/haar_evaluator.py b/src/quask/evaluator/haar_evaluator.py index f12b8fd..6692a73 100644 --- a/src/quask/evaluator/haar_evaluator.py +++ b/src/quask/evaluator/haar_evaluator.py @@ -1,28 +1,28 @@ import numpy as np + from ..core import Kernel from . import KernelEvaluator class HaarEvaluator(KernelEvaluator): - """ - Expressibility measure based on the comparison between the distribution of states obtained with an Haar random circuit and + """Expressibility measure based on the comparison between the distribution of states obtained with an Haar random circuit and the one obtained with the current ansatz. See: Sim, Sukin, Peter D. Johnson, and Alán Aspuru-Guzik. "Expressibility and entangling capability of parameterized quantum circuits for hybrid quantum-classical algorithms." Advanced Quantum Technologies 2.12 (2019): 1900070. """ def __init__(self, n_bins: int, n_samples: int): - """ - Initialization + """Initialization :param n_bins: number of discretization buckets :param n_samples: number of samples approximating the distribution of values """ self.n_bins = n_bins self.n_samples = n_samples - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -30,14 +30,15 @@ def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): :return: cost of the kernel, the lower the better """ haar_histogram = HaarEvaluator.haar_histogram(kernel, self.n_bins) - ansatz_histogram = HaarEvaluator.ansatz_histogram(kernel, self.n_bins, self.n_samples, K) + ansatz_histogram = HaarEvaluator.ansatz_histogram( + kernel, self.n_bins, self.n_samples, K + ) self.last_result = (haar_histogram, ansatz_histogram) return np.linalg.norm(haar_histogram - ansatz_histogram) @staticmethod def ansatz_histogram(kernel, n_bins, n_samples, K: None): - """ - Create a histogram of the fidelities of the ansatz + """Create a histogram of the fidelities of the ansatz :param kernel: kernel object :param n_bins: number of discretization buckets :param n_samples: number of samples approximating the distribution of values @@ -48,12 +49,16 @@ def ansatz_histogram(kernel, n_bins, n_samples, K: None): if type(K) != type(None): for i in range(K.shape[0]): for j in range(K.shape[1]): - index = int(K[i,j] * n_bins) + index = int(K[i, j] * n_bins) histogram[np.minimum(index, n_bins - 1)] += 1 else: for _ in range(n_samples): - theta_1 = np.random.normal(size=(kernel.ansatz.n_features,)) * np.pi - theta_2 = np.random.normal(size=(kernel.ansatz.n_features,)) * np.pi + theta_1 = ( + np.random.normal(size=(kernel.ansatz.n_features,)) * np.pi + ) + theta_2 = ( + np.random.normal(size=(kernel.ansatz.n_features,)) * np.pi + ) fidelity = kernel.kappa(theta_1, theta_2) index = int(fidelity * n_bins) histogram[np.minimum(index, n_bins - 1)] += 1 @@ -62,17 +67,18 @@ def ansatz_histogram(kernel, n_bins, n_samples, K: None): @staticmethod def haar_histogram(kernel, n_bins): - """ - Create a histogram of the Haar random fidelities + """Create a histogram of the Haar random fidelities :param n_bins: number of bins :return: histogram """ - N = 2 ** kernel.ansatz.n_qubits + N = 2**kernel.ansatz.n_qubits def prob(low, high): - return (1-low) ** (N - 1) - (1 - high) ** (N - 1) + return (1 - low) ** (N - 1) - (1 - high) ** (N - 1) - histogram = np.array([prob(i / n_bins, (i+1) / n_bins) for i in range(n_bins)]) + histogram = np.array( + [prob(i / n_bins, (i + 1) / n_bins) for i in range(n_bins)] + ) return histogram def __str__(self): diff --git a/src/quask/evaluator/kernel_alignment_evaluator.py b/src/quask/evaluator/kernel_alignment_evaluator.py index 3abe93a..93d8154 100644 --- a/src/quask/evaluator/kernel_alignment_evaluator.py +++ b/src/quask/evaluator/kernel_alignment_evaluator.py @@ -1,17 +1,18 @@ import numpy as np + from ..core import Kernel from . import KernelEvaluator class KernelAlignmentEvaluator(KernelEvaluator): - """ - Kernel compatibility measure based on the kernel-target alignment + """Kernel compatibility measure based on the kernel-target alignment See: Cristianini, Nello, et al. "On kernel-target alignment." Advances in neural information processing systems 14 (2001). """ - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -26,8 +27,7 @@ def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): @staticmethod def kta(K, y): - """ - Calculates the kernel target alignment + """Calculates the kernel target alignment :param K: kernel matrix :param y: label vector :return: kernel target alignment diff --git a/src/quask/evaluator/kernel_evaluator.py b/src/quask/evaluator/kernel_evaluator.py index 2ea922d..55bb1d8 100644 --- a/src/quask/evaluator/kernel_evaluator.py +++ b/src/quask/evaluator/kernel_evaluator.py @@ -1,17 +1,19 @@ -import numpy as np from abc import ABC, abstractmethod + +import numpy as np + from ..core import Kernel class KernelEvaluator(ABC): - def __init__(self): self.last_result = None @abstractmethod - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints diff --git a/src/quask/evaluator/lie_rank_evaluator.py b/src/quask/evaluator/lie_rank_evaluator.py index d8db4eb..eb6254d 100644 --- a/src/quask/evaluator/lie_rank_evaluator.py +++ b/src/quask/evaluator/lie_rank_evaluator.py @@ -1,28 +1,28 @@ import copy + import numpy as np -from typing import Set + from ..core import Kernel from . import KernelEvaluator class LieRankEvaluator(KernelEvaluator): - """ - Expressibility and 'Efficient classical simulability' measure based on the rank of the Lie algebra obtained by spanning + """Expressibility and 'Efficient classical simulability' measure based on the rank of the Lie algebra obtained by spanning the generators of the circuits. See: Larocca, Martin, et al. "Diagnosing barren plateaus with tools from quantum optimal control." Quantum 6 (2022): 824. """ def __init__(self, T): - """ - Initializer + """Initializer :param T: threshold T > 0 telling how is the minimum dimension of a 'hard-to-simulate' Lie algebra """ super().__init__() self.T = T - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -33,21 +33,22 @@ def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): return -len(self.last_result) def braket_pair(self, a: str, b: str): - """ - Calculate the commutator between two pauli matrices + """Calculate the commutator between two pauli matrices :param a: first Pauli (one of the strings 'I', 'X', 'Y', 'Z') :param b: second Pauli (one of the strings 'I', 'X', 'Y', 'Z') :return: [a, b] """ - assert a in ['I', 'X', 'Y', 'Z'] and b in ['I', 'X', 'Y', 'Z'] - if a == b: return 'I' - if a == 'I': return b - if b == 'I': return a - return list(set(['X', 'Y', 'Z']).difference([a, b]))[0] + assert a in ["I", "X", "Y", "Z"] and b in ["I", "X", "Y", "Z"] + if a == b: + return "I" + if a == "I": + return b + if b == "I": + return a + return list({"X", "Y", "Z"}.difference([a, b]))[0] def braket_strings(self, s1: str, s2: str): - """ - Calculate the communtator between two pauli strings + """Calculate the communtator between two pauli strings :param s1: first Pauli string :param s2: second Pauli string :return: [s1, s2] @@ -55,9 +56,10 @@ def braket_strings(self, s1: str, s2: str): assert len(s1) == len(s2), "Tha Pauli strings have different lengths" return [self.braket_pair(a, b) for (a, b) in zip(s1, s2)] - def __braket_generators(self, initial_generators: Set[str], new_generators: Set[str]): - """ - Return the set of generators obtained by commutating pairwise the elements in the given set + def __braket_generators( + self, initial_generators: set[str], new_generators: set[str] + ): + """Return the set of generators obtained by commutating pairwise the elements in the given set :param initial_generators: first set of generators :param new_generators: second set of generators :return: generators obtained with the pairwise commutation of the given elements (only new ones) @@ -66,25 +68,33 @@ def __braket_generators(self, initial_generators: Set[str], new_generators: Set[ for gen_new in new_generators: for gen_old in initial_generators: braket = "".join(self.braket_strings(gen_new, gen_old)) - if braket not in initial_generators and braket not in new_generators: + if ( + braket not in initial_generators + and braket not in new_generators + ): out_generators.append(braket) return set(out_generators) def get_initial_generators(self, kernel): - """ - Create the initial generators of a kernel, i.e. for each operation apply the generator to the correct wires + """Create the initial generators of a kernel, i.e. for each operation apply the generator to the correct wires and identity everywhere else :param kernel: kernel object :return set of initial generators corresponding to the operations of the kernel """ # get the generators of each operation - generators = [kernel.ansatz.operation_list[i].generator for i in range(kernel.ansatz.n_operations)] + generators = [ + kernel.ansatz.operation_list[i].generator + for i in range(kernel.ansatz.n_operations) + ] # get the wires on which each operation acts - wires = [kernel.ansatz.operation_list[i].wires for i in range(kernel.ansatz.n_operations)] + wires = [ + kernel.ansatz.operation_list[i].wires + for i in range(kernel.ansatz.n_operations) + ] initial_generators = [] for i in range(kernel.ansatz.n_operations): # initialize each generator with identity everyone, as list of char and not as string (the latter is immutable) - initial_generator = ['I'] * kernel.ansatz.n_qubits + initial_generator = ["I"] * kernel.ansatz.n_qubits # assign the generator to each qubit q0, q1 = wires[i][0], wires[i][1] g0, g1 = generators[i][0], generators[i][1] @@ -98,8 +108,7 @@ def get_initial_generators(self, kernel): return set(initial_generators) def braket_generators(self, kernel, T): - """ - Return the basis of the lie algebra of the circuit defined by the kernel. The number of elements is truncated at T + """Return the basis of the lie algebra of the circuit defined by the kernel. The number of elements is truncated at T :param kernel: kernel object :param T: threshold :return: basis of the lie algebra of the generators in kernel @@ -108,7 +117,9 @@ def braket_generators(self, kernel, T): new_generators = copy.deepcopy(initial_generators) all_generators = copy.deepcopy(initial_generators) while len(all_generators) < T and len(new_generators) > 0: - new_generators = self.__braket_generators(all_generators, new_generators) + new_generators = self.__braket_generators( + all_generators, new_generators + ) all_generators = all_generators.union(new_generators) return all_generators diff --git a/src/quask/evaluator/ridge_generalization_evaluator.py b/src/quask/evaluator/ridge_generalization_evaluator.py index ba793ab..99908dd 100644 --- a/src/quask/evaluator/ridge_generalization_evaluator.py +++ b/src/quask/evaluator/ridge_generalization_evaluator.py @@ -1,23 +1,21 @@ import numpy as np from sklearn.kernel_ridge import KernelRidge + from ..core import Kernel from . import KernelEvaluator class RidgeGeneralizationEvaluator(KernelEvaluator): - """ - Evaluates the generalization error of the given kernel - """ + """Evaluates the generalization error of the given kernel""" def __init__(self): - """ - Initialization - """ + """Initialization""" pass - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -31,4 +29,3 @@ def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): y_pred = np.array(krr.predict(X[n_train:])) mse = np.linalg.norm(y_pred - y[n_train:]) / n_test return mse - diff --git a/src/quask/evaluator/spectral_bias_evaluator.py b/src/quask/evaluator/spectral_bias_evaluator.py index 7918372..b52637a 100644 --- a/src/quask/evaluator/spectral_bias_evaluator.py +++ b/src/quask/evaluator/spectral_bias_evaluator.py @@ -1,26 +1,26 @@ import numpy as np from scipy.linalg import eigh + from ..core import Kernel from . import KernelEvaluator class SpectralBiasEvaluator(KernelEvaluator): - """ - Kernel compatibility measure based on the spectral bias framework. + """Kernel compatibility measure based on the spectral bias framework. See: Canatar, Abdulkadir, Blake Bordelon, and Cengiz Pehlevan. "Spectral bias and task-model alignment explain generalization in kernel regression and infinitely wide neural networks." Nature communications 12.1 (2021): 2914. """ def __init__(self, n_eigenvalues_cut): - """ - Initialization + """Initialization :param n_eigenvalues_cut: number of eigenvalues contributing to the cumulative power """ self.n_eigenvalues_cut = n_eigenvalues_cut - def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): - """ - Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + def evaluate( + self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray + ): + r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -31,15 +31,17 @@ def evaluate(self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray): K = kernel.build_kernel(X, X) Lambda, Phi = SpectralBiasEvaluator.decompose_kernel(K) w, a = SpectralBiasEvaluator.calculate_weights(Lambda, Phi, y) - C, powers = SpectralBiasEvaluator.cumulative_power_distribution(w, Lambda, self.n_eigenvalues_cut) + C, powers = SpectralBiasEvaluator.cumulative_power_distribution( + w, Lambda, self.n_eigenvalues_cut + ) self.last_result = (Lambda, Phi, w, a, C, powers) return C - @staticmethod - def decompose_kernel(K, eigenvalue_descending_order=True, eigenvalue_removal_threshold=1e-12): - """ - Decompose the kernel matrix K in its eigenvalues Λ and eigenvectors Φ + def decompose_kernel( + K, eigenvalue_descending_order=True, eigenvalue_removal_threshold=1e-12 + ): + """Decompose the kernel matrix K in its eigenvalues Λ and eigenvectors Φ :param K: kernel matrix, real and symmetric :param eigenvalue_descending_order: if True, the biggest eigenvalue is the first one :return: Lambda vector (n elements) and Phi matrix (N*N matrix) @@ -61,8 +63,7 @@ def decompose_kernel(K, eigenvalue_descending_order=True, eigenvalue_removal_thr @staticmethod def calculate_weights(Lambda, Phi, labels): - """ - Calculates the weights of a predictor given the labels and the kernel eigendecomposition, + """Calculates the weights of a predictor given the labels and the kernel eigendecomposition, as shown in (Canatar et al 2021, inline formula below equation 18). :param Lambda: vectors of m nonnegative eigenvalues 'eta' :param Phi: vectors of m nonnegative eigenvectors 'phi' @@ -76,7 +77,7 @@ def calculate_weights(Lambda, Phi, labels): inv_eigenvalues = np.reciprocal(Lambda, where=Lambda > 0) # weight vectors are calculated by inverting formula: y = \sum_k=1^M w_k \sqrt{lambda_k} \phi_k(x) - the_w = (1 / m) * np.diag(inv_eigenvalues ** 0.5) @ Phi.T @ labels + the_w = (1 / m) * np.diag(inv_eigenvalues**0.5) @ Phi.T @ labels the_w[Lambda == 0] = 0 # weight vector for the components out-of-RKHS @@ -86,17 +87,14 @@ def calculate_weights(Lambda, Phi, labels): @staticmethod def cumulative_power_distribution(w, Lambda, n_eigenvalues): - """ - - :param w: vector of weights + """:param w: vector of weights :param Lambda: vector of eigenvalues :param n_eigenvalues: number of eigenvalues contributing to the cumulative power :return: """ - powers = np.diag(Lambda) @ (w ** 2) + powers = np.diag(Lambda) @ (w**2) return np.sum(powers[:n_eigenvalues]) / np.sum(powers), powers def __str__(self): (Lambda, Phi, w, a, C, powers) = self.last_result return f"""{Lambda=} {Phi=} {w=} {a=} {C=} {powers=}""" - diff --git a/src/quask/optimizer/base_kernel_optimizer.py b/src/quask/optimizer/base_kernel_optimizer.py index a251780..7c916e8 100644 --- a/src/quask/optimizer/base_kernel_optimizer.py +++ b/src/quask/optimizer/base_kernel_optimizer.py @@ -1,18 +1,22 @@ from abc import ABC, abstractmethod + import numpy as np -import copy -from ..core import Operation, Ansatz, Kernel, KernelFactory + +from ..core import Kernel from ..evaluator import KernelEvaluator class BaseKernelOptimizer(ABC): - """ - Abstract class implementing a procedure to optimize the kernel - """ + """Abstract class implementing a procedure to optimize the kernel""" - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): - """ - Initialization + def __init__( + self, + initial_kernel: Kernel, + X: np.ndarray, + y: np.ndarray, + ke: KernelEvaluator, + ): + """Initialization :param initial_kernel: initial kernel object :param X: datapoints :param y: labels @@ -25,8 +29,7 @@ def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: Ker @abstractmethod def optimize(self): - """ - Run the optimization + """Run the optimization :return: optimized kernel object """ pass diff --git a/src/quask/optimizer/bayesian_optimizer.py b/src/quask/optimizer/bayesian_optimizer.py index 6444735..97fc55c 100644 --- a/src/quask/optimizer/bayesian_optimizer.py +++ b/src/quask/optimizer/bayesian_optimizer.py @@ -1,16 +1,21 @@ import numpy as np from joblib import Parallel, delayed from skopt import Optimizer -from skopt.space import Real, Categorical +from skopt.space import Categorical, Real -from ..core import Operation, Ansatz, Kernel, KernelFactory +from ..core import Kernel from ..evaluator import KernelEvaluator from .base_kernel_optimizer import BaseKernelOptimizer class BayesianOptimizer(BaseKernelOptimizer): - - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): + def __init__( + self, + initial_kernel: Kernel, + X: np.ndarray, + y: np.ndarray, + ke: KernelEvaluator, + ): super().__init__(initial_kernel, X, y, ke) self.optimizer = None @@ -35,12 +40,16 @@ def get_sklearn_dimensions(self): def get_kernel(self, the_array): the_array = np.array(the_array, dtype=object) - the_kernel = Kernel.from_numpy(np.concatenate([the_array.ravel(), np.array([self.initial_kernel.type])]), - self.initial_kernel.ansatz.n_features, - self.initial_kernel.ansatz.n_qubits, - self.initial_kernel.ansatz.n_operations, - self.initial_kernel.ansatz.allow_midcircuit_measurement, - shift_second_wire=True) + the_kernel = Kernel.from_numpy( + np.concatenate( + [the_array.ravel(), np.array([self.initial_kernel.type])] + ), + self.initial_kernel.ansatz.n_features, + self.initial_kernel.ansatz.n_qubits, + self.initial_kernel.ansatz.n_operations, + self.initial_kernel.ansatz.allow_midcircuit_measurement, + shift_second_wire=True, + ) return the_kernel def get_cost(self, the_array): @@ -49,19 +58,22 @@ def get_cost(self, the_array): return the_cost def optimize(self, n_epochs=20, n_points=4, n_jobs=4): - self.optimizer = Optimizer( dimensions=self.get_sklearn_dimensions(), random_state=1, - base_estimator='gp', + base_estimator="gp", acq_func="PI", acq_optimizer="sampling", - acq_func_kwargs={"xi": 10000.0, "kappa": 10000.0} + acq_func_kwargs={"xi": 10000.0, "kappa": 10000.0}, ) for i in range(n_epochs): - x = self.optimizer.ask(n_points=n_points) # x is a list of n_points points - y = Parallel(n_jobs=n_jobs)(delayed(lambda array: self.get_cost(array))(v) for v in x) # evaluate points in parallel + x = self.optimizer.ask( + n_points=n_points + ) # x is a list of n_points points + y = Parallel(n_jobs=n_jobs)( + delayed(lambda array: self.get_cost(array))(v) for v in x + ) # evaluate points in parallel self.optimizer.tell(x, y) print(f"Epoch of training {i=}") diff --git a/src/quask/optimizer/metaheuristic_optimizer.py b/src/quask/optimizer/metaheuristic_optimizer.py index 639d340..ca00fc8 100644 --- a/src/quask/optimizer/metaheuristic_optimizer.py +++ b/src/quask/optimizer/metaheuristic_optimizer.py @@ -1,12 +1,12 @@ -import copy -import numpy as np from enum import Enum +import numpy as np from opytimizer import Opytimizer from opytimizer.core import Function from opytimizer.optimizers.swarm import PSO from opytimizer.spaces import GridSpace from opytimizer.utils.callback import Callback + from ..core import Kernel from ..evaluator import KernelEvaluator from .base_kernel_optimizer import BaseKernelOptimizer @@ -19,7 +19,6 @@ class CustomCallback(Callback): def __init__(self): """Initialization method for the customized callback.""" - # You only need to override its parent class super(CustomCallback).__init__() @@ -57,7 +56,6 @@ def on_update_after(self, *update_args): class MetaheuristicType(Enum): - # evolutionary FOREST_OPTIMIZATION = 1 GENETIC_ALGORITHM = 2 @@ -68,46 +66,66 @@ class MetaheuristicType(Enum): class MetaheuristicOptimizer(BaseKernelOptimizer): - - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): + def __init__( + self, + initial_kernel: Kernel, + X: np.ndarray, + y: np.ndarray, + ke: KernelEvaluator, + ): super().__init__(initial_kernel, X, y, ke) def cost(array): array = array.ravel() - the_array = np.concatenate([array, np.array([initial_kernel.type])]) + the_array = np.concatenate( + [array, np.array([initial_kernel.type])] + ) # create kernel - the_kernel = Kernel.from_numpy(the_array, - initial_kernel.ansatz.n_features, - initial_kernel.ansatz.n_qubits, - initial_kernel.ansatz.n_operations, - initial_kernel.ansatz.allow_midcircuit_measurement, - shift_second_wire=True) + the_kernel = Kernel.from_numpy( + the_array, + initial_kernel.ansatz.n_features, + initial_kernel.ansatz.n_qubits, + initial_kernel.ansatz.n_operations, + initial_kernel.ansatz.allow_midcircuit_measurement, + shift_second_wire=True, + ) the_cost = ke.evaluate(the_kernel, None, X, y) - print(f"MetaheuristicOptimizer.cost -> {the_cost: 5.5f} -> {array}") + print( + f"MetaheuristicOptimizer.cost -> {the_cost: 5.5f} -> {array}" + ) return the_cost self.space = self.get_opytimize_space() self.optimizer = PSO() self.cost = cost self.function = Function(cost) - self.opt = Opytimizer(self.space, self.optimizer, self.function, save_agents=True) + self.opt = Opytimizer( + self.space, self.optimizer, self.function, save_agents=True + ) self.history = None self.best_solution = None self.best_cost = None def optimize(self, n_iterations=1000, verbose=False): - self.opt.start(n_iterations=n_iterations, callbacks=[CustomCallback()] if verbose else []) + self.opt.start( + n_iterations=n_iterations, + callbacks=[CustomCallback()] if verbose else [], + ) self.history = self.opt.history data_at_convergence = self.history.get_convergence("best_agent") self.best_solution = data_at_convergence[0].ravel() self.best_cost = data_at_convergence[1].ravel() - the_array = np.concatenate([self.best_solution, np.array([self.initial_kernel.type])]) - return Kernel.from_numpy(the_array, - self.initial_kernel.ansatz.n_features, - self.initial_kernel.ansatz.n_qubits, - self.initial_kernel.ansatz.n_operations, - self.initial_kernel.ansatz.allow_midcircuit_measurement, - shift_second_wire=True) + the_array = np.concatenate( + [self.best_solution, np.array([self.initial_kernel.type])] + ) + return Kernel.from_numpy( + the_array, + self.initial_kernel.ansatz.n_features, + self.initial_kernel.ansatz.n_qubits, + self.initial_kernel.ansatz.n_operations, + self.initial_kernel.ansatz.allow_midcircuit_measurement, + shift_second_wire=True, + ) def get_opytimize_space(self): n_features = self.initial_kernel.ansatz.n_features @@ -118,5 +136,11 @@ def get_opytimize_space(self): n_variables = 5 * n_operations + n_qubits step = [1, 1, 1, 1, 0.2] * n_operations + [1] * n_qubits lower_bound = [0, 0, 0, 0, 0.2] * n_operations + [0] * n_qubits - upper_bound = [len(allowed_generators) - 1, n_qubits - 1, n_qubits - 2, n_features, 1.0] * n_operations + [3] * n_qubits + upper_bound = [ + len(allowed_generators) - 1, + n_qubits - 1, + n_qubits - 2, + n_features, + 1.0, + ] * n_operations + [3] * n_qubits return GridSpace(n_variables, step, lower_bound, upper_bound) diff --git a/src/quask/optimizer/reinforcement_learning_optimizer.py b/src/quask/optimizer/reinforcement_learning_optimizer.py index 8361aca..5807fe2 100644 --- a/src/quask/optimizer/reinforcement_learning_optimizer.py +++ b/src/quask/optimizer/reinforcement_learning_optimizer.py @@ -1,61 +1,73 @@ -import numpy as np import copy -from ..core import Operation, Ansatz, Kernel, KernelFactory + +import numpy as np + +from ..core import Kernel from ..evaluator import KernelEvaluator from .base_kernel_optimizer import BaseKernelOptimizer class ReinforcementLearningOptimizer(BaseKernelOptimizer): - """ - Reinforcement learning based technique for optimize a kernel function - """ + """Reinforcement learning based technique for optimize a kernel function""" - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): - """ - Initialization + def __init__( + self, + initial_kernel: Kernel, + X: np.ndarray, + y: np.ndarray, + ke: KernelEvaluator, + ): + """Initialization :param initial_kernel: initial kernel object :param X: datapoints :param y: labels :param ke: kernel evaluator object """ from mushroom_rl.core import Environment - from mushroom_rl.core import Core - from mushroom_rl.algorithms.value import SARSALambda - from mushroom_rl.policy import EpsGreedy - from mushroom_rl.utils.parameters import Parameter - from mushroom_rl.utils.dataset import compute_J + self.initial_kernel = copy.deepcopy(initial_kernel) self.X = X self.y = y self.ke = ke - self.mdp = Environment.make('WideKernelEnvironment', initial_kernel=self.initial_kernel, X=X, y=y, ke=ke) + self.mdp = Environment.make( + "WideKernelEnvironment", + initial_kernel=self.initial_kernel, + X=X, + y=y, + ke=ke, + ) self.agent = None self.core = None - def optimize(self, initial_episodes=3, n_episodes=100, n_steps_per_fit=1, final_episodes=3): - """ - Optimization routine + def optimize( + self, + initial_episodes=3, + n_episodes=100, + n_steps_per_fit=1, + final_episodes=3, + ): + """Optimization routine :param initial_episodes: :param n_steps: :param n_steps_per_fit: :param final_episodes: :return: """ - from mushroom_rl.core import Environment - from mushroom_rl.core import Core from mushroom_rl.algorithms.value import SARSALambda + from mushroom_rl.core import Core from mushroom_rl.policy import EpsGreedy - from mushroom_rl.utils.parameters import Parameter from mushroom_rl.utils.dataset import compute_J + from mushroom_rl.utils.parameters import Parameter + # Policy - epsilon = Parameter(value=1.) + epsilon = Parameter(value=1.0) pi = EpsGreedy(epsilon=epsilon) - learning_rate = Parameter(.1) + learning_rate = Parameter(0.1) # Agent - self.agent = SARSALambda(self.mdp.info, pi, - learning_rate=learning_rate, - lambda_coeff=.9) + self.agent = SARSALambda( + self.mdp.info, pi, learning_rate=learning_rate, lambda_coeff=0.9 + ) # Reinforcement learning experiment self.core = Core(self.agent, self.mdp) @@ -66,17 +78,25 @@ def optimize(self, initial_episodes=3, n_episodes=100, n_steps_per_fit=1, final_ # Print the average objective value before learning J = np.mean(compute_J(dataset, self.mdp.info.gamma)) - print(f'Objective function before learning: {J}') + print(f"Objective function before learning: {J}") # Train - self.core.learn(n_episodes=n_episodes, n_steps_per_fit=n_steps_per_fit, render=True) + self.core.learn( + n_episodes=n_episodes, n_steps_per_fit=n_steps_per_fit, render=True + ) # Visualize results for 3 episodes dataset = self.core.evaluate(n_episodes=final_episodes, render=True) # Print the average objective value after learning J = np.mean(compute_J(dataset, self.mdp.info.gamma)) - print(f'Objective function after learning: {J}') + print(f"Objective function after learning: {J}") - kernel = Kernel.from_numpy(self.mdp._state[1:], self.mdp.n_features, self.mdp.n_qubits, self.mdp.n_operations, self.mdp.allow_midcircuit_measurement) + kernel = Kernel.from_numpy( + self.mdp._state[1:], + self.mdp.n_features, + self.mdp.n_qubits, + self.mdp.n_operations, + self.mdp.allow_midcircuit_measurement, + ) return kernel diff --git a/src/quask/optimizer/wide_kernel_environment.py b/src/quask/optimizer/wide_kernel_environment.py index b6a9468..b5f87ad 100644 --- a/src/quask/optimizer/wide_kernel_environment.py +++ b/src/quask/optimizer/wide_kernel_environment.py @@ -1,22 +1,26 @@ import numpy as np from mushroom_rl.core import Environment, MDPInfo from mushroom_rl.utils.spaces import Discrete -from ..core import Operation, Ansatz, Kernel, KernelFactory + +from ..core import Kernel from ..evaluator import KernelEvaluator class WideKernelEnvironment(Environment): - """ - Implementation of a Mushroom-RL Environment for our problem - """ + """Implementation of a Mushroom-RL Environment for our problem""" @staticmethod def setup(): WideKernelEnvironment.register() - def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: KernelEvaluator): - """ - Initialization + def __init__( + self, + initial_kernel: Kernel, + X: np.ndarray, + y: np.ndarray, + ke: KernelEvaluator, + ): + """Initialization :param initial_kernel: initial kernel object :param X: datapoints :param y: labels @@ -26,7 +30,9 @@ def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: Ker self.n_operations = self.initial_kernel.ansatz.n_operations self.n_features = self.initial_kernel.ansatz.n_features self.n_qubits = self.initial_kernel.ansatz.n_qubits - self.allow_midcircuit_measurement = self.initial_kernel.ansatz.allow_midcircuit_measurement + self.allow_midcircuit_measurement = ( + self.initial_kernel.ansatz.allow_midcircuit_measurement + ) self.X = X self.y = y self.ke = ke @@ -50,7 +56,9 @@ def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: Ker ) # Create the MDPInfo structure, needed by the environment interface - mdp_info = MDPInfo(observation_space, action_space, gamma=0.99, horizon=100) + mdp_info = MDPInfo( + observation_space, action_space, gamma=0.99, horizon=100 + ) super().__init__(mdp_info) # Create a state class variable to store the current state @@ -60,36 +68,41 @@ def __init__(self, initial_kernel: Kernel, X: np.ndarray, y: np.ndarray, ke: Ker self._viewer = None def serialize_state(self, n_operation, kernel): - """ - Pack the state of the optimization technique + """Pack the state of the optimization technique :param n_operation: number of operations currently performed :param kernel: kernel object :return: serialized state """ - state = np.concatenate([np.array([n_operation], dtype=int), kernel.to_numpy()], dtype=object).ravel() + state = np.concatenate( + [np.array([n_operation], dtype=int), kernel.to_numpy()], + dtype=object, + ).ravel() return state.astype(int) def deserialize_state(self, array): - """ - Deserialized a previously packed state variable + """Deserialized a previously packed state variable :param array: serialized state :return: tuple n_operations, kernel object """ - kernel = Kernel.from_numpy(array[1:], self.n_features, self.n_qubits, self.n_operations, self.allow_midcircuit_measurement) + kernel = Kernel.from_numpy( + array[1:], + self.n_features, + self.n_qubits, + self.n_operations, + self.allow_midcircuit_measurement, + ) n_operations = int(array[0]) return n_operations, kernel def render(self): - """ - Rendering function - we don't need that + """Rendering function - we don't need that :return: None """ n_op, kernel = self.deserialize_state(self._state) print(f"{self.last_reward=:2.4f} {n_op=:2d} {kernel=}") def reset(self, state=None): - """ - Reset the state + """Reset the state :param state: optional state :return: self._state variable """ @@ -101,12 +114,13 @@ def reset(self, state=None): return self._state def unpack_action(self, action): - """ - Unpack an action to a operation + """Unpack an action to a operation :param action: integer representing the action :return: dictionary of the operation """ - generator_index = int(action % len(self.initial_kernel.get_allowed_operations())) + generator_index = int( + action % len(self.initial_kernel.get_allowed_operations()) + ) action = action // len(self.initial_kernel.get_allowed_operations()) wires_0 = int(action % self.n_qubits) @@ -121,20 +135,29 @@ def unpack_action(self, action): action = action // (self.n_features + 1) assert action == 0 - return {'generator': self.initial_kernel.get_allowed_operations()[generator_index], - 'wires': [wires_0, wires_1], - 'feature': feature, - 'bandwidth': 1.0} + return { + "generator": self.initial_kernel.get_allowed_operations()[ + generator_index + ], + "wires": [wires_0, wires_1], + "feature": feature, + "bandwidth": 1.0, + } def step(self, action): - the_action = self.unpack_action(action[0]) # Create kernel from state n_operations, kernel = self.deserialize_state(self._state) # Update kernel - kernel.ansatz.change_operation(n_operations, the_action['feature'], the_action['wires'], the_action['generator'], the_action['bandwidth']) + kernel.ansatz.change_operation( + n_operations, + the_action["feature"], + the_action["wires"], + the_action["generator"], + the_action["bandwidth"], + ) n_operations += 1 # Update state @@ -149,5 +172,3 @@ def step(self, action): # Return all the information + empty dictionary (used to pass additional information) return self._state, reward, absorbing, {} - - diff --git a/src/quask/tests/__init__.py b/src/quask/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/quask/tests/kernel_test.py b/src/quask/tests/kernel_test.py deleted file mode 100644 index a265326..0000000 --- a/src/quask/tests/kernel_test.py +++ /dev/null @@ -1,59 +0,0 @@ -from quask import Operation, Ansatz, KernelType, PennylaneKernel -import numpy as np - - -def test_static_single_qubit(KernelClass): - - # circuit: |0> - RX(pi) - - # |0> - ID - - ansats = Ansatz(n_features=1, n_qubits=2, n_operations=1) - ansats.initialize_to_identity() - ansats.change_generators(0, "XI") - ansats.change_feature(0, -1) - ansats.change_wires(0, [0, 1]) - ansats.change_bandwidth(0, 1) - - # measurement operation = <1|Z|1> - # probabilities: [0.0, 1.0] - # observable: 0.0 * (+1) + 1.0 * (-1) = -1.0 - kernel = KernelClass(ansats, "ZI", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0, 1])), f"Incorrect measurement: {kernel.get_last_probabilities()}" - assert np.isclose(x, -1), "Incorrect observable" - - # measurement operation = <1|X|1> = <1H|Z|H1> = <+|Z|+> - # probabilities: [0.5, 0.5] - # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 - kernel = KernelClass(ansats, "XI", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0.5, 0.5])), f"Incorrect measurement: {kernel.get_last_probabilities()}" - assert np.isclose(x, 0), "Incorrect observable" - - # measurement operation = <1|Y|1> = <1HSdag|Z|SdagH1> = <[1/sqrt(2), -i/sqrt(2)]|Z|[1/sqrt(2), -i/sqrt(2)]> - # probabilities: [0.5, 0.5] - # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 - kernel = KernelClass(ansats, "YI", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0.5, 0.5])), f"Incorrect measurement: {kernel.get_last_probabilities()}" - assert np.isclose(x, 0), "Incorrect observable" - - -def test_static_two_qubit(KernelClass): - - # circuit: |0> - XY(#0) - - # |0> - XY(#0) - - ansats = Ansatz(n_features=1, n_qubits=2, n_operations=1) - ansats.initialize_to_identity() - ansats.change_generators(0, "XY") - ansats.change_feature(0, 0) - ansats.change_wires(0, [0, 1]) - ansats.change_bandwidth(0, 1) - - kernel = KernelClass(ansats, "ZZ", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.pi / 2])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0.5, 0.0, 0.0, 0.5])), "Incorrect measurement" - assert np.isclose(x, 0), "Incorrect observable" - - -test_static_single_qubit(PennylaneKernel) -test_static_two_qubit(PennylaneKernel) diff --git a/tests/kernel_test.py b/tests/kernel_test.py index 401f545..3403c13 100644 --- a/tests/kernel_test.py +++ b/tests/kernel_test.py @@ -1,9 +1,9 @@ -from quask import Operation, Ansatz, KernelType, PennylaneKernel import numpy as np +from quask import Ansatz, KernelType, PennylaneKernel -def test_static_single_qubit(KernelClass): +def test_static_single_qubit(KernelClass): # circuit: |0> - RX(pi) - # |0> - ID - ansats = Ansatz(n_features=1, n_qubits=2, n_operations=1) @@ -18,7 +18,9 @@ def test_static_single_qubit(KernelClass): # observable: 0.0 * (+1) + 1.0 * (-1) = -1.0 kernel = KernelClass(ansats, "ZI", KernelType.OBSERVABLE) x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0, 1])), f"Incorrect measurement: {kernel.get_last_probabilities()}" + assert np.allclose(kernel.get_last_probabilities(), np.array([0, 1])), ( + f"Incorrect measurement: {kernel.get_last_probabilities()}" + ) assert np.isclose(x, -1), "Incorrect observable" # measurement operation = <1|X|1> = <1H|Z|H1> = <+|Z|+> @@ -26,7 +28,9 @@ def test_static_single_qubit(KernelClass): # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 kernel = KernelClass(ansats, "XI", KernelType.OBSERVABLE) x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0.5, 0.5])), f"Incorrect measurement: {kernel.get_last_probabilities()}" + assert np.allclose( + kernel.get_last_probabilities(), np.array([0.5, 0.5]) + ), f"Incorrect measurement: {kernel.get_last_probabilities()}" assert np.isclose(x, 0), "Incorrect observable" # measurement operation = <1|Y|1> = <1HSdag|Z|SdagH1> = <[1/sqrt(2), -i/sqrt(2)]|Z|[1/sqrt(2), -i/sqrt(2)]> @@ -34,12 +38,13 @@ def test_static_single_qubit(KernelClass): # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 kernel = KernelClass(ansats, "YI", KernelType.OBSERVABLE) x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0.5, 0.5])), f"Incorrect measurement: {kernel.get_last_probabilities()}" + assert np.allclose( + kernel.get_last_probabilities(), np.array([0.5, 0.5]) + ), f"Incorrect measurement: {kernel.get_last_probabilities()}" assert np.isclose(x, 0), "Incorrect observable" def test_static_two_qubit(KernelClass): - # circuit: |0> - XY(#0) - # |0> - XY(#0) - ansats = Ansatz(n_features=1, n_qubits=2, n_operations=1) @@ -51,7 +56,9 @@ def test_static_two_qubit(KernelClass): kernel = KernelClass(ansats, "ZZ", KernelType.OBSERVABLE) x = kernel.phi(np.array([np.pi / 2])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0.5, 0.0, 0.0, 0.5])), "Incorrect measurement" + assert np.allclose( + kernel.get_last_probabilities(), np.array([0.5, 0.0, 0.0, 0.5]) + ), "Incorrect measurement" assert np.isclose(x, 0), "Incorrect observable" diff --git a/tests/test_example.py b/tests/test_example.py index 226809c..db5c2f6 100644 --- a/tests/test_example.py +++ b/tests/test_example.py @@ -1,4 +1,3 @@ -import pytest import sys sys.path.append("./src/") @@ -8,10 +7,15 @@ def test_trivial(): - """ Trivial test. """ + """Trivial test.""" print("Passed") def test_ansatz_init(): - ansatz = Ansatz(n_features=2, n_qubits=2, n_operations=2, allow_midcircuit_measurement=False) + ansatz = Ansatz( + n_features=2, + n_qubits=2, + n_operations=2, + allow_midcircuit_measurement=False, + ) assert ansatz is not None, "Could not create an Ansatz object." diff --git a/tests/test_pennylane_kernel.py b/tests/test_pennylane_kernel.py index 078ad9b..4873d52 100644 --- a/tests/test_pennylane_kernel.py +++ b/tests/test_pennylane_kernel.py @@ -1,61 +1,106 @@ import sys + sys.path.append("src/") -import pytest -import quask import numpy as np -from quask.core import Ansatz, Kernel, KernelFactory, KernelType + +from quask.core import Ansatz, Kernel, KernelType from quask.core_implementation import PennylaneKernel + def check_kernel_value(kernel: Kernel, x1: float, x2: float, expected: float): similarity = kernel.kappa(x1, x2) print(similarity, expected) - assert np.isclose(similarity, expected), f"Kernel value is {similarity:0.3f} while {expected:0.3f} was expected" + assert np.isclose(similarity, expected), ( + f"Kernel value is {similarity:0.3f} while {expected:0.3f} was expected" + ) + def check_kernel_rx_value(kernel: Kernel, x1: float, x2: float): - def rx(theta): - return np.array([[np.cos(theta/2), -1j*np.sin(theta/2)], [-1j*np.sin(theta/2), np.cos(theta/2)]]) + def rx(theta): + return np.array( + [ + [np.cos(theta / 2), -1j * np.sin(theta / 2)], + [-1j * np.sin(theta / 2), np.cos(theta / 2)], + ] + ) + ket_zero = np.array([[1], [0]]) ket_phi = np.linalg.inv(rx(x2)) @ rx(x1) @ ket_zero - expected_similarity = (np.abs(ket_phi[0])**2).real - check_kernel_value(kernel, np.array([x1]), np.array([x2]), expected_similarity) + expected_similarity = (np.abs(ket_phi[0]) ** 2).real + check_kernel_value( + kernel, np.array([x1]), np.array([x2]), expected_similarity + ) -def test_rx_kernel_fidelity(): - ansatz = Ansatz(n_features=1, n_qubits=2, n_operations=1, allow_midcircuit_measurement=False) +def test_rx_kernel_fidelity(): + ansatz = Ansatz( + n_features=1, + n_qubits=2, + n_operations=1, + allow_midcircuit_measurement=False, + ) ansatz.initialize_to_identity() - ansatz.change_operation(0, new_feature=0, new_wires=[0, 1], new_generator="XI", new_bandwidth=1.0) - kernel = PennylaneKernel(ansatz, "ZZ", KernelType.FIDELITY, device_name="default.qubit", n_shots=None) + ansatz.change_operation( + 0, + new_feature=0, + new_wires=[0, 1], + new_generator="XI", + new_bandwidth=1.0, + ) + kernel = PennylaneKernel( + ansatz, + "ZZ", + KernelType.FIDELITY, + device_name="default.qubit", + n_shots=None, + ) check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) - check_kernel_rx_value(kernel, 0.00, 0.00) - check_kernel_rx_value(kernel, 0.33, 0.33) - check_kernel_rx_value(kernel, np.pi/2, np.pi/2) - check_kernel_rx_value(kernel, np.pi, np.pi) - check_kernel_rx_value(kernel, 0, np.pi) - check_kernel_rx_value(kernel, 0.33, np.pi) - check_kernel_rx_value(kernel, np.pi/2, np.pi) - check_kernel_rx_value(kernel, 0, 0.55) - check_kernel_rx_value(kernel, 0.33, 0.55) - check_kernel_rx_value(kernel, np.pi/2, 0.55) + check_kernel_rx_value(kernel, 0.00, 0.00) + check_kernel_rx_value(kernel, 0.33, 0.33) + check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) + check_kernel_rx_value(kernel, np.pi, np.pi) + check_kernel_rx_value(kernel, 0, np.pi) + check_kernel_rx_value(kernel, 0.33, np.pi) + check_kernel_rx_value(kernel, np.pi / 2, np.pi) + check_kernel_rx_value(kernel, 0, 0.55) + check_kernel_rx_value(kernel, 0.33, 0.55) + check_kernel_rx_value(kernel, np.pi / 2, 0.55) -def test_rx_kernel_fidelity(): - ansatz = Ansatz(n_features=1, n_qubits=2, n_operations=1, allow_midcircuit_measurement=False) +def test_rx_kernel_fidelity(): + ansatz = Ansatz( + n_features=1, + n_qubits=2, + n_operations=1, + allow_midcircuit_measurement=False, + ) ansatz.initialize_to_identity() - ansatz.change_operation(0, new_feature=0, new_wires=[0, 1], new_generator="XI", new_bandwidth=1.0) - kernel = PennylaneKernel(ansatz, "ZZ", KernelType.SWAP_TEST, device_name="default.qubit", n_shots=None) + ansatz.change_operation( + 0, + new_feature=0, + new_wires=[0, 1], + new_generator="XI", + new_bandwidth=1.0, + ) + kernel = PennylaneKernel( + ansatz, + "ZZ", + KernelType.SWAP_TEST, + device_name="default.qubit", + n_shots=None, + ) check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) - check_kernel_rx_value(kernel, 0.00, 0.00) - check_kernel_rx_value(kernel, 0.33, 0.33) - check_kernel_rx_value(kernel, np.pi/2, np.pi/2) - check_kernel_rx_value(kernel, np.pi, np.pi) - check_kernel_rx_value(kernel, 0, np.pi) - check_kernel_rx_value(kernel, 0.33, np.pi) - check_kernel_rx_value(kernel, np.pi/2, np.pi) - check_kernel_rx_value(kernel, 0, 0.55) - check_kernel_rx_value(kernel, 0.33, 0.55) - check_kernel_rx_value(kernel, np.pi/2, 0.55) - + check_kernel_rx_value(kernel, 0.00, 0.00) + check_kernel_rx_value(kernel, 0.33, 0.33) + check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) + check_kernel_rx_value(kernel, np.pi, np.pi) + check_kernel_rx_value(kernel, 0, np.pi) + check_kernel_rx_value(kernel, 0.33, np.pi) + check_kernel_rx_value(kernel, np.pi / 2, np.pi) + check_kernel_rx_value(kernel, 0, 0.55) + check_kernel_rx_value(kernel, 0.33, 0.55) + check_kernel_rx_value(kernel, np.pi / 2, 0.55) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..63e7859 --- /dev/null +++ b/tox.ini @@ -0,0 +1,21 @@ +[tox] +isolated_build = true +envlist = py{310,311}-pytest{latest},lint + +[testenv] +allowlist_externals = pdm +commands = + pdm sync + pytestlatest: pip install pytest + +# pytest 5 does not work on python>=3.10 +[testenv:py{310,311,312}-pytest{5}] +ignore_outcome = true + +[testenv:lint] +description = lint source code +deps = + ruff +commands = + ruff check + ruff format --check diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..33e8596 --- /dev/null +++ b/uv.lock @@ -0,0 +1,1943 @@ +version = 1 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version < '3.11'", + "python_full_version == '3.11.*'", + "python_full_version >= '3.12'", +] + +[[package]] +name = "alabaster" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929 }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, +] + +[[package]] +name = "appdirs" +version = "1.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/d8/05696357e0311f5b5c316d7b95f46c669dd9c15aaeecbb48c7d0aeb88c40/appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", size = 13470 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128", size = 9566 }, +] + +[[package]] +name = "appnope" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, +] + +[[package]] +name = "astroid" +version = "3.3.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/c5/5c83c48bbf547f3dd8b587529db7cf5a265a3368b33e85e76af8ff6061d3/astroid-3.3.8.tar.gz", hash = "sha256:a88c7994f914a4ea8572fac479459f4955eeccc877be3f2d959a33273b0cf40b", size = 398196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/28/0bc8a17d6cd4cc3c79ae41b7105a2b9a327c110e5ddd37a8a27b29a5c8a2/astroid-3.3.8-py3-none-any.whl", hash = "sha256:187ccc0c248bfbba564826c26f070494f7bc964fd286b6d9fff4420e55de828c", size = 275153 }, +] + +[[package]] +name = "asttokens" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918 }, +] + +[[package]] +name = "astunparse" +version = "1.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, + { name = "wheel" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/af/4182184d3c338792894f34a62672919db7ca008c89abee9b564dd34d8029/astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872", size = 18290 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2b/03/13dde6512ad7b4557eb792fbcf0c653af6076b81e5941d36ec61f7ce6028/astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8", size = 12732 }, +] + +[[package]] +name = "autograd" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ed/67975d75c0fe71220c8df2370c6c1390805790a641359b502f39c042c0c1/autograd-1.7.0.tar.gz", hash = "sha256:de743fd368d6df523cd37305dcd171861a9752a144493677d2c9f5a56983ff2f", size = 2564855 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/90/d13cf396989052cadd8511c1878b0913bbce28eeef5feb95710a92e03076/autograd-1.7.0-py3-none-any.whl", hash = "sha256:49680300f842f3a8722b060ac0d3ed7aca071d1ad4d3d38c9fdadafdcc73c30b", size = 52522 }, +] + +[[package]] +name = "autoray" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/b7/8ec4ffeca00c9360adb94be177313f711071628b21ea912abe6e246051e1/autoray-0.7.0.tar.gz", hash = "sha256:7829d21258512f87e02f23ce74ae5759af4ce8998069d2cce53468f1d701a219", size = 1214555 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/ac/d8fb343def8bc5b7f82f5dcf0892e9020a446f21107a2d7de1537ff2fdf3/autoray-0.7.0-py3-none-any.whl", hash = "sha256:03103957df3d1b66b8068158056c2909a72095b19d1b24262261276a714a5d07", size = 930011 }, +] + +[[package]] +name = "babel" +version = "2.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537 }, +] + +[[package]] +name = "cachetools" +version = "5.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d9/74/57df1ab0ce6bc5f6fa868e08de20df8ac58f9c44330c7671ad922d2bbeae/cachetools-5.5.1.tar.gz", hash = "sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95", size = 28044 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/4e/de4ff18bcf55857ba18d3a4bd48c8a9fde6bb0980c9d20b263f05387fd88/cachetools-5.5.1-py3-none-any.whl", hash = "sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb", size = 9530 }, +] + +[[package]] +name = "certifi" +version = "2025.1.31" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, +] + +[[package]] +name = "cffi" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191 }, + { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592 }, + { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024 }, + { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188 }, + { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571 }, + { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687 }, + { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211 }, + { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325 }, + { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784 }, + { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564 }, + { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, + { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, + { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264 }, + { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651 }, + { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259 }, + { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200 }, + { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235 }, + { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721 }, + { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242 }, + { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999 }, + { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242 }, + { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604 }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, +] + +[[package]] +name = "chardet" +version = "5.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/f7b6ab21ec75897ed80c17d79b15951a719226b9fababf1e40ea74d69079/chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", size = 2069618 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970", size = 199385 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013 }, + { url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285 }, + { url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449 }, + { url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892 }, + { url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123 }, + { url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943 }, + { url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063 }, + { url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578 }, + { url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629 }, + { url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778 }, + { url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453 }, + { url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479 }, + { url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790 }, + { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995 }, + { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471 }, + { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831 }, + { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335 }, + { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862 }, + { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673 }, + { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211 }, + { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039 }, + { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939 }, + { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075 }, + { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340 }, + { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205 }, + { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441 }, + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, +] + +[[package]] +name = "click" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, +] + +[[package]] +name = "click-option-group" +version = "0.5.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/b8/91054601a2e05fd9060cb1baf56be5b24145817b059e078669e1099529c7/click-option-group-0.5.6.tar.gz", hash = "sha256:97d06703873518cc5038509443742b25069a3c7562d1ea72ff08bfadde1ce777", size = 16517 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/75/81ea958bc0f7e410257cb2a42531b93a7695a31930cde87192c010a52c50/click_option_group-0.5.6-py3-none-any.whl", hash = "sha256:38a26d963ee3ad93332ddf782f9259c5bdfe405e73408d943ef5e7d0c3767ec7", size = 12467 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "comm" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/a8/fb783cb0abe2b5fded9f55e5703015cdf1c9c85b3669087c538dd15a6a86/comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", size = 6210 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3", size = 7180 }, +] + +[[package]] +name = "coverage" +version = "7.6.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/12/2a2a923edf4ddabdffed7ad6da50d96a5c126dae7b80a33df7310e329a1e/coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78", size = 207982 }, + { url = "https://files.pythonhosted.org/packages/ca/49/6985dbca9c7be3f3cb62a2e6e492a0c88b65bf40579e16c71ae9c33c6b23/coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c", size = 208414 }, + { url = "https://files.pythonhosted.org/packages/35/93/287e8f1d1ed2646f4e0b2605d14616c9a8a2697d0d1b453815eb5c6cebdb/coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a", size = 236860 }, + { url = "https://files.pythonhosted.org/packages/de/e1/cfdb5627a03567a10031acc629b75d45a4ca1616e54f7133ca1fa366050a/coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165", size = 234758 }, + { url = "https://files.pythonhosted.org/packages/6d/85/fc0de2bcda3f97c2ee9fe8568f7d48f7279e91068958e5b2cc19e0e5f600/coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988", size = 235920 }, + { url = "https://files.pythonhosted.org/packages/79/73/ef4ea0105531506a6f4cf4ba571a214b14a884630b567ed65b3d9c1975e1/coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5", size = 234986 }, + { url = "https://files.pythonhosted.org/packages/c6/4d/75afcfe4432e2ad0405c6f27adeb109ff8976c5e636af8604f94f29fa3fc/coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3", size = 233446 }, + { url = "https://files.pythonhosted.org/packages/86/5b/efee56a89c16171288cafff022e8af44f8f94075c2d8da563c3935212871/coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5", size = 234566 }, + { url = "https://files.pythonhosted.org/packages/f2/db/67770cceb4a64d3198bf2aa49946f411b85ec6b0a9b489e61c8467a4253b/coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244", size = 210675 }, + { url = "https://files.pythonhosted.org/packages/8d/27/e8bfc43f5345ec2c27bc8a1fa77cdc5ce9dcf954445e11f14bb70b889d14/coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e", size = 211518 }, + { url = "https://files.pythonhosted.org/packages/85/d2/5e175fcf6766cf7501a8541d81778fd2f52f4870100e791f5327fd23270b/coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3", size = 208088 }, + { url = "https://files.pythonhosted.org/packages/4b/6f/06db4dc8fca33c13b673986e20e466fd936235a6ec1f0045c3853ac1b593/coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43", size = 208536 }, + { url = "https://files.pythonhosted.org/packages/0d/62/c6a0cf80318c1c1af376d52df444da3608eafc913b82c84a4600d8349472/coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132", size = 240474 }, + { url = "https://files.pythonhosted.org/packages/a3/59/750adafc2e57786d2e8739a46b680d4fb0fbc2d57fbcb161290a9f1ecf23/coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f", size = 237880 }, + { url = "https://files.pythonhosted.org/packages/2c/f8/ef009b3b98e9f7033c19deb40d629354aab1d8b2d7f9cfec284dbedf5096/coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994", size = 239750 }, + { url = "https://files.pythonhosted.org/packages/a6/e2/6622f3b70f5f5b59f705e680dae6db64421af05a5d1e389afd24dae62e5b/coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99", size = 238642 }, + { url = "https://files.pythonhosted.org/packages/2d/10/57ac3f191a3c95c67844099514ff44e6e19b2915cd1c22269fb27f9b17b6/coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd", size = 237266 }, + { url = "https://files.pythonhosted.org/packages/ee/2d/7016f4ad9d553cabcb7333ed78ff9d27248ec4eba8dd21fa488254dff894/coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", size = 238045 }, + { url = "https://files.pythonhosted.org/packages/a7/fe/45af5c82389a71e0cae4546413266d2195c3744849669b0bab4b5f2c75da/coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", size = 210647 }, + { url = "https://files.pythonhosted.org/packages/db/11/3f8e803a43b79bc534c6a506674da9d614e990e37118b4506faf70d46ed6/coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", size = 211508 }, + { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281 }, + { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514 }, + { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537 }, + { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572 }, + { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639 }, + { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072 }, + { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386 }, + { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054 }, + { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904 }, + { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692 }, + { url = "https://files.pythonhosted.org/packages/25/6d/31883d78865529257bf847df5789e2ae80e99de8a460c3453dbfbe0db069/coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", size = 208308 }, + { url = "https://files.pythonhosted.org/packages/70/22/3f2b129cc08de00c83b0ad6252e034320946abfc3e4235c009e57cfeee05/coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", size = 208565 }, + { url = "https://files.pythonhosted.org/packages/97/0a/d89bc2d1cc61d3a8dfe9e9d75217b2be85f6c73ebf1b9e3c2f4e797f4531/coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", size = 241083 }, + { url = "https://files.pythonhosted.org/packages/4c/81/6d64b88a00c7a7aaed3a657b8eaa0931f37a6395fcef61e53ff742b49c97/coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", size = 238235 }, + { url = "https://files.pythonhosted.org/packages/9a/0b/7797d4193f5adb4b837207ed87fecf5fc38f7cc612b369a8e8e12d9fa114/coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", size = 240220 }, + { url = "https://files.pythonhosted.org/packages/65/4d/6f83ca1bddcf8e51bf8ff71572f39a1c73c34cf50e752a952c34f24d0a60/coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", size = 239847 }, + { url = "https://files.pythonhosted.org/packages/30/9d/2470df6aa146aff4c65fee0f87f58d2164a67533c771c9cc12ffcdb865d5/coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", size = 237922 }, + { url = "https://files.pythonhosted.org/packages/08/dd/723fef5d901e6a89f2507094db66c091449c8ba03272861eaefa773ad95c/coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", size = 239783 }, + { url = "https://files.pythonhosted.org/packages/3d/f7/64d3298b2baf261cb35466000628706ce20a82d42faf9b771af447cd2b76/coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", size = 210965 }, + { url = "https://files.pythonhosted.org/packages/d5/58/ec43499a7fc681212fe7742fe90b2bc361cdb72e3181ace1604247a5b24d/coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", size = 211719 }, + { url = "https://files.pythonhosted.org/packages/ab/c9/f2857a135bcff4330c1e90e7d03446b036b2363d4ad37eb5e3a47bbac8a6/coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", size = 209050 }, + { url = "https://files.pythonhosted.org/packages/aa/b3/f840e5bd777d8433caa9e4a1eb20503495709f697341ac1a8ee6a3c906ad/coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", size = 209321 }, + { url = "https://files.pythonhosted.org/packages/85/7d/125a5362180fcc1c03d91850fc020f3831d5cda09319522bcfa6b2b70be7/coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", size = 252039 }, + { url = "https://files.pythonhosted.org/packages/a9/9c/4358bf3c74baf1f9bddd2baf3756b54c07f2cfd2535f0a47f1e7757e54b3/coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", size = 247758 }, + { url = "https://files.pythonhosted.org/packages/cf/c7/de3eb6fc5263b26fab5cda3de7a0f80e317597a4bad4781859f72885f300/coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", size = 250119 }, + { url = "https://files.pythonhosted.org/packages/3e/e6/43de91f8ba2ec9140c6a4af1102141712949903dc732cf739167cfa7a3bc/coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", size = 249597 }, + { url = "https://files.pythonhosted.org/packages/08/40/61158b5499aa2adf9e37bc6d0117e8f6788625b283d51e7e0c53cf340530/coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", size = 247473 }, + { url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737 }, + { url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611 }, + { url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781 }, + { url = "https://files.pythonhosted.org/packages/a1/70/de81bfec9ed38a64fc44a77c7665e20ca507fc3265597c28b0d989e4082e/coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f", size = 200223 }, +] + +[[package]] +name = "debugpy" +version = "1.8.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/25/c74e337134edf55c4dfc9af579eccb45af2393c40960e2795a94351e8140/debugpy-1.8.12.tar.gz", hash = "sha256:646530b04f45c830ceae8e491ca1c9320a2d2f0efea3141487c82130aba70dce", size = 1641122 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/19/dd58334c0a1ec07babf80bf29fb8daf1a7ca4c1a3bbe61548e40616ac087/debugpy-1.8.12-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:a2ba7ffe58efeae5b8fad1165357edfe01464f9aef25e814e891ec690e7dd82a", size = 2076091 }, + { url = "https://files.pythonhosted.org/packages/4c/37/bde1737da15f9617d11ab7b8d5267165f1b7dae116b2585a6643e89e1fa2/debugpy-1.8.12-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbbd4149c4fc5e7d508ece083e78c17442ee13b0e69bfa6bd63003e486770f45", size = 3560717 }, + { url = "https://files.pythonhosted.org/packages/d9/ca/bc67f5a36a7de072908bc9e1156c0f0b272a9a2224cf21540ab1ffd71a1f/debugpy-1.8.12-cp310-cp310-win32.whl", hash = "sha256:b202f591204023b3ce62ff9a47baa555dc00bb092219abf5caf0e3718ac20e7c", size = 5180672 }, + { url = "https://files.pythonhosted.org/packages/c1/b9/e899c0a80dfa674dbc992f36f2b1453cd1ee879143cdb455bc04fce999da/debugpy-1.8.12-cp310-cp310-win_amd64.whl", hash = "sha256:9649eced17a98ce816756ce50433b2dd85dfa7bc92ceb60579d68c053f98dff9", size = 5212702 }, + { url = "https://files.pythonhosted.org/packages/af/9f/5b8af282253615296264d4ef62d14a8686f0dcdebb31a669374e22fff0a4/debugpy-1.8.12-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:36f4829839ef0afdfdd208bb54f4c3d0eea86106d719811681a8627ae2e53dd5", size = 2174643 }, + { url = "https://files.pythonhosted.org/packages/ef/31/f9274dcd3b0f9f7d1e60373c3fa4696a585c55acb30729d313bb9d3bcbd1/debugpy-1.8.12-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a28ed481d530e3138553be60991d2d61103ce6da254e51547b79549675f539b7", size = 3133457 }, + { url = "https://files.pythonhosted.org/packages/ab/ca/6ee59e9892e424477e0c76e3798046f1fd1288040b927319c7a7b0baa484/debugpy-1.8.12-cp311-cp311-win32.whl", hash = "sha256:4ad9a94d8f5c9b954e0e3b137cc64ef3f579d0df3c3698fe9c3734ee397e4abb", size = 5106220 }, + { url = "https://files.pythonhosted.org/packages/d5/1a/8ab508ab05ede8a4eae3b139bbc06ea3ca6234f9e8c02713a044f253be5e/debugpy-1.8.12-cp311-cp311-win_amd64.whl", hash = "sha256:4703575b78dd697b294f8c65588dc86874ed787b7348c65da70cfc885efdf1e1", size = 5130481 }, + { url = "https://files.pythonhosted.org/packages/ba/e6/0f876ecfe5831ebe4762b19214364753c8bc2b357d28c5d739a1e88325c7/debugpy-1.8.12-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:7e94b643b19e8feb5215fa508aee531387494bf668b2eca27fa769ea11d9f498", size = 2500846 }, + { url = "https://files.pythonhosted.org/packages/19/64/33f41653a701f3cd2cbff8b41ebaad59885b3428b5afd0d93d16012ecf17/debugpy-1.8.12-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:086b32e233e89a2740c1615c2f775c34ae951508b28b308681dbbb87bba97d06", size = 4222181 }, + { url = "https://files.pythonhosted.org/packages/32/a6/02646cfe50bfacc9b71321c47dc19a46e35f4e0aceea227b6d205e900e34/debugpy-1.8.12-cp312-cp312-win32.whl", hash = "sha256:2ae5df899732a6051b49ea2632a9ea67f929604fd2b036613a9f12bc3163b92d", size = 5227017 }, + { url = "https://files.pythonhosted.org/packages/da/a6/10056431b5c47103474312cf4a2ec1001f73e0b63b1216706d5fef2531eb/debugpy-1.8.12-cp312-cp312-win_amd64.whl", hash = "sha256:39dfbb6fa09f12fae32639e3286112fc35ae976114f1f3d37375f3130a820969", size = 5267555 }, + { url = "https://files.pythonhosted.org/packages/cf/4d/7c3896619a8791effd5d8c31f0834471fc8f8fb3047ec4f5fc69dd1393dd/debugpy-1.8.12-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:696d8ae4dff4cbd06bf6b10d671e088b66669f110c7c4e18a44c43cf75ce966f", size = 2485246 }, + { url = "https://files.pythonhosted.org/packages/99/46/bc6dcfd7eb8cc969a5716d858e32485eb40c72c6a8dc88d1e3a4d5e95813/debugpy-1.8.12-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:898fba72b81a654e74412a67c7e0a81e89723cfe2a3ea6fcd3feaa3395138ca9", size = 4218616 }, + { url = "https://files.pythonhosted.org/packages/03/dd/d7fcdf0381a9b8094da1f6a1c9f19fed493a4f8576a2682349b3a8b20ec7/debugpy-1.8.12-cp313-cp313-win32.whl", hash = "sha256:22a11c493c70413a01ed03f01c3c3a2fc4478fc6ee186e340487b2edcd6f4180", size = 5226540 }, + { url = "https://files.pythonhosted.org/packages/25/bd/ecb98f5b5fc7ea0bfbb3c355bc1dd57c198a28780beadd1e19915bf7b4d9/debugpy-1.8.12-cp313-cp313-win_amd64.whl", hash = "sha256:fdb3c6d342825ea10b90e43d7f20f01535a72b3a1997850c0c3cefa5c27a4a2c", size = 5267134 }, + { url = "https://files.pythonhosted.org/packages/38/c4/5120ad36405c3008f451f94b8f92ef1805b1e516f6ff870f331ccb3c4cc0/debugpy-1.8.12-py2.py3-none-any.whl", hash = "sha256:274b6a2040349b5c9864e475284bce5bb062e63dce368a394b8cc865ae3b00c6", size = 5229490 }, +] + +[[package]] +name = "decorator" +version = "5.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/0c/8d907af351aa16b42caae42f9d6aa37b900c67308052d10fdce809f8d952/decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", size = 35016 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 }, +] + +[[package]] +name = "diastatic-malt" +version = "2.15.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astunparse" }, + { name = "gast" }, + { name = "termcolor" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/95/27/c2f011f2db21317066831ed026a95463d5ae62acce3f044f63d4ea6ab3a9/diastatic-malt-2.15.2.tar.gz", hash = "sha256:7eb90d8c30b7ff16b4e84c3a65de2ff7f5b7b9d0f5cdea23918e747ff7fb5320", size = 115044 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/73/785c03860b1106f8f0ffbc69f2521bde1b58545114970cbbd3540d7f5434/diastatic_malt-2.15.2-py3-none-any.whl", hash = "sha256:85429257b356030f101c31b2c7d506c4829f21bd865aed796766f900d7908407", size = 167919 }, +] + +[[package]] +name = "distlib" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 }, +] + +[[package]] +name = "docutils" +version = "0.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 }, +] + +[[package]] +name = "dotty-dict" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/ab/88d67f02024700b48cd8232579ad1316aa9df2272c63049c27cc094229d6/dotty_dict-1.3.1.tar.gz", hash = "sha256:4b016e03b8ae265539757a53eba24b9bfda506fb94fbce0bee843c6f05541a15", size = 7699 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/91/e0d457ee03ec33d79ee2cd8d212debb1bc21dfb99728ae35efdb5832dc22/dotty_dict-1.3.1-py3-none-any.whl", hash = "sha256:5022d234d9922f13aa711b4950372a06a6d64cb6d6db9ba43d0ba133ebfce31f", size = 7014 }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "executing" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755", size = 978693 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702 }, +] + +[[package]] +name = "filelock" +version = "3.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/9c/0b15fb47b464e1b663b1acd1253a062aa5feecb07d4e597daea542ebd2b5/filelock-3.17.0.tar.gz", hash = "sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e", size = 18027 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/ec/00d68c4ddfedfe64159999e5f8a98fb8442729a63e2077eb9dcd89623d27/filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338", size = 16164 }, +] + +[[package]] +name = "gast" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3c/14/c566f5ca00c115db7725263408ff952b8ae6d6a4e792ef9c84e77d9af7a1/gast-0.6.0.tar.gz", hash = "sha256:88fc5300d32c7ac6ca7b515310862f71e6fdf2c029bbec7c66c0f5dd47b6b1fb", size = 27708 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/61/8001b38461d751cd1a0c3a6ae84346796a5758123f3ed97a1b121dfbf4f3/gast-0.6.0-py3-none-any.whl", hash = "sha256:52b182313f7330389f72b069ba00f174cfe2a06411099547288839c6cbafbd54", size = 21173 }, +] + +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794 }, +] + +[[package]] +name = "gitpython" +version = "3.1.44" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/89/37df0b71473153574a5cdef8f242de422a0f5d26d7a9e231e6f169b4ad14/gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269", size = 214196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/9a/4114a9057db2f1462d5c8f8390ab7383925fe1ac012eaa42402ad65c2963/GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110", size = 207599 }, +] + +[[package]] +name = "identify" +version = "2.6.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/bf/c68c46601bacd4c6fb4dd751a42b6e7087240eaabc6487f2ef7a48e0e8fc/identify-2.6.6.tar.gz", hash = "sha256:7bec12768ed44ea4761efb47806f0a41f86e7c0a5fdf5950d4648c90eca7e251", size = 99217 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/74/a1/68a395c17eeefb04917034bd0a1bfa765e7654fa150cca473d669aa3afb5/identify-2.6.6-py2.py3-none-any.whl", hash = "sha256:cbd1810bce79f8b671ecb20f53ee0ae8e86ae84b557de31d89709dc2a48ba881", size = 99083 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 }, +] + +[[package]] +name = "importlib-resources" +version = "6.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/8c/f834fbf984f691b4f7ff60f50b514cc3de5cc08abfc3295564dd89c5e2e7/importlib_resources-6.5.2.tar.gz", hash = "sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c", size = 44693 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl", hash = "sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec", size = 37461 }, +] + +[[package]] +name = "ipykernel" +version = "6.29.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appnope", marker = "platform_system == 'Darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/5c/67594cb0c7055dc50814b21731c22a601101ea3b1b50a9a1b090e11f5d0f/ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215", size = 163367 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/5c/368ae6c01c7628438358e6d337c19b05425727fbb221d2a3c4303c372f42/ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5", size = 117173 }, +] + +[[package]] +name = "ipython" +version = "8.32.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/80/4d2a072e0db7d250f134bc11676517299264ebe16d62a8619d49a78ced73/ipython-8.32.0.tar.gz", hash = "sha256:be2c91895b0b9ea7ba49d33b23e2040c352b33eb6a519cca7ce6e0c743444251", size = 5507441 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e1/f4474a7ecdb7745a820f6f6039dc43c66add40f1bcc66485607d93571af6/ipython-8.32.0-py3-none-any.whl", hash = "sha256:cae85b0c61eff1fc48b0a8002de5958b6528fa9c8defb1894da63f42613708aa", size = 825524 }, +] + +[[package]] +name = "jedi" +version = "0.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, +] + +[[package]] +name = "jinja2" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 }, +] + +[[package]] +name = "joblib" +version = "1.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/64/33/60135848598c076ce4b231e1b1895170f45fbcaeaa2c9d5e38b04db70c35/joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e", size = 2116621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/29/df4b9b42f2be0b623cbd5e2140cafcaa2bef0759a00b7b70104dcfe2fb51/joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6", size = 301817 }, +] + +[[package]] +name = "jupyter-client" +version = "8.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105 }, +] + +[[package]] +name = "jupyter-core" +version = "5.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/11/b56381fa6c3f4cc5d2cf54a7dbf98ad9aa0b339ef7a601d6053538b079a7/jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9", size = 87629 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c9/fb/108ecd1fe961941959ad0ee4e12ee7b8b1477247f30b1fdfd83ceaf017f0/jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", size = 28965 }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899 }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195 }, +] + +[[package]] +name = "networkx" +version = "3.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263 }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + +[[package]] +name = "nose2" +version = "0.15.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9b/a6/f29c21026c40476ce3994ac55e16ef60b9c1d2a88d02c3fc20b07d253dab/nose2-0.15.1.tar.gz", hash = "sha256:36770f519df5becd3cbfe0bee4abbfbf9b9f6b4eb4e03361d282b7efcfc4f0df", size = 169809 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/e6/6babe53a1dbfa55f6d30eb7408f4c4994658e5f27e3dbbb2b437912e5a32/nose2-0.15.1-py3-none-any.whl", hash = "sha256:564450c0c4f1602dfe171902ceb4726cc56658af7a620ae1826f1ffc86b09a86", size = 211274 }, +] + +[package.optional-dependencies] +coverage-plugin = [ + { name = "coverage" }, +] + +[[package]] +name = "numpy" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/75/10dd1f8116a8b796cb2c737b674e02d02e80454bda953fa7e65d8c12b016/numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78", size = 18902015 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/21/91/3495b3237510f79f5d81f2508f9f13fea78ebfdf07538fc7444badda173d/numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece", size = 21165245 }, + { url = "https://files.pythonhosted.org/packages/05/33/26178c7d437a87082d11019292dce6d3fe6f0e9026b7b2309cbf3e489b1d/numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04", size = 13738540 }, + { url = "https://files.pythonhosted.org/packages/ec/31/cc46e13bf07644efc7a4bf68df2df5fb2a1a88d0cd0da9ddc84dc0033e51/numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66", size = 5300623 }, + { url = "https://files.pythonhosted.org/packages/6e/16/7bfcebf27bb4f9d7ec67332ffebee4d1bf085c84246552d52dbb548600e7/numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b", size = 6901774 }, + { url = "https://files.pythonhosted.org/packages/f9/a3/561c531c0e8bf082c5bef509d00d56f82e0ea7e1e3e3a7fc8fa78742a6e5/numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd", size = 13907081 }, + { url = "https://files.pythonhosted.org/packages/fa/66/f7177ab331876200ac7563a580140643d1179c8b4b6a6b0fc9838de2a9b8/numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318", size = 19523451 }, + { url = "https://files.pythonhosted.org/packages/25/7f/0b209498009ad6453e4efc2c65bcdf0ae08a182b2b7877d7ab38a92dc542/numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8", size = 19927572 }, + { url = "https://files.pythonhosted.org/packages/3e/df/2619393b1e1b565cd2d4c4403bdd979621e2c4dea1f8532754b2598ed63b/numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326", size = 14400722 }, + { url = "https://files.pythonhosted.org/packages/22/ad/77e921b9f256d5da36424ffb711ae79ca3f451ff8489eeca544d0701d74a/numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97", size = 6472170 }, + { url = "https://files.pythonhosted.org/packages/10/05/3442317535028bc29cf0c0dd4c191a4481e8376e9f0db6bcf29703cadae6/numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131", size = 15905558 }, + { url = "https://files.pythonhosted.org/packages/8b/cf/034500fb83041aa0286e0fb16e7c76e5c8b67c0711bb6e9e9737a717d5fe/numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448", size = 21169137 }, + { url = "https://files.pythonhosted.org/packages/4a/d9/32de45561811a4b87fbdee23b5797394e3d1504b4a7cf40c10199848893e/numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195", size = 13703552 }, + { url = "https://files.pythonhosted.org/packages/c1/ca/2f384720020c7b244d22508cb7ab23d95f179fcfff33c31a6eeba8d6c512/numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57", size = 5298957 }, + { url = "https://files.pythonhosted.org/packages/0e/78/a3e4f9fb6aa4e6fdca0c5428e8ba039408514388cf62d89651aade838269/numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a", size = 6905573 }, + { url = "https://files.pythonhosted.org/packages/a0/72/cfc3a1beb2caf4efc9d0b38a15fe34025230da27e1c08cc2eb9bfb1c7231/numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669", size = 13914330 }, + { url = "https://files.pythonhosted.org/packages/ba/a8/c17acf65a931ce551fee11b72e8de63bf7e8a6f0e21add4c937c83563538/numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951", size = 19534895 }, + { url = "https://files.pythonhosted.org/packages/ba/86/8767f3d54f6ae0165749f84648da9dcc8cd78ab65d415494962c86fac80f/numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9", size = 19937253 }, + { url = "https://files.pythonhosted.org/packages/df/87/f76450e6e1c14e5bb1eae6836478b1028e096fd02e85c1c37674606ab752/numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15", size = 14414074 }, + { url = "https://files.pythonhosted.org/packages/5c/ca/0f0f328e1e59f73754f06e1adfb909de43726d4f24c6a3f8805f34f2b0fa/numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4", size = 6470640 }, + { url = "https://files.pythonhosted.org/packages/eb/57/3a3f14d3a759dcf9bf6e9eda905794726b758819df4663f217d658a58695/numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc", size = 15910230 }, + { url = "https://files.pythonhosted.org/packages/45/40/2e117be60ec50d98fa08c2f8c48e09b3edea93cfcabd5a9ff6925d54b1c2/numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b", size = 20895803 }, + { url = "https://files.pythonhosted.org/packages/46/92/1b8b8dee833f53cef3e0a3f69b2374467789e0bb7399689582314df02651/numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e", size = 13471835 }, + { url = "https://files.pythonhosted.org/packages/7f/19/e2793bde475f1edaea6945be141aef6c8b4c669b90c90a300a8954d08f0a/numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c", size = 5038499 }, + { url = "https://files.pythonhosted.org/packages/e3/ff/ddf6dac2ff0dd50a7327bcdba45cb0264d0e96bb44d33324853f781a8f3c/numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c", size = 6633497 }, + { url = "https://files.pythonhosted.org/packages/72/21/67f36eac8e2d2cd652a2e69595a54128297cdcb1ff3931cfc87838874bd4/numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692", size = 13621158 }, + { url = "https://files.pythonhosted.org/packages/39/68/e9f1126d757653496dbc096cb429014347a36b228f5a991dae2c6b6cfd40/numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a", size = 19236173 }, + { url = "https://files.pythonhosted.org/packages/d1/e9/1f5333281e4ebf483ba1c888b1d61ba7e78d7e910fdd8e6499667041cc35/numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c", size = 19634174 }, + { url = "https://files.pythonhosted.org/packages/71/af/a469674070c8d8408384e3012e064299f7a2de540738a8e414dcfd639996/numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded", size = 14099701 }, + { url = "https://files.pythonhosted.org/packages/d0/3d/08ea9f239d0e0e939b6ca52ad403c84a2bce1bde301a8eb4888c1c1543f1/numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5", size = 6174313 }, + { url = "https://files.pythonhosted.org/packages/b2/b5/4ac39baebf1fdb2e72585c8352c56d063b6126be9fc95bd2bb5ef5770c20/numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a", size = 15606179 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pandas" +version = "2.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "pytz" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9c/d6/9f8431bacc2e19dca897724cd097b1bb224a6ad5433784a44b587c7c13af/pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667", size = 4399213 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/70/c853aec59839bceed032d52010ff5f1b8d87dc3114b762e4ba2727661a3b/pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5", size = 12580827 }, + { url = "https://files.pythonhosted.org/packages/99/f2/c4527768739ffa4469b2b4fff05aa3768a478aed89a2f271a79a40eee984/pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348", size = 11303897 }, + { url = "https://files.pythonhosted.org/packages/ed/12/86c1747ea27989d7a4064f806ce2bae2c6d575b950be087837bdfcabacc9/pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed", size = 66480908 }, + { url = "https://files.pythonhosted.org/packages/44/50/7db2cd5e6373ae796f0ddad3675268c8d59fb6076e66f0c339d61cea886b/pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57", size = 13064210 }, + { url = "https://files.pythonhosted.org/packages/61/61/a89015a6d5536cb0d6c3ba02cebed51a95538cf83472975275e28ebf7d0c/pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42", size = 16754292 }, + { url = "https://files.pythonhosted.org/packages/ce/0d/4cc7b69ce37fac07645a94e1d4b0880b15999494372c1523508511b09e40/pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f", size = 14416379 }, + { url = "https://files.pythonhosted.org/packages/31/9e/6ebb433de864a6cd45716af52a4d7a8c3c9aaf3a98368e61db9e69e69a9c/pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645", size = 11598471 }, + { url = "https://files.pythonhosted.org/packages/a8/44/d9502bf0ed197ba9bf1103c9867d5904ddcaf869e52329787fc54ed70cc8/pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039", size = 12602222 }, + { url = "https://files.pythonhosted.org/packages/52/11/9eac327a38834f162b8250aab32a6781339c69afe7574368fffe46387edf/pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd", size = 11321274 }, + { url = "https://files.pythonhosted.org/packages/45/fb/c4beeb084718598ba19aa9f5abbc8aed8b42f90930da861fcb1acdb54c3a/pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698", size = 15579836 }, + { url = "https://files.pythonhosted.org/packages/cd/5f/4dba1d39bb9c38d574a9a22548c540177f78ea47b32f99c0ff2ec499fac5/pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc", size = 13058505 }, + { url = "https://files.pythonhosted.org/packages/b9/57/708135b90391995361636634df1f1130d03ba456e95bcf576fada459115a/pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3", size = 16744420 }, + { url = "https://files.pythonhosted.org/packages/86/4a/03ed6b7ee323cf30404265c284cee9c65c56a212e0a08d9ee06984ba2240/pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32", size = 14440457 }, + { url = "https://files.pythonhosted.org/packages/ed/8c/87ddf1fcb55d11f9f847e3c69bb1c6f8e46e2f40ab1a2d2abadb2401b007/pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5", size = 11617166 }, + { url = "https://files.pythonhosted.org/packages/17/a3/fb2734118db0af37ea7433f57f722c0a56687e14b14690edff0cdb4b7e58/pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9", size = 12529893 }, + { url = "https://files.pythonhosted.org/packages/e1/0c/ad295fd74bfac85358fd579e271cded3ac969de81f62dd0142c426b9da91/pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4", size = 11363475 }, + { url = "https://files.pythonhosted.org/packages/c6/2a/4bba3f03f7d07207481fed47f5b35f556c7441acddc368ec43d6643c5777/pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3", size = 15188645 }, + { url = "https://files.pythonhosted.org/packages/38/f8/d8fddee9ed0d0c0f4a2132c1dfcf0e3e53265055da8df952a53e7eaf178c/pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319", size = 12739445 }, + { url = "https://files.pythonhosted.org/packages/20/e8/45a05d9c39d2cea61ab175dbe6a2de1d05b679e8de2011da4ee190d7e748/pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8", size = 16359235 }, + { url = "https://files.pythonhosted.org/packages/1d/99/617d07a6a5e429ff90c90da64d428516605a1ec7d7bea494235e1c3882de/pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a", size = 14056756 }, + { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, + { url = "https://files.pythonhosted.org/packages/64/22/3b8f4e0ed70644e85cfdcd57454686b9057c6c38d2f74fe4b8bc2527214a/pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015", size = 12477643 }, + { url = "https://files.pythonhosted.org/packages/e4/93/b3f5d1838500e22c8d793625da672f3eec046b1a99257666c94446969282/pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28", size = 11281573 }, + { url = "https://files.pythonhosted.org/packages/f5/94/6c79b07f0e5aab1dcfa35a75f4817f5c4f677931d4234afcd75f0e6a66ca/pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0", size = 15196085 }, + { url = "https://files.pythonhosted.org/packages/e8/31/aa8da88ca0eadbabd0a639788a6da13bb2ff6edbbb9f29aa786450a30a91/pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24", size = 12711809 }, + { url = "https://files.pythonhosted.org/packages/ee/7c/c6dbdb0cb2a4344cacfb8de1c5808ca885b2e4dcfde8008266608f9372af/pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659", size = 16356316 }, + { url = "https://files.pythonhosted.org/packages/57/b7/8b757e7d92023b832869fa8881a992696a0bfe2e26f72c9ae9f255988d42/pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb", size = 14022055 }, + { url = "https://files.pythonhosted.org/packages/3b/bc/4b18e2b8c002572c5a441a64826252ce5da2aa738855747247a971988043/pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d", size = 11481175 }, + { url = "https://files.pythonhosted.org/packages/76/a3/a5d88146815e972d40d19247b2c162e88213ef51c7c25993942c39dbf41d/pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468", size = 12615650 }, + { url = "https://files.pythonhosted.org/packages/9c/8c/f0fd18f6140ddafc0c24122c8a964e48294acc579d47def376fef12bcb4a/pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18", size = 11290177 }, + { url = "https://files.pythonhosted.org/packages/ed/f9/e995754eab9c0f14c6777401f7eece0943840b7a9fc932221c19d1abee9f/pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2", size = 14651526 }, + { url = "https://files.pythonhosted.org/packages/25/b0/98d6ae2e1abac4f35230aa756005e8654649d305df9a28b16b9ae4353bff/pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4", size = 11871013 }, + { url = "https://files.pythonhosted.org/packages/cc/57/0f72a10f9db6a4628744c8e8f0df4e6e21de01212c7c981d31e50ffc8328/pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d", size = 15711620 }, + { url = "https://files.pythonhosted.org/packages/ab/5f/b38085618b950b79d2d9164a711c52b10aefc0ae6833b96f626b7021b2ed/pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", size = 13098436 }, +] + +[[package]] +name = "parso" +version = "0.8.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650 }, +] + +[[package]] +name = "pennylane" +version = "0.40.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appdirs" }, + { name = "autograd" }, + { name = "autoray" }, + { name = "cachetools" }, + { name = "diastatic-malt" }, + { name = "networkx" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pennylane-lightning" }, + { name = "requests" }, + { name = "rustworkx" }, + { name = "scipy" }, + { name = "tomlkit" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/89/07f61eebb1a367fd673a48122caa6ef1ca37254ea2bd9599384886ef473a/PennyLane-0.40.0-py3-none-any.whl", hash = "sha256:c93bb48ff80833edaf424b3b91e01a56cd25b22170bc99b7e53e7168a1ad4dd1", size = 2042584 }, +] + +[[package]] +name = "pennylane-lightning" +version = "0.40.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pennylane" }, + { name = "scipy-openblas32" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f2/b5/2b9e2a33b434c57bc12d07fd24404642f9bc9939de08c84861b6a0c86ff8/pennylane_lightning-0.40.0.tar.gz", hash = "sha256:edc95e75ef1b4e6dba96e914893175f9448d4d1b53a6e78614cb7587a8a22f2f", size = 705730 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/24/b6427bcf10cab30bf597e0d39b9c690744a8c54b57635c2a32592cd56cad/PennyLane_Lightning-0.40.0-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:3a6915cc17ce99cd4f3d04dcf7d579f59cecdc2866cd4e8e1c33478d86101437", size = 1650344 }, + { url = "https://files.pythonhosted.org/packages/ae/a6/9a5eb31c1aaa9fb4265d5880bdf2bc583a3e4bf354f996938ada3ff42815/PennyLane_Lightning-0.40.0-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:4a66e8c644f634f9d1fda6b9223f5cc106acf4146334a25a23f948ec59b075c0", size = 2096093 }, + { url = "https://files.pythonhosted.org/packages/0b/ae/8b704574c461bac679205d0e00f24d2b59a35336bad1b2531ff30127d0ac/PennyLane_Lightning-0.40.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:a58ab1489fee0424840bc8f91e8f7e32ecc3338a714b2fe1bf68a9026a5a295a", size = 1935474 }, + { url = "https://files.pythonhosted.org/packages/f8/1c/7954b0f12e5d601a3858445dee97ce84b7b446af3b2506dbc4ab2ffc769d/PennyLane_Lightning-0.40.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:7fe9262c602b6c7f0ab893468867e24c63e9cacc7d77e19b448ac1361bb86a47", size = 2415155 }, + { url = "https://files.pythonhosted.org/packages/8c/76/13030e363ee277ca3ed1b83741812526da478acd8db89ace56fc68c2b592/PennyLane_Lightning-0.40.0-cp310-cp310-win_amd64.whl", hash = "sha256:3f75b7d39d63880e9d59562d78ae5ec63d2aed936b2feee3c937dfbcd080b834", size = 5886560 }, + { url = "https://files.pythonhosted.org/packages/eb/c1/8fa27ce4d0312715f95d56f9e774645f755e015240beedc19990d1572e54/PennyLane_Lightning-0.40.0-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:99cf7bcfb3a2a29838cc12f0001e3e7e02d35c5c1d696ce2e5ba0c3f2995c4d9", size = 1651680 }, + { url = "https://files.pythonhosted.org/packages/cd/64/325033ef92fbfabb13a0011937170d8a3464f360b5258b1750b8c47d86d5/PennyLane_Lightning-0.40.0-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:6b89ad785e16cc3b3d155b1abd27e42fcb5854a0e2d90452f6445fc0e80b1cf4", size = 2097858 }, + { url = "https://files.pythonhosted.org/packages/89/b0/d620837b450fb2a636299f544436f6b404113b6f6f794ba3339210174555/PennyLane_Lightning-0.40.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:20052041abc417d74d1794506d4340a8a2298b858e2b94591704e73670d913f9", size = 1937096 }, + { url = "https://files.pythonhosted.org/packages/ad/45/41590719fc296973af12ee69c4fe6b60f5513baaf2fa5da95706302e1bba/PennyLane_Lightning-0.40.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a3db3cf2c3caed80ce561b66bb4bf6b5712ecf0b08db986f24c4ff9e187e82b3", size = 2417872 }, + { url = "https://files.pythonhosted.org/packages/1c/73/3424647aaa4efb76a277b0127e53ddadb08dbb83a4a9278271016d92a399/PennyLane_Lightning-0.40.0-cp311-cp311-win_amd64.whl", hash = "sha256:fed88008b7d468cb1d0e5b3ef92d87f9b600d0896d21eff43655a521cc841d7b", size = 5902729 }, + { url = "https://files.pythonhosted.org/packages/ea/e9/aae813f23d152b1490fb1da6a92988e1223c1d7f3bb794e7ef3c968f6de6/PennyLane_Lightning-0.40.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:e3152f6b53390281334257554ecad90566cd4d200187971d238d2c7691000466", size = 1652466 }, + { url = "https://files.pythonhosted.org/packages/ca/88/731920ac69653fa4865c6fc8dadd825cf7a8912337429a6360cdfae6bc82/PennyLane_Lightning-0.40.0-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:8a4ff3f1d82f664e6d608d155cb019b189aac676c6c7cb40c4f92b15e0d2d485", size = 2100709 }, + { url = "https://files.pythonhosted.org/packages/47/9c/b5212067fb5d887d833a3208f922313a37eacdffab77e418042b69f2ddfe/PennyLane_Lightning-0.40.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:b2209727b8c914c8101087da188cbbc7b332bb77ceab4b6791c7ed7b3c5a942c", size = 1937768 }, + { url = "https://files.pythonhosted.org/packages/ee/18/813c1a1851fe351b7026df7739a4459bacd14c8f953989349deb07721e0d/PennyLane_Lightning-0.40.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:2ba97b4d6aa0a6eb774413ea3272d418959b792de6df8e4196171cad450f25af", size = 2416359 }, + { url = "https://files.pythonhosted.org/packages/7e/9e/b77ad246d048f79872581363e18ef3754a052dd4aa28e9dea37a046b8003/PennyLane_Lightning-0.40.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7715c84290fc1291e315d2c0d2bf5719cbe86e3e92fb538393ab130b3f5ba2", size = 5888346 }, + { url = "https://files.pythonhosted.org/packages/86/9a/bcd5eb98bc1df0cb3f5e97a04267bd5af47767f52898a3194a2a6d5b3fe7/PennyLane_Lightning-0.40.0-py3-none-any.whl", hash = "sha256:96390ce82767b3a66c4f8e0b1bcec2f4f15fb317652cffa9815e371e74458197", size = 935728 }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pockets" +version = "0.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/8e/0601097cfcce2e8c2297db5080e9719f549c2bd4b94420ddc8d3f848bbca/pockets-0.9.1.tar.gz", hash = "sha256:9320f1a3c6f7a9133fe3b571f283bcf3353cd70249025ae8d618e40e9f7e92b3", size = 24993 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/2f/a4583c70fbd8cd04910e2884bcc2bdd670e884061f7b4d70bc13e632a993/pockets-0.9.1-py2.py3-none-any.whl", hash = "sha256:68597934193c08a08eb2bf6a1d85593f627c22f9b065cc727a4f03f669d96d86", size = 26263 }, +] + +[[package]] +name = "pre-commit" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/13/b62d075317d8686071eb843f0bb1f195eb332f48869d3c31a4c6f1e063ac/pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4", size = 193330 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/b3/df14c580d82b9627d173ceea305ba898dca135feb360b6d84019d0803d3b/pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b", size = 220560 }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.50" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/e1/bd15cb8ffdcfeeb2bdc215de3c3cffca11408d829e4b8416dcfe71ba8854/prompt_toolkit-3.0.50.tar.gz", hash = "sha256:544748f3860a2623ca5cd6d2795e7a14f3d0e1c3c9728359013f79877fc89bab", size = 429087 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/ea/d836f008d33151c7a1f62caf3d8dd782e4d15f6a43897f64480c2b8de2ad/prompt_toolkit-3.0.50-py3-none-any.whl", hash = "sha256:9b6427eb19e479d98acff65196a307c555eb567989e6d88ebbb1b509d9779198", size = 387816 }, +] + +[[package]] +name = "psutil" +version = "6.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/5a/07871137bb752428aa4b659f910b399ba6f291156bdea939be3e96cae7cb/psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5", size = 508502 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/99/ca79d302be46f7bdd8321089762dd4476ee725fce16fc2b2e1dbba8cac17/psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8", size = 247511 }, + { url = "https://files.pythonhosted.org/packages/0b/6b/73dbde0dd38f3782905d4587049b9be64d76671042fdcaf60e2430c6796d/psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377", size = 248985 }, + { url = "https://files.pythonhosted.org/packages/17/38/c319d31a1d3f88c5b79c68b3116c129e5133f1822157dd6da34043e32ed6/psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003", size = 284488 }, + { url = "https://files.pythonhosted.org/packages/9c/39/0f88a830a1c8a3aba27fededc642da37613c57cbff143412e3536f89784f/psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160", size = 287477 }, + { url = "https://files.pythonhosted.org/packages/47/da/99f4345d4ddf2845cb5b5bd0d93d554e84542d116934fde07a0c50bd4e9f/psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3", size = 289017 }, + { url = "https://files.pythonhosted.org/packages/38/53/bd755c2896f4461fd4f36fa6a6dcb66a88a9e4b9fd4e5b66a77cf9d4a584/psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53", size = 250602 }, + { url = "https://files.pythonhosted.org/packages/7b/d7/7831438e6c3ebbfa6e01a927127a6cb42ad3ab844247f3c5b96bea25d73d/psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649", size = 254444 }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993 }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842 }, +] + +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, +] + +[[package]] +name = "pydantic" +version = "2.10.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, +] + +[[package]] +name = "pydantic-core" +version = "2.27.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938 }, + { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684 }, + { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169 }, + { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227 }, + { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695 }, + { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662 }, + { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370 }, + { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813 }, + { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287 }, + { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414 }, + { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301 }, + { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685 }, + { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876 }, + { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421 }, + { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998 }, + { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167 }, + { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071 }, + { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244 }, + { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470 }, + { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291 }, + { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613 }, + { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355 }, + { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661 }, + { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261 }, + { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361 }, + { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484 }, + { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102 }, + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, + { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159 }, + { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331 }, + { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467 }, + { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797 }, + { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839 }, + { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861 }, + { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582 }, + { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985 }, + { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715 }, +] + +[[package]] +name = "pygments" +version = "2.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, +] + +[[package]] +name = "pyproject-api" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7e/66/fdc17e94486836eda4ba7113c0db9ac7e2f4eea1b968ee09de2fe75e391b/pyproject_api-1.9.0.tar.gz", hash = "sha256:7e8a9854b2dfb49454fae421cb86af43efbb2b2454e5646ffb7623540321ae6e", size = 22714 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/1d/92b7c765df46f454889d9610292b0ccab15362be3119b9a624458455e8d5/pyproject_api-1.9.0-py3-none-any.whl", hash = "sha256:326df9d68dea22d9d98b5243c46e3ca3161b07a1b9b18e213d1e24fd0e605766", size = 13131 }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "python-gitlab" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, + { name = "requests-toolbelt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c4/ea/e2cde926d63526935c1df259177371a195089b631d67a577fe5c39fbc7e1/python_gitlab-4.13.0.tar.gz", hash = "sha256:576bfb0901faca0c6b2d1ff2592e02944a6ec3e086c3129fb43c2a0df56a1c67", size = 484996 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/5e/5fb4dcae9f5af5463c16952823d446ca449cce920efe8669871f600f0ab9/python_gitlab-4.13.0-py3-none-any.whl", hash = "sha256:8299a054fb571da16e1a8c1868fff01f34ac41ea1410c713a4647b3bbb2aa279", size = 145254 }, +] + +[[package]] +name = "python-semantic-release" +version = "9.18.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "click-option-group" }, + { name = "dotty-dict" }, + { name = "gitpython" }, + { name = "importlib-resources" }, + { name = "jinja2" }, + { name = "pydantic" }, + { name = "python-gitlab" }, + { name = "requests" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/b2/f79bae5c84035fb39720560f92e088762ce10b05d274cc25aa501e4966f7/python_semantic_release-9.18.0.tar.gz", hash = "sha256:bab1d5e2bb531e4002fdce72367dc8f9f80ef8f534e23f83edaaa9faec9c507f", size = 299191 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/39/d3c0c2d2168dff7bc496505891c01959a5c138d304b9661cf9b4b88c035a/python_semantic_release-9.18.0-py3-none-any.whl", hash = "sha256:4a0b93fa6d75c69f42d2429b41dff229e3bf1b4d90a368e4aa62039aaa7cecc6", size = 126449 }, +] + +[[package]] +name = "pytz" +version = "2025.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/57/df1c9157c8d5a05117e455d66fd7cf6dbc46974f832b1058ed4856785d8a/pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e", size = 319617 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/38/ac33370d784287baa1c3d538978b5e2ea064d4c1b93ffbd12826c190dd10/pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57", size = 507930 }, +] + +[[package]] +name = "pywin32" +version = "308" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/a6/3e9f2c474895c1bb61b11fa9640be00067b5c5b363c501ee9c3fa53aec01/pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e", size = 5927028 }, + { url = "https://files.pythonhosted.org/packages/d9/b4/84e2463422f869b4b718f79eb7530a4c1693e96b8a4e5e968de38be4d2ba/pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e", size = 6558484 }, + { url = "https://files.pythonhosted.org/packages/9f/8f/fb84ab789713f7c6feacaa08dad3ec8105b88ade8d1c4f0f0dfcaaa017d6/pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c", size = 7971454 }, + { url = "https://files.pythonhosted.org/packages/eb/e2/02652007469263fe1466e98439831d65d4ca80ea1a2df29abecedf7e47b7/pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a", size = 5928156 }, + { url = "https://files.pythonhosted.org/packages/48/ef/f4fb45e2196bc7ffe09cad0542d9aff66b0e33f6c0954b43e49c33cad7bd/pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b", size = 6559559 }, + { url = "https://files.pythonhosted.org/packages/79/ef/68bb6aa865c5c9b11a35771329e95917b5559845bd75b65549407f9fc6b4/pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6", size = 7972495 }, + { url = "https://files.pythonhosted.org/packages/00/7c/d00d6bdd96de4344e06c4afbf218bc86b54436a94c01c71a8701f613aa56/pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897", size = 5939729 }, + { url = "https://files.pythonhosted.org/packages/21/27/0c8811fbc3ca188f93b5354e7c286eb91f80a53afa4e11007ef661afa746/pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47", size = 6543015 }, + { url = "https://files.pythonhosted.org/packages/9d/0f/d40f8373608caed2255781a3ad9a51d03a594a1248cd632d6a298daca693/pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091", size = 7976033 }, + { url = "https://files.pythonhosted.org/packages/a9/a4/aa562d8935e3df5e49c161b427a3a2efad2ed4e9cf81c3de636f1fdddfd0/pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed", size = 5938579 }, + { url = "https://files.pythonhosted.org/packages/c7/50/b0efb8bb66210da67a53ab95fd7a98826a97ee21f1d22949863e6d588b22/pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4", size = 6542056 }, + { url = "https://files.pythonhosted.org/packages/26/df/2b63e3e4f2df0224f8aaf6d131f54fe4e8c96400eb9df563e2aae2e1a1f9/pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd", size = 7974986 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +] + +[[package]] +name = "pyzmq" +version = "26.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/e3/8d0382cb59feb111c252b54e8728257416a38ffcb2243c4e4775a3c990fe/pyzmq-26.2.1.tar.gz", hash = "sha256:17d72a74e5e9ff3829deb72897a175333d3ef5b5413948cae3cf7ebf0b02ecca", size = 278433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/3d/c2d9d46c033d1b51692ea49a22439f7f66d91d5c938e8b5c56ed7a2151c2/pyzmq-26.2.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:f39d1227e8256d19899d953e6e19ed2ccb689102e6d85e024da5acf410f301eb", size = 1345451 }, + { url = "https://files.pythonhosted.org/packages/0e/df/4754a8abcdeef280651f9bb51446c47659910940b392a66acff7c37f5cef/pyzmq-26.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a23948554c692df95daed595fdd3b76b420a4939d7a8a28d6d7dea9711878641", size = 942766 }, + { url = "https://files.pythonhosted.org/packages/74/da/e6053a3b13c912eded6c2cdeee22ff3a4c33820d17f9eb24c7b6e957ffe7/pyzmq-26.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95f5728b367a042df146cec4340d75359ec6237beebf4a8f5cf74657c65b9257", size = 678488 }, + { url = "https://files.pythonhosted.org/packages/9e/50/614934145244142401ca174ca81071777ab93aa88173973ba0154f491e09/pyzmq-26.2.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95f7b01b3f275504011cf4cf21c6b885c8d627ce0867a7e83af1382ebab7b3ff", size = 917115 }, + { url = "https://files.pythonhosted.org/packages/80/2b/ebeb7bc4fc8e9e61650b2e09581597355a4341d413fa9b2947d7a6558119/pyzmq-26.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80a00370a2ef2159c310e662c7c0f2d030f437f35f478bb8b2f70abd07e26b24", size = 874162 }, + { url = "https://files.pythonhosted.org/packages/79/48/93210621c331ad16313dc2849801411fbae10d91d878853933f2a85df8e7/pyzmq-26.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8531ed35dfd1dd2af95f5d02afd6545e8650eedbf8c3d244a554cf47d8924459", size = 874180 }, + { url = "https://files.pythonhosted.org/packages/f0/8b/40924b4d8e33bfdd54c1970fb50f327e39b90b902f897cf09b30b2e9ac48/pyzmq-26.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cdb69710e462a38e6039cf17259d328f86383a06c20482cc154327968712273c", size = 1208139 }, + { url = "https://files.pythonhosted.org/packages/c8/b2/82d6675fc89bd965eae13c45002c792d33f06824589844b03f8ea8fc6d86/pyzmq-26.2.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e7eeaef81530d0b74ad0d29eec9997f1c9230c2f27242b8d17e0ee67662c8f6e", size = 1520666 }, + { url = "https://files.pythonhosted.org/packages/9d/e2/5ff15f2d3f920dcc559d477bd9bb3faacd6d79fcf7c5448e585c78f84849/pyzmq-26.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:361edfa350e3be1f987e592e834594422338d7174364763b7d3de5b0995b16f3", size = 1420056 }, + { url = "https://files.pythonhosted.org/packages/40/a2/f9bbeccf7f75aa0d8963e224e5730abcefbf742e1f2ae9ea60fd9d6ff72b/pyzmq-26.2.1-cp310-cp310-win32.whl", hash = "sha256:637536c07d2fb6a354988b2dd1d00d02eb5dd443f4bbee021ba30881af1c28aa", size = 583874 }, + { url = "https://files.pythonhosted.org/packages/56/b1/44f513135843272f0e12f5aebf4af35839e2a88eb45411f2c8c010d8c856/pyzmq-26.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:45fad32448fd214fbe60030aa92f97e64a7140b624290834cc9b27b3a11f9473", size = 647367 }, + { url = "https://files.pythonhosted.org/packages/27/9c/1bef14a37b02d651a462811bbdb1390b61cd4a5b5e95cbd7cc2d60ef848c/pyzmq-26.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:d9da0289d8201c8a29fd158aaa0dfe2f2e14a181fd45e2dc1fbf969a62c1d594", size = 561784 }, + { url = "https://files.pythonhosted.org/packages/b9/03/5ecc46a6ed5971299f5c03e016ca637802d8660e44392bea774fb7797405/pyzmq-26.2.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:c059883840e634a21c5b31d9b9a0e2b48f991b94d60a811092bc37992715146a", size = 1346032 }, + { url = "https://files.pythonhosted.org/packages/40/51/48fec8f990ee644f461ff14c8fe5caa341b0b9b3a0ad7544f8ef17d6f528/pyzmq-26.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed038a921df836d2f538e509a59cb638df3e70ca0fcd70d0bf389dfcdf784d2a", size = 943324 }, + { url = "https://files.pythonhosted.org/packages/c1/f4/f322b389727c687845e38470b48d7a43c18a83f26d4d5084603c6c3f79ca/pyzmq-26.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9027a7fcf690f1a3635dc9e55e38a0d6602dbbc0548935d08d46d2e7ec91f454", size = 678418 }, + { url = "https://files.pythonhosted.org/packages/a8/df/2834e3202533bd05032d83e02db7ac09fa1be853bbef59974f2b2e3a8557/pyzmq-26.2.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d75fcb00a1537f8b0c0bb05322bc7e35966148ffc3e0362f0369e44a4a1de99", size = 915466 }, + { url = "https://files.pythonhosted.org/packages/b5/e2/45c0f6e122b562cb8c6c45c0dcac1160a4e2207385ef9b13463e74f93031/pyzmq-26.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0019cc804ac667fb8c8eaecdb66e6d4a68acf2e155d5c7d6381a5645bd93ae4", size = 873347 }, + { url = "https://files.pythonhosted.org/packages/de/b9/3e0fbddf8b87454e914501d368171466a12550c70355b3844115947d68ea/pyzmq-26.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:f19dae58b616ac56b96f2e2290f2d18730a898a171f447f491cc059b073ca1fa", size = 874545 }, + { url = "https://files.pythonhosted.org/packages/1f/1c/1ee41d6e10b2127263b1994bc53b9e74ece015b0d2c0a30e0afaf69b78b2/pyzmq-26.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f5eeeb82feec1fc5cbafa5ee9022e87ffdb3a8c48afa035b356fcd20fc7f533f", size = 1208630 }, + { url = "https://files.pythonhosted.org/packages/3d/a9/50228465c625851a06aeee97c74f253631f509213f979166e83796299c60/pyzmq-26.2.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:000760e374d6f9d1a3478a42ed0c98604de68c9e94507e5452951e598ebecfba", size = 1519568 }, + { url = "https://files.pythonhosted.org/packages/c6/f2/6360b619e69da78863c2108beb5196ae8b955fe1e161c0b886b95dc6b1ac/pyzmq-26.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:817fcd3344d2a0b28622722b98500ae9c8bfee0f825b8450932ff19c0b15bebd", size = 1419677 }, + { url = "https://files.pythonhosted.org/packages/da/d5/f179da989168f5dfd1be8103ef508ade1d38a8078dda4f10ebae3131a490/pyzmq-26.2.1-cp311-cp311-win32.whl", hash = "sha256:88812b3b257f80444a986b3596e5ea5c4d4ed4276d2b85c153a6fbc5ca457ae7", size = 582682 }, + { url = "https://files.pythonhosted.org/packages/60/50/e5b2e9de3ffab73ff92bee736216cf209381081fa6ab6ba96427777d98b1/pyzmq-26.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:ef29630fde6022471d287c15c0a2484aba188adbfb978702624ba7a54ddfa6c1", size = 648128 }, + { url = "https://files.pythonhosted.org/packages/d9/fe/7bb93476dd8405b0fc9cab1fd921a08bd22d5e3016aa6daea1a78d54129b/pyzmq-26.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:f32718ee37c07932cc336096dc7403525301fd626349b6eff8470fe0f996d8d7", size = 562465 }, + { url = "https://files.pythonhosted.org/packages/9c/b9/260a74786f162c7f521f5f891584a51d5a42fd15f5dcaa5c9226b2865fcc/pyzmq-26.2.1-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:a6549ecb0041dafa55b5932dcbb6c68293e0bd5980b5b99f5ebb05f9a3b8a8f3", size = 1348495 }, + { url = "https://files.pythonhosted.org/packages/bf/73/8a0757e4b68f5a8ccb90ddadbb76c6a5f880266cdb18be38c99bcdc17aaa/pyzmq-26.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0250c94561f388db51fd0213cdccbd0b9ef50fd3c57ce1ac937bf3034d92d72e", size = 945035 }, + { url = "https://files.pythonhosted.org/packages/cf/de/f02ec973cd33155bb772bae33ace774acc7cc71b87b25c4829068bec35de/pyzmq-26.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36ee4297d9e4b34b5dc1dd7ab5d5ea2cbba8511517ef44104d2915a917a56dc8", size = 671213 }, + { url = "https://files.pythonhosted.org/packages/d1/80/8fc583085f85ac91682744efc916888dd9f11f9f75a31aef1b78a5486c6c/pyzmq-26.2.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2a9cb17fd83b7a3a3009901aca828feaf20aa2451a8a487b035455a86549c09", size = 908750 }, + { url = "https://files.pythonhosted.org/packages/c3/25/0b4824596f261a3cc512ab152448b383047ff5f143a6906a36876415981c/pyzmq-26.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:786dd8a81b969c2081b31b17b326d3a499ddd1856e06d6d79ad41011a25148da", size = 865416 }, + { url = "https://files.pythonhosted.org/packages/a1/d1/6fda77a034d02034367b040973fd3861d945a5347e607bd2e98c99f20599/pyzmq-26.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:2d88ba221a07fc2c5581565f1d0fe8038c15711ae79b80d9462e080a1ac30435", size = 865922 }, + { url = "https://files.pythonhosted.org/packages/ad/81/48f7fd8a71c427412e739ce576fc1ee14f3dc34527ca9b0076e471676183/pyzmq-26.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1c84c1297ff9f1cd2440da4d57237cb74be21fdfe7d01a10810acba04e79371a", size = 1201526 }, + { url = "https://files.pythonhosted.org/packages/c7/d8/818f15c6ef36b5450e435cbb0d3a51599fc884a5d2b27b46b9c00af68ef1/pyzmq-26.2.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46d4ebafc27081a7f73a0f151d0c38d4291656aa134344ec1f3d0199ebfbb6d4", size = 1512808 }, + { url = "https://files.pythonhosted.org/packages/d9/c4/b3edb7d0ae82ad6fb1a8cdb191a4113c427a01e85139906f3b655b07f4f8/pyzmq-26.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:91e2bfb8e9a29f709d51b208dd5f441dc98eb412c8fe75c24ea464734ccdb48e", size = 1411836 }, + { url = "https://files.pythonhosted.org/packages/69/1c/151e3d42048f02cc5cd6dfc241d9d36b38375b4dee2e728acb5c353a6d52/pyzmq-26.2.1-cp312-cp312-win32.whl", hash = "sha256:4a98898fdce380c51cc3e38ebc9aa33ae1e078193f4dc641c047f88b8c690c9a", size = 581378 }, + { url = "https://files.pythonhosted.org/packages/b6/b9/d59a7462848aaab7277fddb253ae134a570520115d80afa85e952287e6bc/pyzmq-26.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0741edbd0adfe5f30bba6c5223b78c131b5aa4a00a223d631e5ef36e26e6d13", size = 643737 }, + { url = "https://files.pythonhosted.org/packages/55/09/f37e707937cce328944c1d57e5e50ab905011d35252a0745c4f7e5822a76/pyzmq-26.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:e5e33b1491555843ba98d5209439500556ef55b6ab635f3a01148545498355e5", size = 558303 }, + { url = "https://files.pythonhosted.org/packages/4f/2e/fa7a91ce349975971d6aa925b4c7e1a05abaae99b97ade5ace758160c43d/pyzmq-26.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:099b56ef464bc355b14381f13355542e452619abb4c1e57a534b15a106bf8e23", size = 942331 }, + { url = "https://files.pythonhosted.org/packages/64/2b/1f10b34b6dc7ff4b40f668ea25ba9b8093ce61d874c784b90229b367707b/pyzmq-26.2.1-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:651726f37fcbce9f8dd2a6dab0f024807929780621890a4dc0c75432636871be", size = 1345831 }, + { url = "https://files.pythonhosted.org/packages/4c/8d/34884cbd4a8ec050841b5fb58d37af136766a9f95b0b2634c2971deb09da/pyzmq-26.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57dd4d91b38fa4348e237a9388b4423b24ce9c1695bbd4ba5a3eada491e09399", size = 670773 }, + { url = "https://files.pythonhosted.org/packages/0f/f4/d4becfcf9e416ad2564f18a6653f7c6aa917da08df5c3760edb0baa1c863/pyzmq-26.2.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d51a7bfe01a48e1064131f3416a5439872c533d756396be2b39e3977b41430f9", size = 908836 }, + { url = "https://files.pythonhosted.org/packages/07/fa/ab105f1b86b85cb2e821239f1d0900fccd66192a91d97ee04661b5436b4d/pyzmq-26.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7154d228502e18f30f150b7ce94f0789d6b689f75261b623f0fdc1eec642aab", size = 865369 }, + { url = "https://files.pythonhosted.org/packages/c9/48/15d5f415504572dd4b92b52db5de7a5befc76bb75340ba9f36f71306a66d/pyzmq-26.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:f1f31661a80cc46aba381bed475a9135b213ba23ca7ff6797251af31510920ce", size = 865676 }, + { url = "https://files.pythonhosted.org/packages/7e/35/2d91bcc7ccbb56043dd4d2c1763f24a8de5f05e06a134f767a7fb38e149c/pyzmq-26.2.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:290c96f479504439b6129a94cefd67a174b68ace8a8e3f551b2239a64cfa131a", size = 1201457 }, + { url = "https://files.pythonhosted.org/packages/6d/bb/aa7c5119307a5762b8dca6c9db73e3ab4bccf32b15d7c4f376271ff72b2b/pyzmq-26.2.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f2c307fbe86e18ab3c885b7e01de942145f539165c3360e2af0f094dd440acd9", size = 1513035 }, + { url = "https://files.pythonhosted.org/packages/4f/4c/527e6650c2fccec7750b783301329c8a8716d59423818afb67282304ce5a/pyzmq-26.2.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:b314268e716487bfb86fcd6f84ebbe3e5bec5fac75fdf42bc7d90fdb33f618ad", size = 1411881 }, + { url = "https://files.pythonhosted.org/packages/89/9f/e4412ea1b3e220acc21777a5edba8885856403d29c6999aaf00a9459eb03/pyzmq-26.2.1-cp313-cp313-win32.whl", hash = "sha256:edb550616f567cd5603b53bb52a5f842c0171b78852e6fc7e392b02c2a1504bb", size = 581354 }, + { url = "https://files.pythonhosted.org/packages/55/cd/f89dd3e9fc2da0d1619a82c4afb600c86b52bc72d7584953d460bc8d5027/pyzmq-26.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:100a826a029c8ef3d77a1d4c97cbd6e867057b5806a7276f2bac1179f893d3bf", size = 643560 }, + { url = "https://files.pythonhosted.org/packages/a7/99/5de4f8912860013f1116f818a0047659bc20d71d1bc1d48f874bdc2d7b9c/pyzmq-26.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:6991ee6c43e0480deb1b45d0c7c2bac124a6540cba7db4c36345e8e092da47ce", size = 558037 }, + { url = "https://files.pythonhosted.org/packages/06/0b/63b6d7a2f07a77dbc9768c6302ae2d7518bed0c6cee515669ca0d8ec743e/pyzmq-26.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:25e720dba5b3a3bb2ad0ad5d33440babd1b03438a7a5220511d0c8fa677e102e", size = 938580 }, + { url = "https://files.pythonhosted.org/packages/85/38/e5e2c3ffa23ea5f95f1c904014385a55902a11a67cd43c10edf61a653467/pyzmq-26.2.1-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:9ec6abfb701437142ce9544bd6a236addaf803a32628d2260eb3dbd9a60e2891", size = 1339670 }, + { url = "https://files.pythonhosted.org/packages/d2/87/da5519ed7f8b31e4beee8f57311ec02926822fe23a95120877354cd80144/pyzmq-26.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e1eb9d2bfdf5b4e21165b553a81b2c3bd5be06eeddcc4e08e9692156d21f1f6", size = 660983 }, + { url = "https://files.pythonhosted.org/packages/f6/e8/1ca6a2d59562e04d326a026c9e3f791a6f1a276ebde29da478843a566fdb/pyzmq-26.2.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90dc731d8e3e91bcd456aa7407d2eba7ac6f7860e89f3766baabb521f2c1de4a", size = 896509 }, + { url = "https://files.pythonhosted.org/packages/5c/e5/0b4688f7c74bea7e4f1e920da973fcd7d20175f4f1181cb9b692429c6bb9/pyzmq-26.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6a93d684278ad865fc0b9e89fe33f6ea72d36da0e842143891278ff7fd89c3", size = 853196 }, + { url = "https://files.pythonhosted.org/packages/8f/35/c17241da01195001828319e98517683dad0ac4df6fcba68763d61b630390/pyzmq-26.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:c1bb37849e2294d519117dd99b613c5177934e5c04a5bb05dd573fa42026567e", size = 855133 }, + { url = "https://files.pythonhosted.org/packages/d2/14/268ee49bbecc3f72e225addeac7f0e2bd5808747b78c7bf7f87ed9f9d5a8/pyzmq-26.2.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:632a09c6d8af17b678d84df442e9c3ad8e4949c109e48a72f805b22506c4afa7", size = 1191612 }, + { url = "https://files.pythonhosted.org/packages/5e/02/6394498620b1b4349b95c534f3ebc3aef95f39afbdced5ed7ee315c49c14/pyzmq-26.2.1-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:fc409c18884eaf9ddde516d53af4f2db64a8bc7d81b1a0c274b8aa4e929958e8", size = 1500824 }, + { url = "https://files.pythonhosted.org/packages/17/fc/b79f0b72891cbb9917698add0fede71dfb64e83fa3481a02ed0e78c34be7/pyzmq-26.2.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:17f88622b848805d3f6427ce1ad5a2aa3cf61f12a97e684dab2979802024d460", size = 1399943 }, + { url = "https://files.pythonhosted.org/packages/65/d1/e630a75cfb2534574a1258fda54d02f13cf80b576d4ce6d2aa478dc67829/pyzmq-26.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:380816d298aed32b1a97b4973a4865ef3be402a2e760204509b52b6de79d755d", size = 847743 }, + { url = "https://files.pythonhosted.org/packages/27/df/f94a711b4f6c4b41e227f9a938103f52acf4c2e949d91cbc682495a48155/pyzmq-26.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97cbb368fd0debdbeb6ba5966aa28e9a1ae3396c7386d15569a6ca4be4572b99", size = 570991 }, + { url = "https://files.pythonhosted.org/packages/bf/08/0c6f97fb3c9dbfa23382f0efaf8f9aa1396a08a3358974eaae3ee659ed5c/pyzmq-26.2.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf7b5942c6b0dafcc2823ddd9154f419147e24f8df5b41ca8ea40a6db90615c", size = 799664 }, + { url = "https://files.pythonhosted.org/packages/05/14/f4d4fd8bb8988c667845734dd756e9ee65b9a17a010d5f288dfca14a572d/pyzmq-26.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fe6e28a8856aea808715f7a4fc11f682b9d29cac5d6262dd8fe4f98edc12d53", size = 758156 }, + { url = "https://files.pythonhosted.org/packages/e3/fe/72e7e166bda3885810bee7b23049133e142f7c80c295bae02c562caeea16/pyzmq-26.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bd8fdee945b877aa3bffc6a5a8816deb048dab0544f9df3731ecd0e54d8c84c9", size = 556563 }, +] + +[[package]] +name = "quask" +version = "2.0.0a2" +source = { editable = "." } +dependencies = [ + { name = "pandas" }, + { name = "pennylane" }, + { name = "scikit-learn" }, + { name = "scipy" }, +] + +[package.dev-dependencies] +demo = [ + { name = "ipykernel" }, +] +dev = [ + { name = "nose2", extra = ["coverage-plugin"] }, + { name = "tox-pdm" }, +] +docs = [ + { name = "sphinx" }, + { name = "sphinx-autoapi" }, + { name = "sphinx-rtd-theme" }, + { name = "sphinxcontrib-napoleon" }, +] +release = [ + { name = "pre-commit" }, + { name = "python-semantic-release" }, +] + +[package.metadata] +requires-dist = [ + { name = "pandas", specifier = ">=2.2.3" }, + { name = "pennylane", specifier = ">=0.40.0" }, + { name = "scikit-learn", specifier = ">=1.6.1" }, + { name = "scipy", specifier = ">=1.15.1" }, +] + +[package.metadata.requires-dev] +demo = [{ name = "ipykernel", specifier = ">=6.29.5" }] +dev = [ + { name = "nose2", extras = ["coverage-plugin"], specifier = ">=0.15.1" }, + { name = "tox-pdm", specifier = ">=0.7.2" }, +] +docs = [ + { name = "sphinx", specifier = ">=8.1.3" }, + { name = "sphinx-autoapi", specifier = ">=3.4.0" }, + { name = "sphinx-rtd-theme", specifier = ">=3.0.2" }, + { name = "sphinxcontrib-napoleon", specifier = ">=0.7" }, +] +release = [ + { name = "pre-commit", specifier = ">=4.1.0" }, + { name = "python-semantic-release", specifier = ">=9.16.1" }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481 }, +] + +[[package]] +name = "rich" +version = "13.9.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 }, +] + +[[package]] +name = "rustworkx" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/c4/6d6ef39e57610d54c5f106dc3dece9eebce8b9d52d561ae092e3aede1b66/rustworkx-0.16.0.tar.gz", hash = "sha256:9f0dcb83f38d5ca2c3a683eb9b6951c8aec3262fbfe5141946a7ee5ba37e0bb6", size = 349524 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/70/36f5916aee41ffe4f604ad75742eb1bb1b849fb568e010555f9d159cd93e/rustworkx-0.16.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:476a6c67b0142acd941691943750cc6737a48372304489969c2b62d30aaf4c27", size = 2141999 }, + { url = "https://files.pythonhosted.org/packages/94/47/7e7c37fb73efcc87be6414b235534605c4008a4cdbd92a61db23b878eecd/rustworkx-0.16.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:bef2ef42870f806af93979b457e240f6dfa4f867ca33965c620f3a804409ed3a", size = 1940309 }, + { url = "https://files.pythonhosted.org/packages/c6/42/a6d6b3137be55ef1d887becdf6b64b0917c7d437bd483065a88500a55603/rustworkx-0.16.0-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0db3a73bf68b3e66c08322a2fc95d3aa663d037d9b4e49c3509da4898d3529cc", size = 2195350 }, + { url = "https://files.pythonhosted.org/packages/59/d2/1bc99df831c132c4b7420a85ce9150e065f4c993798f31b6a4229f238398/rustworkx-0.16.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f12a13d7486234fa2a84746d5e41f436bf9df43548043e7a232f48804ff8c61", size = 1971689 }, + { url = "https://files.pythonhosted.org/packages/b5/3b/1125e7eb834f4408bcec3cee79947efd504c715fb7ab1876f8cd4bbca497/rustworkx-0.16.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:89efd5c3a4653ddacc55ca39f28b261d43deec7d678f8f8fc6b76b5087f1dfea", size = 3297342 }, + { url = "https://files.pythonhosted.org/packages/4f/e2/e21187b255c6211d71db0d08a44fc16771038b2af41712d66c408d9bec16/rustworkx-0.16.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec0c12aac8c54910ace20ac6ada4b890cd39f95f69100514715f8ad7af9041e4", size = 2110107 }, + { url = "https://files.pythonhosted.org/packages/3c/79/e3fcff21f31253ea85ef196bf2fcabad7802b11468f7d3a5d592cd0ac789/rustworkx-0.16.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d650e39fc1a1534335f7517358ebfc3478bb235428463cfcd7c5750d50377b33", size = 2007544 }, + { url = "https://files.pythonhosted.org/packages/67/04/741ed09c2b0dc0f360f85270c1179ed433785372ac9ab6ab26d3dd3ae02d/rustworkx-0.16.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:293180b83509ee9bff4c3af7ccc1024f6528d61b65d0cb7320bd31924f10cb71", size = 2172787 }, + { url = "https://files.pythonhosted.org/packages/6d/fd/9c71e90f8cde76fed95dbc1e7d019977b89a29492f49ded232c6fad3055f/rustworkx-0.16.0-cp39-abi3-win32.whl", hash = "sha256:040c4368729cf502f756a3b0ff5f1c6915fc389f74dcc6afc6c3833688c97c01", size = 1840183 }, + { url = "https://files.pythonhosted.org/packages/3e/79/9bdd52d2a33d468c81c1827de1b588080cb055d1d3561b194ab7bf2635b5/rustworkx-0.16.0-cp39-abi3-win_amd64.whl", hash = "sha256:905df608843c32fa45ac023687769fe13056edf7584474c801d5c50705d76e9b", size = 1953559 }, +] + +[[package]] +name = "scikit-learn" +version = "1.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "joblib" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/a5/4ae3b3a0755f7b35a280ac90b28817d1f380318973cff14075ab41ef50d9/scikit_learn-1.6.1.tar.gz", hash = "sha256:b4fc2525eca2c69a59260f583c56a7557c6ccdf8deafdba6e060f94c1c59738e", size = 7068312 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/3a/f4597eb41049110b21ebcbb0bcb43e4035017545daa5eedcfeb45c08b9c5/scikit_learn-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d056391530ccd1e501056160e3c9673b4da4805eb67eb2bdf4e983e1f9c9204e", size = 12067702 }, + { url = "https://files.pythonhosted.org/packages/37/19/0423e5e1fd1c6ec5be2352ba05a537a473c1677f8188b9306097d684b327/scikit_learn-1.6.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:0c8d036eb937dbb568c6242fa598d551d88fb4399c0344d95c001980ec1c7d36", size = 11112765 }, + { url = "https://files.pythonhosted.org/packages/70/95/d5cb2297a835b0f5fc9a77042b0a2d029866379091ab8b3f52cc62277808/scikit_learn-1.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8634c4bd21a2a813e0a7e3900464e6d593162a29dd35d25bdf0103b3fce60ed5", size = 12643991 }, + { url = "https://files.pythonhosted.org/packages/b7/91/ab3c697188f224d658969f678be86b0968ccc52774c8ab4a86a07be13c25/scikit_learn-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:775da975a471c4f6f467725dff0ced5c7ac7bda5e9316b260225b48475279a1b", size = 13497182 }, + { url = "https://files.pythonhosted.org/packages/17/04/d5d556b6c88886c092cc989433b2bab62488e0f0dafe616a1d5c9cb0efb1/scikit_learn-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:8a600c31592bd7dab31e1c61b9bbd6dea1b3433e67d264d17ce1017dbdce8002", size = 11125517 }, + { url = "https://files.pythonhosted.org/packages/6c/2a/e291c29670795406a824567d1dfc91db7b699799a002fdaa452bceea8f6e/scikit_learn-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72abc587c75234935e97d09aa4913a82f7b03ee0b74111dcc2881cba3c5a7b33", size = 12102620 }, + { url = "https://files.pythonhosted.org/packages/25/92/ee1d7a00bb6b8c55755d4984fd82608603a3cc59959245068ce32e7fb808/scikit_learn-1.6.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b3b00cdc8f1317b5f33191df1386c0befd16625f49d979fe77a8d44cae82410d", size = 11116234 }, + { url = "https://files.pythonhosted.org/packages/30/cd/ed4399485ef364bb25f388ab438e3724e60dc218c547a407b6e90ccccaef/scikit_learn-1.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc4765af3386811c3ca21638f63b9cf5ecf66261cc4815c1db3f1e7dc7b79db2", size = 12592155 }, + { url = "https://files.pythonhosted.org/packages/a8/f3/62fc9a5a659bb58a03cdd7e258956a5824bdc9b4bb3c5d932f55880be569/scikit_learn-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25fc636bdaf1cc2f4a124a116312d837148b5e10872147bdaf4887926b8c03d8", size = 13497069 }, + { url = "https://files.pythonhosted.org/packages/a1/a6/c5b78606743a1f28eae8f11973de6613a5ee87366796583fb74c67d54939/scikit_learn-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:fa909b1a36e000a03c382aade0bd2063fd5680ff8b8e501660c0f59f021a6415", size = 11139809 }, + { url = "https://files.pythonhosted.org/packages/0a/18/c797c9b8c10380d05616db3bfb48e2a3358c767affd0857d56c2eb501caa/scikit_learn-1.6.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:926f207c804104677af4857b2c609940b743d04c4c35ce0ddc8ff4f053cddc1b", size = 12104516 }, + { url = "https://files.pythonhosted.org/packages/c4/b7/2e35f8e289ab70108f8cbb2e7a2208f0575dc704749721286519dcf35f6f/scikit_learn-1.6.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2c2cae262064e6a9b77eee1c8e768fc46aa0b8338c6a8297b9b6759720ec0ff2", size = 11167837 }, + { url = "https://files.pythonhosted.org/packages/a4/f6/ff7beaeb644bcad72bcfd5a03ff36d32ee4e53a8b29a639f11bcb65d06cd/scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1061b7c028a8663fb9a1a1baf9317b64a257fcb036dae5c8752b2abef31d136f", size = 12253728 }, + { url = "https://files.pythonhosted.org/packages/29/7a/8bce8968883e9465de20be15542f4c7e221952441727c4dad24d534c6d99/scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e69fab4ebfc9c9b580a7a80111b43d214ab06250f8a7ef590a4edf72464dd86", size = 13147700 }, + { url = "https://files.pythonhosted.org/packages/62/27/585859e72e117fe861c2079bcba35591a84f801e21bc1ab85bce6ce60305/scikit_learn-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:70b1d7e85b1c96383f872a519b3375f92f14731e279a7b4c6cfd650cf5dffc52", size = 11110613 }, + { url = "https://files.pythonhosted.org/packages/2e/59/8eb1872ca87009bdcdb7f3cdc679ad557b992c12f4b61f9250659e592c63/scikit_learn-1.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ffa1e9e25b3d93990e74a4be2c2fc61ee5af85811562f1288d5d055880c4322", size = 12010001 }, + { url = "https://files.pythonhosted.org/packages/9d/05/f2fc4effc5b32e525408524c982c468c29d22f828834f0625c5ef3d601be/scikit_learn-1.6.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dc5cf3d68c5a20ad6d571584c0750ec641cc46aeef1c1507be51300e6003a7e1", size = 11096360 }, + { url = "https://files.pythonhosted.org/packages/c8/e4/4195d52cf4f113573fb8ebc44ed5a81bd511a92c0228889125fac2f4c3d1/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c06beb2e839ecc641366000ca84f3cf6fa9faa1777e29cf0c04be6e4d096a348", size = 12209004 }, + { url = "https://files.pythonhosted.org/packages/94/be/47e16cdd1e7fcf97d95b3cb08bde1abb13e627861af427a3651fcb80b517/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8ca8cb270fee8f1f76fa9bfd5c3507d60c6438bbee5687f81042e2bb98e5a97", size = 13171776 }, + { url = "https://files.pythonhosted.org/packages/34/b0/ca92b90859070a1487827dbc672f998da95ce83edce1270fc23f96f1f61a/scikit_learn-1.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:7a1c43c8ec9fde528d664d947dc4c0789be4077a3647f232869f41d9bf50e0fb", size = 11071865 }, + { url = "https://files.pythonhosted.org/packages/12/ae/993b0fb24a356e71e9a894e42b8a9eec528d4c70217353a1cd7a48bc25d4/scikit_learn-1.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a17c1dea1d56dcda2fac315712f3651a1fea86565b64b48fa1bc090249cbf236", size = 11955804 }, + { url = "https://files.pythonhosted.org/packages/d6/54/32fa2ee591af44507eac86406fa6bba968d1eb22831494470d0a2e4a1eb1/scikit_learn-1.6.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6a7aa5f9908f0f28f4edaa6963c0a6183f1911e63a69aa03782f0d924c830a35", size = 11100530 }, + { url = "https://files.pythonhosted.org/packages/3f/58/55856da1adec655bdce77b502e94a267bf40a8c0b89f8622837f89503b5a/scikit_learn-1.6.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0650e730afb87402baa88afbf31c07b84c98272622aaba002559b614600ca691", size = 12433852 }, + { url = "https://files.pythonhosted.org/packages/ff/4f/c83853af13901a574f8f13b645467285a48940f185b690936bb700a50863/scikit_learn-1.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:3f59fe08dc03ea158605170eb52b22a105f238a5d512c4470ddeca71feae8e5f", size = 11337256 }, +] + +[[package]] +name = "scipy" +version = "1.15.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/c6/8eb0654ba0c7d0bb1bf67bf8fbace101a8e4f250f7722371105e8b6f68fc/scipy-1.15.1.tar.gz", hash = "sha256:033a75ddad1463970c96a88063a1df87ccfddd526437136b6ee81ff0312ebdf6", size = 59407493 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/53/b204ce5a4433f1864001b9d16f103b9c25f5002a602ae83585d0ea5f9c4a/scipy-1.15.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:c64ded12dcab08afff9e805a67ff4480f5e69993310e093434b10e85dc9d43e1", size = 41414518 }, + { url = "https://files.pythonhosted.org/packages/c7/fc/54ffa7a8847f7f303197a6ba65a66104724beba2e38f328135a78f0dc480/scipy-1.15.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:5b190b935e7db569960b48840e5bef71dc513314cc4e79a1b7d14664f57fd4ff", size = 32519265 }, + { url = "https://files.pythonhosted.org/packages/f1/77/a98b8ba03d6f371dc31a38719affd53426d4665729dcffbed4afe296784a/scipy-1.15.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:4b17d4220df99bacb63065c76b0d1126d82bbf00167d1730019d2a30d6ae01ea", size = 24792859 }, + { url = "https://files.pythonhosted.org/packages/a7/78/70bb9f0df7444b18b108580934bfef774822e28fd34a68e5c263c7d2828a/scipy-1.15.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:63b9b6cd0333d0eb1a49de6f834e8aeaefe438df8f6372352084535ad095219e", size = 27886506 }, + { url = "https://files.pythonhosted.org/packages/14/a7/f40f6033e06de4176ddd6cc8c3ae9f10a226c3bca5d6b4ab883bc9914a14/scipy-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f151e9fb60fbf8e52426132f473221a49362091ce7a5e72f8aa41f8e0da4f25", size = 38375041 }, + { url = "https://files.pythonhosted.org/packages/17/03/390a1c5c61fd76b0fa4b3c5aa3bdd7e60f6c46f712924f1a9df5705ec046/scipy-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e10b1dd56ce92fba3e786007322542361984f8463c6d37f6f25935a5a6ef52", size = 40597556 }, + { url = "https://files.pythonhosted.org/packages/4e/70/fa95b3ae026b97eeca58204a90868802e5155ac71b9d7bdee92b68115dd3/scipy-1.15.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5dff14e75cdbcf07cdaa1c7707db6017d130f0af9ac41f6ce443a93318d6c6e0", size = 42938505 }, + { url = "https://files.pythonhosted.org/packages/d6/07/427859116bdd71847c898180f01802691f203c3e2455a1eb496130ff07c5/scipy-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:f82fcf4e5b377f819542fbc8541f7b5fbcf1c0017d0df0bc22c781bf60abc4d8", size = 43909663 }, + { url = "https://files.pythonhosted.org/packages/8e/2e/7b71312da9c2dabff53e7c9a9d08231bc34d9d8fdabe88a6f1155b44591c/scipy-1.15.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:5bd8d27d44e2c13d0c1124e6a556454f52cd3f704742985f6b09e75e163d20d2", size = 41424362 }, + { url = "https://files.pythonhosted.org/packages/81/8c/ab85f1aa1cc200c796532a385b6ebf6a81089747adc1da7482a062acc46c/scipy-1.15.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:be3deeb32844c27599347faa077b359584ba96664c5c79d71a354b80a0ad0ce0", size = 32535910 }, + { url = "https://files.pythonhosted.org/packages/3b/9c/6f4b787058daa8d8da21ddff881b4320e28de4704a65ec147adb50cb2230/scipy-1.15.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:5eb0ca35d4b08e95da99a9f9c400dc9f6c21c424298a0ba876fdc69c7afacedf", size = 24809398 }, + { url = "https://files.pythonhosted.org/packages/16/2b/949460a796df75fc7a1ee1becea202cf072edbe325ebe29f6d2029947aa7/scipy-1.15.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:74bb864ff7640dea310a1377d8567dc2cb7599c26a79ca852fc184cc851954ac", size = 27918045 }, + { url = "https://files.pythonhosted.org/packages/5f/36/67fe249dd7ccfcd2a38b25a640e3af7e59d9169c802478b6035ba91dfd6d/scipy-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:667f950bf8b7c3a23b4199db24cb9bf7512e27e86d0e3813f015b74ec2c6e3df", size = 38332074 }, + { url = "https://files.pythonhosted.org/packages/fc/da/452e1119e6f720df3feb588cce3c42c5e3d628d4bfd4aec097bd30b7de0c/scipy-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395be70220d1189756068b3173853029a013d8c8dd5fd3d1361d505b2aa58fa7", size = 40588469 }, + { url = "https://files.pythonhosted.org/packages/7f/71/5f94aceeac99a4941478af94fe9f459c6752d497035b6b0761a700f5f9ff/scipy-1.15.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ce3a000cd28b4430426db2ca44d96636f701ed12e2b3ca1f2b1dd7abdd84b39a", size = 42965214 }, + { url = "https://files.pythonhosted.org/packages/af/25/caa430865749d504271757cafd24066d596217e83326155993980bc22f97/scipy-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:3fe1d95944f9cf6ba77aa28b82dd6bb2a5b52f2026beb39ecf05304b8392864b", size = 43896034 }, + { url = "https://files.pythonhosted.org/packages/d8/6e/a9c42d0d39e09ed7fd203d0ac17adfea759cba61ab457671fe66e523dbec/scipy-1.15.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c09aa9d90f3500ea4c9b393ee96f96b0ccb27f2f350d09a47f533293c78ea776", size = 41478318 }, + { url = "https://files.pythonhosted.org/packages/04/ee/e3e535c81828618878a7433992fecc92fa4df79393f31a8fea1d05615091/scipy-1.15.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0ac102ce99934b162914b1e4a6b94ca7da0f4058b6d6fd65b0cef330c0f3346f", size = 32596696 }, + { url = "https://files.pythonhosted.org/packages/c4/5e/b1b0124be8e76f87115f16b8915003eec4b7060298117715baf13f51942c/scipy-1.15.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:09c52320c42d7f5c7748b69e9f0389266fd4f82cf34c38485c14ee976cb8cb04", size = 24870366 }, + { url = "https://files.pythonhosted.org/packages/14/36/c00cb73eefda85946172c27913ab995c6ad4eee00fa4f007572e8c50cd51/scipy-1.15.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:cdde8414154054763b42b74fe8ce89d7f3d17a7ac5dd77204f0e142cdc9239e9", size = 28007461 }, + { url = "https://files.pythonhosted.org/packages/68/94/aff5c51b3799349a9d1e67a056772a0f8a47db371e83b498d43467806557/scipy-1.15.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c9d8fc81d6a3b6844235e6fd175ee1d4c060163905a2becce8e74cb0d7554ce", size = 38068174 }, + { url = "https://files.pythonhosted.org/packages/b0/3c/0de11ca154e24a57b579fb648151d901326d3102115bc4f9a7a86526ce54/scipy-1.15.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fb57b30f0017d4afa5fe5f5b150b8f807618819287c21cbe51130de7ccdaed2", size = 40249869 }, + { url = "https://files.pythonhosted.org/packages/15/09/472e8d0a6b33199d1bb95e49bedcabc0976c3724edd9b0ef7602ccacf41e/scipy-1.15.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:491d57fe89927fa1aafbe260f4cfa5ffa20ab9f1435025045a5315006a91b8f5", size = 42629068 }, + { url = "https://files.pythonhosted.org/packages/ff/ba/31c7a8131152822b3a2cdeba76398ffb404d81d640de98287d236da90c49/scipy-1.15.1-cp312-cp312-win_amd64.whl", hash = "sha256:900f3fa3db87257510f011c292a5779eb627043dd89731b9c461cd16ef76ab3d", size = 43621992 }, + { url = "https://files.pythonhosted.org/packages/2b/bf/dd68965a4c5138a630eeed0baec9ae96e5d598887835bdde96cdd2fe4780/scipy-1.15.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:100193bb72fbff37dbd0bf14322314fc7cbe08b7ff3137f11a34d06dc0ee6b85", size = 41441136 }, + { url = "https://files.pythonhosted.org/packages/ef/5e/4928581312922d7e4d416d74c416a660addec4dd5ea185401df2269ba5a0/scipy-1.15.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:2114a08daec64980e4b4cbdf5bee90935af66d750146b1d2feb0d3ac30613692", size = 32533699 }, + { url = "https://files.pythonhosted.org/packages/32/90/03f99c43041852837686898c66767787cd41c5843d7a1509c39ffef683e9/scipy-1.15.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:6b3e71893c6687fc5e29208d518900c24ea372a862854c9888368c0b267387ab", size = 24807289 }, + { url = "https://files.pythonhosted.org/packages/9d/52/bfe82b42ae112eaba1af2f3e556275b8727d55ac6e4932e7aef337a9d9d4/scipy-1.15.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:837299eec3d19b7e042923448d17d95a86e43941104d33f00da7e31a0f715d3c", size = 27929844 }, + { url = "https://files.pythonhosted.org/packages/f6/77/54ff610bad600462c313326acdb035783accc6a3d5f566d22757ad297564/scipy-1.15.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82add84e8a9fb12af5c2c1a3a3f1cb51849d27a580cb9e6bd66226195142be6e", size = 38031272 }, + { url = "https://files.pythonhosted.org/packages/f1/26/98585cbf04c7cf503d7eb0a1966df8a268154b5d923c5fe0c1ed13154c49/scipy-1.15.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070d10654f0cb6abd295bc96c12656f948e623ec5f9a4eab0ddb1466c000716e", size = 40210217 }, + { url = "https://files.pythonhosted.org/packages/fd/3f/3d2285eb6fece8bc5dbb2f9f94d61157d61d155e854fd5fea825b8218f12/scipy-1.15.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:55cc79ce4085c702ac31e49b1e69b27ef41111f22beafb9b49fea67142b696c4", size = 42587785 }, + { url = "https://files.pythonhosted.org/packages/48/7d/5b5251984bf0160d6533695a74a5fddb1fa36edd6f26ffa8c871fbd4782a/scipy-1.15.1-cp313-cp313-win_amd64.whl", hash = "sha256:c352c1b6d7cac452534517e022f8f7b8d139cd9f27e6fbd9f3cbd0bfd39f5bef", size = 43640439 }, + { url = "https://files.pythonhosted.org/packages/e7/b8/0e092f592d280496de52e152582030f8a270b194f87f890e1a97c5599b81/scipy-1.15.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0458839c9f873062db69a03de9a9765ae2e694352c76a16be44f93ea45c28d2b", size = 41619862 }, + { url = "https://files.pythonhosted.org/packages/f6/19/0b6e1173aba4db9e0b7aa27fe45019857fb90d6904038b83927cbe0a6c1d/scipy-1.15.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:af0b61c1de46d0565b4b39c6417373304c1d4f5220004058bdad3061c9fa8a95", size = 32610387 }, + { url = "https://files.pythonhosted.org/packages/e7/02/754aae3bd1fa0f2479ade3cfdf1732ecd6b05853f63eee6066a32684563a/scipy-1.15.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:71ba9a76c2390eca6e359be81a3e879614af3a71dfdabb96d1d7ab33da6f2364", size = 24883814 }, + { url = "https://files.pythonhosted.org/packages/1f/ac/d7906201604a2ea3b143bb0de51b3966f66441ba50b7dc182c4505b3edf9/scipy-1.15.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14eaa373c89eaf553be73c3affb11ec6c37493b7eaaf31cf9ac5dffae700c2e0", size = 27944865 }, + { url = "https://files.pythonhosted.org/packages/84/9d/8f539002b5e203723af6a6f513a45e0a7671e9dabeedb08f417ac17e4edc/scipy-1.15.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f735bc41bd1c792c96bc426dece66c8723283695f02df61dcc4d0a707a42fc54", size = 39883261 }, + { url = "https://files.pythonhosted.org/packages/97/c0/62fd3bab828bcccc9b864c5997645a3b86372a35941cdaf677565c25c98d/scipy-1.15.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2722a021a7929d21168830790202a75dbb20b468a8133c74a2c0230c72626b6c", size = 42093299 }, + { url = "https://files.pythonhosted.org/packages/e4/1f/5d46a8d94e9f6d2c913cbb109e57e7eed914de38ea99e2c4d69a9fc93140/scipy-1.15.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bc7136626261ac1ed988dca56cfc4ab5180f75e0ee52e58f1e6aa74b5f3eacd5", size = 43181730 }, +] + +[[package]] +name = "scipy-openblas32" +version = "0.3.29.0.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/14/f9890cf840d8c63962a939a12e21c17c65ef5ab71a13d8f4d3c9e02668da/scipy_openblas32-0.3.29.0.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:6b276ac72c00cc0850588663b9da4c8099d4bee8a2527557747cf6b8ed5179cb", size = 14453532 }, + { url = "https://files.pythonhosted.org/packages/a4/c3/3aa7bfa723a4eb9f00c5bf6b485a0d3bf35311febb15ce9e4d1f9ca9ca47/scipy_openblas32-0.3.29.0.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:dd74159091a83ae7bf7b066345c3d3e43e212cd4537c03a2fd873154e5a179f2", size = 9277657 }, + { url = "https://files.pythonhosted.org/packages/5e/d9/a97b9b1cb777e1998b49e16c183cfee9d81b86319e0e8c4ba283043230e1/scipy_openblas32-0.3.29.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33994f0a37373ff6717fd9c948053a76c272efd516f8b33b3e51ecec786922fe", size = 8212048 }, + { url = "https://files.pythonhosted.org/packages/c9/80/478a397416de9ddbf86ab65832e92690b5fac75e47349df0ef6392d18eb1/scipy_openblas32-0.3.29.0.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d6301960024370f6061c71e8efd8bcb5be22c6526a529ff05c370048adb6b04", size = 6739700 }, + { url = "https://files.pythonhosted.org/packages/80/85/5f31a7605e74c13cdb621cca7154aec319a45f41c7b369422e68783b6ff6/scipy_openblas32-0.3.29.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02d32eafdf101f9503b99bd623e84f109a95cbe16d65492e174ed386339e2e1f", size = 8584619 }, + { url = "https://files.pythonhosted.org/packages/95/68/838526de7b29dad0336cbf9d48f79157be03630f26ba6beceeae9212a3e7/scipy_openblas32-0.3.29.0.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2ca3ee3b9143b86addccda36a741462621413766dbc09896b0b43cc223a3b051", size = 8452669 }, + { url = "https://files.pythonhosted.org/packages/ec/cf/95a90bb785a1b7bf7b9c3d89d3251f33036e97d2d6dfc2a9ec78f060a29d/scipy_openblas32-0.3.29.0.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:768352307e56873538222526b7dbcfd3dcd8615451741d15eef9af718ac93750", size = 9172187 }, + { url = "https://files.pythonhosted.org/packages/ef/6b/e81e658bb52b81a9bd2a9415a1b84c1c1dbb785043e307787aaf1f8eb6f3/scipy_openblas32-0.3.29.0.0-py3-none-win32.whl", hash = "sha256:e56c9c8e5e41d91d357b0d514fc59ca25467fbd68e5bdffa1f3dfa96f3249eb2", size = 5554954 }, + { url = "https://files.pythonhosted.org/packages/65/e3/5e0cd0945aba54312849dac3bca06b6e3dee725c7abb73e854cf79709838/scipy_openblas32-0.3.29.0.0-py3-none-win_amd64.whl", hash = "sha256:8b21c803bdc344a383a1d5d392d3cfe5366d9b89d2aeee963705156000cbbc7a", size = 7077538 }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "smmap" +version = "5.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303 }, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 }, +] + +[[package]] +name = "sphinx" +version = "8.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2", size = 3487125 }, +] + +[[package]] +name = "sphinx-autoapi" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astroid" }, + { name = "jinja2" }, + { name = "pyyaml" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4a/eb/cc243583bb1d518ca3b10998c203d919a8ed90affd4831f2b61ad09043d2/sphinx_autoapi-3.4.0.tar.gz", hash = "sha256:e6d5371f9411bbb9fca358c00a9e57aef3ac94cbfc5df4bab285946462f69e0c", size = 29292 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/d6/f2acdc2567337fd5f5dc091a4e58d8a0fb14927b9779fc1e5ecee96d9824/sphinx_autoapi-3.4.0-py3-none-any.whl", hash = "sha256:4027fef2875a22c5f2a57107c71641d82f6166bf55beb407a47aaf3ef14e7b92", size = 34095 }, +] + +[[package]] +name = "sphinx-rtd-theme" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "sphinx" }, + { name = "sphinxcontrib-jquery" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/44/c97faec644d29a5ceddd3020ae2edffa69e7d00054a8c7a6021e82f20335/sphinx_rtd_theme-3.0.2.tar.gz", hash = "sha256:b7457bc25dda723b20b086a670b9953c859eab60a2a03ee8eb2bb23e176e5f85", size = 7620463 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/77/46e3bac77b82b4df5bb5b61f2de98637724f246b4966cfc34bc5895d852a/sphinx_rtd_theme-3.0.2-py2.py3-none-any.whl", hash = "sha256:422ccc750c3a3a311de4ae327e82affdaf59eb695ba4936538552f3b00f4ee13", size = 7655561 }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300 }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530 }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705 }, +] + +[[package]] +name = "sphinxcontrib-jquery" +version = "4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/f3/aa67467e051df70a6330fe7770894b3e4f09436dea6881ae0b4f3d87cad8/sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a", size = 122331 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/85/749bd22d1a68db7291c89e2ebca53f4306c3f205853cf31e9de279034c3c/sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae", size = 121104 }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 }, +] + +[[package]] +name = "sphinxcontrib-napoleon" +version = "0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pockets" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/eb/ad89500f4cee83187596e07f43ad561f293e8e6e96996005c3319653b89f/sphinxcontrib-napoleon-0.7.tar.gz", hash = "sha256:407382beed396e9f2d7f3043fad6afda95719204a1e1a231ac865f40abcbfcf8", size = 21232 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/f2/6b7627dfe7b4e418e295e254bb15c3a6455f11f8c0ad0d43113f678049c3/sphinxcontrib_napoleon-0.7-py2.py3-none-any.whl", hash = "sha256:711e41a3974bdf110a484aec4c1a556799eb0b3f3b897521a018ad7e2db13fef", size = 17151 }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743 }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 }, +] + +[[package]] +name = "termcolor" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/37/72/88311445fd44c455c7d553e61f95412cf89054308a1aa2434ab835075fc5/termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f", size = 13057 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/be/df630c387a0a054815d60be6a97eb4e8f17385d5d6fe660e1c02750062b4/termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8", size = 7755 }, +] + +[[package]] +name = "threadpoolctl" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/55/b5148dcbf72f5cde221f8bfe3b6a540da7aa1842f6b491ad979a6c8b84af/threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107", size = 41936 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/2c/ffbf7a134b9ab11a67b0cf0726453cedd9c5043a4fe7a35d1cefa9a1bcfb/threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467", size = 18414 }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] + +[[package]] +name = "tomlkit" +version = "0.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/09/a439bec5888f00a54b8b9f05fa94d7f901d6735ef4e55dcec9bc37b5d8fa/tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79", size = 192885 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/b6/a447b5e4ec71e13871be01ba81f5dfc9d0af7e473da256ff46bc0e24026f/tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", size = 37955 }, +] + +[[package]] +name = "tornado" +version = "6.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/45/a0daf161f7d6f36c3ea5fc0c2de619746cc3dd4c76402e9db545bd920f63/tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b", size = 501135 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/7e/71f604d8cea1b58f82ba3590290b66da1e72d840aeb37e0d5f7291bd30db/tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1", size = 436299 }, + { url = "https://files.pythonhosted.org/packages/96/44/87543a3b99016d0bf54fdaab30d24bf0af2e848f1d13d34a3a5380aabe16/tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803", size = 434253 }, + { url = "https://files.pythonhosted.org/packages/cb/fb/fdf679b4ce51bcb7210801ef4f11fdac96e9885daa402861751353beea6e/tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec", size = 437602 }, + { url = "https://files.pythonhosted.org/packages/4f/3b/e31aeffffc22b475a64dbeb273026a21b5b566f74dee48742817626c47dc/tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946", size = 436972 }, + { url = "https://files.pythonhosted.org/packages/22/55/b78a464de78051a30599ceb6983b01d8f732e6f69bf37b4ed07f642ac0fc/tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf", size = 437173 }, + { url = "https://files.pythonhosted.org/packages/79/5e/be4fb0d1684eb822c9a62fb18a3e44a06188f78aa466b2ad991d2ee31104/tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634", size = 437892 }, + { url = "https://files.pythonhosted.org/packages/f5/33/4f91fdd94ea36e1d796147003b490fe60a0215ac5737b6f9c65e160d4fe0/tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73", size = 437334 }, + { url = "https://files.pythonhosted.org/packages/2b/ae/c1b22d4524b0e10da2f29a176fb2890386f7bd1f63aacf186444873a88a0/tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c", size = 437261 }, + { url = "https://files.pythonhosted.org/packages/b5/25/36dbd49ab6d179bcfc4c6c093a51795a4f3bed380543a8242ac3517a1751/tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482", size = 438463 }, + { url = "https://files.pythonhosted.org/packages/61/cc/58b1adeb1bb46228442081e746fcdbc4540905c87e8add7c277540934edb/tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38", size = 438907 }, +] + +[[package]] +name = "tox" +version = "4.24.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cachetools" }, + { name = "chardet" }, + { name = "colorama" }, + { name = "filelock" }, + { name = "packaging" }, + { name = "platformdirs" }, + { name = "pluggy" }, + { name = "pyproject-api" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/7b/97f757e159983737bdd8fb513f4c263cd411a846684814ed5433434a1fa9/tox-4.24.1.tar.gz", hash = "sha256:083a720adbc6166fff0b7d1df9d154f9d00bfccb9403b8abf6bc0ee435d6a62e", size = 194742 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/04/b0d1c1b44c98583cab9eabb4acdba964fdf6b6c597c53cfb8870fd08cbbf/tox-4.24.1-py3-none-any.whl", hash = "sha256:57ba7df7d199002c6df8c2db9e6484f3de6ca8f42013c083ea2d4d1e5c6bdc75", size = 171829 }, +] + +[[package]] +name = "tox-pdm" +version = "0.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "tox" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/02/18bb27f68d094f2f8cea32c7e072d7e7e3ac0fb71e192a772f1fa97e1659/tox_pdm-0.7.2.tar.gz", hash = "sha256:a841a7e1e942a71805624703b9a6d286663bd6af79bba6130ba756975c315308", size = 8792 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/08/b90abe66283809416441e9c778cb73cb637a53b914e9b2a9ded8fbdc51c4/tox_pdm-0.7.2-py3-none-any.whl", hash = "sha256:12f6215416b7acd00a80a9e7128f3dc3e3c89308d60707f5d0a24abdf83ac104", size = 5262 }, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "tzdata" +version = "2025.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762 }, +] + +[[package]] +name = "urllib3" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, +] + +[[package]] +name = "virtualenv" +version = "20.29.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/ca/f23dcb02e161a9bba141b1c08aa50e8da6ea25e6d780528f1d385a3efe25/virtualenv-20.29.1.tar.gz", hash = "sha256:b8b8970138d32fb606192cb97f6cd4bb644fa486be9308fb9b63f81091b5dc35", size = 7658028 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/9b/599bcfc7064fbe5740919e78c5df18e5dceb0887e676256a1061bb5ae232/virtualenv-20.29.1-py3-none-any.whl", hash = "sha256:4e4cb403c0b0da39e13b46b1b2476e505cb0046b25f242bee80f62bf990b2779", size = 4282379 }, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, +] + +[[package]] +name = "wheel" +version = "0.45.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/98/2d9906746cdc6a6ef809ae6338005b3f21bb568bea3165cfc6a243fdc25c/wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729", size = 107545 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/2c/87f3254fd8ffd29e4c02732eee68a83a1d3c346ae39bc6822dcbcb697f2b/wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248", size = 72494 }, +] From 9d0d710d59f39f360b0f47e70c955c26a5684e7c Mon Sep 17 00:00:00 2001 From: IraitzM Date: Thu, 6 Feb 2025 18:05:03 +0100 Subject: [PATCH 02/10] fix(precommit): Update --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 33b5bb6..5bf4c27 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,20 +2,20 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - repo: https://github.com/asottile/pyupgrade - rev: v1.25.0 + rev: v3.19.1 hooks: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.9.3 + rev: v0.9.4 hooks: # Run the linter. - id: ruff @@ -24,7 +24,7 @@ repos: - id: ruff-format - repo: https://github.com/astral-sh/uv-pre-commit # uv version. - rev: 0.5.24 + rev: 0.5.29 hooks: - id: uv-lock - repo: https://github.com/astral-sh/uv-pre-commit From 18d76fa02680e6a49fb0a2e12652f1067ab11325 Mon Sep 17 00:00:00 2001 From: IraitzM Date: Fri, 7 Feb 2025 09:49:16 +0100 Subject: [PATCH 03/10] fix(tests): Still crashing but circular dependencies removed. --- .gitignore | 5 +- pyproject.toml | 2 + src/quask/core/ansatz.py | 2 +- src/quask/core/kernel.py | 34 +-- src/quask/core/kernel_factory.py | 4 +- src/quask/core/operation.py | 4 +- tests/kernel_test.py | 66 ----- tests/test_example.py | 21 -- tests/test_pennylane_kernel.py | 257 ++++++++++++------- uv.lock | 416 +++++++++++++++++++++++++------ 10 files changed, 535 insertions(+), 276 deletions(-) delete mode 100644 tests/kernel_test.py delete mode 100644 tests/test_example.py diff --git a/.gitignore b/.gitignore index 37f7fd0..6101582 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,7 @@ src/quask/optimizer/__pycache__/* .tox # PDM -.pdm-build +.pdm-build + +# Coverage +.coverage diff --git a/pyproject.toml b/pyproject.toml index a023752..e5c5e9d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,8 @@ classifiers = [ dependencies = [ "pandas>=2.2.3", "pennylane>=0.40.0", + "qiskit-ibm-runtime>=0.35.0", + "qiskit>=1.3.2", "scikit-learn>=1.6.1", "scipy>=1.15.1", ] diff --git a/src/quask/core/ansatz.py b/src/quask/core/ansatz.py index 9345328..0ed1534 100644 --- a/src/quask/core/ansatz.py +++ b/src/quask/core/ansatz.py @@ -1,6 +1,6 @@ import numpy as np -from . import Operation +from .operation import Operation class Ansatz: diff --git a/src/quask/core/kernel.py b/src/quask/core/kernel.py index 45caa8a..27a363a 100644 --- a/src/quask/core/kernel.py +++ b/src/quask/core/kernel.py @@ -2,11 +2,13 @@ import numpy as np -from . import Ansatz, KernelFactory, KernelType +from .ansatz import Ansatz +from .kernel_factory import KernelFactory +from .kernel_type import KernelType class Kernel(ABC): - """Abstract class representing a kernel object""" + """Abstract class representing a kernel object.""" PAULIS = ["I", "X", "Y", "Z"] @@ -43,7 +45,6 @@ def kappa(self, x1, x2) -> float: :param x2: second data point :return: Kernel similarity between the two data points """ - pass @abstractmethod def phi(self, x) -> float: @@ -52,7 +53,6 @@ def phi(self, x) -> float: :param x: data point :return: feature map of the datapoint as numpy array """ - pass def get_allowed_operations(self): """Get the list of allowed operations. @@ -62,7 +62,7 @@ def get_allowed_operations(self): return self.ansatz.get_allowed_operations() def build_kernel( - self, X1: np.ndarray, X2: np.ndarray, matrix: str = None + self, x1: np.ndarray, x2: np.ndarray, matrix: str | None = None ) -> np.ndarray: """Build a kernel. @@ -72,30 +72,30 @@ def build_kernel( :return: a single or a matrix of kernel inner products """ # if you gave me only one sample - if len(X1.shape) == 1 and len(X2.shape) == 1: + if len(x1.shape) == 1 and len(x2.shape) == 1: if self.type in [KernelType.FIDELITY, KernelType.SWAP_TEST]: - return self.kappa(X1, X2) + return self.kappa(x1, x2) else: - return self.phi(X1) * self.phi(X2) + return self.phi(x1) * self.phi(x2) # if you gave me multiple samples - assert self.ansatz.n_features == X1.shape[1], ( + assert self.ansatz.n_features == x1.shape[1], ( "Number of features and X1.shape[1] do not match" ) - assert self.ansatz.n_features == X2.shape[1], ( + assert self.ansatz.n_features == x2.shape[1], ( "Number of features and X2.shape[1] do not match" ) if self.type in [KernelType.FIDELITY, KernelType.SWAP_TEST]: if matrix == "train": - return self.kernel_train_matrix(X1, X2) + return self.kernel_train_matrix(x1, x2) elif matrix == "test": - return self.kernel_test_matrix(X1, X2) + return self.kernel_test_matrix(x1, x2) else: - n = X1.shape[0] - m = X2.shape[0] - Phi1 = np.array([self.phi(x) for x in X1]).reshape((n, 1)) - Phi2 = np.array([self.phi(x) for x in X2]).reshape((m, 1)) - return Phi1.dot(Phi2.T) + n = x1.shape[0] + m = x2.shape[0] + phi1 = np.array([self.phi(x) for x in x1]).reshape((n, 1)) + phi2 = np.array([self.phi(x) for x in x2]).reshape((m, 1)) + return phi1.dot(phi2.T) def kernel_train_matrix(self, X1, X2): N = X1.shape[0] diff --git a/src/quask/core/kernel_factory.py b/src/quask/core/kernel_factory.py index 3cab975..a80d15f 100644 --- a/src/quask/core/kernel_factory.py +++ b/src/quask/core/kernel_factory.py @@ -1,5 +1,5 @@ -from . import Ansatz, KernelType - +from .ansatz import Ansatz +from .kernel_type import KernelType class KernelFactory: """Instantiate the concrete object from classes that inherit from (abstract class) Kernel. diff --git a/src/quask/core/operation.py b/src/quask/core/operation.py index 4bd5081..44cf974 100644 --- a/src/quask/core/operation.py +++ b/src/quask/core/operation.py @@ -4,7 +4,9 @@ class Operation: - """Class representing a 2-qubit rotational quantum gates $exp(-i \theta \\sigma_1 \\otimes \\sigma_2)$""" + """Class representing a 2-qubit rotational quantum gates + $exp(-i \theta \\sigma_1 \\otimes \\sigma_2)$. + """ PAULI_GENERATORS = list( a + b for a, b in itertools.product(["I", "X", "Y", "Z"], repeat=2) diff --git a/tests/kernel_test.py b/tests/kernel_test.py deleted file mode 100644 index 3403c13..0000000 --- a/tests/kernel_test.py +++ /dev/null @@ -1,66 +0,0 @@ -import numpy as np - -from quask import Ansatz, KernelType, PennylaneKernel - - -def test_static_single_qubit(KernelClass): - # circuit: |0> - RX(pi) - - # |0> - ID - - ansats = Ansatz(n_features=1, n_qubits=2, n_operations=1) - ansats.initialize_to_identity() - ansats.change_generators(0, "XI") - ansats.change_feature(0, -1) - ansats.change_wires(0, [0, 1]) - ansats.change_bandwidth(0, 1) - - # measurement operation = <1|Z|1> - # probabilities: [0.0, 1.0] - # observable: 0.0 * (+1) + 1.0 * (-1) = -1.0 - kernel = KernelClass(ansats, "ZI", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.inf])) - assert np.allclose(kernel.get_last_probabilities(), np.array([0, 1])), ( - f"Incorrect measurement: {kernel.get_last_probabilities()}" - ) - assert np.isclose(x, -1), "Incorrect observable" - - # measurement operation = <1|X|1> = <1H|Z|H1> = <+|Z|+> - # probabilities: [0.5, 0.5] - # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 - kernel = KernelClass(ansats, "XI", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.inf])) - assert np.allclose( - kernel.get_last_probabilities(), np.array([0.5, 0.5]) - ), f"Incorrect measurement: {kernel.get_last_probabilities()}" - assert np.isclose(x, 0), "Incorrect observable" - - # measurement operation = <1|Y|1> = <1HSdag|Z|SdagH1> = <[1/sqrt(2), -i/sqrt(2)]|Z|[1/sqrt(2), -i/sqrt(2)]> - # probabilities: [0.5, 0.5] - # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 - kernel = KernelClass(ansats, "YI", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.inf])) - assert np.allclose( - kernel.get_last_probabilities(), np.array([0.5, 0.5]) - ), f"Incorrect measurement: {kernel.get_last_probabilities()}" - assert np.isclose(x, 0), "Incorrect observable" - - -def test_static_two_qubit(KernelClass): - # circuit: |0> - XY(#0) - - # |0> - XY(#0) - - ansats = Ansatz(n_features=1, n_qubits=2, n_operations=1) - ansats.initialize_to_identity() - ansats.change_generators(0, "XY") - ansats.change_feature(0, 0) - ansats.change_wires(0, [0, 1]) - ansats.change_bandwidth(0, 1) - - kernel = KernelClass(ansats, "ZZ", KernelType.OBSERVABLE) - x = kernel.phi(np.array([np.pi / 2])) - assert np.allclose( - kernel.get_last_probabilities(), np.array([0.5, 0.0, 0.0, 0.5]) - ), "Incorrect measurement" - assert np.isclose(x, 0), "Incorrect observable" - - -test_static_single_qubit(PennylaneKernel) -test_static_two_qubit(PennylaneKernel) diff --git a/tests/test_example.py b/tests/test_example.py deleted file mode 100644 index db5c2f6..0000000 --- a/tests/test_example.py +++ /dev/null @@ -1,21 +0,0 @@ -import sys - -sys.path.append("./src/") - - -from quask.core import Ansatz - - -def test_trivial(): - """Trivial test.""" - print("Passed") - - -def test_ansatz_init(): - ansatz = Ansatz( - n_features=2, - n_qubits=2, - n_operations=2, - allow_midcircuit_measurement=False, - ) - assert ansatz is not None, "Could not create an Ansatz object." diff --git a/tests/test_pennylane_kernel.py b/tests/test_pennylane_kernel.py index 4873d52..beedf32 100644 --- a/tests/test_pennylane_kernel.py +++ b/tests/test_pennylane_kernel.py @@ -1,106 +1,171 @@ -import sys +"""Basic unit testing for the PennyLane kernels.""" +import unittest -sys.path.append("src/") import numpy as np - from quask.core import Ansatz, Kernel, KernelType from quask.core_implementation import PennylaneKernel -def check_kernel_value(kernel: Kernel, x1: float, x2: float, expected: float): - similarity = kernel.kappa(x1, x2) - print(similarity, expected) - assert np.isclose(similarity, expected), ( - f"Kernel value is {similarity:0.3f} while {expected:0.3f} was expected" - ) +class TestKernel(unittest.TestCase): + """Testing basic functionalities on kernels.""" + + def test_static_single_qubit(self): + """Test static single qubit.""" + # circuit: |0> - RX(pi) - + # |0> - ID - + ansatz = Ansatz(n_features=1, n_qubits=2, n_operations=1) + ansatz.initialize_to_identity() + ansatz.change_generators(0, "XI") + ansatz.change_feature(0, -1) + ansatz.change_wires(0, [0, 1]) + ansatz.change_bandwidth(0, 1) + + # measurement operation = <1|Z|1> + # probabilities: [0.0, 1.0] + # observable: 0.0 * (+1) + 1.0 * (-1) = -1.0 + kernel = PennylaneKernel(ansatz, "ZI", KernelType.OBSERVABLE) + x = kernel.phi(np.array([np.inf])) + assert np.allclose(kernel.get_last_probabilities(), np.array([0, 1])), ( + f"Incorrect measurement: {kernel.get_last_probabilities()}" + ) + assert np.isclose(x, -1), "Incorrect observable" + + # measurement operation = <1|X|1> = <1H|Z|H1> = <+|Z|+> + # probabilities: [0.5, 0.5] + # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 + kernel = PennylaneKernel(ansatz, "XI", KernelType.OBSERVABLE) + x = kernel.phi(np.array([np.inf])) + assert np.allclose( + kernel.get_last_probabilities(), np.array([0.5, 0.5]) + ), f"Incorrect measurement: {kernel.get_last_probabilities()}" + print(x) + assert np.isclose(x, 0), "Incorrect observable" + + # measurement operation + # <1|Y|1> = <1HSdag|Z|SdagH1> = + # = <[1/sqrt(2), -i/sqrt(2)]|Z|[1/sqrt(2), -i/sqrt(2)]> + # probabilities: [0.5, 0.5] + # observable: 0.5 * (+1) + 0.5 * (-1) = 0.0 + kernel = PennylaneKernel(ansatz, "YI", KernelType.OBSERVABLE) + x = kernel.phi(np.array([np.inf])) + assert np.allclose( + kernel.get_last_probabilities(), np.array([0.5, 0.5]) + ), f"Incorrect measurement: {kernel.get_last_probabilities()}" + assert np.isclose(x, 0), "Incorrect observable" + + + def test_static_two_qubit(self): + """Two qubit case.""" + # circuit: |0> - XY(#0) - + # |0> - XY(#0) - + ansatz = Ansatz(n_features=1, n_qubits=2, n_operations=1) + ansatz.initialize_to_identity() + ansatz.change_generators(0, "XY") + ansatz.change_feature(0, 0) + ansatz.change_wires(0, [0, 1]) + ansatz.change_bandwidth(0, 1) + + kernel = PennylaneKernel(ansatz, "ZZ", KernelType.OBSERVABLE) + x = kernel.phi(np.array([np.pi / 2])) + assert np.allclose( + kernel.get_last_probabilities(), np.array([0.5, 0.0, 0.0, 0.5]) + ), "Incorrect measurement" + assert np.isclose(x, 0), "Incorrect observable" + + + def _check_kernel_value(self, kernel: Kernel, x1: float, x2: float, expected: float): + similarity = kernel.kappa(x1, x2) + print(similarity, expected) + assert np.isclose(similarity, expected), ( + f"Kernel value is {similarity:0.3f} while {expected:0.3f} was expected" + ) + + def check_kernel_rx_value(kernel: Kernel, x1: float, x2: float): + def rx(theta): + return np.array( + [ + [np.cos(theta / 2), -1j * np.sin(theta / 2)], + [-1j * np.sin(theta / 2), np.cos(theta / 2)], + ] + ) -def check_kernel_rx_value(kernel: Kernel, x1: float, x2: float): - def rx(theta): - return np.array( - [ - [np.cos(theta / 2), -1j * np.sin(theta / 2)], - [-1j * np.sin(theta / 2), np.cos(theta / 2)], - ] + ket_zero = np.array([[1], [0]]) + ket_phi = np.linalg.inv(rx(x2)) @ rx(x1) @ ket_zero + expected_similarity = (np.abs(ket_phi[0]) ** 2).real + check_kernel_value( + kernel, np.array([x1]), np.array([x2]), expected_similarity ) - ket_zero = np.array([[1], [0]]) - ket_phi = np.linalg.inv(rx(x2)) @ rx(x1) @ ket_zero - expected_similarity = (np.abs(ket_phi[0]) ** 2).real - check_kernel_value( - kernel, np.array([x1]), np.array([x2]), expected_similarity - ) - - -def test_rx_kernel_fidelity(): - ansatz = Ansatz( - n_features=1, - n_qubits=2, - n_operations=1, - allow_midcircuit_measurement=False, - ) - ansatz.initialize_to_identity() - ansatz.change_operation( - 0, - new_feature=0, - new_wires=[0, 1], - new_generator="XI", - new_bandwidth=1.0, - ) - kernel = PennylaneKernel( - ansatz, - "ZZ", - KernelType.FIDELITY, - device_name="default.qubit", - n_shots=None, - ) - - check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) - - check_kernel_rx_value(kernel, 0.00, 0.00) - check_kernel_rx_value(kernel, 0.33, 0.33) - check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) - check_kernel_rx_value(kernel, np.pi, np.pi) - check_kernel_rx_value(kernel, 0, np.pi) - check_kernel_rx_value(kernel, 0.33, np.pi) - check_kernel_rx_value(kernel, np.pi / 2, np.pi) - check_kernel_rx_value(kernel, 0, 0.55) - check_kernel_rx_value(kernel, 0.33, 0.55) - check_kernel_rx_value(kernel, np.pi / 2, 0.55) - - -def test_rx_kernel_fidelity(): - ansatz = Ansatz( - n_features=1, - n_qubits=2, - n_operations=1, - allow_midcircuit_measurement=False, - ) - ansatz.initialize_to_identity() - ansatz.change_operation( - 0, - new_feature=0, - new_wires=[0, 1], - new_generator="XI", - new_bandwidth=1.0, - ) - kernel = PennylaneKernel( - ansatz, - "ZZ", - KernelType.SWAP_TEST, - device_name="default.qubit", - n_shots=None, - ) - - check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) - - check_kernel_rx_value(kernel, 0.00, 0.00) - check_kernel_rx_value(kernel, 0.33, 0.33) - check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) - check_kernel_rx_value(kernel, np.pi, np.pi) - check_kernel_rx_value(kernel, 0, np.pi) - check_kernel_rx_value(kernel, 0.33, np.pi) - check_kernel_rx_value(kernel, np.pi / 2, np.pi) - check_kernel_rx_value(kernel, 0, 0.55) - check_kernel_rx_value(kernel, 0.33, 0.55) - check_kernel_rx_value(kernel, np.pi / 2, 0.55) + def test_rx_kernel_fidelity(): + ansatz = Ansatz( + n_features=1, + n_qubits=2, + n_operations=1, + allow_midcircuit_measurement=False, + ) + ansatz.initialize_to_identity() + ansatz.change_operation( + 0, + new_feature=0, + new_wires=[0, 1], + new_generator="XI", + new_bandwidth=1.0, + ) + kernel = PennylaneKernel( + ansatz, + "ZZ", + KernelType.FIDELITY, + device_name="default.qubit", + n_shots=None, + ) + + check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) + + check_kernel_rx_value(kernel, 0.00, 0.00) + check_kernel_rx_value(kernel, 0.33, 0.33) + check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) + check_kernel_rx_value(kernel, np.pi, np.pi) + check_kernel_rx_value(kernel, 0, np.pi) + check_kernel_rx_value(kernel, 0.33, np.pi) + check_kernel_rx_value(kernel, np.pi / 2, np.pi) + check_kernel_rx_value(kernel, 0, 0.55) + check_kernel_rx_value(kernel, 0.33, 0.55) + check_kernel_rx_value(kernel, np.pi / 2, 0.55) + + + def test_rx_kernel_fidelity(): + ansatz = Ansatz( + n_features=1, + n_qubits=2, + n_operations=1, + allow_midcircuit_measurement=False, + ) + ansatz.initialize_to_identity() + ansatz.change_operation( + 0, + new_feature=0, + new_wires=[0, 1], + new_generator="XI", + new_bandwidth=1.0, + ) + kernel = PennylaneKernel( + ansatz, + "ZZ", + KernelType.SWAP_TEST, + device_name="default.qubit", + n_shots=None, + ) + + check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) + + check_kernel_rx_value(kernel, 0.00, 0.00) + check_kernel_rx_value(kernel, 0.33, 0.33) + check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) + check_kernel_rx_value(kernel, np.pi, np.pi) + check_kernel_rx_value(kernel, 0, np.pi) + check_kernel_rx_value(kernel, 0.33, np.pi) + check_kernel_rx_value(kernel, np.pi / 2, np.pi) + check_kernel_rx_value(kernel, 0, 0.55) + check_kernel_rx_value(kernel, 0.33, 0.55) + check_kernel_rx_value(kernel, np.pi / 2, 0.55) diff --git a/uv.lock b/uv.lock index 33e8596..3da10c0 100644 --- a/uv.lock +++ b/uv.lock @@ -3,7 +3,8 @@ requires-python = ">=3.10" resolution-markers = [ "python_full_version < '3.11'", "python_full_version == '3.11.*'", - "python_full_version >= '3.12'", + "python_full_version == '3.12.*'", + "python_full_version >= '3.13'", ] [[package]] @@ -364,6 +365,43 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a1/70/de81bfec9ed38a64fc44a77c7665e20ca507fc3265597c28b0d989e4082e/coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f", size = 200223 }, ] +[[package]] +name = "cryptography" +version = "44.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/4c/45dfa6829acffa344e3967d6006ee4ae8be57af746ae2eba1c431949b32c/cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02", size = 710657 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/09/8cc67f9b84730ad330b3b72cf867150744bf07ff113cda21a15a1c6d2c7c/cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123", size = 6541833 }, + { url = "https://files.pythonhosted.org/packages/7e/5b/3759e30a103144e29632e7cb72aec28cedc79e514b2ea8896bb17163c19b/cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092", size = 3922710 }, + { url = "https://files.pythonhosted.org/packages/5f/58/3b14bf39f1a0cfd679e753e8647ada56cddbf5acebffe7db90e184c76168/cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f", size = 4137546 }, + { url = "https://files.pythonhosted.org/packages/98/65/13d9e76ca19b0ba5603d71ac8424b5694415b348e719db277b5edc985ff5/cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", size = 3915420 }, + { url = "https://files.pythonhosted.org/packages/b1/07/40fe09ce96b91fc9276a9ad272832ead0fddedcba87f1190372af8e3039c/cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", size = 4154498 }, + { url = "https://files.pythonhosted.org/packages/75/ea/af65619c800ec0a7e4034207aec543acdf248d9bffba0533342d1bd435e1/cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", size = 3932569 }, + { url = "https://files.pythonhosted.org/packages/c7/af/d1deb0c04d59612e3d5e54203159e284d3e7a6921e565bb0eeb6269bdd8a/cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", size = 4016721 }, + { url = "https://files.pythonhosted.org/packages/bd/69/7ca326c55698d0688db867795134bdfac87136b80ef373aaa42b225d6dd5/cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", size = 4240915 }, + { url = "https://files.pythonhosted.org/packages/ef/d4/cae11bf68c0f981e0413906c6dd03ae7fa864347ed5fac40021df1ef467c/cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", size = 2757925 }, + { url = "https://files.pythonhosted.org/packages/64/b1/50d7739254d2002acae64eed4fc43b24ac0cc44bf0a0d388d1ca06ec5bb1/cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd", size = 3202055 }, + { url = "https://files.pythonhosted.org/packages/11/18/61e52a3d28fc1514a43b0ac291177acd1b4de00e9301aaf7ef867076ff8a/cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591", size = 6542801 }, + { url = "https://files.pythonhosted.org/packages/1a/07/5f165b6c65696ef75601b781a280fc3b33f1e0cd6aa5a92d9fb96c410e97/cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7", size = 3922613 }, + { url = "https://files.pythonhosted.org/packages/28/34/6b3ac1d80fc174812486561cf25194338151780f27e438526f9c64e16869/cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc", size = 4137925 }, + { url = "https://files.pythonhosted.org/packages/d0/c7/c656eb08fd22255d21bc3129625ed9cd5ee305f33752ef2278711b3fa98b/cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", size = 3915417 }, + { url = "https://files.pythonhosted.org/packages/ef/82/72403624f197af0db6bac4e58153bc9ac0e6020e57234115db9596eee85d/cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", size = 4155160 }, + { url = "https://files.pythonhosted.org/packages/a2/cd/2f3c440913d4329ade49b146d74f2e9766422e1732613f57097fea61f344/cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", size = 3932331 }, + { url = "https://files.pythonhosted.org/packages/7f/df/8be88797f0a1cca6e255189a57bb49237402b1880d6e8721690c5603ac23/cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", size = 4017372 }, + { url = "https://files.pythonhosted.org/packages/af/36/5ccc376f025a834e72b8e52e18746b927f34e4520487098e283a719c205e/cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", size = 4239657 }, + { url = "https://files.pythonhosted.org/packages/46/b0/f4f7d0d0bcfbc8dd6296c1449be326d04217c57afb8b2594f017eed95533/cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", size = 2758672 }, + { url = "https://files.pythonhosted.org/packages/97/9b/443270b9210f13f6ef240eff73fd32e02d381e7103969dc66ce8e89ee901/cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede", size = 3202071 }, + { url = "https://files.pythonhosted.org/packages/77/d4/fea74422326388bbac0c37b7489a0fcb1681a698c3b875959430ba550daa/cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731", size = 3338857 }, + { url = "https://files.pythonhosted.org/packages/1a/aa/ba8a7467c206cb7b62f09b4168da541b5109838627f582843bbbe0235e8e/cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4", size = 3850615 }, + { url = "https://files.pythonhosted.org/packages/89/fa/b160e10a64cc395d090105be14f399b94e617c879efd401188ce0fea39ee/cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756", size = 4081622 }, + { url = "https://files.pythonhosted.org/packages/47/8f/20ff0656bb0cf7af26ec1d01f780c5cfbaa7666736063378c5f48558b515/cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c", size = 3867546 }, + { url = "https://files.pythonhosted.org/packages/38/d9/28edf32ee2fcdca587146bcde90102a7319b2f2c690edfa627e46d586050/cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa", size = 4090937 }, + { url = "https://files.pythonhosted.org/packages/cc/9d/37e5da7519de7b0b070a3fedd4230fe76d50d2a21403e0f2153d70ac4163/cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c", size = 3128774 }, +] + [[package]] name = "debugpy" version = "1.8.12" @@ -412,6 +450,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/49/73/785c03860b1106f8f0ffbc69f2521bde1b58545114970cbbd3540d7f5434/diastatic_malt-2.15.2-py3-none-any.whl", hash = "sha256:85429257b356030f101c31b2c7d506c4829f21bd865aed796766f900d7908407", size = 167919 }, ] +[[package]] +name = "dill" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/43/86fe3f9e130c4137b0f1b50784dd70a5087b911fe07fa81e53e0c4c47fea/dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c", size = 187000 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a", size = 119418 }, +] + [[package]] name = "distlib" version = "0.3.9" @@ -499,6 +546,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1d/9a/4114a9057db2f1462d5c8f8390ab7383925fe1ac012eaa42402ad65c2963/GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110", size = 207599 }, ] +[[package]] +name = "ibm-cloud-sdk-core" +version = "3.22.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyjwt" }, + { name = "python-dateutil" }, + { name = "requests" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/23/c0/2511acb45026c747627690c96dfffbab35856b89b9446aceba0aa4b5350d/ibm_cloud_sdk_core-3.22.1.tar.gz", hash = "sha256:096dd22c146848a87053f8f2bfbd5dfdf089eefe81ee1c448ca22c4304751dfd", size = 70713 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/20/c11059e24a0bce938163408f9943054af88278652575e1a5a3263d35403d/ibm_cloud_sdk_core-3.22.1-py3-none-any.whl", hash = "sha256:d2195d34705b24c7e3a59ad51f01a974defc5bee3576570d9a0e219139550dd4", size = 69431 }, +] + +[[package]] +name = "ibm-platform-services" +version = "0.59.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ibm-cloud-sdk-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/12/cf/1f80ff579c97e03dc6d101df3f7598bf5c51f41e184339553261f1addc5a/ibm_platform_services-0.59.1.tar.gz", hash = "sha256:5d0f5a64ddb0cc2dfbeb89da0df611faa9b2494a091f8bba5e8f44a497e7c0c3", size = 324644 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/88/be8b7863c42ee9acfd5bf374699a7126260a5bd06ddde07a132a297ed348/ibm_platform_services-0.59.1-py3-none-any.whl", hash = "sha256:bc9a324c387d2ed5d544f5cab597f50ab55a4426f7c1b40a51162a46f9f62962", size = 340775 }, +] + [[package]] name = "identify" version = "2.6.6" @@ -735,6 +809,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, ] +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 }, +] + [[package]] name = "nest-asyncio" version = "1.6.0" @@ -880,6 +963,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650 }, ] +[[package]] +name = "pbr" +version = "6.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/d2/510cc0d218e753ba62a1bc1434651db3cd797a9716a0a66cc714cb4f0935/pbr-6.1.1.tar.gz", hash = "sha256:93ea72ce6989eb2eed99d0f75721474f69ad88128afdef5ac377eb797c4bf76b", size = 125702 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/ac/684d71315abc7b1214d59304e23a982472967f6bf4bde5a98f1503f648dc/pbr-6.1.1-py2.py3-none-any.whl", hash = "sha256:38d4daea5d9fa63b3f626131b9d34947fd0c8be9b05a29276870580050a25a76", size = 108997 }, +] + [[package]] name = "pennylane" version = "0.40.0" @@ -1046,91 +1141,83 @@ wheels = [ [[package]] name = "pydantic" -version = "2.10.6" +version = "2.9.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } +sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, + { url = "https://files.pythonhosted.org/packages/df/e4/ba44652d562cbf0bf320e0f3810206149c8a4e99cdbf66da82e97ab53a15/pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12", size = 434928 }, ] [[package]] name = "pydantic-core" -version = "2.27.2" +version = "2.23.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938 }, - { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684 }, - { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169 }, - { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227 }, - { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695 }, - { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662 }, - { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370 }, - { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813 }, - { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287 }, - { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414 }, - { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301 }, - { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685 }, - { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876 }, - { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421 }, - { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998 }, - { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167 }, - { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071 }, - { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244 }, - { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470 }, - { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291 }, - { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613 }, - { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355 }, - { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661 }, - { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261 }, - { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361 }, - { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484 }, - { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102 }, - { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, - { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, - { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, - { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, - { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, - { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, - { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, - { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, - { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, - { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, - { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, - { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, - { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, - { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, - { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, - { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, - { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, - { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, - { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, - { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, - { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, - { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, - { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, - { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, - { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, - { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, - { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, - { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, - { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159 }, - { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331 }, - { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467 }, - { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797 }, - { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839 }, - { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861 }, - { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582 }, - { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985 }, - { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715 }, +sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/8b/d3ae387f66277bd8104096d6ec0a145f4baa2966ebb2cad746c0920c9526/pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", size = 1867835 }, + { url = "https://files.pythonhosted.org/packages/46/76/f68272e4c3a7df8777798282c5e47d508274917f29992d84e1898f8908c7/pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", size = 1776689 }, + { url = "https://files.pythonhosted.org/packages/cc/69/5f945b4416f42ea3f3bc9d2aaec66c76084a6ff4ff27555bf9415ab43189/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", size = 1800748 }, + { url = "https://files.pythonhosted.org/packages/50/ab/891a7b0054bcc297fb02d44d05c50e68154e31788f2d9d41d0b72c89fdf7/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", size = 1806469 }, + { url = "https://files.pythonhosted.org/packages/31/7c/6e3fa122075d78f277a8431c4c608f061881b76c2b7faca01d317ee39b5d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", size = 2002246 }, + { url = "https://files.pythonhosted.org/packages/ad/6f/22d5692b7ab63fc4acbc74de6ff61d185804a83160adba5e6cc6068e1128/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", size = 2659404 }, + { url = "https://files.pythonhosted.org/packages/11/ac/1e647dc1121c028b691028fa61a4e7477e6aeb5132628fde41dd34c1671f/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", size = 2053940 }, + { url = "https://files.pythonhosted.org/packages/91/75/984740c17f12c3ce18b5a2fcc4bdceb785cce7df1511a4ce89bca17c7e2d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", size = 1921437 }, + { url = "https://files.pythonhosted.org/packages/a0/74/13c5f606b64d93f0721e7768cd3e8b2102164866c207b8cd6f90bb15d24f/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", size = 1966129 }, + { url = "https://files.pythonhosted.org/packages/18/03/9c4aa5919457c7b57a016c1ab513b1a926ed9b2bb7915bf8e506bf65c34b/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", size = 2110908 }, + { url = "https://files.pythonhosted.org/packages/92/2c/053d33f029c5dc65e5cf44ff03ceeefb7cce908f8f3cca9265e7f9b540c8/pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", size = 1735278 }, + { url = "https://files.pythonhosted.org/packages/de/81/7dfe464eca78d76d31dd661b04b5f2036ec72ea8848dd87ab7375e185c23/pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", size = 1917453 }, + { url = "https://files.pythonhosted.org/packages/5d/30/890a583cd3f2be27ecf32b479d5d615710bb926d92da03e3f7838ff3e58b/pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", size = 1865160 }, + { url = "https://files.pythonhosted.org/packages/1d/9a/b634442e1253bc6889c87afe8bb59447f106ee042140bd57680b3b113ec7/pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", size = 1776777 }, + { url = "https://files.pythonhosted.org/packages/75/9a/7816295124a6b08c24c96f9ce73085032d8bcbaf7e5a781cd41aa910c891/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", size = 1799244 }, + { url = "https://files.pythonhosted.org/packages/a9/8f/89c1405176903e567c5f99ec53387449e62f1121894aa9fc2c4fdc51a59b/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607", size = 1805307 }, + { url = "https://files.pythonhosted.org/packages/d5/a5/1a194447d0da1ef492e3470680c66048fef56fc1f1a25cafbea4bc1d1c48/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", size = 2000663 }, + { url = "https://files.pythonhosted.org/packages/13/a5/1df8541651de4455e7d587cf556201b4f7997191e110bca3b589218745a5/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", size = 2655941 }, + { url = "https://files.pythonhosted.org/packages/44/31/a3899b5ce02c4316865e390107f145089876dff7e1dfc770a231d836aed8/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", size = 2052105 }, + { url = "https://files.pythonhosted.org/packages/1b/aa/98e190f8745d5ec831f6d5449344c48c0627ac5fed4e5340a44b74878f8e/pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", size = 1919967 }, + { url = "https://files.pythonhosted.org/packages/ae/35/b6e00b6abb2acfee3e8f85558c02a0822e9a8b2f2d812ea8b9079b118ba0/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", size = 1964291 }, + { url = "https://files.pythonhosted.org/packages/13/46/7bee6d32b69191cd649bbbd2361af79c472d72cb29bb2024f0b6e350ba06/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", size = 2109666 }, + { url = "https://files.pythonhosted.org/packages/39/ef/7b34f1b122a81b68ed0a7d0e564da9ccdc9a2924c8d6c6b5b11fa3a56970/pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", size = 1732940 }, + { url = "https://files.pythonhosted.org/packages/2f/76/37b7e76c645843ff46c1d73e046207311ef298d3f7b2f7d8f6ac60113071/pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", size = 1916804 }, + { url = "https://files.pythonhosted.org/packages/74/7b/8e315f80666194b354966ec84b7d567da77ad927ed6323db4006cf915f3f/pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", size = 1856459 }, + { url = "https://files.pythonhosted.org/packages/14/de/866bdce10ed808323d437612aca1ec9971b981e1c52e5e42ad9b8e17a6f6/pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", size = 1770007 }, + { url = "https://files.pythonhosted.org/packages/dc/69/8edd5c3cd48bb833a3f7ef9b81d7666ccddd3c9a635225214e044b6e8281/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", size = 1790245 }, + { url = "https://files.pythonhosted.org/packages/80/33/9c24334e3af796ce80d2274940aae38dd4e5676298b4398eff103a79e02d/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", size = 1801260 }, + { url = "https://files.pythonhosted.org/packages/a5/6f/e9567fd90104b79b101ca9d120219644d3314962caa7948dd8b965e9f83e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", size = 1996872 }, + { url = "https://files.pythonhosted.org/packages/2d/ad/b5f0fe9e6cfee915dd144edbd10b6e9c9c9c9d7a56b69256d124b8ac682e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", size = 2661617 }, + { url = "https://files.pythonhosted.org/packages/06/c8/7d4b708f8d05a5cbfda3243aad468052c6e99de7d0937c9146c24d9f12e9/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", size = 2071831 }, + { url = "https://files.pythonhosted.org/packages/89/4d/3079d00c47f22c9a9a8220db088b309ad6e600a73d7a69473e3a8e5e3ea3/pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", size = 1917453 }, + { url = "https://files.pythonhosted.org/packages/e9/88/9df5b7ce880a4703fcc2d76c8c2d8eb9f861f79d0c56f4b8f5f2607ccec8/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", size = 1968793 }, + { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, + { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, + { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, + { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, + { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, + { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, + { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, + { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, + { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, + { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, + { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, + { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, + { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, + { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, + { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, + { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135 }, + { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583 }, + { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637 }, + { url = "https://files.pythonhosted.org/packages/29/18/812222b6d18c2d13eebbb0f7cdc170a408d9ced65794fdb86147c77e1982/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", size = 1941963 }, + { url = "https://files.pythonhosted.org/packages/0f/36/c1f3642ac3f05e6bb4aec3ffc399fa3f84895d259cf5f0ce3054b7735c29/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", size = 1915332 }, + { url = "https://files.pythonhosted.org/packages/f7/ca/9c0854829311fb446020ebb540ee22509731abad886d2859c855dd29b904/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", size = 1957926 }, + { url = "https://files.pythonhosted.org/packages/c0/1c/7836b67c42d0cd4441fcd9fafbf6a027ad4b79b6559f80cf11f89fd83648/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", size = 2100342 }, + { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344 }, ] [[package]] @@ -1142,6 +1229,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, ] +[[package]] +name = "pyjwt" +version = "2.10.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997 }, +] + [[package]] name = "pyproject-api" version = "1.9.0" @@ -1155,6 +1251,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b0/1d/92b7c765df46f454889d9610292b0ccab15362be3119b9a624458455e8d5/pyproject_api-1.9.0-py3-none-any.whl", hash = "sha256:326df9d68dea22d9d98b5243c46e3ca3161b07a1b9b18e213d1e24fd0e605766", size = 13131 }, ] +[[package]] +name = "pyspnego" +version = "0.11.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "sspilib", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/f8/53f1fc851dab776a183ffc9f29ebde244fbb467f5237f3ea809519fc4b2e/pyspnego-0.11.2.tar.gz", hash = "sha256:994388d308fb06e4498365ce78d222bf4f3570b6df4ec95738431f61510c971b", size = 225954 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/ea/b3c1438839d8724beff7b31ec42b9d041265dc9ca27ccb54477d442bfbcf/pyspnego-0.11.2-py3-none-any.whl", hash = "sha256:74abc1fb51e59360eb5c5c9086e5962174f1072c7a50cf6da0bda9a4bcfdfbd4", size = 130529 }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1348,6 +1457,54 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e3/fe/72e7e166bda3885810bee7b23049133e142f7c80c295bae02c562caeea16/pyzmq-26.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bd8fdee945b877aa3bffc6a5a8816deb048dab0544f9df3731ecd0e54d8c84c9", size = 556563 }, ] +[[package]] +name = "qiskit" +version = "1.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dill" }, + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "rustworkx" }, + { name = "scipy" }, + { name = "stevedore" }, + { name = "symengine" }, + { name = "sympy" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/35/88f68a1746ecdbfa1b1a13b28d21010732e3aa734876a276a36efaeed0b5/qiskit-1.3.2.tar.gz", hash = "sha256:6e63c619bcc3e29cd59f831af5b161b35951498c272d00da01a3fef7db3743c9", size = 3915105 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/ac/c7bd9f159166c04fa3cad1a8a6c05b76aa2993477be29ea44f50d8e81023/qiskit-1.3.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:3fe16377787e31c67b87b2baa9fe3239ffab46e1697ed7dfc4687f89f283453b", size = 6567126 }, + { url = "https://files.pythonhosted.org/packages/46/12/22fa1f4ac05248e5e15157c255b025a3040e522f32a17ad3821163fa8ec4/qiskit-1.3.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:fc7be685e0f144825201da4c818e370977ab1be07049587899b209beca48a39e", size = 6246552 }, + { url = "https://files.pythonhosted.org/packages/cd/b3/c6e0bbaf6bd0bb2f36c28ef7a672bf3cb0db41faa19611319a5fc76661fc/qiskit-1.3.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f5a91c0f3f90cd1716aa99357965e4011f6f9fa37636c706a8829f7f408384b", size = 6371735 }, + { url = "https://files.pythonhosted.org/packages/6f/b9/610e70f9c9cc7ec8097504abf0e5652f5ed25fc68589171ac5a3b5a67951/qiskit-1.3.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65d5af561b6e0e98b099fe4b7bf099dcd1f09322fa1d47299ba2b2febc873ec7", size = 6720578 }, + { url = "https://files.pythonhosted.org/packages/8e/aa/2dd5662761db927b91378e964f970425bd17ddbc5c8a98d05b8b67d1d47e/qiskit-1.3.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a24090a779bf8153a99d3d8d56fe161ccfd57ef96ab55d4320b3f376320ad1ce", size = 6762392 }, + { url = "https://files.pythonhosted.org/packages/db/87/1ff556f428599f64857f90c5861fe13335e2fcae3ace26162bb54f6871c2/qiskit-1.3.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:253fa4d8b27c9dd1462fe67fec7428c2a3784216aa06babbb1a47547fa2afe8f", size = 7919144 }, + { url = "https://files.pythonhosted.org/packages/5a/b9/5d948b7def96f37285b065b18605b291d3dd82ad569b480d8f15968cfb4a/qiskit-1.3.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309f6db004ea8044df9ac9359c31dcce0cc12afb6ece6eb035ca86b9bf87a21c", size = 6767095 }, + { url = "https://files.pythonhosted.org/packages/9e/0c/88b1c2054650432d2f8311e1d3b1aba3496418b0265f7f7837b44c749665/qiskit-1.3.2-cp39-abi3-win32.whl", hash = "sha256:113a6962b3cd79a0aeeee92072a3e808291e776d8ca7ab25dffaea2e0c288b8d", size = 6124425 }, + { url = "https://files.pythonhosted.org/packages/d2/8a/8d06540a938c0141602e94a1d64949ed948b5cf8bba2c062988a15cd762b/qiskit-1.3.2-cp39-abi3-win_amd64.whl", hash = "sha256:8ec122c81f832c1a9202dae6485d402d1444845be2c53809f10d82cb1423e735", size = 6509080 }, +] + +[[package]] +name = "qiskit-ibm-runtime" +version = "0.35.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ibm-platform-services" }, + { name = "numpy" }, + { name = "pydantic" }, + { name = "python-dateutil" }, + { name = "qiskit" }, + { name = "requests" }, + { name = "requests-ntlm" }, + { name = "urllib3" }, + { name = "websocket-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/ec/342e5e403efcc83b2c967ee6b50900f2f46ae7967939b7eab008f40e06a9/qiskit_ibm_runtime-0.35.0.tar.gz", hash = "sha256:8b5919bfb96215d13ca5b103b8652c194e2e85b78dbe937dc2b6f675646de65f", size = 3065616 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/ea/015c315bf9b2fceb9cd1248251902c95ae0e1c905c61ed3646fb43dd3993/qiskit_ibm_runtime-0.35.0-py3-none-any.whl", hash = "sha256:a2b6dd7f6d24a632fb17b0fe8cfe30b56310679a8c01a79d641302431360eb6d", size = 3162442 }, +] + [[package]] name = "quask" version = "2.0.0a2" @@ -1355,6 +1512,8 @@ source = { editable = "." } dependencies = [ { name = "pandas" }, { name = "pennylane" }, + { name = "qiskit" }, + { name = "qiskit-ibm-runtime" }, { name = "scikit-learn" }, { name = "scipy" }, ] @@ -1382,6 +1541,8 @@ release = [ requires-dist = [ { name = "pandas", specifier = ">=2.2.3" }, { name = "pennylane", specifier = ">=0.40.0" }, + { name = "qiskit", specifier = ">=1.3.2" }, + { name = "qiskit-ibm-runtime", specifier = ">=0.35.0" }, { name = "scikit-learn", specifier = ">=1.6.1" }, { name = "scipy", specifier = ">=1.15.1" }, ] @@ -1418,6 +1579,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, ] +[[package]] +name = "requests-ntlm" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "pyspnego" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/15/74/5d4e1815107e9d78c44c3ad04740b00efd1189e5a9ec11e5275b60864e54/requests_ntlm-1.3.0.tar.gz", hash = "sha256:b29cc2462623dffdf9b88c43e180ccb735b4007228a542220e882c58ae56c668", size = 16112 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/5d/836b97537a390cf811b0488490c389c5a614f0a93acb23f347bd37a2d914/requests_ntlm-1.3.0-py3-none-any.whl", hash = "sha256:4c7534a7d0e482bb0928531d621be4b2c74ace437e88c5a357ceb7452d25a510", size = 6577 }, +] + [[package]] name = "requests-toolbelt" version = "1.0.0" @@ -1569,6 +1744,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/65/e3/5e0cd0945aba54312849dac3bca06b6e3dee725c7abb73e854cf79709838/scipy_openblas32-0.3.29.0.0-py3-none-win_amd64.whl", hash = "sha256:8b21c803bdc344a383a1d5d392d3cfe5366d9b89d2aeee963705156000cbbc7a", size = 7077538 }, ] +[[package]] +name = "setuptools" +version = "75.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ec/089608b791d210aec4e7f97488e67ab0d33add3efccb83a056cbafe3a2a6/setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6", size = 1343222 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/8a/b9dc7678803429e4a3bc9ba462fa3dd9066824d3c607490235c6a796be5a/setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3", size = 1228782 }, +] + [[package]] name = "shellingham" version = "1.5.4" @@ -1741,6 +1925,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, ] +[[package]] +name = "sspilib" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/48/8d634ac9aa5404b77f2d66b5a354751b7bbbf2be2947328fe895034cb750/sspilib-0.2.0.tar.gz", hash = "sha256:4d6cd4290ca82f40705efeb5e9107f7abcd5e647cb201a3d04371305938615b8", size = 55815 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/ac/b59283a2a0c91ef136f4979d711cd8dcd005b9f18b4a50ffaaa50e00f200/sspilib-0.2.0-cp310-cp310-win32.whl", hash = "sha256:e436fa09bcf353a364a74b3ef6910d936fa8cd1493f136e517a9a7e11b319c57", size = 487673 }, + { url = "https://files.pythonhosted.org/packages/c5/bc/84cb16b512902b972cfd89130918f01aabb8016814442ff6bd2cf89d6530/sspilib-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:850a17c98d2b8579b183ce37a8df97d050bc5b31ab13f5a6d9e39c9692fe3754", size = 565326 }, + { url = "https://files.pythonhosted.org/packages/c5/0d/d15fe0e5c87a51b7d693e889656816fd8d67995fbd072ab9852934e9ecf4/sspilib-0.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:a4d788a53b8db6d1caafba36887d5ac2087e6b6be6f01eb48f8afea6b646dbb5", size = 473562 }, + { url = "https://files.pythonhosted.org/packages/70/16/c31487f432724813a27f30c1a63ec07217adf65572e33fe9c4dcfd47a1b3/sspilib-0.2.0-cp311-cp311-win32.whl", hash = "sha256:400d5922c2c2261009921157c4b43d868e84640ad86e4dc84c95b07e5cc38ac6", size = 485419 }, + { url = "https://files.pythonhosted.org/packages/15/e9/0cb63b7f1014eff9c1a5b83920a423080b10f29ddf0264fced6abbdbad28/sspilib-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3e7d19c16ba9189ef8687b591503db06cfb9c5eb32ab1ca3bb9ebc1a8a5f35c", size = 564816 }, + { url = "https://files.pythonhosted.org/packages/b9/d9/3b8295f652afe71c0cdfd731eb7d37cc13a8adbfeacd3d67606d486d79b2/sspilib-0.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:f65c52ead8ce95eb78a79306fe4269ee572ef3e4dcc108d250d5933da2455ecc", size = 472529 }, + { url = "https://files.pythonhosted.org/packages/a9/82/07a49f00c0e7feff26f288b5f0747add197fc0db1ddddfab5fd5bdd94bdf/sspilib-0.2.0-cp312-cp312-win32.whl", hash = "sha256:bdf9a4f424add02951e1f01f47441d2e69a9910471e99c2c88660bd8e184d7f8", size = 487318 }, + { url = "https://files.pythonhosted.org/packages/38/54/949a9e9c07cd6efead79a7f78cc951cb5fa4f9f1fcb25b8520fd2adcdbe0/sspilib-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:40a97ca83e503a175d1dc9461836994e47e8b9bcf56cab81a2c22e27f1993079", size = 569220 }, + { url = "https://files.pythonhosted.org/packages/8f/52/c7a16472e9582474626f48ec79a821f66e5698cf5552baf923dfc636989e/sspilib-0.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:8ffc09819a37005c66a580ff44f544775f9745d5ed1ceeb37df4e5ff128adf36", size = 471371 }, + { url = "https://files.pythonhosted.org/packages/bc/9c/8784d3afe27c2f68620ea60fa2b6347100694db35193ba42714bdf23f882/sspilib-0.2.0-cp313-cp313-win32.whl", hash = "sha256:b9044d6020aa88d512e7557694fe734a243801f9a6874e1c214451eebe493d92", size = 483600 }, + { url = "https://files.pythonhosted.org/packages/49/ad/40f898075c913c75060c17c9cc6d6b86e8f83b6f5e1e017627b07ff53fcd/sspilib-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:c39a698491f43618efca8776a40fb7201d08c415c507f899f0df5ada15abefaa", size = 563678 }, + { url = "https://files.pythonhosted.org/packages/dd/84/3232ee82e33e426cd9e2011111a3136e5715428f0331a6739930b530333a/sspilib-0.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:863b7b214517b09367511c0ef931370f0386ed2c7c5613092bf9b106114c4a0e", size = 469030 }, +] + [[package]] name = "stack-data" version = "0.6.3" @@ -1755,6 +1959,67 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 }, ] +[[package]] +name = "stevedore" +version = "5.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pbr" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4a/e9/4eedccff8332cc40cc60ddd3b28d4c3e255ee7e9c65679fa4533ab98f598/stevedore-5.4.0.tar.gz", hash = "sha256:79e92235ecb828fe952b6b8b0c6c87863248631922c8e8e0fa5b17b232c4514d", size = 513899 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/73/d0091d22a65b55e8fb6aca7b3b6713b5a261dd01cec4cfd28ed127ac0cfc/stevedore-5.4.0-py3-none-any.whl", hash = "sha256:b0be3c4748b3ea7b854b265dcb4caa891015e442416422be16f8b31756107857", size = 49534 }, +] + +[[package]] +name = "symengine" +version = "0.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/ff/a2041497a482a0ae585672fe12cc8983c7fc46ce792811b55a067e5e5516/symengine-0.13.0.tar.gz", hash = "sha256:ab83a08897ebf12579702c2b71ba73d4732fb706cc4291d810aedf39c690c14c", size = 114237 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/ed/964f75a2dc5b0e2c97b732f44dfb9c40fe7c0f5e21a1ecc2edff89db3d81/symengine-0.13.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:259fd4111c7a70c72bdff5686de1949e8132baeb612eacdaf8837720c6fe449b", size = 25867912 }, + { url = "https://files.pythonhosted.org/packages/a3/ce/c74dfbaf487a428984644b3cb5e1131c4808f60eab1456f37a107f20b87a/symengine-0.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:44f2eb28a1e36db0bbd6679435412f79da9743bf9c1cb3eff25e0c343b7ddd48", size = 22711016 }, + { url = "https://files.pythonhosted.org/packages/4b/65/df699e2b4c2bbf608394b05d1095d77b3f02569e09960f7840f708c7c5dc/symengine-0.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d141712fa14d9138bd19e64b10392f850c68d88cd7db29f1bda33e32d1095559", size = 61000047 }, + { url = "https://files.pythonhosted.org/packages/ff/a9/623d97da0da9615367484127dd3b5d1049675832fb9a6a3572f2e072bb86/symengine-0.13.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:830226d933bfcdb93546e4062541627d9a3bc7a178a63fb16c002eb5c5221938", size = 90017189 }, + { url = "https://files.pythonhosted.org/packages/79/a0/d30329ef1bd2b188cb5bbf6d9394e72fa9f38b33a6caa2128ee187716259/symengine-0.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a08090163819a0bbfa97d64bd2d8dac2c5268147ed9c242799d7f7e8728a6f4e", size = 49698796 }, + { url = "https://files.pythonhosted.org/packages/e8/e3/cf99b6353b46b8d9ff05e8d7d24764c8afed7c46b888eece99c6e04cc295/symengine-0.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:1e435dcd8ed25e4c7c21ab1c0376be910efc7f35da76d532367df27b359f0358", size = 17830331 }, + { url = "https://files.pythonhosted.org/packages/47/a7/e69cff22c2b169b469faa390f0102fbdefe1dfede893a086454483db0fc3/symengine-0.13.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:da0eba7e106095cdce88eb275c8a9d7c4586ad88f229394c53e1184155c00745", size = 25878286 }, + { url = "https://files.pythonhosted.org/packages/60/40/bb3faf5a3d4cc99cf5252cc3f4f5267568abd4aae6439374623841cc0025/symengine-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b0c175f4f895a73a925508af03faf7efd6cad8593256bbdb5346bd996d3ec5c8", size = 22721741 }, + { url = "https://files.pythonhosted.org/packages/de/da/d6350f60f11abc7ee56fcb6b996deba7b31584b5942a4c5db7d3d4f324dd/symengine-0.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e58d1e2abd08381aa0cf24c88c0e8b7f592df92619b51e32d36835fbd2dd6ae8", size = 60999516 }, + { url = "https://files.pythonhosted.org/packages/d1/ee/db107db7d0557aa8dbc9485741a60dd4f869d3da32180710506f9ba942b9/symengine-0.13.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1db745f2c7a3c5e83510cf4decb43201f43552dfb05ad8af9787c89708be9ede", size = 90019965 }, + { url = "https://files.pythonhosted.org/packages/8f/f0/0642f5d9681ff26e57c317d0514315cf1b0dfe1bc8f68ee14a13a270d704/symengine-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2572c98b09ac284db6ecff63f6170461194dc94c4209afd34c092ec67873d85", size = 49690621 }, + { url = "https://files.pythonhosted.org/packages/54/85/4300eda41959e3839115b2cb0ddb21818804f5eb129cf92eb9cc55c6efe5/symengine-0.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:12727f02a2919f005aee48e68e0cbb70cf857b19385857b4d985d1c9b075f620", size = 17831939 }, + { url = "https://files.pythonhosted.org/packages/a1/b2/786d3efb98ae1c8e0a9869d6901f24a6633bd621f9e4e1427c86bff35abb/symengine-0.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cf91d24f1bfd6d53228593c7804dd106b71b19674d5afc4fa322d516e1793bdd", size = 25853458 }, + { url = "https://files.pythonhosted.org/packages/3f/74/78b9e7f17c9b9b345d8ef0dbdefebbfc2c7f00693949c6b5808f8a9e54d8/symengine-0.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5615b7eb68890917abd390ebb10434a949165f6064741c1a8cc345fee14e855", size = 22713256 }, + { url = "https://files.pythonhosted.org/packages/1d/a8/69f429946e9a9e63a141dcbe519df8a8c3d56aa75fa8440716871efd8b75/symengine-0.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb92bdf0890de264abaeacbfbdbd4dd7444b94057bd47958d913b662e549ad8a", size = 60847852 }, + { url = "https://files.pythonhosted.org/packages/f5/3c/a613d5fa73c1b05eb4f0a4bc2bfa21314d37c89dcdb355da684b5f9bea46/symengine-0.13.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3bce486fbc0b87970ed1b10ca9d5cafb1fd6b66382fe631261d83592851d7e", size = 89691094 }, + { url = "https://files.pythonhosted.org/packages/90/9f/5a171a9edff23eb0e33e0a2dca295a8b25fd64491ebe8cf765e489bd2bcd/symengine-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7e6bae9cfcdde2775d92fbb0abe3ef04e32f65ebc4c2d164ca33f4da202d4a7", size = 49584342 }, + { url = "https://files.pythonhosted.org/packages/07/16/a69dffc665e5007a0b4f1500fc401316aa070d109f83bc6887802dce199d/symengine-0.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:bced0a1dbdb94737c299384c85ddbad6944ce8dadc334f7bb8dbbd8f6c965807", size = 17787218 }, + { url = "https://files.pythonhosted.org/packages/f2/51/36ea8d87b61f34d585d09ff585cdc2ba136c501e0a96e861fe81fd0efa5b/symengine-0.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d34df77971538e4c29f2d8e5ef7f459c2179465e6cdb7dfd48b79b87ecd8f4d", size = 25838153 }, + { url = "https://files.pythonhosted.org/packages/2a/f7/73cd707633c01760df27d340ac2868788fa0a35034aa09f51f6a289d9a07/symengine-0.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ab2661d9b18867e7c6edbfa7a74b8b0a2a694bd24aa08003dc3214f77cb9d6f2", size = 22706111 }, + { url = "https://files.pythonhosted.org/packages/bc/e7/a1ddc4cc3f2604b18965342523cddd6160b6406d1ef21b58a2dea1c46312/symengine-0.13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53f27b9013878ee4419d8e853664d8ae4b68419e3f4b9b5b7f503d32bf904755", size = 60848269 }, + { url = "https://files.pythonhosted.org/packages/8a/f5/b127d236a8ccce8b85cec8bcb0221cbb6a4e651d6f5511da925e10714a4c/symengine-0.13.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:27987f75ce08c64f453e2b9b74fec6ffc5ca418c4deca0b75580979d4a4e242a", size = 89679345 }, + { url = "https://files.pythonhosted.org/packages/49/d0/b07c71dfb6f7f47f90495d67cb0b2264f94f2fb9380e528fe4fcec4c5cfa/symengine-0.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ea9410330ea15ed4137d7a0a3c43caccacb71490e18036ce5182d08c93baf8", size = 49582795 }, + { url = "https://files.pythonhosted.org/packages/de/c6/3ce562ec269b033a738b99aa75729d564bfe465a765a5b5810200924f5c9/symengine-0.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:5031eb7a5c6675d5195bb57f93cc7d9ac5a7a9a826d4ad6f6b2927746ed7e6e6", size = 17786679 }, + { url = "https://files.pythonhosted.org/packages/ca/0f/02031b4ed54fb088ade94082e4658160333c2d5c6629ca7e567ea5a23720/symengine-0.13.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ce0e5dfb19943bcf3e44a4485bcac4c5533ba3705c63083494eed0b3bf246076", size = 25795209 }, + { url = "https://files.pythonhosted.org/packages/34/c0/03e9e34a4e2af73dd786fb966ee3ad7ffa57659e79e4ac390be9e9f6aded/symengine-0.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c3b77dc54bf1181f6bd3b3338c4e6e5973a8b0fa20a189d15563ef5626e57b04", size = 22670484 }, + { url = "https://files.pythonhosted.org/packages/9d/13/66c8510403089ee157f0a8930a2e043e6f4de9ee514c8084adb958934058/symengine-0.13.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca7c3f6c168f6f5b06b421833c3d3baae56067a94b671bdffbe09b8e4fefd9be", size = 60739889 }, + { url = "https://files.pythonhosted.org/packages/70/fe/d0c778204d855257865e713fcbfef11dde34621e07fee439d4d117f43203/symengine-0.13.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:847523de682416811bacb3ad11507e663b3522fbb35cd27184757e9956d0eaf0", size = 89405899 }, + { url = "https://files.pythonhosted.org/packages/66/f6/f546e527caf35b7d0f14dbcea278134d4e46d7431821b9ca9f5ec3388a6a/symengine-0.13.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2fc1b7d96426463f0c9011e9fb88459d906477c1baa8a996dde6fb2bfa99d4", size = 49474632 }, +] + +[[package]] +name = "sympy" +version = "1.13.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/11/8a/5a7fd6284fa8caac23a26c9ddf9c30485a48169344b4bd3b0f02fef1890f/sympy-1.13.3.tar.gz", hash = "sha256:b27fd2c6530e0ab39e275fc9b683895367e51d5da91baa8d3d64db2565fec4d9", size = 7533196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/ff/c87e0622b1dadea79d2fb0b25ade9ed98954c9033722eb707053d310d4f3/sympy-1.13.3-py3-none-any.whl", hash = "sha256:54612cf55a62755ee71824ce692986f23c88ffa77207b30c1368eda4a7060f73", size = 6189483 }, +] + [[package]] name = "termcolor" version = "2.5.0" @@ -1933,6 +2198,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, ] +[[package]] +name = "websocket-client" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 }, +] + [[package]] name = "wheel" version = "0.45.1" From 46994ed6be77a9611d69ff5ec35c938ebc84a066 Mon Sep 17 00:00:00 2001 From: IraitzM Date: Fri, 7 Feb 2025 09:54:10 +0100 Subject: [PATCH 04/10] chore(no-hash): Remove hashes from requirements.txt --- .pre-commit-config.yaml | 3 +- requirements.txt | 489 ++++++---------------------------------- 2 files changed, 70 insertions(+), 422 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5bf4c27..64ec93e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,4 +31,5 @@ repos: # uv version. rev: 0.5.24 hooks: - - id: uv-export --no-hashes -o requirements.txt + - id: uv-export + args: ["--no-hashes", "--output-file=requirements.txt"] diff --git a/requirements.txt b/requirements.txt index cebcefa..9e217c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,423 +1,70 @@ # This file was autogenerated by uv via the following command: -# uv export --frozen --output-file=requirements.txt +# uv export --no-hashes -o requirements.txt -e . -appdirs==1.4.4 \ - --hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41 \ - --hash=sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128 -astunparse==1.6.3 \ - --hash=sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872 \ - --hash=sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8 -autograd==1.7.0 \ - --hash=sha256:49680300f842f3a8722b060ac0d3ed7aca071d1ad4d3d38c9fdadafdcc73c30b \ - --hash=sha256:de743fd368d6df523cd37305dcd171861a9752a144493677d2c9f5a56983ff2f -autoray==0.7.0 \ - --hash=sha256:03103957df3d1b66b8068158056c2909a72095b19d1b24262261276a714a5d07 \ - --hash=sha256:7829d21258512f87e02f23ce74ae5759af4ce8998069d2cce53468f1d701a219 -cachetools==5.5.1 \ - --hash=sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95 \ - --hash=sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb -certifi==2025.1.31 \ - --hash=sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651 \ - --hash=sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe -chardet==5.2.0 \ - --hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \ - --hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 -charset-normalizer==3.4.1 \ - --hash=sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd \ - --hash=sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601 \ - --hash=sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd \ - --hash=sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d \ - --hash=sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313 \ - --hash=sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd \ - --hash=sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa \ - --hash=sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8 \ - --hash=sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1 \ - --hash=sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2 \ - --hash=sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d \ - --hash=sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b \ - --hash=sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408 \ - --hash=sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3 \ - --hash=sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f \ - --hash=sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a \ - --hash=sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146 \ - --hash=sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6 \ - --hash=sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9 \ - --hash=sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f \ - --hash=sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545 \ - --hash=sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176 \ - --hash=sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b \ - --hash=sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f \ - --hash=sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b \ - --hash=sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9 \ - --hash=sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125 \ - --hash=sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de \ - --hash=sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11 \ - --hash=sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35 \ - --hash=sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f \ - --hash=sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda \ - --hash=sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a \ - --hash=sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971 \ - --hash=sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d \ - --hash=sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f \ - --hash=sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757 \ - --hash=sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a \ - --hash=sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886 \ - --hash=sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77 \ - --hash=sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76 \ - --hash=sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247 \ - --hash=sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85 \ - --hash=sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb \ - --hash=sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7 \ - --hash=sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037 \ - --hash=sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1 \ - --hash=sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807 \ - --hash=sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407 \ - --hash=sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12 \ - --hash=sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3 \ - --hash=sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd \ - --hash=sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00 \ - --hash=sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616 -colorama==0.4.6 \ - --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ - --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 -coverage==7.6.10 \ - --hash=sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9 \ - --hash=sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273 \ - --hash=sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994 \ - --hash=sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e \ - --hash=sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50 \ - --hash=sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e \ - --hash=sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e \ - --hash=sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c \ - --hash=sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853 \ - --hash=sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8 \ - --hash=sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8 \ - --hash=sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe \ - --hash=sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165 \ - --hash=sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb \ - --hash=sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609 \ - --hash=sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098 \ - --hash=sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd \ - --hash=sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3 \ - --hash=sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43 \ - --hash=sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d \ - --hash=sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359 \ - --hash=sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78 \ - --hash=sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99 \ - --hash=sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988 \ - --hash=sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2 \ - --hash=sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0 \ - --hash=sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694 \ - --hash=sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377 \ - --hash=sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23 \ - --hash=sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312 \ - --hash=sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf \ - --hash=sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6 \ - --hash=sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b \ - --hash=sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c \ - --hash=sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690 \ - --hash=sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a \ - --hash=sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f \ - --hash=sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd \ - --hash=sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852 \ - --hash=sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0 \ - --hash=sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244 \ - --hash=sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078 \ - --hash=sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0 \ - --hash=sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132 \ - --hash=sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5 \ - --hash=sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247 \ - --hash=sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022 \ - --hash=sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b \ - --hash=sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3 \ - --hash=sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18 \ - --hash=sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5 \ - --hash=sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f -diastatic-malt==2.15.2 \ - --hash=sha256:7eb90d8c30b7ff16b4e84c3a65de2ff7f5b7b9d0f5cdea23918e747ff7fb5320 \ - --hash=sha256:85429257b356030f101c31b2c7d506c4829f21bd865aed796766f900d7908407 -distlib==0.3.9 \ - --hash=sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87 \ - --hash=sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403 -filelock==3.17.0 \ - --hash=sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338 \ - --hash=sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e -gast==0.6.0 \ - --hash=sha256:52b182313f7330389f72b069ba00f174cfe2a06411099547288839c6cbafbd54 \ - --hash=sha256:88fc5300d32c7ac6ca7b515310862f71e6fdf2c029bbec7c66c0f5dd47b6b1fb -idna==3.10 \ - --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ - --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 -joblib==1.4.2 \ - --hash=sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6 \ - --hash=sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e -networkx==3.4.2 \ - --hash=sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1 \ - --hash=sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f -nose2==0.15.1 \ - --hash=sha256:36770f519df5becd3cbfe0bee4abbfbf9b9f6b4eb4e03361d282b7efcfc4f0df \ - --hash=sha256:564450c0c4f1602dfe171902ceb4726cc56658af7a620ae1826f1ffc86b09a86 -numpy==2.0.2 \ - --hash=sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a \ - --hash=sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195 \ - --hash=sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951 \ - --hash=sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc \ - --hash=sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd \ - --hash=sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318 \ - --hash=sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448 \ - --hash=sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece \ - --hash=sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5 \ - --hash=sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57 \ - --hash=sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78 \ - --hash=sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66 \ - --hash=sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a \ - --hash=sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e \ - --hash=sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c \ - --hash=sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97 \ - --hash=sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c \ - --hash=sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9 \ - --hash=sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669 \ - --hash=sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4 \ - --hash=sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8 \ - --hash=sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c \ - --hash=sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b \ - --hash=sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692 \ - --hash=sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15 \ - --hash=sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131 \ - --hash=sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a \ - --hash=sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326 \ - --hash=sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b \ - --hash=sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded \ - --hash=sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04 -packaging==24.2 \ - --hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \ - --hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f -pandas==2.2.3 \ - --hash=sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a \ - --hash=sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d \ - --hash=sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5 \ - --hash=sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4 \ - --hash=sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0 \ - --hash=sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32 \ - --hash=sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28 \ - --hash=sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f \ - --hash=sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348 \ - --hash=sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18 \ - --hash=sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468 \ - --hash=sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5 \ - --hash=sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667 \ - --hash=sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645 \ - --hash=sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13 \ - --hash=sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3 \ - --hash=sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d \ - --hash=sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb \ - --hash=sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3 \ - --hash=sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039 \ - --hash=sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8 \ - --hash=sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd \ - --hash=sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659 \ - --hash=sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57 \ - --hash=sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4 \ - --hash=sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a \ - --hash=sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9 \ - --hash=sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42 \ - --hash=sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2 \ - --hash=sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc \ - --hash=sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698 \ - --hash=sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed \ - --hash=sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015 \ - --hash=sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24 \ - --hash=sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319 -pennylane==0.40.0 \ - --hash=sha256:c93bb48ff80833edaf424b3b91e01a56cd25b22170bc99b7e53e7168a1ad4dd1 -pennylane-lightning==0.40.0 \ - --hash=sha256:20052041abc417d74d1794506d4340a8a2298b858e2b94591704e73670d913f9 \ - --hash=sha256:2ba97b4d6aa0a6eb774413ea3272d418959b792de6df8e4196171cad450f25af \ - --hash=sha256:3a6915cc17ce99cd4f3d04dcf7d579f59cecdc2866cd4e8e1c33478d86101437 \ - --hash=sha256:3d7715c84290fc1291e315d2c0d2bf5719cbe86e3e92fb538393ab130b3f5ba2 \ - --hash=sha256:3f75b7d39d63880e9d59562d78ae5ec63d2aed936b2feee3c937dfbcd080b834 \ - --hash=sha256:4a66e8c644f634f9d1fda6b9223f5cc106acf4146334a25a23f948ec59b075c0 \ - --hash=sha256:6b89ad785e16cc3b3d155b1abd27e42fcb5854a0e2d90452f6445fc0e80b1cf4 \ - --hash=sha256:7fe9262c602b6c7f0ab893468867e24c63e9cacc7d77e19b448ac1361bb86a47 \ - --hash=sha256:8a4ff3f1d82f664e6d608d155cb019b189aac676c6c7cb40c4f92b15e0d2d485 \ - --hash=sha256:96390ce82767b3a66c4f8e0b1bcec2f4f15fb317652cffa9815e371e74458197 \ - --hash=sha256:99cf7bcfb3a2a29838cc12f0001e3e7e02d35c5c1d696ce2e5ba0c3f2995c4d9 \ - --hash=sha256:a3db3cf2c3caed80ce561b66bb4bf6b5712ecf0b08db986f24c4ff9e187e82b3 \ - --hash=sha256:a58ab1489fee0424840bc8f91e8f7e32ecc3338a714b2fe1bf68a9026a5a295a \ - --hash=sha256:b2209727b8c914c8101087da188cbbc7b332bb77ceab4b6791c7ed7b3c5a942c \ - --hash=sha256:e3152f6b53390281334257554ecad90566cd4d200187971d238d2c7691000466 \ - --hash=sha256:edc95e75ef1b4e6dba96e914893175f9448d4d1b53a6e78614cb7587a8a22f2f \ - --hash=sha256:fed88008b7d468cb1d0e5b3ef92d87f9b600d0896d21eff43655a521cc841d7b -platformdirs==4.3.6 \ - --hash=sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907 \ - --hash=sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb -pluggy==1.5.0 \ - --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ - --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 -pyproject-api==1.9.0 \ - --hash=sha256:326df9d68dea22d9d98b5243c46e3ca3161b07a1b9b18e213d1e24fd0e605766 \ - --hash=sha256:7e8a9854b2dfb49454fae421cb86af43efbb2b2454e5646ffb7623540321ae6e -python-dateutil==2.9.0.post0 \ - --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ - --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 -pytz==2025.1 \ - --hash=sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57 \ - --hash=sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e -requests==2.32.3 \ - --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ - --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 -rustworkx==0.16.0 \ - --hash=sha256:040c4368729cf502f756a3b0ff5f1c6915fc389f74dcc6afc6c3833688c97c01 \ - --hash=sha256:0db3a73bf68b3e66c08322a2fc95d3aa663d037d9b4e49c3509da4898d3529cc \ - --hash=sha256:293180b83509ee9bff4c3af7ccc1024f6528d61b65d0cb7320bd31924f10cb71 \ - --hash=sha256:476a6c67b0142acd941691943750cc6737a48372304489969c2b62d30aaf4c27 \ - --hash=sha256:4f12a13d7486234fa2a84746d5e41f436bf9df43548043e7a232f48804ff8c61 \ - --hash=sha256:89efd5c3a4653ddacc55ca39f28b261d43deec7d678f8f8fc6b76b5087f1dfea \ - --hash=sha256:905df608843c32fa45ac023687769fe13056edf7584474c801d5c50705d76e9b \ - --hash=sha256:9f0dcb83f38d5ca2c3a683eb9b6951c8aec3262fbfe5141946a7ee5ba37e0bb6 \ - --hash=sha256:bef2ef42870f806af93979b457e240f6dfa4f867ca33965c620f3a804409ed3a \ - --hash=sha256:d650e39fc1a1534335f7517358ebfc3478bb235428463cfcd7c5750d50377b33 \ - --hash=sha256:ec0c12aac8c54910ace20ac6ada4b890cd39f95f69100514715f8ad7af9041e4 -scikit-learn==1.6.1 \ - --hash=sha256:0650e730afb87402baa88afbf31c07b84c98272622aaba002559b614600ca691 \ - --hash=sha256:0c8d036eb937dbb568c6242fa598d551d88fb4399c0344d95c001980ec1c7d36 \ - --hash=sha256:1061b7c028a8663fb9a1a1baf9317b64a257fcb036dae5c8752b2abef31d136f \ - --hash=sha256:25fc636bdaf1cc2f4a124a116312d837148b5e10872147bdaf4887926b8c03d8 \ - --hash=sha256:2c2cae262064e6a9b77eee1c8e768fc46aa0b8338c6a8297b9b6759720ec0ff2 \ - --hash=sha256:2e69fab4ebfc9c9b580a7a80111b43d214ab06250f8a7ef590a4edf72464dd86 \ - --hash=sha256:2ffa1e9e25b3d93990e74a4be2c2fc61ee5af85811562f1288d5d055880c4322 \ - --hash=sha256:3f59fe08dc03ea158605170eb52b22a105f238a5d512c4470ddeca71feae8e5f \ - --hash=sha256:6a7aa5f9908f0f28f4edaa6963c0a6183f1911e63a69aa03782f0d924c830a35 \ - --hash=sha256:70b1d7e85b1c96383f872a519b3375f92f14731e279a7b4c6cfd650cf5dffc52 \ - --hash=sha256:72abc587c75234935e97d09aa4913a82f7b03ee0b74111dcc2881cba3c5a7b33 \ - --hash=sha256:775da975a471c4f6f467725dff0ced5c7ac7bda5e9316b260225b48475279a1b \ - --hash=sha256:7a1c43c8ec9fde528d664d947dc4c0789be4077a3647f232869f41d9bf50e0fb \ - --hash=sha256:8634c4bd21a2a813e0a7e3900464e6d593162a29dd35d25bdf0103b3fce60ed5 \ - --hash=sha256:8a600c31592bd7dab31e1c61b9bbd6dea1b3433e67d264d17ce1017dbdce8002 \ - --hash=sha256:926f207c804104677af4857b2c609940b743d04c4c35ce0ddc8ff4f053cddc1b \ - --hash=sha256:a17c1dea1d56dcda2fac315712f3651a1fea86565b64b48fa1bc090249cbf236 \ - --hash=sha256:b3b00cdc8f1317b5f33191df1386c0befd16625f49d979fe77a8d44cae82410d \ - --hash=sha256:b4fc2525eca2c69a59260f583c56a7557c6ccdf8deafdba6e060f94c1c59738e \ - --hash=sha256:c06beb2e839ecc641366000ca84f3cf6fa9faa1777e29cf0c04be6e4d096a348 \ - --hash=sha256:d056391530ccd1e501056160e3c9673b4da4805eb67eb2bdf4e983e1f9c9204e \ - --hash=sha256:dc4765af3386811c3ca21638f63b9cf5ecf66261cc4815c1db3f1e7dc7b79db2 \ - --hash=sha256:dc5cf3d68c5a20ad6d571584c0750ec641cc46aeef1c1507be51300e6003a7e1 \ - --hash=sha256:e8ca8cb270fee8f1f76fa9bfd5c3507d60c6438bbee5687f81042e2bb98e5a97 \ - --hash=sha256:fa909b1a36e000a03c382aade0bd2063fd5680ff8b8e501660c0f59f021a6415 -scipy==1.15.1 \ - --hash=sha256:033a75ddad1463970c96a88063a1df87ccfddd526437136b6ee81ff0312ebdf6 \ - --hash=sha256:0458839c9f873062db69a03de9a9765ae2e694352c76a16be44f93ea45c28d2b \ - --hash=sha256:070d10654f0cb6abd295bc96c12656f948e623ec5f9a4eab0ddb1466c000716e \ - --hash=sha256:09c52320c42d7f5c7748b69e9f0389266fd4f82cf34c38485c14ee976cb8cb04 \ - --hash=sha256:0ac102ce99934b162914b1e4a6b94ca7da0f4058b6d6fd65b0cef330c0f3346f \ - --hash=sha256:0fb57b30f0017d4afa5fe5f5b150b8f807618819287c21cbe51130de7ccdaed2 \ - --hash=sha256:100193bb72fbff37dbd0bf14322314fc7cbe08b7ff3137f11a34d06dc0ee6b85 \ - --hash=sha256:14eaa373c89eaf553be73c3affb11ec6c37493b7eaaf31cf9ac5dffae700c2e0 \ - --hash=sha256:2114a08daec64980e4b4cbdf5bee90935af66d750146b1d2feb0d3ac30613692 \ - --hash=sha256:21e10b1dd56ce92fba3e786007322542361984f8463c6d37f6f25935a5a6ef52 \ - --hash=sha256:2722a021a7929d21168830790202a75dbb20b468a8133c74a2c0230c72626b6c \ - --hash=sha256:395be70220d1189756068b3173853029a013d8c8dd5fd3d1361d505b2aa58fa7 \ - --hash=sha256:3fe1d95944f9cf6ba77aa28b82dd6bb2a5b52f2026beb39ecf05304b8392864b \ - --hash=sha256:491d57fe89927fa1aafbe260f4cfa5ffa20ab9f1435025045a5315006a91b8f5 \ - --hash=sha256:4b17d4220df99bacb63065c76b0d1126d82bbf00167d1730019d2a30d6ae01ea \ - --hash=sha256:4c9d8fc81d6a3b6844235e6fd175ee1d4c060163905a2becce8e74cb0d7554ce \ - --hash=sha256:55cc79ce4085c702ac31e49b1e69b27ef41111f22beafb9b49fea67142b696c4 \ - --hash=sha256:5b190b935e7db569960b48840e5bef71dc513314cc4e79a1b7d14664f57fd4ff \ - --hash=sha256:5bd8d27d44e2c13d0c1124e6a556454f52cd3f704742985f6b09e75e163d20d2 \ - --hash=sha256:5dff14e75cdbcf07cdaa1c7707db6017d130f0af9ac41f6ce443a93318d6c6e0 \ - --hash=sha256:5eb0ca35d4b08e95da99a9f9c400dc9f6c21c424298a0ba876fdc69c7afacedf \ - --hash=sha256:63b9b6cd0333d0eb1a49de6f834e8aeaefe438df8f6372352084535ad095219e \ - --hash=sha256:667f950bf8b7c3a23b4199db24cb9bf7512e27e86d0e3813f015b74ec2c6e3df \ - --hash=sha256:6b3e71893c6687fc5e29208d518900c24ea372a862854c9888368c0b267387ab \ - --hash=sha256:71ba9a76c2390eca6e359be81a3e879614af3a71dfdabb96d1d7ab33da6f2364 \ - --hash=sha256:74bb864ff7640dea310a1377d8567dc2cb7599c26a79ca852fc184cc851954ac \ - --hash=sha256:82add84e8a9fb12af5c2c1a3a3f1cb51849d27a580cb9e6bd66226195142be6e \ - --hash=sha256:837299eec3d19b7e042923448d17d95a86e43941104d33f00da7e31a0f715d3c \ - --hash=sha256:900f3fa3db87257510f011c292a5779eb627043dd89731b9c461cd16ef76ab3d \ - --hash=sha256:9f151e9fb60fbf8e52426132f473221a49362091ce7a5e72f8aa41f8e0da4f25 \ - --hash=sha256:af0b61c1de46d0565b4b39c6417373304c1d4f5220004058bdad3061c9fa8a95 \ - --hash=sha256:bc7136626261ac1ed988dca56cfc4ab5180f75e0ee52e58f1e6aa74b5f3eacd5 \ - --hash=sha256:be3deeb32844c27599347faa077b359584ba96664c5c79d71a354b80a0ad0ce0 \ - --hash=sha256:c09aa9d90f3500ea4c9b393ee96f96b0ccb27f2f350d09a47f533293c78ea776 \ - --hash=sha256:c352c1b6d7cac452534517e022f8f7b8d139cd9f27e6fbd9f3cbd0bfd39f5bef \ - --hash=sha256:c64ded12dcab08afff9e805a67ff4480f5e69993310e093434b10e85dc9d43e1 \ - --hash=sha256:cdde8414154054763b42b74fe8ce89d7f3d17a7ac5dd77204f0e142cdc9239e9 \ - --hash=sha256:ce3a000cd28b4430426db2ca44d96636f701ed12e2b3ca1f2b1dd7abdd84b39a \ - --hash=sha256:f735bc41bd1c792c96bc426dece66c8723283695f02df61dcc4d0a707a42fc54 \ - --hash=sha256:f82fcf4e5b377f819542fbc8541f7b5fbcf1c0017d0df0bc22c781bf60abc4d8 -scipy-openblas32==0.3.29.0.0 \ - --hash=sha256:02d32eafdf101f9503b99bd623e84f109a95cbe16d65492e174ed386339e2e1f \ - --hash=sha256:2ca3ee3b9143b86addccda36a741462621413766dbc09896b0b43cc223a3b051 \ - --hash=sha256:33994f0a37373ff6717fd9c948053a76c272efd516f8b33b3e51ecec786922fe \ - --hash=sha256:6b276ac72c00cc0850588663b9da4c8099d4bee8a2527557747cf6b8ed5179cb \ - --hash=sha256:768352307e56873538222526b7dbcfd3dcd8615451741d15eef9af718ac93750 \ - --hash=sha256:8b21c803bdc344a383a1d5d392d3cfe5366d9b89d2aeee963705156000cbbc7a \ - --hash=sha256:9d6301960024370f6061c71e8efd8bcb5be22c6526a529ff05c370048adb6b04 \ - --hash=sha256:dd74159091a83ae7bf7b066345c3d3e43e212cd4537c03a2fd873154e5a179f2 \ - --hash=sha256:e56c9c8e5e41d91d357b0d514fc59ca25467fbd68e5bdffa1f3dfa96f3249eb2 -six==1.17.0 \ - --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ - --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 -termcolor==2.5.0 \ - --hash=sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8 \ - --hash=sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f -threadpoolctl==3.5.0 \ - --hash=sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107 \ - --hash=sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467 -tomli==2.2.1 ; python_full_version < '3.11' \ - --hash=sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6 \ - --hash=sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd \ - --hash=sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c \ - --hash=sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b \ - --hash=sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8 \ - --hash=sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6 \ - --hash=sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77 \ - --hash=sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff \ - --hash=sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea \ - --hash=sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192 \ - --hash=sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249 \ - --hash=sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee \ - --hash=sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4 \ - --hash=sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98 \ - --hash=sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8 \ - --hash=sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4 \ - --hash=sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281 \ - --hash=sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744 \ - --hash=sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69 \ - --hash=sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13 \ - --hash=sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140 \ - --hash=sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e \ - --hash=sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e \ - --hash=sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc \ - --hash=sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff \ - --hash=sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec \ - --hash=sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2 \ - --hash=sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222 \ - --hash=sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106 \ - --hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \ - --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \ - --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7 -tomlkit==0.13.2 \ - --hash=sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde \ - --hash=sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79 -tox==4.24.1 \ - --hash=sha256:083a720adbc6166fff0b7d1df9d154f9d00bfccb9403b8abf6bc0ee435d6a62e \ - --hash=sha256:57ba7df7d199002c6df8c2db9e6484f3de6ca8f42013c083ea2d4d1e5c6bdc75 -tox-pdm==0.7.2 \ - --hash=sha256:12f6215416b7acd00a80a9e7128f3dc3e3c89308d60707f5d0a24abdf83ac104 \ - --hash=sha256:a841a7e1e942a71805624703b9a6d286663bd6af79bba6130ba756975c315308 -typing-extensions==4.12.2 \ - --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ - --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 -tzdata==2025.1 \ - --hash=sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694 \ - --hash=sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639 -urllib3==2.3.0 \ - --hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \ - --hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d -virtualenv==20.29.1 \ - --hash=sha256:4e4cb403c0b0da39e13b46b1b2476e505cb0046b25f242bee80f62bf990b2779 \ - --hash=sha256:b8b8970138d32fb606192cb97f6cd4bb644fa486be9308fb9b63f81091b5dc35 -wheel==0.45.1 \ - --hash=sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729 \ - --hash=sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248 +annotated-types==0.7.0 +appdirs==1.4.4 +astunparse==1.6.3 +autograd==1.7.0 +autoray==0.7.0 +cachetools==5.5.1 +certifi==2025.1.31 +cffi==1.17.1 ; platform_python_implementation != 'PyPy' +chardet==5.2.0 +charset-normalizer==3.4.1 +colorama==0.4.6 +coverage==7.6.10 +cryptography==44.0.0 +diastatic-malt==2.15.2 +dill==0.3.9 +distlib==0.3.9 +filelock==3.17.0 +gast==0.6.0 +ibm-cloud-sdk-core==3.22.1 +ibm-platform-services==0.59.1 +idna==3.10 +joblib==1.4.2 +mpmath==1.3.0 +networkx==3.4.2 +nose2==0.15.1 +numpy==2.0.2 +packaging==24.2 +pandas==2.2.3 +pbr==6.1.1 +pennylane==0.40.0 +pennylane-lightning==0.40.0 +platformdirs==4.3.6 +pluggy==1.5.0 +pycparser==2.22 ; platform_python_implementation != 'PyPy' +pydantic==2.9.2 +pydantic-core==2.23.4 +pyjwt==2.10.1 +pyproject-api==1.9.0 +pyspnego==0.11.2 +python-dateutil==2.9.0.post0 +pytz==2025.1 +qiskit==1.3.2 +qiskit-ibm-runtime==0.35.0 +requests==2.32.3 +requests-ntlm==1.3.0 +rustworkx==0.16.0 +scikit-learn==1.6.1 +scipy==1.15.1 +scipy-openblas32==0.3.29.0.0 +setuptools==75.8.0 +six==1.17.0 +sspilib==0.2.0 ; sys_platform == 'win32' +stevedore==5.4.0 +symengine==0.13.0 +sympy==1.13.3 +termcolor==2.5.0 +threadpoolctl==3.5.0 +tomli==2.2.1 ; python_full_version < '3.11' +tomlkit==0.13.2 +tox==4.24.1 +tox-pdm==0.7.2 +typing-extensions==4.12.2 +tzdata==2025.1 +urllib3==2.3.0 +virtualenv==20.29.1 +websocket-client==1.8.0 +wheel==0.45.1 From 1e39940dd8dfc8a38ff5b3c4f7e209158349215d Mon Sep 17 00:00:00 2001 From: IraitzM Date: Fri, 7 Feb 2025 10:06:18 +0100 Subject: [PATCH 05/10] fix(tests): Fixed and 59% coverage achieved. --- src/quask/core/ansatz.py | 34 +++++++++------- tests/test_pennylane_kernel.py | 73 +++++++++++++++++----------------- 2 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/quask/core/ansatz.py b/src/quask/core/ansatz.py index 0ed1534..3312a9b 100644 --- a/src/quask/core/ansatz.py +++ b/src/quask/core/ansatz.py @@ -83,7 +83,8 @@ def change_generators(self, operation_index: int, new_generator: str): self.operation_list[operation_index].generator = new_generator def change_feature(self, operation_index: int, new_feature: int): - """Overwrite the operation at the given index with a new feature + """Overwrite the operation at the given index with a new feature. + :param operation_index: index of the operation :param new_feature: feature parameterizing the operation :return: None @@ -97,7 +98,8 @@ def change_feature(self, operation_index: int, new_feature: int): self.operation_list[operation_index].feature = new_feature def change_wires(self, operation_index: int, new_wires: list[int]): - """Overwrite the operation at the given index with a new pair of wires + """Overwrite the operation at the given index with a new pair of wires. + :param operation_index: index of the operation :param new_wires: wires on which the operation is applied :return: None @@ -119,8 +121,10 @@ def change_wires(self, operation_index: int, new_wires: list[int]): ) self.operation_list[operation_index].wires = new_wires - def get_allowed_operations(self): - """Get the list of allowed operation for the ansatz, either only the PAULI_GENERATORS or any operation including measurements + def get_allowed_operations(self) -> list: + """Get the list of allowed operation for the ansatz, either + only the PAULI_GENERATORS or any operation including measurements. + :return: list of allowed operations """ if self.allow_midcircuit_measurement: @@ -129,7 +133,8 @@ def get_allowed_operations(self): return Operation.PAULI_GENERATORS def initialize_to_identity(self): - """Initialize the ansatz to the identity circuit + """Initialize the ansatz to the identity circuit. + :return: None """ self.operation_list = [None] * self.n_operations @@ -139,7 +144,8 @@ def initialize_to_identity(self): ) def initialize_to_random_circuit(self): - """Initialize the ansatz to a random circuit + """Initialize the ansatz to a random circuit. + :return: None """ for i in range(self.n_operations): @@ -154,7 +160,7 @@ def initialize_to_random_circuit(self): ) def initialize_to_known_ansatz(self, ansatz): - """Initialize the ansatz form an already given element + """Initialize the ansatz form an already given element. :param ansatz: Given ansatz :return: None @@ -167,7 +173,8 @@ def initialize_to_known_ansatz(self, ansatz): ) def to_numpy(self): - """Serialize the ansatz to a numpy array + """Serialize the ansatz to a numpy array. + :return: numpy array """ return np.array([op.to_numpy() for op in self.operation_list]).ravel() @@ -184,10 +191,11 @@ def from_numpy( """Deserialize the ansatz from a numpy array. :param array: numpy array - :param n_features: number of feature that can be used to parametrize the operation + :param n_features: number of feature that can be used to parametrize + the operation :param n_qubits: number of qubits of the circuit :param n_operations: number of operations - :param allow_midcircuit_measurement: True if mid-circuit measurement are allowed + :param allow_midcircuit_measurement: True if mid-circuit measurement allowed :return: Ansatz deserialized """ ans = Ansatz( @@ -211,11 +219,9 @@ def from_numpy( return ans def __str__(self): - """Gets the function string. - - :return: str: _description_ - """ + """__str__.""" return str(self.operation_list) def __repr__(self): + """__repr__""" return self.__str__() diff --git a/tests/test_pennylane_kernel.py b/tests/test_pennylane_kernel.py index beedf32..641e104 100644 --- a/tests/test_pennylane_kernel.py +++ b/tests/test_pennylane_kernel.py @@ -2,6 +2,7 @@ import unittest import numpy as np + from quask.core import Ansatz, Kernel, KernelType from quask.core_implementation import PennylaneKernel @@ -16,7 +17,7 @@ def test_static_single_qubit(self): ansatz = Ansatz(n_features=1, n_qubits=2, n_operations=1) ansatz.initialize_to_identity() ansatz.change_generators(0, "XI") - ansatz.change_feature(0, -1) + #ansatz.change_feature(0, -1) ansatz.change_wires(0, [0, 1]) ansatz.change_bandwidth(0, 1) @@ -38,8 +39,7 @@ def test_static_single_qubit(self): assert np.allclose( kernel.get_last_probabilities(), np.array([0.5, 0.5]) ), f"Incorrect measurement: {kernel.get_last_probabilities()}" - print(x) - assert np.isclose(x, 0), "Incorrect observable" + assert np.isclose(x, 0.0), "Incorrect observable" # measurement operation # <1|Y|1> = <1HSdag|Z|SdagH1> = @@ -51,8 +51,7 @@ def test_static_single_qubit(self): assert np.allclose( kernel.get_last_probabilities(), np.array([0.5, 0.5]) ), f"Incorrect measurement: {kernel.get_last_probabilities()}" - assert np.isclose(x, 0), "Incorrect observable" - + assert np.isclose(x, 0.0), "Incorrect observable" def test_static_two_qubit(self): """Two qubit case.""" @@ -70,18 +69,17 @@ def test_static_two_qubit(self): assert np.allclose( kernel.get_last_probabilities(), np.array([0.5, 0.0, 0.0, 0.5]) ), "Incorrect measurement" - assert np.isclose(x, 0), "Incorrect observable" + np.testing.assert_almost_equal(x, 1.0, decimal=6, err_msg="Incorrect observable") def _check_kernel_value(self, kernel: Kernel, x1: float, x2: float, expected: float): similarity = kernel.kappa(x1, x2) - print(similarity, expected) assert np.isclose(similarity, expected), ( f"Kernel value is {similarity:0.3f} while {expected:0.3f} was expected" ) - def check_kernel_rx_value(kernel: Kernel, x1: float, x2: float): + def _check_kernel_rx_value(self, kernel: Kernel, x1: float, x2: float): def rx(theta): return np.array( [ @@ -93,11 +91,12 @@ def rx(theta): ket_zero = np.array([[1], [0]]) ket_phi = np.linalg.inv(rx(x2)) @ rx(x1) @ ket_zero expected_similarity = (np.abs(ket_phi[0]) ** 2).real - check_kernel_value( + self._check_kernel_value( kernel, np.array([x1]), np.array([x2]), expected_similarity ) - def test_rx_kernel_fidelity(): + def test_rx_kernel_fidelity(self): + """Test Rx kernel fidelity.""" ansatz = Ansatz( n_features=1, n_qubits=2, @@ -120,21 +119,21 @@ def test_rx_kernel_fidelity(): n_shots=None, ) - check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) - - check_kernel_rx_value(kernel, 0.00, 0.00) - check_kernel_rx_value(kernel, 0.33, 0.33) - check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) - check_kernel_rx_value(kernel, np.pi, np.pi) - check_kernel_rx_value(kernel, 0, np.pi) - check_kernel_rx_value(kernel, 0.33, np.pi) - check_kernel_rx_value(kernel, np.pi / 2, np.pi) - check_kernel_rx_value(kernel, 0, 0.55) - check_kernel_rx_value(kernel, 0.33, 0.55) - check_kernel_rx_value(kernel, np.pi / 2, 0.55) - - - def test_rx_kernel_fidelity(): + self._check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) + + self._check_kernel_rx_value(kernel, 0.00, 0.00) + self._check_kernel_rx_value(kernel, 0.33, 0.33) + self._check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) + self._check_kernel_rx_value(kernel, np.pi, np.pi) + self._check_kernel_rx_value(kernel, 0, np.pi) + self._check_kernel_rx_value(kernel, 0.33, np.pi) + self._check_kernel_rx_value(kernel, np.pi / 2, np.pi) + self._check_kernel_rx_value(kernel, 0, 0.55) + self._check_kernel_rx_value(kernel, 0.33, 0.55) + self._check_kernel_rx_value(kernel, np.pi / 2, 0.55) + + def test_rx_kernel_fidelity_2(self): + """Test Rx kernel fidelity.""" ansatz = Ansatz( n_features=1, n_qubits=2, @@ -157,15 +156,15 @@ def test_rx_kernel_fidelity(): n_shots=None, ) - check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) - - check_kernel_rx_value(kernel, 0.00, 0.00) - check_kernel_rx_value(kernel, 0.33, 0.33) - check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) - check_kernel_rx_value(kernel, np.pi, np.pi) - check_kernel_rx_value(kernel, 0, np.pi) - check_kernel_rx_value(kernel, 0.33, np.pi) - check_kernel_rx_value(kernel, np.pi / 2, np.pi) - check_kernel_rx_value(kernel, 0, 0.55) - check_kernel_rx_value(kernel, 0.33, 0.55) - check_kernel_rx_value(kernel, np.pi / 2, 0.55) + self._check_kernel_value(kernel, np.array([0.33]), np.array([0.33]), 1.0) + + self._check_kernel_rx_value(kernel, 0.00, 0.00) + self._check_kernel_rx_value(kernel, 0.33, 0.33) + self._check_kernel_rx_value(kernel, np.pi / 2, np.pi / 2) + self._check_kernel_rx_value(kernel, np.pi, np.pi) + self._check_kernel_rx_value(kernel, 0, np.pi) + self._check_kernel_rx_value(kernel, 0.33, np.pi) + self._check_kernel_rx_value(kernel, np.pi / 2, np.pi) + self._check_kernel_rx_value(kernel, 0, 0.55) + self._check_kernel_rx_value(kernel, 0.33, 0.55) + self._check_kernel_rx_value(kernel, np.pi / 2, 0.55) From 77acac5220a69e2ecdeaffcfa5aa44349c7dd397 Mon Sep 17 00:00:00 2001 From: IraitzM Date: Fri, 7 Feb 2025 12:46:42 +0100 Subject: [PATCH 06/10] fix(dependencies): Circular dependencies found. --- .github/workflows/main.yml | 28 + .gitignore | 3 + .python-version | 2 +- README.md | 3 + docs/source/notebooks/getting_started.ipynb | 541 +++++- docs/source/notebooks/quantum_0_intro.ipynb | 93 +- .../notebooks/quantum_1_expressibility.ipynb | 53 +- .../notebooks/quantum_2_projected.ipynb | 78 +- .../notebooks/quantum_2_projected_1.ipynb | 700 ------- docs/source/notebooks/quask_0_backends.ipynb | 57 +- .../source/notebooks/quask_1_evaluators.ipynb | 28 +- pdm.lock | 1608 +++++++++++++++++ pyproject.toml | 16 +- src/quask/__init__.py | 1 + src/quask/core/kernel.py | 4 +- src/quask/core/kernel_factory.py | 18 +- .../core_implementation/qiskit_kernel.py | 43 +- src/quask/evaluator/__init__.py | 9 +- .../centered_kernel_alignment_evaluator.py | 19 +- .../evaluator/covering_number_evaluator.py | 15 +- .../ess_model_complexity_evaluator.py | 23 +- .../geometric_difference_evaluator.py | 19 +- src/quask/evaluator/haar_evaluator.py | 32 +- .../evaluator/kernel_alignment_evaluator.py | 15 +- src/quask/evaluator/kernel_evaluator.py | 7 +- src/quask/evaluator/lie_rank_evaluator.py | 30 +- .../ridge_generalization_evaluator.py | 13 +- .../evaluator/spectral_bias_evaluator.py | 49 +- uv.lock | 361 +++- 29 files changed, 2788 insertions(+), 1080 deletions(-) create mode 100644 .github/workflows/main.yml delete mode 100644 docs/source/notebooks/quantum_2_projected_1.ipynb create mode 100644 pdm.lock diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..82387b6 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,28 @@ +name: Quality assurance + +on: + push: + branches: + - main + +jobs: + build: + name: continuous-integration + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - "3.11" + + steps: + - uses: actions/checkout@v4 + + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install the project + run: uv sync --all-extras --dev + + - uses: eosc-synergy/sqaaas-assessment-action@v2 diff --git a/.gitignore b/.gitignore index 6101582..3190e5a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ *.pyc dist/* build/* +*.egg-info docs/build/* +*/__pycache__/* docs/source/notebooks/.ipynb_checkpoints/* src/quask/__pycache__/* src/quask/core/__pycache__/* @@ -24,6 +26,7 @@ src/quask/optimizer/__pycache__/* # PDM .pdm-build +.pdm-python # Coverage .coverage diff --git a/.python-version b/.python-version index e4fba21..2c07333 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.12 +3.11 diff --git a/README.md b/README.md index e7b44cd..046b4bc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![SQAaaS badge shields.io](https://github.com/EOSC-synergy/quask.assess.sqaaas/raw/master/.badge/status_shields.svg)](https://sqaaas.eosc-synergy.eu/#/full-assessment/report/https://raw.githubusercontent.com/eosc-synergy/quask.assess.sqaaas/master/.report/assessment_output.json) + + # Quantum Advantage Seeker with Kernels (QuASK) QuASK is an actively maintained library for constructing, studying, and benchmarking quantum kernel methods. diff --git a/docs/source/notebooks/getting_started.ipynb b/docs/source/notebooks/getting_started.ipynb index 99c5b87..4a9a4ab 100644 --- a/docs/source/notebooks/getting_started.ipynb +++ b/docs/source/notebooks/getting_started.ipynb @@ -8,19 +8,6 @@ "# Getting started" ] }, - { - "cell_type": "code", - "execution_count": 1, - "id": "f463bcd7-dc70-44fb-8695-2399fe4c925c", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import os\n", - "# to import quask, move from docs/source/notebooks to src\n", - "sys.path.append('../../../src')" - ] - }, { "cell_type": "markdown", "id": "00653702-d41a-41e8-a813-4f9c9b9aed1c", @@ -50,37 +37,11 @@ "source": [ "## Fast installation\n", "\n", - "The easiest way to use _quask_ is by installing it in your Python3 environment (version >= 3.10) via the _pip_ packet manager," - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2de250b-692b-467b-8bbe-6b555eb151e2", - "metadata": {}, - "outputs": [], - "source": [ - "!python3 -m pip install quask==2.0.0-alpha1" - ] - }, - { - "cell_type": "markdown", - "id": "9b9e49a5-5610-47e8-a04c-fed81151d1a7", - "metadata": {}, - "source": [ - "You also need any quantum SDK installed on your system. For example, we can install Qiskit. For more information about the installation process, you can see [the Installation section](installation.html). " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "52b381e9-3a03-4870-a5cc-47685791e3cd", - "metadata": {}, - "outputs": [], - "source": [ - "!python3 -m pip install qiskit qiskit_ibm_runtime\n", - "!python3 -m pip install qiskit_ibm_runtime --upgrade\n", - "!python3 -m pip install qiskit-aer" + "The easiest way to use _quask_ is by installing it in your Python3 environment (version >= 3.10) via the _pip_ packet manager,\n", + "\n", + "```py\n", + "!python3 -m pip install quask==2.0.0-alpha2\n", + "```" ] }, { @@ -88,17 +49,26 @@ "id": "8ad60ede-fcb9-44ad-859f-15a03b045091", "metadata": {}, "source": [ - "You can check if the installation has been successful by running the command:" + "Quask will also include some extra dependencies like Qiskit or Pennylane. You can check if the installation has been successful by running the command:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "ab3dc1db-c3ec-41d3-be46-7d9ccafe4b6f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.0.0-alpha2\n" + ] + } + ], "source": [ "import quask\n", + "\n", "print(quask.__version__)" ] }, @@ -120,13 +90,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "id": "8558acef-bd9e-465a-a042-43f951474b9f", "metadata": {}, "outputs": [], "source": [ - "from quask.core import Ansatz, Kernel, KernelFactory, KernelType\n", - "import numpy as np" + "import numpy as np\n", + "\n", + "from quask.core import Ansatz, KernelFactory, KernelType" ] }, { @@ -143,7 +114,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 3, "id": "1e8e3d9d-9b2d-47ff-b794-e8b93b6de691", "metadata": {}, "outputs": [], @@ -171,7 +142,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 4, "id": "b8ff120f-fad9-4f25-9789-ca1cc5f5dc0d", "metadata": {}, "outputs": [], @@ -198,7 +169,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 5, "id": "bf968d0d-eb19-4397-b868-1ae541c83dbc", "metadata": {}, "outputs": [], @@ -218,12 +189,13 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 6, "id": "07a93cfe-43a8-42fa-9fc8-ab1088a420e9", "metadata": {}, "outputs": [], "source": [ "from quask.core_implementation import QiskitKernel\n", + "\n", "kernel = QiskitKernel(ansatz, \"Z\" * N_QUBITS, KernelType.FIDELITY)" ] }, @@ -237,7 +209,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 7, "id": "814ee677-5dd0-400f-b9d0-3e6eaae1d357", "metadata": {}, "outputs": [ @@ -245,7 +217,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "The kernel value between x1 and x2 is 0.39697265625\n" + "The kernel value between x1 and x2 is 0.82470703125\n" ] } ], @@ -274,13 +246,13 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 8, "id": "d177df5e-8218-47cc-94b8-2184181b06bd", "metadata": {}, "outputs": [], "source": [ "def create_qiskit_noiseless(ansatz: Ansatz, measurement: str, type: KernelType):\n", - " return QiskitKernel(ansatz, measurement, type, n_shots=None)\n", + " return QiskitKernel(ansatz, measurement, type, platform = \"infty_shots\")\n", "\n", "# if you have already added the implementation comment the line below and set the current implementation\n", "KernelFactory.add_implementation('qiskit_noiseless', create_qiskit_noiseless)\n", @@ -298,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 9, "id": "c82fabc9", "metadata": {}, "outputs": [ @@ -306,7 +278,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "The kernel value between x1 and x2 is 0.3881526107367118\n" + "The kernel value between x1 and x2 is 0.9008382065994768\n" ] } ], @@ -335,14 +307,13 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 10, "id": "0eda078b-a07a-463a-99c7-fdb1a888ac78", "metadata": {}, "outputs": [], "source": [ "from sklearn.datasets import load_iris\n", "from sklearn.svm import SVC\n", - "from sklearn.metrics import mean_squared_error, r2_score\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.preprocessing import StandardScaler\n", "import numpy as np" @@ -362,14 +333,14 @@ }, { "cell_type": "code", - "execution_count": 134, + "execution_count": 11, "id": "04903893-8c56-495b-b7e3-c866e2221533", "metadata": {}, "outputs": [], "source": [ "N_ELEMENTS_PER_CLASS = 10\n", "iris = load_iris()\n", - "X = np.row_stack([iris.data[0:N_ELEMENTS_PER_CLASS], iris.data[50:50+N_ELEMENTS_PER_CLASS]])\n", + "X = np.vstack([iris.data[0:N_ELEMENTS_PER_CLASS], iris.data[50:50+N_ELEMENTS_PER_CLASS]])\n", "y = np.array([0] * N_ELEMENTS_PER_CLASS + [1] * N_ELEMENTS_PER_CLASS)" ] }, @@ -383,7 +354,7 @@ }, { "cell_type": "code", - "execution_count": 135, + "execution_count": 12, "id": "c8860146-d5d5-4b2d-90e0-d5f77e342578", "metadata": {}, "outputs": [], @@ -406,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 13, "id": "8269657d-cc87-457e-bcd3-8c799be57dcd", "metadata": {}, "outputs": [], @@ -425,20 +396,435 @@ }, { "cell_type": "code", - "execution_count": 137, + "execution_count": 14, "id": "a739941b-20fb-402b-936f-44e7b8758e2f", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
    SVC(kernel='precomputed')
    In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
    On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
    " + "
    " ], "text/plain": [ "SVC(kernel='precomputed')" ] }, - "execution_count": 137, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -470,7 +856,7 @@ }, { "cell_type": "code", - "execution_count": 138, + "execution_count": 15, "id": "8d31ead9-007d-48a6-869f-757e5149ca85", "metadata": {}, "outputs": [], @@ -490,7 +876,7 @@ }, { "cell_type": "code", - "execution_count": 139, + "execution_count": 16, "id": "6b8ff0e5-d8ca-4a9e-b724-64df7e17f6be", "metadata": {}, "outputs": [ @@ -498,7 +884,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: 0.7\n" + "Accuracy: 0.9\n" ] } ], @@ -518,7 +904,7 @@ }, { "cell_type": "code", - "execution_count": 141, + "execution_count": 17, "id": "4995cefe-2b79-405a-8371-e82f9bcfcad7", "metadata": {}, "outputs": [ @@ -526,13 +912,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "The cost for training kernel according to the Centered-KTA is: -0.12288156059347581\n", - "The cost for testing kernel according to the Centered-KTA is: -0.07224213757570128\n" + "The cost for training kernel according to the Centered-KTA is: -0.26109096985312397\n", + "The cost for testing kernel according to the Centered-KTA is: -0.1688507888426581\n" ] } ], "source": [ "from quask.evaluator import CenteredKernelAlignmentEvaluator\n", + "\n", "ce = CenteredKernelAlignmentEvaluator()\n", "cost_tr = ce.evaluate(None, K_train, X_train, y_train)\n", "cost_te = ce.evaluate(None, K_test, X_test, y_test)\n", @@ -543,7 +930,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -557,7 +944,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.0" + "version": "3.11.11+" } }, "nbformat": 4, diff --git a/docs/source/notebooks/quantum_0_intro.ipynb b/docs/source/notebooks/quantum_0_intro.ipynb index 05c61af..e799bb3 100644 --- a/docs/source/notebooks/quantum_0_intro.ipynb +++ b/docs/source/notebooks/quantum_0_intro.ipynb @@ -8,20 +8,6 @@ "# Quantum kernels " ] }, - { - "cell_type": "code", - "execution_count": 1, - "id": "e3376f7a-c399-4248-9f74-750271325dd0", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import os\n", - "# to import quask, move from docs/source/notebooks to src\n", - "sys.path.append('../../../src')\n", - "import quask" - ] - }, { "cell_type": "markdown", "id": "ae7056d4-25b3-491b-9abf-69f72155668d", @@ -103,7 +89,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 3, "id": "235a0487-ad2d-40e8-a02f-d4752bdaef73", "metadata": {}, "outputs": [ @@ -111,7 +97,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "-i 0.99 * x[2] YZ^(1,0)\n" + "-i 0.61 * x[0] YX^(0,1)\n" ] } ], @@ -160,6 +146,7 @@ "outputs": [], "source": [ "from quask.core import Ansatz\n", + "\n", "N_FEATURES = 2\n", "N_OPERATIONS = 3\n", "N_QUBITS = 2\n", @@ -281,40 +268,40 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "05c6337b-92eb-40ba-929d-ca5d25d7bc16", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
    global phase: π/4\n",
    -       "        ┌──────────┐  ┌─────────┐┌─────────┐┌───────────┐  ┌─────────┐  »\n",
    -       "q0_0: ──┤ Rz(3π/4) ├──┤ Rx(π/2) ├┤ Rz(π/2) ├┤0          ├──┤ Rz(π/2) ├──»\n",
    -       "      ┌─┴──────────┴─┐└┬────────┤└─────────┘│  Rxx(π/2) │┌─┴─────────┴─┐»\n",
    -       "q0_1: ┤ Rx(-0.24498) ├─┤ Rz(-π) ├───────────┤1          ├┤ Rx(-1.8158) ├»\n",
    -       "      └──────────────┘ └────────┘           └───────────┘└─────────────┘»\n",
    -       "«      ┌─────────┐┌──────────┐\n",
    -       "«q0_0: ┤ Rx(π/2) ├┤ Rz(3π/4) ├\n",
    -       "«      └┬────────┤└──────────┘\n",
    -       "«q0_1: ─┤ Rz(-π) ├────────────\n",
    -       "«       └────────┘            
    " + "
    global phase: 3π/4\n",
    +       "      ┌──────────┐ ┌─────────┐┌─────────┐┌───────────┐  ┌─────────┐  »\n",
    +       "q_0: ─┤ Rz(3π/4) ├─┤ Rx(π/2) ├┤ Rz(π/2) ├┤0          ├──┤ Rz(π/2) ├──»\n",
    +       "     ┌┴──────────┴┐└─────────┘└─────────┘│  Rxx(π/2) │┌─┴─────────┴─┐»\n",
    +       "q_1: ┤ Rx(1.3468) ├──────────────────────┤1          ├┤ Rx(-2.9176) ├»\n",
    +       "     └────────────┘                      └───────────┘└─────────────┘»\n",
    +       "«     ┌─────────┐┌──────────┐\n",
    +       "«q_0: ┤ Rx(π/2) ├┤ Rz(-π/4) ├\n",
    +       "«     └─────────┘└──────────┘\n",
    +       "«q_1: ───────────────────────\n",
    +       "«                            
    " ], "text/plain": [ - "global phase: π/4\n", - " ┌──────────┐ ┌─────────┐┌─────────┐┌───────────┐ ┌─────────┐ »\n", - "q0_0: ──┤ Rz(3π/4) ├──┤ Rx(π/2) ├┤ Rz(π/2) ├┤0 ├──┤ Rz(π/2) ├──»\n", - " ┌─┴──────────┴─┐└┬────────┤└─────────┘│ Rxx(π/2) │┌─┴─────────┴─┐»\n", - "q0_1: ┤ Rx(-0.24498) ├─┤ Rz(-π) ├───────────┤1 ├┤ Rx(-1.8158) ├»\n", - " └──────────────┘ └────────┘ └───────────┘└─────────────┘»\n", - "« ┌─────────┐┌──────────┐\n", - "«q0_0: ┤ Rx(π/2) ├┤ Rz(3π/4) ├\n", - "« └┬────────┤└──────────┘\n", - "«q0_1: ─┤ Rz(-π) ├────────────\n", - "« └────────┘ " + "global phase: 3π/4\n", + " ┌──────────┐ ┌─────────┐┌─────────┐┌───────────┐ ┌─────────┐ »\n", + "q_0: ─┤ Rz(3π/4) ├─┤ Rx(π/2) ├┤ Rz(π/2) ├┤0 ├──┤ Rz(π/2) ├──»\n", + " ┌┴──────────┴┐└─────────┘└─────────┘│ Rxx(π/2) │┌─┴─────────┴─┐»\n", + "q_1: ┤ Rx(1.3468) ├──────────────────────┤1 ├┤ Rx(-2.9176) ├»\n", + " └────────────┘ └───────────┘└─────────────┘»\n", + "« ┌─────────┐┌──────────┐\n", + "«q_0: ┤ Rx(π/2) ├┤ Rz(-π/4) ├\n", + "« └─────────┘└──────────┘\n", + "«q_1: ───────────────────────\n", + "« " ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -322,7 +309,7 @@ "source": [ "import numpy as np \n", "from qiskit.circuit.library import CXGate, RXXGate\n", - "from qiskit.quantum_info.synthesis import TwoQubitBasisDecomposer\n", + "from qiskit.synthesis import TwoQubitBasisDecomposer\n", "\n", "decomposer = TwoQubitBasisDecomposer(RXXGate(np.pi / 2), basis_fidelity = 1.0, euler_basis='ZXZ')\n", "circ = decomposer(CXGate().to_matrix())\n", @@ -365,7 +352,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "cae73dda-0a7d-4976-87c3-bf9740aad059", "metadata": {}, "outputs": [], @@ -395,7 +382,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "6d1703ea-50e7-44b5-9964-8177d92ad7d7", "metadata": {}, "outputs": [], @@ -414,7 +401,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "9ed237e3-c435-4b42-980a-e1a8f076fb83", "metadata": {}, "outputs": [], @@ -463,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "37e113f7-8a0b-494b-a490-313f0b719524", "metadata": {}, "outputs": [], @@ -481,7 +468,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "517bf298-e731-4e7e-9384-1dbd8e836ce1", "metadata": {}, "outputs": [], @@ -503,7 +490,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "87eb269d-af19-47b7-8765-5576d4d5f1b6", "metadata": {}, "outputs": [ @@ -511,7 +498,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "The kernel value between x1=array([0.47349073, 0.25305625]) and x2=array([0.8771323 , 0.71764648]) is 0.94700\n" + "The kernel value between x1=array([0.76519594, 0.48092934]) and x2=array([0.57193983, 0.81116519]) is 0.97298\n" ] } ], @@ -534,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "b67e1f54-40a8-45fc-a2e0-9cc2b91596cc", "metadata": {}, "outputs": [ @@ -588,7 +575,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "id": "f1c0286d-6c45-4ad3-a7c2-9f7807c2ce4d", "metadata": {}, "outputs": [ @@ -596,7 +583,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "The kernel value between x1=array([0.47349073, 0.25305625]) and x2=array([0.8771323 , 0.71764648]) is 0.94700\n" + "The kernel value between x1=array([0.76519594, 0.48092934]) and x2=array([0.57193983, 0.81116519]) is 0.97298\n" ] } ], @@ -646,7 +633,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -660,7 +647,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.0" + "version": "3.11.11+" } }, "nbformat": 4, diff --git a/docs/source/notebooks/quantum_1_expressibility.ipynb b/docs/source/notebooks/quantum_1_expressibility.ipynb index 8b99cab..90b0b45 100644 --- a/docs/source/notebooks/quantum_1_expressibility.ipynb +++ b/docs/source/notebooks/quantum_1_expressibility.ipynb @@ -8,19 +8,6 @@ "# Expressibility in quantum kernels " ] }, - { - "cell_type": "code", - "execution_count": 3, - "id": "ab05cb1d-619d-4b67-877e-b07ae538aeb1", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import os\n", - "# to import quask, move from docs/source/notebooks to src\n", - "sys.path.append('../../../src')" - ] - }, { "cell_type": "markdown", "id": "0467a8f8-2c64-484b-8d82-a72be720b92e", @@ -73,7 +60,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "id": "7de9d4d1", "metadata": {}, "outputs": [ @@ -86,7 +73,7 @@ } ], "source": [ - "from quask.core import Ansatz, Kernel, KernelFactory, KernelType\n", + "from quask.core import Ansatz, KernelFactory, KernelType\n", "\n", "print(KernelFactory._KernelFactory__implementations)" ] @@ -101,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 3, "id": "a919b280", "metadata": {}, "outputs": [ @@ -109,7 +96,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'pennylane_noiseless': }\n", + "{'pennylane_noiseless': }\n", "pennylane_noiseless\n" ] } @@ -128,7 +115,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 4, "id": "78122793-3f0d-4eea-b589-b71ee711f45b", "metadata": {}, "outputs": [ @@ -136,7 +123,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Cost (norm of A): 0.16832\n" + "Cost (norm of A): 0.16770\n" ] } ], @@ -200,7 +187,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 5, "id": "5865ed98-39ed-4b18-8c0c-d6e4bde0b928", "metadata": {}, "outputs": [ @@ -233,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 6, "id": "cfdeb8d7", "metadata": {}, "outputs": [], @@ -253,7 +240,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 7, "id": "f17b526f", "metadata": {}, "outputs": [ @@ -262,39 +249,39 @@ "output_type": "stream", "text": [ "Bandwith: 1.00000\n", - "Cost (norm of A): 0.17330\n", + "Cost (norm of A): 0.17632\n", "Cost (-1 * rank of DLA): -4.00000\n", "=====================================\n", "Bandwith: 0.88900\n", - "Cost (norm of A): 0.17907\n", + "Cost (norm of A): 0.17664\n", "Cost (-1 * rank of DLA): -4.00000\n", "=====================================\n", "Bandwith: 0.77800\n", - "Cost (norm of A): 0.17554\n", + "Cost (norm of A): 0.17154\n", "Cost (-1 * rank of DLA): -4.00000\n", "=====================================\n", "Bandwith: 0.66700\n", - "Cost (norm of A): 0.16823\n", + "Cost (norm of A): 0.17166\n", "Cost (-1 * rank of DLA): -4.00000\n", "=====================================\n", "Bandwith: 0.55600\n", - "Cost (norm of A): 0.16663\n", + "Cost (norm of A): 0.16520\n", "Cost (-1 * rank of DLA): -4.00000\n", "=====================================\n", "Bandwith: 0.44500\n", - "Cost (norm of A): 0.16426\n", + "Cost (norm of A): 0.16032\n", "Cost (-1 * rank of DLA): -4.00000\n", "=====================================\n", "Bandwith: 0.33400\n", - "Cost (norm of A): 0.21903\n", + "Cost (norm of A): 0.21419\n", "Cost (-1 * rank of DLA): -4.00000\n", "=====================================\n", "Bandwith: 0.22300\n", - "Cost (norm of A): 0.32297\n", + "Cost (norm of A): 0.32400\n", "Cost (-1 * rank of DLA): -4.00000\n", "=====================================\n", "Bandwith: 0.11200\n", - "Cost (norm of A): 0.44571\n", + "Cost (norm of A): 0.44687\n", "Cost (-1 * rank of DLA): -4.00000\n", "=====================================\n", "Bandwith: 0.00100\n", @@ -372,7 +359,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -386,7 +373,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.0" + "version": "3.11.11+" } }, "nbformat": 4, diff --git a/docs/source/notebooks/quantum_2_projected.ipynb b/docs/source/notebooks/quantum_2_projected.ipynb index a2dabb8..7eec1a3 100644 --- a/docs/source/notebooks/quantum_2_projected.ipynb +++ b/docs/source/notebooks/quantum_2_projected.ipynb @@ -8,19 +8,6 @@ "# Projected quantum kernels\n" ] }, - { - "cell_type": "code", - "execution_count": 2, - "id": "ca5c1ff6-36de-4b58-b25a-75df43f8d3e9", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import os\n", - "# to import quask, move from docs/source/notebooks to src\n", - "# sys.path.append('../../../src')" - ] - }, { "cell_type": "code", "execution_count": 1, @@ -31,14 +18,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'pennylane_noiseless': }\n", + "{'pennylane_noiseless': }\n", "pennylane_noiseless\n" ] } ], "source": [ "# se the default implementation you want to use\n", - "from quask.core import Ansatz, Kernel, KernelFactory, KernelType\n", + "from quask.core import Ansatz, KernelFactory, KernelType\n", "from quask.core_implementation import PennylaneKernel\n", "\n", "def create_pennylane_noiseless(ansatz: Ansatz, measurement: str, type: KernelType):\n", @@ -137,7 +124,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "4533f360-52cf-482b-812b-bd1cd770f079", "metadata": {}, "outputs": [], @@ -155,7 +142,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "c8c04a61-b685-4fd2-8edb-59db83481a4e", "metadata": {}, "outputs": [], @@ -204,7 +191,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "id": "1d019c62-f19c-45ac-9c7b-835d2c3e7633", "metadata": {}, "outputs": [], @@ -252,7 +239,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 7, "id": "b9b053fb", "metadata": {}, "outputs": [], @@ -267,7 +254,7 @@ "\n", "N_ELEMENTS_PER_CLASS = 10\n", "iris = load_iris()\n", - "X = np.row_stack([iris.data[0:N_ELEMENTS_PER_CLASS], iris.data[50:50+N_ELEMENTS_PER_CLASS]])\n", + "X = np.vstack([iris.data[0:N_ELEMENTS_PER_CLASS], iris.data[50:50+N_ELEMENTS_PER_CLASS]])\n", "y = np.array([0] * N_ELEMENTS_PER_CLASS + [1] * N_ELEMENTS_PER_CLASS)\n", "\n", "# Standardize the features\n", @@ -285,7 +272,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 8, "id": "666e7285", "metadata": {}, "outputs": [ @@ -309,7 +296,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "id": "b7ca0716", "metadata": {}, "outputs": [], @@ -338,7 +325,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "id": "c0f1fdf8", "metadata": {}, "outputs": [ @@ -348,7 +335,7 @@ "text": [ "Accuracy projection on (first) qubit 1: 0.7\n", "Accuracy projection on (last) qubit 4: 0.4\n", - "Accuracy fidelity: 0.6\n", + "Accuracy fidelity: 0.3\n", "Accuracy linear: 0.6\n", "Accuracy rbf: 0.6\n" ] @@ -405,23 +392,13 @@ }, { "cell_type": "code", - "execution_count": 133, + "execution_count": 13, "id": "f41437f7", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 133, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZgAAAGdCAYAAAAv9mXmAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAWN0lEQVR4nO3dbYyUhb338f8+wLK1y0awPB0XpYYTFFBB0Cp3bBuJxoinJo2tdzAhmGjTLgqSmEIbNcbCStMaErAoprUkFdHEGK2JNoZGqK0EBDWStlJvPbrVAHqiu4p1gZ05L3q6PdyjdAf4c83g55PMCyczXr/MDvvdawdmGsrlcjkA4BhrLHoAACcmgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUzcf7gKVSKd55551oa2uLhoaG4314AI5CuVyODz/8MMaNGxeNjYc/RznugXnnnXeio6PjeB8WgGOou7s7Tj311MPe5rgHpq2tLSIiLpp5SzQ3txzvw3+mj8cOK3pChdKQohdU+sLuA0VPqFAaUntnwvuHH/c/Wv/SkA/7i55Q4W+jau9xGvZftfc4nfTGB0VPGHCwvy82vXbPwPfywznuX91//Fqsubklmptr55t685Da2fIP/UOLXlCpubmp6AkVSs21F5jSkNr7xtk8pPa+cTYN9TgNRnNT7fww/g+DeYnDi/wApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKY4oMPfcc0+cfvrpMWzYsLjgggti69atx3oXAHWu6sA8/PDDsXjx4rj99ttjx44dcc4558Rll10We/fuzdgHQJ2qOjB33313XH/99TF//vw466yz4t57740vfOEL8Ytf/CJjHwB1qqrA7N+/P7Zv3x6zZ8/+5/+gsTFmz54dzz///Kfep6+vL3p7ew+5AHDiqyow7733XvT398fo0aMPuX706NGxe/fuT71PV1dXtLe3D1x8miXA50P63yJbunRp9PT0DFy6u7uzDwlADajq4+ROOeWUaGpqij179hxy/Z49e2LMmDGfep+WlpZoaam9T2MDIFdVZzBDhw6N8847LzZu3DhwXalUio0bN8aFF154zMcBUL+q/kDsxYsXx7x582LGjBlx/vnnx8qVK2Pfvn0xf/78jH0A1KmqA/Ptb3873n333bjtttti9+7dce6558bT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DAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEgRdWBefvtt+Paa6+NkSNHRmtra0ydOjVeeOGFjG0A1LGqPg/m/fffj1mzZsXXv/71eOqpp+JLX/pS/OUvf4mTTz45ax8AdaqqwKxYsSI6OjrigQceGLhuwoQJx3wUAPWvql+RPfHEEzFjxoy4+uqrY9SoUTFt2rS4//77D3ufvr6+6O3tPeQCwImvqsC8/vrrsWbNmpg4cWL85je/ie9+97tx0003xbp16z7zPl1dXdHe3j5w6ejoOOrRANS+qgJTKpVi+vTpsXz58pg2bVrccMMNcf3118e99977mfdZunRp9PT0DFy6u7uPejQAta+qwIwdOzbOOuusQ64788wz46233vrM+7S0tMTw4cMPuQBw4qsqMLNmzYpXX331kOt27doVp5122jEdBUD9qyowN998c2zZsiWWL18er732Wqxfvz7Wrl0bnZ2dWfsAqFNVBWbmzJnx2GOPxUMPPRRTpkyJO++8M1auXBlz587N2gdAnarq38FERMyZMyfmzJmTsQWAE4j3IgMghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIUfV7kR0rfxvVHE1DCzt8havmPF/0hAr/0b6j6AkVbtizoOgJFf42plT0hApXX7yl6AkVHtk2s+gJFd6Yc/iPXC/Cv7fNK3pChYOr3i56woCD5QODvq0zGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNAiuaiDjzsv/qjeUh/UYev8OjGrxQ9ocIj7TOLnlBh9FuloidUaHm/oegJFR49UHvPp/Y3a+/nyX9vm1f0hAotO04qekKF5jGji57wT6X9EXsGd9Pae8YBcEIQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIEVVgenv749bb701JkyYEK2trXHGGWfEnXfeGeVyOWsfAHWqqs+DWbFiRaxZsybWrVsXkydPjhdeeCHm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", + "image/png": "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", "text/plain": [ "
    " ] @@ -433,12 +410,12 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "plt.imshow(K_train_1)" + "plt.imshow(K_train_1);" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 14, "id": "a9cfbe5f", "metadata": {}, "outputs": [ @@ -446,7 +423,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "[0.03671272559474694, 0.5715453830052944, 0.7968808921734044, 0.09647781596276615, 0.1805535420850637, 0.5715453830052948, 0.21989891011575627, 0.9993946120620129, 0.2838746697951175, 0.030764066789510918]\n", + "[np.float64(0.03671272559474694), np.float64(0.5715453830052948), np.float64(0.7968808921734044), np.float64(0.09647781596276594), np.float64(0.1805535420850637), np.float64(0.5715453830052948), np.float64(0.21989891011575627), np.float64(0.9993946120620129), np.float64(0.2838746697951175), np.float64(0.030764066789510918)]\n", "[0, 1, 1, 0, 0, 1, 0, 1, 0, 0]\n", "Training accuracy projection on (first) qubit 1: 0.8\n", "Training accuracy projection on (last) qubit 4: 0.6\n", @@ -493,7 +470,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 15, "id": "45f755cf-83e2-4459-95cc-07a1050d84ad", "metadata": {}, "outputs": [ @@ -535,7 +512,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 16, "id": "ed11b716", "metadata": {}, "outputs": [ @@ -543,14 +520,15 @@ "name": "stdout", "output_type": "stream", "text": [ - "Cost (norm) of the training projected kernel on qubit 1: 0.375\n", - "Cost (norm) of the training projected kernel on qubit 4: 0.374\n", - "Cost (norm) of the training fidelity kernel: 0.374\n" + "Cost (norm) of the training projected kernel on qubit 1: 0.438\n", + "Cost (norm) of the training projected kernel on qubit 4: 0.437\n", + "Cost (norm) of the training fidelity kernel: 0.435\n" ] } ], "source": [ "from quask.evaluator import HaarEvaluator\n", + "\n", "he = HaarEvaluator(n_bins=40, n_samples=10000)\n", "cost = he.evaluate(kernel=kernel_proj_1, K=K_train_1, X=None, y=None)\n", "print(f\"Cost (norm) of the training projected kernel on qubit 1: {cost:.3f}\")\n", @@ -600,7 +578,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "id": "012da86c", "metadata": {}, "outputs": [ @@ -608,9 +586,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "geometric difference of training projected kernel on qubit 1 with linear and rbf: [0.869, 2.517] - sqrt of m: 3.162\n", - "geometric difference of training projected kernel on qubit 4 with linear and rbf: [4.219, 1.821] - sqrt of m: 3.162\n", - "geometric difference of training fidelity kernel with linear and rbf: [2.862, 1.481] - sqrt of m: 3.162\n" + "geometric difference of training projected kernel on qubit 1 with linear and rbf: [np.float64(0.869), np.float64(2.517)] - sqrt of m: 3.162\n", + "geometric difference of training projected kernel on qubit 4 with linear and rbf: [np.float64(4.928), np.float64(2.375)] - sqrt of m: 3.162\n", + "geometric difference of training fidelity kernel with linear and rbf: [np.float64(2.862), np.float64(1.481)] - sqrt of m: 3.162\n" ] } ], @@ -675,7 +653,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -689,7 +667,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.0" + "version": "3.11.11+" } }, "nbformat": 4, diff --git a/docs/source/notebooks/quantum_2_projected_1.ipynb b/docs/source/notebooks/quantum_2_projected_1.ipynb deleted file mode 100644 index bc17119..0000000 --- a/docs/source/notebooks/quantum_2_projected_1.ipynb +++ /dev/null @@ -1,700 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "9d15079b-8f4a-4f61-9742-b4c0d5cd27d6", - "metadata": {}, - "source": [ - "# Projected quantum kernels\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "ca5c1ff6-36de-4b58-b25a-75df43f8d3e9", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import os\n", - "# to import quask, move from docs/source/notebooks to src\n", - "# sys.path.append('../../../src')" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "b427a929", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'pennylane_noiseless': }\n", - "pennylane_noiseless\n" - ] - } - ], - "source": [ - "# se the default implementation you want to use\n", - "from quask.core import Ansatz, Kernel, KernelFactory, KernelType\n", - "from quask.core_implementation import PennylaneKernel\n", - "\n", - "def create_pennylane_noiseless(ansatz: Ansatz, measurement: str, type: KernelType):\n", - " return PennylaneKernel(ansatz, measurement, type, device_name=\"default.qubit\", n_shots=None)\n", - "\n", - "KernelFactory.add_implementation('pennylane_noiseless', create_pennylane_noiseless)\n", - "KernelFactory.set_current_implementation('pennylane_noiseless')\n", - "print(KernelFactory._KernelFactory__implementations)\n", - "print(KernelFactory._KernelFactory__current_implementation)" - ] - }, - { - "cell_type": "markdown", - "id": "a9eb156b-61e8-43db-8074-8c24e908f6f1", - "metadata": {}, - "source": [ - "To understand Projected Quantum Kernels we should understand the limitations\n", - "of \"traditional\" quantum kernels. These limitations have very deep implications\n", - "in the understanding of kernel methods also on a classical perspective." - ] - }, - { - "cell_type": "markdown", - "id": "a0bc7a86-9592-4576-ae55-49fa9c68405e", - "metadata": {}, - "source": [ - "## Expressibility and curse of dimensionality in kernel methods\n", - "\n", - "When approaching a ML problem we could ask if it makes sense at all to use QML techniques, such as quantum kernel methods. We understood in the last years \\[kbs21\\],\\[Hua21\\] that having a large Hilbert space where we can compute classically intractable inner products does not guarantee an advantage. But, why?\n", - "\n", - "When dealing with kernel methods, whether classical or quantum, we must exercise caution when working in high-dimensional (or even infinite-dimensional) Hilbert spaces. This is due to the fact that in\n", - "high dimensions, the problem of generalization becomes hard, _i.e._ the trained kernel is prone to overfitting.\n", - "In turn, an exponential (in the number of features/qubits) number of datapoints are needed to learn the target function we aim to estimate. These phenomena are explored in the [upcoming tutorial](xxx).\n", - "\n", - "For instance, in the classical context, the Gaussian kernel maps any $\\mathbf{x} \\in \\mathbb{R}^d$ to a multi-dimensional Gaussian distribution with an average of $\\mathbf{x}$ and a covariance matrix of $\\sigma I$. When $\\sigma$ is small, data points are mapped to different regions of this infinite-dimensional Hilbert space, and $\\kappa(\\mathbf{x}, \\mathbf{x}') \\approx 0$ for all $\\mathbf{x} \\neq \\mathbf{x}'$. This is known as the phenonenon of _curse of dimensionality_, or _orthogonality catastrophe_. To avoid this, a larger $\\sigma$ is chosen to ensure that most data points relevant to our task have some nontrivial overlap.\n", - "\n", - "As the Hilbert space for quantum systems grows exponentially with the number of qubits $n$, similar challenges can arise when using quantum kernels. This situation occurs with expressible $U(\\cdot)$, which allows access to various regions within the Hilbert space. In such cases, similar to classical kernels, techniques must be employed to control expressibility and, consequently, the model's complexity." - ] - }, - { - "cell_type": "markdown", - "id": "9d015e55-133a-4f59-aff6-c292aaee05d1", - "metadata": {}, - "source": [ - "### Projection as expressibility control\n", - "\n", - "The authors of \\[Hua21\\], who initially addressed the challenge of the exponential dimensionality of Hilbert space in the context of quantum kernels, have introduced the concept of _projected quantum kernels_ to mitigate this issue. Then, in \\[kbs21\\] they proved as this projected kernel must intertwine with a correct inductive bias to obtain some good performance.\n", - "\n", - "The concept is straightforward: first, the unitary transformation $U$ maps classical data into the Hilbert space of the quantum system. Subsequently, a projection maps these elements back to a lower-dimensional Hilbert space. The overall transformation, thanks to the contribution of $U$, remains beyond the capabilities of classical kernels.\n", - "\n", - "For a single data point encoded in the quantum system, denoted as $\\rho_x = U(x) \\rho_0 U(x)$, projected quantum kernels can be implemented in two different ways:\n", - "- We can implement the feature map $\\phi(x) = \\mathrm{\\tilde{Tr}}[\\rho_x]$, with $\\mathrm{\\tilde{Tr}}$ representing partial trace.\n", - "- Alternatively, we can implement the feature map $\\phi(x) = \\{ \\mathrm{Tr}[\\rho_x O^{(j)}] \\}_{j=1}^k$, where the observable $O^{(j)}$ is employed for the projections.\n", - "\n", - "Finally, the kernel $\\kappa(x, x')$ is explicitly constructed as the inner product between $\\phi(x)$ and $\\phi(x')$.\n" - ] - }, - { - "cell_type": "markdown", - "id": "39cd1083-1bd1-4651-8113-1020fa96b1e8", - "metadata": {}, - "source": [ - "### Implementation of projected quantum kernel in _quask_\n", - "\n", - "We first create the parameterized quantum circuit $U$ as in the previous tutorials. " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "d1d0e2df-e91a-48ed-8410-b83a580c1b56", - "metadata": {}, - "outputs": [], - "source": [ - "from quask.core import Ansatz, Kernel, KernelFactory, KernelType\n", - "\n", - "N_FEATURES = 2\n", - "N_OPERATIONS = 3\n", - "N_QUBITS = 2\n", - "ansatz = Ansatz(n_features=N_FEATURES, n_qubits=N_QUBITS, n_operations=N_OPERATIONS)\n", - "ansatz.initialize_to_identity()\n", - "ansatz.change_operation(0, new_feature=0, new_wires=[0, 1], new_generator=\"ZZ\", new_bandwidth=1.0)\n", - "ansatz.change_operation(1, new_feature=1, new_wires=[0, 1], new_generator=\"XX\", new_bandwidth=1.0)\n", - "ansatz.change_operation(2, new_feature=2, new_wires=[0, 1], new_generator=\"IX\", new_bandwidth=0.123)" - ] - }, - { - "cell_type": "markdown", - "id": "60a8e11d-4858-46fe-9ea7-7198d905092d", - "metadata": {}, - "source": [ - "Now, by employing the SWAP test over a subset of the $n$ qubits, only a small and constant number of qubits are measured, hence projecting in the subspace relative to those qubit selected by the SWAP test. This calculation is equivalent to performing the inner product between partial traces of two quantum-encoded data points. \n", - "\n", - "In the following example, the measurement is performed only on the first of two qubits." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "4533f360-52cf-482b-812b-bd1cd770f079", - "metadata": {}, - "outputs": [], - "source": [ - "kernel = KernelFactory.create_kernel(ansatz, \"ZI\", KernelType.SWAP_TEST)" - ] - }, - { - "cell_type": "markdown", - "id": "6e5eecf2-0c12-42f6-831b-f92e2cb4a786", - "metadata": {}, - "source": [ - "We can also obtain the kernel by projecting onto a single observable described by a Pauli string." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c8c04a61-b685-4fd2-8edb-59db83481a4e", - "metadata": {}, - "outputs": [], - "source": [ - "kernel = KernelFactory.create_kernel(ansatz, \"XY\", KernelType.OBSERVABLE)" - ] - }, - { - "cell_type": "markdown", - "id": "96dfd18b-69f9-4d16-a77a-333537011e52", - "metadata": {}, - "source": [ - "Multiple observable can be tested if we compose together kernel functions made of different observables. Due to the properties of positive semidefinite functions, the sum and product and tensor of positive semidefinite operators is again positive semidefinite." - ] - }, - { - "cell_type": "markdown", - "id": "730358bc-6945-452a-bd63-dec11173be8f", - "metadata": {}, - "source": [ - "## Learning of quantum processes\n", - "\n", - "The projected quantum kernel finds application in the realm of learning a quantum process, described by a function:\n", - "\n", - "$$f(x) = \\mathrm{Tr}[U^\\dagger(x) \\rho_0 U(x) O]$$\n", - "\n", - "Here, $U$ represents a parameterized quantum circuit, $\\rho_0$ is the initial state, and $O$ stands for the observable. This family of functions carries significant theoretical importance, as it has facilitated the formal demonstration of quantum advantages. It also holds practical significance, as certain use cases in physics and chemistry can be conceptualized as quantum processes.\n", - "\n", - "We are given a dataset, denoted as $\\{ (x^{(j)}, y^{(j)}) \\}_{j=1}^m$. Additionally, we assume that each label in this dataset is noise-free, meaning that $y^{(j)} = f(x^{(j)})$.\n" - ] - }, - { - "cell_type": "markdown", - "id": "5e9caac0", - "metadata": {}, - "source": [ - "## Create a Quantum Dataset \n", - "\n", - "We can use a $U$ quantum circuit inspired by quantum many-body physics, e.g. a Ising Hamiltonian with transverse field (open boundary condition is implemented by linear entanglement),\n", - "$$ H = \\sum_{i=1}^{n-1} \\sigma_i^z \\sigma_{i+1}^z + \\lambda \\sum_{i=1}^n \\sigma_i^x $$\n", - "where $n$ is the number of qubits.\n", - "\n", - "Then, U for the $j-th$ datapoint $\\{x_j^{(i)}\\}_{i=1}^n$ (which has $i$ number of features equal to the number of qubits $n$) will look like:\n", - "$$ U (x_j) = \\exp(\\sum_{i=1}^{n-1}x_{ji}x_{ji+1}\\sigma_i^z \\sigma_{i+1}^z + \\sum_{i=1}^n x_{ji}\\sigma_i^x) $$" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "1d019c62-f19c-45ac-9c7b-835d2c3e7633", - "metadata": {}, - "outputs": [], - "source": [ - "# let us define the Ansatz which implements this\n", - "def ManyBodyAnsatz(N_FEATURES, N_QUBITS, N_OPERATIONS, bandwidth):\n", - " ansatz = Ansatz(n_features=N_FEATURES, n_qubits=N_QUBITS, n_operations=N_OPERATIONS)\n", - " ansatz.initialize_to_identity()\n", - " # linear CZ entanglement\n", - " for j in range(N_QUBITS-1):\n", - " ansatz.change_operation(j, new_feature=N_QUBITS+j, new_wires=[j, j+1], new_generator=\"ZZ\", new_bandwidth=bandwidth)\n", - "\n", - " # single qubit rotations in x: RX wall\n", - " for i in range(N_QUBITS-1):\n", - " j += 1\n", - " ansatz.change_operation(j, new_feature=i, new_wires=[i, i+1], new_generator=\"XI\", new_bandwidth=bandwidth)\n", - " ansatz.change_operation(2*N_QUBITS-2, new_feature=N_QUBITS-1, new_wires=[N_QUBITS-1, 0], new_generator=\"XI\", new_bandwidth=bandwidth)\n", - " return ansatz\n", - "\n", - "# help funciton to select on which qubit we want to perform our measurement\n", - "def measurement_qubit(N_QUBITS, measurement):\n", - " pauli_string = \"\"\n", - " for i in range(N_QUBITS):\n", - " if i < measurement:\n", - " pauli_string = pauli_string + \"I\"\n", - " if i == measurement:\n", - " pauli_string = pauli_string + \"Z\"\n", - " if i > measurement:\n", - " pauli_string = pauli_string + \"I\"\n", - " return pauli_string\n", - "\n", - "# we define the function which will give us quantum labels for our dataset\n", - "def QuantumTargetFunction(ansatz, N_QUBITS, measurement):\n", - " kernel = KernelFactory.create_kernel(ansatz, measurement_qubit(N_QUBITS=N_QUBITS, measurement=measurement), KernelType.OBSERVABLE)\n", - " return kernel" - ] - }, - { - "cell_type": "markdown", - "id": "27e4d384", - "metadata": {}, - "source": [ - "Now, we can take a classical dataset, e.g. the _iris_ (check tutorial [Getting Started](\"../getting_started.html\")) dataset and change its labels with the quantum ones" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "b9b053fb", - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.datasets import load_digits\n", - "from sklearn.svm import SVC\n", - "from sklearn.metrics.pairwise import linear_kernel, rbf_kernel\n", - "from sklearn.metrics import mean_squared_error, r2_score\n", - "from sklearn.model_selection import train_test_split\n", - "from sklearn.preprocessing import StandardScaler\n", - "from sklearn.decomposition import PCA\n", - "import numpy as np\n", - "\n", - "N_ELEMENTS_PER_CLASS = 10\n", - "digits = load_digits()\n", - "data, labels = load_digits(return_X_y=True)\n", - "# X = np.row_stack([digits.data[0:N_ELEMENTS_PER_CLASS], digits.data[50:50+N_ELEMENTS_PER_CLASS]])\n", - "X_reduced = PCA(n_components=2).fit_transform(data)\n", - "y = np.array([0] * N_ELEMENTS_PER_CLASS + [1] * N_ELEMENTS_PER_CLASS)\n", - "\n", - "# Standardize the features\n", - "scaler = StandardScaler()\n", - "X = scaler.fit_transform(X_reduced)" - ] - }, - { - "cell_type": "markdown", - "id": "d7f54614", - "metadata": {}, - "source": [ - "As explained already in the first tutorial on [Quantum Kernels](../tutorials_quantum/quantum_0_intro.html), The features of the Unitary operator can be customed. We need to add them to a datapoint's feature. Here $x^{(j)}$ lives in a $\\mathbb{R}^4$ space. We can add, for the $i,i+1$ $ZZ$ interaction, the product of the nearest-neighbor features to the datapoint. Hence, $x = \\{x_0,x_1,x_2,x_3,x_0x_1,x_1x_2,x_2x_3\\} \\in \\mathbb{R}^7$, in general, if the original vector has $n$ features, for this Unitary we will need $2n-1$ features. In this way, our `ManyBodyAnsatz` knows where to take the features to build the parametrized circuit." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "666e7285", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(20, 7)\n" - ] - } - ], - "source": [ - "X_new = []\n", - "for x in X:\n", - " for i in range(x.shape[0]-1):\n", - " x = np.append(x, x[i]*x[i+1])\n", - " X_new.append(x)\n", - "\n", - "print(np.asarray(X_new).shape)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "b7ca0716", - "metadata": {}, - "outputs": [], - "source": [ - "# instantiate the ansatz to sample from a quantum distribution\n", - "N_FEATURES = 7\n", - "N_QUBITS = 4\n", - "N_OPERATIONS = 7\n", - "bandwidth = 1\n", - "ansatz = ManyBodyAnsatz(N_FEATURES=N_FEATURES, N_QUBITS=N_QUBITS, N_OPERATIONS=N_OPERATIONS, bandwidth=bandwidth)\n", - "kernel_proj_1 = QuantumTargetFunction(ansatz=ansatz, N_QUBITS=N_QUBITS, measurement=0)\n", - "kernel_proj_4 = QuantumTargetFunction(ansatz=ansatz, N_QUBITS=N_QUBITS, measurement=3)\n", - "kernel_fid = KernelFactory.create_kernel(ansatz, \"Z\" * N_QUBITS, KernelType.FIDELITY)\n", - "y_quantum = [kernel_proj_1.kappa(x,x) for x in X_new]\n", - "new_labels = [1 if y >= 1/2 else 0 for y in y_quantum]" - ] - }, - { - "cell_type": "markdown", - "id": "58c21fc0", - "metadata": {}, - "source": [ - "We have created a quantum dataset with labels, $i.e.$ classes, sampled from a quantum distribution given by our quantum feature map.\n", - "Now, we can use the dataset as always to test our kernels" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "c0f1fdf8", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Accuracy projection on (first) qubit 1: 0.7\n", - "Accuracy projection on (last) qubit 4: 0.4\n", - "Accuracy fidelity: 0.6\n", - "Accuracy linear: 0.6\n", - "Accuracy rbf: 0.6\n" - ] - } - ], - "source": [ - "# Split the data into training and testing sets\n", - "X_new = np.array(X_new)\n", - "X_train, X_test, y_train, y_test = train_test_split(X_new, new_labels, test_size=0.5, random_state=5454)\n", - "\n", - "# Instantiate a machine learning model\n", - "model_proj_1 = SVC(kernel='precomputed')\n", - "model_proj_4 = SVC(kernel='precomputed')\n", - "model_fid = SVC(kernel='precomputed')\n", - "model_lin = SVC(kernel='precomputed')\n", - "model_rbf = SVC(kernel='precomputed')\n", - "\n", - "# Fit the model to the training data\n", - "K_train_1 = kernel_proj_1.build_kernel(X_train, X_train)\n", - "model_proj_1.fit(K_train_1, y_train)\n", - "K_train_4 = kernel_proj_4.build_kernel(X_train, X_train)\n", - "model_proj_4.fit(K_train_4, y_train)\n", - "K_train_fid = kernel_fid.build_kernel(X_train, X_train)\n", - "model_fid.fit(K_train_fid, y_train)\n", - "K_train_lin = linear_kernel(X_train)\n", - "model_lin.fit(K_train_lin, y_train)\n", - "K_train_rbf = rbf_kernel(X_train)\n", - "model_rbf.fit(K_train_rbf, y_train)\n", - "\n", - "# Predict the labels for the test data\n", - "K_test_1 = kernel_proj_1.build_kernel(X_test, X_train)\n", - "y_pred_1 = model_proj_1.predict(K_test_1)\n", - "K_test_4 = kernel_proj_4.build_kernel(X_test, X_train)\n", - "y_pred_4 = model_proj_4.predict(K_test_4)\n", - "K_test_fid = kernel_fid.build_kernel(X_test, X_train)\n", - "y_pred_fid = model_fid.predict(K_test_fid)\n", - "K_test_lin = linear_kernel(X_test, X_train)\n", - "y_pred_lin = model_lin.predict(K_test_lin)\n", - "K_test_rbf = rbf_kernel(X_test, X_train)\n", - "y_pred_rbf = model_rbf.predict(K_test_rbf)\n", - "\n", - "# Calculate the accuracy\n", - "accuracy_1 = np.sum(y_test == y_pred_1) / len(y_test)\n", - "print(\"Accuracy projection on (first) qubit 1:\", accuracy_1)\n", - "accuracy_4 = np.sum(y_test == y_pred_4) / len(y_test)\n", - "print(\"Accuracy projection on (last) qubit 4:\", accuracy_4)\n", - "accuracy_fid = np.sum(y_test == y_pred_fid) / len(y_test)\n", - "print(\"Accuracy fidelity:\", accuracy_fid)\n", - "accuracy_lin = np.sum(y_test == y_pred_lin) / len(y_test)\n", - "print(\"Accuracy linear:\", accuracy_lin)\n", - "accuracy_rbf = np.sum(y_test == y_pred_rbf) / len(y_test)\n", - "print(\"Accuracy rbf:\", accuracy_rbf)" - ] - }, - { - "cell_type": "code", - "execution_count": 133, - "id": "f41437f7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 133, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZgAAAGdCAYAAAAv9mXmAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAWN0lEQVR4nO3dbYyUhb338f8+wLK1y0awPB0XpYYTFFBB0Cp3bBuJxoinJo2tdzAhmGjTLgqSmEIbNcbCStMaErAoprUkFdHEGK2JNoZGqK0EBDWStlJvPbrVAHqiu4p1gZ05L3q6PdyjdAf4c83g55PMCyczXr/MDvvdawdmGsrlcjkA4BhrLHoAACcmgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUzcf7gKVSKd55551oa2uLhoaG4314AI5CuVyODz/8MMaNGxeNjYc/RznugXnnnXeio6PjeB8WgGOou7s7Tj311MPe5rgHpq2tLSIiLpp5SzQ3txzvw3+mj8cOK3pChdKQohdU+sLuA0VPqFAaUntnwvuHH/c/Wv/SkA/7i55Q4W+jau9xGvZftfc4nfTGB0VPGHCwvy82vXbPwPfywznuX91//Fqsubklmptr55t685Da2fIP/UOLXlCpubmp6AkVSs21F5jSkNr7xtk8pPa+cTYN9TgNRnNT7fww/g+DeYnDi/wApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKY4oMPfcc0+cfvrpMWzYsLjgggti69atx3oXAHWu6sA8/PDDsXjx4rj99ttjx44dcc4558Rll10We/fuzdgHQJ2qOjB33313XH/99TF//vw466yz4t57740vfOEL8Ytf/CJjHwB1qqrA7N+/P7Zv3x6zZ8/+5/+gsTFmz54dzz///Kfep6+vL3p7ew+5AHDiqyow7733XvT398fo0aMPuX706NGxe/fuT71PV1dXtLe3D1x8miXA50P63yJbunRp9PT0DFy6u7uzDwlADajq4+ROOeWUaGpqij179hxy/Z49e2LMmDGfep+WlpZoaam9T2MDIFdVZzBDhw6N8847LzZu3DhwXalUio0bN8aFF154zMcBUL+q/kDsxYsXx7x582LGjBlx/vnnx8qVK2Pfvn0xf/78jH0A1KmqA/Ptb3873n333bjtttti9+7dce6558bT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DAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEgRdWBefvtt+Paa6+NkSNHRmtra0ydOjVeeOGFjG0A1LGqPg/m/fffj1mzZsXXv/71eOqpp+JLX/pS/OUvf4mTTz45ax8AdaqqwKxYsSI6OjrigQceGLhuwoQJx3wUAPWvql+RPfHEEzFjxoy4+uqrY9SoUTFt2rS4//77D3ufvr6+6O3tPeQCwImvqsC8/vrrsWbNmpg4cWL85je/ie9+97tx0003xbp16z7zPl1dXdHe3j5w6ejoOOrRANS+qgJTKpVi+vTpsXz58pg2bVrccMMNcf3118e99977mfdZunRp9PT0DFy6u7uPejQAta+qwIwdOzbOOuusQ64788wz46233vrM+7S0tMTw4cMPuQBw4qsqMLNmzYpXX331kOt27doVp5122jEdBUD9qyowN998c2zZsiWWL18er732Wqxfvz7Wrl0bnZ2dWfsAqFNVBWbmzJnx2GOPxUMPPRRTpkyJO++8M1auXBlz587N2gdAnarq38FERMyZMyfmzJmTsQWAE4j3IgMghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIUfV7kR0rfxvVHE1DCzt8havmPF/0hAr/0b6j6AkVbtizoOgJFf42plT0hApXX7yl6AkVHtk2s+gJFd6Yc/iPXC/Cv7fNK3pChYOr3i56woCD5QODvq0zGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNAiuaiDjzsv/qjeUh/UYev8OjGrxQ9ocIj7TOLnlBh9FuloidUaHm/oegJFR49UHvPp/Y3a+/nyX9vm1f0hAotO04qekKF5jGji57wT6X9EXsGd9Pae8YBcEIQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIEVVgenv749bb701JkyYEK2trXHGGWfEnXfeGeVyOWsfAHWqqs+DWbFiRaxZsybWrVsXkydPjhdeeCHmz58f7e3tcdNNN2VtBKAOVRWYP/zhD/GNb3wjrrjiioiIOP300+Ohhx6KrVu3powDoH5V9Suyiy66KDZu3Bi7du2KiIiXX345nnvuubj88ss/8z59fX3R29t7yAWAE19VZzBLliyJ3t7emDRpUjQ1NUV/f38sW7Ys5s6d+5n36erqijvuuOOohwJQX6o6g3nkkUfiwQcfjPXr18eOHTti3bp18ZOf/CTWrVv3mfdZunRp9PT0DFy6u7uPejQAta+qM5hbbrkllixZEtdcc01EREydOjXefPPN6Orqinnz5n3qfVpaWqKlpeXolwJQV6o6g/n444+jsfHQuzQ1NUWpVDqmowCof1WdwVx55ZWxbNmyGD9+fEyePDlefPHFuPvuu+O6667L2gdAnaoqMKtWrYpbb701vve978XevXtj3Lhx8Z3vfCduu+22rH0A1KmqAtPW1hYrV66MlStXJs0B4EThvcgASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUlT1XmTH0klvfBDNTbXzOTETN+0uekKF8id9RU+o0HjavxU9oUJD34GiJ1QY/UFP0RMqNLYPL3pChYOr3i56QoXmMaOLnlDhwJfHFD1hwMGDn0TsGdxtncEAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApGg+3gcsl8sREXGwv+94H/qwyuX9RU+oUC4fKHpChcYa+7pFRDSUau9xKtXg86mxVHtfu4M1+ByPUu197Q4e/KToCQMOHvz78+gf38sPp6E8mFsdQ3/961+jo6PjeB4SgGOsu7s7Tj311MPe5rgHplQqxTvvvBNtbW3R0NBwxP+f3t7e6OjoiO7u7hg+fPgxXHhi8TgNjsdpcDxOg3MiP07lcjk+/PDDGDduXDQ2Hv5VluP+K7LGxsZ/Wb1qDB8+/IT7AmbwOA2Ox2lwPE6Dc6I+Tu3t7YO6nRf5AUghMACkqNvAtLS0xO233x4tLS1FT6lpHqfB8TgNjsdpcDxOf3fcX+QH4POhbs9gAKhtAgNACoEBIIXAAJCibgNzzz33xOmnnx7Dhg2LCy64ILZu3Vr0pJrS1dUVM2fOjLa2thg1alRcddVV8eqrrxY9q6bddddd0dDQEIsWLSp6Ss15++2349prr42RI0dGa2trTJ06NV544YWiZ9WU/v7+uPXWW2PChAnR2toaZ5xxRtx5552Des+uE1VdBubhhx+OxYsXx+233x47duyIc845Jy677LLYu3dv0dNqxqZNm6KzszO2bNkSzzzzTBw4cCAuvfTS2LdvX9HTatK2bdvivvvui7PPPrvoKTXn/fffj1mzZsWQIUPiqaeeij/+8Y/x05/+NE4++eSip9WUFStWxJo1a2L16tXxpz/9KVasWBE//vGPY9WqVUVPK0xd/jXlCy64IGbOnBmrV6+OiL+/v1lHR0fceOONsWTJkoLX1aZ33303Ro0aFZs2bYqLL7646Dk15aOPPorp06fHz372s/jRj34U5557bqxcubLoWTVjyZIl8fvf/z5+97vfFT2lps2ZMydGjx4dP//5zweu++Y3vxmtra3xq1/9qsBlxam7M5j9+/fH9u3bY/bs2QPXNTY2xuzZs+P5558vcFlt6+npiYiIESNGFLyk9nR2dsYVV1xxyHOKf3riiSdixowZcfXVV8eoUaNi2rRpcf/99xc9q+ZcdNFFsXHjxti1a1dERLz88svx3HPPxeWXX17wsuIc9ze7PFrvvfde9Pf3x+jRow+5fvTo0fHnP/+5oFW1rVQqxaJFi2LWrFkxZcqUoufUlA0bNsSOHTti27ZtRU+pWa+//nqsWbMmFi9eHD/4wQ9i27ZtcdNNN8XQoUNj3rx5Rc+rGUuWLIne3t6YNGlSNDU1RX9/fyxbtizmzp1b9LTC1F1gqF5nZ2fs3LkznnvuuaKn1JTu7u5YuHBhPPPMMzFs2LCi59SsUqkUM2bMiOXLl0dExLRp02Lnzp1x7733Csz/8sgjj8SDDz4Y69evj8mTJ8dLL70UixYtinHjxn1uH6e6C8wpp5wSTU1NsWfPnkOu37NnT4wZM6agVbVrwYIF8eSTT8bmzZuP6ccknAi2b98ee/fujenTpw9c19/fH5s3b47Vq1dHX19fNDU1FbiwNowdOzbOOuusQ64788wz49FHHy1oUW265ZZbYsmSJXHNNddERMTUqVPjzTffjK6urs9tYOruNZihQ4fGeeedFxs3bhy4rlQqxcaNG+PCCy8scFltKZfLsWDBgnjsscfit7/9bUyYMKHoSTXnkksuiVdeeSVeeumlgcuMGTNi7ty58dJLL4nL/5g1a1bFX3HftWtXnHbaaQUtqk0ff/xxxQdwNTU1RalUKmhR8eruDCYiYvHixTFv3ryYMWNGnH/++bFy5crYt29fzJ8/v+hpNaOzszPWr18fjz/+eLS1tcXu3bsj4u8fFNTa2lrwutrQ1tZW8ZrUSSedFCNHjvRa1f9y8803x0UXXRTLly+Pb33rW7F169ZYu3ZtrF27tuhpNeXKK6+MZcuWxfjx42Py5Mnx4osvxt133x3XXXdd0dOKU65Tq1atKo8fP748dOjQ8vnnn1/esmVL0ZNqSkR86uWBBx4oelpN++pXv1peuHBh0TNqzq9//evylClTyi0tLeVJkyaV165dW/SkmtPb21teuHBhefz48eVhw4aVv/zlL5d/+MMflvv6+oqeVpi6/HcwANS+unsNBoD6IDAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKf4bTRHlC2UABwgAAAAASUVORK5CYII=", - "text/plain": [ - "
    " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "plt.imshow(K_train_1)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "a9cfbe5f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0.03671272559474694, 0.5715453830052944, 0.7968808921734044, 0.09647781596276615, 0.1805535420850637, 0.5715453830052948, 0.21989891011575627, 0.9993946120620129, 0.2838746697951175, 0.030764066789510918]\n", - "[0, 1, 1, 0, 0, 1, 0, 1, 0, 0]\n", - "Training accuracy projection on (first) qubit 1: 0.8\n", - "Training accuracy projection on (last) qubit 4: 0.6\n", - "Training accuracy fidelity: 0.9\n", - "Training accuracy linear: 0.9\n", - "Training accuracy rbf: 0.9\n" - ] - } - ], - "source": [ - "print([K_train_1[i,i] for i in range(len(K_train_1))])\n", - "print(y_train)\n", - "\n", - "accuracy_1 = np.sum(y_train == model_proj_1.predict(K_train_1)) / len(y_train)\n", - "accuracy_4 = np.sum(y_train == model_proj_4.predict(K_train_4)) / len(y_train)\n", - "accuracy_fid = np.sum(y_train == model_fid.predict(K_train_fid)) / len(y_train)\n", - "accuracy_lin = np.sum(y_train == model_lin.predict(K_train_lin)) / len(y_train)\n", - "accuracy_rbf = np.sum(y_train == model_rbf.predict(K_train_rbf)) / len(y_train)\n", - "print(\"Training accuracy projection on (first) qubit 1:\", accuracy_1)\n", - "print(\"Training accuracy projection on (last) qubit 4:\", accuracy_4)\n", - "print(\"Training accuracy fidelity:\", accuracy_fid)\n", - "print(\"Training accuracy linear:\", accuracy_lin)\n", - "print(\"Training accuracy rbf:\", accuracy_rbf)" - ] - }, - { - "cell_type": "markdown", - "id": "0d747e21-af0d-4604-8ba2-c3aba23a4768", - "metadata": {}, - "source": [ - "### S-value\n", - "\n", - "We can train a kernel machine on a dataset using a kernel $\\kappa$. The resulting model takes the form $h(x) = w^\\top \\phi(x)$. \n", - "This representation is a kernel machine in its primal form, and the corresponding kernel Gram matrix is defined as $K = [\\kappa(x^{(i)}, x^{(j)})]_{i,j=1}^m$. Assuming that the kernel Gram matrix is normalized, i.e., $\\mathrm{Tr}[K]=m$, we can define the _s-value_, a quantity that depends on the process $f$, the input data, and the kernel Gram matrix $K$:\n", - "\n", - "$$s_K = \\sum_{i,j=1}^m (K_{i,j}^{-1}) \\, f(x^{(i)}) \\, f(x^{(j)})$$\n", - "\n", - "This value quantifies how well the kernel function captures the behavior of the quantum process. The kernel is indeed able to capture the relationship within the data if:\n", - "\n", - "$$\\kappa(x^{(i)}, x^{(j)}) \\approx f(x^{(i)}) \\, f(x^{(j)})$$\n", - "\n", - "It's important to note that $s_K = \\lVert w \\rVert$, making it a measure of the model's complexity. Higher values of $s_K$ suggest that the kernel machine $h$ becomes a more complex function, which can lead to overfitting and poor generalization performance.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "45f755cf-83e2-4459-95cc-07a1050d84ad", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Model complexity of the training projected kernel on qubit 1: 0.807\n", - "Model complexity of the training projected kernel on qubit 4: 0.648\n", - "Model complexity of the training fidelity kernel: 8.060\n", - "Model complexity of the training linear kernel: 2.031\n", - "Model complexity of the training rbf kernel: 8.010\n" - ] - } - ], - "source": [ - "from quask.evaluator import EssModelComplexityEvaluator\n", - "\n", - "sm_eval = EssModelComplexityEvaluator()\n", - "sm_1 = sm_eval.evaluate(kernel=kernel_proj_1, K=K_train_1, X=None, y=np.asarray(y_train))\n", - "print(f\"Model complexity of the training projected kernel on qubit 1: {sm_1:.3f}\")\n", - "sm_4 = sm_eval.evaluate(kernel=kernel_proj_4, K=K_train_4, X=None, y=np.asarray(y_train))\n", - "print(f\"Model complexity of the training projected kernel on qubit 4: {sm_4:.3f}\")\n", - "sm_fid = sm_eval.evaluate(kernel=kernel_fid, K=K_train_fid, X=None, y=np.asarray(y_train))\n", - "print(f\"Model complexity of the training fidelity kernel: {sm_fid:.3f}\")\n", - "sm_lin = sm_eval.evaluate(kernel=None, K=K_train_lin, X=None, y=np.asarray(y_train))\n", - "print(f\"Model complexity of the training linear kernel: {sm_lin:.3f}\")\n", - "sm_rbf = sm_eval.evaluate(kernel=None, K=K_train_rbf, X=None, y=np.asarray(y_train))\n", - "print(f\"Model complexity of the training rbf kernel: {sm_rbf:.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "e255dd89", - "metadata": {}, - "source": [ - "We can also check if the feature maps we choose are expressive in terms of the `HaarEvaluator`" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "ed11b716", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Cost (norm) of the training projected kernel on qubit 1: 0.375\n", - "Cost (norm) of the training projected kernel on qubit 4: 0.374\n", - "Cost (norm) of the training fidelity kernel: 0.374\n" - ] - } - ], - "source": [ - "from quask.evaluator import HaarEvaluator\n", - "he = HaarEvaluator(n_bins=40, n_samples=10000)\n", - "cost = he.evaluate(kernel=kernel_proj_1, K=K_train_1, X=None, y=None)\n", - "print(f\"Cost (norm) of the training projected kernel on qubit 1: {cost:.3f}\")\n", - "cost = he.evaluate(kernel=kernel_proj_4, K=K_train_4, X=None, y=None)\n", - "print(f\"Cost (norm) of the training projected kernel on qubit 4: {cost:.3f}\")\n", - "cost = he.evaluate(kernel=kernel_fid, K=K_train_fid, X=None, y=None)\n", - "print(f\"Cost (norm) of the training fidelity kernel: {cost:.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "b4e9220e-0540-4c09-a431-03382448283a", - "metadata": {}, - "source": [ - "### Geometric difference\n", - "\n", - "While the quantity $s_K$ compare a kernel and the target function, the geometric difference quantifies the divergence between two kernels. \n", - "\n", - "Assume for the two kernel matrices $K_1, K_2$ that their trace is equal to $m$. This is a valid assumption for quantum kernels, as the inner product between unitary vectors (or corresponding density matrices) is one, which then has to be multiplied for the $m$ elements. For classical kernels, the Gram matrix needs to be normalized. \n", - "\n", - "The geometric difference is defined by\n", - "$$g(K_1, K_2) = \\sqrt{\\lVert \\sqrt{K_2} K_1^{-1} \\sqrt{K_2} \\rVert_{\\infty}},$$\n", - "where $\\lVert \\cdot \\rVert_\\infty$ is the spectral norm, i.e. the largest singular value. \n", - "\n", - "One should use the geometric difference to compare the quantum kernel $K_Q$ with several classical kernels $K_{C_1}, K_{C_2}, ...$. Then, $\\min g(K_C, K_Q)$ has to be calculated: \n", - "* if this difference is small, $g(K_C, K_Q) \\ll \\sqrt{m}$, then one of the classical kernels, the one with the smallest geometric difference, is guaranteed to provide similar performances;\n", - "* if the difference is high, $g(K_C, K_Q) \\approx \\sqrt{m}$, the quantum kernel might outperform all the classical kernels tested. " - ] - }, - { - "cell_type": "markdown", - "id": "c2e7e570-460c-47c0-8519-dc44698c4f54", - "metadata": {}, - "source": [ - "### Geometry Test\n", - "\n", - "The geometry test, introduced by [Hua21], serves as a means to assess whether a particular dataset holds the potential for a quantum advantage or if such an advantage is unlikely. The test operates as follows:\n", - "\n", - "- When $g(K_C, K_Q) \\ll \\sqrt{m}$, a classical kernel exhibits behavior similar to the quantum kernel, rendering the use of the quantum kernel redundant.\n", - "\n", - "- When $g(K_C, K_Q) \\approx \\sqrt{m}$, the quantum kernel significantly deviates from all tested classical kernels. The outcome depends on the complexity of classical kernel machines:\n", - " - If the complexity of any classical kernel machine is low ($s_{K_C} \\ll m$), classical kernels perform well, and the quantum kernel's divergence from classical $K_C$, doesn't yield superior performance.\n", - " - When the complexity of all classical kernel machines is high ($s_{K_C} \\approx m$), classical models struggle to learn the function $f$. In this scenario:\n", - " - If the quantum model's complexity is low ($s_{K_Q} \\ll m$), the quantum kernel successfully solves the task while the classical models do not.\n", - " - If the quantum model's complexity is high ($s_{K_Q} \\approx m$), even the quantum model struggles to solve the problem.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "012da86c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "geometric difference of training projected kernel on qubit 1 with linear and rbf: [0.869, 2.517] - sqrt of m: 3.162\n", - "geometric difference of training projected kernel on qubit 4 with linear and rbf: [4.219, 1.821] - sqrt of m: 3.162\n", - "geometric difference of training fidelity kernel with linear and rbf: [2.862, 1.481] - sqrt of m: 3.162\n" - ] - } - ], - "source": [ - "from quask.evaluator import GeometricDifferenceEvaluator\n", - "\n", - "lam = 0.0001 # regularization \n", - "g_eval = GeometricDifferenceEvaluator([K_train_lin,K_train_rbf], lam)\n", - "g_p1 = g_eval.evaluate(kernel=kernel_proj_1, K=K_train_1, X=None, y=None)\n", - "g_p1 = [round(g,3) for g in g_p1]\n", - "g_p4 = g_eval.evaluate(kernel=kernel_proj_4, K=K_train_4, X=None, y=None)\n", - "g_p4 = [round(g,3) for g in g_p4]\n", - "g_fid = g_eval.evaluate(kernel=kernel_fid, K=K_train_fid, X=None, y=None)\n", - "g_fid = [round(g,3) for g in g_fid]\n", - "print(f\"geometric difference of training projected kernel on qubit 1 with linear and rbf: {g_p1} - sqrt of m: {np.sqrt(len(X_train)):.3f}\")\n", - "print(f\"geometric difference of training projected kernel on qubit 4 with linear and rbf: {g_p4} - sqrt of m: {np.sqrt(len(X_train)):.3f}\")\n", - "print(f\"geometric difference of training fidelity kernel with linear and rbf: {g_fid} - sqrt of m: {np.sqrt(len(X_train)):.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "5cbe0999", - "metadata": {}, - "source": [ - "Let us follow the geometry test above:\n", - "* for the Quantum Kernel Projected on the first qubit we have $g_{1,lin} = 0.869 < \\sqrt{m}$ and $g_{1,rbf} = 2.517 \\approx \\sqrt{m}$\n", - " - Then, we check the _model complexity_ of the rbf kernel and we see that is $s_{K_{rbf}} = 8.010 \\approx m$ there is chance of advantage\n", - " - The model complexity of the projected kernel on the first qubit is $s_{K_{p1}} = 0.807 \\ll m$\n", - " - We confirm there is **potential quantum advantage** over the rbf kernel for the Quantum Kernel Projected on the first qubit\n", - "* for the Quantum Kernel Projected on the lastt qubit we have $g_{4,lin} = 4.219 \\approx \\sqrt{m}$ and $g_{4,rbf} = 1.821 \\approx \\sqrt{m}$\n", - " - Then, we check the _model complexity_ of the linear kernel and we see that is $s_{K_{lin}} = 2.031 < m$ so the classical kernel is still able to perform well\n", - " - In addition, the model complexity of the projected kernel on the last qubit is $s_{K_{p4}} = 0.648 \\ll m$ that could also indicate a poorly expressive feature map (underfitting)\n", - " - We confirm there is **NO quantum advantage** over the linear nor the rbf kernel for the Quantum Kernel Projected on the last qubit\n", - "* for the Quantum Fidelity Kernel we have $g_{fid,lin} = 2.862 \\approx \\sqrt{m}$ and $g_{fid,rbf} = 1.481 \\approx \\sqrt{m}$\n", - " - Then, we check the _model complexity_ of the linear kernel and we see that is $s_{K_{lin}} = 2.031 < m$ so the classical kernel is still able to perform well\n", - " - In addition, the model complexity of the projected kernel on the last qubit is $s_{K_{fid}} = 8.060 \\ll m$ that could also indicate a too expressive feature map (overfitting)\n", - " - We confirm there is **NO quantum advantage** over the linear nor the rbf kernel for the Quantum Kernel Projected on the last qubit\n", - "\n", - "All these results are in line with the accuracies we registered" - ] - }, - { - "cell_type": "markdown", - "id": "7cb9e979-3e4e-48bb-a646-f050f6d8e953", - "metadata": {}, - "source": [ - "## References\n", - "\n", - "\\[Hua21\\] Huang, HY., Broughton, M., Mohseni, M. et al. Power of data in quantum machine learning. Nat Commun 12, 2631 (2021). https://doi.org/10.1038/s41467-021-22539-9" - ] - }, - { - "cell_type": "raw", - "id": "40deb309-9858-4c34-80eb-4aa31c91c478", - "metadata": {}, - "source": [ - ".. note::\n", - "\n", - " Author's note." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.0" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/source/notebooks/quask_0_backends.ipynb b/docs/source/notebooks/quask_0_backends.ipynb index bd5440f..065abe7 100644 --- a/docs/source/notebooks/quask_0_backends.ipynb +++ b/docs/source/notebooks/quask_0_backends.ipynb @@ -31,20 +31,7 @@ "id": "64952e1b-d803-4c3b-bcd7-3711132447bf", "metadata": {}, "source": [ - "## Working with the Qiskit backend\n", - "\n", - "We support Qiskit SDK. It can be installed via _pip_ using the following command:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6d1c3648-ec2a-4e0d-9b93-6844a4218856", - "metadata": {}, - "outputs": [], - "source": [ - "# !pip install qiskit\n", - "# !pip install qiskit_ibm_runtime" + "## Working with the Qiskit backend" ] }, { @@ -52,7 +39,7 @@ "id": "ba4e8c2d-4811-48ed-9cef-76a64a59f31d", "metadata": {}, "source": [ - "Once configured, the class `core_implementation.QiskitKernel` can be used. The objects of this class need few configurations:\n", + "The class `core_implementation.QiskitKernel` can be used. The objects of this class need few configurations:\n", "* platform, \"BasicAer\" or \"QiskitRuntimeService\" for simulation and access to IBM cloud\n", "* backend, the default ones for \"BasicAer\" platform, or one of the available in your account for \"QiskitRuntimeService\" platform\n", "* the number of samples\n", @@ -63,16 +50,16 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "4d46eb24-da24-4d6c-a7d8-75f1c67668cf", "metadata": {}, "outputs": [], "source": [ - "from quask.core import Ansatz, Kernel, KernelFactory, KernelType\n", + "from quask.core import Ansatz, KernelFactory, KernelType\n", "from quask.core_implementation import QiskitKernel\n", "\n", "def create_qiskit_noiseless(ansatz: Ansatz, measurement: str, type: KernelType):\n", - " return QiskitKernel(ansatz, measurement, type, device_name=\"default.qubit\", n_shots=None)\n", + " return QiskitKernel(ansatz, measurement, type, device_name=\"BasicAer\", n_shots=None)\n", "\n", "KernelFactory.add_implementation('qiskit_noiseless', create_qiskit_noiseless)" ] @@ -82,19 +69,7 @@ "id": "2832927f-d226-4fe7-9cc2-ac282776c75d", "metadata": {}, "source": [ - "## Working with the Pennylane backend\n", - "\n", - "We support Pennylane SDK. It can be installed via _pip_ using the following command:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2e7b2283-7eb3-4696-86f2-92a477300297", - "metadata": {}, - "outputs": [], - "source": [ - "# !pip install pennylane" + "## Working with the Pennylane backend" ] }, { @@ -102,19 +77,19 @@ "id": "d56e4a7a-1bf9-4d79-97ac-ed7c69d00cba", "metadata": {}, "source": [ - "Once configured, the class `core_implementation.PennylaneKernel` can be used. The objects of this class need few configurations:\n", + "The class `core_implementation.PennylaneKernel` can be used. The objects of this class need few configurations:\n", "* the name of the device to be used ('default.qubit' being the noiseless simulator);\n", "* the number of shots ('None' being infinite shots)." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "87fed844-e812-4ae1-bd2b-d8ca1b60e4a3", "metadata": {}, "outputs": [], "source": [ - "from quask.core import Ansatz, Kernel, KernelFactory, KernelType\n", + "from quask.core import Ansatz, KernelFactory, KernelType\n", "from quask.core_implementation import PennylaneKernel\n", "\n", "def create_pennylane_noiseless(ansatz: Ansatz, measurement: str, type: KernelType):\n", @@ -177,12 +152,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "35b79ebe-801e-4c59-9ff2-246d7e0c16db", "metadata": {}, "outputs": [], "source": [ - "from quask.core import Ansatz, Kernel, KernelFactory, KernelType\n", + "from quask.core import Ansatz, KernelFactory, KernelType\n", "from quask.core_implementation import BraketKernel\n", " \n", "def create_braket(ansatz: Ansatz, measurement: str, type: KernelType):\n", @@ -217,9 +192,11 @@ ] }, { - "cell_type": "raw", + "cell_type": "code", + "execution_count": null, "id": "093d368c", "metadata": {}, + "outputs": [], "source": [ "# !pip install qibo" ] @@ -245,7 +222,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "66c8b270-0760-4743-a718-3f77c7a0967a", "metadata": {}, "outputs": [], @@ -294,7 +271,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -308,7 +285,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.0" + "version": "3.11.11+" } }, "nbformat": 4, diff --git a/docs/source/notebooks/quask_1_evaluators.ipynb b/docs/source/notebooks/quask_1_evaluators.ipynb index 122dcd7..e8d4cb3 100644 --- a/docs/source/notebooks/quask_1_evaluators.ipynb +++ b/docs/source/notebooks/quask_1_evaluators.ipynb @@ -41,12 +41,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "938ac932-729f-484f-a914-23e3d88b6782", "metadata": {}, "outputs": [], "source": [ "from quask.evaluator import HaarEvaluator\n", + "\n", "n = 100 # number of bins discretizing the histogram\n", "m = 10000 #number of randomly sampled data for creating the ansatz's ensemble of states\n", "h_eval = HaarEvaluator(n, m)" @@ -64,7 +65,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "36359d8b-8554-446b-91e1-eba97bfcf692", "metadata": {}, "outputs": [], @@ -86,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "1dace440-d38d-4fcb-9f8c-832760f1760b", "metadata": {}, "outputs": [], @@ -117,7 +118,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "70bfcef1-3853-401c-a9f7-cec61fe3f4d2", "metadata": {}, "outputs": [], @@ -153,12 +154,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "661b3276-602e-47a5-b390-f7e14ed019c3", "metadata": {}, "outputs": [], "source": [ "from quask.evaluator import KernelAlignmentEvaluator\n", + "\n", "ka_eval = KernelAlignmentEvaluator()" ] }, @@ -174,12 +176,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "4ab4991c-9ea9-41f7-ab22-683cb3b949cc", "metadata": {}, "outputs": [], "source": [ "from quask.evaluator import CenteredKernelAlignmentEvaluator\n", + "\n", "cka_eval = CenteredKernelAlignmentEvaluator()" ] }, @@ -193,12 +196,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "b38103f8-ad3d-47ee-935a-5f8a5c04a4e5", "metadata": {}, "outputs": [], "source": [ "from quask.evaluator import RidgeGeneralizationEvaluator\n", + "\n", "rg_eval = RidgeGeneralizationEvaluator()" ] }, @@ -214,12 +218,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "dcfd35cf-458d-48ce-b48d-cd5c8c5b4c9f", "metadata": {}, "outputs": [], "source": [ "from quask.evaluator import EssModelComplexityEvaluator\n", + "\n", "smc_eval = EssModelComplexityEvaluator()" ] }, @@ -235,12 +240,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "4de53f91-2057-4dd9-94a9-ad9832fa21b6", "metadata": {}, "outputs": [], "source": [ "from quask.evaluator import SpectralBiasEvaluator\n", + "\n", "sb_eval = SpectralBiasEvaluator(10)" ] }, @@ -288,7 +294,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -302,7 +308,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.12" + "version": "3.11.11+" } }, "nbformat": 4, diff --git a/pdm.lock b/pdm.lock new file mode 100644 index 0000000..1301fd0 --- /dev/null +++ b/pdm.lock @@ -0,0 +1,1608 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default", "demo"] +strategy = ["inherit_metadata"] +lock_version = "4.5.0" +content_hash = "sha256:9afc2122ebb2ee0d9d31ff6ff9cbb3c9e91a2ef962d60ff8427e9e6cca972941" + +[[metadata.targets]] +requires_python = ">=3.10" + +[[package]] +name = "annotated-types" +version = "0.7.0" +requires_python = ">=3.8" +summary = "Reusable constraint types to use with typing.Annotated" +groups = ["default"] +dependencies = [ + "typing-extensions>=4.0.0; python_version < \"3.9\"", +] +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "appdirs" +version = "1.4.4" +summary = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +groups = ["default"] +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 = "appnope" +version = "0.1.4" +requires_python = ">=3.6" +summary = "Disable App Nap on macOS >= 10.9" +groups = ["demo"] +marker = "platform_system == \"Darwin\"" +files = [ + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, +] + +[[package]] +name = "asttokens" +version = "3.0.0" +requires_python = ">=3.8" +summary = "Annotate AST trees with source code positions" +groups = ["demo"] +files = [ + {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"}, + {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"}, +] + +[[package]] +name = "astunparse" +version = "1.6.3" +summary = "An AST unparser for Python" +groups = ["default"] +dependencies = [ + "six<2.0,>=1.6.1", + "wheel<1.0,>=0.23.0", +] +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]] +name = "autograd" +version = "1.7.0" +requires_python = ">=3.8" +summary = "Efficiently computes derivatives of NumPy code." +groups = ["default"] +dependencies = [ + "numpy", +] +files = [ + {file = "autograd-1.7.0-py3-none-any.whl", hash = "sha256:49680300f842f3a8722b060ac0d3ed7aca071d1ad4d3d38c9fdadafdcc73c30b"}, + {file = "autograd-1.7.0.tar.gz", hash = "sha256:de743fd368d6df523cd37305dcd171861a9752a144493677d2c9f5a56983ff2f"}, +] + +[[package]] +name = "autoray" +version = "0.7.0" +requires_python = ">=3.9" +summary = "Abstract your array operations." +groups = ["default"] +files = [ + {file = "autoray-0.7.0-py3-none-any.whl", hash = "sha256:03103957df3d1b66b8068158056c2909a72095b19d1b24262261276a714a5d07"}, + {file = "autoray-0.7.0.tar.gz", hash = "sha256:7829d21258512f87e02f23ce74ae5759af4ce8998069d2cce53468f1d701a219"}, +] + +[[package]] +name = "cachetools" +version = "5.5.1" +requires_python = ">=3.7" +summary = "Extensible memoizing collections and decorators" +groups = ["default"] +files = [ + {file = "cachetools-5.5.1-py3-none-any.whl", hash = "sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb"}, + {file = "cachetools-5.5.1.tar.gz", hash = "sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95"}, +] + +[[package]] +name = "certifi" +version = "2025.1.31" +requires_python = ">=3.6" +summary = "Python package for providing Mozilla's CA Bundle." +groups = ["default"] +files = [ + {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, + {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, +] + +[[package]] +name = "cffi" +version = "1.17.1" +requires_python = ">=3.8" +summary = "Foreign Function Interface for Python calling C code." +groups = ["default", "demo"] +marker = "implementation_name == \"pypy\" or platform_python_implementation != \"PyPy\"" +dependencies = [ + "pycparser", +] +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.1" +requires_python = ">=3.7" +summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +groups = ["default"] +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +summary = "Cross-platform colored terminal text." +groups = ["demo"] +marker = "sys_platform == \"win32\"" +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 = "comm" +version = "0.2.2" +requires_python = ">=3.8" +summary = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." +groups = ["demo"] +dependencies = [ + "traitlets>=4", +] +files = [ + {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, + {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, +] + +[[package]] +name = "cryptography" +version = "44.0.0" +requires_python = "!=3.9.0,!=3.9.1,>=3.7" +summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +groups = ["default"] +dependencies = [ + "cffi>=1.12; platform_python_implementation != \"PyPy\"", +] +files = [ + {file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543"}, + {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e"}, + {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e"}, + {file = "cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053"}, + {file = "cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd"}, + {file = "cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c"}, + {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64"}, + {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285"}, + {file = "cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417"}, + {file = "cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c"}, + {file = "cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02"}, +] + +[[package]] +name = "debugpy" +version = "1.8.12" +requires_python = ">=3.8" +summary = "An implementation of the Debug Adapter Protocol for Python" +groups = ["demo"] +files = [ + {file = "debugpy-1.8.12-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:a2ba7ffe58efeae5b8fad1165357edfe01464f9aef25e814e891ec690e7dd82a"}, + {file = "debugpy-1.8.12-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbbd4149c4fc5e7d508ece083e78c17442ee13b0e69bfa6bd63003e486770f45"}, + {file = "debugpy-1.8.12-cp310-cp310-win32.whl", hash = "sha256:b202f591204023b3ce62ff9a47baa555dc00bb092219abf5caf0e3718ac20e7c"}, + {file = "debugpy-1.8.12-cp310-cp310-win_amd64.whl", hash = "sha256:9649eced17a98ce816756ce50433b2dd85dfa7bc92ceb60579d68c053f98dff9"}, + {file = "debugpy-1.8.12-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:36f4829839ef0afdfdd208bb54f4c3d0eea86106d719811681a8627ae2e53dd5"}, + {file = "debugpy-1.8.12-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a28ed481d530e3138553be60991d2d61103ce6da254e51547b79549675f539b7"}, + {file = "debugpy-1.8.12-cp311-cp311-win32.whl", hash = "sha256:4ad9a94d8f5c9b954e0e3b137cc64ef3f579d0df3c3698fe9c3734ee397e4abb"}, + {file = "debugpy-1.8.12-cp311-cp311-win_amd64.whl", hash = "sha256:4703575b78dd697b294f8c65588dc86874ed787b7348c65da70cfc885efdf1e1"}, + {file = "debugpy-1.8.12-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:7e94b643b19e8feb5215fa508aee531387494bf668b2eca27fa769ea11d9f498"}, + {file = "debugpy-1.8.12-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:086b32e233e89a2740c1615c2f775c34ae951508b28b308681dbbb87bba97d06"}, + {file = "debugpy-1.8.12-cp312-cp312-win32.whl", hash = "sha256:2ae5df899732a6051b49ea2632a9ea67f929604fd2b036613a9f12bc3163b92d"}, + {file = "debugpy-1.8.12-cp312-cp312-win_amd64.whl", hash = "sha256:39dfbb6fa09f12fae32639e3286112fc35ae976114f1f3d37375f3130a820969"}, + {file = "debugpy-1.8.12-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:696d8ae4dff4cbd06bf6b10d671e088b66669f110c7c4e18a44c43cf75ce966f"}, + {file = "debugpy-1.8.12-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:898fba72b81a654e74412a67c7e0a81e89723cfe2a3ea6fcd3feaa3395138ca9"}, + {file = "debugpy-1.8.12-cp313-cp313-win32.whl", hash = "sha256:22a11c493c70413a01ed03f01c3c3a2fc4478fc6ee186e340487b2edcd6f4180"}, + {file = "debugpy-1.8.12-cp313-cp313-win_amd64.whl", hash = "sha256:fdb3c6d342825ea10b90e43d7f20f01535a72b3a1997850c0c3cefa5c27a4a2c"}, + {file = "debugpy-1.8.12-py2.py3-none-any.whl", hash = "sha256:274b6a2040349b5c9864e475284bce5bb062e63dce368a394b8cc865ae3b00c6"}, + {file = "debugpy-1.8.12.tar.gz", hash = "sha256:646530b04f45c830ceae8e491ca1c9320a2d2f0efea3141487c82130aba70dce"}, +] + +[[package]] +name = "decorator" +version = "5.1.1" +requires_python = ">=3.5" +summary = "Decorators for Humans" +groups = ["demo"] +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 = "diastatic-malt" +version = "2.15.2" +requires_python = ">=3.9" +summary = "A library for Python operator overloading" +groups = ["default"] +dependencies = [ + "astunparse", + "gast", + "termcolor", +] +files = [ + {file = "diastatic-malt-2.15.2.tar.gz", hash = "sha256:7eb90d8c30b7ff16b4e84c3a65de2ff7f5b7b9d0f5cdea23918e747ff7fb5320"}, + {file = "diastatic_malt-2.15.2-py3-none-any.whl", hash = "sha256:85429257b356030f101c31b2c7d506c4829f21bd865aed796766f900d7908407"}, +] + +[[package]] +name = "dill" +version = "0.3.9" +requires_python = ">=3.8" +summary = "serialize all of Python" +groups = ["default"] +files = [ + {file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"}, + {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +requires_python = ">=3.7" +summary = "Backport of PEP 654 (exception groups)" +groups = ["demo"] +marker = "python_version < \"3.11\"" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[[package]] +name = "executing" +version = "2.2.0" +requires_python = ">=3.8" +summary = "Get the currently executing AST node of a frame, and other information" +groups = ["demo"] +files = [ + {file = "executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa"}, + {file = "executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755"}, +] + +[[package]] +name = "gast" +version = "0.6.0" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +summary = "Python AST that abstracts the underlying Python version" +groups = ["default"] +files = [ + {file = "gast-0.6.0-py3-none-any.whl", hash = "sha256:52b182313f7330389f72b069ba00f174cfe2a06411099547288839c6cbafbd54"}, + {file = "gast-0.6.0.tar.gz", hash = "sha256:88fc5300d32c7ac6ca7b515310862f71e6fdf2c029bbec7c66c0f5dd47b6b1fb"}, +] + +[[package]] +name = "ibm-cloud-sdk-core" +version = "3.22.1" +requires_python = ">=3.9" +summary = "Core library used by SDKs for IBM Cloud Services" +groups = ["default"] +dependencies = [ + "PyJWT<3.0.0,>=2.8.0", + "python-dateutil<3.0.0,>=2.8.2", + "requests<3.0.0,>=2.31.0", + "urllib3<3.0.0,>=2.1.0", +] +files = [ + {file = "ibm_cloud_sdk_core-3.22.1-py3-none-any.whl", hash = "sha256:d2195d34705b24c7e3a59ad51f01a974defc5bee3576570d9a0e219139550dd4"}, + {file = "ibm_cloud_sdk_core-3.22.1.tar.gz", hash = "sha256:096dd22c146848a87053f8f2bfbd5dfdf089eefe81ee1c448ca22c4304751dfd"}, +] + +[[package]] +name = "ibm-platform-services" +version = "0.59.1" +requires_python = ">=3.9" +summary = "Python client library for IBM Cloud Platform Services" +groups = ["default"] +dependencies = [ + "ibm-cloud-sdk-core<4.0.0,>=3.22.0", +] +files = [ + {file = "ibm_platform_services-0.59.1-py3-none-any.whl", hash = "sha256:bc9a324c387d2ed5d544f5cab597f50ab55a4426f7c1b40a51162a46f9f62962"}, + {file = "ibm_platform_services-0.59.1.tar.gz", hash = "sha256:5d0f5a64ddb0cc2dfbeb89da0df611faa9b2494a091f8bba5e8f44a497e7c0c3"}, +] + +[[package]] +name = "idna" +version = "3.10" +requires_python = ">=3.6" +summary = "Internationalized Domain Names in Applications (IDNA)" +groups = ["default"] +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[[package]] +name = "ipykernel" +version = "6.29.5" +requires_python = ">=3.8" +summary = "IPython Kernel for Jupyter" +groups = ["demo"] +dependencies = [ + "appnope; platform_system == \"Darwin\"", + "comm>=0.1.1", + "debugpy>=1.6.5", + "ipython>=7.23.1", + "jupyter-client>=6.1.12", + "jupyter-core!=5.0.*,>=4.12", + "matplotlib-inline>=0.1", + "nest-asyncio", + "packaging", + "psutil", + "pyzmq>=24", + "tornado>=6.1", + "traitlets>=5.4.0", +] +files = [ + {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, + {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, +] + +[[package]] +name = "ipython" +version = "8.32.0" +requires_python = ">=3.10" +summary = "IPython: Productive Interactive Computing" +groups = ["demo"] +dependencies = [ + "colorama; sys_platform == \"win32\"", + "decorator", + "exceptiongroup; python_version < \"3.11\"", + "jedi>=0.16", + "matplotlib-inline", + "pexpect>4.3; sys_platform != \"win32\" and sys_platform != \"emscripten\"", + "prompt-toolkit<3.1.0,>=3.0.41", + "pygments>=2.4.0", + "stack-data", + "traitlets>=5.13.0", + "typing-extensions>=4.6; python_version < \"3.12\"", +] +files = [ + {file = "ipython-8.32.0-py3-none-any.whl", hash = "sha256:cae85b0c61eff1fc48b0a8002de5958b6528fa9c8defb1894da63f42613708aa"}, + {file = "ipython-8.32.0.tar.gz", hash = "sha256:be2c91895b0b9ea7ba49d33b23e2040c352b33eb6a519cca7ce6e0c743444251"}, +] + +[[package]] +name = "jedi" +version = "0.19.2" +requires_python = ">=3.6" +summary = "An autocompletion tool for Python that can be used for text editors." +groups = ["demo"] +dependencies = [ + "parso<0.9.0,>=0.8.4", +] +files = [ + {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, + {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, +] + +[[package]] +name = "joblib" +version = "1.4.2" +requires_python = ">=3.8" +summary = "Lightweight pipelining with Python functions" +groups = ["default"] +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + +[[package]] +name = "jupyter-client" +version = "8.6.3" +requires_python = ">=3.8" +summary = "Jupyter protocol implementation and client libraries" +groups = ["demo"] +dependencies = [ + "importlib-metadata>=4.8.3; python_version < \"3.10\"", + "jupyter-core!=5.0.*,>=4.12", + "python-dateutil>=2.8.2", + "pyzmq>=23.0", + "tornado>=6.2", + "traitlets>=5.3", +] +files = [ + {file = "jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f"}, + {file = "jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419"}, +] + +[[package]] +name = "jupyter-core" +version = "5.7.2" +requires_python = ">=3.8" +summary = "Jupyter core package. A base package on which Jupyter projects rely." +groups = ["demo"] +dependencies = [ + "platformdirs>=2.5", + "pywin32>=300; sys_platform == \"win32\" and platform_python_implementation != \"PyPy\"", + "traitlets>=5.3", +] +files = [ + {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, + {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, +] + +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +requires_python = ">=3.8" +summary = "Inline Matplotlib backend for Jupyter" +groups = ["demo"] +dependencies = [ + "traitlets", +] +files = [ + {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, + {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +summary = "Python library for arbitrary-precision floating-point arithmetic" +groups = ["default"] +files = [ + {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, + {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +requires_python = ">=3.5" +summary = "Patch asyncio to allow nested event loops" +groups = ["demo"] +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + +[[package]] +name = "networkx" +version = "3.4.2" +requires_python = ">=3.10" +summary = "Python package for creating and manipulating graphs and networks" +groups = ["default"] +files = [ + {file = "networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"}, + {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, +] + +[[package]] +name = "numpy" +version = "2.0.2" +requires_python = ">=3.9" +summary = "Fundamental package for array computing in Python" +groups = ["default"] +files = [ + {file = "numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece"}, + {file = "numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04"}, + {file = "numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66"}, + {file = "numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b"}, + {file = "numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd"}, + {file = "numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318"}, + {file = "numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8"}, + {file = "numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326"}, + {file = "numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97"}, + {file = "numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131"}, + {file = "numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448"}, + {file = "numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195"}, + {file = "numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57"}, + {file = "numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a"}, + {file = "numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669"}, + {file = "numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951"}, + {file = "numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9"}, + {file = "numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15"}, + {file = "numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4"}, + {file = "numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc"}, + {file = "numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b"}, + {file = "numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e"}, + {file = "numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c"}, + {file = "numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c"}, + {file = "numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692"}, + {file = "numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a"}, + {file = "numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c"}, + {file = "numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded"}, + {file = "numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5"}, + {file = "numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a"}, + {file = "numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78"}, +] + +[[package]] +name = "packaging" +version = "24.2" +requires_python = ">=3.8" +summary = "Core utilities for Python packages" +groups = ["default", "demo"] +files = [ + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, +] + +[[package]] +name = "pandas" +version = "2.2.3" +requires_python = ">=3.9" +summary = "Powerful data structures for data analysis, time series, and statistics" +groups = ["default"] +dependencies = [ + "numpy>=1.22.4; python_version < \"3.11\"", + "numpy>=1.23.2; python_version == \"3.11\"", + "numpy>=1.26.0; python_version >= \"3.12\"", + "python-dateutil>=2.8.2", + "pytz>=2020.1", + "tzdata>=2022.7", +] +files = [ + {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, + {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"}, + {file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"}, + {file = "pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039"}, + {file = "pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd"}, + {file = "pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698"}, + {file = "pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc"}, + {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3"}, + {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32"}, + {file = "pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5"}, + {file = "pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9"}, + {file = "pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4"}, + {file = "pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3"}, + {file = "pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319"}, + {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8"}, + {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a"}, + {file = "pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13"}, + {file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"}, + {file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"}, + {file = "pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0"}, + {file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"}, + {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659"}, + {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"}, + {file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"}, + {file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"}, + {file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"}, + {file = "pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2"}, + {file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"}, + {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d"}, + {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"}, + {file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"}, +] + +[[package]] +name = "parso" +version = "0.8.4" +requires_python = ">=3.6" +summary = "A Python Parser" +groups = ["demo"] +files = [ + {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, + {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, +] + +[[package]] +name = "pbr" +version = "6.1.1" +requires_python = ">=2.6" +summary = "Python Build Reasonableness" +groups = ["default"] +dependencies = [ + "setuptools", +] +files = [ + {file = "pbr-6.1.1-py2.py3-none-any.whl", hash = "sha256:38d4daea5d9fa63b3f626131b9d34947fd0c8be9b05a29276870580050a25a76"}, + {file = "pbr-6.1.1.tar.gz", hash = "sha256:93ea72ce6989eb2eed99d0f75721474f69ad88128afdef5ac377eb797c4bf76b"}, +] + +[[package]] +name = "pennylane" +version = "0.40.0" +summary = "PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network." +groups = ["default"] +dependencies = [ + "appdirs", + "autograd", + "autoray>=0.6.11", + "cachetools", + "diastatic-malt", + "networkx", + "numpy<2.1", + "packaging", + "pennylane-lightning>=0.40", + "requests", + "rustworkx>=0.14.0", + "scipy", + "tomlkit", + "typing-extensions", +] +files = [ + {file = "PennyLane-0.40.0-py3-none-any.whl", hash = "sha256:c93bb48ff80833edaf424b3b91e01a56cd25b22170bc99b7e53e7168a1ad4dd1"}, +] + +[[package]] +name = "pennylane-lightning" +version = "0.40.0" +requires_python = ">=3.10" +summary = "PennyLane-Lightning plugin" +groups = ["default"] +dependencies = [ + "pennylane>=0.37", + "scipy-openblas32>=0.3.26", +] +files = [ + {file = "PennyLane_Lightning-0.40.0-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:3a6915cc17ce99cd4f3d04dcf7d579f59cecdc2866cd4e8e1c33478d86101437"}, + {file = "PennyLane_Lightning-0.40.0-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:4a66e8c644f634f9d1fda6b9223f5cc106acf4146334a25a23f948ec59b075c0"}, + {file = "PennyLane_Lightning-0.40.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:a58ab1489fee0424840bc8f91e8f7e32ecc3338a714b2fe1bf68a9026a5a295a"}, + {file = "PennyLane_Lightning-0.40.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:7fe9262c602b6c7f0ab893468867e24c63e9cacc7d77e19b448ac1361bb86a47"}, + {file = "PennyLane_Lightning-0.40.0-cp310-cp310-win_amd64.whl", hash = "sha256:3f75b7d39d63880e9d59562d78ae5ec63d2aed936b2feee3c937dfbcd080b834"}, + {file = "PennyLane_Lightning-0.40.0-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:99cf7bcfb3a2a29838cc12f0001e3e7e02d35c5c1d696ce2e5ba0c3f2995c4d9"}, + {file = "PennyLane_Lightning-0.40.0-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:6b89ad785e16cc3b3d155b1abd27e42fcb5854a0e2d90452f6445fc0e80b1cf4"}, + {file = "PennyLane_Lightning-0.40.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:20052041abc417d74d1794506d4340a8a2298b858e2b94591704e73670d913f9"}, + {file = "PennyLane_Lightning-0.40.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a3db3cf2c3caed80ce561b66bb4bf6b5712ecf0b08db986f24c4ff9e187e82b3"}, + {file = "PennyLane_Lightning-0.40.0-cp311-cp311-win_amd64.whl", hash = "sha256:fed88008b7d468cb1d0e5b3ef92d87f9b600d0896d21eff43655a521cc841d7b"}, + {file = "PennyLane_Lightning-0.40.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:e3152f6b53390281334257554ecad90566cd4d200187971d238d2c7691000466"}, + {file = "PennyLane_Lightning-0.40.0-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:8a4ff3f1d82f664e6d608d155cb019b189aac676c6c7cb40c4f92b15e0d2d485"}, + {file = "PennyLane_Lightning-0.40.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:b2209727b8c914c8101087da188cbbc7b332bb77ceab4b6791c7ed7b3c5a942c"}, + {file = "PennyLane_Lightning-0.40.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:2ba97b4d6aa0a6eb774413ea3272d418959b792de6df8e4196171cad450f25af"}, + {file = "PennyLane_Lightning-0.40.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7715c84290fc1291e315d2c0d2bf5719cbe86e3e92fb538393ab130b3f5ba2"}, + {file = "PennyLane_Lightning-0.40.0-py3-none-any.whl", hash = "sha256:96390ce82767b3a66c4f8e0b1bcec2f4f15fb317652cffa9815e371e74458197"}, + {file = "pennylane_lightning-0.40.0.tar.gz", hash = "sha256:edc95e75ef1b4e6dba96e914893175f9448d4d1b53a6e78614cb7587a8a22f2f"}, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +summary = "Pexpect allows easy control of interactive console applications." +groups = ["demo"] +marker = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" +dependencies = [ + "ptyprocess>=0.5", +] +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +requires_python = ">=3.8" +summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +groups = ["demo"] +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.50" +requires_python = ">=3.8.0" +summary = "Library for building powerful interactive command lines in Python" +groups = ["demo"] +dependencies = [ + "wcwidth", +] +files = [ + {file = "prompt_toolkit-3.0.50-py3-none-any.whl", hash = "sha256:9b6427eb19e479d98acff65196a307c555eb567989e6d88ebbb1b509d9779198"}, + {file = "prompt_toolkit-3.0.50.tar.gz", hash = "sha256:544748f3860a2623ca5cd6d2795e7a14f3d0e1c3c9728359013f79877fc89bab"}, +] + +[[package]] +name = "psutil" +version = "6.1.1" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +summary = "Cross-platform lib for process and system monitoring in Python." +groups = ["demo"] +files = [ + {file = "psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8"}, + {file = "psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3"}, + {file = "psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53"}, + {file = "psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649"}, + {file = "psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5"}, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +summary = "Run a subprocess in a pseudo terminal" +groups = ["demo"] +marker = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +summary = "Safely evaluate AST nodes without side effects" +groups = ["demo"] +files = [ + {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, + {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, +] + +[[package]] +name = "pycparser" +version = "2.22" +requires_python = ">=3.8" +summary = "C parser in Python" +groups = ["default", "demo"] +marker = "implementation_name == \"pypy\" or platform_python_implementation != \"PyPy\"" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pydantic" +version = "2.9.2" +requires_python = ">=3.8" +summary = "Data validation using Python type hints" +groups = ["default"] +dependencies = [ + "annotated-types>=0.6.0", + "pydantic-core==2.23.4", + "typing-extensions>=4.12.2; python_version >= \"3.13\"", + "typing-extensions>=4.6.1; python_version < \"3.13\"", +] +files = [ + {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, + {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, +] + +[[package]] +name = "pydantic-core" +version = "2.23.4" +requires_python = ">=3.8" +summary = "Core functionality for Pydantic validation and serialization" +groups = ["default"] +dependencies = [ + "typing-extensions!=4.7.0,>=4.6.0", +] +files = [ + {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, + {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, + {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, + {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, + {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, + {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, + {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, + {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, + {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, + {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, + {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, + {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, + {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, + {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, + {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, + {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, + {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, + {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, + {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, + {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, + {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, +] + +[[package]] +name = "pygments" +version = "2.19.1" +requires_python = ">=3.8" +summary = "Pygments is a syntax highlighting package written in Python." +groups = ["demo"] +files = [ + {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, + {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, +] + +[[package]] +name = "pyjwt" +version = "2.10.1" +requires_python = ">=3.9" +summary = "JSON Web Token implementation in Python" +groups = ["default"] +files = [ + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, +] + +[[package]] +name = "pyspnego" +version = "0.11.2" +requires_python = ">=3.8" +summary = "Windows Negotiate Authentication Client and Server" +groups = ["default"] +dependencies = [ + "cryptography", + "sspilib>=0.1.0; sys_platform == \"win32\"", +] +files = [ + {file = "pyspnego-0.11.2-py3-none-any.whl", hash = "sha256:74abc1fb51e59360eb5c5c9086e5962174f1072c7a50cf6da0bda9a4bcfdfbd4"}, + {file = "pyspnego-0.11.2.tar.gz", hash = "sha256:994388d308fb06e4498365ce78d222bf4f3570b6df4ec95738431f61510c971b"}, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +summary = "Extensions to the standard Python datetime module" +groups = ["default", "demo"] +dependencies = [ + "six>=1.5", +] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[[package]] +name = "pytz" +version = "2025.1" +summary = "World timezone definitions, modern and historical" +groups = ["default"] +files = [ + {file = "pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57"}, + {file = "pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e"}, +] + +[[package]] +name = "pywin32" +version = "308" +summary = "Python for Window Extensions" +groups = ["demo"] +marker = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\"" +files = [ + {file = "pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e"}, + {file = "pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e"}, + {file = "pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c"}, + {file = "pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a"}, + {file = "pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b"}, + {file = "pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6"}, + {file = "pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897"}, + {file = "pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47"}, + {file = "pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091"}, + {file = "pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed"}, + {file = "pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4"}, + {file = "pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd"}, +] + +[[package]] +name = "pyzmq" +version = "26.2.1" +requires_python = ">=3.7" +summary = "Python bindings for 0MQ" +groups = ["demo"] +dependencies = [ + "cffi; implementation_name == \"pypy\"", +] +files = [ + {file = "pyzmq-26.2.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:f39d1227e8256d19899d953e6e19ed2ccb689102e6d85e024da5acf410f301eb"}, + {file = "pyzmq-26.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a23948554c692df95daed595fdd3b76b420a4939d7a8a28d6d7dea9711878641"}, + {file = "pyzmq-26.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95f5728b367a042df146cec4340d75359ec6237beebf4a8f5cf74657c65b9257"}, + {file = "pyzmq-26.2.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95f7b01b3f275504011cf4cf21c6b885c8d627ce0867a7e83af1382ebab7b3ff"}, + {file = "pyzmq-26.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80a00370a2ef2159c310e662c7c0f2d030f437f35f478bb8b2f70abd07e26b24"}, + {file = "pyzmq-26.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:8531ed35dfd1dd2af95f5d02afd6545e8650eedbf8c3d244a554cf47d8924459"}, + {file = "pyzmq-26.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cdb69710e462a38e6039cf17259d328f86383a06c20482cc154327968712273c"}, + {file = "pyzmq-26.2.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e7eeaef81530d0b74ad0d29eec9997f1c9230c2f27242b8d17e0ee67662c8f6e"}, + {file = "pyzmq-26.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:361edfa350e3be1f987e592e834594422338d7174364763b7d3de5b0995b16f3"}, + {file = "pyzmq-26.2.1-cp310-cp310-win32.whl", hash = "sha256:637536c07d2fb6a354988b2dd1d00d02eb5dd443f4bbee021ba30881af1c28aa"}, + {file = "pyzmq-26.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:45fad32448fd214fbe60030aa92f97e64a7140b624290834cc9b27b3a11f9473"}, + {file = "pyzmq-26.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:d9da0289d8201c8a29fd158aaa0dfe2f2e14a181fd45e2dc1fbf969a62c1d594"}, + {file = "pyzmq-26.2.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:c059883840e634a21c5b31d9b9a0e2b48f991b94d60a811092bc37992715146a"}, + {file = "pyzmq-26.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed038a921df836d2f538e509a59cb638df3e70ca0fcd70d0bf389dfcdf784d2a"}, + {file = "pyzmq-26.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9027a7fcf690f1a3635dc9e55e38a0d6602dbbc0548935d08d46d2e7ec91f454"}, + {file = "pyzmq-26.2.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d75fcb00a1537f8b0c0bb05322bc7e35966148ffc3e0362f0369e44a4a1de99"}, + {file = "pyzmq-26.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0019cc804ac667fb8c8eaecdb66e6d4a68acf2e155d5c7d6381a5645bd93ae4"}, + {file = "pyzmq-26.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:f19dae58b616ac56b96f2e2290f2d18730a898a171f447f491cc059b073ca1fa"}, + {file = "pyzmq-26.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f5eeeb82feec1fc5cbafa5ee9022e87ffdb3a8c48afa035b356fcd20fc7f533f"}, + {file = "pyzmq-26.2.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:000760e374d6f9d1a3478a42ed0c98604de68c9e94507e5452951e598ebecfba"}, + {file = "pyzmq-26.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:817fcd3344d2a0b28622722b98500ae9c8bfee0f825b8450932ff19c0b15bebd"}, + {file = "pyzmq-26.2.1-cp311-cp311-win32.whl", hash = "sha256:88812b3b257f80444a986b3596e5ea5c4d4ed4276d2b85c153a6fbc5ca457ae7"}, + {file = "pyzmq-26.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:ef29630fde6022471d287c15c0a2484aba188adbfb978702624ba7a54ddfa6c1"}, + {file = "pyzmq-26.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:f32718ee37c07932cc336096dc7403525301fd626349b6eff8470fe0f996d8d7"}, + {file = "pyzmq-26.2.1-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:a6549ecb0041dafa55b5932dcbb6c68293e0bd5980b5b99f5ebb05f9a3b8a8f3"}, + {file = "pyzmq-26.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0250c94561f388db51fd0213cdccbd0b9ef50fd3c57ce1ac937bf3034d92d72e"}, + {file = "pyzmq-26.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36ee4297d9e4b34b5dc1dd7ab5d5ea2cbba8511517ef44104d2915a917a56dc8"}, + {file = "pyzmq-26.2.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2a9cb17fd83b7a3a3009901aca828feaf20aa2451a8a487b035455a86549c09"}, + {file = "pyzmq-26.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:786dd8a81b969c2081b31b17b326d3a499ddd1856e06d6d79ad41011a25148da"}, + {file = "pyzmq-26.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:2d88ba221a07fc2c5581565f1d0fe8038c15711ae79b80d9462e080a1ac30435"}, + {file = "pyzmq-26.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1c84c1297ff9f1cd2440da4d57237cb74be21fdfe7d01a10810acba04e79371a"}, + {file = "pyzmq-26.2.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46d4ebafc27081a7f73a0f151d0c38d4291656aa134344ec1f3d0199ebfbb6d4"}, + {file = "pyzmq-26.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:91e2bfb8e9a29f709d51b208dd5f441dc98eb412c8fe75c24ea464734ccdb48e"}, + {file = "pyzmq-26.2.1-cp312-cp312-win32.whl", hash = "sha256:4a98898fdce380c51cc3e38ebc9aa33ae1e078193f4dc641c047f88b8c690c9a"}, + {file = "pyzmq-26.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0741edbd0adfe5f30bba6c5223b78c131b5aa4a00a223d631e5ef36e26e6d13"}, + {file = "pyzmq-26.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:e5e33b1491555843ba98d5209439500556ef55b6ab635f3a01148545498355e5"}, + {file = "pyzmq-26.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:099b56ef464bc355b14381f13355542e452619abb4c1e57a534b15a106bf8e23"}, + {file = "pyzmq-26.2.1-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:651726f37fcbce9f8dd2a6dab0f024807929780621890a4dc0c75432636871be"}, + {file = "pyzmq-26.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57dd4d91b38fa4348e237a9388b4423b24ce9c1695bbd4ba5a3eada491e09399"}, + {file = "pyzmq-26.2.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d51a7bfe01a48e1064131f3416a5439872c533d756396be2b39e3977b41430f9"}, + {file = "pyzmq-26.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7154d228502e18f30f150b7ce94f0789d6b689f75261b623f0fdc1eec642aab"}, + {file = "pyzmq-26.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:f1f31661a80cc46aba381bed475a9135b213ba23ca7ff6797251af31510920ce"}, + {file = "pyzmq-26.2.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:290c96f479504439b6129a94cefd67a174b68ace8a8e3f551b2239a64cfa131a"}, + {file = "pyzmq-26.2.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f2c307fbe86e18ab3c885b7e01de942145f539165c3360e2af0f094dd440acd9"}, + {file = "pyzmq-26.2.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:b314268e716487bfb86fcd6f84ebbe3e5bec5fac75fdf42bc7d90fdb33f618ad"}, + {file = "pyzmq-26.2.1-cp313-cp313-win32.whl", hash = "sha256:edb550616f567cd5603b53bb52a5f842c0171b78852e6fc7e392b02c2a1504bb"}, + {file = "pyzmq-26.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:100a826a029c8ef3d77a1d4c97cbd6e867057b5806a7276f2bac1179f893d3bf"}, + {file = "pyzmq-26.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:6991ee6c43e0480deb1b45d0c7c2bac124a6540cba7db4c36345e8e092da47ce"}, + {file = "pyzmq-26.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:25e720dba5b3a3bb2ad0ad5d33440babd1b03438a7a5220511d0c8fa677e102e"}, + {file = "pyzmq-26.2.1-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:9ec6abfb701437142ce9544bd6a236addaf803a32628d2260eb3dbd9a60e2891"}, + {file = "pyzmq-26.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e1eb9d2bfdf5b4e21165b553a81b2c3bd5be06eeddcc4e08e9692156d21f1f6"}, + {file = "pyzmq-26.2.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90dc731d8e3e91bcd456aa7407d2eba7ac6f7860e89f3766baabb521f2c1de4a"}, + {file = "pyzmq-26.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6a93d684278ad865fc0b9e89fe33f6ea72d36da0e842143891278ff7fd89c3"}, + {file = "pyzmq-26.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:c1bb37849e2294d519117dd99b613c5177934e5c04a5bb05dd573fa42026567e"}, + {file = "pyzmq-26.2.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:632a09c6d8af17b678d84df442e9c3ad8e4949c109e48a72f805b22506c4afa7"}, + {file = "pyzmq-26.2.1-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:fc409c18884eaf9ddde516d53af4f2db64a8bc7d81b1a0c274b8aa4e929958e8"}, + {file = "pyzmq-26.2.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:17f88622b848805d3f6427ce1ad5a2aa3cf61f12a97e684dab2979802024d460"}, + {file = "pyzmq-26.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:380816d298aed32b1a97b4973a4865ef3be402a2e760204509b52b6de79d755d"}, + {file = "pyzmq-26.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97cbb368fd0debdbeb6ba5966aa28e9a1ae3396c7386d15569a6ca4be4572b99"}, + {file = "pyzmq-26.2.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf7b5942c6b0dafcc2823ddd9154f419147e24f8df5b41ca8ea40a6db90615c"}, + {file = "pyzmq-26.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fe6e28a8856aea808715f7a4fc11f682b9d29cac5d6262dd8fe4f98edc12d53"}, + {file = "pyzmq-26.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bd8fdee945b877aa3bffc6a5a8816deb048dab0544f9df3731ecd0e54d8c84c9"}, + {file = "pyzmq-26.2.1.tar.gz", hash = "sha256:17d72a74e5e9ff3829deb72897a175333d3ef5b5413948cae3cf7ebf0b02ecca"}, +] + +[[package]] +name = "qiskit" +version = "1.3.2" +requires_python = ">=3.9" +summary = "An open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives." +groups = ["default"] +dependencies = [ + "dill>=0.3", + "numpy<3,>=1.17", + "python-dateutil>=2.8.0", + "rustworkx>=0.15.0", + "scipy>=1.5", + "stevedore>=3.0.0", + "symengine<0.14,>=0.11", + "sympy>=1.3", + "typing-extensions", +] +files = [ + {file = "qiskit-1.3.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:3fe16377787e31c67b87b2baa9fe3239ffab46e1697ed7dfc4687f89f283453b"}, + {file = "qiskit-1.3.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:fc7be685e0f144825201da4c818e370977ab1be07049587899b209beca48a39e"}, + {file = "qiskit-1.3.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f5a91c0f3f90cd1716aa99357965e4011f6f9fa37636c706a8829f7f408384b"}, + {file = "qiskit-1.3.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65d5af561b6e0e98b099fe4b7bf099dcd1f09322fa1d47299ba2b2febc873ec7"}, + {file = "qiskit-1.3.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a24090a779bf8153a99d3d8d56fe161ccfd57ef96ab55d4320b3f376320ad1ce"}, + {file = "qiskit-1.3.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:253fa4d8b27c9dd1462fe67fec7428c2a3784216aa06babbb1a47547fa2afe8f"}, + {file = "qiskit-1.3.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309f6db004ea8044df9ac9359c31dcce0cc12afb6ece6eb035ca86b9bf87a21c"}, + {file = "qiskit-1.3.2-cp39-abi3-win32.whl", hash = "sha256:113a6962b3cd79a0aeeee92072a3e808291e776d8ca7ab25dffaea2e0c288b8d"}, + {file = "qiskit-1.3.2-cp39-abi3-win_amd64.whl", hash = "sha256:8ec122c81f832c1a9202dae6485d402d1444845be2c53809f10d82cb1423e735"}, + {file = "qiskit-1.3.2.tar.gz", hash = "sha256:6e63c619bcc3e29cd59f831af5b161b35951498c272d00da01a3fef7db3743c9"}, +] + +[[package]] +name = "qiskit-ibm-runtime" +version = "0.35.0" +requires_python = ">=3.9" +summary = "IBM Quantum client for Qiskit Runtime." +groups = ["default"] +dependencies = [ + "ibm-platform-services>=0.22.6", + "numpy>=1.13", + "pydantic<2.10,>=2.5.0", + "python-dateutil>=2.8.0", + "qiskit>=1.1.0", + "requests-ntlm>=1.1.0", + "requests>=2.19", + "urllib3>=1.21.1", + "websocket-client>=1.5.1", +] +files = [ + {file = "qiskit_ibm_runtime-0.35.0-py3-none-any.whl", hash = "sha256:a2b6dd7f6d24a632fb17b0fe8cfe30b56310679a8c01a79d641302431360eb6d"}, + {file = "qiskit_ibm_runtime-0.35.0.tar.gz", hash = "sha256:8b5919bfb96215d13ca5b103b8652c194e2e85b78dbe937dc2b6f675646de65f"}, +] + +[[package]] +name = "requests" +version = "2.32.3" +requires_python = ">=3.8" +summary = "Python HTTP for Humans." +groups = ["default"] +dependencies = [ + "certifi>=2017.4.17", + "charset-normalizer<4,>=2", + "idna<4,>=2.5", + "urllib3<3,>=1.21.1", +] +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[[package]] +name = "requests-ntlm" +version = "1.3.0" +requires_python = ">=3.8" +summary = "This package allows for HTTP NTLM authentication using the requests library." +groups = ["default"] +dependencies = [ + "cryptography>=1.3", + "pyspnego>=0.4.0", + "requests>=2.0.0", +] +files = [ + {file = "requests_ntlm-1.3.0-py3-none-any.whl", hash = "sha256:4c7534a7d0e482bb0928531d621be4b2c74ace437e88c5a357ceb7452d25a510"}, + {file = "requests_ntlm-1.3.0.tar.gz", hash = "sha256:b29cc2462623dffdf9b88c43e180ccb735b4007228a542220e882c58ae56c668"}, +] + +[[package]] +name = "rustworkx" +version = "0.16.0" +requires_python = ">=3.9" +summary = "A python graph library implemented in Rust" +groups = ["default"] +dependencies = [ + "numpy<3,>=1.16.0", +] +files = [ + {file = "rustworkx-0.16.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:476a6c67b0142acd941691943750cc6737a48372304489969c2b62d30aaf4c27"}, + {file = "rustworkx-0.16.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:bef2ef42870f806af93979b457e240f6dfa4f867ca33965c620f3a804409ed3a"}, + {file = "rustworkx-0.16.0-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0db3a73bf68b3e66c08322a2fc95d3aa663d037d9b4e49c3509da4898d3529cc"}, + {file = "rustworkx-0.16.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f12a13d7486234fa2a84746d5e41f436bf9df43548043e7a232f48804ff8c61"}, + {file = "rustworkx-0.16.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:89efd5c3a4653ddacc55ca39f28b261d43deec7d678f8f8fc6b76b5087f1dfea"}, + {file = "rustworkx-0.16.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec0c12aac8c54910ace20ac6ada4b890cd39f95f69100514715f8ad7af9041e4"}, + {file = "rustworkx-0.16.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d650e39fc1a1534335f7517358ebfc3478bb235428463cfcd7c5750d50377b33"}, + {file = "rustworkx-0.16.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:293180b83509ee9bff4c3af7ccc1024f6528d61b65d0cb7320bd31924f10cb71"}, + {file = "rustworkx-0.16.0-cp39-abi3-win32.whl", hash = "sha256:040c4368729cf502f756a3b0ff5f1c6915fc389f74dcc6afc6c3833688c97c01"}, + {file = "rustworkx-0.16.0-cp39-abi3-win_amd64.whl", hash = "sha256:905df608843c32fa45ac023687769fe13056edf7584474c801d5c50705d76e9b"}, + {file = "rustworkx-0.16.0.tar.gz", hash = "sha256:9f0dcb83f38d5ca2c3a683eb9b6951c8aec3262fbfe5141946a7ee5ba37e0bb6"}, +] + +[[package]] +name = "scikit-learn" +version = "1.6.1" +requires_python = ">=3.9" +summary = "A set of python modules for machine learning and data mining" +groups = ["default"] +dependencies = [ + "joblib>=1.2.0", + "numpy>=1.19.5", + "scipy>=1.6.0", + "threadpoolctl>=3.1.0", +] +files = [ + {file = "scikit_learn-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d056391530ccd1e501056160e3c9673b4da4805eb67eb2bdf4e983e1f9c9204e"}, + {file = "scikit_learn-1.6.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:0c8d036eb937dbb568c6242fa598d551d88fb4399c0344d95c001980ec1c7d36"}, + {file = "scikit_learn-1.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8634c4bd21a2a813e0a7e3900464e6d593162a29dd35d25bdf0103b3fce60ed5"}, + {file = "scikit_learn-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:775da975a471c4f6f467725dff0ced5c7ac7bda5e9316b260225b48475279a1b"}, + {file = "scikit_learn-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:8a600c31592bd7dab31e1c61b9bbd6dea1b3433e67d264d17ce1017dbdce8002"}, + {file = "scikit_learn-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72abc587c75234935e97d09aa4913a82f7b03ee0b74111dcc2881cba3c5a7b33"}, + {file = "scikit_learn-1.6.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b3b00cdc8f1317b5f33191df1386c0befd16625f49d979fe77a8d44cae82410d"}, + {file = "scikit_learn-1.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc4765af3386811c3ca21638f63b9cf5ecf66261cc4815c1db3f1e7dc7b79db2"}, + {file = "scikit_learn-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25fc636bdaf1cc2f4a124a116312d837148b5e10872147bdaf4887926b8c03d8"}, + {file = "scikit_learn-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:fa909b1a36e000a03c382aade0bd2063fd5680ff8b8e501660c0f59f021a6415"}, + {file = "scikit_learn-1.6.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:926f207c804104677af4857b2c609940b743d04c4c35ce0ddc8ff4f053cddc1b"}, + {file = "scikit_learn-1.6.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2c2cae262064e6a9b77eee1c8e768fc46aa0b8338c6a8297b9b6759720ec0ff2"}, + {file = "scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1061b7c028a8663fb9a1a1baf9317b64a257fcb036dae5c8752b2abef31d136f"}, + {file = "scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e69fab4ebfc9c9b580a7a80111b43d214ab06250f8a7ef590a4edf72464dd86"}, + {file = "scikit_learn-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:70b1d7e85b1c96383f872a519b3375f92f14731e279a7b4c6cfd650cf5dffc52"}, + {file = "scikit_learn-1.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ffa1e9e25b3d93990e74a4be2c2fc61ee5af85811562f1288d5d055880c4322"}, + {file = "scikit_learn-1.6.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dc5cf3d68c5a20ad6d571584c0750ec641cc46aeef1c1507be51300e6003a7e1"}, + {file = "scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c06beb2e839ecc641366000ca84f3cf6fa9faa1777e29cf0c04be6e4d096a348"}, + {file = "scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8ca8cb270fee8f1f76fa9bfd5c3507d60c6438bbee5687f81042e2bb98e5a97"}, + {file = "scikit_learn-1.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:7a1c43c8ec9fde528d664d947dc4c0789be4077a3647f232869f41d9bf50e0fb"}, + {file = "scikit_learn-1.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a17c1dea1d56dcda2fac315712f3651a1fea86565b64b48fa1bc090249cbf236"}, + {file = "scikit_learn-1.6.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6a7aa5f9908f0f28f4edaa6963c0a6183f1911e63a69aa03782f0d924c830a35"}, + {file = "scikit_learn-1.6.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0650e730afb87402baa88afbf31c07b84c98272622aaba002559b614600ca691"}, + {file = "scikit_learn-1.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:3f59fe08dc03ea158605170eb52b22a105f238a5d512c4470ddeca71feae8e5f"}, + {file = "scikit_learn-1.6.1.tar.gz", hash = "sha256:b4fc2525eca2c69a59260f583c56a7557c6ccdf8deafdba6e060f94c1c59738e"}, +] + +[[package]] +name = "scipy" +version = "1.15.1" +requires_python = ">=3.10" +summary = "Fundamental algorithms for scientific computing in Python" +groups = ["default"] +dependencies = [ + "numpy<2.5,>=1.23.5", +] +files = [ + {file = "scipy-1.15.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:c64ded12dcab08afff9e805a67ff4480f5e69993310e093434b10e85dc9d43e1"}, + {file = "scipy-1.15.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:5b190b935e7db569960b48840e5bef71dc513314cc4e79a1b7d14664f57fd4ff"}, + {file = "scipy-1.15.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:4b17d4220df99bacb63065c76b0d1126d82bbf00167d1730019d2a30d6ae01ea"}, + {file = "scipy-1.15.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:63b9b6cd0333d0eb1a49de6f834e8aeaefe438df8f6372352084535ad095219e"}, + {file = "scipy-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f151e9fb60fbf8e52426132f473221a49362091ce7a5e72f8aa41f8e0da4f25"}, + {file = "scipy-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e10b1dd56ce92fba3e786007322542361984f8463c6d37f6f25935a5a6ef52"}, + {file = "scipy-1.15.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5dff14e75cdbcf07cdaa1c7707db6017d130f0af9ac41f6ce443a93318d6c6e0"}, + {file = "scipy-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:f82fcf4e5b377f819542fbc8541f7b5fbcf1c0017d0df0bc22c781bf60abc4d8"}, + {file = "scipy-1.15.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:5bd8d27d44e2c13d0c1124e6a556454f52cd3f704742985f6b09e75e163d20d2"}, + {file = "scipy-1.15.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:be3deeb32844c27599347faa077b359584ba96664c5c79d71a354b80a0ad0ce0"}, + {file = "scipy-1.15.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:5eb0ca35d4b08e95da99a9f9c400dc9f6c21c424298a0ba876fdc69c7afacedf"}, + {file = "scipy-1.15.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:74bb864ff7640dea310a1377d8567dc2cb7599c26a79ca852fc184cc851954ac"}, + {file = "scipy-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:667f950bf8b7c3a23b4199db24cb9bf7512e27e86d0e3813f015b74ec2c6e3df"}, + {file = "scipy-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395be70220d1189756068b3173853029a013d8c8dd5fd3d1361d505b2aa58fa7"}, + {file = "scipy-1.15.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ce3a000cd28b4430426db2ca44d96636f701ed12e2b3ca1f2b1dd7abdd84b39a"}, + {file = "scipy-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:3fe1d95944f9cf6ba77aa28b82dd6bb2a5b52f2026beb39ecf05304b8392864b"}, + {file = "scipy-1.15.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c09aa9d90f3500ea4c9b393ee96f96b0ccb27f2f350d09a47f533293c78ea776"}, + {file = "scipy-1.15.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0ac102ce99934b162914b1e4a6b94ca7da0f4058b6d6fd65b0cef330c0f3346f"}, + {file = "scipy-1.15.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:09c52320c42d7f5c7748b69e9f0389266fd4f82cf34c38485c14ee976cb8cb04"}, + {file = "scipy-1.15.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:cdde8414154054763b42b74fe8ce89d7f3d17a7ac5dd77204f0e142cdc9239e9"}, + {file = "scipy-1.15.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c9d8fc81d6a3b6844235e6fd175ee1d4c060163905a2becce8e74cb0d7554ce"}, + {file = "scipy-1.15.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fb57b30f0017d4afa5fe5f5b150b8f807618819287c21cbe51130de7ccdaed2"}, + {file = "scipy-1.15.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:491d57fe89927fa1aafbe260f4cfa5ffa20ab9f1435025045a5315006a91b8f5"}, + {file = "scipy-1.15.1-cp312-cp312-win_amd64.whl", hash = "sha256:900f3fa3db87257510f011c292a5779eb627043dd89731b9c461cd16ef76ab3d"}, + {file = "scipy-1.15.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:100193bb72fbff37dbd0bf14322314fc7cbe08b7ff3137f11a34d06dc0ee6b85"}, + {file = "scipy-1.15.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:2114a08daec64980e4b4cbdf5bee90935af66d750146b1d2feb0d3ac30613692"}, + {file = "scipy-1.15.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:6b3e71893c6687fc5e29208d518900c24ea372a862854c9888368c0b267387ab"}, + {file = "scipy-1.15.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:837299eec3d19b7e042923448d17d95a86e43941104d33f00da7e31a0f715d3c"}, + {file = "scipy-1.15.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82add84e8a9fb12af5c2c1a3a3f1cb51849d27a580cb9e6bd66226195142be6e"}, + {file = "scipy-1.15.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070d10654f0cb6abd295bc96c12656f948e623ec5f9a4eab0ddb1466c000716e"}, + {file = "scipy-1.15.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:55cc79ce4085c702ac31e49b1e69b27ef41111f22beafb9b49fea67142b696c4"}, + {file = "scipy-1.15.1-cp313-cp313-win_amd64.whl", hash = "sha256:c352c1b6d7cac452534517e022f8f7b8d139cd9f27e6fbd9f3cbd0bfd39f5bef"}, + {file = "scipy-1.15.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0458839c9f873062db69a03de9a9765ae2e694352c76a16be44f93ea45c28d2b"}, + {file = "scipy-1.15.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:af0b61c1de46d0565b4b39c6417373304c1d4f5220004058bdad3061c9fa8a95"}, + {file = "scipy-1.15.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:71ba9a76c2390eca6e359be81a3e879614af3a71dfdabb96d1d7ab33da6f2364"}, + {file = "scipy-1.15.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14eaa373c89eaf553be73c3affb11ec6c37493b7eaaf31cf9ac5dffae700c2e0"}, + {file = "scipy-1.15.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f735bc41bd1c792c96bc426dece66c8723283695f02df61dcc4d0a707a42fc54"}, + {file = "scipy-1.15.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2722a021a7929d21168830790202a75dbb20b468a8133c74a2c0230c72626b6c"}, + {file = "scipy-1.15.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bc7136626261ac1ed988dca56cfc4ab5180f75e0ee52e58f1e6aa74b5f3eacd5"}, + {file = "scipy-1.15.1.tar.gz", hash = "sha256:033a75ddad1463970c96a88063a1df87ccfddd526437136b6ee81ff0312ebdf6"}, +] + +[[package]] +name = "scipy-openblas32" +version = "0.3.29.0.0" +requires_python = ">=3.7" +summary = "Provides OpenBLAS for python packaging" +groups = ["default"] +files = [ + {file = "scipy_openblas32-0.3.29.0.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:6b276ac72c00cc0850588663b9da4c8099d4bee8a2527557747cf6b8ed5179cb"}, + {file = "scipy_openblas32-0.3.29.0.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:dd74159091a83ae7bf7b066345c3d3e43e212cd4537c03a2fd873154e5a179f2"}, + {file = "scipy_openblas32-0.3.29.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33994f0a37373ff6717fd9c948053a76c272efd516f8b33b3e51ecec786922fe"}, + {file = "scipy_openblas32-0.3.29.0.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d6301960024370f6061c71e8efd8bcb5be22c6526a529ff05c370048adb6b04"}, + {file = "scipy_openblas32-0.3.29.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02d32eafdf101f9503b99bd623e84f109a95cbe16d65492e174ed386339e2e1f"}, + {file = "scipy_openblas32-0.3.29.0.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2ca3ee3b9143b86addccda36a741462621413766dbc09896b0b43cc223a3b051"}, + {file = "scipy_openblas32-0.3.29.0.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:768352307e56873538222526b7dbcfd3dcd8615451741d15eef9af718ac93750"}, + {file = "scipy_openblas32-0.3.29.0.0-py3-none-win32.whl", hash = "sha256:e56c9c8e5e41d91d357b0d514fc59ca25467fbd68e5bdffa1f3dfa96f3249eb2"}, + {file = "scipy_openblas32-0.3.29.0.0-py3-none-win_amd64.whl", hash = "sha256:8b21c803bdc344a383a1d5d392d3cfe5366d9b89d2aeee963705156000cbbc7a"}, +] + +[[package]] +name = "setuptools" +version = "75.8.0" +requires_python = ">=3.9" +summary = "Easily download, build, install, upgrade, and uninstall Python packages" +groups = ["default"] +files = [ + {file = "setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"}, + {file = "setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6"}, +] + +[[package]] +name = "six" +version = "1.17.0" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +summary = "Python 2 and 3 compatibility utilities" +groups = ["default", "demo"] +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sspilib" +version = "0.2.0" +requires_python = ">=3.8" +summary = "SSPI API bindings for Python" +groups = ["default"] +marker = "sys_platform == \"win32\"" +files = [ + {file = "sspilib-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:34f566ba8b332c91594e21a71200de2d4ce55ca5a205541d4128ed23e3c98777"}, + {file = "sspilib-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b11e4f030de5c5de0f29bcf41a6e87c9fd90cb3b0f64e446a6e1d1aef4d08f5"}, + {file = "sspilib-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e82f87d77a9da62ce1eac22f752511a99495840177714c772a9d27b75220f78"}, + {file = "sspilib-0.2.0-cp310-cp310-win32.whl", hash = "sha256:e436fa09bcf353a364a74b3ef6910d936fa8cd1493f136e517a9a7e11b319c57"}, + {file = "sspilib-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:850a17c98d2b8579b183ce37a8df97d050bc5b31ab13f5a6d9e39c9692fe3754"}, + {file = "sspilib-0.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:a4d788a53b8db6d1caafba36887d5ac2087e6b6be6f01eb48f8afea6b646dbb5"}, + {file = "sspilib-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e0943204c8ba732966fdc5b69e33cf61d8dc6b24e6ed875f32055d9d7e2f76cd"}, + {file = "sspilib-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d1cdfc5ec2f151f26e21aa50ccc7f9848c969d6f78264ae4f38347609f6722df"}, + {file = "sspilib-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a6c33495a3de1552120c4a99219ebdd70e3849717867b8cae3a6a2f98fef405"}, + {file = "sspilib-0.2.0-cp311-cp311-win32.whl", hash = "sha256:400d5922c2c2261009921157c4b43d868e84640ad86e4dc84c95b07e5cc38ac6"}, + {file = "sspilib-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3e7d19c16ba9189ef8687b591503db06cfb9c5eb32ab1ca3bb9ebc1a8a5f35c"}, + {file = "sspilib-0.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:f65c52ead8ce95eb78a79306fe4269ee572ef3e4dcc108d250d5933da2455ecc"}, + {file = "sspilib-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:abac93a90335590b49ef1fc162b538576249c7f58aec0c7bcfb4b860513979b4"}, + {file = "sspilib-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1208720d8e431af674c5645cec365224d035f241444d5faa15dc74023ece1277"}, + {file = "sspilib-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48dceb871ecf9cf83abdd0e6db5326e885e574f1897f6ae87d736ff558f4bfa"}, + {file = "sspilib-0.2.0-cp312-cp312-win32.whl", hash = "sha256:bdf9a4f424add02951e1f01f47441d2e69a9910471e99c2c88660bd8e184d7f8"}, + {file = "sspilib-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:40a97ca83e503a175d1dc9461836994e47e8b9bcf56cab81a2c22e27f1993079"}, + {file = "sspilib-0.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:8ffc09819a37005c66a580ff44f544775f9745d5ed1ceeb37df4e5ff128adf36"}, + {file = "sspilib-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:40ff410b64198cf1d704718754fc5fe7b9609e0c49bf85c970f64c6fc2786db4"}, + {file = "sspilib-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:02d8e0b6033de8ccf509ba44fdcda7e196cdedc0f8cf19eb22c5e4117187c82f"}, + {file = "sspilib-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad7943fe14f8f6d72623ab6401991aa39a2b597bdb25e531741b37932402480f"}, + {file = "sspilib-0.2.0-cp313-cp313-win32.whl", hash = "sha256:b9044d6020aa88d512e7557694fe734a243801f9a6874e1c214451eebe493d92"}, + {file = "sspilib-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:c39a698491f43618efca8776a40fb7201d08c415c507f899f0df5ada15abefaa"}, + {file = "sspilib-0.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:863b7b214517b09367511c0ef931370f0386ed2c7c5613092bf9b106114c4a0e"}, + {file = "sspilib-0.2.0.tar.gz", hash = "sha256:4d6cd4290ca82f40705efeb5e9107f7abcd5e647cb201a3d04371305938615b8"}, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +summary = "Extract data from python stack frames and tracebacks for informative displays" +groups = ["demo"] +dependencies = [ + "asttokens>=2.1.0", + "executing>=1.2.0", + "pure-eval", +] +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[[package]] +name = "stevedore" +version = "5.4.0" +requires_python = ">=3.9" +summary = "Manage dynamic plugins for Python applications" +groups = ["default"] +dependencies = [ + "pbr>=2.0.0", +] +files = [ + {file = "stevedore-5.4.0-py3-none-any.whl", hash = "sha256:b0be3c4748b3ea7b854b265dcb4caa891015e442416422be16f8b31756107857"}, + {file = "stevedore-5.4.0.tar.gz", hash = "sha256:79e92235ecb828fe952b6b8b0c6c87863248631922c8e8e0fa5b17b232c4514d"}, +] + +[[package]] +name = "symengine" +version = "0.13.0" +requires_python = "<4,>=3.8" +summary = "Python library providing wrappers to SymEngine" +groups = ["default"] +files = [ + {file = "symengine-0.13.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:259fd4111c7a70c72bdff5686de1949e8132baeb612eacdaf8837720c6fe449b"}, + {file = "symengine-0.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:44f2eb28a1e36db0bbd6679435412f79da9743bf9c1cb3eff25e0c343b7ddd48"}, + {file = "symengine-0.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d141712fa14d9138bd19e64b10392f850c68d88cd7db29f1bda33e32d1095559"}, + {file = "symengine-0.13.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:830226d933bfcdb93546e4062541627d9a3bc7a178a63fb16c002eb5c5221938"}, + {file = "symengine-0.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a08090163819a0bbfa97d64bd2d8dac2c5268147ed9c242799d7f7e8728a6f4e"}, + {file = "symengine-0.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:1e435dcd8ed25e4c7c21ab1c0376be910efc7f35da76d532367df27b359f0358"}, + {file = "symengine-0.13.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:da0eba7e106095cdce88eb275c8a9d7c4586ad88f229394c53e1184155c00745"}, + {file = "symengine-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b0c175f4f895a73a925508af03faf7efd6cad8593256bbdb5346bd996d3ec5c8"}, + {file = "symengine-0.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e58d1e2abd08381aa0cf24c88c0e8b7f592df92619b51e32d36835fbd2dd6ae8"}, + {file = "symengine-0.13.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1db745f2c7a3c5e83510cf4decb43201f43552dfb05ad8af9787c89708be9ede"}, + {file = "symengine-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2572c98b09ac284db6ecff63f6170461194dc94c4209afd34c092ec67873d85"}, + {file = "symengine-0.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:12727f02a2919f005aee48e68e0cbb70cf857b19385857b4d985d1c9b075f620"}, + {file = "symengine-0.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cf91d24f1bfd6d53228593c7804dd106b71b19674d5afc4fa322d516e1793bdd"}, + {file = "symengine-0.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5615b7eb68890917abd390ebb10434a949165f6064741c1a8cc345fee14e855"}, + {file = "symengine-0.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb92bdf0890de264abaeacbfbdbd4dd7444b94057bd47958d913b662e549ad8a"}, + {file = "symengine-0.13.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3bce486fbc0b87970ed1b10ca9d5cafb1fd6b66382fe631261d83592851d7e"}, + {file = "symengine-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7e6bae9cfcdde2775d92fbb0abe3ef04e32f65ebc4c2d164ca33f4da202d4a7"}, + {file = "symengine-0.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:bced0a1dbdb94737c299384c85ddbad6944ce8dadc334f7bb8dbbd8f6c965807"}, + {file = "symengine-0.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d34df77971538e4c29f2d8e5ef7f459c2179465e6cdb7dfd48b79b87ecd8f4d"}, + {file = "symengine-0.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ab2661d9b18867e7c6edbfa7a74b8b0a2a694bd24aa08003dc3214f77cb9d6f2"}, + {file = "symengine-0.13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53f27b9013878ee4419d8e853664d8ae4b68419e3f4b9b5b7f503d32bf904755"}, + {file = "symengine-0.13.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:27987f75ce08c64f453e2b9b74fec6ffc5ca418c4deca0b75580979d4a4e242a"}, + {file = "symengine-0.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ea9410330ea15ed4137d7a0a3c43caccacb71490e18036ce5182d08c93baf8"}, + {file = "symengine-0.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:5031eb7a5c6675d5195bb57f93cc7d9ac5a7a9a826d4ad6f6b2927746ed7e6e6"}, + {file = "symengine-0.13.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ce0e5dfb19943bcf3e44a4485bcac4c5533ba3705c63083494eed0b3bf246076"}, + {file = "symengine-0.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c3b77dc54bf1181f6bd3b3338c4e6e5973a8b0fa20a189d15563ef5626e57b04"}, + {file = "symengine-0.13.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca7c3f6c168f6f5b06b421833c3d3baae56067a94b671bdffbe09b8e4fefd9be"}, + {file = "symengine-0.13.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:847523de682416811bacb3ad11507e663b3522fbb35cd27184757e9956d0eaf0"}, + {file = "symengine-0.13.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2fc1b7d96426463f0c9011e9fb88459d906477c1baa8a996dde6fb2bfa99d4"}, + {file = "symengine-0.13.0.tar.gz", hash = "sha256:ab83a08897ebf12579702c2b71ba73d4732fb706cc4291d810aedf39c690c14c"}, +] + +[[package]] +name = "sympy" +version = "1.13.3" +requires_python = ">=3.8" +summary = "Computer algebra system (CAS) in Python" +groups = ["default"] +dependencies = [ + "mpmath<1.4,>=1.1.0", +] +files = [ + {file = "sympy-1.13.3-py3-none-any.whl", hash = "sha256:54612cf55a62755ee71824ce692986f23c88ffa77207b30c1368eda4a7060f73"}, + {file = "sympy-1.13.3.tar.gz", hash = "sha256:b27fd2c6530e0ab39e275fc9b683895367e51d5da91baa8d3d64db2565fec4d9"}, +] + +[[package]] +name = "termcolor" +version = "2.5.0" +requires_python = ">=3.9" +summary = "ANSI color formatting for output in terminal" +groups = ["default"] +files = [ + {file = "termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8"}, + {file = "termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f"}, +] + +[[package]] +name = "threadpoolctl" +version = "3.5.0" +requires_python = ">=3.8" +summary = "threadpoolctl" +groups = ["default"] +files = [ + {file = "threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467"}, + {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, +] + +[[package]] +name = "tomlkit" +version = "0.13.2" +requires_python = ">=3.8" +summary = "Style preserving TOML library" +groups = ["default"] +files = [ + {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, + {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, +] + +[[package]] +name = "tornado" +version = "6.4.2" +requires_python = ">=3.8" +summary = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +groups = ["demo"] +files = [ + {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1"}, + {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803"}, + {file = "tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec"}, + {file = "tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946"}, + {file = "tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf"}, + {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634"}, + {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73"}, + {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c"}, + {file = "tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482"}, + {file = "tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38"}, + {file = "tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b"}, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +requires_python = ">=3.8" +summary = "Traitlets Python configuration system" +groups = ["demo"] +files = [ + {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, + {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +requires_python = ">=3.8" +summary = "Backported and Experimental Type Hints for Python 3.8+" +groups = ["default", "demo"] +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2025.1" +requires_python = ">=2" +summary = "Provider of IANA time zone data" +groups = ["default"] +files = [ + {file = "tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639"}, + {file = "tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694"}, +] + +[[package]] +name = "urllib3" +version = "2.3.0" +requires_python = ">=3.9" +summary = "HTTP library with thread-safe connection pooling, file post, and more." +groups = ["default"] +files = [ + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +summary = "Measures the displayed width of unicode strings in a terminal" +groups = ["demo"] +dependencies = [ + "backports-functools-lru-cache>=1.2.1; python_version < \"3.2\"", +] +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[[package]] +name = "websocket-client" +version = "1.8.0" +requires_python = ">=3.8" +summary = "WebSocket client for Python with low level API options" +groups = ["default"] +files = [ + {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, + {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, +] + +[[package]] +name = "wheel" +version = "0.45.1" +requires_python = ">=3.8" +summary = "A built-package format for Python" +groups = ["default"] +files = [ + {file = "wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248"}, + {file = "wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729"}, +] diff --git a/pyproject.toml b/pyproject.toml index e5c5e9d..5936f7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,6 @@ authors = [ ] requires-python = ">=3.10" description = "Quantum Advantage Seeker with Kernels (QuASK): a software framework to speed up the research in quantum machine learning" -url = "https://quask.web.cern.ch/" classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", @@ -25,19 +24,23 @@ dependencies = [ "scikit-learn>=1.6.1", "scipy>=1.15.1", ] +readme = {file = "README.md", content-type = "text/markdown"} + +[project.urls] +Homepage = "https://quask.web.cern.ch/" [build-system] requires = ["pdm-backend"] build-backend = "pdm.backend" [tool.pdm.build] -includes = ["dcm/"] +includes = ["src/quask/"] [tool.pdm.version] source = "file" path = "src/quask/__version__.py" -[dependency-groups] +[project.optional-dependencies] dev = [ "nose2[coverage_plugin]>=0.15.1", "tox-pdm>=0.7.2", @@ -86,7 +89,7 @@ commit_message = "{version}\n\nAutomatically generated by python-semantic-releas commit_parser = "angular" logging_use_named_masks = false major_on_zero = true -version_variables = ["arc/quask/__version__.py:__version__"] +version_variables = ["src/quask/__version__.py:__version__"] allow_zero_version = true no_git_verify = false tag_format = "{version}" @@ -141,3 +144,8 @@ insecure = false [tool.semantic_release.publish] dist_glob_patterns = ["dist/*"] upload_to_vcs_release = true + +[dependency-groups] +demo = [ + "matplotlib>=3.10.0", +] diff --git a/src/quask/__init__.py b/src/quask/__init__.py index e69de29..c23364d 100644 --- a/src/quask/__init__.py +++ b/src/quask/__init__.py @@ -0,0 +1 @@ +from quask.__version__ import __version__ \ No newline at end of file diff --git a/src/quask/core/kernel.py b/src/quask/core/kernel.py index 27a363a..35ac132 100644 --- a/src/quask/core/kernel.py +++ b/src/quask/core/kernel.py @@ -62,13 +62,13 @@ def get_allowed_operations(self): return self.ansatz.get_allowed_operations() def build_kernel( - self, x1: np.ndarray, x2: np.ndarray, matrix: str | None = None + self, x1: np.ndarray, x2: np.ndarray, matrix: str = "train" ) -> np.ndarray: """Build a kernel. :param X1: a single datapoint or a list of datapoints :param X2: a single datapoint or a list of datapoints - :param matrix: training or testing matrix + :param matrix: training or testing matrix. Default to train :return: a single or a matrix of kernel inner products """ # if you gave me only one sample diff --git a/src/quask/core/kernel_factory.py b/src/quask/core/kernel_factory.py index a80d15f..61e0508 100644 --- a/src/quask/core/kernel_factory.py +++ b/src/quask/core/kernel_factory.py @@ -2,11 +2,12 @@ from .kernel_type import KernelType class KernelFactory: - """Instantiate the concrete object from classes that inherit from (abstract class) Kernel. - Implement the self-registering factory pattern + """Kernel factory. + + Instantiate the concrete object from classes + that inherit from (abstract class) Kernel. """ - # to see the implementations and the current_implementation you can call it in this way: ._KernelFactory__implementations, ._KernelFactory__current_implementation __implementations = {} """Dictionary containing pairs (name, function to create the kernel).""" @@ -15,7 +16,10 @@ class KernelFactory: @staticmethod def add_implementation(name, fn): - """Add the current closure function as one of the possible implementations available + """Adds implementation. + + Add the current closure function as one of the + possible implementations available. :param name: name of the implementation :param fn: function that creates the quantum kernel @@ -43,15 +47,15 @@ def set_current_implementation(name): KernelFactory.__current_implementation = name @staticmethod - def create_kernel(ansatz: Ansatz, measurement: str, type: KernelType): + def create_kernel(ansatz: Ansatz, measurement: str, ktype: KernelType): """Create a kernel object using the default class chosen. :param ansatz: Ansatz object representing the unitary transformation :param measurement: Pauli string representing the measurement - :param type: type of kernel, fidelity, swap test or observable + :param ktype: type of kernel, fidelity, swap test or observable :return: kernel object of the default concrete class """ fn = KernelFactory.__implementations[ KernelFactory.__current_implementation ] - return fn(ansatz, measurement, type) + return fn(ansatz, measurement, ktype) diff --git a/src/quask/core_implementation/qiskit_kernel.py b/src/quask/core_implementation/qiskit_kernel.py index 8c9f189..e707694 100644 --- a/src/quask/core_implementation/qiskit_kernel.py +++ b/src/quask/core_implementation/qiskit_kernel.py @@ -30,9 +30,9 @@ def __init__( platform: str = "finite_shots", backend: IBMBackend = None, n_shots: int = 2048, - options: dict = None, + options: dict | None = None, optimization_level: int = 2, - layout: list = None, + layout: list | None = None, ): """Initialization. @@ -60,7 +60,7 @@ def get_backend( channel: str, ibm_token: str, group_instance: str, - device: str = None, + device: str | None = None, ): service = QiskitRuntimeService( channel=channel, token=ibm_token, instance=group_instance @@ -115,34 +115,56 @@ def get_estimator_options(self): return estimator_options def get_sampler(self): + """Get sampler. + + Returns: + Sampler: Qiskit sampler. + """ if self.platform == "infty_shots": return Statevector elif self.platform == "finite_shots": return StatevectorSampler(default_shots=self.n_shots) + elif self.platform == "ibm_quantum": options = self.get_sampler_options() return IBMSampler(backend=self.backend, options=options) def get_estimator(self): + """Get Estimator. + + Returns: + Estimator: Qiskit Estimator. + """ if self.platform == "infty_shots": return StatevectorEstimator + elif self.platform == "ibm_quantum": options = self.get_estimator_options() return IBMEstimator(backend=self.backend, options=options) def get_running_method(self, qc: QuantumCircuit): + """Running the circuit to obtain its outcome. + + Args: + qc (QuantumCircuit): Circuit to be executed + + Returns: + _type_: _description_ + """ sampler = self.get_sampler() if self.platform == "infty_shots": - res = Statevector.from_instruction(qc).data[0].real + return Statevector.from_instruction(qc).data[0].real + elif self.platform == "finite_shots": qc.measure_all() - counts = sampler.run([qc]).result()[0].data.meas.get_int_counts() + counts = sampler.run([qc]).result()[0].data.meas.get_counts() dist = QuasiDistribution( {meas: count / self.n_shots for meas, count in counts.items()}, shots=self.n_shots, ) - res = dist.get(0, 0.0) + return dist.get(0, 0.0) + elif self.platform == "ibm_quantum": qc.measure_all() logical_circuit = qc @@ -154,9 +176,8 @@ def get_running_method(self, qc: QuantumCircuit): physical_circuit = pm.run(logical_circuit) job = sampler.run([physical_circuit]) print(f"Job sent to hardware. Job ID: {job.job_id()}") - res = job - return res + return job def get_job_results(self, job: RuntimeJobV2): counts = job.result()[0].data.meas.get_int_counts() @@ -205,13 +226,13 @@ def kappa(self, x1: np.ndarray, x2: np.ndarray) -> float: qc.h(0) qc.append( self.get_qiskit_ansatz().assign_parameters( - x1.tolist() + [1.0] + [*x1.tolist(), 1.0] ), range(1, 1 + self.ansatz.n_qubits), ) qc.append( self.get_qiskit_ansatz().assign_parameters( - x2.tolist() + [1.0] + [*x2.tolist(), 1.0] ), range(self.ansatz.n_qubits), ) @@ -226,7 +247,7 @@ def kappa(self, x1: np.ndarray, x2: np.ndarray) -> float: def phi(self, x: np.ndarray) -> float: if self.type == KernelType.OBSERVABLE: assert len(x) == self.ansatz.n_features - complete_features = x.tolist() + [1.0] + complete_features = [*x.tolist(), 1.0] circuit = self.get_qiskit_ansatz().bind_parameters( complete_features ) diff --git a/src/quask/evaluator/__init__.py b/src/quask/evaluator/__init__.py index f016a0b..a256b75 100644 --- a/src/quask/evaluator/__init__.py +++ b/src/quask/evaluator/__init__.py @@ -1,9 +1,6 @@ -from .centered_kernel_alignment_evaluator import ( - CenteredKernelAlignmentEvaluator as CenteredKernelAlignmentEvaluator, -) -from .covering_number_evaluator import ( - CoveringNumberEvaluator as CoveringNumberEvaluator, -) +from .centered_kernel_alignment_evaluator import CenteredKernelAlignmentEvaluator +from .covering_number_evaluator import CoveringNumberEvaluator + from .ess_model_complexity_evaluator import ( EssModelComplexityEvaluator as EssModelComplexityEvaluator, ) diff --git a/src/quask/evaluator/centered_kernel_alignment_evaluator.py b/src/quask/evaluator/centered_kernel_alignment_evaluator.py index e997029..cb8821c 100644 --- a/src/quask/evaluator/centered_kernel_alignment_evaluator.py +++ b/src/quask/evaluator/centered_kernel_alignment_evaluator.py @@ -1,19 +1,25 @@ import numpy as np from ..core import Kernel -from . import KernelAlignmentEvaluator, KernelEvaluator +from .kernel_alignment_evaluator import KernelAlignmentEvaluator +from .kernel_evaluator import KernelEvaluator class CenteredKernelAlignmentEvaluator(KernelEvaluator): - """Kernel compatibility measure based on the centered kernel-target alignment - See: Cortes, Corinna, Mehryar Mohri, and Afshin Rostamizadeh. "Algorithms for learning kernels based on centered alignment." + """Kernel compatibility measure based on the centered kernel-target alignment. + + See: "Algorithms for learning kernels based on centered alignment." + Cortes, Corinna, Mehryar Mohri, and Afshin Rostamizadeh. The Journal of Machine Learning Research 13.1 (2012): 795-828. """ def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions. + :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -22,13 +28,14 @@ def evaluate( """ if K is None: K = kernel.build_kernel(X, X) - Kc = CenteredKernelAlignmentEvaluator.center_kernel(K) + Kc = self.center_kernel(K) kta = KernelAlignmentEvaluator.kta(Kc, y) return -np.abs(kta) @staticmethod def center_kernel(K): - """Center a kernel (subtract its mean value) + """Center a kernel (subtract its mean value). + :param K: kernel matrix :return: centered kernel """ diff --git a/src/quask/evaluator/covering_number_evaluator.py b/src/quask/evaluator/covering_number_evaluator.py index ef9174f..d33a25a 100644 --- a/src/quask/evaluator/covering_number_evaluator.py +++ b/src/quask/evaluator/covering_number_evaluator.py @@ -1,19 +1,26 @@ import numpy as np from ..core import Kernel -from . import KernelEvaluator +from .kernel_evaluator import KernelEvaluator class CoveringNumberEvaluator(KernelEvaluator): - """Expressibility measure based on the covering number associated with the hypothesis class related to the current ansatz. - See: Du, Yuxuan, et al. "Efficient measure for the expressivity of variational quantum algorithms." Physical Review Letters + """Covering number evaluator. + + Expressibility measure based on the covering number associated + with the hypothesis class related to the current ansatz. + See: Du, Yuxuan, et al. "Efficient measure for the expressivity of + variational quantum algorithms." Physical Review Letters 128.8 (2022): 080506. """ def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions. + :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints diff --git a/src/quask/evaluator/ess_model_complexity_evaluator.py b/src/quask/evaluator/ess_model_complexity_evaluator.py index a70255e..5e79bd1 100644 --- a/src/quask/evaluator/ess_model_complexity_evaluator.py +++ b/src/quask/evaluator/ess_model_complexity_evaluator.py @@ -1,18 +1,22 @@ import numpy as np from ..core import Kernel -from . import KernelEvaluator +from .kernel_evaluator import KernelEvaluator class EssModelComplexityEvaluator(KernelEvaluator): """Calculate the model complexity s(K). - See Equation F1 in "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938) + + See Equation F1 in "The power of data in quantum machine learning" + (https://arxiv.org/abs/2011.01938) """ def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) @@ -27,8 +31,10 @@ def evaluate( @staticmethod def calculate_model_complexity(k, y, normalization_lambda=0.001): - """Calculate the model complexity s(K), which is equation F1 in - "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938). + """Calculate the model complexity s(K), which is equation F1 in. + + "The power of data in quantum machine learning" + (https://arxiv.org/abs/2011.01938). :param k: Kernel gram matrix :param y: Labels @@ -60,8 +66,11 @@ def calculate_model_complexity_training(k, y, normalization_lambda=0.001): def calculate_model_complexity_generalized( k, y, normalization_lambda=0.001 ): - """Calculate the model complexity s(K), which is equation M1 in - "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938). + """Complexity calculation. + + Calculate the model complexity s(K), which is equation M1 in + "The power of data in quantum machine learning" + (https://arxiv.org/abs/2011.01938). :param k: Kernel gram matrix :param y: Labels diff --git a/src/quask/evaluator/geometric_difference_evaluator.py b/src/quask/evaluator/geometric_difference_evaluator.py index d625ba2..e9e6874 100644 --- a/src/quask/evaluator/geometric_difference_evaluator.py +++ b/src/quask/evaluator/geometric_difference_evaluator.py @@ -2,19 +2,22 @@ from scipy.linalg import sqrtm from ..core import Kernel -from . import KernelEvaluator +from .kernel_evaluator import KernelEvaluator class GeometricDifferenceEvaluator(KernelEvaluator): - """Calculate the geometric difference g(K_1 || K_2), and characterize - the separation between classical and quantum kernels. - See Equation F9 in "The power of data in quantum machine learning" (https://arxiv.org/abs/2011.01938) + """Calculate the geometric difference g(K_1 || K_2). + + Characterize the separation between classical and quantum kernels. + See Equation F9 in "The power of data in quantum machine learning" + (https://arxiv.org/abs/2011.01938) """ def __init__(self, list_classical_kernel_matrices, lam): """Initialization. - :param list_classical_kernel_matrices: List of kernel matrices obtained with classical kernels + :param list_classical_kernel_matrices: List of kernel matrices obtained + with classical kernels :param lam: normalization constant lambda """ super().__init__() @@ -24,7 +27,9 @@ def __init__(self, list_classical_kernel_matrices, lam): def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) @@ -45,7 +50,7 @@ def evaluate( @staticmethod def g(k_1, k_2, lam): - """Method to calculate the geometric difference + """Method to calculate the geometric difference. :param k_1: first matrix (quantum usually) :param k_2: second matrix (classical usually) diff --git a/src/quask/evaluator/haar_evaluator.py b/src/quask/evaluator/haar_evaluator.py index 6692a73..f5e7a5b 100644 --- a/src/quask/evaluator/haar_evaluator.py +++ b/src/quask/evaluator/haar_evaluator.py @@ -1,28 +1,40 @@ import numpy as np from ..core import Kernel -from . import KernelEvaluator +from .kernel_evaluator import KernelEvaluator class HaarEvaluator(KernelEvaluator): - """Expressibility measure based on the comparison between the distribution of states obtained with an Haar random circuit and + """Haar evaluator. + + Expressibility measure based on the comparison between + the distribution of states obtained with an Haar random circuit and the one obtained with the current ansatz. - See: Sim, Sukin, Peter D. Johnson, and Alán Aspuru-Guzik. "Expressibility and entangling capability of parameterized quantum - circuits for hybrid quantum-classical algorithms." Advanced Quantum Technologies 2.12 (2019): 1900070. + + See: Sim, Sukin, Peter D. Johnson, and Alán Aspuru-Guzik. + "Expressibility and entangling capability of parameterized quantum + circuits for hybrid quantum-classical algorithms." + Advanced Quantum Technologies 2.12 (2019): 1900070. """ def __init__(self, n_bins: int, n_samples: int): - """Initialization + """Initialization. + :param n_bins: number of discretization buckets - :param n_samples: number of samples approximating the distribution of values + :param n_samples: number of samples approximating the distribution + of values """ + super().__init__() + self.n_bins = n_bins self.n_samples = n_samples def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -38,7 +50,8 @@ def evaluate( @staticmethod def ansatz_histogram(kernel, n_bins, n_samples, K: None): - """Create a histogram of the fidelities of the ansatz + """Create a histogram of the fidelities of the ansatz. + :param kernel: kernel object :param n_bins: number of discretization buckets :param n_samples: number of samples approximating the distribution of values @@ -67,7 +80,8 @@ def ansatz_histogram(kernel, n_bins, n_samples, K: None): @staticmethod def haar_histogram(kernel, n_bins): - """Create a histogram of the Haar random fidelities + """Create a histogram of the Haar random fidelities. + :param n_bins: number of bins :return: histogram """ diff --git a/src/quask/evaluator/kernel_alignment_evaluator.py b/src/quask/evaluator/kernel_alignment_evaluator.py index 93d8154..137e4b8 100644 --- a/src/quask/evaluator/kernel_alignment_evaluator.py +++ b/src/quask/evaluator/kernel_alignment_evaluator.py @@ -1,18 +1,22 @@ import numpy as np from ..core import Kernel -from . import KernelEvaluator +from .kernel_evaluator import KernelEvaluator class KernelAlignmentEvaluator(KernelEvaluator): - """Kernel compatibility measure based on the kernel-target alignment - See: Cristianini, Nello, et al. "On kernel-target alignment." Advances in neural information processing systems 14 (2001). + """Kernel compatibility measure based on the kernel-target alignment. + + See: Cristianini, Nello, et al. "On kernel-target alignment." + Advances in neural information processing systems 14 (2001). """ def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -27,7 +31,8 @@ def evaluate( @staticmethod def kta(K, y): - """Calculates the kernel target alignment + """Calculates the kernel target alignment. + :param K: kernel matrix :param y: label vector :return: kernel target alignment diff --git a/src/quask/evaluator/kernel_evaluator.py b/src/quask/evaluator/kernel_evaluator.py index 55bb1d8..88f2694 100644 --- a/src/quask/evaluator/kernel_evaluator.py +++ b/src/quask/evaluator/kernel_evaluator.py @@ -6,18 +6,21 @@ class KernelEvaluator(ABC): + """Adds an evaluate functionality to the core kernel.""" def __init__(self): + """Init function.""" self.last_result = None @abstractmethod def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints :param y: labels :return: cost of the kernel, the lower the better """ - pass diff --git a/src/quask/evaluator/lie_rank_evaluator.py b/src/quask/evaluator/lie_rank_evaluator.py index eb6254d..ec60a83 100644 --- a/src/quask/evaluator/lie_rank_evaluator.py +++ b/src/quask/evaluator/lie_rank_evaluator.py @@ -3,18 +3,23 @@ import numpy as np from ..core import Kernel -from . import KernelEvaluator +from .kernel_evaluator import KernelEvaluator class LieRankEvaluator(KernelEvaluator): - """Expressibility and 'Efficient classical simulability' measure based on the rank of the Lie algebra obtained by spanning + """Expressibility and 'Efficient classical simulability'. + + Measure based on the rank of the Lie algebra obtained by spanning the generators of the circuits. - See: Larocca, Martin, et al. "Diagnosing barren plateaus with tools from quantum optimal control." Quantum 6 (2022): 824. + See: Larocca, Martin, et al. "Diagnosing barren plateaus with tools + from quantum optimal control." Quantum 6 (2022): 824. """ def __init__(self, T): - """Initializer - :param T: threshold T > 0 telling how is the minimum dimension of a 'hard-to-simulate' Lie algebra + """Initializer. + + :param T: threshold T > 0 telling how is the minimum dimension of + a 'hard-to-simulate' Lie algebra """ super().__init__() self.T = T @@ -22,7 +27,10 @@ def __init__(self, T): def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions. + :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -33,7 +41,8 @@ def evaluate( return -len(self.last_result) def braket_pair(self, a: str, b: str): - """Calculate the commutator between two pauli matrices + """Calculate the commutator between two pauli matrices. + :param a: first Pauli (one of the strings 'I', 'X', 'Y', 'Z') :param b: second Pauli (one of the strings 'I', 'X', 'Y', 'Z') :return: [a, b] @@ -48,7 +57,8 @@ def braket_pair(self, a: str, b: str): return list({"X", "Y", "Z"}.difference([a, b]))[0] def braket_strings(self, s1: str, s2: str): - """Calculate the communtator between two pauli strings + """Calculate the communtator between two pauli strings. + :param s1: first Pauli string :param s2: second Pauli string :return: [s1, s2] @@ -59,7 +69,8 @@ def braket_strings(self, s1: str, s2: str): def __braket_generators( self, initial_generators: set[str], new_generators: set[str] ): - """Return the set of generators obtained by commutating pairwise the elements in the given set + """Return the set of generators obtained by commutating pairwise the elements in the given set. + :param initial_generators: first set of generators :param new_generators: second set of generators :return: generators obtained with the pairwise commutation of the given elements (only new ones) @@ -125,3 +136,4 @@ def braket_generators(self, kernel, T): def __str__(self): return str(self.last_result) + diff --git a/src/quask/evaluator/ridge_generalization_evaluator.py b/src/quask/evaluator/ridge_generalization_evaluator.py index 99908dd..6e263d5 100644 --- a/src/quask/evaluator/ridge_generalization_evaluator.py +++ b/src/quask/evaluator/ridge_generalization_evaluator.py @@ -2,20 +2,19 @@ from sklearn.kernel_ridge import KernelRidge from ..core import Kernel -from . import KernelEvaluator +from .kernel_evaluator import KernelEvaluator class RidgeGeneralizationEvaluator(KernelEvaluator): - """Evaluates the generalization error of the given kernel""" - - def __init__(self): - """Initialization""" - pass + """Evaluates the generalization error of the given kernel.""" def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions. + :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints diff --git a/src/quask/evaluator/spectral_bias_evaluator.py b/src/quask/evaluator/spectral_bias_evaluator.py index b52637a..61b8245 100644 --- a/src/quask/evaluator/spectral_bias_evaluator.py +++ b/src/quask/evaluator/spectral_bias_evaluator.py @@ -2,25 +2,35 @@ from scipy.linalg import eigh from ..core import Kernel -from . import KernelEvaluator +from .kernel_evaluator import KernelEvaluator class SpectralBiasEvaluator(KernelEvaluator): """Kernel compatibility measure based on the spectral bias framework. - See: Canatar, Abdulkadir, Blake Bordelon, and Cengiz Pehlevan. "Spectral bias and task-model alignment explain generalization - in kernel regression and infinitely wide neural networks." Nature communications 12.1 (2021): 2914. + + See: Canatar, Abdulkadir, Blake Bordelon, and Cengiz Pehlevan. + "Spectral bias and task-model alignment explain generalization + in kernel regression and infinitely wide neural networks." + Nature communications 12.1 (2021): 2914. """ def __init__(self, n_eigenvalues_cut): - """Initialization - :param n_eigenvalues_cut: number of eigenvalues contributing to the cumulative power + """Initialization. + + :param n_eigenvalues_cut: number of eigenvalues contributing to the + cumulative power """ + super().__init__() + self.n_eigenvalues_cut = n_eigenvalues_cut def evaluate( self, kernel: Kernel, K: np.ndarray, X: np.ndarray, y: np.ndarray ): - r"""Evaluate the current kernel and return the corresponding cost. Lower cost values corresponds to better solutions + r"""Evaluate the current kernel and return the corresponding cost. + + Lower cost values corresponds to better solutions. + :param kernel: kernel object :param K: optional kernel matrix \kappa(X, X) :param X: datapoints @@ -41,7 +51,11 @@ def evaluate( def decompose_kernel( K, eigenvalue_descending_order=True, eigenvalue_removal_threshold=1e-12 ): - """Decompose the kernel matrix K in its eigenvalues Λ and eigenvectors Φ + """Decompose kernel. + + Decompose the kernel matrix K in its eigenvalues Λ + and eigenvectors Φ. + :param K: kernel matrix, real and symmetric :param eigenvalue_descending_order: if True, the biggest eigenvalue is the first one :return: Lambda vector (n elements) and Phi matrix (N*N matrix) @@ -53,7 +67,8 @@ def decompose_kernel( Lambda = Lambda[::-1] Phi = Phi[:, ::-1] - # kernel matrix is positive definite, any (small) negative eigenvalue is effectively a numerical error + # kernel matrix is positive definite, any (small) negative eigenvalue + # is effectively a numerical error Lambda[Lambda < 0] = 0 # remove the smallest positive eigenvalues, as they are useless @@ -63,11 +78,16 @@ def decompose_kernel( @staticmethod def calculate_weights(Lambda, Phi, labels): - """Calculates the weights of a predictor given the labels and the kernel eigendecomposition, - as shown in (Canatar et al 2021, inline formula below equation 18). + """Calculate weights. + + Calculates the weights of a predictor given the labels and the kernel + eigendecomposition, as shown in (Canatar et al 2021, + inline formula below equation 18). + :param Lambda: vectors of m nonnegative eigenvalues 'eta' :param Phi: vectors of m nonnegative eigenvectors 'phi' - :param labels: vector of m labels corresponding to 'm' ground truth labels or predictor outputs + :param labels: vector of m labels corresponding to 'm' ground truth + labels or predictor outputs :return: vector w of RKHS weights, vector a of out-of-RKHS weights """ # get the number of training elements @@ -76,7 +96,8 @@ def calculate_weights(Lambda, Phi, labels): # invert nonzero eigenvalues inv_eigenvalues = np.reciprocal(Lambda, where=Lambda > 0) - # weight vectors are calculated by inverting formula: y = \sum_k=1^M w_k \sqrt{lambda_k} \phi_k(x) + # weight vectors are calculated by inverting formula: + # y = \sum_k=1^M w_k \sqrt{lambda_k} \phi_k(x) the_w = (1 / m) * np.diag(inv_eigenvalues**0.5) @ Phi.T @ labels the_w[Lambda == 0] = 0 @@ -87,7 +108,9 @@ def calculate_weights(Lambda, Phi, labels): @staticmethod def cumulative_power_distribution(w, Lambda, n_eigenvalues): - """:param w: vector of weights + """Cumulative power. + + :param w: vector of weights :param Lambda: vector of eigenvalues :param n_eigenvalues: number of eigenvalues contributing to the cumulative power :return: diff --git a/uv.lock b/uv.lock index 3da10c0..909c5de 100644 --- a/uv.lock +++ b/uv.lock @@ -306,6 +306,70 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3", size = 7180 }, ] +[[package]] +name = "contourpy" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/25/c2/fc7193cc5383637ff390a712e88e4ded0452c9fbcf84abe3de5ea3df1866/contourpy-1.3.1.tar.gz", hash = "sha256:dfd97abd83335045a913e3bcc4a09c0ceadbe66580cf573fe961f4a825efa699", size = 13465753 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/a3/80937fe3efe0edacf67c9a20b955139a1a622730042c1ea991956f2704ad/contourpy-1.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a045f341a77b77e1c5de31e74e966537bba9f3c4099b35bf4c2e3939dd54cdab", size = 268466 }, + { url = "https://files.pythonhosted.org/packages/82/1d/e3eaebb4aa2d7311528c048350ca8e99cdacfafd99da87bc0a5f8d81f2c2/contourpy-1.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:500360b77259914f7805af7462e41f9cb7ca92ad38e9f94d6c8641b089338124", size = 253314 }, + { url = "https://files.pythonhosted.org/packages/de/f3/d796b22d1a2b587acc8100ba8c07fb7b5e17fde265a7bb05ab967f4c935a/contourpy-1.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2f926efda994cdf3c8d3fdb40b9962f86edbc4457e739277b961eced3d0b4c1", size = 312003 }, + { url = "https://files.pythonhosted.org/packages/bf/f5/0e67902bc4394daee8daa39c81d4f00b50e063ee1a46cb3938cc65585d36/contourpy-1.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:adce39d67c0edf383647a3a007de0a45fd1b08dedaa5318404f1a73059c2512b", size = 351896 }, + { url = "https://files.pythonhosted.org/packages/1f/d6/e766395723f6256d45d6e67c13bb638dd1fa9dc10ef912dc7dd3dcfc19de/contourpy-1.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abbb49fb7dac584e5abc6636b7b2a7227111c4f771005853e7d25176daaf8453", size = 320814 }, + { url = "https://files.pythonhosted.org/packages/a9/57/86c500d63b3e26e5b73a28b8291a67c5608d4aa87ebd17bd15bb33c178bc/contourpy-1.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0cffcbede75c059f535725c1680dfb17b6ba8753f0c74b14e6a9c68c29d7ea3", size = 324969 }, + { url = "https://files.pythonhosted.org/packages/b8/62/bb146d1289d6b3450bccc4642e7f4413b92ebffd9bf2e91b0404323704a7/contourpy-1.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab29962927945d89d9b293eabd0d59aea28d887d4f3be6c22deaefbb938a7277", size = 1265162 }, + { url = "https://files.pythonhosted.org/packages/18/04/9f7d132ce49a212c8e767042cc80ae390f728060d2eea47058f55b9eff1c/contourpy-1.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:974d8145f8ca354498005b5b981165b74a195abfae9a8129df3e56771961d595", size = 1324328 }, + { url = "https://files.pythonhosted.org/packages/46/23/196813901be3f97c83ababdab1382e13e0edc0bb4e7b49a7bff15fcf754e/contourpy-1.3.1-cp310-cp310-win32.whl", hash = "sha256:ac4578ac281983f63b400f7fe6c101bedc10651650eef012be1ccffcbacf3697", size = 173861 }, + { url = "https://files.pythonhosted.org/packages/e0/82/c372be3fc000a3b2005061ca623a0d1ecd2eaafb10d9e883a2fc8566e951/contourpy-1.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:174e758c66bbc1c8576992cec9599ce8b6672b741b5d336b5c74e35ac382b18e", size = 218566 }, + { url = "https://files.pythonhosted.org/packages/12/bb/11250d2906ee2e8b466b5f93e6b19d525f3e0254ac8b445b56e618527718/contourpy-1.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8b974d8db2c5610fb4e76307e265de0edb655ae8169e8b21f41807ccbeec4b", size = 269555 }, + { url = "https://files.pythonhosted.org/packages/67/71/1e6e95aee21a500415f5d2dbf037bf4567529b6a4e986594d7026ec5ae90/contourpy-1.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20914c8c973f41456337652a6eeca26d2148aa96dd7ac323b74516988bea89fc", size = 254549 }, + { url = "https://files.pythonhosted.org/packages/31/2c/b88986e8d79ac45efe9d8801ae341525f38e087449b6c2f2e6050468a42c/contourpy-1.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19d40d37c1c3a4961b4619dd9d77b12124a453cc3d02bb31a07d58ef684d3d86", size = 313000 }, + { url = "https://files.pythonhosted.org/packages/c4/18/65280989b151fcf33a8352f992eff71e61b968bef7432fbfde3a364f0730/contourpy-1.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:113231fe3825ebf6f15eaa8bc1f5b0ddc19d42b733345eae0934cb291beb88b6", size = 352925 }, + { url = "https://files.pythonhosted.org/packages/f5/c7/5fd0146c93220dbfe1a2e0f98969293b86ca9bc041d6c90c0e065f4619ad/contourpy-1.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dbbc03a40f916a8420e420d63e96a1258d3d1b58cbdfd8d1f07b49fcbd38e85", size = 323693 }, + { url = "https://files.pythonhosted.org/packages/85/fc/7fa5d17daf77306840a4e84668a48ddff09e6bc09ba4e37e85ffc8e4faa3/contourpy-1.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a04ecd68acbd77fa2d39723ceca4c3197cb2969633836ced1bea14e219d077c", size = 326184 }, + { url = "https://files.pythonhosted.org/packages/ef/e7/104065c8270c7397c9571620d3ab880558957216f2b5ebb7e040f85eeb22/contourpy-1.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c414fc1ed8ee1dbd5da626cf3710c6013d3d27456651d156711fa24f24bd1291", size = 1268031 }, + { url = "https://files.pythonhosted.org/packages/e2/4a/c788d0bdbf32c8113c2354493ed291f924d4793c4a2e85b69e737a21a658/contourpy-1.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:31c1b55c1f34f80557d3830d3dd93ba722ce7e33a0b472cba0ec3b6535684d8f", size = 1325995 }, + { url = "https://files.pythonhosted.org/packages/a6/e6/a2f351a90d955f8b0564caf1ebe4b1451a3f01f83e5e3a414055a5b8bccb/contourpy-1.3.1-cp311-cp311-win32.whl", hash = "sha256:f611e628ef06670df83fce17805c344710ca5cde01edfdc72751311da8585375", size = 174396 }, + { url = "https://files.pythonhosted.org/packages/a8/7e/cd93cab453720a5d6cb75588cc17dcdc08fc3484b9de98b885924ff61900/contourpy-1.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:b2bdca22a27e35f16794cf585832e542123296b4687f9fd96822db6bae17bfc9", size = 219787 }, + { url = "https://files.pythonhosted.org/packages/37/6b/175f60227d3e7f5f1549fcb374592be311293132207e451c3d7c654c25fb/contourpy-1.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0ffa84be8e0bd33410b17189f7164c3589c229ce5db85798076a3fa136d0e509", size = 271494 }, + { url = "https://files.pythonhosted.org/packages/6b/6a/7833cfae2c1e63d1d8875a50fd23371394f540ce809d7383550681a1fa64/contourpy-1.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805617228ba7e2cbbfb6c503858e626ab528ac2a32a04a2fe88ffaf6b02c32bc", size = 255444 }, + { url = "https://files.pythonhosted.org/packages/7f/b3/7859efce66eaca5c14ba7619791b084ed02d868d76b928ff56890d2d059d/contourpy-1.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ade08d343436a94e633db932e7e8407fe7de8083967962b46bdfc1b0ced39454", size = 307628 }, + { url = "https://files.pythonhosted.org/packages/48/b2/011415f5e3f0a50b1e285a0bf78eb5d92a4df000553570f0851b6e309076/contourpy-1.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47734d7073fb4590b4a40122b35917cd77be5722d80683b249dac1de266aac80", size = 347271 }, + { url = "https://files.pythonhosted.org/packages/84/7d/ef19b1db0f45b151ac78c65127235239a8cf21a59d1ce8507ce03e89a30b/contourpy-1.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ba94a401342fc0f8b948e57d977557fbf4d515f03c67682dd5c6191cb2d16ec", size = 318906 }, + { url = "https://files.pythonhosted.org/packages/ba/99/6794142b90b853a9155316c8f470d2e4821fe6f086b03e372aca848227dd/contourpy-1.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efa874e87e4a647fd2e4f514d5e91c7d493697127beb95e77d2f7561f6905bd9", size = 323622 }, + { url = "https://files.pythonhosted.org/packages/3c/0f/37d2c84a900cd8eb54e105f4fa9aebd275e14e266736778bb5dccbf3bbbb/contourpy-1.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1bf98051f1045b15c87868dbaea84f92408337d4f81d0e449ee41920ea121d3b", size = 1266699 }, + { url = "https://files.pythonhosted.org/packages/3a/8a/deb5e11dc7d9cc8f0f9c8b29d4f062203f3af230ba83c30a6b161a6effc9/contourpy-1.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:61332c87493b00091423e747ea78200659dc09bdf7fd69edd5e98cef5d3e9a8d", size = 1326395 }, + { url = "https://files.pythonhosted.org/packages/1a/35/7e267ae7c13aaf12322ccc493531f1e7f2eb8fba2927b9d7a05ff615df7a/contourpy-1.3.1-cp312-cp312-win32.whl", hash = "sha256:e914a8cb05ce5c809dd0fe350cfbb4e881bde5e2a38dc04e3afe1b3e58bd158e", size = 175354 }, + { url = "https://files.pythonhosted.org/packages/a1/35/c2de8823211d07e8a79ab018ef03960716c5dff6f4d5bff5af87fd682992/contourpy-1.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:08d9d449a61cf53033612cb368f3a1b26cd7835d9b8cd326647efe43bca7568d", size = 220971 }, + { url = "https://files.pythonhosted.org/packages/9a/e7/de62050dce687c5e96f946a93546910bc67e483fe05324439e329ff36105/contourpy-1.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a761d9ccfc5e2ecd1bf05534eda382aa14c3e4f9205ba5b1684ecfe400716ef2", size = 271548 }, + { url = "https://files.pythonhosted.org/packages/78/4d/c2a09ae014ae984c6bdd29c11e74d3121b25eaa117eca0bb76340efd7e1c/contourpy-1.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:523a8ee12edfa36f6d2a49407f705a6ef4c5098de4f498619787e272de93f2d5", size = 255576 }, + { url = "https://files.pythonhosted.org/packages/ab/8a/915380ee96a5638bda80cd061ccb8e666bfdccea38d5741cb69e6dbd61fc/contourpy-1.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece6df05e2c41bd46776fbc712e0996f7c94e0d0543af1656956d150c4ca7c81", size = 306635 }, + { url = "https://files.pythonhosted.org/packages/29/5c/c83ce09375428298acd4e6582aeb68b1e0d1447f877fa993d9bf6cd3b0a0/contourpy-1.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:573abb30e0e05bf31ed067d2f82500ecfdaec15627a59d63ea2d95714790f5c2", size = 345925 }, + { url = "https://files.pythonhosted.org/packages/29/63/5b52f4a15e80c66c8078a641a3bfacd6e07106835682454647aca1afc852/contourpy-1.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fa36448e6a3a1a9a2ba23c02012c43ed88905ec80163f2ffe2421c7192a5d7", size = 318000 }, + { url = "https://files.pythonhosted.org/packages/9a/e2/30ca086c692691129849198659bf0556d72a757fe2769eb9620a27169296/contourpy-1.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ea9924d28fc5586bf0b42d15f590b10c224117e74409dd7a0be3b62b74a501c", size = 322689 }, + { url = "https://files.pythonhosted.org/packages/6b/77/f37812ef700f1f185d348394debf33f22d531e714cf6a35d13d68a7003c7/contourpy-1.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5b75aa69cb4d6f137b36f7eb2ace9280cfb60c55dc5f61c731fdf6f037f958a3", size = 1268413 }, + { url = "https://files.pythonhosted.org/packages/3f/6d/ce84e79cdd128542ebeb268f84abb4b093af78e7f8ec504676673d2675bc/contourpy-1.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:041b640d4ec01922083645a94bb3b2e777e6b626788f4095cf21abbe266413c1", size = 1326530 }, + { url = "https://files.pythonhosted.org/packages/72/22/8282f4eae20c73c89bee7a82a19c4e27af9b57bb602ecaa00713d5bdb54d/contourpy-1.3.1-cp313-cp313-win32.whl", hash = "sha256:36987a15e8ace5f58d4d5da9dca82d498c2bbb28dff6e5d04fbfcc35a9cb3a82", size = 175315 }, + { url = "https://files.pythonhosted.org/packages/e3/d5/28bca491f65312b438fbf076589dcde7f6f966b196d900777f5811b9c4e2/contourpy-1.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7895f46d47671fa7ceec40f31fae721da51ad34bdca0bee83e38870b1f47ffd", size = 220987 }, + { url = "https://files.pythonhosted.org/packages/2f/24/a4b285d6adaaf9746e4700932f579f1a7b6f9681109f694cfa233ae75c4e/contourpy-1.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9ddeb796389dadcd884c7eb07bd14ef12408aaae358f0e2ae24114d797eede30", size = 285001 }, + { url = "https://files.pythonhosted.org/packages/48/1d/fb49a401b5ca4f06ccf467cd6c4f1fd65767e63c21322b29b04ec40b40b9/contourpy-1.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:19c1555a6801c2f084c7ddc1c6e11f02eb6a6016ca1318dd5452ba3f613a1751", size = 268553 }, + { url = "https://files.pythonhosted.org/packages/79/1e/4aef9470d13fd029087388fae750dccb49a50c012a6c8d1d634295caa644/contourpy-1.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:841ad858cff65c2c04bf93875e384ccb82b654574a6d7f30453a04f04af71342", size = 310386 }, + { url = "https://files.pythonhosted.org/packages/b0/34/910dc706ed70153b60392b5305c708c9810d425bde12499c9184a1100888/contourpy-1.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4318af1c925fb9a4fb190559ef3eec206845f63e80fb603d47f2d6d67683901c", size = 349806 }, + { url = "https://files.pythonhosted.org/packages/31/3c/faee6a40d66d7f2a87f7102236bf4780c57990dd7f98e5ff29881b1b1344/contourpy-1.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:14c102b0eab282427b662cb590f2e9340a9d91a1c297f48729431f2dcd16e14f", size = 321108 }, + { url = "https://files.pythonhosted.org/packages/17/69/390dc9b20dd4bb20585651d7316cc3054b7d4a7b4f8b710b2b698e08968d/contourpy-1.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05e806338bfeaa006acbdeba0ad681a10be63b26e1b17317bfac3c5d98f36cda", size = 327291 }, + { url = "https://files.pythonhosted.org/packages/ef/74/7030b67c4e941fe1e5424a3d988080e83568030ce0355f7c9fc556455b01/contourpy-1.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4d76d5993a34ef3df5181ba3c92fabb93f1eaa5729504fb03423fcd9f3177242", size = 1263752 }, + { url = "https://files.pythonhosted.org/packages/f0/ed/92d86f183a8615f13f6b9cbfc5d4298a509d6ce433432e21da838b4b63f4/contourpy-1.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:89785bb2a1980c1bd87f0cb1517a71cde374776a5f150936b82580ae6ead44a1", size = 1318403 }, + { url = "https://files.pythonhosted.org/packages/b3/0e/c8e4950c77dcfc897c71d61e56690a0a9df39543d2164040301b5df8e67b/contourpy-1.3.1-cp313-cp313t-win32.whl", hash = "sha256:8eb96e79b9f3dcadbad2a3891672f81cdcab7f95b27f28f1c67d75f045b6b4f1", size = 185117 }, + { url = "https://files.pythonhosted.org/packages/c1/31/1ae946f11dfbd229222e6d6ad8e7bd1891d3d48bde5fbf7a0beb9491f8e3/contourpy-1.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:287ccc248c9e0d0566934e7d606201abd74761b5703d804ff3df8935f523d546", size = 236668 }, + { url = "https://files.pythonhosted.org/packages/3e/4f/e56862e64b52b55b5ddcff4090085521fc228ceb09a88390a2b103dccd1b/contourpy-1.3.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b457d6430833cee8e4b8e9b6f07aa1c161e5e0d52e118dc102c8f9bd7dd060d6", size = 265605 }, + { url = "https://files.pythonhosted.org/packages/b0/2e/52bfeeaa4541889f23d8eadc6386b442ee2470bd3cff9baa67deb2dd5c57/contourpy-1.3.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb76c1a154b83991a3cbbf0dfeb26ec2833ad56f95540b442c73950af2013750", size = 315040 }, + { url = "https://files.pythonhosted.org/packages/52/94/86bfae441707205634d80392e873295652fc313dfd93c233c52c4dc07874/contourpy-1.3.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:44a29502ca9c7b5ba389e620d44f2fbe792b1fb5734e8b931ad307071ec58c53", size = 218221 }, +] + [[package]] name = "coverage" version = "7.6.10" @@ -402,6 +466,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/9d/37e5da7519de7b0b070a3fedd4230fe76d50d2a21403e0f2153d70ac4163/cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c", size = 3128774 }, ] +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, +] + [[package]] name = "debugpy" version = "1.8.12" @@ -513,6 +586,47 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/89/ec/00d68c4ddfedfe64159999e5f8a98fb8442729a63e2077eb9dcd89623d27/filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338", size = 16164 }, ] +[[package]] +name = "fonttools" +version = "4.55.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/24/de7e40adc99be2aa5adc6321bbdf3cf58dbe751b87343da658dd3fc7d946/fonttools-4.55.8.tar.gz", hash = "sha256:54d481d456dcd59af25d4a9c56b2c4c3f20e9620b261b84144e5950f33e8df17", size = 3458915 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/b8/82b3444cb081798eabb8397452ddf73680e623d7fdf9c575594a2240b8a2/fonttools-4.55.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d11600f5343092697d7434f3bf77a393c7ae74be206fe30e577b9a195fd53165", size = 2752288 }, + { url = "https://files.pythonhosted.org/packages/86/8f/9c5f2172e9f6dcf52bb6477bcd5a023d056114787c8184b683c34996f5a1/fonttools-4.55.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c96f2506ce1a0beeaa9595f9a8b7446477eb133f40c0e41fc078744c28149f80", size = 2280718 }, + { url = "https://files.pythonhosted.org/packages/c6/a6/b7cd7b54412bb7a27e282ee54459cae24524ad0eab6f81ead2a91d435287/fonttools-4.55.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b5f05ef72e846e9f49ccdd74b9da4309901a4248434c63c1ee9321adcb51d65", size = 4562177 }, + { url = "https://files.pythonhosted.org/packages/0e/16/eff3be24cecb9336639148c40507f949c193642d8369352af480597633fb/fonttools-4.55.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba45b637da80a262b55b7657aec68da2ac54b8ae7891cd977a5dbe5fd26db429", size = 4604843 }, + { url = "https://files.pythonhosted.org/packages/b5/95/737574364439cbcc5e6d4f3e000f15432141680ca8cb5c216b619a3d1cab/fonttools-4.55.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:edcffaeadba9a334c1c3866e275d7dd495465e7dbd296f688901bdbd71758113", size = 4559127 }, + { url = "https://files.pythonhosted.org/packages/5f/07/ea90834742f9b3e51a05f0f15f7c817eb7aab3d6ebf4f06c4626825ccb89/fonttools-4.55.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b9f9fce3c9b2196e162182ec5db8af8eb3acd0d76c2eafe9fdba5f370044e556", size = 4728575 }, + { url = "https://files.pythonhosted.org/packages/93/74/0c816d83cd2945a25aed592b0cb3c9ba32e8b259781bf41dc112204129d9/fonttools-4.55.8-cp310-cp310-win32.whl", hash = "sha256:f089e8da0990cfe2d67e81d9cf581ff372b48dc5acf2782701844211cd1f0eb3", size = 2155662 }, + { url = "https://files.pythonhosted.org/packages/78/bc/f5a24229edd8cdd7494f2099e1c62fca288dad4c8637ee62df04459db27e/fonttools-4.55.8-cp310-cp310-win_amd64.whl", hash = "sha256:01ea3901b0802fc5f9e854f5aeb5bc27770dd9dd24c28df8f74ba90f8b3f5915", size = 2200126 }, + { url = "https://files.pythonhosted.org/packages/0a/e3/834e0919b34b40a6a2895f533323231bba3b8f5ae22c19ab725b84cf84c0/fonttools-4.55.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:95f5a1d4432b3cea6571f5ce4f4e9b25bf36efbd61c32f4f90130a690925d6ee", size = 2753424 }, + { url = "https://files.pythonhosted.org/packages/b6/f9/9cf7fc04da85d37cfa1c287f0a25c274d6940dad259dbaa9fd796b87bd3c/fonttools-4.55.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d20f152de7625a0008ba1513f126daaaa0de3b4b9030aa72dd5c27294992260", size = 2281635 }, + { url = "https://files.pythonhosted.org/packages/35/1f/25330293a5bb6bd50825725270c587c2b25c2694020a82d2c424d2fd5469/fonttools-4.55.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5a3ff5bb95fd5a3962b2754f8435e6d930c84fc9e9921c51e802dddf40acd56", size = 4869363 }, + { url = "https://files.pythonhosted.org/packages/f2/e0/e58b10ef50830145ba94dbeb64b70773af61cfccea663d485c7fae2aab65/fonttools-4.55.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b99d4fd2b6d0a00c7336c8363fccc7a11eccef4b17393af75ca6e77cf93ff413", size = 4898604 }, + { url = "https://files.pythonhosted.org/packages/e0/66/b59025011dbae1ea10dcb60f713a10e54d17cde5c8dc48db75af79dc2088/fonttools-4.55.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d637e4d33e46619c79d1a6c725f74d71b574cd15fb5bbb9b6f3eba8f28363573", size = 4877804 }, + { url = "https://files.pythonhosted.org/packages/67/76/abbbae972af55d54f83fcaeb90e26aaac937c8711b5a32d7c63768c37891/fonttools-4.55.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0f38bfb6b7a39c4162c3eb0820a0bdf8e3bdd125cd54e10ba242397d15e32439", size = 5045913 }, + { url = "https://files.pythonhosted.org/packages/8b/f2/5eb68b5202731b008ccfd4ad6d82af9a8abdec411609e76fdd6c43881f2c/fonttools-4.55.8-cp311-cp311-win32.whl", hash = "sha256:acfec948de41cd5e640d5c15d0200e8b8e7c5c6bb82afe1ca095cbc4af1188ee", size = 2154525 }, + { url = "https://files.pythonhosted.org/packages/42/d6/96dc2462006ffa16c8d475244e372abdc47d03a7bd38be0f29e7ae552af4/fonttools-4.55.8-cp311-cp311-win_amd64.whl", hash = "sha256:604c805b41241b4880e2dc86cf2d4754c06777371c8299799ac88d836cb18c3b", size = 2201043 }, + { url = "https://files.pythonhosted.org/packages/e9/ce/8358af1c353d890d4c6cbcc3d64242631f91a93f8384b76bc49db800f1de/fonttools-4.55.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:63403ee0f2fa4e1de28e539f8c24f2bdca1d8ecb503fa9ea2d231d9f1e729809", size = 2747851 }, + { url = "https://files.pythonhosted.org/packages/1b/3d/7a906f58f80c1ed37bbdf7b3f9b6792906156cb9143b067bf54c38405134/fonttools-4.55.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:302e1003a760b222f711d5ba6d1ad7fd5f7f713eb872cd6a3eb44390bc9770af", size = 2279102 }, + { url = "https://files.pythonhosted.org/packages/0a/0a/91a923a9de012e0f751ef8e13e1a5ea10f3a1b8416ae9afd5db1ad351b20/fonttools-4.55.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e72a7816ff8a759be9ca36ca46934f8ccf4383711ef597d9240306fe1878cb8d", size = 4784092 }, + { url = "https://files.pythonhosted.org/packages/e8/07/4b8a5c8a746cc8c8103c6462d057d8806bd925347ac3905055686dd40e94/fonttools-4.55.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03c2b50b54e6e8b3564b232e57e8f58be217cf441cf0155745d9e44a76f9c30f", size = 4855206 }, + { url = "https://files.pythonhosted.org/packages/37/df/09bf09ff8eae1e74bf16f9df514fd60af9f3d994e3edb0339f7d0bbc59e2/fonttools-4.55.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a7230f7590f9570d26ee903b6a4540274494e200fae978df0d9325b7b9144529", size = 4762599 }, + { url = "https://files.pythonhosted.org/packages/84/58/a80d97818a3bede7e4b58318302e89e749b9639c890ecbc972a6e533201f/fonttools-4.55.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:466a78984f0572305c3c48377f4e3f7f4e909f1209f45ef8e7041d5c8a744a56", size = 4990188 }, + { url = "https://files.pythonhosted.org/packages/a8/e3/1f1b1a70527ab9a1b9bfe1829a783a042c108ab3357af626e8e69a21f0e2/fonttools-4.55.8-cp312-cp312-win32.whl", hash = "sha256:243cbfc0b7cb1c307af40e321f8343a48d0a080bc1f9466cf2b5468f776ef108", size = 2142995 }, + { url = "https://files.pythonhosted.org/packages/61/cf/08c4954c944799458690eb0e498209fb6a2e79e20a869189f56d18e909b6/fonttools-4.55.8-cp312-cp312-win_amd64.whl", hash = "sha256:a19059aa892676822c1f05cb5a67296ecdfeb267fe7c47d4758f3e8e942c2b2a", size = 2189833 }, + { url = "https://files.pythonhosted.org/packages/87/fe/02a377477c5c95cb118ce8b7501d868e79fce310681a536bd1099bde6874/fonttools-4.55.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:332883b6280b9d90d2ba7e9e81be77cf2ace696161e60cdcf40cfcd2b3ed06fa", size = 2735213 }, + { url = "https://files.pythonhosted.org/packages/58/e4/a839f867e636419d7e5ca426a470df575bf7b20cc780862d6f64caee405c/fonttools-4.55.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6b8d7c149d47b47de7ec81763396c8266e5ebe2e0b14aa9c3ccf29e52260ab2f", size = 2272614 }, + { url = "https://files.pythonhosted.org/packages/31/c0/085d1fb2cff1589e038a67579660e16cdc0ea0ffe839a849879af43f6b1a/fonttools-4.55.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dfae7c94987149bdaa0388e6c937566aa398fa0eec973b17952350a069cff4e", size = 4762524 }, + { url = "https://files.pythonhosted.org/packages/b3/75/00670fa832e2986f9c6bfbd029f0a1e90a14333f0a6c02632284e9c1baa0/fonttools-4.55.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0fe12f06169af2fdc642d26a8df53e40adc3beedbd6ffedb19f1c5397b63afd", size = 4834537 }, + { url = "https://files.pythonhosted.org/packages/f4/a5/0fd300cdd1f9ab09857ba016a7acb9eff2fb3695109eb44d93ee28389a41/fonttools-4.55.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f971aa5f50c22dc4b63a891503624ae2c77330429b34ead32f23c2260c5618cd", size = 4742903 }, + { url = "https://files.pythonhosted.org/packages/59/e8/bb8da5e52802333e9ef23112583f9c24279f6cf720b005434f21f0e063fb/fonttools-4.55.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:708cb17b2590b7f6c6854999df0039ff1140dda9e6f56d67c3599ba6f968fab5", size = 4963841 }, + { url = "https://files.pythonhosted.org/packages/74/2b/e8268cfddb35d1ad964fcfe12d105ae4a7112b89fa098681dce110a97f9f/fonttools-4.55.8-cp313-cp313-win32.whl", hash = "sha256:cfe9cf30f391a0f2875247a3e5e44d8dcb61596e5cf89b360cdffec8a80e9961", size = 2141024 }, + { url = "https://files.pythonhosted.org/packages/b8/f9/3c69478a63250ad015a9ff1a75cd72d00aed0c26c188bd838ad5b67f7c83/fonttools-4.55.8-cp313-cp313-win_amd64.whl", hash = "sha256:1e10efc8ee10d6f1fe2931d41bccc90cd4b872f2ee4ff21f2231a2c293b2dbf8", size = 2186823 }, + { url = "https://files.pythonhosted.org/packages/cc/e6/efdcd5d6858b951c29d56de31a19355579d826712bf390d964a21b076ddb/fonttools-4.55.8-py3-none-any.whl", hash = "sha256:07636dae94f7fe88561f9da7a46b13d8e3f529f87fdb221b11d85f91eabceeb7", size = 1089900 }, +] + [[package]] name = "gast" version = "0.6.0" @@ -718,6 +832,93 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c9/fb/108ecd1fe961941959ad0ee4e12ee7b8b1477247f30b1fdfd83ceaf017f0/jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", size = 28965 }, ] +[[package]] +name = "kiwisolver" +version = "1.4.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/59/7c91426a8ac292e1cdd53a63b6d9439abd573c875c3f92c146767dd33faf/kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e", size = 97538 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/5f/4d8e9e852d98ecd26cdf8eaf7ed8bc33174033bba5e07001b289f07308fd/kiwisolver-1.4.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88c6f252f6816a73b1f8c904f7bbe02fd67c09a69f7cb8a0eecdbf5ce78e63db", size = 124623 }, + { url = "https://files.pythonhosted.org/packages/1d/70/7f5af2a18a76fe92ea14675f8bd88ce53ee79e37900fa5f1a1d8e0b42998/kiwisolver-1.4.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72941acb7b67138f35b879bbe85be0f6c6a70cab78fe3ef6db9c024d9223e5b", size = 66720 }, + { url = "https://files.pythonhosted.org/packages/c6/13/e15f804a142353aefd089fadc8f1d985561a15358c97aca27b0979cb0785/kiwisolver-1.4.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce2cf1e5688edcb727fdf7cd1bbd0b6416758996826a8be1d958f91880d0809d", size = 65413 }, + { url = "https://files.pythonhosted.org/packages/ce/6d/67d36c4d2054e83fb875c6b59d0809d5c530de8148846b1370475eeeece9/kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c8bf637892dc6e6aad2bc6d4d69d08764166e5e3f69d469e55427b6ac001b19d", size = 1650826 }, + { url = "https://files.pythonhosted.org/packages/de/c6/7b9bb8044e150d4d1558423a1568e4f227193662a02231064e3824f37e0a/kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:034d2c891f76bd3edbdb3ea11140d8510dca675443da7304205a2eaa45d8334c", size = 1628231 }, + { url = "https://files.pythonhosted.org/packages/b6/38/ad10d437563063eaaedbe2c3540a71101fc7fb07a7e71f855e93ea4de605/kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d47b28d1dfe0793d5e96bce90835e17edf9a499b53969b03c6c47ea5985844c3", size = 1408938 }, + { url = "https://files.pythonhosted.org/packages/52/ce/c0106b3bd7f9e665c5f5bc1e07cc95b5dabd4e08e3dad42dbe2faad467e7/kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb158fe28ca0c29f2260cca8c43005329ad58452c36f0edf298204de32a9a3ed", size = 1422799 }, + { url = "https://files.pythonhosted.org/packages/d0/87/efb704b1d75dc9758087ba374c0f23d3254505edaedd09cf9d247f7878b9/kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5536185fce131780ebd809f8e623bf4030ce1b161353166c49a3c74c287897f", size = 1354362 }, + { url = "https://files.pythonhosted.org/packages/eb/b3/fd760dc214ec9a8f208b99e42e8f0130ff4b384eca8b29dd0efc62052176/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:369b75d40abedc1da2c1f4de13f3482cb99e3237b38726710f4a793432b1c5ff", size = 2222695 }, + { url = "https://files.pythonhosted.org/packages/a2/09/a27fb36cca3fc01700687cc45dae7a6a5f8eeb5f657b9f710f788748e10d/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:641f2ddf9358c80faa22e22eb4c9f54bd3f0e442e038728f500e3b978d00aa7d", size = 2370802 }, + { url = "https://files.pythonhosted.org/packages/3d/c3/ba0a0346db35fe4dc1f2f2cf8b99362fbb922d7562e5f911f7ce7a7b60fa/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d561d2d8883e0819445cfe58d7ddd673e4015c3c57261d7bdcd3710d0d14005c", size = 2334646 }, + { url = "https://files.pythonhosted.org/packages/41/52/942cf69e562f5ed253ac67d5c92a693745f0bed3c81f49fc0cbebe4d6b00/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1732e065704b47c9afca7ffa272f845300a4eb959276bf6970dc07265e73b605", size = 2467260 }, + { url = "https://files.pythonhosted.org/packages/32/26/2d9668f30d8a494b0411d4d7d4ea1345ba12deb6a75274d58dd6ea01e951/kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bcb1ebc3547619c3b58a39e2448af089ea2ef44b37988caf432447374941574e", size = 2288633 }, + { url = "https://files.pythonhosted.org/packages/98/99/0dd05071654aa44fe5d5e350729961e7bb535372935a45ac89a8924316e6/kiwisolver-1.4.8-cp310-cp310-win_amd64.whl", hash = "sha256:89c107041f7b27844179ea9c85d6da275aa55ecf28413e87624d033cf1f6b751", size = 71885 }, + { url = "https://files.pythonhosted.org/packages/6c/fc/822e532262a97442989335394d441cd1d0448c2e46d26d3e04efca84df22/kiwisolver-1.4.8-cp310-cp310-win_arm64.whl", hash = "sha256:b5773efa2be9eb9fcf5415ea3ab70fc785d598729fd6057bea38d539ead28271", size = 65175 }, + { url = "https://files.pythonhosted.org/packages/da/ed/c913ee28936c371418cb167b128066ffb20bbf37771eecc2c97edf8a6e4c/kiwisolver-1.4.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a4d3601908c560bdf880f07d94f31d734afd1bb71e96585cace0e38ef44c6d84", size = 124635 }, + { url = "https://files.pythonhosted.org/packages/4c/45/4a7f896f7467aaf5f56ef093d1f329346f3b594e77c6a3c327b2d415f521/kiwisolver-1.4.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:856b269c4d28a5c0d5e6c1955ec36ebfd1651ac00e1ce0afa3e28da95293b561", size = 66717 }, + { url = "https://files.pythonhosted.org/packages/5f/b4/c12b3ac0852a3a68f94598d4c8d569f55361beef6159dce4e7b624160da2/kiwisolver-1.4.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c2b9a96e0f326205af81a15718a9073328df1173a2619a68553decb7097fd5d7", size = 65413 }, + { url = "https://files.pythonhosted.org/packages/a9/98/1df4089b1ed23d83d410adfdc5947245c753bddfbe06541c4aae330e9e70/kiwisolver-1.4.8-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5020c83e8553f770cb3b5fc13faac40f17e0b205bd237aebd21d53d733adb03", size = 1343994 }, + { url = "https://files.pythonhosted.org/packages/8d/bf/b4b169b050c8421a7c53ea1ea74e4ef9c335ee9013216c558a047f162d20/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dace81d28c787956bfbfbbfd72fdcef014f37d9b48830829e488fdb32b49d954", size = 1434804 }, + { url = "https://files.pythonhosted.org/packages/66/5a/e13bd341fbcf73325ea60fdc8af752addf75c5079867af2e04cc41f34434/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11e1022b524bd48ae56c9b4f9296bce77e15a2e42a502cceba602f804b32bb79", size = 1450690 }, + { url = "https://files.pythonhosted.org/packages/9b/4f/5955dcb376ba4a830384cc6fab7d7547bd6759fe75a09564910e9e3bb8ea/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b9b4d2892fefc886f30301cdd80debd8bb01ecdf165a449eb6e78f79f0fabd6", size = 1376839 }, + { url = "https://files.pythonhosted.org/packages/3a/97/5edbed69a9d0caa2e4aa616ae7df8127e10f6586940aa683a496c2c280b9/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a96c0e790ee875d65e340ab383700e2b4891677b7fcd30a699146f9384a2bb0", size = 1435109 }, + { url = "https://files.pythonhosted.org/packages/13/fc/e756382cb64e556af6c1809a1bbb22c141bbc2445049f2da06b420fe52bf/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23454ff084b07ac54ca8be535f4174170c1094a4cff78fbae4f73a4bcc0d4dab", size = 2245269 }, + { url = "https://files.pythonhosted.org/packages/76/15/e59e45829d7f41c776d138245cabae6515cb4eb44b418f6d4109c478b481/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:87b287251ad6488e95b4f0b4a79a6d04d3ea35fde6340eb38fbd1ca9cd35bbbc", size = 2393468 }, + { url = "https://files.pythonhosted.org/packages/e9/39/483558c2a913ab8384d6e4b66a932406f87c95a6080112433da5ed668559/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b21dbe165081142b1232a240fc6383fd32cdd877ca6cc89eab93e5f5883e1c25", size = 2355394 }, + { url = "https://files.pythonhosted.org/packages/01/aa/efad1fbca6570a161d29224f14b082960c7e08268a133fe5dc0f6906820e/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:768cade2c2df13db52475bd28d3a3fac8c9eff04b0e9e2fda0f3760f20b3f7fc", size = 2490901 }, + { url = "https://files.pythonhosted.org/packages/c9/4f/15988966ba46bcd5ab9d0c8296914436720dd67fca689ae1a75b4ec1c72f/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d47cfb2650f0e103d4bf68b0b5804c68da97272c84bb12850d877a95c056bd67", size = 2312306 }, + { url = "https://files.pythonhosted.org/packages/2d/27/bdf1c769c83f74d98cbc34483a972f221440703054894a37d174fba8aa68/kiwisolver-1.4.8-cp311-cp311-win_amd64.whl", hash = "sha256:ed33ca2002a779a2e20eeb06aea7721b6e47f2d4b8a8ece979d8ba9e2a167e34", size = 71966 }, + { url = "https://files.pythonhosted.org/packages/4a/c9/9642ea855604aeb2968a8e145fc662edf61db7632ad2e4fb92424be6b6c0/kiwisolver-1.4.8-cp311-cp311-win_arm64.whl", hash = "sha256:16523b40aab60426ffdebe33ac374457cf62863e330a90a0383639ce14bf44b2", size = 65311 }, + { url = "https://files.pythonhosted.org/packages/fc/aa/cea685c4ab647f349c3bc92d2daf7ae34c8e8cf405a6dcd3a497f58a2ac3/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6af5e8815fd02997cb6ad9bbed0ee1e60014438ee1a5c2444c96f87b8843502", size = 124152 }, + { url = "https://files.pythonhosted.org/packages/c5/0b/8db6d2e2452d60d5ebc4ce4b204feeb16176a851fd42462f66ade6808084/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bade438f86e21d91e0cf5dd7c0ed00cda0f77c8c1616bd83f9fc157fa6760d31", size = 66555 }, + { url = "https://files.pythonhosted.org/packages/60/26/d6a0db6785dd35d3ba5bf2b2df0aedc5af089962c6eb2cbf67a15b81369e/kiwisolver-1.4.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b83dc6769ddbc57613280118fb4ce3cd08899cc3369f7d0e0fab518a7cf37fdb", size = 65067 }, + { url = "https://files.pythonhosted.org/packages/c9/ed/1d97f7e3561e09757a196231edccc1bcf59d55ddccefa2afc9c615abd8e0/kiwisolver-1.4.8-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111793b232842991be367ed828076b03d96202c19221b5ebab421ce8bcad016f", size = 1378443 }, + { url = "https://files.pythonhosted.org/packages/29/61/39d30b99954e6b46f760e6289c12fede2ab96a254c443639052d1b573fbc/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257af1622860e51b1a9d0ce387bf5c2c4f36a90594cb9514f55b074bcc787cfc", size = 1472728 }, + { url = "https://files.pythonhosted.org/packages/0c/3e/804163b932f7603ef256e4a715e5843a9600802bb23a68b4e08c8c0ff61d/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b5637c3f316cab1ec1c9a12b8c5f4750a4c4b71af9157645bf32830e39c03a", size = 1478388 }, + { url = "https://files.pythonhosted.org/packages/8a/9e/60eaa75169a154700be74f875a4d9961b11ba048bef315fbe89cb6999056/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:782bb86f245ec18009890e7cb8d13a5ef54dcf2ebe18ed65f795e635a96a1c6a", size = 1413849 }, + { url = "https://files.pythonhosted.org/packages/bc/b3/9458adb9472e61a998c8c4d95cfdfec91c73c53a375b30b1428310f923e4/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc978a80a0db3a66d25767b03688f1147a69e6237175c0f4ffffaaedf744055a", size = 1475533 }, + { url = "https://files.pythonhosted.org/packages/e4/7a/0a42d9571e35798de80aef4bb43a9b672aa7f8e58643d7bd1950398ffb0a/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:36dbbfd34838500a31f52c9786990d00150860e46cd5041386f217101350f0d3", size = 2268898 }, + { url = "https://files.pythonhosted.org/packages/d9/07/1255dc8d80271400126ed8db35a1795b1a2c098ac3a72645075d06fe5c5d/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:eaa973f1e05131de5ff3569bbba7f5fd07ea0595d3870ed4a526d486fe57fa1b", size = 2425605 }, + { url = "https://files.pythonhosted.org/packages/84/df/5a3b4cf13780ef6f6942df67b138b03b7e79e9f1f08f57c49957d5867f6e/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a66f60f8d0c87ab7f59b6fb80e642ebb29fec354a4dfad687ca4092ae69d04f4", size = 2375801 }, + { url = "https://files.pythonhosted.org/packages/8f/10/2348d068e8b0f635c8c86892788dac7a6b5c0cb12356620ab575775aad89/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858416b7fb777a53f0c59ca08190ce24e9abbd3cffa18886a5781b8e3e26f65d", size = 2520077 }, + { url = "https://files.pythonhosted.org/packages/32/d8/014b89fee5d4dce157d814303b0fce4d31385a2af4c41fed194b173b81ac/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:085940635c62697391baafaaeabdf3dd7a6c3643577dde337f4d66eba021b2b8", size = 2338410 }, + { url = "https://files.pythonhosted.org/packages/bd/72/dfff0cc97f2a0776e1c9eb5bef1ddfd45f46246c6533b0191887a427bca5/kiwisolver-1.4.8-cp312-cp312-win_amd64.whl", hash = "sha256:01c3d31902c7db5fb6182832713d3b4122ad9317c2c5877d0539227d96bb2e50", size = 71853 }, + { url = "https://files.pythonhosted.org/packages/dc/85/220d13d914485c0948a00f0b9eb419efaf6da81b7d72e88ce2391f7aed8d/kiwisolver-1.4.8-cp312-cp312-win_arm64.whl", hash = "sha256:a3c44cb68861de93f0c4a8175fbaa691f0aa22550c331fefef02b618a9dcb476", size = 65424 }, + { url = "https://files.pythonhosted.org/packages/79/b3/e62464a652f4f8cd9006e13d07abad844a47df1e6537f73ddfbf1bc997ec/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1c8ceb754339793c24aee1c9fb2485b5b1f5bb1c2c214ff13368431e51fc9a09", size = 124156 }, + { url = "https://files.pythonhosted.org/packages/8d/2d/f13d06998b546a2ad4f48607a146e045bbe48030774de29f90bdc573df15/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a62808ac74b5e55a04a408cda6156f986cefbcf0ada13572696b507cc92fa1", size = 66555 }, + { url = "https://files.pythonhosted.org/packages/59/e3/b8bd14b0a54998a9fd1e8da591c60998dc003618cb19a3f94cb233ec1511/kiwisolver-1.4.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68269e60ee4929893aad82666821aaacbd455284124817af45c11e50a4b42e3c", size = 65071 }, + { url = "https://files.pythonhosted.org/packages/f0/1c/6c86f6d85ffe4d0ce04228d976f00674f1df5dc893bf2dd4f1928748f187/kiwisolver-1.4.8-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d142fba9c464bc3bbfeff15c96eab0e7310343d6aefb62a79d51421fcc5f1b", size = 1378053 }, + { url = "https://files.pythonhosted.org/packages/4e/b9/1c6e9f6dcb103ac5cf87cb695845f5fa71379021500153566d8a8a9fc291/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc373e0eef45b59197de815b1b28ef89ae3955e7722cc9710fb91cd77b7f47", size = 1472278 }, + { url = "https://files.pythonhosted.org/packages/ee/81/aca1eb176de671f8bda479b11acdc42c132b61a2ac861c883907dde6debb/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77e6f57a20b9bd4e1e2cedda4d0b986ebd0216236f0106e55c28aea3d3d69b16", size = 1478139 }, + { url = "https://files.pythonhosted.org/packages/49/f4/e081522473671c97b2687d380e9e4c26f748a86363ce5af48b4a28e48d06/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08e77738ed7538f036cd1170cbed942ef749137b1311fa2bbe2a7fda2f6bf3cc", size = 1413517 }, + { url = "https://files.pythonhosted.org/packages/8f/e9/6a7d025d8da8c4931522922cd706105aa32b3291d1add8c5427cdcd66e63/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5ce1e481a74b44dd5e92ff03ea0cb371ae7a0268318e202be06c8f04f4f1246", size = 1474952 }, + { url = "https://files.pythonhosted.org/packages/82/13/13fa685ae167bee5d94b415991c4fc7bb0a1b6ebea6e753a87044b209678/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc2ace710ba7c1dfd1a3b42530b62b9ceed115f19a1656adefce7b1782a37794", size = 2269132 }, + { url = "https://files.pythonhosted.org/packages/ef/92/bb7c9395489b99a6cb41d502d3686bac692586db2045adc19e45ee64ed23/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3452046c37c7692bd52b0e752b87954ef86ee2224e624ef7ce6cb21e8c41cc1b", size = 2425997 }, + { url = "https://files.pythonhosted.org/packages/ed/12/87f0e9271e2b63d35d0d8524954145837dd1a6c15b62a2d8c1ebe0f182b4/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7e9a60b50fe8b2ec6f448fe8d81b07e40141bfced7f896309df271a0b92f80f3", size = 2376060 }, + { url = "https://files.pythonhosted.org/packages/02/6e/c8af39288edbce8bf0fa35dee427b082758a4b71e9c91ef18fa667782138/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:918139571133f366e8362fa4a297aeba86c7816b7ecf0bc79168080e2bd79957", size = 2520471 }, + { url = "https://files.pythonhosted.org/packages/13/78/df381bc7b26e535c91469f77f16adcd073beb3e2dd25042efd064af82323/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e063ef9f89885a1d68dd8b2e18f5ead48653176d10a0e324e3b0030e3a69adeb", size = 2338793 }, + { url = "https://files.pythonhosted.org/packages/d0/dc/c1abe38c37c071d0fc71c9a474fd0b9ede05d42f5a458d584619cfd2371a/kiwisolver-1.4.8-cp313-cp313-win_amd64.whl", hash = "sha256:a17b7c4f5b2c51bb68ed379defd608a03954a1845dfed7cc0117f1cc8a9b7fd2", size = 71855 }, + { url = "https://files.pythonhosted.org/packages/a0/b6/21529d595b126ac298fdd90b705d87d4c5693de60023e0efcb4f387ed99e/kiwisolver-1.4.8-cp313-cp313-win_arm64.whl", hash = "sha256:3cd3bc628b25f74aedc6d374d5babf0166a92ff1317f46267f12d2ed54bc1d30", size = 65430 }, + { url = "https://files.pythonhosted.org/packages/34/bd/b89380b7298e3af9b39f49334e3e2a4af0e04819789f04b43d560516c0c8/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:370fd2df41660ed4e26b8c9d6bbcad668fbe2560462cba151a721d49e5b6628c", size = 126294 }, + { url = "https://files.pythonhosted.org/packages/83/41/5857dc72e5e4148eaac5aa76e0703e594e4465f8ab7ec0fc60e3a9bb8fea/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:84a2f830d42707de1d191b9490ac186bf7997a9495d4e9072210a1296345f7dc", size = 67736 }, + { url = "https://files.pythonhosted.org/packages/e1/d1/be059b8db56ac270489fb0b3297fd1e53d195ba76e9bbb30e5401fa6b759/kiwisolver-1.4.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7a3ad337add5148cf51ce0b55642dc551c0b9d6248458a757f98796ca7348712", size = 66194 }, + { url = "https://files.pythonhosted.org/packages/e1/83/4b73975f149819eb7dcf9299ed467eba068ecb16439a98990dcb12e63fdd/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7506488470f41169b86d8c9aeff587293f530a23a23a49d6bc64dab66bedc71e", size = 1465942 }, + { url = "https://files.pythonhosted.org/packages/c7/2c/30a5cdde5102958e602c07466bce058b9d7cb48734aa7a4327261ac8e002/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f0121b07b356a22fb0414cec4666bbe36fd6d0d759db3d37228f496ed67c880", size = 1595341 }, + { url = "https://files.pythonhosted.org/packages/ff/9b/1e71db1c000385aa069704f5990574b8244cce854ecd83119c19e83c9586/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6d6bd87df62c27d4185de7c511c6248040afae67028a8a22012b010bc7ad062", size = 1598455 }, + { url = "https://files.pythonhosted.org/packages/85/92/c8fec52ddf06231b31cbb779af77e99b8253cd96bd135250b9498144c78b/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:291331973c64bb9cce50bbe871fb2e675c4331dab4f31abe89f175ad7679a4d7", size = 1522138 }, + { url = "https://files.pythonhosted.org/packages/0b/51/9eb7e2cd07a15d8bdd976f6190c0164f92ce1904e5c0c79198c4972926b7/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:893f5525bb92d3d735878ec00f781b2de998333659507d29ea4466208df37bed", size = 1582857 }, + { url = "https://files.pythonhosted.org/packages/0f/95/c5a00387a5405e68ba32cc64af65ce881a39b98d73cc394b24143bebc5b8/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b47a465040146981dc9db8647981b8cb96366fbc8d452b031e4f8fdffec3f26d", size = 2293129 }, + { url = "https://files.pythonhosted.org/packages/44/83/eeb7af7d706b8347548313fa3a3a15931f404533cc54fe01f39e830dd231/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:99cea8b9dd34ff80c521aef46a1dddb0dcc0283cf18bde6d756f1e6f31772165", size = 2421538 }, + { url = "https://files.pythonhosted.org/packages/05/f9/27e94c1b3eb29e6933b6986ffc5fa1177d2cd1f0c8efc5f02c91c9ac61de/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:151dffc4865e5fe6dafce5480fab84f950d14566c480c08a53c663a0020504b6", size = 2390661 }, + { url = "https://files.pythonhosted.org/packages/d9/d4/3c9735faa36ac591a4afcc2980d2691000506050b7a7e80bcfe44048daa7/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:577facaa411c10421314598b50413aa1ebcf5126f704f1e5d72d7e4e9f020d90", size = 2546710 }, + { url = "https://files.pythonhosted.org/packages/4c/fa/be89a49c640930180657482a74970cdcf6f7072c8d2471e1babe17a222dc/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:be4816dc51c8a471749d664161b434912eee82f2ea66bd7628bd14583a833e85", size = 2349213 }, + { url = "https://files.pythonhosted.org/packages/1f/f9/ae81c47a43e33b93b0a9819cac6723257f5da2a5a60daf46aa5c7226ea85/kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e7a019419b7b510f0f7c9dceff8c5eae2392037eae483a7f9162625233802b0a", size = 60403 }, + { url = "https://files.pythonhosted.org/packages/58/ca/f92b5cb6f4ce0c1ebfcfe3e2e42b96917e16f7090e45b21102941924f18f/kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:286b18e86682fd2217a48fc6be6b0f20c1d0ed10958d8dc53453ad58d7be0bf8", size = 58657 }, + { url = "https://files.pythonhosted.org/packages/80/28/ae0240f732f0484d3a4dc885d055653c47144bdf59b670aae0ec3c65a7c8/kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4191ee8dfd0be1c3666ccbac178c5a05d5f8d689bbe3fc92f3c4abec817f8fe0", size = 84948 }, + { url = "https://files.pythonhosted.org/packages/5d/eb/78d50346c51db22c7203c1611f9b513075f35c4e0e4877c5dde378d66043/kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cd2785b9391f2873ad46088ed7599a6a71e762e1ea33e87514b1a441ed1da1c", size = 81186 }, + { url = "https://files.pythonhosted.org/packages/43/f8/7259f18c77adca88d5f64f9a522792e178b2691f3748817a8750c2d216ef/kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c07b29089b7ba090b6f1a669f1411f27221c3662b3a1b7010e67b59bb5a6f10b", size = 80279 }, + { url = "https://files.pythonhosted.org/packages/3a/1d/50ad811d1c5dae091e4cf046beba925bcae0a610e79ae4c538f996f63ed5/kiwisolver-1.4.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:65ea09a5a3faadd59c2ce96dc7bf0f364986a315949dc6374f04396b0d60e09b", size = 71762 }, +] + [[package]] name = "markdown-it-py" version = "3.0.0" @@ -788,6 +989,58 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, ] +[[package]] +name = "matplotlib" +version = "3.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/68/dd/fa2e1a45fce2d09f4aea3cee169760e672c8262325aa5796c49d543dc7e6/matplotlib-3.10.0.tar.gz", hash = "sha256:b886d02a581b96704c9d1ffe55709e49b4d2d52709ccebc4be42db856e511278", size = 36686418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/ec/3cdff7b5239adaaacefcc4f77c316dfbbdf853c4ed2beec467e0fec31b9f/matplotlib-3.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2c5829a5a1dd5a71f0e31e6e8bb449bc0ee9dbfb05ad28fc0c6b55101b3a4be6", size = 8160551 }, + { url = "https://files.pythonhosted.org/packages/41/f2/b518f2c7f29895c9b167bf79f8529c63383ae94eaf49a247a4528e9a148d/matplotlib-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2a43cbefe22d653ab34bb55d42384ed30f611bcbdea1f8d7f431011a2e1c62e", size = 8034853 }, + { url = "https://files.pythonhosted.org/packages/ed/8d/45754b4affdb8f0d1a44e4e2bcd932cdf35b256b60d5eda9f455bb293ed0/matplotlib-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:607b16c8a73943df110f99ee2e940b8a1cbf9714b65307c040d422558397dac5", size = 8446724 }, + { url = "https://files.pythonhosted.org/packages/09/5a/a113495110ae3e3395c72d82d7bc4802902e46dc797f6b041e572f195c56/matplotlib-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01d2b19f13aeec2e759414d3bfe19ddfb16b13a1250add08d46d5ff6f9be83c6", size = 8583905 }, + { url = "https://files.pythonhosted.org/packages/12/b1/8b1655b4c9ed4600c817c419f7eaaf70082630efd7556a5b2e77a8a3cdaf/matplotlib-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e6c6461e1fc63df30bf6f80f0b93f5b6784299f721bc28530477acd51bfc3d1", size = 9395223 }, + { url = "https://files.pythonhosted.org/packages/5a/85/b9a54d64585a6b8737a78a61897450403c30f39e0bd3214270bb0b96f002/matplotlib-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:994c07b9d9fe8d25951e3202a68c17900679274dadfc1248738dcfa1bd40d7f3", size = 8025355 }, + { url = "https://files.pythonhosted.org/packages/0c/f1/e37f6c84d252867d7ddc418fff70fc661cfd363179263b08e52e8b748e30/matplotlib-3.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:fd44fc75522f58612ec4a33958a7e5552562b7705b42ef1b4f8c0818e304a363", size = 8171677 }, + { url = "https://files.pythonhosted.org/packages/c7/8b/92e9da1f28310a1f6572b5c55097b0c0ceb5e27486d85fb73b54f5a9b939/matplotlib-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c58a9622d5dbeb668f407f35f4e6bfac34bb9ecdcc81680c04d0258169747997", size = 8044945 }, + { url = "https://files.pythonhosted.org/packages/c5/cb/49e83f0fd066937a5bd3bc5c5d63093703f3637b2824df8d856e0558beef/matplotlib-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:845d96568ec873be63f25fa80e9e7fae4be854a66a7e2f0c8ccc99e94a8bd4ef", size = 8458269 }, + { url = "https://files.pythonhosted.org/packages/b2/7d/2d873209536b9ee17340754118a2a17988bc18981b5b56e6715ee07373ac/matplotlib-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5439f4c5a3e2e8eab18e2f8c3ef929772fd5641876db71f08127eed95ab64683", size = 8599369 }, + { url = "https://files.pythonhosted.org/packages/b8/03/57d6cbbe85c61fe4cbb7c94b54dce443d68c21961830833a1f34d056e5ea/matplotlib-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4673ff67a36152c48ddeaf1135e74ce0d4bce1bbf836ae40ed39c29edf7e2765", size = 9405992 }, + { url = "https://files.pythonhosted.org/packages/14/cf/e382598f98be11bf51dd0bc60eca44a517f6793e3dc8b9d53634a144620c/matplotlib-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:7e8632baebb058555ac0cde75db885c61f1212e47723d63921879806b40bec6a", size = 8034580 }, + { url = "https://files.pythonhosted.org/packages/44/c7/6b2d8cb7cc251d53c976799cacd3200add56351c175ba89ab9cbd7c1e68a/matplotlib-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4659665bc7c9b58f8c00317c3c2a299f7f258eeae5a5d56b4c64226fca2f7c59", size = 8172465 }, + { url = "https://files.pythonhosted.org/packages/42/2a/6d66d0fba41e13e9ca6512a0a51170f43e7e7ed3a8dfa036324100775612/matplotlib-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d44cb942af1693cced2604c33a9abcef6205601c445f6d0dc531d813af8a2f5a", size = 8043300 }, + { url = "https://files.pythonhosted.org/packages/90/60/2a60342b27b90a16bada939a85e29589902b41073f59668b904b15ea666c/matplotlib-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a994f29e968ca002b50982b27168addfd65f0105610b6be7fa515ca4b5307c95", size = 8448936 }, + { url = "https://files.pythonhosted.org/packages/a7/b2/d872fc3d753516870d520595ddd8ce4dd44fa797a240999f125f58521ad7/matplotlib-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b0558bae37f154fffda54d779a592bc97ca8b4701f1c710055b609a3bac44c8", size = 8594151 }, + { url = "https://files.pythonhosted.org/packages/f4/bd/b2f60cf7f57d014ab33e4f74602a2b5bdc657976db8196bbc022185f6f9c/matplotlib-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:503feb23bd8c8acc75541548a1d709c059b7184cde26314896e10a9f14df5f12", size = 9400347 }, + { url = "https://files.pythonhosted.org/packages/9f/6e/264673e64001b99d747aff5a288eca82826c024437a3694e19aed1decf46/matplotlib-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:c40ba2eb08b3f5de88152c2333c58cee7edcead0a2a0d60fcafa116b17117adc", size = 8039144 }, + { url = "https://files.pythonhosted.org/packages/72/11/1b2a094d95dcb6e6edd4a0b238177c439006c6b7a9fe8d31801237bf512f/matplotlib-3.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96f2886f5c1e466f21cc41b70c5a0cd47bfa0015eb2d5793c88ebce658600e25", size = 8173073 }, + { url = "https://files.pythonhosted.org/packages/0d/c4/87b6ad2723070511a411ea719f9c70fde64605423b184face4e94986de9d/matplotlib-3.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:12eaf48463b472c3c0f8dbacdbf906e573013df81a0ab82f0616ea4b11281908", size = 8043892 }, + { url = "https://files.pythonhosted.org/packages/57/69/cb0812a136550b21361335e9ffb7d459bf6d13e03cb7b015555d5143d2d6/matplotlib-3.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fbbabc82fde51391c4da5006f965e36d86d95f6ee83fb594b279564a4c5d0d2", size = 8450532 }, + { url = "https://files.pythonhosted.org/packages/ea/3a/bab9deb4fb199c05e9100f94d7f1c702f78d3241e6a71b784d2b88d7bebd/matplotlib-3.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad2e15300530c1a94c63cfa546e3b7864bd18ea2901317bae8bbf06a5ade6dcf", size = 8593905 }, + { url = "https://files.pythonhosted.org/packages/8b/66/742fd242f989adc1847ddf5f445815f73ad7c46aa3440690cc889cfa423c/matplotlib-3.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3547d153d70233a8496859097ef0312212e2689cdf8d7ed764441c77604095ae", size = 9399609 }, + { url = "https://files.pythonhosted.org/packages/fa/d6/54cee7142cef7d910a324a7aedf335c0c147b03658b54d49ec48166f10a6/matplotlib-3.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:c55b20591ced744aa04e8c3e4b7543ea4d650b6c3c4b208c08a05b4010e8b442", size = 8039076 }, + { url = "https://files.pythonhosted.org/packages/43/14/815d072dc36e88753433bfd0385113405efb947e6895ff7b4d2e8614a33b/matplotlib-3.10.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9ade1003376731a971e398cc4ef38bb83ee8caf0aee46ac6daa4b0506db1fd06", size = 8211000 }, + { url = "https://files.pythonhosted.org/packages/9a/76/34e75f364194ec352678adcb540964be6f35ec7d3d8c75ebcb17e6839359/matplotlib-3.10.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95b710fea129c76d30be72c3b38f330269363fbc6e570a5dd43580487380b5ff", size = 8087707 }, + { url = "https://files.pythonhosted.org/packages/c3/2b/b6bc0dff6a72d333bc7df94a66e6ce662d224e43daa8ad8ae4eaa9a77f55/matplotlib-3.10.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdbaf909887373c3e094b0318d7ff230b2ad9dcb64da7ade654182872ab2593", size = 8477384 }, + { url = "https://files.pythonhosted.org/packages/c2/2d/b5949fb2b76e9b47ab05e25a5f5f887c70de20d8b0cbc704a4e2ee71c786/matplotlib-3.10.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d907fddb39f923d011875452ff1eca29a9e7f21722b873e90db32e5d8ddff12e", size = 8610334 }, + { url = "https://files.pythonhosted.org/packages/d6/9a/6e3c799d5134d9af44b01c787e1360bee38cf51850506ea2e743a787700b/matplotlib-3.10.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3b427392354d10975c1d0f4ee18aa5844640b512d5311ef32efd4dd7db106ede", size = 9406777 }, + { url = "https://files.pythonhosted.org/packages/0e/dd/e6ae97151e5ed648ab2ea48885bc33d39202b640eec7a2910e2c843f7ac0/matplotlib-3.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5fd41b0ec7ee45cd960a8e71aea7c946a28a0b8a4dcee47d2856b2af051f334c", size = 8109742 }, + { url = "https://files.pythonhosted.org/packages/32/5f/29def7ce4e815ab939b56280976ee35afffb3bbdb43f332caee74cb8c951/matplotlib-3.10.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:81713dd0d103b379de4516b861d964b1d789a144103277769238c732229d7f03", size = 8155500 }, + { url = "https://files.pythonhosted.org/packages/de/6d/d570383c9f7ca799d0a54161446f9ce7b17d6c50f2994b653514bcaa108f/matplotlib-3.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:359f87baedb1f836ce307f0e850d12bb5f1936f70d035561f90d41d305fdacea", size = 8032398 }, + { url = "https://files.pythonhosted.org/packages/c9/b4/680aa700d99b48e8c4393fa08e9ab8c49c0555ee6f4c9c0a5e8ea8dfde5d/matplotlib-3.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae80dc3a4add4665cf2faa90138384a7ffe2a4e37c58d83e115b54287c4f06ef", size = 8587361 }, +] + [[package]] name = "matplotlib-inline" version = "0.1.7" @@ -1039,6 +1292,73 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, ] +[[package]] +name = "pillow" +version = "11.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/1c/2dcea34ac3d7bc96a1fd1bd0a6e06a57c67167fec2cff8d95d88229a8817/pillow-11.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8", size = 3229983 }, + { url = "https://files.pythonhosted.org/packages/14/ca/6bec3df25e4c88432681de94a3531cc738bd85dea6c7aa6ab6f81ad8bd11/pillow-11.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192", size = 3101831 }, + { url = "https://files.pythonhosted.org/packages/d4/2c/668e18e5521e46eb9667b09e501d8e07049eb5bfe39d56be0724a43117e6/pillow-11.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a07dba04c5e22824816b2615ad7a7484432d7f540e6fa86af60d2de57b0fcee2", size = 4314074 }, + { url = "https://files.pythonhosted.org/packages/02/80/79f99b714f0fc25f6a8499ecfd1f810df12aec170ea1e32a4f75746051ce/pillow-11.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e267b0ed063341f3e60acd25c05200df4193e15a4a5807075cd71225a2386e26", size = 4394933 }, + { url = "https://files.pythonhosted.org/packages/81/aa/8d4ad25dc11fd10a2001d5b8a80fdc0e564ac33b293bdfe04ed387e0fd95/pillow-11.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bd165131fd51697e22421d0e467997ad31621b74bfc0b75956608cb2906dda07", size = 4353349 }, + { url = "https://files.pythonhosted.org/packages/84/7a/cd0c3eaf4a28cb2a74bdd19129f7726277a7f30c4f8424cd27a62987d864/pillow-11.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:abc56501c3fd148d60659aae0af6ddc149660469082859fa7b066a298bde9482", size = 4476532 }, + { url = "https://files.pythonhosted.org/packages/8f/8b/a907fdd3ae8f01c7670dfb1499c53c28e217c338b47a813af8d815e7ce97/pillow-11.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:54ce1c9a16a9561b6d6d8cb30089ab1e5eb66918cb47d457bd996ef34182922e", size = 4279789 }, + { url = "https://files.pythonhosted.org/packages/6f/9a/9f139d9e8cccd661c3efbf6898967a9a337eb2e9be2b454ba0a09533100d/pillow-11.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:73ddde795ee9b06257dac5ad42fcb07f3b9b813f8c1f7f870f402f4dc54b5269", size = 4413131 }, + { url = "https://files.pythonhosted.org/packages/a8/68/0d8d461f42a3f37432203c8e6df94da10ac8081b6d35af1c203bf3111088/pillow-11.1.0-cp310-cp310-win32.whl", hash = "sha256:3a5fe20a7b66e8135d7fd617b13272626a28278d0e578c98720d9ba4b2439d49", size = 2291213 }, + { url = "https://files.pythonhosted.org/packages/14/81/d0dff759a74ba87715509af9f6cb21fa21d93b02b3316ed43bda83664db9/pillow-11.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6123aa4a59d75f06e9dd3dac5bf8bc9aa383121bb3dd9a7a612e05eabc9961a", size = 2625725 }, + { url = "https://files.pythonhosted.org/packages/ce/1f/8d50c096a1d58ef0584ddc37e6f602828515219e9d2428e14ce50f5ecad1/pillow-11.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:a76da0a31da6fcae4210aa94fd779c65c75786bc9af06289cd1c184451ef7a65", size = 2375213 }, + { url = "https://files.pythonhosted.org/packages/dd/d6/2000bfd8d5414fb70cbbe52c8332f2283ff30ed66a9cde42716c8ecbe22c/pillow-11.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e06695e0326d05b06833b40b7ef477e475d0b1ba3a6d27da1bb48c23209bf457", size = 3229968 }, + { url = "https://files.pythonhosted.org/packages/d9/45/3fe487010dd9ce0a06adf9b8ff4f273cc0a44536e234b0fad3532a42c15b/pillow-11.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96f82000e12f23e4f29346e42702b6ed9a2f2fea34a740dd5ffffcc8c539eb35", size = 3101806 }, + { url = "https://files.pythonhosted.org/packages/e3/72/776b3629c47d9d5f1c160113158a7a7ad177688d3a1159cd3b62ded5a33a/pillow-11.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3cd561ded2cf2bbae44d4605837221b987c216cff94f49dfeed63488bb228d2", size = 4322283 }, + { url = "https://files.pythonhosted.org/packages/e4/c2/e25199e7e4e71d64eeb869f5b72c7ddec70e0a87926398785ab944d92375/pillow-11.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f189805c8be5ca5add39e6f899e6ce2ed824e65fb45f3c28cb2841911da19070", size = 4402945 }, + { url = "https://files.pythonhosted.org/packages/c1/ed/51d6136c9d5911f78632b1b86c45241c712c5a80ed7fa7f9120a5dff1eba/pillow-11.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dd0052e9db3474df30433f83a71b9b23bd9e4ef1de13d92df21a52c0303b8ab6", size = 4361228 }, + { url = "https://files.pythonhosted.org/packages/48/a4/fbfe9d5581d7b111b28f1d8c2762dee92e9821bb209af9fa83c940e507a0/pillow-11.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:837060a8599b8f5d402e97197d4924f05a2e0d68756998345c829c33186217b1", size = 4484021 }, + { url = "https://files.pythonhosted.org/packages/39/db/0b3c1a5018117f3c1d4df671fb8e47d08937f27519e8614bbe86153b65a5/pillow-11.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa8dd43daa836b9a8128dbe7d923423e5ad86f50a7a14dc688194b7be5c0dea2", size = 4287449 }, + { url = "https://files.pythonhosted.org/packages/d9/58/bc128da7fea8c89fc85e09f773c4901e95b5936000e6f303222490c052f3/pillow-11.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0a2f91f8a8b367e7a57c6e91cd25af510168091fb89ec5146003e424e1558a96", size = 4419972 }, + { url = "https://files.pythonhosted.org/packages/5f/bb/58f34379bde9fe197f51841c5bbe8830c28bbb6d3801f16a83b8f2ad37df/pillow-11.1.0-cp311-cp311-win32.whl", hash = "sha256:c12fc111ef090845de2bb15009372175d76ac99969bdf31e2ce9b42e4b8cd88f", size = 2291201 }, + { url = "https://files.pythonhosted.org/packages/3a/c6/fce9255272bcf0c39e15abd2f8fd8429a954cf344469eaceb9d0d1366913/pillow-11.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd43429d0d7ed6533b25fc993861b8fd512c42d04514a0dd6337fb3ccf22761", size = 2625686 }, + { url = "https://files.pythonhosted.org/packages/c8/52/8ba066d569d932365509054859f74f2a9abee273edcef5cd75e4bc3e831e/pillow-11.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f7955ecf5609dee9442cbface754f2c6e541d9e6eda87fad7f7a989b0bdb9d71", size = 2375194 }, + { url = "https://files.pythonhosted.org/packages/95/20/9ce6ed62c91c073fcaa23d216e68289e19d95fb8188b9fb7a63d36771db8/pillow-11.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a", size = 3226818 }, + { url = "https://files.pythonhosted.org/packages/b9/d8/f6004d98579a2596c098d1e30d10b248798cceff82d2b77aa914875bfea1/pillow-11.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b", size = 3101662 }, + { url = "https://files.pythonhosted.org/packages/08/d9/892e705f90051c7a2574d9f24579c9e100c828700d78a63239676f960b74/pillow-11.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3", size = 4329317 }, + { url = "https://files.pythonhosted.org/packages/8c/aa/7f29711f26680eab0bcd3ecdd6d23ed6bce180d82e3f6380fb7ae35fcf3b/pillow-11.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a", size = 4412999 }, + { url = "https://files.pythonhosted.org/packages/c8/c4/8f0fe3b9e0f7196f6d0bbb151f9fba323d72a41da068610c4c960b16632a/pillow-11.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1", size = 4368819 }, + { url = "https://files.pythonhosted.org/packages/38/0d/84200ed6a871ce386ddc82904bfadc0c6b28b0c0ec78176871a4679e40b3/pillow-11.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f", size = 4496081 }, + { url = "https://files.pythonhosted.org/packages/84/9c/9bcd66f714d7e25b64118e3952d52841a4babc6d97b6d28e2261c52045d4/pillow-11.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91", size = 4296513 }, + { url = "https://files.pythonhosted.org/packages/db/61/ada2a226e22da011b45f7104c95ebda1b63dcbb0c378ad0f7c2a710f8fd2/pillow-11.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c", size = 4431298 }, + { url = "https://files.pythonhosted.org/packages/e7/c4/fc6e86750523f367923522014b821c11ebc5ad402e659d8c9d09b3c9d70c/pillow-11.1.0-cp312-cp312-win32.whl", hash = "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6", size = 2291630 }, + { url = "https://files.pythonhosted.org/packages/08/5c/2104299949b9d504baf3f4d35f73dbd14ef31bbd1ddc2c1b66a5b7dfda44/pillow-11.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf", size = 2626369 }, + { url = "https://files.pythonhosted.org/packages/37/f3/9b18362206b244167c958984b57c7f70a0289bfb59a530dd8af5f699b910/pillow-11.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5", size = 2375240 }, + { url = "https://files.pythonhosted.org/packages/b3/31/9ca79cafdce364fd5c980cd3416c20ce1bebd235b470d262f9d24d810184/pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", size = 3226640 }, + { url = "https://files.pythonhosted.org/packages/ac/0f/ff07ad45a1f172a497aa393b13a9d81a32e1477ef0e869d030e3c1532521/pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", size = 3101437 }, + { url = "https://files.pythonhosted.org/packages/08/2f/9906fca87a68d29ec4530be1f893149e0cb64a86d1f9f70a7cfcdfe8ae44/pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", size = 4326605 }, + { url = "https://files.pythonhosted.org/packages/b0/0f/f3547ee15b145bc5c8b336401b2d4c9d9da67da9dcb572d7c0d4103d2c69/pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", size = 4411173 }, + { url = "https://files.pythonhosted.org/packages/b1/df/bf8176aa5db515c5de584c5e00df9bab0713548fd780c82a86cba2c2fedb/pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", size = 4369145 }, + { url = "https://files.pythonhosted.org/packages/de/7c/7433122d1cfadc740f577cb55526fdc39129a648ac65ce64db2eb7209277/pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", size = 4496340 }, + { url = "https://files.pythonhosted.org/packages/25/46/dd94b93ca6bd555588835f2504bd90c00d5438fe131cf01cfa0c5131a19d/pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", size = 4296906 }, + { url = "https://files.pythonhosted.org/packages/a8/28/2f9d32014dfc7753e586db9add35b8a41b7a3b46540e965cb6d6bc607bd2/pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", size = 4431759 }, + { url = "https://files.pythonhosted.org/packages/33/48/19c2cbe7403870fbe8b7737d19eb013f46299cdfe4501573367f6396c775/pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", size = 2291657 }, + { url = "https://files.pythonhosted.org/packages/3b/ad/285c556747d34c399f332ba7c1a595ba245796ef3e22eae190f5364bb62b/pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", size = 2626304 }, + { url = "https://files.pythonhosted.org/packages/e5/7b/ef35a71163bf36db06e9c8729608f78dedf032fc8313d19bd4be5c2588f3/pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", size = 2375117 }, + { url = "https://files.pythonhosted.org/packages/79/30/77f54228401e84d6791354888549b45824ab0ffde659bafa67956303a09f/pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", size = 3230060 }, + { url = "https://files.pythonhosted.org/packages/ce/b1/56723b74b07dd64c1010fee011951ea9c35a43d8020acd03111f14298225/pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", size = 3106192 }, + { url = "https://files.pythonhosted.org/packages/e1/cd/7bf7180e08f80a4dcc6b4c3a0aa9e0b0ae57168562726a05dc8aa8fa66b0/pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", size = 4446805 }, + { url = "https://files.pythonhosted.org/packages/97/42/87c856ea30c8ed97e8efbe672b58c8304dee0573f8c7cab62ae9e31db6ae/pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", size = 4530623 }, + { url = "https://files.pythonhosted.org/packages/ff/41/026879e90c84a88e33fb00cc6bd915ac2743c67e87a18f80270dfe3c2041/pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", size = 4465191 }, + { url = "https://files.pythonhosted.org/packages/e5/fb/a7960e838bc5df57a2ce23183bfd2290d97c33028b96bde332a9057834d3/pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", size = 2295494 }, + { url = "https://files.pythonhosted.org/packages/d7/6c/6ec83ee2f6f0fda8d4cf89045c6be4b0373ebfc363ba8538f8c999f63fcd/pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", size = 2631595 }, + { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651 }, + { url = "https://files.pythonhosted.org/packages/fa/c5/389961578fb677b8b3244fcd934f720ed25a148b9a5cc81c91bdf59d8588/pillow-11.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8c730dc3a83e5ac137fbc92dfcfe1511ce3b2b5d7578315b63dbbb76f7f51d90", size = 3198345 }, + { url = "https://files.pythonhosted.org/packages/c4/fa/803c0e50ffee74d4b965229e816af55276eac1d5806712de86f9371858fd/pillow-11.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d33d2fae0e8b170b6a6c57400e077412240f6f5bb2a342cf1ee512a787942bb", size = 3072938 }, + { url = "https://files.pythonhosted.org/packages/dc/67/2a3a5f8012b5d8c63fe53958ba906c1b1d0482ebed5618057ef4d22f8076/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8d65b38173085f24bc07f8b6c505cbb7418009fa1a1fcb111b1f4961814a442", size = 3400049 }, + { url = "https://files.pythonhosted.org/packages/e5/a0/514f0d317446c98c478d1872497eb92e7cde67003fed74f696441e647446/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:015c6e863faa4779251436db398ae75051469f7c903b043a48f078e437656f83", size = 3422431 }, + { url = "https://files.pythonhosted.org/packages/cd/00/20f40a935514037b7d3f87adfc87d2c538430ea625b63b3af8c3f5578e72/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d44ff19eea13ae4acdaaab0179fa68c0c6f2f45d66a4d8ec1eda7d6cecbcc15f", size = 3446208 }, + { url = "https://files.pythonhosted.org/packages/28/3c/7de681727963043e093c72e6c3348411b0185eab3263100d4490234ba2f6/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d3d8da4a631471dfaf94c10c85f5277b1f8e42ac42bade1ac67da4b4a7359b73", size = 3509746 }, + { url = "https://files.pythonhosted.org/packages/41/67/936f9814bdd74b2dfd4822f1f7725ab5d8ff4103919a1664eb4874c58b2f/pillow-11.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0", size = 2626353 }, +] + [[package]] name = "platformdirs" version = "4.3.6" @@ -1238,6 +1558,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997 }, ] +[[package]] +name = "pyparsing" +version = "3.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/1a/3544f4f299a47911c2ab3710f534e52fea62a633c96806995da5d25be4b2/pyparsing-3.2.1.tar.gz", hash = "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a", size = 1067694 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/a7/c8a2d361bf89c0d9577c934ebb7421b25dc84bf3a8e3ac0a40aed9acc547/pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1", size = 107716 }, +] + [[package]] name = "pyproject-api" version = "1.9.0" @@ -1518,7 +1847,7 @@ dependencies = [ { name = "scipy" }, ] -[package.dev-dependencies] +[package.optional-dependencies] demo = [ { name = "ipykernel" }, ] @@ -1537,32 +1866,32 @@ release = [ { name = "python-semantic-release" }, ] +[package.dev-dependencies] +demo = [ + { name = "matplotlib" }, +] + [package.metadata] requires-dist = [ + { name = "ipykernel", marker = "extra == 'demo'", specifier = ">=6.29.5" }, + { name = "nose2", extras = ["coverage-plugin"], marker = "extra == 'dev'", specifier = ">=0.15.1" }, { name = "pandas", specifier = ">=2.2.3" }, { name = "pennylane", specifier = ">=0.40.0" }, + { name = "pre-commit", marker = "extra == 'release'", specifier = ">=4.1.0" }, + { name = "python-semantic-release", marker = "extra == 'release'", specifier = ">=9.16.1" }, { name = "qiskit", specifier = ">=1.3.2" }, { name = "qiskit-ibm-runtime", specifier = ">=0.35.0" }, { name = "scikit-learn", specifier = ">=1.6.1" }, { name = "scipy", specifier = ">=1.15.1" }, + { name = "sphinx", marker = "extra == 'docs'", specifier = ">=8.1.3" }, + { name = "sphinx-autoapi", marker = "extra == 'docs'", specifier = ">=3.4.0" }, + { name = "sphinx-rtd-theme", marker = "extra == 'docs'", specifier = ">=3.0.2" }, + { name = "sphinxcontrib-napoleon", marker = "extra == 'docs'", specifier = ">=0.7" }, + { name = "tox-pdm", marker = "extra == 'dev'", specifier = ">=0.7.2" }, ] [package.metadata.requires-dev] -demo = [{ name = "ipykernel", specifier = ">=6.29.5" }] -dev = [ - { name = "nose2", extras = ["coverage-plugin"], specifier = ">=0.15.1" }, - { name = "tox-pdm", specifier = ">=0.7.2" }, -] -docs = [ - { name = "sphinx", specifier = ">=8.1.3" }, - { name = "sphinx-autoapi", specifier = ">=3.4.0" }, - { name = "sphinx-rtd-theme", specifier = ">=3.0.2" }, - { name = "sphinxcontrib-napoleon", specifier = ">=0.7" }, -] -release = [ - { name = "pre-commit", specifier = ">=4.1.0" }, - { name = "python-semantic-release", specifier = ">=9.16.1" }, -] +demo = [{ name = "matplotlib", specifier = ">=3.10.0" }] [[package]] name = "requests" From 0d2821a027f0a7efddfad8ca2f6d52f2d21c9a25 Mon Sep 17 00:00:00 2001 From: IraitzM Date: Fri, 7 Feb 2025 12:54:05 +0100 Subject: [PATCH 07/10] chore(ruff): Formatting improvements. --- src/quask/core/kernel_factory.py | 1 + src/quask/core/operation.py | 22 +++++++++++++++++----- src/quask/evaluator/__init__.py | 20 +++++++++++--------- tests/test_pennylane_kernel.py | 1 - 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/quask/core/kernel_factory.py b/src/quask/core/kernel_factory.py index 61e0508..de7d8c1 100644 --- a/src/quask/core/kernel_factory.py +++ b/src/quask/core/kernel_factory.py @@ -1,6 +1,7 @@ from .ansatz import Ansatz from .kernel_type import KernelType + class KernelFactory: """Kernel factory. diff --git a/src/quask/core/operation.py b/src/quask/core/operation.py index 44cf974..0de0362 100644 --- a/src/quask/core/operation.py +++ b/src/quask/core/operation.py @@ -4,7 +4,9 @@ class Operation: - """Class representing a 2-qubit rotational quantum gates + r"""Operation. + + Class representing a 2-qubit rotational quantum gates $exp(-i \theta \\sigma_1 \\otimes \\sigma_2)$. """ @@ -17,10 +19,12 @@ class Operation: def __init__( self, generator: str, wires: list[int], feature: int, bandwidth: float ): - """Operation initializer + """Operation initializer. + :param generator: one of the elements of Operation.OPERATIONS :param wires: pair of integers - :param feature: index of the feature parameterizing the element (can be -1 for constant feature '1') + :param feature: index of the feature parameterizing the element + (can be -1 for constant feature '1') :param bandwidth: bandwidth parameter in range [0,1] """ self.generator: str = generator @@ -29,7 +33,11 @@ def __init__( self.bandwidth: float = bandwidth def to_numpy(self): - """Serialize the Operation object to a numpy array format + """To Numpy. + + Serialize the Operation object + to a numpy array format. + :return: numpy array representing the operation """ return np.array( @@ -44,7 +52,11 @@ def to_numpy(self): @staticmethod def from_numpy(array): - """Deserialize the operation object given its numpy array description + """From Numpy array. + + Deserialize the operation object given + its numpy array description. + :param array: numpy array :return: Operation object """ diff --git a/src/quask/evaluator/__init__.py b/src/quask/evaluator/__init__.py index a256b75..1a3c624 100644 --- a/src/quask/evaluator/__init__.py +++ b/src/quask/evaluator/__init__.py @@ -1,21 +1,23 @@ -from .centered_kernel_alignment_evaluator import CenteredKernelAlignmentEvaluator +from .centered_kernel_alignment_evaluator import ( + CenteredKernelAlignmentEvaluator +) from .covering_number_evaluator import CoveringNumberEvaluator - from .ess_model_complexity_evaluator import ( - EssModelComplexityEvaluator as EssModelComplexityEvaluator, + EssModelComplexityEvaluator ) from .geometric_difference_evaluator import ( - GeometricDifferenceEvaluator as GeometricDifferenceEvaluator, + GeometricDifferenceEvaluator, ) from .haar_evaluator import HaarEvaluator as HaarEvaluator + from .kernel_alignment_evaluator import ( - KernelAlignmentEvaluator as KernelAlignmentEvaluator, + KernelAlignmentEvaluator, ) -from .kernel_evaluator import KernelEvaluator as KernelEvaluator -from .lie_rank_evaluator import LieRankEvaluator as LieRankEvaluator +from .kernel_evaluator import KernelEvaluator +from .lie_rank_evaluator import LieRankEvaluator from .ridge_generalization_evaluator import ( - RidgeGeneralizationEvaluator as RidgeGeneralizationEvaluator, + RidgeGeneralizationEvaluator, ) from .spectral_bias_evaluator import ( - SpectralBiasEvaluator as SpectralBiasEvaluator, + SpectralBiasEvaluator, ) diff --git a/tests/test_pennylane_kernel.py b/tests/test_pennylane_kernel.py index 641e104..2cba576 100644 --- a/tests/test_pennylane_kernel.py +++ b/tests/test_pennylane_kernel.py @@ -2,7 +2,6 @@ import unittest import numpy as np - from quask.core import Ansatz, Kernel, KernelType from quask.core_implementation import PennylaneKernel From b05a55b24fb2bd62be988e7aa5561eab1717830d Mon Sep 17 00:00:00 2001 From: IraitzM Date: Fri, 7 Feb 2025 15:39:14 +0100 Subject: [PATCH 08/10] chore(pdm): Switched to PDM as uv seems not to work properly --- .github/workflows/main.yml | 14 +- pdm.lock | 259 +++++++++++++++++++++++++++++++++++-- pyproject.toml | 1 + 3 files changed, 260 insertions(+), 14 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 82387b6..f7601d6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,12 +17,14 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install uv and set the python version - uses: astral-sh/setup-uv@v5 - with: - python-version: ${{ matrix.python-version }} + - name: Setup PDM + uses: pdm-project/setup-pdm@v4 - - name: Install the project - run: uv sync --all-extras --dev + # You are now able to use PDM in your workflow + - name: Install dependencies + run: pdm sync + + - name: Check coverage + run: pdm run coverage run -m nose2 - uses: eosc-synergy/sqaaas-assessment-action@v2 diff --git a/pdm.lock b/pdm.lock index 1301fd0..e1bd28d 100644 --- a/pdm.lock +++ b/pdm.lock @@ -2,10 +2,10 @@ # It is not intended for manual editing. [metadata] -groups = ["default", "demo"] +groups = ["default", "demo", "dev"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:9afc2122ebb2ee0d9d31ff6ff9cbb3c9e91a2ef962d60ff8427e9e6cca972941" +content_hash = "sha256:e66a47e8daa33693c831368dbcf1ae7bf185416626c4fea97836fa99c6ffdb51" [[metadata.targets]] requires_python = ">=3.10" @@ -101,7 +101,7 @@ name = "cachetools" version = "5.5.1" requires_python = ">=3.7" summary = "Extensible memoizing collections and decorators" -groups = ["default"] +groups = ["default", "dev"] files = [ {file = "cachetools-5.5.1-py3-none-any.whl", hash = "sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb"}, {file = "cachetools-5.5.1.tar.gz", hash = "sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95"}, @@ -178,6 +178,17 @@ files = [ {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] +[[package]] +name = "chardet" +version = "5.2.0" +requires_python = ">=3.7" +summary = "Universal encoding detector for Python 3" +groups = ["dev"] +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + [[package]] name = "charset-normalizer" version = "3.4.1" @@ -246,8 +257,7 @@ name = "colorama" version = "0.4.6" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" summary = "Cross-platform colored terminal text." -groups = ["demo"] -marker = "sys_platform == \"win32\"" +groups = ["demo", "dev"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -267,6 +277,67 @@ files = [ {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, ] +[[package]] +name = "coverage" +version = "7.6.10" +requires_python = ">=3.9" +summary = "Code coverage measurement for Python" +groups = ["dev"] +files = [ + {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, + {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5"}, + {file = "coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244"}, + {file = "coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e"}, + {file = "coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3"}, + {file = "coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377"}, + {file = "coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8"}, + {file = "coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609"}, + {file = "coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853"}, + {file = "coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852"}, + {file = "coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359"}, + {file = "coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247"}, + {file = "coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9"}, + {file = "coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694"}, + {file = "coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6"}, + {file = "coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e"}, + {file = "coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe"}, + {file = "coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2"}, + {file = "coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312"}, + {file = "coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d"}, + {file = "coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f"}, + {file = "coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23"}, +] + [[package]] name = "cryptography" version = "44.0.0" @@ -371,6 +442,16 @@ files = [ {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"}, ] +[[package]] +name = "distlib" +version = "0.3.9" +summary = "Distribution utilities" +groups = ["dev"] +files = [ + {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, + {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, +] + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -394,6 +475,17 @@ files = [ {file = "executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755"}, ] +[[package]] +name = "filelock" +version = "3.17.0" +requires_python = ">=3.9" +summary = "A platform independent file lock." +groups = ["dev"] +files = [ + {file = "filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338"}, + {file = "filelock-3.17.0.tar.gz", hash = "sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e"}, +] + [[package]] name = "gast" version = "0.6.0" @@ -603,6 +695,33 @@ files = [ {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, ] +[[package]] +name = "nose2" +version = "0.15.1" +requires_python = ">=3.8" +summary = "unittest with plugins" +groups = ["dev"] +files = [ + {file = "nose2-0.15.1-py3-none-any.whl", hash = "sha256:564450c0c4f1602dfe171902ceb4726cc56658af7a620ae1826f1ffc86b09a86"}, + {file = "nose2-0.15.1.tar.gz", hash = "sha256:36770f519df5becd3cbfe0bee4abbfbf9b9f6b4eb4e03361d282b7efcfc4f0df"}, +] + +[[package]] +name = "nose2" +version = "0.15.1" +extras = ["coverage_plugin"] +requires_python = ">=3.8" +summary = "unittest with plugins" +groups = ["dev"] +dependencies = [ + "coverage", + "nose2==0.15.1", +] +files = [ + {file = "nose2-0.15.1-py3-none-any.whl", hash = "sha256:564450c0c4f1602dfe171902ceb4726cc56658af7a620ae1826f1ffc86b09a86"}, + {file = "nose2-0.15.1.tar.gz", hash = "sha256:36770f519df5becd3cbfe0bee4abbfbf9b9f6b4eb4e03361d282b7efcfc4f0df"}, +] + [[package]] name = "numpy" version = "2.0.2" @@ -648,7 +767,7 @@ name = "packaging" version = "24.2" requires_python = ">=3.8" summary = "Core utilities for Python packages" -groups = ["default", "demo"] +groups = ["default", "demo", "dev"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -805,12 +924,23 @@ name = "platformdirs" version = "4.3.6" requires_python = ">=3.8" summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -groups = ["demo"] +groups = ["demo", "dev"] files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] +[[package]] +name = "pluggy" +version = "1.5.0" +requires_python = ">=3.8" +summary = "plugin and hook calling mechanisms for python" +groups = ["dev"] +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + [[package]] name = "prompt-toolkit" version = "3.0.50" @@ -983,6 +1113,21 @@ files = [ {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] +[[package]] +name = "pyproject-api" +version = "1.9.0" +requires_python = ">=3.9" +summary = "API to interact with the python pyproject.toml based projects" +groups = ["dev"] +dependencies = [ + "packaging>=24.2", + "tomli>=2.2.1; python_version < \"3.11\"", +] +files = [ + {file = "pyproject_api-1.9.0-py3-none-any.whl", hash = "sha256:326df9d68dea22d9d98b5243c46e3ca3161b07a1b9b18e213d1e24fd0e605766"}, + {file = "pyproject_api-1.9.0.tar.gz", hash = "sha256:7e8a9854b2dfb49454fae421cb86af43efbb2b2454e5646ffb7623540321ae6e"}, +] + [[package]] name = "pyspnego" version = "0.11.2" @@ -1497,6 +1642,48 @@ files = [ {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, ] +[[package]] +name = "tomli" +version = "2.2.1" +requires_python = ">=3.8" +summary = "A lil' TOML parser" +groups = ["dev"] +marker = "python_version < \"3.11\"" +files = [ + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] + [[package]] name = "tomlkit" version = "0.13.2" @@ -1528,6 +1715,45 @@ files = [ {file = "tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b"}, ] +[[package]] +name = "tox" +version = "4.24.1" +requires_python = ">=3.8" +summary = "tox is a generic virtualenv management and test command line tool" +groups = ["dev"] +dependencies = [ + "cachetools>=5.5", + "chardet>=5.2", + "colorama>=0.4.6", + "filelock>=3.16.1", + "packaging>=24.2", + "platformdirs>=4.3.6", + "pluggy>=1.5", + "pyproject-api>=1.8", + "tomli>=2.1; python_version < \"3.11\"", + "typing-extensions>=4.12.2; python_version < \"3.11\"", + "virtualenv>=20.27.1", +] +files = [ + {file = "tox-4.24.1-py3-none-any.whl", hash = "sha256:57ba7df7d199002c6df8c2db9e6484f3de6ca8f42013c083ea2d4d1e5c6bdc75"}, + {file = "tox-4.24.1.tar.gz", hash = "sha256:083a720adbc6166fff0b7d1df9d154f9d00bfccb9403b8abf6bc0ee435d6a62e"}, +] + +[[package]] +name = "tox-pdm" +version = "0.7.2" +requires_python = ">=3.7" +summary = "A plugin for tox that utilizes PDM as the package manager and installer" +groups = ["dev"] +dependencies = [ + "tomli; python_version < \"3.11\"", + "tox>=4.0", +] +files = [ + {file = "tox_pdm-0.7.2-py3-none-any.whl", hash = "sha256:12f6215416b7acd00a80a9e7128f3dc3e3c89308d60707f5d0a24abdf83ac104"}, + {file = "tox_pdm-0.7.2.tar.gz", hash = "sha256:a841a7e1e942a71805624703b9a6d286663bd6af79bba6130ba756975c315308"}, +] + [[package]] name = "traitlets" version = "5.14.3" @@ -1544,7 +1770,7 @@ name = "typing-extensions" version = "4.12.2" requires_python = ">=3.8" summary = "Backported and Experimental Type Hints for Python 3.8+" -groups = ["default", "demo"] +groups = ["default", "demo", "dev"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, @@ -1572,6 +1798,23 @@ files = [ {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] +[[package]] +name = "virtualenv" +version = "20.29.1" +requires_python = ">=3.8" +summary = "Virtual Python Environment builder" +groups = ["dev"] +dependencies = [ + "distlib<1,>=0.3.7", + "filelock<4,>=3.12.2", + "importlib-metadata>=6.6; python_version < \"3.8\"", + "platformdirs<5,>=3.9.1", +] +files = [ + {file = "virtualenv-20.29.1-py3-none-any.whl", hash = "sha256:4e4cb403c0b0da39e13b46b1b2476e505cb0046b25f242bee80f62bf990b2779"}, + {file = "virtualenv-20.29.1.tar.gz", hash = "sha256:b8b8970138d32fb606192cb97f6cd4bb644fa486be9308fb9b63f81091b5dc35"}, +] + [[package]] name = "wcwidth" version = "0.2.13" diff --git a/pyproject.toml b/pyproject.toml index 5936f7d..034b92c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,7 @@ path = "src/quask/__version__.py" dev = [ "nose2[coverage_plugin]>=0.15.1", "tox-pdm>=0.7.2", + "coverage>=7.6.10", ] demo = [ "ipykernel>=6.29.5", From 384ae4e848539689639536ddceb4e8f4bd84916c Mon Sep 17 00:00:00 2001 From: IraitzM Date: Fri, 7 Feb 2025 19:31:46 +0100 Subject: [PATCH 09/10] enhance(docs): Added extra params for quality increase. --- CODE_OF_CONDUCT.md | 132 +++++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 7 ++ README.md | 158 ++++++++++++++++++++++++++++----------------- 3 files changed, 239 insertions(+), 58 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..073dd58 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[INSERT CONTACT METHOD]. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e8fc2fa --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# Contributing guide + +Welcome to the data complexity project. This contributing guide is still pending so be patient. + +## Table of contents + +[TOC] \ No newline at end of file diff --git a/README.md b/README.md index 046b4bc..fd841bb 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,18 @@ [![SQAaaS badge shields.io](https://github.com/EOSC-synergy/quask.assess.sqaaas/raw/master/.badge/status_shields.svg)](https://sqaaas.eosc-synergy.eu/#/full-assessment/report/https://raw.githubusercontent.com/eosc-synergy/quask.assess.sqaaas/master/.report/assessment_output.json) - # Quantum Advantage Seeker with Kernels (QuASK) -QuASK is an actively maintained library for constructing, studying, and benchmarking quantum kernel methods. +QuASK is an actively maintained library for constructing, +studying, and benchmarking quantum kernel methods. -It is designed to simplify the process of choosing a quantum kernel, automate the machine learning pipeline at all its stages, and provide pedagogical guidance for early-stage researchers to utilize these tools to their full potential. +It is designed to simplify the process of choosing a quantum kernel, +automate the machine learning pipeline at all its stages, and provide +pedagogical guidance for early-stage researchers to utilize these tools +to their full potential. -QuASK promotes the use of reusable code and is available as a library that can be seamlessly integrated into existing code bases. It is written in Python 3, can be easily installed using pip, and is accessible on PyPI. +QuASK promotes the use of reusable code and is available as a library that +can be seamlessly integrated into existing code bases. It is written in Python 3, +can be easily installed using pip, and is accessible on PyPI. *Homepage*: [quask.web.cern.ch](https://quask.web.cern.ch/) @@ -18,111 +23,148 @@ QuASK promotes the use of reusable code and is available as a library that can b The easiest way to use *quask* is by installing it in your Python3 environment (version >= 3.10) via the *pip* packet manager, - python3 -m pip install -U quask==2.0.0-alpha1 +```sh +python3 -m pip install -U quask==2.0.0-alpha1 +``` -You also need any quantum SDK installed on your system. For example, we can install Qiskit (but we can also work with Pennylane, Braket, Qibo, and the modular nature of the software allows the creation of your own custom backends). +You also need any quantum SDK installed on your system. For example, we can install +Qiskit (but we can also work with Pennylane, Braket, Qibo, and the modular nature of +the software allows the creation of your own custom backends). - python3 -m pip install qiskit qiskit_ibm_runtime - python3 -m pip install qiskit_ibm_runtime --upgrade - python3 -m pip install qiskit-aer +```sh +python3 -m pip install qiskit qiskit_ibm_runtime +python3 -m pip install qiskit_ibm_runtime --upgrade +python3 -m pip install qiskit-aer +``` See the [Installation section](https://quask.readthedocs.io/en/latest/installation.html) of our documentation page for more information. ## Examples -The fastest way to start developing using _quask_ is via our [Getting started](https://quask.readthedocs.io/en/latest/getting_started.html) guide. +The fastest way to start developing using _quask_ is via our +[Getting started](https://quask.readthedocs.io/en/latest/getting_started.html) +guide. -If you are not familiar with the concept of kernel methods in classical machine learning, we have developed a [series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_classical/index.html) on the topic. +If you are not familiar with the concept of kernel methods in classical +machine learning, we have developed a +[series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_classical/index.html) +on the topic. -If you are not familiar with the concept of quantum kernels, we have developed a [series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_quantum/index.html) on the topic, which is also used to showcase the basic functionalities of _quask_. +If you are not familiar with the concept of quantum kernels, we have developed a +[series of introductory tutorials](https://quask.readthedocs.io/en/latest/tutorials_quantum/index.html) +on the topic, which is also used to showcase the basic functionalities of _quask_. -Then [advanced features of _quask_](https://quask.readthedocs.io/en/latest/tutorials_quask/index.html) are shown, including the use of different backends, the criteria to evaluate a quantum kernel, and the automatic optimization approach. +Then [advanced features of _quask_](https://quask.readthedocs.io/en/latest/tutorials_quask/index.html) +are shown, including the use of different backends, the criteria to evaluate a quantum kernel, and the +automatic optimization approach. Finally, [look here for some applications](https://quask.readthedocs.io/en/latest/tutorials_applications/index.html). - ## Source - ### Deployment to PyPI The software is uploaded to [PyPI](https://pypi.org/project/quask/). ### Test -The suite of test for _quask_ is currently under development.To run the available tests, type - - pytest +The suite of test for _quask_ is currently under development. +To run the available tests, type +```sh +pytest +``` You can also specify specific test scripts. - pytest tests/test_example.py - - _quask_ has been developed and tested with the following versions of the quantum frameworks: - -* PennyLane==0.32.0 -* PennyLane-Lightning==0.32.0 -* qiskit==0.44.1 -* qiskit-aer==0.12.2 -* qiskit-ibm-runtime==0.14.0 +```sh +pytest tests/test_example.py +``` + _quask_ has been developed and tested with the following versions + of the quantum frameworks: +* PennyLane>=0.40.0 +* PennyLane-Lightning>=0.40.0 +* qiskit>=1.3.2 +* qiskit-aer>=0.15 +* qiskit-ibm-runtime==>=0.35.0 ## Documentation -The documentation is available at our [Read the Docs](https://quask.readthedocs.io/en/latest/) domain. +The documentation is available at our +[Read the Docs](https://quask.readthedocs.io/en/latest/) +domain. ### Generate the documentation -The documentation has been generated with Sphinx (v7.2.6) and uses the Furo theme. To install it, run +The documentation has been generated with Sphinx (v7.2.6) +and uses the Furo theme. To install it, run - python3 -m pip install -U sphinx - python3 -m pip install furo +```sh +python3 -m pip install -U sphinx +python3 -m pip install furo +``` To generate the documentation, run - cd docs - make clean && make html +```sh +cd docs +make clean && make html +``` -The Sphinx configuration file (`conf.py`) has the following, non-standard options: +The Sphinx configuration file (`conf.py`) has the following, +non-standard options: - html_theme = 'furo' - html_theme_options = { - "sidebar_hide_name": True - } - autodoc_mock_imports = ["skopt", "skopt.space", "django", "mushroom_rl", "opytimizer", "pennylane", "qiskit", "qiskit_ibm_runtime", "qiskit_aer"] +```sh +html_theme = 'furo' +html_theme_options = { + "sidebar_hide_name": True +} +autodoc_mock_imports = ["skopt", "skopt.space", "django", "mushroom_rl", "opytimizer", "pennylane", "qiskit", "qiskit_ibm_runtime", "qiskit_aer"] +``` ### Generate the UML diagrams -Currently, the pages generated from the Python notebooks has to be compiled to RST format manually. We could use in the future the [nbsphinx extension](https://docs.readthedocs.io/en/stable/guides/jupyter.html) to automatize this process. This has the advantage that the documentation is always up to date, the disadvantage is that the process is much slower. +Currently, the pages generated from the Python notebooks has to be compiled +to RST format manually. We could use in the future the +[nbsphinx extension](https://docs.readthedocs.io/en/stable/guides/jupyter.html) +to automatize this process. This has the advantage that the documentation is +always up to date, the disadvantage is that the process is much slower. ### Generate the UML diagrams -The UML diagrams in the [Platform overview](https://quask.readthedocs.io/en/latest/platform_overview.html) page of the documentation are generated using pyreverse and Graphviz. They can be installed via: +The UML diagrams in the [Platform overview](https://quask.readthedocs.io/en/latest/platform_overview.html) +page of the documentation are generated using pyreverse and Graphviz. They can be installed via: - sudo apt-get install graphviz - python3 -m pip install pylint +```sh +sudo apt-get install graphviz +python3 -m pip install pylint +``` The UML diagrams are created via: - - cd src/quask - pyreverse -o png -p QUASK . - +```sh +cd src/quask +pyreverse -o png -p QUASK . +``` ## Acknowledgements -The platform has been developed with the contribution of [Massimiliano Incudini](https://incud.github.io), Francesco Di Marcantonio, Davide Tezza, Roman Wixinger, Sofia Vallecorsa, and [Michele Grossi](https://scholar.google.com/citations?user=cnfcO7cAAAAJ&hl=en). +The platform has been developed with the contribution of [Massimiliano Incudini](https://incud.github.io), +Francesco Di Marcantonio, Davide Tezza, Roman Wixinger, Sofia Vallecorsa, +and [Michele Grossi](https://scholar.google.com/citations?user=cnfcO7cAAAAJ&hl=en). If you have used _quask_ for your project, please consider citing us. - @article{dimarcantonio2023quask, - title={Quantum Advantage Seeker with Kernels (QuASK): a software framework to accelerate research in quantum machine learning}, - author={Di Marcantonio, Francesco and Incudini, Massimiliano and Tezza, Davide and Grossi, Michele}, - journal={Quantum Machine Intelligence}, - volume={5}, - number={1}, - pages={20}, - year={2023}, - publisher={Springer} - } +``` +@article{dimarcantonio2023quask, + title={Quantum Advantage Seeker with Kernels (QuASK): a software framework to accelerate research in quantum machine learning}, + author={Di Marcantonio, Francesco and Incudini, Massimiliano and Tezza, Davide and Grossi, Michele}, + journal={Quantum Machine Intelligence}, + volume={5}, + number={1}, + pages={20}, + year={2023}, + publisher={Springer} +} +``` From 2154749953ee4628e01faae79ce9e909f97529e2 Mon Sep 17 00:00:00 2001 From: IraitzM Date: Fri, 7 Feb 2025 19:45:52 +0100 Subject: [PATCH 10/10] fix(badge): Badge reference fixed. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd841bb..f655d4e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![SQAaaS badge shields.io](https://github.com/EOSC-synergy/quask.assess.sqaaas/raw/master/.badge/status_shields.svg)](https://sqaaas.eosc-synergy.eu/#/full-assessment/report/https://raw.githubusercontent.com/eosc-synergy/quask.assess.sqaaas/master/.report/assessment_output.json) +[![SQAaaS badge shields.io](https://github.com/EOSC-synergy/QuASK.assess.sqaaas/raw/main/.badge/status_shields.svg)](https://sqaaas.eosc-synergy.eu/#/full-assessment/report/https://raw.githubusercontent.com/eosc-synergy/QuASK.assess.sqaaas/main/.report/assessment_output.json) # Quantum Advantage Seeker with Kernels (QuASK)