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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. schubmult/__init__.py +94 -1
  2. schubmult/perm_lib.py +232 -819
  3. schubmult/poly_lib/__init__.py +31 -0
  4. schubmult/poly_lib/poly_lib.py +244 -0
  5. schubmult/poly_lib/schub_poly.py +148 -0
  6. schubmult/poly_lib/variables.py +204 -0
  7. schubmult/rings/__init__.py +17 -0
  8. schubmult/rings/_quantum_schubert_polynomial_ring.py +788 -0
  9. schubmult/rings/_schubert_polynomial_ring.py +1006 -0
  10. schubmult/rings/_tensor_schub_ring.py +128 -0
  11. schubmult/rings/_utils.py +55 -0
  12. schubmult/{sage_integration → sage}/__init__.py +4 -1
  13. schubmult/{sage_integration → sage}/_fast_double_schubert_polynomial_ring.py +67 -109
  14. schubmult/{sage_integration → sage}/_fast_schubert_polynomial_ring.py +33 -28
  15. schubmult/{sage_integration → sage}/_indexing.py +9 -5
  16. schubmult/schub_lib/__init__.py +51 -0
  17. schubmult/{schubmult_double/_funcs.py → schub_lib/double.py} +532 -596
  18. schubmult/{schubmult_q/_funcs.py → schub_lib/quantum.py} +54 -53
  19. schubmult/schub_lib/quantum_double.py +954 -0
  20. schubmult/schub_lib/schub_lib.py +659 -0
  21. schubmult/{schubmult_py/_funcs.py → schub_lib/single.py} +45 -35
  22. schubmult/schub_lib/tests/__init__.py +0 -0
  23. schubmult/schub_lib/tests/legacy_perm_lib.py +946 -0
  24. schubmult/schub_lib/tests/test_vs_old.py +109 -0
  25. schubmult/scripts/__init__.py +0 -0
  26. schubmult/scripts/schubmult_double.py +378 -0
  27. schubmult/scripts/schubmult_py.py +84 -0
  28. schubmult/scripts/schubmult_q.py +109 -0
  29. schubmult/scripts/schubmult_q_double.py +207 -0
  30. schubmult/utils/__init__.py +0 -0
  31. schubmult/{_base_argparse.py → utils/argparse.py} +29 -5
  32. schubmult/utils/logging.py +16 -0
  33. schubmult/utils/parsing.py +20 -0
  34. schubmult/utils/perm_utils.py +135 -0
  35. schubmult/utils/test_utils.py +65 -0
  36. schubmult-3.0.0.dist-info/METADATA +1234 -0
  37. schubmult-3.0.0.dist-info/RECORD +41 -0
  38. {schubmult-2.0.4.dist-info → schubmult-3.0.0.dist-info}/WHEEL +1 -1
  39. schubmult-3.0.0.dist-info/entry_points.txt +5 -0
  40. schubmult/_tests.py +0 -24
  41. schubmult/schubmult_double/__init__.py +0 -12
  42. schubmult/schubmult_double/__main__.py +0 -6
  43. schubmult/schubmult_double/_script.py +0 -474
  44. schubmult/schubmult_py/__init__.py +0 -12
  45. schubmult/schubmult_py/__main__.py +0 -6
  46. schubmult/schubmult_py/_script.py +0 -97
  47. schubmult/schubmult_q/__init__.py +0 -8
  48. schubmult/schubmult_q/__main__.py +0 -6
  49. schubmult/schubmult_q/_script.py +0 -166
  50. schubmult/schubmult_q_double/__init__.py +0 -10
  51. schubmult/schubmult_q_double/__main__.py +0 -6
  52. schubmult/schubmult_q_double/_funcs.py +0 -540
  53. schubmult/schubmult_q_double/_script.py +0 -396
  54. schubmult-2.0.4.dist-info/METADATA +0 -542
  55. schubmult-2.0.4.dist-info/RECORD +0 -30
  56. schubmult-2.0.4.dist-info/entry_points.txt +0 -5
  57. {schubmult-2.0.4.dist-info → schubmult-3.0.0.dist-info}/licenses/LICENSE +0 -0
  58. {schubmult-2.0.4.dist-info → schubmult-3.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,128 @@
1
+ from functools import cache
2
+
3
+ import symengine
4
+ from symengine import expand
5
+ from sympy import Add, Basic, Dict, Expr, Mul, sympify
6
+
7
+ import schubmult.perm_lib as pl
8
+
9
+
10
+ def _tensor_product_of_dicts(d1, d2):
11
+ ret_dict = {}
12
+ for k1, v1 in d1.items():
13
+ this_dict = {}
14
+ for k2, v2 in d2.items():
15
+ this_dict[(k1, k2)] = v1 * v2
16
+ ret_dict = pl.add_perm_dict(ret_dict, this_dict)
17
+ return Dict(ret_dict)
18
+
19
+
20
+ class TensorBasisElement(Expr):
21
+ is_commutative = False
22
+
23
+ def __new__(cls, k1, k2, basis, tensor_symbol=" # "):
24
+ obj = Expr.__new__(cls, k1, k2, basis)
25
+ obj._elem1 = basis.basis1._from_dict({k1: 1})
26
+ obj._elem2 = basis.basis2._from_dict({k2: 1})
27
+ obj._tensor_symbol = tensor_symbol
28
+ return obj
29
+
30
+ def _sympystr(self, printer):
31
+ return f"{printer.doprint(self._elem1)}{self._tensor_symbol}{printer.doprint(self._elem2)}"
32
+
33
+
34
+ class TensorAlgebraElement(Expr):
35
+ # tensor ring
36
+ def __new__(cls, _dict, basis):
37
+ return TensorAlgebraElement.__xnew_cached__(cls, Dict(_dict), basis)
38
+
39
+ @staticmethod
40
+ def __xnew__(_class, _dict, basis):
41
+ _dict = Dict({k: v for k, v in _dict.items() if expand(v) != 0})
42
+ return Expr.__new__(_class, _dict, basis)
43
+
44
+ @property
45
+ def coeff_dict(self):
46
+ return self.args[0]
47
+
48
+ @staticmethod
49
+ @cache
50
+ def __xnew_cached__(_class, _dict, basis):
51
+ return TensorAlgebraElement.__xnew__(_class, _dict, basis)
52
+
53
+ @property
54
+ def basis(self):
55
+ return self.args[1]
56
+
57
+ def __mul__(self, other):
58
+ ret_dict = {}
59
+ for k1, v1 in self.coeff_dict.items():
60
+ for k2, v2 in other.coeff_dict.items():
61
+ dict1 = self.basis.basis1._from_dict({k1[0]: v1 * v2}) * self.basis.basis1._from_dict({k2[0]: 1})
62
+ dict2 = self.basis.basis2._from_dict({k1[1]: 1}) * self.basis.basis2._from_dict({k2[1]: 1})
63
+ ret_dict = pl.add_perm_dict(ret_dict, _tensor_product_of_dicts(dict1.coeff_dict, dict2.coeff_dict))
64
+ return self.basis._from_dict(ret_dict)
65
+
66
+ def __add__(self, other):
67
+ return self.basis._from_dict(pl.add_perm_dict(self.coeff_dict, other.coeff_dict))
68
+
69
+ def __sub__(self, other):
70
+ return self.basis._from_dict(pl.add_perm_dict(self.coeff_dict, {k: -v for k, v in other.coeff_dict.items()}))
71
+
72
+ @cache
73
+ def cached_sympystr(self, printer):
74
+ ret_list = [Mul(v, TensorBasisElement(k[0], k[1], self.basis)) for k, v in self.coeff_dict.items()]
75
+ return printer.doprint(Add(*ret_list))
76
+
77
+ def _sympystr(self, printer):
78
+ return self.cached_sympystr(printer)
79
+
80
+ def expand(self, **_):
81
+ return sympify(
82
+ symengine.Add(
83
+ *[v * symengine.sympify(self.basis.basis1._from_dict({k[0]: 1}).expand()) * symengine.sympify(self.basis.basis2._from_dict({k[1]: 1}).expand()) for k, v in self.coeff_dict.items()],
84
+ ),
85
+ )
86
+
87
+
88
+ class TensorAlgebraBasis(Basic):
89
+ # tensor ring
90
+ def __new__(cls, basis1, basis2):
91
+ return TensorAlgebraBasis.__xnew_cached__(cls, basis1, basis2)
92
+
93
+ @staticmethod
94
+ def __xnew__(_class, basis1, basis2):
95
+ return Basic.__new__(_class, basis1, basis2)
96
+
97
+ @property
98
+ def basis1(self):
99
+ return self.args[0]
100
+
101
+ @property
102
+ def basis2(self):
103
+ return self.args[1]
104
+
105
+ @property
106
+ def coeff_dict(self):
107
+ return self.args[0]
108
+
109
+ def _from_dict(self, _dict):
110
+ return TensorAlgebraElement(_dict, self)
111
+
112
+ @staticmethod
113
+ @cache
114
+ def __xnew_cached__(_class, basis1, basis2):
115
+ return TensorAlgebraBasis.__xnew__(_class, basis1, basis2)
116
+
117
+ def call2(self, *args):
118
+ def calla(*a):
119
+ return TensorAlgebraElement._from_dict(_tensor_product_of_dicts(self.basis1(*args).coeff_dict, self.basis2(*a).coeff_dict))
120
+
121
+ return calla
122
+
123
+ def __call__(self, *args):
124
+ return self.call2(args)
125
+
126
+
127
+ # def TensorAlgebra_basis(Basic):
128
+ # pass
@@ -0,0 +1,55 @@
1
+ from functools import cache
2
+
3
+ from symengine import sympify
4
+
5
+ from schubmult.poly_lib.variables import GeneratingSet
6
+
7
+ NoneVar = 1e10
8
+ ZeroVar = 0
9
+
10
+
11
+
12
+
13
+
14
+ @cache
15
+ def poly_ring(v: str):
16
+ if v == ZeroVar:
17
+ return tuple([sympify(0) for i in range(100)])
18
+ if v == NoneVar:
19
+ return tuple([sympify(0) for i in range(100)])
20
+ return GeneratingSet(str(v))
21
+
22
+ # def _schubifyit(func):
23
+ # @wraps(func)
24
+ # def wrapper(f, g):
25
+ # g = _sympify(g)
26
+ # if isinstance(g, Poly):
27
+ # return func(f, g)
28
+ # elif isinstance(g, Integer):
29
+ # g = f.from_expr(g, *f.gens, domain=f.domain)
30
+ # return func(f, g)
31
+ # elif isinstance(g, Expr):
32
+ # try:
33
+ # g = f.from_expr(g, *f.gens)
34
+ # except PolynomialError:
35
+ # if g.is_Matrix:
36
+ # return NotImplemented
37
+ # expr_method = getattr(f.as_expr(), func.__name__)
38
+ # result = expr_method(g)
39
+ # if result is not NotImplemented:
40
+ # sympy_deprecation_warning(
41
+ # """
42
+ # Mixing Poly with non-polynomial expressions in binary
43
+ # operations is deprecated. Either explicitly convert
44
+ # the non-Poly operand to a Poly with as_poly() or
45
+ # convert the Poly to an Expr with as_expr().
46
+ # """,
47
+ # deprecated_since_version="1.6",
48
+ # active_deprecations_target="deprecated-poly-nonpoly-binary-operations",
49
+ # )
50
+ # return result
51
+ # else:
52
+ # return func(f, g)
53
+ # else:
54
+ # return NotImplemented
55
+ # return wrapper
@@ -1,4 +1,7 @@
1
- from sage.all import * # noqa: F403
1
+ try:
2
+ import sage # noqa: F401
3
+ except ImportError:
4
+ raise ImportError("SageMath is not installed. Please install SageMath to use this module.")
2
5
 
3
6
  from ._fast_double_schubert_polynomial_ring import (
4
7
  FastDoubleSchubertPolynomial,
@@ -10,7 +10,7 @@ from sage.combinat.composition import (
10
10
  Compositions,
11
11
  )
12
12
  from sage.combinat.free_module import CombinatorialFreeModule
13
- from sage.combinat.permutation import Permutation, Permutations, from_lehmer_code
13
+ from sage.combinat.permutation import Permutation, Permutations
14
14
  from sage.misc.cachefunc import cached_method
15
15
  from sage.misc.parser import Parser
16
16
  from sage.rings.polynomial.flatten import FlatteningMorphism
@@ -19,14 +19,16 @@ from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
19
19
  from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
20
20
  from sympy import sympify
21
21
 
22
+ import schubmult.perm_lib as pl
23
+
22
24
  # from . import (
23
25
  # FastSchubertPolynomialRing_base,
24
26
  # FastSchubertPolynomialRing,
25
27
  # FastSchubertPolynomial,
26
- # )
27
- import schubmult.sage_integration._fast_schubert_polynomial_ring as bork
28
- import schubmult.schubmult_double as yz
29
- import schubmult.schubmult_q_double as qyz
28
+ # )as
29
+ import schubmult.sage._fast_schubert_polynomial_ring as bork
30
+ import schubmult.schub_lib.double as yz
31
+ import schubmult.schub_lib.quantum_double as qyz
30
32
  from schubmult.perm_lib import permtrim
31
33
 
32
34
  from ._indexing import _coerce_index
@@ -153,12 +155,13 @@ class FastDoubleSchubertPolynomial_class(CombinatorialFreeModule.Element):
153
155
  return None
154
156
  return self.parent()._q_ring
155
157
 
158
+ # can speed this up
156
159
  def expand(self):
157
160
  if self.parent()._quantum:
158
161
  return sum(
159
162
  [
160
163
  qyz.schubpoly_quantum(
161
- tuple(_coerce_index(k[0], self.parent()._ascode, False)),
164
+ pl.Permutation(_coerce_index(k[0], self.parent()._ascode, False)),
162
165
  self.parent()._base_polynomial_ring.gens(),
163
166
  self.parent()._coeff_polynomial_rings[k[1]].gens(),
164
167
  self.parent()._q_ring.gens(),
@@ -169,12 +172,12 @@ class FastDoubleSchubertPolynomial_class(CombinatorialFreeModule.Element):
169
172
  )
170
173
  return sum(
171
174
  [
172
- yz.schubmult(
173
- {(1, 2): v},
174
- tuple(_coerce_index(k[0], self.parent()._ascode, False)),
175
+ yz.schubmult_double(
176
+ {pl.Permutation([]): v},
177
+ pl.Permutation(_coerce_index(k[0], self.parent()._ascode, False)),
175
178
  self.parent()._base_polynomial_ring.gens(),
176
179
  self.parent()._coeff_polynomial_rings[k[1]].gens(),
177
- ).get((1, 2), 0)
180
+ ).get(pl.Permutation([]), 0)
178
181
  for k, v in self.monomial_coefficients().items()
179
182
  ],
180
183
  )
@@ -305,6 +308,16 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
305
308
 
306
309
  self._sc_rep = f"{'Q' if quantum else ''}DS{base_variable_name}"
307
310
 
311
+ # [('bracket', None),
312
+ # ('iterate_key', False),
313
+ # ('latex_bracket', False), ('latex_names', None),
314
+ # ('latex_prefix', None), ('latex_scalar_mult', None),
315
+ # ('names', None), ('prefix', 'x'),
316
+ # ('scalar_mult', '*'),
317
+ # ('sorting_key', <function ...<lambda> at ...>),
318
+ # ('sorting_reverse', False), ('string_quotes', True),
319
+ # ('tensor_symbol', None)]
320
+
308
321
  CombinatorialFreeModule.__init__(
309
322
  self,
310
323
  self._coeff_polynomial_ring,
@@ -312,6 +325,7 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
312
325
  category=cat,
313
326
  prefix=self._sc_rep,
314
327
  )
328
+ # print_options
315
329
  self._populate_coercion_lists_()
316
330
  self._parser = None
317
331
 
@@ -326,29 +340,22 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
326
340
  def set_coproduct_indices(self, indices):
327
341
  self._splitter = indices
328
342
 
329
- def _element_constructor_(self, *x):
330
- if len(x) == 1:
331
- x = x[0]
332
- elif len(x) > 2:
333
- raise ValueError("Bad index for element")
334
-
343
+ def _element_constructor_(self, x, vname=None):
335
344
  if isinstance(x, str):
336
345
  return self.parser().parse(x)
337
- if isinstance(x, list) or isinstance(x, tuple) or isinstance(x, Permutation) or isinstance(x, Composition):
338
- # checking the input to avoid symmetrica crashing Sage, see trac 12924
339
- if x in self._index_wrapper:
340
- elem = self._from_dict({self._index_wrapper((x[0], x[1])): self.base_ring().one()})
341
- else:
342
- elem = self._from_dict(
343
- {
344
- self._index_wrapper(
345
- (
346
- _coerce_index(x, self._ascode, self._ascode),
347
- self._varlist[0],
348
- ),
349
- ): self.base_ring().one(),
350
- },
351
- )
346
+ if (x, vname) in self._index_wrapper:
347
+ elem = self._from_dict({self._index_wrapper((x, vname)): self.base_ring().one()})
348
+ elif isinstance(x, list) or isinstance(x, tuple) or isinstance(x, Permutation) or isinstance(x, Composition) or isinstance(x, pl.Permutation):
349
+ elem = self._from_dict(
350
+ {
351
+ self._index_wrapper(
352
+ (
353
+ _coerce_index(x, self._ascode, self._ascode),
354
+ self._varlist[0] if vname is None else vname,
355
+ ),
356
+ ): self.base_ring().one(),
357
+ },
358
+ )
352
359
  elif isinstance(x, FastDoubleSchubertPolynomial):
353
360
  if x.base_varname == self._base_varname and (self._quantum == x.parent()._quantum) and (not self._quantum or x.q_varname == self._q_varname):
354
361
  elem = self._from_dict(
@@ -362,9 +369,9 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
362
369
 
363
370
  for k, v in x.monomial_coefficients().items():
364
371
  if self._quantum:
365
- res = qyz.schubmult_db(
366
- {(1, 2): self._coeff_polynomial_ring(v)},
367
- tuple(_coerce_index(k, x.parent()._ascode, False)),
372
+ res = qyz.schubmult_q_double_fast(
373
+ {pl.Permutation([]): self._coeff_polynomial_ring(v)},
374
+ pl.Permutation(list(_coerce_index(k, x.parent()._ascode, False))),
368
375
  self._coeff_polynomial_rings[self._varlist[0]].gens(),
369
376
  [
370
377
  0
@@ -375,9 +382,9 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
375
382
  self._q_ring.gens(),
376
383
  )
377
384
  else:
378
- res = yz.schubmult(
379
- {(1, 2): self._coeff_polynomial_ring(v)},
380
- tuple(_coerce_index(k, x.parent()._ascode, False)),
385
+ res = yz.schubmult_double(
386
+ {pl.Permutation([]): self._coeff_polynomial_ring(v)},
387
+ pl.Permutation(list(_coerce_index(k, x.parent()._ascode, False))),
381
388
  self._coeff_polynomial_rings[self._varlist[0]].gens(),
382
389
  [
383
390
  0
@@ -401,16 +408,16 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
401
408
  sympy_floff = sympify(str(x))
402
409
  val = syme.sympify(sympy_floff)
403
410
  if self._quantum:
404
- result = qyz.mult_poly(
405
- {(1, 2): 1},
411
+ result = qyz.mult_poly_q_double(
412
+ {pl.Permutation([]): 1},
406
413
  val,
407
414
  [syme.Symbol(str(g)) for g in self._base_polynomial_ring.gens()],
408
415
  [syme.Symbol(str(g)) for g in self._coeff_polynomial_rings[self._varlist[0]].gens()],
409
416
  [syme.Symbol(str(g)) for g in self._q_ring.gens()],
410
417
  )
411
418
  else:
412
- result = yz.mult_poly(
413
- {(1, 2): 1},
419
+ result = yz.mult_poly_double(
420
+ {pl.Permutation([]): 1},
414
421
  val,
415
422
  [syme.Symbol(str(g)) for g in self._base_polynomial_ring.gens()],
416
423
  [syme.Symbol(str(g)) for g in self._coeff_polynomial_rings[self._varlist[0]].gens()],
@@ -437,28 +444,28 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
437
444
  ]
438
445
 
439
446
  def product_on_basis(self, left, right):
440
- le = tuple(left[0])
441
- ri = tuple(right[0])
442
- var_y = [self._coeff_polynomial_ring(g) for g in self._coeff_polynomial_rings[left[1]].gens()]
443
- var_z = [self._coeff_polynomial_ring(g) for g in self._coeff_polynomial_rings[right[1]].gens()]
447
+ le = _coerce_index(left[0], self._ascode, False)
448
+ ri = _coerce_index(right[0], self._ascode, False)
449
+ var_y = [syme.sympify(str(g)) for g in self._coeff_polynomial_rings[left[1]].gens()]
450
+ var_z = [syme.sympify(str(g)) for g in self._coeff_polynomial_rings[right[1]].gens()]
444
451
  if self._quantum:
445
- result = qyz.schubmult_db(
446
- {tuple(_coerce_index(le, self._ascode, False)): 1},
447
- tuple(_coerce_index(ri, self._ascode, False)),
452
+ result = qyz.schubmult_q_double_fast(
453
+ {pl.Permutation(le): 1},
454
+ pl.Permutation(ri),
448
455
  var_y,
449
456
  var_z,
450
- self._q_ring.gens(),
457
+ [syme.sympify(str(g)) for g in self._q_ring.gens()],
451
458
  )
452
459
  else:
453
- result = yz.schubmult(
454
- {tuple(_coerce_index(le, self._ascode, False)): 1},
455
- tuple(_coerce_index(ri, self._ascode, False)),
460
+ result = yz.schubmult_double(
461
+ {pl.Permutation(le): 1},
462
+ pl.Permutation(ri),
456
463
  var_y,
457
464
  var_z,
458
465
  )
459
466
  result = {k: v for k, v in result.items() if v != 0}
460
467
  return sum(
461
- [self._coeff_polynomial_ring(v) * self((_coerce_index(k, False, self._ascode), left[1])) for k, v in result.items()],
468
+ [self._coeff_polynomial_ring(str(v)) * self(_coerce_index(k, False, self._ascode), left[1]) for k, v in result.items()],
462
469
  )
463
470
 
464
471
  def _coerce_map_from_(self, S):
@@ -477,65 +484,16 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
477
484
  raise NotImplementedError("Quantum double Schubert polynomials have no coproduct")
478
485
  indices = self._splitter
479
486
  indices = sorted(indices)
480
- subs_dict_coprod = {}
481
- mperm = indm[0]
482
- mperm = _coerce_index(mperm, self._ascode, False)
483
487
  RR = self._coeff_polynomial_rings[indm[1]]
484
- RBase = self._coeff_polynomial_rings[self._varlist[0]]
485
- k = len(indices)
486
- n = len(mperm)
487
- kcd = [indices[i] - i - 1 for i in range(len(indices))] + [n + 1 - k for i in range(k, n)]
488
- max_required = max([kcd[i] + i for i in range(len(kcd))])
489
- kcd2 = kcd + [0 for i in range(len(kcd), max_required)] + [0]
490
- N = len(kcd)
491
- kperm = from_lehmer_code(kcd2).inverse()
492
- # r = [sum(self.base_ring()._first_ngens(j)) for j in range(100)]
493
- vn = [f"soible_{i}" for i in range(N * 2 + 1)]
494
- TR = PolynomialRing(self.base_ring(), N * 2 + 1, vn)
495
-
496
- for i in range(N * 2 + 1):
497
- if i <= N:
498
- subs_dict_coprod[TR.gens()[i]] = self._coeff_polynomial_ring(RR.gens()[i])
499
- else:
500
- subs_dict_coprod[TR.gens()[i]] = self._coeff_polynomial_ring(RBase.gens()[i - N])
501
-
502
- coeff_dict = {tuple(kperm): 1}
503
- coeff_dict = yz.schubmult(
504
- coeff_dict,
505
- tuple(mperm),
506
- list(TR.gens()),
507
- RR.gens(),
508
- )
488
+ TR = self._coeff_polynomial_rings[self._varlist[0]]
509
489
 
510
- inv_kperm = kperm.number_of_inversions()
511
- inverse_kperm = kperm.inverse()
490
+ coeff_dict = yz.schub_coprod_double(permtrim(indm[0]), indices, [syme.sympify(str(g)) for g in TR.gens()], [syme.sympify(str(g)) for g in RR.gens()])
512
491
  total_sum = 0
513
- for perm, val in coeff_dict.items():
514
- pperm = Permutation(list(perm))
515
- downperm = pperm.left_action_product(inverse_kperm)
516
- if downperm.number_of_inversions() == pperm.number_of_inversions() - inv_kperm:
517
- flag = True
518
- for i in range(N):
519
- if downperm[i] > N:
520
- flag = False
521
- break
522
- if not flag:
523
- continue
524
- firstperm = Permutation(permtrim(list(downperm[0:N])))
525
- secondperm = Permutation(
526
- permtrim([downperm[i] - N for i in range(N, len(downperm))]),
527
- )
528
- val = TR(val).subs(subs_dict_coprod)
529
- total_sum += self._coeff_polynomial_ring(val) * self(
530
- (_coerce_index(firstperm, False, self._ascode), indm[1]),
531
- ).tensor(
532
- self(
533
- (
534
- _coerce_index(secondperm, False, self._ascode),
535
- self._varlist[0],
536
- ),
537
- ),
538
- )
492
+ for (fp, sp), val in coeff_dict.items():
493
+ firstperm = Permutation(list(fp))
494
+ secondperm = Permutation(list(sp))
495
+ # val = syme.sympify(val).subs(subs_dict_coprod)
496
+ total_sum += self._coeff_polynomial_ring(val) * self(_coerce_index(firstperm, False, self._ascode), indm[1]).tensor(self(_coerce_index(secondperm, False, self._ascode), self._varlist[0]))
539
497
  return total_sum
540
498
 
541
499
  def _repr_(self):
@@ -17,11 +17,12 @@ from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
17
17
  from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
18
18
  from sympy import sympify
19
19
 
20
- import schubmult.sage_integration._fast_double_schubert_polynomial_ring as bork
21
- import schubmult.schubmult_double as yz
22
- import schubmult.schubmult_py as py
23
- import schubmult.schubmult_q as sq
24
- import schubmult.schubmult_q_double as qyz
20
+ import schubmult.perm_lib as pl
21
+ import schubmult.sage._fast_double_schubert_polynomial_ring as bork
22
+ import schubmult.schub_lib.double as yz
23
+ import schubmult.schub_lib.quantum as sq
24
+ import schubmult.schub_lib.quantum_double as qyz
25
+ import schubmult.schub_lib.single as py
25
26
  from schubmult.perm_lib import permtrim
26
27
 
27
28
  from ._indexing import _coerce_index
@@ -143,7 +144,7 @@ class FastSchubertPolynomial_class(CombinatorialFreeModule.Element):
143
144
  [
144
145
  self.parent()._polynomial_ring(
145
146
  qyz.schubpoly_quantum(
146
- tuple(_coerce_index(k, self.parent()._ascode, False)),
147
+ pl.Permutation(_coerce_index(k, self.parent()._ascode, False)),
147
148
  self.parent()._polynomial_ring.gens(),
148
149
  [0 for i in range(100)],
149
150
  self.parent()._q_ring.gens(),
@@ -156,17 +157,24 @@ class FastSchubertPolynomial_class(CombinatorialFreeModule.Element):
156
157
  return sum(
157
158
  [
158
159
  self.parent()._polynomial_ring(
159
- yz.schubmult(
160
- {(1, 2): v},
161
- tuple(_coerce_index(k, self.parent()._ascode, False)),
160
+ yz.schubmult_double(
161
+ {pl.Permutation([]): v},
162
+ pl.Permutation(_coerce_index(k, self.parent()._ascode, False)),
162
163
  self.parent()._polynomial_ring.gens(),
163
164
  [0 for i in range(100)],
164
- ).get((1, 2), 0),
165
+ ).get(pl.Permutation([]), 0),
165
166
  )
166
167
  for k, v in self.monomial_coefficients().items()
167
168
  ],
168
169
  )
169
170
 
171
+ # PDB STEP WHEN LATEX CALLED
172
+ # def _latex_(self):
173
+ # rep = "\\mathfrak{S}"
174
+ # if self.is_quantum:
175
+ # rep+=f"^{'{'}{self.q_varname}{'}'}"
176
+ # rep+="_{"+str(()"
177
+
170
178
 
171
179
  @cache
172
180
  def _single_schub_parser(passed):
@@ -265,12 +273,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
265
273
  def _element_constructor_(self, x):
266
274
  if isinstance(x, str):
267
275
  return self.parser().parse(x)
268
- if (
269
- isinstance(x, list)
270
- or isinstance(x, tuple)
271
- or isinstance(x, Composition)
272
- or isinstance(x, Permutation)
273
- ):
276
+ if isinstance(x, (list, tuple, Composition, Permutation, pl.Permutation)):
274
277
  # checking the input to avoid symmetrica crashing Sage, see trac 12924
275
278
  elem = self._from_dict(
276
279
  {_coerce_index(x, self._ascode, self._ascode): self.base_ring().one()},
@@ -296,15 +299,15 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
296
299
  sympy_floff = sympify(str(x))
297
300
  val = syme.sympify(sympy_floff)
298
301
  if self._quantum:
299
- result = sq.mult_poly(
300
- {(1, 2): 1},
302
+ result = sq.mult_poly_q(
303
+ {pl.Permutation([]): 1},
301
304
  val,
302
305
  [syme.Symbol(str(g)) for g in self._polynomial_ring.gens()],
303
306
  [syme.Symbol(str(g)) for g in self._q_ring.gens()],
304
307
  )
305
308
  else:
306
- result = py.mult_poly(
307
- {(1, 2): 1},
309
+ result = py.mult_poly_py(
310
+ {pl.Permutation([]): 1},
308
311
  val,
309
312
  [syme.Symbol(str(g)) for g in self._polynomial_ring.gens()],
310
313
  )
@@ -334,17 +337,17 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
334
337
  return sum(
335
338
  [
336
339
  self.base_ring()(str(v)) * self(_coerce_index(k, False, self._ascode))
337
- for k, v in sq.schubmult_db(
338
- {tuple(_coerce_index(left, self._ascode, False)): self.base_ring()(1)},
339
- tuple(_coerce_index(right, self._ascode, False)),
340
- list(self._q_ring.gens()),
340
+ for k, v in sq.schubmult_q_fast(
341
+ {pl.Permutation(_coerce_index(left, self._ascode, False)): 1},
342
+ pl.Permutation(_coerce_index(right, self._ascode, False)),
343
+ [syme.sympify(str(g)) for g in self._q_ring.gens()],
341
344
  ).items()
342
345
  ],
343
346
  )
344
347
  return sum(
345
348
  [
346
349
  self.base_ring()(v) * self(_coerce_index(k, False, self._ascode))
347
- for k, v in py.schubmult(
350
+ for k, v in py.schubmult_py(
348
351
  {tuple(_coerce_index(left, self._ascode, False)): 1},
349
352
  tuple(_coerce_index(right, self._ascode, False)),
350
353
  ).items()
@@ -365,7 +368,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
365
368
  N = len(kcd)
366
369
  kperm = from_lehmer_code(kcd2).inverse()
367
370
  coeff_dict = {tuple(kperm): 1}
368
- coeff_dict = py.schubmult(coeff_dict, tuple(mperm))
371
+ coeff_dict = py.schubmult_py(coeff_dict, tuple(mperm))
369
372
 
370
373
  inv_kperm = kperm.number_of_inversions()
371
374
  inverse_kperm = kperm.inverse()
@@ -390,9 +393,11 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
390
393
  ).tensor(self(_coerce_index(secondperm, False, self._ascode)))
391
394
  return total_sum
392
395
 
396
+ def _latex_(self, S):
397
+ return f"Boobfucker {S}"
393
398
 
394
- def _repr_(self):
395
- return f"Ring of Schubert polynomials in {self._base_varname} with {len(self._polynomial_ring.gens())} variables over {self._q_ring.base_ring()}"
399
+ def _repr_(self):
400
+ return f"Ring of Schubert polynomials in {self._base_varname} with {len(self._polynomial_ring.gens())} variables over {self._q_ring.base_ring()}"
396
401
 
397
402
 
398
403
  FastSchubertPolynomial = FastSchubertPolynomial_class
@@ -1,21 +1,24 @@
1
1
  from sage.combinat.composition import Composition
2
2
  from sage.combinat.permutation import Permutation
3
3
 
4
+ import schubmult.perm_lib as pl
4
5
  from schubmult.perm_lib import permtrim, trimcode, uncode
5
6
 
6
7
 
7
8
  def _coerce_index(indexed_obj, is_comp, should_be_comp):
8
9
  if is_comp == should_be_comp:
9
- if isinstance(indexed_obj, list) or isinstance(indexed_obj, tuple):
10
+ if isinstance(indexed_obj, (list, tuple, pl.Permutation)):
10
11
  if is_comp:
11
12
  return Composition(trimcode(permtrim(uncode(list(indexed_obj)))))
12
- return Permutation(permtrim(list(indexed_obj))).remove_extra_fixed_points()
13
+ return Permutation(list(permtrim(list(indexed_obj))))
13
14
  if not is_comp:
14
15
  if isinstance(indexed_obj, Permutation):
15
16
  return indexed_obj.remove_extra_fixed_points()
17
+ if isinstance(indexed_obj, pl.Permutation):
18
+ return Permutation(list(indexed_obj))
16
19
  if isinstance(indexed_obj, dict):
17
20
  {
18
- Permutation(permtrim(list(k))).remove_extra_fixed_points(): v
21
+ Permutation(list(permtrim(list(k)))): v
19
22
  for k, v in indexed_obj.items()
20
23
  }
21
24
  elif is_comp:
@@ -24,11 +27,11 @@ def _coerce_index(indexed_obj, is_comp, should_be_comp):
24
27
  or isinstance(indexed_obj, tuple)
25
28
  or isinstance(indexed_obj, Composition)
26
29
  ):
27
- return Permutation(permtrim(uncode(list(indexed_obj)))).remove_extra_fixed_points()
30
+ return Permutation(list(permtrim(uncode(list(indexed_obj)))))
28
31
 
29
32
  if isinstance(indexed_obj, dict): # keys are comps
30
33
  return {
31
- Permutation(permtrim(uncode(list(k)))).remove_extra_fixed_points(): v
34
+ Permutation(list(permtrim(uncode(list(k))))): v
32
35
  for k, v in indexed_obj.items()
33
36
  }
34
37
  else:
@@ -36,6 +39,7 @@ def _coerce_index(indexed_obj, is_comp, should_be_comp):
36
39
  isinstance(indexed_obj, list)
37
40
  or isinstance(indexed_obj, tuple)
38
41
  or isinstance(indexed_obj, Permutation)
42
+ or isinstance(indexed_obj, pl.Permutation)
39
43
  ):
40
44
  return Composition(trimcode(list(indexed_obj)))
41
45