Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions grassmann_tensor/tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,32 @@ def permute(self, before_by_after: tuple[int, ...]) -> GrassmannTensor:
_mask=mask,
)

def reverse(self, indices: tuple[int, ...]) -> GrassmannTensor:
"""
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.
"""
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()))

Copilot AI Aug 8, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The expression i in indices should be parenthesized for clarity. The current precedence could be confusing. Consider: arrow = tuple(self.arrow[i] ^ (i in indices) for i in range(self.tensor.dim()))

Suggested change
arrow = tuple(self.arrow[i] ^ i in indices for i in range(self.tensor.dim()))
arrow = tuple(self.arrow[i] ^ (i in indices) for i in range(self.tensor.dim()))

Copilot uses AI. Check for mistakes.
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]),

Copilot AI Aug 8, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The condition index in indices and self.arrow[index] should be parenthesized for clarity: (index in indices) and self.arrow[index]

Suggested change
(self._unsqueeze(parity, index, self.tensor.dim()) for index, parity in enumerate(self.parity) if index in indices and self.arrow[index]),
(self._unsqueeze(parity, index, self.tensor.dim()) for index, parity in enumerate(self.parity) if (index in indices and self.arrow[index])),

Copilot uses AI. Check for mistakes.
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()})."
Expand Down