diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 9815b351..55778e56 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -60,7 +60,7 @@ jobs: path: dist merge-multiple: true - name: Generate artifact attestation for sdist and wheel(s) - uses: actions/attest-build-provenance@v1.4.3 + uses: actions/attest-build-provenance@v1.4.4 with: subject-path: "dist/*" - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ba55eac2..4638d79f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -59,7 +59,7 @@ repos: # Python linting and formatting using ruff - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.2 + rev: v0.7.3 hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -87,7 +87,7 @@ repos: # Check for spelling - repo: https://github.com/crate-ci/typos - rev: v1.27.0 + rev: v1.27.3 hooks: - id: typos @@ -140,6 +140,6 @@ repos: # Check the pyproject.toml file - repo: https://github.com/henryiii/validate-pyproject-schema-store - rev: 2024.10.21 + rev: 2024.11.11 hooks: - id: validate-pyproject diff --git a/docs/StatePrep.ipynb b/docs/StatePrep.ipynb index efa41821..69f275f0 100644 --- a/docs/StatePrep.ipynb +++ b/docs/StatePrep.ipynb @@ -253,6 +253,158 @@ "cc_simulator.plot_state_prep(ps, min_errors=50, name=\"Distance 5\")" ] }, + { + "cell_type": "markdown", + "id": "81eec694ef6af97a", + "metadata": {}, + "source": [ + "## Deterministic state preparation ($d < 5$)\n", + "A possible disadvantage of the above approach is that the verification circuits are non-deterministic. This means that we potentially have to run the circuit multiple times to successfully prepare the state. This can be circumvented by using the information gained from the verification measurements to possibly identify the dangerous error and correct it. If this this is done for every possible (single) error, we refer to the state preparation as deterministic [^1].\n", + "\n", + "For small codes ($d < 5$ i.e. we need to consider only a single error) this problem is still tractable and can be solved in an optimal way using satisfiability solvers. QECC can automatically generate deterministic state preparation circuits for such codes.\n", + "\n", + "[^1]: https://arxiv.org/abs/2301.10017\n", + "\n", + "For this we come back to our $d=3$ Steane code. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2373b4ee6cee29d", + "metadata": {}, + "outputs": [], + "source": [ + "non_ft_sp.circ.draw(output=\"mpl\", initial_state=True)" + ] + }, + { + "cell_type": "markdown", + "id": "6c8eecaac4df6b88", + "metadata": {}, + "source": [ + "And initialize an instance of the deterministic verification helper class to facilitate the generation of the deterministic FT state preparation circuit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1877841300be6d01", + "metadata": {}, + "outputs": [], + "source": [ + "from mqt.qecc.ft_stateprep import DeterministicVerificationHelper\n", + "\n", + "det_helper = DeterministicVerificationHelper(non_ft_sp)" + ] + }, + { + "cell_type": "markdown", + "id": "40c9070837bcd21", + "metadata": {}, + "source": [ + "Calling the `get_solution` method will generate the non-deterministic verification circuit using either the optimal or the heuristic method discussed above. The deterministic verification circuit, separated into X and Z correction layers) is then generated using the satisfiability solver." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3c83621b4ca7a1a1", + "metadata": {}, + "outputs": [], + "source": [ + "det_verify = det_helper.get_solution(use_optimal_verification=True)\n", + "det_verify_x, det_verify_z = det_verify" + ] + }, + { + "cell_type": "markdown", + "id": "15b8f7d65e69be64", + "metadata": {}, + "source": [ + "Such a `DeterministicVerification` object contains the stabilizer measurements for the non-deterministic verification circuit, the stabilizer measurements for the different deterministic verification circuits, depending on the non-deterministic measurement outcomes, and the final correction Pauli operators that need to be applied to the data qubits.\n", + "\n", + "The non-deterministic verification measurements are stored in the `stabs` attribute as a list of numpy arrays where each array represents a stabilizer measurement.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "75ac41577e4c0296", + "metadata": {}, + "outputs": [], + "source": [ + "det_verify_x.stabs" + ] + }, + { + "cell_type": "markdown", + "id": "ddecefba679c91c1", + "metadata": {}, + "source": [ + "The deterministic verification measurements are stored in the `det_stabs` attribute as a dictionary where the keys are the non-deterministic measurement outcomes (converted to int) and the values is a tuple with the first element being the deterministic stabilizer measurements and the second element being again a dictionary with the Pauli corrections for the deterministic measurement outcomes.\n", + "\n", + "For example for the Steane code whenever the non-deterministic verification triggers (1) the logical operator on qubits 2,3,6 hast to measured. If the outcome is 1, a Pauli correction on qubit 3 has to be applied, otherwise no correction is necessary." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45c29390eb2eb0e4", + "metadata": {}, + "outputs": [], + "source": [ + "det_verify_x.det_correction" + ] + }, + { + "cell_type": "markdown", + "id": "42c85a709d72bf40", + "metadata": {}, + "source": [ + "For the case where the non-deterministic verification measurements need to be flagged (not the case for the Steane code), the `hook_corrections` attribute contains the additional stabilizer measurements and corrections in the same format as the `det_stabs` attribute." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab975d4c4a1c11b7", + "metadata": {}, + "outputs": [], + "source": [ + "det_verify_x.hook_corrections" + ] + }, + { + "cell_type": "markdown", + "id": "d4527b797f83f919", + "metadata": {}, + "source": [ + "### Simulating deterministic state preparation circuits with Qsample\n", + "The resulting `DeterministicVerification` object can be used to directly simulate the deterministic state preparation circuit using the [Qsample](https://github.com/dpwinter/qsample) under the hood. The `NoisyDFTStatePrepSimulator` class automatically constructs a valid Qsample protocol containing the correct circuits and conditional paths to simulate the deterministic state preparation. The passed Error Model and simulation parameters are directly passed to Qsample and explained in the [Qsample documentation](https://dpwinter.github.io/qsample/). Similarly also the Qsample callbacks can be used to e.g. directly plot the logical error rates, showing the expected quadratic scaling." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "90f4d2760bc20453", + "metadata": {}, + "outputs": [], + "source": [ + "from qsample import callbacks, noise\n", + "\n", + "from mqt.qecc.ft_stateprep import NoisyDFTStatePrepSimulator\n", + "\n", + "error_model = noise.E1_1 # depolarizing error model\n", + "err_params = {\"q\": [1e-4, 5e-4, 1e-3, 5e-3, 1e-2, 5e-2, 1e-1, 5e-1]}\n", + "shots_dss = 2000\n", + "p_max = {\"q\": 0.01}\n", + "L = 1\n", + "\n", + "qsample_sim = NoisyDFTStatePrepSimulator(non_ft_sp.circ, det_verify, steane_code, error_model)\n", + "sampling_stats = qsample_sim.dss_logical_error_rates(err_params, p_max, L, shots_dss, callbacks=[callbacks.PlotStats()])" + ] + }, { "cell_type": "markdown", "id": "f9ad305e-929f-470f-86c5-e3e958750539", @@ -260,13 +412,13 @@ "source": [ "# Circuits and Evaluations\n", "\n", - "The circuits and benchmark scripts used for our work https://arxiv.org/abs/2408.11894, can be found [here](https://github.com/cda-tum/mqt-qecc/tree/main/src/mqt/qecc/ft_stateprep/eval)." + "The circuits and benchmark scripts used for our non-deterministic work https://arxiv.org/abs/2408.11894, can be found [here](https://github.com/cda-tum/mqt-qecc/tree/main/scripts/ft_stateprep/eval) and for the deterministic work [here](https://github.com/cda-tum/mqt-qecc/tree/main/scripts/ft_stateprep/eval_det)." ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "venv3_12", "language": "python", "name": "python3" }, diff --git a/docs/library/StatePrep.rst b/docs/library/StatePrep.rst index c1c09e4a..938ec52d 100644 --- a/docs/library/StatePrep.rst +++ b/docs/library/StatePrep.rst @@ -27,3 +27,23 @@ State preparation circuits can be simulated using the :class:`NoisyNDFTStatePrep .. autoclass:: NoisyNDFTStatePrepSimulator :members: + +:math:`d<5` codes +--------------------------------------------------------- +For small distance codes QECC provides functionality to not only synthesize state preparation circuits based on post-selection but also preparation protocols that yield the logical Pauli state deterministically. +Such a deterministic protocol consists of three parts: (1) a (non-deterministic) verification, (2) a deterministic correction if one of the verification measurements yields a non-trivial result, and (3) a hook correction for the case that one of the verification measurement flags indicates a hook error. +To facilitate the handling (e.g. collecting statistics regarding ancilla and CNOT count) QECC provides the :class:`DeterministicVerification` class. + + .. autoclass:: DeterministicVerification + :members: + +The :class:`DeterministicVerification` for a certain :class:`StatePrepCircuit` can be obtained using the wrapper class :class:`DeterministicVerificationHelper` which provides the two functions :func:`get_solution` and :func:`get_global_solution` where the latter optimizes over all possible(*potentially exponentially many*) non-deterministic verifications to find the global optimum (recommended only for codes with small qubit number). +The two :class:`DeterministicVerification` objects returned correspond to the two layers of verification (X and Z errors). + + .. autoclass:: DeterministicVerificationHelper + :members: +The resulting protocol consisting of the two-layered verification can be converted to a `Qsample `_ protocol and simulated using Dynamic Subset Sampling :cite:labelpar:`heussenDynamicalSubsetSampling2024`. +The protocol construction and simulation is done automatically by the :class:`NoisyDFTStatePrepSimulator` class where the returned numbers correspond to the upper and lower bounds with corresponding errors as described at the `Qsample Documentation `_. + + .. autoclass:: NoisyDFTStatePrepSimulator + :members: diff --git a/docs/refs.bib b/docs/refs.bib index fd2a9aea..b0e1fb96 100644 --- a/docs/refs.bib +++ b/docs/refs.bib @@ -149,3 +149,16 @@ @article{pryadko2023qdistrnd journal={arXiv preprint arXiv:2308.15140}, year={2023} } + +@article{heussenDynamicalSubsetSampling2024, + title = {Dynamical Subset Sampling of Quantum Error-Correcting Protocols}, + author = {Heu{\ss}en, Sascha and Winter, Don and Rispler, Manuel and M{\"u}ller, Markus}, + year = {2024}, + month = feb, + journal = {Physical Review Research}, + volume = {6}, + number = {1}, + pages = {013177}, + publisher = {American Physical Society}, + doi = {10.1103/PhysRevResearch.6.013177}, +} diff --git a/pyproject.toml b/pyproject.toml index 9aae5f76..efe27170 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,6 +56,9 @@ dependencies = [ "numba>=0.59; python_version > '3.11'", "numba>=0.57; python_version <= '3.11'", "pymatching>=2.2.1", + "qsample>=0.0.2", + "urllib3>=1.26.20,<2.0", # Required by qsample + "fastcore>=1.7.10" # Required by qsample (to be removed) ] dynamic = ["version"] @@ -158,6 +161,10 @@ filterwarnings = [ "ignore:.*pkg_resources.*:DeprecationWarning:", "ignore:.*The retworkx package is deprecated*:DeprecationWarning:pymatching", 'ignore:.*qiskit.providers.provider.Provider.*:DeprecationWarning:', + 'ignore::DeprecationWarning:.*(simpleeval).*', + 'ignore::RuntimeWarning:.*(qsample).*', + 'ignore:.*invalid escape sequence.*::.*qsample.*', + 'ignore:.*invalid escape sequence.*::.*latextools.*', ] [tool.coverage] @@ -186,7 +193,7 @@ exclude = [ [[tool.mypy.overrides]] module = ["qiskit.*", "qecsim.*", "qiskit_aer.*", "matplotlib.*", "scipy.*", "ldpc.*", "pytest_console_scripts.*", - "z3.*", "bposd.*", "numba.*", "pymatching.*", "stim.*", "multiprocess.*", "sinter.*"] + "z3.*", "bposd.*", "numba.*", "pymatching.*", "stim.*", "multiprocess.*", "sinter.*", "qsample.*", "pandas.*"] ignore_missing_imports = true diff --git a/src/mqt/qecc/ft_stateprep/eval/README.md b/scripts/ft_stateprep/eval/README.md similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/README.md rename to scripts/ft_stateprep/eval/README.md diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/carbon/zero_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/carbon/zero_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/carbon/zero_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/carbon/zero_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/carbon/zero_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/carbon/zero_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/carbon/zero_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/carbon/zero_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/carbon/zero_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/carbon/zero_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/carbon/zero_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/carbon/zero_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/carbon/zero_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/carbon/zero_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/cc_4_8_8/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/cc_4_8_8/zero_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/cc_4_8_8/zero_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/cc_4_8_8/zero_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/cc_4_8_8/zero_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/cc_4_8_8/zero_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/cc_4_8_8/zero_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/cc_4_8_8/zero_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/cc_4_8_8/zero_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/cc_4_8_8/zero_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/cc_4_8_8/zero_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/cc_4_8_8/zero_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/cc_4_8_8/zero_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/cc_4_8_8/zero_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/cc_4_8_8/zero_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/cc_4_8_8/zero_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/cc_6_6_6/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/cc_6_6_6/zero_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/cc_6_6_6/zero_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/cc_6_6_6/zero_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/cc_6_6_6/zero_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/cc_6_6_6/zero_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/cc_6_6_6/zero_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/cc_6_6_6/zero_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/cc_6_6_6/zero_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/cc_6_6_6/zero_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/cc_6_6_6/zero_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/cc_6_6_6/zero_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/cc_6_6_6/zero_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/cc_6_6_6/zero_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/cc_6_6_6/zero_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/cc_6_6_6/zero_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/hamming/plus_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/hamming/plus_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/plus_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/hamming/plus_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/hamming/plus_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/hamming/plus_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/plus_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/hamming/plus_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/hamming/plus_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/hamming/plus_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/plus_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/hamming/plus_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/plus_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/hamming/plus_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/hamming/zero_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/hamming/zero_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/zero_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/hamming/zero_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/hamming/zero_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/hamming/zero_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/zero_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/hamming/zero_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/hamming/zero_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/hamming/zero_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/hamming/zero_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/hamming/zero_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/hamming/zero_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/hamming/zero_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/plus_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d3/zero_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_naive.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_naive.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_naive.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_naive.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_naive.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_naive.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_naive.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_naive.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/rotated_surface_d5/zero_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/rotated_surface_d5/zero_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/shor/plus_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/shor/plus_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/shor/plus_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/shor/plus_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/shor/plus_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/shor/plus_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/shor/plus_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/shor/plus_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/shor/plus_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/shor/plus_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/shor/plus_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/shor/plus_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/plus_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/shor/plus_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/shor/zero_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/shor/zero_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/shor/zero_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/shor/zero_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/shor/zero_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/shor/zero_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/shor/zero_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/shor/zero_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/shor/zero_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/shor/zero_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/shor/zero_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/shor/zero_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/shor/zero_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/shor/zero_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/steane/plus_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/steane/plus_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/steane/plus_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/steane/plus_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/steane/plus_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/steane/plus_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/steane/plus_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/steane/plus_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/steane/plus_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/steane/plus_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/steane/plus_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/steane/plus_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/plus_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/steane/plus_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/steane/zero_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/steane/zero_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/steane/zero_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/steane/zero_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/steane/zero_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/steane/zero_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/steane/zero_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/steane/zero_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/steane/zero_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/steane/zero_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/steane/zero_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/steane/zero_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/steane/zero_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/steane/zero_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/tetrahedral/plus_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/tetrahedral/plus_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/tetrahedral/plus_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/tetrahedral/plus_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/plus_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/tetrahedral/plus_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_heuristic.stim b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_opt.qasm rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_opt.stim b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_opt.stim rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_heuristic_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_opt_opt.qasm b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_opt_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_opt_opt.qasm rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_opt_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_opt_opt.stim b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_opt_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_ft_opt_opt.stim rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_ft_opt_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_heuristic.qasm b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_heuristic.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_heuristic.qasm rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_heuristic.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_heuristic.stim b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_heuristic.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_heuristic.stim rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_heuristic.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_opt.qasm b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_opt.qasm similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_opt.qasm rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_opt.qasm diff --git a/src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_opt.stim b/scripts/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_opt.stim similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_opt.stim rename to scripts/ft_stateprep/eval/circuits/tetrahedral/zero_non_ft_opt.stim diff --git a/src/mqt/qecc/ft_stateprep/eval/estimate_logical_error_rate.py b/scripts/ft_stateprep/eval/estimate_logical_error_rate.py similarity index 98% rename from src/mqt/qecc/ft_stateprep/eval/estimate_logical_error_rate.py rename to scripts/ft_stateprep/eval/estimate_logical_error_rate.py index 8d5d7db6..aff0360e 100644 --- a/src/mqt/qecc/ft_stateprep/eval/estimate_logical_error_rate.py +++ b/scripts/ft_stateprep/eval/estimate_logical_error_rate.py @@ -94,7 +94,7 @@ def main() -> None: qc, code=code, p=args.p_error, zero_state=args.zero_state, parallel_gates=not args.no_parallel_gates ) res = sim.logical_error_rate(min_errors=args.n_errors) - print(",".join([str(x) for x in res])) # noqa: T201 + print(",".join([str(x) for x in res])) if __name__ == "__main__": diff --git a/src/mqt/qecc/ft_stateprep/eval/run_eval_on_code.sh b/scripts/ft_stateprep/eval/run_eval_on_code.sh similarity index 100% rename from src/mqt/qecc/ft_stateprep/eval/run_eval_on_code.sh rename to scripts/ft_stateprep/eval/run_eval_on_code.sh diff --git a/scripts/ft_stateprep/eval_det/circuits/11_1_3/zero_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/11_1_3/zero_heuristic.qasm new file mode 100644 index 00000000..14069f8c --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/11_1_3/zero_heuristic.qasm @@ -0,0 +1,23 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[11]; +h q[0]; +h q[1]; +h q[2]; +h q[3]; +h q[4]; +cx q[4],q[9]; +cx q[4],q[7]; +cx q[3],q[5]; +cx q[4],q[10]; +cx q[2],q[9]; +cx q[1],q[7]; +cx q[0],q[5]; +cx q[3],q[6]; +cx q[1],q[10]; +cx q[9],q[5]; +cx q[7],q[8]; +cx q[1],q[9]; +cx q[0],q[7]; +cx q[10],q[6]; +cx q[5],q[8]; diff --git a/scripts/ft_stateprep/eval_det/circuits/16_2_4/zero_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/16_2_4/zero_heuristic.qasm new file mode 100644 index 00000000..118a1ccf --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/16_2_4/zero_heuristic.qasm @@ -0,0 +1,33 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[16]; +h q[0]; +h q[1]; +h q[2]; +h q[3]; +h q[4]; +h q[5]; +h q[6]; +cx q[5],q[12]; +cx q[4],q[12]; +cx q[2],q[10]; +cx q[6],q[7]; +cx q[5],q[8]; +cx q[3],q[11]; +cx q[1],q[9]; +cx q[0],q[10]; +cx q[12],q[13]; +cx q[6],q[11]; +cx q[4],q[7]; +cx q[3],q[8]; +cx q[13],q[14]; +cx q[12],q[9]; +cx q[10],q[15]; +cx q[6],q[12]; +cx q[5],q[11]; +cx q[4],q[8]; +cx q[3],q[7]; +cx q[2],q[13]; +cx q[1],q[15]; +cx q[0],q[14]; +cx q[9],q[10]; diff --git a/scripts/ft_stateprep/eval_det/circuits/carbon/zero_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/carbon/zero_heuristic.qasm new file mode 100644 index 00000000..0cb023bf --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/carbon/zero_heuristic.qasm @@ -0,0 +1,27 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[12]; +h q[0]; +h q[1]; +h q[2]; +h q[4]; +h q[7]; +cx q[7],q[11]; +cx q[1],q[5]; +cx q[7],q[9]; +cx q[4],q[10]; +cx q[2],q[8]; +cx q[1],q[3]; +cx q[0],q[6]; +cx q[10],q[9]; +cx q[8],q[7]; +cx q[6],q[11]; +cx q[4],q[3]; +cx q[2],q[1]; +cx q[0],q[5]; +cx q[11],q[10]; +cx q[9],q[8]; +cx q[7],q[6]; +cx q[5],q[4]; +cx q[3],q[2]; +cx q[1],q[0]; diff --git a/scripts/ft_stateprep/eval_det/circuits/carbon/zero_opt.qasm b/scripts/ft_stateprep/eval_det/circuits/carbon/zero_opt.qasm new file mode 100644 index 00000000..7cbb7eec --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/carbon/zero_opt.qasm @@ -0,0 +1,24 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[12]; +h q[1]; +h q[2]; +h q[4]; +h q[6]; +h q[8]; +cx q[1],q[7]; +cx q[6],q[9]; +cx q[2],q[5]; +cx q[7],q[0]; +cx q[7],q[6]; +cx q[4],q[10]; +cx q[5],q[11]; +cx q[9],q[3]; +cx q[10],q[1]; +cx q[8],q[5]; +cx q[7],q[2]; +cx q[8],q[4]; +cx q[8],q[9]; +cx q[2],q[8]; +cx q[9],q[0]; +cx q[4],q[7]; diff --git a/scripts/ft_stateprep/eval_det/circuits/hamming/zero_ft_heuristic_opt.qasm b/scripts/ft_stateprep/eval_det/circuits/hamming/zero_ft_heuristic_opt.qasm new file mode 100644 index 00000000..9c3baff3 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/hamming/zero_ft_heuristic_opt.qasm @@ -0,0 +1,29 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[15]; +h q[0]; +h q[1]; +h q[3]; +h q[7]; +cx q[7],q[11]; +cx q[3],q[5]; +cx q[1],q[2]; +cx q[11],q[13]; +cx q[7],q[9]; +cx q[5],q[6]; +cx q[3],q[4]; +cx q[0],q[2]; +cx q[13],q[14]; +cx q[11],q[12]; +cx q[9],q[10]; +cx q[7],q[8]; +cx q[1],q[5]; +cx q[0],q[4]; +cx q[2],q[6]; +cx q[3],q[11]; +cx q[1],q[9]; +cx q[0],q[8]; +cx q[5],q[13]; +cx q[4],q[12]; +cx q[2],q[10]; +cx q[6],q[14]; diff --git a/scripts/ft_stateprep/eval_det/circuits/hamming/zero_ft_opt.qasm b/scripts/ft_stateprep/eval_det/circuits/hamming/zero_ft_opt.qasm new file mode 100644 index 00000000..cf586641 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/hamming/zero_ft_opt.qasm @@ -0,0 +1,29 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[15]; +h q[0]; +h q[1]; +h q[11]; +h q[12]; +cx q[0],q[10]; +cx q[1],q[0]; +cx q[1],q[7]; +cx q[12],q[3]; +cx q[10],q[6]; +cx q[1],q[8]; +cx q[11],q[4]; +cx q[3],q[11]; +cx q[11],q[13]; +cx q[8],q[9]; +cx q[0],q[14]; +cx q[12],q[10]; +cx q[1],q[3]; +cx q[6],q[5]; +cx q[11],q[0]; +cx q[0],q[6]; +cx q[0],q[7]; +cx q[10],q[1]; +cx q[1],q[11]; +cx q[4],q[9]; +cx q[4],q[2]; +cx q[5],q[4]; diff --git a/scripts/ft_stateprep/eval_det/circuits/hypercube/zero_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/hypercube/zero_heuristic.qasm new file mode 100644 index 00000000..0dda57b4 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/hypercube/zero_heuristic.qasm @@ -0,0 +1,33 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[16]; +h q[0]; +h q[1]; +h q[3]; +h q[7]; +h q[11]; +cx q[3],q[12]; +cx q[1],q[9]; +cx q[0],q[8]; +cx q[12],q[14]; +cx q[11],q[8]; +cx q[9],q[10]; +cx q[7],q[3]; +cx q[1],q[5]; +cx q[0],q[4]; +cx q[14],q[15]; +cx q[12],q[13]; +cx q[11],q[10]; +cx q[7],q[4]; +cx q[5],q[6]; +cx q[1],q[2]; +cx q[8],q[9]; +cx q[3],q[0]; +cx q[11],q[15]; +cx q[7],q[6]; +cx q[10],q[14]; +cx q[8],q[12]; +cx q[4],q[5]; +cx q[3],q[2]; +cx q[9],q[13]; +cx q[0],q[1]; diff --git a/scripts/ft_stateprep/eval_det/circuits/shor/zero_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/shor/zero_heuristic.qasm new file mode 100644 index 00000000..90622fb2 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/shor/zero_heuristic.qasm @@ -0,0 +1,14 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[9]; +h q[0]; +h q[2]; +cx q[2],q[6]; +cx q[0],q[3]; +cx q[6],q[8]; +cx q[3],q[4]; +cx q[2],q[0]; +cx q[6],q[7]; +cx q[4],q[5]; +cx q[3],q[2]; +cx q[0],q[1]; diff --git a/scripts/ft_stateprep/eval_det/circuits/shor/zero_opt.qasm b/scripts/ft_stateprep/eval_det/circuits/shor/zero_opt.qasm new file mode 100644 index 00000000..004bf475 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/shor/zero_opt.qasm @@ -0,0 +1,13 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[9]; +h q[2]; +h q[7]; +cx q[7],q[4]; +cx q[2],q[7]; +cx q[2],q[0]; +cx q[4],q[5]; +cx q[7],q[8]; +cx q[4],q[3]; +cx q[7],q[6]; +cx q[0],q[1]; diff --git a/scripts/ft_stateprep/eval_det/circuits/steane/zero_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/steane/zero_heuristic.qasm new file mode 100644 index 00000000..2df628f2 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/steane/zero_heuristic.qasm @@ -0,0 +1,14 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[7]; +h q[0]; +h q[1]; +h q[3]; +cx q[3],q[5]; +cx q[0],q[2]; +cx q[5],q[6]; +cx q[3],q[4]; +cx q[1],q[0]; +cx q[2],q[6]; +cx q[1],q[5]; +cx q[0],q[4]; diff --git a/scripts/ft_stateprep/eval_det/circuits/steane/zero_opt.qasm b/scripts/ft_stateprep/eval_det/circuits/steane/zero_opt.qasm new file mode 100644 index 00000000..9d04cd08 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/steane/zero_opt.qasm @@ -0,0 +1,14 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[7]; +h q[0]; +h q[3]; +h q[5]; +cx q[3],q[1]; +cx q[5],q[4]; +cx q[0],q[2]; +cx q[4],q[3]; +cx q[1],q[0]; +cx q[1],q[6]; +cx q[2],q[4]; +cx q[4],q[6]; diff --git a/scripts/ft_stateprep/eval_det/circuits/surface_3/plus_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/surface_3/plus_heuristic.qasm new file mode 100644 index 00000000..7106b8c2 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/surface_3/plus_heuristic.qasm @@ -0,0 +1,16 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[9]; +h q[2]; +h q[4]; +h q[5]; +h q[6]; +h q[7]; +cx q[7],q[3]; +cx q[5],q[1]; +cx q[4],q[3]; +cx q[2],q[1]; +cx q[7],q[8]; +cx q[6],q[3]; +cx q[4],q[2]; +cx q[1],q[0]; diff --git a/scripts/ft_stateprep/eval_det/circuits/surface_3/plus_opt.qasm b/scripts/ft_stateprep/eval_det/circuits/surface_3/plus_opt.qasm new file mode 100644 index 00000000..f90ec699 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/surface_3/plus_opt.qasm @@ -0,0 +1,16 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[9]; +h q[0]; +h q[3]; +h q[4]; +h q[5]; +h q[7]; +cx q[0],q[1]; +cx q[4],q[2]; +cx q[7],q[8]; +cx q[3],q[6]; +cx q[1],q[2]; +cx q[5],q[4]; +cx q[8],q[3]; +cx q[4],q[6]; diff --git a/scripts/ft_stateprep/eval_det/circuits/surface_3/zero_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/surface_3/zero_heuristic.qasm new file mode 100644 index 00000000..82994398 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/surface_3/zero_heuristic.qasm @@ -0,0 +1,15 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[9]; +h q[0]; +h q[2]; +h q[5]; +h q[6]; +cx q[5],q[8]; +cx q[0],q[4]; +cx q[5],q[7]; +cx q[0],q[3]; +cx q[7],q[4]; +cx q[6],q[3]; +cx q[2],q[5]; +cx q[0],q[1]; diff --git a/scripts/ft_stateprep/eval_det/circuits/surface_3/zero_opt.qasm b/scripts/ft_stateprep/eval_det/circuits/surface_3/zero_opt.qasm new file mode 100644 index 00000000..0d8395c8 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/surface_3/zero_opt.qasm @@ -0,0 +1,15 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[9]; +h q[3]; +h q[4]; +h q[5]; +h q[8]; +cx q[8],q[0]; +cx q[0],q[1]; +cx q[3],q[6]; +cx q[5],q[2]; +cx q[4],q[8]; +cx q[8],q[5]; +cx q[1],q[3]; +cx q[8],q[7]; diff --git a/scripts/ft_stateprep/eval_det/circuits/tetrahedral/plus_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/tetrahedral/plus_heuristic.qasm new file mode 100644 index 00000000..3a9cec96 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/tetrahedral/plus_heuristic.qasm @@ -0,0 +1,31 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[15]; +h q[2]; +h q[4]; +h q[6]; +h q[10]; +h q[13]; +cx q[13],q[11]; +cx q[11],q[12]; +cx q[6],q[5]; +cx q[10],q[3]; +cx q[4],q[1]; +cx q[11],q[9]; +cx q[12],q[8]; +cx q[4],q[7]; +cx q[3],q[5]; +cx q[2],q[1]; +cx q[7],q[14]; +cx q[6],q[13]; +cx q[2],q[9]; +cx q[1],q[8]; +cx q[3],q[0]; +cx q[5],q[4]; +cx q[13],q[14]; +cx q[9],q[10]; +cx q[1],q[0]; +cx q[4],q[12]; +cx q[6],q[7]; +cx q[5],q[11]; +cx q[2],q[3]; diff --git a/scripts/ft_stateprep/eval_det/circuits/tetrahedral/zero_heuristic.qasm b/scripts/ft_stateprep/eval_det/circuits/tetrahedral/zero_heuristic.qasm new file mode 100644 index 00000000..fb826706 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/tetrahedral/zero_heuristic.qasm @@ -0,0 +1,29 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[15]; +h q[2]; +h q[6]; +h q[7]; +h q[14]; +cx q[6],q[9]; +cx q[7],q[11]; +cx q[2],q[11]; +cx q[14],q[3]; +cx q[3],q[1]; +cx q[11],q[6]; +cx q[7],q[12]; +cx q[9],q[1]; +cx q[14],q[7]; +cx q[2],q[0]; +cx q[7],q[13]; +cx q[0],q[8]; +cx q[6],q[14]; +cx q[11],q[7]; +cx q[13],q[5]; +cx q[1],q[13]; +cx q[7],q[10]; +cx q[6],q[7]; +cx q[11],q[4]; +cx q[3],q[11]; +cx q[9],q[2]; +cx q[1],q[8]; diff --git a/scripts/ft_stateprep/eval_det/circuits/tetrahedral/zero_opt.qasm b/scripts/ft_stateprep/eval_det/circuits/tetrahedral/zero_opt.qasm new file mode 100644 index 00000000..fb826706 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/circuits/tetrahedral/zero_opt.qasm @@ -0,0 +1,29 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[15]; +h q[2]; +h q[6]; +h q[7]; +h q[14]; +cx q[6],q[9]; +cx q[7],q[11]; +cx q[2],q[11]; +cx q[14],q[3]; +cx q[3],q[1]; +cx q[11],q[6]; +cx q[7],q[12]; +cx q[9],q[1]; +cx q[14],q[7]; +cx q[2],q[0]; +cx q[7],q[13]; +cx q[0],q[8]; +cx q[6],q[14]; +cx q[11],q[7]; +cx q[13],q[5]; +cx q[1],q[13]; +cx q[7],q[10]; +cx q[6],q[7]; +cx q[11],q[4]; +cx q[3],q[11]; +cx q[9],q[2]; +cx q[1],q[8]; diff --git a/scripts/ft_stateprep/eval_det/eval.py b/scripts/ft_stateprep/eval_det/eval.py new file mode 100644 index 00000000..d43d7e4e --- /dev/null +++ b/scripts/ft_stateprep/eval_det/eval.py @@ -0,0 +1,180 @@ +"""Evaluation script for the deterministic state preparation verification and simulation.""" + +from __future__ import annotations + +import logging +from concurrent.futures import ProcessPoolExecutor +from pathlib import Path +from time import time +from typing import TYPE_CHECKING + +import numpy as np +import pandas as pd +import qsample as qs +from qiskit import QuantumCircuit + +import mqt.qecc.ft_stateprep as ftsp +from mqt.qecc import codes + +if TYPE_CHECKING: + from mqt.qecc import CSSCode + +logger = logging.getLogger() +logger.setLevel(logging.INFO) + +# The directory where the circuits are stored +# The expected directory structure is: +# circ_dir +# ├── code_name +# │ ├── {zero,plus}_{heuristic,opt}.qasm +prefix = (Path(__file__) / "../circuits/").resolve() +# Synthesis parameters +max_timeout_global = 3000 +min_timeout_global = 8 +max_ancillas_global = 8 + +# Simulation parameters +err_params = {"q": [1e-4, 5e-4, 1e-3, 5e-3, 1e-2, 5e-2, 1e-1, 5e-1]} +err_model = qs.noise.E1_1 +shots_dss = 8000 +p_max = {"q": 0.01} +L = 3 + + +# Helper functions +def _extract_parameters(file_path: Path) -> tuple[str, bool, str]: + # Extract the code name from the parent directory + code_name = file_path.parent.name + file_path_str = str(file_path) + zero_state = "zero" in file_path_str + # Extract the procedure from the filename + if "heuristic" in file_path_str: + procedure = "heuristic" + elif "opt" in file_path_str: + procedure = "opt" + else: + procedure = "unknown" + + return code_name, zero_state, procedure + + +def _codes_from_matrix(code_name: str) -> CSSCode: + if code_name == "11_1_3": + matrix = np.array([ + [1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0], + [0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1], + [0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0], + [0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0], + [0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1], + ]) + return codes.CSSCode(distance=3, Hx=matrix, Hz=matrix) + if code_name == "16_2_4": + matrix = np.array([ + [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1], + [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1], + [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], + [0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0], + [0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0], + [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0], + ]) + return codes.CSSCode(distance=4, Hx=matrix, Hz=matrix) + if code_name == "hypercube": + matrix = np.array([ + [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], + [0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0], + [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], + ]) + return codes.CSSCode(distance=4, Hx=matrix, Hz=matrix) + msg = f"Code {code_name} not recognized." + raise ValueError(msg) + + +def run_parallel(path: Path) -> pd.DataFrame: + """Run the evaluation for a single circuit file and return the results as a DataFrame. + + Args: + path: The path to the circuit file. + + Returns: + The results of the evaluation as a DataFrame. + """ + # load code and circuit + code_name, zero_state, procedure = _extract_parameters(path) + if code_name in {"11_1_3", "16_2_4", "hypercube"}: + code = _codes_from_matrix(code_name) + else: + code = codes.CSSCode.from_code_name(code_name) + state_prep_circ = ftsp.StatePrepCircuit(QuantumCircuit.from_qasm_file(path), code, zero_state) + + start_time = time() + + verify_helper = ftsp.DeterministicVerificationHelper(state_prep_circ) + verify_heuristic = verify_helper.get_solution( + min_timeout=min_timeout_global, + max_timeout=max_timeout_global, + max_ancillas=max_ancillas_global, + use_optimal_verification=False, + ) + verify_optimal = verify_helper.get_solution( + min_timeout=min_timeout_global, + max_timeout=max_timeout_global, + max_ancillas=max_ancillas_global, + use_optimal_verification=True, + ) + verify_global = verify_helper.get_global_solution( + min_timeout=min_timeout_global, + max_timeout=max_timeout_global, + max_ancillas=max_ancillas_global, + ) + + sim_heuristic = ftsp.NoisyDFTStatePrepSimulator(state_prep_circ.circ, verify_heuristic, code, err_model, zero_state) + stats_heuristic = sim_heuristic.dss_logical_error_rates( + err_params=err_params, p_max=p_max, dss_l=L, shots=shots_dss + ) + sim_optimal = ftsp.NoisyDFTStatePrepSimulator(state_prep_circ.circ, verify_optimal, code, err_model, zero_state) + stats_optimal = sim_optimal.dss_logical_error_rates(err_params=err_params, p_max=p_max, dss_l=L, shots=shots_dss) + sim_global = ftsp.NoisyDFTStatePrepSimulator(state_prep_circ.circ, verify_global, code, err_model, zero_state) + stats_global = sim_global.dss_logical_error_rates(err_params=err_params, p_max=p_max, dss_l=L, shots=shots_dss) + + results_run = pd.DataFrame() + verifications = ["heuristic", "optimal", "global"] + for name, verify, stats in zip( + verifications, [verify_heuristic, verify_optimal, verify_global], [stats_heuristic, stats_optimal, stats_global] + ): + results_run = pd.concat([ + results_run, + pd.DataFrame({ + "code": [code_name], + "zero_state": [zero_state], + "global_opt": [False], + "verification": [name], + "procedure": [procedure], + "verification_stabs_0": [verify[0].stabs], + "recovery_stabs_0": [verify[0].det_correction], + "flags_0": [verify[0].hook_corrections], + "verification_stabs_1": [verify[1].stabs], + "recovery_stabs_1": [verify[1].det_correction], + "flags_1": [verify[1].hook_corrections], + "logical_error_rates": [stats], + "time": [time() - start_time], + }), + ]) + + results_run.to_csv(f"results_{code_name}_{zero_state}_{procedure}.csv") + + return results_run + + +if __name__ == "__main__": + # get all filepaths in the directory + file_paths = list(prefix.glob("**/*.qasm")) + + # run in parallel + with ProcessPoolExecutor() as executor: + dfs = list(executor.map(run_parallel, file_paths)) + + results = pd.concat(dfs, ignore_index=True) + results.to_csv("results.csv") diff --git a/scripts/ft_stateprep/eval_det/plot.ipynb b/scripts/ft_stateprep/eval_det/plot.ipynb new file mode 100644 index 00000000..02b09f7d --- /dev/null +++ b/scripts/ft_stateprep/eval_det/plot.ipynb @@ -0,0 +1,187 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "from mqt.qecc.ft_stateprep import DeterministicVerification" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data = pd.read_csv(\"results.csv\", index_col=0)\n", + "data.reset_index(inplace=True, drop=True)\n", + "data.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 1. Compute numbers for the table" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "eval_names = {\"array\": np.array, \"int8\": np.int8, \"nan\": np.nan}\n", + "for index, row in data.iterrows():\n", + " verify_0 = DeterministicVerification(\n", + " eval(row[\"verification_stabs_0\"], eval_names), # noqa: S307\n", + " eval(row[\"recovery_stabs_0\"], eval_names), # noqa: S307\n", + " eval(row[\"flags_0\"], eval_names), # noqa: S307\n", + " )\n", + " verify_1 = DeterministicVerification(\n", + " eval(row[\"verification_stabs_1\"], eval_names), # noqa: S307\n", + " eval(row[\"recovery_stabs_1\"], eval_names), # noqa: S307\n", + " eval(row[\"flags_1\"], eval_names), # noqa: S307\n", + " )\n", + " # add column\n", + " funs = [min, max, sum, np.mean]\n", + " data.at[index, \"verify_num_anc_0\"] = verify_0.num_ancillae_verification()\n", + " data.at[index, \"verify_num_cnots_0\"] = verify_0.num_cnots_verification()\n", + " data.at[index, \"verify_num_anc_1\"] = verify_1.num_ancillae_verification()\n", + " data.at[index, \"verify_num_cnots_1\"] = verify_1.num_cnots_verification()\n", + " data.at[index, \"correction_num_anc_0\"] = str([verify_0.stat_ancillae_correction(fun) for fun in funs])\n", + " data.at[index, \"correction_num_anc_list_0\"] = str(verify_0.stat_ancillae_correction(list))\n", + " data.at[index, \"correction_num_cnots_0\"] = str([verify_0.stat_cnots_correction(fun) for fun in funs])\n", + " data.at[index, \"correction_num_cnots_list_0\"] = str(verify_0.stat_cnots_correction(list))\n", + " data.at[index, \"correction_num_anc_1\"] = str([verify_1.stat_ancillae_correction(fun) for fun in funs])\n", + " data.at[index, \"correction_num_anc_list_1\"] = str(verify_1.stat_ancillae_correction(list))\n", + " data.at[index, \"correction_num_cnots_1\"] = str([verify_1.stat_cnots_correction(fun) for fun in funs])\n", + " data.at[index, \"correction_num_cnots_list_1\"] = str(verify_1.stat_cnots_correction(list))\n", + " data.at[index, \"flag_num_anc_0\"] = verify_0.num_ancillae_hooks()\n", + " data.at[index, \"flag_num_cnots_0\"] = verify_0.num_cnots_hooks()\n", + " data.at[index, \"flag_num_anc_1\"] = verify_1.num_ancillae_hooks()\n", + " data.at[index, \"flag_num_cnots_1\"] = verify_1.num_cnots_hooks()\n", + " data.at[index, \"flag_correction_num_anc_0\"] = str([verify_0.stat_ancillae_hook_corrections(fun) for fun in funs])\n", + " data.at[index, \"flag_correction_num_anc_list_0\"] = str(verify_0.stat_ancillae_hook_corrections(list))\n", + " data.at[index, \"flag_correction_num_cnots_0\"] = str([verify_0.stat_cnots_hook_corrections(fun) for fun in funs])\n", + " data.at[index, \"flag_correction_num_cnots_list_0\"] = str(verify_0.stat_cnots_hook_corrections(list))\n", + " data.at[index, \"flag_correction_num_anc_1\"] = str([verify_1.stat_ancillae_hook_corrections(fun) for fun in funs])\n", + " data.at[index, \"flag_correction_num_anc_list_1\"] = str(verify_1.stat_ancillae_hook_corrections(list))\n", + " data.at[index, \"flag_correction_num_cnots_1\"] = str([verify_1.stat_cnots_hook_corrections(fun) for fun in funs])\n", + " data.at[index, \"flag_correction_num_cnots_list_1\"] = str(verify_1.stat_cnots_hook_corrections(list))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# remove above columns\n", + "data_table = data.copy()\n", + "\n", + "stats_columns = [\n", + " \"verification_stabs_0\",\n", + " \"recovery_stabs_0\",\n", + " \"flags_0\",\n", + " \"verification_stabs_1\",\n", + " \"recovery_stabs_1\",\n", + " \"flags_1\",\n", + "]\n", + "error_rates_columns = [\"logical_error_rates\"]\n", + "data_table = data_table.drop(columns=stats_columns)\n", + "data_table = data_table.drop(columns=error_rates_columns)\n", + "# data_table" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2. Create Plot with logical error rates" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(5, 4))\n", + "ax = fig.add_subplot(111)\n", + "\n", + "physical_error_rates = [1e-4, 5e-4, 1e-3, 5e-3, 1e-2, 5e-2, 1e-1, 5e-1]\n", + "# fmts = ['o--', 's--', 'd--', 'x--', 'v--', '^--', '<--', '>--' , 'o--']\n", + "fmts = [\"o:\", \"s:\", \"d:\", \"x:\", \"v:\", \"^:\", \"<:\", \">:\", \"o:\"]\n", + "fmt_idx = 0\n", + "\n", + "data_sorted = data.sort_values(by=\"code\")\n", + "\n", + "sim_col = \"logical_error_rates\"\n", + "for _, row in data_sorted.iterrows():\n", + " if not row[\"zero_state\"] and row[\"code\"] != \"tetrahedral\":\n", + " continue\n", + " if row[\"zero_state\"] and row[\"code\"] == \"tetrahedral\":\n", + " continue\n", + " if row[\"procedure\"] != \"heuristic\" or row[\"verification\"] != \"optimal\":\n", + " continue\n", + " code_name = row[\"code\"].capitalize()\n", + " if code_name == \"16_2_4\":\n", + " code_name = r\"$[[16, 2, 4]]$\"\n", + " elif code_name == \"11_1_3\":\n", + " code_name = r\"$[[11, 1, 3]]$\"\n", + " elif code_name == \"Hypercube\":\n", + " code_name = \"Tesseract\"\n", + " upper_bound, std = eval(row[sim_col], eval_names)[-2:] # noqa: S307\n", + " ax.errorbar(physical_error_rates, upper_bound, label=code_name, fmt=fmts[fmt_idx])\n", + " fmt_idx += 1\n", + "\n", + "\n", + "# add linear line as reference\n", + "ax.plot(physical_error_rates, physical_error_rates, label=\"Linear\", linestyle=\"--\", color=\"black\", alpha=0.5)\n", + "\n", + "ax.set_xscale(\"log\")\n", + "ax.set_yscale(\"log\")\n", + "ax.set_ylabel(\"Logical error rate $p_{\\mathrm{L}}$\")\n", + "ax.set_xlabel(r\"Physical error rate $p$\")\n", + "ax.set_xlim(1e-4, 0.5)\n", + "ax.set_ylim(1e-7, 1)\n", + "\n", + "ax.legend(loc=\"lower right\")\n", + "# define order of legend\n", + "handles, labels = ax.get_legend_handles_labels()\n", + "order = [0, 7, 6, 8, 1, 9, 4, 3, 2, 5]\n", + "ax.legend([handles[idx] for idx in order], [labels[idx] for idx in order], loc=\"lower right\")\n", + "\n", + "plt.show()\n", + "fig.savefig(\"logical_error_rates.pdf\", bbox_inches=\"tight\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/scripts/ft_stateprep/eval_det/results.csv b/scripts/ft_stateprep/eval_det/results.csv new file mode 100644 index 00000000..7a558112 --- /dev/null +++ b/scripts/ft_stateprep/eval_det/results.csv @@ -0,0 +1,255 @@ +,code,zero_state,global_opt,verification,procedure,verification_stabs_0,recovery_stabs_0,flags_0,verification_stabs_1,recovery_stabs_1,flags_1,logical_error_rates,time +0,11_1_3,True,False,heuristic,heuristic,"[array([0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1]), array([0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0])]","{1: ([array([1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0])}), 2: ([array([1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0])}), 3: ([array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0])})}","[False, False]","[array([0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1])]","{1: ([array([1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0], dtype=int8), array([0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 2: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0])})}","[{1: ([array([1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1])})}]","[array([1.36176014e-06, 3.36684140e-05, 1.32801595e-04, 2.95387824e-03, + 1.01014594e-02, 5.57616851e-02, 2.44545397e-02, 1.29472270e-11]), array([4.50776961e-06, 2.23700243e-05, 4.53927314e-05, 3.49721121e-04, + 1.03286855e-03, 7.83148358e-03, 4.89439969e-03, 9.70586081e-12]), array([9.72771097e-06, 2.39839689e-04, 9.42934406e-04, 2.06001432e-02, + 7.01644854e-02, 6.10048758e-01, 9.22135163e-01, 1.00000000e+00]), array([4.72523102e-06, nan, nan, nan, + nan, nan, nan, nan])]",525.493499994278 +0,11_1_3,True,False,optimal,heuristic,"[array([0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1], dtype=int8), array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0], dtype=int8)]","{1: ([array([0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0])}), 2: ([array([1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 1: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1])}), 3: ([array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], dtype=int8)], {0: array([0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 1: array([1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0])})}","[False, False]","[array([0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0], dtype=int8)]","{1: ([array([1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0])})}","[{1: ([array([0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0])})}]","[array([6.99230991e-07, 1.73110456e-05, 6.84026209e-05, 1.54863612e-03, + 5.45297154e-03, 4.20873366e-02, 2.73948505e-02, 2.47850856e-11]), array([4.37464123e-06, 2.16675010e-05, 4.35069275e-05, 3.01388592e-04, + 8.89210028e-04, 8.92195019e-03, 8.27128523e-03, 1.17787789e-09]), array([1.08030839e-05, 2.65883388e-04, 1.04301212e-03, 2.23819240e-02, + 7.45544936e-02, 5.78223171e-01, 8.78129276e-01, 1.00000000e+00]), array([4.78186107e-06, 1.05074571e-05, nan, nan, + nan, nan, nan, nan])]",525.493898153305 +0,11_1_3,True,False,global,heuristic,"[array([1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0], dtype=int8), array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], dtype=int8)]","{1: ([array([1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1])}), 2: ([array([0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[False, False]","[array([0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0], dtype=int8)]","{1: ([array([1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0])})}","[{1: ([array([0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0])})}]","[array([6.42041791e-07, 1.60915812e-05, 6.45381152e-05, 1.62048417e-03, + 6.30379458e-03, 6.91692396e-02, 5.58285607e-02, 1.20573042e-09]), array([3.96284116e-06, 1.96351452e-05, 3.94317816e-05, 2.69345838e-04, + 7.91581855e-04, 1.02796978e-02, 1.21035502e-02, 2.81418546e-09]), array([1.00962464e-05, 2.48745668e-04, 9.77074487e-04, 2.12043221e-02, + 7.17127263e-02, 6.09507772e-01, 9.20762601e-01, 1.00000000e+00]), array([4.1133973e-06, nan, nan, nan, + nan, nan, nan, nan])]",525.4942150115967 +0,16_2_4,True,False,heuristic,heuristic,"[array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1]), array([0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0])]","{1: ([array([0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0], dtype=int8), array([0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 2: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]), 4: array([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 5: array([0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]), 6: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 7: array([0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0])}), 2: ([array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])}), 3: ([array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], dtype=int8)], {0: array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0])})}","[False, {1: ([array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], dtype=int8), array([0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]), 3: array([1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0])})}]","[array([0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0])]","{1: ([array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], dtype=int8), array([1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[{1: ([array([0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], dtype=int8), array([0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 1: array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0]), 2: array([0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0])})}]","[array([2.39388733e-06, 5.92472380e-05, 2.33943808e-04, 5.21120069e-03, + 1.76186389e-02, 7.11312815e-02, 1.62616377e-02, 3.11870338e-16]), array([3.17607936e-06, 1.57237885e-05, 3.21358253e-05, 2.43091677e-04, + 5.91580554e-04, 1.55812489e-03, 1.04845259e-03, 8.12796831e-17]), array([1.15562628e-05, 2.82650439e-04, 1.10039290e-03, 2.23841028e-02, + 7.07589251e-02, 4.24057683e-01, 5.00089205e-01, 5.00000000e-01]), array([nan, nan, nan, nan, nan, nan, nan, nan])]",165.36054301261902 +0,16_2_4,True,False,optimal,heuristic,"[array([0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1], dtype=int8), array([0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0], dtype=int8)]","{1: ([array([0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0])}), 2: ([array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], dtype=int8), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0], dtype=int8)], {0: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8), 1: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8)})}","[False, False]","[array([0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0], dtype=int8), array([1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1], dtype=int8)]","{1: ([array([0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0], dtype=int8), array([0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0])}), 2: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)}), 3: ([array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0])})}, {1: ([array([1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], dtype=int8), array([1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1]), 3: array([1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}]","[array([2.42592052e-06, 5.97513509e-05, 2.34559684e-04, 5.01635937e-03, + 1.62919415e-02, 5.62352877e-02, 1.38372925e-02, 7.03092930e-15]), array([3.64435428e-06, 1.77979316e-05, 3.49715206e-05, 1.83079083e-04, + 3.64220823e-04, 3.28146109e-03, 2.55338020e-03, 5.53124893e-15]), array([1.15636248e-05, 2.82103408e-04, 1.09467608e-03, 2.16611686e-02, + 6.61142288e-02, 3.67712247e-01, 4.83721607e-01, 5.00000000e-01]), array([nan, nan, nan, nan, nan, nan, nan, nan])]",165.36099100112915 +0,carbon,True,False,optimal,heuristic,"[array([0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0], dtype=int8), array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], dtype=int8)]","{1: ([array([0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1], dtype=int8), array([0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 3: array([0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0])}), 2: ([array([1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1])}), 3: ([array([0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1])})}","[False, False]","[array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0], dtype=int8)]","{1: ([array([1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0], dtype=int8), array([0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0]), 2: array([0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}","[{1: ([array([0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1])})}]","[array([1.15770240e-06, 2.87555957e-05, 1.14052486e-04, 2.63036831e-03, + 9.27130203e-03, 5.33877439e-02, 2.38691739e-02, 1.38188948e-11]), array([2.33275589e-06, 1.16191928e-05, 2.38519006e-05, 1.95035255e-04, + 5.58252254e-04, 3.70528847e-03, 2.01877918e-03, 4.49111619e-12]), array([5.98736011e-06, 1.47449296e-04, 5.78879696e-04, 1.25181503e-02, + 4.21811294e-02, 3.41561676e-01, 4.79397171e-01, 5.00000000e-01]), array([2.39821951e-06, nan, nan, nan, + nan, nan, nan, nan])]",47.95860719680786 +0,carbon,True,False,heuristic,opt,"[array([1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0]), array([1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0])]","{1: ([array([0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0])}), 2: ([array([0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[False, False]","[array([1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1]), array([1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0])]","{1: ([array([1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0])}), 2: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[{1: ([array([0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1])})}, {1: ([array([1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 1: array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}]","[array([1.64593715e-06, 4.06570222e-05, 1.60186959e-04, 3.53383074e-03, + 1.19757958e-02, 6.03643241e-02, 2.08688496e-02, 2.31493371e-14]), array([3.35672354e-06, 1.65009523e-05, 3.27243487e-05, 1.97588852e-04, + 5.20492603e-04, 3.29876761e-03, 1.77898858e-03, 3.85591492e-14]), array([6.13158724e-06, 1.50343592e-04, 5.87061165e-04, 1.21874064e-02, + 3.93198615e-02, 3.00611126e-01, 4.62622283e-01, 5.00000000e-01]), array([nan, nan, nan, nan, nan, nan, nan, nan])]",555.3856289386749 +0,carbon,True,False,optimal,opt,"[array([1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1], dtype=int8)]","{1: ([array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1], dtype=int8), array([1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0], dtype=int8), array([0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0], dtype=int8)], {0: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0]), 2: array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]), 4: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]), 5: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 6: array([0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]), 7: array([0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0])})}",[False],"[array([1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1], dtype=int8)]","{1: ([array([0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0])})}","[{1: ([array([0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0])})}]","[array([1.04687362e-06, 2.60734243e-05, 1.03772101e-04, 2.46547705e-03, + 9.05319426e-03, 7.57574133e-02, 5.38733056e-02, 3.28449955e-09]), array([1.63130347e-06, 8.27266395e-06, 1.77258932e-05, 1.87970731e-04, + 6.00620140e-04, 5.74748432e-03, 6.22670547e-03, 1.22685416e-09]), array([4.93566694e-06, 1.21720560e-04, 4.78697346e-04, 1.04864328e-02, + 3.58544661e-02, 3.18761546e-01, 4.73631937e-01, 5.00000003e-01]), array([1.29350754e-06, nan, nan, nan, + nan, nan, nan, nan])]",555.3860461711884 +0,carbon,True,False,global,opt,"[array([1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1], dtype=int8)]","{1: ([array([0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0], dtype=int8), array([0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1], dtype=int8), array([1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1], dtype=int8)], {0: array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0]), 3: array([0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 4: array([0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]), 5: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 6: array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]), 7: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0])})}",[False],"[array([1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1], dtype=int8)]","{1: ([array([0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}","[{1: ([array([1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}]","[array([1.31784537e-06, 3.27589353e-05, 1.30070050e-04, 3.03509776e-03, + 1.09190677e-02, 8.07356361e-02, 5.07922722e-02, 5.63853194e-10]), array([1.63892470e-06, 8.39233219e-06, 1.83991579e-05, 2.10289691e-04, + 6.52454581e-04, 5.04650059e-03, 4.81305631e-03, 1.61565817e-10]), array([5.51009614e-06, 1.35771955e-04, 5.33406769e-04, 1.15975904e-02, + 3.93310252e-02, 3.31987137e-01, 4.79351695e-01, 5.00000000e-01]), array([1.27031377e-06, nan, nan, nan, + nan, nan, nan, nan])]",555.386369228363 +0,hamming,True,False,heuristic,heuristic,"[array([0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0]), array([1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0])]","{1: ([array([0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0], dtype=int8), array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 4: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]), 5: array([0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 6: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 7: array([0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0])}), 2: ([array([0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]), 2: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1]), 3: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1])}), 3: ([array([0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 2: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0])})}","[False, {1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([6.61610700e-07, 1.63677577e-05, 6.46182445e-05, 1.45424399e-03, + 5.09674806e-03, 4.14179422e-02, 3.12386689e-02, 5.01208178e-11]), array([4.57740380e-07, 2.26259419e-06, 4.52196025e-06, 2.04962682e-05, + nan, nan, 1.64453791e-03, 2.09023972e-11]), array([6.86322583e-07, 1.69886848e-05, 6.71224224e-05, 1.52506875e-03, + 5.45096858e-03, 6.56920934e-02, 1.21850263e-01, 1.42857143e-01]), array([3.64398444e-07, nan, nan, nan, + nan, nan, nan, nan])]",2124.010397911072 +0,hamming,True,False,optimal,heuristic,"[array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], dtype=int8)]","{1: ([array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8), array([0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])}), 2: ([array([0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0], dtype=int8), array([0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])}), 3: ([array([0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), array([1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]), 1: array([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0]), 2: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[False, False]",[],{},[],"[array([4.39790649e-07, 1.09076689e-05, 4.31986042e-05, 9.96865036e-04, + 3.60327578e-03, 3.75695807e-02, 4.15513540e-02, 2.58997734e-08]), array([3.45720831e-07, 1.72511896e-06, 3.52049619e-06, 2.57187544e-05, + 5.78148664e-05, nan, 2.11622881e-03, 1.24339239e-08]), array([4.63585353e-07, 1.15010221e-05, 4.55664276e-05, 1.05673846e-03, + 3.86082054e-03, 5.15881839e-02, 1.06749703e-01, 1.42857152e-01]), array([3.43602263e-07, 1.17578734e-06, nan, nan, + nan, nan, nan, nan])]",2124.011169910431 +0,hamming,True,False,global,heuristic,"[array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], dtype=int8)]","{1: ([array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8), array([0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 3: array([1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0])}), 2: ([array([0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0], dtype=int8), array([0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0])}), 3: ([array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1], dtype=int8), array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], dtype=int8)], {0: array([0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 1: array([0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[False, False]",[],{},[],"[array([4.08140916e-07, 1.01474289e-05, 4.03069207e-05, 9.49286812e-04, + 3.49517128e-03, 3.68341936e-02, 3.84455680e-02, 3.79363443e-08]), array([3.56055005e-07, 1.79165684e-06, 3.73851741e-06, 3.23392713e-05, + 8.50434877e-05, nan, 1.69862502e-03, 1.96108766e-08]), array([4.30598864e-07, 1.07163307e-05, 4.26225612e-05, 1.01749854e-03, + 3.83531588e-03, 5.68882687e-02, 1.14408531e-01, 1.42857159e-01]), array([3.60657754e-07, 1.34116295e-06, 1.12376783e-06, nan, + nan, nan, nan, nan])]",2124.0122339725494 +0,hamming,True,False,heuristic,opt,"[array([1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0]), array([1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]","{1: ([array([0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), array([0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 3: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0])}), 2: ([array([1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 1: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 2: array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)}), 3: ([array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8), array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1]), 2: array([0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 3: array([1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1])})}","[False, False]",[],{},[],"[array([3.89670218e-07, 9.68395460e-06, 3.84449328e-05, 9.01552866e-04, + 3.30243440e-03, 3.41879695e-02, 3.91383787e-02, 4.56872399e-07]), array([3.79809173e-07, 1.89915633e-06, 3.89559514e-06, 2.80438219e-05, + 4.15983259e-05, nan, 3.43455532e-03, 1.41502062e-07]), array([4.16440988e-07, 1.03534528e-05, 4.11274872e-05, 9.72473296e-04, + 3.62695892e-03, 5.20903243e-02, 1.08624845e-01, 1.42857368e-01]), array([3.79784622e-07, 1.89609802e-06, 3.87146621e-06, 2.45595296e-05, + nan, nan, nan, nan])]",530.8170511722565 +0,hamming,True,False,optimal,opt,"[array([1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1], dtype=int8)]","{1: ([array([0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 2: array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)}), 2: ([array([0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 3: array([0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[False, False]",[],{},[],"[array([3.82058902e-07, 9.47484754e-06, 3.75180197e-05, 8.63549172e-04, + 3.10270977e-03, 2.93231865e-02, 2.91845677e-02, 5.24203388e-08]), array([3.46171966e-07, 1.69557281e-06, 3.26601787e-06, nan, + nan, 1.97866574e-04, 3.54036422e-03, 3.27999985e-08]), array([4.06297624e-07, 1.00869611e-05, 3.99978408e-05, 9.32368954e-04, + 3.41606632e-03, 4.39487377e-02, 9.07926825e-02, 1.42857058e-01]), array([3.43880024e-07, 1.09506070e-06, nan, nan, + nan, nan, nan, nan])]",530.8174641132355 +0,hamming,True,False,global,opt,"[array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1], dtype=int8), array([1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)]","{1: ([array([0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0], dtype=int8), array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 3: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0])}), 2: ([array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1], dtype=int8), array([0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 3: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[False, False]",[],{},[],"[array([3.85661454e-07, 9.56650158e-06, 3.78931154e-05, 8.75045323e-04, + 3.16180927e-03, 3.23234022e-02, 3.62270681e-02, 1.15189588e-07]), array([3.37216769e-07, 1.66860273e-06, 3.31508551e-06, 1.16360831e-05, + nan, nan, 4.24449702e-03, 5.48335538e-08]), array([4.09354455e-07, 1.01610269e-05, 4.02840170e-05, 9.38948422e-04, + 3.44990160e-03, 4.71895169e-02, 9.93231577e-02, 1.42857127e-01]), array([3.40192687e-07, 1.27968694e-06, 8.55345228e-07, nan, + nan, nan, nan, nan])]",530.8177988529205 +0,hypercube,True,False,heuristic,heuristic,"[array([1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1]), array([0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0])]","{1: ([array([0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1], dtype=int8), array([0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0])}), 2: ([array([0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0], dtype=int8), array([1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0])}), 3: ([array([0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0])})}","[False, False]","[array([1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1]), array([1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0])]","{1: ([array([0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])}), 2: ([array([0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], dtype=int8)], {0: array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1], dtype=int8), array([0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1])})}, {1: ([array([1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0], dtype=int8), array([0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0])})}]","[array([2.85919396e-05, 1.69713032e-04, 4.04226449e-04, 4.20543584e-03, + 1.19767064e-02, 3.28072758e-02, 4.56281454e-03, 5.31069402e-19]), array([3.73564486e-06, 1.80260936e-05, 3.44302067e-05, 1.01189510e-04, + nan, 3.68242915e-04, 2.13689567e-04, 2.32375218e-19]), array([3.14858259e-05, 2.39850036e-04, 6.74203196e-04, 9.24879905e-03, + 2.66129851e-02, 1.35213381e-01, 1.63994924e-01, 1.66666667e-01]), array([nan, nan, nan, nan, nan, nan, nan, nan])]",1630.665078163147 +0,hypercube,True,False,optimal,heuristic,"[array([0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1], dtype=int8), array([0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0], dtype=int8)]","{1: ([array([1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0], dtype=int8), array([0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0]), 3: array([0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])}), 2: ([array([0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 2: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0])}), 3: ([array([0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0], dtype=int8), array([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0]), 1: array([0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0]), 3: array([0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0])})}","[False, False]","[array([0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1], dtype=int8)]","{1: ([array([1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}","[{1: ([array([0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], dtype=int8), array([0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1]), 3: array([0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}]","[array([1.07315329e-06, 2.64951000e-05, 1.04315301e-04, 2.28184398e-03, + 7.61387066e-03, 3.28911493e-02, 1.01644350e-02, 1.35598497e-13]), array([8.48950677e-07, 4.21527082e-06, 8.60657466e-06, 6.01070580e-05, + 1.13840299e-04, 6.06351583e-04, 9.90029513e-04, 1.07322563e-13]), array([3.60789584e-06, 8.84674239e-05, 3.45462270e-04, 7.16870597e-03, + 2.30261669e-02, 1.40624968e-01, 1.67231452e-01, 1.66666667e-01]), array([5.69869772e-07, nan, nan, nan, + nan, nan, nan, nan])]",1630.665530204773 +0,hypercube,True,False,global,heuristic,"[array([0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0], dtype=int8), array([0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0], dtype=int8)]","{1: ([array([1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], dtype=int8), array([1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]), 3: array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])}), 2: ([array([0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], dtype=int8), array([0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0])}), 3: ([array([0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], dtype=int8), array([0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0])})}","[False, False]","[array([0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1], dtype=int8)]","{1: ([array([1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0], dtype=int8), array([0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1]), 3: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1])})}]","[array([1.08712327e-06, 2.68813591e-05, 1.06038652e-04, 2.35391535e-03, + 7.98569698e-03, 3.65162076e-02, 1.09604338e-02, 2.29595809e-14]), array([8.17450206e-07, 4.06805669e-06, 8.35579479e-06, 6.20849820e-05, + 1.38488053e-04, 5.95254275e-04, 4.94857035e-04, 6.44441689e-15]), array([3.64123520e-06, 8.92945920e-05, 3.48733922e-04, 7.23991624e-03, + 2.32524383e-02, 1.42176090e-01, 1.68070862e-01, 1.66666667e-01]), array([4.61409234e-07, nan, nan, nan, + nan, nan, nan, nan])]",1630.665892124176 +0,steane,True,False,heuristic,heuristic,"[array([0, 0, 1, 0, 1, 1, 0])]","{1: ([array([0, 1, 0, 0, 1, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 1, 0, 0])})}",[False],[],{},[],"[array([2.77938646e-07, 6.90938877e-06, 2.74433852e-05, 6.48440939e-04, + 2.41694628e-03, 3.42535000e-02, 6.68775329e-02, 1.65877203e-03]), array([1.36972233e-06, 6.92993316e-06, 1.44985057e-05, 1.40052013e-04, + 4.78510582e-04, 6.97986897e-03, 1.70130938e-02, 1.23475067e-03]), array([3.66179710e-07, 9.14105437e-06, 3.64974634e-05, 8.99498578e-04, + 3.53697805e-03, 7.82010413e-02, 2.65502451e-01, 9.99248278e-01]), array([1.36971865e-06, 6.92950332e-06, 1.44954584e-05, 1.39977677e-04, + 4.78813636e-04, 6.99989706e-03, 1.61435468e-02, 7.92671178e-04])]",25.7897047996521 +0,steane,True,False,optimal,heuristic,"[array([0, 0, 1, 0, 1, 1, 0], dtype=int8)]","{1: ([array([0, 1, 0, 0, 1, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 1, 0, 0])})}",[False],[],{},[],"[array([1.95505838e-07, 4.89140251e-06, 1.95830745e-05, 4.91808989e-04, + 1.96685266e-03, 4.18580769e-02, 1.09005505e-01, 2.81306936e-03]), array([1.44025633e-06, 7.24511602e-06, 1.49187530e-05, 1.27455920e-04, + 4.25043335e-04, 7.18634897e-03, 1.99737977e-02, 1.24622398e-03]), array([2.80419644e-07, 7.01406219e-06, 2.80736294e-05, 7.04850483e-04, + 2.82994862e-03, 6.91522231e-02, 2.44986402e-01, 9.97442310e-01]), array([1.44025238e-06, 7.24464531e-06, 1.49152809e-05, 1.27284958e-04, + 4.24538441e-04, 7.31696587e-03, 2.16918760e-02, 1.55087645e-03])]",25.79061198234558 +0,steane,True,False,global,heuristic,"[array([0, 0, 1, 0, 1, 1, 0], dtype=int8)]","{1: ([array([0, 1, 0, 0, 1, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 1, 0, 0])})}",[False],[],{},[],"[array([2.00314057e-07, 4.99521992e-06, 1.99176203e-05, 4.85198918e-04, + 1.87641364e-03, 3.42301693e-02, 8.45746886e-02, 3.70542490e-03]), array([1.51346868e-06, 7.58991274e-06, 1.54916535e-05, 1.21426622e-04, + 3.95786659e-04, 7.77755583e-03, 2.61675497e-02, 2.52840099e-03]), array([2.83238533e-07, 7.08385446e-06, 2.83494324e-05, 7.11105173e-04, + 2.85207690e-03, 6.93635899e-02, 2.45418358e-01, 9.97938750e-01]), array([1.51346383e-06, 7.58931449e-06, 1.54870451e-05, 1.21167382e-04, + 3.95610405e-04, 7.89789858e-03, 2.55917051e-02, 2.05536265e-03])]",25.791008949279785 +0,steane,True,False,heuristic,opt,"[array([1, 1, 0, 0, 1, 1, 0])]","{1: ([array([0, 0, 1, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 1, 0, 0, 0])})}",[False],[],{},[],"[array([2.00345625e-07, 4.99518423e-06, 1.99133305e-05, 4.84242868e-04, + 1.86820793e-03, 3.32100143e-02, 7.85664019e-02, 1.90430900e-03]), array([1.44475137e-06, 7.28959016e-06, 1.51468342e-05, 1.39638471e-04, + 4.73482667e-04, 7.57008543e-03, 2.02662984e-02, 9.01433905e-04]), array([2.93816176e-07, 7.35312624e-06, 2.94506597e-05, 7.43437951e-04, + 3.00493820e-03, 7.67265615e-02, 2.78281677e-01, 1.00000411e+00]), array([1.44474997e-06, 7.28940166e-06, 1.51452648e-05, 1.39533983e-04, + 4.73502234e-04, 7.63904605e-03, 1.93382264e-02, 5.74671325e-04])]",26.64948081970215 +0,steane,True,False,optimal,opt,"[array([1, 0, 0, 0, 0, 1, 1], dtype=int8)]","{1: ([array([0, 0, 1, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 1])})}",[False],[],{},[],"[array([2.13384519e-07, 5.30981260e-06, 2.11157520e-05, 5.03694319e-04, + 1.89871307e-03, 2.87743254e-02, 5.79085753e-02, 4.26985375e-04]), array([1.59451713e-06, 8.00013992e-06, 1.63510416e-05, 1.29826241e-04, + 4.21817958e-04, 6.64970735e-03, 1.70397048e-02, 7.43548424e-04]), array([3.06103483e-07, 7.64421493e-06, 3.05352998e-05, 7.55351036e-04, + 2.98368393e-03, 6.81251548e-02, 2.38585318e-01, 9.97307068e-01]), array([1.59451412e-06, 7.99975989e-06, 1.63480396e-05, 1.29648060e-04, + 4.22022540e-04, 7.18915231e-03, 2.04955135e-02, 1.03985581e-03])]",26.649830102920532 +0,steane,True,False,global,opt,"[array([0, 0, 1, 1, 0, 0, 1], dtype=int8)]","{1: ([array([1, 0, 0, 0, 0, 1, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 1])})}",[False],[],{},[],"[array([2.80958369e-07, 7.00214948e-06, 2.78994326e-05, 6.75559861e-04, + 2.59211151e-03, 4.38792834e-02, 9.64144222e-02, 7.59814330e-04]), array([1.50928159e-06, 7.61325927e-06, 1.57987420e-05, 1.44176479e-04, + 4.89507288e-04, 7.93974636e-03, 2.00610072e-02, 5.56328433e-04]), array([3.77337148e-07, 9.42560240e-06, 3.76631250e-05, 9.33568826e-04, + 3.69272334e-03, 8.26943669e-02, 2.75002615e-01, 9.97774942e-01]), array([1.50927526e-06, 7.61248704e-06, 1.57928579e-05, 1.43722384e-04, + 4.86308286e-04, 7.43015274e-03, 1.78647100e-02, 6.01239345e-04])]",26.650152921676636 +0,surface_3,False,False,heuristic,heuristic,"[array([0, 0, 0, 0, 1, 1, 1, 0, 0])]","{1: ([array([0, 0, 1, 0, 1, 0, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 1, 0, 0, 0]), 1: array([0, 0, 0, 0, 1, 0, 0, 0, 1])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 1, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([5.49164266e-07, 1.36703726e-05, 5.43867040e-05, 1.29979469e-03, + 4.89417521e-03, 6.66739011e-02, 1.02107079e-01, 2.31600254e-05]), array([1.75116823e-06, 8.89591495e-06, 1.88929204e-05, 1.99195743e-04, + 6.87719769e-04, 1.15464983e-02, 2.40444157e-02, 2.51299442e-05]), array([6.56117570e-07, 1.63605339e-05, 6.52322315e-05, 1.59080549e-03, + 6.18050352e-03, 1.26786632e-01, 3.91947577e-01, 9.99903306e-01]), array([1.81921695e-06, 7.00818979e-06, 7.54609327e-06, nan, + 3.67580197e-04, 1.06895468e-02, 2.37818156e-02, nan])]",36.99601721763611 +0,surface_3,False,False,optimal,heuristic,"[array([0, 0, 0, 1, 1, 1, 0, 0, 0], dtype=int8)]","{1: ([array([0, 0, 1, 1, 1, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 1, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 1, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([6.17090460e-07, 1.52991977e-05, 6.05624565e-05, 1.39297342e-03, + 5.02046751e-03, 5.42467451e-02, 7.35921087e-02, 7.12092671e-06]), array([1.80568512e-06, 9.13247036e-06, 1.91728257e-05, 1.88937825e-04, + 6.39633667e-04, 9.86191013e-03, 2.01931676e-02, 1.54153222e-05]), array([7.29272166e-07, 1.81076210e-05, 7.18192706e-05, 1.68241615e-03, + 6.24663718e-03, 1.07503937e-01, 3.41850855e-01, 9.99892434e-01]), array([1.86910946e-06, 6.71773616e-06, nan, nan, + 1.79669058e-04, 7.67265700e-03, 8.18186107e-03, nan])]",36.99643611907959 +0,surface_3,False,False,global,heuristic,"[array([0, 0, 0, 1, 1, 1, 0, 0, 0], dtype=int8)]","{1: ([array([0, 0, 1, 1, 1, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 1, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 1, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([4.78619701e-07, 1.19288108e-05, 4.75299745e-05, 1.14952586e-03, + 4.39117073e-03, 6.64921848e-02, 1.15607689e-01, 6.00224093e-05]), array([1.78096371e-06, 8.99259699e-06, 1.87953445e-05, 1.79100471e-04, + 5.90875900e-04, 6.88875727e-03, 1.33199770e-02, 2.28051106e-05]), array([6.10190153e-07, 1.52590672e-05, 6.10554874e-05, 1.52798019e-03, + 6.09917544e-03, 1.36464466e-01, 4.17230536e-01, 9.99922701e-01]), array([1.83481516e-06, 6.80348037e-06, 4.46572069e-06, nan, + 2.55314402e-05, 2.91249783e-03, nan, nan])]",36.99676704406738 +0,surface_3,False,False,heuristic,opt,"[array([1, 1, 0, 1, 1, 0, 0, 0, 0])]","{1: ([array([0, 0, 0, 1, 1, 1, 0, 0, 0], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 0, 1, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([4.17046736e-07, 1.03410959e-05, 4.09445721e-05, 9.44876225e-04, + 3.43229695e-03, 4.36463737e-02, 7.74998599e-02, 1.10890181e-05]), array([1.79206346e-06, 9.03980879e-06, 1.88562105e-05, 1.77860122e-04, + 5.88446320e-04, 8.13673054e-03, 1.91509192e-02, 1.07109672e-05]), array([5.19616005e-07, 1.29852011e-05, 5.19148997e-05, 1.29271257e-03, + 5.14408002e-03, 1.19212133e-01, 3.88801897e-01, 9.99929825e-01]), array([1.85890443e-06, 7.07727939e-06, 6.52258619e-06, nan, + nan, nan, nan, nan])]",37.29507803916931 +0,surface_3,False,False,optimal,opt,"[array([0, 0, 1, 1, 1, 0, 0, 0, 0], dtype=int8)]","{1: ([array([0, 0, 0, 1, 1, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 1, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 0, 1, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 1, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([2.63174563e-07, 6.56857442e-06, 2.62177779e-05, 6.41785363e-04, + 2.47913615e-03, 3.75917213e-02, 5.92809625e-02, 3.21170652e-06]), array([1.91250058e-06, 9.59585930e-06, 1.97101431e-05, 1.65510200e-04, + 5.38741287e-04, 8.06317273e-03, 1.63389659e-02, 1.57610448e-05]), array([3.76348195e-07, 9.40576246e-06, 3.76097634e-05, 9.38849269e-04, + 3.75818349e-03, 9.52562179e-02, 3.42344153e-01, 9.99878793e-01]), array([2.01534066e-06, 9.13565539e-06, 1.60421888e-05, 4.77629321e-05, + 2.43369681e-04, 2.81520382e-03, nan, nan])]",37.29552912712097 +0,surface_3,False,False,global,opt,"[array([0, 0, 1, 1, 1, 0, 0, 0, 0], dtype=int8)]","{1: ([array([0, 0, 0, 1, 1, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 1, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 0, 1, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 1, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([3.97748530e-07, 9.89957874e-06, 3.93772706e-05, 9.39960291e-04, + 3.53676569e-03, 4.89413291e-02, 7.89720984e-02, 4.00347966e-05]), array([1.76497802e-06, 8.93468260e-06, 1.88018641e-05, 1.88785159e-04, + 6.54334545e-04, 1.28040896e-02, 2.93415769e-02, 3.92106759e-05]), array([5.36722151e-07, 1.33866631e-05, 5.33920408e-05, 1.30604682e-03, + 5.09901854e-03, 1.10713419e-01, 3.63944794e-01, 9.99896896e-01]), array([1.86315493e-06, 7.69045905e-06, 1.10088746e-05, nan, + 2.29403416e-04, nan, nan, nan])]",37.297500133514404 +0,surface_3,True,False,heuristic,heuristic,"[array([1, 0, 1, 0, 1, 1, 0, 0, 0])]","{1: ([array([1, 0, 0, 0, 1, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 1, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 1, 0, 0, 0, 0])})}",[False],[],{},[],"[array([3.51976982e-07, 8.76566840e-06, 3.48942411e-05, 8.39029250e-04, + 3.19328382e-03, 5.16778337e-02, 1.11119373e-01, 1.39433989e-03]), array([1.50541521e-06, 7.58953847e-06, 1.57446229e-05, 1.43645901e-04, + 4.88584759e-04, 9.43840552e-03, 2.93881159e-02, 9.11381273e-04]), array([4.62770692e-07, 1.15443133e-05, 4.60529587e-05, 1.12692894e-03, + 4.39016255e-03, 8.97417022e-02, 2.81954955e-01, 9.98435184e-01]), array([1.50542292e-06, 7.59043478e-06, 1.57510374e-05, 1.43981943e-04, + 4.91059333e-04, 1.00281278e-02, 3.18012932e-02, 9.18644724e-04])]",34.378907918930054 +0,surface_3,True,False,optimal,heuristic,"[array([0, 1, 0, 0, 1, 0, 0, 0, 1], dtype=int8)]","{1: ([array([0, 1, 0, 0, 1, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 1, 0, 1, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([2.42859676e-07, 6.03258515e-06, 2.39370445e-05, 5.60981627e-04, + 2.06841520e-03, 2.62617628e-02, 4.23420442e-02, 4.04880786e-05]), array([1.80598966e-06, 9.04909904e-06, 1.84982173e-05, 1.48271145e-04, + 4.75064825e-04, 6.87086877e-03, 1.56935270e-02, 4.55130899e-05]), array([3.55075001e-07, 8.86970879e-06, 3.54445596e-05, 8.80672473e-04, + 3.50709421e-03, 8.76951168e-02, 3.21467689e-01, 9.99876861e-01]), array([1.90243244e-06, 8.06645380e-06, 1.21449458e-05, nan, + 9.36193183e-05, 5.09787470e-03, nan, nan])]",34.37936305999756 +0,surface_3,True,False,global,heuristic,"[array([0, 1, 0, 0, 1, 0, 0, 0, 1], dtype=int8)]","{1: ([array([0, 1, 0, 0, 1, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 1, 0, 1, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([2.31513120e-07, 5.74206083e-06, 2.27413084e-05, 5.24994469e-04, + 1.89979976e-03, 2.08051552e-02, 2.78624737e-02, 3.26115135e-06]), array([1.72133152e-06, 8.62154334e-06, 1.76039821e-05, 1.39311354e-04, + 4.43727164e-04, 6.46702018e-03, 1.50069599e-02, 3.83013070e-05]), array([3.49923405e-07, 8.72069188e-06, 3.47490082e-05, 8.44971197e-04, + 3.28733531e-03, 7.64874945e-02, 2.87957446e-01, 9.99777059e-01]), array([1.83209366e-06, 8.11583310e-06, 1.36372157e-05, nan, + 2.06182864e-04, 5.14263453e-03, 1.15524221e-02, nan])]",34.37979006767273 +0,surface_3,True,False,heuristic,opt,"[array([0, 0, 0, 1, 1, 0, 1, 0, 1])]","{1: ([array([1, 0, 0, 0, 1, 0, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 1, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 1, 1, 0, 0, 0])})}","[{1: ([array([0, 0, 0, 1, 0, 0, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 0, 0, 0, 1, 0, 0])})}]",[],{},[],"[array([3.01717950e-07, 7.47296824e-06, 2.95454820e-05, 6.72749769e-04, + 2.39324829e-03, 2.29694746e-02, 2.63911420e-02, 1.72404795e-06]), array([1.71869451e-06, 8.68084107e-06, 1.81594278e-05, 1.74727666e-04, + 5.82339761e-04, 7.30632851e-03, 1.30918239e-02, 3.36387877e-06]), array([4.17646028e-07, 1.04400175e-05, 4.17557361e-05, 1.04418698e-03, + 4.18681954e-03, 1.05987357e-01, 3.74143742e-01, 9.99964233e-01]), array([1.81633364e-06, 8.15825414e-06, 1.44553143e-05, 1.07002698e-04, + 4.35818789e-04, 5.92686902e-03, nan, nan])]",36.35913586616516 +0,surface_3,True,False,optimal,opt,"[array([0, 1, 0, 0, 1, 0, 0, 1, 0], dtype=int8)]","{1: ([array([1, 0, 0, 0, 1, 0, 0, 1, 0], dtype=int8)], {0: array([0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 1, 1])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([2.81251129e-07, 6.99721920e-06, 2.78189000e-05, 6.61825249e-04, + 2.48306263e-03, 3.46921927e-02, 5.85179195e-02, 1.93502386e-05]), array([1.72957250e-06, 8.67416307e-06, 1.77786038e-05, 1.47521397e-04, + 4.95314396e-04, 1.04792618e-02, 2.51474349e-02, 2.26659431e-05]), array([3.98752883e-07, 9.95616666e-06, 3.97627033e-05, 9.82879538e-04, + 3.88567949e-03, 9.14362171e-02, 3.21787091e-01, 9.99833085e-01]), array([1.84698124e-06, 8.03849989e-06, 1.29737090e-05, nan, + 1.76666569e-04, 4.36002273e-03, nan, nan])]",36.36020588874817 +0,surface_3,True,False,global,opt,"[array([0, 1, 0, 0, 1, 0, 0, 1, 0], dtype=int8)]","{1: ([array([1, 0, 0, 0, 1, 0, 0, 1, 0], dtype=int8)], {0: array([0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 1, 1])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 1]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([2.85196754e-07, 7.06698443e-06, 2.79562623e-05, 6.39470638e-04, + 2.28789223e-03, 2.29996666e-02, 2.80452209e-02, 3.16954183e-06]), array([1.69151504e-06, 8.51014011e-06, 1.75979826e-05, 1.57052990e-04, + 5.30650731e-04, 1.05594596e-02, 2.76577001e-02, 7.79293073e-05]), array([3.97584786e-07, 9.91251755e-06, 3.95171452e-05, 9.63761966e-04, + 3.75539334e-03, 8.44249627e-02, 3.01490578e-01, 9.99761293e-01]), array([1.79814603e-06, 7.90723481e-06, 1.31398224e-05, 1.99433740e-05, + 2.60649824e-04, 7.43640024e-03, 1.17801656e-02, nan])]",36.36116290092468 +0,tetrahedral,False,False,heuristic,heuristic,"[array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0])]","{1: ([array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0], dtype=int8), array([0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]), 3: array([0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}]",[],{},[],"[array([2.71205836e-06, 6.72874264e-05, 2.66562370e-04, 6.13507131e-03, + 2.18701067e-02, 1.64243895e-01, 1.01666193e-01, 4.63289534e-10]), array([2.23599489e-06, 1.16686198e-05, 2.65930338e-05, 3.41838783e-04, + 1.10682324e-03, 1.48537609e-02, 2.66906541e-02, 3.02532192e-08]), array([2.89535332e-06, 7.18766063e-05, 2.84971001e-04, 6.62149887e-03, + 2.40692677e-02, 2.86066304e-01, 6.01717437e-01, 9.99999927e-01]), array([2.00166339e-06, nan, nan, nan, + nan, 4.24813763e-03, nan, nan])]",6171.229279994965 +0,tetrahedral,False,False,optimal,heuristic,"[array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0], dtype=int8)]","{1: ([array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0], dtype=int8), array([0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]), 3: array([0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}]",[],{},[],"[array([2.84573986e-06, 7.03733755e-05, 2.77692579e-04, 6.22932890e-03, + 2.17793009e-02, 1.84011156e-01, 1.57548021e-01, 7.59754211e-10]), array([2.17272915e-06, 1.15240765e-05, 2.71187095e-05, 3.77776717e-04, + 1.23344969e-03, 1.40689184e-02, 1.73456558e-02, 1.78922457e-10]), array([3.02683318e-06, 7.49528617e-05, 2.96279654e-04, 6.75575019e-03, + 2.42619939e-02, 3.27536784e-01, 7.40005278e-01, 9.99999999e-01]), array([1.89325025e-06, nan, nan, nan, + 3.29892379e-04, nan, nan, nan])]",6171.2296550273895 +0,tetrahedral,False,False,global,heuristic,"[array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0], dtype=int8)]","{1: ([array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0])})}","[{1: ([array([0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0], dtype=int8), array([0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]), 2: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}]",[],{},[],"[array([2.97501831e-06, 7.38451425e-05, 2.92702590e-04, 6.76243010e-03, + 2.41893789e-02, 1.80337318e-01, 1.05641398e-01, 5.78592997e-10]), array([2.26916034e-06, 1.19916558e-05, 2.80120840e-05, 3.80751787e-04, + 1.22388837e-03, 1.04734571e-02, 1.01676402e-02, 1.92769823e-10]), array([3.16002318e-06, 7.84863962e-05, 3.11407902e-04, 7.30795388e-03, + 2.71006866e-02, 3.87945509e-01, 7.89330163e-01, 1.00000000e+00]), array([1.98403199e-06, nan, nan, nan, + nan, nan, nan, nan])]",6171.22997713089 +0,tetrahedral,True,False,heuristic,heuristic,"[array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0])]","{1: ([array([1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], dtype=int8), array([0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0]), 2: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0]), 3: array([0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([4.62931423e-07, 1.15112299e-05, 4.57418548e-05, 1.08899956e-03, + 4.12567246e-03, 6.32103841e-02, 8.98840419e-02, 5.25938964e-08]), array([2.01309596e-06, 1.01293031e-05, 2.11484562e-05, 2.02864587e-04, + 6.87778862e-04, 1.20344324e-02, 2.15659208e-02, 4.97569145e-07]), array([6.62396772e-07, 1.65033063e-05, 6.57488522e-05, 1.60711090e-03, + 6.36754142e-03, 1.66440831e-01, 5.28489014e-01, 9.99998814e-01]), array([2.03569050e-06, 6.06144539e-06, nan, nan, + nan, nan, nan, nan])]",421.2212119102478 +0,tetrahedral,True,False,optimal,heuristic,"[array([0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0], dtype=int8)]","{1: ([array([1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], dtype=int8), array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0]), 3: array([0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([3.39592312e-07, 8.52337313e-06, 3.42490776e-05, 8.76063903e-04, + 3.50780341e-03, 5.05063521e-02, 5.46828691e-02, 3.96523886e-09]), array([2.09107766e-06, 1.04808720e-05, 2.16553063e-05, 1.95023313e-04, + 6.60468359e-04, 1.05302347e-02, 1.46278487e-02, 1.98779082e-08]), array([5.58894721e-07, 1.39932493e-05, 5.60828479e-05, 1.42850075e-03, + 5.87427773e-03, 1.65934061e-01, 5.41374528e-01, 9.99999844e-01]), array([2.17383809e-06, 8.66466822e-06, 1.09480688e-05, nan, + 3.27690150e-04, 7.66904643e-03, nan, nan])]",421.2217071056366 +0,tetrahedral,True,False,global,heuristic,"[array([1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], dtype=int8)]","{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0], dtype=int8), array([0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1]), 3: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([7.74752926e-05, 3.91078695e-04, 7.91498703e-04, 4.33766401e-03, + 9.57731030e-03, 5.18182612e-02, 4.45837985e-02, 1.68337019e-08]), array([1.19561036e-05, 5.88626220e-05, 1.15628082e-04, 5.28502483e-04, + 1.06804493e-03, 1.13541599e-02, 1.61969947e-02, 8.86534770e-09]), array([7.76987391e-05, 3.96648087e-04, 8.13709633e-04, 4.89525015e-03, + 1.19471308e-02, 1.70958189e-01, 5.55265561e-01, 9.99999962e-01]), array([nan, nan, nan, nan, nan, nan, nan, nan])]",421.222069978714 +0,tetrahedral,True,False,heuristic,opt,"[array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0])]","{1: ([array([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0], dtype=int8), array([1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1]), 2: array([1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1]), 3: array([0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([4.18102538e-07, 1.03309981e-05, 4.07235079e-05, 9.05051099e-04, + 3.12042343e-03, 2.25022754e-02, 1.67439248e-02, 1.46461844e-09]), array([2.03640255e-06, 1.02230213e-05, 2.12123361e-05, 1.94043485e-04, + 6.34706024e-04, 1.11035975e-02, 2.07250526e-02, 2.24172244e-08]), array([6.20787139e-07, 1.53790327e-05, 6.08325799e-05, 1.40263794e-03, + 5.18337654e-03, 1.21646822e-01, 4.75043781e-01, 9.99999860e-01]), array([2.06522333e-06, 7.09346061e-06, nan, nan, + 3.10094666e-05, nan, nan, nan])]",421.3850209712982 +0,tetrahedral,True,False,optimal,opt,"[array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], dtype=int8)]","{1: ([array([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0], dtype=int8), array([1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1]), 2: array([1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1]), 3: array([0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([4.51626894e-07, 1.12347536e-05, 4.46541899e-05, 1.05503252e-03, + 3.88451100e-03, 3.74369768e-02, 3.17404022e-02, 9.28498969e-09]), array([2.05538206e-06, 1.03241640e-05, 2.14562698e-05, 2.00464313e-04, + 6.80090276e-04, 1.11064989e-02, 1.64603737e-02, 1.39007381e-08]), array([6.51554999e-07, 1.62392813e-05, 6.47206514e-05, 1.58121659e-03, + 6.22771957e-03, 1.61517108e-01, 5.45678133e-01, 9.99999928e-01]), array([2.11888427e-06, 8.07623402e-06, 7.64895404e-06, nan, + 1.78469427e-04, 5.02708661e-03, nan, nan])]",421.3860580921173 +0,tetrahedral,True,False,global,opt,"[array([0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0], dtype=int8)]","{1: ([array([0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], dtype=int8), array([1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1]), 2: array([1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0]), 3: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([3.56413689e-07, 8.81210911e-06, 3.47652104e-05, 7.79797776e-04, + 2.73513330e-03, 2.50416322e-02, 2.45041670e-02, 1.12413322e-09]), array([2.08835363e-06, 1.04578988e-05, 2.15556120e-05, 1.88542221e-04, + 6.13118089e-04, 1.14871437e-02, 2.61850265e-02, 1.75618391e-07]), array([5.68886580e-07, 1.40952641e-05, 5.57734800e-05, 1.29690000e-03, + 4.89329163e-03, 1.25954707e-01, 4.65499121e-01, 9.99999592e-01]), array([2.11860451e-06, 6.93022772e-06, nan, nan, + nan, 5.75078675e-03, 1.32845238e-02, nan])]",421.3871719837189 +0,16_2_4,True,False,global,heuristic,"[array([1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1], dtype=int8), array([0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0], dtype=int8)]","{1: ([array([0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], dtype=int8), array([0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0])}), 2: ([array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1], dtype=int8), array([0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 2: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 3: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8), 1: array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], dtype=int8)})}","[False, False]","[array([0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], dtype=int8), array([1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0], dtype=int8)]","{1: ([array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1], dtype=int8), array([0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3: array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])}), 2: ([array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[{1: ([array([0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 1: array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}, {1: ([array([1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], dtype=int8), array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 1: array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1]), 2: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 3: array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])})}]","[array([1.93952335e-06, 4.78816101e-05, 1.88497679e-04, 4.11700854e-03, + 1.36890016e-02, 5.56315718e-02, 1.51756148e-02, 4.67226514e-16]), array([3.51234526e-06, 1.71887626e-05, 3.39768575e-05, 1.97117291e-04, + 4.73012465e-04, 3.19592300e-03, 1.73359199e-03, 2.39986154e-15]), array([1.00852821e-05, 2.46087128e-04, 9.55186777e-04, 1.89694296e-02, + 5.83629858e-02, 3.57813807e-01, 4.82772150e-01, 5.00000000e-01]), array([nan, nan, nan, nan, nan, nan, nan, nan])]",486.9667320251465 +0,shor,True,False,heuristic,heuristic,"[array([0, 1, 0, 1, 0, 0, 0, 1, 0]), array([0, 0, 0, 1, 1, 0, 0, 0, 0])]","{1: ([array([1, 0, 0, 0, 0, 1, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 1, 0, 0, 1, 1, 0])}), 2: ([array([0, 0, 1, 1, 0, 0, 0, 1, 0], dtype=int8)], {0: array([0, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 1, 1, 0])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 1, 1, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}, False]",[],{},[],"[array([4.75542821e-07, 1.18472155e-05, 4.71810434e-05, 1.13704554e-03, + 4.32888046e-03, 6.52742426e-02, 1.14590741e-01, 2.83822117e-05]), array([2.47997711e-06, 1.22943902e-05, 2.43796734e-05, 1.23489892e-04, + 3.23700769e-04, 1.12202104e-02, 2.74289064e-02, 1.48843887e-05]), array([5.85930704e-07, 1.46602916e-05, 5.86992140e-05, 1.47705712e-03, + 5.93658833e-03, 1.39004587e-01, 4.34961843e-01, 9.99964360e-01]), array([2.49050153e-06, 9.84780646e-06, 1.04183524e-05, nan, + nan, nan, nan, nan])]",58.70700216293335 +0,shor,True,False,optimal,heuristic,"[array([0, 0, 1, 0, 0, 1, 0, 1, 0], dtype=int8), array([0, 1, 1, 0, 0, 0, 0, 0, 0], dtype=int8)]","{1: ([array([1, 0, 0, 0, 0, 1, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([1, 0, 0, 0, 0, 0, 0, 0, 0])}), 2: ([array([1, 0, 0, 1, 0, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 1, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 1, 1, 0])}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 1, 1, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}, False]",[],{},[],"[array([4.12994257e-07, 1.03043299e-05, 4.11116126e-05, 1.00382949e-03, + 3.87186239e-03, 6.00690758e-02, 1.00900042e-01, 1.10143588e-05]), array([2.35128468e-06, 1.16623223e-05, 2.31594459e-05, 1.19542134e-04, + 3.10505704e-04, 1.07469857e-02, 2.56412185e-02, 8.97886713e-06]), array([5.13382843e-07, 1.28461689e-05, 5.14419178e-05, 1.29668327e-03, + 5.23070971e-03, 1.28528074e-01, 4.21465399e-01, 9.99972299e-01]), array([2.46715476e-06, 1.18456261e-05, 2.23855080e-05, nan, + nan, nan, nan, nan])]",58.70743489265442 +0,shor,True,False,global,heuristic,"[array([0, 1, 1, 0, 0, 0, 0, 0, 0], dtype=int8), array([0, 1, 0, 0, 1, 0, 1, 0, 0], dtype=int8)]","{1: ([array([1, 0, 0, 0, 0, 1, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 1, 1, 1, 0, 0, 0])}), 2: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 1, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)}), 3: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([1, 1, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}","[False, {1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([5.60252069e-07, 1.38903058e-05, 5.49863630e-05, 1.26465379e-03, + 4.55542884e-03, 4.82306257e-02, 6.23770582e-02, 7.39926682e-06]), array([2.43304941e-06, 1.21563572e-05, 2.46694057e-05, 1.83097412e-04, + 5.65824759e-04, 7.19520859e-03, 1.41309522e-02, 6.90297395e-06]), array([6.64242463e-07, 1.65088554e-05, 6.55568481e-05, 1.55026123e-03, + 5.82102152e-03, 1.06249163e-01, 3.43847337e-01, 9.99926625e-01]), array([2.45994874e-06, 1.02147063e-05, 1.42665888e-05, nan, + nan, nan, nan, nan])]",58.70777201652527 +0,shor,True,False,heuristic,opt,"[array([0, 1, 0, 0, 1, 0, 1, 0, 0])]","{1: ([array([1, 0, 0, 1, 0, 0, 0, 1, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 1, 1, 1, 0, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([3.79909972e-07, 9.46228534e-06, 3.76716109e-05, 9.06128895e-04, + 3.44564629e-03, 5.32042861e-02, 1.00942659e-01, 1.11512026e-04]), array([1.70954467e-06, 8.60603257e-06, 1.78043148e-05, 1.58651986e-04, + 5.28828976e-04, 8.11709968e-03, 1.85726260e-02, 7.10695876e-05]), array([4.69420253e-07, 1.17337932e-05, 4.69257092e-05, 1.17037649e-03, + 4.65941058e-03, 1.05967837e-01, 3.42348620e-01, 9.99575859e-01]), array([1.78839732e-06, 7.60542103e-06, 1.17476889e-05, nan, + 2.63673341e-04, 5.48018653e-03, 7.47823097e-03, nan])]",26.015491008758545 +0,shor,True,False,optimal,opt,"[array([0, 1, 0, 0, 1, 0, 0, 1, 0], dtype=int8)]","{1: ([array([1, 0, 0, 1, 0, 0, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8), 1: array([0, 0, 0, 1, 1, 1, 0, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([4.09485464e-07, 1.02132961e-05, 4.07329420e-05, 9.93312580e-04, + 3.83998323e-03, 6.64824446e-02, 1.42473361e-01, 3.89372748e-04]), array([1.69857706e-06, 8.59564127e-06, 1.80378623e-05, 1.78214632e-04, + 6.14415817e-04, 1.11854678e-02, 2.78897202e-02, 1.44766417e-04]), array([4.91737630e-07, 1.22973686e-05, 4.92077919e-05, 1.23257137e-03, + 4.92996982e-03, 1.14116368e-01, 3.66881278e-01, 9.99631260e-01]), array([1.79188767e-06, 7.76527884e-06, 1.28248439e-05, 8.80076374e-05, + 4.21980264e-04, 7.39128556e-03, 1.25633583e-02, nan])]",26.015876054763794 +0,shor,True,False,global,opt,"[array([0, 1, 0, 0, 1, 0, 0, 1, 0], dtype=int8)]","{1: ([array([1, 0, 0, 1, 0, 0, 1, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 1, 1, 1, 0, 0, 0])})}","[{1: ([array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)], {0: array([0, 0, 0, 0, 0, 0, 0, 0, 0]), 1: array([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)})}]",[],{},[],"[array([4.40916233e-07, 1.09768350e-05, 4.36771532e-05, 1.04610565e-03, + 3.95827774e-03, 5.93788662e-02, 1.10256861e-01, 1.15165140e-04]), array([1.65278171e-06, 8.33739222e-06, 1.73456718e-05, 1.60812687e-04, + 5.38151667e-04, 7.89017026e-03, 1.79455177e-02, 7.89885639e-05]), array([5.28896638e-07, 1.32090112e-05, 5.27688243e-05, 1.30557206e-03, + 5.15188991e-03, 1.12540548e-01, 3.56775530e-01, 9.99676861e-01]), array([1.74214511e-06, 7.32062908e-06, 1.08997776e-05, nan, + 2.10990460e-04, 5.84093809e-03, 1.17423962e-02, nan])]",26.016201972961426 diff --git a/src/mqt/qecc/ft_stateprep/__init__.py b/src/mqt/qecc/ft_stateprep/__init__.py index 3e597881..e1df66bf 100644 --- a/src/mqt/qecc/ft_stateprep/__init__.py +++ b/src/mqt/qecc/ft_stateprep/__init__.py @@ -3,6 +3,7 @@ from __future__ import annotations from .simulation import LutDecoder, NoisyNDFTStatePrepSimulator +from .simulation_det import NoisyDFTStatePrepSimulator from .state_prep import ( StatePrepCircuit, depth_optimal_prep_circuit, @@ -14,9 +15,13 @@ heuristic_verification_stabilizers, naive_verification_circuit, ) +from .state_prep_det import DeterministicVerification, DeterministicVerificationHelper __all__ = [ + "DeterministicVerification", + "DeterministicVerificationHelper", "LutDecoder", + "NoisyDFTStatePrepSimulator", "NoisyNDFTStatePrepSimulator", "StatePrepCircuit", "depth_optimal_prep_circuit", diff --git a/src/mqt/qecc/ft_stateprep/simulation_det.py b/src/mqt/qecc/ft_stateprep/simulation_det.py new file mode 100644 index 00000000..d4a68250 --- /dev/null +++ b/src/mqt/qecc/ft_stateprep/simulation_det.py @@ -0,0 +1,419 @@ +"""Simulation of deterministic state preparation circuits using qsample (https://github.com/dpwinter/qsample).""" + +from __future__ import annotations + +from functools import partial +from typing import TYPE_CHECKING + +import numpy as np +import qsample as qs + +from ..codes import InvalidCSSCodeError +from .simulation import LutDecoder + +if TYPE_CHECKING: + import numpy.typing as npt + from qiskit import QuantumCircuit + from qsample.callbacks import Callback, CallbackList + + from ..codes import CSSCode + from .state_prep_det import DeterministicCorrection, DeterministicVerification + + +class UnsupportedCodeError(ValueError): + """Raised when the code is not supported by the simulator.""" + + +def _support_int(array: npt.NDArray[np.int8]) -> list[int]: + """Return the indices of the non-zero elements of the array.""" + return [int(i) for i in np.where(array)[0]] + + +def return_correction(outcome: int, corrections: dict[int, npt.NDArray[np.int8]], zero_state: bool) -> qs.Circuit: + """Return the det correction circuit for the given outcome of the D-verification.""" + correction = _support_int(corrections[outcome]) + if len(correction) == 0: + return qs.Circuit([], noisy=False) + correction_circuit = [] + if zero_state: + correction_circuit.append({"X": set(correction)}) + else: + correction_circuit.append({"Z": set(correction)}) + return qs.Circuit(correction_circuit, noisy=False) + + +def ndv_outcome_check(outcome: int, correction_index: int, num_measurements: int, cutoff: int, flag: bool) -> bool: + """Check if the outcome of the AND-verification is equal to the given outcome.""" + outcome_bitstring = format(outcome, f"0{num_measurements}b") + if not flag: + # return False if any of the flags triggered + if "1" in outcome_bitstring[cutoff:]: + return False + correction_outcome_bitstring = format(correction_index, f"0{cutoff}b") + return outcome_bitstring[:cutoff] == correction_outcome_bitstring + correction_outcome_bitstring = format(correction_index, f"0{num_measurements - cutoff}b") + return outcome_bitstring[cutoff:] == correction_outcome_bitstring + + +# perform decoding using LUT +def decode_failure( + measurements: int, code: CSSCode, decoder: LutDecoder, zero_state: bool, num_measurements: int +) -> bool: + """Check if the decoding failed.""" + # convert outcome to binary numpy int8 array + measurements_array = np.array([int(x) for x in f"{measurements:0{num_measurements}b}"], dtype=np.int8) + num_syndromes = num_measurements - code.n + syndrome = measurements_array[:num_syndromes] + state = measurements_array[num_syndromes:] + if zero_state: + estimate = decoder.decode_x(syndrome) + observables = code.Lz + else: + estimate = decoder.decode_z(syndrome) + observables = code.Lx + corrected = state + estimate + + # check if logical error + return bool(np.any(corrected @ observables.T % 2 != 0)) + + +class NoisyDFTStatePrepSimulator: + """Class to simulate the state preparation circuits using qsample (https://github.com/dpwinter/qsample).""" + + def __init__( + self, + state_prep_circuit: QuantumCircuit, + verifications: tuple[DeterministicVerification, DeterministicVerification], + code: CSSCode, + err_model: type[qs.ErrorModel] = qs.noise.E1_1, + zero_state: bool = True, + ) -> None: + """Initialize the simulator. + + Args: + state_prep_circuit: The state preparation circuit to simulate. + verifications: The deterministic verification circuits for the two layers. + code: The CSS code used for the state preparation circuit. + err_model: The error model to use for the simulation. + zero_state: If True the state preparation circuit prepares the |0> state, otherwise the |+> state. + """ + if code.Hx is None or code.Hz is None: + msg = "The code must have both X and Z checks." + raise InvalidCSSCodeError(msg) + + if code.distance >= 5: + msg = "Only distance <5 CSS codes are supported." + raise UnsupportedCodeError(msg) + + self.code = code + self.err_model = err_model + self.zero_state = zero_state + self._ancilla_index = code.n + + # create LUT + self.decoder = LutDecoder(code) + if zero_state: + self.decoder.generate_x_lut() + else: + self.decoder.generate_z_lut() + + # create protocol + self.protocol = qs.Protocol() + self._create_det_protocol(state_prep_circuit, verifications, code) + + def _create_det_protocol( + self, + non_det_state_prep_circuit: QuantumCircuit, + verifications: tuple[DeterministicVerification, DeterministicVerification], + code: CSSCode, + ) -> None: + """Create the protocol for the noisy deterministic state preparation circuit based on the given Verifications. + + Args: + non_det_state_prep_circuit: The state preparation circuit for the NonDet-verification. + verifications: The deterministic verifications for the two layers. + code: The CSS code used for the state preparation circuit. + """ + circ = qiskit_to_qsample(non_det_state_prep_circuit) + self.protocol.add_node(name="PREP", circuit=circ) + self.protocol.add_edge("START", "PREP", check="True") + + # create AND-verifications + self.protocol.add_node( + name="NDV_0", + circuit=self._create_stab_measurement_circuit( + verifications[0].stabs, + hook_corrections=verifications[0].hook_corrections, + z_stabs=self.zero_state, + noisy=True, + ), + ) + self.protocol.add_node( + name="NDV_1", + circuit=self._create_stab_measurement_circuit( + verifications[1].stabs, + hook_corrections=verifications[1].hook_corrections, + z_stabs=not self.zero_state, + noisy=True, + ), + ) + + self.protocol.add_edge("PREP", "NDV_0", check="True") + + # create decoding circuit + matrix = code.Hz if self.zero_state else code.Hx + decoding_circuit = self._create_stab_measurement_circuit(matrix, z_stabs=self.zero_state, noisy=False) + if not self.zero_state: + decoding_circuit.append({"H": set(range(self.code.n))}) + decoding_circuit.append({"measure": set(range(self.code.n))}) + + self.protocol.add_node(name="DEC", circuit=decoding_circuit) + + # add layers + self._append_verification(verifications[0], layer="0", end_node="NDV_1", z_stabs=self.zero_state) + self._append_verification(verifications[1], layer="1", end_node="DEC", z_stabs=not self.zero_state) + + # add decoding and failure check + self._append_decoding(code) + + def _append_verification( + self, verification: DeterministicVerification, layer: str, end_node: str, z_stabs: bool + ) -> None: + """Append a deterministic verification circuits to the protocol and connect them to the following node. + + Args: + verification: The deterministic verification circuit to append. + layer: The layer of the verification circuit ("0" or "1"). + end_node: The name of the node to connect the verification to. + z_stabs: If True the verification uses Z-stabilizers, otherwise X-stabilizers. + """ + assert layer in {"0", "1"}, "Layer must be either '0' or '1'." + # case of no errors detected + self.protocol.add_edge(f"NDV_{layer}", end_node, check=f"NDV_{layer}[-1] == 0 or NDV_{layer}[-1] == None") + + num_measurements = verification.num_ancillas_verification() + verification.num_ancillas_hooks() + num_non_det_measurements = verification.num_ancillas_verification() + + for outcome, (cor_stabs, rec) in verification.det_correction.items(): + # det corrections + self.protocol.add_node( + name=f"COR_{layer}_{outcome}", + circuit=self._create_stab_measurement_circuit(cor_stabs, z_stabs=z_stabs, noisy=True), + ) + self.protocol.check_functions[f"ndv_outcome_check_{layer}_{outcome}"] = partial( + ndv_outcome_check, + correction_index=outcome, + num_measurements=num_measurements, + cutoff=num_non_det_measurements, + flag=False, + ) + self.protocol.add_edge( + f"NDV_{layer}", f"COR_{layer}_{outcome}", check=f"ndv_outcome_check_{layer}_{outcome}(NDV_{layer}[-1])" + ) + # recovery + self.protocol.check_functions[f"return_correction_circuit_{layer}_{outcome}"] = partial( + return_correction, corrections=rec, zero_state=z_stabs + ) + self.protocol.add_edge( + f"COR_{layer}_{outcome}", + f"REC_{layer}", + check=f"return_correction_circuit_{layer}_{outcome}(COR_{layer}_{outcome}[-1])", + ) + self.protocol.add_edge(f"REC_{layer}", end_node, check="True") + + # hooks + hooks_idx = 0 + for hook_correction in verification.hook_corrections: + if not hook_correction: + continue + hook_stabs, rec = hook_correction[1] + outcome = int("0" * hooks_idx + "1" + "0" * (verification.num_ancillas_hooks() - hooks_idx - 1), 2) + self.protocol.add_node( + name=f"COR_{layer}_H_{hooks_idx}", + circuit=self._create_stab_measurement_circuit(hook_stabs, z_stabs=not z_stabs, noisy=True), + ) + self.protocol.check_functions[f"ndv_outcome_check_h_{layer}_{hooks_idx}"] = partial( + ndv_outcome_check, + correction_index=outcome, + num_measurements=num_measurements, + cutoff=num_non_det_measurements, + flag=True, + ) + self.protocol.add_edge( + f"NDV_{layer}", + f"COR_{layer}_H_{hooks_idx}", + check=f"ndv_outcome_check_h_{layer}_{hooks_idx}(NDV_{layer}[-1])", + ) + + # recovery + self.protocol.check_functions[f"return_correction_circuit_{layer}_hook_{hooks_idx}"] = partial( + return_correction, corrections=rec, zero_state=not z_stabs + ) + self.protocol.add_edge( + f"COR_{layer}_H_{hooks_idx}", + f"REC_{layer}", + check=f"return_correction_circuit_{layer}_hook_{hooks_idx}(COR_{layer}_H_{hooks_idx}[-1])", + ) + self.protocol.add_edge(f"REC_{layer}", end_node, check="True") + hooks_idx += 1 + + def _append_decoding(self, code: CSSCode) -> None: + """Append the decoding circuit to the end of the protocol. + + This consists of measuring the stabilizers of the code and using the LUT decoder to correct the errors. + If the correction is not successful the protocol terminates with FAIL. + + Args: + code: The CSS code used for the state preparation circuit. + """ + assert code.Hx is not None + assert code.Hz is not None + + num_measurements = self.code.n + num_measurements += len(code.Hz) if self.zero_state else len(code.Hx) + + self.protocol.check_functions["decode_failure"] = partial( + decode_failure, + code=code, + decoder=self.decoder, + zero_state=self.zero_state, + num_measurements=num_measurements, + ) + self.protocol.add_edge("DEC", "FAIL", check="decode_failure(DEC[-1])") + + def dss_logical_error_rates( + self, + err_params: dict[str, list[float]], + p_max: dict[str, float], + dss_l: int = 3, + shots: int = 1000, + callbacks: Callback | CallbackList | None = None, + ) -> list[npt.NDArray[np.float64]]: + """Calculate the logical error rate of the deterministic state preparation circuit using subset sampling. + + For more detail on the parameters see the qsample documentation (https://dpwinter.github.io/qsample/). + + Args: + err_params: The error parameters (physical errors) for the error model. + p_max: The physical error rate to sample at for the subset sampling. + dss_l: The sampling depth for the subset sampling. + shots: The number of shots to use for the simulation. + callbacks: A list of callback functions to call after each layer from qsample. + """ + if callbacks is None: + callbacks = [] + sampler = qs.SubsetSampler( + protocol=self.protocol, + simulator=qs.StabilizerSimulator, + p_max=p_max, + err_model=self.err_model, + err_params=err_params, + L=dss_l, + ) + sampler.run(n_shots=shots, callbacks=callbacks) + return [s / self.code.k for s in sampler.stats()] + + def mc_logical_error_rates( + self, err_params: dict[str, list[float]], shots: int = 10000, callbacks: Callback | CallbackList | None = None + ) -> list[npt.NDArray[np.float64]]: + """Calculate the logical error rate of the deterministic state preparation circuit using direct Monte Carlo sampling. + + Args: + err_params: The error parameters (physical errors) for the error model. + shots: The number of shots to use for the simulation. + callbacks: A list of callback functions to call after each layer from qsample. + """ + if callbacks is None: + callbacks = [] + sampler = qs.DirectSampler( + protocol=self.protocol, simulator=qs.StabilizerSimulator, err_model=self.err_model, err_params=err_params + ) + sampler.run(n_shots=shots, callbacks=callbacks) + return [s / self.code.k for s in sampler.stats()] + + def _create_stab_measurement_circuit( + self, + verification_stabilizers: list[npt.NDArray[np.int8]], + z_stabs: bool, + hook_corrections: list[DeterministicCorrection] | None = None, + noisy: bool = True, + ) -> qs.Circuit: + """Create the deterministic verification circuit for the given verification stabilizers. + + Args: + verification_stabilizers: The stabilizers to measure. + z_stabs: If True the stabilizers are Z-stabilizers, otherwise X-stabilizers. + hook_corrections: Whether to apply hook corrections for the stabilizers. + noisy: If True the circuit is noisy, otherwise it is noiseless (used for decoding). + """ + num_stabs = len(verification_stabilizers) + if num_stabs == 0: + return qs.Circuit([{"I": {0}}], noisy=False) + if hook_corrections is None: + hook_corrections = [{}] * num_stabs + + circuit: list[dict[str, set[int]] | dict[str, set[tuple[int, int]]]] = [] + # init new ancillas + num_ancillas = len(verification_stabilizers) + sum(1 for hook in hook_corrections if hook) + circuit.append({"init": set(range(self._ancilla_index, self._ancilla_index + num_ancillas))}) + + flag_ancilla_index = self._ancilla_index + len(verification_stabilizers) + for stabilizer, flagged in zip(verification_stabilizers, [bool(hook) for hook in hook_corrections]): + stabilizer_sup = _support_int(stabilizer) + if not z_stabs: + circuit.append({"H": {self._ancilla_index}}) + for qubit_idx, qubit in enumerate(stabilizer_sup): + # add flag + if flagged and qubit_idx == 1: + if z_stabs: + circuit.extend(( + {"H": {flag_ancilla_index}}, + {"CNOT": {(flag_ancilla_index, self._ancilla_index)}}, + )) + else: + circuit.append({"CNOT": {(self._ancilla_index, flag_ancilla_index)}}) + if flagged and qubit_idx == len(stabilizer_sup) - 1: + if z_stabs: + circuit.extend(( + {"CNOT": {(flag_ancilla_index, self._ancilla_index)}}, + {"H": {flag_ancilla_index}}, + )) + else: + circuit.append({"CNOT": {(self._ancilla_index, flag_ancilla_index)}}) + flag_ancilla_index += 1 + + # add stab cnots + if z_stabs: + circuit.append({"CNOT": {(qubit, self._ancilla_index)}}) + else: + circuit.append({"CNOT": {(self._ancilla_index, qubit)}}) + if not z_stabs: + circuit.append({"H": {self._ancilla_index}}) + # circuit.append({"measure": {self._ancilla_index}}) + self._ancilla_index += 1 + circuit.append({"measure": set(range(self._ancilla_index - num_stabs, flag_ancilla_index))}) + self._ancilla_index = flag_ancilla_index + if len(circuit) == 0: + # qsample does not like empty circuits + return qs.Circuit([{"I": {0}}], noisy=False) + return qs.Circuit(circuit, noisy=noisy) + + +def qiskit_to_qsample(qiskit_circuit: QuantumCircuit) -> qs.Circuit: + """Convert a Qiskit circuit to a qsample circuit. Only supports H, X, Y, Z, CX, and MEASURE gates.""" + custom_circuit = [{"init": set(range(qiskit_circuit.num_qubits))}] + for circ_instruction in qiskit_circuit.data: + qargs = circ_instruction.qubits + instruction = circ_instruction.operation + gate_name = instruction.name.upper() + if gate_name == "CX": + gate_name = "CNOT" + # collect measurements to combine them at the end + if gate_name == "MEASURE": + gate_name = "measure" + if len(qargs) == 1: + qubits = qiskit_circuit.qubits.index(qargs[0]) + else: + qubits = tuple(qiskit_circuit.qubits.index(q) for q in qargs) + custom_circuit.append({gate_name: {qubits}}) + return qs.Circuit(custom_circuit, noisy=True) diff --git a/src/mqt/qecc/ft_stateprep/state_prep.py b/src/mqt/qecc/ft_stateprep/state_prep.py index 437cc162..64e4717c 100644 --- a/src/mqt/qecc/ft_stateprep/state_prep.py +++ b/src/mqt/qecc/ft_stateprep/state_prep.py @@ -4,7 +4,7 @@ import logging from collections import defaultdict -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, TypeVar, cast import multiprocess import numpy as np @@ -18,7 +18,7 @@ logger = logging.getLogger(__name__) if TYPE_CHECKING: # pragma: no cover - from collections.abc import Callable + from collections.abc import Callable, Iterable import numpy.typing as npt from qiskit import AncillaQubit, ClBit, DAGNode, Qubit @@ -302,7 +302,7 @@ def _generate_circ_with_bounded_depth( + list(np.delete(additions[d - 1, col, :], [col])) ) ), - _symbolic_vector_eq(columns[d, :, col], columns[d - 1, :, col]), + symbolic_vector_eq(columns[d, :, col], columns[d - 1, :, col]), ) ) @@ -362,7 +362,7 @@ def _generate_circ_with_bounded_gates( # if column is not involved in any addition at certain depth, it is the same as the previous column for d in range(1, max_cnots + 1): for col in range(n): - s.add(z3.Implies(targets[d - 1] != col, _symbolic_vector_eq(columns[d, :, col], columns[d - 1, :, col]))) + s.add(z3.Implies(targets[d - 1] != col, symbolic_vector_eq(columns[d, :, col], columns[d - 1, :, col]))) # assert that final check matrix has n-checks.shape[0] zero columns s.add(_final_matrix_constraint(columns)) @@ -414,8 +414,6 @@ def fun(param: int) -> QuantumCircuit | None: max_timeout, ) - if res is None: - return None circ, curr_param = res if circ is None: return None @@ -426,11 +424,12 @@ def fun(param: int) -> QuantumCircuit | None: logging.info("Trying to minimize param") while True: logging.info(f"Trying param {curr_param - 1}") - opt_res = _run_with_timeout(fun, curr_param - 1, timeout=max_timeout) - if opt_res is None or (isinstance(opt_res, str) and opt_res == "timeout"): + opt_res: QuantumCircuit | str | None = run_with_timeout(fun, curr_param - 1, timeout=max_timeout) + if opt_res and not (isinstance(opt_res, str) and opt_res == "timeout"): + circ = opt_res + curr_param -= 1 + else: break - circ = opt_res - curr_param -= 1 logging.info(f"Optimal param: {curr_param}") return StatePrepCircuit(circ, code, zero_state) @@ -507,7 +506,10 @@ def _build_circuit_from_list_and_checks( return circ -def _run_with_timeout(func: Callable[[Any], Any], *args: Any, timeout: int = 10) -> Any | str | None: # noqa: ANN401 +S = TypeVar("S") + + +def run_with_timeout(func: Callable[[Any], S | None], *args: Any, timeout: int = 10) -> S | str | None: # noqa: ANN401 """Run a function with a timeout. If the function does not complete within the timeout, return None. @@ -525,18 +527,23 @@ def _run_with_timeout(func: Callable[[Any], Any], *args: Any, timeout: int = 10) if p.is_alive(): p.terminate() return "timeout" - return return_list[0] + if return_list[0] is None: + return None + return cast(S, return_list[0]) + + +T = TypeVar("T") def iterative_search_with_timeout( - fun: Callable[[int], QuantumCircuit], + fun: Callable[[int], T], min_param: int, max_param: int, min_timeout: int, max_timeout: int, param_factor: float = 2, timeout_factor: float = 2, -) -> None | tuple[None | QuantumCircuit, int]: +) -> tuple[T | None, int]: """Geometrically increases the parameter and timeout until a result is found or the maximum timeout is reached. Args: @@ -553,9 +560,9 @@ def iterative_search_with_timeout( while curr_timeout <= max_timeout: while curr_param <= max_param: logging.info(f"Running iterative search with param={curr_param} and timeout={curr_timeout}") - res = _run_with_timeout(fun, curr_param, timeout=curr_timeout) + res = run_with_timeout(fun, curr_param, timeout=curr_timeout) if res is not None and (not isinstance(res, str) or res != "timeout"): - return res, curr_param + return cast(T, res), curr_param if curr_param == max_param: break @@ -588,10 +595,49 @@ def gate_optimal_verification_stabilizers( additional_faults: Faults to verify in addition to the faults propagating in the state preparation circuit. Returns: - A list of stabilizers to verify the state preparation circuit. + A list of stabilizers for each number of errors to verify the state preparation circuit. + """ + return [ + stabs[0] if stabs != [] else [] + for stabs in all_gate_optimal_verification_stabilizers( + sp_circ, + x_errors, + min_timeout, + max_timeout, + max_ancillas, + additional_faults, + return_all_solutions=False, + ) + ] + + +def all_gate_optimal_verification_stabilizers( + sp_circ: StatePrepCircuit, + x_errors: bool = True, + min_timeout: int = 1, + max_timeout: int = 3600, + max_ancillas: int | None = None, + additional_faults: npt.NDArray[np.int8] | None = None, + return_all_solutions: bool = False, +) -> list[list[list[npt.NDArray[np.int8]]]]: + """Return all equivalent verification stabilizers for the state preparation circuit. + + The method uses an iterative search to find the optimal set of stabilizers by repeatedly computing the optimal circuit for each number of ancillas and cnots. This is repeated for each number of independent correctable errors in the state preparation circuit. Thus the verification circuit is constructed of multiple "layers" of stabilizers, each layer corresponding to a fault set it verifies. + + Args: + sp_circ: The state preparation circuit to verify. + x_errors: If True, verify the X errors. If False, verify the Z errors. + min_timeout: The minimum time to allow each search to run for. + max_timeout: The maximum time to allow each search to run for. + max_ancillas: The maximum number of ancillas to allow in each layer verification circuit. + additional_faults: Faults to verify in addition to the faults propagating in the state preparation circuit. + return_all_solutions: If False only the first solution for each number of errors is returned. If True all solutions are returned. + + Returns: + A list of all equivalent stabilizers for each number of errors to verify the state preparation circuit. """ max_errors = sp_circ.max_errors - layers: list[list[npt.NDArray[np.int8]]] = [[] for _ in range(max_errors)] + layers: list[list[list[npt.NDArray[np.int8]]]] = [[] for _ in range(max_errors)] if max_ancillas is None: max_ancillas = sp_circ.max_z_measurements if x_errors else sp_circ.max_x_measurements @@ -636,12 +682,8 @@ def fun(num_cnots: int) -> list[npt.NDArray[np.int8]] | None: max_timeout, ) - if res is None: - logging.info(f"No verification stabilizers found for {num_errors} errors") - layers[num_errors - 1] = [] - continue measurements, num_cnots = res - if measurements is None or (isinstance(measurements, str) and measurements == "timeout"): + if measurements is None: logging.info(f"No verification stabilizers found for {num_errors} errors") return [] # No solution found @@ -658,15 +700,16 @@ def search_cnots(num_cnots: int) -> list[npt.NDArray[np.int8]] | None: while num_cnots - 1 > 0: logging.info(f"Trying {num_cnots - 1} CNOTs") - cnot_opt = _run_with_timeout( + cnot_opt = run_with_timeout( search_cnots, num_cnots - 1, timeout=max_timeout, ) - if cnot_opt is None or (isinstance(cnot_opt, str) and cnot_opt == "timeout"): + if cnot_opt and not isinstance(cnot_opt, str): + num_cnots -= 1 + measurements = cnot_opt + else: break - num_cnots -= 1 - measurements = cnot_opt logging.info(f"Minimal number of CNOTs for {num_errors} errors is: {num_cnots}") # If the number of CNOTs is minimal, we can reduce the number of ancillas @@ -677,17 +720,26 @@ def search_cnots(num_cnots: int) -> list[npt.NDArray[np.int8]] | None: def search_anc(num_anc: int) -> list[npt.NDArray[np.int8]] | None: return verification_stabilizers(sp_circ, faults, num_anc, num_cnots, x_errors=x_errors) # noqa: B023 - anc_opt = _run_with_timeout( + anc_opt = run_with_timeout( search_anc, num_anc - 1, timeout=max_timeout, ) - if anc_opt is None or (isinstance(anc_opt, str) and anc_opt == "timeout"): + if anc_opt and not isinstance(anc_opt, str): + num_anc -= 1 + measurements = anc_opt + else: break - num_anc -= 1 - measurements = anc_opt logging.info(f"Minimal number of ancillas for {num_errors} errors is: {num_anc}") - layers[num_errors - 1] = measurements + if not return_all_solutions: + layers[num_errors - 1] = [measurements] + else: + all_stabs = all_verification_stabilizers( + sp_circ, faults, num_anc, num_cnots, x_errors=x_errors, return_all_solutions=True + ) + if all_stabs: + layers[num_errors - 1] = all_stabs + logger.info(f"Found {len(layers[num_errors - 1])} equivalent solutions for {num_errors} errors") return layers @@ -706,7 +758,7 @@ def _verification_circuit( if full_fault_tolerance: if not flag_first_layer: - additional_errors = _hook_errors(measurements_1) + additional_errors = get_hook_errors(measurements_1) layers_2 = verification_stabs_fun(sp_circ, not sp_circ.zero_state, additional_errors) else: layers_2 = verification_stabs_fun(sp_circ, not sp_circ.zero_state, None) @@ -935,7 +987,7 @@ def cost(cover: set[frozenset[int]]) -> tuple[int, int]: logging.info("Finding coset leaders.") measurements = [] for c in cover: - leaders = [_coset_leader(m, non_candidate_checks) for m in mapping[c]] + leaders = [coset_leader(m, non_candidate_checks) for m in mapping[c]] leaders.sort(key=np.sum) measurements.append(leaders[0]) else: @@ -1006,9 +1058,10 @@ def _measure_ft_stabs( return measured_circ -def _vars_to_stab( +def vars_to_stab( measurement: list[z3.BoolRef | bool], generators: npt.NDArray[np.int8] ) -> npt.NDArray[z3.BoolRef | bool]: + """Compute the stabilizer measured giving the generators and the measurement variables.""" measurement_stab = _symbolic_scalar_mult(generators[0], measurement[0]) for i, scalar in enumerate(measurement[1:]): measurement_stab = _symbolic_vector_add(measurement_stab, _symbolic_scalar_mult(generators[i + 1], scalar)) @@ -1022,15 +1075,41 @@ def verification_stabilizers( num_cnots: int, x_errors: bool = True, ) -> list[npt.NDArray[np.int8]] | None: - """Return verification stabilizers for num_errors independent errors in the state preparation circuit using z3. + """Return a verification stabilizers for num_errors independent errors in the state preparation circuit using z3. Args: sp_circ: The state preparation circuit. fault_set: The set of errors to verify. num_anc: The maximum number of ancilla qubits to use. - num_cnots: The maximumg number of CNOT gates to use. + num_cnots: The maximum number of CNOT gates to use. x_errors: If True, the errors are X errors. Otherwise, the errors are Z errors. """ + stabs_list = all_verification_stabilizers( + sp_circ, fault_set, num_anc, num_cnots, x_errors, return_all_solutions=False + ) + if stabs_list: + return stabs_list[0] + return None + + +def all_verification_stabilizers( + sp_circ: StatePrepCircuit, + fault_set: npt.NDArray[np.int8], + num_anc: int, + num_cnots: int, + x_errors: bool = True, + return_all_solutions: bool = False, +) -> list[list[npt.NDArray[np.int8]]] | None: + """Return a list of verification stabilizers for num_errors independent errors in the state preparation circuit using z3. + + Args: + sp_circ: The state preparation circuit. + fault_set: The set of errors to verify. + num_anc: The maximum number of ancilla qubits to use. + num_cnots: The maximum number of CNOT gates to use. + x_errors: If True, the errors are X errors. Otherwise, the errors are Z errors. + return_all_solutions: If True, return all solutions. Otherwise, return the first solution found. + """ # Measurements are written as sums of generators # The variables indicate which generators are non-zero in the sum gens = sp_circ.z_checks if x_errors else sp_circ.x_checks @@ -1039,12 +1118,12 @@ def verification_stabilizers( measurement_vars = [[z3.Bool(f"m_{anc}_{i}") for i in range(n_gens)] for anc in range(num_anc)] solver = z3.Solver() - measurement_stabs = [_vars_to_stab(vars_, gens) for vars_ in measurement_vars] + measurement_stabs = [vars_to_stab(vars_, gens) for vars_ in measurement_vars] # assert that each error is detected solver.add( z3.And([ - z3.PbGe([(_odd_overlap(measurement, error), 1) for measurement in measurement_stabs], 1) + z3.PbGe([(odd_overlap(measurement, error), 1) for measurement in measurement_stabs], 1) for error in fault_set ]) ) @@ -1056,7 +1135,8 @@ def verification_stabilizers( ) ) - if solver.check() == z3.sat: + solutions = [] + while solver.check() == z3.sat: model = solver.model() # Extract stabilizer measurements from model actual_measurements = [] @@ -1066,21 +1146,27 @@ def verification_stabilizers( if model[m[g]]: v += gens[g] actual_measurements.append(v % 2) - - return actual_measurements + if not return_all_solutions: + return [actual_measurements] + solutions.append(actual_measurements) + # add constraint to avoid same solution again + solver.add(z3.Or([vars_[i] != model[vars_[i]] for vars_ in measurement_vars for i in range(n_gens)])) + if solutions: + return solutions return None -def _coset_leader(error: npt.NDArray[np.int8], generators: npt.NDArray[np.int8]) -> npt.NDArray[np.int8]: +def coset_leader(error: npt.NDArray[np.int8], generators: npt.NDArray[np.int8]) -> npt.NDArray[np.int8]: + """Compute the coset leader of an error given a set of generators.""" if len(generators) == 0: return error s = z3.Optimize() leader = [z3.Bool(f"e_{i}") for i in range(len(error))] coeff = [z3.Bool(f"c_{i}") for i in range(len(generators))] - g = _vars_to_stab(coeff, generators) + g = vars_to_stab(coeff, generators) - s.add(_symbolic_vector_eq(np.array(leader), _symbolic_vector_add(error.astype(bool), g))) + s.add(symbolic_vector_eq(np.array(leader), _symbolic_vector_add(error.astype(bool), g))) s.minimize(z3.Sum(leader)) s.check() # always SAT @@ -1122,26 +1208,35 @@ def _symbolic_vector_add( return np.array(v_new) -def _odd_overlap(v_sym: npt.NDArray[z3.BoolRef | bool], v_con: npt.NDArray[np.int8]) -> z3.BoolRef: +def odd_overlap(v_sym: npt.NDArray[z3.BoolRef | bool], v_con: npt.NDArray[np.int8]) -> z3.BoolRef: """Return True if the overlap of symbolic vector with constant vector is odd.""" + if np.array_equal(v_con, np.zeros(len(v_con), dtype=np.int8)): + return z3.BoolVal(False) return z3.PbEq([(v_sym[i], 1) for i, c in enumerate(v_con) if c == 1], 1) -def _symbolic_vector_eq(v1: npt.NDArray[z3.BoolRef | bool], v2: npt.NDArray[z3.BoolRef | bool]) -> z3.BoolRef: +def symbolic_vector_eq(v1: npt.NDArray[z3.BoolRef | bool], v2: npt.NDArray[z3.BoolRef | bool]) -> z3.BoolRef: """Return assertion that two symbolic vectors should be equal.""" constraints = [False for _ in v1] + + def convert_bools(vector: Iterable[z3.BoolRef | bool | np.bool_]) -> list[z3.BoolRef | bool]: + return [ + True if z3.is_true(v) else False if z3.is_false(v) else v if isinstance(v, z3.BoolRef) else bool(v) + for v in vector + ] + + v1 = convert_bools(v1) + v2 = convert_bools(v2) + for i in range(len(v1)): # If one of the elements is a bool, we can simplify the expression - v1_i_is_bool = isinstance(v1[i], (bool, np.bool_)) - v2_i_is_bool = isinstance(v2[i], (bool, np.bool_)) - if v1_i_is_bool: + if isinstance(v1[i], bool): v1[i] = bool(v1[i]) if v1[i]: constraints[i] = v2[i] else: - constraints[i] = z3.Not(v2[i]) if not v2_i_is_bool else not v2[i] - - elif v2_i_is_bool: + constraints[i] = z3.Not(v2[i]) if not isinstance(v2[i], bool) else not v2[i] + elif isinstance(v2[i], bool): v2[i] = bool(v2[i]) if v2[i]: constraints[i] = v1[i] @@ -1170,8 +1265,8 @@ def _column_addition_constraint( add_col1_to_col2 = z3.Implies( col_add_vars[d - 1, col_1, col_2], z3.And( - _symbolic_vector_eq(columns[d, :, col_2], col_sum), - _symbolic_vector_eq(columns[d, :, col_1], columns[d - 1, :, col_1]), + symbolic_vector_eq(columns[d, :, col_2], col_sum), + symbolic_vector_eq(columns[d, :, col_1], columns[d - 1, :, col_1]), ), ) @@ -1179,8 +1274,8 @@ def _column_addition_constraint( add_col2_to_col1 = z3.Implies( col_add_vars[d - 1, col_2, col_1], z3.And( - _symbolic_vector_eq(columns[d, :, col_1], col_sum), - _symbolic_vector_eq(columns[d, :, col_2], columns[d - 1, :, col_2]), + symbolic_vector_eq(columns[d, :, col_1], col_sum), + symbolic_vector_eq(columns[d, :, col_2], columns[d - 1, :, col_2]), ), ) @@ -1227,7 +1322,7 @@ def _remove_trivial_faults( logging.info("Removing trivial faults.") max_w = 1 for i, fault in enumerate(faults): - faults[i] = _coset_leader(fault, stabs) + faults[i] = coset_leader(fault, stabs) faults = faults[np.where(np.sum(faults, axis=1) > max_w * num_errors)[0]] # unique faults @@ -1621,7 +1716,7 @@ def measure_flagged_8( qc.measure(ancilla, measurement_bit) -def _hook_errors(measurements: list[npt.NDArray[np.int8]]) -> npt.NDArray[np.int8]: +def get_hook_errors(measurements: list[npt.NDArray[np.int8]]) -> npt.NDArray[np.int8]: """Assuming CNOTs are executed in ascending order of qubit index, this function gives all the hook errors of the given stabilizer measurements.""" errors = [] for stab in measurements: diff --git a/src/mqt/qecc/ft_stateprep/state_prep_det.py b/src/mqt/qecc/ft_stateprep/state_prep_det.py new file mode 100644 index 00000000..76b55ade --- /dev/null +++ b/src/mqt/qecc/ft_stateprep/state_prep_det.py @@ -0,0 +1,811 @@ +"""Synthesizing deterministic state preparation circuits for d<5 CSS codes.""" + +from __future__ import annotations + +import logging +from itertools import product +from typing import TYPE_CHECKING + +import numpy as np +import z3 +from ldpc import mod2 + +from .state_prep import ( + StatePrepCircuit, + all_gate_optimal_verification_stabilizers, + coset_leader, + get_hook_errors, + heuristic_verification_stabilizers, + iterative_search_with_timeout, + odd_overlap, + run_with_timeout, + symbolic_vector_eq, + vars_to_stab, +) + +logger = logging.getLogger(__name__) + +if TYPE_CHECKING: + from collections.abc import Callable + + import numpy.typing as npt + + from ..codes import CSSCode + + Recovery = tuple[list[npt.NDArray[np.int8]], dict[int, npt.NDArray[np.int8]]] + Recoveries = dict[int, Recovery] + DeterministicCorrection = dict[int, tuple[list[npt.NDArray[np.int8]], Recoveries]] + Verification = list[npt.NDArray[np.int8]] + + +class DeterministicVerification: + """Class to store deterministic verification stabilizers and corrections.""" + + def __init__( + self, + and_verification_stabs: Verification, + det_correction: DeterministicCorrection, + hook_corrections: list[DeterministicCorrection] | None = None, + ) -> None: + """Initialize a deterministic verification object. + + Args: + and_verification_stabs: The non-deterministic verification stabilizers to be measured. + det_correction: The deterministic correction for the non-deterministic verification stabilizers. + hook_corrections: the hook corrections for the non-deterministic verification stabilizers. + """ + self.stabs = and_verification_stabs + self.det_correction = det_correction + self.hook_corrections: list[DeterministicCorrection] = [{}] * len(and_verification_stabs) + if hook_corrections: + assert len(hook_corrections) == len(and_verification_stabs) + self.hook_corrections = hook_corrections + + def copy(self) -> DeterministicVerification: + """Return a copy of the deterministic verification object.""" + return DeterministicVerification(self.stabs, self.det_correction, self.hook_corrections) + + @staticmethod + def _stat_cnots_correction(fun: Callable[..., int], correction: DeterministicCorrection) -> int: + """Return stats on the CNOTs in the deterministic correction.""" + return fun([np.sum([np.sum(m) for m in v[0]]) for v in correction.values()]) + + @staticmethod + def _stat_anc_correction(fun: Callable[..., int], correction: DeterministicCorrection) -> int: + """Return stats on the ancillas in the deterministic correction.""" + return fun([len(v[0]) for v in correction.values()]) + + @staticmethod + def _num_branches_correction(correction: DeterministicCorrection) -> int: + """Return the number of branches in the deterministic correction.""" + return sum(len(v[1]) for v in correction.values()) + + # Statistics methods + def num_ancillas_verification(self) -> int: + """Return the number of ancillas needed for the verification.""" + return len(self.stabs) + + def num_cnots_verification(self) -> int: + """Return the number of CNOTs needed for the verification.""" + return np.sum([np.sum(m) for m in self.stabs]) + + def num_ancillas_correction(self) -> int: + """Return the number of ancillas needed for the correction.""" + return self._stat_anc_correction(sum, self.det_correction) + + def stat_ancillas_correction(self, fun: Callable[..., int]) -> int: + """Return some statistics on the ancillas in the deterministic correction using the function fun. + + Args: + fun: The function to use for the statistics, e.g. sum, max, min, etc. + """ + return self._stat_anc_correction(fun, self.det_correction) + + def num_cnots_correction(self) -> int: + """Return the number of CNOTs needed for the correction.""" + return self._stat_cnots_correction(sum, self.det_correction) + + def stat_cnots_correction(self, fun: Callable[..., int]) -> int: + """Return some statistics on the CNOTs in the deterministic correction using the function fun. + + Args: + fun: The function to use for the statistics, e.g. sum, max, min, etc. + """ + return self._stat_cnots_correction(fun, self.det_correction) + + def num_ancillas_hooks(self) -> int: + """Return the number of ancillas needed for the hook corrections.""" + return len([v for v in self.hook_corrections if v]) + + def num_cnots_hooks(self) -> int: + """Return the number of CNOTs needed for the hook corrections (two per ancilla).""" + return self.num_ancillas_hooks() * 2 + + def num_ancillas_hook_corrections(self) -> int: + """Return the number of ancillas needed for the hook corrections of the verification stabilizers.""" + return sum(self._stat_anc_correction(sum, c) if c != {} else 0 for c in self.hook_corrections) + + def stat_ancillas_hook_corrections(self, fun: Callable[..., int]) -> int: + """Return some statistics on the ancillas in the hook corrections of the verification stabilizers using the function fun. + + Args: + fun: The function to use for the statistics, e.g. sum, max, min, etc. + """ + return fun([self._stat_anc_correction(fun, c) if c != {} else 0 for c in self.hook_corrections]) + + def num_cnots_hook_corrections(self) -> int: + """Return the number of CNOTs needed for the hook corrections of the verification stabilizers.""" + return sum(self._stat_cnots_correction(sum, c) if c != {} else 0 for c in self.hook_corrections) + + def stat_cnots_hook_corrections(self, fun: Callable[..., int]) -> int: + """Return some statistics on the CNOTs in the hook corrections of the verification stabilizers using the function fun. + + Args: + fun: The function to use for the statistics, e.g. sum, max, min, etc. + """ + return fun([self._stat_cnots_correction(fun, c) if c != {} else 0 for c in self.hook_corrections]) + + def num_ancillas_total(self) -> int: + """Return the total number of ancillas needed for the verification and correction.""" + return ( + self.num_ancillas_verification() + + self.num_ancillas_correction() + + self.num_ancillas_hooks() + + self.num_ancillas_hook_corrections() + ) + + def num_cnots_total(self) -> int: + """Return the total number of CNOTs needed for the verification and correction.""" + return ( + self.num_cnots_verification() + + self.num_cnots_correction() + + self.num_cnots_hooks() + + self.num_cnots_hook_corrections() + ) + + def num_branches_det_correction(self) -> int: + """Return the number of branches in the deterministic correction.""" + return self._num_branches_correction(self.det_correction) + + def num_branches_hook_corrections(self) -> int: + """Return the number of branches in the hook corrections of the verification stabilizers.""" + return sum(self._num_branches_correction(c) for c in self.hook_corrections) + + def num_branches_total(self) -> int: + """Return the total number of branches in the verification and correction.""" + return self.num_branches_det_correction() + self.num_branches_hook_corrections() + + +class DeterministicVerificationHelper: + """Class to compute the deterministic verification stabilizers and corrections for a given state preparation circuit.""" + + def __init__(self, state_prep: StatePrepCircuit, use_optimal_verification: bool = True) -> None: + """Initialize the deterministic verification helper with a given state preparation circuit. + + Args: + state_prep: The state preparation circuit to compute the deterministic verification for (must be a CSS code and d<5). + use_optimal_verification: If True, the optimal verification stabilizers are computed, otherwise heuristic verification stabilizers are used. + """ + self.state_prep = state_prep + self.code = state_prep.code + assert self.code.distance < 5, "Only d=3 and d=4 codes are supported." + self.num_qubits = self.code.n + self.layer_x_errors = [self.state_prep.zero_state, not self.state_prep.zero_state] + self.use_optimal_verification = use_optimal_verification + # Variable to store the deterministic verification stabilizers and corrections for the two layers + self._layers: list[list[DeterministicVerification]] = [[], []] + # Variable to store the deterministic verification stabilizers and corrections for the hook propagation solution + self._hook_propagation_solutions: list[tuple[DeterministicVerification, DeterministicVerification]] = [] + + def _compute_non_det_stabs( + self, + min_timeout: int = 1, + max_timeout: int = 3600, + max_ancillas: int | None = None, + compute_all_solutions: bool = False, + ) -> None: + """Computes the non-deterministic verification stabilizers for both layers (X and Z). + + Args: + min_timeout: The minimum time in seconds to run the verification stabilizers. + max_timeout: The maximum time in seconds to run the verification stabilizers. + max_ancillas: The maximum number of ancillas to use in the verification stabilizers. + compute_all_solutions: If True, all equivalent verification stabilizers are computed and stored. + """ + for idx, x_errors in enumerate(self.layer_x_errors): + logger.info(f"Computing non-deterministic verification stabilizers for layer {idx + 1} / 2.") + # if self.use_optimal_verification: + stabs_all = all_gate_optimal_verification_stabilizers( + self.state_prep, + x_errors=x_errors, + min_timeout=min_timeout, + max_timeout=max_timeout, + max_ancillas=max_ancillas, + return_all_solutions=compute_all_solutions, + )[0] + for stabs in stabs_all: + verify = DeterministicVerification(stabs, {}) + self._layers[idx].append(verify) + + def _compute_det_corrections( + self, min_timeout: int = 1, max_timeout: int = 3600, max_ancillas: int | None = None, layer_idx: int = 0 + ) -> None: + """Returns the deterministic verification stabilizers for the first layer of non-deterministic verification stabilizers.""" + x_errors = self.layer_x_errors[layer_idx] + logger.info(f"Computing deterministic verification for layer {layer_idx}.") + for verify_idx, verify in enumerate(self._layers[layer_idx]): + logger.info( + f"Computing deterministic verification for non-det verification {verify_idx + 1} / {len(self._layers[layer_idx])}." + ) + self._layers[layer_idx][verify_idx].det_correction = deterministic_correction( + self.state_prep, + verify.stabs, + min_timeout=min_timeout, + max_timeout=max_timeout, + max_ancillas=max_ancillas, + zero_state=x_errors, + ) + + @staticmethod + def _trivial_hook_errors(hook_errors: list[npt.NDArray[np.int8]], code: CSSCode, x_error: bool) -> bool: + """Checks if the hook errors are trivial (stabilizers) by checking if the rank of the code stabilizers is the same. + + Args: + hook_errors: The hook errors to check. + code: The CSS code to check the rank of the stabilizers. + x_error: If True, the Z stabilizers are checked, otherwise the X stabilizers are checked. + + Returns: + bool: True if all hook errors are trivial, False otherwise. + """ + errors_trivial = [] + code_stabs = np.vstack((code.Hz, code.Lz)) if x_error else np.vstack((code.Hx, code.Lx)) + rank = mod2.rank(code_stabs) + for error in hook_errors: + single_qubit_deviation = [(error + np.eye(code.n, dtype=np.int8)[i]) % 2 for i in range(code.n)] + stabs_plus_single_qubit = [np.vstack((code_stabs, single_qubit_deviation[i])) for i in range(code.n)] + trivial = any(mod2.rank(m) == rank for m in stabs_plus_single_qubit) + errors_trivial.append(trivial) + return bool(all(errors_trivial)) + + def _compute_hook_corrections( + self, min_timeout: int = 1, max_timeout: int = 3600, max_ancillas: int | None = None + ) -> None: + """Computes the additional stabilizers to measure with corresponding corrections for the hook errors of each stabilizer measurement in layer 2.""" + for layer_idx, x_error in enumerate(self.layer_x_errors): + logger.info(f"Computing deterministic verification for hook errors of layer {layer_idx + 1} / 2.") + for verify_idx, verify in enumerate(self._layers[layer_idx]): + logger.info( + f"Computing deterministic hook correction for non-det verification {verify_idx + 1} / {len(self._layers[layer_idx])}." + ) + if not verify.stabs: + self._layers[layer_idx][verify_idx].hook_corrections = [{}] * len(verify.stabs) + continue + for stab_idx, stab in enumerate(verify.stabs): + hook_errors = list(get_hook_errors([stab])) + if self._trivial_hook_errors(hook_errors, self.code, not x_error): + continue + + # hook errors are non-trivial + # add case of error on hook ancilla + hook_errors = np.vstack((hook_errors, np.zeros(self.num_qubits, dtype=np.int8))) + self._layers[layer_idx][verify_idx].hook_corrections[stab_idx] = { + 1: deterministic_correction_single_outcome( + self.state_prep, + hook_errors, + min_timeout=min_timeout, + max_timeout=max_timeout, + max_ancillas=max_ancillas, + zero_state=not x_error, + ) + } + + def _filter_and_stabs(self) -> None: + """Only keep the best non-deterministic verification stabilizers with minimal number of ancillas and CNOTs.""" + self._best_num_anc = 0 + self._best_num_cnots = 0 + for layer_idx in range(2): + # get best numbers + best_num_anc = int(1e6) + best_num_cnots = int(1e6) + best_case_indices = [] + for idx_verify, verify in enumerate(self._layers[layer_idx]): + num_anc = verify.num_ancillas_verification() + verify.num_ancillas_hooks() + num_cnot = verify.num_cnots_verification() + verify.num_cnots_hooks() + if best_num_anc > num_anc or (best_num_anc == num_anc and best_num_cnots > num_cnot): + best_num_anc = num_anc + best_num_cnots = num_cnot + best_case_indices = [idx_verify] + elif best_num_anc == num_anc and best_num_cnots == num_cnot: + best_case_indices.append(idx_verify) + # filter out all but the best case + self._layers[layer_idx] = [self._layers[layer_idx][idx] for idx in best_case_indices] + # save the best numbers + self._best_num_anc += best_num_anc + self._best_num_cnots += best_num_cnots + + def _recompute_hook_propagation_corrections( + self, + verify_2_list: list[DeterministicVerification], + verify: DeterministicVerification, + stabs_flagged: list[bool], + min_timeout: int = 1, + max_timeout: int = 3600, + max_ancillas: int | None = None, + ) -> None: + for verify_2_idx, verify_2 in enumerate(verify_2_list): + verify_2_list[verify_2_idx].det_correction = deterministic_correction( + self.state_prep, + verify_2.stabs, + min_timeout=min_timeout, + max_timeout=max_timeout, + max_ancillas=max_ancillas, + zero_state=not self.state_prep.zero_state, + ) + for stab_idx, stab in enumerate(verify_2.stabs): + hook_errors_2 = list(get_hook_errors([stab])) + if self._trivial_hook_errors(hook_errors_2, self.code, self.state_prep.zero_state): + verify_2_list[verify_2_idx].hook_corrections[stab_idx] = {} + else: + hook_errors_2 = np.vstack((hook_errors_2, np.zeros(self.num_qubits, dtype=np.int8))) + verify_2_list[verify_2_idx].hook_corrections[stab_idx] = { + 1: deterministic_correction_single_outcome( + self.state_prep, + hook_errors_2, + min_timeout=min_timeout, + max_timeout=max_timeout, + max_ancillas=max_ancillas, + zero_state=self.state_prep.zero_state, + ) + } + + # choose the best solution + verify_2_best = verify_2_list[0] + num_anc_verify_2 = verify_2_best.num_ancillas_total() + num_cnots_verify_2 = verify_2_best.num_cnots_total() + for verify_2 in verify_2_list[1:]: + if num_anc_verify_2 > verify_2.num_ancillas_total() or ( + num_anc_verify_2 == verify_2.num_ancillas_total() and num_cnots_verify_2 > verify_2.num_cnots_total() + ): + num_anc_verify_2 = verify_2.num_ancillas_total() + num_cnots_verify_2 = verify_2.num_cnots_total() + verify_2_best = verify_2 + + # modify the first layer verification and reduce necessary hooks + verify_new = verify.copy() + # compute necessary hooks + for idx, flag in enumerate(stabs_flagged): + if flag: + verify_new.hook_corrections[idx] = { + 1: deterministic_correction_single_outcome( + self.state_prep, + get_hook_errors([verify.stabs[idx]]), + min_timeout=min_timeout, + max_timeout=max_timeout, + max_ancillas=max_ancillas, + zero_state=not self.state_prep.zero_state, + ) + } + else: + verify_new.hook_corrections[idx] = {} + + self._hook_propagation_solutions.append((verify_new, verify_2_best)) + + def _compute_hook_propagation_solutions( + self, + min_timeout: int = 1, + max_timeout: int = 3600, + max_ancillas: int | None = None, + compute_all_solutions: bool = False, + ) -> None: + """Computes the second layer assuming the hook errors are not flagged but propagated.""" + if not self._layers[1]: + # no second layer + return + + for verify in self._layers[0]: + logger.info(f"Computing hook propagation solutions for verification {verify} / {len(self._layers[0])}.") + # create possible combinations of which hook errors are flagged + # need_hook_corrections = [ + # not self._trivial_hook_errors(_hook_errors([stab]), self.code, not x_errors) for stab in stabs + # ] + stabs_flagged_all = [ + not self._trivial_hook_errors(get_hook_errors([stab]), self.code, not self.layer_x_errors[0]) + for stab in verify.stabs + ] + # stabs_flagged_all = [True if hook else False for hook in verify.hook_corrections] + stabs_flagged_all_indices = [idx for idx, flag in enumerate(stabs_flagged_all) if flag] + stabs_flagged_indices_combs = list(product([False, True], repeat=len(stabs_flagged_all_indices)))[:-1] + stabs_flagged_combs = [] + for comb in stabs_flagged_indices_combs: + stabs_flagged = [False] * len(stabs_flagged_all) + for idx_comb, idx in enumerate(stabs_flagged_all_indices): + stabs_flagged[idx] = comb[idx_comb] + stabs_flagged_combs.append(stabs_flagged) + + # iterate over combinations: + for stabs_flagged in stabs_flagged_combs: + # get hook errors + hook_errors = np.empty((0, self.num_qubits), dtype=np.int8) + for idx, flag in enumerate(stabs_flagged): + if not flag: + hook_errors = np.vstack((hook_errors, get_hook_errors([verify.stabs[idx]]))) + if self._trivial_hook_errors(hook_errors, self.code, not self.state_prep.zero_state): + continue + # hook errors require different verification in second layer + # compute new verification + if self.use_optimal_verification: + stabs_2_list = all_gate_optimal_verification_stabilizers( + self.state_prep, + x_errors=not self.state_prep.zero_state, + min_timeout=min_timeout, + max_timeout=max_timeout, + max_ancillas=max_ancillas, + additional_faults=hook_errors, + return_all_solutions=compute_all_solutions, + )[0] + else: + stabs_2_list = heuristic_verification_stabilizers( + self.state_prep, x_errors=not self.state_prep.zero_state, additional_faults=hook_errors + )[0] + stabs_2_list = [stabs_2_list] + verify_2_list = [DeterministicVerification(stabs_2, {}) for stabs_2 in stabs_2_list] + # check if better than normal verification + anc_saved = ( + sum(stabs_flagged_all) + - sum(stabs_flagged) + + self._layers[1][0].num_ancillas_verification() + - verify_2_list[0].num_ancillas_verification() + ) + cnots_saved = ( + 2 * sum(stabs_flagged_all) + - 2 * sum(stabs_flagged) + + self._layers[1][0].num_cnots_verification() + - verify_2_list[0].num_cnots_verification() + ) + if anc_saved > 0 or (anc_saved == 0 and cnots_saved > 0): + # hook propagation is better than hook correction + # compute deterministic verification + self._recompute_hook_propagation_corrections( + verify_2_list, verify, stabs_flagged, min_timeout, max_timeout, max_ancillas + ) + + def get_solution( + self, + min_timeout: int = 1, + max_timeout: int = 3600, + max_ancillas: int | None = None, + use_optimal_verification: bool = True, + ) -> tuple[DeterministicVerification, DeterministicVerification]: + """Returns a tuple representing the first layer, second layer and hook error corrections.""" + if max_ancillas is None: + max_ancillas = self.code.Hx.shape[0] + self.code.Hz.shape[0] + self.use_optimal_verification = use_optimal_verification + + self._compute_non_det_stabs(min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas) + self._compute_det_corrections( + min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas, layer_idx=0 + ) + self._compute_hook_propagation_solutions( + min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas, compute_all_solutions=False + ) + + # if hook propagation is worse, compute the hook corrections and deterministic corrections + if len(self._hook_propagation_solutions) == 0: + self._compute_hook_corrections(min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas) + self._compute_det_corrections( + min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas, layer_idx=1 + ) + if len(self._layers[1]) == 0: + return self._layers[0][0], DeterministicVerification([], {}) + return self._layers[0][0], self._layers[1][0] + # else return the hook propagation solution + return self._hook_propagation_solutions[0] + + def get_global_solution( + self, + min_timeout: int = 1, + max_timeout: int = 3600, + max_ancillas: int | None = None, + ) -> tuple[DeterministicVerification, DeterministicVerification]: + """Returns the optimal non-deterministic verification stabilizers for the first and second layer regarding the number of ancillas and CNOTs.""" + if max_ancillas is None: + max_ancillas = self.code.Hx.shape[0] + self.code.Hz.shape[0] + + self._compute_non_det_stabs( + min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas, compute_all_solutions=True + ) + self._filter_and_stabs() + self._compute_det_corrections( + min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas, layer_idx=0 + ) + self._compute_hook_propagation_solutions( + min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas, compute_all_solutions=False + ) + + # if hook propagation is worse, compute the hook corrections and deterministic corrections + if len(self._hook_propagation_solutions) == 0: + self._compute_hook_corrections(min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas) + self._compute_det_corrections( + min_timeout=min_timeout, max_timeout=max_timeout, max_ancillas=max_ancillas, layer_idx=1 + ) + + # compute the best solution + best_stab_indices = [0, 0] + for layer_idx in range(2): + best_num_anc = 3 * max_ancillas + best_num_cnots = 3 * max_ancillas * self.num_qubits + for idx_verify, verify in enumerate(self._layers[layer_idx]): + num_anc = verify.num_ancillas_total() + num_cnots = verify.num_cnots_total() + if best_num_anc > num_anc or (best_num_anc == num_anc and best_num_cnots > num_cnots): + best_num_anc = num_anc + best_num_cnots = num_cnots + best_stab_indices[layer_idx] = idx_verify + if len(self._layers[1]) == 0: + return self._layers[0][best_stab_indices[0]], DeterministicVerification([], {}) + return self._layers[0][best_stab_indices[0]], self._layers[1][best_stab_indices[1]] + + # else return the hook propagation solution + + best_num_anc = 3 * max_ancillas + best_num_cnots = 3 * max_ancillas * self.num_qubits + best_solution = self._hook_propagation_solutions[0] + for verify, verify_2 in self._hook_propagation_solutions[1:]: + # check if better than overall best solution + num_anc = verify.num_ancillas_total() + verify_2.num_ancillas_total() + num_cnots = verify.num_cnots_total() + verify_2.num_cnots_total() + if best_num_anc > num_anc or (best_num_anc == num_anc and best_num_cnots > num_cnots): + best_num_anc = num_anc + best_num_cnots = num_cnots + # save the new verification + best_solution = (verify, verify_2) + return best_solution + + +def deterministic_correction( + sp_circ: StatePrepCircuit, + and_d3_verification_stabilizers: list[npt.NDArray[np.int8]], + min_timeout: int = 1, + max_timeout: int = 3600, + max_ancillas: int | None = None, + zero_state: bool = True, + additional_faults: npt.NDArray[np.int8] | None = None, +) -> DeterministicCorrection: + """Returns a deterministic verification for non-deterministic verification stabilizers. + + It computes the corresponding fault set and then solves the problem if finding optimal deterministic verification + stabilizers for each non-deterministic verification outcome separately. + + Args: + sp_circ: The state preparation circuit to compute the deterministic verification for. + and_d3_verification_stabilizers: The non-deterministic verification stabilizers to be measured. + min_timeout: The minimum time in seconds to run the verification stabilizers. + max_timeout: The maximum time in seconds to run the verification stabilizers. + max_ancillas: The maximum number of ancillas to use in the verification stabilizers. + zero_state: If True, the X errors are considered, otherwise the Z errors are considered. + additional_faults: Additional faults to consider in the fault set (e.g. hook errors). + """ + num_and_stabs = len(and_d3_verification_stabilizers) + num_qubits = sp_circ.code.n + if max_ancillas is None: + max_ancillas = sp_circ.code.Hx.shape[0] + sp_circ.code.Hz.shape[0] + + # get the fault set + if additional_faults is not None: + fault_set = sp_circ.combine_faults(additional_faults=additional_faults, x_errors=zero_state) + else: + fault_set = sp_circ.compute_fault_set(1, x_errors=zero_state) + + det_verify = {} + for verify_outcome_int in range(1, 2**num_and_stabs): + verify_outcome = _int_to_int8_array(verify_outcome_int, num_and_stabs) + logger.info( + f"Computing deterministic verification for non-det outcome {verify_outcome}: {verify_outcome_int}/{2** num_and_stabs - 1}" + ) + + # only consider errors that triggered the verification pattern + errors_filtered = np.array([ + error + for error in fault_set + if np.array_equal(verify_outcome, [np.sum(m * error) % 2 for m in and_d3_verification_stabilizers]) + ]) + + # append single-qubit errors that could have triggered the verification pattern + for qubit in range(num_qubits): + # compute error pattern of single-qubit error on qubit i + error_pattern = [ + np.sum(m * np.eye(num_qubits, dtype=np.int8)[qubit]) % 2 for m in and_d3_verification_stabilizers + ] + for i in range(num_and_stabs): + if np.array_equal(verify_outcome, error_pattern): + # if not already in the fault set + if len(errors_filtered) == 0: + errors_filtered = np.array([np.eye(num_qubits, dtype=np.int8)[qubit]]) + elif not np.any(np.all(errors_filtered == np.eye(num_qubits, dtype=np.int8)[qubit], axis=1)): + errors_filtered = np.vstack((errors_filtered, np.eye(num_qubits, dtype=np.int8)[qubit])) + else: + error_pattern[i] = 0 + + # add the no-error case for the error being on one of the verification ancillas + if np.sum(verify_outcome) == 1: + errors_filtered = np.vstack((errors_filtered, np.zeros(num_qubits, dtype=np.int8))) + # case of no errors or only one error is trivial + if errors_filtered.shape[0] == 0: + det_verify[verify_outcome_int] = ( + np.zeros((num_qubits, 0), dtype=np.int8), + {0: np.zeros(num_qubits, dtype=np.int8), 1: np.zeros(num_qubits, dtype=np.int8)}, + ) + elif errors_filtered.shape[0] == 1: + det_verify[verify_outcome_int] = ( + [np.zeros(num_qubits, dtype=np.int8)], + {0: errors_filtered[0], 1: errors_filtered[0]}, + ) + else: + det_verify[verify_outcome_int] = deterministic_correction_single_outcome( + sp_circ, errors_filtered, min_timeout, max_timeout, max_ancillas, zero_state + ) + return det_verify + + +def deterministic_correction_single_outcome( + sp_circ: StatePrepCircuit, + fault_set: npt.NDArray[np.int8], + min_timeout: int, + max_timeout: int, + max_ancillas: int | None = None, + zero_state: bool = True, +) -> Recovery: + """Returns the deterministic recovery for a set of errors. + + Geometrically increases the number of ancilla qubits until a solution is found. + Then, first the number of ancillas is optimized and then the number of CNOTs. + + Args: + sp_circ: The state preparation circuit to compute the deterministic verification for. + fault_set: The set of errors to consider for the deterministic verification. + min_timeout: The minimum time in seconds to run the verification stabilizers. + max_timeout: The maximum time in seconds to run the verification stabilizers. + max_ancillas: The maximum number of ancillas to use in the verification stabilizers. + zero_state: If True, the X errors are considered, otherwise the Z errors are considered. + """ + num_anc = 1 + num_qubits = sp_circ.code.n + if max_ancillas is None: + max_ancillas = sp_circ.code.Hx.shape[0] + sp_circ.code.Hz.shape[0] + + def _func(num_anc: int) -> Recovery | None: + return correction_stabilizers(sp_circ, fault_set, num_anc, num_anc * num_qubits, x_errors=zero_state) + + res = iterative_search_with_timeout(_func, num_anc, max_ancillas, min_timeout, max_timeout) + assert res[0], "No deterministic verification found." + optimal_det_verify: Recovery = res[0] + + num_anc = res[1] + logger.info(f"Found deterministic verification with {num_anc} ancillas.") + + while num_anc > 1: + logger.info(f"Trying to reduce the number of ancillas to {num_anc - 1}.") + det_verify: Recovery | str | None = run_with_timeout(_func, num_anc - 1, timeout=max_timeout) + if det_verify and not isinstance(det_verify, str): + optimal_det_verify = det_verify + num_anc -= 1 + else: + break + logger.info(f"Optimal number of ancillas: {num_anc}.") + + # try to reduce the number of CNOTs + def min_cnot_func(num_cnots: int) -> Recovery | None: + return correction_stabilizers(sp_circ, fault_set, num_anc, num_cnots, x_errors=zero_state) + + num_cnots = 2 + while num_cnots > 1: + # set the max number of CNOTs to the number returned by the previous step + num_cnots = np.sum([np.sum(m) for m in optimal_det_verify[0]]) + + logger.info(f"Trying to reduce the number of CNOTs to {num_cnots - 1}.") + det_verify = run_with_timeout(min_cnot_func, num_cnots - 1, timeout=max_timeout) + if det_verify and not isinstance(det_verify, str): + optimal_det_verify = det_verify + num_cnots -= 1 + else: + break + logger.info(f"Optimal number of CNOTs: {num_cnots}.") + return optimal_det_verify + + +def correction_stabilizers( + sp_circ: StatePrepCircuit, + fault_set: npt.NDArray[np.int8], + num_anc: int, + num_cnot: int, + x_errors: bool = True, +) -> Recovery | None: + """Return deterministic verification stabilizers with corresponding corrections using z3.""" + gens = sp_circ.z_checks if x_errors else sp_circ.x_checks + correction_gens = sp_circ.x_checks if x_errors else sp_circ.z_checks + + n_gens = gens.shape[0] + n_corr_gens = correction_gens.shape[0] + n_qubits = sp_circ.code.n + n_errors = fault_set.shape[0] + + # Measurements are written as sums of generators + # The variables indicate which generators are non-zero in the sum + measurement_vars = [[z3.Bool(f"m_{anc}_{i}") for i in range(n_gens)] for anc in range(num_anc)] + measurement_stabs = [vars_to_stab(vars_, gens) for vars_ in measurement_vars] + + # create "stabilizer degree of freedom" variables + free_var = [[z3.Bool(f"free_{e}_{g}") for g in range(n_corr_gens)] for e in range(n_errors)] + free_stabs = [vars_to_stab(vars_, correction_gens) for vars_ in free_var] + + # correction variables for each possible deterministic verification outcome + corrections = [[z3.Bool(f"c_{anc}_{i}") for i in range(n_qubits)] for anc in range(2**num_anc)] + + solver = z3.Solver() + + # for each error, the pattern is computed and the corresponding correction is applied + for idx_error, error in enumerate(fault_set): + error_pattern = [odd_overlap(measurement, error) for measurement in measurement_stabs] + for det_pattern, correction in enumerate(corrections): + det_pattern_bool = _int_to_bool_array(det_pattern, num_anc) + # check if error triggers the pattern + triggered = symbolic_vector_eq(error_pattern, det_pattern_bool) + # constraint: weight(error + correction + arbitrary free stabilizer) <= 1 + final_error = [ + z3.Xor(correction[i] if error[i] == 0 else z3.Not(correction[i]), free_stabs[idx_error][i]) + for i in range(n_qubits) + ] + solver.add(z3.If(triggered, z3.Sum(final_error) <= 1, True)) + + # assert that not too many CNOTs are used + solver.add(z3.PbLe([(measurement[q], 1) for measurement in measurement_stabs for q in range(n_qubits)], num_cnot)) + + if solver.check() == z3.sat: + return _extract_measurement_and_correction( + solver.model(), gens, correction_gens, n_qubits, num_anc, measurement_vars, corrections + ) + return None + + +def _extract_measurement_and_correction( + model: z3.Model, + gens: list[npt.NDArray[np.int8]], + correction_gens: list[npt.NDArray[np.int8]], + n_qubits: int, + num_anc: int, + measurement_vars: list[list[z3.BoolRef]], + corrections: list[list[z3.BoolRef]], +) -> Recovery: + """Extract deterministic verification stabilizers and corrections from sat z3 solver.""" + # get measurements + actual_measurements = [] + for m in measurement_vars: + v = np.zeros(len(gens[0]), dtype=np.int8) + for g in range(len(gens)): + if model[m[g]]: + v += gens[g] + actual_measurements.append(v % 2) + + # get corrections for each pattern + actual_corrections = {} + for outcome in range(2**num_anc): + actual_correction = np.array( + [int(bool(model[corrections[outcome][i]])) for i in range(n_qubits)], dtype=np.int8 + ) + + if np.sum(actual_correction) == 0: + actual_corrections[outcome] = actual_correction + else: + actual_corrections[outcome] = coset_leader(actual_correction, np.array(correction_gens)) + return actual_measurements, actual_corrections + + +def _int_to_bool_array(num: int, num_anc: int) -> npt.NDArray[np.bool_]: + """Convert an integer to a boolean array of length num_anc corresponding to the binary representation of the integer.""" + return np.array([bool(num & (1 << i)) for i in range(num_anc)])[::-1] + + +def _int_to_int8_array(num: int, n_qubits: int) -> npt.NDArray[np.int8]: + """Convert an integer to an int8 array of length n_qubits.""" + return np.array([int(bool(num & (1 << i))) for i in range(n_qubits)], dtype=np.int8)[::-1] diff --git a/test/python/ft_stateprep/test_deterministic.py b/test/python/ft_stateprep/test_deterministic.py new file mode 100644 index 00000000..7d487a30 --- /dev/null +++ b/test/python/ft_stateprep/test_deterministic.py @@ -0,0 +1,151 @@ +"""Test synthesis and simulation of deterministic FT state preparation circuits.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import numpy as np +import pytest +from ldpc import mod2 +from qsample import noise + +from mqt.qecc import CSSCode +from mqt.qecc.ft_stateprep import DeterministicVerificationHelper, NoisyDFTStatePrepSimulator, heuristic_prep_circuit + +if TYPE_CHECKING: + import numpy.typing as npt + + from mqt.qecc.ft_stateprep import DeterministicVerification, StatePrepCircuit + +# Simulation parameters +err_params = {"q": [1e-4, 5e-4, 1e-3, 5e-3, 1e-2, 5e-2, 1e-1, 5e-1]} +err_model = noise.E1_1 +shots_dss = 4000 +p_max = {"q": 0.01} +L = 3 + + +@pytest.fixture +def steane_code_sp_plus() -> StatePrepCircuit: + """Return a non-ft state preparation circuit for the Steane code.""" + steane_code = CSSCode.from_code_name("Steane") + sp_circ = heuristic_prep_circuit(steane_code, zero_state=False) + sp_circ.compute_fault_sets() + return sp_circ + + +@pytest.fixture +def css_11_1_3_code_sp() -> StatePrepCircuit: + """Return a non-ft state preparation circuit for the 11_1_3 code.""" + check_matrix = np.array([ + [1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0], + [0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1], + [0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0], + [0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0], + [0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1], + ]) + code = CSSCode(distance=3, Hx=check_matrix, Hz=check_matrix) + sp_circ = heuristic_prep_circuit(code) + sp_circ.compute_fault_sets() + return sp_circ + + +def in_span(m: npt.NDArray[np.int_], v: npt.NDArray[np.int_]) -> bool: + """Check if a vector is in the row space of a matrix.""" + return bool(mod2.rank(np.vstack((m, v))) == mod2.rank(m)) + + +def assert_statistics( + verify: DeterministicVerification, + num_ancillas_verification: int, + num_cnots_verification: int, + num_ancillas_correction: int, + num_cnots_correction: int, + num_ancillas_hooks: int = 0, + num_cnots_hooks: int = 0, + num_ancillas_hook_corrections: int = 0, + num_cnots_hook_corrections: int = 0, +) -> None: + """Assert that the statistics of a deterministic verification are correct.""" + assert verify.num_ancillas_verification() == num_ancillas_verification + assert verify.num_cnots_verification() == num_cnots_verification + assert verify.num_ancillas_correction() <= num_ancillas_correction + assert verify.num_cnots_correction() <= num_cnots_correction + assert verify.num_ancillas_hooks() == num_ancillas_hooks + assert verify.num_cnots_hooks() == num_cnots_hooks + assert verify.num_ancillas_hook_corrections() == num_ancillas_hook_corrections + assert verify.num_cnots_hook_corrections() == num_cnots_hook_corrections + + +def assert_stabs(verify: DeterministicVerification, code: CSSCode, z_stabs: bool) -> None: + """Assert that the measurement stabs of a deterministic verification are correct.""" + checks = np.vstack((code.Hz, code.Lz)) + checks_other = np.vstack((code.Hx, code.Lx)) + if not z_stabs: + checks, checks_other = checks_other, checks + + for stab in verify.stabs: + assert in_span(checks, stab) + for correction in verify.det_correction.values(): + stabs, _ = correction + for stab in stabs: + assert in_span(checks, stab) + for hook in verify.hook_corrections: + if not hook: + continue + for correction in hook.values(): + stabs, _ = correction + for stab in stabs: + assert in_span(checks_other, stab) + + +def assert_scaling(simulation_results: list[npt.NDArray[np.float64]]) -> None: + """Assert that the logical error rates scales approximately quadratically.""" + dss_upper_bound = simulation_results[-2] + x = np.log10(err_params["q"]) + y = np.log10(dss_upper_bound) + m = np.diff(y) / np.diff(x) + assert np.average(m[:3]) > 1.5 + + +def test_11_1_3_det_verification(css_11_1_3_code_sp: StatePrepCircuit) -> None: + """Test deterministic verification of the 11_1_3 code state preparation circuit.""" + verify_helper = DeterministicVerificationHelper(css_11_1_3_code_sp) + verify_x, verify_z = verify_helper.get_solution() + + # as this is not optimal it might be possible that different verification result in different corrections + assert_statistics(verify_x, 2, 8, 4, 14, 0, 0) + assert_stabs(verify_x, css_11_1_3_code_sp.code, z_stabs=True) + + assert_statistics(verify_z, 1, 4, 1, 4, 1, 2, 1, 3) + assert_stabs(verify_z, css_11_1_3_code_sp.code, z_stabs=False) + + # perform simulation + simulator = NoisyDFTStatePrepSimulator( + css_11_1_3_code_sp.circ, (verify_x, verify_z), css_11_1_3_code_sp.code, err_model + ) + simulation_results = simulator.dss_logical_error_rates(err_params, p_max, L, shots_dss) + assert_scaling(simulation_results) + + +def test_steane_det_verification(steane_code_sp_plus: StatePrepCircuit) -> None: + """Test deterministic verification of the Steane code state preparation circuit.""" + verify_helper = DeterministicVerificationHelper(steane_code_sp_plus) + verify_z_opt, verify_x_opt = verify_helper.get_solution() + verify_z_global, verify_x_global = verify_helper.get_global_solution() + + # Check right statistics + for verify_x, verify_z in zip((verify_x_opt, verify_x_global), (verify_z_opt, verify_z_global)): + assert_statistics(verify_z, 1, 3, 1, 3, 0, 0) + assert_stabs(verify_z, steane_code_sp_plus.code, z_stabs=False) + + # second verification is trivial + assert verify_x.num_ancillas_total() == 0 + assert verify_x.num_cnots_total() == 0 + + # perform simulation + simulator = NoisyDFTStatePrepSimulator( + steane_code_sp_plus.circ, (verify_z, verify_x), steane_code_sp_plus.code, err_model, False + ) + simulation_results = simulator.dss_logical_error_rates(err_params, p_max, L, shots_dss) + assert_scaling(simulation_results) diff --git a/uv.lock b/uv.lock index cec0e893..be41e373 100644 --- a/uv.lock +++ b/uv.lock @@ -24,6 +24,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/89/03/a851e84fcbb85214dc637b6378121ef9a0dd61b4c65264675d8a5c9b1ae7/antlr4_python3_runtime-4.13.2-py3-none-any.whl", hash = "sha256:fe3835eb8d33daece0e799090eda89719dbccee7aa39ef94eed3818cafa5a7e8", size = 144462 }, ] +[[package]] +name = "anytree" +version = "2.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/44/2dd9c5d0c3befe899738b930aa056e003b1441bfbf34aab8fce90b2b7dea/anytree-2.12.1.tar.gz", hash = "sha256:244def434ccf31b668ed282954e5d315b4e066c4940b94aff4a7962d85947830", size = 31110 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/fb/ff946843e6b55ae9fda84df3964d6c233cd2261dface789f5be02ab79bc5/anytree-2.12.1-py3-none-any.whl", hash = "sha256:5ea9e61caf96db1e5b3d0a914378d2cd83c269dfce1fb8242ce96589fa3382f0", size = 44914 }, +] + +[[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" @@ -260,6 +281,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, ] +[[package]] +name = "chp-sim" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/7c/8cd37f6f0bf0eae8c63b4366eddf84a7df230930fd5594da538c42810557/chp_sim-0.1.1-py3-none-any.whl", hash = "sha256:760cbab16cbd6d96923d2a1db790158b0d9f23ceacf1ae56220492b1b5941524", size = 11172 }, +] + [[package]] name = "click" version = "8.1.7" @@ -370,71 +402,71 @@ wheels = [ [[package]] name = "coverage" -version = "7.6.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/12/3669b6382792783e92046730ad3327f53b2726f0603f4c311c4da4824222/coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", size = 798716 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/93/4ad92f71e28ece5c0326e5f4a6630aa4928a8846654a65cfff69b49b95b9/coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", size = 206713 }, - { url = "https://files.pythonhosted.org/packages/01/ae/747a580b1eda3f2e431d87de48f0604bd7bc92e52a1a95185a4aa585bc47/coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", size = 207149 }, - { url = "https://files.pythonhosted.org/packages/07/1a/1f573f8a6145f6d4c9130bbc120e0024daf1b24cf2a78d7393fa6eb6aba7/coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", size = 235584 }, - { url = "https://files.pythonhosted.org/packages/40/42/c8523f2e4db34aa9389caee0d3688b6ada7a84fcc782e943a868a7f302bd/coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", size = 233486 }, - { url = "https://files.pythonhosted.org/packages/8d/95/565c310fffa16ede1a042e9ea1ca3962af0d8eb5543bc72df6b91dc0c3d5/coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", size = 234649 }, - { url = "https://files.pythonhosted.org/packages/d5/81/3b550674d98968ec29c92e3e8650682be6c8b1fa7581a059e7e12e74c431/coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", size = 233744 }, - { url = "https://files.pythonhosted.org/packages/0d/70/d66c7f51b3e33aabc5ea9f9624c1c9d9655472962270eb5e7b0d32707224/coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", size = 232204 }, - { url = "https://files.pythonhosted.org/packages/23/2d/2b3a2dbed7a5f40693404c8a09e779d7c1a5fbed089d3e7224c002129ec8/coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", size = 233335 }, - { url = "https://files.pythonhosted.org/packages/5a/4f/92d1d2ad720d698a4e71c176eacf531bfb8e0721d5ad560556f2c484a513/coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", size = 209435 }, - { url = "https://files.pythonhosted.org/packages/c7/b9/cdf158e7991e2287bcf9082670928badb73d310047facac203ff8dcd5ff3/coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", size = 210243 }, - { url = "https://files.pythonhosted.org/packages/87/31/9c0cf84f0dfcbe4215b7eb95c31777cdc0483c13390e69584c8150c85175/coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", size = 206819 }, - { url = "https://files.pythonhosted.org/packages/53/ed/a38401079ad320ad6e054a01ec2b61d270511aeb3c201c80e99c841229d5/coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", size = 207263 }, - { url = "https://files.pythonhosted.org/packages/20/e7/c3ad33b179ab4213f0d70da25a9c214d52464efa11caeab438592eb1d837/coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", size = 239205 }, - { url = "https://files.pythonhosted.org/packages/36/91/fc02e8d8e694f557752120487fd982f654ba1421bbaa5560debf96ddceda/coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", size = 236612 }, - { url = "https://files.pythonhosted.org/packages/cc/57/cb08f0eda0389a9a8aaa4fc1f9fec7ac361c3e2d68efd5890d7042c18aa3/coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", size = 238479 }, - { url = "https://files.pythonhosted.org/packages/d5/c9/2c7681a9b3ca6e6f43d489c2e6653a53278ed857fd6e7010490c307b0a47/coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", size = 237405 }, - { url = "https://files.pythonhosted.org/packages/b5/4e/ebfc6944b96317df8b537ae875d2e57c27b84eb98820bc0a1055f358f056/coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", size = 236038 }, - { url = "https://files.pythonhosted.org/packages/13/f2/3a0bf1841a97c0654905e2ef531170f02c89fad2555879db8fe41a097871/coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", size = 236812 }, - { url = "https://files.pythonhosted.org/packages/b9/9c/66bf59226b52ce6ed9541b02d33e80a6e816a832558fbdc1111a7bd3abd4/coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", size = 209400 }, - { url = "https://files.pythonhosted.org/packages/2a/a0/b0790934c04dfc8d658d4a62acb8f7ca0efdf3818456fcad757b11c6479d/coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", size = 210243 }, - { url = "https://files.pythonhosted.org/packages/7d/e7/9291de916d084f41adddfd4b82246e68d61d6a75747f075f7e64628998d2/coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", size = 207013 }, - { url = "https://files.pythonhosted.org/packages/27/03/932c2c5717a7fa80cd43c6a07d3177076d97b79f12f40f882f9916db0063/coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", size = 207251 }, - { url = "https://files.pythonhosted.org/packages/d5/3f/0af47dcb9327f65a45455fbca846fe96eb57c153af46c4754a3ba678938a/coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", size = 240268 }, - { url = "https://files.pythonhosted.org/packages/8a/3c/37a9d81bbd4b23bc7d46ca820e16174c613579c66342faa390a271d2e18b/coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", size = 237298 }, - { url = "https://files.pythonhosted.org/packages/c0/70/6b0627e5bd68204ee580126ed3513140b2298995c1233bd67404b4e44d0e/coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", size = 239367 }, - { url = "https://files.pythonhosted.org/packages/3c/eb/634d7dfab24ac3b790bebaf9da0f4a5352cbc125ce6a9d5c6cf4c6cae3c7/coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", size = 238853 }, - { url = "https://files.pythonhosted.org/packages/d9/0d/8e3ed00f1266ef7472a4e33458f42e39492e01a64281084fb3043553d3f1/coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", size = 237160 }, - { url = "https://files.pythonhosted.org/packages/ce/9c/4337f468ef0ab7a2e0887a9c9da0e58e2eada6fc6cbee637a4acd5dfd8a9/coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", size = 238824 }, - { url = "https://files.pythonhosted.org/packages/5e/09/3e94912b8dd37251377bb02727a33a67ee96b84bbbe092f132b401ca5dd9/coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", size = 209639 }, - { url = "https://files.pythonhosted.org/packages/01/69/d4f3a4101171f32bc5b3caec8ff94c2c60f700107a6aaef7244b2c166793/coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", size = 210428 }, - { url = "https://files.pythonhosted.org/packages/c2/4d/2dede4f7cb5a70fb0bb40a57627fddf1dbdc6b9c1db81f7c4dcdcb19e2f4/coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", size = 207039 }, - { url = "https://files.pythonhosted.org/packages/3f/f9/d86368ae8c79e28f1fb458ebc76ae9ff3e8bd8069adc24e8f2fed03c58b7/coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", size = 207298 }, - { url = "https://files.pythonhosted.org/packages/64/c5/b4cc3c3f64622c58fbfd4d8b9a7a8ce9d355f172f91fcabbba1f026852f6/coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", size = 239813 }, - { url = "https://files.pythonhosted.org/packages/8a/86/14c42e60b70a79b26099e4d289ccdfefbc68624d096f4481163085aa614c/coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", size = 236959 }, - { url = "https://files.pythonhosted.org/packages/7f/f8/4436a643631a2fbab4b44d54f515028f6099bfb1cd95b13cfbf701e7f2f2/coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", size = 238950 }, - { url = "https://files.pythonhosted.org/packages/49/50/1571810ddd01f99a0a8be464a4ac8b147f322cd1e8e296a1528984fc560b/coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", size = 238610 }, - { url = "https://files.pythonhosted.org/packages/f3/8c/6312d241fe7cbd1f0cade34a62fea6f333d1a261255d76b9a87074d8703c/coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", size = 236697 }, - { url = "https://files.pythonhosted.org/packages/ce/5f/fef33dfd05d87ee9030f614c857deb6df6556b8f6a1c51bbbb41e24ee5ac/coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", size = 238541 }, - { url = "https://files.pythonhosted.org/packages/a9/64/6a984b6e92e1ea1353b7ffa08e27f707a5e29b044622445859200f541e8c/coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", size = 209707 }, - { url = "https://files.pythonhosted.org/packages/5c/60/ce5a9e942e9543783b3db5d942e0578b391c25cdd5e7f342d854ea83d6b7/coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", size = 210439 }, - { url = "https://files.pythonhosted.org/packages/78/53/6719677e92c308207e7f10561a1b16ab8b5c00e9328efc9af7cfd6fb703e/coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", size = 207784 }, - { url = "https://files.pythonhosted.org/packages/fa/dd/7054928930671fcb39ae6a83bb71d9ab5f0afb733172543ced4b09a115ca/coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", size = 208058 }, - { url = "https://files.pythonhosted.org/packages/b5/7d/fd656ddc2b38301927b9eb3aae3fe827e7aa82e691923ed43721fd9423c9/coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", size = 250772 }, - { url = "https://files.pythonhosted.org/packages/90/d0/eb9a3cc2100b83064bb086f18aedde3afffd7de6ead28f69736c00b7f302/coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", size = 246490 }, - { url = "https://files.pythonhosted.org/packages/45/44/3f64f38f6faab8a0cfd2c6bc6eb4c6daead246b97cf5f8fc23bf3788f841/coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", size = 248848 }, - { url = "https://files.pythonhosted.org/packages/5d/11/4c465a5f98656821e499f4b4619929bd5a34639c466021740ecdca42aa30/coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", size = 248340 }, - { url = "https://files.pythonhosted.org/packages/f1/96/ebecda2d016cce9da812f404f720ca5df83c6b29f65dc80d2000d0078741/coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", size = 246229 }, - { url = "https://files.pythonhosted.org/packages/16/d9/3d820c00066ae55d69e6d0eae11d6149a5ca7546de469ba9d597f01bf2d7/coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", size = 247510 }, - { url = "https://files.pythonhosted.org/packages/8f/c3/4fa1eb412bb288ff6bfcc163c11700ff06e02c5fad8513817186e460ed43/coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", size = 210353 }, - { url = "https://files.pythonhosted.org/packages/7e/77/03fc2979d1538884d921c2013075917fc927f41cd8526909852fe4494112/coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", size = 211502 }, - { url = "https://files.pythonhosted.org/packages/fb/27/7efede2355bd1417137246246ab0980751b3ba6065102518a2d1eba6a278/coverage-7.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3", size = 206714 }, - { url = "https://files.pythonhosted.org/packages/f3/94/594af55226676d078af72b329372e2d036f9ba1eb6bcf1f81debea2453c7/coverage-7.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c", size = 207146 }, - { url = "https://files.pythonhosted.org/packages/d5/13/19de1c5315b22795dd67dbd9168281632424a344b648d23d146572e42c2b/coverage-7.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076", size = 235180 }, - { url = "https://files.pythonhosted.org/packages/db/26/8fba01ce9f376708c7efed2761cea740f50a1b4138551886213797a4cecd/coverage-7.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376", size = 233100 }, - { url = "https://files.pythonhosted.org/packages/74/66/4db60266551b89e820b457bc3811a3c5eaad3c1324cef7730c468633387a/coverage-7.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0", size = 234231 }, - { url = "https://files.pythonhosted.org/packages/2a/9b/7b33f0892fccce50fc82ad8da76c7af1731aea48ec71279eef63a9522db7/coverage-7.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858", size = 233383 }, - { url = "https://files.pythonhosted.org/packages/91/49/6ff9c4e8a67d9014e1c434566e9169965f970350f4792a0246cd0d839442/coverage-7.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111", size = 231863 }, - { url = "https://files.pythonhosted.org/packages/81/f9/c9d330dec440676b91504fcceebca0814718fa71c8498cf29d4e21e9dbfc/coverage-7.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901", size = 232854 }, - { url = "https://files.pythonhosted.org/packages/ee/d9/605517a023a0ba8eb1f30d958f0a7ff3a21867b07dcb42618f862695ca0e/coverage-7.6.4-cp39-cp39-win32.whl", hash = "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09", size = 209437 }, - { url = "https://files.pythonhosted.org/packages/aa/79/2626903efa84e9f5b9c8ee6972de8338673fdb5bb8d8d2797740bf911027/coverage-7.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f", size = 210209 }, - { url = "https://files.pythonhosted.org/packages/cc/56/e1d75e8981a2a92c2a777e67c26efa96c66da59d645423146eb9ff3a851b/coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", size = 198954 }, +version = "7.6.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/68/26895f8b068e384b1ec9ab122565b913b735e6b4c618b3d265a280607edc/coverage-7.6.7.tar.gz", hash = "sha256:d79d4826e41441c9a118ff045e4bccb9fdbdcb1d02413e7ea6eb5c87b5439d24", size = 799938 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/c9/84898713e61208ddbe71b991d8f311d9ca175629ce5f1a46018acc643572/coverage-7.6.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:108bb458827765d538abcbf8288599fee07d2743357bdd9b9dad456c287e121e", size = 206875 }, + { url = "https://files.pythonhosted.org/packages/f0/69/7dfd65f0e284617f72d974f6dfedc7bc16f86172e5bc6ebc8b63430263f3/coverage-7.6.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c973b2fe4dc445cb865ab369df7521df9c27bf40715c837a113edaa2aa9faf45", size = 207307 }, + { url = "https://files.pythonhosted.org/packages/d1/ce/6e356b2bc751bdaadd77c714336b98ec45ccaf0cfe085b6b25d34f7cceb8/coverage-7.6.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c6b24007c4bcd0b19fac25763a7cac5035c735ae017e9a349b927cfc88f31c1", size = 235744 }, + { url = "https://files.pythonhosted.org/packages/35/49/a7ab3d5a507d32344994cab856784e8d603c0b698070f7667c3ae41e8e50/coverage-7.6.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acbb8af78f8f91b3b51f58f288c0994ba63c646bc1a8a22ad072e4e7e0a49f1c", size = 233645 }, + { url = "https://files.pythonhosted.org/packages/bd/41/de07328d2e79916fcc6cd53a5a1d18d163483519ab95f7f60fe15276811c/coverage-7.6.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad32a981bcdedb8d2ace03b05e4fd8dace8901eec64a532b00b15217d3677dd2", size = 234807 }, + { url = "https://files.pythonhosted.org/packages/e4/cc/2a669319b1295e0c52e8cfbbb163b32188b62f3b0bbe7014ef402b24b7cf/coverage-7.6.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:34d23e28ccb26236718a3a78ba72744212aa383141961dd6825f6595005c8b06", size = 233902 }, + { url = "https://files.pythonhosted.org/packages/68/71/a1bb90cb177358a2d364b3968a2069225f614d6824c3d959dee688ca0902/coverage-7.6.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e25bacb53a8c7325e34d45dddd2f2fbae0dbc230d0e2642e264a64e17322a777", size = 232363 }, + { url = "https://files.pythonhosted.org/packages/eb/dc/87551219d3437214523d1c7de0a717bead7a3369ed9bae05a7fd2854476f/coverage-7.6.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af05bbba896c4472a29408455fe31b3797b4d8648ed0a2ccac03e074a77e2314", size = 233493 }, + { url = "https://files.pythonhosted.org/packages/ca/a4/d74ae3a3fb9e55fe5d9b811ce68a6bd8df3ae0a92c336acbc00075bc24fa/coverage-7.6.7-cp310-cp310-win32.whl", hash = "sha256:796c9b107d11d2d69e1849b2dfe41730134b526a49d3acb98ca02f4985eeff7a", size = 209593 }, + { url = "https://files.pythonhosted.org/packages/77/cb/7984c4d0404e8fcc4ada226b240965ef056e7a20e61a18c9038bf88e7624/coverage-7.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:987a8e3da7da4eed10a20491cf790589a8e5e07656b6dc22d3814c4d88faf163", size = 210398 }, + { url = "https://files.pythonhosted.org/packages/c6/d7/1bf7bb0943237149ad01977190ac5c2e17add1f4fe7cabc06401682137f6/coverage-7.6.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7e61b0e77ff4dddebb35a0e8bb5a68bf0f8b872407d8d9f0c726b65dfabe2469", size = 206979 }, + { url = "https://files.pythonhosted.org/packages/83/eb/863b2cd654353b94c6ad834008df813424bf3e8f110e5f655fe5dc4c423b/coverage-7.6.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a5407a75ca4abc20d6252efeb238377a71ce7bda849c26c7a9bece8680a5d99", size = 207431 }, + { url = "https://files.pythonhosted.org/packages/35/c9/d7a02a9654c41174fb99402c0fbd9583d0d2cb8714e7f948117fa7f919c4/coverage-7.6.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df002e59f2d29e889c37abd0b9ee0d0e6e38c24f5f55d71ff0e09e3412a340ec", size = 239368 }, + { url = "https://files.pythonhosted.org/packages/11/64/6c43a0ec43e5ddc5e09b0b589e3fd31def05fc463920d084e5af35fe527d/coverage-7.6.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:673184b3156cba06154825f25af33baa2671ddae6343f23175764e65a8c4c30b", size = 236769 }, + { url = "https://files.pythonhosted.org/packages/1c/dc/e77d98ae433c556c29328712a07fed0e6d159a63b2ec81039ce0a13a24a3/coverage-7.6.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e69ad502f1a2243f739f5bd60565d14a278be58be4c137d90799f2c263e7049a", size = 238634 }, + { url = "https://files.pythonhosted.org/packages/cc/84/50df3a8426d686057496171b4ccdb64528dacc4f42e94dceb7de3c598a69/coverage-7.6.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:60dcf7605c50ea72a14490d0756daffef77a5be15ed1b9fea468b1c7bda1bc3b", size = 237562 }, + { url = "https://files.pythonhosted.org/packages/2e/0f/9560196247574c1ccdab64cb923d69119fd5abd5b3db28d601ab2b452861/coverage-7.6.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9c2eb378bebb2c8f65befcb5147877fc1c9fbc640fc0aad3add759b5df79d55d", size = 236197 }, + { url = "https://files.pythonhosted.org/packages/df/14/38b7c081e86e845df1867143ddb6e05bf8395f60ab3923c023a56d97cca1/coverage-7.6.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c0317288f032221d35fa4cbc35d9f4923ff0dfd176c79c9b356e8ef8ef2dff4", size = 236970 }, + { url = "https://files.pythonhosted.org/packages/8b/f3/af34f814ca3814f798878ae368b638edb91298595470614f5265f3f416fa/coverage-7.6.7-cp311-cp311-win32.whl", hash = "sha256:951aade8297358f3618a6e0660dc74f6b52233c42089d28525749fc8267dccd2", size = 209557 }, + { url = "https://files.pythonhosted.org/packages/5a/9e/5d1080d83d752873bd9dedea5524c0f5fe68a3d5e1e58c590865bd724591/coverage-7.6.7-cp311-cp311-win_amd64.whl", hash = "sha256:5e444b8e88339a2a67ce07d41faabb1d60d1004820cee5a2c2b54e2d8e429a0f", size = 210402 }, + { url = "https://files.pythonhosted.org/packages/84/30/30e9df650b9038962c62d900b093a17414d5b43b4d07d47b8698d9e7ce26/coverage-7.6.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f07ff574986bc3edb80e2c36391678a271d555f91fd1d332a1e0f4b5ea4b6ea9", size = 207172 }, + { url = "https://files.pythonhosted.org/packages/88/8b/e28f86412317b9514692fd6f9d8ac6faa12494c3f470c3c63f202e10c756/coverage-7.6.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:49ed5ee4109258973630c1f9d099c7e72c5c36605029f3a91fe9982c6076c82b", size = 207406 }, + { url = "https://files.pythonhosted.org/packages/ac/46/da1bd9a3a893f74f5ce85f35e2755fcb00a80ed21e18d300c54f64938b1c/coverage-7.6.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3e8796434a8106b3ac025fd15417315d7a58ee3e600ad4dbcfddc3f4b14342c", size = 240424 }, + { url = "https://files.pythonhosted.org/packages/f6/12/af8e932496de1997bf4a36785d025ddac6427cbaf6954f26c2edaf21a58a/coverage-7.6.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3b925300484a3294d1c70f6b2b810d6526f2929de954e5b6be2bf8caa1f12c1", size = 237456 }, + { url = "https://files.pythonhosted.org/packages/60/a2/23eb11eb60f825a84397cb94701d6f41d2e8e88ad7d0ba2b4339f38435fb/coverage-7.6.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c42ec2c522e3ddd683dec5cdce8e62817afb648caedad9da725001fa530d354", size = 239527 }, + { url = "https://files.pythonhosted.org/packages/47/9e/63b318bc469308a32b0fbd6c80e2ea05dd7a2b7e840a46b3974843083a8c/coverage-7.6.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0266b62cbea568bd5e93a4da364d05de422110cbed5056d69339bd5af5685433", size = 239011 }, + { url = "https://files.pythonhosted.org/packages/99/47/1e84b067df3f021dfbc9cba09ec9acd4cb64938648a234e5bdf3006fd08b/coverage-7.6.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e5f2a0f161d126ccc7038f1f3029184dbdf8f018230af17ef6fd6a707a5b881f", size = 237316 }, + { url = "https://files.pythonhosted.org/packages/12/9d/96baaafc948d4a0ef2248a611d41051eea0917ef881d744879dd20be7c4a/coverage-7.6.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c132b5a22821f9b143f87446805e13580b67c670a548b96da945a8f6b4f2efbb", size = 238980 }, + { url = "https://files.pythonhosted.org/packages/87/d9/97af1886ca3f612d0cea2999d33e90d2f5b8fdf9bedc2d3bc75883efec4c/coverage-7.6.7-cp312-cp312-win32.whl", hash = "sha256:7c07de0d2a110f02af30883cd7dddbe704887617d5c27cf373362667445a4c76", size = 209801 }, + { url = "https://files.pythonhosted.org/packages/f8/4d/1e31c2018b1b3738154639f94188b1f54098fbf0f80c7ec104928576d0bb/coverage-7.6.7-cp312-cp312-win_amd64.whl", hash = "sha256:fd49c01e5057a451c30c9b892948976f5d38f2cbd04dc556a82743ba8e27ed8c", size = 210587 }, + { url = "https://files.pythonhosted.org/packages/21/87/c590d0c7eeb884995d9d06b429c5e88e9fcd65d3a6a686d9476cb50b72a9/coverage-7.6.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:46f21663e358beae6b368429ffadf14ed0a329996248a847a4322fb2e35d64d3", size = 207199 }, + { url = "https://files.pythonhosted.org/packages/40/ee/c88473c4f69c952f4425fabe045cb78d2027634ce50c9d7f7987d389b604/coverage-7.6.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:40cca284c7c310d622a1677f105e8507441d1bb7c226f41978ba7c86979609ab", size = 207454 }, + { url = "https://files.pythonhosted.org/packages/b8/07/afda6e10c50e3a8c21020c5c1d1b4f3d7eff1c190305cef2962adf8de018/coverage-7.6.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77256ad2345c29fe59ae861aa11cfc74579c88d4e8dbf121cbe46b8e32aec808", size = 239971 }, + { url = "https://files.pythonhosted.org/packages/85/43/bd1934b75e31f2a49665be6a6b7f8bfaff7266ba19721bdb90239f5e9ed7/coverage-7.6.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87ea64b9fa52bf395272e54020537990a28078478167ade6c61da7ac04dc14bc", size = 237119 }, + { url = "https://files.pythonhosted.org/packages/2b/19/7a70458c1624724086195b40628e91bc5b9ca180cdfefcc778285c49c7b2/coverage-7.6.7-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d608a7808793e3615e54e9267519351c3ae204a6d85764d8337bd95993581a8", size = 239109 }, + { url = "https://files.pythonhosted.org/packages/f3/2c/3dee671415ff13c05ca68243b2264fc95a5eea57697cffa7986b68b8f608/coverage-7.6.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdd94501d65adc5c24f8a1a0eda110452ba62b3f4aeaba01e021c1ed9cb8f34a", size = 238769 }, + { url = "https://files.pythonhosted.org/packages/37/ad/e0d1228638711aeacacc98d1197af6226b6d062d12c81a6bcc17d3234533/coverage-7.6.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:82c809a62e953867cf57e0548c2b8464207f5f3a6ff0e1e961683e79b89f2c55", size = 236854 }, + { url = "https://files.pythonhosted.org/packages/90/95/6467e9d9765a63c7f142703a7f212f6af114bd73a6c1cffeb7ad7f003a86/coverage-7.6.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb684694e99d0b791a43e9fc0fa58efc15ec357ac48d25b619f207c41f2fd384", size = 238701 }, + { url = "https://files.pythonhosted.org/packages/b2/7a/fc11a163f0fd6ce8539d0f1b565873fe6903b900214ff71b5d80d16154c3/coverage-7.6.7-cp313-cp313-win32.whl", hash = "sha256:963e4a08cbb0af6623e61492c0ec4c0ec5c5cf74db5f6564f98248d27ee57d30", size = 209865 }, + { url = "https://files.pythonhosted.org/packages/f2/91/58be3a56efff0c3481e48e2caa56d5d6f3c5c8d385bf4adbecdfd85484b0/coverage-7.6.7-cp313-cp313-win_amd64.whl", hash = "sha256:14045b8bfd5909196a90da145a37f9d335a5d988a83db34e80f41e965fb7cb42", size = 210597 }, + { url = "https://files.pythonhosted.org/packages/34/7e/fed983809c2eccb09c5ddccfdb08efb7f2dd1ae3454dabf1c92c5a2e9946/coverage-7.6.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f2c7a045eef561e9544359a0bf5784b44e55cefc7261a20e730baa9220c83413", size = 207944 }, + { url = "https://files.pythonhosted.org/packages/c7/e0/2c1a157986a3927c3920e8e3938a3fdf33ea22b6f371dc3b679f13f619e2/coverage-7.6.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dd4e4a49d9c72a38d18d641135d2fb0bdf7b726ca60a103836b3d00a1182acd", size = 208215 }, + { url = "https://files.pythonhosted.org/packages/35/2f/77b086b228f6443ae5499467d1629c7428925b390cd171350c403bc00f14/coverage-7.6.7-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c95e0fa3d1547cb6f021ab72f5c23402da2358beec0a8e6d19a368bd7b0fb37", size = 250930 }, + { url = "https://files.pythonhosted.org/packages/60/d8/2ffea937d89ee328fc6e47c2515b890735bdf3f195d507d1c78b5fa96939/coverage-7.6.7-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f63e21ed474edd23f7501f89b53280014436e383a14b9bd77a648366c81dce7b", size = 246647 }, + { url = "https://files.pythonhosted.org/packages/b2/81/efbb3b00a7f7eb5f54a3b3b9f19b26d770a0b7d3870d651f07d2451c5504/coverage-7.6.7-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead9b9605c54d15be228687552916c89c9683c215370c4a44f1f217d2adcc34d", size = 249006 }, + { url = "https://files.pythonhosted.org/packages/eb/91/ce36990cbefaf7909e96c888ed4d83f3471fc1be3273a5beda10896cde0f/coverage-7.6.7-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0573f5cbf39114270842d01872952d301027d2d6e2d84013f30966313cadb529", size = 248500 }, + { url = "https://files.pythonhosted.org/packages/75/3f/b8c87dfdd96276870fb4abc7e2957cba7d20d8a435fcd816d807869ec833/coverage-7.6.7-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e2c8e3384c12dfa19fa9a52f23eb091a8fad93b5b81a41b14c17c78e23dd1d8b", size = 246388 }, + { url = "https://files.pythonhosted.org/packages/a0/51/62273e1d5c25bb8fbef5fbbadc75b4a3e08c11b80516d0a97c25e5cced5b/coverage-7.6.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:70a56a2ec1869e6e9fa69ef6b76b1a8a7ef709972b9cc473f9ce9d26b5997ce3", size = 247669 }, + { url = "https://files.pythonhosted.org/packages/75/e5/d7772e56a7eace80e98ac39f2756d4b690fc0ce2384418174e02519a26a8/coverage-7.6.7-cp313-cp313t-win32.whl", hash = "sha256:dbba8210f5067398b2c4d96b4e64d8fb943644d5eb70be0d989067c8ca40c0f8", size = 210510 }, + { url = "https://files.pythonhosted.org/packages/2d/12/f2666e4e36b43221391ffcd971ab0c50e19439c521c2c87cd7e0b49ddba2/coverage-7.6.7-cp313-cp313t-win_amd64.whl", hash = "sha256:dfd14bcae0c94004baba5184d1c935ae0d1231b8409eb6c103a5fd75e8ecdc56", size = 211660 }, + { url = "https://files.pythonhosted.org/packages/4c/3d/5ee1ccc37d39e4c06194492e15cd6327d0a85b6c4f14c112fd19b65dc6a7/coverage-7.6.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37a15573f988b67f7348916077c6d8ad43adb75e478d0910957394df397d2874", size = 206870 }, + { url = "https://files.pythonhosted.org/packages/c2/91/cfdf3c9f4c141d2172b5abd9631853144537d4849d00d08eff2b7e3a8318/coverage-7.6.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b6cce5c76985f81da3769c52203ee94722cd5d5889731cd70d31fee939b74bf0", size = 207305 }, + { url = "https://files.pythonhosted.org/packages/0f/67/6b0460017083bd9330d2d74e3b5aff3e85f9918c96ae8eae8135a262cc34/coverage-7.6.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ab9763d291a17b527ac6fd11d1a9a9c358280adb320e9c2672a97af346ac2c", size = 235338 }, + { url = "https://files.pythonhosted.org/packages/92/59/0c3a8a3f5ef007862774cb8d25580ba8cc3a60e79d2e0798efb117eaea7b/coverage-7.6.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cf96ceaa275f071f1bea3067f8fd43bec184a25a962c754024c973af871e1b7", size = 233259 }, + { url = "https://files.pythonhosted.org/packages/cd/fc/68d19fb8688d976cb0da7713ca632ca5a5423c92aeae377161d9b888bb38/coverage-7.6.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aee9cf6b0134d6f932d219ce253ef0e624f4fa588ee64830fcba193269e4daa3", size = 234387 }, + { url = "https://files.pythonhosted.org/packages/9d/8a/e76da4084c59420f4f9fac8a5d4b08f0281774f56375c59e76e27eafdb8d/coverage-7.6.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2bc3e45c16564cc72de09e37413262b9f99167803e5e48c6156bccdfb22c8327", size = 233539 }, + { url = "https://files.pythonhosted.org/packages/61/b7/cc00329039500147d3b5724ca412e6b5b8124da7c2865b673a09f04e71fa/coverage-7.6.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:623e6965dcf4e28a3debaa6fcf4b99ee06d27218f46d43befe4db1c70841551c", size = 232021 }, + { url = "https://files.pythonhosted.org/packages/a1/af/1710b65f590d52c9c5f1a238142feb2ef1ff61915fa41531b372e920bee3/coverage-7.6.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850cfd2d6fc26f8346f422920ac204e1d28814e32e3a58c19c91980fa74d8289", size = 233013 }, + { url = "https://files.pythonhosted.org/packages/fc/99/32773e1f26cbfe11a0cadc4a4163a2249f04e83f0b8def93d85c572d0628/coverage-7.6.7-cp39-cp39-win32.whl", hash = "sha256:c296263093f099da4f51b3dff1eff5d4959b527d4f2f419e16508c5da9e15e8c", size = 209597 }, + { url = "https://files.pythonhosted.org/packages/d7/ef/4b86263d312da7df483a84b69b4e0575fd777fb673fbef95a4df8a68a07c/coverage-7.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:90746521206c88bdb305a4bf3342b1b7316ab80f804d40c536fc7d329301ee13", size = 210367 }, + { url = "https://files.pythonhosted.org/packages/e1/ec/dc663f7d34651aca74a531d10800595d9ec28a78b8306705721900b17a23/coverage-7.6.7-pp39.pp310-none-any.whl", hash = "sha256:0ddcb70b3a3a57581b450571b31cb774f23eb9519c2aaa6176d3a84c9fc57671", size = 199113 }, ] [package.optional-dependencies] @@ -534,6 +566,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b5/fd/afcd0496feca3276f509df3dbd5dae726fcc756f1a08d9e25abe1733f962/executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf", size = 25805 }, ] +[[package]] +name = "fastcore" +version = "1.7.20" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e5/94/d8315c2dace419e6f65dc721c21039fe2a0d87871088652013e738df8816/fastcore-1.7.20.tar.gz", hash = "sha256:316dcb0e2d5e338e069f338b3c136ca9eb4ce950ca433da2a80952fc5928ddab", size = 80075 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/ac/41f6f2d4840d5b1521881adbfee8b2000e5f5d4e762a945c15c7bd4af90a/fastcore-1.7.20-py3-none-any.whl", hash = "sha256:7d81f2a0da27d10df6d0b0050b08ea3eb2b1bb2894e8970f246be49c9a593c01", size = 83676 }, +] + [[package]] name = "fastjsonschema" version = "2.20.0" @@ -545,49 +589,65 @@ wheels = [ [[package]] name = "fonttools" -version = "4.54.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/1d/70b58e342e129f9c0ce030029fb4b2b0670084bbbfe1121d008f6a1e361c/fonttools-4.54.1.tar.gz", hash = "sha256:957f669d4922f92c171ba01bef7f29410668db09f6c02111e22b2bce446f3285", size = 3463867 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/f9/285c9a2d0e86b9bf2babfe19bec00502361fda56cea144d6a269ab9a32e6/fonttools-4.54.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ed7ee041ff7b34cc62f07545e55e1468808691dddfd315d51dd82a6b37ddef2", size = 2766970 }, - { url = "https://files.pythonhosted.org/packages/2f/9a/9d899e7ae55b0dd30632e6ca36c0f5fa1205b1b096ec171c9be903673058/fonttools-4.54.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41bb0b250c8132b2fcac148e2e9198e62ff06f3cc472065dff839327945c5882", size = 2254639 }, - { url = "https://files.pythonhosted.org/packages/16/6f/b99e0c347732fb003077a2cff38c26f381969b74329aa5597e344d540fe1/fonttools-4.54.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7965af9b67dd546e52afcf2e38641b5be956d68c425bef2158e95af11d229f10", size = 4574346 }, - { url = "https://files.pythonhosted.org/packages/e5/12/9a45294a7c4520cc32936edd15df1d5c24af701d2f5f51070a9a43d7664b/fonttools-4.54.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278913a168f90d53378c20c23b80f4e599dca62fbffae4cc620c8eed476b723e", size = 4630045 }, - { url = "https://files.pythonhosted.org/packages/64/52/ba4f00eb6003e4089264cd9ce126cddec2b39c78f1ab01be9dc389a197ca/fonttools-4.54.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0e88e3018ac809b9662615072dcd6b84dca4c2d991c6d66e1970a112503bba7e", size = 4569527 }, - { url = "https://files.pythonhosted.org/packages/41/ff/85f93a14c8acf978f332508f980dcaff5ed5f0cf284371eb101a78f0b1f4/fonttools-4.54.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4aa4817f0031206e637d1e685251ac61be64d1adef111060df84fdcbc6ab6c44", size = 4741677 }, - { url = "https://files.pythonhosted.org/packages/6f/f0/06ea7d9f8b7b6d4758a50271517db04039c4c6da8fa0475d417e005624d0/fonttools-4.54.1-cp310-cp310-win32.whl", hash = "sha256:7e3b7d44e18c085fd8c16dcc6f1ad6c61b71ff463636fcb13df7b1b818bd0c02", size = 2166797 }, - { url = "https://files.pythonhosted.org/packages/71/73/545c817e34b8c34585291951722e1a5ae579380deb009576d9d244b13ab0/fonttools-4.54.1-cp310-cp310-win_amd64.whl", hash = "sha256:dd9cc95b8d6e27d01e1e1f1fae8559ef3c02c76317da650a19047f249acd519d", size = 2210552 }, - { url = "https://files.pythonhosted.org/packages/aa/2c/8b5d82fe2d9c7f260fb73121418f5e07d4e38c329ea3886a5b0e55586113/fonttools-4.54.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5419771b64248484299fa77689d4f3aeed643ea6630b2ea750eeab219588ba20", size = 2768112 }, - { url = "https://files.pythonhosted.org/packages/37/2e/f94118b92f7b6a9ec93840101b64bfdd09f295b266133857e8e852a5c35c/fonttools-4.54.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:301540e89cf4ce89d462eb23a89464fef50915255ece765d10eee8b2bf9d75b2", size = 2254739 }, - { url = "https://files.pythonhosted.org/packages/45/4b/8a32f56a13e78256192f77d6b65583c43538c7955f5420887bb574b91ddf/fonttools-4.54.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ae5091547e74e7efecc3cbf8e75200bc92daaeb88e5433c5e3e95ea8ce5aa7", size = 4879772 }, - { url = "https://files.pythonhosted.org/packages/96/13/748b7f7239893ff0796de11074b0ad8aa4c3da2d9f4d79a128b0b16147f3/fonttools-4.54.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82834962b3d7c5ca98cb56001c33cf20eb110ecf442725dc5fdf36d16ed1ab07", size = 4927686 }, - { url = "https://files.pythonhosted.org/packages/7c/82/91bc5a378b4a0593fa90ea706f68ce7e9e871c6873e0d91e134d107758db/fonttools-4.54.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d26732ae002cc3d2ecab04897bb02ae3f11f06dd7575d1df46acd2f7c012a8d8", size = 4890789 }, - { url = "https://files.pythonhosted.org/packages/ea/ca/82be5d4f8b78405cdb3f7f3f1316af5e8db93216121f19da9f684a35beee/fonttools-4.54.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58974b4987b2a71ee08ade1e7f47f410c367cdfc5a94fabd599c88165f56213a", size = 5061351 }, - { url = "https://files.pythonhosted.org/packages/da/2f/fd6e1b01c80c473c3ac52492dcf8d26cdf5f4a89b4f30875ecfbda55e7ff/fonttools-4.54.1-cp311-cp311-win32.whl", hash = "sha256:ab774fa225238986218a463f3fe151e04d8c25d7de09df7f0f5fce27b1243dbc", size = 2166210 }, - { url = "https://files.pythonhosted.org/packages/63/f1/3a081cd047d83b5966cb0d7ef3fea929ee6eddeb94d8fbfdb2a19bd60cc7/fonttools-4.54.1-cp311-cp311-win_amd64.whl", hash = "sha256:07e005dc454eee1cc60105d6a29593459a06321c21897f769a281ff2d08939f6", size = 2211946 }, - { url = "https://files.pythonhosted.org/packages/27/b6/f9d365932dcefefdcc794985f8846471e60932070c557e0f66ed195fccec/fonttools-4.54.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:54471032f7cb5fca694b5f1a0aaeba4af6e10ae989df408e0216f7fd6cdc405d", size = 2761873 }, - { url = "https://files.pythonhosted.org/packages/67/9d/cfbfe36e5061a8f68b154454ba2304eb01f40d4ba9b63e41d9058909baed/fonttools-4.54.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fa92cb248e573daab8d032919623cc309c005086d743afb014c836636166f08", size = 2251828 }, - { url = "https://files.pythonhosted.org/packages/90/41/5573e074739efd9227dd23647724f01f6f07ad062fe09d02e91c5549dcf7/fonttools-4.54.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a911591200114969befa7f2cb74ac148bce5a91df5645443371aba6d222e263", size = 4792544 }, - { url = "https://files.pythonhosted.org/packages/08/07/aa85cc62abcc940b25d14b542cf585eebf4830032a7f6a1395d696bb3231/fonttools-4.54.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93d458c8a6a354dc8b48fc78d66d2a8a90b941f7fec30e94c7ad9982b1fa6bab", size = 4875892 }, - { url = "https://files.pythonhosted.org/packages/47/23/c5726c2615446c498a976bed21c35a242a97eee39930a2655d616ca885cc/fonttools-4.54.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5eb2474a7c5be8a5331146758debb2669bf5635c021aee00fd7c353558fc659d", size = 4769822 }, - { url = "https://files.pythonhosted.org/packages/8f/7b/87f7f7d35e0732ac67422dfa6f05e2b568fb6ca2dcd7f3e4f500293cfd75/fonttools-4.54.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9c563351ddc230725c4bdf7d9e1e92cbe6ae8553942bd1fb2b2ff0884e8b714", size = 5029455 }, - { url = "https://files.pythonhosted.org/packages/e0/09/241aa498587889576838aa73c78d22b70ce06970807a5475d372baa7ccb7/fonttools-4.54.1-cp312-cp312-win32.whl", hash = "sha256:fdb062893fd6d47b527d39346e0c5578b7957dcea6d6a3b6794569370013d9ac", size = 2154411 }, - { url = "https://files.pythonhosted.org/packages/b9/0a/a57caaff3bc880779317cb157e5b49dc47fad54effe027016abd355b0651/fonttools-4.54.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4564cf40cebcb53f3dc825e85910bf54835e8a8b6880d59e5159f0f325e637e", size = 2200412 }, - { url = "https://files.pythonhosted.org/packages/05/3d/cc515cae84a11d696f2cb7c139a90997b15f02e2e97ec09a5d79302cbcd7/fonttools-4.54.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6e37561751b017cf5c40fce0d90fd9e8274716de327ec4ffb0df957160be3bff", size = 2749174 }, - { url = "https://files.pythonhosted.org/packages/03/03/05d4b22d1a674d066380657f60bbc0eda2d206446912e676d1a33a206878/fonttools-4.54.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:357cacb988a18aace66e5e55fe1247f2ee706e01debc4b1a20d77400354cddeb", size = 2246267 }, - { url = "https://files.pythonhosted.org/packages/52/c3/bb6086adb675e8b0963a7dbb7769e7118c95b687dd318cd660aefd4b4c8c/fonttools-4.54.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e953cc0bddc2beaf3a3c3b5dd9ab7554677da72dfaf46951e193c9653e515a", size = 4855090 }, - { url = "https://files.pythonhosted.org/packages/80/a1/d7192b6a104e3f9ea8e5b1c3463a6240399f0fa826a782eff636cbe0495a/fonttools-4.54.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58d29b9a294573d8319f16f2f79e42428ba9b6480442fa1836e4eb89c4d9d61c", size = 5005449 }, - { url = "https://files.pythonhosted.org/packages/5a/6c/ecfd5c6cd8c9006e85b128d073af26bb263e8aa47506374cb14b25bcf65f/fonttools-4.54.1-cp313-cp313-win32.whl", hash = "sha256:9ef1b167e22709b46bf8168368b7b5d3efeaaa746c6d39661c1b4405b6352e58", size = 2152496 }, - { url = "https://files.pythonhosted.org/packages/63/da/f7a1d837de419e3d4cccbd0dbf53c7399f610f65ceb9bcbf2480f3ae7950/fonttools-4.54.1-cp313-cp313-win_amd64.whl", hash = "sha256:262705b1663f18c04250bd1242b0515d3bbae177bee7752be67c979b7d47f43d", size = 2197257 }, - { url = "https://files.pythonhosted.org/packages/99/14/298292fce6f163f04ec31a79bb6627d9ca85c9874d402f33415ebae313f7/fonttools-4.54.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f5b8a096e649768c2f4233f947cf9737f8dbf8728b90e2771e2497c6e3d21d13", size = 2769825 }, - { url = "https://files.pythonhosted.org/packages/86/dc/acf23baaefac9893d99f5a7dc3396ecfbc4747597075009c8b6452e4b2a6/fonttools-4.54.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4e10d2e0a12e18f4e2dd031e1bf7c3d7017be5c8dbe524d07706179f355c5dac", size = 2256120 }, - { url = "https://files.pythonhosted.org/packages/28/bc/9c57b3f19a4178318e9f1ee4cb6b5be91a07ef11a2a26716ceed3bebc2cc/fonttools-4.54.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31c32d7d4b0958600eac75eaf524b7b7cb68d3a8c196635252b7a2c30d80e986", size = 4578956 }, - { url = "https://files.pythonhosted.org/packages/8c/e7/24870ef7d4014b7904a3b9911199ffe04532d1fb73cf70856471f9f8b252/fonttools-4.54.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c39287f5c8f4a0c5a55daf9eaf9ccd223ea59eed3f6d467133cc727d7b943a55", size = 4637480 }, - { url = "https://files.pythonhosted.org/packages/5d/41/c72f79b24969d04c14bd543faaa3a126d71114eb0e896227e1692a39bec2/fonttools-4.54.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a7a310c6e0471602fe3bf8efaf193d396ea561486aeaa7adc1f132e02d30c4b9", size = 4572104 }, - { url = "https://files.pythonhosted.org/packages/8b/47/b897833f6d659147498517fef95b8978a2125da11392983e0f3acf4671a9/fonttools-4.54.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d3b659d1029946f4ff9b6183984578041b520ce0f8fb7078bb37ec7445806b33", size = 4744962 }, - { url = "https://files.pythonhosted.org/packages/40/ea/61664ee6a587fe59dd67224d3939a3e253e012bbf19b905b934a8c306cf9/fonttools-4.54.1-cp39-cp39-win32.whl", hash = "sha256:e96bc94c8cda58f577277d4a71f51c8e2129b8b36fd05adece6320dd3d57de8a", size = 2167431 }, - { url = "https://files.pythonhosted.org/packages/3c/87/566f79796150029bfce1c93c10adb1c46017fac2caac3996a0a6f73c96e1/fonttools-4.54.1-cp39-cp39-win_amd64.whl", hash = "sha256:e8a4b261c1ef91e7188a30571be6ad98d1c6d9fa2427244c545e2fa0a2494dd7", size = 2211153 }, - { url = "https://files.pythonhosted.org/packages/57/5e/de2e6e51cb6894f2f2bc2641f6c845561361b622e96df3cca04df77222c9/fonttools-4.54.1-py3-none-any.whl", hash = "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd", size = 1096920 }, +version = "4.55.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4e/053fe1b5c0ce346c0a9d0557492c654362bafb14f026eae0d3ee98009152/fonttools-4.55.0.tar.gz", hash = "sha256:7636acc6ab733572d5e7eec922b254ead611f1cdad17be3f0be7418e8bfaca71", size = 3490431 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/8c/57600ebff0b2119b725bc11eeea32b17b0220f3fae71b5fff082a1891270/fonttools-4.55.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:51c029d4c0608a21a3d3d169dfc3fb776fde38f00b35ca11fdab63ba10a16f61", size = 2770301 }, + { url = "https://files.pythonhosted.org/packages/02/94/dff7e57a751918b133a303418202b4f43e3dc3c887e2a648089e0463b1a7/fonttools-4.55.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bca35b4e411362feab28e576ea10f11268b1aeed883b9f22ed05675b1e06ac69", size = 2295806 }, + { url = "https://files.pythonhosted.org/packages/09/31/ff18d79d449510850fe4a96c0ba50ee6d0b9b815a6b5a2489d809e9a8db5/fonttools-4.55.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ce4ba6981e10f7e0ccff6348e9775ce25ffadbee70c9fd1a3737e3e9f5fa74f", size = 4577709 }, + { url = "https://files.pythonhosted.org/packages/c4/03/8136887d1b0b7a9831c7e8e2598c0e5851e31cc2231295769350349a236b/fonttools-4.55.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31d00f9852a6051dac23294a4cf2df80ced85d1d173a61ba90a3d8f5abc63c60", size = 4633411 }, + { url = "https://files.pythonhosted.org/packages/a7/37/86ac06a7505e57de2daaf0a1cc885b7767c74d376ef2cf82933e8ef79399/fonttools-4.55.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e198e494ca6e11f254bac37a680473a311a88cd40e58f9cc4dc4911dfb686ec6", size = 4572887 }, + { url = "https://files.pythonhosted.org/packages/0d/85/1e429359d1842a104b638433587ff62d9dc8339a8c467787087962502a53/fonttools-4.55.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7208856f61770895e79732e1dcbe49d77bd5783adf73ae35f87fcc267df9db81", size = 4745036 }, + { url = "https://files.pythonhosted.org/packages/81/65/763ac1fe2a3e52220f7a7fd2a5de0c784045e773aa9d299450019ac66f9e/fonttools-4.55.0-cp310-cp310-win32.whl", hash = "sha256:e7e6a352ff9e46e8ef8a3b1fe2c4478f8a553e1b5a479f2e899f9dc5f2055880", size = 2170126 }, + { url = "https://files.pythonhosted.org/packages/3e/67/93939482715e629c4bd6fd1f3d154c1bf45b81ee383f50e44d31fa542f83/fonttools-4.55.0-cp310-cp310-win_amd64.whl", hash = "sha256:636caaeefe586d7c84b5ee0734c1a5ab2dae619dc21c5cf336f304ddb8f6001b", size = 2213882 }, + { url = "https://files.pythonhosted.org/packages/17/50/75461e050ded02b9eaa8097df52c2a8752cf4c24db8b44b150755b76c8f1/fonttools-4.55.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fa34aa175c91477485c44ddfbb51827d470011e558dfd5c7309eb31bef19ec51", size = 2771444 }, + { url = "https://files.pythonhosted.org/packages/de/5e/98130db3770e8d12f70aa61f2555c32284d4e9c592862469d32b7ee48626/fonttools-4.55.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:37dbb3fdc2ef7302d3199fb12468481cbebaee849e4b04bc55b77c24e3c49189", size = 2296439 }, + { url = "https://files.pythonhosted.org/packages/17/35/36fe271296fe7624811f5261a0662155e075b43b79ffacea85a03f36593d/fonttools-4.55.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5263d8e7ef3c0ae87fbce7f3ec2f546dc898d44a337e95695af2cd5ea21a967", size = 4883141 }, + { url = "https://files.pythonhosted.org/packages/47/2b/9bf7527260d265281dd812951aa22f3d1c331bcc91e86e7038dc6b9737cb/fonttools-4.55.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f307f6b5bf9e86891213b293e538d292cd1677e06d9faaa4bf9c086ad5f132f6", size = 4931050 }, + { url = "https://files.pythonhosted.org/packages/0b/7b/7324d3aa8424c71b63ba2e76eb4a46d6947e23065996e755c1682e666f42/fonttools-4.55.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f0a4b52238e7b54f998d6a56b46a2c56b59c74d4f8a6747fb9d4042190f37cd3", size = 4894154 }, + { url = "https://files.pythonhosted.org/packages/2c/53/a54926be69e43d277877106a6cbfab467cb02f9c756258c7c9932e8eb382/fonttools-4.55.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3e569711464f777a5d4ef522e781dc33f8095ab5efd7548958b36079a9f2f88c", size = 5064715 }, + { url = "https://files.pythonhosted.org/packages/0c/f7/9602868af9a2dfc4659637a752da8691655e81a2d6138231dcaa1efe8840/fonttools-4.55.0-cp311-cp311-win32.whl", hash = "sha256:2b3ab90ec0f7b76c983950ac601b58949f47aca14c3f21eed858b38d7ec42b05", size = 2169536 }, + { url = "https://files.pythonhosted.org/packages/30/57/9e2ddd16ad84ab26616ae4346b3b15e9a50669ca1b442cbe760af073807c/fonttools-4.55.0-cp311-cp311-win_amd64.whl", hash = "sha256:aa046f6a63bb2ad521004b2769095d4c9480c02c1efa7d7796b37826508980b6", size = 2215265 }, + { url = "https://files.pythonhosted.org/packages/ec/79/38209f8f6235021b6209147ec7b2f748afde65c59c6274ac96fef3912094/fonttools-4.55.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:838d2d8870f84fc785528a692e724f2379d5abd3fc9dad4d32f91cf99b41e4a7", size = 2765205 }, + { url = "https://files.pythonhosted.org/packages/e3/07/434a21eab80524613c9753db2ff21d6bc3cf264412d8833a85022fd39088/fonttools-4.55.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f46b863d74bab7bb0d395f3b68d3f52a03444964e67ce5c43ce43a75efce9246", size = 2293908 }, + { url = "https://files.pythonhosted.org/packages/c8/63/aa3274d9be36aaaef8c087e413cbc1dd682ff94776a82c111bad88482947/fonttools-4.55.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33b52a9cfe4e658e21b1f669f7309b4067910321757fec53802ca8f6eae96a5a", size = 4795901 }, + { url = "https://files.pythonhosted.org/packages/fc/0b/dbe13f2c8d745ffdf5c2bc25391263927d4ec2b927e44d5d5f70cd372873/fonttools-4.55.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:732a9a63d6ea4a81b1b25a1f2e5e143761b40c2e1b79bb2b68e4893f45139a40", size = 4879252 }, + { url = "https://files.pythonhosted.org/packages/46/85/eefb400ec66e9e7c159d13c72aba473d9c2a0c556d812b0916418aa9019e/fonttools-4.55.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7dd91ac3fcb4c491bb4763b820bcab6c41c784111c24172616f02f4bc227c17d", size = 4773177 }, + { url = "https://files.pythonhosted.org/packages/93/75/f06d175df4d7dbad97061c8698210ce4231cce9aa56cc263f3b6b5340540/fonttools-4.55.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1f0e115281a32ff532118aa851ef497a1b7cda617f4621c1cdf81ace3e36fb0c", size = 5032809 }, + { url = "https://files.pythonhosted.org/packages/78/eb/f3520ba63b5e4a034f2bfd34d8ab32eb95a1bf37a1f792ea48461fba08f6/fonttools-4.55.0-cp312-cp312-win32.whl", hash = "sha256:6c99b5205844f48a05cb58d4a8110a44d3038c67ed1d79eb733c4953c628b0f6", size = 2157762 }, + { url = "https://files.pythonhosted.org/packages/aa/d1/5f007861cab890f2a35a19a1d2a2815655ec10b0ea7fd881b1d3aaab0076/fonttools-4.55.0-cp312-cp312-win_amd64.whl", hash = "sha256:f8c8c76037d05652510ae45be1cd8fb5dd2fd9afec92a25374ac82255993d57c", size = 2203746 }, + { url = "https://files.pythonhosted.org/packages/c3/87/a669ac26c6077e37ffb06abf29c5571789eefe518d06c52df392181ee694/fonttools-4.55.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8118dc571921dc9e4b288d9cb423ceaf886d195a2e5329cc427df82bba872cd9", size = 2752519 }, + { url = "https://files.pythonhosted.org/packages/0c/e9/4822ad238fe215133c7df20f1cdb1a58cfb634a31523e77ff0fb2033970a/fonttools-4.55.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01124f2ca6c29fad4132d930da69158d3f49b2350e4a779e1efbe0e82bd63f6c", size = 2286819 }, + { url = "https://files.pythonhosted.org/packages/3e/a4/d7941c3897129e60fe68d20e4819fda4d0c4858d77badae0e80ca6440b36/fonttools-4.55.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ffd58d2691f11f7c8438796e9f21c374828805d33e83ff4b76e4635633674c", size = 4770382 }, + { url = "https://files.pythonhosted.org/packages/31/cf/c51ea1348f9fba9c627439afad9dee0090040809ab431f4422b5bfdda34c/fonttools-4.55.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5435e5f1eb893c35c2bc2b9cd3c9596b0fcb0a59e7a14121562986dd4c47b8dd", size = 4858336 }, + { url = "https://files.pythonhosted.org/packages/73/be/36c1fe0e5c9a96b068ddd7e82001243bbe7fe12549c8d14e1bd025bf40c9/fonttools-4.55.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d12081729280c39d001edd0f4f06d696014c26e6e9a0a55488fabc37c28945e4", size = 4756072 }, + { url = "https://files.pythonhosted.org/packages/5c/18/6dd381c29f215a017f79aa9fea0722424a0046b47991c4390a78ff87ce0c/fonttools-4.55.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a7ad1f1b98ab6cb927ab924a38a8649f1ffd7525c75fe5b594f5dab17af70e18", size = 5008668 }, + { url = "https://files.pythonhosted.org/packages/b8/95/316f20092b389b927dba1d1dccd3f541853f96e707e210f1b9f4e7bacdd5/fonttools-4.55.0-cp313-cp313-win32.whl", hash = "sha256:abe62987c37630dca69a104266277216de1023cf570c1643bb3a19a9509e7a1b", size = 2155841 }, + { url = "https://files.pythonhosted.org/packages/35/ca/b4638aa3e446184892e2f9cc8ef44bb506f47fea04580df7fb84f5a4363d/fonttools-4.55.0-cp313-cp313-win_amd64.whl", hash = "sha256:2863555ba90b573e4201feaf87a7e71ca3b97c05aa4d63548a4b69ea16c9e998", size = 2200587 }, + { url = "https://files.pythonhosted.org/packages/ca/83/12c26ce25df9de2d247c31f27cddd1acd08078ad18631032db6ce946f01e/fonttools-4.55.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f901cef813f7c318b77d1c5c14cf7403bae5cb977cede023e22ba4316f0a8f6", size = 2773168 }, + { url = "https://files.pythonhosted.org/packages/db/19/03e7de9889c668e19c34bfb6c261252294b6ddeb06cd5f9864bf01f162a1/fonttools-4.55.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8c9679fc0dd7e8a5351d321d8d29a498255e69387590a86b596a45659a39eb0d", size = 2297131 }, + { url = "https://files.pythonhosted.org/packages/e3/9d/5f981c69f99d07e59a7f2f58efa91e87ffc3bbd548a2979704a3382f53df/fonttools-4.55.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd2820a8b632f3307ebb0bf57948511c2208e34a4939cf978333bc0a3f11f838", size = 4582322 }, + { url = "https://files.pythonhosted.org/packages/1d/3e/0841e7bf38ad317c960992dd03bac041899a1c21396013e6ddcfd2bc48c5/fonttools-4.55.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23bbbb49bec613a32ed1b43df0f2b172313cee690c2509f1af8fdedcf0a17438", size = 4640834 }, + { url = "https://files.pythonhosted.org/packages/3a/0f/39e95369fae73e06b5110fdc245f71c82f2d6870a2cef96440045a2a3b23/fonttools-4.55.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a656652e1f5d55b9728937a7e7d509b73d23109cddd4e89ee4f49bde03b736c6", size = 4575466 }, + { url = "https://files.pythonhosted.org/packages/5e/e6/fed351dec03c335eeaf3d276c1b3995c33c59bde0ed7911bc8d55661a41b/fonttools-4.55.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f50a1f455902208486fbca47ce33054208a4e437b38da49d6721ce2fef732fcf", size = 4748309 }, + { url = "https://files.pythonhosted.org/packages/c2/8c/6295c8b395f26b7c6be42ac55308b704b4c0709a2e7770c54d64810150c1/fonttools-4.55.0-cp39-cp39-win32.whl", hash = "sha256:161d1ac54c73d82a3cded44202d0218ab007fde8cf194a23d3dd83f7177a2f03", size = 2170761 }, + { url = "https://files.pythonhosted.org/packages/9b/fa/0bd359e011f71afb11f33d8f7adc9cd81213a42c8e62d05ba75befd228ad/fonttools-4.55.0-cp39-cp39-win_amd64.whl", hash = "sha256:ca7fd6987c68414fece41c96836e945e1f320cda56fc96ffdc16e54a44ec57a2", size = 2214479 }, + { url = "https://files.pythonhosted.org/packages/b4/4a/786589606d4989cb34d8bc766cd687d955aaf3039c367fe7104bcf82dc98/fonttools-4.55.0-py3-none-any.whl", hash = "sha256:12db5888cd4dd3fcc9f0ee60c6edd3c7e1fd44b7dd0f31381ea03df68f8a153f", size = 1100249 }, +] + +[[package]] +name = "fs" +version = "2.4.16" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appdirs" }, + { name = "setuptools" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5d/a9/af5bfd5a92592c16cdae5c04f68187a309be8a146b528eac3c6e30edbad2/fs-2.4.16.tar.gz", hash = "sha256:ae97c7d51213f4b70b6a958292530289090de3a7e15841e108fbe144f069d313", size = 187441 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/5c/a3d95dc1ec6cdeb032d789b552ecc76effa3557ea9186e1566df6aac18df/fs-2.4.16-py2.py3-none-any.whl", hash = "sha256:660064febbccda264ae0b6bace80a8d1be9e089e0a5eb2427b7d517f9a91545c", size = 135261 }, ] [[package]] @@ -704,14 +764,14 @@ wheels = [ [[package]] name = "jedi" -version = "0.19.1" +version = "0.19.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "parso" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d6/99/99b493cec4bf43176b678de30f81ed003fd6a647a301b9c927280c600f0a/jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", size = 1227821 } +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/20/9f/bc63f0f0737ad7a60800bfd472a4836661adae21f9c2535f3957b1e54ceb/jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0", size = 1569361 }, + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, ] [[package]] @@ -902,6 +962,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b0/bf/ea8887e9f31a8f93ca306699d11909c6140151393a4216f0d9f85a004077/latexcodec-3.0.0-py3-none-any.whl", hash = "sha256:6f3477ad5e61a0a99bd31a6a370c34e88733a6bad9c921a3ffcfacada12f41a7", size = 18150 }, ] +[[package]] +name = "latextools" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fs" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/96/35c67a8a318c782a9d36ce6dae30c4f441aff1c4341040fa9a873e6fb216/latextools-0.5.0-py3-none-any.whl", hash = "sha256:6e6bb6c8c98ca3e11a84da724c5c081cdc78ff29aaadbaadbe5ef66d327aa4bd", size = 27267 }, +] + [[package]] name = "ldpc" version = "0.1.60" @@ -1132,10 +1203,11 @@ wheels = [ [[package]] name = "mqt-qecc" -version = "1.8.2.dev93+gfb2c93f.d20241108" +version = "1.8.3.dev8+g033066f" source = { editable = "." } dependencies = [ { name = "bposd" }, + { name = "fastcore" }, { name = "ldpc" }, { name = "multiprocess" }, { name = "numba" }, @@ -1144,8 +1216,9 @@ dependencies = [ { name = "qecsim" }, { name = "qiskit", extra = ["qasm3-import"] }, { name = "qiskit-aer" }, + { name = "qsample" }, { name = "stim" }, - { name = "stimbposd" }, + { name = "urllib3" }, { name = "z3-solver" }, ] @@ -1197,6 +1270,7 @@ visualization = [ [package.metadata] requires-dist = [ { name = "bposd", specifier = ">=1.6" }, + { name = "fastcore", specifier = ">=1.7.10" }, { name = "furo", marker = "extra == 'docs'", specifier = ">=2023.9.10" }, { name = "ipykernel", marker = "extra == 'docs'" }, { name = "ldpc", specifier = ">=0.1.53,<2" }, @@ -1218,6 +1292,7 @@ requires-dist = [ { name = "qiskit", extras = ["qasm3-import"], specifier = ">=1.0.0" }, { name = "qiskit", extras = ["visualization"], marker = "extra == 'docs'" }, { name = "qiskit-aer", specifier = ">=0.15.0" }, + { name = "qsample", specifier = ">=0.0.2" }, { name = "scipy", marker = "extra == 'visualization'" }, { name = "setuptools-scm", marker = "extra == 'docs'", specifier = ">=8.1" }, { name = "sphinx-autodoc-typehints", marker = "extra == 'docs'" }, @@ -1225,7 +1300,7 @@ requires-dist = [ { name = "sphinxcontrib-bibtex", marker = "extra == 'docs'", specifier = ">=2.4.2" }, { name = "sphinxext-opengraph", marker = "extra == 'docs'", specifier = ">=0.9" }, { name = "stim", specifier = ">=1.13.0" }, - { name = "stimbposd" }, + { name = "urllib3", specifier = ">=1.26.20,<2.0" }, { name = "z3-solver", specifier = ">=4.12" }, ] @@ -1421,11 +1496,11 @@ wheels = [ [[package]] name = "openqasm3" -version = "0.5.0" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/f1/c63ef1778a387a3377f2a9ca6be497303745ee634e5b9f3cfd0776f40d76/openqasm3-0.5.0.tar.gz", hash = "sha256:bf8bf4ed098393447e552eaea18b0a34a2429d228477683d6b579348bc17bfc8", size = 517167 } +sdist = { url = "https://files.pythonhosted.org/packages/a3/30/9e366c43b71b496d0efbfbc1f644a2839c5d972fca042cfa079e849fab2d/openqasm3-1.0.0.tar.gz", hash = "sha256:3f2bb1cca855cff114e046bac22d59adbf9b754cac6398961aa6d22588fb688e", size = 534507 } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/91/574addbe722736081d1b9c78212f8cac5e9d93c8bc79059c84871034c527/openqasm3-0.5.0-py3-none-any.whl", hash = "sha256:40991ac057b9e3c208d1b34242b0aad8a3b9840df0335a652b1e4e4248937b1c", size = 524019 }, + { url = "https://files.pythonhosted.org/packages/40/5a/e33f705f0ea2a83fd6c797eddf5b5a5cd2256a4f31dcb9624f055f6e14bf/openqasm3-1.0.0-py3-none-any.whl", hash = "sha256:d4371737b4a49b0d56248ed3d30766a94000bccfb43303ec9c7ead351a1b6cc3", size = 539775 }, ] [package.optional-dependencies] @@ -1637,6 +1712,19 @@ 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 = "projectq" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "matplotlib" }, + { name = "networkx" }, + { name = "numpy" }, + { name = "requests" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/30/88/48c8347cadf6afb7f329e7c06d30880159e2a50b6e8a643c7667c26ffaf0/projectq-0.8.0.tar.gz", hash = "sha256:0bcd242afabe947ac4737dffab1de62628b84125ee6ccb3ec23bd4f1d082ec60", size = 433667 } + [[package]] name = "prompt-toolkit" version = "3.0.48" @@ -2129,15 +2217,38 @@ wheels = [ [[package]] name = "qiskit-qasm3-import" -version = "0.5.0" +version = "0.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "openqasm3", extra = ["parser"] }, { name = "qiskit" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/69/40/e6ea9dc59d50bbf5ca61e695cd986ded1386ab65f6bfb0181144555d7c1f/qiskit_qasm3_import-0.5.0.tar.gz", hash = "sha256:d8d39ac176eaa7f2414dab897ff449ea1e5d854230b262b21724d138939a6476", size = 34063 } +sdist = { url = "https://files.pythonhosted.org/packages/f4/a7/0c5241d05e999b0f13e89241b4c2c2c488add7f3240642612591fdd4f2d8/qiskit_qasm3_import-0.5.1.tar.gz", hash = "sha256:334fff0080667fe9cb39e807b0875a2658b01d33b4c964a8816411b30938c107", size = 34055 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cd/1d/12529a4ab9910ab15409ac79fff32a729cf54d65187b386954a52fd84f2b/qiskit_qasm3_import-0.5.0-py3-none-any.whl", hash = "sha256:137f98e870160dc274eb920603c1c0032f2534b5e365b0243e57b25dfee46f61", size = 27620 }, + { url = "https://files.pythonhosted.org/packages/c2/f2/d061b1eb3edd70b4503c06ebe94e087d089de01187b7b5d8d99a43df010a/qiskit_qasm3_import-0.5.1-py3-none-any.whl", hash = "sha256:ba6cc1ce3b142c069be07e945816a4bc1458fafe950df4f0eb15ae97d5275102", size = 27614 }, +] + +[[package]] +name = "qsample" +version = "0.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anytree" }, + { name = "chp-sim" }, + { name = "dill" }, + { name = "latextools" }, + { name = "matplotlib" }, + { name = "networkx" }, + { name = "numpy" }, + { name = "projectq" }, + { name = "pydot" }, + { name = "scipy" }, + { name = "simpleeval" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bb/55/c0d0a6ab89c17dfe294425ec3cd32bebf61a8d23864383fca4f5cae856f8/qsample-0.0.2.tar.gz", hash = "sha256:92be0415d3ef45b574fc57f4eb242f5a0c182a4028029c2b18cc14bb42e33102", size = 43847 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/25/8dd8096cad59b98de59737c7ff7bfb9535d86216c5a95e403d06fc005c7e/qsample-0.0.2-py3-none-any.whl", hash = "sha256:b6a85139dec3ab69e49b18b1b2f608814415efd2d07875b278a3644a42db58d2", size = 44643 }, ] [[package]] @@ -2170,9 +2281,9 @@ wheels = [ [[package]] name = "rpds-py" -version = "0.21.0" +version = "0.20.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/23/80/afdf96daf9b27d61483ef05b38f282121db0e38f5fd4e89f40f5c86c2a4f/rpds_py-0.21.0.tar.gz", hash = "sha256:ed6378c9d66d0de903763e7706383d60c33829581f0adff47b6535f1802fa6db", size = 26335 } +sdist = { url = "https://files.pythonhosted.org/packages/25/cb/8e919951f55d109d658f81c9b49d0cc3b48637c50792c5d2e77032b8c5da/rpds_py-0.20.1.tar.gz", hash = "sha256:e1791c4aabd117653530dccd24108fa03cc6baf21f58b950d0a73c3b3b29a350", size = 25931 } wheels = [ { url = "https://files.pythonhosted.org/packages/4c/a4/91747f902f166c589f1753cbd8bda713aceb75817c8bb597058a38aa85e6/rpds_py-0.21.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a017f813f24b9df929674d0332a374d40d7f0162b326562daae8066b502d0590", size = 327473 }, { url = "https://files.pythonhosted.org/packages/8a/72/75a30a07f96ae210e732c50c7339e742945fdc83661e65a1c80fcf39ceea/rpds_py-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:20cc1ed0bcc86d8e1a7e968cce15be45178fd16e2ff656a243145e0b439bd250", size = 318359 }, @@ -2338,11 +2449,11 @@ wheels = [ [[package]] name = "setuptools" -version = "75.3.0" +version = "75.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ed/22/a438e0caa4576f8c383fa4d35f1cc01655a46c75be358960d815bfbb12bd/setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686", size = 1351577 } +sdist = { url = "https://files.pythonhosted.org/packages/c8/db/722a42ffdc226e950c4757b3da7b56ff5c090bb265dccd707f7b8a3c6fee/setuptools-75.5.0.tar.gz", hash = "sha256:5c4ccb41111392671f02bb5f8436dfc5a9a7185e80500531b133f5775c4163ef", size = 1336032 } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/12/282ee9bce8b58130cb762fbc9beabd531549952cac11fc56add11dcb7ea0/setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd", size = 1251070 }, + { url = "https://files.pythonhosted.org/packages/fe/df/88ccbee85aefbca071db004fdc8f8d2507d55d5a9dc27ebb93c92edb1bd8/setuptools-75.5.0-py3-none-any.whl", hash = "sha256:87cb777c3b96d638ca02031192d40390e0ad97737e27b6b4fa831bea86f2f829", size = 1222710 }, ] [[package]] @@ -2360,6 +2471,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a0/b9/1906bfeb30f2fc13bb39bf7ddb8749784c05faadbd18a21cf141ba37bff2/setuptools_scm-8.1.0-py3-none-any.whl", hash = "sha256:897a3226a6fd4a6eb2f068745e49733261a21f70b1bb28fce0339feb978d9af3", size = 43666 }, ] +[[package]] +name = "simpleeval" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/6f/15be211749430f52f2c8f0c69158a6fc961c03aac93fa28d44d1a6f5ebc7/simpleeval-1.0.3.tar.gz", hash = "sha256:67bbf246040ac3b57c29cf048657b9cf31d4e7b9d6659684daa08ca8f1e45829", size = 24358 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/e9/e58082fbb8cecbb6fb4133033c40cc50c248b1a331582be3a0f39138d65b/simpleeval-1.0.3-py3-none-any.whl", hash = "sha256:e3bdbb8c82c26297c9a153902d0fd1858a6c3774bf53ff4f134788c3f2035c38", size = 15762 }, +] + [[package]] name = "sinter" version = "1.14.0" @@ -2600,21 +2720,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0b/73/a0db8eb3e200a703d476a8c9091caee71b00d324d6bcdf3fe085dbfbe8ad/stim-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:19b4aab97e347bafc03d95231025cab5abc93151611b6a811ccf4f13df86cd66", size = 2586106 }, ] -[[package]] -name = "stimbposd" -version = "0.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ldpc" }, - { name = "numpy" }, - { name = "sinter" }, - { name = "stim" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/de/42/4dcfb18c8ec6809236817fc0ee1016b2999266dad84e807afd2fcc2fd446/stimbposd-0.0.1.tar.gz", hash = "sha256:a9a62651e5699a31e2b52c299d23d0af7fecdd7ff99dcd31ed393041f36bf6b4", size = 35089 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/e9/5a6a7f6e10db5b40d05e4deb6e0966a39f103bf0195aab4a82a47fe0941f/stimbposd-0.0.1-py3-none-any.whl", hash = "sha256:2d2519a66d6d8fef6ce08ab052380d3aac54462f3caf7b7c3b73b6ae38cc04ce", size = 13155 }, -] - [[package]] name = "symengine" version = "0.13.0" @@ -2684,11 +2789,11 @@ wheels = [ [[package]] name = "tomli" -version = "2.0.2" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", size = 16096 } +sdist = { url = "https://files.pythonhosted.org/packages/1e/e4/1b6cbcc82d8832dd0ce34767d5c560df8a3547ad8cbc427f34601415930a/tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8", size = 16622 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", size = 13237 }, + { url = "https://files.pythonhosted.org/packages/de/f7/4da0ffe1892122c9ea096c57f64c2753ae5dd3ce85488802d11b0992cc6d/tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391", size = 13750 }, ] [[package]] @@ -2750,11 +2855,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.2.3" +version = "1.26.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +sdist = { url = "https://files.pythonhosted.org/packages/e4/e8/6ff5e6bc22095cfc59b6ea711b687e2b7ed4bdb373f7eeec370a97d7392f/urllib3-1.26.20.tar.gz", hash = "sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32", size = 307380 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, + { url = "https://files.pythonhosted.org/packages/33/cf/8435d5a7159e2a9c83a95896ed596f68cf798005fe107cc655b5c5c14704/urllib3-1.26.20-py2.py3-none-any.whl", hash = "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e", size = 144225 }, ] [[package]] @@ -2791,9 +2896,9 @@ wheels = [ [[package]] name = "zipp" -version = "3.20.2" +version = "3.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", size = 24199 } +sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545 } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", size = 9200 }, + { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630 }, ]