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.
- schubmult/__init__.py +1 -0
- schubmult/_base_argparse.py +174 -0
- schubmult/perm_lib.py +999 -0
- schubmult/sage_integration/__init__.py +25 -0
- schubmult/sage_integration/_fast_double_schubert_polynomial_ring.py +528 -0
- schubmult/sage_integration/_fast_schubert_polynomial_ring.py +356 -0
- schubmult/sage_integration/_indexing.py +44 -0
- schubmult/schubmult_double/__init__.py +18 -0
- schubmult/schubmult_double/__main__.py +5 -0
- schubmult/schubmult_double/_funcs.py +1590 -0
- schubmult/schubmult_double/_script.py +407 -0
- schubmult/schubmult_double/_vars.py +16 -0
- schubmult/schubmult_py/__init__.py +10 -0
- schubmult/schubmult_py/__main__.py +5 -0
- schubmult/schubmult_py/_funcs.py +111 -0
- schubmult/schubmult_py/_script.py +115 -0
- schubmult/schubmult_py/_vars.py +3 -0
- schubmult/schubmult_q/__init__.py +12 -0
- schubmult/schubmult_q/__main__.py +5 -0
- schubmult/schubmult_q/_funcs.py +304 -0
- schubmult/schubmult_q/_script.py +157 -0
- schubmult/schubmult_q/_vars.py +18 -0
- schubmult/schubmult_q_double/__init__.py +14 -0
- schubmult/schubmult_q_double/__main__.py +5 -0
- schubmult/schubmult_q_double/_funcs.py +507 -0
- schubmult/schubmult_q_double/_script.py +337 -0
- schubmult/schubmult_q_double/_vars.py +21 -0
- schubmult-2.0.0.dist-info/METADATA +455 -0
- schubmult-2.0.0.dist-info/RECORD +36 -0
- schubmult-2.0.0.dist-info/WHEEL +5 -0
- schubmult-2.0.0.dist-info/entry_points.txt +5 -0
- schubmult-2.0.0.dist-info/licenses/LICENSE +674 -0
- schubmult-2.0.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/test_fast_double_schubert.py +145 -0
- 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
|
+
|