schubmult 2.0.4__py3-none-any.whl → 3.0.1__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 (58) hide show
  1. schubmult/__init__.py +96 -1
  2. schubmult/perm_lib.py +254 -819
  3. schubmult/poly_lib/__init__.py +31 -0
  4. schubmult/poly_lib/poly_lib.py +276 -0
  5. schubmult/poly_lib/schub_poly.py +148 -0
  6. schubmult/poly_lib/variables.py +204 -0
  7. schubmult/rings/__init__.py +18 -0
  8. schubmult/rings/_quantum_schubert_polynomial_ring.py +752 -0
  9. schubmult/rings/_schubert_polynomial_ring.py +1031 -0
  10. schubmult/rings/_tensor_schub_ring.py +128 -0
  11. schubmult/rings/_utils.py +55 -0
  12. schubmult/{sage_integration → sage}/__init__.py +4 -1
  13. schubmult/{sage_integration → sage}/_fast_double_schubert_polynomial_ring.py +67 -109
  14. schubmult/{sage_integration → sage}/_fast_schubert_polynomial_ring.py +33 -28
  15. schubmult/{sage_integration → sage}/_indexing.py +9 -5
  16. schubmult/schub_lib/__init__.py +51 -0
  17. schubmult/{schubmult_double/_funcs.py → schub_lib/double.py} +532 -596
  18. schubmult/{schubmult_q/_funcs.py → schub_lib/quantum.py} +54 -53
  19. schubmult/schub_lib/quantum_double.py +954 -0
  20. schubmult/schub_lib/schub_lib.py +659 -0
  21. schubmult/{schubmult_py/_funcs.py → schub_lib/single.py} +45 -35
  22. schubmult/schub_lib/tests/__init__.py +0 -0
  23. schubmult/schub_lib/tests/legacy_perm_lib.py +946 -0
  24. schubmult/schub_lib/tests/test_vs_old.py +109 -0
  25. schubmult/scripts/__init__.py +0 -0
  26. schubmult/scripts/schubmult_double.py +378 -0
  27. schubmult/scripts/schubmult_py.py +84 -0
  28. schubmult/scripts/schubmult_q.py +109 -0
  29. schubmult/scripts/schubmult_q_double.py +207 -0
  30. schubmult/utils/__init__.py +0 -0
  31. schubmult/{_base_argparse.py → utils/argparse.py} +29 -5
  32. schubmult/utils/logging.py +16 -0
  33. schubmult/utils/parsing.py +20 -0
  34. schubmult/utils/perm_utils.py +135 -0
  35. schubmult/utils/test_utils.py +65 -0
  36. schubmult-3.0.1.dist-info/METADATA +1234 -0
  37. schubmult-3.0.1.dist-info/RECORD +41 -0
  38. {schubmult-2.0.4.dist-info → schubmult-3.0.1.dist-info}/WHEEL +1 -1
  39. schubmult-3.0.1.dist-info/entry_points.txt +5 -0
  40. schubmult/_tests.py +0 -24
  41. schubmult/schubmult_double/__init__.py +0 -12
  42. schubmult/schubmult_double/__main__.py +0 -6
  43. schubmult/schubmult_double/_script.py +0 -474
  44. schubmult/schubmult_py/__init__.py +0 -12
  45. schubmult/schubmult_py/__main__.py +0 -6
  46. schubmult/schubmult_py/_script.py +0 -97
  47. schubmult/schubmult_q/__init__.py +0 -8
  48. schubmult/schubmult_q/__main__.py +0 -6
  49. schubmult/schubmult_q/_script.py +0 -166
  50. schubmult/schubmult_q_double/__init__.py +0 -10
  51. schubmult/schubmult_q_double/__main__.py +0 -6
  52. schubmult/schubmult_q_double/_funcs.py +0 -540
  53. schubmult/schubmult_q_double/_script.py +0 -396
  54. schubmult-2.0.4.dist-info/METADATA +0 -542
  55. schubmult-2.0.4.dist-info/RECORD +0 -30
  56. schubmult-2.0.4.dist-info/entry_points.txt +0 -5
  57. {schubmult-2.0.4.dist-info → schubmult-3.0.1.dist-info}/licenses/LICENSE +0 -0
  58. {schubmult-2.0.4.dist-info → schubmult-3.0.1.dist-info}/top_level.txt +0 -0
@@ -1,396 +0,0 @@
1
- import sys
2
- from functools import cached_property
3
-
4
- import numpy as np
5
- from symengine import expand, symarray, sympify
6
-
7
- from schubmult._base_argparse import schub_argparse
8
- from schubmult.perm_lib import (
9
- check_blocks,
10
- code,
11
- count_less_than,
12
- inv,
13
- inverse,
14
- is_parabolic,
15
- longest_element,
16
- medium_theta,
17
- mulperm,
18
- omega,
19
- permtrim,
20
- q_var,
21
- q_vector,
22
- reduce_q_coeff,
23
- trimcode,
24
- uncode,
25
- )
26
- from schubmult.schubmult_double import compute_positive_rep, div_diff, posify
27
- from schubmult.schubmult_q_double._funcs import (
28
- factor_out_q_keep_factored,
29
- # mult_poly,
30
- nil_hecke,
31
- schubmult,
32
- schubmult_db,
33
- )
34
-
35
-
36
- class _gvars:
37
- @cached_property
38
- def n(self):
39
- return 100
40
-
41
- # @cached_property
42
- # def fvar(self):
43
- # return 100
44
-
45
- @cached_property
46
- def var1(self):
47
- return tuple(symarray("x", self.n).tolist())
48
-
49
- @cached_property
50
- def var2(self):
51
- return tuple(symarray("y", self.n).tolist())
52
-
53
- @cached_property
54
- def var3(self):
55
- return tuple(symarray("z", self.n).tolist())
56
-
57
- @cached_property
58
- def var_r(self):
59
- return symarray("r", 100)
60
-
61
-
62
- _vars = _gvars()
63
-
64
-
65
- def _display_full(coeff_dict, args, formatter, posified=None, var2=_vars.var2, var3=_vars.var3):
66
- raw_result_dict = {}
67
- mult = args.mult
68
-
69
- perms = args.perms
70
-
71
- ascode = args.ascode
72
- same = args.same
73
- check = args.check
74
- msg = args.msg
75
- display_positive = args.display_positive
76
- expa = args.expa
77
- slow = args.slow
78
- nilhecke_apply = False
79
- subs_dict2 = {}
80
- for i in range(1, 100):
81
- sm = var2[1]
82
- for j in range(1, i):
83
- sm += _vars.var_r[j]
84
- subs_dict2[var2[i]] = sm
85
-
86
- coeff_perms = list(coeff_dict.keys())
87
- coeff_perms.sort(key=lambda x: (inv(x), *x))
88
-
89
- for perm in coeff_perms:
90
- val = coeff_dict[perm]
91
- if expand(val) != 0:
92
- try:
93
- int(val)
94
- except Exception:
95
- val2 = 0
96
- if display_positive and not posified:
97
- q_dict = factor_out_q_keep_factored(val)
98
- for q_part in q_dict:
99
- try:
100
- val2 += q_part * int(q_dict[q_part])
101
- except Exception:
102
- if same:
103
- to_add = q_part * expand(sympify(q_dict[q_part]).xreplace(subs_dict2))
104
- val2 += to_add
105
- else:
106
- try:
107
- if len(perms) == 2:
108
- u = tuple(permtrim([*perms[0]]))
109
- v = tuple(permtrim([*perms[1]]))
110
- if (
111
- len(perms) == 2
112
- and code(inverse(perms[1])) == medium_theta(inverse(perms[1]))
113
- and not mult
114
- and not slow
115
- and not nilhecke_apply
116
- ):
117
- val2 += q_part * q_dict[q_part]
118
- else:
119
- q_part2 = q_part
120
- if not mult and not nilhecke_apply and len(perms) == 2:
121
- qv = q_vector(q_part)
122
- u2, v2, w2 = u, v, perm
123
- u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
124
- while did_one:
125
- u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
126
- q_part2 = np.prod(
127
- [q_var[i + 1] ** qv[i] for i in range(len(qv))],
128
- )
129
- if q_part2 == 1:
130
- # reduced to classical coefficient
131
- val2 += q_part * posify(
132
- q_dict[q_part],
133
- u2,
134
- v2,
135
- w2,
136
- var2,
137
- var3,
138
- msg,
139
- False,
140
- )
141
- else:
142
- val2 += q_part * compute_positive_rep(
143
- q_dict[q_part],
144
- var2,
145
- var3,
146
- msg,
147
- False,
148
- )
149
- else:
150
- val2 += q_part * compute_positive_rep(
151
- q_dict[q_part],
152
- var2,
153
- var3,
154
- msg,
155
- False,
156
- )
157
- except Exception as e:
158
- if mult:
159
- print(
160
- "warning; --display-positive is on but result is not positive",
161
- file=sys.stderr,
162
- )
163
- val2 = val
164
- break
165
- print(
166
- f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {coeff_dict.get(perm,0)=}",
167
- )
168
- print(f"Exception: {e}")
169
- import traceback
170
-
171
- traceback.print_exc()
172
- exit(1)
173
- if not same and check and expand(val - val2) != 0:
174
- if mult:
175
- val2 = val
176
- else:
177
- print(
178
- f"error: value not equal; write to schubmult@gmail.com with the case {perms=} {perm=} {val2=} {coeff_dict.get(perm,0)=}",
179
- )
180
- exit(1)
181
- val = val2
182
- if expa:
183
- val = expand(val)
184
- if val != 0:
185
- if ascode:
186
- raw_result_dict[tuple(trimcode(perm))] = val
187
- if formatter:
188
- print(f"{trimcode(perm)!s} {formatter(val)}")
189
- else:
190
- raw_result_dict[tuple(perm)] = val
191
- if formatter:
192
- print(f"{perm!s} {formatter(val)}")
193
- return raw_result_dict
194
-
195
-
196
- def main(argv=None):
197
- if argv is None:
198
- argv = sys.argv
199
- var2 = tuple(symarray("y", 100))
200
- var3 = tuple(symarray("z", 100))
201
- try:
202
- sys.setrecursionlimit(1000000)
203
-
204
- args, formatter = schub_argparse(
205
- "schubmult_q_double",
206
- "Compute coefficients of products of quantum double Schubert polynomials in the same or different sets of coefficient variables",
207
- yz=True,
208
- quantum=True,
209
- argv=argv[1:],
210
- )
211
- subs_dict2 = {}
212
- for i in range(1, 100):
213
- sm = var2[1]
214
- for j in range(1, i):
215
- sm += _vars.var_r[j]
216
- subs_dict2[var2[i]] = sm
217
-
218
- mult = args.mult # noqa: F841
219
- mulstring = args.mulstring # noqa: F841
220
-
221
- perms = args.perms
222
-
223
- ascode = args.ascode
224
- msg = args.msg
225
- display_positive = args.display_positive
226
- pr = args.pr
227
- parabolic_index = [int(s) for s in args.parabolic]
228
- parabolic = len(parabolic_index) != 0
229
- slow = args.slow
230
- nil_N = 0
231
- nilhecke = False
232
- nilhecke_apply = False
233
- same = args.same
234
- if same:
235
- var3 = var2
236
-
237
- if args.nilhecke is not None:
238
- nilhecke = True
239
- nil_N = args.nilhecke
240
- if args.nilhecke_apply is not None:
241
- nil_N = args.nilhecke_apply
242
- nilhecke_apply = True
243
-
244
- if ascode:
245
- for i in range(len(perms)):
246
- perms[i] = tuple(permtrim(uncode(perms[i])))
247
- else:
248
- for i in range(len(perms)):
249
- if len(perms[i]) < 2 and (len(perms[i]) == 0 or perms[i][0] == 1):
250
- perms[i] = (1, 2)
251
- perms[i] = tuple(permtrim([*perms[i]]))
252
-
253
- if nilhecke:
254
- coeff_dict = nil_hecke({(1, 2): 1}, perms[0], nil_N)
255
- elif nilhecke_apply:
256
- coeff_dict0 = nil_hecke({(1, 2): 1}, perms[0], nil_N, var2, var2)
257
- coeff_dict = {(1, 2): 0}
258
- for v in coeff_dict0:
259
- coeff_dict[(1, 2)] += coeff_dict0[v] * div_diff(v, perms[1], var2, var3)
260
- else:
261
- coeff_dict = {perms[0]: 1}
262
- for perm in perms[1:]:
263
- if not slow:
264
- coeff_dict = schubmult_db(coeff_dict, perm, var2, var3)
265
- else:
266
- coeff_dict = schubmult(coeff_dict, perm, var2, var3)
267
- # if mult:
268
- # for v in var2:
269
- # globals()[str(v)] = v
270
- # for v in var3:
271
- # globals()[str(v)] = v
272
- # for v in var_x:
273
- # globals()[str(v)] = v
274
- # for v in q_var:
275
- # globals()[str(v)] = v
276
-
277
- # mul_exp = eval(mulstring)
278
- # coeff_dict = mult_poly(coeff_dict, mul_exp)
279
-
280
- posified = False
281
- if parabolic:
282
- if display_positive:
283
- posified = True
284
- w_P = longest_element(parabolic_index)
285
- w_P_prime = [1, 2]
286
- coeff_dict_update = {}
287
- for w_1 in coeff_dict:
288
- val = coeff_dict[w_1]
289
- q_dict = factor_out_q_keep_factored(val)
290
- for q_part in q_dict:
291
- qv = q_vector(q_part)
292
- w = [*w_1]
293
- good = True
294
- parabolic_index2 = []
295
- for i in range(len(parabolic_index)):
296
- if omega(parabolic_index[i], qv) == 0:
297
- parabolic_index2 += [parabolic_index[i]]
298
- elif omega(parabolic_index[i], qv) != -1:
299
- good = False
300
- break
301
- if not good:
302
- continue
303
- w_P_prime = longest_element(parabolic_index2)
304
- if not check_blocks(qv, parabolic_index):
305
- continue
306
- w = permtrim(mulperm(mulperm(w, w_P_prime), w_P))
307
- if not is_parabolic(w, parabolic_index):
308
- continue
309
-
310
- w = tuple(permtrim(w))
311
-
312
- new_q_part = np.prod(
313
- [
314
- q_var[index + 1 - count_less_than(parabolic_index, index + 1)] ** qv[index]
315
- for index in range(len(qv))
316
- if index + 1 not in parabolic_index
317
- ],
318
- )
319
-
320
- try:
321
- new_q_part = int(new_q_part)
322
- except Exception:
323
- pass
324
- q_val_part = q_dict[q_part]
325
- if display_positive:
326
- try:
327
- q_val_part = int(q_val_part)
328
- except Exception:
329
- if same:
330
- q_val_part = expand(sympify(q_val_part).xreplace(subs_dict2))
331
- else:
332
- try:
333
- if len(perms) == 2 and q_part == 1:
334
- u = permtrim([*perms[0]])
335
- v = permtrim([*perms[1]])
336
- q_val_part = posify(
337
- q_dict[q_part],
338
- tuple(u),
339
- tuple(v),
340
- w_1,
341
- var2,
342
- var3,
343
- msg,
344
- False,
345
- )
346
- else:
347
- qv = q_vector(q_part)
348
- u2, v2, w2 = perms[0], perms[1], w_1
349
- u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
350
- while did_one:
351
- u2, v2, w2, qv, did_one = reduce_q_coeff(u2, v2, w2, qv)
352
- q_part2 = np.prod(
353
- [q_var[i + 1] ** qv[i] for i in range(len(qv))],
354
- )
355
- if q_part2 == 1:
356
- q_val_part = posify(
357
- q_dict[q_part],
358
- u2,
359
- v2,
360
- w2,
361
- var2,
362
- var3,
363
- msg,
364
- False,
365
- )
366
- else:
367
- q_val_part = compute_positive_rep(
368
- q_dict[q_part],
369
- var2,
370
- var3,
371
- msg,
372
- False,
373
- )
374
- except Exception as e:
375
- print(
376
- f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {q_part*q_val_part=} {coeff_dict.get(w_1,0)=}",
377
- )
378
- print(f"Exception: {e}")
379
- exit(1)
380
- coeff_dict_update[w] = coeff_dict_update.get(w, 0) + new_q_part * q_val_part
381
-
382
- coeff_dict = coeff_dict_update
383
-
384
- raw_result_dict = {}
385
- if pr or formatter is None:
386
- raw_result_dict = _display_full(coeff_dict, args, formatter, posified)
387
- if formatter is None:
388
- return raw_result_dict
389
- except BrokenPipeError:
390
- pass
391
-
392
-
393
- if __name__ == "__main__":
394
- import sys
395
-
396
- sys.exit(main(sys.argv))