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.
- schubmult/__init__.py +94 -1
- schubmult/perm_lib.py +233 -880
- schubmult/poly_lib/__init__.py +31 -0
- schubmult/poly_lib/poly_lib.py +244 -0
- schubmult/poly_lib/schub_poly.py +148 -0
- schubmult/poly_lib/variables.py +204 -0
- schubmult/rings/__init__.py +17 -0
- schubmult/rings/_quantum_schubert_polynomial_ring.py +788 -0
- schubmult/rings/_schubert_polynomial_ring.py +1006 -0
- schubmult/rings/_tensor_schub_ring.py +128 -0
- schubmult/rings/_utils.py +55 -0
- schubmult/{sage_integration → sage}/__init__.py +17 -15
- schubmult/{sage_integration → sage}/_fast_double_schubert_polynomial_ring.py +142 -220
- schubmult/{sage_integration → sage}/_fast_schubert_polynomial_ring.py +78 -72
- schubmult/sage/_indexing.py +51 -0
- schubmult/schub_lib/__init__.py +51 -0
- schubmult/{schubmult_double/_funcs.py → schub_lib/double.py} +618 -798
- schubmult/{schubmult_q/_funcs.py → schub_lib/quantum.py} +70 -72
- 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} +58 -48
- 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} +40 -11
- 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.0.dist-info/METADATA +1234 -0
- schubmult-3.0.0.dist-info/RECORD +41 -0
- {schubmult-2.0.3.dist-info → schubmult-3.0.0.dist-info}/WHEEL +1 -1
- schubmult-3.0.0.dist-info/entry_points.txt +5 -0
- schubmult/_tests.py +0 -9
- schubmult/sage_integration/_indexing.py +0 -51
- schubmult/schubmult_double/__init__.py +0 -22
- schubmult/schubmult_double/__main__.py +0 -5
- schubmult/schubmult_double/_script.py +0 -474
- schubmult/schubmult_py/__init__.py +0 -13
- schubmult/schubmult_py/__main__.py +0 -5
- schubmult/schubmult_py/_script.py +0 -96
- schubmult/schubmult_q/__init__.py +0 -13
- schubmult/schubmult_q/__main__.py +0 -5
- schubmult/schubmult_q/_script.py +0 -160
- schubmult/schubmult_q_double/__init__.py +0 -17
- schubmult/schubmult_q_double/__main__.py +0 -5
- schubmult/schubmult_q_double/_funcs.py +0 -540
- schubmult/schubmult_q_double/_script.py +0 -398
- schubmult-2.0.3.dist-info/METADATA +0 -455
- schubmult-2.0.3.dist-info/RECORD +0 -30
- schubmult-2.0.3.dist-info/entry_points.txt +0 -5
- {schubmult-2.0.3.dist-info → schubmult-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {schubmult-2.0.3.dist-info → schubmult-3.0.0.dist-info}/top_level.txt +0 -0
@@ -1,51 +1,49 @@
|
|
1
1
|
from bisect import bisect_left
|
2
|
-
from functools import cache
|
2
|
+
from functools import cache, cached_property
|
3
|
+
|
4
|
+
import numpy as np
|
5
|
+
import psutil
|
6
|
+
import pulp as pu
|
7
|
+
import sympy
|
3
8
|
from cachetools import cached
|
4
9
|
from cachetools.keys import hashkey
|
5
|
-
from
|
10
|
+
from sortedcontainers import SortedList
|
11
|
+
from symengine import Add, Integer, Mul, Pow, sympify
|
12
|
+
|
6
13
|
from schubmult.perm_lib import (
|
7
|
-
|
8
|
-
|
9
|
-
|
14
|
+
Permutation,
|
15
|
+
code,
|
16
|
+
cycle,
|
10
17
|
dominates,
|
11
|
-
compute_vpathdicts,
|
12
|
-
inverse,
|
13
|
-
theta,
|
14
|
-
permtrim,
|
15
18
|
inv,
|
16
|
-
|
17
|
-
|
19
|
+
one_dominates,
|
20
|
+
phi1,
|
21
|
+
theta,
|
18
22
|
uncode,
|
19
|
-
|
20
|
-
|
23
|
+
)
|
24
|
+
from schubmult.poly_lib.poly_lib import efficient_subs, elem_sym_func, elem_sym_poly, expand
|
25
|
+
from schubmult.poly_lib.schub_poly import schubpoly
|
26
|
+
from schubmult.poly_lib.variables import CustomGeneratingSet, GeneratingSet, GeneratingSet_base
|
27
|
+
from schubmult.schub_lib.schub_lib import (
|
28
|
+
compute_vpathdicts,
|
21
29
|
divdiffable,
|
30
|
+
elem_sym_perms,
|
31
|
+
elem_sym_perms_op,
|
32
|
+
is_coeff_irreducible,
|
33
|
+
is_split_two,
|
22
34
|
pull_out_var,
|
23
|
-
cycle,
|
24
|
-
will_formula_work,
|
25
|
-
one_dominates,
|
26
|
-
is_reducible,
|
27
35
|
reduce_coeff,
|
28
36
|
reduce_descents,
|
29
37
|
try_reduce_u,
|
30
38
|
try_reduce_v,
|
31
|
-
|
32
|
-
zero,
|
39
|
+
will_formula_work,
|
33
40
|
)
|
34
|
-
|
35
|
-
|
36
|
-
import sympy
|
37
|
-
import psutil
|
38
|
-
from sortedcontainers import SortedList
|
39
|
-
from functools import cached_property
|
41
|
+
from schubmult.utils.logging import get_logger
|
42
|
+
from schubmult.utils.perm_utils import add_perm_dict
|
40
43
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
# var2,
|
45
|
-
# var3,
|
46
|
-
# _vars.var1,
|
47
|
-
# var_y,
|
48
|
-
# )
|
44
|
+
zero = sympify(0)
|
45
|
+
|
46
|
+
logger = get_logger(__name__)
|
49
47
|
|
50
48
|
|
51
49
|
class _gvars:
|
@@ -59,19 +57,28 @@ class _gvars:
|
|
59
57
|
|
60
58
|
@cached_property
|
61
59
|
def var1(self):
|
62
|
-
return
|
60
|
+
return GeneratingSet("x")
|
63
61
|
|
64
62
|
@cached_property
|
65
63
|
def var2(self):
|
66
|
-
return
|
64
|
+
return GeneratingSet("y")
|
67
65
|
|
68
66
|
@cached_property
|
69
67
|
def var3(self):
|
70
|
-
return
|
68
|
+
return GeneratingSet("z")
|
71
69
|
|
72
70
|
@cached_property
|
73
71
|
def var_r(self):
|
74
|
-
return
|
72
|
+
return GeneratingSet("r")
|
73
|
+
|
74
|
+
@cached_property
|
75
|
+
def var_g1(self):
|
76
|
+
return GeneratingSet("y")
|
77
|
+
|
78
|
+
@cached_property
|
79
|
+
def var_g2(self):
|
80
|
+
return GeneratingSet("z")
|
81
|
+
|
75
82
|
|
76
83
|
|
77
84
|
_vars = _gvars()
|
@@ -86,8 +93,8 @@ def count_sorted(mn, tp):
|
|
86
93
|
return ct
|
87
94
|
|
88
95
|
|
89
|
-
def E(p, k, varl=_vars.var2[1:]):
|
90
|
-
|
96
|
+
# def E(p, k, varl=_vars.var2[1:]):
|
97
|
+
# return elem_sym_poly(p, k, _vars.var1[1:], varl)
|
91
98
|
|
92
99
|
|
93
100
|
def single_variable(coeff_dict, varnum, var2=None):
|
@@ -130,72 +137,82 @@ def single_variable_down(coeff_dict, varnum, var2=_vars.var2):
|
|
130
137
|
return ret
|
131
138
|
|
132
139
|
|
133
|
-
def
|
134
|
-
|
140
|
+
def mult_poly_double(coeff_dict, poly, var_x=_vars.var1, var_y=_vars.var2):
|
141
|
+
# try:
|
142
|
+
# poly = sympify(poly)
|
143
|
+
# except SympifyError:
|
144
|
+
# poly = sympy.sympify(poly)
|
145
|
+
# var_x = tuple([sympy.sympify(v) for v in var_x])
|
146
|
+
# var_y = tuple([sympy.sympify(v) for v in var_y])
|
147
|
+
# return mult_poly_sympy(coeff_dict, poly, var_x=_vars.var1, var_y=_vars.var2)
|
148
|
+
if not isinstance(var_x, GeneratingSet_base):
|
149
|
+
var_x = CustomGeneratingSet(var_x)
|
150
|
+
if var_x.index(poly) != -1:
|
135
151
|
return single_variable(coeff_dict, var_x.index(poly), var_y)
|
136
|
-
|
152
|
+
if isinstance(poly, Mul):
|
137
153
|
ret = coeff_dict
|
138
154
|
for a in poly.args:
|
139
|
-
ret =
|
155
|
+
ret = mult_poly_double(ret, a, var_x, var_y)
|
140
156
|
return ret
|
141
|
-
|
157
|
+
if isinstance(poly, Pow):
|
142
158
|
base = poly.args[0]
|
143
159
|
exponent = int(poly.args[1])
|
144
160
|
ret = coeff_dict
|
145
161
|
for i in range(int(exponent)):
|
146
|
-
ret =
|
162
|
+
ret = mult_poly_double(ret, base, var_x, var_y)
|
147
163
|
return ret
|
148
|
-
|
164
|
+
if isinstance(poly, Add):
|
149
165
|
ret = {}
|
150
166
|
for a in poly.args:
|
151
|
-
ret = add_perm_dict(ret,
|
152
|
-
return ret
|
153
|
-
else:
|
154
|
-
ret = {}
|
155
|
-
for perm in coeff_dict:
|
156
|
-
ret[perm] = poly * coeff_dict[perm]
|
167
|
+
ret = add_perm_dict(ret, mult_poly_double(coeff_dict, a, var_x, var_y))
|
157
168
|
return ret
|
169
|
+
ret = {}
|
170
|
+
for perm in coeff_dict:
|
171
|
+
ret[perm] = poly * coeff_dict[perm]
|
172
|
+
return ret
|
173
|
+
|
174
|
+
|
175
|
+
# def mult_poly_symy(coeff_dict, poly, var_x=_vars.sympy_var1, var_y=_vars.sympy_var2):
|
158
176
|
|
159
177
|
|
160
178
|
def mult_poly_down(coeff_dict, poly):
|
161
179
|
if poly in _vars.var1:
|
162
180
|
return single_variable_down(coeff_dict, _vars.var1.index(poly))
|
163
|
-
|
181
|
+
if isinstance(poly, Mul):
|
164
182
|
ret = coeff_dict
|
165
183
|
for a in poly.args:
|
166
184
|
ret = mult_poly_down(ret, a)
|
167
185
|
return ret
|
168
|
-
|
186
|
+
if isinstance(poly, Pow):
|
169
187
|
base = poly.args[0]
|
170
188
|
exponent = int(poly.args[1])
|
171
189
|
ret = coeff_dict
|
172
190
|
for i in range(int(exponent)):
|
173
191
|
ret = mult_poly_down(ret, base)
|
174
192
|
return ret
|
175
|
-
|
193
|
+
if isinstance(poly, Add):
|
176
194
|
ret = {}
|
177
195
|
for a in poly.args:
|
178
196
|
ret = add_perm_dict(ret, mult_poly_down(coeff_dict, a))
|
179
197
|
return ret
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
return ret
|
198
|
+
ret = {}
|
199
|
+
for perm in coeff_dict:
|
200
|
+
ret[perm] = poly * coeff_dict[perm]
|
201
|
+
return ret
|
185
202
|
|
186
203
|
|
187
204
|
def nilhecke_mult(coeff_dict1, coeff_dict2):
|
188
205
|
ret = {}
|
189
206
|
for w in coeff_dict2:
|
190
|
-
w1 =
|
207
|
+
w1 = w
|
191
208
|
inv_w1 = inv(w1)
|
192
209
|
poly = coeff_dict2[w]
|
193
210
|
did_mul = mult_poly_down(coeff_dict1, poly)
|
194
211
|
for v in did_mul:
|
195
212
|
v1 = [*v]
|
196
|
-
addperm =
|
213
|
+
addperm = v1 * w1
|
197
214
|
if inv(addperm) == inv(v1) + inv_w1:
|
198
|
-
toadd =
|
215
|
+
toadd = addperm
|
199
216
|
ret[toadd] = ret.get(toadd, 0) + did_mul[v]
|
200
217
|
return ret
|
201
218
|
|
@@ -203,48 +220,63 @@ def nilhecke_mult(coeff_dict1, coeff_dict2):
|
|
203
220
|
def forwardcoeff(u, v, perm, var2=None, var3=None):
|
204
221
|
th = theta(v)
|
205
222
|
muv = uncode(th)
|
206
|
-
vmun1 =
|
223
|
+
vmun1 = (~v) * muv
|
207
224
|
|
208
|
-
w =
|
225
|
+
w = perm * vmun1
|
209
226
|
if inv(w) == inv(vmun1) + inv(perm):
|
210
|
-
coeff_dict =
|
211
|
-
|
227
|
+
coeff_dict = schubmult_double_pair(u, muv, var2, var3)
|
228
|
+
# logger.debug(f"{coeff_dict.get(w,0)=} {w=} {perm=} {vmun1=} {v=} {muv=}")
|
229
|
+
return coeff_dict.get(w, 0)
|
212
230
|
return 0
|
213
231
|
|
214
232
|
|
215
233
|
def dualcoeff(u, v, perm, var2=None, var3=None):
|
216
|
-
if u ==
|
217
|
-
|
234
|
+
if inv(u) == 0:
|
235
|
+
# logger.debug("Recording line number")
|
236
|
+
vp = v * (~perm)
|
218
237
|
if inv(vp) == inv(v) - inv(perm):
|
219
|
-
|
220
|
-
|
221
|
-
|
238
|
+
return schubpoly(vp, var2, var3)
|
239
|
+
dpret = []
|
240
|
+
ret = 0
|
241
|
+
if dominates(u, perm):
|
242
|
+
dpret = dualpieri(u, v, perm)
|
222
243
|
else:
|
244
|
+
# logger.debug("Recording line number")
|
223
245
|
dpret = []
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
246
|
+
# logger.debug("Recording line number")
|
247
|
+
th = theta(u)
|
248
|
+
muu = uncode(th)
|
249
|
+
umun1 = (~u) * muu
|
250
|
+
w = perm * umun1
|
251
|
+
# logger.debug("spiggle")
|
252
|
+
# logger.debug(f"{u=} {muu=} {v=} {w=} {perm=}")
|
253
|
+
# logger.debug(f"{w=} {perm=}")
|
254
|
+
if inv(w) == inv(umun1) + inv(perm):
|
255
|
+
dpret = dualpieri(muu, v, w)
|
256
|
+
# logger.debug(f"{muu=} {v=} {w=}")
|
257
|
+
# logger.debug(f"{dpret=}")
|
258
|
+
for vlist, vp in dpret:
|
259
|
+
# logger.debug("Recording line number")
|
260
|
+
toadd = 1
|
261
|
+
for i in range(len(vlist)):
|
262
|
+
for j in range(len(vlist[i])):
|
263
|
+
toadd *= var2[i + 1] - var3[vlist[i][j]]
|
264
|
+
toadd *= schubpoly(vp, var2, var3, len(vlist) + 1)
|
265
|
+
ret += toadd
|
266
|
+
return ret
|
267
|
+
# logger.debug("Recording line number")
|
268
|
+
# schub_val = schubmult_one(u, v, var2, var3)
|
269
|
+
# val_ret = schub_val.get(perm, 0)
|
270
|
+
# if expand(val - val_ret) != 0:
|
271
|
+
# # logger.debug(f"{schub_val=}")
|
272
|
+
# # logger.debug(f"{val=} {u=} {v=} {var2[1]=} {var3[1]=} {perm=} {schub_val.get(perm,0)=}")
|
273
|
+
# logger.debug(f"good to go {ret=}")
|
243
274
|
|
244
275
|
|
245
276
|
def dualpieri(mu, v, w):
|
246
|
-
|
247
|
-
|
277
|
+
# logger.debug(f"dualpieri {mu=} {v=} {w=}")
|
278
|
+
lm = code(~mu)
|
279
|
+
cn1w = code(~w)
|
248
280
|
while len(lm) > 0 and lm[-1] == 0:
|
249
281
|
lm.pop()
|
250
282
|
while len(cn1w) > 0 and cn1w[-1] == 0:
|
@@ -254,33 +286,38 @@ def dualpieri(mu, v, w):
|
|
254
286
|
for i in range(len(lm)):
|
255
287
|
if lm[i] > cn1w[i]:
|
256
288
|
return []
|
257
|
-
c = [1, 2]
|
289
|
+
c = Permutation([1, 2])
|
258
290
|
for i in range(len(lm), len(cn1w)):
|
259
|
-
c =
|
260
|
-
c = permtrim(c)
|
291
|
+
c = cycle(i - len(lm) + 1, cn1w[i]) * c
|
292
|
+
# c = permtrim(c)
|
293
|
+
# logger.debug("Recording line number")
|
261
294
|
res = [[[], v]]
|
295
|
+
# logger.debug(f"{v=} {type(v)=}")
|
262
296
|
for i in range(len(lm)):
|
297
|
+
# logger.debug(f"{res=}")
|
263
298
|
res2 = []
|
264
299
|
for vlist, vplist in res:
|
265
300
|
vp = vplist
|
266
301
|
vpl = divdiffable(vp, cycle(lm[i] + 1, cn1w[i] - lm[i]))
|
267
|
-
|
302
|
+
# logger.debug(f"{vpl=} {type(vpl)=}")
|
303
|
+
if len(vpl) == 0:
|
268
304
|
continue
|
269
305
|
vl = pull_out_var(lm[i] + 1, vpl)
|
306
|
+
# logger.debug(f"{vl=}")
|
270
307
|
for pw, vpl2 in vl:
|
271
|
-
res2 += [[vlist
|
308
|
+
res2 += [[[*vlist, pw], vpl2]]
|
272
309
|
res = res2
|
273
310
|
if len(lm) == len(cn1w):
|
274
311
|
return res
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
312
|
+
res2 = []
|
313
|
+
for vlist, vplist in res:
|
314
|
+
vp = vplist
|
315
|
+
vpl = divdiffable(vp, c)
|
316
|
+
if len(vpl) == 0:
|
317
|
+
continue
|
318
|
+
res2 += [[vlist, vpl]]
|
319
|
+
# logger.debug(f"{res2=}")
|
320
|
+
return res2
|
284
321
|
|
285
322
|
|
286
323
|
dimen = 0
|
@@ -288,19 +325,30 @@ monom_to_vec = {}
|
|
288
325
|
|
289
326
|
|
290
327
|
@cache
|
291
|
-
def
|
292
|
-
return
|
328
|
+
def schubmult_double_pair(perm1, perm2, var2=None, var3=None):
|
329
|
+
return schubmult_double({perm1: 1}, perm2, var2, var3)
|
293
330
|
|
294
331
|
|
295
|
-
|
296
|
-
|
332
|
+
@cache
|
333
|
+
def schubmult_double_pair_generic(perm1, perm2):
|
334
|
+
return schubmult_double({perm1: 1}, perm2, _vars.var_g1, _vars.var_g2)
|
335
|
+
|
336
|
+
|
337
|
+
def schubmult_double(perm_dict, v, var2=None, var3=None):
|
338
|
+
if isinstance(var2, str):
|
339
|
+
var2 = GeneratingSet(var2)
|
340
|
+
if isinstance(var3, str):
|
341
|
+
var3 = GeneratingSet(var3)
|
342
|
+
perm_dict = {Permutation(k): v for k, v in perm_dict.items()}
|
343
|
+
v = Permutation(v)
|
344
|
+
vn1 = ~v
|
297
345
|
th = theta(vn1)
|
298
346
|
if len(th) == 0:
|
299
347
|
return perm_dict
|
300
348
|
if th[0] == 0:
|
301
349
|
return perm_dict
|
302
|
-
mu =
|
303
|
-
vmu =
|
350
|
+
mu = uncode(th)
|
351
|
+
vmu = v * mu
|
304
352
|
inv_vmu = inv(vmu)
|
305
353
|
inv_mu = inv(mu)
|
306
354
|
ret_dict = {}
|
@@ -310,18 +358,19 @@ def schubmult(perm_dict, v, var2=None, var3=None):
|
|
310
358
|
vpathdicts = compute_vpathdicts(th, vmu, True)
|
311
359
|
for u, val in perm_dict.items():
|
312
360
|
inv_u = inv(u)
|
313
|
-
vpathsums = {u: {(1, 2): val}}
|
361
|
+
vpathsums = {u: {Permutation([1, 2]): val}}
|
314
362
|
for index in range(thL):
|
315
363
|
mx_th = 0
|
316
364
|
for vp in vpathdicts[index]:
|
317
365
|
for v2, vdiff, s in vpathdicts[index][vp]:
|
318
|
-
|
319
|
-
mx_th = th[index] - vdiff
|
366
|
+
mx_th = max(mx_th, th[index] - vdiff)
|
320
367
|
newpathsums = {}
|
321
368
|
for up in vpathsums:
|
322
369
|
inv_up = inv(up)
|
323
370
|
newperms = elem_sym_perms(
|
324
|
-
up,
|
371
|
+
up,
|
372
|
+
min(mx_th, (inv_mu - (inv_up - inv_u)) - inv_vmu),
|
373
|
+
th[index],
|
325
374
|
)
|
326
375
|
for up2, udiff in newperms:
|
327
376
|
if up2 not in newpathsums:
|
@@ -332,7 +381,8 @@ def schubmult(perm_dict, v, var2=None, var3=None):
|
|
332
381
|
continue
|
333
382
|
for v2, vdiff, s in vpathdicts[index][v]:
|
334
383
|
newpathsums[up2][v2] = newpathsums[up2].get(
|
335
|
-
v2,
|
384
|
+
v2,
|
385
|
+
zero,
|
336
386
|
) + s * sumval * elem_sym_func(
|
337
387
|
th[index],
|
338
388
|
index + 1,
|
@@ -346,18 +396,18 @@ def schubmult(perm_dict, v, var2=None, var3=None):
|
|
346
396
|
var3,
|
347
397
|
)
|
348
398
|
vpathsums = newpathsums
|
349
|
-
toget =
|
350
|
-
ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget, 0) for ep in vpathsums}, ret_dict)
|
399
|
+
toget = vmu
|
400
|
+
ret_dict = add_perm_dict({Permutation(ep): vpathsums[ep].get(toget, 0) for ep in vpathsums}, ret_dict)
|
351
401
|
return ret_dict
|
352
402
|
|
353
403
|
|
354
404
|
def schubmult_down(perm_dict, v, var2=None, var3=None):
|
355
|
-
vn1 =
|
405
|
+
vn1 = ~v
|
356
406
|
th = theta(vn1)
|
357
407
|
if th[0] == 0:
|
358
408
|
return perm_dict
|
359
|
-
mu =
|
360
|
-
vmu =
|
409
|
+
mu = uncode(th)
|
410
|
+
vmu = v * mu
|
361
411
|
ret_dict = {}
|
362
412
|
|
363
413
|
while th[-1] == 0:
|
@@ -365,13 +415,12 @@ def schubmult_down(perm_dict, v, var2=None, var3=None):
|
|
365
415
|
thL = len(th)
|
366
416
|
vpathdicts = compute_vpathdicts(th, vmu, True)
|
367
417
|
for u, val in perm_dict.items():
|
368
|
-
vpathsums = {u: {(1, 2): val}}
|
418
|
+
vpathsums = {u: {Permutation([1, 2]): val}}
|
369
419
|
for index in range(thL):
|
370
420
|
mx_th = 0
|
371
421
|
for vp in vpathdicts[index]:
|
372
422
|
for v2, vdiff, s in vpathdicts[index][vp]:
|
373
|
-
|
374
|
-
mx_th = th[index] - vdiff
|
423
|
+
mx_th = max(mx_th, th[index] - vdiff)
|
375
424
|
newpathsums = {}
|
376
425
|
for up in vpathsums:
|
377
426
|
newperms = elem_sym_perms_op(up, mx_th, th[index])
|
@@ -384,7 +433,8 @@ def schubmult_down(perm_dict, v, var2=None, var3=None):
|
|
384
433
|
continue
|
385
434
|
for v2, vdiff, s in vpathdicts[index][v]:
|
386
435
|
newpathsums[up2][v2] = newpathsums[up2].get(
|
387
|
-
v2,
|
436
|
+
v2,
|
437
|
+
zero,
|
388
438
|
) + s * sumval * elem_sym_func(
|
389
439
|
th[index],
|
390
440
|
index + 1,
|
@@ -398,14 +448,13 @@ def schubmult_down(perm_dict, v, var2=None, var3=None):
|
|
398
448
|
var3,
|
399
449
|
)
|
400
450
|
vpathsums = newpathsums
|
401
|
-
toget =
|
451
|
+
toget = vmu
|
402
452
|
ret_dict = add_perm_dict({ep: vpathsums[ep].get(toget, 0) for ep in vpathsums}, ret_dict)
|
403
453
|
return ret_dict
|
404
454
|
|
405
455
|
|
406
456
|
def poly_to_vec(poly, vec0=None, var3=_vars.var3):
|
407
|
-
|
408
|
-
poly = expand(poly.xreplace({var3[1]: 0}))
|
457
|
+
poly = expand(sympify(poly).xreplace({var3[1]: 0}))
|
409
458
|
|
410
459
|
dc = poly.as_coefficients_dict()
|
411
460
|
|
@@ -428,18 +477,18 @@ def poly_to_vec(poly, vec0=None, var3=_vars.var3):
|
|
428
477
|
return vec
|
429
478
|
|
430
479
|
|
431
|
-
def shiftsub(pol, var2=_vars.var2
|
432
|
-
subs_dict =
|
433
|
-
return sympify(pol)
|
480
|
+
def shiftsub(pol, var2=_vars.var2):
|
481
|
+
subs_dict = {var2[i]: var2[i + 1] for i in range(99)}
|
482
|
+
return efficient_subs(sympify(pol), subs_dict)
|
434
483
|
|
435
484
|
|
436
|
-
def shiftsubz(pol,
|
437
|
-
subs_dict =
|
438
|
-
return sympify(pol)
|
485
|
+
def shiftsubz(pol, var3=_vars.var3):
|
486
|
+
subs_dict = {var3[i]: var3[i + 1] for i in range(99)}
|
487
|
+
return efficient_subs(sympify(pol), subs_dict)
|
439
488
|
|
440
489
|
|
441
490
|
def init_basevec(dc):
|
442
|
-
global dimen, monom_to_vec, base_vec
|
491
|
+
global dimen, monom_to_vec, base_vec # noqa: PLW0603
|
443
492
|
monom_to_vec = {}
|
444
493
|
index = 0
|
445
494
|
for mn in dc:
|
@@ -462,12 +511,11 @@ def split_flat_term(arg):
|
|
462
511
|
ys += [arg2.args[1]]
|
463
512
|
else:
|
464
513
|
ys += [arg2]
|
514
|
+
elif isinstance(arg2, Mul):
|
515
|
+
for i in range(abs(int(arg2.args[0]))):
|
516
|
+
zs += [-arg2.args[1]]
|
465
517
|
else:
|
466
|
-
|
467
|
-
for i in range(abs(int(arg2.args[0]))):
|
468
|
-
zs += [-arg2.args[1]]
|
469
|
-
else:
|
470
|
-
zs += [arg2]
|
518
|
+
zs += [arg2]
|
471
519
|
return ys, zs
|
472
520
|
|
473
521
|
|
@@ -481,11 +529,11 @@ def is_flat_term(term):
|
|
481
529
|
return True
|
482
530
|
|
483
531
|
|
484
|
-
def flatten_factors(term
|
532
|
+
def flatten_factors(term):
|
485
533
|
found_one = False
|
486
534
|
if is_flat_term(term):
|
487
535
|
return term, False
|
488
|
-
|
536
|
+
if isinstance(term, Pow):
|
489
537
|
if is_flat_term(term.args[0]) and len(term.args[0].args) > 2:
|
490
538
|
ys, zs = split_flat_term(term.args[0])
|
491
539
|
terms = [1]
|
@@ -496,11 +544,10 @@ def flatten_factors(term, var2=_vars.var2, var3=_vars.var3):
|
|
496
544
|
terms2 += [t * (ys[i] + zs[i])]
|
497
545
|
terms = terms2
|
498
546
|
return Add(*terms)
|
499
|
-
|
547
|
+
if is_flat_term(term.args[0]):
|
500
548
|
return term, False
|
501
|
-
|
502
|
-
|
503
|
-
elif isinstance(term, Mul):
|
549
|
+
return flatten_factors(term.args[0]) ** term.args[1], True
|
550
|
+
if isinstance(term, Mul):
|
504
551
|
terms = [1]
|
505
552
|
for arg in term.args:
|
506
553
|
terms2 = []
|
@@ -528,7 +575,7 @@ def flatten_factors(term, var2=_vars.var2, var3=_vars.var3):
|
|
528
575
|
else:
|
529
576
|
term = Add(*terms)
|
530
577
|
return term, found_one
|
531
|
-
|
578
|
+
if isinstance(term, Add):
|
532
579
|
res = 0
|
533
580
|
for arg in term.args:
|
534
581
|
flat, found = flatten_factors(arg)
|
@@ -536,11 +583,13 @@ def flatten_factors(term, var2=_vars.var2, var3=_vars.var3):
|
|
536
583
|
found_one = True
|
537
584
|
res += flat
|
538
585
|
return res, found_one
|
586
|
+
return None
|
539
587
|
|
540
588
|
|
541
589
|
def fres(v):
|
542
590
|
for s in v.free_symbols:
|
543
591
|
return s
|
592
|
+
return None
|
544
593
|
|
545
594
|
|
546
595
|
def split_mul(arg0, var2=None, var3=None):
|
@@ -614,7 +663,7 @@ def is_negative(term):
|
|
614
663
|
sign = 1
|
615
664
|
if isinstance(term, Integer) or isinstance(term, int):
|
616
665
|
return term < 0
|
617
|
-
|
666
|
+
if isinstance(term, Mul):
|
618
667
|
for arg in term.args:
|
619
668
|
if isinstance(arg, Integer):
|
620
669
|
sign *= arg
|
@@ -625,49 +674,32 @@ def is_negative(term):
|
|
625
674
|
mulsign = 1
|
626
675
|
if str(arg.args[0]).find("-y") != -1:
|
627
676
|
mulsign = -1
|
628
|
-
sign *= mulsign
|
677
|
+
sign *= mulsign**term.index
|
629
678
|
elif isinstance(term, Pow):
|
630
679
|
mulsign = 1
|
631
680
|
if str(term.args[0]).find("-y") != -1:
|
632
681
|
mulsign = -1
|
633
|
-
sign *= mulsign
|
682
|
+
sign *= mulsign**term.index
|
634
683
|
return sign < 0
|
635
684
|
|
636
685
|
|
637
|
-
def find_base_vectors(monom_list,
|
686
|
+
def find_base_vectors(monom_list, var2, var3, depth):
|
638
687
|
size = 0
|
639
688
|
mn_fullcount = {}
|
640
689
|
# pairs_checked = set()
|
641
|
-
monom_list =
|
690
|
+
monom_list = {tuple(mn) for mn in monom_list}
|
642
691
|
ct = 0
|
643
692
|
while ct < depth and size != len(monom_list):
|
644
693
|
size = len(monom_list)
|
645
|
-
# found = False
|
646
|
-
# for mn in mons2:
|
647
|
-
# if mn not in monom_list:
|
648
|
-
# found = True
|
649
|
-
# break
|
650
|
-
# if not found:
|
651
|
-
# print("Breaking")
|
652
|
-
# break
|
653
|
-
|
654
694
|
monom_list2 = set(monom_list)
|
655
695
|
additional_set2 = set()
|
656
696
|
for mn in monom_list:
|
657
|
-
# res = 1
|
658
|
-
# for tp in mn:
|
659
|
-
# res *= var2[tp[0]] - var3[tp[1]]
|
660
|
-
# if poly_to_vec(res,vec) is None:
|
661
|
-
# continue
|
662
|
-
|
663
697
|
mncount = mn_fullcount.get(mn, {})
|
664
698
|
if mncount == {}:
|
665
699
|
for tp in mn:
|
666
700
|
mncount[tp] = mncount.get(tp, 0) + 1
|
667
701
|
mn_fullcount[mn] = mncount
|
668
702
|
for mn2 in monom_list:
|
669
|
-
# if (mn,mn2) in pairs_checked:
|
670
|
-
# continue
|
671
703
|
mn2count = mn_fullcount.get(mn2, {})
|
672
704
|
if mn2count == {}:
|
673
705
|
for tp in mn2:
|
@@ -692,8 +724,7 @@ def find_base_vectors(monom_list, monom_list_neg, var2, var3, depth):
|
|
692
724
|
break
|
693
725
|
# print(f"{mn,mn2}")
|
694
726
|
if diff_term1 is None or diff_term2 is None:
|
695
|
-
|
696
|
-
exit(1)
|
727
|
+
raise Exception(f"{mn=} {mn2=}")
|
697
728
|
if diff_term2[1] == diff_term1[1]:
|
698
729
|
continue
|
699
730
|
new_term1 = (diff_term1[0], diff_term2[1])
|
@@ -708,19 +739,9 @@ def find_base_vectors(monom_list, monom_list_neg, var2, var3, depth):
|
|
708
739
|
mn4 = list(mn2[:index2]) + list(mn2[index2 + 1 :])
|
709
740
|
index2 = bisect_left(mn4, new_term2)
|
710
741
|
mn4_t = tuple(mn4[:index2] + [new_term2] + mn4[index2:])
|
711
|
-
# res = 1
|
712
|
-
# for tp in mn3_t:
|
713
|
-
# res *= var2[tp[0]] - var3[tp[1]]
|
714
|
-
# if poly_to_vec(res,vec) is not None:
|
715
742
|
if mn3_t not in monom_list2:
|
716
743
|
additional_set2.add(mn3_t)
|
717
744
|
monom_list2.add(mn3_t)
|
718
|
-
# res = 1
|
719
|
-
# for tp in mn4_t:
|
720
|
-
# res *= var2[tp[0]] - var3[tp[1]]
|
721
|
-
##
|
722
|
-
## additional_set2.add(mn3_t)
|
723
|
-
# if poly_to_vec(res,vec) is not None:
|
724
745
|
if mn4_t not in monom_list2:
|
725
746
|
additional_set2.add(mn4_t)
|
726
747
|
monom_list2.add(mn4_t)
|
@@ -737,41 +758,34 @@ def find_base_vectors(monom_list, monom_list_neg, var2, var3, depth):
|
|
737
758
|
return ret, monom_list
|
738
759
|
|
739
760
|
|
740
|
-
def compute_positive_rep(val, var2=
|
761
|
+
def compute_positive_rep(val, var2=GeneratingSet("y"), var3=GeneratingSet("z"), msg=False, do_pos_neg=True):
|
762
|
+
do_pos_neg = False
|
741
763
|
notint = False
|
742
764
|
try:
|
743
|
-
int(expand(val))
|
744
|
-
val2 = expand(val)
|
765
|
+
val2 = int(expand(val))
|
766
|
+
# val2 = expand(val)
|
745
767
|
except Exception:
|
746
768
|
notint = True
|
747
769
|
if notint:
|
748
770
|
frees = val.free_symbols
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
for
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
for
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
varsimp2 = [m for m in frees if m in var2list]
|
763
|
-
varsimp3 = [m for m in frees if m in var3list]
|
764
|
-
varsimp2.sort(key=lambda k: var2list.index(k))
|
765
|
-
varsimp3.sort(key=lambda k: var3list.index(k))
|
766
|
-
|
767
|
-
var22 = [sympy.sympify(m) for m in varsimp2]
|
768
|
-
var33 = [sympy.sympify(m) for m in varsimp3]
|
771
|
+
# logger.debug(f"{frees=}")
|
772
|
+
# logger.debug(f"{[type(s) for s in frees]=}")
|
773
|
+
varsimp2 = [m for m in frees if var2.index(m) != -1]
|
774
|
+
varsimp3 = [m for m in frees if var3.index(m) != -1]
|
775
|
+
varsimp2.sort(key=lambda k: var2.index(k))
|
776
|
+
varsimp3.sort(key=lambda k: var3.index(k))
|
777
|
+
# logger.debug(f"{varsimp2=}")
|
778
|
+
# logger.debug(f"{varsimp3=}")
|
779
|
+
var22 = [sympy.sympify(v) for v in varsimp2]
|
780
|
+
var33 = [sympy.sympify(v) for v in varsimp3]
|
781
|
+
# var22 = [sympy.sympify(m) for m in varsimp2]
|
782
|
+
# var33 = [sympy.sympify(m) for m in varsimp3]
|
769
783
|
n1 = len(varsimp2)
|
770
784
|
|
771
|
-
for i in range(len(varsimp2)):
|
772
|
-
|
773
|
-
for i in range(len(varsimp3)):
|
774
|
-
|
785
|
+
# for i in range(len(varsimp2)):
|
786
|
+
# varsimp2[i] = var2[var2list.index(varsimp2[i])]
|
787
|
+
# for i in range(len(varsimp3)):
|
788
|
+
# varsimp3[i] = var3[var3list.index(varsimp3[i])]
|
775
789
|
|
776
790
|
base_vectors = []
|
777
791
|
base_monoms = []
|
@@ -798,9 +812,9 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
|
|
798
812
|
depth = 1
|
799
813
|
|
800
814
|
mons = split_monoms(pos_part, varsimp2, varsimp3)
|
801
|
-
mons =
|
815
|
+
mons = {tuple(mn) for mn in mons}
|
802
816
|
mons2 = split_monoms(neg_part, varsimp2, varsimp3)
|
803
|
-
mons2 =
|
817
|
+
mons2 = {tuple(mn2) for mn2 in mons2}
|
804
818
|
|
805
819
|
# mons2 = split_monoms(neg_part)
|
806
820
|
# for mn in mons2:
|
@@ -827,12 +841,9 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
|
|
827
841
|
for j in range(len(bad_vectors) - 1, -1, -1):
|
828
842
|
base_monoms.pop(bad_vectors[j])
|
829
843
|
|
830
|
-
vrs = [
|
831
|
-
pu.LpVariable(name=f"a{i}", lowBound=0, cat="Integer")
|
832
|
-
for i in range(len(base_vectors))
|
833
|
-
]
|
844
|
+
vrs = [pu.LpVariable(name=f"a{i}", lowBound=0, cat="Integer") for i in range(len(base_vectors))]
|
834
845
|
lp_prob = pu.LpProblem("Problem", pu.LpMinimize)
|
835
|
-
lp_prob +=
|
846
|
+
lp_prob += 0
|
836
847
|
eqs = [*base_vec]
|
837
848
|
for j in range(len(base_vectors)):
|
838
849
|
for i in base_vectors[j]:
|
@@ -862,38 +873,37 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
|
|
862
873
|
raise KeyboardInterrupt()
|
863
874
|
status = lp_prob.status
|
864
875
|
else:
|
876
|
+
# logger.debug("this")
|
865
877
|
val_poly = sympy.poly(expand(val), *var22, *var33)
|
866
878
|
vec = poly_to_vec(val)
|
867
879
|
mn = val_poly.monoms()
|
868
880
|
L1 = tuple([0 for i in range(n1)])
|
869
881
|
mn1L = []
|
870
882
|
lookup = {}
|
883
|
+
# logger.debug("this")
|
871
884
|
for mm0 in mn:
|
872
885
|
key = mm0[n1:]
|
873
886
|
if key not in lookup:
|
874
887
|
lookup[key] = []
|
875
888
|
mm0n1 = mm0[:n1]
|
876
889
|
st = set(mm0n1)
|
877
|
-
if len(st.intersection(
|
890
|
+
if len(st.intersection({0, 1})) == len(st) and 1 in st:
|
878
891
|
lookup[key] += [mm0]
|
879
892
|
if mm0n1 == L1:
|
880
893
|
mn1L += [mm0]
|
894
|
+
# logger.debug("this")
|
881
895
|
for mn1 in mn1L:
|
882
896
|
comblistmn1 = [1]
|
883
897
|
for i in range(n1, len(mn1)):
|
884
898
|
if mn1[i] != 0:
|
885
899
|
arr = np.array(comblistmn1)
|
886
900
|
comblistmn12 = []
|
887
|
-
mn1_2 =
|
901
|
+
mn1_2 = (*mn1[n1:i], 0, *mn1[i + 1 :])
|
888
902
|
for mm0 in lookup[mn1_2]:
|
889
903
|
comblistmn12 += (
|
890
904
|
arr
|
891
905
|
* np.prod(
|
892
|
-
[
|
893
|
-
varsimp2[k] - varsimp3[i - n1]
|
894
|
-
for k in range(n1)
|
895
|
-
if mm0[k] == 1
|
896
|
-
]
|
906
|
+
[varsimp2[k] - varsimp3[i - n1] for k in range(n1) if mm0[k] == 1],
|
897
907
|
)
|
898
908
|
).tolist()
|
899
909
|
comblistmn1 = comblistmn12
|
@@ -903,12 +913,9 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
|
|
903
913
|
if vec0 is not None:
|
904
914
|
base_vectors += [vec0]
|
905
915
|
base_monoms += [b1]
|
906
|
-
vrs = [
|
907
|
-
pu.LpVariable(name=f"a{i}", lowBound=0, cat="Integer")
|
908
|
-
for i in range(len(base_vectors))
|
909
|
-
]
|
916
|
+
vrs = [pu.LpVariable(name=f"a{i}", lowBound=0, cat="Integer") for i in range(len(base_vectors))]
|
910
917
|
lp_prob = pu.LpProblem("Problem", pu.LpMinimize)
|
911
|
-
lp_prob +=
|
918
|
+
lp_prob += 0
|
912
919
|
eqs = [*base_vec]
|
913
920
|
for j in range(len(base_vectors)):
|
914
921
|
for i in base_vectors[j]:
|
@@ -919,7 +926,9 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
|
|
919
926
|
eqs[i] += bvi * vrs[j]
|
920
927
|
for i in range(dimen):
|
921
928
|
lp_prob += eqs[i] == vec[i]
|
929
|
+
# logger.debug("I IS SOLVING")
|
922
930
|
try:
|
931
|
+
# logger.debug("I IS SOLVING BOLVING")
|
923
932
|
solver = pu.PULP_CBC_CMD(msg=msg)
|
924
933
|
status = lp_prob.solve(solver)
|
925
934
|
except KeyboardInterrupt:
|
@@ -944,145 +953,74 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
|
|
944
953
|
b1 = base_monoms[k]
|
945
954
|
if x != 0 and x is not None:
|
946
955
|
val2 += int(x) * b1
|
956
|
+
# logger.debug(f"{val2=}")
|
947
957
|
return val2
|
948
958
|
|
949
959
|
|
950
|
-
def
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
last = diff_perm[last] - 1
|
964
|
-
cycle.add(last + 1)
|
965
|
-
if len(cycle) > 1 and cycle not in cycles:
|
966
|
-
cycles += [cycle]
|
967
|
-
if len(cycles) > 2:
|
968
|
-
break
|
969
|
-
if len(cycles) == 2:
|
970
|
-
return True, cycles
|
971
|
-
else:
|
972
|
-
return False, []
|
973
|
-
|
974
|
-
|
975
|
-
def is_coeff_irreducible(u, v, w):
|
976
|
-
return (
|
977
|
-
not will_formula_work(u, v)
|
978
|
-
and not will_formula_work(v, u)
|
979
|
-
and not one_dominates(u, w)
|
980
|
-
and not is_reducible(v)
|
981
|
-
and inv(w) - inv(u) > 1
|
982
|
-
and not is_split_two(u, v, w)[0]
|
983
|
-
and len([i for i in code(v) if i != 0]) > 1
|
984
|
-
)
|
985
|
-
|
986
|
-
|
987
|
-
def is_hook(cd):
|
988
|
-
started = False
|
989
|
-
done = False
|
990
|
-
found_zero_after = False
|
991
|
-
for i in range(len(cd)):
|
992
|
-
if (done or found_zero_after) and cd[i] != 0:
|
993
|
-
return False
|
994
|
-
if cd[i] == 1 and not started:
|
995
|
-
started = True
|
996
|
-
if cd[i] > 1:
|
997
|
-
done = True
|
998
|
-
if started and cd[i] == 0:
|
999
|
-
found_zero_after = True
|
1000
|
-
if started or done:
|
1001
|
-
return True
|
1002
|
-
return False
|
1003
|
-
|
1004
|
-
|
1005
|
-
def div_diff(i, poly, var2=_vars.var2):
|
1006
|
-
return sympify(
|
1007
|
-
sympy.div(sympy.sympify(poly - permy(poly, i)), sympy.sympify(var2[i] - var2[i + 1]))[0]
|
1008
|
-
)
|
1009
|
-
|
1010
|
-
|
1011
|
-
def skew_div_diff(u, w, poly):
|
1012
|
-
d = -1
|
1013
|
-
for i in range(len(w) - 1):
|
1014
|
-
if w[i] > w[i + 1]:
|
1015
|
-
d = i
|
1016
|
-
break
|
1017
|
-
d2 = -1
|
1018
|
-
for i in range(len(u) - 1):
|
1019
|
-
if u[i] > u[i + 1]:
|
1020
|
-
d2 = i
|
1021
|
-
break
|
1022
|
-
if d == -1:
|
1023
|
-
if d2 == -1:
|
1024
|
-
return poly
|
1025
|
-
return 0
|
1026
|
-
w2 = [*w]
|
1027
|
-
w2[d], w2[d + 1] = w2[d + 1], w2[d]
|
1028
|
-
if d < len(u) - 1 and u[d] > u[d + 1]:
|
1029
|
-
u2 = [*u]
|
1030
|
-
u2[d], u2[d + 1] = u2[d + 1], u2[d]
|
1031
|
-
return skew_div_diff(u2, w2, permy(poly, d + 1))
|
1032
|
-
else:
|
1033
|
-
return skew_div_diff(u, w2, div_diff(d + 1, poly))
|
960
|
+
def posify_generic_partial(val, u2, v2, w2):
|
961
|
+
val2 = val
|
962
|
+
val = posify(val, u2, v2, w2, var2=_vars.var_g1, var3=_vars.var_g2, msg=True, do_pos_neg=False, sign_only=False, optimize=False)
|
963
|
+
if expand(val - val2) != 0:
|
964
|
+
# logger.debug("Warning, failed on a case")
|
965
|
+
raise Exception(f"{val=} {val2=} {u2=} {v2=} {w2=}")
|
966
|
+
# print("FROFL")
|
967
|
+
return val
|
968
|
+
|
969
|
+
|
970
|
+
@cache
|
971
|
+
def schubmult_generic_partial_posify(u2, v2):
|
972
|
+
return {w2: posify_generic_partial(val, u2, v2, w2) for w2, val in schubmult_double_pair_generic(u2, v2).items()}
|
1034
973
|
|
1035
974
|
|
1036
975
|
@cached(
|
1037
976
|
cache={},
|
1038
|
-
key=lambda val,
|
977
|
+
key=lambda val, u2, v2, w2, var2=None, var3=None, msg=False, do_pos_neg=False, sign_only=False, optimize=True: hashkey(val, u2, v2, w2, var2, var3, msg, do_pos_neg, sign_only, optimize),
|
978
|
+
)
|
979
|
+
def posify(
|
980
|
+
val,
|
1039
981
|
u2,
|
1040
982
|
v2,
|
1041
983
|
w2,
|
1042
984
|
var2=None,
|
1043
985
|
var3=None,
|
1044
986
|
msg=False,
|
1045
|
-
do_pos_neg=
|
1046
|
-
sign_only=False
|
1047
|
-
|
1048
|
-
|
1049
|
-
val, u2, v2, w2, var2=None, var3=None, msg=False, do_pos_neg=True, sign_only=False, n=_vars.n
|
987
|
+
do_pos_neg=False,
|
988
|
+
sign_only=False,
|
989
|
+
optimize=True,
|
990
|
+
n=_vars.n,
|
1050
991
|
):
|
992
|
+
# logger.debug(f"NEW {val=} {u2=} {v2=} {w2=}")
|
993
|
+
oldval = val
|
1051
994
|
if inv(u2) + inv(v2) - inv(w2) == 0:
|
995
|
+
# logger.debug(f"Hmm this is probably not or val inty true {val=}")
|
1052
996
|
return val
|
1053
|
-
|
1054
|
-
if set(cdv) == set([0, 1]) and do_pos_neg:
|
1055
|
-
return val
|
1056
|
-
# if is_hook(cdv):
|
1057
|
-
# print(f"Could've {cdv}")
|
997
|
+
|
1058
998
|
if not sign_only and expand(val) == 0:
|
999
|
+
# logger.debug(f"Hmm this is probably not true {u2=} {v2=} {w2=} {val=}")
|
1059
1000
|
return 0
|
1060
|
-
|
1061
|
-
u, v, w =
|
1062
|
-
|
1001
|
+
# logger.debug("proceeding")
|
1002
|
+
u, v, w = u2, v2, w2
|
1003
|
+
# u, v, w = try_reduce_v(u2, v2, w2)
|
1004
|
+
if is_coeff_irreducible(u2, v2, w2):
|
1063
1005
|
u, v, w = try_reduce_u(u2, v2, w2)
|
1064
1006
|
if is_coeff_irreducible(u, v, w):
|
1065
|
-
u, v, w =
|
1007
|
+
u, v, w = u2, v2, w2
|
1066
1008
|
if is_coeff_irreducible(u, v, w):
|
1067
|
-
w0 =
|
1009
|
+
w0 = w
|
1068
1010
|
u, v, w = reduce_descents(u, v, w)
|
1069
1011
|
if is_coeff_irreducible(u, v, w):
|
1070
1012
|
u, v, w = reduce_coeff(u, v, w)
|
1071
1013
|
if is_coeff_irreducible(u, v, w):
|
1072
|
-
while is_coeff_irreducible(u, v, w) and
|
1073
|
-
permtrim([*w])
|
1074
|
-
):
|
1014
|
+
while is_coeff_irreducible(u, v, w) and w0 != w:
|
1075
1015
|
w0 = w
|
1076
1016
|
u, v, w = reduce_descents(u, v, w)
|
1077
1017
|
if is_coeff_irreducible(u, v, w):
|
1078
1018
|
u, v, w = reduce_coeff(u, v, w)
|
1079
|
-
u = tuple(u)
|
1080
|
-
v = tuple(v)
|
1081
|
-
w = tuple(w)
|
1082
1019
|
|
1083
1020
|
if w != w2 and sign_only:
|
1021
|
+
# logger.debug(f"Return 0 ")
|
1084
1022
|
return 0
|
1085
|
-
|
1023
|
+
# logger.debug(f"Reduced to {u2=} {v2=} {w2=} {val=}")
|
1086
1024
|
if is_coeff_irreducible(u, v, w):
|
1087
1025
|
u3, v3, w3 = try_reduce_v(u, v, w)
|
1088
1026
|
if not is_coeff_irreducible(u3, v3, w3):
|
@@ -1092,8 +1030,9 @@ def posify(
|
|
1092
1030
|
if not is_coeff_irreducible(u3, v3, w3):
|
1093
1031
|
u, v, w = u3, v3, w3
|
1094
1032
|
split_two_b, split_two = is_split_two(u, v, w)
|
1095
|
-
|
1033
|
+
# logger.debug("Recording line number")
|
1096
1034
|
if len([i for i in code(v) if i != 0]) == 1:
|
1035
|
+
# logger.debug("Recording line number")
|
1097
1036
|
if sign_only:
|
1098
1037
|
return 0
|
1099
1038
|
cv = code(v)
|
@@ -1106,32 +1045,35 @@ def posify(
|
|
1106
1045
|
r = inv(w) - inv_u
|
1107
1046
|
val = 0
|
1108
1047
|
w2 = w
|
1109
|
-
hvarset = (
|
1110
|
-
|
1111
|
-
|
1112
|
-
+ [w2[b] for b in range(k, len(u)) if u[b] != w2[b]]
|
1113
|
-
+ [w2[b] for b in range(len(u), len(w2))]
|
1114
|
-
)
|
1115
|
-
val = elem_sym_poly(
|
1048
|
+
hvarset = [w2[i] for i in range(min(len(w2), k))] + [i + 1 for i in range(len(w2), k)] + [w2[b] for b in range(k, len(u)) if u[b] != w2[b]] + [w2[b] for b in range(len(u), len(w2))]
|
1049
|
+
# logger.debug(f"Returning {u2=} {v2=} {w2=} {val=}")
|
1050
|
+
return elem_sym_poly(
|
1116
1051
|
p - r,
|
1117
1052
|
k + p - 1,
|
1118
1053
|
[-var3[i] for i in range(1, n)],
|
1119
1054
|
[-var2[i] for i in hvarset],
|
1120
1055
|
)
|
1121
|
-
|
1056
|
+
# if expand(val - oldval) != 0:
|
1057
|
+
# # logger.debug("This is bad")
|
1058
|
+
# # logger.debug(f"{u2=} {v2=} {w2=} {val=} {oldval=}")
|
1059
|
+
if will_formula_work(v, u) or dominates(u, w):
|
1060
|
+
# logger.debug("Recording line number")
|
1122
1061
|
if sign_only:
|
1123
1062
|
return 0
|
1124
|
-
|
1125
|
-
|
1063
|
+
return dualcoeff(u, v, w, var2, var3)
|
1064
|
+
# if expand(val - oldval) != 0:
|
1065
|
+
# logger.debug("This is bad")
|
1066
|
+
# logger.debug(f"{u2=} {v2=} {w2=} {val=} {oldval=} {will_formula_work(v,u)=} {dominates(u,w)=}")
|
1067
|
+
# logger.debug(f"Returning {u2=} {v2=} {w2=} {val=}")
|
1068
|
+
if inv(w) - inv(u) == 1:
|
1069
|
+
# logger.debug("Recording line number")
|
1126
1070
|
if sign_only:
|
1127
1071
|
return 0
|
1128
1072
|
a, b = -1, -1
|
1129
1073
|
for i in range(len(w)):
|
1130
1074
|
if a == -1 and u[i] != w[i]:
|
1131
1075
|
a = i
|
1132
|
-
elif i >= len(u) and w[i] != i + 1:
|
1133
|
-
b = i
|
1134
|
-
elif b == -1 and u[i] != w[i]:
|
1076
|
+
elif (i >= len(u) and w[i] != i + 1) or (b == -1 and u[i] != w[i]):
|
1135
1077
|
b = i
|
1136
1078
|
arr = [[[], v]]
|
1137
1079
|
d = -1
|
@@ -1148,17 +1090,16 @@ def posify(
|
|
1148
1090
|
elif i > a:
|
1149
1091
|
i2 += 1
|
1150
1092
|
for vr, v2 in arr:
|
1151
|
-
dpret = pull_out_var(i2,
|
1093
|
+
dpret = pull_out_var(i2, v2)
|
1152
1094
|
for v3r, v3 in dpret:
|
1153
|
-
arr2 += [[vr
|
1095
|
+
arr2 += [[[*vr, v3r], v3]]
|
1154
1096
|
arr = arr2
|
1155
1097
|
val = 0
|
1156
1098
|
for L in arr:
|
1157
|
-
v3 =
|
1099
|
+
v3 = L[-1]
|
1158
1100
|
if v3[0] < v3[1]:
|
1159
1101
|
continue
|
1160
|
-
|
1161
|
-
v3[0], v3[1] = v3[1], v3[0]
|
1102
|
+
v3 = v3.swap(0, 1)
|
1162
1103
|
toadd = 1
|
1163
1104
|
for i in range(d):
|
1164
1105
|
if i in [a, b]:
|
@@ -1177,454 +1118,333 @@ def posify(
|
|
1177
1118
|
toadd *= var2[yv] - var3[oaf[j]]
|
1178
1119
|
toadd *= schubpoly(v3, [0, var2[w[a]], var2[w[b]]], var3)
|
1179
1120
|
val += toadd
|
1180
|
-
|
1121
|
+
# if expand(val - oldval) != 0:
|
1122
|
+
# logger.debug("This is bad")
|
1123
|
+
# logger.debug(f"{u2=} {v2=} {w2=} {val=} {oldval=}")
|
1124
|
+
# logger.debug(f"good to go {u2=} {v2=} {w2=}")
|
1125
|
+
return val
|
1126
|
+
# if split_two_b:
|
1127
|
+
# # logger.debug("Recording line number")
|
1128
|
+
# if sign_only:
|
1129
|
+
# return 0
|
1130
|
+
# cycles = split_two
|
1131
|
+
# a1, b1 = cycles[0]
|
1132
|
+
# a2, b2 = cycles[1]
|
1133
|
+
# a1 -= 1
|
1134
|
+
# b1 -= 1
|
1135
|
+
# a2 -= 1
|
1136
|
+
# b2 -= 1
|
1137
|
+
# spo = sorted([a1, b1, a2, b2])
|
1138
|
+
# real_a1 = min(spo.index(a1), spo.index(b1))
|
1139
|
+
# real_a2 = min(spo.index(a2), spo.index(b2))
|
1140
|
+
# real_b1 = max(spo.index(a1), spo.index(b1))
|
1141
|
+
# real_b2 = max(spo.index(a2), spo.index(b2))
|
1142
|
+
|
1143
|
+
# good1 = False
|
1144
|
+
# good2 = False
|
1145
|
+
# if real_b1 - real_a1 == 1:
|
1146
|
+
# good1 = True
|
1147
|
+
# if real_b2 - real_a2 == 1:
|
1148
|
+
# good2 = True
|
1149
|
+
# a, b = -1, -1
|
1150
|
+
# if good1 and not good2:
|
1151
|
+
# a, b = min(a2, b2), max(a2, b2)
|
1152
|
+
# if good2 and not good1:
|
1153
|
+
# a, b = min(a1, b1), max(a1, b1)
|
1154
|
+
# arr = [[[], v]]
|
1155
|
+
# d = -1
|
1156
|
+
# for i in range(len(v) - 1):
|
1157
|
+
# if v[i] > v[i + 1]:
|
1158
|
+
# d = i + 1
|
1159
|
+
# for i in range(d):
|
1160
|
+
# arr2 = []
|
1161
|
+
|
1162
|
+
# if i in [a1, b1, a2, b2]:
|
1163
|
+
# continue
|
1164
|
+
# i2 = 1
|
1165
|
+
# i2 += len([aa for aa in [a1, b1, a2, b2] if i > aa])
|
1166
|
+
# for vr, v2 in arr:
|
1167
|
+
# dpret = pull_out_var(i2, v2)
|
1168
|
+
# for v3r, v3 in dpret:
|
1169
|
+
# arr2 += [[[*vr, (v3r, i + 1)], v3]]
|
1170
|
+
# arr = arr2
|
1171
|
+
# val = 0
|
1172
|
+
|
1173
|
+
# if good1:
|
1174
|
+
# arr2 = []
|
1175
|
+
# for L in arr:
|
1176
|
+
# v3 = L[-1]
|
1177
|
+
# if v3[real_a1] < v3[real_b1]:
|
1178
|
+
# continue
|
1179
|
+
# v3 = v3.swap(real_a1, real_b1)
|
1180
|
+
# arr2 += [[L[0], v3]]
|
1181
|
+
# arr = arr2
|
1182
|
+
# if not good2:
|
1183
|
+
# for i in range(4):
|
1184
|
+
# arr2 = []
|
1185
|
+
|
1186
|
+
# if i in [real_a2, real_b2]:
|
1187
|
+
# continue
|
1188
|
+
# if i == real_a1:
|
1189
|
+
# var_index = min(a1, b1) + 1
|
1190
|
+
# elif i == real_b1:
|
1191
|
+
# var_index = max(a1, b1) + 1
|
1192
|
+
# i2 = 1
|
1193
|
+
# i2 += len([aa for aa in [real_a2, real_b2] if i > aa])
|
1194
|
+
# for vr, v2 in arr:
|
1195
|
+
# dpret = pull_out_var(i2, v2)
|
1196
|
+
# for v3r, v3 in dpret:
|
1197
|
+
# arr2 += [[[*vr, (v3r, var_index)], v3]]
|
1198
|
+
# arr = arr2
|
1199
|
+
# if good2:
|
1200
|
+
# arr2 = []
|
1201
|
+
# for L in arr:
|
1202
|
+
# v3 = L[-1]
|
1203
|
+
# try:
|
1204
|
+
# if v3[real_a2] < v3[real_b2]:
|
1205
|
+
# continue
|
1206
|
+
# v3 = v3.swap(real_a2, real_b2)
|
1207
|
+
# except IndexError:
|
1208
|
+
# continue
|
1209
|
+
# arr2 += [[L[0], v3]]
|
1210
|
+
# arr = arr2
|
1211
|
+
# if not good1:
|
1212
|
+
# for i in range(4):
|
1213
|
+
# arr2 = []
|
1214
|
+
|
1215
|
+
# if i in [real_a1, real_b1]:
|
1216
|
+
# continue
|
1217
|
+
# i2 = 1
|
1218
|
+
# i2 += len([aa for aa in [real_a1, real_b1] if i > aa])
|
1219
|
+
# if i == real_a2:
|
1220
|
+
# var_index = min(a2, b2) + 1
|
1221
|
+
# elif i == real_b2:
|
1222
|
+
# var_index = max(a2, b2) + 1
|
1223
|
+
# for vr, v2 in arr:
|
1224
|
+
# dpret = pull_out_var(i2, v2)
|
1225
|
+
# for v3r, v3 in dpret:
|
1226
|
+
# arr2 += [[[*vr, (v3r, var_index)], v3]]
|
1227
|
+
# arr = arr2
|
1228
|
+
|
1229
|
+
# for L in arr:
|
1230
|
+
# v3 = L[-1]
|
1231
|
+
# tomul = 1
|
1232
|
+
# doschubpoly = True
|
1233
|
+
# if (not good1 or not good2) and v3[0] < v3[1] and (good1 or good2):
|
1234
|
+
# continue
|
1235
|
+
# if (good1 or good2) and (not good1 or not good2):
|
1236
|
+
# v3 = v3.swap(0, 1)
|
1237
|
+
# elif not good1 and not good2:
|
1238
|
+
# doschubpoly = False
|
1239
|
+
# if v3[0] < v3[1]:
|
1240
|
+
# dual_u = uncode([2, 0])
|
1241
|
+
# dual_w = Permutation([4, 2, 1, 3])
|
1242
|
+
# coeff = perm_act(dualcoeff(dual_u, v3, dual_w, var2, var3), 2, var2)
|
1243
|
+
|
1244
|
+
# elif len(v3) < 3 or v3[1] < v3[2]:
|
1245
|
+
# if len(v3) <= 3 or v3[2] < v3[3]:
|
1246
|
+
# coeff = 0
|
1247
|
+
# continue
|
1248
|
+
# v3 = v3.swap(0, 1).swap(2, 3)
|
1249
|
+
# coeff = perm_act(schubpoly(v3, var2, var3), 2, var2)
|
1250
|
+
# elif len(v3) <= 3 or v3[2] < v3[3]:
|
1251
|
+
# if len(v3) <= 3:
|
1252
|
+
# v3 += [4]
|
1253
|
+
# v3 = v3.swap(2, 3)
|
1254
|
+
# coeff = perm_act(
|
1255
|
+
# posify(
|
1256
|
+
# schubmult_one(Permutation([1, 3, 2]), v3, var2, var3).get(
|
1257
|
+
# Permutation([2, 4, 3, 1]),
|
1258
|
+
# 0,
|
1259
|
+
# ),
|
1260
|
+
# Permutation([1, 3, 2]),
|
1261
|
+
# v3,
|
1262
|
+
# Permutation([2, 4, 3, 1]),
|
1263
|
+
# var2,
|
1264
|
+
# var3,
|
1265
|
+
# msg,
|
1266
|
+
# do_pos_neg,
|
1267
|
+
# optimize=optimize,
|
1268
|
+
# ),
|
1269
|
+
# 2,
|
1270
|
+
# var2,
|
1271
|
+
# )
|
1272
|
+
# # logger.debug(f"{coeff=}")
|
1273
|
+
# else:
|
1274
|
+
# coeff = perm_act(
|
1275
|
+
# schubmult_one(Permutation([1, 3, 2]), v3, var2, var3).get(
|
1276
|
+
# Permutation([2, 4, 1, 3]),
|
1277
|
+
# 0,
|
1278
|
+
# ),
|
1279
|
+
# 2,
|
1280
|
+
# var2,
|
1281
|
+
# )
|
1282
|
+
# # logger.debug(f"{coeff=}")
|
1283
|
+
# # if expand(coeff) == 0:
|
1284
|
+
# # # logger.debug("coeff 0 oh no")
|
1285
|
+
# tomul = sympify(coeff)
|
1286
|
+
# toadd = 1
|
1287
|
+
# for i in range(len(L[0])):
|
1288
|
+
# var_index = L[0][i][1]
|
1289
|
+
# oaf = L[0][i][0]
|
1290
|
+
# if var_index - 1 >= len(w):
|
1291
|
+
# yv = var_index
|
1292
|
+
# else:
|
1293
|
+
# yv = w[var_index - 1]
|
1294
|
+
# for j in range(len(oaf)):
|
1295
|
+
# toadd *= var2[yv] - var3[oaf[j]]
|
1296
|
+
# if (not good1 or not good2) and (good1 or good2):
|
1297
|
+
# varo = [0, var2[w[a]], var2[w[b]]]
|
1298
|
+
# else:
|
1299
|
+
# varo = [0, *[var2[w[spo[k]]] for k in range(4)]]
|
1300
|
+
# if doschubpoly:
|
1301
|
+
# toadd *= schubpoly(v3, varo, var3)
|
1302
|
+
# else:
|
1303
|
+
# subs_dict3 = {var2[i]: varo[i] for i in range(len(varo))}
|
1304
|
+
# toadd *= efficient_subs(tomul, subs_dict3)
|
1305
|
+
# val += toadd
|
1306
|
+
# # logger.debug(f"accum {val=}")
|
1307
|
+
# #logger.debug(f"{expand(val-oldval)=}")
|
1308
|
+
# # logger.debug(f"Returning {u2=} {v2=} {w2=} {val=}")
|
1309
|
+
# return val
|
1310
|
+
if will_formula_work(u, v):
|
1311
|
+
# logger.debug("Recording line number")
|
1181
1312
|
if sign_only:
|
1182
1313
|
return 0
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
good2 = False
|
1198
|
-
if real_b1 - real_a1 == 1:
|
1199
|
-
good1 = True
|
1200
|
-
if real_b2 - real_a2 == 1:
|
1201
|
-
good2 = True
|
1202
|
-
a, b = -1, -1
|
1203
|
-
if good1 and not good2:
|
1204
|
-
a, b = min(a2, b2), max(a2, b2)
|
1205
|
-
if good2 and not good1:
|
1206
|
-
a, b = min(a1, b1), max(a1, b1)
|
1207
|
-
arr = [[[], v]]
|
1208
|
-
d = -1
|
1209
|
-
for i in range(len(v) - 1):
|
1210
|
-
if v[i] > v[i + 1]:
|
1211
|
-
d = i + 1
|
1212
|
-
for i in range(d):
|
1213
|
-
arr2 = []
|
1214
|
-
|
1215
|
-
if i in [a1, b1, a2, b2]:
|
1216
|
-
continue
|
1217
|
-
i2 = 1
|
1218
|
-
i2 += len([aa for aa in [a1, b1, a2, b2] if i > aa])
|
1219
|
-
for vr, v2 in arr:
|
1220
|
-
dpret = pull_out_var(i2, [*v2])
|
1221
|
-
for v3r, v3 in dpret:
|
1222
|
-
arr2 += [[vr + [(v3r, i + 1)], v3]]
|
1223
|
-
arr = arr2
|
1224
|
-
val = 0
|
1225
|
-
|
1226
|
-
if good1:
|
1227
|
-
arr2 = []
|
1228
|
-
for L in arr:
|
1229
|
-
v3 = [*L[-1]]
|
1230
|
-
if v3[real_a1] < v3[real_b1]:
|
1231
|
-
continue
|
1232
|
-
else:
|
1233
|
-
v3[real_a1], v3[real_b1] = v3[real_b1], v3[real_a1]
|
1234
|
-
arr2 += [[L[0], v3]]
|
1235
|
-
arr = arr2
|
1236
|
-
if not good2:
|
1237
|
-
for i in range(4):
|
1238
|
-
arr2 = []
|
1239
|
-
|
1240
|
-
if i in [real_a2, real_b2]:
|
1241
|
-
continue
|
1242
|
-
if i == real_a1:
|
1243
|
-
var_index = min(a1, b1) + 1
|
1244
|
-
elif i == real_b1:
|
1245
|
-
var_index = max(a1, b1) + 1
|
1246
|
-
i2 = 1
|
1247
|
-
i2 += len([aa for aa in [real_a2, real_b2] if i > aa])
|
1248
|
-
for vr, v2 in arr:
|
1249
|
-
dpret = pull_out_var(i2, [*v2])
|
1250
|
-
for v3r, v3 in dpret:
|
1251
|
-
arr2 += [[vr + [(v3r, var_index)], v3]]
|
1252
|
-
arr = arr2
|
1253
|
-
if good2:
|
1254
|
-
arr2 = []
|
1255
|
-
for L in arr:
|
1256
|
-
v3 = [*L[-1]]
|
1257
|
-
try:
|
1258
|
-
if v3[real_a2] < v3[real_b2]:
|
1259
|
-
continue
|
1260
|
-
else:
|
1261
|
-
v3[real_a2], v3[real_b2] = v3[real_b2], v3[real_a2]
|
1262
|
-
except IndexError:
|
1263
|
-
continue
|
1264
|
-
arr2 += [[L[0], v3]]
|
1265
|
-
arr = arr2
|
1266
|
-
if not good1:
|
1267
|
-
for i in range(4):
|
1268
|
-
arr2 = []
|
1269
|
-
|
1270
|
-
if i in [real_a1, real_b1]:
|
1271
|
-
continue
|
1272
|
-
i2 = 1
|
1273
|
-
i2 += len([aa for aa in [real_a1, real_b1] if i > aa])
|
1274
|
-
if i == real_a2:
|
1275
|
-
var_index = min(a2, b2) + 1
|
1276
|
-
elif i == real_b2:
|
1277
|
-
var_index = max(a2, b2) + 1
|
1278
|
-
for vr, v2 in arr:
|
1279
|
-
dpret = pull_out_var(i2, [*v2])
|
1280
|
-
for v3r, v3 in dpret:
|
1281
|
-
arr2 += [[vr + [(v3r, var_index)], v3]]
|
1282
|
-
arr = arr2
|
1283
|
-
|
1284
|
-
for L in arr:
|
1285
|
-
v3 = [*L[-1]]
|
1286
|
-
tomul = 1
|
1287
|
-
doschubpoly = True
|
1288
|
-
if (not good1 or not good2) and v3[0] < v3[1] and (good1 or good2):
|
1289
|
-
continue
|
1290
|
-
elif (good1 or good2) and (not good1 or not good2):
|
1291
|
-
v3[0], v3[1] = v3[1], v3[0]
|
1292
|
-
elif not good1 and not good2:
|
1293
|
-
doschubpoly = False
|
1294
|
-
if v3[0] < v3[1]:
|
1295
|
-
dual_u = uncode([2, 0])
|
1296
|
-
dual_w = [4, 2, 1, 3]
|
1297
|
-
coeff = permy(dualcoeff(dual_u, v3, dual_w, var2, var3), 2)
|
1298
|
-
|
1299
|
-
elif len(v3) < 3 or v3[1] < v3[2]:
|
1300
|
-
if len(v3) <= 3 or v3[2] < v3[3]:
|
1301
|
-
coeff = 0
|
1302
|
-
continue
|
1303
|
-
else:
|
1304
|
-
v3[0], v3[1] = v3[1], v3[0]
|
1305
|
-
v3[2], v3[3] = v3[3], v3[2]
|
1306
|
-
coeff = permy(schubpoly(v3, var2, var3), 2)
|
1307
|
-
elif len(v3) <= 3 or v3[2] < v3[3]:
|
1308
|
-
if len(v3) <= 3:
|
1309
|
-
v3 += [4]
|
1310
|
-
v3[2], v3[3] = v3[3], v3[2]
|
1311
|
-
coeff = permy(
|
1312
|
-
posify(
|
1313
|
-
schubmult_one((1, 3, 2), tuple(permtrim([*v3])), var2, var3).get(
|
1314
|
-
(2, 4, 3, 1), 0
|
1315
|
-
),
|
1316
|
-
(1, 3, 2),
|
1317
|
-
tuple(permtrim([*v3])),
|
1318
|
-
(2, 4, 3, 1),
|
1319
|
-
var2,
|
1320
|
-
var3,
|
1321
|
-
msg,
|
1322
|
-
do_pos_neg,
|
1323
|
-
),
|
1324
|
-
2,
|
1325
|
-
)
|
1326
|
-
else:
|
1327
|
-
coeff = permy(
|
1328
|
-
schubmult_one((1, 3, 2), tuple(permtrim([*v3])), var2, var3).get(
|
1329
|
-
(2, 4, 1, 3), 0
|
1330
|
-
),
|
1331
|
-
2,
|
1332
|
-
)
|
1333
|
-
tomul = sympify(coeff)
|
1334
|
-
toadd = 1
|
1335
|
-
for i in range(len(L[0])):
|
1336
|
-
var_index = L[0][i][1]
|
1337
|
-
oaf = L[0][i][0]
|
1338
|
-
if var_index - 1 >= len(w):
|
1339
|
-
yv = var_index
|
1340
|
-
else:
|
1341
|
-
yv = w[var_index - 1]
|
1342
|
-
for j in range(len(oaf)):
|
1343
|
-
toadd *= var2[yv] - var3[oaf[j]]
|
1344
|
-
if (not good1 or not good2) and (good1 or good2):
|
1345
|
-
varo = [0, var2[w[a]], var2[w[b]]]
|
1346
|
-
else:
|
1347
|
-
varo = [0, *[var2[w[spo[k]]] for k in range(4)]]
|
1348
|
-
if doschubpoly:
|
1349
|
-
toadd *= schubpoly(v3, varo, var3)
|
1350
|
-
else:
|
1351
|
-
subs_dict3 = {var2[i]: varo[i] for i in range(len(varo))}
|
1352
|
-
toadd *= tomul.subs(subs_dict3)
|
1353
|
-
val += toadd
|
1354
|
-
elif will_formula_work(u, v):
|
1314
|
+
# logger.debug(f"Returning {u2=} {v2=} {w2=} {val=}")
|
1315
|
+
return forwardcoeff(u, v, w, var2, var3)
|
1316
|
+
# if expand(val - oldval) != 0:
|
1317
|
+
# # logger.debug("This is bad")
|
1318
|
+
# # logger.debug(f"{u2=} {v2=} {w2=} {val=} {oldval=}")
|
1319
|
+
# logger.debug("Recording line number")
|
1320
|
+
# c01 = code(u)
|
1321
|
+
# c02 = code(w)
|
1322
|
+
# c03 = code(v)
|
1323
|
+
|
1324
|
+
c1 = code(~u)
|
1325
|
+
c2 = code(~w)
|
1326
|
+
|
1327
|
+
if one_dominates(u, w):
|
1355
1328
|
if sign_only:
|
1356
1329
|
return 0
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
c01
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1330
|
+
while c1[0] != c2[0]:
|
1331
|
+
w = w.swap(c2[0] - 1, c2[0])
|
1332
|
+
v = v.swap(c2[0] - 1, c2[0])
|
1333
|
+
# w[c2[0] - 1], w[c2[0]] = w[c2[0]], w[c2[0] - 1]
|
1334
|
+
# v[c2[0] - 1], v[c2[0]] = v[c2[0]], v[c2[0] - 1]
|
1335
|
+
# w = tuple(w)
|
1336
|
+
# v = tuple(v)
|
1337
|
+
c2 = code(~w)
|
1338
|
+
# c03 = code(v)
|
1339
|
+
# c01 = code(u)
|
1340
|
+
# c02 = code(w)
|
1341
|
+
# if is_reducible(v):
|
1342
|
+
# # logger.debug("Recording line number")
|
1343
|
+
# if sign_only:
|
1344
|
+
# return 0
|
1345
|
+
# newc = []
|
1346
|
+
# elemc = []
|
1347
|
+
# for i in range(len(c03)):
|
1348
|
+
# if c03[i] > 0:
|
1349
|
+
# newc += [c03[i] - 1]
|
1350
|
+
# elemc += [1]
|
1351
|
+
# else:
|
1352
|
+
# break
|
1353
|
+
# v3 = uncode(newc)
|
1354
|
+
# coeff_dict = schubmult_one(
|
1355
|
+
# u,
|
1356
|
+
# uncode(elemc),
|
1357
|
+
# var2,
|
1358
|
+
# var3,
|
1359
|
+
# )
|
1360
|
+
# val = 0
|
1361
|
+
# for new_w in coeff_dict:
|
1362
|
+
# tomul = coeff_dict[new_w]
|
1363
|
+
# newval = schubmult_one(new_w, uncode(newc), var2, var3).get(
|
1364
|
+
# w,
|
1365
|
+
# 0,
|
1366
|
+
# )
|
1367
|
+
# # logger.debug(f"Calling posify on {newval=} {new_w=} {uncode(newc)=} {w=}")
|
1368
|
+
# newval = posify(newval, new_w, uncode(newc), w, var2, var3, msg, do_pos_neg, optimize=optimize)
|
1369
|
+
# val += tomul * shiftsubz(newval)
|
1370
|
+
# # if expand(val - oldval) != 0:
|
1371
|
+
# # # logger.debug("This is bad")
|
1372
|
+
# # # logger.debug(f"{u2=} {v2=} {w2=} {val=} {oldval=}")
|
1373
|
+
# # logger.debug(f"Returning {u2=} {v2=} {w2=} {val=}")
|
1374
|
+
# return val
|
1375
|
+
# removed, iffy (hard to implement)
|
1376
|
+
# if c01[0] == c02[0] and c01[0] != 0:
|
1377
|
+
# # logger.debug("Recording line number")
|
1378
|
+
# if sign_only:
|
1379
|
+
# return 0
|
1380
|
+
# varl = c01[0]
|
1381
|
+
# u3 = uncode([0] + c01[1:])
|
1382
|
+
# w3 = uncode([0] + c02[1:])
|
1383
|
+
# val = 0
|
1384
|
+
# val = schubmult_one(u3, v, var2, var3).get(
|
1385
|
+
# w3,
|
1386
|
+
# 0,
|
1387
|
+
# )
|
1388
|
+
# # logger.debug(f"Calling posify on {val=} {u3=} {v=} {w3=}")
|
1389
|
+
# val = posify(val, u3, v, w3, var2, var3, msg, do_pos_neg, optimize=optimize)
|
1390
|
+
# for i in range(varl):
|
1391
|
+
# val = perm_act(val, i + 1, var2)
|
1392
|
+
# # if expand(val - oldval) != 0:
|
1393
|
+
# # # logger.debug("This is bad")
|
1394
|
+
# # # logger.debug(f"{u2=} {v2=} {w2=} {val=} {oldval=}")
|
1395
|
+
# # logger.debug(f"Returning {u2=} {v2=} {w2=} {val=}")
|
1396
|
+
# return val
|
1397
|
+
if c1[0] == c2[0]:
|
1398
|
+
# logger.debug("Recording line number")
|
1426
1399
|
if sign_only:
|
1427
1400
|
return 0
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
if c03[i] > 0:
|
1432
|
-
newc += [c03[i] - 1]
|
1433
|
-
elemc += [1]
|
1434
|
-
else:
|
1435
|
-
break
|
1436
|
-
v3 = uncode(newc)
|
1437
|
-
coeff_dict = schubmult_one(
|
1438
|
-
tuple(permtrim([*u])), tuple(permtrim(uncode(elemc))), var2, var3
|
1439
|
-
)
|
1440
|
-
val = 0
|
1441
|
-
for new_w in coeff_dict:
|
1442
|
-
tomul = coeff_dict[new_w]
|
1443
|
-
newval = schubmult_one(new_w, tuple(permtrim(uncode(newc))), var2, var3).get(
|
1444
|
-
tuple(permtrim([*w])), 0
|
1445
|
-
)
|
1446
|
-
newval = posify(
|
1447
|
-
newval,
|
1448
|
-
new_w,
|
1449
|
-
tuple(permtrim(uncode(newc))),
|
1450
|
-
w,
|
1451
|
-
var2,
|
1452
|
-
var3,
|
1453
|
-
msg,
|
1454
|
-
do_pos_neg,
|
1455
|
-
)
|
1456
|
-
val += tomul * shiftsubz(newval)
|
1457
|
-
elif c01[0] == c02[0] and c01[0] != 0:
|
1458
|
-
if sign_only:
|
1459
|
-
return 0
|
1460
|
-
varl = c01[0]
|
1461
|
-
u3 = uncode([0] + c01[1:])
|
1462
|
-
w3 = uncode([0] + c02[1:])
|
1463
|
-
val = 0
|
1464
|
-
val = schubmult_one(tuple(permtrim(u3)), tuple(permtrim([*v])), var2, var3).get(
|
1465
|
-
tuple(permtrim(w3)), 0
|
1466
|
-
)
|
1467
|
-
val = posify(
|
1468
|
-
val,
|
1469
|
-
tuple(permtrim(u3)),
|
1470
|
-
tuple(permtrim([*v])),
|
1471
|
-
tuple(permtrim(w3)),
|
1472
|
-
var2,
|
1473
|
-
var3,
|
1474
|
-
msg,
|
1475
|
-
do_pos_neg,
|
1476
|
-
)
|
1477
|
-
for i in range(varl):
|
1478
|
-
val = permy(val, i + 1)
|
1479
|
-
elif c1[0] == c2[0]:
|
1480
|
-
if sign_only:
|
1481
|
-
return 0
|
1482
|
-
vp = pull_out_var(c1[0] + 1, [*v])
|
1483
|
-
u3 = tuple(permtrim(phi1(u)))
|
1484
|
-
w3 = tuple(permtrim(phi1(w)))
|
1401
|
+
vp = pull_out_var(c1[0] + 1, v)
|
1402
|
+
u3 = phi1(u)
|
1403
|
+
w3 = phi1(w)
|
1485
1404
|
val = 0
|
1486
1405
|
for arr, v3 in vp:
|
1487
1406
|
tomul = 1
|
1488
1407
|
for i in range(len(arr)):
|
1489
1408
|
tomul *= var2[1] - var3[arr[i]]
|
1490
1409
|
|
1491
|
-
val2 =
|
1492
|
-
|
1410
|
+
val2 = schubmult_double_pair(u3, v3, var2, var3).get(
|
1411
|
+
w3,
|
1412
|
+
0,
|
1493
1413
|
)
|
1494
|
-
val2 = posify(val2, u3,
|
1414
|
+
val2 = posify(val2, u3, v3, w3, var2, var3, msg, do_pos_neg, optimize=optimize)
|
1495
1415
|
val += tomul * shiftsub(val2)
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
#
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
# arr2 = []
|
1508
|
-
#
|
1509
|
-
# if i+1 in indices:
|
1510
|
-
# continue
|
1511
|
-
# i2 = 1
|
1512
|
-
# i2 += len([aa for aa in indices if i+1>aa])
|
1513
|
-
# for vr, v2 in arr:
|
1514
|
-
# dpret = pull_out_var(i2,[*v2])
|
1515
|
-
# for v3r, v3 in dpret:
|
1516
|
-
# arr2 += [[vr + [(v3r,i+1)],v3]]
|
1517
|
-
# arr = arr2
|
1518
|
-
# val = 0
|
1519
|
-
#
|
1520
|
-
# for L in arr:
|
1521
|
-
# v3 = [*L[-1]]
|
1522
|
-
# tomul = 1
|
1523
|
-
# toadd = 1
|
1524
|
-
# for i in range(len(L[0])):
|
1525
|
-
# var_index = L[0][i][1]
|
1526
|
-
# oaf = L[0][i][0]
|
1527
|
-
# if var_index-1>=len(w):
|
1528
|
-
# yv = var_index
|
1529
|
-
# else:
|
1530
|
-
# yv = w[var_index-1]
|
1531
|
-
# for j in range(len(oaf)):
|
1532
|
-
# toadd*= var2[yv] - var3[oaf[j]]
|
1533
|
-
# pooly = skew_div_diff(u,w,schubpoly(v3,[0,*[var2[a] for a in indices]],var3))
|
1534
|
-
# if toadd == 0:
|
1535
|
-
# continue
|
1536
|
-
# if pooly !=0:
|
1537
|
-
# coeff = compute_positive_rep(pooly,var2,var3,msg,False)
|
1538
|
-
# else:
|
1539
|
-
# coeff = 0
|
1540
|
-
# if coeff == -1:
|
1541
|
-
# return -1
|
1542
|
-
# tomul = sympify(coeff)
|
1543
|
-
# toadd*=tomul#.subs(subs_dict3)
|
1544
|
-
# val += toadd
|
1545
|
-
else:
|
1546
|
-
if not sign_only:
|
1547
|
-
if inv(u) + inv(v) - inv(w) == 1:
|
1548
|
-
val2 = compute_positive_rep(val, var2, var3, msg, False)
|
1549
|
-
else:
|
1550
|
-
val2 = compute_positive_rep(val, var2, var3, msg, do_pos_neg)
|
1551
|
-
if val2 is not None:
|
1552
|
-
val = val2
|
1416
|
+
# if expand(val - oldval) != 0:
|
1417
|
+
# # logger.debug("This is bad")
|
1418
|
+
# # logger.debug(f"{u2=} {v2=} {w2=} {val=} {oldval=")
|
1419
|
+
# logger.debug(f"Returning {u2=} {v2=} {w2=} {val=}")
|
1420
|
+
return val
|
1421
|
+
# logger.debug("Fell all the way through. Cleverness did not save us")
|
1422
|
+
if not sign_only:
|
1423
|
+
# logger.debug("Recording line number")
|
1424
|
+
if optimize:
|
1425
|
+
if inv(u) + inv(v) - inv(w) == 1:
|
1426
|
+
val2 = compute_positive_rep(val, var2, var3, msg, False)
|
1553
1427
|
else:
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
for i in range(len(cd)):
|
1575
|
-
if cd[i] != 0:
|
1576
|
-
not_zero = True
|
1577
|
-
elif not_zero and cd[i] == 0:
|
1578
|
-
not_zero = False
|
1579
|
-
index = i
|
1580
|
-
num_zeros_to_miss = 0
|
1581
|
-
for j in range(index):
|
1582
|
-
if cd[j] != 0:
|
1583
|
-
num_zeros_to_miss = max(num_zeros_to_miss, cd[j] - (index - 1 - j))
|
1584
|
-
num_zeros = 0
|
1585
|
-
for j in range(index, len(cd)):
|
1586
|
-
if cd[j] != 0:
|
1587
|
-
break
|
1588
|
-
else:
|
1589
|
-
num_zeros += 1
|
1590
|
-
if num_zeros >= num_zeros_to_miss:
|
1591
|
-
cd1 = cd[:index]
|
1592
|
-
cd2 = [0 for i in range(index)] + cd[index:]
|
1593
|
-
perms2 += [
|
1594
|
-
tuple(permtrim(uncode(cd1))),
|
1595
|
-
tuple(permtrim(uncode(cd2))),
|
1596
|
-
]
|
1597
|
-
did = True
|
1598
|
-
break
|
1599
|
-
if not did:
|
1600
|
-
perms2 += [perm]
|
1601
|
-
return perms2
|
1602
|
-
|
1603
|
-
|
1604
|
-
def schubpoly(v, var2=None, var3=None, start_var=1):
|
1605
|
-
n = 0
|
1606
|
-
for j in range(len(v) - 2, -1, -1):
|
1607
|
-
if v[j] > v[j + 1]:
|
1608
|
-
n = j + 1
|
1609
|
-
break
|
1610
|
-
if n == 0:
|
1611
|
-
return 1
|
1612
|
-
lst = pull_out_var(n, v)
|
1613
|
-
ret = 0
|
1614
|
-
for pw, vp in lst:
|
1615
|
-
tomul = 1
|
1616
|
-
for p in pw:
|
1617
|
-
tomul *= var2[start_var + n - 1] - var3[p]
|
1618
|
-
ret += tomul * schubpoly(vp, var2, var3, start_var)
|
1619
|
-
return ret
|
1620
|
-
|
1621
|
-
|
1622
|
-
def permy(val, i, var2=_vars.var2):
|
1623
|
-
subsdict = {var2[i]: var2[i + 1], var2[i + 1]: var2[i]}
|
1624
|
-
return sympify(val).subs(subsdict)
|
1625
|
-
|
1626
|
-
|
1627
|
-
def schub_coprod(mperm, indices, var2=_vars.var2, var3=_vars.var3):
|
1428
|
+
val2 = compute_positive_rep(val, var2, var3, msg, do_pos_neg)
|
1429
|
+
if val2 is not None:
|
1430
|
+
val = val2
|
1431
|
+
return val
|
1432
|
+
# logger.debug("RETURNINGOLDVAL")
|
1433
|
+
return oldval
|
1434
|
+
# logger.debug("Recording line number")
|
1435
|
+
d = expand(val).as_coefficients_dict()
|
1436
|
+
for v in d.values():
|
1437
|
+
if v < 0:
|
1438
|
+
return -1
|
1439
|
+
return 1
|
1440
|
+
|
1441
|
+
# if expand(val - oldval) !=0:
|
1442
|
+
# # logger.debug("NONONOONOO")
|
1443
|
+
# raise Exception
|
1444
|
+
# return val
|
1445
|
+
|
1446
|
+
|
1447
|
+
def schub_coprod_double(mperm, indices, var2=_vars.var2, var3=_vars.var3):
|
1628
1448
|
indices = sorted(indices)
|
1629
1449
|
subs_dict_coprod = {}
|
1630
1450
|
k = len(indices)
|
@@ -1633,9 +1453,9 @@ def schub_coprod(mperm, indices, var2=_vars.var2, var3=_vars.var3):
|
|
1633
1453
|
max_required = max([kcd[i] + i for i in range(len(kcd))])
|
1634
1454
|
kcd2 = kcd + [0 for i in range(len(kcd), max_required)] + [0]
|
1635
1455
|
N = len(kcd)
|
1636
|
-
kperm =
|
1456
|
+
kperm = ~uncode(kcd2)
|
1637
1457
|
inv_kperm = inv(kperm)
|
1638
|
-
vn =
|
1458
|
+
vn = GeneratingSet("soible")
|
1639
1459
|
|
1640
1460
|
for i in range(1, N * 2 + 1):
|
1641
1461
|
if i <= N:
|
@@ -1643,14 +1463,14 @@ def schub_coprod(mperm, indices, var2=_vars.var2, var3=_vars.var3):
|
|
1643
1463
|
else:
|
1644
1464
|
subs_dict_coprod[vn[i]] = var3[i - N]
|
1645
1465
|
|
1646
|
-
coeff_dict = {
|
1647
|
-
coeff_dict =
|
1466
|
+
coeff_dict = {kperm: 1}
|
1467
|
+
coeff_dict = schubmult_double(coeff_dict, mperm, vn, var2)
|
1648
1468
|
|
1649
|
-
inverse_kperm =
|
1469
|
+
inverse_kperm = ~kperm
|
1650
1470
|
|
1651
1471
|
ret_dict = {}
|
1652
1472
|
for perm in coeff_dict:
|
1653
|
-
downperm =
|
1473
|
+
downperm = perm * inverse_kperm
|
1654
1474
|
if inv(downperm) == inv(perm) - inv_kperm:
|
1655
1475
|
flag = True
|
1656
1476
|
for i in range(N):
|
@@ -1659,12 +1479,12 @@ def schub_coprod(mperm, indices, var2=_vars.var2, var3=_vars.var3):
|
|
1659
1479
|
break
|
1660
1480
|
if not flag:
|
1661
1481
|
continue
|
1662
|
-
firstperm = downperm[0:N]
|
1663
|
-
secondperm = [downperm[i] - N for i in range(N, len(downperm))]
|
1482
|
+
firstperm = Permutation(downperm[0:N])
|
1483
|
+
secondperm = Permutation([downperm[i] - N for i in range(N, len(downperm))])
|
1664
1484
|
|
1665
|
-
val = sympify(coeff_dict[perm])
|
1485
|
+
val = efficient_subs(sympify(coeff_dict[perm]), subs_dict_coprod)
|
1666
1486
|
|
1667
|
-
key = (
|
1487
|
+
key = (firstperm, secondperm)
|
1668
1488
|
ret_dict[key] = val
|
1669
1489
|
|
1670
1490
|
return ret_dict
|