schubmult 2.0.0__py3-none-any.whl
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/__init__.py +1 -0
- schubmult/_base_argparse.py +174 -0
- schubmult/perm_lib.py +999 -0
- schubmult/sage_integration/__init__.py +25 -0
- schubmult/sage_integration/_fast_double_schubert_polynomial_ring.py +528 -0
- schubmult/sage_integration/_fast_schubert_polynomial_ring.py +356 -0
- schubmult/sage_integration/_indexing.py +44 -0
- schubmult/schubmult_double/__init__.py +18 -0
- schubmult/schubmult_double/__main__.py +5 -0
- schubmult/schubmult_double/_funcs.py +1590 -0
- schubmult/schubmult_double/_script.py +407 -0
- schubmult/schubmult_double/_vars.py +16 -0
- schubmult/schubmult_py/__init__.py +10 -0
- schubmult/schubmult_py/__main__.py +5 -0
- schubmult/schubmult_py/_funcs.py +111 -0
- schubmult/schubmult_py/_script.py +115 -0
- schubmult/schubmult_py/_vars.py +3 -0
- schubmult/schubmult_q/__init__.py +12 -0
- schubmult/schubmult_q/__main__.py +5 -0
- schubmult/schubmult_q/_funcs.py +304 -0
- schubmult/schubmult_q/_script.py +157 -0
- schubmult/schubmult_q/_vars.py +18 -0
- schubmult/schubmult_q_double/__init__.py +14 -0
- schubmult/schubmult_q_double/__main__.py +5 -0
- schubmult/schubmult_q_double/_funcs.py +507 -0
- schubmult/schubmult_q_double/_script.py +337 -0
- schubmult/schubmult_q_double/_vars.py +21 -0
- schubmult-2.0.0.dist-info/METADATA +455 -0
- schubmult-2.0.0.dist-info/RECORD +36 -0
- schubmult-2.0.0.dist-info/WHEEL +5 -0
- schubmult-2.0.0.dist-info/entry_points.txt +5 -0
- schubmult-2.0.0.dist-info/licenses/LICENSE +674 -0
- schubmult-2.0.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/test_fast_double_schubert.py +145 -0
- tests/test_fast_schubert.py +38 -0
@@ -0,0 +1,407 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import sympy
|
3
|
+
import sys
|
4
|
+
from ._vars import (
|
5
|
+
var2,
|
6
|
+
var3,
|
7
|
+
var_x,
|
8
|
+
var,
|
9
|
+
)
|
10
|
+
from ._funcs import (
|
11
|
+
mult_poly,
|
12
|
+
mult_poly_down,
|
13
|
+
schubmult,
|
14
|
+
schubmult_down,
|
15
|
+
compute_positive_rep,
|
16
|
+
posify,
|
17
|
+
split_perms,
|
18
|
+
)
|
19
|
+
from symengine import symarray, expand, sympify
|
20
|
+
from schubmult._base_argparse import schub_argparse
|
21
|
+
from schubmult.perm_lib import (
|
22
|
+
add_perm_dict,
|
23
|
+
inverse,
|
24
|
+
theta,
|
25
|
+
permtrim,
|
26
|
+
inv,
|
27
|
+
mulperm,
|
28
|
+
code,
|
29
|
+
uncode,
|
30
|
+
will_formula_work,
|
31
|
+
mu_A,
|
32
|
+
trimcode,
|
33
|
+
)
|
34
|
+
|
35
|
+
|
36
|
+
def _display(val):
|
37
|
+
print(val)
|
38
|
+
|
39
|
+
|
40
|
+
def _display_full(
|
41
|
+
coeff_dict,
|
42
|
+
args,
|
43
|
+
formatter,
|
44
|
+
posified=None,
|
45
|
+
check_coeff_dict=None,
|
46
|
+
kperm=None,
|
47
|
+
var2=var2,
|
48
|
+
var3=var3,
|
49
|
+
N=None,
|
50
|
+
):
|
51
|
+
perms = args.perms
|
52
|
+
mult = args.mult
|
53
|
+
ascode = args.ascode
|
54
|
+
coprod = args.coprod
|
55
|
+
check = args.check
|
56
|
+
msg = args.msg
|
57
|
+
down = args.down
|
58
|
+
same = args.same
|
59
|
+
display_positive = args.display_positive
|
60
|
+
|
61
|
+
coeff_perms = list(coeff_dict.keys())
|
62
|
+
if coprod:
|
63
|
+
pos = perms[1]
|
64
|
+
pos2 = []
|
65
|
+
last_descent = -1
|
66
|
+
poso = []
|
67
|
+
for i in range(len(perms[0]) - 1):
|
68
|
+
if perms[0][i] > perms[0][i + 1]:
|
69
|
+
last_descent = i + 1
|
70
|
+
for i in range(1, last_descent + 1):
|
71
|
+
if i not in pos:
|
72
|
+
pos2 += [i - 1]
|
73
|
+
else:
|
74
|
+
poso += [i - 1]
|
75
|
+
|
76
|
+
mu_W = uncode(theta(inverse(perms[0])))
|
77
|
+
|
78
|
+
the_top_perm = tuple(permtrim(mulperm(list(perms[0]), mu_W)))
|
79
|
+
|
80
|
+
muA = uncode(mu_A(code(mu_W), poso))
|
81
|
+
muB = uncode(mu_A(code(mu_W), pos2))
|
82
|
+
subs_dict = {}
|
83
|
+
inv_kperm = inv(kperm)
|
84
|
+
inverse_kperm = inverse(kperm)
|
85
|
+
var2neg = np.array([-var2[i] for i in range(len(var2))])
|
86
|
+
var3neg = np.array([-var3[i] for i in range(len(var3))])
|
87
|
+
|
88
|
+
for i in range(1, 100):
|
89
|
+
if i <= N:
|
90
|
+
subs_dict[var[i]] = var2[i]
|
91
|
+
else:
|
92
|
+
subs_dict[var[i]] = var3[i - N]
|
93
|
+
|
94
|
+
coeff_perms.sort(key=lambda x: (inv(x), *x))
|
95
|
+
|
96
|
+
perm_pairs = []
|
97
|
+
|
98
|
+
for perm in coeff_perms:
|
99
|
+
downperm = mulperm(list(perm), inverse_kperm)
|
100
|
+
if inv(downperm) == inv(perm) - inv_kperm:
|
101
|
+
flag = True
|
102
|
+
for i in range(N):
|
103
|
+
if downperm[i] > N:
|
104
|
+
flag = False
|
105
|
+
break
|
106
|
+
if not flag:
|
107
|
+
continue
|
108
|
+
firstperm = downperm[0:N]
|
109
|
+
secondperm = [downperm[i] - N for i in range(N, len(downperm))]
|
110
|
+
perm_pairs += [[permtrim(firstperm), permtrim(secondperm)]]
|
111
|
+
|
112
|
+
if ascode:
|
113
|
+
width = max(
|
114
|
+
[len(str(trimcode(perm[0])) + " " + str(trimcode(perm[1]))) for perm in perm_pairs]
|
115
|
+
)
|
116
|
+
else:
|
117
|
+
width = max([len(str(perm[0]) + " " + str(perm[1])) for perm in perm_pairs])
|
118
|
+
|
119
|
+
for perm in coeff_perms:
|
120
|
+
val = coeff_dict[perm]
|
121
|
+
downperm = mulperm(list(perm), inverse_kperm)
|
122
|
+
if inv(downperm) == inv(perm) - inv_kperm:
|
123
|
+
flag = True
|
124
|
+
for i in range(N):
|
125
|
+
if downperm[i] > N:
|
126
|
+
flag = False
|
127
|
+
break
|
128
|
+
if not flag:
|
129
|
+
continue
|
130
|
+
firstperm = downperm[0:N]
|
131
|
+
secondperm = [downperm[i] - N for i in range(N, len(downperm))]
|
132
|
+
val = sympify(val).subs(subs_dict)
|
133
|
+
|
134
|
+
if val != 0:
|
135
|
+
if display_positive and not same:
|
136
|
+
if val != 0:
|
137
|
+
val2 = posify(
|
138
|
+
val,
|
139
|
+
tuple(permtrim(mulperm(firstperm, muA))),
|
140
|
+
tuple(permtrim(mulperm(secondperm, muB))),
|
141
|
+
the_top_perm,
|
142
|
+
tuple(var2neg.tolist()),
|
143
|
+
tuple(var3neg.tolist()),
|
144
|
+
msg,
|
145
|
+
False,
|
146
|
+
)
|
147
|
+
if expand(val - val2) != 0:
|
148
|
+
_display(
|
149
|
+
f"error; write to schubmult@gmail.com with the case {perms=}\n{code(firstperm)=} {code(secondperm)=}\n{val2=}\n{val=}"
|
150
|
+
)
|
151
|
+
_display(
|
152
|
+
f"{code(tuple(permtrim(mulperm(firstperm,muA))))=},{code(tuple(permtrim(mulperm(secondperm,muB))))=},{code(the_top_perm)=}\n{expand(val-val2)=}"
|
153
|
+
)
|
154
|
+
exit(1)
|
155
|
+
val = val2
|
156
|
+
else:
|
157
|
+
val = 0
|
158
|
+
if val != 0:
|
159
|
+
if not ascode:
|
160
|
+
width2 = (
|
161
|
+
width
|
162
|
+
- len(str(permtrim(firstperm)))
|
163
|
+
- len(str(permtrim(secondperm)))
|
164
|
+
)
|
165
|
+
_display(
|
166
|
+
f"{tuple(permtrim(firstperm))}{' ':>{width2}}{tuple(permtrim(secondperm))} {formatter(val)}"
|
167
|
+
)
|
168
|
+
else:
|
169
|
+
width2 = (
|
170
|
+
width
|
171
|
+
- len(str(trimcode(firstperm)))
|
172
|
+
- len(str(trimcode(secondperm)))
|
173
|
+
)
|
174
|
+
_display(
|
175
|
+
f"{trimcode(firstperm)}{' ':>{width2}}{trimcode(secondperm)} {formatter(val)}"
|
176
|
+
)
|
177
|
+
else:
|
178
|
+
if ascode:
|
179
|
+
width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys()])
|
180
|
+
else:
|
181
|
+
width = max([len(str(perm)) for perm in coeff_dict.keys()])
|
182
|
+
|
183
|
+
coeff_perms = list(coeff_dict.keys())
|
184
|
+
coeff_perms.sort(key=lambda x: (inv(x), *x))
|
185
|
+
|
186
|
+
var_r = symarray("r", 100)
|
187
|
+
for perm in coeff_perms:
|
188
|
+
val = coeff_dict[perm]
|
189
|
+
if val != 0:
|
190
|
+
notint = False
|
191
|
+
try:
|
192
|
+
int(val)
|
193
|
+
except Exception:
|
194
|
+
notint = True
|
195
|
+
if notint and display_positive:
|
196
|
+
if same:
|
197
|
+
subs_dict = {}
|
198
|
+
for i in range(1, 100):
|
199
|
+
sm = var2[1]
|
200
|
+
for j in range(1, i):
|
201
|
+
sm += var_r[j]
|
202
|
+
subs_dict[var2[i]] = sm
|
203
|
+
val = expand(sympify(coeff_dict[perm]).xreplace(subs_dict))
|
204
|
+
else:
|
205
|
+
try:
|
206
|
+
if len(perms) == 2 and not posified and not mult:
|
207
|
+
if not down:
|
208
|
+
val = posify(
|
209
|
+
val,
|
210
|
+
perms[0],
|
211
|
+
perms[1],
|
212
|
+
perm,
|
213
|
+
var2,
|
214
|
+
var3,
|
215
|
+
msg,
|
216
|
+
)
|
217
|
+
else:
|
218
|
+
val = posify(
|
219
|
+
val,
|
220
|
+
perm,
|
221
|
+
perms[1],
|
222
|
+
perms[0],
|
223
|
+
var2,
|
224
|
+
var3,
|
225
|
+
msg,
|
226
|
+
)
|
227
|
+
elif not posified and not mult:
|
228
|
+
val = compute_positive_rep(val, var2, var3, msg)
|
229
|
+
elif not posified:
|
230
|
+
val = compute_positive_rep(val, var2, var3, msg, do_pos_neg=False)
|
231
|
+
except Exception:
|
232
|
+
if mult:
|
233
|
+
_display(
|
234
|
+
"warning; --display-positive is on but result is not positive",
|
235
|
+
file=sys.stderr,
|
236
|
+
)
|
237
|
+
else:
|
238
|
+
_display(
|
239
|
+
f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_coeff_dict.get(perm,0)=}"
|
240
|
+
)
|
241
|
+
exit(1)
|
242
|
+
if check and expand(val - check_coeff_dict.get(perm, 0)) != 0:
|
243
|
+
_display(
|
244
|
+
f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_coeff_dict.get(perm,0)=}"
|
245
|
+
)
|
246
|
+
exit(1)
|
247
|
+
if val != 0:
|
248
|
+
if ascode:
|
249
|
+
_display(f"{str(trimcode(perm)):>{width}} {formatter(val)}")
|
250
|
+
else:
|
251
|
+
_display(f"{str(perm):>{width}} {formatter(val)}")
|
252
|
+
|
253
|
+
|
254
|
+
def main():
|
255
|
+
global var2, var3
|
256
|
+
try:
|
257
|
+
sys.setrecursionlimit(1000000)
|
258
|
+
|
259
|
+
# TEMP
|
260
|
+
sympy.init_printing()
|
261
|
+
|
262
|
+
args, formatter = schub_argparse(
|
263
|
+
"schubmult_double",
|
264
|
+
"Compute coefficients of product of double Schubert polynomials in the same or different sets of coefficient variables",
|
265
|
+
yz=True,
|
266
|
+
)
|
267
|
+
|
268
|
+
mult = args.mult
|
269
|
+
mulstring = args.mulstring
|
270
|
+
|
271
|
+
perms = args.perms
|
272
|
+
|
273
|
+
ascode = args.ascode
|
274
|
+
coprod = args.coprod
|
275
|
+
same = args.same
|
276
|
+
msg = args.msg
|
277
|
+
down = args.down
|
278
|
+
display_positive = args.display_positive
|
279
|
+
pr = args.pr
|
280
|
+
|
281
|
+
if same:
|
282
|
+
var3 = var2
|
283
|
+
|
284
|
+
posified = False
|
285
|
+
if coprod:
|
286
|
+
if ascode:
|
287
|
+
mperm = tuple(permtrim(uncode(perms[0])))
|
288
|
+
else:
|
289
|
+
mperm = tuple(permtrim(perms[0]))
|
290
|
+
|
291
|
+
perms[0] = mperm
|
292
|
+
pos = perms[1]
|
293
|
+
|
294
|
+
k = len(pos)
|
295
|
+
n = len(perms[0])
|
296
|
+
kcd = [pos[i] - i - 1 for i in range(len(pos))] + [n + 1 - k for i in range(k, n)]
|
297
|
+
N = len(kcd)
|
298
|
+
|
299
|
+
kperm = inverse(uncode(kcd))
|
300
|
+
coeff_dict = {tuple(kperm): 1}
|
301
|
+
coeff_dict = schubmult(coeff_dict, perms[0], var, var2)
|
302
|
+
|
303
|
+
if pr:
|
304
|
+
_display_full(
|
305
|
+
coeff_dict,
|
306
|
+
args,
|
307
|
+
formatter,
|
308
|
+
posified=posified,
|
309
|
+
kperm=kperm,
|
310
|
+
var2=var2,
|
311
|
+
var3=var3,
|
312
|
+
N=N,
|
313
|
+
)
|
314
|
+
else:
|
315
|
+
if ascode:
|
316
|
+
for i in range(len(perms)):
|
317
|
+
perms[i] = tuple(permtrim(uncode(perms[i])))
|
318
|
+
else:
|
319
|
+
for i in range(len(perms)):
|
320
|
+
if len(perms[i]) < 2 and (len(perms[i]) == 0 or perms[i][0] == 1):
|
321
|
+
perms[i] = (1, 2)
|
322
|
+
perms[i] = tuple(permtrim([*perms[i]]))
|
323
|
+
|
324
|
+
size = 0
|
325
|
+
orig_perms = [*perms]
|
326
|
+
while len(perms) != size:
|
327
|
+
size = len(perms)
|
328
|
+
perms = split_perms(perms)
|
329
|
+
|
330
|
+
coeff_dict = {perms[0]: 1}
|
331
|
+
check_coeff_dict = {perms[0]: 1}
|
332
|
+
|
333
|
+
if mult:
|
334
|
+
for v in var2:
|
335
|
+
globals()[str(v)] = v
|
336
|
+
for v in var3:
|
337
|
+
globals()[str(v)] = v
|
338
|
+
for v in var_x:
|
339
|
+
globals()[str(v)] = v
|
340
|
+
|
341
|
+
if down:
|
342
|
+
for perm in orig_perms[1:]:
|
343
|
+
check_coeff_dict = schubmult_down(check_coeff_dict, perm, var2, var3)
|
344
|
+
if mult:
|
345
|
+
mul_exp = eval(mulstring)
|
346
|
+
check_coeff_dict = mult_poly_down(check_coeff_dict, mul_exp)
|
347
|
+
else:
|
348
|
+
for perm in orig_perms[1:]:
|
349
|
+
check_coeff_dict = schubmult(check_coeff_dict, perm, var2, var3)
|
350
|
+
if mult:
|
351
|
+
mul_exp = eval(mulstring)
|
352
|
+
check_coeff_dict = mult_poly(check_coeff_dict, mul_exp)
|
353
|
+
|
354
|
+
if (
|
355
|
+
display_positive
|
356
|
+
and len(perms) == 2
|
357
|
+
and will_formula_work(perms[0], perms[1])
|
358
|
+
and not mult
|
359
|
+
and not down
|
360
|
+
and not same
|
361
|
+
):
|
362
|
+
coeff_dict = {}
|
363
|
+
th = theta(perms[1])
|
364
|
+
muv = uncode(th)
|
365
|
+
muvn1v = mulperm(inverse(muv), perms[1])
|
366
|
+
coeff_dict2 = {perms[0]: 1}
|
367
|
+
coeff_dict2 = schubmult(coeff_dict2, muv, var2, var3)
|
368
|
+
for perm, val in coeff_dict2.items():
|
369
|
+
w = mulperm([*perm], muvn1v)
|
370
|
+
if inv(w) + inv(muvn1v) == inv(perm):
|
371
|
+
coeff_dict[tuple(permtrim(w))] = val
|
372
|
+
posified = True
|
373
|
+
|
374
|
+
if display_positive and len(perms) > 2 and not mult and not same:
|
375
|
+
coeff_dict2 = dict(coeff_dict)
|
376
|
+
for perm in perms[1:]:
|
377
|
+
coeff_dict3 = {}
|
378
|
+
for u in coeff_dict2:
|
379
|
+
coeff_dict4 = {u: 1}
|
380
|
+
coeff_dict4 = schubmult(coeff_dict4, perm, var2, var3)
|
381
|
+
for w in coeff_dict4:
|
382
|
+
coeff_dict4[w] = coeff_dict2[u] * posify(
|
383
|
+
coeff_dict4[w], u, perm, w, var2, var3, msg
|
384
|
+
)
|
385
|
+
coeff_dict3 = add_perm_dict(coeff_dict4, coeff_dict3)
|
386
|
+
coeff_dict2 = coeff_dict3
|
387
|
+
coeff_dict = coeff_dict2
|
388
|
+
posified = True
|
389
|
+
elif not posified:
|
390
|
+
coeff_dict = check_coeff_dict
|
391
|
+
|
392
|
+
if pr:
|
393
|
+
_display_full(
|
394
|
+
coeff_dict,
|
395
|
+
args,
|
396
|
+
formatter,
|
397
|
+
posified=posified,
|
398
|
+
check_coeff_dict=check_coeff_dict,
|
399
|
+
var2=var2,
|
400
|
+
var3=var3,
|
401
|
+
)
|
402
|
+
except BrokenPipeError:
|
403
|
+
pass
|
404
|
+
|
405
|
+
|
406
|
+
if __name__ == "__main__":
|
407
|
+
main()
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from symengine import symarray
|
2
|
+
|
3
|
+
n = 100
|
4
|
+
fvar = 0
|
5
|
+
|
6
|
+
var = tuple(symarray("x", n).tolist())
|
7
|
+
var2 = tuple(symarray("y", n).tolist())
|
8
|
+
var3 = tuple(symarray("z", n).tolist())
|
9
|
+
|
10
|
+
var_x = symarray("x", 100).tolist()
|
11
|
+
var_y = var2
|
12
|
+
var_z = var3
|
13
|
+
|
14
|
+
x = var_x
|
15
|
+
y = var_y
|
16
|
+
z = var_z
|
@@ -0,0 +1,111 @@
|
|
1
|
+
from ._vars import var_x
|
2
|
+
from schubmult.perm_lib import (
|
3
|
+
elem_sym_perms,
|
4
|
+
add_perm_dict,
|
5
|
+
compute_vpathdicts,
|
6
|
+
inverse,
|
7
|
+
theta,
|
8
|
+
permtrim,
|
9
|
+
inv,
|
10
|
+
mulperm,
|
11
|
+
uncode,
|
12
|
+
)
|
13
|
+
from symengine import Add, Mul, Pow
|
14
|
+
|
15
|
+
|
16
|
+
def single_variable(coeff_dict, varnum):
|
17
|
+
ret = {}
|
18
|
+
for u in coeff_dict:
|
19
|
+
new_perms_k = elem_sym_perms(u, 1, varnum)
|
20
|
+
new_perms_km1 = []
|
21
|
+
if varnum > 1:
|
22
|
+
new_perms_km1 = elem_sym_perms(u, 1, varnum - 1)
|
23
|
+
for perm, udiff in new_perms_k:
|
24
|
+
if udiff == 1:
|
25
|
+
ret[perm] = ret.get(perm, 0) + coeff_dict[u]
|
26
|
+
for perm, udiff in new_perms_km1:
|
27
|
+
if udiff == 1:
|
28
|
+
ret[perm] = ret.get(perm, 0) - coeff_dict[u]
|
29
|
+
return ret
|
30
|
+
|
31
|
+
|
32
|
+
def mult_poly(coeff_dict, poly, var_x=var_x):
|
33
|
+
if poly in var_x:
|
34
|
+
return single_variable(coeff_dict, var_x.index(poly))
|
35
|
+
elif isinstance(poly, Mul):
|
36
|
+
ret = coeff_dict
|
37
|
+
for a in poly.args:
|
38
|
+
ret = mult_poly(ret, a, var_x)
|
39
|
+
return ret
|
40
|
+
elif isinstance(poly, Pow):
|
41
|
+
base = poly.args[0]
|
42
|
+
exponent = int(poly.args[1])
|
43
|
+
ret = coeff_dict
|
44
|
+
for i in range(int(exponent)):
|
45
|
+
ret = mult_poly(ret, base, var_x)
|
46
|
+
return ret
|
47
|
+
elif isinstance(poly, Add):
|
48
|
+
ret = {}
|
49
|
+
for a in poly.args:
|
50
|
+
ret = add_perm_dict(ret, mult_poly(coeff_dict, a, var_x))
|
51
|
+
return ret
|
52
|
+
else:
|
53
|
+
ret = {}
|
54
|
+
for perm in coeff_dict:
|
55
|
+
ret[perm] = poly * coeff_dict[perm]
|
56
|
+
return ret
|
57
|
+
|
58
|
+
|
59
|
+
def schubmult(perm_dict, v):
|
60
|
+
vn1 = inverse(v)
|
61
|
+
th = theta(vn1)
|
62
|
+
if th[0] == 0:
|
63
|
+
return perm_dict
|
64
|
+
mu = permtrim(uncode(th))
|
65
|
+
vmu = permtrim(mulperm(list(v), mu))
|
66
|
+
inv_vmu = inv(vmu)
|
67
|
+
inv_mu = inv(mu)
|
68
|
+
ret_dict = {}
|
69
|
+
while th[-1] == 0:
|
70
|
+
th.pop()
|
71
|
+
vpathdicts = compute_vpathdicts(th, vmu)
|
72
|
+
|
73
|
+
mx_th = [0 for i in range(len(th))]
|
74
|
+
for index in range(len(th)):
|
75
|
+
for vp in vpathdicts[index]:
|
76
|
+
for v2, vdiff, s in vpathdicts[index][vp]:
|
77
|
+
if th[index] - vdiff > mx_th[index]:
|
78
|
+
mx_th[index] = th[index] - vdiff
|
79
|
+
|
80
|
+
for u, val in perm_dict.items():
|
81
|
+
inv_u = inv(u)
|
82
|
+
vpathsums = {u: {(1, 2): val}}
|
83
|
+
|
84
|
+
for index in range(len(th)):
|
85
|
+
newpathsums = {}
|
86
|
+
for up in vpathsums:
|
87
|
+
inv_up = inv(up)
|
88
|
+
newperms = elem_sym_perms(
|
89
|
+
up,
|
90
|
+
min(mx_th[index], inv_mu - inv_vmu - (inv_up - inv_u)),
|
91
|
+
th[index],
|
92
|
+
)
|
93
|
+
for vp in vpathsums[up]:
|
94
|
+
sumval = vpathsums[up][vp]
|
95
|
+
if sumval == 0:
|
96
|
+
continue
|
97
|
+
for v2, vdiff, s in vpathdicts[index][vp]:
|
98
|
+
addsumval = s * sumval
|
99
|
+
for up2, udiff in newperms:
|
100
|
+
if vdiff + udiff == th[index]:
|
101
|
+
if up2 not in newpathsums:
|
102
|
+
newpathsums[up2] = {}
|
103
|
+
newpathsums[up2][v2] = (
|
104
|
+
newpathsums[up2].get(v2, 0) + addsumval
|
105
|
+
)
|
106
|
+
vpathsums = newpathsums
|
107
|
+
toget = tuple(vmu)
|
108
|
+
ret_dict = add_perm_dict(
|
109
|
+
{ep: vpathsums[ep].get(toget, 0) for ep in vpathsums}, ret_dict
|
110
|
+
)
|
111
|
+
return ret_dict
|
@@ -0,0 +1,115 @@
|
|
1
|
+
from ._funcs import (
|
2
|
+
mult_poly,
|
3
|
+
schubmult,
|
4
|
+
)
|
5
|
+
from symengine import sympify
|
6
|
+
from schubmult._base_argparse import schub_argparse
|
7
|
+
from schubmult.perm_lib import (
|
8
|
+
inverse,
|
9
|
+
theta,
|
10
|
+
permtrim,
|
11
|
+
inv,
|
12
|
+
mulperm,
|
13
|
+
code,
|
14
|
+
uncode,
|
15
|
+
trimcode,
|
16
|
+
)
|
17
|
+
|
18
|
+
|
19
|
+
def main():
|
20
|
+
try:
|
21
|
+
args = schub_argparse("schubmult_py", "Compute products of ordinary Schubert polynomials")
|
22
|
+
|
23
|
+
mult = args.mult
|
24
|
+
mulstring = args.mulstring
|
25
|
+
|
26
|
+
perms = args.perms
|
27
|
+
|
28
|
+
for perm in perms:
|
29
|
+
try:
|
30
|
+
for i in range(len(perm)):
|
31
|
+
perm[i] = int(perm[i])
|
32
|
+
except Exception as e:
|
33
|
+
print("Permutations must have integer values")
|
34
|
+
raise e
|
35
|
+
|
36
|
+
ascode = args.ascode
|
37
|
+
pr = args.pr
|
38
|
+
coprod = args.coprod
|
39
|
+
|
40
|
+
if coprod:
|
41
|
+
if ascode:
|
42
|
+
perms[0] = tuple(permtrim(uncode(perms[0])))
|
43
|
+
pos = [*perms[1]]
|
44
|
+
pos.sort()
|
45
|
+
mperm = perms[0]
|
46
|
+
|
47
|
+
cd = code(mperm)
|
48
|
+
perms[0] = mperm
|
49
|
+
|
50
|
+
while cd[-1] == 0:
|
51
|
+
cd.pop()
|
52
|
+
k = len(pos)
|
53
|
+
n = len(perms[0])
|
54
|
+
kcd = [pos[i] - i - 1 for i in range(len(pos))] + [n + 1 - k for i in range(k, n)]
|
55
|
+
N = len(kcd)
|
56
|
+
kperm = inverse(uncode(kcd))
|
57
|
+
coeff_dict = {tuple(permtrim(kperm)): 1}
|
58
|
+
coeff_dict = schubmult(coeff_dict, tuple(permtrim([*perms[0]])))
|
59
|
+
|
60
|
+
inv_kperm = inv(kperm)
|
61
|
+
inverse_kperm = inverse(kperm)
|
62
|
+
if pr:
|
63
|
+
for perm, val in coeff_dict.items():
|
64
|
+
downperm = mulperm(list(perm), inverse_kperm)
|
65
|
+
if inv(downperm) == inv(perm) - inv_kperm:
|
66
|
+
flag = True
|
67
|
+
for i in range(N):
|
68
|
+
if downperm[i] > N:
|
69
|
+
flag = False
|
70
|
+
break
|
71
|
+
if not flag:
|
72
|
+
continue
|
73
|
+
firstperm = downperm[0:N]
|
74
|
+
secondperm = [downperm[i] - N for i in range(N, len(downperm))]
|
75
|
+
if val != 0:
|
76
|
+
# firstcode = code(firstperm)
|
77
|
+
# while len(firstcode)>0 and firstcode[-1] == 0:
|
78
|
+
# firstcode.pop()
|
79
|
+
# secondcode = code(secondperm)
|
80
|
+
# while len(secondcode)>0 and secondcode[-1] == 0:
|
81
|
+
# secondcode.pop()
|
82
|
+
if ascode:
|
83
|
+
print(f"{val} {trimcode(firstperm)} {trimcode(secondperm)}")
|
84
|
+
else:
|
85
|
+
print(
|
86
|
+
f"{val} {tuple(permtrim(firstperm))} {tuple(permtrim(secondperm))}"
|
87
|
+
)
|
88
|
+
else:
|
89
|
+
if ascode:
|
90
|
+
for i in range(len(perms)):
|
91
|
+
perms[i] = tuple(permtrim(uncode(perms[i])))
|
92
|
+
|
93
|
+
perms.sort(reverse=True, key=lambda x: sum(theta(inverse(x))) - inv(x))
|
94
|
+
|
95
|
+
coeff_dict = {tuple(permtrim([*perms[0]])): 1}
|
96
|
+
|
97
|
+
for perm in perms[1:]:
|
98
|
+
coeff_dict = schubmult(coeff_dict, tuple(permtrim([*perm])))
|
99
|
+
if mult:
|
100
|
+
mul_exp = sympify(mulstring)
|
101
|
+
coeff_dict = mult_poly(coeff_dict, mul_exp)
|
102
|
+
|
103
|
+
if pr:
|
104
|
+
for perm, val in coeff_dict.items():
|
105
|
+
if val != 0:
|
106
|
+
if ascode:
|
107
|
+
print(f"{val} {trimcode(perm)}")
|
108
|
+
else:
|
109
|
+
print(f"{val} {perm}")
|
110
|
+
except BrokenPipeError:
|
111
|
+
pass
|
112
|
+
|
113
|
+
|
114
|
+
if __name__ == "__main__":
|
115
|
+
main()
|