Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
CompWithSym._canonicalize_sym_antisym: Refactor, fix index validation…
Browse files Browse the repository at this point in the history
…, add tests
  • Loading branch information
mkoeppe committed Sep 2, 2022
1 parent c6b6b2e commit bec2f65
Showing 1 changed file with 54 additions and 44 deletions.
98 changes: 54 additions & 44 deletions src/sage/tensor/modules/comp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2998,10 +2998,61 @@ def __init__(self, ring, frame, nb_indices, start_index=0,
self._sym, self._antisym = self._canonicalize_sym_antisym(
nb_indices, sym, antisym)

@staticmethod
def _canonicalize_sym_or_antisym(nb_indices, sym_or_antisym):
r"""
Bring ``sym`` or ``antisym`` to its canonical form.
INPUT:
- ``nb_indices`` -- number of integer indices labeling the components
- ``sym_or_antisym`` -- (default: ``None``) a symmetry/antisymmetry
or an iterable of symmetries or an iterable of antisymmetries
among the tensor arguments: each symmetry is described by a tuple
containing the positions of the involved arguments, with the
convention ``position = 0`` for the first argument. For instance:
TESTS::
sage: from sage.tensor.modules.comp import CompWithSym
sage: CompWithSym._canonicalize_sym_or_antisym(3, [0, -1])
Traceback (most recent call last):
...
IndexError: invalid index position: -1 not in [0,2]
sage: CompWithSym._canonicalize_sym_or_antisym(3, [3, 1])
Traceback (most recent call last):
...
IndexError: invalid index position: 3 not in [0,2]
"""
if not sym_or_antisym:
return ()
# Handle the case that sym_or_antisym is an iterator
sym_or_antisym = tuple(sym_or_antisym)
result_sym_or_antisym = []
if isinstance(sym_or_antisym[0], (int, Integer)):
# a single symmetry is provided as a tuple or a range object;
# it is converted to a 1-item list:
sym_or_antisym = (tuple(sym_or_antisym),)
for isym in sym_or_antisym:
if len(isym) < 2:
# Drop trivial symmetry
continue
isym = tuple(sorted(isym))
if isym[0] < 0:
raise IndexError("invalid index position: " + str(isym[0]) +
" not in [0," + str(nb_indices-1) + "]")
if isym[-1] > nb_indices - 1:
raise IndexError("invalid index position: " + str(isym[-1]) +
" not in [0," + str(nb_indices-1) + "]")
result_sym_or_antisym.append(isym)
# Canonicalize sort order, make tuples
return tuple(sorted(result_sym_or_antisym))

@staticmethod
def _canonicalize_sym_antisym(nb_indices, sym=None, antisym=None):
r"""
Bring sym and antisym into their canonical form.
Bring ``sym`` and ``antisym`` into their canonical form.
INPUT:
Expand Down Expand Up @@ -3029,46 +3080,8 @@ def _canonicalize_sym_antisym(nb_indices, sym=None, antisym=None):
if not sym and not antisym:
# fast path
return (), ()
result_sym = []
if sym is None:
sym = ()
else:
# Handle the case that sym is an iterator
sym = tuple(sym)
if sym:
if isinstance(sym[0], (int, Integer)):
# a single symmetry is provided as a tuple or a range object;
# it is converted to a 1-item list:
sym = (tuple(sym),)
for isym in sym:
if len(isym) < 2:
# Drop trivial symmetry
continue
isym = tuple(sorted(isym))
if isym[0] < 0 or isym[-1] > nb_indices - 1:
raise IndexError("invalid index position: " + str(i) +
" not in [0," + str(nb_indices-1) + "]")
result_sym.append(isym)
result_antisym = []
if antisym is None:
antisym = []
else:
# Handle the case that antisym is an iterator
antisym = list(antisym)
if antisym:
if isinstance(antisym[0], (int, Integer)):
# a single antisymmetry is provided as a tuple or a range
# object; it is converted to a 1-item list:
antisym = [tuple(antisym)]
for isym in antisym:
if len(isym) < 2:
# Drop trivial antisymmetry
continue
isym = tuple(sorted(isym))
if isym[0] < 0 or isym[-1] > nb_indices - 1:
raise IndexError("invalid index position: " + str(i) +
" not in [0," + str(nb_indices - 1) + "]")
result_antisym.append(isym)
result_sym = CompWithSym._canonicalize_sym_or_antisym(nb_indices, sym)
result_antisym = CompWithSym._canonicalize_sym_or_antisym(nb_indices, antisym)
# Final consistency check:
index_list = []
for isym in result_sym:
Expand All @@ -3079,9 +3092,6 @@ def _canonicalize_sym_antisym(nb_indices, sym=None, antisym=None):
# There is a repeated index position:
raise IndexError("incompatible lists of symmetries: the same " +
"index position appears more than once")
# Canonicalize sort order, make tuples
result_sym = tuple(sorted(result_sym))
result_antisym = tuple(sorted(result_antisym))
return result_sym, result_antisym

def _repr_(self):
Expand Down

0 comments on commit bec2f65

Please sign in to comment.