schubmult 2.0.3__py3-none-any.whl → 2.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. schubmult/__init__.py +1 -1
  2. schubmult/_base_argparse.py +11 -6
  3. schubmult/_tests.py +19 -4
  4. schubmult/perm_lib.py +52 -112
  5. schubmult/sage_integration/__init__.py +13 -14
  6. schubmult/sage_integration/_fast_double_schubert_polynomial_ring.py +92 -128
  7. schubmult/sage_integration/_fast_schubert_polynomial_ring.py +55 -54
  8. schubmult/sage_integration/_indexing.py +35 -39
  9. schubmult/schubmult_double/__init__.py +5 -15
  10. schubmult/schubmult_double/__main__.py +1 -0
  11. schubmult/schubmult_double/_funcs.py +140 -256
  12. schubmult/schubmult_double/_script.py +41 -41
  13. schubmult/schubmult_py/__init__.py +3 -4
  14. schubmult/schubmult_py/__main__.py +1 -0
  15. schubmult/schubmult_py/_funcs.py +18 -18
  16. schubmult/schubmult_py/_script.py +12 -11
  17. schubmult/schubmult_q/__init__.py +2 -7
  18. schubmult/schubmult_q/__main__.py +1 -0
  19. schubmult/schubmult_q/_funcs.py +24 -27
  20. schubmult/schubmult_q/_script.py +27 -21
  21. schubmult/schubmult_q_double/__init__.py +4 -11
  22. schubmult/schubmult_q_double/__main__.py +1 -0
  23. schubmult/schubmult_q_double/_funcs.py +48 -48
  24. schubmult/schubmult_q_double/_script.py +39 -41
  25. schubmult-2.0.4.dist-info/METADATA +542 -0
  26. schubmult-2.0.4.dist-info/RECORD +30 -0
  27. {schubmult-2.0.3.dist-info → schubmult-2.0.4.dist-info}/WHEEL +1 -1
  28. schubmult-2.0.3.dist-info/METADATA +0 -455
  29. schubmult-2.0.3.dist-info/RECORD +0 -30
  30. {schubmult-2.0.3.dist-info → schubmult-2.0.4.dist-info}/entry_points.txt +0 -0
  31. {schubmult-2.0.3.dist-info → schubmult-2.0.4.dist-info}/licenses/LICENSE +0 -0
  32. {schubmult-2.0.3.dist-info → schubmult-2.0.4.dist-info}/top_level.txt +0 -0
@@ -1,42 +1,43 @@
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 symengine import sympify, Add, Mul, Pow, expand, Integer, symarray
10
+ from sortedcontainers import SortedList
11
+ from symengine import Add, Integer, Mul, Pow, expand, symarray, sympify
12
+
6
13
  from schubmult.perm_lib import (
7
- elem_sym_perms,
8
- elem_sym_poly,
9
14
  add_perm_dict,
10
- dominates,
11
- compute_vpathdicts,
12
- inverse,
13
- theta,
14
- permtrim,
15
- inv,
16
- mulperm,
17
15
  code,
18
- uncode,
16
+ compute_vpathdicts,
17
+ cycle,
18
+ divdiffable,
19
+ dominates,
19
20
  elem_sym_func,
21
+ elem_sym_perms,
20
22
  elem_sym_perms_op,
21
- divdiffable,
22
- pull_out_var,
23
- cycle,
24
- will_formula_work,
25
- one_dominates,
23
+ elem_sym_poly,
24
+ inv,
25
+ inverse,
26
26
  is_reducible,
27
+ mulperm,
28
+ one_dominates,
29
+ permtrim,
30
+ phi1,
31
+ pull_out_var,
27
32
  reduce_coeff,
28
33
  reduce_descents,
34
+ theta,
29
35
  try_reduce_u,
30
36
  try_reduce_v,
31
- phi1,
37
+ uncode,
38
+ will_formula_work,
32
39
  zero,
33
40
  )
34
- import numpy as np
35
- import pulp as pu
36
- import sympy
37
- import psutil
38
- from sortedcontainers import SortedList
39
- from functools import cached_property
40
41
 
41
42
  # NO GLOBAL VARS
42
43
  # from ._vars import (
@@ -133,55 +134,53 @@ def single_variable_down(coeff_dict, varnum, var2=_vars.var2):
133
134
  def mult_poly(coeff_dict, poly, var_x=_vars.var1, var_y=_vars.var2):
134
135
  if poly in var_x:
135
136
  return single_variable(coeff_dict, var_x.index(poly), var_y)
136
- elif isinstance(poly, Mul):
137
+ if isinstance(poly, Mul):
137
138
  ret = coeff_dict
138
139
  for a in poly.args:
139
140
  ret = mult_poly(ret, a, var_x, var_y)
140
141
  return ret
141
- elif isinstance(poly, Pow):
142
+ if isinstance(poly, Pow):
142
143
  base = poly.args[0]
143
144
  exponent = int(poly.args[1])
144
145
  ret = coeff_dict
145
146
  for i in range(int(exponent)):
146
147
  ret = mult_poly(ret, base, var_x, var_y)
147
148
  return ret
148
- elif isinstance(poly, Add):
149
+ if isinstance(poly, Add):
149
150
  ret = {}
150
151
  for a in poly.args:
151
152
  ret = add_perm_dict(ret, mult_poly(coeff_dict, a, var_x, var_y))
152
153
  return ret
153
- else:
154
- ret = {}
155
- for perm in coeff_dict:
156
- ret[perm] = poly * coeff_dict[perm]
157
- return ret
154
+ ret = {}
155
+ for perm in coeff_dict:
156
+ ret[perm] = poly * coeff_dict[perm]
157
+ return ret
158
158
 
159
159
 
160
160
  def mult_poly_down(coeff_dict, poly):
161
161
  if poly in _vars.var1:
162
162
  return single_variable_down(coeff_dict, _vars.var1.index(poly))
163
- elif isinstance(poly, Mul):
163
+ if isinstance(poly, Mul):
164
164
  ret = coeff_dict
165
165
  for a in poly.args:
166
166
  ret = mult_poly_down(ret, a)
167
167
  return ret
168
- elif isinstance(poly, Pow):
168
+ if isinstance(poly, Pow):
169
169
  base = poly.args[0]
170
170
  exponent = int(poly.args[1])
171
171
  ret = coeff_dict
172
172
  for i in range(int(exponent)):
173
173
  ret = mult_poly_down(ret, base)
174
174
  return ret
175
- elif isinstance(poly, Add):
175
+ if isinstance(poly, Add):
176
176
  ret = {}
177
177
  for a in poly.args:
178
178
  ret = add_perm_dict(ret, mult_poly_down(coeff_dict, a))
179
179
  return ret
180
- else:
181
- ret = {}
182
- for perm in coeff_dict:
183
- ret[perm] = poly * coeff_dict[perm]
184
- return ret
180
+ ret = {}
181
+ for perm in coeff_dict:
182
+ ret[perm] = poly * coeff_dict[perm]
183
+ return ret
185
184
 
186
185
 
187
186
  def nilhecke_mult(coeff_dict1, coeff_dict2):
@@ -268,19 +267,18 @@ def dualpieri(mu, v, w):
268
267
  continue
269
268
  vl = pull_out_var(lm[i] + 1, vpl)
270
269
  for pw, vpl2 in vl:
271
- res2 += [[vlist + [pw], vpl2]]
270
+ res2 += [[[*vlist, pw], vpl2]]
272
271
  res = res2
273
272
  if len(lm) == len(cn1w):
274
273
  return res
275
- else:
276
- res2 = []
277
- for vlist, vplist in res:
278
- vp = vplist
279
- vpl = divdiffable(vp, c)
280
- if vpl == []:
281
- continue
282
- res2 += [[vlist, vpl]]
283
- return res2
274
+ res2 = []
275
+ for vlist, vplist in res:
276
+ vp = vplist
277
+ vpl = divdiffable(vp, c)
278
+ if vpl == []:
279
+ continue
280
+ res2 += [[vlist, vpl]]
281
+ return res2
284
282
 
285
283
 
286
284
  dimen = 0
@@ -315,13 +313,14 @@ def schubmult(perm_dict, v, var2=None, var3=None):
315
313
  mx_th = 0
316
314
  for vp in vpathdicts[index]:
317
315
  for v2, vdiff, s in vpathdicts[index][vp]:
318
- if th[index] - vdiff > mx_th:
319
- mx_th = th[index] - vdiff
316
+ mx_th = max(mx_th, th[index] - vdiff)
320
317
  newpathsums = {}
321
318
  for up in vpathsums:
322
319
  inv_up = inv(up)
323
320
  newperms = elem_sym_perms(
324
- up, min(mx_th, (inv_mu - (inv_up - inv_u)) - inv_vmu), th[index]
321
+ up,
322
+ min(mx_th, (inv_mu - (inv_up - inv_u)) - inv_vmu),
323
+ th[index],
325
324
  )
326
325
  for up2, udiff in newperms:
327
326
  if up2 not in newpathsums:
@@ -332,7 +331,8 @@ def schubmult(perm_dict, v, var2=None, var3=None):
332
331
  continue
333
332
  for v2, vdiff, s in vpathdicts[index][v]:
334
333
  newpathsums[up2][v2] = newpathsums[up2].get(
335
- v2, zero
334
+ v2,
335
+ zero,
336
336
  ) + s * sumval * elem_sym_func(
337
337
  th[index],
338
338
  index + 1,
@@ -370,8 +370,7 @@ def schubmult_down(perm_dict, v, var2=None, var3=None):
370
370
  mx_th = 0
371
371
  for vp in vpathdicts[index]:
372
372
  for v2, vdiff, s in vpathdicts[index][vp]:
373
- if th[index] - vdiff > mx_th:
374
- mx_th = th[index] - vdiff
373
+ mx_th = max(mx_th, th[index] - vdiff)
375
374
  newpathsums = {}
376
375
  for up in vpathsums:
377
376
  newperms = elem_sym_perms_op(up, mx_th, th[index])
@@ -384,7 +383,8 @@ def schubmult_down(perm_dict, v, var2=None, var3=None):
384
383
  continue
385
384
  for v2, vdiff, s in vpathdicts[index][v]:
386
385
  newpathsums[up2][v2] = newpathsums[up2].get(
387
- v2, zero
386
+ v2,
387
+ zero,
388
388
  ) + s * sumval * elem_sym_func(
389
389
  th[index],
390
390
  index + 1,
@@ -404,7 +404,6 @@ def schubmult_down(perm_dict, v, var2=None, var3=None):
404
404
 
405
405
 
406
406
  def poly_to_vec(poly, vec0=None, var3=_vars.var3):
407
- global dimen, monom_to_vec, base_vec
408
407
  poly = expand(poly.xreplace({var3[1]: 0}))
409
408
 
410
409
  dc = poly.as_coefficients_dict()
@@ -428,18 +427,18 @@ def poly_to_vec(poly, vec0=None, var3=_vars.var3):
428
427
  return vec
429
428
 
430
429
 
431
- def shiftsub(pol, var2=_vars.var2, var3=_vars.var3):
432
- subs_dict = dict([(var2[i], var2[i + 1]) for i in range(99)])
430
+ def shiftsub(pol, var2=_vars.var2):
431
+ subs_dict = {var2[i]: var2[i + 1] for i in range(99)}
433
432
  return sympify(pol).subs(subs_dict)
434
433
 
435
434
 
436
- def shiftsubz(pol, var2=_vars.var2, var3=_vars.var3):
437
- subs_dict = dict([(var3[i], var3[i + 1]) for i in range(99)])
435
+ def shiftsubz(pol, var3=_vars.var3):
436
+ subs_dict = {var3[i]: var3[i + 1] for i in range(99)}
438
437
  return sympify(pol).subs(subs_dict)
439
438
 
440
439
 
441
440
  def init_basevec(dc):
442
- global dimen, monom_to_vec, base_vec
441
+ global dimen, monom_to_vec, base_vec # noqa: PLW0603
443
442
  monom_to_vec = {}
444
443
  index = 0
445
444
  for mn in dc:
@@ -462,12 +461,11 @@ def split_flat_term(arg):
462
461
  ys += [arg2.args[1]]
463
462
  else:
464
463
  ys += [arg2]
464
+ elif isinstance(arg2, Mul):
465
+ for i in range(abs(int(arg2.args[0]))):
466
+ zs += [-arg2.args[1]]
465
467
  else:
466
- if isinstance(arg2, Mul):
467
- for i in range(abs(int(arg2.args[0]))):
468
- zs += [-arg2.args[1]]
469
- else:
470
- zs += [arg2]
468
+ zs += [arg2]
471
469
  return ys, zs
472
470
 
473
471
 
@@ -481,11 +479,11 @@ def is_flat_term(term):
481
479
  return True
482
480
 
483
481
 
484
- def flatten_factors(term, var2=_vars.var2, var3=_vars.var3):
482
+ def flatten_factors(term):
485
483
  found_one = False
486
484
  if is_flat_term(term):
487
485
  return term, False
488
- elif isinstance(term, Pow):
486
+ if isinstance(term, Pow):
489
487
  if is_flat_term(term.args[0]) and len(term.args[0].args) > 2:
490
488
  ys, zs = split_flat_term(term.args[0])
491
489
  terms = [1]
@@ -496,11 +494,10 @@ def flatten_factors(term, var2=_vars.var2, var3=_vars.var3):
496
494
  terms2 += [t * (ys[i] + zs[i])]
497
495
  terms = terms2
498
496
  return Add(*terms)
499
- elif is_flat_term(term.args[0]):
497
+ if is_flat_term(term.args[0]):
500
498
  return term, False
501
- else:
502
- return flatten_factors(term.args[0]) ** term.args[1], True
503
- elif isinstance(term, Mul):
499
+ return flatten_factors(term.args[0]) ** term.args[1], True
500
+ if isinstance(term, Mul):
504
501
  terms = [1]
505
502
  for arg in term.args:
506
503
  terms2 = []
@@ -528,7 +525,7 @@ def flatten_factors(term, var2=_vars.var2, var3=_vars.var3):
528
525
  else:
529
526
  term = Add(*terms)
530
527
  return term, found_one
531
- elif isinstance(term, Add):
528
+ if isinstance(term, Add):
532
529
  res = 0
533
530
  for arg in term.args:
534
531
  flat, found = flatten_factors(arg)
@@ -536,11 +533,13 @@ def flatten_factors(term, var2=_vars.var2, var3=_vars.var3):
536
533
  found_one = True
537
534
  res += flat
538
535
  return res, found_one
536
+ return None
539
537
 
540
538
 
541
539
  def fres(v):
542
540
  for s in v.free_symbols:
543
541
  return s
542
+ return None
544
543
 
545
544
 
546
545
  def split_mul(arg0, var2=None, var3=None):
@@ -614,7 +613,7 @@ def is_negative(term):
614
613
  sign = 1
615
614
  if isinstance(term, Integer) or isinstance(term, int):
616
615
  return term < 0
617
- elif isinstance(term, Mul):
616
+ if isinstance(term, Mul):
618
617
  for arg in term.args:
619
618
  if isinstance(arg, Integer):
620
619
  sign *= arg
@@ -634,11 +633,11 @@ def is_negative(term):
634
633
  return sign < 0
635
634
 
636
635
 
637
- def find_base_vectors(monom_list, monom_list_neg, var2, var3, depth):
636
+ def find_base_vectors(monom_list, var2, var3, depth):
638
637
  size = 0
639
638
  mn_fullcount = {}
640
639
  # pairs_checked = set()
641
- monom_list = set([tuple(mn) for mn in monom_list])
640
+ monom_list = {tuple(mn) for mn in monom_list}
642
641
  ct = 0
643
642
  while ct < depth and size != len(monom_list):
644
643
  size = len(monom_list)
@@ -798,9 +797,9 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
798
797
  depth = 1
799
798
 
800
799
  mons = split_monoms(pos_part, varsimp2, varsimp3)
801
- mons = set([tuple(mn) for mn in mons])
800
+ mons = {tuple(mn) for mn in mons}
802
801
  mons2 = split_monoms(neg_part, varsimp2, varsimp3)
803
- mons2 = set([tuple(mn2) for mn2 in mons2])
802
+ mons2 = {tuple(mn2) for mn2 in mons2}
804
803
 
805
804
  # mons2 = split_monoms(neg_part)
806
805
  # for mn in mons2:
@@ -827,12 +826,9 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
827
826
  for j in range(len(bad_vectors) - 1, -1, -1):
828
827
  base_monoms.pop(bad_vectors[j])
829
828
 
830
- vrs = [
831
- pu.LpVariable(name=f"a{i}", lowBound=0, cat="Integer")
832
- for i in range(len(base_vectors))
833
- ]
829
+ vrs = [pu.LpVariable(name=f"a{i}", lowBound=0, cat="Integer") for i in range(len(base_vectors))]
834
830
  lp_prob = pu.LpProblem("Problem", pu.LpMinimize)
835
- lp_prob += int(0)
831
+ lp_prob += 0
836
832
  eqs = [*base_vec]
837
833
  for j in range(len(base_vectors)):
838
834
  for i in base_vectors[j]:
@@ -874,7 +870,7 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
874
870
  lookup[key] = []
875
871
  mm0n1 = mm0[:n1]
876
872
  st = set(mm0n1)
877
- if len(st.intersection(set([0, 1]))) == len(st) and 1 in st:
873
+ if len(st.intersection({0, 1})) == len(st) and 1 in st:
878
874
  lookup[key] += [mm0]
879
875
  if mm0n1 == L1:
880
876
  mn1L += [mm0]
@@ -884,16 +880,12 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
884
880
  if mn1[i] != 0:
885
881
  arr = np.array(comblistmn1)
886
882
  comblistmn12 = []
887
- mn1_2 = tuple([*mn1[n1:i]] + [0] + [*mn1[i + 1 :]])
883
+ mn1_2 = (*mn1[n1:i], 0, *mn1[i + 1 :])
888
884
  for mm0 in lookup[mn1_2]:
889
885
  comblistmn12 += (
890
886
  arr
891
887
  * np.prod(
892
- [
893
- varsimp2[k] - varsimp3[i - n1]
894
- for k in range(n1)
895
- if mm0[k] == 1
896
- ]
888
+ [varsimp2[k] - varsimp3[i - n1] for k in range(n1) if mm0[k] == 1],
897
889
  )
898
890
  ).tolist()
899
891
  comblistmn1 = comblistmn12
@@ -903,12 +895,9 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
903
895
  if vec0 is not None:
904
896
  base_vectors += [vec0]
905
897
  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
- ]
898
+ vrs = [pu.LpVariable(name=f"a{i}", lowBound=0, cat="Integer") for i in range(len(base_vectors))]
910
899
  lp_prob = pu.LpProblem("Problem", pu.LpMinimize)
911
- lp_prob += int(0)
900
+ lp_prob += 0
912
901
  eqs = [*base_vec]
913
902
  for j in range(len(base_vectors)):
914
903
  for i in base_vectors[j]:
@@ -947,7 +936,7 @@ def compute_positive_rep(val, var2=None, var3=None, msg=False, do_pos_neg=True):
947
936
  return val2
948
937
 
949
938
 
950
- def is_split_two(u, v, w):
939
+ def is_split_two(u, v, w): # noqa: ARG001
951
940
  if inv(w) - inv(u) != 2:
952
941
  return False, []
953
942
  diff_perm = mulperm(inverse([*u]), [*w])
@@ -956,7 +945,7 @@ def is_split_two(u, v, w):
956
945
  for i in range(len(identity)):
957
946
  if diff_perm[i] != identity[i]:
958
947
  cycle0 = set()
959
- cycle = set([i + 1])
948
+ cycle = {i + 1}
960
949
  last = i
961
950
  while len(cycle0) != len(cycle):
962
951
  cycle0 = cycle
@@ -968,8 +957,7 @@ def is_split_two(u, v, w):
968
957
  break
969
958
  if len(cycles) == 2:
970
959
  return True, cycles
971
- else:
972
- return False, []
960
+ return False, []
973
961
 
974
962
 
975
963
  def is_coeff_irreducible(u, v, w):
@@ -1004,7 +992,7 @@ def is_hook(cd):
1004
992
 
1005
993
  def div_diff(i, poly, var2=_vars.var2):
1006
994
  return sympify(
1007
- sympy.div(sympy.sympify(poly - permy(poly, i)), sympy.sympify(var2[i] - var2[i + 1]))[0]
995
+ sympy.div(sympy.sympify(poly - permy(poly, i)), sympy.sympify(var2[i] - var2[i + 1]))[0],
1008
996
  )
1009
997
 
1010
998
 
@@ -1029,13 +1017,15 @@ def skew_div_diff(u, w, poly):
1029
1017
  u2 = [*u]
1030
1018
  u2[d], u2[d + 1] = u2[d + 1], u2[d]
1031
1019
  return skew_div_diff(u2, w2, permy(poly, d + 1))
1032
- else:
1033
- return skew_div_diff(u, w2, div_diff(d + 1, poly))
1020
+ return skew_div_diff(u, w2, div_diff(d + 1, poly))
1034
1021
 
1035
1022
 
1036
1023
  @cached(
1037
1024
  cache={},
1038
- key=lambda val,
1025
+ key=lambda val, u2, v2, w2, var2=None, var3=None, msg=False, do_pos_neg=True, sign_only=False: hashkey(u2, v2, w2, var2, var3, msg, do_pos_neg, sign_only),
1026
+ )
1027
+ def posify(
1028
+ val,
1039
1029
  u2,
1040
1030
  v2,
1041
1031
  w2,
@@ -1043,18 +1033,15 @@ def skew_div_diff(u, w, poly):
1043
1033
  var3=None,
1044
1034
  msg=False,
1045
1035
  do_pos_neg=True,
1046
- sign_only=False: hashkey(u2, v2, w2, var2, var3, msg, do_pos_neg, sign_only),
1047
- )
1048
- def posify(
1049
- val, u2, v2, w2, var2=None, var3=None, msg=False, do_pos_neg=True, sign_only=False, n=_vars.n
1036
+ sign_only=False,
1037
+ n=_vars.n,
1050
1038
  ):
1051
1039
  if inv(u2) + inv(v2) - inv(w2) == 0:
1052
1040
  return val
1053
1041
  cdv = code(v2)
1054
- if set(cdv) == set([0, 1]) and do_pos_neg:
1042
+ if set(cdv) == {0, 1} and do_pos_neg:
1055
1043
  return val
1056
- # if is_hook(cdv):
1057
- # print(f"Could've {cdv}")
1044
+
1058
1045
  if not sign_only and expand(val) == 0:
1059
1046
  return 0
1060
1047
 
@@ -1070,7 +1057,7 @@ def posify(
1070
1057
  u, v, w = reduce_coeff(u, v, w)
1071
1058
  if is_coeff_irreducible(u, v, w):
1072
1059
  while is_coeff_irreducible(u, v, w) and tuple(permtrim(w0)) != tuple(
1073
- permtrim([*w])
1060
+ permtrim([*w]),
1074
1061
  ):
1075
1062
  w0 = w
1076
1063
  u, v, w = reduce_descents(u, v, w)
@@ -1106,12 +1093,7 @@ def posify(
1106
1093
  r = inv(w) - inv_u
1107
1094
  val = 0
1108
1095
  w2 = w
1109
- hvarset = (
1110
- [w2[i] for i in range(min(len(w2), k))]
1111
- + [i + 1 for i in range(len(w2), k)]
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
- )
1096
+ 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))]
1115
1097
  val = elem_sym_poly(
1116
1098
  p - r,
1117
1099
  k + p - 1,
@@ -1129,9 +1111,7 @@ def posify(
1129
1111
  for i in range(len(w)):
1130
1112
  if a == -1 and u[i] != w[i]:
1131
1113
  a = i
1132
- elif i >= len(u) and w[i] != i + 1:
1133
- b = i
1134
- elif b == -1 and u[i] != w[i]:
1114
+ elif (i >= len(u) and w[i] != i + 1) or (b == -1 and u[i] != w[i]):
1135
1115
  b = i
1136
1116
  arr = [[[], v]]
1137
1117
  d = -1
@@ -1150,15 +1130,14 @@ def posify(
1150
1130
  for vr, v2 in arr:
1151
1131
  dpret = pull_out_var(i2, [*v2])
1152
1132
  for v3r, v3 in dpret:
1153
- arr2 += [[vr + [v3r], v3]]
1133
+ arr2 += [[[*vr, v3r], v3]]
1154
1134
  arr = arr2
1155
1135
  val = 0
1156
1136
  for L in arr:
1157
1137
  v3 = [*L[-1]]
1158
1138
  if v3[0] < v3[1]:
1159
1139
  continue
1160
- else:
1161
- v3[0], v3[1] = v3[1], v3[0]
1140
+ v3[0], v3[1] = v3[1], v3[0]
1162
1141
  toadd = 1
1163
1142
  for i in range(d):
1164
1143
  if i in [a, b]:
@@ -1219,7 +1198,7 @@ def posify(
1219
1198
  for vr, v2 in arr:
1220
1199
  dpret = pull_out_var(i2, [*v2])
1221
1200
  for v3r, v3 in dpret:
1222
- arr2 += [[vr + [(v3r, i + 1)], v3]]
1201
+ arr2 += [[[*vr, (v3r, i + 1)], v3]]
1223
1202
  arr = arr2
1224
1203
  val = 0
1225
1204
 
@@ -1229,8 +1208,7 @@ def posify(
1229
1208
  v3 = [*L[-1]]
1230
1209
  if v3[real_a1] < v3[real_b1]:
1231
1210
  continue
1232
- else:
1233
- v3[real_a1], v3[real_b1] = v3[real_b1], v3[real_a1]
1211
+ v3[real_a1], v3[real_b1] = v3[real_b1], v3[real_a1]
1234
1212
  arr2 += [[L[0], v3]]
1235
1213
  arr = arr2
1236
1214
  if not good2:
@@ -1248,7 +1226,7 @@ def posify(
1248
1226
  for vr, v2 in arr:
1249
1227
  dpret = pull_out_var(i2, [*v2])
1250
1228
  for v3r, v3 in dpret:
1251
- arr2 += [[vr + [(v3r, var_index)], v3]]
1229
+ arr2 += [[[*vr, (v3r, var_index)], v3]]
1252
1230
  arr = arr2
1253
1231
  if good2:
1254
1232
  arr2 = []
@@ -1257,8 +1235,7 @@ def posify(
1257
1235
  try:
1258
1236
  if v3[real_a2] < v3[real_b2]:
1259
1237
  continue
1260
- else:
1261
- v3[real_a2], v3[real_b2] = v3[real_b2], v3[real_a2]
1238
+ v3[real_a2], v3[real_b2] = v3[real_b2], v3[real_a2]
1262
1239
  except IndexError:
1263
1240
  continue
1264
1241
  arr2 += [[L[0], v3]]
@@ -1278,7 +1255,7 @@ def posify(
1278
1255
  for vr, v2 in arr:
1279
1256
  dpret = pull_out_var(i2, [*v2])
1280
1257
  for v3r, v3 in dpret:
1281
- arr2 += [[vr + [(v3r, var_index)], v3]]
1258
+ arr2 += [[[*vr, (v3r, var_index)], v3]]
1282
1259
  arr = arr2
1283
1260
 
1284
1261
  for L in arr:
@@ -1287,7 +1264,7 @@ def posify(
1287
1264
  doschubpoly = True
1288
1265
  if (not good1 or not good2) and v3[0] < v3[1] and (good1 or good2):
1289
1266
  continue
1290
- elif (good1 or good2) and (not good1 or not good2):
1267
+ if (good1 or good2) and (not good1 or not good2):
1291
1268
  v3[0], v3[1] = v3[1], v3[0]
1292
1269
  elif not good1 and not good2:
1293
1270
  doschubpoly = False
@@ -1300,10 +1277,9 @@ def posify(
1300
1277
  if len(v3) <= 3 or v3[2] < v3[3]:
1301
1278
  coeff = 0
1302
1279
  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)
1280
+ v3[0], v3[1] = v3[1], v3[0]
1281
+ v3[2], v3[3] = v3[3], v3[2]
1282
+ coeff = permy(schubpoly(v3, var2, var3), 2)
1307
1283
  elif len(v3) <= 3 or v3[2] < v3[3]:
1308
1284
  if len(v3) <= 3:
1309
1285
  v3 += [4]
@@ -1311,7 +1287,8 @@ def posify(
1311
1287
  coeff = permy(
1312
1288
  posify(
1313
1289
  schubmult_one((1, 3, 2), tuple(permtrim([*v3])), var2, var3).get(
1314
- (2, 4, 3, 1), 0
1290
+ (2, 4, 3, 1),
1291
+ 0,
1315
1292
  ),
1316
1293
  (1, 3, 2),
1317
1294
  tuple(permtrim([*v3])),
@@ -1326,7 +1303,8 @@ def posify(
1326
1303
  else:
1327
1304
  coeff = permy(
1328
1305
  schubmult_one((1, 3, 2), tuple(permtrim([*v3])), var2, var3).get(
1329
- (2, 4, 1, 3), 0
1306
+ (2, 4, 1, 3),
1307
+ 0,
1330
1308
  ),
1331
1309
  2,
1332
1310
  )
@@ -1355,50 +1333,6 @@ def posify(
1355
1333
  if sign_only:
1356
1334
  return 0
1357
1335
  val = forwardcoeff(u, v, w, var2, var3)
1358
- # elif inv(w) - inv(u) == 2:
1359
- # indices = []
1360
- # for i in range(len(w)):
1361
- # if i>=len(u) or u[i]!=w[i]:
1362
- # indices += [i+1]
1363
- # arr = [[[],v]]
1364
- # d = -1
1365
- # for i in range(len(v)-1):
1366
- # if v[i]>v[i+1]:
1367
- # d = i + 1
1368
- # for i in range(d):
1369
- # arr2 = []
1370
- #
1371
- # if i+1 in indices:
1372
- # continue
1373
- # i2 = 1
1374
- # i2 += len([aa for aa in indices if i+1>aa])
1375
- # for vr, v2 in arr:
1376
- # dpret = pull_out_var(i2,[*v2])
1377
- # for v3r, v3 in dpret:
1378
- # arr2 += [[vr + [(v3r,i+1)],v3]]
1379
- # arr = arr2
1380
- # val = 0
1381
- #
1382
- # for L in arr:
1383
- # v3 = [*L[-1]]
1384
- # tomul = 1
1385
- # pooly = skew_div_diff(u,w,schubpoly(v3,[0,*[var2[a] for a in indices]],var3))
1386
- # coeff = compute_positive_rep(pooly,var2,var3,msg,False)
1387
- # if coeff == -1:
1388
- # return -1
1389
- # tomul = sympify(coeff)
1390
- # toadd = 1
1391
- # for i in range(len(L[0])):
1392
- # var_index = L[0][i][1]
1393
- # oaf = L[0][i][0]
1394
- # if var_index-1>=len(w):
1395
- # yv = var_index
1396
- # else:
1397
- # yv = w[var_index-1]
1398
- # for j in range(len(oaf)):
1399
- # toadd*= var2[yv] - var3[oaf[j]]
1400
- # toadd*=tomul#.subs(subs_dict3)
1401
- # val += toadd
1402
1336
  else:
1403
1337
  c01 = code(u)
1404
1338
  c02 = code(w)
@@ -1435,13 +1369,17 @@ def posify(
1435
1369
  break
1436
1370
  v3 = uncode(newc)
1437
1371
  coeff_dict = schubmult_one(
1438
- tuple(permtrim([*u])), tuple(permtrim(uncode(elemc))), var2, var3
1372
+ tuple(permtrim([*u])),
1373
+ tuple(permtrim(uncode(elemc))),
1374
+ var2,
1375
+ var3,
1439
1376
  )
1440
1377
  val = 0
1441
1378
  for new_w in coeff_dict:
1442
1379
  tomul = coeff_dict[new_w]
1443
1380
  newval = schubmult_one(new_w, tuple(permtrim(uncode(newc))), var2, var3).get(
1444
- tuple(permtrim([*w])), 0
1381
+ tuple(permtrim([*w])),
1382
+ 0,
1445
1383
  )
1446
1384
  newval = posify(
1447
1385
  newval,
@@ -1462,7 +1400,8 @@ def posify(
1462
1400
  w3 = uncode([0] + c02[1:])
1463
1401
  val = 0
1464
1402
  val = schubmult_one(tuple(permtrim(u3)), tuple(permtrim([*v])), var2, var3).get(
1465
- tuple(permtrim(w3)), 0
1403
+ tuple(permtrim(w3)),
1404
+ 0,
1466
1405
  )
1467
1406
  val = posify(
1468
1407
  val,
@@ -1489,78 +1428,24 @@ def posify(
1489
1428
  tomul *= var2[1] - var3[arr[i]]
1490
1429
 
1491
1430
  val2 = schubmult_one(tuple(permtrim(u3)), tuple(permtrim(v3)), var2, var3).get(
1492
- tuple(permtrim(w3)), 0
1431
+ tuple(permtrim(w3)),
1432
+ 0,
1493
1433
  )
1494
1434
  val2 = posify(val2, u3, tuple(permtrim(v3)), w3, var2, var3, msg, do_pos_neg)
1495
1435
  val += tomul * shiftsub(val2)
1496
- # elif inv(w)-inv(u)==2 and len(trimcode(u)) == len(trimcode(w)):
1497
- # indices = []
1498
- # for i in range(len(w)):
1499
- # if i>=len(u) or u[i]!=w[i]:
1500
- # indices += [i+1]
1501
- # arr = [[[],v]]
1502
- # d = -1
1503
- # for i in range(len(v)-1):
1504
- # if v[i]>v[i+1]:
1505
- # d = i + 1
1506
- # for i in range(d):
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
1436
+ elif not sign_only:
1437
+ if inv(u) + inv(v) - inv(w) == 1:
1438
+ val2 = compute_positive_rep(val, var2, var3, msg, False)
1553
1439
  else:
1554
- # st = str(expand(val))
1555
- # if st.find("-")!=-1:
1556
- # return -1
1557
- # else:
1558
- # return val
1559
- d = expand(val).as_coefficients_dict()
1560
- for v in d.values():
1561
- if v < 0:
1562
- return -1
1563
- return 1
1440
+ val2 = compute_positive_rep(val, var2, var3, msg, do_pos_neg)
1441
+ if val2 is not None:
1442
+ val = val2
1443
+ else:
1444
+ d = expand(val).as_coefficients_dict()
1445
+ for v in d.values():
1446
+ if v < 0:
1447
+ return -1
1448
+ return 1
1564
1449
  return val
1565
1450
 
1566
1451
 
@@ -1585,8 +1470,7 @@ def split_perms(perms):
1585
1470
  for j in range(index, len(cd)):
1586
1471
  if cd[j] != 0:
1587
1472
  break
1588
- else:
1589
- num_zeros += 1
1473
+ num_zeros += 1
1590
1474
  if num_zeros >= num_zeros_to_miss:
1591
1475
  cd1 = cd[:index]
1592
1476
  cd2 = [0 for i in range(index)] + cd[index:]