schubmult 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. schubmult/__init__.py +1 -0
  2. schubmult/_base_argparse.py +174 -0
  3. schubmult/perm_lib.py +999 -0
  4. schubmult/sage_integration/__init__.py +25 -0
  5. schubmult/sage_integration/_fast_double_schubert_polynomial_ring.py +528 -0
  6. schubmult/sage_integration/_fast_schubert_polynomial_ring.py +356 -0
  7. schubmult/sage_integration/_indexing.py +44 -0
  8. schubmult/schubmult_double/__init__.py +18 -0
  9. schubmult/schubmult_double/__main__.py +5 -0
  10. schubmult/schubmult_double/_funcs.py +1590 -0
  11. schubmult/schubmult_double/_script.py +407 -0
  12. schubmult/schubmult_double/_vars.py +16 -0
  13. schubmult/schubmult_py/__init__.py +10 -0
  14. schubmult/schubmult_py/__main__.py +5 -0
  15. schubmult/schubmult_py/_funcs.py +111 -0
  16. schubmult/schubmult_py/_script.py +115 -0
  17. schubmult/schubmult_py/_vars.py +3 -0
  18. schubmult/schubmult_q/__init__.py +12 -0
  19. schubmult/schubmult_q/__main__.py +5 -0
  20. schubmult/schubmult_q/_funcs.py +304 -0
  21. schubmult/schubmult_q/_script.py +157 -0
  22. schubmult/schubmult_q/_vars.py +18 -0
  23. schubmult/schubmult_q_double/__init__.py +14 -0
  24. schubmult/schubmult_q_double/__main__.py +5 -0
  25. schubmult/schubmult_q_double/_funcs.py +507 -0
  26. schubmult/schubmult_q_double/_script.py +337 -0
  27. schubmult/schubmult_q_double/_vars.py +21 -0
  28. schubmult-2.0.0.dist-info/METADATA +455 -0
  29. schubmult-2.0.0.dist-info/RECORD +36 -0
  30. schubmult-2.0.0.dist-info/WHEEL +5 -0
  31. schubmult-2.0.0.dist-info/entry_points.txt +5 -0
  32. schubmult-2.0.0.dist-info/licenses/LICENSE +674 -0
  33. schubmult-2.0.0.dist-info/top_level.txt +2 -0
  34. tests/__init__.py +0 -0
  35. tests/test_fast_double_schubert.py +145 -0
  36. tests/test_fast_schubert.py +38 -0
@@ -0,0 +1,337 @@
1
+ import sys
2
+ import numpy as np
3
+ from ._vars import var_x, var2, var3, var2_t, var3_t
4
+ from ._funcs import schubmult, schubmult_db, mult_poly, nil_hecke, factor_out_q_keep_factored
5
+ from schubmult.schubmult_double import compute_positive_rep, posify, div_diff
6
+ from symengine import expand, sympify, symarray
7
+ from schubmult.perm_lib import (
8
+ inverse,
9
+ medium_theta,
10
+ permtrim,
11
+ inv,
12
+ mulperm,
13
+ uncode,
14
+ q_var,
15
+ q_vector,
16
+ reduce_q_coeff,
17
+ code,
18
+ trimcode,
19
+ longest_element,
20
+ check_blocks,
21
+ is_parabolic,
22
+ count_less_than,
23
+ omega,
24
+ )
25
+ from schubmult._base_argparse import schub_argparse
26
+
27
+
28
+ def _display_full(coeff_dict, args, formatter, posified=None, var2=var2, var3=var3):
29
+ mult = args.mult
30
+
31
+ perms = args.perms
32
+
33
+ ascode = args.ascode
34
+ same = args.same
35
+ check = args.check
36
+ msg = args.msg
37
+ display_positive = args.display_positive
38
+ expa = args.expa
39
+ slow = args.slow
40
+ nilhecke_apply = False
41
+
42
+ coeff_perms = list(coeff_dict.keys())
43
+ coeff_perms.sort(key=lambda x: (inv(x), *x))
44
+
45
+ var_r = symarray("r", 100)
46
+ for perm in coeff_perms:
47
+ val = coeff_dict[perm]
48
+ if not same and expand(val) != 0:
49
+ try:
50
+ int(val)
51
+ except Exception:
52
+ val2 = 0
53
+ if display_positive and not posified and not same:
54
+ q_dict = factor_out_q_keep_factored(val)
55
+ for q_part in q_dict:
56
+ try:
57
+ val2 += q_part * int(q_dict[q_part])
58
+ except Exception:
59
+ try:
60
+ if len(perms) == 2:
61
+ u = tuple(permtrim([*perms[0]]))
62
+ v = tuple(permtrim([*perms[1]]))
63
+ if (
64
+ len(perms) == 2
65
+ and code(inverse(perms[1])) == medium_theta(inverse(perms[1]))
66
+ and not mult
67
+ and not slow
68
+ and not nilhecke_apply
69
+ ):
70
+ val2 += q_part * q_dict[q_part]
71
+ else:
72
+ q_part2 = q_part
73
+ if not mult and not nilhecke_apply and len(perms) == 2:
74
+ qv = q_vector(q_part)
75
+ u2, v2, w2 = u, v, perm
76
+ u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
77
+ while did_one:
78
+ u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
79
+ q_part2 = np.prod(
80
+ [q_var[i + 1] ** qv[i] for i in range(len(qv))]
81
+ )
82
+ if q_part2 == 1:
83
+ # reduced to classical coefficient
84
+ val2 += q_part * posify(
85
+ q_dict[q_part],
86
+ u2,
87
+ v2,
88
+ w2,
89
+ var2_t,
90
+ var3_t,
91
+ msg,
92
+ False,
93
+ )
94
+ else:
95
+ val2 += q_part * compute_positive_rep(
96
+ q_dict[q_part],
97
+ var2_t,
98
+ var3_t,
99
+ msg,
100
+ False,
101
+ )
102
+ else:
103
+ val2 += q_part * compute_positive_rep(
104
+ q_dict[q_part],
105
+ var2_t,
106
+ var3_t,
107
+ msg,
108
+ False,
109
+ )
110
+ except Exception as e:
111
+ if mult:
112
+ print(
113
+ "warning; --display-positive is on but result is not positive",
114
+ file=sys.stderr,
115
+ )
116
+ val2 = val
117
+ break
118
+ else:
119
+ print(
120
+ f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {coeff_dict.get(perm,0)=}"
121
+ )
122
+ print(f"Exception: {e}")
123
+ import traceback
124
+
125
+ traceback.print_exc()
126
+ exit(1)
127
+ if check and expand(val - val2) != 0:
128
+ if mult:
129
+ val2 = val
130
+ else:
131
+ print(
132
+ f"error: value not equal; write to schubmult@gmail.com with the case {perms=} {perm=} {val2=} {coeff_dict.get(perm,0)=}"
133
+ )
134
+ exit(1)
135
+ val = val2
136
+ if same and display_positive:
137
+ if same:
138
+ subs_dict = {}
139
+ for i in range(1, 100):
140
+ sm = var2[1]
141
+ for j in range(1, i):
142
+ sm += var_r[j]
143
+ subs_dict[var2[i]] = sm
144
+ val = sympify(coeff_dict[perm]).subs(subs_dict)
145
+ elif expa:
146
+ val = expand(val)
147
+ if val != 0:
148
+ if ascode:
149
+ print(f"{str(trimcode(perm))} {formatter(val)}")
150
+ else:
151
+ print(f"{str(perm)} {formatter(val)}")
152
+
153
+
154
+ def main():
155
+ global var2, var3
156
+ try:
157
+ sys.setrecursionlimit(1000000)
158
+
159
+ args, formatter = schub_argparse(
160
+ "schubmult_q_double",
161
+ "Compute coefficients of products of quantum double Schubert polynomials in the same or different sets of coefficient variables",
162
+ yz=True,
163
+ quantum=True,
164
+ )
165
+
166
+ mult = args.mult
167
+ mulstring = args.mulstring
168
+
169
+ perms = args.perms
170
+
171
+ ascode = args.ascode
172
+ msg = args.msg
173
+ display_positive = args.display_positive
174
+ pr = args.pr
175
+ parabolic_index = [int(s) for s in args.parabolic]
176
+ parabolic = len(parabolic_index) != 0
177
+ slow = args.slow
178
+ nil_N = 0
179
+ nilhecke = False
180
+ nilhecke_apply = False
181
+ same = args.same
182
+ if same:
183
+ var3 = var2
184
+
185
+ if args.nilhecke is not None:
186
+ nilhecke = True
187
+ nil_N = args.nilhecke
188
+ if args.nilhecke_apply is not None:
189
+ nil_N = args.nilhecke_apply
190
+ nilhecke_apply = True
191
+
192
+ if ascode:
193
+ for i in range(len(perms)):
194
+ perms[i] = tuple(permtrim(uncode(perms[i])))
195
+ else:
196
+ for i in range(len(perms)):
197
+ if len(perms[i]) < 2 and (len(perms[i]) == 0 or perms[i][0] == 1):
198
+ perms[i] = (1, 2)
199
+ perms[i] = tuple(permtrim([*perms[i]]))
200
+
201
+ if nilhecke:
202
+ coeff_dict = nil_hecke({(1, 2): 1}, perms[0], nil_N)
203
+ elif nilhecke_apply:
204
+ coeff_dict0 = nil_hecke({(1, 2): 1}, perms[0], nil_N, var2, var2)
205
+ coeff_dict = {(1, 2): 0}
206
+ for v in coeff_dict0:
207
+ coeff_dict[(1, 2)] += coeff_dict0[v] * div_diff(v, perms[1], var2, var3)
208
+ else:
209
+ coeff_dict = {perms[0]: 1}
210
+ for perm in perms[1:]:
211
+ if not slow:
212
+ coeff_dict = schubmult_db(coeff_dict, perm, var2, var3)
213
+ else:
214
+ coeff_dict = schubmult(coeff_dict, perm, var2, var3)
215
+ if mult:
216
+ for v in var2:
217
+ globals()[str(v)] = v
218
+ for v in var3:
219
+ globals()[str(v)] = v
220
+ for v in var_x:
221
+ globals()[str(v)] = v
222
+ for v in q_var:
223
+ globals()[str(v)] = v
224
+
225
+ mul_exp = eval(mulstring)
226
+ coeff_dict = mult_poly(coeff_dict, mul_exp)
227
+
228
+ posified = False
229
+ if parabolic:
230
+ if display_positive:
231
+ posified = True
232
+ w_P = longest_element(parabolic_index)
233
+ w_P_prime = [1, 2]
234
+ coeff_dict_update = {}
235
+ for w_1 in coeff_dict:
236
+ val = coeff_dict[w_1]
237
+ q_dict = factor_out_q_keep_factored(val)
238
+ for q_part in q_dict:
239
+ qv = q_vector(q_part)
240
+ w = [*w_1]
241
+ good = True
242
+ parabolic_index2 = []
243
+ for i in range(len(parabolic_index)):
244
+ if omega(parabolic_index[i], qv) == 0:
245
+ parabolic_index2 += [parabolic_index[i]]
246
+ elif omega(parabolic_index[i], qv) != -1:
247
+ good = False
248
+ break
249
+ if not good:
250
+ continue
251
+ w_P_prime = longest_element(parabolic_index2)
252
+ if not check_blocks(qv, parabolic_index):
253
+ continue
254
+ w = permtrim(mulperm(mulperm(w, w_P_prime), w_P))
255
+ if not is_parabolic(w, parabolic_index):
256
+ continue
257
+
258
+ w = tuple(permtrim(w))
259
+
260
+ new_q_part = np.prod(
261
+ [
262
+ q_var[index + 1 - count_less_than(parabolic_index, index + 1)]
263
+ ** qv[index]
264
+ for index in range(len(qv))
265
+ if index + 1 not in parabolic_index
266
+ ]
267
+ )
268
+
269
+ try:
270
+ new_q_part = int(new_q_part)
271
+ except Exception:
272
+ pass
273
+ q_val_part = q_dict[q_part]
274
+ if display_positive and not same:
275
+ try:
276
+ q_val_part = int(q_val_part)
277
+ except Exception:
278
+ try:
279
+ if len(perms) == 2 and q_part == 1:
280
+ u = permtrim([*perms[0]])
281
+ v = permtrim([*perms[1]])
282
+ q_val_part = posify(
283
+ q_dict[q_part],
284
+ tuple(u),
285
+ tuple(v),
286
+ w_1,
287
+ var2_t,
288
+ var3_t,
289
+ msg,
290
+ False,
291
+ )
292
+ else:
293
+ qv = q_vector(q_part)
294
+ u2, v2, w2 = perms[0], perms[1], w_1
295
+ u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
296
+ while did_one:
297
+ u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
298
+ q_part2 = np.prod(
299
+ [q_var[i + 1] ** qv[i] for i in range(len(qv))]
300
+ )
301
+ if q_part2 == 1:
302
+ q_val_part = posify(
303
+ q_dict[q_part],
304
+ u2,
305
+ v2,
306
+ w2,
307
+ var2_t,
308
+ var3_t,
309
+ msg,
310
+ False,
311
+ )
312
+ else:
313
+ q_val_part = compute_positive_rep(
314
+ q_dict[q_part],
315
+ var2_t,
316
+ var3_t,
317
+ msg,
318
+ False,
319
+ )
320
+ except Exception as e:
321
+ print(
322
+ f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {q_part*q_val_part=} {coeff_dict.get(w_1,0)=}"
323
+ )
324
+ print(f"Exception: {e}")
325
+ exit(1)
326
+ coeff_dict_update[w] = coeff_dict_update.get(w, 0) + new_q_part * q_val_part
327
+
328
+ coeff_dict = coeff_dict_update
329
+
330
+ if pr:
331
+ _display_full(coeff_dict, args, formatter, posified)
332
+ except BrokenPipeError:
333
+ pass
334
+
335
+
336
+ if __name__ == "__main__":
337
+ main()
@@ -0,0 +1,21 @@
1
+ from symengine import symarray
2
+ from schubmult.perm_lib import q_var
3
+
4
+ var2 = symarray("y", 100)
5
+ var3 = symarray("z", 100)
6
+
7
+ var_y = var2.tolist()
8
+ var_z = var3.tolist()
9
+ var_x = symarray("x", 100).tolist()
10
+
11
+ x = var_x
12
+ y = var_y
13
+ z = var_z
14
+
15
+ q_var2 = q_var.tolist()
16
+
17
+ var2_t = tuple(var2.tolist())
18
+ var3_t = tuple(var3.tolist())
19
+
20
+ n = 100
21
+