Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
GuillaumeLaplante-Anfossi
GitHub Repository: GuillaumeLaplante-Anfossi/Poissons
Path: blob/main/GeneratingDiagonalsViaShift/diagonals_via_shift.py
1017 views
1
'''
2
A quick script for generating diagonals using the shift method of SU from
3
"Comparing Diagonals on the Associahedra"
4
5
6
Use the two natural shift pairs
7
- (L,R) i.e the SU original
8
- (L',R') a symmetry of the prior pair, and we now know these are LA diagonals.
9
'''
10
from itertools import permutations, chain, combinations, product
11
from copy import deepcopy
12
import sys
13
14
def powerset(iterable):
15
'''
16
https://stackoverflow.com/questions/1482308/how-to-get-all-subsets-of-a-set-powerset
17
returns a generator for the powerset
18
'''
19
s = list(iterable)
20
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
21
22
def vertex_generator(n):
23
'''
24
returns a generator (iterable) for the permutations of size n,
25
which correspond to vertices.
26
'''
27
return permutations(range(1,n+1))
28
29
def strong_complimentary_pair(v):
30
'''
31
returns the strong complimentary pair of a given vertex
32
'''
33
merge_desc = [[v[0]]]
34
merge_asc = [[v[0]]]
35
36
prev = v[0]
37
for x in v[1:]:
38
if x>prev:
39
merge_asc[-1].append(x)
40
merge_desc.append([x])
41
if x<prev:
42
merge_desc[-1].append(x)
43
merge_asc.append([x])
44
prev = x
45
46
#Sort the subpartitions so in standard form
47
merge_asc = [sorted(x) for x in merge_asc]
48
merge_desc = [sorted(x) for x in merge_desc]
49
50
return merge_desc, merge_asc
51
52
def R_shifts(lcp,j=0):
53
'''
54
returns all possibe R shifts of the left elem of complementary pair when j=0
55
'''
56
shifts = [lcp]
57
58
if j == len(lcp)-1:
59
#no right shift possible
60
return shifts
61
62
feasible_Ms = powerset(lcp[j][1:])
63
64
for M in feasible_Ms:
65
if len(M)==0:
66
#If M is emptyset go to next.
67
shifts = R_shifts(lcp,j+1)
68
#min M_j > max A_{j+1} then perform shift
69
elif M[0]>lcp[j+1][-1]:
70
shift = deepcopy(lcp) #copy the contents not the pointer
71
shift[j] = list(set(lcp[j]) - set(M))
72
shift[j+1] = sorted(shift[j+1]+list(M))
73
74
#Recurse
75
shifts = shifts + R_shifts(shift,j+1)
76
77
return shifts
78
79
80
def L_shifts(rcp,j=None):
81
'''
82
returns all possibe L shifts of the right elem of complementary pair
83
84
We use the indexing B_1...B_q (instead of Bq...B1)
85
Also refer to Ns as Ms
86
'''
87
shifts = [rcp]
88
if j is None:
89
j = len(rcp)-1
90
if j==0:
91
#No left shift possible
92
return shifts
93
94
feasible_Ms = powerset(rcp[j][1:])
95
96
for M in feasible_Ms:
97
if len(M)==0:
98
#If M is emptyset go to next.
99
shifts = L_shifts(rcp,j-1)
100
#min M_j > max A_{j-1} then perform shift
101
elif M[0]>rcp[j-1][-1]:
102
shift = deepcopy(rcp) #copy the contents not the pointer
103
shift[j] = list(set(rcp[j]) - set(M))
104
shift[j-1] = sorted(shift[j-1]+list(M))
105
106
#Recurse
107
shifts = shifts + L_shifts(shift,j-1)
108
109
return shifts
110
111
def LR_shift_of_v(v):
112
'''
113
returns A_v x B_v
114
'''
115
lcp, rcp = strong_complimentary_pair(v)
116
pairs = []
117
for l in R_shifts(lcp):
118
for r in L_shifts(rcp):
119
pairs.append([l,r])
120
121
return pairs
122
123
def diagonal_via_LR_shift(n):
124
pairs = []
125
for v in vertex_generator(n):
126
pairs = pairs + LR_shift_of_v(v)
127
return pairs
128
129
130
def R_prime_shifts(lcp,j=None):
131
'''
132
returns all possibe R shifts of the left elem of complementary pair when j=0
133
'''
134
shifts = [lcp]
135
136
if j is None:
137
j = len(lcp)-1
138
139
if j == 0:
140
#no right prime shift possible
141
return shifts
142
143
feasible_Ms = powerset(lcp[j][:-1])
144
145
for M in feasible_Ms:
146
if len(M)==0:
147
#If M is emptyset go to next.
148
shifts = R_prime_shifts(lcp,j-1)
149
#max M_j < min A_{j-1} then perform shift
150
elif M[-1]<lcp[j-1][0]:
151
shift = deepcopy(lcp) #copy the contents not the pointer
152
shift[j] = list(set(lcp[j]) - set(M))
153
shift[j-1] = sorted(shift[j-1]+list(M))
154
155
#Recurse
156
shifts = shifts + R_prime_shifts(shift,j-1)
157
158
return shifts
159
160
161
def L_prime_shifts(rcp,j=None):
162
'''
163
returns all possibe L shifts of the right elem of complementary pair
164
165
We use the indexing B_1...B_q (instead of Bq...B1)
166
Also refer to Ns as Ms
167
'''
168
shifts = [rcp]
169
if j is None:
170
j = 0
171
if j==len(rcp)-1:
172
#No left shift possible
173
return shifts
174
175
feasible_Ms = powerset(rcp[j][:-1])
176
177
for M in feasible_Ms:
178
if len(M)==0:
179
shifts = L_prime_shifts(rcp,j+1)
180
#max M_j < min A_{j+1} then perform shift
181
elif M[-1]<rcp[j+1][0]:
182
shift = deepcopy(rcp) #copy the contents not the pointer
183
shift[j] = list(set(rcp[j]) - set(M))
184
shift[j+1] = sorted(shift[j+1]+list(M))
185
186
#Recurse
187
shifts = shifts + L_prime_shifts(shift,j+1)
188
189
return shifts
190
191
def LR_prime_shift_of_v(v):
192
'''
193
returns A_v x B_v
194
'''
195
lcp,rcp = strong_complimentary_pair(v)
196
pairs = []
197
for l in R_prime_shifts(lcp):
198
for r in L_prime_shifts(rcp):
199
pairs.append([l,r])
200
201
return pairs
202
203
def diagonal_via_LR_prime_shift(n):
204
pairs = []
205
for v in vertex_generator(n):
206
pairs = pairs + LR_prime_shift_of_v(v)
207
return pairs
208
209
def SU_diag(n):
210
return diagonal_via_LR_shift(n)
211
212
def LA_diag(n):
213
return diagonal_via_LR_prime_shift(n)
214
215
if __name__ == "__main__":
216
v = list(vertex_generator(3))[3]
217
print(v)
218
lcp,rcp = strong_complimentary_pair(v)
219
print(lcp,rcp)
220
print(R_prime_shifts([[2],[1,3,4]]))
221
print()
222
223
print(diagonal_via_LR_shift(3))
224
print()
225
print(diagonal_via_LR_prime_shift(3))
226
227
for k in range(1,7):
228
n1 = len(diagonal_via_LR_shift(k))
229
n2 = len(diagonal_via_LR_prime_shift(k))
230
print(n1,n2)
231
232
233
#Printing out lists for comparison.
234
for k in range(1,7):
235
s = "./Examples/Shift/n={}.txt".format(k)
236
with open(s, 'w') as f:
237
sys.stdout = f # Change the standard output to file.
238
print(diagonal_via_LR_shift(k))
239
240
s = "./Examples/PrimeShift/n={}.txt".format(k)
241
with open(s, 'w') as f:
242
sys.stdout = f # Change the standard output to file.
243
print(diagonal_via_LR_prime_shift(k))
244