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

Commit

Permalink
Merge #30229
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Koeppe committed Aug 29, 2022
2 parents 6cd438c + 04706dd commit 6ca796c
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 187 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
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ def ambient_second_fundamental_form(self):
g.restrict(chart.domain()).contract(pf[j]) *
self.scalar_field({chart: k.comp(chart.frame())[:][i, j]})
for i in range(self._dim) for j in range(self._dim))
gam_rst._sym = [(0, 1)]
gam_rst._sym = ((0, 1),)
self._ambient_second_fundamental_form.set_restriction(gam_rst)

charts = iter(self.top_charts())
Expand Down
43 changes: 6 additions & 37 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 Expand Up @@ -957,13 +926,13 @@ def symmetries(self):
elif len(self._sym) == 1:
s = "symmetry: {}; ".format(self._sym[0])
else:
s = "symmetries: {}; ".format(self._sym)
s = "symmetries: {}; ".format(list(self._sym))
if not self._antisym:
a = "no antisymmetry"
elif len(self._antisym) == 1:
a = "antisymmetry: {}".format(self._antisym[0])
else:
a = "antisymmetries: {}".format(self._antisym)
a = "antisymmetries: {}".format(list(self._antisym))
print(s + a)

#### End of simple accessors #####
Expand Down
8 changes: 4 additions & 4 deletions src/sage/manifolds/differentiable/vectorfield_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ def tensor(self, tensor_type, name=None, latex_name=None, sym=None,
# a single antisymmetry is provided as a tuple or a
# range object; it is converted to a 1-item list:
antisym = [tuple(antisym)]
if isinstance(antisym, list):
if isinstance(antisym, (tuple, list)):
antisym0 = antisym[0]
else:
antisym0 = antisym
Expand All @@ -799,7 +799,7 @@ def tensor(self, tensor_type, name=None, latex_name=None, sym=None,
# a single antisymmetry is provided as a tuple or a
# range object; it is converted to a 1-item list:
antisym = [tuple(antisym)]
if isinstance(antisym, list):
if isinstance(antisym, (tuple, list)):
antisym0 = antisym[0]
else:
antisym0 = antisym
Expand Down Expand Up @@ -2102,7 +2102,7 @@ def tensor(self, tensor_type, name=None, latex_name=None, sym=None,
# a single antisymmetry is provided as a tuple or a
# range object; it is converted to a 1-item list:
antisym = [tuple(antisym)]
if isinstance(antisym, list):
if isinstance(antisym, (tuple, list)):
antisym0 = antisym[0]
else:
antisym0 = antisym
Expand All @@ -2114,7 +2114,7 @@ def tensor(self, tensor_type, name=None, latex_name=None, sym=None,
# a single antisymmetry is provided as a tuple or a
# range object; it is converted to a 1-item list:
antisym = [tuple(antisym)]
if isinstance(antisym, list):
if isinstance(antisym, (tuple, list)):
antisym0 = antisym[0]
else:
antisym0 = antisym
Expand Down
90 changes: 61 additions & 29 deletions src/sage/tensor/modules/comp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1806,12 +1806,12 @@ def __mul__(self, other):
"same starting index")
if isinstance(other, CompWithSym):
sym = []
if other._sym != []:
if other._sym:
for s in other._sym:
ns = tuple(s[i]+self._nid for i in range(len(s)))
sym.append(ns)
antisym = []
if other._antisym != []:
if other._antisym:
for s in other._antisym:
ns = tuple(s[i]+self._nid for i in range(len(s)))
antisym.append(ns)
Expand Down Expand Up @@ -3029,46 +3029,76 @@ def __init__(self, ring, frame, nb_indices, start_index=0,
"""
Components.__init__(self, ring, frame, nb_indices, start_index,
output_formatter)
self._sym = []
if sym is not None and sym != []:
self._sym, self._antisym = self._canonicalize_sym_antisym(
nb_indices, sym, antisym)

@staticmethod
def _canonicalize_sym_antisym(nb_indices, sym=None, antisym=None):
r"""
Bring sym and antisym into their canonical form.
EXAMPLES::
sage: from sage.tensor.modules.comp import CompWithSym
sage: CompWithSym._canonicalize_sym_antisym(6, [(2, 1)])
(((1, 2),), ())
"""
result_sym = []
if sym is None:
sym = []
else:
# Handle the case that sym is an iterator
sym = list(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:
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>self._nid-1:
if i < 0 or i > nb_indices - 1:
raise IndexError("invalid index position: " + str(i) +
" not in [0," + str(self._nid-1) + "]")
self._sym.append(tuple(isym))
self._antisym = []
if antisym is not None and antisym != []:
" not in [0," + str(nb_indices-1) + "]")
result_sym.append(tuple(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:
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>self._nid-1:
if i < 0 or i > nb_indices - 1:
raise IndexError("invalid index position: " + str(i) +
" not in [0," + str(self._nid-1) + "]")
self._antisym.append(tuple(isym))
" not in [0," + str(nb_indices - 1) + "]")
result_antisym.append(tuple(isym))
# Final consistency check:
index_list = []
for isym in self._sym:
for isym in result_sym:
index_list += isym
for isym in self._antisym:
for isym in result_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 " +
"index position appears more then once")
"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_symmetry(self):
r"""
Expand Down Expand Up @@ -3394,9 +3424,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 @@ -3417,6 +3447,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 @@ -3547,7 +3579,7 @@ def paral_sum(a, b, local_list_ind):
com = tuple(set(isym).intersection(set(osym)))
if len(com) > 1:
common_antisym.append(com)
if common_sym != [] or common_antisym != []:
if common_sym or common_antisym:
result = CompWithSym(self._ring, self._frame, self._nid,
self._sindex, self._output_formatter,
common_sym, common_antisym)
Expand Down Expand Up @@ -3655,11 +3687,11 @@ def __mul__(self, other):
sym = list(self._sym)
antisym = list(self._antisym)
if isinstance(other, CompWithSym):
if other._sym != []:
if other._sym:
for s in other._sym:
ns = tuple(s[i]+self._nid for i in range(len(s)))
sym.append(ns)
if other._antisym != []:
if other._antisym:
for s in other._antisym:
ns = tuple(s[i]+self._nid for i in range(len(s)))
antisym.append(ns)
Expand Down Expand Up @@ -3985,7 +4017,7 @@ def non_redundant_index_generator(self):
si = self._sindex
imax = self._dim - 1 + si
ind = [si for k in range(self._nid)]
sym = self._sym.copy() # we may modify this in the following
sym = list(self._sym) # we may modify this in the following
antisym = self._antisym
for pos in range(self._nid):
for isym in antisym:
Expand Down Expand Up @@ -4161,7 +4193,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 @@ -4439,10 +4471,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
Loading

0 comments on commit 6ca796c

Please sign in to comment.