schubmult 1.3.7__tar.gz → 1.3.8__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.7 → schubmult-1.3.8}/PKG-INFO +1 -1
  2. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/perm_lib.py +22 -0
  3. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_double/schubmult_double.py +15 -4
  4. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_py/schubmult_py.py +60 -4
  5. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_q/schubmult_q.py +56 -0
  6. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_q_double/schubmult_q_double.py +13 -2
  7. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_q_yz/schubmult_q_yz.py +85 -12
  8. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_yz/schubmult_yz.py +181 -11
  9. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult.egg-info/PKG-INFO +1 -1
  10. {schubmult-1.3.7 → schubmult-1.3.8}/setup.py +1 -1
  11. {schubmult-1.3.7 → schubmult-1.3.8}/LICENSE +0 -0
  12. {schubmult-1.3.7 → schubmult-1.3.8}/README.md +0 -0
  13. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/__init__.py +0 -0
  14. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_double/__init__.py +0 -0
  15. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_double/__main__.py +0 -0
  16. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_py/__init__.py +0 -0
  17. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_py/__main__.py +0 -0
  18. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_q/__init__.py +0 -0
  19. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_q/__main__.py +0 -0
  20. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_q_double/__init__.py +0 -0
  21. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_q_double/__main__.py +0 -0
  22. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_q_yz/__init__.py +0 -0
  23. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_q_yz/__main__.py +0 -0
  24. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_yz/__init__.py +0 -0
  25. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult/schubmult_yz/__main__.py +0 -0
  26. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult.egg-info/SOURCES.txt +0 -0
  27. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult.egg-info/dependency_links.txt +0 -0
  28. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult.egg-info/entry_points.txt +0 -0
  29. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult.egg-info/requires.txt +0 -0
  30. {schubmult-1.3.7 → schubmult-1.3.8}/schubmult.egg-info/top_level.txt +0 -0
  31. {schubmult-1.3.7 → schubmult-1.3.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: schubmult
3
- Version: 1.3.7
3
+ Version: 1.3.8
4
4
  Summary: Computing Littlewood-Richardson coefficients of Schubert polynomials
5
5
  Home-page: https://github.com/matthematics/schubmult
6
6
  Author: Matt Samuel
@@ -139,6 +139,28 @@ def elem_sym_perms(orig_perm,p,k):
139
139
  up_perm_list = perm_list
140
140
  return total_list
141
141
 
142
+ def elem_sym_perms_op(orig_perm,p,k):
143
+ total_list = [(orig_perm,0)]
144
+ up_perm_list = [(orig_perm,k)]
145
+ for pp in range(p):
146
+ perm_list = []
147
+ for up_perm, last in up_perm_list:
148
+ up_perm2 = [*up_perm]
149
+ if len(up_perm2) < k + 1:
150
+ 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]]
152
+ for j in range(last,len(up_perm2)):
153
+ for i in pos_list:
154
+ if has_bruhat_descent(up_perm2,i,j):
155
+ new_perm = [*up_perm2]
156
+ new_perm[i],new_perm[j] = new_perm[j],new_perm[i]
157
+ new_perm_add = tuple(permtrim(new_perm))
158
+ perm_list += [(new_perm_add,j)]
159
+ total_list+=[(new_perm_add,pp+1)]
160
+ up_perm_list = perm_list
161
+ return total_list
162
+
163
+
142
164
  def strict_theta(u):
143
165
  ret = [*trimcode(u)]
144
166
  did_one = True
@@ -2,7 +2,7 @@ from symengine import *
2
2
  from functools import cache
3
3
  from itertools import chain
4
4
  from schubmult.perm_lib import *
5
- from schubmult.schubmult_yz import schubmult
5
+ from schubmult.schubmult_yz import schubmult, mult_poly
6
6
  import sys
7
7
 
8
8
  n = 100
@@ -17,7 +17,7 @@ var_q = Symbol("q")
17
17
  subs_dict = {}
18
18
 
19
19
  for i in range(1,n):
20
- sm = var_r[0]
20
+ sm = var2[1]
21
21
  for j in range(1,i):
22
22
  sm += var_r[j]
23
23
  subs_dict[var2[i]] = sm
@@ -32,11 +32,16 @@ def main():
32
32
  pr = True
33
33
  ascode = False
34
34
  coprod = False
35
+ mult = False
36
+ mulstring = ""
35
37
  try:
36
38
  for s in sys.argv[1:]:
37
39
  if s == "-np" or s == "--no-print":
38
40
  pr = False
39
41
  continue
42
+ if mult:
43
+ mulstring+=s
44
+ continue
40
45
  if s == "-code":
41
46
  ascode = True
42
47
  continue
@@ -47,11 +52,14 @@ def main():
47
52
  perms += [curperm]
48
53
  curperm = []
49
54
  continue
55
+ if s == "-mult":
56
+ mult = True
57
+ continue
50
58
  curperm += [int(s)]
51
59
  except Exception:
52
60
  print("**** schubmult_double ****")
53
61
  print("Purpose: Compute products (and coproducts) of double Schubert polynomials in the same set of variables")
54
- print("Usage: schubmult_double <-np|--no-print> <-code> perm1 - perm2 < - perm 3 ... >")
62
+ print("Usage: schubmult_double <-np|--no-print> <-code> perm1 - perm2 < - perm 3 ... > <-mult poly>")
55
63
  print("Alternative usage: schubmult_double <-code> -coprod perm - indexlist")
56
64
  exit(1)
57
65
 
@@ -145,7 +153,10 @@ def main():
145
153
 
146
154
  for perm in perms[1:]:
147
155
  coeff_dict = schubmult(coeff_dict,tuple(permtrim([*perm])),var2,var2)
148
-
156
+ if mult:
157
+ mul_exp = sympify(mulstring)
158
+ coeff_dict = mult_poly(coeff_dict,mul_exp)
159
+
149
160
  if pr:
150
161
  if ascode:
151
162
  width = max([len(str(trimcode(perm))) for perm in coeff_dict.keys()])
@@ -2,6 +2,50 @@ import sys
2
2
  from functools import cache
3
3
  from itertools import chain
4
4
  from schubmult.perm_lib import *
5
+ from symengine import *
6
+
7
+ var_x = symarray("x",100).tolist()
8
+
9
+ def single_variable(coeff_dict,varnum):
10
+ ret = {}
11
+ for u in coeff_dict:
12
+ new_perms_k = elem_sym_perms(u,1,varnum)
13
+ new_perms_km1 = []
14
+ if varnum > 1:
15
+ new_perms_km1 = elem_sym_perms(u,1,varnum-1)
16
+ for perm, udiff in new_perms_k:
17
+ if udiff == 1:
18
+ ret[perm] = ret.get(perm,0) + coeff_dict[u]
19
+ for perm, udiff in new_perms_km1:
20
+ if udiff == 1:
21
+ ret[perm] = ret.get(perm,0) - coeff_dict[u]
22
+ return ret
23
+
24
+ def mult_poly(coeff_dict,poly):
25
+ if poly in var_x:
26
+ return single_variable(coeff_dict,var_x.index(poly))
27
+ elif isinstance(poly,Mul):
28
+ ret = coeff_dict
29
+ for a in poly.args:
30
+ ret = mult_poly(ret,a)
31
+ return ret
32
+ elif isinstance(poly,Pow):
33
+ base = poly.args[0]
34
+ exponent = int(poly.args[1])
35
+ ret = coeff_dict
36
+ for i in range(int(exponent)):
37
+ ret = mult_poly(ret,base)
38
+ return ret
39
+ elif isinstance(poly,Add):
40
+ ret = {}
41
+ for a in poly.args:
42
+ ret = add_perm_dict(ret,mult_poly(coeff_dict,a))
43
+ return ret
44
+ else:
45
+ ret = {}
46
+ for perm in coeff_dict:
47
+ ret[perm] = poly*coeff_dict[perm]
48
+ return ret
5
49
 
6
50
  def schubmult(perm_dict,v):
7
51
  vn1 = inverse(v)
@@ -58,9 +102,17 @@ def main():
58
102
  pr = True
59
103
  coprod = False
60
104
  ascode = False
105
+ mult = False
106
+ mulstring = ""
61
107
 
62
108
  try:
63
109
  for s in sys.argv[1:]:
110
+ if mult:
111
+ mulstring += s
112
+ continue
113
+ if s == "-mult":
114
+ mult = True
115
+ continue
64
116
  if s == "-np" or s == "--no-print":
65
117
  pr = False
66
118
  continue
@@ -73,8 +125,9 @@ def main():
73
125
  if s == "-":
74
126
  perms += [tuple(curperm)]
75
127
  curperm = []
76
- continue
77
- curperm += [int(s)]
128
+ continue
129
+ else:
130
+ curperm += [int(s)]
78
131
  except Exception:
79
132
  print("**** schubmult_py ****")
80
133
  print("Purpose: Compute products (and coproducts) of ordinary Schubert polynomials")
@@ -138,11 +191,14 @@ def main():
138
191
 
139
192
 
140
193
  perms.sort(reverse=True,key=lambda x: sum(theta(inverse(x)))-inv(x))
141
-
194
+
142
195
  coeff_dict = {tuple(permtrim([*perms[0]])): 1}
143
-
196
+
144
197
  for perm in perms[1:]:
145
198
  coeff_dict = schubmult(coeff_dict,tuple(permtrim([*perm])))
199
+ if mult:
200
+ mul_exp = sympify(mulstring)
201
+ coeff_dict = mult_poly(coeff_dict,mul_exp)
146
202
 
147
203
  if pr:
148
204
  for perm, val in coeff_dict.items():
@@ -14,6 +14,49 @@ var_q = Symbol("q")
14
14
 
15
15
  subs_dict = {}
16
16
 
17
+ var_x = symarray("x",100).tolist()
18
+
19
+ def single_variable(coeff_dict,varnum):
20
+ ret = {}
21
+ for u in coeff_dict:
22
+ new_perms_k = elem_sym_perms_q(u,1,varnum)
23
+ new_perms_km1 = []
24
+ if varnum > 1:
25
+ new_perms_km1 = elem_sym_perms_q(u,1,varnum-1)
26
+ for perm, udiff, mul_val in new_perms_k:
27
+ if udiff == 1:
28
+ ret[perm] = ret.get(perm,0) + coeff_dict[u]*mul_val
29
+ for perm, udiff, mul_val in new_perms_km1:
30
+ if udiff == 1:
31
+ ret[perm] = ret.get(perm,0) - coeff_dict[u]*mul_val
32
+ return ret
33
+
34
+ def mult_poly(coeff_dict,poly):
35
+ if poly in var_x:
36
+ return single_variable(coeff_dict,var_x.index(poly))
37
+ elif isinstance(poly,Mul):
38
+ ret = coeff_dict
39
+ for a in poly.args:
40
+ ret = mult_poly(ret,a)
41
+ return ret
42
+ elif isinstance(poly,Pow):
43
+ base = poly.args[0]
44
+ exponent = int(poly.args[1])
45
+ ret = coeff_dict
46
+ for i in range(int(exponent)):
47
+ ret = mult_poly(ret,base)
48
+ return ret
49
+ elif isinstance(poly,Add):
50
+ ret = {}
51
+ for a in poly.args:
52
+ ret = add_perm_dict(ret,mult_poly(coeff_dict,a))
53
+ return ret
54
+ else:
55
+ ret = {}
56
+ for perm in coeff_dict:
57
+ ret[perm] = poly*coeff_dict[perm]
58
+ return ret
59
+
17
60
  for i in range(1,n):
18
61
  sm = var_r[0]
19
62
  for j in range(1,i):
@@ -132,11 +175,17 @@ def main():
132
175
  grass = False
133
176
  grass_q_n = 0
134
177
  equiv = False
178
+ mult = False
179
+ mulstring = ""
180
+
135
181
  try:
136
182
  for s in sys.argv[1:]:
137
183
  if s == "-np" or s == "--no-print":
138
184
  pr = False
139
185
  continue
186
+ if mult:
187
+ mulstring += s
188
+ continue
140
189
  if s == "-code":
141
190
  ascode = True
142
191
  continue
@@ -150,6 +199,9 @@ def main():
150
199
  grass = True
151
200
  grass_q_n = int(s)
152
201
  continue
202
+ if s == "-mult":
203
+ mult = True
204
+ continue
153
205
  if s == "-":
154
206
  perms += [curperm]
155
207
  curperm = []
@@ -294,6 +346,10 @@ def main():
294
346
 
295
347
  for perm in perms[1:]:
296
348
  coeff_dict = schubmult(coeff_dict,tuple(permtrim([*perm])))
349
+
350
+ if mult:
351
+ mul_exp = sympify(mulstring)
352
+ coeff_dict = mult_poly(coeff_dict,mul_exp)
297
353
 
298
354
  if pr:
299
355
  if ascode:
@@ -1,5 +1,5 @@
1
1
  from schubmult.perm_lib import *
2
- from schubmult.schubmult_q_yz import schubmult
2
+ from schubmult.schubmult_q_yz import schubmult, mult_poly
3
3
  from symengine import *
4
4
  import sys
5
5
 
@@ -15,7 +15,7 @@ var_r = symarray('r',100)
15
15
  subs_dict = {}
16
16
 
17
17
  for i in range(1,100):
18
- sm = var_r[0]
18
+ sm = var2[1]
19
19
  for j in range(1,i):
20
20
  sm += var_r[j]
21
21
  subs_dict[var2[i]] = sm
@@ -36,11 +36,19 @@ def main():
36
36
  coprod = False
37
37
  check = True
38
38
  msg = False
39
+ mult = False
40
+ mulstring = ""
39
41
  try:
40
42
  for s in sys.argv[1:]:
41
43
  if s == "-np" or s == "--no-print":
42
44
  pr = False
43
45
  continue
46
+ if mult:
47
+ mulstring += s
48
+ continue
49
+ if s == "-mult":
50
+ mult = True
51
+ continue
44
52
  if s == "-nocheck":
45
53
  check = False
46
54
  continue
@@ -89,6 +97,9 @@ def main():
89
97
  coeff_dict = {perms[0]: 1}
90
98
  for perm in perms[1:]:
91
99
  coeff_dict = schubmult(coeff_dict,perm,var2,var2)
100
+ if mult:
101
+ mul_exp = sympify(mulstring)
102
+ coeff_dict = mult_poly(coeff_dict,mul_exp)
92
103
 
93
104
  if pr:
94
105
  if ascode:
@@ -6,9 +6,59 @@ import sys
6
6
  var2 = symarray("y",100)
7
7
  var3 = symarray("z",100)
8
8
 
9
- var_x = symarray("x",100)
9
+ var_y = var2.tolist()
10
+ var_z = var3.tolist()
11
+ var_x = symarray("x",100).tolist()
12
+
13
+ def single_variable(coeff_dict,varnum):
14
+ ret = {}
15
+ for u in coeff_dict:
16
+ if varnum -1 < len(u):
17
+ ret[u] = ret.get(u,0) + var2[u[varnum-1]]*coeff_dict[u]
18
+ else:
19
+ ret[u] = ret.get(u,0) + var2[varnum]*coeff_dict[u]
20
+ new_perms_k = elem_sym_perms_q(u,1,varnum)
21
+ new_perms_km1 = []
22
+ if varnum > 1:
23
+ new_perms_km1 = elem_sym_perms_q(u,1,varnum-1)
24
+ for perm, udiff, mul_val in new_perms_k:
25
+ if udiff == 1:
26
+ ret[perm] = ret.get(perm,0) + coeff_dict[u]*mul_val
27
+ for perm, udiff, mul_val in new_perms_km1:
28
+ if udiff == 1:
29
+ ret[perm] = ret.get(perm,0) - coeff_dict[u]*mul_val
30
+ return ret
31
+
32
+ def mult_poly(coeff_dict,poly):
33
+ if poly in var_x:
34
+ return single_variable(coeff_dict,var_x.index(poly))
35
+ elif isinstance(poly,Mul):
36
+ ret = coeff_dict
37
+ for a in poly.args:
38
+ ret = mult_poly(ret,a)
39
+ return ret
40
+ elif isinstance(poly,Pow):
41
+ base = poly.args[0]
42
+ exponent = int(poly.args[1])
43
+ ret = coeff_dict
44
+ for i in range(int(exponent)):
45
+ ret = mult_poly(ret,base)
46
+ return ret
47
+ elif isinstance(poly,Add):
48
+ ret = {}
49
+ for a in poly.args:
50
+ ret = add_perm_dict(ret,mult_poly(coeff_dict,a))
51
+ return ret
52
+ else:
53
+ ret = {}
54
+ for perm in coeff_dict:
55
+ ret[perm] = poly*coeff_dict[perm]
56
+ return ret
57
+
10
58
 
11
59
  def nil_hecke(perm_dict,v,n,var2=var2,var3=var3):
60
+ if v == (1,2):
61
+ return perm_dict
12
62
  th = strict_theta(inverse(v))
13
63
  mu = permtrim(uncode(th))
14
64
  vmu = permtrim(mulperm([*v],mu))
@@ -51,6 +101,8 @@ def nil_hecke(perm_dict,v,n,var2=var2,var3=var3):
51
101
 
52
102
 
53
103
  def schubmult(perm_dict,v,var2=var2,var3=var3):
104
+ if v == (1,2):
105
+ return perm_dict
54
106
  th = strict_theta(inverse(v))
55
107
  mu = permtrim(uncode(th))
56
108
  vmu = permtrim(mulperm([*v],mu))
@@ -189,7 +241,7 @@ var3_t = tuple(var3.tolist())
189
241
  def print_usage():
190
242
  print("**** schubmult_q_yz ****")
191
243
  print("Purpose: Compute Molev-Sagan coefficients of quantum double Schubert polynomials")
192
- print("Usage: schubmult_q_yz <-np|--no-print> <-code> <--display-positive> <--optimizer-message> perm1 - perm2 < - perm3 .. >")
244
+ print("Usage: schubmult_q_yz <-np|--no-print> <-code> <--display-positive> <--optimizer-message> perm1 - perm2 < - perm3 .. > <-mult poly_expression>")
193
245
  print(" *** Computes products")
194
246
  print("Alternative usage: schubmult_q_yz -nil-hecke n <-code> <--display-positive> perm")
195
247
  print(" *** Computes nil-Hecke representation of quantum double Schubert polynomial, limiting to the group S_n")
@@ -210,9 +262,12 @@ def main():
210
262
  check = True
211
263
  msg = False
212
264
  just_nil = False
265
+ mult = False
213
266
 
214
267
  nil_N = 0
215
268
 
269
+ mulstring = ""
270
+
216
271
  try:
217
272
  for s in sys.argv[1:]:
218
273
  if just_nil:
@@ -222,6 +277,12 @@ def main():
222
277
  if s == "-np" or s == "--no-print":
223
278
  pr = False
224
279
  continue
280
+ if mult:
281
+ mulstring += s
282
+ continue
283
+ if s == "-mult":
284
+ mult = True
285
+ continue
225
286
  if s == "-nocheck":
226
287
  check = False
227
288
  continue
@@ -243,11 +304,11 @@ def main():
243
304
  continue
244
305
  if s == "--usage" or s == "--help":
245
306
  print_usage()
246
- exit(0)
307
+ exit(0)
247
308
  if s == "-":
248
309
  perms += [curperm]
249
310
  curperm = []
250
- continue
311
+ continue
251
312
  curperm += [int(s)]
252
313
  except Exception:
253
314
  print_usage()
@@ -268,11 +329,15 @@ def main():
268
329
 
269
330
  if nilhecke:
270
331
  coeff_dict = nil_hecke({(1,2): 1},perms[0],nil_N)
271
- rep = ("y","x")
332
+ rep = ("y","x")
272
333
  else:
273
334
  coeff_dict = {perms[0]: 1}
274
335
  for perm in perms[1:]:
275
336
  coeff_dict = schubmult(coeff_dict,perm)
337
+ if mult:
338
+ mul_exp = sympify(mulstring)
339
+ coeff_dict = mult_poly(coeff_dict,mul_exp)
340
+ rep = ("","")
276
341
  rep = ("","")
277
342
 
278
343
  if pr:
@@ -301,11 +366,11 @@ def main():
301
366
  val2 += q_part*int(q_dict[q_part])
302
367
  except Exception:
303
368
  try:
304
- if len(perms) == 2 and q_part == 1:
369
+ if len(perms) == 2 and q_part == 1 and not mult:
305
370
  u = permtrim([*perms[0]])
306
371
  v = permtrim([*perms[1]])
307
372
  val2 += posify(q_dict[q_part],tuple(u),tuple(v),perm,var2_t,var3_t,msg,False)
308
- elif len(perms) == 2 and q_part in q_var2:
373
+ elif len(perms) == 2 and q_part in q_var2 and not mult:
309
374
  i = q_var2.index(q_part)
310
375
  u = permtrim([*perms[0]])
311
376
  v = permtrim([*perms[1]])
@@ -318,12 +383,20 @@ def main():
318
383
  else:
319
384
  val2 += q_part*compute_positive_rep(q_dict[q_part],var2_t,var3_t,msg,False)
320
385
  except Exception as e:
321
- print(f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {coeff_dict.get(perm,0)=}")
322
- print(f"Exception: {e}")
323
- exit(1)
386
+ if mult:
387
+ print("warning; --display-positive is on but result is not positive",file=sys.stderr)
388
+ val2 = val
389
+ break
390
+ else:
391
+ print(f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {coeff_dict.get(perm,0)=}")
392
+ print(f"Exception: {e}")
393
+ exit(1)
324
394
  if check and expand(val - val2)!=0:
325
- print(f"error: value not equal; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {coeff_dict.get(perm,0)=}")
326
- exit(1)
395
+ if mult:
396
+ val2 = val
397
+ else:
398
+ print(f"error: value not equal; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {coeff_dict.get(perm,0)=}")
399
+ exit(1)
327
400
  val = val2
328
401
  if val!=0:
329
402
  if ascode:
@@ -27,6 +27,99 @@ var = tuple(symarray('x',n).tolist())
27
27
  var2 = tuple(symarray('y',n).tolist())
28
28
  var3 = tuple(symarray('z',n).tolist())
29
29
 
30
+ var_x = symarray("x",100).tolist()
31
+
32
+ def single_variable(coeff_dict,varnum):
33
+ ret = {}
34
+ for u in coeff_dict:
35
+ if varnum -1 < len(u):
36
+ ret[u] = ret.get(u,0) + var2[u[varnum-1]]*coeff_dict[u]
37
+ else:
38
+ ret[u] = ret.get(u,0) + var2[varnum]*coeff_dict[u]
39
+ new_perms_k = elem_sym_perms(u,1,varnum)
40
+ new_perms_km1 = []
41
+ if varnum > 1:
42
+ new_perms_km1 = elem_sym_perms(u,1,varnum-1)
43
+ for perm, udiff in new_perms_k:
44
+ if udiff == 1:
45
+ ret[perm] = ret.get(perm,0) + coeff_dict[u]
46
+ for perm, udiff in new_perms_km1:
47
+ if udiff == 1:
48
+ ret[perm] = ret.get(perm,0) - coeff_dict[u]
49
+ return ret
50
+
51
+ def single_variable_down(coeff_dict,varnum):
52
+ ret = {}
53
+ for u in coeff_dict:
54
+ if varnum -1 < len(u):
55
+ ret[u] = ret.get(u,0) + var2[u[varnum-1]]*coeff_dict[u]
56
+ else:
57
+ ret[u] = ret.get(u,0) + var2[varnum]*coeff_dict[u]
58
+ new_perms_k = elem_sym_perms_op(u,1,varnum)
59
+ new_perms_km1 = []
60
+ if varnum > 1:
61
+ new_perms_km1 = elem_sym_perms_op(u,1,varnum-1)
62
+ for perm, udiff in new_perms_k:
63
+ if udiff == 1:
64
+ ret[perm] = ret.get(perm,0) + coeff_dict[u]
65
+ for perm, udiff in new_perms_km1:
66
+ if udiff == 1:
67
+ ret[perm] = ret.get(perm,0) - coeff_dict[u]
68
+ return ret
69
+
70
+
71
+ def mult_poly(coeff_dict,poly):
72
+ if poly in var_x:
73
+ return single_variable(coeff_dict,var_x.index(poly))
74
+ elif isinstance(poly,Mul):
75
+ ret = coeff_dict
76
+ for a in poly.args:
77
+ ret = mult_poly(ret,a)
78
+ return ret
79
+ elif isinstance(poly,Pow):
80
+ base = poly.args[0]
81
+ exponent = int(poly.args[1])
82
+ ret = coeff_dict
83
+ for i in range(int(exponent)):
84
+ ret = mult_poly(ret,base)
85
+ return ret
86
+ elif isinstance(poly,Add):
87
+ ret = {}
88
+ for a in poly.args:
89
+ ret = add_perm_dict(ret,mult_poly(coeff_dict,a))
90
+ return ret
91
+ else:
92
+ ret = {}
93
+ for perm in coeff_dict:
94
+ ret[perm] = poly*coeff_dict[perm]
95
+ return ret
96
+
97
+ def mult_poly_down(coeff_dict,poly):
98
+ if poly in var_x:
99
+ return single_variable_down(coeff_dict,var_x.index(poly))
100
+ elif isinstance(poly,Mul):
101
+ ret = coeff_dict
102
+ for a in poly.args:
103
+ ret = mult_poly_down(ret,a)
104
+ return ret
105
+ elif isinstance(poly,Pow):
106
+ base = poly.args[0]
107
+ exponent = int(poly.args[1])
108
+ ret = coeff_dict
109
+ for i in range(int(exponent)):
110
+ ret = mult_poly_down(ret,base)
111
+ return ret
112
+ elif isinstance(poly,Add):
113
+ ret = {}
114
+ for a in poly.args:
115
+ ret = add_perm_dict(ret,mult_poly_down(coeff_dict,a))
116
+ return ret
117
+ else:
118
+ ret = {}
119
+ for perm in coeff_dict:
120
+ ret[perm] = poly*coeff_dict[perm]
121
+ return ret
122
+
30
123
 
31
124
  def forwardcoeff(u,v,perm,var2=var2,var3=var3):
32
125
  th = theta(v)
@@ -160,6 +253,49 @@ def schubmult(perm_dict,v,var2=var2,var3=var3):
160
253
  ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget,0) for ep in vpathsums},ret_dict)
161
254
  return ret_dict
162
255
 
256
+ def schubmult_down(perm_dict,v,var2=var2,var3=var3):
257
+ vn1 = inverse(v)
258
+ th = theta(vn1)
259
+ if th[0]==0:
260
+ return perm_dict
261
+ mu = permtrim(uncode(th))
262
+ vmu = permtrim(mulperm([*v],mu))
263
+ inv_vmu = inv(vmu)
264
+ inv_mu = inv(mu)
265
+ ret_dict = {}
266
+ vpaths = [([(vmu,0)],1)]
267
+ while th[-1] == 0:
268
+ th.pop()
269
+ thL = len(th)
270
+ vpathdicts = compute_vpathdicts(th,vmu,True)
271
+ for u,val in perm_dict.items():
272
+ inv_u = inv(u)
273
+ vpathsums = {u: {(1,2): val}}
274
+ for index in range(thL):
275
+ mx_th = 0
276
+ for vp in vpathdicts[index]:
277
+ for v2,vdiff,s in vpathdicts[index][vp]:
278
+ if th[index]-vdiff > mx_th:
279
+ mx_th = th[index] - vdiff
280
+ newpathsums = {}
281
+ for up in vpathsums:
282
+ inv_up = inv(up)
283
+ newperms = elem_sym_perms_op(up,mx_th,th[index])
284
+ for up2, udiff in newperms:
285
+ if up2 not in newpathsums:
286
+ newpathsums[up2]={}
287
+ for v in vpathdicts[index]:
288
+ sumval = vpathsums[up].get(v,zero)
289
+ if sumval == 0:
290
+ continue
291
+ for v2,vdiff,s in vpathdicts[index][v]:
292
+ newpathsums[up2][v2] = newpathsums[up2].get(v2,zero)+s*sumval*elem_sym_func(th[index],index+1,up2,up,v,v2,udiff,vdiff,var2,var3)
293
+ vpathsums = newpathsums
294
+ toget = tuple(vmu)
295
+ ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget,0) for ep in vpathsums},ret_dict)
296
+ return ret_dict
297
+
298
+
163
299
  fvar = 0
164
300
 
165
301
  def poly_to_vec(poly,vec0=None):
@@ -1294,11 +1430,24 @@ def main():
1294
1430
  coprod = False
1295
1431
  check = True
1296
1432
  msg = False
1433
+ mult = False
1434
+ mulstring = ""
1435
+ down = False
1436
+
1297
1437
  try:
1298
1438
  for s in sys.argv[1:]:
1299
1439
  if s == "-np" or s == "--no-print":
1300
1440
  pr = False
1301
1441
  continue
1442
+ if mult:
1443
+ mulstring += s
1444
+ continue
1445
+ if s == "-mult":
1446
+ mult = True
1447
+ continue
1448
+ if s == "-down":
1449
+ down = True
1450
+ continue
1302
1451
  if s == "-coprod":
1303
1452
  coprod = True
1304
1453
  continue
@@ -1318,7 +1467,7 @@ def main():
1318
1467
  ascode = True
1319
1468
  continue
1320
1469
  if s == "--usage":
1321
- print("Usage: schubmult_yz <-np|--no-print> <-code> <--display-positive> <--optimizer-message> perm1 - perm2 < - perm3 .. >")
1470
+ print("Usage: schubmult_yz <-np|--no-print> <-code> <--display-positive> <--optimizer-message> perm1 - perm2 < - perm3 .. > <-mult poly_expression>")
1322
1471
  print("Alternative usage: schubmult_yz <-code> <--display-positive> -coprod perm - indexlist")
1323
1472
  exit(0)
1324
1473
  if s == "-":
@@ -1462,9 +1611,22 @@ def main():
1462
1611
 
1463
1612
  coeff_dict = {perms[0]: 1}
1464
1613
  check_coeff_dict = {perms[0]: 1}
1465
- for perm in orig_perms[1:]:
1466
- check_coeff_dict = schubmult(check_coeff_dict,perm)
1467
- if display_positive and len(perms)==2 and will_formula_work(perms[0],perms[1]):
1614
+
1615
+ if down:
1616
+ for perm in orig_perms[1:]:
1617
+ check_coeff_dict = schubmult_down(check_coeff_dict,perm)
1618
+ if mult:
1619
+ mul_exp = sympify(mulstring)
1620
+ check_coeff_dict = mult_poly_down(check_coeff_dict,mul_exp)
1621
+ else:
1622
+ for perm in orig_perms[1:]:
1623
+ check_coeff_dict = schubmult(check_coeff_dict,perm)
1624
+ if mult:
1625
+ mul_exp = sympify(mulstring)
1626
+ check_coeff_dict = mult_poly(check_coeff_dict,mul_exp)
1627
+
1628
+
1629
+ if display_positive and len(perms)==2 and will_formula_work(perms[0],perms[1]) and not mult and not down:
1468
1630
  coeff_dict = {}
1469
1631
  th = theta(perms[1])
1470
1632
  muv = uncode(th)
@@ -1477,7 +1639,7 @@ def main():
1477
1639
  coeff_dict[tuple(permtrim(w))] = val
1478
1640
  posified = True
1479
1641
 
1480
- if display_positive and len(perms)>2:
1642
+ if display_positive and len(perms)>2 and not mult:
1481
1643
  coeff_dict2 = dict(coeff_dict)
1482
1644
  for perm in perms[1:]:
1483
1645
  coeff_dict3 = {}
@@ -1513,13 +1675,21 @@ def main():
1513
1675
  if notint and display_positive:
1514
1676
  valu = val
1515
1677
  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:
1678
+ if len(perms) == 2 and not posified and not mult:
1679
+ if not down:
1680
+ val = posify(val,perms[0],perms[1],perm,var2,var3,msg)
1681
+ else:
1682
+ val = posify(val,perm,perms[1],perms[0],var2,var3,msg)
1683
+ elif not posified and not mult:
1519
1684
  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)
1685
+ elif not posified:
1686
+ val = compute_positive_rep(val,var2,var3,msg,do_pos_neg=False)
1687
+ except Exception:
1688
+ if mult:
1689
+ print(f"warning; --display-positive is on but result is not positive",file=sys.stderr)
1690
+ else:
1691
+ print(f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_coeff_dict.get(perm,0)=}")
1692
+ exit(1)
1523
1693
  if check and expand(val - check_coeff_dict.get(perm,0))!=0:
1524
1694
  print(f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_coeff_dict.get(perm,0)=}")
1525
1695
  exit(1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: schubmult
3
- Version: 1.3.7
3
+ Version: 1.3.8
4
4
  Summary: Computing Littlewood-Richardson coefficients of Schubert polynomials
5
5
  Home-page: https://github.com/matthematics/schubmult
6
6
  Author: Matt Samuel
@@ -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.7",
9
+ version="1.3.8",
10
10
  description="Computing Littlewood-Richardson coefficients of Schubert polynomials",
11
11
  long_description=long_description,
12
12
  long_description_content_type='text/markdown',
File without changes
File without changes
File without changes