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