Skip to content

Commit e63a3f5

Browse files
committed
a few details in combinat (designs)
1 parent 1cf0c13 commit e63a3f5

File tree

5 files changed

+63
-56
lines changed

5 files changed

+63
-56
lines changed

src/sage/combinat/designs/group_divisible_designs.py

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,20 @@
2424
---------
2525
"""
2626

27-
#*****************************************************************************
27+
# ****************************************************************************
2828
# This program is free software: you can redistribute it and/or modify
2929
# it under the terms of the GNU General Public License as published by
3030
# the Free Software Foundation, either version 2 of the License, or
3131
# (at your option) any later version.
32-
# http://www.gnu.org/licenses/
33-
#*****************************************************************************
32+
# https://www.gnu.org/licenses/
33+
# ****************************************************************************
3434

3535
from sage.arith.misc import is_prime_power
36-
from sage.misc.unknown import Unknown
36+
from sage.misc.unknown import Unknown
3737
from .incidence_structures import IncidenceStructure
3838

39-
def group_divisible_design(v,K,G,existence=False,check=False):
39+
40+
def group_divisible_design(v, K, G, existence=False, check=False):
4041
r"""
4142
Return a `(v,K,G)`-Group Divisible Design.
4243
@@ -90,36 +91,31 @@ def group_divisible_design(v,K,G,existence=False,check=False):
9091
blocks = None
9192

9293
# from a (v+1,k,1)-BIBD
93-
if (len(G) == 1 and
94-
len(K) == 1 and
95-
G[0]+1 in K):
94+
if len(G) == 1 == len(K) and G[0] + 1 in K:
9695
from .bibd import balanced_incomplete_block_design
9796
k = K[0]
9897
if existence:
99-
return balanced_incomplete_block_design(v+1,k,existence=True)
100-
BIBD = balanced_incomplete_block_design(v+1,k)
98+
return balanced_incomplete_block_design(v + 1, k, existence=True)
99+
BIBD = balanced_incomplete_block_design(v + 1, k)
101100
groups = [[x for x in S if x != v] for S in BIBD if v in S]
102-
d = {p:i for i,p in enumerate(sum(groups,[]))}
101+
d = {p: i for i, p in enumerate(sum(groups, []))}
103102
d[v] = v
104103
BIBD.relabel(d)
105-
groups = [list(range((k-1)*i,(k-1)*(i+1))) for i in range(v//(k-1))]
104+
groups = [list(range((k - 1) * i, (k - 1) * (i + 1)))
105+
for i in range(v // (k - 1))]
106106
blocks = [S for S in BIBD if v not in S]
107107

108108
# (v,{4},{2})-GDD
109-
elif (v % 2 == 0 and
110-
K == [4] and
111-
G == [2] and
112-
GDD_4_2(v//2,existence=True)):
109+
elif (v % 2 == 0 and K == [4] and
110+
G == [2] and GDD_4_2(v // 2, existence=True)):
113111
if existence:
114112
return True
115-
return GDD_4_2(v//2,check=check)
113+
return GDD_4_2(v // 2, check=check)
116114

117115
# From a TD(k,g)
118-
elif (len(G) == 1 and
119-
len(K) == 1 and
120-
K[0]*G[0] == v):
116+
elif (len(G) == 1 == len(K) and K[0] * G[0] == v):
121117
from .orthogonal_arrays import transversal_design
122-
return transversal_design(k=K[0],n=G[0],existence=existence)
118+
return transversal_design(k=K[0], n=G[0], existence=existence)
123119

124120
if blocks:
125121
return GroupDivisibleDesign(v,
@@ -134,7 +130,8 @@ def group_divisible_design(v,K,G,existence=False,check=False):
134130
return Unknown
135131
raise NotImplementedError
136132

137-
def GDD_4_2(q,existence=False,check=True):
133+
134+
def GDD_4_2(q, existence=False, check=True):
138135
r"""
139136
Return a `(2q,\{4\},\{2\})`-GDD for `q` a prime power with `q\equiv 1\pmod{6}`.
140137
@@ -180,26 +177,27 @@ def GDD_4_2(q,existence=False,check=True):
180177
return True
181178

182179
from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
183-
G = GF(q,'x')
180+
G = GF(q, 'x')
184181
w = G.primitive_element()
185182
e = w**((q - 1) // 3)
186183

187184
# A first parallel class is defined. G acts on it, which yields all others.
188-
first_class = [[(0,0),(1,w**i),(1,e*w**i),(1,e*e*w**i)]
185+
first_class = [[(0, 0), (1, w**i), (1, e * w**i), (1, e * e * w**i)]
189186
for i in range((q - 1) // 6)]
190187

191-
label = {p:i for i,p in enumerate(G)}
192-
classes = [[[2*label[x[1]+g]+(x[0]+j) % 2 for x in S]
188+
label = {p: i for i, p in enumerate(G)}
189+
classes = [[[2 * label[x[1] + g] + (x[0] + j) % 2 for x in S]
193190
for S in first_class]
194191
for g in G for j in range(2)]
195192

196-
return GroupDivisibleDesign(2*q,
197-
groups=[[i,i+1] for i in range(0,2*q,2)],
198-
blocks=sum(classes,[]),
199-
K=[4],
200-
G=[2],
201-
check=check,
202-
copy=False)
193+
return GroupDivisibleDesign(2 * q,
194+
groups=[[i, i + 1] for i in range(0, 2 * q, 2)],
195+
blocks=sum(classes, []),
196+
K=[4],
197+
G=[2],
198+
check=check,
199+
copy=False)
200+
203201

204202
class GroupDivisibleDesign(IncidenceStructure):
205203
r"""
@@ -261,9 +259,9 @@ class GroupDivisibleDesign(IncidenceStructure):
261259
sage: GDD = GroupDivisibleDesign('abcdefghiklm',None,D)
262260
sage: sorted(GDD.groups())
263261
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['k', 'l', 'm']]
264-
265262
"""
266-
def __init__(self, points, groups, blocks, G=None, K=None, lambd=1, check=True, copy=True,**kwds):
263+
def __init__(self, points, groups, blocks, G=None, K=None, lambd=1,
264+
check=True, copy=True, **kwds):
267265
r"""
268266
Constructor function
269267
@@ -286,16 +284,17 @@ def __init__(self, points, groups, blocks, G=None, K=None, lambd=1, check=True,
286284
check=False,
287285
**kwds)
288286

289-
if (groups is None or
290-
(copy is False and self._point_to_index is None)):
287+
if (groups is None or (copy is False and self._point_to_index is None)):
291288
self._groups = groups
292289
elif self._point_to_index is None:
293290
self._groups = [g[:] for g in groups]
294291
else:
295292
self._groups = [[self._point_to_index[x] for x in g] for g in groups]
296293

297294
if check or groups is None:
298-
is_gdd = is_group_divisible_design(self._groups,self._blocks,self.num_points(),G,K,lambd,verbose=1)
295+
is_gdd = is_group_divisible_design(self._groups, self._blocks,
296+
self.num_points(), G, K,
297+
lambd, verbose=1)
299298
assert is_gdd
300299
if groups is None:
301300
self._groups = is_gdd[1]
@@ -337,7 +336,7 @@ def groups(self):
337336

338337
def __repr__(self):
339338
r"""
340-
Returns a string that describes self
339+
Return a string that describes ``self``.
341340
342341
EXAMPLES::
343342
@@ -347,16 +346,15 @@ def __repr__(self):
347346
sage: GDD = GroupDivisibleDesign(40,groups,TD); GDD
348347
Group Divisible Design on 40 points of type 10^4
349348
"""
349+
group_sizes = [len(g) for g in self._groups]
350350

351-
group_sizes = [len(_) for _ in self._groups]
352-
353-
gdd_type = ["{}^{}".format(s,group_sizes.count(s))
354-
for s in sorted(set(group_sizes))]
351+
gdd_type = ("{}^{}".format(s, group_sizes.count(s))
352+
for s in sorted(set(group_sizes)))
355353
gdd_type = ".".join(gdd_type)
356354

357355
if not gdd_type:
358356
gdd_type = "1^0"
359357

360358
v = self.num_points()
361359

362-
return "Group Divisible Design on {} points of type {}".format(v,gdd_type)
360+
return "Group Divisible Design on {} points of type {}".format(v, gdd_type)

src/sage/combinat/designs/resolvable_bibd.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ def resolvable_balanced_incomplete_block_design(v,k,existence=False):
140140
return Unknown
141141
raise NotImplementedError("I don't know how to build a ({},{},1)-RBIBD!".format(v,3))
142142

143+
143144
def kirkman_triple_system(v,existence=False):
144145
r"""
145146
Return a Kirkman Triple System on `v` points.
@@ -437,6 +438,7 @@ def v_4_1_rbibd(v,existence=False):
437438
assert BIBD.is_resolvable()
438439
return BIBD
439440

441+
440442
def PBD_4_7(v,check=True, existence=False):
441443
r"""
442444
Return a `(v,\{4,7\})`-PBD
@@ -683,6 +685,7 @@ def PBD_4_7(v,check=True, existence=False):
683685
check=check,
684686
copy=False)
685687

688+
686689
def PBD_4_7_from_Y(gdd,check=True):
687690
r"""
688691
Return a `(3v+1,\{4,7\})`-PBD from a `(v,\{4,5,7\},\NN-\{3,6,10\})`-GDD.

src/sage/combinat/designs/twographs.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
from sage.combinat.designs.incidence_structures import IncidenceStructure
6060
from itertools import combinations
6161

62+
6263
class TwoGraph(IncidenceStructure):
6364
r"""
6465
Two-graphs class.
@@ -199,9 +200,10 @@ def taylor_twograph(q):
199200
from sage.graphs.generators.classical_geometries import TaylorTwographSRG
200201
return TaylorTwographSRG(q).twograph()
201202

202-
def is_twograph(T):
203+
204+
def is_twograph(T) -> bool:
203205
r"""
204-
Checks that the incidence system `T` is a two-graph
206+
Check whether the incidence system `T` is a two-graph.
205207
206208
INPUT:
207209
@@ -237,7 +239,7 @@ def is_twograph(T):
237239
return False
238240

239241
# A structure for a fast triple existence check
240-
v_to_blocks = {v:set() for v in range(T.num_points())}
242+
v_to_blocks = {v: set() for v in range(T.num_points())}
241243
for B in T._blocks:
242244
B = frozenset(B)
243245
for x in B:
@@ -248,8 +250,8 @@ def has_triple(x_y_z):
248250
return bool(v_to_blocks[x] & v_to_blocks[y] & v_to_blocks[z])
249251

250252
# Check that every quadruple contains an even number of triples
251-
for quad in combinations(range(T.num_points()),4):
252-
if sum(map(has_triple,combinations(quad,3))) % 2 == 1:
253+
for quad in combinations(range(T.num_points()), 4):
254+
if sum(map(has_triple, combinations(quad, 3))) % 2 == 1:
253255
return False
254256

255257
return True
@@ -296,10 +298,10 @@ def twograph_descendant(G, v, name=None):
296298
sage: twograph_descendant(p, 5, name=True)
297299
descendant of Petersen graph at 5: Graph on 9 vertices
298300
"""
299-
G = G.seidel_switching(G.neighbors(v),inplace=False)
301+
G = G.seidel_switching(G.neighbors(v), inplace=False)
300302
G.delete_vertex(v)
301303
if name:
302-
G.name('descendant of '+G.name()+' at '+str(v))
304+
G.name('descendant of ' + G.name() + ' at ' + str(v))
303305
else:
304306
G.name('')
305307
return G

src/sage/combinat/matrices/dlxcpp.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
22
Dancing links C++ wrapper
33
"""
4-
#*****************************************************************************
4+
# ****************************************************************************
55
# Copyright (C) 2008 Carlo Hamalainen <[email protected]>,
66
#
77
# Distributed under the terms of the GNU General Public License (GPL)
@@ -13,14 +13,15 @@
1313
#
1414
# The full text of the GPL is available at:
1515
#
16-
# http://www.gnu.org/licenses/
17-
#*****************************************************************************
16+
# https://www.gnu.org/licenses/
17+
# ****************************************************************************
1818

1919
# OneExactCover and AllExactCovers are almost exact copies of the
2020
# functions with the same name in sage/combinat/dlx.py by Tom Boothby.
2121

2222
from .dancing_links import dlx_solver
2323

24+
2425
def DLXCPP(rows):
2526
"""
2627
Solves the Exact Cover problem by using the Dancing Links algorithm
@@ -85,6 +86,7 @@ def DLXCPP(rows):
8586
while x.search():
8687
yield x.get_solution()
8788

89+
8890
def AllExactCovers(M):
8991
"""
9092
Solves the exact cover problem on the matrix M (treated as a dense
@@ -112,6 +114,7 @@ def AllExactCovers(M):
112114
for s in DLXCPP(rows):
113115
yield [M.row(i) for i in s]
114116

117+
115118
def OneExactCover(M):
116119
"""
117120
Solves the exact cover problem on the matrix M (treated as a dense

src/sage/combinat/tuple.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
#
1616
# https://www.gnu.org/licenses/
1717
# ****************************************************************************
18+
from itertools import product, combinations_with_replacement
1819

1920
from sage.arith.misc import binomial
21+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
2022
from sage.rings.integer_ring import ZZ
2123
from sage.structure.parent import Parent
2224
from sage.structure.unique_representation import UniqueRepresentation
23-
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
24-
from itertools import product, combinations_with_replacement
25+
2526

2627
class Tuples(Parent, UniqueRepresentation):
2728
"""

0 commit comments

Comments
 (0)