schubmult 1.3.2__tar.gz → 1.3.3__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.2 → schubmult-1.3.3}/PKG-INFO +15 -13
- {schubmult-1.3.2 → schubmult-1.3.3}/README.md +14 -12
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/perm_lib.py +22 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_double/schubmult_double.py +7 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_py/schubmult_py.py +2 -0
- schubmult-1.3.3/schubmult/schubmult_q/schubmult_q.py +318 -0
- schubmult-1.3.3/schubmult/schubmult_q_double/__init__.py +1 -0
- schubmult-1.3.3/schubmult/schubmult_q_double/__main__.py +5 -0
- schubmult-1.3.3/schubmult/schubmult_q_double/schubmult_q_double.py +119 -0
- schubmult-1.3.3/schubmult/schubmult_q_yz/__init__.py +1 -0
- schubmult-1.3.3/schubmult/schubmult_q_yz/__main__.py +5 -0
- schubmult-1.3.3/schubmult/schubmult_q_yz/schubmult_q_yz.py +207 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_yz/schubmult_yz.py +10 -4
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult.egg-info/PKG-INFO +15 -13
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult.egg-info/SOURCES.txt +6 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult.egg-info/entry_points.txt +2 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/setup.py +4 -2
- schubmult-1.3.2/schubmult/schubmult_q/schubmult_q.py +0 -105
- {schubmult-1.3.2 → schubmult-1.3.3}/LICENSE +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/__init__.py +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_double/__init__.py +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_double/__main__.py +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_py/__init__.py +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_py/__main__.py +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_q/__init__.py +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_q/__main__.py +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_yz/__init__.py +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult/schubmult_yz/__main__.py +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult.egg-info/dependency_links.txt +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult.egg-info/requires.txt +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/schubmult.egg-info/top_level.txt +0 -0
- {schubmult-1.3.2 → schubmult-1.3.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: schubmult
|
3
|
-
Version: 1.3.
|
3
|
+
Version: 1.3.3
|
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,13 +15,15 @@ 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. Since version 1.3.
|
18
|
+
This is a set of python scripts written by Matt Samuel for computing Littlewood-Richardson coefficients of (ordinary or double) Schubert polynomials. Since version 1.3.3, 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
|
22
22
|
schubmult_double 1 3 4 6 2 5 - 2 1 5 7 3 4 6
|
23
|
-
schubmult_yz 1 3 4 6 2 5 - 2 1 5 7 3 4 6
|
24
|
-
schubmult_q 5 1 4 3 2 -
|
23
|
+
schubmult_yz 1 3 4 6 2 5 - 2 1 5 7 3 4 6 --display-positive
|
24
|
+
schubmult_q 5 1 4 3 2 - 5 1 3 4 2
|
25
|
+
schubmult_q_double 5 1 4 3 2 - 5 1 3 4 2
|
26
|
+
schubmult_q_yz 5 1 4 3 2 - 2 5 1 3 4 --display-positive
|
25
27
|
```
|
26
28
|
|
27
29
|
The same execution with the Lehmer code:
|
@@ -29,28 +31,30 @@ The same execution with the Lehmer code:
|
|
29
31
|
```
|
30
32
|
schubmult_py -code 0 0 1 5 6 2 3 4 - 5 6 0 0 0 0 1 2 3 4
|
31
33
|
schubmult_double -code 0 1 1 2 - 1 0 2 3
|
32
|
-
schubmult_yz -code 0 1 1 2 - 1 0 2 3
|
33
|
-
schubmult_q -code 4 0 2 1 -
|
34
|
+
schubmult_yz -code 0 1 1 2 - 1 0 2 3 --display-positive
|
35
|
+
schubmult_q -code 4 0 2 1 - 4 0 1 1
|
36
|
+
schubmult_q_double -code 4 0 2 1 - 4 0 1 1
|
37
|
+
schubmult_q_yz 5 4 0 2 1 - 1 3 --display-positive
|
34
38
|
```
|
35
39
|
|
36
40
|
For coproducts:
|
37
41
|
```
|
38
42
|
schubmult_py -coprod 1 3 5 7 2 4 6 - 2 4
|
39
43
|
schubmult_double -coprod 1 3 5 7 2 4 6 - 2 4
|
40
|
-
schubmult_yz -coprod 1 3 5 7 2 4 6 - 2 4
|
44
|
+
schubmult_yz -coprod 1 3 5 7 2 4 6 - 2 4 --display-positive
|
41
45
|
```
|
42
46
|
or
|
43
47
|
```
|
44
48
|
schubmult_py -code -coprod 0 1 2 3 - 2 4
|
45
49
|
schubmult_double -code -coprod 0 1 2 3 - 2 4
|
46
|
-
schubmult_yz -code -coprod 0 1 2 3 - 2 4
|
50
|
+
schubmult_yz -code -coprod 0 1 2 3 - 2 4 --display-positive
|
47
51
|
```
|
48
52
|
|
49
53
|
|
50
54
|
|
51
|
-
Runtime will vary tremendously by case. The general problem is #P-hard. Though the result is always nonnegative and the problem is in GapP, it is not known to be in #P at this time.
|
55
|
+
Runtime will vary tremendously by case. The general problem is #P-hard. Though the result is always nonnegative (which at least is known for schubmult_py, schubmult_q, schubmult_double, and schubmult_q_double) and the problem is in GapP, it is not known to be in #P at this time.
|
52
56
|
|
53
|
-
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.
|
57
|
+
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.
|
54
58
|
|
55
59
|
New in version 1.1.0, schubmult_xx -coprod allows you to split (double) Schubert polynomials along certain indices (not available for schubmult_q). 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).
|
56
60
|
|
@@ -69,9 +73,7 @@ from schubmult.schubmult_py import schubmult
|
|
69
73
|
coeff_dict = schubmult({(1,3,4,6,2,5): 1},(2,1,5,7,3,4,6))
|
70
74
|
```
|
71
75
|
|
72
|
-
|
73
|
-
|
74
|
-
Version 1.0.18 adds the command line argument --display-positive to schubmult_yz, which displays the result positively (if possible, this is still only always possible conjecturally). This is highly processor intensive.
|
76
|
+
Version 1.0.18 adds the command line argument --display-positive to schubmult_yz (and version 1.3.3 adds --display-positive to 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.
|
75
77
|
|
76
78
|

|
77
79
|
|
@@ -2,13 +2,15 @@
|
|
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. Since version 1.3.
|
5
|
+
This is a set of python scripts written by Matt Samuel for computing Littlewood-Richardson coefficients of (ordinary or double) Schubert polynomials. Since version 1.3.3, 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
|
9
9
|
schubmult_double 1 3 4 6 2 5 - 2 1 5 7 3 4 6
|
10
|
-
schubmult_yz 1 3 4 6 2 5 - 2 1 5 7 3 4 6
|
11
|
-
schubmult_q 5 1 4 3 2 -
|
10
|
+
schubmult_yz 1 3 4 6 2 5 - 2 1 5 7 3 4 6 --display-positive
|
11
|
+
schubmult_q 5 1 4 3 2 - 5 1 3 4 2
|
12
|
+
schubmult_q_double 5 1 4 3 2 - 5 1 3 4 2
|
13
|
+
schubmult_q_yz 5 1 4 3 2 - 2 5 1 3 4 --display-positive
|
12
14
|
```
|
13
15
|
|
14
16
|
The same execution with the Lehmer code:
|
@@ -16,28 +18,30 @@ The same execution with the Lehmer code:
|
|
16
18
|
```
|
17
19
|
schubmult_py -code 0 0 1 5 6 2 3 4 - 5 6 0 0 0 0 1 2 3 4
|
18
20
|
schubmult_double -code 0 1 1 2 - 1 0 2 3
|
19
|
-
schubmult_yz -code 0 1 1 2 - 1 0 2 3
|
20
|
-
schubmult_q -code 4 0 2 1 -
|
21
|
+
schubmult_yz -code 0 1 1 2 - 1 0 2 3 --display-positive
|
22
|
+
schubmult_q -code 4 0 2 1 - 4 0 1 1
|
23
|
+
schubmult_q_double -code 4 0 2 1 - 4 0 1 1
|
24
|
+
schubmult_q_yz 5 4 0 2 1 - 1 3 --display-positive
|
21
25
|
```
|
22
26
|
|
23
27
|
For coproducts:
|
24
28
|
```
|
25
29
|
schubmult_py -coprod 1 3 5 7 2 4 6 - 2 4
|
26
30
|
schubmult_double -coprod 1 3 5 7 2 4 6 - 2 4
|
27
|
-
schubmult_yz -coprod 1 3 5 7 2 4 6 - 2 4
|
31
|
+
schubmult_yz -coprod 1 3 5 7 2 4 6 - 2 4 --display-positive
|
28
32
|
```
|
29
33
|
or
|
30
34
|
```
|
31
35
|
schubmult_py -code -coprod 0 1 2 3 - 2 4
|
32
36
|
schubmult_double -code -coprod 0 1 2 3 - 2 4
|
33
|
-
schubmult_yz -code -coprod 0 1 2 3 - 2 4
|
37
|
+
schubmult_yz -code -coprod 0 1 2 3 - 2 4 --display-positive
|
34
38
|
```
|
35
39
|
|
36
40
|
|
37
41
|
|
38
|
-
Runtime will vary tremendously by case. The general problem is #P-hard. Though the result is always nonnegative and the problem is in GapP, it is not known to be in #P at this time.
|
42
|
+
Runtime will vary tremendously by case. The general problem is #P-hard. Though the result is always nonnegative (which at least is known for schubmult_py, schubmult_q, schubmult_double, and schubmult_q_double) and the problem is in GapP, it is not known to be in #P at this time.
|
39
43
|
|
40
|
-
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.
|
44
|
+
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.
|
41
45
|
|
42
46
|
New in version 1.1.0, schubmult_xx -coprod allows you to split (double) Schubert polynomials along certain indices (not available for schubmult_q). 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).
|
43
47
|
|
@@ -56,9 +60,7 @@ from schubmult.schubmult_py import schubmult
|
|
56
60
|
coeff_dict = schubmult({(1,3,4,6,2,5): 1},(2,1,5,7,3,4,6))
|
57
61
|
```
|
58
62
|
|
59
|
-
|
60
|
-
|
61
|
-
Version 1.0.18 adds the command line argument --display-positive to schubmult_yz, which displays the result positively (if possible, this is still only always possible conjecturally). This is highly processor intensive.
|
63
|
+
Version 1.0.18 adds the command line argument --display-positive to schubmult_yz (and version 1.3.3 adds --display-positive to 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.
|
62
64
|
|
63
65
|

|
64
66
|
|
@@ -313,6 +313,28 @@ def elem_sym_func(k,i,u1,u2,v1,v2,udiff,vdiff,varl1,varl2):
|
|
313
313
|
zvars = [varl2[i] for i in call_zvars(v1,v2,k,i)]
|
314
314
|
return elem_sym_poly(newk-vdiff,newk,yvars,zvars)
|
315
315
|
|
316
|
+
def elem_sym_func_q(k,i,u1,u2,v1,v2,udiff,vdiff,varl1,varl2):
|
317
|
+
global zero, one
|
318
|
+
newk = k - udiff
|
319
|
+
if newk < vdiff:
|
320
|
+
return zero
|
321
|
+
if newk == vdiff:
|
322
|
+
return one
|
323
|
+
yvars = []
|
324
|
+
mlen = max(len(u1),len(u2))
|
325
|
+
u1 = [*u1] + [a+1 for a in range(len(u1),mlen)]
|
326
|
+
u2 = [*u2] + [a+1 for a in range(len(u2),mlen)]
|
327
|
+
for j in range(min(len(u1),k)):
|
328
|
+
if u1[j]==u2[j]:
|
329
|
+
yvars += [varl1[u2[j]]]
|
330
|
+
for j in range(len(u1),min(k,len(u2))):
|
331
|
+
if u2[j]==j+1:
|
332
|
+
yvars += [varl1[u2[j]]]
|
333
|
+
for j in range(len(u2),k):
|
334
|
+
yvars += [varl1[j+1]]
|
335
|
+
zvars = [varl2[a] for a in call_zvars(v1,v2,k,i)]
|
336
|
+
return elem_sym_poly(newk-vdiff,newk,yvars,zvars)
|
337
|
+
|
316
338
|
def trimcode(perm):
|
317
339
|
cd = code(perm)
|
318
340
|
while len(cd)>0 and cd[-1] == 0:
|
@@ -12,6 +12,8 @@ var2 = symarray('y',n)
|
|
12
12
|
var3 = var2
|
13
13
|
var_r = symarray('r',n)
|
14
14
|
|
15
|
+
var_q = Symbol("q")
|
16
|
+
|
15
17
|
subs_dict = {}
|
16
18
|
|
17
19
|
for i in range(1,n):
|
@@ -20,6 +22,8 @@ for i in range(1,n):
|
|
20
22
|
sm += var_r[j]
|
21
23
|
subs_dict[var2[i]] = sm
|
22
24
|
|
25
|
+
|
26
|
+
|
23
27
|
def main():
|
24
28
|
try:
|
25
29
|
perms=[]
|
@@ -45,12 +49,15 @@ def main():
|
|
45
49
|
continue
|
46
50
|
curperm += [int(s)]
|
47
51
|
except Exception:
|
52
|
+
print("**** schubmult_double ****")
|
53
|
+
print("Purpose: Compute products (and coproducts) of double Schubert polynomials in the same set of variables")
|
48
54
|
print("Usage: schubmult_double <-np|--no-print> <-code> perm1 - perm2 < - perm 3 ... >")
|
49
55
|
print("Alternative usage: schubmult_double <-code> -coprod perm - indexlist")
|
50
56
|
exit(1)
|
51
57
|
|
52
58
|
perms += [curperm]
|
53
59
|
|
60
|
+
|
54
61
|
if coprod:
|
55
62
|
subs_dict_coprod = {}
|
56
63
|
if ascode:
|
@@ -76,6 +76,8 @@ def main():
|
|
76
76
|
continue
|
77
77
|
curperm += [int(s)]
|
78
78
|
except Exception:
|
79
|
+
print("**** schubmult_py ****")
|
80
|
+
print("Purpose: Compute products (and coproducts) of ordinary Schubert polynomials")
|
79
81
|
print("Usage: schubmult_py <-np|--no-print> <-code> perm1 - perm2 <- perm3...>")
|
80
82
|
print("Alternative usage: schubmult_py -coprod <-np> <perm> - <index list>")
|
81
83
|
exit(1)
|
@@ -0,0 +1,318 @@
|
|
1
|
+
from symengine import *
|
2
|
+
from functools import cache
|
3
|
+
from itertools import chain
|
4
|
+
from schubmult.perm_lib import *
|
5
|
+
import schubmult.schubmult_yz as yz
|
6
|
+
import sys
|
7
|
+
|
8
|
+
var = symarray('x', n)
|
9
|
+
var2 = symarray('y',n)
|
10
|
+
var3 = var2
|
11
|
+
var_r = symarray('r',n)
|
12
|
+
|
13
|
+
var_q = Symbol("q")
|
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 schubmult(perm_dict,v):
|
24
|
+
vn1 = inverse(v)
|
25
|
+
th = [len(v)-i for i in range(1,len(v)+1)]
|
26
|
+
mu = permtrim(uncode(th))
|
27
|
+
vmu = permtrim(mulperm([*v],mu))
|
28
|
+
#print(f"{th=} {mu=} {vmu=}")
|
29
|
+
inv_vmu = inv(vmu)
|
30
|
+
inv_mu = inv(mu)
|
31
|
+
ret_dict = {}
|
32
|
+
vpaths = [([(vmu,0)],1)]
|
33
|
+
while th[-1] == 0:
|
34
|
+
th.pop()
|
35
|
+
thL = len(th)
|
36
|
+
vpathdicts = compute_vpathdicts(th,vmu,True)
|
37
|
+
for u,val in perm_dict.items():
|
38
|
+
inv_u = inv(u)
|
39
|
+
vpathsums = {u: {(1,2): val}}
|
40
|
+
for index in range(thL):
|
41
|
+
mx_th = 0
|
42
|
+
for vp in vpathdicts[index]:
|
43
|
+
for v2,vdiff,s in vpathdicts[index][vp]:
|
44
|
+
if th[index]-vdiff > mx_th:
|
45
|
+
mx_th = th[index] - vdiff
|
46
|
+
newpathsums = {}
|
47
|
+
for up in vpathsums:
|
48
|
+
newperms = elem_sym_perms_q(up,mx_th,th[index])
|
49
|
+
for up2, udiff, mul_val in newperms:
|
50
|
+
if up2 not in newpathsums:
|
51
|
+
newpathsums[up2]={}
|
52
|
+
for v in vpathdicts[index]:
|
53
|
+
sumval = vpathsums[up].get(v,zero)
|
54
|
+
if sumval == 0:
|
55
|
+
continue
|
56
|
+
for v2,vdiff,s in vpathdicts[index][v]:
|
57
|
+
if udiff+vdiff==th[index]:
|
58
|
+
newpathsums[up2][v2] = newpathsums[up2].get(v2,zero)+s*sumval*mul_val
|
59
|
+
vpathsums = newpathsums
|
60
|
+
toget = tuple(vmu)
|
61
|
+
ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget,0) for ep in vpathsums},ret_dict)
|
62
|
+
return ret_dict
|
63
|
+
|
64
|
+
var_q = Symbol("q")
|
65
|
+
|
66
|
+
def grass_q_replace(perm,k,d,n):
|
67
|
+
if k-d<0:
|
68
|
+
return None
|
69
|
+
#print("Here")
|
70
|
+
ret = []
|
71
|
+
cd = code(perm)
|
72
|
+
for i in range(k-d,k):
|
73
|
+
if i>=len(cd) or cd[i]<d:
|
74
|
+
return None
|
75
|
+
grass_rep = [0 for i in range(n)]
|
76
|
+
perm2 = [*perm] + [i+1 for i in range(len(perm),n)]
|
77
|
+
for i in range(k,n):
|
78
|
+
grass_rep[perm2[i]-1] = 2
|
79
|
+
num_0 = 0
|
80
|
+
#print(f"{grass_rep=} {d=}")
|
81
|
+
for i in range(len(grass_rep)-1,-1,-1):
|
82
|
+
if num_0 == d:
|
83
|
+
break
|
84
|
+
if grass_rep[i] == 0:
|
85
|
+
grass_rep[i] = 1
|
86
|
+
num_0 += 1
|
87
|
+
num_2 = 0
|
88
|
+
for i in range(len(grass_rep)):
|
89
|
+
if num_2 == d:
|
90
|
+
break
|
91
|
+
if grass_rep[i] == 2:
|
92
|
+
grass_rep[i] = 1
|
93
|
+
num_2 += 1
|
94
|
+
#print(f"New {grass_rep=}")
|
95
|
+
k1 = k - d
|
96
|
+
k2 = k + d
|
97
|
+
pos_1 = 0
|
98
|
+
pos_2 = 0
|
99
|
+
pos_3 = 0
|
100
|
+
new_perm = [0 for i in range(n)]
|
101
|
+
for i in range(len(grass_rep)):
|
102
|
+
if grass_rep[i] == 0:
|
103
|
+
new_perm[pos_1] = i+1
|
104
|
+
pos_1 += 1
|
105
|
+
if grass_rep[i] == 1:
|
106
|
+
new_perm[k1+pos_2] = i+1
|
107
|
+
pos_2 += 1
|
108
|
+
if grass_rep[i] == 2:
|
109
|
+
new_perm[k2+pos_3] = i+1
|
110
|
+
pos_3 += 1
|
111
|
+
return tuple(permtrim(new_perm))
|
112
|
+
|
113
|
+
def to_two_step(perm,k1,k2,n):
|
114
|
+
rep = [0 for i in range(n)]
|
115
|
+
perm2 = [*perm] + [i+1 for i in range(len(perm),n)]
|
116
|
+
for i in range(n):
|
117
|
+
if i<k1:
|
118
|
+
rep[perm2[i]-1] = 0
|
119
|
+
elif i<k2:
|
120
|
+
rep[perm2[i]-1] = 1
|
121
|
+
else:
|
122
|
+
rep[perm2[i]-1] = 2
|
123
|
+
return rep
|
124
|
+
|
125
|
+
def main():
|
126
|
+
try:
|
127
|
+
perms=[]
|
128
|
+
curperm = []
|
129
|
+
|
130
|
+
pr = True
|
131
|
+
ascode = False
|
132
|
+
grass = False
|
133
|
+
grass_q_n = 0
|
134
|
+
equiv = False
|
135
|
+
try:
|
136
|
+
for s in sys.argv[1:]:
|
137
|
+
if s == "-np" or s == "--no-print":
|
138
|
+
pr = False
|
139
|
+
continue
|
140
|
+
if s == "-code":
|
141
|
+
ascode = True
|
142
|
+
continue
|
143
|
+
if s == "-grass":
|
144
|
+
grass = None
|
145
|
+
continue
|
146
|
+
if s == "-equiv":
|
147
|
+
equiv = True
|
148
|
+
continue
|
149
|
+
if grass is None:
|
150
|
+
grass = True
|
151
|
+
grass_q_n = int(s)
|
152
|
+
continue
|
153
|
+
if s == "-":
|
154
|
+
perms += [curperm]
|
155
|
+
curperm = []
|
156
|
+
continue
|
157
|
+
curperm += [int(s)]
|
158
|
+
except Exception:
|
159
|
+
print("**** schubmult_q ****")
|
160
|
+
print("Purpose: Compute the structure constants of quantum Schubert polynomials")
|
161
|
+
print("Usage: schubmult_q <-np|--no-print> <-code> <-grass n> <-equiv> perm1 - perm2 < - perm 3 ... >")
|
162
|
+
print("For the -grass option, must use Grassmannian permutations. -equiv only works together with -grass.")
|
163
|
+
exit(1)
|
164
|
+
|
165
|
+
perms += [curperm]
|
166
|
+
|
167
|
+
|
168
|
+
if grass:
|
169
|
+
perms_t = []
|
170
|
+
if ascode:
|
171
|
+
perms_t = [tuple(permtrim(uncode(perms[i]))) for i in range(len(perms))]
|
172
|
+
else:
|
173
|
+
perms_t = [tuple(permtrim(perms[i])) for i in range(len(perms))]
|
174
|
+
|
175
|
+
k = -1
|
176
|
+
|
177
|
+
for perm in perms_t:
|
178
|
+
desc = -1
|
179
|
+
for i in range(len(perm)-1):
|
180
|
+
if desc != -1 and perm[i]>perm[i+1]:
|
181
|
+
print("Error: permutations must have one descent")
|
182
|
+
exit(1)
|
183
|
+
elif desc == -1:
|
184
|
+
if perm[i]>perm[i+1]:
|
185
|
+
if k != -1 and k != i+1:
|
186
|
+
print("Error: permutations must all have the same descent")
|
187
|
+
exit(1)
|
188
|
+
k = i+1
|
189
|
+
desc = i+1
|
190
|
+
#perms1 = [perms_t[0]]
|
191
|
+
#perms2 = [perms_t[1]]
|
192
|
+
perms1 = []
|
193
|
+
perms2 = []
|
194
|
+
for d in range(100,-1,-1):
|
195
|
+
#print(f"{k=} {d=}")
|
196
|
+
grass_rep_1 = grass_q_replace(perms_t[0],k,d,grass_q_n)
|
197
|
+
grass_rep_2 = grass_q_replace(perms_t[1],k,d,grass_q_n)
|
198
|
+
#print(f"{grass_rep_1} {grass_rep_2}")
|
199
|
+
if grass_rep_1 is None or grass_rep_2 is None:
|
200
|
+
continue
|
201
|
+
perms1 += [grass_rep_1]
|
202
|
+
perms2 += [grass_rep_2]
|
203
|
+
for i in range(len(perms1)):
|
204
|
+
d = len(perms1) - i - 1
|
205
|
+
#print(f"{d=} {perms1[i]=} {perms2[i]=}")
|
206
|
+
if equiv:
|
207
|
+
coeff_dict = yz.schubmult({perms1[i]: 1},perms2[i],var2,var2)
|
208
|
+
else:
|
209
|
+
coeff_dict = yz.schubmult({perms1[i]: 1},perms2[i],[0 for i in range(100)],[0 for i in range(100)])
|
210
|
+
|
211
|
+
#if ascode:
|
212
|
+
# width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys()])
|
213
|
+
#else:
|
214
|
+
# width = max([len(str(perm)) for perm in coeff_dict.keys()])
|
215
|
+
k1 = k - d
|
216
|
+
k2 = k + d
|
217
|
+
coeff_perms = list([key for key in coeff_dict.keys() if len(key)<=grass_q_n])
|
218
|
+
|
219
|
+
coeff_perms.sort(key=lambda x: (inv(x),*x))
|
220
|
+
|
221
|
+
coeff_perms2 = []
|
222
|
+
|
223
|
+
for perm in coeff_perms:
|
224
|
+
two_step = to_two_step(perm,k1,k2,grass_q_n)
|
225
|
+
num_1 = len([i for i in range(len(two_step)) if two_step[i] == 1])
|
226
|
+
if num_1 != 2*d:
|
227
|
+
coeff_perms2 += [None]
|
228
|
+
continue
|
229
|
+
one_step = [*two_step]
|
230
|
+
one_step.reverse()
|
231
|
+
two_step_r = [*two_step]
|
232
|
+
two_step_r.reverse()
|
233
|
+
for i in range(len(one_step)-1,-1,-1):
|
234
|
+
if one_step[i] == 0:
|
235
|
+
break
|
236
|
+
if one_step[i] == 1:
|
237
|
+
one_step[i] = 0
|
238
|
+
no_good = False
|
239
|
+
for i in range(len(one_step)):
|
240
|
+
if one_step[i] == 1:
|
241
|
+
one_step[i] = 2
|
242
|
+
elif one_step[i] == 2:
|
243
|
+
if len([j for j in range(len(one_step)) if one_step[j]==1]) != 0:
|
244
|
+
no_good = True
|
245
|
+
break
|
246
|
+
num_0 = len([i for i in range(len(one_step)) if one_step[i] == 0])
|
247
|
+
if num_0 != k or no_good:
|
248
|
+
#print(f"No good {one_step=} {two_step_r=} {no_good=}")
|
249
|
+
coeff_perms2 += [None]
|
250
|
+
continue
|
251
|
+
pos_0 = 0
|
252
|
+
pos_1 = 0
|
253
|
+
one_step.reverse()
|
254
|
+
#print(f"{two_step=}")
|
255
|
+
#print(f"{one_step=}")
|
256
|
+
grass_perm = [0 for i in range(len(one_step))]
|
257
|
+
for i in range(len(one_step)):
|
258
|
+
if one_step[i] == 0:
|
259
|
+
grass_perm[pos_0] = i+1
|
260
|
+
pos_0 += 1
|
261
|
+
else:
|
262
|
+
grass_perm[k+pos_1] = i+1
|
263
|
+
pos_1 += 1
|
264
|
+
coeff_perms2 += [tuple(permtrim(grass_perm))]
|
265
|
+
|
266
|
+
try:
|
267
|
+
if ascode:
|
268
|
+
width = max([len(str(trimcode(perm))) for perm in coeff_perms2 if perm is not None])
|
269
|
+
else:
|
270
|
+
width = max([len(str(perm)) for perm in coeff_perms2 if perm is not None])
|
271
|
+
except ValueError:
|
272
|
+
continue
|
273
|
+
|
274
|
+
for i in range(len(coeff_perms)):
|
275
|
+
if coeff_perms2[i] is None:
|
276
|
+
continue
|
277
|
+
perm = coeff_perms[i]
|
278
|
+
val = (var_q**d) * sympify(coeff_dict[perm]).subs(subs_dict).expand()
|
279
|
+
|
280
|
+
if val != 0:
|
281
|
+
if ascode:
|
282
|
+
print(f"{str(trimcode(coeff_perms2[i])):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
283
|
+
else:
|
284
|
+
print(f"{str(coeff_perms2[i]):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
285
|
+
#print(f"{str(two_step):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
286
|
+
#else:
|
287
|
+
# print(f"{str(perm):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
288
|
+
else:
|
289
|
+
if ascode:
|
290
|
+
for i in range(len(perms)):
|
291
|
+
perms[i] = uncode(perms[i])
|
292
|
+
|
293
|
+
coeff_dict = {tuple(permtrim([*perms[0]])): 1}
|
294
|
+
|
295
|
+
for perm in perms[1:]:
|
296
|
+
coeff_dict = schubmult(coeff_dict,tuple(permtrim([*perm])))
|
297
|
+
|
298
|
+
if pr:
|
299
|
+
if ascode:
|
300
|
+
width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys() if expand(coeff_dict[perm])!=0])
|
301
|
+
else:
|
302
|
+
width = max([len(str(perm)) for perm in coeff_dict.keys() if expand(coeff_dict[perm])!=0])
|
303
|
+
|
304
|
+
coeff_perms = list(coeff_dict.keys())
|
305
|
+
coeff_perms.sort(key=lambda x: (inv(x),*x))
|
306
|
+
|
307
|
+
for perm in coeff_perms:
|
308
|
+
val = sympify(coeff_dict[perm]).expand()
|
309
|
+
if val != 0:
|
310
|
+
if ascode:
|
311
|
+
print(f"{str(trimcode(perm)):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
312
|
+
else:
|
313
|
+
print(f"{str(perm):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
314
|
+
except BrokenPipeError:
|
315
|
+
pass
|
316
|
+
|
317
|
+
if __name__ == "__main__":
|
318
|
+
main()
|
@@ -0,0 +1 @@
|
|
1
|
+
from .schubmult_q_double import *
|
@@ -0,0 +1,119 @@
|
|
1
|
+
from schubmult.perm_lib import *
|
2
|
+
from schubmult.schubmult_q_yz import schubmult
|
3
|
+
from symengine import *
|
4
|
+
import sys
|
5
|
+
|
6
|
+
|
7
|
+
q_var = symarray("q",100)
|
8
|
+
|
9
|
+
var2 = symarray("y",100)
|
10
|
+
var3 = symarray("z",100)
|
11
|
+
|
12
|
+
var3 = var2
|
13
|
+
var_r = symarray('r',100)
|
14
|
+
|
15
|
+
subs_dict = {}
|
16
|
+
|
17
|
+
for i in range(1,100):
|
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
|
+
|
24
|
+
|
25
|
+
def main():
|
26
|
+
global var2
|
27
|
+
try:
|
28
|
+
sys.setrecursionlimit(1000000)
|
29
|
+
|
30
|
+
perms=[]
|
31
|
+
curperm = []
|
32
|
+
|
33
|
+
pr = True
|
34
|
+
display_positive = False
|
35
|
+
ascode = False
|
36
|
+
coprod = False
|
37
|
+
check = True
|
38
|
+
msg = False
|
39
|
+
try:
|
40
|
+
for s in sys.argv[1:]:
|
41
|
+
if s == "-np" or s == "--no-print":
|
42
|
+
pr = False
|
43
|
+
continue
|
44
|
+
if s == "-coprod":
|
45
|
+
coprod = True
|
46
|
+
continue
|
47
|
+
if s == "-nocheck":
|
48
|
+
check = False
|
49
|
+
continue
|
50
|
+
if s == "--display-positive":
|
51
|
+
display_positive = True
|
52
|
+
continue
|
53
|
+
if s == "--optimizer-message":
|
54
|
+
msg = True
|
55
|
+
continue
|
56
|
+
if s == "--version":
|
57
|
+
print(f"Python version {sys.version}")
|
58
|
+
exit(0)
|
59
|
+
if s == "-code":
|
60
|
+
ascode = True
|
61
|
+
continue
|
62
|
+
if s == "--usage":
|
63
|
+
print("Usage: schubmult_yz <-np|--no-print> <-code> <--display-positive> <--optimizer-message> perm1 - perm2 < - perm3 .. >")
|
64
|
+
print("Alternative usage: schubmult_yz <-code> <--display-positive> -coprod perm - indexlist")
|
65
|
+
exit(0)
|
66
|
+
if s == "-":
|
67
|
+
perms += [curperm]
|
68
|
+
curperm = []
|
69
|
+
continue
|
70
|
+
curperm += [int(s)]
|
71
|
+
except Exception:
|
72
|
+
print("Usage: schubmult_q_yz <-np|--no-print> <-code> <--display-positive> <--optimizer-message> perm1 - perm2 < - perm3 .. >")
|
73
|
+
print("Alternative usage: schubmult_yz <-code> <--display-positive> <--optimizer-message> -coprod perm - indexlist")
|
74
|
+
exit(1)
|
75
|
+
|
76
|
+
perms += [curperm]
|
77
|
+
|
78
|
+
|
79
|
+
if ascode:
|
80
|
+
for i in range(len(perms)):
|
81
|
+
perms[i] = tuple(permtrim(uncode(perms[i])))
|
82
|
+
else:
|
83
|
+
for i in range(len(perms)):
|
84
|
+
perms[i] = tuple(permtrim([*perms[i]]))
|
85
|
+
|
86
|
+
size = 0
|
87
|
+
L = len(perms)
|
88
|
+
|
89
|
+
coeff_dict = {perms[0]: 1}
|
90
|
+
for perm in perms[1:]:
|
91
|
+
coeff_dict = schubmult(coeff_dict,perm,var2,var2)
|
92
|
+
|
93
|
+
if pr:
|
94
|
+
if ascode:
|
95
|
+
width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys() if expand(sympify(coeff_dict[perm]).subs(subs_dict))!=0])
|
96
|
+
else:
|
97
|
+
width = max([len(str(perm)) for perm in coeff_dict.keys() if expand(sympify(coeff_dict[perm]).subs(subs_dict))!=0])
|
98
|
+
|
99
|
+
coeff_perms = list(coeff_dict.keys())
|
100
|
+
coeff_perms.sort(key=lambda x: (inv(x),*x))
|
101
|
+
|
102
|
+
for perm in coeff_perms:
|
103
|
+
val = expand(sympify(coeff_dict[perm]).subs(subs_dict)).simplify()
|
104
|
+
if val != 0:
|
105
|
+
notint = False
|
106
|
+
try:
|
107
|
+
int(val)
|
108
|
+
except Exception:
|
109
|
+
notint = True
|
110
|
+
if val!=0:
|
111
|
+
if ascode:
|
112
|
+
print(f"{str(trimcode(perm)):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
113
|
+
else:
|
114
|
+
print(f"{str(perm):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
115
|
+
except BrokenPipeError:
|
116
|
+
pass
|
117
|
+
|
118
|
+
if __name__ == "__main__":
|
119
|
+
main()
|
@@ -0,0 +1 @@
|
|
1
|
+
from .schubmult_q_yz import *
|
@@ -0,0 +1,207 @@
|
|
1
|
+
from schubmult.perm_lib import *
|
2
|
+
from schubmult.schubmult_yz import compute_positive_rep
|
3
|
+
from symengine import *
|
4
|
+
import sys
|
5
|
+
|
6
|
+
|
7
|
+
#q_var = symarray("q",100)
|
8
|
+
|
9
|
+
var2 = symarray("y",100)
|
10
|
+
var3 = symarray("z",100)
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
def schubmult(perm_dict,v,var2=var2,var3=var3):
|
18
|
+
vn1 = inverse(v)
|
19
|
+
th = [len(v)-i for i in range(1,len(v))]
|
20
|
+
mu = permtrim(uncode(th))
|
21
|
+
vmu = permtrim(mulperm([*v],mu))
|
22
|
+
inv_vmu = inv(vmu)
|
23
|
+
inv_mu = inv(mu)
|
24
|
+
ret_dict = {}
|
25
|
+
vpaths = [([(vmu,0)],1)]
|
26
|
+
while th[-1] == 0:
|
27
|
+
th.pop()
|
28
|
+
thL = len(th)
|
29
|
+
vpathdicts = compute_vpathdicts(th,vmu,True)
|
30
|
+
for u,val in perm_dict.items():
|
31
|
+
inv_u = inv(u)
|
32
|
+
vpathsums = {u: {(1,2): val}}
|
33
|
+
for index in range(thL):
|
34
|
+
mx_th = 0
|
35
|
+
for vp in vpathdicts[index]:
|
36
|
+
for v2,vdiff,s in vpathdicts[index][vp]:
|
37
|
+
if th[index]-vdiff > mx_th:
|
38
|
+
mx_th = th[index] - vdiff
|
39
|
+
newpathsums = {}
|
40
|
+
for up in vpathsums:
|
41
|
+
inv_up = inv(up)
|
42
|
+
newperms = elem_sym_perms_q(up,mx_th,th[index])
|
43
|
+
for up2, udiff,mul_val in newperms:
|
44
|
+
if up2 not in newpathsums:
|
45
|
+
newpathsums[up2]={}
|
46
|
+
for v in vpathdicts[index]:
|
47
|
+
sumval = vpathsums[up].get(v,zero)*mul_val
|
48
|
+
if sumval == 0:
|
49
|
+
continue
|
50
|
+
for v2,vdiff,s in vpathdicts[index][v]:
|
51
|
+
#print(f"{code(up2)=} {elem_sym_func_q(th[index],index+1,up,up2,v,v2,udiff,vdiff,var2,var3)=} {mul_val=} {sumval=}")
|
52
|
+
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)
|
53
|
+
vpathsums = newpathsums
|
54
|
+
toget = tuple(vmu)
|
55
|
+
ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget,0) for ep in vpathsums},ret_dict)
|
56
|
+
return ret_dict
|
57
|
+
|
58
|
+
def factor_out_q(poly):
|
59
|
+
coeff_dict = expand(poly).as_coefficients_dict()
|
60
|
+
ret = {}
|
61
|
+
q_var2 = q_var.tolist()
|
62
|
+
for key in coeff_dict:
|
63
|
+
coeff = coeff_dict[key]
|
64
|
+
if coeff == 0:
|
65
|
+
continue
|
66
|
+
q_part = 1
|
67
|
+
yz_part = coeff
|
68
|
+
if isinstance(key,Mul):
|
69
|
+
for var_maybe_pow in key.args:
|
70
|
+
if isinstance(var_maybe_pow,Pow):
|
71
|
+
real_var = var_maybe_pow.args[0]
|
72
|
+
if real_var in q_var2:
|
73
|
+
q_part*=var_maybe_pow
|
74
|
+
else:
|
75
|
+
yz_part*=var_maybe_pow
|
76
|
+
else:
|
77
|
+
real_var = var_maybe_pow
|
78
|
+
if real_var in q_var2:
|
79
|
+
q_part*=var_maybe_pow
|
80
|
+
else:
|
81
|
+
yz_part*=var_maybe_pow
|
82
|
+
elif isinstance(key,Pow):
|
83
|
+
real_var = key.args[0]
|
84
|
+
if real_var in q_var2:
|
85
|
+
q_part*=key
|
86
|
+
else:
|
87
|
+
yz_part*=key
|
88
|
+
else:
|
89
|
+
if key in q_var2:
|
90
|
+
q_part *= key
|
91
|
+
else:
|
92
|
+
yz_part*=key
|
93
|
+
|
94
|
+
ret[q_part] = ret.get(q_part,0) + yz_part
|
95
|
+
return ret
|
96
|
+
def main():
|
97
|
+
global var2
|
98
|
+
try:
|
99
|
+
sys.setrecursionlimit(1000000)
|
100
|
+
|
101
|
+
perms=[]
|
102
|
+
curperm = []
|
103
|
+
|
104
|
+
pr = True
|
105
|
+
display_positive = False
|
106
|
+
ascode = False
|
107
|
+
coprod = False
|
108
|
+
check = True
|
109
|
+
msg = False
|
110
|
+
try:
|
111
|
+
for s in sys.argv[1:]:
|
112
|
+
if s == "-np" or s == "--no-print":
|
113
|
+
pr = False
|
114
|
+
continue
|
115
|
+
if s == "-coprod":
|
116
|
+
coprod = True
|
117
|
+
continue
|
118
|
+
if s == "-nocheck":
|
119
|
+
check = False
|
120
|
+
continue
|
121
|
+
if s == "--display-positive":
|
122
|
+
display_positive = True
|
123
|
+
continue
|
124
|
+
if s == "--optimizer-message":
|
125
|
+
msg = True
|
126
|
+
continue
|
127
|
+
if s == "--version":
|
128
|
+
print(f"Python version {sys.version}")
|
129
|
+
exit(0)
|
130
|
+
if s == "-code":
|
131
|
+
ascode = True
|
132
|
+
continue
|
133
|
+
if s == "--usage":
|
134
|
+
print("Usage: schubmult_yz <-np|--no-print> <-code> <--display-positive> <--optimizer-message> perm1 - perm2 < - perm3 .. >")
|
135
|
+
print("Alternative usage: schubmult_yz <-code> <--display-positive> -coprod perm - indexlist")
|
136
|
+
exit(0)
|
137
|
+
if s == "-":
|
138
|
+
perms += [curperm]
|
139
|
+
curperm = []
|
140
|
+
continue
|
141
|
+
curperm += [int(s)]
|
142
|
+
except Exception:
|
143
|
+
print("Usage: schubmult_q_yz <-np|--no-print> <-code> <--display-positive> <--optimizer-message> perm1 - perm2 < - perm3 .. >")
|
144
|
+
print("Alternative usage: schubmult_yz <-code> <--display-positive> <--optimizer-message> -coprod perm - indexlist")
|
145
|
+
exit(1)
|
146
|
+
|
147
|
+
perms += [curperm]
|
148
|
+
|
149
|
+
|
150
|
+
if ascode:
|
151
|
+
for i in range(len(perms)):
|
152
|
+
perms[i] = tuple(permtrim(uncode(perms[i])))
|
153
|
+
else:
|
154
|
+
for i in range(len(perms)):
|
155
|
+
perms[i] = tuple(permtrim([*perms[i]]))
|
156
|
+
|
157
|
+
size = 0
|
158
|
+
L = len(perms)
|
159
|
+
|
160
|
+
coeff_dict = {perms[0]: 1}
|
161
|
+
for perm in perms[1:]:
|
162
|
+
coeff_dict = schubmult(coeff_dict,perm)
|
163
|
+
|
164
|
+
if pr:
|
165
|
+
if ascode:
|
166
|
+
width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys() if expand(coeff_dict[perm])!=0])
|
167
|
+
else:
|
168
|
+
width = max([len(str(perm)) for perm in coeff_dict.keys() if expand(coeff_dict[perm])!=0])
|
169
|
+
|
170
|
+
coeff_perms = list(coeff_dict.keys())
|
171
|
+
coeff_perms.sort(key=lambda x: (inv(x),*x))
|
172
|
+
|
173
|
+
for perm in coeff_perms:
|
174
|
+
val = sympify(coeff_dict[perm]).simplify()
|
175
|
+
if val != 0:
|
176
|
+
notint = False
|
177
|
+
try:
|
178
|
+
int(val)
|
179
|
+
except Exception:
|
180
|
+
notint = True
|
181
|
+
val2 = 0
|
182
|
+
if display_positive:
|
183
|
+
q_dict = factor_out_q(val)
|
184
|
+
for q_part in q_dict:
|
185
|
+
#print(f"{q_part=} {q_dict[q_part]=}")
|
186
|
+
try:
|
187
|
+
val2 += q_part*int(q_dict[q_part])
|
188
|
+
except Exception:
|
189
|
+
try:
|
190
|
+
val2 += q_part*compute_positive_rep(q_dict[q_part],var2,var3,msg,False)
|
191
|
+
except TypeError:
|
192
|
+
print(f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_coeff_dict.get(perm,0)=}")
|
193
|
+
exit(1)
|
194
|
+
if check and expand(val - val2)!=0:
|
195
|
+
print(f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_coeff_dict.get(perm,0)=}")
|
196
|
+
exit(1)
|
197
|
+
val = val2
|
198
|
+
if val!=0:
|
199
|
+
if ascode:
|
200
|
+
print(f"{str(trimcode(perm)):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
201
|
+
else:
|
202
|
+
print(f"{str(perm):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
203
|
+
except BrokenPipeError:
|
204
|
+
pass
|
205
|
+
|
206
|
+
if __name__ == "__main__":
|
207
|
+
main()
|
@@ -1327,6 +1327,8 @@ def main():
|
|
1327
1327
|
continue
|
1328
1328
|
curperm += [int(s)]
|
1329
1329
|
except Exception:
|
1330
|
+
print("**** schubmult_yz ****")
|
1331
|
+
print("Purpose: Compute products (and coproducts) of double Schubert polynomials in different sets of variables")
|
1330
1332
|
print("Usage: schubmult_yz <-np|--no-print> <-code> <--display-positive> <--optimizer-message> perm1 - perm2 < - perm3 .. >")
|
1331
1333
|
print("Alternative usage: schubmult_yz <-code> <--display-positive> <--optimizer-message> -coprod perm - indexlist")
|
1332
1334
|
exit(1)
|
@@ -1510,10 +1512,14 @@ def main():
|
|
1510
1512
|
notint = True
|
1511
1513
|
if notint and display_positive:
|
1512
1514
|
valu = val
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1515
|
+
try:
|
1516
|
+
if len(perms) == 2 and not posified:
|
1517
|
+
val = posify(val,perms[0],perms[1],perm,var2,var3,msg)
|
1518
|
+
elif not posified:
|
1519
|
+
val = compute_positive_rep(val,var2,var3,msg)
|
1520
|
+
except TypeError:
|
1521
|
+
print(f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_coeff_dict.get(perm,0)=}")
|
1522
|
+
exit(1)
|
1517
1523
|
if check and expand(val - check_coeff_dict.get(perm,0))!=0:
|
1518
1524
|
print(f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_coeff_dict.get(perm,0)=}")
|
1519
1525
|
exit(1)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: schubmult
|
3
|
-
Version: 1.3.
|
3
|
+
Version: 1.3.3
|
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,13 +15,15 @@ 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. Since version 1.3.
|
18
|
+
This is a set of python scripts written by Matt Samuel for computing Littlewood-Richardson coefficients of (ordinary or double) Schubert polynomials. Since version 1.3.3, 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
|
22
22
|
schubmult_double 1 3 4 6 2 5 - 2 1 5 7 3 4 6
|
23
|
-
schubmult_yz 1 3 4 6 2 5 - 2 1 5 7 3 4 6
|
24
|
-
schubmult_q 5 1 4 3 2 -
|
23
|
+
schubmult_yz 1 3 4 6 2 5 - 2 1 5 7 3 4 6 --display-positive
|
24
|
+
schubmult_q 5 1 4 3 2 - 5 1 3 4 2
|
25
|
+
schubmult_q_double 5 1 4 3 2 - 5 1 3 4 2
|
26
|
+
schubmult_q_yz 5 1 4 3 2 - 2 5 1 3 4 --display-positive
|
25
27
|
```
|
26
28
|
|
27
29
|
The same execution with the Lehmer code:
|
@@ -29,28 +31,30 @@ The same execution with the Lehmer code:
|
|
29
31
|
```
|
30
32
|
schubmult_py -code 0 0 1 5 6 2 3 4 - 5 6 0 0 0 0 1 2 3 4
|
31
33
|
schubmult_double -code 0 1 1 2 - 1 0 2 3
|
32
|
-
schubmult_yz -code 0 1 1 2 - 1 0 2 3
|
33
|
-
schubmult_q -code 4 0 2 1 -
|
34
|
+
schubmult_yz -code 0 1 1 2 - 1 0 2 3 --display-positive
|
35
|
+
schubmult_q -code 4 0 2 1 - 4 0 1 1
|
36
|
+
schubmult_q_double -code 4 0 2 1 - 4 0 1 1
|
37
|
+
schubmult_q_yz 5 4 0 2 1 - 1 3 --display-positive
|
34
38
|
```
|
35
39
|
|
36
40
|
For coproducts:
|
37
41
|
```
|
38
42
|
schubmult_py -coprod 1 3 5 7 2 4 6 - 2 4
|
39
43
|
schubmult_double -coprod 1 3 5 7 2 4 6 - 2 4
|
40
|
-
schubmult_yz -coprod 1 3 5 7 2 4 6 - 2 4
|
44
|
+
schubmult_yz -coprod 1 3 5 7 2 4 6 - 2 4 --display-positive
|
41
45
|
```
|
42
46
|
or
|
43
47
|
```
|
44
48
|
schubmult_py -code -coprod 0 1 2 3 - 2 4
|
45
49
|
schubmult_double -code -coprod 0 1 2 3 - 2 4
|
46
|
-
schubmult_yz -code -coprod 0 1 2 3 - 2 4
|
50
|
+
schubmult_yz -code -coprod 0 1 2 3 - 2 4 --display-positive
|
47
51
|
```
|
48
52
|
|
49
53
|
|
50
54
|
|
51
|
-
Runtime will vary tremendously by case. The general problem is #P-hard. Though the result is always nonnegative and the problem is in GapP, it is not known to be in #P at this time.
|
55
|
+
Runtime will vary tremendously by case. The general problem is #P-hard. Though the result is always nonnegative (which at least is known for schubmult_py, schubmult_q, schubmult_double, and schubmult_q_double) and the problem is in GapP, it is not known to be in #P at this time.
|
52
56
|
|
53
|
-
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.
|
57
|
+
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.
|
54
58
|
|
55
59
|
New in version 1.1.0, schubmult_xx -coprod allows you to split (double) Schubert polynomials along certain indices (not available for schubmult_q). 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).
|
56
60
|
|
@@ -69,9 +73,7 @@ from schubmult.schubmult_py import schubmult
|
|
69
73
|
coeff_dict = schubmult({(1,3,4,6,2,5): 1},(2,1,5,7,3,4,6))
|
70
74
|
```
|
71
75
|
|
72
|
-
|
73
|
-
|
74
|
-
Version 1.0.18 adds the command line argument --display-positive to schubmult_yz, which displays the result positively (if possible, this is still only always possible conjecturally). This is highly processor intensive.
|
76
|
+
Version 1.0.18 adds the command line argument --display-positive to schubmult_yz (and version 1.3.3 adds --display-positive to 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.
|
75
77
|
|
76
78
|

|
77
79
|
|
@@ -19,6 +19,12 @@ schubmult/schubmult_py/schubmult_py.py
|
|
19
19
|
schubmult/schubmult_q/__init__.py
|
20
20
|
schubmult/schubmult_q/__main__.py
|
21
21
|
schubmult/schubmult_q/schubmult_q.py
|
22
|
+
schubmult/schubmult_q_double/__init__.py
|
23
|
+
schubmult/schubmult_q_double/__main__.py
|
24
|
+
schubmult/schubmult_q_double/schubmult_q_double.py
|
25
|
+
schubmult/schubmult_q_yz/__init__.py
|
26
|
+
schubmult/schubmult_q_yz/__main__.py
|
27
|
+
schubmult/schubmult_q_yz/schubmult_q_yz.py
|
22
28
|
schubmult/schubmult_yz/__init__.py
|
23
29
|
schubmult/schubmult_yz/__main__.py
|
24
30
|
schubmult/schubmult_yz/schubmult_yz.py
|
@@ -2,5 +2,7 @@
|
|
2
2
|
schubmult_double = schubmult.schubmult_double.__main__:main
|
3
3
|
schubmult_py = schubmult.schubmult_py.__main__:main
|
4
4
|
schubmult_q = schubmult.schubmult_q.__main__:main
|
5
|
+
schubmult_q_double = schubmult.schubmult_q_double.__main__:main
|
6
|
+
schubmult_q_yz = schubmult.schubmult_q_yz.__main__:main
|
5
7
|
schubmult_yz = schubmult.schubmult_yz.__main__:main
|
6
8
|
|
@@ -6,7 +6,7 @@ long_description = (this_directory / "README.md").read_text()
|
|
6
6
|
|
7
7
|
setup(
|
8
8
|
name="schubmult",
|
9
|
-
version="1.3.
|
9
|
+
version="1.3.3",
|
10
10
|
description="Computing Littlewood-Richardson coefficients of Schubert polynomials",
|
11
11
|
long_description=long_description,
|
12
12
|
long_description_content_type='text/markdown',
|
@@ -31,6 +31,8 @@ setup(
|
|
31
31
|
entry_points={"console_scripts": ["schubmult_py=schubmult.schubmult_py.__main__:main",
|
32
32
|
"schubmult_double=schubmult.schubmult_double.__main__:main",
|
33
33
|
"schubmult_yz=schubmult.schubmult_yz.__main__:main",
|
34
|
-
"schubmult_q=schubmult.schubmult_q.__main__:main"
|
34
|
+
"schubmult_q=schubmult.schubmult_q.__main__:main",
|
35
|
+
"schubmult_q_double=schubmult.schubmult_q_double.__main__:main",
|
36
|
+
"schubmult_q_yz=schubmult.schubmult_q_yz.__main__:main"
|
35
37
|
]},
|
36
38
|
)
|
@@ -1,105 +0,0 @@
|
|
1
|
-
from symengine import *
|
2
|
-
from functools import cache
|
3
|
-
from itertools import chain
|
4
|
-
from schubmult.perm_lib import *
|
5
|
-
import sys
|
6
|
-
|
7
|
-
def schubmult(perm_dict,v):
|
8
|
-
vn1 = inverse(v)
|
9
|
-
th = [len(v)-i for i in range(1,len(v)+1)]
|
10
|
-
mu = permtrim(uncode(th))
|
11
|
-
vmu = permtrim(mulperm([*v],mu))
|
12
|
-
#print(f"{th=} {mu=} {vmu=}")
|
13
|
-
inv_vmu = inv(vmu)
|
14
|
-
inv_mu = inv(mu)
|
15
|
-
ret_dict = {}
|
16
|
-
vpaths = [([(vmu,0)],1)]
|
17
|
-
while th[-1] == 0:
|
18
|
-
th.pop()
|
19
|
-
thL = len(th)
|
20
|
-
vpathdicts = compute_vpathdicts(th,vmu,True)
|
21
|
-
for u,val in perm_dict.items():
|
22
|
-
inv_u = inv(u)
|
23
|
-
vpathsums = {u: {(1,2): val}}
|
24
|
-
for index in range(thL):
|
25
|
-
mx_th = 0
|
26
|
-
for vp in vpathdicts[index]:
|
27
|
-
for v2,vdiff,s in vpathdicts[index][vp]:
|
28
|
-
if th[index]-vdiff > mx_th:
|
29
|
-
mx_th = th[index] - vdiff
|
30
|
-
newpathsums = {}
|
31
|
-
for up in vpathsums:
|
32
|
-
newperms = elem_sym_perms_q(up,mx_th,th[index])
|
33
|
-
for up2, udiff, mul_val in newperms:
|
34
|
-
if up2 not in newpathsums:
|
35
|
-
newpathsums[up2]={}
|
36
|
-
for v in vpathdicts[index]:
|
37
|
-
sumval = vpathsums[up].get(v,zero)
|
38
|
-
if sumval == 0:
|
39
|
-
continue
|
40
|
-
for v2,vdiff,s in vpathdicts[index][v]:
|
41
|
-
if udiff+vdiff==th[index]:
|
42
|
-
newpathsums[up2][v2] = newpathsums[up2].get(v2,zero)+s*sumval*mul_val
|
43
|
-
vpathsums = newpathsums
|
44
|
-
toget = tuple(vmu)
|
45
|
-
ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget,0) for ep in vpathsums},ret_dict)
|
46
|
-
return ret_dict
|
47
|
-
|
48
|
-
|
49
|
-
def main():
|
50
|
-
try:
|
51
|
-
perms=[]
|
52
|
-
curperm = []
|
53
|
-
|
54
|
-
pr = True
|
55
|
-
ascode = False
|
56
|
-
try:
|
57
|
-
for s in sys.argv[1:]:
|
58
|
-
if s == "-np" or s == "--no-print":
|
59
|
-
pr = False
|
60
|
-
continue
|
61
|
-
if s == "-code":
|
62
|
-
ascode = True
|
63
|
-
continue
|
64
|
-
if s == "-":
|
65
|
-
perms += [curperm]
|
66
|
-
curperm = []
|
67
|
-
continue
|
68
|
-
curperm += [int(s)]
|
69
|
-
except Exception:
|
70
|
-
print("Usage: schubmult_q <-np|--no-print> <-code> perm1 - perm2 < - perm 3 ... >")
|
71
|
-
exit(1)
|
72
|
-
|
73
|
-
perms += [curperm]
|
74
|
-
|
75
|
-
|
76
|
-
if ascode:
|
77
|
-
for i in range(len(perms)):
|
78
|
-
perms[i] = uncode(perms[i])
|
79
|
-
|
80
|
-
coeff_dict = {tuple(permtrim([*perms[0]])): 1}
|
81
|
-
|
82
|
-
for perm in perms[1:]:
|
83
|
-
coeff_dict = schubmult(coeff_dict,tuple(permtrim([*perm])))
|
84
|
-
|
85
|
-
if pr:
|
86
|
-
if ascode:
|
87
|
-
width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys()])
|
88
|
-
else:
|
89
|
-
width = max([len(str(perm)) for perm in coeff_dict.keys()])
|
90
|
-
|
91
|
-
coeff_perms = list(coeff_dict.keys())
|
92
|
-
coeff_perms.sort(key=lambda x: (inv(x),*x))
|
93
|
-
|
94
|
-
for perm in coeff_perms:
|
95
|
-
val = sympify(coeff_dict[perm]).expand()
|
96
|
-
if val != 0:
|
97
|
-
if ascode:
|
98
|
-
print(f"{str(trimcode(perm)):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
99
|
-
else:
|
100
|
-
print(f"{str(perm):>{width}} {str(val).replace('**','^').replace('*',' ')}")
|
101
|
-
except BrokenPipeError:
|
102
|
-
pass
|
103
|
-
|
104
|
-
if __name__ == "__main__":
|
105
|
-
main()
|
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
|