From bb6f9c4e1f2b44806a221ca946f7fdc88d56a8a3 Mon Sep 17 00:00:00 2001 From: Hao Zhang Date: Thu, 31 Jul 2025 16:36:47 +0800 Subject: [PATCH 1/2] Add support for reverse. --- parity_tensor/parity_tensor.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/parity_tensor/parity_tensor.py b/parity_tensor/parity_tensor.py index 77fe9e6..a700df5 100644 --- a/parity_tensor/parity_tensor.py +++ b/parity_tensor/parity_tensor.py @@ -143,6 +143,32 @@ def permute(self, before_by_after: tuple[int, ...]) -> ParityTensor: _mask=mask, ) + def reverse(self, indices: tuple[int, ...]) -> ParityTensor: + """ + Reverse the specified indices of the parity tensor. + + A single sign is generated during reverse, which should be applied to one of the connected two tensors. + This package always applies it to the tensor with arrow as True. + """ + assert len(set(indices)) == len(indices), f"Indices must be unique. Got {indices}." + assert all(0 <= i < self.tensor.dim() for i in indices), f"Indices must be within tensor dimensions. Got {indices}." + + arrow = tuple(self.arrow[i] ^ i in indices for i in range(self.tensor.dim())) + tensor = self.tensor + + total_parity = functools.reduce( + torch.logical_xor, + (self._unsqueeze(parity, index, self.tensor.dim()) for index, parity in enumerate(self.parity) if index in indices and self.arrow[index]), + torch.zeros([], dtype=torch.bool, device=self.tensor.device), + ) + tensor = torch.where(total_parity, -tensor, +tensor) + + return dataclasses.replace( + self, + _arrow=arrow, + _tensor=tensor, + ) + def __post_init__(self) -> None: assert len(self._arrow) == self._tensor.dim(), f"Arrow length ({len(self._arrow)}) must match tensor dimensions ({self._tensor.dim()})." assert len(self._edges) == self._tensor.dim(), f"Edges length ({len(self._edges)}) must match tensor dimensions ({self._tensor.dim()})." From aa0f211bbd4cfe5b0d48fd74977044ad6186ca99 Mon Sep 17 00:00:00 2001 From: Hao Zhang Date: Fri, 8 Aug 2025 03:54:32 +0800 Subject: [PATCH 2/2] Update name changes caused by renaming. --- grassmann_tensor/tensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grassmann_tensor/tensor.py b/grassmann_tensor/tensor.py index 5c5ac51..30ec73e 100644 --- a/grassmann_tensor/tensor.py +++ b/grassmann_tensor/tensor.py @@ -143,9 +143,9 @@ def permute(self, before_by_after: tuple[int, ...]) -> GrassmannTensor: _mask=mask, ) - def reverse(self, indices: tuple[int, ...]) -> ParityTensor: + def reverse(self, indices: tuple[int, ...]) -> GrassmannTensor: """ - Reverse the specified indices of the parity tensor. + Reverse the specified indices of the Grassmann tensor. A single sign is generated during reverse, which should be applied to one of the connected two tensors. This package always applies it to the tensor with arrow as True.