schubmult 1.3.9__tar.gz → 1.4.1__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.3.9 → schubmult-1.4.1}/PKG-INFO +5 -5
- {schubmult-1.3.9 → schubmult-1.4.1}/README.md +4 -4
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/perm_lib.py +157 -2
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q/schubmult_q.py +96 -2
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_double/schubmult_q_double.py +9 -2
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_yz/schubmult_q_yz.py +154 -26
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_yz/schubmult_yz.py +16 -2
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/PKG-INFO +5 -5
- {schubmult-1.3.9 → schubmult-1.4.1}/setup.py +1 -1
- {schubmult-1.3.9 → schubmult-1.4.1}/LICENSE +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/__init__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_double/__init__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_double/__main__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_double/schubmult_double.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_py/__init__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_py/__main__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_py/schubmult_py.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q/__init__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q/__main__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_double/__init__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_double/__main__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_yz/__init__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_yz/__main__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_yz/__init__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_yz/__main__.py +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/SOURCES.txt +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/dependency_links.txt +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/entry_points.txt +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/requires.txt +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/top_level.txt +0 -0
- {schubmult-1.3.9 → schubmult-1.4.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: schubmult
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.4.1
|
4
4
|
Summary: Computing Littlewood-Richardson coefficients of Schubert polynomials
|
5
5
|
Home-page: https://github.com/matthematics/schubmult
|
6
6
|
Author: Matt Samuel
|
@@ -15,7 +15,7 @@ License-File: LICENSE
|
|
15
15
|
|
16
16
|
## Program and package for computing Littlewood-Richardson coefficients of Schubert polynomials
|
17
17
|
|
18
|
-
This is a set of python scripts written by Matt Samuel for computing Littlewood-Richardson coefficients of (ordinary or double) Schubert polynomials.
|
18
|
+
This is a set of python scripts written by Matt Samuel for computing (equivariant, Molev-Sagan) Littlewood-Richardson coefficients of (ordinary or double) Schubert polynomials. It also handles (double) quantum Schubert polynomials, if double then either in the same set or different sets of coefficient variables; that is to say it compute the (equivariant/mixed) Gromov-Witten invariants of the complete flag variety. It has the same command line syntax as the program "schubmult" in lrcalc by Anders Buch. Example:
|
19
19
|
|
20
20
|
```
|
21
21
|
schubmult_py 1 2 4 9 11 6 8 12 3 5 7 10 - 6 8 1 2 3 4 7 10 12 14 5 9 11 13
|
@@ -50,7 +50,7 @@ schubmult_double -code -coprod 0 1 2 3 - 2 4
|
|
50
50
|
schubmult_yz -code -coprod 0 1 2 3 - 2 4 --display-positive
|
51
51
|
```
|
52
52
|
|
53
|
-
|
53
|
+
schubmult_q_yz has a feature for displaying the coefficients of the divided difference operators in the evaluation of the quantum double Schubert polynomials on the commuting difference operators of Fomin, Gelfand, and Postnikov. It is necessary to cap the value of n in the group S_n we are working in because as n increases the expression does not stabilize.
|
54
54
|
```
|
55
55
|
schubmult_q_yz -nil-hecke 6 -code 2 2 --display-positive
|
56
56
|
```
|
@@ -59,7 +59,7 @@ Runtime will vary tremendously by case. The general problem is #P-hard. Though t
|
|
59
59
|
|
60
60
|
schubmult_py is for multiplying ordinary Schubert polynomials. schubmult_yz is for multiplying double Schubert polynomials in different sets of coefficient variables (labeled y and z), and schubmult_double is for multiplying double Schubert polynomials in the same set of coefficient variables. Similarly, schubmult_q is for multiplying quantum Schubert polynomials, schubmult_q_double is for multiplying quantum double Schubert polynomials in the same set of coefficient variables, and schubmult_q_yz is for multiplying quantum double Schubert polynomials in different sets of coefficient variables, or in other words it computes the Gromov-Witten invariants, equivariant Gromov-Witten invariants, and (mixed?) equivariant Gromov-Witten invariants of the complete flag variety. All have the same command line syntax as schubmult, except when using the -code option. schubmult_double/schubmult_q_double display the result with nonnegative coefficients in terms of the negative simple roots (and the q variables), and schubmult_yz and schubmult_q_yz optionally display the result positively in terms of y_i-z_j (and q) with the --display-positive option.
|
61
61
|
|
62
|
-
|
62
|
+
schubmult_xx -coprod allows you to split (double) Schubert polynomials along certain indices (not available for quantum). It takes one permutation as an argument, followed by a dash -, then the set of indices you would like to split on. These coefficients are always nonnegative since they occur as product coefficients (this is actually how they are computed).
|
63
63
|
|
64
64
|
When imported as a python package, the relevant packages are schubmult.perm_lib, which has various permutation manipulation functions, and three modules that have functions of the same name (function name is "schubmult"): schubmult.schubmult_py, schubmult.schubmult_yz, schubmult.schubmult_double. Function takes a permutation dictionary (keys are tuples of ints, which must be trimmed permutations, and values are either integers or symengine values, which can also be integers) as well as a permutation as its second argument, which is the (double) Schubert polynomial to multiply by. Returns a dictionary of the same form with the coefficients.
|
65
65
|
|
@@ -76,7 +76,7 @@ from schubmult.schubmult_py import schubmult
|
|
76
76
|
coeff_dict = schubmult({(1,3,4,6,2,5): 1},(2,1,5,7,3,4,6))
|
77
77
|
```
|
78
78
|
|
79
|
-
|
79
|
+
The command line argument --display-positive is available in schubmult_yz and schubmult_q_yz, which displays the result positively (if possible, this is still only always possible conjecturally). It will fail and print out the offending case if it finds a counterexample. This is highly processor intensive.
|
80
80
|
|
81
81
|

|
82
82
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
## Program and package for computing Littlewood-Richardson coefficients of Schubert polynomials
|
4
4
|
|
5
|
-
This is a set of python scripts written by Matt Samuel for computing Littlewood-Richardson coefficients of (ordinary or double) Schubert polynomials.
|
5
|
+
This is a set of python scripts written by Matt Samuel for computing (equivariant, Molev-Sagan) Littlewood-Richardson coefficients of (ordinary or double) Schubert polynomials. It also handles (double) quantum Schubert polynomials, if double then either in the same set or different sets of coefficient variables; that is to say it compute the (equivariant/mixed) Gromov-Witten invariants of the complete flag variety. It has the same command line syntax as the program "schubmult" in lrcalc by Anders Buch. Example:
|
6
6
|
|
7
7
|
```
|
8
8
|
schubmult_py 1 2 4 9 11 6 8 12 3 5 7 10 - 6 8 1 2 3 4 7 10 12 14 5 9 11 13
|
@@ -37,7 +37,7 @@ schubmult_double -code -coprod 0 1 2 3 - 2 4
|
|
37
37
|
schubmult_yz -code -coprod 0 1 2 3 - 2 4 --display-positive
|
38
38
|
```
|
39
39
|
|
40
|
-
|
40
|
+
schubmult_q_yz has a feature for displaying the coefficients of the divided difference operators in the evaluation of the quantum double Schubert polynomials on the commuting difference operators of Fomin, Gelfand, and Postnikov. It is necessary to cap the value of n in the group S_n we are working in because as n increases the expression does not stabilize.
|
41
41
|
```
|
42
42
|
schubmult_q_yz -nil-hecke 6 -code 2 2 --display-positive
|
43
43
|
```
|
@@ -46,7 +46,7 @@ Runtime will vary tremendously by case. The general problem is #P-hard. Though t
|
|
46
46
|
|
47
47
|
schubmult_py is for multiplying ordinary Schubert polynomials. schubmult_yz is for multiplying double Schubert polynomials in different sets of coefficient variables (labeled y and z), and schubmult_double is for multiplying double Schubert polynomials in the same set of coefficient variables. Similarly, schubmult_q is for multiplying quantum Schubert polynomials, schubmult_q_double is for multiplying quantum double Schubert polynomials in the same set of coefficient variables, and schubmult_q_yz is for multiplying quantum double Schubert polynomials in different sets of coefficient variables, or in other words it computes the Gromov-Witten invariants, equivariant Gromov-Witten invariants, and (mixed?) equivariant Gromov-Witten invariants of the complete flag variety. All have the same command line syntax as schubmult, except when using the -code option. schubmult_double/schubmult_q_double display the result with nonnegative coefficients in terms of the negative simple roots (and the q variables), and schubmult_yz and schubmult_q_yz optionally display the result positively in terms of y_i-z_j (and q) with the --display-positive option.
|
48
48
|
|
49
|
-
|
49
|
+
schubmult_xx -coprod allows you to split (double) Schubert polynomials along certain indices (not available for quantum). It takes one permutation as an argument, followed by a dash -, then the set of indices you would like to split on. These coefficients are always nonnegative since they occur as product coefficients (this is actually how they are computed).
|
50
50
|
|
51
51
|
When imported as a python package, the relevant packages are schubmult.perm_lib, which has various permutation manipulation functions, and three modules that have functions of the same name (function name is "schubmult"): schubmult.schubmult_py, schubmult.schubmult_yz, schubmult.schubmult_double. Function takes a permutation dictionary (keys are tuples of ints, which must be trimmed permutations, and values are either integers or symengine values, which can also be integers) as well as a permutation as its second argument, which is the (double) Schubert polynomial to multiply by. Returns a dictionary of the same form with the coefficients.
|
52
52
|
|
@@ -63,7 +63,7 @@ from schubmult.schubmult_py import schubmult
|
|
63
63
|
coeff_dict = schubmult({(1,3,4,6,2,5): 1},(2,1,5,7,3,4,6))
|
64
64
|
```
|
65
65
|
|
66
|
-
|
66
|
+
The command line argument --display-positive is available in schubmult_yz and schubmult_q_yz, which displays the result positively (if possible, this is still only always possible conjecturally). It will fail and print out the offending case if it finds a counterexample. This is highly processor intensive.
|
67
67
|
|
68
68
|

|
69
69
|
|
@@ -8,6 +8,11 @@ n = 100
|
|
8
8
|
|
9
9
|
q_var = symarray("q",n)
|
10
10
|
|
11
|
+
def getpermval(perm,index):
|
12
|
+
if index<len(perm):
|
13
|
+
return perm[index]
|
14
|
+
return index+1
|
15
|
+
|
11
16
|
def inv(perm):
|
12
17
|
L = len(perm)
|
13
18
|
v = [i for i in range(1,L+1)]
|
@@ -148,7 +153,7 @@ def elem_sym_perms_op(orig_perm,p,k):
|
|
148
153
|
up_perm2 = [*up_perm]
|
149
154
|
if len(up_perm2) < k + 1:
|
150
155
|
up_perm2 += [i+1 for i in range(len(up_perm2),k+2)]
|
151
|
-
pos_list = [i for i in range(k) if up_perm2
|
156
|
+
pos_list = [i for i in range(k) if getpermval(up_perm2,i) == getpermval(orig_perm,i)]
|
152
157
|
for j in range(last,len(up_perm2)):
|
153
158
|
for i in pos_list:
|
154
159
|
if has_bruhat_descent(up_perm2,i,j):
|
@@ -229,7 +234,81 @@ def elem_sym_perms_q_op(orig_perm,p,k,n):
|
|
229
234
|
up_perm_list = perm_list
|
230
235
|
return total_list
|
231
236
|
|
237
|
+
qvar_list = q_var.tolist()
|
232
238
|
|
239
|
+
def q_vector(q_exp):
|
240
|
+
ret = []
|
241
|
+
|
242
|
+
if q_exp == 1:
|
243
|
+
return ret
|
244
|
+
if q_exp in q_var:
|
245
|
+
i = qvar_list.index(q_exp)
|
246
|
+
ret = [0 for j in range(i-1)] + [1]
|
247
|
+
return ret
|
248
|
+
if isinstance(q_exp, Pow):
|
249
|
+
qv = q_exp.args[0]
|
250
|
+
expon = int(q_exp.args[1])
|
251
|
+
i = qvar_list.index(qv)
|
252
|
+
ret = [0 for j in range(i-1)] + [expon]
|
253
|
+
return ret
|
254
|
+
if isinstance(q_exp, Mul):
|
255
|
+
for a in q_exp.args:
|
256
|
+
v1 = q_vector(a)
|
257
|
+
v1 += [0 for i in range(len(v1),len(ret))]
|
258
|
+
ret += [0 for i in range(len(ret),len(v1))]
|
259
|
+
ret = [ret[i] + v1[i] for i in range(len(ret))]
|
260
|
+
return ret
|
261
|
+
|
262
|
+
return None
|
263
|
+
|
264
|
+
def omega(i,qv):
|
265
|
+
i = i - 1
|
266
|
+
if len(qv) == 0 or i > len(qv):
|
267
|
+
return 0
|
268
|
+
if i == 0:
|
269
|
+
if len(qv) == 1:
|
270
|
+
return 2*qv[0]
|
271
|
+
return 2*qv[0] - qv[1]
|
272
|
+
if i == len(qv):
|
273
|
+
return -qv[-1]
|
274
|
+
if i == len(qv) - 1:
|
275
|
+
return 2*qv[-1] - qv[-2]
|
276
|
+
return 2*qv[i] - qv[i-1] - qv[i+1]
|
277
|
+
|
278
|
+
def sg(i,w):
|
279
|
+
if i>=len(w) - 1 or w[i]<w[i+1]:
|
280
|
+
return 0
|
281
|
+
return 1
|
282
|
+
|
283
|
+
def reduce_q_coeff(u, v, w, qv):
|
284
|
+
for i in range(len(qv)):
|
285
|
+
if (i<len(u)-1 and u[i]>u[i+1] and (i>=len(v)-1 or v[i]<v[i+1]) and (i>=len(w)-1 or w[i]<w[i+1]) and sg(i,w) + omega(i+1,qv) == 1):
|
286
|
+
ret_u = [*u]
|
287
|
+
ret_u[i], ret_u[i+1] = ret_u[i+1], ret_u[i]
|
288
|
+
ret_w = [*w] + [j+1 for j in range(len(w),i+2)]
|
289
|
+
ret_w[i], ret_w[i+1] = ret_w[i+1], ret_w[i]
|
290
|
+
qv_ret = [*qv]
|
291
|
+
qv_ret[i] -= 1
|
292
|
+
return tuple(permtrim(ret_u)), v, tuple(permtrim(ret_w)), qv_ret, True
|
293
|
+
elif (i<len(v)-1 and v[i]>v[i+1] and (i>=len(u)-1 or u[i]<u[i+1]) and (i>=len(w)-1 or w[i]<w[i+1]) and sg(i,w) + omega(i+1,qv) == 1):
|
294
|
+
ret_v = [*v]
|
295
|
+
ret_v[i], ret_v[i+1] = ret_v[i+1], ret_v[i]
|
296
|
+
ret_w = [*w] + [j+1 for j in range(len(w),i+2)]
|
297
|
+
ret_w[i], ret_w[i+1] = ret_w[i+1], ret_w[i]
|
298
|
+
qv_ret = [*qv]
|
299
|
+
qv_ret[i] -= 1
|
300
|
+
return u, tuple(permtrim(ret_v)), tuple(permtrim(ret_w)), qv_ret, True
|
301
|
+
elif (i<len(u)-1 and u[i]>u[i+1] and i<len(v)-1 and v[i]>v[i+1] and sg(i,w)+omega(i+1,qv) == 2):
|
302
|
+
ret_u = [*u]
|
303
|
+
ret_u[i], ret_u[i+1] = ret_u[i+1], ret_u[i]
|
304
|
+
ret_w = [*w] + [j+1 for j in range(len(w),i+2)]
|
305
|
+
ret_w[i], ret_w[i+1] = ret_w[i+1], ret_w[i]
|
306
|
+
qv_ret = [*qv]
|
307
|
+
if i>=len(w)-1 or w[i]<w[i+1]:
|
308
|
+
qv_ret[i] -= 1
|
309
|
+
return tuple(permtrim(ret_u)), v, tuple(permtrim(ret_w)), qv_ret, True
|
310
|
+
return u, v, w, qv, False
|
311
|
+
|
233
312
|
# perms and inversion diff
|
234
313
|
def kdown_perms(perm,monoperm,p,k):
|
235
314
|
inv_m = inv(monoperm)
|
@@ -663,4 +742,80 @@ def pull_out_var(vnum,v):
|
|
663
742
|
vpm2.pop(vnum-1)
|
664
743
|
vp = permtrim(vpm2)
|
665
744
|
ret_list += [[[v[i] for i in range(vnum,len(v)) if ((i>len(vp) and v[i]==i) or (i<=len(vp) and v[i]==vp[i-1]))],vp]]
|
666
|
-
return ret_list
|
745
|
+
return ret_list
|
746
|
+
|
747
|
+
def get_cycles(perm):
|
748
|
+
cycle_set = []
|
749
|
+
done_vals = set()
|
750
|
+
for i in range(len(perm)):
|
751
|
+
p = i + 1
|
752
|
+
if perm[i] == p:
|
753
|
+
continue
|
754
|
+
if p in done_vals:
|
755
|
+
continue
|
756
|
+
cycle = []
|
757
|
+
m = -1
|
758
|
+
max_index = -1
|
759
|
+
while p not in done_vals:
|
760
|
+
cycle += [p]
|
761
|
+
done_vals.add(p)
|
762
|
+
if p>m:
|
763
|
+
m = p
|
764
|
+
max_index = len(cycle) - 1
|
765
|
+
p = perm[p-1]
|
766
|
+
cycle = tuple(cycle[max_index+1:] + cycle[:max_index+1])
|
767
|
+
cycle_set += [cycle]
|
768
|
+
return cycle_set
|
769
|
+
|
770
|
+
def double_elem_sym_q(u,p1,p2,k):
|
771
|
+
ret_list = {}
|
772
|
+
perms1 = elem_sym_perms_q(u,p1,k)
|
773
|
+
iu = inverse(u)
|
774
|
+
for perm1, udiff1, mul_val1 in perms1:
|
775
|
+
perms2 = elem_sym_perms_q(perm1,p2,k)
|
776
|
+
cycles1 = get_cycles(tuple(permtrim(mulperm(iu,[*perm1]))))
|
777
|
+
cycles1_dict = {}
|
778
|
+
for c in cycles1:
|
779
|
+
if c[-1] not in cycles1_dict:
|
780
|
+
cycles1_dict[c[-1]] = []
|
781
|
+
cycles1_dict[c[-1]]+= [set(c)]
|
782
|
+
ip1 = inverse(perm1)
|
783
|
+
for perm2, udiff2, mul_val2 in perms2:
|
784
|
+
cycles2 = get_cycles(tuple(permtrim(mulperm(ip1,[*perm2]))))
|
785
|
+
good = True
|
786
|
+
for i in range(len(cycles2)):
|
787
|
+
c2 = cycles2[i]
|
788
|
+
if c2[-1] not in cycles1_dict:
|
789
|
+
continue
|
790
|
+
for c1_s in cycles1_dict[c2[-1]]:
|
791
|
+
for a in range(len(c2)-2,-1,-1):
|
792
|
+
if c2[a] in c1_s:
|
793
|
+
good = False
|
794
|
+
break
|
795
|
+
if not good:
|
796
|
+
break
|
797
|
+
if not good:
|
798
|
+
break
|
799
|
+
|
800
|
+
if good:
|
801
|
+
if (perm1,udiff1,mul_val1) not in ret_list:
|
802
|
+
ret_list[(perm1,udiff1,mul_val1)] = []
|
803
|
+
ret_list[(perm1,udiff1,mul_val1)] += [(perm2,udiff2,mul_val2)]
|
804
|
+
return ret_list
|
805
|
+
|
806
|
+
def medium_theta(perm):
|
807
|
+
cd = code(perm)
|
808
|
+
found_one = True
|
809
|
+
while found_one:
|
810
|
+
found_one = False
|
811
|
+
for i in range(len(cd)-1):
|
812
|
+
if cd[i]<cd[i+1]:
|
813
|
+
found_one = True
|
814
|
+
cd[i], cd[i+1] = cd[i+1]+1, cd[i]
|
815
|
+
break
|
816
|
+
if cd[i]==cd[i+1] and cd[i]!=0 and i>0 and cd[i-1]<=cd[i]+1:
|
817
|
+
#if cd[i]==cd[i+1] and i>0 and cd[i-1]<=cd[i]+1:
|
818
|
+
cd[i]+=1
|
819
|
+
found_one = True
|
820
|
+
break
|
821
|
+
return cd
|
@@ -63,6 +63,92 @@ for i in range(1,n):
|
|
63
63
|
sm += var_r[j]
|
64
64
|
subs_dict[var2[i]] = sm
|
65
65
|
|
66
|
+
def schubmult_db(perm_dict,v,var2=var2,var3=var3):
|
67
|
+
if v == (1,2):
|
68
|
+
return perm_dict
|
69
|
+
th = medium_theta(inverse(v))
|
70
|
+
#print(f"{th=}")
|
71
|
+
while th[-1] == 0:
|
72
|
+
th.pop()
|
73
|
+
#if len(set(th))!=len(th):
|
74
|
+
# print(f"medium theta {th=}")
|
75
|
+
mu = permtrim(uncode(th))
|
76
|
+
vmu = permtrim(mulperm([*v],mu))
|
77
|
+
inv_vmu = inv(vmu)
|
78
|
+
inv_mu = inv(mu)
|
79
|
+
ret_dict = {}
|
80
|
+
vpaths = [([(vmu,0)],1)]
|
81
|
+
|
82
|
+
thL = len(th)
|
83
|
+
#if thL!=2 and len(set(thL))!=1:
|
84
|
+
# raise ValueError("Not what I can do")
|
85
|
+
vpathdicts = compute_vpathdicts(th,vmu,True)
|
86
|
+
#print(f"{vpathdicts=}")
|
87
|
+
for u,val in perm_dict.items():
|
88
|
+
inv_u = inv(u)
|
89
|
+
vpathsums = {u: {(1,2): val}}
|
90
|
+
for index in range(thL):
|
91
|
+
if index>0 and th[index-1] == th[index]:
|
92
|
+
continue
|
93
|
+
mx_th = 0
|
94
|
+
for vp in vpathdicts[index]:
|
95
|
+
for v2,vdiff,s in vpathdicts[index][vp]:
|
96
|
+
if th[index]-vdiff > mx_th:
|
97
|
+
mx_th = th[index] - vdiff
|
98
|
+
if index<len(th)-1 and th[index] == th[index+1]:
|
99
|
+
mx_th1 = 0
|
100
|
+
for vp in vpathdicts[index+1]:
|
101
|
+
for v2,vdiff,s in vpathdicts[index+1][vp]:
|
102
|
+
if th[index+1]-vdiff > mx_th1:
|
103
|
+
mx_th1 = th[index+1] - vdiff
|
104
|
+
newpathsums = {}
|
105
|
+
for up in vpathsums:
|
106
|
+
newpathsums0 = {}
|
107
|
+
inv_up = inv(up)
|
108
|
+
newperms = double_elem_sym_q(up,mx_th,mx_th1,th[index])
|
109
|
+
for v in vpathdicts[index]:
|
110
|
+
sumval = vpathsums[up].get(v,zero)
|
111
|
+
if sumval == 0:
|
112
|
+
continue
|
113
|
+
for v2,vdiff2,s2 in vpathdicts[index][v]:
|
114
|
+
for up1, udiff1, mul_val1 in newperms:
|
115
|
+
if (up1,udiff1,mul_val1) not in newpathsums0:
|
116
|
+
newpathsums0[(up1,udiff1,mul_val1)] = {}
|
117
|
+
if udiff1 + vdiff2 == th[index]:
|
118
|
+
newpathsums0[(up1,udiff1,mul_val1)][v2] = newpathsums0[(up1,udiff1,mul_val1)].get(v2,zero)+s2*sumval*mul_val1
|
119
|
+
|
120
|
+
for up1, udiff1, mul_val1 in newpathsums0:
|
121
|
+
for v in vpathdicts[index+1]:
|
122
|
+
sumval = newpathsums0[(up1,udiff1,mul_val1)].get(v,zero)
|
123
|
+
if sumval == 0:
|
124
|
+
continue
|
125
|
+
for v2,vdiff2,s2 in vpathdicts[index+1][v]:
|
126
|
+
for up2, udiff2, mul_val2 in newperms[(up1,udiff1,mul_val1)]:
|
127
|
+
if up2 not in newpathsums:
|
128
|
+
newpathsums[up2]={}
|
129
|
+
if udiff2 + vdiff2 == th[index+1]:
|
130
|
+
newpathsums[up2][v2] = newpathsums[up2].get(v2,zero)+s2*sumval*mul_val2
|
131
|
+
else:
|
132
|
+
newpathsums = {}
|
133
|
+
for up in vpathsums:
|
134
|
+
inv_up = inv(up)
|
135
|
+
newperms = elem_sym_perms_q(up,min(mx_th,(inv_mu-(inv_up-inv_u))-inv_vmu),th[index])
|
136
|
+
for up2, udiff, mul_val in newperms:
|
137
|
+
if up2 not in newpathsums:
|
138
|
+
newpathsums[up2]={}
|
139
|
+
for v in vpathdicts[index]:
|
140
|
+
sumval = vpathsums[up].get(v,zero)
|
141
|
+
if sumval == 0:
|
142
|
+
continue
|
143
|
+
for v2,vdiff,s in vpathdicts[index][v]:
|
144
|
+
if udiff+vdiff==th[index]:
|
145
|
+
newpathsums[up2][v2] = newpathsums[up2].get(v2,zero)+s*sumval*mul_val
|
146
|
+
vpathsums = newpathsums
|
147
|
+
toget = tuple(vmu)
|
148
|
+
ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget,0) for ep in vpathsums},ret_dict)
|
149
|
+
return ret_dict
|
150
|
+
|
151
|
+
|
66
152
|
def schubmult(perm_dict,v):
|
67
153
|
th = strict_theta(inverse(v))
|
68
154
|
mu = permtrim(uncode(th))
|
@@ -177,12 +263,16 @@ def main():
|
|
177
263
|
equiv = False
|
178
264
|
mult = False
|
179
265
|
mulstring = ""
|
266
|
+
slow = False
|
180
267
|
|
181
268
|
try:
|
182
269
|
for s in sys.argv[1:]:
|
183
270
|
if s == "-np" or s == "--no-print":
|
184
271
|
pr = False
|
185
272
|
continue
|
273
|
+
if s == "--slow":
|
274
|
+
slow = True
|
275
|
+
continue
|
186
276
|
if mult:
|
187
277
|
mulstring += s
|
188
278
|
continue
|
@@ -344,8 +434,12 @@ def main():
|
|
344
434
|
|
345
435
|
coeff_dict = {tuple(permtrim([*perms[0]])): 1}
|
346
436
|
|
347
|
-
|
348
|
-
|
437
|
+
if not slow:
|
438
|
+
for perm in perms[1:]:
|
439
|
+
coeff_dict = schubmult_db(coeff_dict,tuple(permtrim([*perm])))
|
440
|
+
else:
|
441
|
+
for perm in perms[1:]:
|
442
|
+
coeff_dict = schubmult(coeff_dict,tuple(permtrim([*perm])))
|
349
443
|
|
350
444
|
if mult:
|
351
445
|
mul_exp = sympify(mulstring)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from schubmult.perm_lib import *
|
2
|
-
from schubmult.schubmult_q_yz import schubmult, mult_poly
|
2
|
+
from schubmult.schubmult_q_yz import schubmult, schubmult_db, mult_poly
|
3
3
|
from symengine import *
|
4
4
|
import sys
|
5
5
|
|
@@ -37,12 +37,16 @@ def main():
|
|
37
37
|
check = True
|
38
38
|
msg = False
|
39
39
|
mult = False
|
40
|
+
slow = False
|
40
41
|
mulstring = ""
|
41
42
|
try:
|
42
43
|
for s in sys.argv[1:]:
|
43
44
|
if s == "-np" or s == "--no-print":
|
44
45
|
pr = False
|
45
46
|
continue
|
47
|
+
if s == "--slow":
|
48
|
+
slow = True
|
49
|
+
continue
|
46
50
|
if mult:
|
47
51
|
mulstring += s
|
48
52
|
continue
|
@@ -96,7 +100,10 @@ def main():
|
|
96
100
|
|
97
101
|
coeff_dict = {perms[0]: 1}
|
98
102
|
for perm in perms[1:]:
|
99
|
-
|
103
|
+
if slow:
|
104
|
+
coeff_dict = schubmult(coeff_dict,perm,var2,var2)
|
105
|
+
else:
|
106
|
+
coeff_dict = schubmult_db(coeff_dict,perm,var2,var2)
|
100
107
|
if mult:
|
101
108
|
mul_exp = sympify(mulstring)
|
102
109
|
coeff_dict = mult_poly(coeff_dict,mul_exp)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from schubmult.perm_lib import *
|
2
2
|
from schubmult.schubmult_yz import compute_positive_rep, posify
|
3
|
+
import schubmult.schubmult_yz as norm_yz
|
3
4
|
from symengine import *
|
4
5
|
import sys
|
5
6
|
|
@@ -149,6 +150,104 @@ def schubmult(perm_dict,v,var2=var2,var3=var3):
|
|
149
150
|
ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget,0) for ep in vpathsums},ret_dict)
|
150
151
|
return ret_dict
|
151
152
|
|
153
|
+
def schubmult_db(perm_dict,v,var2=var2,var3=var3):
|
154
|
+
if v == (1,2):
|
155
|
+
return perm_dict
|
156
|
+
th = medium_theta(inverse(v))
|
157
|
+
#print(f"{th=}")
|
158
|
+
while th[-1] == 0:
|
159
|
+
th.pop()
|
160
|
+
#if len(set(th))!=len(th):
|
161
|
+
# print(f"medium theta {th=}")
|
162
|
+
mu = permtrim(uncode(th))
|
163
|
+
vmu = permtrim(mulperm([*v],mu))
|
164
|
+
inv_vmu = inv(vmu)
|
165
|
+
inv_mu = inv(mu)
|
166
|
+
ret_dict = {}
|
167
|
+
vpaths = [([(vmu,0)],1)]
|
168
|
+
|
169
|
+
thL = len(th)
|
170
|
+
#if thL!=2 and len(set(thL))!=1:
|
171
|
+
# raise ValueError("Not what I can do")
|
172
|
+
vpathdicts = compute_vpathdicts(th,vmu,True)
|
173
|
+
#print(f"{vpathdicts=}")
|
174
|
+
for u,val in perm_dict.items():
|
175
|
+
inv_u = inv(u)
|
176
|
+
vpathsums = {u: {(1,2): val}}
|
177
|
+
for index in range(thL):
|
178
|
+
if index>0 and th[index-1] == th[index]:
|
179
|
+
continue
|
180
|
+
mx_th = 0
|
181
|
+
for vp in vpathdicts[index]:
|
182
|
+
for v2,vdiff,s in vpathdicts[index][vp]:
|
183
|
+
if th[index]-vdiff > mx_th:
|
184
|
+
mx_th = th[index] - vdiff
|
185
|
+
if index<len(th)-1 and th[index] == th[index+1]:
|
186
|
+
mx_th1 = 0
|
187
|
+
for vp in vpathdicts[index+1]:
|
188
|
+
for v2,vdiff,s in vpathdicts[index+1][vp]:
|
189
|
+
if th[index+1]-vdiff > mx_th1:
|
190
|
+
mx_th1 = th[index+1] - vdiff
|
191
|
+
newpathsums = {}
|
192
|
+
for up in vpathsums:
|
193
|
+
newpathsums0 = {}
|
194
|
+
inv_up = inv(up)
|
195
|
+
newperms = double_elem_sym_q(up,mx_th,mx_th1,th[index])
|
196
|
+
#for up1, up2, udiff1,udiff2,mul_val1,mul_val2 in newperms:
|
197
|
+
for v in vpathdicts[index]:
|
198
|
+
sumval = vpathsums[up].get(v,zero)
|
199
|
+
if sumval == 0:
|
200
|
+
continue
|
201
|
+
for v2,vdiff2,s2 in vpathdicts[index][v]:
|
202
|
+
for up1, udiff1, mul_val1 in newperms:
|
203
|
+
esim1 = elem_sym_func_q(th[index],index+1,up,up1,v,v2,udiff1,vdiff2,var2,var3)*mul_val1*s2
|
204
|
+
mulfac = sumval*esim1
|
205
|
+
if (up1,udiff1,mul_val1) not in newpathsums0:
|
206
|
+
newpathsums0[(up1,udiff1,mul_val1)] = {}
|
207
|
+
#newpathsums0[(up1, udiff1, mul_val1
|
208
|
+
newpathsums0[(up1,udiff1,mul_val1)][v2] = newpathsums0[(up1,udiff1,mul_val1)].get(v2,0) + mulfac
|
209
|
+
|
210
|
+
for up1, udiff1, mul_val1 in newpathsums0:
|
211
|
+
for v in vpathdicts[index+1]:
|
212
|
+
sumval = newpathsums0[(up1,udiff1,mul_val1)].get(v,zero)
|
213
|
+
if sumval == 0:
|
214
|
+
continue
|
215
|
+
for v2,vdiff2,s2 in vpathdicts[index+1][v]:
|
216
|
+
for up2, udiff2, mul_val2 in newperms[(up1,udiff1,mul_val1)]:
|
217
|
+
esim1 = elem_sym_func_q(th[index+1],index+2,up1,up2,v,v2,udiff2,vdiff2,var2,var3)*mul_val2*s2
|
218
|
+
mulfac = sumval*esim1
|
219
|
+
if up2 not in newpathsums:
|
220
|
+
newpathsums[up2] = {}
|
221
|
+
newpathsums[up2][v2] = newpathsums[up2].get(v2,0) + mulfac
|
222
|
+
#for up2, udiff2, mul_val2 in newperms[(up1,udiff1,mul_val1)]:
|
223
|
+
# if up2 not in newpathsums:
|
224
|
+
# newpathsums[up2]={}
|
225
|
+
# for v3,vdiff3,s3 in vpathdicts[index+1][v2]:
|
226
|
+
# newpathsums[up2][v3] = newpathsums[up2].get(v3,zero)+s3*mul_val2*mulfac*elem_sym_func_q(th[index+1],index+2,up1,up2,v2,v3,udiff2,vdiff3,var2,var3)
|
227
|
+
else:
|
228
|
+
newpathsums = {}
|
229
|
+
for up in vpathsums:
|
230
|
+
inv_up = inv(up)
|
231
|
+
newperms = elem_sym_perms_q(up,min(mx_th,(inv_mu-(inv_up-inv_u))-inv_vmu),th[index])
|
232
|
+
for up2, udiff,mul_val in newperms:
|
233
|
+
if up2 not in newpathsums:
|
234
|
+
newpathsums[up2]={}
|
235
|
+
for v in vpathdicts[index]:
|
236
|
+
sumval = vpathsums[up].get(v,zero)*mul_val
|
237
|
+
if sumval == 0:
|
238
|
+
continue
|
239
|
+
for v2,vdiff,s in vpathdicts[index][v]:
|
240
|
+
newpathsums[up2][v2] = newpathsums[up2].get(v2,zero)+s*sumval*elem_sym_func_q(th[index],index+1,up,up2,v,v2,udiff,vdiff,var2,var3)
|
241
|
+
vpathsums = newpathsums
|
242
|
+
toget = tuple(vmu)
|
243
|
+
ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget,0) for ep in vpathsums},ret_dict)
|
244
|
+
return ret_dict
|
245
|
+
|
246
|
+
def div_diff(v,w,var2=var2,var3=var3):
|
247
|
+
coeff_dict = {v: 1}
|
248
|
+
coeff_dict = norm_yz.schubmult_down(coeff_dict,w,var2,var3)
|
249
|
+
return coeff_dict.get((1,2),0)
|
250
|
+
|
152
251
|
q_var2 = q_var.tolist()
|
153
252
|
|
154
253
|
def sum_q_dict(q_dict1,q_dict2):
|
@@ -266,10 +365,12 @@ def main():
|
|
266
365
|
ascode = False
|
267
366
|
coprod = False
|
268
367
|
nilhecke = False
|
368
|
+
nilhecke_apply = False
|
269
369
|
check = True
|
270
370
|
msg = False
|
271
371
|
just_nil = False
|
272
372
|
mult = False
|
373
|
+
slow = False
|
273
374
|
|
274
375
|
nil_N = 0
|
275
376
|
|
@@ -283,6 +384,9 @@ def main():
|
|
283
384
|
just_nil = False
|
284
385
|
nil_N = int(s)
|
285
386
|
continue
|
387
|
+
if s == "--slow":
|
388
|
+
slow = True
|
389
|
+
continue
|
286
390
|
if s == "--norep":
|
287
391
|
norep = True
|
288
392
|
continue
|
@@ -311,6 +415,10 @@ def main():
|
|
311
415
|
nilhecke = True
|
312
416
|
just_nil = True
|
313
417
|
continue
|
418
|
+
if s == "-nil-hecke-apply":
|
419
|
+
nilhecke_apply = True
|
420
|
+
just_nil = True
|
421
|
+
continue
|
314
422
|
if s == "--version":
|
315
423
|
print(f"Python version {sys.version}")
|
316
424
|
exit(0)
|
@@ -346,11 +454,20 @@ def main():
|
|
346
454
|
|
347
455
|
if nilhecke:
|
348
456
|
coeff_dict = nil_hecke({(1,2): 1},perms[0],nil_N)
|
349
|
-
rep = ("y","x")
|
457
|
+
rep = ("y","x")
|
458
|
+
elif nilhecke_apply:
|
459
|
+
coeff_dict0 = nil_hecke({(1,2): 1},perms[0],nil_N,var2,var2)
|
460
|
+
coeff_dict = {(1,2): 0}
|
461
|
+
for v in coeff_dict0:
|
462
|
+
coeff_dict[(1,2)] += coeff_dict0[v]*div_diff(v,perms[1],var2,var3)
|
463
|
+
rep = ("y","x")
|
350
464
|
else:
|
351
465
|
coeff_dict = {perms[0]: 1}
|
352
466
|
for perm in perms[1:]:
|
353
|
-
|
467
|
+
if not slow:
|
468
|
+
coeff_dict = schubmult_db(coeff_dict,perm)
|
469
|
+
else:
|
470
|
+
coeff_dict = schubmult(coeff_dict,perm)
|
354
471
|
if mult:
|
355
472
|
for v in var2:
|
356
473
|
globals()[str(v)] = v
|
@@ -358,15 +475,18 @@ def main():
|
|
358
475
|
globals()[str(v)] = v
|
359
476
|
for v in var_x:
|
360
477
|
globals()[str(v)] = v
|
478
|
+
for v in q_var:
|
479
|
+
globals()[str(v)] = v
|
480
|
+
q = q_var
|
361
481
|
mul_exp = eval(mulstring)
|
362
482
|
coeff_dict = mult_poly(coeff_dict,mul_exp)
|
363
483
|
rep = ("","")
|
364
484
|
|
365
485
|
if pr:
|
366
|
-
if ascode:
|
367
|
-
|
368
|
-
else:
|
369
|
-
|
486
|
+
#if ascode:
|
487
|
+
# width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys() if expand(coeff_dict[perm])!=0])
|
488
|
+
#else:
|
489
|
+
# width = max([len(str(perm)) for perm in coeff_dict.keys() if expand(coeff_dict[perm])!=0])
|
370
490
|
|
371
491
|
coeff_perms = list(coeff_dict.keys())
|
372
492
|
coeff_perms.sort(key=lambda x: (inv(x),*x))
|
@@ -388,22 +508,28 @@ def main():
|
|
388
508
|
val2 += q_part*int(q_dict[q_part])
|
389
509
|
except Exception:
|
390
510
|
try:
|
391
|
-
if len(perms) == 2
|
392
|
-
u = permtrim([*perms[0]])
|
393
|
-
v = permtrim([*perms[1]])
|
394
|
-
|
395
|
-
|
396
|
-
i = q_var2.index(q_part)
|
397
|
-
u = permtrim([*perms[0]])
|
398
|
-
v = permtrim([*perms[1]])
|
399
|
-
#print(f"{u=} {v=} {q_part=} {q_dict[q_part]=}")
|
400
|
-
if i<len(u) and i<len(v) and u[i-1]>u[i] and v[i-1]>v[i]:
|
401
|
-
u[i], u[i-1] = u[i-1], u[i]
|
402
|
-
v[i], v[i-1] = v[i-1], v[i]
|
403
|
-
#print(f"new {u=} {v=}")
|
404
|
-
val2 += q_part*posify(q_dict[q_part],tuple(permtrim(u)),tuple(permtrim(v)),perm,var2_t,var3_t,msg,False)
|
511
|
+
if len(perms) == 2:
|
512
|
+
u = tuple(permtrim([*perms[0]]))
|
513
|
+
v = tuple(permtrim([*perms[1]]))
|
514
|
+
if len(perms) == 2 and code(inverse(perms[1])) == medium_theta(inverse(perms[1])) and not mult and not slow and not nilhecke_apply:
|
515
|
+
val2 += q_part*q_dict[q_part]
|
405
516
|
else:
|
406
|
-
|
517
|
+
q_part2 = q_part
|
518
|
+
if not mult and not nilhecke_apply and len(perms) == 2:
|
519
|
+
qv = q_vector(q_part)
|
520
|
+
u2, v2, w2 = u, v, perm
|
521
|
+
u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
|
522
|
+
while did_one:
|
523
|
+
u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
|
524
|
+
q_part2 = np.prod([q_var[i+1]**qv[i] for i in range(len(qv))])
|
525
|
+
if q_part2 == 1:
|
526
|
+
#if q_part != q_part2:
|
527
|
+
# print("Posified q part")
|
528
|
+
val2 += q_part*posify(q_dict[q_part],u2,v2,w2,var2_t,var3_t,msg,False)
|
529
|
+
else:
|
530
|
+
val2 += q_part*compute_positive_rep(q_dict[q_part],var2_t,var3_t,msg,False)
|
531
|
+
else:
|
532
|
+
val2 += q_part*compute_positive_rep(q_dict[q_part],var2_t,var3_t,msg,False)
|
407
533
|
except Exception as e:
|
408
534
|
if mult:
|
409
535
|
print("warning; --display-positive is on but result is not positive",file=sys.stderr)
|
@@ -412,12 +538,14 @@ def main():
|
|
412
538
|
else:
|
413
539
|
print(f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {coeff_dict.get(perm,0)=}")
|
414
540
|
print(f"Exception: {e}")
|
541
|
+
import traceback
|
542
|
+
traceback.print_exc()
|
415
543
|
exit(1)
|
416
544
|
if check and expand(val - val2)!=0:
|
417
545
|
if mult:
|
418
546
|
val2 = val
|
419
547
|
else:
|
420
|
-
print(f"error: value not equal; write to schubmult@gmail.com with the case {perms=} {perm=} {
|
548
|
+
print(f"error: value not equal; write to schubmult@gmail.com with the case {perms=} {perm=} {val2=} {coeff_dict.get(perm,0)=}")
|
421
549
|
exit(1)
|
422
550
|
val = val2
|
423
551
|
if expa:
|
@@ -425,14 +553,14 @@ def main():
|
|
425
553
|
if val!=0:
|
426
554
|
if ascode:
|
427
555
|
if norep:
|
428
|
-
print(f"{str(trimcode(perm))
|
556
|
+
print(f"{str(trimcode(perm))} {str(val).replace(*rep)}")
|
429
557
|
else:
|
430
|
-
print(f"{str(trimcode(perm))
|
558
|
+
print(f"{str(trimcode(perm))} {str(val).replace('**','^').replace('*',' ').replace(*rep)}")
|
431
559
|
else:
|
432
560
|
if norep:
|
433
|
-
print(f"{str(perm)
|
561
|
+
print(f"{str(perm)} {str(val).replace(*rep)}")
|
434
562
|
else:
|
435
|
-
print(f"{str(perm)
|
563
|
+
print(f"{str(perm)} {str(val).replace('**','^').replace('*',' ').replace(*rep)}")
|
436
564
|
except BrokenPipeError:
|
437
565
|
pass
|
438
566
|
|
@@ -129,7 +129,21 @@ def mult_poly_down(coeff_dict,poly):
|
|
129
129
|
ret[perm] = poly*coeff_dict[perm]
|
130
130
|
return ret
|
131
131
|
|
132
|
-
|
132
|
+
def nilhecke_mult(coeff_dict1,coeff_dict2):
|
133
|
+
ret = {}
|
134
|
+
for w in coeff_dict2:
|
135
|
+
w1 = [*w]
|
136
|
+
inv_w1 = inv(w1)
|
137
|
+
poly = coeff_dict2[w]
|
138
|
+
did_mul = mult_poly_down(coeff_dict1,poly)
|
139
|
+
for v in did_mul:
|
140
|
+
v1 = [*v1]
|
141
|
+
addperm = mulperm(v1,w1)
|
142
|
+
if inv(addperm) == inv(v1) + inv_w1:
|
143
|
+
toadd = tuple(permtrim(addperm))
|
144
|
+
ret[toadd] = ret.get(toadd,0) + did_mul[v]
|
145
|
+
return ret
|
146
|
+
|
133
147
|
def forwardcoeff(u,v,perm,var2=var2,var3=var3):
|
134
148
|
th = theta(v)
|
135
149
|
muv = uncode(th)
|
@@ -1301,7 +1315,7 @@ def posify(val,u2,v2,w2,var2=var2,var3=var3,msg=False,do_pos_neg=True,sign_only=
|
|
1301
1315
|
val2 = schubmult_one(tuple(permtrim(u3)),tuple(permtrim(v3)),var2,var3).get(tuple(permtrim(w3)),0)
|
1302
1316
|
val2 = posify(val2,u3,tuple(permtrim(v3)),w3,var2,var3,msg,do_pos_neg)
|
1303
1317
|
val += tomul*shiftsub(val2)
|
1304
|
-
elif inv(w)-inv(u)==2:
|
1318
|
+
elif inv(w)-inv(u)==2 and len(trimcode(u)) == len(trimcode(w)):
|
1305
1319
|
indices = []
|
1306
1320
|
for i in range(len(w)):
|
1307
1321
|
if i>=len(u) or u[i]!=w[i]:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: schubmult
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.4.1
|
4
4
|
Summary: Computing Littlewood-Richardson coefficients of Schubert polynomials
|
5
5
|
Home-page: https://github.com/matthematics/schubmult
|
6
6
|
Author: Matt Samuel
|
@@ -15,7 +15,7 @@ License-File: LICENSE
|
|
15
15
|
|
16
16
|
## Program and package for computing Littlewood-Richardson coefficients of Schubert polynomials
|
17
17
|
|
18
|
-
This is a set of python scripts written by Matt Samuel for computing Littlewood-Richardson coefficients of (ordinary or double) Schubert polynomials.
|
18
|
+
This is a set of python scripts written by Matt Samuel for computing (equivariant, Molev-Sagan) Littlewood-Richardson coefficients of (ordinary or double) Schubert polynomials. It also handles (double) quantum Schubert polynomials, if double then either in the same set or different sets of coefficient variables; that is to say it compute the (equivariant/mixed) Gromov-Witten invariants of the complete flag variety. It has the same command line syntax as the program "schubmult" in lrcalc by Anders Buch. Example:
|
19
19
|
|
20
20
|
```
|
21
21
|
schubmult_py 1 2 4 9 11 6 8 12 3 5 7 10 - 6 8 1 2 3 4 7 10 12 14 5 9 11 13
|
@@ -50,7 +50,7 @@ schubmult_double -code -coprod 0 1 2 3 - 2 4
|
|
50
50
|
schubmult_yz -code -coprod 0 1 2 3 - 2 4 --display-positive
|
51
51
|
```
|
52
52
|
|
53
|
-
|
53
|
+
schubmult_q_yz has a feature for displaying the coefficients of the divided difference operators in the evaluation of the quantum double Schubert polynomials on the commuting difference operators of Fomin, Gelfand, and Postnikov. It is necessary to cap the value of n in the group S_n we are working in because as n increases the expression does not stabilize.
|
54
54
|
```
|
55
55
|
schubmult_q_yz -nil-hecke 6 -code 2 2 --display-positive
|
56
56
|
```
|
@@ -59,7 +59,7 @@ Runtime will vary tremendously by case. The general problem is #P-hard. Though t
|
|
59
59
|
|
60
60
|
schubmult_py is for multiplying ordinary Schubert polynomials. schubmult_yz is for multiplying double Schubert polynomials in different sets of coefficient variables (labeled y and z), and schubmult_double is for multiplying double Schubert polynomials in the same set of coefficient variables. Similarly, schubmult_q is for multiplying quantum Schubert polynomials, schubmult_q_double is for multiplying quantum double Schubert polynomials in the same set of coefficient variables, and schubmult_q_yz is for multiplying quantum double Schubert polynomials in different sets of coefficient variables, or in other words it computes the Gromov-Witten invariants, equivariant Gromov-Witten invariants, and (mixed?) equivariant Gromov-Witten invariants of the complete flag variety. All have the same command line syntax as schubmult, except when using the -code option. schubmult_double/schubmult_q_double display the result with nonnegative coefficients in terms of the negative simple roots (and the q variables), and schubmult_yz and schubmult_q_yz optionally display the result positively in terms of y_i-z_j (and q) with the --display-positive option.
|
61
61
|
|
62
|
-
|
62
|
+
schubmult_xx -coprod allows you to split (double) Schubert polynomials along certain indices (not available for quantum). It takes one permutation as an argument, followed by a dash -, then the set of indices you would like to split on. These coefficients are always nonnegative since they occur as product coefficients (this is actually how they are computed).
|
63
63
|
|
64
64
|
When imported as a python package, the relevant packages are schubmult.perm_lib, which has various permutation manipulation functions, and three modules that have functions of the same name (function name is "schubmult"): schubmult.schubmult_py, schubmult.schubmult_yz, schubmult.schubmult_double. Function takes a permutation dictionary (keys are tuples of ints, which must be trimmed permutations, and values are either integers or symengine values, which can also be integers) as well as a permutation as its second argument, which is the (double) Schubert polynomial to multiply by. Returns a dictionary of the same form with the coefficients.
|
65
65
|
|
@@ -76,7 +76,7 @@ from schubmult.schubmult_py import schubmult
|
|
76
76
|
coeff_dict = schubmult({(1,3,4,6,2,5): 1},(2,1,5,7,3,4,6))
|
77
77
|
```
|
78
78
|
|
79
|
-
|
79
|
+
The command line argument --display-positive is available in schubmult_yz and schubmult_q_yz, which displays the result positively (if possible, this is still only always possible conjecturally). It will fail and print out the offending case if it finds a counterexample. This is highly processor intensive.
|
80
80
|
|
81
81
|

|
82
82
|
|
@@ -6,7 +6,7 @@ long_description = (this_directory / "README.md").read_text()
|
|
6
6
|
|
7
7
|
setup(
|
8
8
|
name="schubmult",
|
9
|
-
version="1.
|
9
|
+
version="1.4.1",
|
10
10
|
description="Computing Littlewood-Richardson coefficients of Schubert polynomials",
|
11
11
|
long_description=long_description,
|
12
12
|
long_description_content_type='text/markdown',
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|