Skip to content

Commit a94c866

Browse files
author
Release Manager
committed
gh-40408: simpler code in delta complexes in particular, as suggested by `ruff check --select=SIM113` ### 📝 Checklist - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. URL: #40408 Reported by: Frédéric Chapoton Reviewer(s): David Coudert
2 parents 912c282 + add104e commit a94c866

File tree

1 file changed

+47
-67
lines changed

1 file changed

+47
-67
lines changed

src/sage/topology/delta_complex.py

Lines changed: 47 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,8 @@ def store_bdry(simplex, faces):
290290
pass
291291
else:
292292
if isinstance(data, (list, tuple)):
293-
dim = 0
294-
for s in data:
293+
for dim, s in enumerate(data):
295294
new_data[dim] = s
296-
dim += 1
297295
elif isinstance(data, dict):
298296
if all(isinstance(a, (int, Integer)) for a in data):
299297
# a dictionary indexed by integers
@@ -316,10 +314,7 @@ def store_bdry(simplex, faces):
316314
new_delayed = {}
317315
current = {}
318316
for x in old_data_by_dim[dim]:
319-
if x in data:
320-
bdry = data[x]
321-
else:
322-
bdry = True
317+
bdry = data.get(x, True)
323318
if isinstance(bdry, Simplex):
324319
# case 1
325320
# value is a simplex, so x is glued to the old
@@ -353,7 +348,7 @@ def store_bdry(simplex, faces):
353348
current[x] = store_bdry(x, x.faces())
354349
old_delayed = new_delayed
355350
if dim > 0:
356-
old_data_by_dim[dim-1].extend(old_delayed.keys())
351+
old_data_by_dim[dim-1].extend(old_delayed)
357352
else:
358353
raise ValueError("data is not a list, tuple, or dictionary")
359354
for n in new_data:
@@ -435,7 +430,7 @@ def subcomplex(self, data):
435430
# in self which are not in the subcomplex.
436431
new_data = {}
437432
# max_dim: maximum dimension of cells being added
438-
max_dim = max(data.keys())
433+
max_dim = max(data)
439434
# cells_to_add: in each dimension, add these cells to
440435
# new_dict. start with the cells given in new_data and add
441436
# faces of cells one dimension higher.
@@ -471,7 +466,7 @@ def subcomplex(self, data):
471466
sub._is_subcomplex_of = {self: new_data}
472467
return sub
473468

474-
def __hash__(self):
469+
def __hash__(self) -> int:
475470
r"""
476471
TESTS::
477472
@@ -482,7 +477,7 @@ def __hash__(self):
482477
"""
483478
return hash(frozenset(self._cells_dict.items()))
484479

485-
def __eq__(self, right):
480+
def __eq__(self, right) -> bool:
486481
r"""
487482
Two `\Delta`-complexes are equal, according to this, if they have
488483
the same ``_cells_dict``.
@@ -499,7 +494,7 @@ def __eq__(self, right):
499494
"""
500495
return self._cells_dict == right._cells_dict
501496

502-
def __ne__(self, other):
497+
def __ne__(self, other) -> bool:
503498
r"""
504499
Return ``True`` if ``self`` and ``other`` are not equal.
505500
@@ -556,15 +551,15 @@ def cells(self, subcomplex=None):
556551
return cells
557552
if subcomplex._is_subcomplex_of is None or self not in subcomplex._is_subcomplex_of:
558553
if subcomplex == self:
559-
for d in range(-1, max(cells.keys())+1):
554+
for d in range(-1, max(cells) + 1):
560555
l = len(cells[d])
561-
cells[d] = [None]*l # get rid of all cells
556+
cells[d] = [None] * l # get rid of all cells
562557
return cells
563558
else:
564559
raise ValueError("this is not a subcomplex of self")
565560
else:
566561
subcomplex_cells = subcomplex._is_subcomplex_of[self]
567-
for d in range(max(subcomplex_cells.keys()) + 1):
562+
for d in range(max(subcomplex_cells) + 1):
568563
L = list(cells[d])
569564
for c in subcomplex_cells[d]:
570565
L[c] = None
@@ -638,33 +633,30 @@ def chain_complex(self, subcomplex=None, augmented=False,
638633
augmented = False
639634

640635
differentials = {}
641-
if augmented:
642-
empty_simplex = 1 # number of (-1)-dimensional simplices
643-
else:
644-
empty_simplex = 0
636+
# number of (-1)-dimensional simplices
637+
empty_simplex = 1 if augmented else 0
638+
645639
vertices = self.n_cells(0, subcomplex=subcomplex)
646640
old = vertices
647641
old_real = [x for x in old if x is not None] # remove faces not in subcomplex
648642
n = len(old_real)
649-
differentials[0] = matrix(base_ring, empty_simplex, n, n*empty_simplex*[1])
643+
differentials[0] = matrix(base_ring, empty_simplex, n,
644+
n * empty_simplex * [1])
650645
# current is list of simplices in dimension dim
651646
# current_real is list of simplices in dimension dim, with None filtered out
652647
# old is list of simplices in dimension dim-1
653648
# old_real is list of simplices in dimension dim-1, with None filtered out
654-
for dim in range(1, self.dimension()+1):
649+
for dim in range(1, self.dimension() + 1):
655650
current = list(self.n_cells(dim, subcomplex=subcomplex))
656651
current_real = [x for x in current if x is not None]
657-
i = 0
658652
i_real = 0
659653
translate = {}
660-
for s in old:
654+
for i, s in enumerate(old):
661655
if s is not None:
662656
translate[i] = i_real
663657
i_real += 1
664-
i += 1
665658
mat_dict = {}
666-
col = 0
667-
for s in current_real:
659+
for col, s in enumerate(current_real):
668660
sign = 1
669661
for row in s:
670662
if old[row] is not None:
@@ -674,14 +666,13 @@ def chain_complex(self, subcomplex=None, augmented=False,
674666
else:
675667
mat_dict[(actual_row, col)] = sign
676668
sign *= -1
677-
col += 1
678669
differentials[dim] = matrix(base_ring, len(old_real), len(current_real), mat_dict)
679670
old = current
680671
old_real = current_real
681672
if cochain:
682673
cochain_diffs = {}
683674
for dim in differentials:
684-
cochain_diffs[dim-1] = differentials[dim].transpose()
675+
cochain_diffs[dim - 1] = differentials[dim].transpose()
685676
return ChainComplex(data=cochain_diffs, degree=1,
686677
base_ring=base_ring, check=check)
687678
else:
@@ -975,30 +966,24 @@ def product(self, other):
975966
# vertices: the vertices in the product are of the form (v,w)
976967
# for v a vertex in self, w a vertex in other
977968
vertices = []
978-
l_idx = 0
979-
for v in self.n_cells(0):
980-
r_idx = 0
981-
for w in other.n_cells(0):
969+
for l_idx, v in enumerate(self.n_cells(0)):
970+
for r_idx, w in enumerate(other.n_cells(0)):
982971
# one vertex for each pair (v,w)
983972
# store its indices in bdries; store its boundary in vertices
984973
bdries[(0, l_idx, 0, r_idx, ((0, 0),))] = len(vertices)
985974
vertices.append(()) # add new vertex (simplex with empty bdry)
986-
r_idx += 1
987-
l_idx += 1
988975
data.append(tuple(vertices))
989976
# dim of the product:
990977
maxdim = self.dimension() + other.dimension()
991978
# d-cells, d>0: these are obtained by taking products of cells
992979
# of dimensions k and n, where n+k >= d and n <= d, k <= d.
993980
simplices = []
994981
new = {}
995-
for d in range(1, maxdim+1):
996-
for k in range(d+1):
997-
for n in range(d-k, d+1):
998-
k_idx = 0
999-
for k_cell in self.n_cells(k):
1000-
n_idx = 0
1001-
for n_cell in other.n_cells(n):
982+
for d in range(1, maxdim + 1):
983+
for k in range(d + 1):
984+
for n in range(d - k, d + 1):
985+
for k_idx, k_cell in enumerate(self.n_cells(k)):
986+
for n_idx, n_cell in enumerate(other.n_cells(n)):
1002987
# find d-dimensional faces in product of
1003988
# k_cell and n_cell. to avoid repetition,
1004989
# only look for faces which use all
@@ -1049,8 +1034,6 @@ def product(self, other):
10491034
n_face_dim, n_face_idx,
10501035
face_path)])
10511036
simplices.append(tuple(bdry_list))
1052-
n_idx += 1
1053-
k_idx += 1
10541037
# add d-simplices to data, store d-simplices in bdries,
10551038
# reset simplices
10561039
data.append(tuple(simplices))
@@ -1081,9 +1064,9 @@ def disjoint_union(self, right):
10811064
# len(self.n_cells(n-1)) to it
10821065
for n in range(dim, 0, -1):
10831066
data[n] = list(self.n_cells(n))
1084-
translate = len(self.n_cells(n-1))
1067+
translate = len(self.n_cells(n - 1))
10851068
for f in right.n_cells(n):
1086-
data[n].append(tuple([a+translate for a in f]))
1069+
data[n].append(tuple([a + translate for a in f]))
10871070
data[0] = self.n_cells(0) + right.n_cells(0)
10881071
return DeltaComplex(data)
10891072

@@ -1194,23 +1177,22 @@ def connected_sum(self, other):
11941177
glued = copy(renaming)
11951178
# process_later: cells one dim lower to be added to data
11961179
process_later = []
1197-
old_idx = 0
1198-
new_idx = len(data[n-1])
1180+
new_idx = len(data[n - 1])
11991181
# build 'renaming'
1200-
for s in right_cells[n-1]:
1182+
for old_idx, s in enumerate(right_cells[n - 1]):
12011183
if old_idx not in renaming:
12021184
process_later.append(s)
12031185
renaming[old_idx] = new_idx
12041186
new_idx += 1
1205-
old_idx += 1
12061187
# reindex all simplices to be processed and add them to data
12071188
for s in process_now:
12081189
data[n].append(tuple([renaming[i] for i in s]))
12091190
# set up for next loop, one dimension down
12101191
renaming = {}
12111192
process_now = process_later
12121193
for f in glued:
1213-
renaming.update(dict(zip(right_cells[n-1][f], data[n-1][glued[f]])))
1194+
renaming.update(dict(zip(right_cells[n - 1][f],
1195+
data[n - 1][glued[f]])))
12141196
# deal with vertices separately. we just need to add enough
12151197
# vertices: all the vertices from Right, minus the number
12161198
# being glued, which should be dim+1, the number of vertices
@@ -1302,7 +1284,7 @@ def elementary_subdivision(self, idx=-1):
13021284
cells_dict[0].append(())
13031285
# added_cells: dict indexed by (n-1)-cells, with value the
13041286
# corresponding new n-cell.
1305-
added_cells = {(): len(cells_dict[0])-1}
1287+
added_cells = {(): len(cells_dict[0]) - 1}
13061288
for n in range(dim):
13071289
new_cells = {}
13081290
# for each n-cell in the standard simplex, add an
@@ -1316,15 +1298,15 @@ def elementary_subdivision(self, idx=-1):
13161298
cell = []
13171299
for i in simplex:
13181300
if n > 0:
1319-
bdry = tuple(std_cells[n-1][i])
1301+
bdry = tuple(std_cells[n - 1][i])
13201302
else:
13211303
bdry = ()
13221304
cell.append(added_cells[bdry])
13231305
# last face is the image of the old simplex)
13241306
cell.append(pi[n][simplex])
13251307
cell = tuple(cell)
1326-
cells_dict[n+1].append(cell)
1327-
new_cells[simplex] = len(cells_dict[n+1])-1
1308+
cells_dict[n + 1].append(cell)
1309+
new_cells[simplex] = len(cells_dict[n + 1]) - 1
13281310
added_cells = new_cells
13291311
return DeltaComplex(cells_dict)
13301312

@@ -1397,7 +1379,8 @@ def _epi_from_standard_simplex(self, idx=-1, dim=None):
13971379
faces_dict = {}
13981380
for cell in n_cells:
13991381
if n > 1:
1400-
faces = [tuple(simplex_cells[n-1][cell[j]]) for j in range(n+1)]
1382+
faces = [tuple(simplex_cells[n - 1][cell[j]])
1383+
for j in range(n + 1)]
14011384
one_cell = dict(zip(faces, self_cells[n][n_cells[cell]]))
14021385
else:
14031386
temp = dict(zip(cell, self_cells[n][n_cells[cell]]))
@@ -1407,7 +1390,7 @@ def _epi_from_standard_simplex(self, idx=-1, dim=None):
14071390
for j in one_cell:
14081391
if j not in faces_dict:
14091392
faces_dict[j] = one_cell[j]
1410-
mapping[n-1] = faces_dict
1393+
mapping[n - 1] = faces_dict
14111394
return mapping
14121395

14131396
def _is_glued(self, idx=-1, dim=None):
@@ -1450,16 +1433,16 @@ def _is_glued(self, idx=-1, dim=None):
14501433
i = self.dimension() - 1
14511434
i_faces = set(simplex)
14521435
# if there are enough i_faces, then no gluing is evident so far
1453-
not_glued = (len(i_faces) == binomial(dim+1, i+1))
1436+
not_glued = (len(i_faces) == binomial(dim + 1, i + 1))
14541437
while not_glued and i > 0:
14551438
# count the (i-1) cells and compare to (n+1) choose i.
14561439
old_faces = i_faces
14571440
i_faces = set()
14581441
all_cells = self.n_cells(i)
14591442
for face in old_faces:
14601443
i_faces.update(all_cells[face])
1461-
not_glued = (len(i_faces) == binomial(dim+1, i))
1462-
i = i-1
1444+
not_glued = (len(i_faces) == binomial(dim + 1, i))
1445+
i -= 1
14631446
return not not_glued
14641447

14651448
def face_poset(self):
@@ -1480,16 +1463,12 @@ def face_poset(self):
14801463
covers = {}
14811464
# store each n-simplex as a pair (n, idx).
14821465
for n in range(dim, 0, -1):
1483-
idx = 0
1484-
for s in self.n_cells(n):
1485-
covers[(n, idx)] = list({(n-1, i) for i in s})
1486-
idx += 1
1466+
for idx, s in enumerate(self.n_cells(n)):
1467+
covers[(n, idx)] = [(n - 1, i) for i in set(s)]
14871468
# deal with vertices separately: they have no covers (in the
14881469
# dual poset).
1489-
idx = 0
1490-
for s in self.n_cells(0):
1470+
for idx, s in enumerate(self.n_cells(0)):
14911471
covers[(0, idx)] = []
1492-
idx += 1
14931472
return Poset(Poset(covers).hasse_diagram().reverse())
14941473

14951474
# implement using the definition? the simplices are obtained by
@@ -1674,7 +1653,8 @@ def Sphere(self, n):
16741653
"""
16751654
if n == 1:
16761655
return DeltaComplex([[()], [(0, 0)]])
1677-
return DeltaComplex({Simplex(n): True, Simplex(range(1, n+2)): Simplex(n)})
1656+
return DeltaComplex({Simplex(n): True,
1657+
Simplex(range(1, n + 2)): Simplex(n)})
16781658

16791659
def Torus(self):
16801660
r"""

0 commit comments

Comments
 (0)