-
Notifications
You must be signed in to change notification settings - Fork 0
/
bisc_post_process.sage
269 lines (198 loc) · 7.72 KB
/
bisc_post_process.sage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
load("../pattern-avoidance/mesh_patterns.sage")
'''
TODO: Go through and clean up
Is everything in here in use?
'''
def describe_bisc_output(OP):
mult = 1
flip = True
for k in OP.keys():
clpatts_of_this_length = OP[k].keys()
print "There are " + str(len(clpatts_of_this_length)) + " underlying classical patterns of length " + str(k)
for clpatt in clpatts_of_this_length:
new_factor = len(OP[k][clpatt])
mult = mult*new_factor
print "There are " + str(new_factor) + " different shadings on " + str(clpatt)
if flip:
print "The number of sets to monitor at the start of the clean-up phase is " + str(mult)
flip = False
def display_forb_output(patts_w_shadings_dict):
'''
Input is the output of forb, i.e., a dictionary
whose keys are lengths of pattern. Each length
points to a dictionary of classical patterns of that
length. The values of those dictionaries are the
shadings of those patterns.
The output is a list of mesh patterns that
we can plot nicely
'''
res = []
for d in patts_w_shadings_dict.values():
for patt, shadings in d.items():
for s in shadings:
res.append((patt,s))
return res
'''
-------------------------------------------------------------------------
Function checks whether the patterns in SG suffice
to describe the permutations in the dictionary D up to length L
There are two subfunctions below
'''
def patterns_suffice(SG, L, D, stop_on_failure=False, parallel=False, ncpus=0):
for n in [1..L]:
if n not in D.keys():
print 'The dictionary does not contain permutations of length ' + str(n)
break
print "Now checking permutations of length " + str(n)
if not parallel:
avoiding_perms = []
for b in D[n]:
b_avoids = avoids_mpats_many_shadings(b,SG)
if b_avoids:
if stop_on_failure:
print "!!!! The permutation " + str(b) + " avoids the patterns !!!!"
return False, [b]
else:
avoiding_perms.append(b)
if D[n] and avoiding_perms:
print "!!!! There are permutations of length " + str(n) + " that avoid the patterns !!!!"
return False, avoiding_perms
else:
if not ncpus:
ncpus = sage.parallel.ncpus.ncpus()
# Slicing the set D[n] into ncpus pieces
sliced = map( lambda permlist : (permlist,SG), sl(D[n],ncpus) )
if stop_on_failure:
some_perm_fails = not all(map(lambda x: x[1], permlist_contains_patts_w_shadings(sliced)))
if some_perm_fails:
print "!!!! There are permutations of length " + str(n) + " that avoid the patterns !!!!"
return False, []
else:
avoiding_perms = reduce( lambda l1,l2 : l1+l2, map(lambda x: x[1], perms_avoiding_patts_w_shadings(sliced)))
if avoiding_perms:
print "!!!! There are permutations of length " + str(n) + " that avoid the patterns !!!!"
return False, avoiding_perms
print "There are no permutations in the complement that avoid the found patterns"
return True, []
def sl(lst,i):
'''
Slice a list lst into i pieces
'''
if i == 1 or not lst:
return [lst]
n = len(lst)
if i >= n:
return map(lambda x : [x], lst)
res = []
m = n//i
for j in range(i):
res.append( lst[(j*m):((j+1)*m)] )
j = j+1
if mod(n,i) != 0:
res[-1].extend(lst[j*m::])
return res
@parallel
def permlist_contains_patts_w_shadings(permlist,patts_w_shadings):
'''
Go through the permutations in permlist
returns False if one of them avoids the patterns (with multiple
shadings) in patts_w_shadings
Supports parallel
'''
for perm in permlist:
if avoids_mpats_many_shadings(perm,patts_w_shadings) == True:
return False
return True
@parallel
def perms_avoiding_patts_w_shadings(permlist,patts_w_shadings):
'''
Go through the permutations in permlist
returns the ones that avoid the patterns (with multiple
shadings) in patts_w_shadings
Supports parallel
'''
res = []
for perm in permlist:
if avoids_mpats_many_shadings(perm,patts_w_shadings) == True:
res.append(perm)
return res
'''
-------------------------------------------------------------------------
Function checks whether the patterns in the base b suffice
to describe the permutations in the dictionary D up to length L
There are two subfunctions below. We also make use of the slice function above
'''
def base_suffices(b,L,D,stop_on_failure=False,parallel=False,ncpus=0):
for n in [1..L]:
if n not in D.keys():
print 'The dictionary does not contain permutations of length ' + str(n)
break
print "Now checking permutations of length " + str(n)
if not parallel:
avoiding_perms = []
for perm in D[n]:
perm_avoids = avoids_mpats(perm,b)
if perm_avoids and stop_on_failure:
print "The permutation " + str(perm) + " avoids the patterns"
return []
else:
avoiding_perms.append(perm)
if D[n] and perm_avoids:
print "There are permutations of length " + str(n) + " that avoid the patterns"
return avoiding_perms
else:
if not ncpus:
ncpus = sage.parallel.ncpus.ncpus()
# Slicing the set D[n] into ncpus pieces
sliced = map( lambda permlist : (permlist,b), sl(D[n],ncpus) )
if stop_on_failure:
some_perm_fails = not all(map(lambda x: x[1], permlist_contains_patts(sliced)))
if some_perm_fails:
print "There are permutations of length " + str(n) + " that avoid the patterns"
return []
else:
avoiding_perms = reduce( lambda l1,l2 : l1+l2, map(lambda x: x[1], perms_avoiding_patts(sliced)))
if avoiding_perms:
print "There are permutations of length " + str(n) + " that avoid the patterns"
return avoiding_perms
@parallel
def permlist_contains_patts(permlist,patts):
'''
Go through the permutations in permlist
returns False if one of them avoids the patterns in patts
Supports parallel
'''
for perm in permlist:
if avoids_mpats(perm,patts) == True:
return False
return True
@parallel
def perms_avoiding_patts(permlist,patts):
'''
Go through the permutations in permlist
returns the ones that avoid the patterns patts
Supports parallel
'''
res = []
for perm in permlist:
if avoids_mpats(perm,patts) == True:
res.append(perm)
return res
# This is defunct as there was something broken in Hjalti's repo after a Sage
# update
def dict_to_MeshPatts(patts_w_shadings_dict):
'''
Input is the output of forb, i.e., a dictionary
whose keys are lengths of pattern. Each length
points to a dictionary of classical patterns of that
length. The values of those dictionaries are the
shadings of those patterns.
The output is a list of MeshPattern objects that
we can plot nicely
'''
res = []
for d in patts_w_shadings_dict.values():
for patt, shadings in d.items():
for s in shadings:
res.append(MeshPattern(patt,s))
return res