schubmult 1.1.6__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {schubmult-1.1.6 → schubmult-1.2.0}/PKG-INFO +1 -1
- schubmult-1.2.0/schubmult/perm_lib.py +530 -0
- schubmult-1.2.0/schubmult/schubmult_double/schubmult_double.py +162 -0
- schubmult-1.2.0/schubmult/schubmult_py/schubmult_py.py +156 -0
- schubmult-1.2.0/schubmult/schubmult_yz/schubmult_yz.py +898 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult.egg-info/PKG-INFO +1 -1
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult.egg-info/SOURCES.txt +1 -2
- schubmult-1.2.0/schubmult.egg-info/requires.txt +5 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/setup.py +5 -4
- schubmult-1.1.6/schubmult/perm_lib.py +0 -242
- schubmult-1.1.6/schubmult/schubmult_double/schubmult_double.py +0 -166
- schubmult-1.1.6/schubmult/schubmult_py/schubmult_py.py +0 -159
- schubmult-1.1.6/schubmult/schubmult_yz/schubmult_yz.py +0 -362
- schubmult-1.1.6/schubmult/schubmult_yz/schubmult_yz_test.py +0 -87
- schubmult-1.1.6/schubmult.egg-info/requires.txt +0 -4
- {schubmult-1.1.6 → schubmult-1.2.0}/LICENSE +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/README.md +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult/__init__.py +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult/schubmult_double/__init__.py +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult/schubmult_double/__main__.py +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult/schubmult_py/__init__.py +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult/schubmult_py/__main__.py +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult/schubmult_py/schubmult_py_bak.py +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult/schubmult_py/schubmult_py_parallel.py +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult/schubmult_yz/__init__.py +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult/schubmult_yz/__main__.py +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult.egg-info/dependency_links.txt +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult.egg-info/entry_points.txt +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/schubmult.egg-info/top_level.txt +0 -0
- {schubmult-1.1.6 → schubmult-1.2.0}/setup.cfg +0 -0
@@ -0,0 +1,530 @@
|
|
1
|
+
from symengine import *
|
2
|
+
from functools import cache
|
3
|
+
from itertools import chain
|
4
|
+
from bisect import bisect_left
|
5
|
+
|
6
|
+
def inv(perm):
|
7
|
+
L = len(perm)
|
8
|
+
v = [i for i in range(1,L+1)]
|
9
|
+
ans = 0
|
10
|
+
for i in range(L):
|
11
|
+
itr = bisect_left(v, perm[i])
|
12
|
+
ans += itr
|
13
|
+
v = v[:itr] + v[itr + 1 :]
|
14
|
+
return ans
|
15
|
+
|
16
|
+
def mulperm(perm1,perm2):
|
17
|
+
if len(perm1)<len(perm2):
|
18
|
+
return [perm1[perm2[i]-1] if perm2[i]<=len(perm1) else perm2[i] for i in range(len(perm2))]
|
19
|
+
else:
|
20
|
+
return [perm1[perm2[i]-1] for i in range(len(perm2))]+perm1[len(perm2):]
|
21
|
+
|
22
|
+
def uncode(cd):
|
23
|
+
cd2 = list(cd)
|
24
|
+
if cd2 == []:
|
25
|
+
return [1,2]
|
26
|
+
max_required = max([cd2[i]+i for i in range(len(cd2))])
|
27
|
+
cd2 += [0 for i in range(len(cd2),max_required)]
|
28
|
+
fullperm = [i+1 for i in range(len(cd2)+1)]
|
29
|
+
perm = []
|
30
|
+
for i in range(len(cd2)):
|
31
|
+
perm += [fullperm[cd2[i]]]
|
32
|
+
fullperm.pop(cd2[i])
|
33
|
+
perm += [fullperm[0]]
|
34
|
+
return perm
|
35
|
+
|
36
|
+
|
37
|
+
def code(perm):
|
38
|
+
ret = []
|
39
|
+
for i in range(len(perm)-1):
|
40
|
+
ret += [0]
|
41
|
+
for j in range(i+1,len(perm)):
|
42
|
+
if perm[i]>perm[j]:
|
43
|
+
ret[-1] += 1
|
44
|
+
return ret
|
45
|
+
|
46
|
+
def reversecode(perm):
|
47
|
+
ret = []
|
48
|
+
for i in range(len(perm)-1,0,-1):
|
49
|
+
ret = [0] + ret
|
50
|
+
for j in range(i,-1,-1):
|
51
|
+
if perm[i]>perm[j]:
|
52
|
+
ret[-1] += 1
|
53
|
+
return ret
|
54
|
+
|
55
|
+
def reverseuncode(cd):
|
56
|
+
cd2 = list(cd)
|
57
|
+
if cd2 == []:
|
58
|
+
return [1,2]
|
59
|
+
#max_required = max([cd2[i]+i for i in range(len(cd2))])
|
60
|
+
#cd2 += [0 for i in range(len(cd2),max_required)]
|
61
|
+
fullperm = [i+1 for i in range(len(cd2)+1)]
|
62
|
+
perm = []
|
63
|
+
for i in range(len(cd2)-1,0,-1):
|
64
|
+
perm = [fullperm[cd2[i]]] + perm
|
65
|
+
fullperm.pop(cd2[i])
|
66
|
+
perm += [fullperm[0]]
|
67
|
+
return perm
|
68
|
+
|
69
|
+
def inverse(perm):
|
70
|
+
retperm = [0 for i in range(len(perm))]
|
71
|
+
for i in range(len(perm)):
|
72
|
+
retperm[perm[i]-1] = i+1
|
73
|
+
return retperm
|
74
|
+
|
75
|
+
def permtrim(perm):
|
76
|
+
L = len(perm)
|
77
|
+
while L > 2 and perm[-1] == L:
|
78
|
+
L = perm.pop() - 1
|
79
|
+
return perm
|
80
|
+
|
81
|
+
def has_bruhat_descent(perm,i,j):
|
82
|
+
if perm[i]<perm[j]:
|
83
|
+
return False
|
84
|
+
for p in range(i+1,j):
|
85
|
+
if perm[i]>perm[p] and perm[p]>perm[j]:
|
86
|
+
return False
|
87
|
+
return True
|
88
|
+
|
89
|
+
def has_bruhat_ascent(perm,i,j):
|
90
|
+
if perm[i]>perm[j]:
|
91
|
+
return False
|
92
|
+
for p in range(i+1,j):
|
93
|
+
if perm[i]<perm[p] and perm[p]<perm[j]:
|
94
|
+
return False
|
95
|
+
return True
|
96
|
+
|
97
|
+
def elem_sym_perms(orig_perm,p,k):
|
98
|
+
total_list = [(orig_perm,0)]
|
99
|
+
up_perm_list = [(orig_perm,1000000000)]
|
100
|
+
for pp in range(p):
|
101
|
+
perm_list = []
|
102
|
+
for up_perm, last in up_perm_list:
|
103
|
+
up_perm2 = [*up_perm,len(up_perm)+1]
|
104
|
+
if len(up_perm2) < k + 1:
|
105
|
+
up_perm2 += [i+1 for i in range(len(up_perm2),k+2)]
|
106
|
+
pos_list = [i for i in range(k) if up_perm2[i] < last]
|
107
|
+
for j in range(k,len(up_perm2)):
|
108
|
+
if up_perm2[j]>=last:
|
109
|
+
continue
|
110
|
+
for i in pos_list:
|
111
|
+
if has_bruhat_ascent(up_perm2,i,j):
|
112
|
+
new_perm = [*up_perm2]
|
113
|
+
new_perm[i],new_perm[j] = new_perm[j],new_perm[i]
|
114
|
+
if new_perm[-1] == len(new_perm):
|
115
|
+
new_perm_add = tuple(new_perm[:-1])
|
116
|
+
else:
|
117
|
+
new_perm_add = tuple(new_perm)
|
118
|
+
perm_list += [(new_perm_add,up_perm2[j])]
|
119
|
+
total_list+=[(new_perm_add,pp+1)]
|
120
|
+
up_perm_list = perm_list
|
121
|
+
return total_list
|
122
|
+
|
123
|
+
# perms and inversion diff
|
124
|
+
def kdown_perms(perm,monoperm,p,k):
|
125
|
+
inv_m = inv(monoperm)
|
126
|
+
inv_p = inv(perm)
|
127
|
+
full_perm_list = []
|
128
|
+
|
129
|
+
if inv(mulperm(list(perm),monoperm)) == inv_m - inv_p:
|
130
|
+
full_perm_list+= [(tuple(perm),0,1)]
|
131
|
+
|
132
|
+
down_perm_list = [(perm,1)]
|
133
|
+
if len(perm)<k:
|
134
|
+
return full_perm_list
|
135
|
+
a2 = k-1
|
136
|
+
for pp in range(1,p+1):
|
137
|
+
down_perm_list2 = []
|
138
|
+
for perm2, s in down_perm_list:
|
139
|
+
L = len(perm2)
|
140
|
+
if L<k:
|
141
|
+
continue
|
142
|
+
s2 = -s
|
143
|
+
for b in chain(range(k-1),range(k,L)):
|
144
|
+
if perm2[b] != perm[b]:
|
145
|
+
continue
|
146
|
+
if b < a2:
|
147
|
+
i,j = b,a2
|
148
|
+
else:
|
149
|
+
i,j,s2 = a2,b,s
|
150
|
+
if has_bruhat_descent(perm2,i,j):
|
151
|
+
new_perm = [*perm2]
|
152
|
+
new_perm[a2],new_perm[b] = new_perm[b],new_perm[a2]
|
153
|
+
permtrim(new_perm)
|
154
|
+
down_perm_list2 += [(new_perm,s2)]
|
155
|
+
if inv(mulperm(new_perm,monoperm)) == inv_m - inv_p + pp:
|
156
|
+
full_perm_list += [(tuple(new_perm),pp,s2)]
|
157
|
+
down_perm_list = down_perm_list2
|
158
|
+
return full_perm_list
|
159
|
+
|
160
|
+
def compute_vpathdicts(th,vmu,smpify=False):
|
161
|
+
vpathdicts = [{} for index in range(len(th))]
|
162
|
+
vpathdicts[-1][tuple(vmu)] = None
|
163
|
+
S = sum(th)
|
164
|
+
thL = len(th)
|
165
|
+
th2 = [*th]
|
166
|
+
top = code(inverse(uncode(th)))
|
167
|
+
for i in range(thL-1,-1,-1):
|
168
|
+
top2 = code(inverse(uncode(top)))
|
169
|
+
while top2[-1]==0:
|
170
|
+
top2.pop()
|
171
|
+
top2.pop()
|
172
|
+
top = code(inverse(uncode(top2)))
|
173
|
+
monoperm = uncode(top)
|
174
|
+
if len(monoperm) < 2:
|
175
|
+
monoperm = [1,2]
|
176
|
+
k = i+1
|
177
|
+
for last_perm in vpathdicts[i]:
|
178
|
+
newperms = kdown_perms(last_perm,monoperm,th[i],k)
|
179
|
+
vpathdicts[i][last_perm]=newperms
|
180
|
+
if i>0:
|
181
|
+
for trip in newperms:
|
182
|
+
vpathdicts[i-1][trip[0]] = None
|
183
|
+
vpathdicts2 = [{} for i in range(len(th))]
|
184
|
+
for i in range(len(th)):
|
185
|
+
for key,valueset in vpathdicts[i].items():
|
186
|
+
for value in valueset:
|
187
|
+
key2 = value[0]
|
188
|
+
if key2 not in vpathdicts2[i]:
|
189
|
+
vpathdicts2[i][key2]=set()
|
190
|
+
v2 = value[2]
|
191
|
+
if smpify:
|
192
|
+
v2 = sympify(v2)
|
193
|
+
vpathdicts2[i][key2].add((key,value[1],v2))
|
194
|
+
#print(vpathdicts2)
|
195
|
+
return vpathdicts2
|
196
|
+
|
197
|
+
|
198
|
+
def theta(perm):
|
199
|
+
cd = code(perm)
|
200
|
+
for i in range(len(cd)-1,0,-1):
|
201
|
+
for j in range(i-1,-1,-1):
|
202
|
+
if cd[j] < cd[i]:
|
203
|
+
cd[i]+=1
|
204
|
+
cd.sort(reverse=True)
|
205
|
+
return cd
|
206
|
+
|
207
|
+
def add_perm_dict(d1,d2):
|
208
|
+
for k,v in d2.items():
|
209
|
+
d1[k] = d1.get(k,0)+v
|
210
|
+
return d1
|
211
|
+
|
212
|
+
zero = sympify(0)
|
213
|
+
one = sympify(1)
|
214
|
+
|
215
|
+
def elem_sym_poly(p,k,varl1,varl2,xstart=0,ystart=0):
|
216
|
+
global zero, one
|
217
|
+
if p>k:
|
218
|
+
return zero
|
219
|
+
if p == 0:
|
220
|
+
return one
|
221
|
+
if p == 1:
|
222
|
+
res = varl1[xstart] - varl2[ystart]
|
223
|
+
for i in range(1,k):
|
224
|
+
res += varl1[xstart+i] - varl2[ystart+i]
|
225
|
+
return res
|
226
|
+
if p == k:
|
227
|
+
res = (varl1[xstart] - varl2[ystart]) * (varl1[xstart+1] - varl2[ystart])
|
228
|
+
for i in range(2,k):
|
229
|
+
res *= (varl1[i+xstart] - varl2[ystart])
|
230
|
+
return res
|
231
|
+
mid = k//2
|
232
|
+
xsm = xstart + mid
|
233
|
+
ysm = ystart + mid
|
234
|
+
kmm = k - mid
|
235
|
+
res = elem_sym_poly(p,mid,varl1,varl2,xstart,ystart)+elem_sym_poly(p,kmm,varl1,varl2,xsm,ysm)
|
236
|
+
for p2 in range(max(1,p-kmm),min(p,mid+1)):
|
237
|
+
res += elem_sym_poly(p2,mid,varl1,varl2,xstart,ystart)*elem_sym_poly(p-p2,kmm,varl1,varl2,xsm,ysm-p2)
|
238
|
+
return res
|
239
|
+
|
240
|
+
@cache
|
241
|
+
def call_zvars(v1,v2,k,i):
|
242
|
+
v3 = [*v2]+[j for j in range(len(v2)+1,i+1)]
|
243
|
+
zvars = [v3[i-1]] + \
|
244
|
+
[v3[j] for j in range(len(v1),len(v3)) if v3[j]!=j+1 and j!=i-1] + \
|
245
|
+
[v3[j] for j in range(len(v1)) if v1[j]!=v3[j] and j!=i-1]
|
246
|
+
return zvars
|
247
|
+
|
248
|
+
def elem_sym_func(k,i,u1,u2,v1,v2,udiff,vdiff,varl1,varl2):
|
249
|
+
global zero, one
|
250
|
+
newk = k - udiff
|
251
|
+
if newk < vdiff:
|
252
|
+
return zero
|
253
|
+
if newk == vdiff:
|
254
|
+
return one
|
255
|
+
yvars = []
|
256
|
+
for j in range(min(len(u1),k)):
|
257
|
+
if u1[j]==u2[j]:
|
258
|
+
yvars += [varl1[u2[j]]]
|
259
|
+
for j in range(len(u1),min(k,len(u2))):
|
260
|
+
if u2[j]==j+1:
|
261
|
+
yvars += [varl1[u2[j]]]
|
262
|
+
for j in range(len(u2),k):
|
263
|
+
yvars += [varl1[j+1]]
|
264
|
+
zvars = [varl2[i] for i in call_zvars(v1,v2,k,i)]
|
265
|
+
return elem_sym_poly(newk-vdiff,newk,yvars,zvars)
|
266
|
+
|
267
|
+
def trimcode(perm):
|
268
|
+
cd = code(perm)
|
269
|
+
while len(cd)>0 and cd[-1] == 0:
|
270
|
+
cd.pop()
|
271
|
+
return cd
|
272
|
+
|
273
|
+
def p_trans(part):
|
274
|
+
newpart = []
|
275
|
+
if len(part)==0 or part[0]==0:
|
276
|
+
return [0]
|
277
|
+
for i in range(1,part[0]+1):
|
278
|
+
cnt = 0
|
279
|
+
for j in range(len(part)):
|
280
|
+
if part[j]>=i:
|
281
|
+
cnt += 1
|
282
|
+
if cnt == 0:
|
283
|
+
break
|
284
|
+
newpart += [cnt]
|
285
|
+
return newpart
|
286
|
+
|
287
|
+
def cycle(p,q):
|
288
|
+
return [i for i in range(1,p)] + [i+1 for i in range(p,p+q)] + [p]
|
289
|
+
|
290
|
+
def phi1(u):
|
291
|
+
c_star = code(inverse(u))
|
292
|
+
c_star.pop(0)
|
293
|
+
phi_u = inverse(uncode(c_star))
|
294
|
+
return phi_u
|
295
|
+
|
296
|
+
def one_dominates(u,w):
|
297
|
+
c_star_u = code(inverse(u))
|
298
|
+
c_star_w = code(inverse(w))
|
299
|
+
|
300
|
+
a = c_star_u[0]
|
301
|
+
b = c_star_w[0]
|
302
|
+
|
303
|
+
for i in range(a,b):
|
304
|
+
if i>=len(u)-1:
|
305
|
+
return True
|
306
|
+
if u[i]>u[i+1]:
|
307
|
+
return False
|
308
|
+
return True
|
309
|
+
|
310
|
+
def dominates(u,w):
|
311
|
+
u2 = [*u]
|
312
|
+
w2 = [*w]
|
313
|
+
while u2 != [1,2] and one_dominates(u2,w2):
|
314
|
+
u2 = phi1(u2)
|
315
|
+
w2 = phi1(w2)
|
316
|
+
if u2 == [1,2]:
|
317
|
+
return True
|
318
|
+
return False
|
319
|
+
|
320
|
+
def reduce_coeff(u,v,w):
|
321
|
+
t_mu_u_t = theta(inverse(u))
|
322
|
+
t_mu_v_t = theta(inverse(v))
|
323
|
+
|
324
|
+
mu_u_inv = uncode(t_mu_u_t)
|
325
|
+
mu_v_inv = uncode(t_mu_v_t)
|
326
|
+
|
327
|
+
t_mu_u = p_trans(t_mu_u_t)
|
328
|
+
t_mu_v = p_trans(t_mu_v_t)
|
329
|
+
|
330
|
+
t_mu_u += [0 for i in range(len(t_mu_u),max(len(t_mu_u),len(t_mu_v)))]
|
331
|
+
t_mu_v += [0 for i in range(len(t_mu_v),max(len(t_mu_u),len(t_mu_v)))]
|
332
|
+
|
333
|
+
t_mu_uv = [t_mu_u[i] + t_mu_v[i] for i in range(len(t_mu_u))]
|
334
|
+
t_mu_uv_t = p_trans(t_mu_uv)
|
335
|
+
|
336
|
+
mu_uv_inv = uncode(t_mu_uv_t)
|
337
|
+
|
338
|
+
if inv(mulperm(list(w),mu_uv_inv)) != inv(mu_uv_inv) - inv(w):
|
339
|
+
return u, v, w
|
340
|
+
|
341
|
+
umu = mulperm(list(u),mu_u_inv)
|
342
|
+
vmu = mulperm(list(v),mu_v_inv)
|
343
|
+
wmu = mulperm(list(w),mu_uv_inv)
|
344
|
+
|
345
|
+
t_mu_w = theta(inverse(wmu))
|
346
|
+
|
347
|
+
mu_w = uncode(t_mu_w)
|
348
|
+
|
349
|
+
w_prime = mulperm(wmu,mu_w)
|
350
|
+
|
351
|
+
if permtrim(list(w)) == permtrim(w_prime):
|
352
|
+
return (permtrim(list(u)),permtrim(list(v)),permtrim(list(w)))
|
353
|
+
|
354
|
+
A = []
|
355
|
+
B = []
|
356
|
+
indexA = 0
|
357
|
+
|
358
|
+
while len(t_mu_u_t)>0 and t_mu_u_t[-1] == 0:
|
359
|
+
t_mu_u_t.pop()
|
360
|
+
|
361
|
+
while len(t_mu_v_t)>0 and t_mu_v_t[-1] == 0:
|
362
|
+
t_mu_v_t.pop()
|
363
|
+
|
364
|
+
while len(t_mu_uv_t)>0 and t_mu_uv_t[-1] == 0:
|
365
|
+
t_mu_uv_t.pop()
|
366
|
+
|
367
|
+
for index in range(len(t_mu_uv_t)):
|
368
|
+
if indexA<len(t_mu_u_t) and t_mu_uv_t[index] == t_mu_u_t[indexA]:
|
369
|
+
A += [index]
|
370
|
+
indexA+=1
|
371
|
+
else:
|
372
|
+
B += [index]
|
373
|
+
|
374
|
+
mu_w_A = uncode(mu_A(code(mu_w),A))
|
375
|
+
mu_w_B = uncode(mu_A(code(mu_w),B))
|
376
|
+
|
377
|
+
return (permtrim(mulperm(umu,mu_w_A)),permtrim(mulperm(vmu,mu_w_B)),permtrim(w_prime))
|
378
|
+
|
379
|
+
def mu_A(mu,A):
|
380
|
+
mu_t = p_trans(mu)
|
381
|
+
mu_A_t = []
|
382
|
+
for i in range(len(A)):
|
383
|
+
if A[i]<len(mu_t):
|
384
|
+
mu_A_t += [mu_t[A[i]]]
|
385
|
+
return p_trans(mu_A_t)
|
386
|
+
|
387
|
+
def reduce_descents(u,v,w):
|
388
|
+
u2 = [*u]
|
389
|
+
v2 = [*v]
|
390
|
+
w2 = [*w]
|
391
|
+
found_one = True
|
392
|
+
while found_one:
|
393
|
+
found_one = False
|
394
|
+
if will_formula_work(u2,v2) or will_formula_work(v2,u2) or one_dominates(u2,w2) or is_reducible(v2) or inv(w2) - inv(u2) == 1:
|
395
|
+
break
|
396
|
+
for i in range(len(w2)-2,-1,-1):
|
397
|
+
if w2[i]>w2[i+1] and i<len(v2)-1 and v2[i]>v2[i+1] and (i>=len(u2)-1 or u2[i]<u2[i+1]):
|
398
|
+
w2[i], w2[i+1] = w2[i+1], w2[i]
|
399
|
+
v2[i], v2[i+1] = v2[i+1], v2[i]
|
400
|
+
found_one = True
|
401
|
+
elif w2[i]>w2[i+1] and i<len(u2)-1 and u2[i]>u2[i+1] and (i>=len(v2)-1 or v2[i]<v2[i+1]):
|
402
|
+
w2[i], w2[i+1] = w2[i+1], w2[i]
|
403
|
+
u2[i], u2[i+1] = u2[i+1], u2[i]
|
404
|
+
found_one = True
|
405
|
+
if found_one:
|
406
|
+
break
|
407
|
+
return permtrim(u2), permtrim(v2), permtrim(w2)
|
408
|
+
|
409
|
+
def is_reducible(v):
|
410
|
+
c03 = code(v)
|
411
|
+
found0 = False
|
412
|
+
good = True
|
413
|
+
for i in range(len(c03)):
|
414
|
+
if c03[i] == 0:
|
415
|
+
found0 = True
|
416
|
+
elif c03[i] != 0 and found0 == True:
|
417
|
+
good = False
|
418
|
+
break
|
419
|
+
return good
|
420
|
+
|
421
|
+
def try_reduce_v(u, v, w):
|
422
|
+
if is_reducible(v):
|
423
|
+
return tuple(permtrim([*u])), tuple(permtrim([*v])), tuple(permtrim([*w]))
|
424
|
+
u2 = [*u]
|
425
|
+
v2 = [*v]
|
426
|
+
w2 = [*w]
|
427
|
+
cv = code(v2)
|
428
|
+
for i in range(len(v2)-2,-1,-1):
|
429
|
+
if cv[i] == 0 and i<len(cv)-1 and cv[i+1] != 0:
|
430
|
+
if i>=len(u2)-1 or u2[i] < u2[i+1]:
|
431
|
+
v2[i], v2[i+1] = v2[i+1], v2[i]
|
432
|
+
if i>=len(w2)-1:
|
433
|
+
w2 += [j for j in range(len(w2)+1,i+3)]
|
434
|
+
w2[i+1], w2[i] = w2[i], w2[i+1]
|
435
|
+
if is_reducible(v2):
|
436
|
+
return tuple(permtrim(u2)), tuple(permtrim(v2)), tuple(permtrim(w2))
|
437
|
+
else:
|
438
|
+
return try_reduce_v(u2,v2,w2)
|
439
|
+
elif i<len(w2)-1 and w2[i]>w2[i+1]:
|
440
|
+
u2[i], u2[i+1] = u2[i+1], u2[i]
|
441
|
+
v2[i], v2[i+1] = v2[i+1], v2[i]
|
442
|
+
return try_reduce_v(u2, v2, w2)
|
443
|
+
else:
|
444
|
+
return tuple(permtrim(u2)), tuple(permtrim(v2)), tuple(permtrim(w2))
|
445
|
+
return tuple(permtrim(u2)), tuple(permtrim(v2)), tuple(permtrim(w2))
|
446
|
+
|
447
|
+
def try_reduce_u(u, v, w):
|
448
|
+
if one_dominates(u,w):
|
449
|
+
return u, v, w
|
450
|
+
u2 = [*u]
|
451
|
+
v2 = [*v]
|
452
|
+
w2 = [*w]
|
453
|
+
cu = code(u)
|
454
|
+
for i in range(len(u2)-2,-1,-1):
|
455
|
+
if cu[i] == 0 and i<len(cu)-1 and cu[i+1] != 0:
|
456
|
+
if i>=len(v2)-1 or v2[i] < v2[i+1]:
|
457
|
+
u2[i], u2[i+1] = u2[i+1], u2[i]
|
458
|
+
if i>len(w2)-1:
|
459
|
+
w2 += [j for j in range(len(w2)+1,i+3)]
|
460
|
+
w2[i+1], w2[i] = w2[i], w2[i+1]
|
461
|
+
if one_dominates(u,w):
|
462
|
+
return tuple(permtrim(u2)), tuple(permtrim(v2)), tuple(permtrim(w2))
|
463
|
+
else:
|
464
|
+
return try_reduce_u(u2,v2,w2)
|
465
|
+
elif i<len(w2)-1 and w2[i]>w2[i+1]:
|
466
|
+
u2[i], u2[i+1] = u2[i+1], u2[i]
|
467
|
+
v2[i], v2[i+1] = v2[i+1], v2[i]
|
468
|
+
return try_reduce_u(u2, v2, w2)
|
469
|
+
else:
|
470
|
+
return tuple(permtrim(u2)), tuple(permtrim(v2)), tuple(permtrim(w2))
|
471
|
+
return tuple(permtrim(u2)), tuple(permtrim(v2)), tuple(permtrim(w2))
|
472
|
+
|
473
|
+
def pull_out_var(vnum,v):
|
474
|
+
vn1 = inverse(v)
|
475
|
+
th = theta(vn1)
|
476
|
+
if th[0]==0:
|
477
|
+
return [[[],v]]
|
478
|
+
muvn1 = permtrim(uncode(th))
|
479
|
+
lm = p_trans(th)
|
480
|
+
if vnum>len(lm):
|
481
|
+
return [[[],v]]
|
482
|
+
lmpop = [*lm]
|
483
|
+
k = lmpop.pop(vnum-1)
|
484
|
+
inv_v = inv(v)
|
485
|
+
vmuvn1 = mulperm(v,muvn1)
|
486
|
+
muvn1in1 = permtrim(uncode(lmpop))
|
487
|
+
ret_list = []
|
488
|
+
vpm_list = [(vmuvn1,k)]
|
489
|
+
for p in range(k+1):
|
490
|
+
vpm_list2 = []
|
491
|
+
for vpm, b in vpm_list:
|
492
|
+
vp = permtrim(mulperm(vpm,muvn1in1))
|
493
|
+
|
494
|
+
pos_list = [i for i in range(k) if ((i<len(vpm) and vmuvn1[i] == vpm[i]) or (i>=len(vpm) and vmuvn1[i] == i+1))]
|
495
|
+
if inv(vp)==inv_v-k+p:
|
496
|
+
ret_list += [[[vpm[i] for i in pos_list if i<len(vpm)]+[i+1 for i in pos_list if i>=len(vpm) and vmuvn1[i] == i+1],vp]]
|
497
|
+
if len(vpm) < k + 1:
|
498
|
+
continue
|
499
|
+
for j in range(b,len(vpm)):
|
500
|
+
for i in pos_list:
|
501
|
+
if has_bruhat_descent(vpm,i,j):
|
502
|
+
vpm[i],vpm[j] = vpm[j],vpm[i]
|
503
|
+
vpm_list2+=[(permtrim([*vpm]),j)]
|
504
|
+
vpm[i],vpm[j] = vpm[j],vpm[i]
|
505
|
+
vpm_list = vpm_list2
|
506
|
+
return ret_list
|
507
|
+
|
508
|
+
def divdiffable(v,u):
|
509
|
+
inv_v = inv(v)
|
510
|
+
inv_u = inv(u)
|
511
|
+
perm2 = permtrim(mulperm(v,inverse(u)))
|
512
|
+
if inv(perm2) != inv_v - inv_u:
|
513
|
+
return []
|
514
|
+
return perm2
|
515
|
+
|
516
|
+
def will_formula_work(u,v):
|
517
|
+
muv = uncode(theta(v))
|
518
|
+
vn1muv = mulperm(inverse(v),muv)
|
519
|
+
while True:
|
520
|
+
found_one = False
|
521
|
+
for i in range(len(vn1muv)-1):
|
522
|
+
if vn1muv[i]>vn1muv[i+1]:
|
523
|
+
found_one = True
|
524
|
+
if i<len(u)-1 and u[i]>u[i+1]:
|
525
|
+
return False
|
526
|
+
else:
|
527
|
+
vn1muv[i],vn1muv[i+1] = vn1muv[i+1],vn1muv[i]
|
528
|
+
break
|
529
|
+
if not found_one:
|
530
|
+
return True
|
@@ -0,0 +1,162 @@
|
|
1
|
+
from symengine import *
|
2
|
+
from functools import cache
|
3
|
+
from itertools import chain
|
4
|
+
from schubmult.perm_lib import *
|
5
|
+
from schubmult.schubmult_yz import schubmult
|
6
|
+
import sys
|
7
|
+
|
8
|
+
n = 100
|
9
|
+
|
10
|
+
var = symarray('x', n)
|
11
|
+
var2 = symarray('y',n)
|
12
|
+
var3 = var2
|
13
|
+
var_r = symarray('r',n)
|
14
|
+
|
15
|
+
subs_dict = {}
|
16
|
+
|
17
|
+
for i in range(1,n):
|
18
|
+
sm = var_r[0]
|
19
|
+
for j in range(1,i):
|
20
|
+
sm += var_r[j]
|
21
|
+
subs_dict[var2[i]] = sm
|
22
|
+
|
23
|
+
def main():
|
24
|
+
try:
|
25
|
+
perms=[]
|
26
|
+
curperm = []
|
27
|
+
|
28
|
+
pr = True
|
29
|
+
ascode = False
|
30
|
+
coprod = False
|
31
|
+
try:
|
32
|
+
for s in sys.argv[1:]:
|
33
|
+
if s == "-np" or s == "--no-print":
|
34
|
+
pr = False
|
35
|
+
continue
|
36
|
+
if s == "-code":
|
37
|
+
ascode = True
|
38
|
+
continue
|
39
|
+
if s == "-coprod":
|
40
|
+
coprod = True
|
41
|
+
continue
|
42
|
+
if s == "-":
|
43
|
+
perms += [curperm]
|
44
|
+
curperm = []
|
45
|
+
continue
|
46
|
+
curperm += [int(s)]
|
47
|
+
except Exception:
|
48
|
+
print("Usage: schubmult_double <-np|--no-print> <-code> perm1 - perm2 < - perm 3 ... >")
|
49
|
+
print("Alternative usage: schubmult_double <-code> -coprod perm - indexlist")
|
50
|
+
exit(1)
|
51
|
+
|
52
|
+
perms += [curperm]
|
53
|
+
|
54
|
+
if coprod:
|
55
|
+
subs_dict_coprod = {}
|
56
|
+
if ascode:
|
57
|
+
mperm = tuple(permtrim(uncode(perms[0])))
|
58
|
+
else:
|
59
|
+
mperm = tuple(permtrim(perms[0]))
|
60
|
+
|
61
|
+
cd = code(mperm)
|
62
|
+
perms[0] = mperm
|
63
|
+
pos = perms[1]
|
64
|
+
|
65
|
+
while cd[-1] == 0:
|
66
|
+
cd.pop()
|
67
|
+
k = len(pos)
|
68
|
+
n = len(perms[0])
|
69
|
+
kcd = [pos[i]-i-1 for i in range(len(pos))] + [n+1-k for i in range(k,n)]
|
70
|
+
N = len(kcd)
|
71
|
+
|
72
|
+
for i in range(1,100):
|
73
|
+
if i<=N:
|
74
|
+
subs_dict_coprod[var[i]] = var2[i]
|
75
|
+
else:
|
76
|
+
subs_dict_coprod[var[i]] = var2[i-N]
|
77
|
+
|
78
|
+
kperm = inverse(uncode(kcd))
|
79
|
+
coeff_dict = {tuple(kperm): 1}
|
80
|
+
coeff_dict = schubmult(coeff_dict,perms[0],var,var2)
|
81
|
+
|
82
|
+
inv_perm0 = inv(perms[0])
|
83
|
+
inv_kperm = inv(kperm)
|
84
|
+
inverse_kperm = inverse(kperm)
|
85
|
+
if pr:
|
86
|
+
coeff_perms = list(coeff_dict.keys())
|
87
|
+
coeff_perms.sort(key=lambda x: (inv(x),*x))
|
88
|
+
|
89
|
+
perm_pairs = []
|
90
|
+
|
91
|
+
for perm in coeff_perms:
|
92
|
+
downperm = mulperm(list(perm),inverse_kperm)
|
93
|
+
if inv(downperm) == inv(perm) - inv_kperm:
|
94
|
+
flag = True
|
95
|
+
for i in range(N):
|
96
|
+
if downperm[i] > N:
|
97
|
+
flag = False
|
98
|
+
break
|
99
|
+
if not flag:
|
100
|
+
continue
|
101
|
+
firstperm = downperm[0:N]
|
102
|
+
secondperm = [downperm[i]-N for i in range(N,len(downperm))]
|
103
|
+
perm_pairs += [[permtrim(firstperm),permtrim(secondperm)]]
|
104
|
+
|
105
|
+
if ascode:
|
106
|
+
width = max([len(str(trimcode(perm[0]))+" "+str(trimcode(perm[1]))) for perm in perm_pairs])
|
107
|
+
else:
|
108
|
+
width = max([len(str(perm[0])+" "+str(perm[1])) for perm in perm_pairs])
|
109
|
+
|
110
|
+
for perm in coeff_perms:
|
111
|
+
val = coeff_dict[perm]
|
112
|
+
downperm = mulperm(list(perm),inverse_kperm)
|
113
|
+
if inv(downperm) == inv(perm) - inv_kperm:
|
114
|
+
flag = True
|
115
|
+
for i in range(N):
|
116
|
+
if downperm[i] > N:
|
117
|
+
flag = False
|
118
|
+
break
|
119
|
+
if not flag:
|
120
|
+
continue
|
121
|
+
firstperm = downperm[0:N]
|
122
|
+
secondperm = [downperm[i]-N for i in range(N,len(downperm))]
|
123
|
+
val = sympify(val).subs(subs_dict_coprod)
|
124
|
+
val = sympify(val).subs(subs_dict).expand()
|
125
|
+
if val != 0:
|
126
|
+
if not ascode:
|
127
|
+
width2 = width - len(str(permtrim(firstperm))) - len(str(permtrim(secondperm)))
|
128
|
+
print(f"{tuple(permtrim(firstperm))}{' ':>{width2}}{tuple(permtrim(secondperm))} {str(val).replace('**','^').replace('*',' ')}")
|
129
|
+
else:
|
130
|
+
width2 = width - len(str(trimcode(firstperm))) - len(str(trimcode(secondperm)))
|
131
|
+
print(f"{trimcode(firstperm)}{' ':>{width2}}{trimcode(secondperm)} {str(val).replace('**','^').replace('*',' ')}")
|
132
|
+
else:
|
133
|
+
if ascode:
|
134
|
+
for i in range(len(perms)):
|
135
|
+
perms[i] = uncode(perms[i])
|
136
|
+
|
137
|
+
coeff_dict = {tuple(permtrim([*perms[0]])): 1}
|
138
|
+
|
139
|
+
for perm in perms[1:]:
|
140
|
+
coeff_dict = schubmult(coeff_dict,tuple(permtrim([*perm])),var2,var2)
|
141
|
+
|
142
|
+
if pr:
|
143
|
+
if ascode:
|
144
|
+
width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys()])
|
145
|
+
else:
|
146
|
+
width = max([len(str(perm)) for perm in coeff_dict.keys()])
|
147
|
+
|
148
|
+
coeff_perms = list(coeff_dict.keys())
|
149
|
+
coeff_perms.sort(key=lambda x: (inv(x),*x))
|
150
|
+
|
151
|
+
for perm in coeff_perms:
|
152
|
+
val = sympify(coeff_dict[perm]).subs(subs_dict).expand()
|
153
|
+
if val != 0:
|
154
|
+
if ascode:
|
155
|
+
print(f"{str(trimcode(perm)):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
156
|
+
else:
|
157
|
+
print(f"{str(perm):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
158
|
+
except BrokenPipeError:
|
159
|
+
pass
|
160
|
+
|
161
|
+
if __name__ == "__main__":
|
162
|
+
main()
|