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

Commit

Permalink
src/sage/tensor, src/sage/manifolds: Sort _sym, _antisym, store as tu…
Browse files Browse the repository at this point in the history
…ples of tuples
  • Loading branch information
Matthias Koeppe committed Aug 29, 2022
1 parent 07ab991 commit 3619b4c
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 86 deletions.
8 changes: 4 additions & 4 deletions src/sage/manifolds/differentiable/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ def set(self, symbiform):
raise TypeError("the argument must be a tensor field")
if symbiform._tensor_type != (0,2):
raise TypeError("the argument must be of tensor type (0,2)")
if symbiform._sym != [(0,1)]:
if symbiform._sym != ((0,1),):
raise TypeError("the argument must be symmetric")
if not symbiform._domain.is_subset(self._domain):
raise TypeError("the symmetric bilinear form is not defined " +
Expand Down Expand Up @@ -2301,7 +2301,7 @@ def set(self, symbiform):
"values on a parallelizable domain")
if symbiform._tensor_type != (0,2):
raise TypeError("the argument must be of tensor type (0,2)")
if symbiform._sym != [(0,1)]:
if symbiform._sym != ((0,1),):
raise TypeError("the argument must be symmetric")
if symbiform._vmodule is not self._vmodule:
raise TypeError("the symmetric bilinear form and the metric are " +
Expand Down Expand Up @@ -2781,7 +2781,7 @@ def set(self, symbiform):
raise TypeError("the argument must be a tensor field")
if symbiform._tensor_type != (0,2):
raise TypeError("the argument must be of tensor type (0,2)")
if symbiform._sym != [(0,1)]:
if symbiform._sym != ((0,1),):
raise TypeError("the argument must be symmetric")
if not symbiform._domain.is_subset(self._domain):
raise TypeError("the symmetric bilinear form is not defined " +
Expand Down Expand Up @@ -3019,7 +3019,7 @@ def set(self, symbiform):
"values on a parallelizable domain")
if symbiform._tensor_type != (0,2):
raise TypeError("the argument must be of tensor type (0,2)")
if symbiform._sym != [(0,1)]:
if symbiform._sym != ((0,1),):
raise TypeError("the argument must be symmetric")
if symbiform._vmodule is not self._vmodule:
raise TypeError("the symmetric bilinear form and the metric are " +
Expand Down
39 changes: 4 additions & 35 deletions src/sage/manifolds/differentiable/tensorfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
from sage.rings.integer import Integer
from sage.rings.integer_ring import ZZ
from sage.structure.element import ModuleElementWithMutability
from sage.tensor.modules.comp import CompWithSym
from sage.tensor.modules.free_module_tensor import FreeModuleTensor
from sage.tensor.modules.tensor_with_indices import TensorWithIndices

Expand Down Expand Up @@ -495,40 +496,8 @@ def __init__(
self._restrictions = {} # dict. of restrictions of self on subdomains
# of self._domain, with the subdomains as keys
# Treatment of symmetry declarations:
self._sym = []
if sym is not None and sym != []:
if isinstance(sym[0], (int, Integer)):
# a single symmetry is provided as a tuple -> 1-item list:
sym = [tuple(sym)]
for isym in sym:
if len(isym) > 1:
for i in isym:
if i < 0 or i > self._tensor_rank - 1:
raise IndexError("invalid position: {}".format(i) +
" not in [0,{}]".format(self._tensor_rank-1))
self._sym.append(tuple(isym))
self._antisym = []
if antisym is not None and antisym != []:
if isinstance(antisym[0], (int, Integer)):
# a single antisymmetry is provided as a tuple -> 1-item list:
antisym = [tuple(antisym)]
for isym in antisym:
if len(isym) > 1:
for i in isym:
if i < 0 or i > self._tensor_rank - 1:
raise IndexError("invalid position: {}".format(i) +
" not in [0,{}]".format(self._tensor_rank-1))
self._antisym.append(tuple(isym))
# Final consistency check:
index_list = []
for isym in self._sym:
index_list += isym
for isym in self._antisym:
index_list += isym
if len(index_list) != len(set(index_list)):
# There is a repeated index position:
raise IndexError("incompatible lists of symmetries: the same " +
"position appears more than once")
self._sym, self._antisym = CompWithSym._canonicalize_sym_antisym(
self._tensor_rank, sym, antisym)
# Initialization of derived quantities:
self._init_derived()

Expand Down Expand Up @@ -591,7 +560,7 @@ def _repr_(self):
"""
# Special cases
if self._tensor_type == (0,2) and self._sym == [(0,1)]:
if self._tensor_type == (0,2) and self._sym == ((0,1),):
description = "Field of symmetric bilinear forms "
if self._name is not None:
description += self._name + " "
Expand Down
29 changes: 18 additions & 11 deletions src/sage/tensor/modules/comp.py
Original file line number Diff line number Diff line change
Expand Up @@ -3008,7 +3008,7 @@ def _canonicalize_sym_antisym(nb_indices, sym=None, antisym=None):
sage: from sage.tensor.modules.comp import CompWithSym
sage: CompWithSym._canonicalize_sym_antisym(6, [(2, 1)])
([(2, 1)], [])
(((1, 2),), ())
"""
result_sym = []
if sym is None:
Expand All @@ -3023,8 +3023,8 @@ def _canonicalize_sym_antisym(nb_indices, sym=None, antisym=None):
sym = [tuple(sym)]
for isym in sym:
if len(isym) < 2:
raise IndexError("at least two index positions must be " +
"provided to define a symmetry")
# Drop trivial symmetry
continue
for i in isym:
if i < 0 or i > nb_indices - 1:
raise IndexError("invalid index position: " + str(i) +
Expand All @@ -3043,8 +3043,8 @@ def _canonicalize_sym_antisym(nb_indices, sym=None, antisym=None):
antisym = [tuple(antisym)]
for isym in antisym:
if len(isym) < 2:
raise IndexError("at least two index positions must be " +
"provided to define an antisymmetry")
# Drop trivial antisymmetry
continue
for i in isym:
if i < 0 or i > nb_indices - 1:
raise IndexError("invalid index position: " + str(i) +
Expand All @@ -3060,6 +3060,11 @@ 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(s)) for s in result_sym]
result_antisym = [tuple(sorted(s)) for s in result_antisym]
result_sym = tuple(sorted(result_sym))
result_antisym = tuple(sorted(result_antisym))
return result_sym, result_antisym

def _repr_(self):
Expand Down Expand Up @@ -3392,9 +3397,9 @@ def swap_adjacent_indices(self, pos1, pos2, pos3):
[[0, 7, 8], [-7, 0, 9], [-8, -9, 0]]]
sage: c1 = c.swap_adjacent_indices(0,1,3)
sage: c._antisym # c is antisymmetric with respect to the last pair of indices...
[(1, 2)]
((1, 2),)
sage: c1._antisym #...while c1 is antisymmetric with respect to the first pair of indices
[(0, 1)]
((0, 1),)
sage: c[0,1,2]
3
sage: c1[1,2,0]
Expand All @@ -3415,6 +3420,8 @@ def swap_adjacent_indices(self, pos1, pos2, pos3):
for s in self._antisym:
new_s = [new_lpos.index(pos) for pos in s]
result._antisym.append(tuple(sorted(new_s)))
result._sym, result._antisym = self._canonicalize_sym_antisym(
self._nid, result._sym, result._antisym)
# The values:
for ind, val in self._comp.items():
new_ind = ind[:pos1] + ind[pos2:pos3] + ind[pos1:pos2] + ind[pos3:]
Expand Down Expand Up @@ -4159,7 +4166,7 @@ def symmetrize(self, *pos):
(0, 0, 1)
], with symmetry on the index positions (0, 1), with symmetry on the index positions (2, 3)
sage: a1._sym # a1 has two distinct symmetries:
[(0, 1), (2, 3)]
((0, 1), (2, 3))
sage: a[0,1,2,0] == a[0,0,2,1] # a is symmetric w.r.t. positions 1 and 3
True
sage: a1[0,1,2,0] == a1[0,0,2,1] # a1 is not
Expand Down Expand Up @@ -4437,10 +4444,10 @@ def antisymmetrize(self, *pos):
(1, 0, 0),
(0, 1, 0),
(0, 0, 1)
], with antisymmetry on the index positions (1, 3),
with antisymmetry on the index positions (0, 2)
], with antisymmetry on the index positions (0, 2),
with antisymmetry on the index positions (1, 3)
sage: s._antisym # the antisymmetry (0,1,2) has been reduced to (0,2), since 1 is involved in the new antisymmetry (1,3):
[(1, 3), (0, 2)]
((0, 2), (1, 3))
Partial antisymmetrization of 4-indices components with a symmetry on
the first two indices::
Expand Down
39 changes: 3 additions & 36 deletions src/sage/tensor/modules/free_module_tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,41 +309,8 @@ def __init__(
# bases, with the bases as keys (initially empty)

# Treatment of symmetry declarations:
self._sym = []
if sym is not None and sym != []:
if isinstance(sym[0], (int, Integer)):
# a single symmetry is provided as a tuple -> 1-item list:
sym = [tuple(sym)]
for isym in sym:
if len(isym) > 1:
for i in isym:
if i<0 or i>self._tensor_rank-1:
raise IndexError("invalid position: " + str(i) +
" not in [0," + str(self._tensor_rank-1) + "]")
self._sym.append(tuple(isym))
self._antisym = []
if antisym is not None and antisym != []:
if isinstance(antisym[0], (int, Integer)):
# a single antisymmetry is provided as a tuple -> 1-item list:
antisym = [tuple(antisym)]
for isym in antisym:
if len(isym) > 1:
for i in isym:
if i<0 or i>self._tensor_rank-1:
raise IndexError("invalid position: " + str(i) +
" not in [0," + str(self._tensor_rank-1) + "]")
self._antisym.append(tuple(isym))

# Final consistency check:
index_list = []
for isym in self._sym:
index_list += isym
for isym in self._antisym:
index_list += isym
if len(index_list) != len(set(index_list)):
# There is a repeated index position:
raise IndexError("incompatible lists of symmetries: the same " +
"position appears more than once")
self._sym, self._antisym = CompWithSym._canonicalize_sym_antisym(
self._tensor_rank, sym, antisym)

# Initialization of derived quantities:
FreeModuleTensor._init_derived(self)
Expand Down Expand Up @@ -405,7 +372,7 @@ def _repr_(self):
"""
# Special cases
if self._tensor_type == (0,2) and self._sym == [(0,1)]:
if self._tensor_type == (0,2) and self._sym == ((0,1),):
description = "Symmetric bilinear form "
else:
# Generic case
Expand Down

0 comments on commit 3619b4c

Please sign in to comment.