From 6d70fecd396a17dcc348b4c2cc9dc7b2775ed97b Mon Sep 17 00:00:00 2001 From: Filippo Miatto Date: Sun, 28 Jan 2024 14:33:27 -0800 Subject: [PATCH 01/30] Create wires.py Part of MM 1.0 refactor --- mrmustard/lab/utils/wires.py | 321 +++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 mrmustard/lab/utils/wires.py diff --git a/mrmustard/lab/utils/wires.py b/mrmustard/lab/utils/wires.py new file mode 100644 index 000000000..7fa20bb3e --- /dev/null +++ b/mrmustard/lab/utils/wires.py @@ -0,0 +1,321 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""`Wires` class for handling the connectivity of an object in a circuit.""" + +from __future__ import annotations + +from typing import Iterable, Optional +import numpy as np +from mrmustard import settings + +# pylint: disable=protected-access + + +class Wires: + r"""`Wires` class for handling the connectivity of an object in a circuit. + In MrMustard, ``CircuitComponent``s have a ``Wires`` object as attribute + to handle the wires of the component and to connect components together. + + Wires are arranged into four groups, and each of the groups can + span multiple modes: + _______________ + input bra modes --->| circuit |---> output bra modes + input ket modes --->| component |---> output ket modes + --------------- + Each of the four groups can be empty. In particular, the wires of a state have + no inputs and the wires of a measurement have no outputs. Similarly, + a standard unitary transformation has no bra wires. + + We refer to these four groups in a "standard order": + 0. output_bra for all modes + 1. input_bra for all modes + 2. output_ket for all modes + 3. input_ket for all modes + + A ``Wires`` object can return subsets (views) of itself. Available subsets are: + - input/output (wires on input/output side) + - bra/ket (wires on bra/ket side) + - modes (wires on the given modes) + + For example, ``wires.input`` returns a ``Wires`` object with only the input wires + (on bra and ket sides and on all the modes). + Note that these can be combined together: ``wires.input.bra[(1,2)] returns a + ``Wires`` object with only the input bra wires on modes 1 and 2. + Note these are views of the original ``Wires`` object, i.e. we can set the ``ids`` on the + views and it will be set on the original, e.g. this is a valid way to connect two sets + of wires by setting their ids to be equal: ``wires1.output.ids = wires2.input.ids``. + + A very useful feature of the ``Wires`` class is the support for the right shift + operator ``>>``. This allows us to connect two ``Wires`` objects together as + ``wires1 >> wires2``. This will return the ``Wires`` object of the two + wires objects connected together as if they were in a circuit: + ____________ ____________ + in bra --->| wires1 |---> out bra ---> in bra --->| wires2 |---> out bra + in ket --->| |---> out ket ---> in ket --->| |---> out ket + ------------ ------------ + The returned ``Wires`` object will contain the surviving wires of the two + ``Wires`` objects and it will raise an error if there are overlaps between + the surviving wires. This is especially useful for handling the ordering of the + wires when connecting components together: we are always guaranteed that a + ``Wires`` object will provide the wires in the standard order. + + Args: + modes_out_bra (Iterable[int]): The output modes on the bra side. + modes_in_bra (Iterable[int]): The input modes on the bra side. + modes_out_ket (Iterable[int]): The output modes on the ket side. + modes_in_ket (Iterable[int]): The input modes on the ket side. + + Note that the order of the modes passed to initialize the object doesn't matter, + as they get sorted at init time. + """ + + def __init__( + self, + modes_out_bra: Optional[Iterable[int]] = None, + modes_in_bra: Optional[Iterable[int]] = None, + modes_out_ket: Optional[Iterable[int]] = None, + modes_in_ket: Optional[Iterable[int]] = None, + ) -> None: + modes_out_bra = modes_out_bra or [] + modes_in_bra = modes_in_bra or [] + modes_out_ket = modes_out_ket or [] + modes_in_ket = modes_in_ket or [] + + self._modes = sorted( + set(modes_out_bra) | set(modes_in_bra) | set(modes_out_ket) | set(modes_in_ket) + ) + randint = settings.rng.integers # MM random number generator + outbra = {m: randint(1, 2**62) if m in modes_out_bra else 0 for m in self._modes} + inbra = {m: randint(1, 2**62) if m in modes_in_bra else 0 for m in self._modes} + outket = {m: randint(1, 2**62) if m in modes_out_ket else 0 for m in self._modes} + inket = {m: randint(1, 2**62) if m in modes_in_ket else 0 for m in self._modes} + self._id_array = np.array([[outbra[m], inbra[m], outket[m], inket[m]] for m in self._modes]) + self._mask = np.ones_like(self._id_array) # multiplicative mask + + def _args(self): + r"""Returns the same args one needs to initialize this object.""" + ob_modes = np.array(self._modes)[self._id_array[:, 0] > 0].tolist() + ib_modes = np.array(self._modes)[self._id_array[:, 1] > 0].tolist() + ok_modes = np.array(self._modes)[self._id_array[:, 2] > 0].tolist() + ik_modes = np.array(self._modes)[self._id_array[:, 3] > 0].tolist() + return tuple(ob_modes), tuple(ib_modes), tuple(ok_modes), tuple(ik_modes) + + @classmethod + def _from_data(cls, id_array: np.ndarray, modes: list[int], mask=None): + r"""Private class method to initialize Wires object from the given data.""" + w = cls() + w._id_array = id_array + w._modes = modes + w._mask = mask if mask is not None else np.ones_like(w._id_array) + return w + + def _view(self, masked_rows: tuple[int, ...] = (), masked_cols: tuple[int, ...] = ()) -> Wires: + r"""A masked view of this Wires object.""" + w = self._from_data(self._id_array, self._modes, self._mask.copy()) + w._mask[masked_rows, :] = -1 + w._mask[:, masked_cols] = -1 + return w + + def _mode(self, mode: int) -> np.ndarray: + "A slice of the id_array matrix at the given mode." + return np.maximum(0, self.id_array[[self._modes.index(mode)]])[0] + + @property + def id_array(self) -> np.ndarray: + "The id_array of the available wires in the standard order (bra/ket x out/in x mode)." + return self._id_array * self._mask + + @property + def ids(self) -> list[int]: + "The list of ids of the available wires in the standard order." + flat = self.id_array.T.ravel() + return flat[flat > 0].tolist() + + @ids.setter + def ids(self, ids: list[int]): + "Sets the ids of the available wires." + if len(ids) != len(self.ids): + raise ValueError(f"wrong number of ids (expected {len(self.ids)}, got {len(ids)})") + self._id_array.flat[self.id_array.flatten() > 0] = ids + + @property + def modes(self) -> list[int]: + "The set of modes spanned by the populated wires." + return [m for m in self._modes if any(self.id_array[self._modes.index(m)] > 0)] + + @property + def indices(self) -> list[int]: + r"""Returns the array of indices of this subset in the standard order. + (bra/ket x out/in x mode). Use this to get the indices for bargmann contractions. + """ + flat = self.id_array.T.ravel() + flat = flat[flat != 0] + return np.where(flat > 0)[0].tolist() + + @property + def input(self) -> Wires: + "A view of self without output wires" + return self._view(masked_cols=(0, 2)) + + @property + def output(self) -> Wires: + "A view of self without input wires" + return self._view(masked_cols=(1, 3)) + + @property + def ket(self) -> Wires: + "A view of self without bra wires" + return self._view(masked_cols=(0, 1)) + + @property + def bra(self) -> Wires: + "A view of self without ket wires" + return self._view(masked_cols=(2, 3)) + + @property + def adjoint(self) -> Wires: + r""" + The adjoint (ket <-> bra) of this wires object. + """ + return self._from_data(self._id_array[:, [2, 3, 0, 1]], self._modes, self._mask) + + @property + def dual(self) -> Wires: + r""" + The dual (in <-> out) of this wires object. + """ + return self._from_data(self._id_array[:, [1, 0, 3, 2]], self._modes, self._mask) + + def copy(self) -> Wires: + r"""A copy of this Wires object with new ids.""" + w = Wires(*self._args()) + w._mask = self._mask.copy() + return w + + def __bool__(self) -> bool: + return True if len(self.ids) > 0 else False + + def __getitem__(self, modes: Iterable[int] | int) -> Wires: + "A view of this Wires object with wires only on the given modes." + modes = [modes] if isinstance(modes, int) else modes + idxs = tuple(list(self._modes).index(m) for m in set(self._modes).difference(modes)) + return self._view(masked_rows=idxs) + + def __lshift__(self, other: Wires) -> Wires: + return (other.dual >> self.dual).dual # how cool is this + + def __rshift__(self, other: Wires) -> Wires: + r"""Returns a new Wires object with the wires of self and other combined as two + components in a circuit where the output of self connects to the input of other: + ``self >> other`` + All surviving wires are arranged in the standard order. + A ValueError is raised if there are any surviving wires that overlap, which is the only + possible way two objects aren't compatible in a circuit.""" + all_modes = sorted(set(self.modes) | set(other.modes)) + new_id_array = np.zeros((len(all_modes), 4), dtype=np.int64) + for i, m in enumerate(all_modes): + if m in self.modes and m in other.modes: + # m-th row of self and other (and self output bra = sob, etc...) + sob, sib, sok, sik = self._mode(m) + oob, oib, ook, oik = other._mode(m) + errors = { + "output bra": sob and oob and not oib, + "output ket": sok and ook and not oik, + "input bra": oib and sib and not sob, + "input ket": oik and sik and not sok, + } + if any(errors.values()): + position = [k for k, v in errors.items() if v][0] + raise ValueError(f"{position} wire overlap at mode {m}") + if bool(sob) == bool(oib): # if the inner wires are both there or both not there + new_id_array[i] += np.array([oob, sib, 0, 0]) + elif not sib and not sob: # no wires on self + new_id_array[i] += np.array([oob, oib, 0, 0]) + else: # no wires on other + new_id_array[i] += np.array([sob, sib, 0, 0]) + if bool(sok) == bool(oik): # same as above but on the ket side + new_id_array[i] += np.array([0, 0, ook, sik]) + elif not sik and not sok: + new_id_array[i] += np.array([0, 0, ook, oik]) + else: + new_id_array[i] += np.array([0, 0, sok, sik]) + elif m in self.modes and not m in other.modes: + new_id_array[i] += self._mode(m) + elif m in other.modes and not m in self.modes: + new_id_array[i] += other._mode(m) + return self._from_data(np.abs(new_id_array), all_modes) + + def __repr__(self) -> str: + ob_modes, ib_modes, ok_modes, ik_modes = self._args() + return f"Wires({ob_modes}, {ib_modes}, {ok_modes}, {ik_modes})" + + def _repr_html_(self): # pragma: no cover + "A matrix plot of the id_array." + row_labels = map(str, self._modes) + col_labels = ["bra-out", "bra-in", "ket-out", "ket-in"] + array = np.abs(self.id_array) / (self.id_array + 1e-15) + idxs = (i for i in self.indices) + box_size = "60px" # Set the size of the squares + html = '' + # colors + active = "#5b9bd5" + inactive = "#d6e8f7" + + # Add column headers + html += "" + for label in [""] + col_labels: # Add an empty string for the top-left cell + html += f'' + html += "" + + # Initialize rows with row labels + rows_html = [ + f'' + for label in row_labels + ] + + # Add table cells (column by column) + for label, col in zip(col_labels, array.T): + for row_idx, value in enumerate(col): + color = ( + "white" + if np.isclose(value, 0) + else (active if np.isclose(value, 1) else inactive) + ) + cell_html = f'' + ) + else: + cell_html += '">' + rows_html[row_idx] += cell_html + + # Close the rows and add them to the HTML table + for row_html in rows_html: + row_html += "" + html += row_html + + html += "
{label}
{label}{str(next(idxs))}
" + + try: + from IPython.core.display import display, HTML # pylint: disable=import-outside-toplevel + + display(HTML(html)) + except ImportError as e: + raise ImportError( + "To display the wires in a jupyter notebook you need to `pip install IPython` first." + ) from e From 544cd740b985516b2993ed7e7f1d4b83f902e9b5 Mon Sep 17 00:00:00 2001 From: Filippo Miatto Date: Sun, 28 Jan 2024 14:36:18 -0800 Subject: [PATCH 02/30] adds wires tests --- tests/test_lab/test_wires.py | 96 ++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 tests/test_lab/test_wires.py diff --git a/tests/test_lab/test_wires.py b/tests/test_lab/test_wires.py new file mode 100644 index 000000000..790b2e2fc --- /dev/null +++ b/tests/test_lab/test_wires.py @@ -0,0 +1,96 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests for Wires class.""" + +# pylint: disable=missing-function-docstring +# pylint: disable=protected-access + +import pytest +from mrmustard.lab_dev.wires import Wires + + +def test_wires_view_has_same_ids(): + w = Wires([0], [0], [0], [0]) + assert set(w.ids) == set(w._view().ids) + + +def test_view_can_edit_original(): + w = Wires([0], [0], [0], [0]) + w._view().ids = [9, 99, 999, 9999] + assert w.ids == [9, 99, 999, 9999] + + +def test_wire_subsets(): + w = Wires([0], [1], [2], [3]) + assert w.output.bra.modes == [0] + assert w.input.bra.modes == [1] + assert w.output.ket.modes == [2] + assert w.input.ket.modes == [3] + + +def test_wire_mode_subsets(): + w = Wires([10], [11], [12], [13]) + assert w[10].ids == w.output.bra.ids + assert w[11].ids == w.input.bra.ids + assert w[12].ids == w.output.ket.ids + assert w[13].ids == w.input.ket.ids + + +def test_indices(): + w = Wires([0, 1, 2], [3, 4, 5], [6, 7], [8]) + assert w.output.indices == [0, 1, 2, 6, 7] + assert w.bra.indices == [0, 1, 2, 3, 4, 5] + assert w.input.indices == [3, 4, 5, 8] + assert w.ket.indices == [6, 7, 8] + + +def test_setting_ids(): + w = Wires([0], [0], [0], [0]) + w.ids = [9, 99, 999, 9999] + assert w.ids == [9, 99, 999, 9999] + + +def test_add_wires(): + w1 = Wires([0], [1], [2], [3]) + w2 = Wires([1], [2], [3], [4]) + w12 = Wires([0, 1], [1, 2], [2, 3], [3, 4]) + assert (w1 + w2).modes == w12.modes + + +def test_cant_add_overlapping_wires(): + w1 = Wires([0], [1], [2], [3]) + w2 = Wires([0], [2], [3], [4]) + with pytest.raises(Exception): + w1 + w2 + + +def test_args(): + w = Wires([0], [1], [2], [3]) + assert w._args() == ((0,), (1,), (2,), (3,)) + + +def test_right_shift_general_contraction(): + # contracts 1,1 on bra side + # contracts 3,3 and 13,13 on ket side (note order doesn't matter) + u = Wires([1, 5], [2, 6, 15], [3, 7, 13], [4, 8]) + v = Wires([0, 9, 14], [1, 10], [2, 11], [13, 3, 12]) + assert (u >> v)._args() == ((0, 5, 9, 14), (2, 6, 10, 15), (2, 7, 11), (4, 8, 12)) + + +def test_error_if_cant_contract(): + u = Wires([], [], [0], []) # only output wire + v = Wires([], [], [0], []) # only output wire + with pytest.raises(ValueError): + u >> v From 1a0eee89eb44f0a000016c1bc1c486b0e4256186 Mon Sep 17 00:00:00 2001 From: Filippo Miatto Date: Sun, 28 Jan 2024 14:40:08 -0800 Subject: [PATCH 03/30] blacked --- mrmustard/lab/abstract/measurement.py | 6 ++---- mrmustard/lab/gates.py | 4 +--- mrmustard/lab/utils/wires.py | 9 ++++++--- mrmustard/training/callbacks.py | 6 +++--- mrmustard/utils/typing.py | 3 +-- tests/test_math/test_backend_manager.py | 1 + tests/test_math/test_compactFock.py | 1 + 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/mrmustard/lab/abstract/measurement.py b/mrmustard/lab/abstract/measurement.py index b0f017281..5f3d87bfd 100644 --- a/mrmustard/lab/abstract/measurement.py +++ b/mrmustard/lab/abstract/measurement.py @@ -87,12 +87,10 @@ def outcome(self): ... @abstractmethod - def _measure_fock(self, other: State) -> Union[State, float]: - ... + def _measure_fock(self, other: State) -> Union[State, float]: ... @abstractmethod - def _measure_gaussian(self, other: State) -> Union[State, float]: - ... + def _measure_gaussian(self, other: State) -> Union[State, float]: ... def primal(self, other: State) -> Union[State, float]: """performs the measurement procedure according to the representation of the incoming state""" diff --git a/mrmustard/lab/gates.py b/mrmustard/lab/gates.py index aadba4bde..374cf39df 100644 --- a/mrmustard/lab/gates.py +++ b/mrmustard/lab/gates.py @@ -1041,9 +1041,7 @@ def primal(self, state): coeff = math.cast( math.exp( - -0.5 - * self.phase_stdev.value**2 - * math.arange(-dm.shape[-2] + 1, dm.shape[-1]) ** 2 + -0.5 * self.phase_stdev.value**2 * math.arange(-dm.shape[-2] + 1, dm.shape[-1]) ** 2 ), dm.dtype, ) diff --git a/mrmustard/lab/utils/wires.py b/mrmustard/lab/utils/wires.py index 7fa20bb3e..48b49b12b 100644 --- a/mrmustard/lab/utils/wires.py +++ b/mrmustard/lab/utils/wires.py @@ -241,9 +241,9 @@ def __rshift__(self, other: Wires) -> Wires: raise ValueError(f"{position} wire overlap at mode {m}") if bool(sob) == bool(oib): # if the inner wires are both there or both not there new_id_array[i] += np.array([oob, sib, 0, 0]) - elif not sib and not sob: # no wires on self + elif not sib and not sob: # no wires on self new_id_array[i] += np.array([oob, oib, 0, 0]) - else: # no wires on other + else: # no wires on other new_id_array[i] += np.array([sob, sib, 0, 0]) if bool(sok) == bool(oik): # same as above but on the ket side new_id_array[i] += np.array([0, 0, ook, sik]) @@ -312,7 +312,10 @@ def _repr_html_(self): # pragma: no cover html += "" try: - from IPython.core.display import display, HTML # pylint: disable=import-outside-toplevel + from IPython.core.display import ( + display, + HTML, + ) # pylint: disable=import-outside-toplevel display(HTML(html)) except ImportError as e: diff --git a/mrmustard/training/callbacks.py b/mrmustard/training/callbacks.py index a343fd94d..a5e8a7874 100644 --- a/mrmustard/training/callbacks.py +++ b/mrmustard/training/callbacks.py @@ -254,9 +254,9 @@ def call( orig_cost = np.array(optimizer.callback_history["orig_cost"][-1]).item() obj_scalars[f"{obj_tag}/orig_cost"] = orig_cost if self.cost_converter is not None: - obj_scalars[ - f"{obj_tag}/{self.cost_converter.__name__}(orig_cost)" - ] = self.cost_converter(orig_cost) + obj_scalars[f"{obj_tag}/{self.cost_converter.__name__}(orig_cost)"] = ( + self.cost_converter(orig_cost) + ) for k, v in obj_scalars.items(): tf.summary.scalar(k, data=v, step=self.optimizer_step) diff --git a/mrmustard/utils/typing.py b/mrmustard/utils/typing.py index 36cf64bd9..84a157784 100644 --- a/mrmustard/utils/typing.py +++ b/mrmustard/utils/typing.py @@ -95,5 +95,4 @@ class Batch(Protocol[T_co]): r"""Anything that can iterate over objects of type T_co.""" - def __iter__(self) -> Iterator[T_co]: - ... + def __iter__(self) -> Iterator[T_co]: ... diff --git a/tests/test_math/test_backend_manager.py b/tests/test_math/test_backend_manager.py index 963ca5cc9..64935f3c0 100644 --- a/tests/test_math/test_backend_manager.py +++ b/tests/test_math/test_backend_manager.py @@ -29,6 +29,7 @@ class TestBackendManager: r""" Tests the BackendManager. """ + l1 = [1.0] l2 = [1.0 + 0.0j, -2.0 + 2.0j] l3 = [[1.0, 2.0], [-3.0, 4.0]] diff --git a/tests/test_math/test_compactFock.py b/tests/test_math/test_compactFock.py index dd51e51fe..48761e5ab 100644 --- a/tests/test_math/test_compactFock.py +++ b/tests/test_math/test_compactFock.py @@ -1,6 +1,7 @@ """ Unit tests for mrmustard.math.compactFock.compactFock~ """ + import importlib import numpy as np From cd088c1fb3ddc47d845797621f005d8e43d4ad7c Mon Sep 17 00:00:00 2001 From: Filippo Miatto Date: Sun, 28 Jan 2024 15:00:18 -0800 Subject: [PATCH 04/30] fixed import --- tests/test_lab/test_wires.py | 2 +- tests/test_lab_dev/test_wires.py | 96 ++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 tests/test_lab_dev/test_wires.py diff --git a/tests/test_lab/test_wires.py b/tests/test_lab/test_wires.py index 790b2e2fc..a47d0198d 100644 --- a/tests/test_lab/test_wires.py +++ b/tests/test_lab/test_wires.py @@ -18,7 +18,7 @@ # pylint: disable=protected-access import pytest -from mrmustard.lab_dev.wires import Wires +from mrmustard.lab.wires import Wires def test_wires_view_has_same_ids(): diff --git a/tests/test_lab_dev/test_wires.py b/tests/test_lab_dev/test_wires.py new file mode 100644 index 000000000..790b2e2fc --- /dev/null +++ b/tests/test_lab_dev/test_wires.py @@ -0,0 +1,96 @@ +# Copyright 2023 Xanadu Quantum Technologies Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests for Wires class.""" + +# pylint: disable=missing-function-docstring +# pylint: disable=protected-access + +import pytest +from mrmustard.lab_dev.wires import Wires + + +def test_wires_view_has_same_ids(): + w = Wires([0], [0], [0], [0]) + assert set(w.ids) == set(w._view().ids) + + +def test_view_can_edit_original(): + w = Wires([0], [0], [0], [0]) + w._view().ids = [9, 99, 999, 9999] + assert w.ids == [9, 99, 999, 9999] + + +def test_wire_subsets(): + w = Wires([0], [1], [2], [3]) + assert w.output.bra.modes == [0] + assert w.input.bra.modes == [1] + assert w.output.ket.modes == [2] + assert w.input.ket.modes == [3] + + +def test_wire_mode_subsets(): + w = Wires([10], [11], [12], [13]) + assert w[10].ids == w.output.bra.ids + assert w[11].ids == w.input.bra.ids + assert w[12].ids == w.output.ket.ids + assert w[13].ids == w.input.ket.ids + + +def test_indices(): + w = Wires([0, 1, 2], [3, 4, 5], [6, 7], [8]) + assert w.output.indices == [0, 1, 2, 6, 7] + assert w.bra.indices == [0, 1, 2, 3, 4, 5] + assert w.input.indices == [3, 4, 5, 8] + assert w.ket.indices == [6, 7, 8] + + +def test_setting_ids(): + w = Wires([0], [0], [0], [0]) + w.ids = [9, 99, 999, 9999] + assert w.ids == [9, 99, 999, 9999] + + +def test_add_wires(): + w1 = Wires([0], [1], [2], [3]) + w2 = Wires([1], [2], [3], [4]) + w12 = Wires([0, 1], [1, 2], [2, 3], [3, 4]) + assert (w1 + w2).modes == w12.modes + + +def test_cant_add_overlapping_wires(): + w1 = Wires([0], [1], [2], [3]) + w2 = Wires([0], [2], [3], [4]) + with pytest.raises(Exception): + w1 + w2 + + +def test_args(): + w = Wires([0], [1], [2], [3]) + assert w._args() == ((0,), (1,), (2,), (3,)) + + +def test_right_shift_general_contraction(): + # contracts 1,1 on bra side + # contracts 3,3 and 13,13 on ket side (note order doesn't matter) + u = Wires([1, 5], [2, 6, 15], [3, 7, 13], [4, 8]) + v = Wires([0, 9, 14], [1, 10], [2, 11], [13, 3, 12]) + assert (u >> v)._args() == ((0, 5, 9, 14), (2, 6, 10, 15), (2, 7, 11), (4, 8, 12)) + + +def test_error_if_cant_contract(): + u = Wires([], [], [0], []) # only output wire + v = Wires([], [], [0], []) # only output wire + with pytest.raises(ValueError): + u >> v From 486fcc6a806f907af155b975b532837da71e0dd4 Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 07:54:28 +0000 Subject: [PATCH 05/30] moved files --- mrmustard/lab/{utils => }/wires.py | 0 tests/test_lab/test_wires.py | 8 +-- tests/test_lab_dev/test_wires.py | 96 ------------------------------ 3 files changed, 4 insertions(+), 100 deletions(-) rename mrmustard/lab/{utils => }/wires.py (100%) delete mode 100644 tests/test_lab_dev/test_wires.py diff --git a/mrmustard/lab/utils/wires.py b/mrmustard/lab/wires.py similarity index 100% rename from mrmustard/lab/utils/wires.py rename to mrmustard/lab/wires.py diff --git a/tests/test_lab/test_wires.py b/tests/test_lab/test_wires.py index a47d0198d..6b123b587 100644 --- a/tests/test_lab/test_wires.py +++ b/tests/test_lab/test_wires.py @@ -62,18 +62,18 @@ def test_setting_ids(): assert w.ids == [9, 99, 999, 9999] -def test_add_wires(): +def test_non_overlapping_wires(): w1 = Wires([0], [1], [2], [3]) w2 = Wires([1], [2], [3], [4]) w12 = Wires([0, 1], [1, 2], [2, 3], [3, 4]) - assert (w1 + w2).modes == w12.modes + assert (w1 >> w2).modes == w12.modes def test_cant_add_overlapping_wires(): w1 = Wires([0], [1], [2], [3]) w2 = Wires([0], [2], [3], [4]) - with pytest.raises(Exception): - w1 + w2 + with pytest.raises(ValueError): + w1 >> w2 def test_args(): diff --git a/tests/test_lab_dev/test_wires.py b/tests/test_lab_dev/test_wires.py deleted file mode 100644 index 790b2e2fc..000000000 --- a/tests/test_lab_dev/test_wires.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright 2023 Xanadu Quantum Technologies Inc. - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tests for Wires class.""" - -# pylint: disable=missing-function-docstring -# pylint: disable=protected-access - -import pytest -from mrmustard.lab_dev.wires import Wires - - -def test_wires_view_has_same_ids(): - w = Wires([0], [0], [0], [0]) - assert set(w.ids) == set(w._view().ids) - - -def test_view_can_edit_original(): - w = Wires([0], [0], [0], [0]) - w._view().ids = [9, 99, 999, 9999] - assert w.ids == [9, 99, 999, 9999] - - -def test_wire_subsets(): - w = Wires([0], [1], [2], [3]) - assert w.output.bra.modes == [0] - assert w.input.bra.modes == [1] - assert w.output.ket.modes == [2] - assert w.input.ket.modes == [3] - - -def test_wire_mode_subsets(): - w = Wires([10], [11], [12], [13]) - assert w[10].ids == w.output.bra.ids - assert w[11].ids == w.input.bra.ids - assert w[12].ids == w.output.ket.ids - assert w[13].ids == w.input.ket.ids - - -def test_indices(): - w = Wires([0, 1, 2], [3, 4, 5], [6, 7], [8]) - assert w.output.indices == [0, 1, 2, 6, 7] - assert w.bra.indices == [0, 1, 2, 3, 4, 5] - assert w.input.indices == [3, 4, 5, 8] - assert w.ket.indices == [6, 7, 8] - - -def test_setting_ids(): - w = Wires([0], [0], [0], [0]) - w.ids = [9, 99, 999, 9999] - assert w.ids == [9, 99, 999, 9999] - - -def test_add_wires(): - w1 = Wires([0], [1], [2], [3]) - w2 = Wires([1], [2], [3], [4]) - w12 = Wires([0, 1], [1, 2], [2, 3], [3, 4]) - assert (w1 + w2).modes == w12.modes - - -def test_cant_add_overlapping_wires(): - w1 = Wires([0], [1], [2], [3]) - w2 = Wires([0], [2], [3], [4]) - with pytest.raises(Exception): - w1 + w2 - - -def test_args(): - w = Wires([0], [1], [2], [3]) - assert w._args() == ((0,), (1,), (2,), (3,)) - - -def test_right_shift_general_contraction(): - # contracts 1,1 on bra side - # contracts 3,3 and 13,13 on ket side (note order doesn't matter) - u = Wires([1, 5], [2, 6, 15], [3, 7, 13], [4, 8]) - v = Wires([0, 9, 14], [1, 10], [2, 11], [13, 3, 12]) - assert (u >> v)._args() == ((0, 5, 9, 14), (2, 6, 10, 15), (2, 7, 11), (4, 8, 12)) - - -def test_error_if_cant_contract(): - u = Wires([], [], [0], []) # only output wire - v = Wires([], [], [0], []) # only output wire - with pytest.raises(ValueError): - u >> v From a013d1d2a3760e75869e75eee9e1556b5c6530a5 Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:16:08 +0000 Subject: [PATCH 06/30] updated changelog --- .github/CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 2458d4c80..99437fa3f 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -15,12 +15,15 @@ * Added an Ansatz abstract class and PolyExpAnsatz concrete implementation. This is used in the Bargmann representation. [(#295)](https://github.com/XanaduAI/MrMustard/pull/295) -* Added `complex_gaussian_integral` and `real_gaussian_integral` methods. +* Added `complex_gaussian_integral` method. [(#295)](https://github.com/XanaduAI/MrMustard/pull/295) * Added `Bargmann` representation (parametrized by Abc). Supports all algebraic operations and CV (exact) inner product. [(#296)](https://github.com/XanaduAI/MrMustard/pull/296) +* Added a new class `Wires` in `mrmustard.lab` to handle the connectivity of objects in a circuit. + [(#330)](https://github.com/XanaduAI/MrMustard/pull/330) + ### Breaking changes * Removed circular dependencies by: * Removing `graphics.py`--moved `ProgressBar` to `training` and `mikkel_plot` to `lab`. From 81d58ad1e4652a849808246398b11f256faa9bce Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:20:09 +0000 Subject: [PATCH 07/30] Refactor __bool__ method in Wires class --- mrmustard/lab/wires.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index 48b49b12b..467795b70 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -205,7 +205,7 @@ def copy(self) -> Wires: return w def __bool__(self) -> bool: - return True if len(self.ids) > 0 else False + return len(self.ids) > 0 def __getitem__(self, modes: Iterable[int] | int) -> Wires: "A view of this Wires object with wires only on the given modes." From 362b1004b7c06898a1f8413aa421cbc6ec12d48a Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:21:39 +0000 Subject: [PATCH 08/30] Fix pointless statements in test cases --- tests/test_lab/test_wires.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_lab/test_wires.py b/tests/test_lab/test_wires.py index 6b123b587..20ca42849 100644 --- a/tests/test_lab/test_wires.py +++ b/tests/test_lab/test_wires.py @@ -73,7 +73,7 @@ def test_cant_add_overlapping_wires(): w1 = Wires([0], [1], [2], [3]) w2 = Wires([0], [2], [3], [4]) with pytest.raises(ValueError): - w1 >> w2 + w1 >> w2 # pylint: disable=pointless-statement def test_args(): @@ -93,4 +93,4 @@ def test_error_if_cant_contract(): u = Wires([], [], [0], []) # only output wire v = Wires([], [], [0], []) # only output wire with pytest.raises(ValueError): - u >> v + u >> v # pylint: disable=pointless-statement From 77d7429aca2eab241f1faf57467932f5d95f1c0e Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:23:20 +0000 Subject: [PATCH 09/30] Fix display issue in Wires class --- mrmustard/lab/wires.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index 467795b70..c9a70e284 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -312,11 +312,7 @@ def _repr_html_(self): # pragma: no cover html += "" try: - from IPython.core.display import ( - display, - HTML, - ) # pylint: disable=import-outside-toplevel - + from IPython.core.display import display, HTML # pylint: disable=import-outside-toplevel display(HTML(html)) except ImportError as e: raise ImportError( From 93c58c89fa27a45680abea161d115a39fd2e3d9c Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:41:54 +0000 Subject: [PATCH 10/30] Refactor wire connection logic in Wires class --- mrmustard/lab/wires.py | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index c9a70e284..ec2ab365d 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -215,6 +215,21 @@ def __getitem__(self, modes: Iterable[int] | int) -> Wires: def __lshift__(self, other: Wires) -> Wires: return (other.dual >> self.dual).dual # how cool is this + + @staticmethod + def _outin(si, so, oi, oo): + r"""Returns the output and input wires of the composite object made by connecting + two single-mode ket (or bra) objects: + --|self|-- --|other|-- + At this stage we are guaranteed that the configurations `|self|-- |other|--` and + `--|self| --|other|` (which would be invalid) have already been excluded. + """ + if bool(so) == bool(oi): # if the inner wires are either both there or both not there + return np.array([oo, si]) + elif not si and not so: # no wires on self + return np.array([oo, oi]) + else: # no wires on other + return np.array([so, si]) def __rshift__(self, other: Wires) -> Wires: r"""Returns a new Wires object with the wires of self and other combined as two @@ -227,30 +242,18 @@ def __rshift__(self, other: Wires) -> Wires: new_id_array = np.zeros((len(all_modes), 4), dtype=np.int64) for i, m in enumerate(all_modes): if m in self.modes and m in other.modes: - # m-th row of self and other (and self output bra = sob, etc...) - sob, sib, sok, sik = self._mode(m) - oob, oib, ook, oik = other._mode(m) + sob, sib, sok, sik = self._mode(m) # m-th row of self + oob, oib, ook, oik = other._mode(m) # m-th row of other errors = { - "output bra": sob and oob and not oib, - "output ket": sok and ook and not oik, - "input bra": oib and sib and not sob, - "input ket": oik and sik and not sok, + "output bra": sob and oob and not oib, # |s|- |o|- (bra) + "output ket": sok and ook and not oik, # |s|- |o|- (ket) + "input bra": oib and sib and not sob, # -|s| -|o| (bra) + "input ket": oik and sik and not sok, # -|s| -|o| (ket) } if any(errors.values()): position = [k for k, v in errors.items() if v][0] raise ValueError(f"{position} wire overlap at mode {m}") - if bool(sob) == bool(oib): # if the inner wires are both there or both not there - new_id_array[i] += np.array([oob, sib, 0, 0]) - elif not sib and not sob: # no wires on self - new_id_array[i] += np.array([oob, oib, 0, 0]) - else: # no wires on other - new_id_array[i] += np.array([sob, sib, 0, 0]) - if bool(sok) == bool(oik): # same as above but on the ket side - new_id_array[i] += np.array([0, 0, ook, sik]) - elif not sik and not sok: - new_id_array[i] += np.array([0, 0, ook, oik]) - else: - new_id_array[i] += np.array([0, 0, sok, sik]) + new_id_array[i] += np.hstack([self._outin(sib, sob, oib, oob), self._outin(sik, sok, oik, ook)]) elif m in self.modes and not m in other.modes: new_id_array[i] += self._mode(m) elif m in other.modes and not m in self.modes: From 84f7f04f652ef542efeaea5653f921f5686d0a24 Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:44:29 +0000 Subject: [PATCH 11/30] Fix whitespace issue in wires.py --- mrmustard/lab/wires.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index ec2ab365d..ca4270e64 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -215,7 +215,7 @@ def __getitem__(self, modes: Iterable[int] | int) -> Wires: def __lshift__(self, other: Wires) -> Wires: return (other.dual >> self.dual).dual # how cool is this - + @staticmethod def _outin(si, so, oi, oo): r"""Returns the output and input wires of the composite object made by connecting @@ -254,9 +254,9 @@ def __rshift__(self, other: Wires) -> Wires: position = [k for k, v in errors.items() if v][0] raise ValueError(f"{position} wire overlap at mode {m}") new_id_array[i] += np.hstack([self._outin(sib, sob, oib, oob), self._outin(sik, sok, oik, ook)]) - elif m in self.modes and not m in other.modes: + elif m in self.modes and m not in other.modes: new_id_array[i] += self._mode(m) - elif m in other.modes and not m in self.modes: + elif m in other.modes and m not in self.modes: new_id_array[i] += other._mode(m) return self._from_data(np.abs(new_id_array), all_modes) From 06226eeb2a3b5f3ff1f21370f2fdcf0f6d998cd1 Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:49:09 +0000 Subject: [PATCH 12/30] Fix data type in Wires class methods --- mrmustard/lab/wires.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index ca4270e64..919134748 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -225,11 +225,11 @@ def _outin(si, so, oi, oo): `--|self| --|other|` (which would be invalid) have already been excluded. """ if bool(so) == bool(oi): # if the inner wires are either both there or both not there - return np.array([oo, si]) + return np.array([oo, si], dtype=np.int64) elif not si and not so: # no wires on self - return np.array([oo, oi]) + return np.array([oo, oi], dtype=np.int64) else: # no wires on other - return np.array([so, si]) + return np.array([so, si], dtype=np.int64) def __rshift__(self, other: Wires) -> Wires: r"""Returns a new Wires object with the wires of self and other combined as two @@ -258,7 +258,7 @@ def __rshift__(self, other: Wires) -> Wires: new_id_array[i] += self._mode(m) elif m in other.modes and m not in self.modes: new_id_array[i] += other._mode(m) - return self._from_data(np.abs(new_id_array), all_modes) + return self._from_data(new_id_array, all_modes) # abs to turn hidden ids (negative) into visible def __repr__(self) -> str: ob_modes, ib_modes, ok_modes, ik_modes = self._args() From 466d676d52acd51f29c5f4064360b6c166f5be0d Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:51:34 +0000 Subject: [PATCH 13/30] Fix pylint warnings in test_wires.py --- tests/test_lab/test_wires.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_lab/test_wires.py b/tests/test_lab/test_wires.py index 20ca42849..1f470bc89 100644 --- a/tests/test_lab/test_wires.py +++ b/tests/test_lab/test_wires.py @@ -73,7 +73,7 @@ def test_cant_add_overlapping_wires(): w1 = Wires([0], [1], [2], [3]) w2 = Wires([0], [2], [3], [4]) with pytest.raises(ValueError): - w1 >> w2 # pylint: disable=pointless-statement + w1 >> w2 # pylint: disable=pointless-statement # type: ignore def test_args(): @@ -93,4 +93,4 @@ def test_error_if_cant_contract(): u = Wires([], [], [0], []) # only output wire v = Wires([], [], [0], []) # only output wire with pytest.raises(ValueError): - u >> v # pylint: disable=pointless-statement + u >> v # pylint: disable=pointless-statement # type: ignore From 4907ec0a72df2261851efd7c1f50fe553d0f1233 Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:55:04 +0000 Subject: [PATCH 14/30] Refactor __rshift__ method in Wires class --- mrmustard/lab/wires.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index 919134748..8b41e1651 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -219,8 +219,7 @@ def __lshift__(self, other: Wires) -> Wires: @staticmethod def _outin(si, so, oi, oo): r"""Returns the output and input wires of the composite object made by connecting - two single-mode ket (or bra) objects: - --|self|-- --|other|-- + two single-mode ket (or bra) objects like --|self|-- and --|other|-- At this stage we are guaranteed that the configurations `|self|-- |other|--` and `--|self| --|other|` (which would be invalid) have already been excluded. """ From 797ebc5508ae839e5615d0d0be424e21003d5172 Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 08:55:39 +0000 Subject: [PATCH 15/30] simplify errors raised in Wires class --- mrmustard/lab/wires.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index 8b41e1651..0e49b1dce 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -231,33 +231,26 @@ def _outin(si, so, oi, oo): return np.array([so, si], dtype=np.int64) def __rshift__(self, other: Wires) -> Wires: - r"""Returns a new Wires object with the wires of self and other combined as two - components in a circuit where the output of self connects to the input of other: - ``self >> other`` - All surviving wires are arranged in the standard order. - A ValueError is raised if there are any surviving wires that overlap, which is the only - possible way two objects aren't compatible in a circuit.""" all_modes = sorted(set(self.modes) | set(other.modes)) new_id_array = np.zeros((len(all_modes), 4), dtype=np.int64) + for i, m in enumerate(all_modes): if m in self.modes and m in other.modes: sob, sib, sok, sik = self._mode(m) # m-th row of self oob, oib, ook, oik = other._mode(m) # m-th row of other - errors = { - "output bra": sob and oob and not oib, # |s|- |o|- (bra) - "output ket": sok and ook and not oik, # |s|- |o|- (ket) - "input bra": oib and sib and not sob, # -|s| -|o| (bra) - "input ket": oik and sik and not sok, # -|s| -|o| (ket) - } - if any(errors.values()): - position = [k for k, v in errors.items() if v][0] - raise ValueError(f"{position} wire overlap at mode {m}") + + if (sob and oob and not oib) or (sok and ook and not oik): + raise ValueError(f"Output wire overlap at mode {m}") + elif (oib and sib and not sob) or (oik and sik and not sok): + raise ValueError(f"Input wire overlap at mode {m}") + new_id_array[i] += np.hstack([self._outin(sib, sob, oib, oob), self._outin(sik, sok, oik, ook)]) - elif m in self.modes and m not in other.modes: + elif m in self.modes: new_id_array[i] += self._mode(m) - elif m in other.modes and m not in self.modes: + elif m in other.modes: new_id_array[i] += other._mode(m) - return self._from_data(new_id_array, all_modes) # abs to turn hidden ids (negative) into visible + + return self._from_data(new_id_array, all_modes) def __repr__(self) -> str: ob_modes, ib_modes, ok_modes, ik_modes = self._args() From 247a34fd09f29c158aec88068ea77988f89e3957 Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 09:09:14 +0000 Subject: [PATCH 16/30] Refactor wire mode merging logic --- mrmustard/lab/wires.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index 0e49b1dce..2481c28f7 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -234,21 +234,20 @@ def __rshift__(self, other: Wires) -> Wires: all_modes = sorted(set(self.modes) | set(other.modes)) new_id_array = np.zeros((len(all_modes), 4), dtype=np.int64) - for i, m in enumerate(all_modes): - if m in self.modes and m in other.modes: - sob, sib, sok, sik = self._mode(m) # m-th row of self - oob, oib, ook, oik = other._mode(m) # m-th row of other + for m in set(self.modes) & set(other.modes): + sob, sib, sok, sik = self._mode(m) # m-th row of self + oob, oib, ook, oik = other._mode(m) # m-th row of other + + if (sob and oob and not oib) or (sok and ook and not oik): + raise ValueError(f"Output wire overlap at mode {m}") + if (oib and sib and not sob) or (oik and sik and not sok): + raise ValueError(f"Input wire overlap at mode {m}") - if (sob and oob and not oib) or (sok and ook and not oik): - raise ValueError(f"Output wire overlap at mode {m}") - elif (oib and sib and not sob) or (oik and sik and not sok): - raise ValueError(f"Input wire overlap at mode {m}") - - new_id_array[i] += np.hstack([self._outin(sib, sob, oib, oob), self._outin(sik, sok, oik, ook)]) - elif m in self.modes: - new_id_array[i] += self._mode(m) - elif m in other.modes: - new_id_array[i] += other._mode(m) + new_id_array[all_modes.index(m)] = np.hstack([self._outin(sib, sob, oib, oob), self._outin(sik, sok, oik, ook)]) + for m in set(self.modes) - set(other.modes): + new_id_array[all_modes.index(m)] = self._mode(m) + for m in set(other.modes) - set(self.modes): + new_id_array[all_modes.index(m)] = other._mode(m) return self._from_data(new_id_array, all_modes) From ebb95f5f5cd8612cec700915b3b59407bb80074f Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 09:09:54 +0000 Subject: [PATCH 17/30] Fix typo in comment --- mrmustard/lab/wires.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index 2481c28f7..b5a55e4ed 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -219,7 +219,7 @@ def __lshift__(self, other: Wires) -> Wires: @staticmethod def _outin(si, so, oi, oo): r"""Returns the output and input wires of the composite object made by connecting - two single-mode ket (or bra) objects like --|self|-- and --|other|-- + two single-mode (ket or bra) objects like --|self|-- and --|other|-- At this stage we are guaranteed that the configurations `|self|-- |other|--` and `--|self| --|other|` (which would be invalid) have already been excluded. """ From d7c219f60ba411cc388e93c95cec03bf324ace42 Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 09:43:12 +0000 Subject: [PATCH 18/30] Fix formatting issues in Wires class --- mrmustard/lab/wires.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index b5a55e4ed..e3fa3b109 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -220,7 +220,7 @@ def __lshift__(self, other: Wires) -> Wires: def _outin(si, so, oi, oo): r"""Returns the output and input wires of the composite object made by connecting two single-mode (ket or bra) objects like --|self|-- and --|other|-- - At this stage we are guaranteed that the configurations `|self|-- |other|--` and + At this stage we are guaranteed that the configurations `|self|-- |other|--` and `--|self| --|other|` (which would be invalid) have already been excluded. """ if bool(so) == bool(oi): # if the inner wires are either both there or both not there @@ -233,7 +233,7 @@ def _outin(si, so, oi, oo): def __rshift__(self, other: Wires) -> Wires: all_modes = sorted(set(self.modes) | set(other.modes)) new_id_array = np.zeros((len(all_modes), 4), dtype=np.int64) - + for m in set(self.modes) & set(other.modes): sob, sib, sok, sik = self._mode(m) # m-th row of self oob, oib, ook, oik = other._mode(m) # m-th row of other @@ -242,13 +242,15 @@ def __rshift__(self, other: Wires) -> Wires: raise ValueError(f"Output wire overlap at mode {m}") if (oib and sib and not sob) or (oik and sik and not sok): raise ValueError(f"Input wire overlap at mode {m}") - - new_id_array[all_modes.index(m)] = np.hstack([self._outin(sib, sob, oib, oob), self._outin(sik, sok, oik, ook)]) + + new_id_array[all_modes.index(m)] = np.hstack( + [self._outin(sib, sob, oib, oob), self._outin(sik, sok, oik, ook)] + ) for m in set(self.modes) - set(other.modes): new_id_array[all_modes.index(m)] = self._mode(m) for m in set(other.modes) - set(self.modes): new_id_array[all_modes.index(m)] = other._mode(m) - + return self._from_data(new_id_array, all_modes) def __repr__(self) -> str: @@ -306,7 +308,11 @@ def _repr_html_(self): # pragma: no cover html += "" try: - from IPython.core.display import display, HTML # pylint: disable=import-outside-toplevel + from IPython.core.display import ( + display, + HTML, + ) # pylint: disable=import-outside-toplevel + display(HTML(html)) except ImportError as e: raise ImportError( From a5edc3253feaf62d6f7f616c8df69f9cec8aa34e Mon Sep 17 00:00:00 2001 From: ziofil Date: Mon, 29 Jan 2024 09:47:18 +0000 Subject: [PATCH 19/30] Fix import error in Wires class --- mrmustard/lab/wires.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index e3fa3b109..6f5d2a8d2 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -17,11 +17,13 @@ from __future__ import annotations from typing import Iterable, Optional + import numpy as np + from mrmustard import settings # pylint: disable=protected-access - +# pylint: disable=import-outside-toplevel class Wires: r"""`Wires` class for handling the connectivity of an object in a circuit. @@ -309,9 +311,9 @@ def _repr_html_(self): # pragma: no cover try: from IPython.core.display import ( - display, HTML, - ) # pylint: disable=import-outside-toplevel + display, + ) display(HTML(html)) except ImportError as e: From 0e9e04c4bf75652add6d03d231da58a52cc7cf31 Mon Sep 17 00:00:00 2001 From: ziofil Date: Tue, 30 Jan 2024 18:04:59 +0000 Subject: [PATCH 20/30] blacked --- mrmustard/lab/wires.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index 6f5d2a8d2..8d27e494c 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -25,6 +25,7 @@ # pylint: disable=protected-access # pylint: disable=import-outside-toplevel + class Wires: r"""`Wires` class for handling the connectivity of an object in a circuit. In MrMustard, ``CircuitComponent``s have a ``Wires`` object as attribute From eddf339b68d619c102f3dd0727fbdf8c3a0d16c5 Mon Sep 17 00:00:00 2001 From: ziofil Date: Tue, 30 Jan 2024 18:07:09 +0000 Subject: [PATCH 21/30] simplify attempt (for codecov) --- mrmustard/lab/wires.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab/wires.py index 8d27e494c..9f4107622 100644 --- a/mrmustard/lab/wires.py +++ b/mrmustard/lab/wires.py @@ -241,9 +241,13 @@ def __rshift__(self, other: Wires) -> Wires: sob, sib, sok, sik = self._mode(m) # m-th row of self oob, oib, ook, oik = other._mode(m) # m-th row of other - if (sob and oob and not oib) or (sok and ook and not oik): + out_bra_issue = sob and oob and not oib + out_ket_issue = sok and ook and not oik + if out_bra_issue or out_ket_issue: raise ValueError(f"Output wire overlap at mode {m}") - if (oib and sib and not sob) or (oik and sik and not sok): + in_bra_issue = oib and sib and not sob + in_ket_issue = oik and sik and not sok + if in_bra_issue or in_ket_issue: raise ValueError(f"Input wire overlap at mode {m}") new_id_array[all_modes.index(m)] = np.hstack( From a75934322b801e3d857f17d7238b916ea682b90d Mon Sep 17 00:00:00 2001 From: ziofil Date: Tue, 30 Jan 2024 18:27:05 +0000 Subject: [PATCH 22/30] trick codefactor --- mrmustard/lab/abstract/state.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mrmustard/lab/abstract/state.py b/mrmustard/lab/abstract/state.py index f914fdbb6..25b2ab177 100644 --- a/mrmustard/lab/abstract/state.py +++ b/mrmustard/lab/abstract/state.py @@ -591,7 +591,6 @@ def get_modes(self, item) -> State: fock_partitioned = fock.trace(self.dm(self.cutoffs), keep=item_idx) return State(dm=fock_partitioned, modes=item) - # TODO: refactor def __eq__(self, other) -> bool: # pylint: disable=too-many-return-statements r"""Returns whether the states are equal.""" if self.num_modes != other.num_modes: From a2af8c3762abed604914973424a8421cc254b883 Mon Sep 17 00:00:00 2001 From: ziofil Date: Tue, 30 Jan 2024 18:58:51 +0000 Subject: [PATCH 23/30] moved wires --- mrmustard/{lab => lab_dev}/wires.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mrmustard/{lab => lab_dev}/wires.py (100%) diff --git a/mrmustard/lab/wires.py b/mrmustard/lab_dev/wires.py similarity index 100% rename from mrmustard/lab/wires.py rename to mrmustard/lab_dev/wires.py From ddec32232226025621d286dbd698df0a2786fad4 Mon Sep 17 00:00:00 2001 From: ziofil Date: Tue, 30 Jan 2024 19:03:18 +0000 Subject: [PATCH 24/30] updated import and moved test_wires.py --- tests/{test_lab => test_lab_dev}/test_wires.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/{test_lab => test_lab_dev}/test_wires.py (98%) diff --git a/tests/test_lab/test_wires.py b/tests/test_lab_dev/test_wires.py similarity index 98% rename from tests/test_lab/test_wires.py rename to tests/test_lab_dev/test_wires.py index 1f470bc89..cc4921fc9 100644 --- a/tests/test_lab/test_wires.py +++ b/tests/test_lab_dev/test_wires.py @@ -18,7 +18,7 @@ # pylint: disable=protected-access import pytest -from mrmustard.lab.wires import Wires +from mrmustard.lab_dev.wires import Wires def test_wires_view_has_same_ids(): From fab19915f80d7a209be13b89c125a570d9747940 Mon Sep 17 00:00:00 2001 From: SamFerracin Date: Thu, 1 Feb 2024 14:12:26 -0500 Subject: [PATCH 25/30] Tests and docs for wires final (merge first) (#334) **Description of the Change:** Tests and docs for wires final --------- Co-authored-by: Yuan <16817699+sylviemonet@users.noreply.github.com> Co-authored-by: ziofil Co-authored-by: Filippo Miatto --- .github/workflows/tests_docs.yml | 40 +++++ doc/code/lab_dev.rst | 9 + doc/code/lab_dev/wires.rst | 8 + doc/index.rst | 1 + mrmustard/lab_dev/wires.py | 277 +++++++++++++++++++++---------- tests/test_lab_dev/test_wires.py | 235 +++++++++++++++++--------- 6 files changed, 407 insertions(+), 163 deletions(-) create mode 100644 .github/workflows/tests_docs.yml create mode 100644 doc/code/lab_dev.rst create mode 100644 doc/code/lab_dev/wires.rst diff --git a/.github/workflows/tests_docs.yml b/.github/workflows/tests_docs.yml new file mode 100644 index 000000000..16d1a25fc --- /dev/null +++ b/.github/workflows/tests_docs.yml @@ -0,0 +1,40 @@ +name: Docs tests +on: + push: + branches: + - develop + pull_request: + paths: + - '.github/workflows/tests.yml' + - 'mrmustard/**' + - 'pyproject.toml' + - 'poetry.lock' + - 'pytest.ini' + +jobs: + docs: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: + HYPOTHESIS_PROFILE: ci + + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Setup python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + + - name: Install dependencies + run: | + python -m pip install --no-cache-dir --upgrade pip + pip install --no-cache-dir poetry==1.4.0 + poetry config virtualenvs.create false + poetry install --extras "ray" --with dev + + - name: Run tests + run: python -m pytest --doctest-modules mrmustard/lab_dev \ No newline at end of file diff --git a/doc/code/lab_dev.rst b/doc/code/lab_dev.rst new file mode 100644 index 000000000..ff5b179af --- /dev/null +++ b/doc/code/lab_dev.rst @@ -0,0 +1,9 @@ +mrmustard.lab_dev +================= + +.. toctree:: + :maxdepth: 1 + + lab_dev/wires + +.. currentmodule:: mrmustard.lab_dev \ No newline at end of file diff --git a/doc/code/lab_dev/wires.rst b/doc/code/lab_dev/wires.rst new file mode 100644 index 000000000..9b7bf82a6 --- /dev/null +++ b/doc/code/lab_dev/wires.rst @@ -0,0 +1,8 @@ +mrmustard.lab_dev.wires +======================= + +.. currentmodule:: mrmustard.lab_dev.wires + +.. automodapi:: mrmustard.lab_dev.wires + :no-heading: + :include-all-objects: \ No newline at end of file diff --git a/doc/index.rst b/doc/index.rst index 53934e9b1..38e9f7fe7 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -128,6 +128,7 @@ Mr Mustard supports the following in a fully differentiable way: code/mm code/lab + code/lab_dev code/physics code/math code/training diff --git a/mrmustard/lab_dev/wires.py b/mrmustard/lab_dev/wires.py index 9f4107622..291f19af4 100644 --- a/mrmustard/lab_dev/wires.py +++ b/mrmustard/lab_dev/wires.py @@ -12,73 +12,96 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""`Wires` class for handling the connectivity of an object in a circuit.""" +""" ``Wires`` class for supporting tensor network functionalities.""" from __future__ import annotations from typing import Iterable, Optional - import numpy as np from mrmustard import settings -# pylint: disable=protected-access +__all__ = ["Wires"] + # pylint: disable=import-outside-toplevel class Wires: - r"""`Wires` class for handling the connectivity of an object in a circuit. - In MrMustard, ``CircuitComponent``s have a ``Wires`` object as attribute - to handle the wires of the component and to connect components together. - - Wires are arranged into four groups, and each of the groups can - span multiple modes: - _______________ - input bra modes --->| circuit |---> output bra modes - input ket modes --->| component |---> output ket modes - --------------- - Each of the four groups can be empty. In particular, the wires of a state have - no inputs and the wires of a measurement have no outputs. Similarly, - a standard unitary transformation has no bra wires. - - We refer to these four groups in a "standard order": - 0. output_bra for all modes - 1. input_bra for all modes - 2. output_ket for all modes - 3. input_ket for all modes - - A ``Wires`` object can return subsets (views) of itself. Available subsets are: - - input/output (wires on input/output side) - - bra/ket (wires on bra/ket side) - - modes (wires on the given modes) - - For example, ``wires.input`` returns a ``Wires`` object with only the input wires - (on bra and ket sides and on all the modes). - Note that these can be combined together: ``wires.input.bra[(1,2)] returns a - ``Wires`` object with only the input bra wires on modes 1 and 2. - Note these are views of the original ``Wires`` object, i.e. we can set the ``ids`` on the - views and it will be set on the original, e.g. this is a valid way to connect two sets - of wires by setting their ids to be equal: ``wires1.output.ids = wires2.input.ids``. - - A very useful feature of the ``Wires`` class is the support for the right shift - operator ``>>``. This allows us to connect two ``Wires`` objects together as - ``wires1 >> wires2``. This will return the ``Wires`` object of the two - wires objects connected together as if they were in a circuit: - ____________ ____________ - in bra --->| wires1 |---> out bra ---> in bra --->| wires2 |---> out bra - in ket --->| |---> out ket ---> in ket --->| |---> out ket - ------------ ------------ - The returned ``Wires`` object will contain the surviving wires of the two - ``Wires`` objects and it will raise an error if there are overlaps between - the surviving wires. This is especially useful for handling the ordering of the - wires when connecting components together: we are always guaranteed that a - ``Wires`` object will provide the wires in the standard order. + r""" + A class with wire functionality for tensor network applications. + + In MrMustard, we represent circuit components as tensors in a tensor network. The wires of + these components describe how they connect with the surrounding components. For example, an + `N`-mode pure state has `N` ket wires on the output side, while a `N`-mode mixed state + has `N` ket wires and `N` bra wires on the output side. + + ``Wires`` objects store the information related to the wires of circuit components. Each wire + in a ``Wires`` object is specified by a numerical id, which is random and unique. When two different + ``Wires`` object have one or more wires with the same ids, we treat them as connected. Otherwise, + we treat them as disconnected. + + The list of all these ids can be accessed using the ``ids`` property. + + .. code-block:: + + >>> from mrmustard.lab_dev.wires import Wires + + >>> modes_out_bra=[0, 1] + >>> modes_in_bra=[1, 2] + >>> modes_out_ket=[0, 3] + >>> modes_in_ket=[1, 2, 3] + >>> w = Wires(modes_out_bra, modes_in_bra, modes_out_ket, modes_in_ket) + + >>> # access the modes + >>> modes = w.modes + >>> assert w.modes == [0, 1, 2, 3] + + >>> # access the ids + >>> ids = w.ids + >>> assert len(ids) == 9 + + >>> # get input/output subsets + >>> w_in = w.input + >>> assert w_in.modes == [1, 2, 3] + + >>> # get ket/bra subsets + >>> w_in_bra = w_in.bra + >>> assert w_in_bra.modes == [1, 2] + + The standard order for the list of ids is: + + - ids for all the output bra wires. + + - ids for all the input bra wires. + + - ids for all the output ket wires. + + - ids for all the input ket wires. + + .. code-block:: + + >>> assert w.output.bra.ids == w.ids[:2] + >>> assert w.input.bra.ids == w.ids[2:4] + >>> assert w.output.ket.ids == w.ids[4:6] + >>> assert w.input.ket.ids == w.ids[6:] + + To access the index of a su set of wires in standard order (i.e. skipping over wires not belonging to the subset), + one can use the ``indices`` attribute: + + .. code-block:: + + >>> w = Wires(modes_in_ket = [0,1], modes_out_ket = [0,1]) + + >>> assert w.indices == [0,1,2,3] + >>> assert w.input.indices == [2,3] + + Note that subsets return new ``Wires`` objects with the same ids as the original object. Args: - modes_out_bra (Iterable[int]): The output modes on the bra side. - modes_in_bra (Iterable[int]): The input modes on the bra side. - modes_out_ket (Iterable[int]): The output modes on the ket side. - modes_in_ket (Iterable[int]): The input modes on the ket side. + modes_out_bra: The output modes on the bra side. + modes_in_bra: The input modes on the bra side. + modes_out_ket: The output modes on the ket side. + modes_in_ket: The input modes on the ket side. Note that the order of the modes passed to initialize the object doesn't matter, as they get sorted at init time. @@ -108,7 +131,10 @@ def __init__( self._mask = np.ones_like(self._id_array) # multiplicative mask def _args(self): - r"""Returns the same args one needs to initialize this object.""" + r""" + Returns the input arguments needed to initialize the same ``Wires`` object + (with different ids). + """ ob_modes = np.array(self._modes)[self._id_array[:, 0] > 0].tolist() ib_modes = np.array(self._modes)[self._id_array[:, 1] > 0].tolist() ok_modes = np.array(self._modes)[self._id_array[:, 2] > 0].tolist() @@ -116,8 +142,10 @@ def _args(self): return tuple(ob_modes), tuple(ib_modes), tuple(ok_modes), tuple(ik_modes) @classmethod - def _from_data(cls, id_array: np.ndarray, modes: list[int], mask=None): - r"""Private class method to initialize Wires object from the given data.""" + def _from_data(cls, id_array, modes, mask=None): + r""" + Initializes ``Wires`` object from its private attributes. + """ w = cls() w._id_array = id_array w._modes = modes @@ -125,43 +153,71 @@ def _from_data(cls, id_array: np.ndarray, modes: list[int], mask=None): return w def _view(self, masked_rows: tuple[int, ...] = (), masked_cols: tuple[int, ...] = ()) -> Wires: - r"""A masked view of this Wires object.""" + r""" + A masked view of this Wires object. + """ w = self._from_data(self._id_array, self._modes, self._mask.copy()) w._mask[masked_rows, :] = -1 w._mask[:, masked_cols] = -1 return w def _mode(self, mode: int) -> np.ndarray: - "A slice of the id_array matrix at the given mode." + r""" + A slice of the id_array matrix at the given mode. + """ return np.maximum(0, self.id_array[[self._modes.index(mode)]])[0] @property def id_array(self) -> np.ndarray: - "The id_array of the available wires in the standard order (bra/ket x out/in x mode)." + r""" + The id_array of the available wires in a two-dimensional array, where line ``j`` contains + the ids (in the standard order) for mode ``j``. + """ return self._id_array * self._mask @property def ids(self) -> list[int]: - "The list of ids of the available wires in the standard order." + r""" + The list of ids of the available wires in the standard order. + """ flat = self.id_array.T.ravel() return flat[flat > 0].tolist() @ids.setter def ids(self, ids: list[int]): - "Sets the ids of the available wires." + r""" + Sets the ids of the available wires. + + Args: + ids: The new ids. + + Raises: + ValueError: If the number of ids does not match the expected number. + """ if len(ids) != len(self.ids): raise ValueError(f"wrong number of ids (expected {len(self.ids)}, got {len(ids)})") self._id_array.flat[self.id_array.flatten() > 0] = ids @property def modes(self) -> list[int]: - "The set of modes spanned by the populated wires." + r""" + The list of modes of the populated wires. + """ return [m for m in self._modes if any(self.id_array[self._modes.index(m)] > 0)] @property def indices(self) -> list[int]: - r"""Returns the array of indices of this subset in the standard order. - (bra/ket x out/in x mode). Use this to get the indices for bargmann contractions. + r""" + The array of indices of this ``Wires`` in the standard order. The array of indices + of this ``Wires`` in the standard order. When a subset is selected, it skips the + indices of wires that do not belong to the subset. + + .. code-block:: + + >>> w = Wires(modes_in_ket = [0,1], modes_out_ket = [0,1]) + + >>> assert w.indices == [0,1,2,3] + >>> assert w.input.indices == [2,3] """ flat = self.id_array.T.ravel() flat = flat[flat != 0] @@ -169,49 +225,85 @@ def indices(self) -> list[int]: @property def input(self) -> Wires: - "A view of self without output wires" + r""" + A view of this ``Wires`` object without output wires. + """ return self._view(masked_cols=(0, 2)) @property def output(self) -> Wires: - "A view of self without input wires" + r""" + A view of this ``Wires`` object without input wires. + """ return self._view(masked_cols=(1, 3)) @property def ket(self) -> Wires: - "A view of self without bra wires" + r""" + A view of this ``Wires`` object without bra wires. + """ return self._view(masked_cols=(0, 1)) @property def bra(self) -> Wires: - "A view of self without ket wires" + r""" + A view of this ``Wires`` object without ket wires. + """ return self._view(masked_cols=(2, 3)) @property def adjoint(self) -> Wires: r""" - The adjoint (ket <-> bra) of this wires object. + The adjoint of this wires object, obtained by swapping ket and bra wires. """ return self._from_data(self._id_array[:, [2, 3, 0, 1]], self._modes, self._mask) @property def dual(self) -> Wires: r""" - The dual (in <-> out) of this wires object. + The dual of this wires object, obtained by swapping input and output wires. """ return self._from_data(self._id_array[:, [1, 0, 3, 2]], self._modes, self._mask) def copy(self) -> Wires: - r"""A copy of this Wires object with new ids.""" + r""" + A copy of this ``Wires`` object, with new ids. + """ w = Wires(*self._args()) w._mask = self._mask.copy() return w + def __add__(self, other: Wires) -> Wires: + r""" + A new ``Wires`` object that combines the wires of ``self`` and those of ``other``. + + Args: + other: The wire to add. + + Raise: + ValueError: If the two ``Wires`` being added have an overlap that cannot be resolved. + """ + modes_rows = {} + all_modes = sorted(set(self.modes) | set(other.modes)) + for m in all_modes: + self_row = self.id_array[self._modes.index(m)] if m in self.modes else np.zeros(4) + other_row = other.id_array[other._modes.index(m)] if m in other.modes else np.zeros(4) + if np.any(np.where(self_row > 0) == np.where(other_row > 0)): + raise ValueError(f"wires overlap on mode {m}") + modes_rows[m] = [s if s > 0 else o for s, o in zip(self_row, other_row)] + combined_array = np.array([modes_rows[m] for m in sorted(modes_rows)]) + return self._from_data(combined_array, sorted(modes_rows), np.ones_like(combined_array)) + def __bool__(self) -> bool: + r""" + Returns ``True`` if this ``Wires`` object has ids, ``False`` otherwise. + """ return len(self.ids) > 0 def __getitem__(self, modes: Iterable[int] | int) -> Wires: - "A view of this Wires object with wires only on the given modes." + r""" + A view of this Wires object with wires only on the given modes. + """ modes = [modes] if isinstance(modes, int) else modes idxs = tuple(list(self._modes).index(m) for m in set(self._modes).difference(modes)) return self._view(masked_rows=idxs) @@ -220,26 +312,38 @@ def __lshift__(self, other: Wires) -> Wires: return (other.dual >> self.dual).dual # how cool is this @staticmethod - def _outin(si, so, oi, oo): - r"""Returns the output and input wires of the composite object made by connecting - two single-mode (ket or bra) objects like --|self|-- and --|other|-- - At this stage we are guaranteed that the configurations `|self|-- |other|--` and - `--|self| --|other|` (which would be invalid) have already been excluded. + def _outin(self_in: int, self_out: int, other_in: int, other_out: int) -> np.ndarray: + r""" + Returns the ids of the composite object made by connecting an object self with ids + ``self_in`` and ``self_out`` to an object other with ids ``other_in`` and ``other_out``. + + Assumes that the configurations ``--|self| --|other|`` or ``|self|-- |other|--``, + which would lead to an overlap of wires, have already been excluded. + + Note that the order of the returned ids is ``[out, in]``, as per standard order. """ - if bool(so) == bool(oi): # if the inner wires are either both there or both not there - return np.array([oo, si], dtype=np.int64) - elif not si and not so: # no wires on self - return np.array([oo, oi], dtype=np.int64) + if bool(self_out) == bool( + other_in + ): # if the inner wires are either both there or both not there + return np.array([other_out, self_in], dtype=np.int64) + elif not self_in and not self_out: # no wires on self + return np.array([other_out, other_in], dtype=np.int64) else: # no wires on other - return np.array([so, si], dtype=np.int64) + return np.array([self_out, self_in], dtype=np.int64) def __rshift__(self, other: Wires) -> Wires: + r""" + A new Wires object with the wires of ``self`` and ``other`` combined as two + components in a circuit: the output of self connects to the input of other wherever + they match. All surviving wires are arranged in the standard order. + A ValueError is raised if there are any surviving wires that overlap. + """ all_modes = sorted(set(self.modes) | set(other.modes)) new_id_array = np.zeros((len(all_modes), 4), dtype=np.int64) for m in set(self.modes) & set(other.modes): - sob, sib, sok, sik = self._mode(m) # m-th row of self - oob, oib, ook, oik = other._mode(m) # m-th row of other + sob, sib, sok, sik = self._mode(m) # row of self + oob, oib, ook, oik = other._mode(m) # row of other out_bra_issue = sob and oob and not oib out_ket_issue = sok and ook and not oik @@ -315,10 +419,7 @@ def _repr_html_(self): # pragma: no cover html += "" try: - from IPython.core.display import ( - HTML, - display, - ) + from IPython.display import display, HTML display(HTML(html)) except ImportError as e: diff --git a/tests/test_lab_dev/test_wires.py b/tests/test_lab_dev/test_wires.py index cc4921fc9..4e1241c65 100644 --- a/tests/test_lab_dev/test_wires.py +++ b/tests/test_lab_dev/test_wires.py @@ -14,83 +14,168 @@ """Tests for Wires class.""" -# pylint: disable=missing-function-docstring -# pylint: disable=protected-access +# pylint: disable=protected-access, missing-function-docstring +import numpy as np import pytest -from mrmustard.lab_dev.wires import Wires - - -def test_wires_view_has_same_ids(): - w = Wires([0], [0], [0], [0]) - assert set(w.ids) == set(w._view().ids) - - -def test_view_can_edit_original(): - w = Wires([0], [0], [0], [0]) - w._view().ids = [9, 99, 999, 9999] - assert w.ids == [9, 99, 999, 9999] - - -def test_wire_subsets(): - w = Wires([0], [1], [2], [3]) - assert w.output.bra.modes == [0] - assert w.input.bra.modes == [1] - assert w.output.ket.modes == [2] - assert w.input.ket.modes == [3] - - -def test_wire_mode_subsets(): - w = Wires([10], [11], [12], [13]) - assert w[10].ids == w.output.bra.ids - assert w[11].ids == w.input.bra.ids - assert w[12].ids == w.output.ket.ids - assert w[13].ids == w.input.ket.ids - - -def test_indices(): - w = Wires([0, 1, 2], [3, 4, 5], [6, 7], [8]) - assert w.output.indices == [0, 1, 2, 6, 7] - assert w.bra.indices == [0, 1, 2, 3, 4, 5] - assert w.input.indices == [3, 4, 5, 8] - assert w.ket.indices == [6, 7, 8] - -def test_setting_ids(): - w = Wires([0], [0], [0], [0]) - w.ids = [9, 99, 999, 9999] - assert w.ids == [9, 99, 999, 9999] - - -def test_non_overlapping_wires(): - w1 = Wires([0], [1], [2], [3]) - w2 = Wires([1], [2], [3], [4]) - w12 = Wires([0, 1], [1, 2], [2, 3], [3, 4]) - assert (w1 >> w2).modes == w12.modes - - -def test_cant_add_overlapping_wires(): - w1 = Wires([0], [1], [2], [3]) - w2 = Wires([0], [2], [3], [4]) - with pytest.raises(ValueError): - w1 >> w2 # pylint: disable=pointless-statement # type: ignore - - -def test_args(): - w = Wires([0], [1], [2], [3]) - assert w._args() == ((0,), (1,), (2,), (3,)) - - -def test_right_shift_general_contraction(): - # contracts 1,1 on bra side - # contracts 3,3 and 13,13 on ket side (note order doesn't matter) - u = Wires([1, 5], [2, 6, 15], [3, 7, 13], [4, 8]) - v = Wires([0, 9, 14], [1, 10], [2, 11], [13, 3, 12]) - assert (u >> v)._args() == ((0, 5, 9, 14), (2, 6, 10, 15), (2, 7, 11), (4, 8, 12)) +from mrmustard.lab_dev.wires import Wires -def test_error_if_cant_contract(): - u = Wires([], [], [0], []) # only output wire - v = Wires([], [], [0], []) # only output wire - with pytest.raises(ValueError): - u >> v # pylint: disable=pointless-statement # type: ignore +class TestWires: + r""" + Tests for the Wires class. + """ + + @pytest.mark.parametrize("modes_out_bra", [[0], [1, 2]]) + @pytest.mark.parametrize("modes_in_bra", [None, [1], [2, 3]]) + @pytest.mark.parametrize("modes_out_ket", [None, [2], [3, 4]]) + @pytest.mark.parametrize("modes_in_ket", [None, [3], [4, 5]]) + def test_init(self, modes_out_bra, modes_in_bra, modes_out_ket, modes_in_ket): + w = Wires(modes_out_bra, modes_in_bra, modes_out_ket, modes_in_ket) + + modes_out_bra = modes_out_bra or [] + modes_in_bra = modes_in_bra or [] + modes_out_ket = modes_out_ket or [] + modes_in_ket = modes_in_ket or [] + modes = list( + set(modes_out_bra) | set(modes_in_bra) | set(modes_out_ket) | set(modes_in_ket) + ) + + assert w.modes == modes + assert w.output.bra.modes == modes_out_bra + assert w.input.bra.modes == modes_in_bra + assert w.output.ket.modes == modes_out_ket + assert w.input.ket.modes == modes_in_ket + + def test_args(self): + w = Wires([0], [1], [2], [3]) + assert w._args() == ((0,), (1,), (2,), (3,)) + + def test_from_data(self): + id_array = [[1, 2, 0, 0], [0, 3, 4, 0], [0, 0, 5, 0], [0, 0, 0, 6]] + modes = [5, 6, 7, 8] + w = Wires._from_data(id_array, modes) + + assert np.allclose(w.id_array, id_array) + assert w.ids == [1, 2, 3, 4, 5, 6] + assert w.modes == modes + + def test_view(self): + w = Wires([0], [0], [0], [0]) + assert set(w.ids) == set(w._view().ids) + + def test_view_can_edit_original(self): + w = Wires([0], [0], [0], [0]) + w._view().ids = [9, 99, 999, 9999] + assert w.ids == [9, 99, 999, 9999] + + def test_wire_subsets(self): + w = Wires([0], [1], [2], [3]) + assert w.output.bra.modes == [0] + assert w.input.bra.modes == [1] + assert w.output.ket.modes == [2] + assert w.input.ket.modes == [3] + + w = Wires([10], [11], [12], [13]) + assert w[10].ids == w.output.bra.ids + assert w[11].ids == w.input.bra.ids + assert w[12].ids == w.output.ket.ids + assert w[13].ids == w.input.ket.ids + + def test_id_array(self): + w = Wires([0, 1], [2], [3, 4, 5], [6]) + assert w.id_array.shape == (7, 4) + + def test_ids(self): + w = Wires([0, 1], [2], [3, 4, 5], [6]) + + assert w.output.bra.ids == w.ids[:2] + assert w.input.bra.ids == [w.ids[2]] + assert w.output.ket.ids == w.ids[3:6] + assert w.input.ket.ids == [w.ids[-1]] + + def test_ids_setter(self): + w1 = Wires([0, 1], [2], [3, 4, 5], [6]) + w2 = Wires([0, 1], [2], [3, 4, 5], [6]) + + assert w1.ids != w2.ids + + w1.ids = w2.ids + assert w1.ids == w2.ids + + def test_indices(self): + w = Wires([0, 1, 2], [3, 4, 5], [6, 7], [8]) + + assert w.output.indices == [0, 1, 2, 6, 7] + assert w.bra.indices == [0, 1, 2, 3, 4, 5] + assert w.input.indices == [3, 4, 5, 8] + assert w.ket.indices == [6, 7, 8] + + def test_adjoint(self): + w = Wires([0, 1, 2], [3, 4, 5], [6, 7], [8]) + w_adj = w.adjoint + + assert w.input.ket.modes == w_adj.input.bra.modes + assert w.output.ket.modes == w_adj.output.bra.modes + assert w.input.bra.modes == w_adj.input.ket.modes + assert w.output.bra.modes == w_adj.output.ket.modes + + def test_dual(self): + w = Wires([0, 1, 2], [3, 4, 5], [6, 7], [8]) + w_d = w.dual + + assert w.input.ket.modes == w_d.output.ket.modes + assert w.output.ket.modes == w_d.input.ket.modes + assert w.input.bra.modes == w_d.output.bra.modes + assert w.output.bra.modes == w_d.input.bra.modes + + def test_copy(self): + w = Wires([0, 1, 2], [3, 4, 5], [6, 7], [8]) + w_cp = w.copy() + + assert w.input.ket.modes == w_cp.input.ket.modes + assert w.output.ket.modes == w_cp.output.ket.modes + assert w.input.bra.modes == w_cp.input.bra.modes + assert w.output.bra.modes == w_cp.output.bra.modes + + def test_add(self): + w1 = Wires([0], [1], [2], [3]) + w2 = Wires([1], [2], [3], [4]) + w12 = Wires([0, 1], [1, 2], [2, 3], [3, 4]) + + assert (w1 + w2).modes == w12.modes + + def test_add_error(self): + w1 = Wires([0], [1], [2], [3]) + w2 = Wires([0], [2], [3], [4]) + with pytest.raises(Exception): + w1 + w2 + + def test_bool(self): + assert Wires([0]) + assert not Wires([0]).input + + def test_getitem(self): + w = Wires([0, 1], [0, 1]) + w0 = w[0] + w1 = w[1] + + assert w0.modes == [0] + assert w0.ids == [w.ids[0], w.ids[2]] + + assert w1.modes == [1] + assert w1.ids == [w.ids[1], w.ids[3]] + + def test_rshift(self): + # contracts 1,1 on bra side + # contracts 3,3 and 13,13 on ket side (note order doesn't matter) + u = Wires([1, 5], [2, 6, 15], [3, 7, 13], [4, 8]) + v = Wires([0, 9, 14], [1, 10], [2, 11], [13, 3, 12]) + assert (u >> v)._args() == ((0, 5, 9, 14), (2, 6, 10, 15), (2, 7, 11), (4, 8, 12)) + + def test_rshift_error(self): + u = Wires([], [], [0], []) # only output wire + v = Wires([], [], [0], []) # only output wire + with pytest.raises(ValueError): + u >> v From e26a19e4a5cb8a238f8ce88905b26e1d9488872f Mon Sep 17 00:00:00 2001 From: Filippo Miatto Date: Thu, 1 Feb 2024 11:51:20 -0800 Subject: [PATCH 26/30] Update mrmustard/lab_dev/wires.py Co-authored-by: SamFerracin --- mrmustard/lab_dev/wires.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mrmustard/lab_dev/wires.py b/mrmustard/lab_dev/wires.py index 291f19af4..d7e50d5ad 100644 --- a/mrmustard/lab_dev/wires.py +++ b/mrmustard/lab_dev/wires.py @@ -23,7 +23,6 @@ __all__ = ["Wires"] -# pylint: disable=import-outside-toplevel class Wires: From 832f1439ad02f1851125edf2d1d24f1cdc0713b4 Mon Sep 17 00:00:00 2001 From: SamFerracin Date: Fri, 9 Feb 2024 10:17:59 -0500 Subject: [PATCH 27/30] black + ipython --- mrmustard/lab_dev/wires.py | 12 +- poetry.lock | 530 ++++++++++++++++++++++++++----------- pyproject.toml | 1 + 3 files changed, 377 insertions(+), 166 deletions(-) diff --git a/mrmustard/lab_dev/wires.py b/mrmustard/lab_dev/wires.py index d7e50d5ad..a96391dbe 100644 --- a/mrmustard/lab_dev/wires.py +++ b/mrmustard/lab_dev/wires.py @@ -16,6 +16,7 @@ from __future__ import annotations +from IPython.display import display, HTML from typing import Iterable, Optional import numpy as np @@ -24,7 +25,6 @@ __all__ = ["Wires"] - class Wires: r""" A class with wire functionality for tensor network applications. @@ -416,12 +416,4 @@ def _repr_html_(self): # pragma: no cover html += row_html html += "" - - try: - from IPython.display import display, HTML - - display(HTML(html)) - except ImportError as e: - raise ImportError( - "To display the wires in a jupyter notebook you need to `pip install IPython` first." - ) from e + display(HTML(html)) diff --git a/poetry.lock b/poetry.lock index 9bab967b6..fec0eab42 100644 --- a/poetry.lock +++ b/poetry.lock @@ -63,6 +63,24 @@ lazy-object-proxy = ">=1.4.0" setuptools = ">=20.0" wrapt = ">=1.11,<1.13" +[[package]] +name = "asttokens" +version = "2.4.1" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = "*" +files = [ + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, +] + +[package.dependencies] +six = ">=1.12.0" + +[package.extras] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] + [[package]] name = "astunparse" version = "1.6.3" @@ -586,6 +604,20 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "executing" +version = "2.0.1" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.5" +files = [ + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + [[package]] name = "filelock" version = "3.13.1" @@ -615,60 +647,60 @@ files = [ [[package]] name = "fonttools" -version = "4.47.2" +version = "4.48.1" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.47.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3b629108351d25512d4ea1a8393a2dba325b7b7d7308116b605ea3f8e1be88df"}, - {file = "fonttools-4.47.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c19044256c44fe299d9a73456aabee4b4d06c6b930287be93b533b4737d70aa1"}, - {file = "fonttools-4.47.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8be28c036b9f186e8c7eaf8a11b42373e7e4949f9e9f370202b9da4c4c3f56c"}, - {file = "fonttools-4.47.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f83a4daef6d2a202acb9bf572958f91cfde5b10c8ee7fb1d09a4c81e5d851fd8"}, - {file = "fonttools-4.47.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a5a5318ba5365d992666ac4fe35365f93004109d18858a3e18ae46f67907670"}, - {file = "fonttools-4.47.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8f57ecd742545362a0f7186774b2d1c53423ed9ece67689c93a1055b236f638c"}, - {file = "fonttools-4.47.2-cp310-cp310-win32.whl", hash = "sha256:a1c154bb85dc9a4cf145250c88d112d88eb414bad81d4cb524d06258dea1bdc0"}, - {file = "fonttools-4.47.2-cp310-cp310-win_amd64.whl", hash = "sha256:3e2b95dce2ead58fb12524d0ca7d63a63459dd489e7e5838c3cd53557f8933e1"}, - {file = "fonttools-4.47.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:29495d6d109cdbabe73cfb6f419ce67080c3ef9ea1e08d5750240fd4b0c4763b"}, - {file = "fonttools-4.47.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0a1d313a415eaaba2b35d6cd33536560deeebd2ed758b9bfb89ab5d97dc5deac"}, - {file = "fonttools-4.47.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90f898cdd67f52f18049250a6474185ef6544c91f27a7bee70d87d77a8daf89c"}, - {file = "fonttools-4.47.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3480eeb52770ff75140fe7d9a2ec33fb67b07efea0ab5129c7e0c6a639c40c70"}, - {file = "fonttools-4.47.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0255dbc128fee75fb9be364806b940ed450dd6838672a150d501ee86523ac61e"}, - {file = "fonttools-4.47.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f791446ff297fd5f1e2247c188de53c1bfb9dd7f0549eba55b73a3c2087a2703"}, - {file = "fonttools-4.47.2-cp311-cp311-win32.whl", hash = "sha256:740947906590a878a4bde7dd748e85fefa4d470a268b964748403b3ab2aeed6c"}, - {file = "fonttools-4.47.2-cp311-cp311-win_amd64.whl", hash = "sha256:63fbed184979f09a65aa9c88b395ca539c94287ba3a364517698462e13e457c9"}, - {file = "fonttools-4.47.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4ec558c543609e71b2275c4894e93493f65d2f41c15fe1d089080c1d0bb4d635"}, - {file = "fonttools-4.47.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e040f905d542362e07e72e03612a6270c33d38281fd573160e1003e43718d68d"}, - {file = "fonttools-4.47.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6dd58cc03016b281bd2c74c84cdaa6bd3ce54c5a7f47478b7657b930ac3ed8eb"}, - {file = "fonttools-4.47.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32ab2e9702dff0dd4510c7bb958f265a8d3dd5c0e2547e7b5f7a3df4979abb07"}, - {file = "fonttools-4.47.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a808f3c1d1df1f5bf39be869b6e0c263570cdafb5bdb2df66087733f566ea71"}, - {file = "fonttools-4.47.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ac71e2e201df041a2891067dc36256755b1229ae167edbdc419b16da78732c2f"}, - {file = "fonttools-4.47.2-cp312-cp312-win32.whl", hash = "sha256:69731e8bea0578b3c28fdb43dbf95b9386e2d49a399e9a4ad736b8e479b08085"}, - {file = "fonttools-4.47.2-cp312-cp312-win_amd64.whl", hash = "sha256:b3e1304e5f19ca861d86a72218ecce68f391646d85c851742d265787f55457a4"}, - {file = "fonttools-4.47.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:254d9a6f7be00212bf0c3159e0a420eb19c63793b2c05e049eb337f3023c5ecc"}, - {file = "fonttools-4.47.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eabae77a07c41ae0b35184894202305c3ad211a93b2eb53837c2a1143c8bc952"}, - {file = "fonttools-4.47.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86a5ab2873ed2575d0fcdf1828143cfc6b977ac448e3dc616bb1e3d20efbafa"}, - {file = "fonttools-4.47.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13819db8445a0cec8c3ff5f243af6418ab19175072a9a92f6cc8ca7d1452754b"}, - {file = "fonttools-4.47.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4e743935139aa485fe3253fc33fe467eab6ea42583fa681223ea3f1a93dd01e6"}, - {file = "fonttools-4.47.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d49ce3ea7b7173faebc5664872243b40cf88814ca3eb135c4a3cdff66af71946"}, - {file = "fonttools-4.47.2-cp38-cp38-win32.whl", hash = "sha256:94208ea750e3f96e267f394d5588579bb64cc628e321dbb1d4243ffbc291b18b"}, - {file = "fonttools-4.47.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f750037e02beb8b3569fbff701a572e62a685d2a0e840d75816592280e5feae"}, - {file = "fonttools-4.47.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3d71606c9321f6701642bd4746f99b6089e53d7e9817fc6b964e90d9c5f0ecc6"}, - {file = "fonttools-4.47.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:86e0427864c6c91cf77f16d1fb9bf1bbf7453e824589e8fb8461b6ee1144f506"}, - {file = "fonttools-4.47.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a00bd0e68e88987dcc047ea31c26d40a3c61185153b03457956a87e39d43c37"}, - {file = "fonttools-4.47.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5d77479fb885ef38a16a253a2f4096bc3d14e63a56d6246bfdb56365a12b20c"}, - {file = "fonttools-4.47.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5465df494f20a7d01712b072ae3ee9ad2887004701b95cb2cc6dcb9c2c97a899"}, - {file = "fonttools-4.47.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4c811d3c73b6abac275babb8aa439206288f56fdb2c6f8835e3d7b70de8937a7"}, - {file = "fonttools-4.47.2-cp39-cp39-win32.whl", hash = "sha256:5b60e3afa9635e3dfd3ace2757039593e3bd3cf128be0ddb7a1ff4ac45fa5a50"}, - {file = "fonttools-4.47.2-cp39-cp39-win_amd64.whl", hash = "sha256:7ee48bd9d6b7e8f66866c9090807e3a4a56cf43ffad48962725a190e0dd774c8"}, - {file = "fonttools-4.47.2-py3-none-any.whl", hash = "sha256:7eb7ad665258fba68fd22228a09f347469d95a97fb88198e133595947a20a184"}, - {file = "fonttools-4.47.2.tar.gz", hash = "sha256:7df26dd3650e98ca45f1e29883c96a0b9f5bb6af8d632a6a108bc744fa0bd9b3"}, -] - -[package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] + {file = "fonttools-4.48.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:702ae93058c81f46461dc4b2c79f11d3c3d8fd7296eaf8f75b4ba5bbf813cd5f"}, + {file = "fonttools-4.48.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97f0a49fa6aa2d6205c6f72f4f98b74ef4b9bfdcb06fd78e6fe6c7af4989b63e"}, + {file = "fonttools-4.48.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3260db55f1843e57115256e91247ad9f68cb02a434b51262fe0019e95a98738"}, + {file = "fonttools-4.48.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e740a7602c2bb71e1091269b5dbe89549749a8817dc294b34628ffd8b2bf7124"}, + {file = "fonttools-4.48.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4108b1d247953dd7c90ec8f457a2dec5fceb373485973cc852b14200118a51ee"}, + {file = "fonttools-4.48.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56339ec557f0c342bddd7c175f5e41c45fc21282bee58a86bd9aa322bec715f2"}, + {file = "fonttools-4.48.1-cp310-cp310-win32.whl", hash = "sha256:bff5b38d0e76eb18e0b8abbf35d384e60b3371be92f7be36128ee3e67483b3ec"}, + {file = "fonttools-4.48.1-cp310-cp310-win_amd64.whl", hash = "sha256:f7449493886da6a17472004d3818cc050ba3f4a0aa03fb47972e4fa5578e6703"}, + {file = "fonttools-4.48.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:18b35fd1a850ed7233a99bbd6774485271756f717dac8b594958224b54118b61"}, + {file = "fonttools-4.48.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cad5cfd044ea2e306fda44482b3dd32ee47830fa82dfa4679374b41baa294f5f"}, + {file = "fonttools-4.48.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f30e605c7565d0da6f0aec75a30ec372072d016957cd8fc4469721a36ea59b7"}, + {file = "fonttools-4.48.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aee76fd81a8571c68841d6ef0da750d5ff08ff2c5f025576473016f16ac3bcf7"}, + {file = "fonttools-4.48.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5057ade278e67923000041e2b195c9ea53e87f227690d499b6a4edd3702f7f01"}, + {file = "fonttools-4.48.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b10633aafc5932995a391ec07eba5e79f52af0003a1735b2306b3dab8a056d48"}, + {file = "fonttools-4.48.1-cp311-cp311-win32.whl", hash = "sha256:0d533f89819f9b3ee2dbedf0fed3825c425850e32bdda24c558563c71be0064e"}, + {file = "fonttools-4.48.1-cp311-cp311-win_amd64.whl", hash = "sha256:d20588466367f05025bb1efdf4e5d498ca6d14bde07b6928b79199c588800f0a"}, + {file = "fonttools-4.48.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0a2417547462e468edf35b32e3dd06a6215ac26aa6316b41e03b8eeaf9f079ea"}, + {file = "fonttools-4.48.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cf5a0cd974f85a80b74785db2d5c3c1fd6cc09a2ba3c837359b2b5da629ee1b0"}, + {file = "fonttools-4.48.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0452fcbfbce752ba596737a7c5ec5cf76bc5f83847ce1781f4f90eab14ece252"}, + {file = "fonttools-4.48.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578c00f93868f64a4102ecc5aa600a03b49162c654676c3fadc33de2ddb88a81"}, + {file = "fonttools-4.48.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:63dc592a16cd08388d8c4c7502b59ac74190b23e16dfc863c69fe1ea74605b68"}, + {file = "fonttools-4.48.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9b58638d8a85e3a1b32ec0a91d9f8171a877b4b81c408d4cb3257d0dee63e092"}, + {file = "fonttools-4.48.1-cp312-cp312-win32.whl", hash = "sha256:d10979ef14a8beaaa32f613bb698743f7241d92f437a3b5e32356dfb9769c65d"}, + {file = "fonttools-4.48.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdfd7557d1bd294a200bd211aa665ca3b02998dcc18f8211a5532da5b8fad5c5"}, + {file = "fonttools-4.48.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3cdb9a92521b81bf717ebccf592bd0292e853244d84115bfb4db0c426de58348"}, + {file = "fonttools-4.48.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b4ec6d42a7555f5ae35f3b805482f0aad0f1baeeef54859492ea3b782959d4a"}, + {file = "fonttools-4.48.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:902e9c4e9928301912f34a6638741b8ae0b64824112b42aaf240e06b735774b1"}, + {file = "fonttools-4.48.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8c8b54bd1420c184a995f980f1a8076f87363e2bb24239ef8c171a369d85a31"}, + {file = "fonttools-4.48.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:12ee86abca46193359ea69216b3a724e90c66ab05ab220d39e3fc068c1eb72ac"}, + {file = "fonttools-4.48.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6978bade7b6c0335095bdd0bd97f8f3d590d2877b370f17e03e0865241694eb5"}, + {file = "fonttools-4.48.1-cp38-cp38-win32.whl", hash = "sha256:bcd77f89fc1a6b18428e7a55dde8ef56dae95640293bfb8f4e929929eba5e2a2"}, + {file = "fonttools-4.48.1-cp38-cp38-win_amd64.whl", hash = "sha256:f40441437b039930428e04fb05ac3a132e77458fb57666c808d74a556779e784"}, + {file = "fonttools-4.48.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0d2b01428f7da26f229a5656defc824427b741e454b4e210ad2b25ed6ea2aed4"}, + {file = "fonttools-4.48.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:df48798f9a4fc4c315ab46e17873436c8746f5df6eddd02fad91299b2af7af95"}, + {file = "fonttools-4.48.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2eb4167bde04e172a93cf22c875d8b0cff76a2491f67f5eb069566215302d45d"}, + {file = "fonttools-4.48.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c900508c46274d32d308ae8e82335117f11aaee1f7d369ac16502c9a78930b0a"}, + {file = "fonttools-4.48.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:594206b31c95fcfa65f484385171fabb4ec69f7d2d7f56d27f17db26b7a31814"}, + {file = "fonttools-4.48.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:292922dc356d7f11f5063b4111a8b719efb8faea92a2a88ed296408d449d8c2e"}, + {file = "fonttools-4.48.1-cp39-cp39-win32.whl", hash = "sha256:4709c5bf123ba10eac210d2d5c9027d3f472591d9f1a04262122710fa3d23199"}, + {file = "fonttools-4.48.1-cp39-cp39-win_amd64.whl", hash = "sha256:63c73b9dd56a94a3cbd2f90544b5fca83666948a9e03370888994143b8d7c070"}, + {file = "fonttools-4.48.1-py3-none-any.whl", hash = "sha256:e3e33862fc5261d46d9aae3544acb36203b1a337d00bdb5d3753aae50dac860e"}, + {file = "fonttools-4.48.1.tar.gz", hash = "sha256:8b8a45254218679c7f1127812761e7854ed5c8e34349aebf581e8c9204e7495a"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] interpolatable = ["munkres", "pycairo", "scipy"] -lxml = ["lxml (>=4.0,<5)"] +lxml = ["lxml (>=4.0)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] repacker = ["uharfbuzz (>=0.23.0)"] @@ -766,13 +798,13 @@ files = [ [[package]] name = "fsspec" -version = "2023.12.2" +version = "2024.2.0" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2023.12.2-py3-none-any.whl", hash = "sha256:d800d87f72189a745fa3d6b033b9dc4a34ad069f60ca60b943a63599f5501960"}, - {file = "fsspec-2023.12.2.tar.gz", hash = "sha256:8548d39e8810b59c38014934f6b31e57f40c1b20f911f4cc2b85389c7e9bf0cb"}, + {file = "fsspec-2024.2.0-py3-none-any.whl", hash = "sha256:817f969556fa5916bc682e02ca2045f96ff7f586d45110fcb76022063ad2c7d8"}, + {file = "fsspec-2024.2.0.tar.gz", hash = "sha256:b6ad1a679f760dda52b1168c859d01b7b80648ea6f7f7c7f5a8a91dc3f3ecb84"}, ] [package.extras] @@ -790,7 +822,7 @@ github = ["requests"] gs = ["gcsfs"] gui = ["panel"] hdfs = ["pyarrow (>=1)"] -http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "requests"] +http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"] libarchive = ["libarchive-c"] oci = ["ocifs"] s3 = ["s3fs"] @@ -835,13 +867,13 @@ requests = ["requests (>=2.20.0,<3.0.0.dev0)"] [[package]] name = "google-auth-oauthlib" -version = "1.0.0" +version = "1.2.0" description = "Google Authentication Library" optional = false python-versions = ">=3.6" files = [ - {file = "google-auth-oauthlib-1.0.0.tar.gz", hash = "sha256:e375064964820b47221a7e1b7ee1fd77051b6323c3f9e3e19785f78ab67ecfc5"}, - {file = "google_auth_oauthlib-1.0.0-py2.py3-none-any.whl", hash = "sha256:95880ca704928c300f48194d1770cf5b1462835b6e49db61445a520f793fd5fb"}, + {file = "google-auth-oauthlib-1.2.0.tar.gz", hash = "sha256:292d2d3783349f2b0734a0a0207b1e1e322ac193c2c09d8f7c613fb7cc501ea8"}, + {file = "google_auth_oauthlib-1.2.0-py2.py3-none-any.whl", hash = "sha256:297c1ce4cb13a99b5834c74a1fe03252e1e499716718b190f56bcb9c4abc4faf"}, ] [package.dependencies] @@ -1070,6 +1102,43 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "ipython" +version = "8.18.1" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.9" +files = [ + {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, + {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +prompt-toolkit = ">=3.0.41,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} + +[package.extras] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +black = ["black"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] + [[package]] name = "isort" version = "5.13.2" @@ -1084,6 +1153,25 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] +[[package]] +name = "jedi" +version = "0.19.1" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, +] + +[package.dependencies] +parso = ">=0.8.3,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + [[package]] name = "jinja2" version = "3.1.3" @@ -1163,13 +1251,13 @@ test = ["ipython", "mock", "numpy", "pytest (>=4.4)"] [[package]] name = "keras" -version = "2.14.0" +version = "2.15.0" description = "Deep learning for humans." optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "keras-2.14.0-py3-none-any.whl", hash = "sha256:d7429d1d2131cc7eb1f2ea2ec330227c7d9d38dab3dfdf2e78defee4ecc43fcd"}, - {file = "keras-2.14.0.tar.gz", hash = "sha256:22788bdbc86d9988794fe9703bb5205141da797c4faeeb59497c58c3d94d34ed"}, + {file = "keras-2.15.0-py3-none-any.whl", hash = "sha256:2dcc6d2e30cf9c951064b63c1f4c404b966c59caf09e01f3549138ec8ee0dd1f"}, + {file = "keras-2.15.0.tar.gz", hash = "sha256:81871d298c064dc4ac6b58440fdae67bfcf47c8d7ad28580fab401834c06a575"}, ] [[package]] @@ -1564,6 +1652,20 @@ pillow = ">=8" pyparsing = ">=2.3.1" python-dateutil = ">=2.7" +[[package]] +name = "matplotlib-inline" +version = "0.1.6" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.5" +files = [ + {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, + {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, +] + +[package.dependencies] +traitlets = "*" + [[package]] name = "mccabe" version = "0.6.1" @@ -1924,6 +2026,21 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + [[package]] name = "partd" version = "1.4.1" @@ -1953,6 +2070,20 @@ files = [ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] +[[package]] +name = "pexpect" +version = "4.9.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + [[package]] name = "pillow" version = "10.2.0" @@ -2068,6 +2199,20 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "prompt-toolkit" +version = "3.0.43" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, + {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, +] + +[package.dependencies] +wcwidth = "*" + [[package]] name = "protobuf" version = "4.25.2" @@ -2088,6 +2233,31 @@ files = [ {file = "protobuf-4.25.2.tar.gz", hash = "sha256:fe599e175cb347efc8ee524bcd4b902d11f7262c0e569ececcb89995c15f0a5e"}, ] +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] + +[package.extras] +tests = ["pytest"] + [[package]] name = "pyaml" version = "23.12.0" @@ -2386,31 +2556,31 @@ files = [ [[package]] name = "ray" -version = "2.9.1" +version = "2.9.2" description = "Ray provides a simple, universal API for building distributed applications." optional = true python-versions = ">=3.8" files = [ - {file = "ray-2.9.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:586d462e555ba51840fbfce4d62b0ed886930e520517b34a88befeb4fb4c244a"}, - {file = "ray-2.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb3dbb0639fedf2bc2b98784bb94dbdc2c2a470c91c6b54e12c51d0a0069aebf"}, - {file = "ray-2.9.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:74a1d12117e87ffd7411fadb96b40bf66ca7d32fdb2049cd3dd66705a0923f9e"}, - {file = "ray-2.9.1-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:50436361012cefdd90ebb8c920711cb334cf64d7a5677c9b72e60d8c9e23ee70"}, - {file = "ray-2.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:8760d406d782cbf6684c2b98c09bd4893a14c009c2287cbe65aa11cb6e7a571f"}, - {file = "ray-2.9.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:cd974b141088b752d1eed4d6d0cf94e8ed63b97d5f1d5f5844970f3f373dde87"}, - {file = "ray-2.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e9d99496effa490f94e43c10a09964146269733cd24610d3b6902b566190a9b"}, - {file = "ray-2.9.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:1907649d69efdc1b9ffbc03db086f6d768216cb73908ebd4038ac5030effef9e"}, - {file = "ray-2.9.1-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:fabc520990c1b98dde592813d62737e5e817460e0ac359f32ba029ace292cbe2"}, - {file = "ray-2.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:bb0c83c0f40a5ab4139f9357d3fd4ef8a2e8b46f5c023fe45f305fe2297c520c"}, - {file = "ray-2.9.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:e7b1f3284b35aa98968ba8cdc8ea43f6a0afe42090711f2db678d3f73c5cb8f9"}, - {file = "ray-2.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:38b7a3282783f74cfd232b0e04bfde40e51e13bf3f83423ce97b2ae577a4a345"}, - {file = "ray-2.9.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:177a5a018d9ff0eef822b279f7af62ca5f5935e4d83246105868017ee298faae"}, - {file = "ray-2.9.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:917efa43b88d5f5de19a5ffa7c4aa0aa28399a0c33595d83c26d5b9f79dfb861"}, - {file = "ray-2.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:94961e948763a101d99f9e9cfe8ba1d789f5ca030ebc8089fbf02da1d085f870"}, - {file = "ray-2.9.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:9efc8a2035521c5d66b625222a7b03c7759f1c0969d382697fd688577bea21a4"}, - {file = "ray-2.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4aa6a66fb20a35ded74674ad8d48e813afd4e65a0bc8ccd99e981bccf656ce13"}, - {file = "ray-2.9.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f063f0140bc1ea0b02f8ee59abd8e964866c1ca6c768a2b0fd19b691cf9feace"}, - {file = "ray-2.9.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:334c47ca24dbe59e295e2d46152c09ff113f2c2cde873181da11c24dfdacfcfb"}, - {file = "ray-2.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:c2e360743ae25babfcb436250275550fd96a567c830393ff5dd7fc708875c4c9"}, + {file = "ray-2.9.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:f879522e7d9b809d3aa28fb627ab87344b31cf79e1829b9b67f0581305e2bb84"}, + {file = "ray-2.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ccbcf7f57bf10c52b3ebcec6e8d9114491ef12a20255e70ba0d5f12a81e9391c"}, + {file = "ray-2.9.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a3059e1d4287db33811e7604b4ecc1aa79dc2d745b49e5ec3415060da61cb749"}, + {file = "ray-2.9.2-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:11a0fd3f75ca07f727b1e83c3b2c74e75dc1fe0aba99a416a865f83e7ff23620"}, + {file = "ray-2.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:1e5c4733314bab19d89b373836899e76b2ab839d45f59966b431c89076feaab7"}, + {file = "ray-2.9.2-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:1a734c1c586e666f5024b46405c3df52b634977c9565bca16a01d6fefc457578"}, + {file = "ray-2.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:47975fcb4b6e6cadd35da4b78f3e643f5ab6e99a688d79980ca2f0dca345d034"}, + {file = "ray-2.9.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:7d7ed76fa40abe81eefb158d505f046de0614d994fc8027f5b05889824503257"}, + {file = "ray-2.9.2-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:83fd7961d39da5ae68731be430891a21a13d0257bc25ab6adf13712297e309fa"}, + {file = "ray-2.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:5929ac8221ba3b6446cd0885a0ade50cfaaecacba771dfeed57ead8b5c6fdd14"}, + {file = "ray-2.9.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:61b5a742f1f249e92893433720423f729018d40ee26a015b6a12b443d0e2e3eb"}, + {file = "ray-2.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:51552b1142944e13ba1da0c44395a627701c563fbe3f6c490001e6e4fd0ee011"}, + {file = "ray-2.9.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8b715b0ad9aa027836ecb7dc33b3a2dfc91c5d9d22a0ddf72c0844df5d641fca"}, + {file = "ray-2.9.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:e1a35e2a3de4e3875bd1e76770fb89149adc773193a5e79488db4047ef14ffd0"}, + {file = "ray-2.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:8d97f674c675370550ec4347e7e8dee0f99e38dd8f220ff8acb8ca15c208d73a"}, + {file = "ray-2.9.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:efa2c60ab11f41e4d43a227cd6bf491f9f2f8ed820c482c7d8d86a2412b6fd05"}, + {file = "ray-2.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5ebd71ef2e4d76752a1ff048e9d4c22811c7e990e8d4e3b30974b3e4099411b6"}, + {file = "ray-2.9.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d84064ab3aa2868991a98dc6a54cc2221abcaf9406eb95fa2ec0f66006585f92"}, + {file = "ray-2.9.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:bc95efd035dcdc2f2b549ce3e13c5abf2043f3136b8a5980d77f4f098a9a6796"}, + {file = "ray-2.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:aea2ad4dbad2d6bd21ba17f7a2fcf762f53d8bcbc30b9d6916245e447a971e48"}, ] [package.dependencies] @@ -2430,16 +2600,16 @@ requests = "*" tensorboardX = {version = ">=1.9", optional = true, markers = "extra == \"tune\""} [package.extras] -air = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi", "fsspec", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "numpy (>=1.20)", "opencensus", "pandas", "pandas (>=1.3)", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pyarrow (>=6.0.1)", "pydantic (<2.0.dev0 || >=2.5.dev0,<3)", "requests", "smart-open", "starlette", "tensorboardX (>=1.9)", "uvicorn[standard]", "virtualenv (>=20.0.24,!=20.21.1)", "watchfiles"] -all = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "dm-tree", "fastapi", "fsspec", "gpustat (>=1.0.0)", "grpcio (!=1.56.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "gymnasium (==0.28.1)", "lz4", "numpy (>=1.20)", "opencensus", "opentelemetry-api", "opentelemetry-exporter-otlp", "opentelemetry-sdk", "pandas", "pandas (>=1.3)", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pyarrow (>=6.0.1)", "pydantic (<2.0.dev0 || >=2.5.dev0,<3)", "pyyaml", "ray-cpp (==2.9.1)", "requests", "rich", "scikit-image", "scipy", "smart-open", "starlette", "tensorboardX (>=1.9)", "typer", "uvicorn[standard]", "virtualenv (>=20.0.24,!=20.21.1)", "watchfiles"] +air = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi (<=0.108.0)", "fsspec", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "numpy (>=1.20)", "opencensus", "pandas", "pandas (>=1.3)", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pyarrow (>=6.0.1)", "pydantic (<2.0.dev0 || >=2.5.dev0,<3)", "requests", "smart-open", "starlette", "tensorboardX (>=1.9)", "uvicorn[standard]", "virtualenv (>=20.0.24,!=20.21.1)", "watchfiles"] +all = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "dm-tree", "fastapi (<=0.108.0)", "fsspec", "gpustat (>=1.0.0)", "grpcio (!=1.56.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "gymnasium (==0.28.1)", "lz4", "numpy (>=1.20)", "opencensus", "opentelemetry-api", "opentelemetry-exporter-otlp", "opentelemetry-sdk", "pandas", "pandas (>=1.3)", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pyarrow (>=6.0.1)", "pydantic (<2.0.dev0 || >=2.5.dev0,<3)", "pyyaml", "ray-cpp (==2.9.2)", "requests", "rich", "scikit-image", "scipy", "smart-open", "starlette", "tensorboardX (>=1.9)", "typer", "uvicorn[standard]", "virtualenv (>=20.0.24,!=20.21.1)", "watchfiles"] client = ["grpcio (!=1.56.0)"] -cpp = ["ray-cpp (==2.9.1)"] +cpp = ["ray-cpp (==2.9.2)"] data = ["fsspec", "numpy (>=1.20)", "pandas (>=1.3)", "pyarrow (>=6.0.1)"] default = ["aiohttp (>=3.7)", "aiohttp-cors", "colorful", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2.0.dev0 || >=2.5.dev0,<3)", "requests", "smart-open", "virtualenv (>=20.0.24,!=20.21.1)"] observability = ["opentelemetry-api", "opentelemetry-exporter-otlp", "opentelemetry-sdk"] rllib = ["dm-tree", "fsspec", "gymnasium (==0.28.1)", "lz4", "pandas", "pyarrow (>=6.0.1)", "pyyaml", "requests", "rich", "scikit-image", "scipy", "tensorboardX (>=1.9)", "typer"] -serve = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2.0.dev0 || >=2.5.dev0,<3)", "requests", "smart-open", "starlette", "uvicorn[standard]", "virtualenv (>=20.0.24,!=20.21.1)", "watchfiles"] -serve-grpc = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2.0.dev0 || >=2.5.dev0,<3)", "requests", "smart-open", "starlette", "uvicorn[standard]", "virtualenv (>=20.0.24,!=20.21.1)", "watchfiles"] +serve = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi (<=0.108.0)", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2.0.dev0 || >=2.5.dev0,<3)", "requests", "smart-open", "starlette", "uvicorn[standard]", "virtualenv (>=20.0.24,!=20.21.1)", "watchfiles"] +serve-grpc = ["aiohttp (>=3.7)", "aiohttp-cors", "aiorwlock", "colorful", "fastapi (<=0.108.0)", "gpustat (>=1.0.0)", "grpcio (>=1.32.0)", "grpcio (>=1.42.0)", "opencensus", "prometheus-client (>=0.7.1)", "py-spy (>=0.2.0)", "pydantic (<2.0.dev0 || >=2.5.dev0,<3)", "requests", "smart-open", "starlette", "uvicorn[standard]", "virtualenv (>=20.0.24,!=20.21.1)", "watchfiles"] train = ["fsspec", "pandas", "pyarrow (>=6.0.1)", "requests", "tensorboardX (>=1.9)"] tune = ["fsspec", "pandas", "pyarrow (>=6.0.1)", "requests", "tensorboardX (>=1.9)"] @@ -3034,6 +3204,25 @@ lint = ["docutils-stubs", "flake8", "mypy"] standalone = ["Sphinx (>=5)"] test = ["pytest"] +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + [[package]] name = "sympy" version = "1.12" @@ -3050,22 +3239,22 @@ mpmath = ">=0.19" [[package]] name = "tensorboard" -version = "2.14.1" +version = "2.15.2" description = "TensorBoard lets you watch Tensors Flow" optional = false python-versions = ">=3.9" files = [ - {file = "tensorboard-2.14.1-py3-none-any.whl", hash = "sha256:3db108fb58f023b6439880e177743c5f1e703e9eeb5fb7d597871f949f85fd58"}, + {file = "tensorboard-2.15.2-py3-none-any.whl", hash = "sha256:a6f6443728064d962caea6d34653e220e34ef8df764cb06a8212c17e1a8f0622"}, ] [package.dependencies] absl-py = ">=0.4" google-auth = ">=1.6.3,<3" -google-auth-oauthlib = ">=0.5,<1.1" +google-auth-oauthlib = ">=0.5,<2" grpcio = ">=1.48.2" markdown = ">=2.6.8" numpy = ">=1.12.0" -protobuf = ">=3.19.6" +protobuf = ">=3.19.6,<4.24.0 || >4.24.0" requests = ">=2.21.0,<3" setuptools = ">=41.0.0" six = ">1.9" @@ -3102,26 +3291,26 @@ protobuf = ">=3.20" [[package]] name = "tensorflow" -version = "2.14.1" +version = "2.15.0" description = "TensorFlow is an open source machine learning framework for everyone." optional = false python-versions = ">=3.9" files = [ - {file = "tensorflow-2.14.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:f6e9ac1e53db30f1759148f731f87b9d12da5ce0f153fc49406824efd486aae7"}, - {file = "tensorflow-2.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:7156bf1f7311dada7dba5345b526a38e6f4e4f4b8509bee162a24342bf6571b2"}, - {file = "tensorflow-2.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5781aadad5b46e2de4e373b0ca15a852b90d58982270a6db02ec52e4986316d"}, - {file = "tensorflow-2.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a955c42164eff4d751732c1274ca4bf059db60c9e2362098ce1eed7177c3fe9"}, - {file = "tensorflow-2.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:4be5f4327a6e854f64b4dcfd08a51c5fc7cc3fea8c76c5bf5c0c3deb002d5221"}, - {file = "tensorflow-2.14.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:597dd6665a91b3d4b881f0d40277eb55b65b04567553206a46e7db9cfa067310"}, - {file = "tensorflow-2.14.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:9833e61423ad2726f81e3fc770558b81d5f0a454bdb2dad717c5474ea837ce91"}, - {file = "tensorflow-2.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14a48a087954722d9e73086e8ce28a14b1f9f889ea5845c7c0bf30d8747ab6e2"}, - {file = "tensorflow-2.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9aa05a98450fa5bc4efd529383b7d15c10ec12b0238a6744baa1508c4bfa4d5"}, - {file = "tensorflow-2.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:11958d12e39d44a9f5fc753fc312dd1726a8506f2d2606e01421ca4ee9dc5c55"}, - {file = "tensorflow-2.14.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d95404f78a8d5e3d2481383dbe2d2286341ccf9bc5cbb19d857c646494d860c6"}, - {file = "tensorflow-2.14.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:511c4c5bfb2af17c6ca22663f98a7267c4386bf5486fbe78ee2d21482a6fa822"}, - {file = "tensorflow-2.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f66d2990157cf27f80c730878cb8befa8ed9716223494037d31c80fbe5f64370"}, - {file = "tensorflow-2.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9ab2747f75aba0327bfe6092b963694f1001781e5d2c0d251dfeed02b0c3bba"}, - {file = "tensorflow-2.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:7f5c9215bc00ba88f1cde1399f8160a5cb865c20ad71a1d5a6869f9fad62d9a5"}, + {file = "tensorflow-2.15.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:9b248e0f4316b3a3c54cd1f83edfb7a761d473060c1972a8ea31a90d5de3aa72"}, + {file = "tensorflow-2.15.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:eaf420d8b8ec1d4bd75859be7d7545d8e7052726eed8456fdbba63718e7e07ea"}, + {file = "tensorflow-2.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e98aab454fc73ff1900314821e5bafbf20840ada2004c8caccf4d92e0e12a628"}, + {file = "tensorflow-2.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed601b43df9b7d9bed0203b34bcb9356efd4f671eaaac1046b7166a2afee0cf8"}, + {file = "tensorflow-2.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:2d88f8b71f4a8d9ab9dc7c8e42b14ca0f53d1daab0f989b8f2918907c2891f41"}, + {file = "tensorflow-2.15.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:1e0716622ed7af867d8b1997b00a2940f1a1587dee923ff53efa2ee506992f32"}, + {file = "tensorflow-2.15.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:124930e7d4f5d74c61a5c80d642a26c22fe0c42fdd383fe9ee5803c3ac9ed4ce"}, + {file = "tensorflow-2.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:852efeb4d18beedac0120c4f2d4f4dccf4c090bb6740c5199d395ff609e85e98"}, + {file = "tensorflow-2.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee8ec2b2c6c942ae65d25746e53cdc475e82d5fcbbb3009ce47f5963d69ebfc"}, + {file = "tensorflow-2.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:e05a48006930e4e9e68468e7affed3bbce8a1c7fe6df86500496ad1558804a78"}, + {file = "tensorflow-2.15.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:2cfcdde1ff3c01be617e99ce9783c49cb11da5796ce32a31855412bd092c0bcf"}, + {file = "tensorflow-2.15.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:896bda03f722700a9918d144aee5152a75f1be5e6c5045fd0683b8318a3fc9d9"}, + {file = "tensorflow-2.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7697b005ce48fec8b2ee8cf25bcbd138f16b5e17f99f7c01a6ea3f2429f86c6"}, + {file = "tensorflow-2.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fa865956d96b7614f247c36e4c22b1543ba5ce656fbe8e4f6266ae7a4917132"}, + {file = "tensorflow-2.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:01108746e1bbfcd48dfabf7f51ddca7693b91ea6821f6f62a27b5a5ebf0817c5"}, ] [package.dependencies] @@ -3132,35 +3321,35 @@ gast = ">=0.2.1,<0.5.0 || >0.5.0,<0.5.1 || >0.5.1,<0.5.2 || >0.5.2" google-pasta = ">=0.1.1" grpcio = ">=1.24.3,<2.0" h5py = ">=2.9.0" -keras = ">=2.14.0,<2.15" +keras = ">=2.15.0,<2.16" libclang = ">=13.0.0" -ml-dtypes = "0.2.0" +ml-dtypes = ">=0.2.0,<0.3.0" numpy = ">=1.23.5,<2.0.0" opt-einsum = ">=2.3.2" packaging = "*" protobuf = ">=3.20.3,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" setuptools = "*" six = ">=1.12.0" -tensorboard = ">=2.14,<2.15" -tensorflow-estimator = ">=2.14.0,<2.15" +tensorboard = ">=2.15,<2.16" +tensorflow-estimator = ">=2.15.0,<2.16" tensorflow-io-gcs-filesystem = ">=0.23.1" termcolor = ">=1.1.0" typing-extensions = ">=3.6.6" wrapt = ">=1.11.0,<1.15" [package.extras] -and-cuda = ["nvidia-cublas-cu11 (==11.11.3.6)", "nvidia-cuda-cupti-cu11 (==11.8.87)", "nvidia-cuda-nvcc-cu11 (==11.8.89)", "nvidia-cuda-runtime-cu11 (==11.8.89)", "nvidia-cudnn-cu11 (==8.7.0.84)", "nvidia-cufft-cu11 (==10.9.0.58)", "nvidia-curand-cu11 (==10.3.0.86)", "nvidia-cusolver-cu11 (==11.4.1.48)", "nvidia-cusparse-cu11 (==11.7.5.86)", "nvidia-nccl-cu11 (==2.16.5)", "tensorrt (==8.5.3.1)"] +and-cuda = ["nvidia-cublas-cu12 (==12.2.5.6)", "nvidia-cuda-cupti-cu12 (==12.2.142)", "nvidia-cuda-nvcc-cu12 (==12.2.140)", "nvidia-cuda-nvrtc-cu12 (==12.2.140)", "nvidia-cuda-runtime-cu12 (==12.2.140)", "nvidia-cudnn-cu12 (==8.9.4.25)", "nvidia-cufft-cu12 (==11.0.8.103)", "nvidia-curand-cu12 (==10.3.3.141)", "nvidia-cusolver-cu12 (==11.5.2.141)", "nvidia-cusparse-cu12 (==12.1.2.141)", "nvidia-nccl-cu12 (==2.16.5)", "nvidia-nvjitlink-cu12 (==12.2.140)", "tensorrt (==8.6.1.post1)", "tensorrt-bindings (==8.6.1)", "tensorrt-libs (==8.6.1)"] [[package]] name = "tensorflow-cpu-aws" -version = "2.14.1" +version = "2.15.0" description = "TensorFlow is an open source machine learning framework for everyone." optional = false python-versions = ">=3.9" files = [ - {file = "tensorflow_cpu_aws-2.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e35e9d90fc448973b39cd2b76a03a66de88700424a40dcc0ff90b8d40b1a3a"}, - {file = "tensorflow_cpu_aws-2.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:618af0ac57a7bb6b51c9b409c2838c9910ca2fd2ae2b1f986ae98ebf59a919e5"}, - {file = "tensorflow_cpu_aws-2.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e65af267aed15f4a59a8fd7a3ffe11ce43a71a33b0cd27122015b134443d872"}, + {file = "tensorflow_cpu_aws-2.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a751f4d6a16360347851d2e680b8bfddb8ab7799723f1fd5c171fa1f2e8c04aa"}, + {file = "tensorflow_cpu_aws-2.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e60763a3140306f9d6a793fbe888cea0f7da158f1c1fb4984a6e050aa75d5ce9"}, + {file = "tensorflow_cpu_aws-2.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c34f814a545f4263223c654e2c5cba0d4f0252f8a78d18db5c3fcff8a5a31d5c"}, ] [package.dependencies] @@ -3171,45 +3360,45 @@ gast = ">=0.2.1,<0.5.0 || >0.5.0,<0.5.1 || >0.5.1,<0.5.2 || >0.5.2" google-pasta = ">=0.1.1" grpcio = ">=1.24.3,<2.0" h5py = ">=2.9.0" -keras = ">=2.14.0,<2.15" +keras = ">=2.15.0,<2.16" libclang = ">=13.0.0" -ml-dtypes = "0.2.0" +ml-dtypes = ">=0.2.0,<0.3.0" numpy = ">=1.23.5,<2.0.0" opt-einsum = ">=2.3.2" packaging = "*" protobuf = ">=3.20.3,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" setuptools = "*" six = ">=1.12.0" -tensorboard = ">=2.14,<2.15" -tensorflow-estimator = ">=2.14.0,<2.15" +tensorboard = ">=2.15,<2.16" +tensorflow-estimator = ">=2.15.0,<2.16" tensorflow-io-gcs-filesystem = ">=0.23.1" termcolor = ">=1.1.0" typing-extensions = ">=3.6.6" wrapt = ">=1.11.0,<1.15" [package.extras] -and-cuda = ["nvidia-cublas-cu11 (==11.11.3.6)", "nvidia-cuda-cupti-cu11 (==11.8.87)", "nvidia-cuda-nvcc-cu11 (==11.8.89)", "nvidia-cuda-runtime-cu11 (==11.8.89)", "nvidia-cudnn-cu11 (==8.7.0.84)", "nvidia-cufft-cu11 (==10.9.0.58)", "nvidia-curand-cu11 (==10.3.0.86)", "nvidia-cusolver-cu11 (==11.4.1.48)", "nvidia-cusparse-cu11 (==11.7.5.86)", "nvidia-nccl-cu11 (==2.16.5)", "tensorrt (==8.5.3.1)"] +and-cuda = ["nvidia-cublas-cu12 (==12.2.5.6)", "nvidia-cuda-cupti-cu12 (==12.2.142)", "nvidia-cuda-nvcc-cu12 (==12.2.140)", "nvidia-cuda-nvrtc-cu12 (==12.2.140)", "nvidia-cuda-runtime-cu12 (==12.2.140)", "nvidia-cudnn-cu12 (==8.9.4.25)", "nvidia-cufft-cu12 (==11.0.8.103)", "nvidia-curand-cu12 (==10.3.3.141)", "nvidia-cusolver-cu12 (==11.5.2.141)", "nvidia-cusparse-cu12 (==12.1.2.141)", "nvidia-nccl-cu12 (==2.16.5)", "nvidia-nvjitlink-cu12 (==12.2.140)", "tensorrt (==8.6.1.post1)", "tensorrt-bindings (==8.6.1)", "tensorrt-libs (==8.6.1)"] [[package]] name = "tensorflow-estimator" -version = "2.14.0" +version = "2.15.0" description = "TensorFlow Estimator." optional = false python-versions = ">=3.7" files = [ - {file = "tensorflow_estimator-2.14.0-py2.py3-none-any.whl", hash = "sha256:820bf57c24aa631abb1bbe4371739ed77edb11361d61381fd8e790115ac0fd57"}, + {file = "tensorflow_estimator-2.15.0-py2.py3-none-any.whl", hash = "sha256:aedf21eec7fb2dc91150fc91a1ce12bc44dbb72278a08b58e79ff87c9e28f153"}, ] [[package]] name = "tensorflow-intel" -version = "2.14.1" +version = "2.15.0" description = "TensorFlow is an open source machine learning framework for everyone." optional = false python-versions = ">=3.9" files = [ - {file = "tensorflow_intel-2.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:d53589eed39607059923e660dfdb28dc65a4b89bec5889a78941bf8ec936d716"}, - {file = "tensorflow_intel-2.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:dc4b0fb2cf2768104630357e9c06b801163e31db22ef2fd0419a0c09ae2e2315"}, - {file = "tensorflow_intel-2.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:78c11785eaa1047ac2e4746c86286f6629df0289e73616ce052a82761e1de678"}, + {file = "tensorflow_intel-2.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:66f9078b5a64e9c05e9f7a77fb0fb8d21c5be006da2e5e380b61bea8f10a4774"}, + {file = "tensorflow_intel-2.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:4710b0ea84defaafc0d6cc51162ebef8b07da015fc68375661451861c5bf4421"}, + {file = "tensorflow_intel-2.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:ebbc3220c9919a0b43f5ccb94bdced5236edc30dab31d4905e2991b67f26298e"}, ] [package.dependencies] @@ -3220,24 +3409,24 @@ gast = ">=0.2.1,<0.5.0 || >0.5.0,<0.5.1 || >0.5.1,<0.5.2 || >0.5.2" google-pasta = ">=0.1.1" grpcio = ">=1.24.3,<2.0" h5py = ">=2.9.0" -keras = ">=2.14.0,<2.15" +keras = ">=2.15.0,<2.16" libclang = ">=13.0.0" -ml-dtypes = "0.2.0" +ml-dtypes = ">=0.2.0,<0.3.0" numpy = ">=1.23.5,<2.0.0" opt-einsum = ">=2.3.2" packaging = "*" protobuf = ">=3.20.3,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" setuptools = "*" six = ">=1.12.0" -tensorboard = ">=2.14,<2.15" -tensorflow-estimator = ">=2.14.0,<2.15" +tensorboard = ">=2.15,<2.16" +tensorflow-estimator = ">=2.15.0,<2.16" tensorflow-io-gcs-filesystem = ">=0.23.1" termcolor = ">=1.1.0" typing-extensions = ">=3.6.6" wrapt = ">=1.11.0,<1.15" [package.extras] -and-cuda = ["nvidia-cublas-cu11 (==11.11.3.6)", "nvidia-cuda-cupti-cu11 (==11.8.87)", "nvidia-cuda-nvcc-cu11 (==11.8.89)", "nvidia-cuda-runtime-cu11 (==11.8.89)", "nvidia-cudnn-cu11 (==8.7.0.84)", "nvidia-cufft-cu11 (==10.9.0.58)", "nvidia-curand-cu11 (==10.3.0.86)", "nvidia-cusolver-cu11 (==11.4.1.48)", "nvidia-cusparse-cu11 (==11.7.5.86)", "nvidia-nccl-cu11 (==2.16.5)", "tensorrt (==8.5.3.1)"] +and-cuda = ["nvidia-cublas-cu12 (==12.2.5.6)", "nvidia-cuda-cupti-cu12 (==12.2.142)", "nvidia-cuda-nvcc-cu12 (==12.2.140)", "nvidia-cuda-nvrtc-cu12 (==12.2.140)", "nvidia-cuda-runtime-cu12 (==12.2.140)", "nvidia-cudnn-cu12 (==8.9.4.25)", "nvidia-cufft-cu12 (==11.0.8.103)", "nvidia-curand-cu12 (==10.3.3.141)", "nvidia-cusolver-cu12 (==11.5.2.141)", "nvidia-cusparse-cu12 (==12.1.2.141)", "nvidia-nccl-cu12 (==2.16.5)", "nvidia-nvjitlink-cu12 (==12.2.140)", "tensorrt (==8.6.1.post1)", "tensorrt-bindings (==8.6.1)", "tensorrt-libs (==8.6.1)"] [[package]] name = "tensorflow-io-gcs-filesystem" @@ -3276,40 +3465,43 @@ tensorflow-rocm = ["tensorflow-rocm (>=2.11.0,<2.12.0)"] [[package]] name = "tensorflow-io-gcs-filesystem" -version = "0.35.0" +version = "0.36.0" description = "TensorFlow IO" optional = false python-versions = ">=3.7, <3.12" files = [ - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:5521721b38105496d4b43a4ffb0af5b04cc4873d464f26fbceddf8d63815ce98"}, - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd8f30908bf8b7b2a017d6b145720d105aff7f998422671b71729708ec7b2fe4"}, - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac8f1de60fdf9c734aea967b98555e366ac8743f77bca15c49eff023f587076b"}, - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:35b6eca7225c815d962254327195f191d88c3c9c2278a5ab23e0ac834acbadbb"}, - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e997389bfe008210cbd97c0c738d64282a2f03ad4d0536013bb0a9efde0c283"}, - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8fb3402fb1457482c386ea19371bc76383412ae9ea4396edb1e8adb4ba76f21"}, - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb6bf8f5b40207ecb17e7fdc3b4fc824a8361267c14e9528c1688e16de135cb7"}, - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:c4f786eebd98d401565374722f2e67f3878675b0d87489cbaa13c70ee6ac370a"}, - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fce1466bdb91096b6d22e7df17358ba228bcb92db5cff83f2f9f1c68eb26788"}, - {file = "tensorflow_io_gcs_filesystem-0.35.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1856fe321fdb75f3386d92109c60db6ef097f610b450f9cc69d76444fb9980d1"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:702c6df62b38095ff613c433546d9424d4f33902a5ab26b00fd26457e27a99fa"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e9b8aaca2789af356c42afda0f52380f82e5abb2f3c0b85087833fcfe03875d8"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c477aed96864ceae77d7051c3b687f28813aba7320fc5dd552164fad6ec8d1a1"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be1ff92559dfa23048b01179a1827081947583f5c6f9986ccac471df8a29322a"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:72c3ca4b8c0d8dbdd970699d05a100107cf200317ad8e6a8373e2c37225cd552"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:848e8e89a0f49258c7782189c938d8d1162d989da1a80c79f95c7af3ef6006c8"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d72db1ab03edb65fa1e98d06e504ccbc64282d38ab3589afb6db66dc448d1c1"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bd4d946b5fa23220daa473a80e511a5fb27493d7e49d17dff0bb43bb0a31f32"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa346fd1dd9f57848b73874007440504f060fadd689fa1cc29cc49817d0eeaf3"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:0a4437824424a4423cf86162cb8b21b1bec24698194332748b50bb952e62ab9f"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:31806bd7ac2db789161bc720747de22947063265561a4c17be54698fd9780b03"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc0e57976c1aa035af6281f0330cfb8dd50eee2f63412ecc84d60ff5075d29b7"}, + {file = "tensorflow_io_gcs_filesystem-0.36.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e97ff5c280eb10f699098ae21057be2b146d39e8a906cd5db91f2ea6c34e47d0"}, ] [package.extras] -tensorflow = ["tensorflow (>=2.14.0,<2.15.0)"] -tensorflow-aarch64 = ["tensorflow-aarch64 (>=2.14.0,<2.15.0)"] -tensorflow-cpu = ["tensorflow-cpu (>=2.14.0,<2.15.0)"] -tensorflow-gpu = ["tensorflow-gpu (>=2.14.0,<2.15.0)"] -tensorflow-rocm = ["tensorflow-rocm (>=2.14.0,<2.15.0)"] +tensorflow = ["tensorflow (>=2.15.0,<2.16.0)"] +tensorflow-aarch64 = ["tensorflow-aarch64 (>=2.15.0,<2.16.0)"] +tensorflow-cpu = ["tensorflow-cpu (>=2.15.0,<2.16.0)"] +tensorflow-gpu = ["tensorflow-gpu (>=2.15.0,<2.16.0)"] +tensorflow-rocm = ["tensorflow-rocm (>=2.15.0,<2.16.0)"] [[package]] name = "tensorflow-macos" -version = "2.14.1" +version = "2.15.0" description = "TensorFlow is an open source machine learning framework for everyone." optional = false python-versions = ">=3.9" files = [ - {file = "tensorflow_macos-2.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:5b9832df0852fa534cbd3362b6e00ba1c9d4b541fdfd987d0bba3927229435bc"}, - {file = "tensorflow_macos-2.14.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:428f071cf9e901c8182be9f7278a79beea6f9e4b687bf0d5e8e8faefb7bcc760"}, - {file = "tensorflow_macos-2.14.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:4d7ce47f3c593f71eaa98ed3c8fe3c83b6010cc63d06aaf12037845196d06d85"}, + {file = "tensorflow_macos-2.15.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:cdfb4cd80ddfdf189212f4e3747a4404702d58cc6a346ab8887bd567ca3284f8"}, + {file = "tensorflow_macos-2.15.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6933b6a298bcce3b302fa55c6943a2e2caba44601d0e5d0a86cae248fd90da8f"}, + {file = "tensorflow_macos-2.15.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:9bffd0da3f63ef5f16b198aa225eec1220c199ec937ba6bddcd34bc5bda13fd2"}, ] [package.dependencies] @@ -3320,24 +3512,24 @@ gast = ">=0.2.1,<0.5.0 || >0.5.0,<0.5.1 || >0.5.1,<0.5.2 || >0.5.2" google-pasta = ">=0.1.1" grpcio = ">=1.24.3,<2.0" h5py = ">=2.9.0" -keras = ">=2.14.0,<2.15" +keras = ">=2.15.0,<2.16" libclang = ">=13.0.0" -ml-dtypes = "0.2.0" +ml-dtypes = ">=0.2.0,<0.3.0" numpy = ">=1.23.5,<2.0.0" opt-einsum = ">=2.3.2" packaging = "*" protobuf = ">=3.20.3,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" setuptools = "*" six = ">=1.12.0" -tensorboard = ">=2.14,<2.15" -tensorflow-estimator = ">=2.14.0,<2.15" +tensorboard = ">=2.15,<2.16" +tensorflow-estimator = ">=2.15.0,<2.16" tensorflow-io-gcs-filesystem = ">=0.23.1" termcolor = ">=1.1.0" typing-extensions = ">=3.6.6" wrapt = ">=1.11.0,<1.15" [package.extras] -and-cuda = ["nvidia-cublas-cu11 (==11.11.3.6)", "nvidia-cuda-cupti-cu11 (==11.8.87)", "nvidia-cuda-nvcc-cu11 (==11.8.89)", "nvidia-cuda-runtime-cu11 (==11.8.89)", "nvidia-cudnn-cu11 (==8.7.0.84)", "nvidia-cufft-cu11 (==10.9.0.58)", "nvidia-curand-cu11 (==10.3.0.86)", "nvidia-cusolver-cu11 (==11.4.1.48)", "nvidia-cusparse-cu11 (==11.7.5.86)", "nvidia-nccl-cu11 (==2.16.5)", "tensorrt (==8.5.3.1)"] +and-cuda = ["nvidia-cublas-cu12 (==12.2.5.6)", "nvidia-cuda-cupti-cu12 (==12.2.142)", "nvidia-cuda-nvcc-cu12 (==12.2.140)", "nvidia-cuda-nvrtc-cu12 (==12.2.140)", "nvidia-cuda-runtime-cu12 (==12.2.140)", "nvidia-cudnn-cu12 (==8.9.4.25)", "nvidia-cufft-cu12 (==11.0.8.103)", "nvidia-curand-cu12 (==10.3.3.141)", "nvidia-cusolver-cu12 (==11.5.2.141)", "nvidia-cusparse-cu12 (==12.1.2.141)", "nvidia-nccl-cu12 (==2.16.5)", "nvidia-nvjitlink-cu12 (==12.2.140)", "tensorrt (==8.6.1.post1)", "tensorrt-bindings (==8.6.1)", "tensorrt-libs (==8.6.1)"] [[package]] name = "tensorflow-probability" @@ -3438,6 +3630,21 @@ files = [ {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"}, ] +[[package]] +name = "traitlets" +version = "5.14.1" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +files = [ + {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, + {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] + [[package]] name = "typing-extensions" version = "4.9.0" @@ -3477,6 +3684,17 @@ h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + [[package]] name = "werkzeug" version = "3.0.1" @@ -3555,4 +3773,4 @@ ray = ["ray", "scikit-optimize"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.11" -content-hash = "970e86ff1dd5fc529221b750bc6be686fecf8a48dbf4d063046bf05d5171d092" +content-hash = "b6cddfebdac8750aa146284e66ef208da1b15941836d4d4614a6646d2b8761b1" diff --git a/pyproject.toml b/pyproject.toml index 3fdd13c08..082bbb89e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ ray = { version = "^2.5.0", extras = ["tune"], optional = true } scikit-optimize = { version = "^0.9.0", optional = true } networkx = "^3.1" julia = "0.6.1" +ipython = ">=8.18.1" ###################### The Tensorflow Section ###################### # Dedicated for making sure that poetry can install tensorflow on all platforms. From 97aefdafe6152ada8696954a6d59aa827b990646 Mon Sep 17 00:00:00 2001 From: SamFerracin Date: Fri, 9 Feb 2024 10:18:49 -0500 Subject: [PATCH 28/30] protected access --- mrmustard/lab_dev/wires.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mrmustard/lab_dev/wires.py b/mrmustard/lab_dev/wires.py index a96391dbe..122dd92ca 100644 --- a/mrmustard/lab_dev/wires.py +++ b/mrmustard/lab_dev/wires.py @@ -25,6 +25,7 @@ __all__ = ["Wires"] +# pylint: disable=protected-access class Wires: r""" A class with wire functionality for tensor network applications. From 42308242cb7587be2c35007ebbb9ac340f4e42db Mon Sep 17 00:00:00 2001 From: SamFerracin Date: Fri, 9 Feb 2024 10:26:01 -0500 Subject: [PATCH 29/30] two more codefactor --- mrmustard/lab_dev/wires.py | 2 +- tests/test_lab_dev/test_wires.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mrmustard/lab_dev/wires.py b/mrmustard/lab_dev/wires.py index 122dd92ca..31bf6ce55 100644 --- a/mrmustard/lab_dev/wires.py +++ b/mrmustard/lab_dev/wires.py @@ -16,8 +16,8 @@ from __future__ import annotations -from IPython.display import display, HTML from typing import Iterable, Optional +from IPython.display import display, HTML import numpy as np from mrmustard import settings diff --git a/tests/test_lab_dev/test_wires.py b/tests/test_lab_dev/test_wires.py index 4e1241c65..160f130af 100644 --- a/tests/test_lab_dev/test_wires.py +++ b/tests/test_lab_dev/test_wires.py @@ -150,7 +150,7 @@ def test_add_error(self): w1 = Wires([0], [1], [2], [3]) w2 = Wires([0], [2], [3], [4]) with pytest.raises(Exception): - w1 + w2 + w1 + w2 # pylint: disable=pointless-statement def test_bool(self): assert Wires([0]) @@ -178,4 +178,4 @@ def test_rshift_error(self): u = Wires([], [], [0], []) # only output wire v = Wires([], [], [0], []) # only output wire with pytest.raises(ValueError): - u >> v + u >> v # pylint: disable=pointless-statement From 64f2ed382d6e708876db5a1faed9967e4ae595f3 Mon Sep 17 00:00:00 2001 From: SamFerracin Date: Fri, 9 Feb 2024 14:17:38 -0500 Subject: [PATCH 30/30] changelog --- .github/CHANGELOG.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 418115a5d..9bbe87361 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -1,3 +1,25 @@ +# Release 0.7.1 (current develop) + +### New features + +### Breaking changes + +### Improvements + +### Bug fixes + +### Documentation + +### Tests + +### Contributors +[Samuele Ferracin](https://github.com/SamFerracin), +[Yuan Yao](https://github.com/sylviemonet) +[Filippo Miatto](https://github.com/ziofil) + + +--- + # Release 0.7.0 (current release) ### New features @@ -21,9 +43,6 @@ * Added `Bargmann` representation (parametrized by Abc). Supports all algebraic operations and CV (exact) inner product. [(#296)](https://github.com/XanaduAI/MrMustard/pull/296) -* Added a new class `Wires` in `mrmustard.lab` to handle the connectivity of objects in a circuit. - [(#330)](https://github.com/XanaduAI/MrMustard/pull/330) - ### Breaking changes * Removed circular dependencies by: * Removing `graphics.py`--moved `ProgressBar` to `training` and `mikkel_plot` to `lab`.