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.
- schubmult/__init__.py +96 -1
- schubmult/perm_lib.py +254 -819
- schubmult/poly_lib/__init__.py +31 -0
- schubmult/poly_lib/poly_lib.py +276 -0
- schubmult/poly_lib/schub_poly.py +148 -0
- schubmult/poly_lib/variables.py +204 -0
- schubmult/rings/__init__.py +18 -0
- schubmult/rings/_quantum_schubert_polynomial_ring.py +752 -0
- schubmult/rings/_schubert_polynomial_ring.py +1031 -0
- schubmult/rings/_tensor_schub_ring.py +128 -0
- schubmult/rings/_utils.py +55 -0
- schubmult/{sage_integration → sage}/__init__.py +4 -1
- schubmult/{sage_integration → sage}/_fast_double_schubert_polynomial_ring.py +67 -109
- schubmult/{sage_integration → sage}/_fast_schubert_polynomial_ring.py +33 -28
- schubmult/{sage_integration → sage}/_indexing.py +9 -5
- schubmult/schub_lib/__init__.py +51 -0
- schubmult/{schubmult_double/_funcs.py → schub_lib/double.py} +532 -596
- schubmult/{schubmult_q/_funcs.py → schub_lib/quantum.py} +54 -53
- schubmult/schub_lib/quantum_double.py +954 -0
- schubmult/schub_lib/schub_lib.py +659 -0
- schubmult/{schubmult_py/_funcs.py → schub_lib/single.py} +45 -35
- schubmult/schub_lib/tests/__init__.py +0 -0
- schubmult/schub_lib/tests/legacy_perm_lib.py +946 -0
- schubmult/schub_lib/tests/test_vs_old.py +109 -0
- schubmult/scripts/__init__.py +0 -0
- schubmult/scripts/schubmult_double.py +378 -0
- schubmult/scripts/schubmult_py.py +84 -0
- schubmult/scripts/schubmult_q.py +109 -0
- schubmult/scripts/schubmult_q_double.py +207 -0
- schubmult/utils/__init__.py +0 -0
- schubmult/{_base_argparse.py → utils/argparse.py} +29 -5
- schubmult/utils/logging.py +16 -0
- schubmult/utils/parsing.py +20 -0
- schubmult/utils/perm_utils.py +135 -0
- schubmult/utils/test_utils.py +65 -0
- schubmult-3.0.1.dist-info/METADATA +1234 -0
- schubmult-3.0.1.dist-info/RECORD +41 -0
- {schubmult-2.0.4.dist-info → schubmult-3.0.1.dist-info}/WHEEL +1 -1
- schubmult-3.0.1.dist-info/entry_points.txt +5 -0
- schubmult/_tests.py +0 -24
- schubmult/schubmult_double/__init__.py +0 -12
- schubmult/schubmult_double/__main__.py +0 -6
- schubmult/schubmult_double/_script.py +0 -474
- schubmult/schubmult_py/__init__.py +0 -12
- schubmult/schubmult_py/__main__.py +0 -6
- schubmult/schubmult_py/_script.py +0 -97
- schubmult/schubmult_q/__init__.py +0 -8
- schubmult/schubmult_q/__main__.py +0 -6
- schubmult/schubmult_q/_script.py +0 -166
- schubmult/schubmult_q_double/__init__.py +0 -10
- schubmult/schubmult_q_double/__main__.py +0 -6
- schubmult/schubmult_q_double/_funcs.py +0 -540
- schubmult/schubmult_q_double/_script.py +0 -396
- schubmult-2.0.4.dist-info/METADATA +0 -542
- schubmult-2.0.4.dist-info/RECORD +0 -30
- schubmult-2.0.4.dist-info/entry_points.txt +0 -5
- {schubmult-2.0.4.dist-info → schubmult-3.0.1.dist-info}/licenses/LICENSE +0 -0
- {schubmult-2.0.4.dist-info → schubmult-3.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
import schubmult.poly_lib.variables as schub_vars
|
2
|
+
import schubmult.schub_lib.schub_lib as schub_lib
|
3
|
+
import schubmult.perm_lib as pl
|
4
|
+
import schubmult.schub_lib.tests.legacy_perm_lib as opl
|
5
|
+
q_var = schub_vars.GeneratingSet("q")
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
def test_double_elem_sym_q():
|
10
|
+
ret_list = {}
|
11
|
+
ret_list_N = {}
|
12
|
+
u= tuple([7,5,1,6,4,2,3])
|
13
|
+
u_N = pl.Permutation(u)
|
14
|
+
p1 = 3
|
15
|
+
p2 = 5
|
16
|
+
k = 6
|
17
|
+
|
18
|
+
perms1 = opl.elem_sym_perms_q(u, p1, k, q_var)
|
19
|
+
perms1_N = schub_lib.elem_sym_perms_q(u_N, p1, k, q_var)
|
20
|
+
iu = opl.inverse(u)
|
21
|
+
iu_N = ~u_N
|
22
|
+
for perm1, udiff1, mul_val1 in perms1:
|
23
|
+
perm1_N = pl.Permutation(perm1)
|
24
|
+
assert (perm1_N, udiff1, mul_val1) in perms1_N, f"Permutation {perm1} not found in new result"
|
25
|
+
perms2 = opl.elem_sym_perms_q(perm1, p2, k, q_var)
|
26
|
+
perms2_N = schub_lib.elem_sym_perms_q(perm1_N, p2, k, q_var)
|
27
|
+
cycles1 = opl.get_cycles(opl.mulperm([*iu],[*perm1]))
|
28
|
+
cycles1_N = (iu_N*perm1_N).get_cycles()
|
29
|
+
assert cycles1 == cycles1_N
|
30
|
+
cycles1_dict = {}
|
31
|
+
for c in cycles1:
|
32
|
+
if c[-1] not in cycles1_dict:
|
33
|
+
cycles1_dict[c[-1]] = []
|
34
|
+
cycles1_dict[c[-1]] += [set(c)]
|
35
|
+
ip1 = opl.inverse(perm1)
|
36
|
+
ip1_N = ~perm1_N
|
37
|
+
assert ip1 == list(ip1_N)
|
38
|
+
for perm2, udiff2, mul_val2 in perms2:
|
39
|
+
perm2_N = pl.Permutation(perm2)
|
40
|
+
assert (perm2_N, udiff2, mul_val2) in perms2_N, f"Permutation {perm2} not found in new result"
|
41
|
+
cycles2 = opl.get_cycles(opl.mulperm([*ip1],[*perm2]))
|
42
|
+
cycles2_N = (ip1_N*perm2_N).get_cycles()
|
43
|
+
assert cycles2 == cycles2_N
|
44
|
+
good = True
|
45
|
+
for i in range(len(cycles2)):
|
46
|
+
c2 = cycles2[i]
|
47
|
+
if c2[-1] not in cycles1_dict:
|
48
|
+
continue
|
49
|
+
for c1_s in cycles1_dict[c2[-1]]:
|
50
|
+
for a in range(len(c2) - 2, -1, -1):
|
51
|
+
if c2[a] in c1_s:
|
52
|
+
good = False
|
53
|
+
break
|
54
|
+
if not good:
|
55
|
+
break
|
56
|
+
if not good:
|
57
|
+
break
|
58
|
+
|
59
|
+
if good:
|
60
|
+
if (perm1, udiff1, mul_val1) not in ret_list:
|
61
|
+
ret_list[(perm1, udiff1, mul_val1)] = []
|
62
|
+
ret_list[(perm1, udiff1, mul_val1)] += [(perm2, udiff2, mul_val2)]
|
63
|
+
return ret_list
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
def test_elem_sym_q():
|
68
|
+
# Test the function with a sample permutation
|
69
|
+
old_perm = tuple([5,1,4,2,3])
|
70
|
+
orig_perm = pl.Permutation(old_perm)
|
71
|
+
p = 3
|
72
|
+
k = 5
|
73
|
+
result_old = opl.elem_sym_perms_q(old_perm, p, k)
|
74
|
+
result_new = schub_lib.elem_sym_perms_q(orig_perm, p, k)
|
75
|
+
assert len(result_old) == len(result_new), "Length of results do not match"
|
76
|
+
for i in range(len(result_old)):
|
77
|
+
# print(f"{result_old[i]=} {result_new[i]=}")
|
78
|
+
assert pl.Permutation(result_old[i][0]) == result_new[i][0], f"Permutation mismatch at index {i}"
|
79
|
+
assert result_old[i][2] == result_new[i][2], f"Value mismatch at index {i}"
|
80
|
+
# def double_elem_sym_q(u, p1, p2, k, q_var=q_var):
|
81
|
+
old_perm = tuple([7,5,1,6,4,2,3])
|
82
|
+
orig_perm = pl.Permutation(old_perm)
|
83
|
+
p1 = 3
|
84
|
+
p2 = 5
|
85
|
+
k = 6
|
86
|
+
result_old = opl.double_elem_sym_q(old_perm, p1, p2, k)
|
87
|
+
result_new = schub_lib.double_elem_sym_q(orig_perm, p1, p2, k)
|
88
|
+
assert len(result_old) == len(result_new), "Length of results do not match"
|
89
|
+
print("OLD")
|
90
|
+
print("\n".join([str((str(b),str(result_old[b]))) for b in result_old]))
|
91
|
+
print("NEW")
|
92
|
+
print("\n".join([str((str(b),str(result_new[b]))) for b in result_new]))
|
93
|
+
for k, v in result_old.items():
|
94
|
+
k2 = (pl.Permutation(k[0]),k[1],k[2])
|
95
|
+
assert k2 in result_new, f"Key {k2} not found in new result"
|
96
|
+
v2 = result_new[k2]
|
97
|
+
v = sorted(v)
|
98
|
+
v2 = sorted(v2)
|
99
|
+
assert len(v) == len(v2)
|
100
|
+
for i in range(len(v)):
|
101
|
+
assert pl.Permutation(v[i][0]) == v2[i][0]
|
102
|
+
assert v[i][2] == v2[i][2]
|
103
|
+
|
104
|
+
#double_elem_sym_q
|
105
|
+
# assert pl.Permutation(result_old[i][1]) == result_new[i][1], f"Value mismatch at index {i}"
|
106
|
+
# assert pl.Permutation(result_old[i][2]) == result_new[i][2], f"Last j mismatch at index {i}"
|
107
|
+
# Print the result
|
108
|
+
# for perm, val, last_j in result:
|
109
|
+
# # print(f"Permutation: {perm}, Value: {val}, Last j: {last_j}")
|
File without changes
|
@@ -0,0 +1,378 @@
|
|
1
|
+
import sys
|
2
|
+
from functools import cached_property
|
3
|
+
|
4
|
+
import sympy
|
5
|
+
from symengine import expand, sympify
|
6
|
+
|
7
|
+
from schubmult import GeneratingSet, Permutation, efficient_subs, mult_poly_double, permtrim, posify, schub_coprod_double, schubmult_double, theta, uncode
|
8
|
+
from schubmult.perm_lib import split_perms
|
9
|
+
from schubmult.schub_lib.schub_lib import will_formula_work
|
10
|
+
from schubmult.utils.argparse import schub_argparse
|
11
|
+
from schubmult.utils.logging import get_logger
|
12
|
+
from schubmult.utils.perm_utils import (
|
13
|
+
add_perm_dict,
|
14
|
+
mu_A,
|
15
|
+
)
|
16
|
+
|
17
|
+
logger = get_logger(__name__)
|
18
|
+
|
19
|
+
|
20
|
+
class _gvars:
|
21
|
+
@cached_property
|
22
|
+
def n(self):
|
23
|
+
return 100
|
24
|
+
|
25
|
+
@cached_property
|
26
|
+
def var1(self):
|
27
|
+
return GeneratingSet("x")
|
28
|
+
|
29
|
+
@cached_property
|
30
|
+
def var2(self):
|
31
|
+
return GeneratingSet("y")
|
32
|
+
|
33
|
+
@cached_property
|
34
|
+
def var3(self):
|
35
|
+
return GeneratingSet("z")
|
36
|
+
|
37
|
+
@cached_property
|
38
|
+
def var_r(self):
|
39
|
+
return GeneratingSet("r")
|
40
|
+
|
41
|
+
|
42
|
+
_vars = _gvars()
|
43
|
+
|
44
|
+
|
45
|
+
def _display(val):
|
46
|
+
print(val)
|
47
|
+
|
48
|
+
|
49
|
+
subs_dict = {}
|
50
|
+
for i in range(1, 100):
|
51
|
+
sm = _vars.var2[1]
|
52
|
+
for j in range(1, i):
|
53
|
+
sm += _vars.var_r[j]
|
54
|
+
subs_dict[_vars.var2[i]] = sm
|
55
|
+
|
56
|
+
|
57
|
+
def sv_posify(val):
|
58
|
+
# this has just y's, we want to rearrange
|
59
|
+
# can we do this without an optimization
|
60
|
+
val = sympify(sympy.simplify(val.subs(subs_dict)))
|
61
|
+
bingle_dict = {}
|
62
|
+
for i in range(1, len(_vars.var_r) - 1):
|
63
|
+
bingle_dict[_vars.var_r[i]] = _vars.var2[i + 1] - _vars.var2[i] # sympy.Add(*[_vars.var2[i+1], - _vars.var2[i]],evaluate=False)
|
64
|
+
# oh bay does that bar bangled banber bet bave space buckets of cheese
|
65
|
+
# val = sympy.simplify(val)
|
66
|
+
return val.xreplace(bingle_dict)
|
67
|
+
|
68
|
+
|
69
|
+
def pre_posify(perms, perm, val, check, check_val, same, down, var2, var3, msg):
|
70
|
+
try:
|
71
|
+
return int(val)
|
72
|
+
except Exception:
|
73
|
+
if same:
|
74
|
+
val = sv_posify(val) # efficient_subs(sympify(val), subs_dict).expand() # expand(sympify(val).xreplace(subs_dict))
|
75
|
+
else:
|
76
|
+
if not down:
|
77
|
+
val = posify(
|
78
|
+
val,
|
79
|
+
perms[0],
|
80
|
+
perms[1],
|
81
|
+
perm,
|
82
|
+
var2,
|
83
|
+
var3,
|
84
|
+
msg,
|
85
|
+
)
|
86
|
+
else:
|
87
|
+
val = posify(
|
88
|
+
val,
|
89
|
+
perm,
|
90
|
+
perms[1],
|
91
|
+
perms[0],
|
92
|
+
var2,
|
93
|
+
var3,
|
94
|
+
msg,
|
95
|
+
)
|
96
|
+
# except Exception:
|
97
|
+
# _display(
|
98
|
+
# f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_val=}",
|
99
|
+
# )
|
100
|
+
# exit(1)
|
101
|
+
# if check and expand(val - check_coeff_dict.get(perm, 0)) != 0:
|
102
|
+
if check and expand(val - check_val) != 0:
|
103
|
+
_display(
|
104
|
+
f"error; write to schubmult@gmail.com with the case {perms=} {perm=} {val=} {check_val=}",
|
105
|
+
)
|
106
|
+
# logger.debug("Yep it's here")
|
107
|
+
exit(1)
|
108
|
+
return val
|
109
|
+
|
110
|
+
|
111
|
+
def flip_symbol_signs(val):
|
112
|
+
subs_dict = {}
|
113
|
+
for s in val.free_symbols:
|
114
|
+
if _vars.var2.index(s) != -1 or _vars.var3.index(s) != -1:
|
115
|
+
subs_dict[s] = -s
|
116
|
+
return efficient_subs(val, subs_dict)
|
117
|
+
|
118
|
+
|
119
|
+
def _display_full(
|
120
|
+
coeff_dict,
|
121
|
+
args,
|
122
|
+
formatter,
|
123
|
+
var2,
|
124
|
+
var3,
|
125
|
+
check=True,
|
126
|
+
):
|
127
|
+
subs_dict2 = {}
|
128
|
+
for i in range(1, 100):
|
129
|
+
sm = var2[1]
|
130
|
+
for j in range(1, i):
|
131
|
+
sm += _vars.var_r[j]
|
132
|
+
subs_dict2[var2[i]] = sm
|
133
|
+
raw_result_dict = {}
|
134
|
+
perms = args.perms
|
135
|
+
ascode = args.ascode
|
136
|
+
Permutation.print_as_code = ascode
|
137
|
+
coprod = args.coprod
|
138
|
+
msg = args.msg
|
139
|
+
same = args.same
|
140
|
+
display_positive = args.display_positive
|
141
|
+
perms[0] = Permutation(perms[0])
|
142
|
+
pos = list(perms[1])
|
143
|
+
pos2 = []
|
144
|
+
last_descent = -1
|
145
|
+
poso = []
|
146
|
+
for i in range(len(perms[0]) - 1):
|
147
|
+
if perms[0][i] > perms[0][i + 1]:
|
148
|
+
last_descent = i + 1
|
149
|
+
for i in range(1, last_descent + 1):
|
150
|
+
if i not in pos:
|
151
|
+
pos2 += [i - 1]
|
152
|
+
else:
|
153
|
+
poso += [i - 1]
|
154
|
+
|
155
|
+
mu_W = uncode(theta(~perms[0]))
|
156
|
+
|
157
|
+
the_top_perm = perms[0] * mu_W
|
158
|
+
|
159
|
+
muA = uncode(mu_A(mu_W.code, poso))
|
160
|
+
muB = uncode(mu_A(mu_W.code, pos2))
|
161
|
+
|
162
|
+
coeff_perms = list(coeff_dict.keys())
|
163
|
+
if coprod:
|
164
|
+
perm_pairs = coeff_perms
|
165
|
+
width = max([len(sympy.sstr(perm[0]) + " " + sympy.sstr(perm[1])) for perm in perm_pairs])
|
166
|
+
|
167
|
+
for firstperm, secondperm in perm_pairs:
|
168
|
+
val = coeff_dict[(firstperm, secondperm)]
|
169
|
+
if same and display_positive:
|
170
|
+
val = sv_posify(val) # efficient_subs(sympify(val), subs_dict2).expand()
|
171
|
+
if val != 0:
|
172
|
+
if display_positive and not same:
|
173
|
+
if val != 0:
|
174
|
+
try:
|
175
|
+
val = int(expand(val))
|
176
|
+
except Exception as e: # noqa: F841
|
177
|
+
val2 = posify(
|
178
|
+
flip_symbol_signs(val),
|
179
|
+
firstperm * muA,
|
180
|
+
secondperm * muB,
|
181
|
+
the_top_perm,
|
182
|
+
var2,
|
183
|
+
var3,
|
184
|
+
msg,
|
185
|
+
False,
|
186
|
+
)
|
187
|
+
val2 = flip_symbol_signs(val2)
|
188
|
+
if check and expand(val - val2) != 0:
|
189
|
+
_display(
|
190
|
+
f"error; write to schubmult@gmail.com with the case {perms=}\n{sympy.sstr(firstperm)=} {sympy.sstr(secondperm)=}\n{val2=}\n{val=}",
|
191
|
+
)
|
192
|
+
_display(f"{firstperm*muA=} {secondperm*muB=} {the_top_perm=}")
|
193
|
+
exit(1)
|
194
|
+
val = val2
|
195
|
+
else:
|
196
|
+
val = 0
|
197
|
+
if val != 0:
|
198
|
+
width2 = width - len(sympy.sstr(permtrim(firstperm))) - len(sympy.sstr(permtrim(secondperm)))
|
199
|
+
raw_result_dict[(permtrim(firstperm), Permutation(secondperm))] = val
|
200
|
+
if formatter:
|
201
|
+
_display(
|
202
|
+
f"{sympy.sstr(permtrim(firstperm))}{' ':>{width2}}{sympy.sstr(Permutation(secondperm))} {formatter(val)}",
|
203
|
+
)
|
204
|
+
else:
|
205
|
+
width = max([len(sympy.sstr(perm)) for perm in coeff_dict.keys()])
|
206
|
+
|
207
|
+
coeff_perms = list(coeff_dict.keys())
|
208
|
+
coeff_perms.sort(key=lambda x: (x.inv, *x))
|
209
|
+
|
210
|
+
for perm in coeff_perms:
|
211
|
+
val = coeff_dict[perm]
|
212
|
+
# if val != 0:
|
213
|
+
if val != 0:
|
214
|
+
raw_result_dict[perm] = val
|
215
|
+
if formatter:
|
216
|
+
_display(f"{sympy.sstr(perm)!s:>{width}} {formatter(val)}")
|
217
|
+
return raw_result_dict
|
218
|
+
|
219
|
+
|
220
|
+
def main(argv=None):
|
221
|
+
if argv is None:
|
222
|
+
argv = sys.argv
|
223
|
+
|
224
|
+
try:
|
225
|
+
var2 = GeneratingSet("y")
|
226
|
+
var3 = GeneratingSet("z")
|
227
|
+
sys.setrecursionlimit(1000000)
|
228
|
+
|
229
|
+
# TEMP
|
230
|
+
sympy.init_printing()
|
231
|
+
|
232
|
+
args, formatter = schub_argparse(
|
233
|
+
"schubmult_double",
|
234
|
+
"Compute coefficients of products of double Schubert polynomials in the same or different sets of coefficient variables",
|
235
|
+
argv=argv[1:],
|
236
|
+
yz=True,
|
237
|
+
)
|
238
|
+
|
239
|
+
mult = args.mult
|
240
|
+
mulstring = args.mulstring
|
241
|
+
|
242
|
+
perms = args.perms
|
243
|
+
|
244
|
+
ascode = args.ascode
|
245
|
+
coprod = args.coprod
|
246
|
+
same = args.same
|
247
|
+
msg = args.msg
|
248
|
+
down = args.down
|
249
|
+
check = args.check
|
250
|
+
display_positive = args.display_positive
|
251
|
+
pr = args.pr
|
252
|
+
# debug = args.debug
|
253
|
+
|
254
|
+
# logger.log(logging.DEBUG, f"main boing 1 {var2=}{var3=}{same=}")
|
255
|
+
if same:
|
256
|
+
var3 = var2
|
257
|
+
# logger.log(logging.DEBUG, f"main boing 2 {var2=}{var3=}{same=}")
|
258
|
+
posified = False
|
259
|
+
if coprod:
|
260
|
+
if ascode:
|
261
|
+
perms[0] = uncode(perms[0])
|
262
|
+
pos = [*perms[1]]
|
263
|
+
pos.sort()
|
264
|
+
mperm = Permutation(perms[0])
|
265
|
+
|
266
|
+
coeff_dict = schub_coprod_double(mperm, pos, var2, var3)
|
267
|
+
|
268
|
+
if pr or formatter is None:
|
269
|
+
# logger.log(logging.DEBUG, f"main {var2=}{var3=}{same=}")
|
270
|
+
raw_result_dict = _display_full(
|
271
|
+
coeff_dict,
|
272
|
+
args,
|
273
|
+
formatter,
|
274
|
+
var2=var2,
|
275
|
+
var3=var3,
|
276
|
+
)
|
277
|
+
if formatter is None:
|
278
|
+
return raw_result_dict
|
279
|
+
else:
|
280
|
+
if ascode:
|
281
|
+
for i in range(len(perms)):
|
282
|
+
perms[i] = uncode(perms[i])
|
283
|
+
else:
|
284
|
+
for i in range(len(perms)):
|
285
|
+
if len(perms[i]) < 2 and (len(perms[i]) == 0 or perms[i][0] == 1):
|
286
|
+
perms[i] = Permutation([])
|
287
|
+
perms[i] = Permutation(perms[i])
|
288
|
+
|
289
|
+
size = 0
|
290
|
+
orig_perms = [*perms]
|
291
|
+
while len(perms) != size:
|
292
|
+
size = len(perms)
|
293
|
+
perms = split_perms(perms)
|
294
|
+
|
295
|
+
coeff_dict = {perms[0]: 1}
|
296
|
+
check_coeff_dict = {perms[0]: 1}
|
297
|
+
|
298
|
+
# if mult:
|
299
|
+
# for v in var2:
|
300
|
+
# ()[str(v)] = v
|
301
|
+
# for v in var3:
|
302
|
+
# globals()[str(v)] = v
|
303
|
+
# for v in _vars.var1:
|
304
|
+
# globals()[str(v)] = v
|
305
|
+
|
306
|
+
# if down:
|
307
|
+
# for perm in orig_perms[1:]:
|
308
|
+
# check_coeff_dict = schubmult_down(check_coeff_dict, perm, var2, var3)
|
309
|
+
# if mult:
|
310
|
+
# mul_exp = eval(mulstring)
|
311
|
+
# check_coeff_dict = mult_poly_down(check_coeff_dict, mul_exp)
|
312
|
+
# else:
|
313
|
+
for perm in orig_perms[1:]:
|
314
|
+
check_coeff_dict = schubmult_double(check_coeff_dict, perm, var2, var3)
|
315
|
+
# coeff_dict = check_coeff_dict
|
316
|
+
if mult:
|
317
|
+
mul_exp = eval(mulstring)
|
318
|
+
check_coeff_dict = mult_poly_double(check_coeff_dict, mul_exp)
|
319
|
+
# preprocess positivity
|
320
|
+
if display_positive and len(perms) == 2 and will_formula_work(perms[0], perms[1]) and not mult and not down and not same:
|
321
|
+
coeff_dict = {}
|
322
|
+
th = theta(perms[1])
|
323
|
+
muv = uncode(th)
|
324
|
+
muvn1v = (~muv) * perms[1]
|
325
|
+
coeff_dict2 = {perms[0]: 1}
|
326
|
+
coeff_dict2 = schubmult_double(coeff_dict2, muv, var2, var3)
|
327
|
+
for perm, val in coeff_dict2.items():
|
328
|
+
w = perm * muvn1v
|
329
|
+
if w.inv + muvn1v.inv == perm.inv:
|
330
|
+
coeff_dict[Permutation(w)] = val
|
331
|
+
posified = True
|
332
|
+
|
333
|
+
if display_positive and len(perms) > 2 and not mult and not same:
|
334
|
+
coeff_dict2 = dict(coeff_dict)
|
335
|
+
for perm in perms[1:]:
|
336
|
+
coeff_dict3 = {}
|
337
|
+
for u in coeff_dict2:
|
338
|
+
coeff_dict4 = {u: 1}
|
339
|
+
coeff_dict4 = schubmult_double(coeff_dict4, perm, var2, var3)
|
340
|
+
for w in coeff_dict4:
|
341
|
+
coeff_dict4[w] = coeff_dict2[u] * posify(
|
342
|
+
coeff_dict4[w],
|
343
|
+
u,
|
344
|
+
perm,
|
345
|
+
w,
|
346
|
+
var2,
|
347
|
+
var3,
|
348
|
+
msg,
|
349
|
+
)
|
350
|
+
coeff_dict3 = add_perm_dict(coeff_dict4, coeff_dict3)
|
351
|
+
coeff_dict2 = coeff_dict3
|
352
|
+
coeff_dict = coeff_dict2
|
353
|
+
posified = True
|
354
|
+
elif not posified:
|
355
|
+
coeff_dict = check_coeff_dict
|
356
|
+
|
357
|
+
if not posified and display_positive:
|
358
|
+
# print(f"{coeff_dict=}")
|
359
|
+
coeff_dict = {k: pre_posify(perms, k, v, check, check_coeff_dict.get(k, 0), same, down, var2, var3, msg) for k, v in coeff_dict.items()}
|
360
|
+
|
361
|
+
if pr or formatter is None:
|
362
|
+
raw_result_dict = _display_full(
|
363
|
+
coeff_dict,
|
364
|
+
args,
|
365
|
+
formatter,
|
366
|
+
var2,
|
367
|
+
var3,
|
368
|
+
)
|
369
|
+
|
370
|
+
if formatter is None:
|
371
|
+
return raw_result_dict
|
372
|
+
except BrokenPipeError:
|
373
|
+
pass
|
374
|
+
return 0
|
375
|
+
|
376
|
+
|
377
|
+
if __name__ == "__main__":
|
378
|
+
sys.exit(main(sys.argv))
|
@@ -0,0 +1,84 @@
|
|
1
|
+
import sys
|
2
|
+
|
3
|
+
import sympy
|
4
|
+
from symengine import sympify
|
5
|
+
|
6
|
+
from schubmult import Permutation, mult_poly_py, permtrim, schub_coprod_py, schubmult_py, theta, uncode
|
7
|
+
from schubmult.utils.argparse import schub_argparse
|
8
|
+
|
9
|
+
|
10
|
+
def main(argv=None):
|
11
|
+
if argv is None:
|
12
|
+
argv = sys.argv
|
13
|
+
try:
|
14
|
+
args, formatter = schub_argparse(
|
15
|
+
"schubmult_py",
|
16
|
+
"Compute products of ordinary Schubert polynomials",
|
17
|
+
argv=argv[1:],
|
18
|
+
)
|
19
|
+
|
20
|
+
mult = args.mult
|
21
|
+
mulstring = args.mulstring
|
22
|
+
|
23
|
+
perms = args.perms
|
24
|
+
|
25
|
+
for perm in perms:
|
26
|
+
try:
|
27
|
+
for i in range(len(perm)):
|
28
|
+
perm[i] = int(perm[i])
|
29
|
+
except Exception as e:
|
30
|
+
print("Permutations must have integer values")
|
31
|
+
raise e
|
32
|
+
|
33
|
+
ascode = args.ascode
|
34
|
+
Permutation.print_as_code = ascode
|
35
|
+
pr = args.pr
|
36
|
+
coprod = args.coprod
|
37
|
+
raw_result_dict = {}
|
38
|
+
if coprod:
|
39
|
+
if ascode:
|
40
|
+
perms[0] = uncode(perms[0])
|
41
|
+
pos = [*perms[1]]
|
42
|
+
pos.sort()
|
43
|
+
mperm = Permutation(perms[0])
|
44
|
+
|
45
|
+
coeff_dict = schub_coprod_py(mperm, pos)
|
46
|
+
|
47
|
+
if pr or formatter is None:
|
48
|
+
for firstperm, secondperm in coeff_dict:
|
49
|
+
val = coeff_dict[(firstperm, secondperm)]
|
50
|
+
if val != 0:
|
51
|
+
if formatter is None:
|
52
|
+
raw_result_dict[(firstperm, secondperm)] = val
|
53
|
+
else:
|
54
|
+
print(f"{val} {sympy.sstr(firstperm)} {sympy.sstr(secondperm)}")
|
55
|
+
else:
|
56
|
+
if ascode:
|
57
|
+
for i in range(len(perms)):
|
58
|
+
perms[i] = permtrim(uncode(perms[i]))
|
59
|
+
else:
|
60
|
+
perms = [permtrim(perm) for perm in perms]
|
61
|
+
perms.sort(reverse=True, key=lambda x: sum(theta(~x)) - x.inv)
|
62
|
+
|
63
|
+
coeff_dict = {permtrim([*perms[0]]): 1}
|
64
|
+
|
65
|
+
for perm in perms[1:]:
|
66
|
+
coeff_dict = schubmult_py(coeff_dict, Permutation(perm))
|
67
|
+
if mult:
|
68
|
+
mul_exp = sympify(mulstring)
|
69
|
+
coeff_dict = mult_poly_py(coeff_dict, mul_exp)
|
70
|
+
|
71
|
+
if pr or formatter is None:
|
72
|
+
for perm, val in coeff_dict.items():
|
73
|
+
if val != 0:
|
74
|
+
raw_result_dict[perm] = val
|
75
|
+
if formatter:
|
76
|
+
print(f"{val} {sympy.sstr(perm)}")
|
77
|
+
if formatter is None:
|
78
|
+
return raw_result_dict
|
79
|
+
except BrokenPipeError:
|
80
|
+
pass
|
81
|
+
|
82
|
+
|
83
|
+
if __name__ == "__main__":
|
84
|
+
sys.exit(main(sys.argv))
|
@@ -0,0 +1,109 @@
|
|
1
|
+
import sys
|
2
|
+
|
3
|
+
import sympy
|
4
|
+
from symengine import sympify
|
5
|
+
|
6
|
+
from schubmult import GeneratingSet, Permutation, apply_peterson_woodward, schubmult_q, schubmult_q_fast, uncode
|
7
|
+
from schubmult.utils.argparse import schub_argparse
|
8
|
+
|
9
|
+
q_var = GeneratingSet("q")
|
10
|
+
|
11
|
+
|
12
|
+
def _display_full(coeff_dict, args, formatter):
|
13
|
+
raw_result_dict = {}
|
14
|
+
ascode = args.ascode
|
15
|
+
Permutation.print_as_code = ascode
|
16
|
+
parabolic_index = []
|
17
|
+
start = 0
|
18
|
+
for i in range(len(args.parabolic)):
|
19
|
+
end = start + int(args.parabolic[i])
|
20
|
+
parabolic_index += list(range(start + 1, end))
|
21
|
+
start = end
|
22
|
+
parabolic = len(parabolic_index) != 0
|
23
|
+
|
24
|
+
if parabolic:
|
25
|
+
coeff_dict = apply_peterson_woodward(coeff_dict, parabolic_index)
|
26
|
+
|
27
|
+
coeff_perms = list(coeff_dict.keys())
|
28
|
+
coeff_perms.sort(key=lambda x: (x.inv, *x))
|
29
|
+
|
30
|
+
for perm in coeff_perms:
|
31
|
+
val = sympify(coeff_dict[perm]).expand()
|
32
|
+
if val != 0:
|
33
|
+
raw_result_dict[perm] = val
|
34
|
+
if formatter:
|
35
|
+
print(f"{sympy.sstr(perm)!s} {formatter(val)}")
|
36
|
+
return raw_result_dict
|
37
|
+
|
38
|
+
|
39
|
+
def main(argv=None):
|
40
|
+
if argv is None:
|
41
|
+
argv = sys.argv
|
42
|
+
try:
|
43
|
+
args, formatter = schub_argparse(
|
44
|
+
"schubmult_q",
|
45
|
+
"Compute products of quantum Schubert polynomials",
|
46
|
+
argv=argv[1:],
|
47
|
+
quantum=True,
|
48
|
+
)
|
49
|
+
|
50
|
+
perms = args.perms
|
51
|
+
|
52
|
+
for perm in perms:
|
53
|
+
try:
|
54
|
+
for i in range(len(perm)):
|
55
|
+
perm[i] = int(perm[i])
|
56
|
+
except Exception as e:
|
57
|
+
print("Permutations must have integer values")
|
58
|
+
raise e
|
59
|
+
|
60
|
+
ascode = args.ascode
|
61
|
+
pr = args.pr
|
62
|
+
parabolic_index = [int(s) for s in args.parabolic]
|
63
|
+
parabolic = len(parabolic_index) != 0
|
64
|
+
slow = args.slow
|
65
|
+
|
66
|
+
if parabolic and len(perms) != 2:
|
67
|
+
print("Only two permutations supported for parabolic.")
|
68
|
+
exit(1)
|
69
|
+
|
70
|
+
if ascode:
|
71
|
+
for i in range(len(perms)):
|
72
|
+
perms[i] = uncode(perms[i])
|
73
|
+
else:
|
74
|
+
perms = [Permutation(perm) for perm in perms]
|
75
|
+
|
76
|
+
# if parabolic:
|
77
|
+
# for i in range(len(parabolic_index)):
|
78
|
+
# index = parabolic_index[i] - 1
|
79
|
+
# if sg(index, perms[0]) == 1 or sg(index, perms[1]) == 1:
|
80
|
+
# print(
|
81
|
+
# "Parabolic given but elements are not minimal length coset representatives.",
|
82
|
+
# )
|
83
|
+
# exit(1)
|
84
|
+
|
85
|
+
coeff_dict = {perms[0]: 1}
|
86
|
+
|
87
|
+
if not slow:
|
88
|
+
for perm in perms[1:]:
|
89
|
+
coeff_dict = schubmult_q_fast(coeff_dict, perm)
|
90
|
+
else:
|
91
|
+
for perm in perms[1:]:
|
92
|
+
coeff_dict = schubmult_q(coeff_dict, perm)
|
93
|
+
|
94
|
+
# if mult:
|
95
|
+
# mul_exp = sympify(mulstring)
|
96
|
+
# coeff_dict = mult_poly(coeff_dict, mul_exp)
|
97
|
+
|
98
|
+
if pr or formatter is None:
|
99
|
+
raw_result_dict = _display_full(coeff_dict, args, formatter)
|
100
|
+
if formatter is None:
|
101
|
+
return raw_result_dict
|
102
|
+
except BrokenPipeError:
|
103
|
+
pass
|
104
|
+
|
105
|
+
|
106
|
+
if __name__ == "__main__":
|
107
|
+
import sys
|
108
|
+
|
109
|
+
sys.exit(main(sys.argv))
|