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.
Files changed (31) hide show
  1. {schubmult-1.3.9 → schubmult-1.4.1}/PKG-INFO +5 -5
  2. {schubmult-1.3.9 → schubmult-1.4.1}/README.md +4 -4
  3. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/perm_lib.py +157 -2
  4. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q/schubmult_q.py +96 -2
  5. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_double/schubmult_q_double.py +9 -2
  6. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_yz/schubmult_q_yz.py +154 -26
  7. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_yz/schubmult_yz.py +16 -2
  8. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/PKG-INFO +5 -5
  9. {schubmult-1.3.9 → schubmult-1.4.1}/setup.py +1 -1
  10. {schubmult-1.3.9 → schubmult-1.4.1}/LICENSE +0 -0
  11. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/__init__.py +0 -0
  12. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_double/__init__.py +0 -0
  13. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_double/__main__.py +0 -0
  14. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_double/schubmult_double.py +0 -0
  15. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_py/__init__.py +0 -0
  16. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_py/__main__.py +0 -0
  17. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_py/schubmult_py.py +0 -0
  18. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q/__init__.py +0 -0
  19. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q/__main__.py +0 -0
  20. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_double/__init__.py +0 -0
  21. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_double/__main__.py +0 -0
  22. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_yz/__init__.py +0 -0
  23. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_q_yz/__main__.py +0 -0
  24. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_yz/__init__.py +0 -0
  25. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult/schubmult_yz/__main__.py +0 -0
  26. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/SOURCES.txt +0 -0
  27. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/dependency_links.txt +0 -0
  28. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/entry_points.txt +0 -0
  29. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/requires.txt +0 -0
  30. {schubmult-1.3.9 → schubmult-1.4.1}/schubmult.egg-info/top_level.txt +0 -0
  31. {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.9
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. 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:
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
- Since version 1.3.7, 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.
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
- 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).
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
- 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.
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
  ![](https://raw.githubusercontent.com/matthematics/schubmult/main/positive_image.png)
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. 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:
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
- Since version 1.3.7, 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.
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
- 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).
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
- 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.
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
  ![](https://raw.githubusercontent.com/matthematics/schubmult/main/positive_image.png)
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[i] == orig_perm[i]]
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
- for perm in perms[1:]:
348
- coeff_dict = schubmult(coeff_dict,tuple(permtrim([*perm])))
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
- coeff_dict = schubmult(coeff_dict,perm,var2,var2)
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
- coeff_dict = schubmult(coeff_dict,perm)
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
- width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys() if expand(coeff_dict[perm])!=0])
368
- else:
369
- width = max([len(str(perm)) for perm in coeff_dict.keys() if expand(coeff_dict[perm])!=0])
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 and q_part == 1 and not mult:
392
- u = permtrim([*perms[0]])
393
- v = permtrim([*perms[1]])
394
- val2 += posify(q_dict[q_part],tuple(u),tuple(v),perm,var2_t,var3_t,msg,False)
395
- elif len(perms) == 2 and q_part in q_var2 and not mult:
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
- val2 += q_part*compute_positive_rep(q_dict[q_part],var2_t,var3_t,msg,False)
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=} {val=} {coeff_dict.get(perm,0)=}")
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)):>{width}} {str(val).replace(*rep)}")
556
+ print(f"{str(trimcode(perm))} {str(val).replace(*rep)}")
429
557
  else:
430
- print(f"{str(trimcode(perm)):>{width}} {str(val).replace('**','^').replace('*',' ').replace(*rep)}")
558
+ print(f"{str(trimcode(perm))} {str(val).replace('**','^').replace('*',' ').replace(*rep)}")
431
559
  else:
432
560
  if norep:
433
- print(f"{str(perm):>{width}} {str(val).replace(*rep)}")
561
+ print(f"{str(perm)} {str(val).replace(*rep)}")
434
562
  else:
435
- print(f"{str(perm):>{width}} {str(val).replace('**','^').replace('*',' ').replace(*rep)}")
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.9
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. 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:
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
- Since version 1.3.7, 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.
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
- 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).
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
- 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.
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
  ![](https://raw.githubusercontent.com/matthematics/schubmult/main/positive_image.png)
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.3.9",
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