schubmult 2.0.2__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 (40) hide show
  1. schubmult/__init__.py +1 -1
  2. schubmult/_base_argparse.py +42 -8
  3. schubmult/_tests.py +24 -0
  4. schubmult/perm_lib.py +52 -112
  5. schubmult/sage_integration/__init__.py +13 -13
  6. schubmult/sage_integration/_fast_double_schubert_polynomial_ring.py +139 -118
  7. schubmult/sage_integration/_fast_schubert_polynomial_ring.py +88 -49
  8. schubmult/sage_integration/_indexing.py +35 -32
  9. schubmult/schubmult_double/__init__.py +6 -12
  10. schubmult/schubmult_double/__main__.py +2 -1
  11. schubmult/schubmult_double/_funcs.py +245 -281
  12. schubmult/schubmult_double/_script.py +128 -70
  13. schubmult/schubmult_py/__init__.py +5 -3
  14. schubmult/schubmult_py/__main__.py +2 -1
  15. schubmult/schubmult_py/_funcs.py +68 -23
  16. schubmult/schubmult_py/_script.py +40 -58
  17. schubmult/schubmult_q/__init__.py +3 -7
  18. schubmult/schubmult_q/__main__.py +2 -1
  19. schubmult/schubmult_q/_funcs.py +41 -60
  20. schubmult/schubmult_q/_script.py +39 -30
  21. schubmult/schubmult_q_double/__init__.py +5 -11
  22. schubmult/schubmult_q_double/__main__.py +2 -1
  23. schubmult/schubmult_q_double/_funcs.py +99 -66
  24. schubmult/schubmult_q_double/_script.py +209 -150
  25. schubmult-2.0.4.dist-info/METADATA +542 -0
  26. schubmult-2.0.4.dist-info/RECORD +30 -0
  27. {schubmult-2.0.2.dist-info → schubmult-2.0.4.dist-info}/WHEEL +1 -1
  28. schubmult-2.0.4.dist-info/entry_points.txt +5 -0
  29. {schubmult-2.0.2.dist-info → schubmult-2.0.4.dist-info}/top_level.txt +0 -1
  30. schubmult/schubmult_double/_vars.py +0 -18
  31. schubmult/schubmult_py/_vars.py +0 -3
  32. schubmult/schubmult_q/_vars.py +0 -18
  33. schubmult/schubmult_q_double/_vars.py +0 -21
  34. schubmult-2.0.2.dist-info/METADATA +0 -455
  35. schubmult-2.0.2.dist-info/RECORD +0 -36
  36. schubmult-2.0.2.dist-info/entry_points.txt +0 -5
  37. tests/__init__.py +0 -0
  38. tests/test_fast_double_schubert.py +0 -145
  39. tests/test_fast_schubert.py +0 -38
  40. {schubmult-2.0.2.dist-info → schubmult-2.0.4.dist-info}/licenses/LICENSE +0 -0
@@ -1,28 +1,32 @@
1
+ from functools import cache
2
+
3
+ # from sage.misc.parser import Parser
4
+ import symengine as syme
1
5
  from sage.all import * # noqa: F403
2
- from sage.categories.graded_bialgebras_with_basis import GradedBialgebrasWithBasis
3
6
  from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis
4
- from sage.combinat.free_module import CombinatorialFreeModule
5
-
6
- from sage.combinat.permutation import Permutations, Permutation, from_lehmer_code
7
+ from sage.categories.graded_bialgebras_with_basis import GradedBialgebrasWithBasis
7
8
  from sage.combinat.composition import (
8
- Compositions,
9
9
  Composition,
10
+ Compositions,
10
11
  )
12
+ from sage.combinat.free_module import CombinatorialFreeModule
13
+ from sage.combinat.permutation import Permutation, Permutations, from_lehmer_code
11
14
  from sage.misc.cachefunc import cached_method
12
- from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
13
15
  from sage.rings.polynomial.multi_polynomial import MPolynomial
16
+ from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
14
17
  from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
15
- from ._indexing import _coerce_index
16
-
18
+ from sympy import sympify
17
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
18
23
  import schubmult.schubmult_q as sq
19
24
  import schubmult.schubmult_q_double as qyz
20
- import schubmult.schubmult_py as py
21
- import schubmult.schubmult_double as yz
25
+ from schubmult.perm_lib import permtrim
22
26
 
27
+ from ._indexing import _coerce_index
23
28
 
24
- from sympy import sympify
25
- import symengine as syme
29
+ # FastQuantumDoubleSchubertPolynomialRing = bork.FastQuantumDoubleSchubertPolynomialRing
26
30
 
27
31
 
28
32
  def FastSchubertPolynomialRing(
@@ -33,9 +37,10 @@ def FastSchubertPolynomialRing(
33
37
  code_display: bool = False,
34
38
  q_varname: str = "q",
35
39
  is_quantum: bool = False,
36
- indices: tuple[int] = tuple([1]),
40
+ indices: tuple[int] = (1,),
37
41
  ):
38
- """Wrapper function to return a double Schubert polynomial Ring
42
+ """
43
+ Wrapper function to return a double Schubert polynomial Ring
39
44
 
40
45
  Calls the _xbasis class to return a (quantum) Schubert
41
46
  polynomial ring with the indicated base ring, number of variables,
@@ -62,6 +67,7 @@ def FastSchubertPolynomialRing(
62
67
 
63
68
  Returns:
64
69
  FastSchubertPolynomialRing_xbasis: Element constructor of the ring
70
+
65
71
  """
66
72
  if is_quantum:
67
73
  QR = PolynomialRing(R, num_vars, q_varname)
@@ -86,7 +92,8 @@ def FastQuantumSchubertPolynomialRing(
86
92
  q_varname: str = "q",
87
93
  code_display: bool = False,
88
94
  ):
89
- """Quantum Schubert ring generator
95
+ """
96
+ Quantum Schubert ring generator
90
97
 
91
98
  Wraps FastSchubertPolynomialRing(), omitting indices and setting
92
99
  is_quantum to True.
@@ -101,6 +108,7 @@ def FastQuantumSchubertPolynomialRing(
101
108
 
102
109
  Returns:
103
110
  FastSchubertPolynomialRing_xbasis: Element constructor of the ring
111
+
104
112
  """
105
113
  return FastSchubertPolynomialRing(
106
114
  R,
@@ -140,30 +148,52 @@ class FastSchubertPolynomial_class(CombinatorialFreeModule.Element):
140
148
  [0 for i in range(100)],
141
149
  self.parent()._q_ring.gens(),
142
150
  v,
143
- )
144
- )
145
- for k, v in self.monomial_coefficients().items()
146
- ]
147
- )
148
- else:
149
- return sum(
150
- [
151
- self.parent()._polynomial_ring(
152
- yz.schubmult(
153
- {(1, 2): v},
154
- tuple(_coerce_index(k, self.parent()._ascode, False)),
155
- self.parent()._polynomial_ring.gens(),
156
- [0 for i in range(100)],
157
- ).get((1, 2), 0)
151
+ ),
158
152
  )
159
153
  for k, v in self.monomial_coefficients().items()
160
- ]
154
+ ],
161
155
  )
156
+ return sum(
157
+ [
158
+ self.parent()._polynomial_ring(
159
+ yz.schubmult(
160
+ {(1, 2): v},
161
+ tuple(_coerce_index(k, self.parent()._ascode, False)),
162
+ self.parent()._polynomial_ring.gens(),
163
+ [0 for i in range(100)],
164
+ ).get((1, 2), 0),
165
+ )
166
+ for k, v in self.monomial_coefficients().items()
167
+ ],
168
+ )
169
+
170
+
171
+ @cache
172
+ def _single_schub_parser(passed):
173
+ if passed._quantum:
174
+ q_varname = passed._q_varname
175
+ else:
176
+ q_varname = "q"
177
+ QDRing = bork.FastQuantumDoubleSchubertPolynomialRing(
178
+ passed.base_ring(),
179
+ len(passed._polynomial_ring.gens()),
180
+ passed._base_varname,
181
+ coeff_variable_names="y",
182
+ code_display=passed._ascode,
183
+ q_varname=q_varname,
184
+ )
185
+ return QDRing.parser()
162
186
 
163
187
 
164
188
  class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
165
189
  Element = FastSchubertPolynomial_class
166
190
 
191
+ def parser(self):
192
+ if self._parser is None:
193
+ self._parser = _single_schub_parser(self)
194
+ return self._parser
195
+
196
+
167
197
  def __init__(
168
198
  self,
169
199
  R,
@@ -193,12 +223,15 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
193
223
  index_set = Compositions()
194
224
  self._ascode = True
195
225
 
226
+ self._sc_rep = f"{'Q' if quantum else ''}S{base_variable_name}"
227
+
196
228
  CombinatorialFreeModule.__init__(
197
229
  self,
198
230
  R if not quantum else QR,
199
231
  index_set,
200
232
  category=cat,
201
- prefix=f"QS{base_variable_name}",
233
+ prefix=self._sc_rep,
234
+ bracket="(",
202
235
  )
203
236
  self._q_ring = QR
204
237
  self._base_varname = base_variable_name
@@ -209,6 +242,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
209
242
  else PolynomialRing(QR, num_vars, base_variable_name)
210
243
  )
211
244
  self._populate_coercion_lists_()
245
+ self._parser = None
212
246
 
213
247
  def _coerce_map_from_(self, S):
214
248
  if isinstance(S, MPolynomialRing_base):
@@ -217,6 +251,8 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
217
251
  return True
218
252
  if isinstance(S, FastSchubertPolynomialRing_base):
219
253
  return True
254
+ if isinstance(S, str):
255
+ return True
220
256
  return super()._coerce_map_from_(S)
221
257
 
222
258
  @cached_method
@@ -227,6 +263,8 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
227
263
  self._splitter = indices
228
264
 
229
265
  def _element_constructor_(self, x):
266
+ if isinstance(x, str):
267
+ return self.parser().parse(x)
230
268
  if (
231
269
  isinstance(x, list)
232
270
  or isinstance(x, tuple)
@@ -235,7 +273,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
235
273
  ):
236
274
  # checking the input to avoid symmetrica crashing Sage, see trac 12924
237
275
  elem = self._from_dict(
238
- {_coerce_index(x, self._ascode, self._ascode): self.base_ring().one()}
276
+ {_coerce_index(x, self._ascode, self._ascode): self.base_ring().one()},
239
277
  )
240
278
  elif isinstance(x, FastSchubertPolynomial):
241
279
  if (
@@ -247,7 +285,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
247
285
  {
248
286
  _coerce_index(k, x.parent()._ascode, self._ascode): v
249
287
  for k, v in x.monomial_coefficients().items()
250
- }
288
+ },
251
289
  )
252
290
  else:
253
291
  return self(x.expand())
@@ -276,7 +314,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
276
314
  if self._quantum
277
315
  else self.base_ring()(str(v))
278
316
  for k, v in result.items()
279
- }
317
+ },
280
318
  )
281
319
  else:
282
320
  raise TypeError(f"Could not convert {x=} to {self}")
@@ -301,18 +339,17 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
301
339
  tuple(_coerce_index(right, self._ascode, False)),
302
340
  list(self._q_ring.gens()),
303
341
  ).items()
304
- ]
305
- )
306
- else:
307
- return sum(
308
- [
309
- self.base_ring()(v) * self(_coerce_index(k, False, self._ascode))
310
- for k, v in py.schubmult(
311
- {tuple(_coerce_index(left, self._ascode, False)): 1},
312
- tuple(_coerce_index(right, self._ascode, False)),
313
- ).items()
314
- ]
342
+ ],
315
343
  )
344
+ return sum(
345
+ [
346
+ self.base_ring()(v) * self(_coerce_index(k, False, self._ascode))
347
+ for k, v in py.schubmult(
348
+ {tuple(_coerce_index(left, self._ascode, False)): 1},
349
+ tuple(_coerce_index(right, self._ascode, False)),
350
+ ).items()
351
+ ],
352
+ )
316
353
 
317
354
  def coproduct_on_basis(self, mperm):
318
355
  if self._quantum:
@@ -344,10 +381,12 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
344
381
  break
345
382
  if not flag:
346
383
  continue
347
- firstperm = Permutation(list(downperm[0:N]))
348
- secondperm = Permutation([downperm[i] - N for i in range(N, len(downperm))])
384
+ firstperm = Permutation(permtrim(list(downperm[0:N])))
385
+ secondperm = Permutation(
386
+ permtrim([downperm[i] - N for i in range(N, len(downperm))]),
387
+ )
349
388
  total_sum += self.base_ring()(val) * self(
350
- _coerce_index(firstperm, False, self._ascode)
389
+ _coerce_index(firstperm, False, self._ascode),
351
390
  ).tensor(self(_coerce_index(secondperm, False, self._ascode)))
352
391
  return total_sum
353
392
 
@@ -1,8 +1,7 @@
1
- from sage.combinat.permutation import Permutation
2
-
3
1
  from sage.combinat.composition import Composition
2
+ from sage.combinat.permutation import Permutation
4
3
 
5
- from schubmult.perm_lib import uncode, trimcode, permtrim
4
+ from schubmult.perm_lib import permtrim, trimcode, uncode
6
5
 
7
6
 
8
7
  def _coerce_index(indexed_obj, is_comp, should_be_comp):
@@ -10,35 +9,39 @@ def _coerce_index(indexed_obj, is_comp, should_be_comp):
10
9
  if isinstance(indexed_obj, list) or isinstance(indexed_obj, tuple):
11
10
  if is_comp:
12
11
  return Composition(trimcode(permtrim(uncode(list(indexed_obj)))))
13
- else:
14
- return Permutation(permtrim(list(indexed_obj)))
15
- else:
16
- return indexed_obj
17
- else:
18
- if is_comp:
19
- if (
20
- isinstance(indexed_obj, list)
21
- or isinstance(indexed_obj, tuple)
22
- or isinstance(indexed_obj, Composition)
23
- ):
24
- return Permutation(permtrim(uncode(list(indexed_obj))))
12
+ return Permutation(permtrim(list(indexed_obj))).remove_extra_fixed_points()
13
+ if not is_comp:
14
+ if isinstance(indexed_obj, Permutation):
15
+ return indexed_obj.remove_extra_fixed_points()
16
+ if isinstance(indexed_obj, dict):
17
+ {
18
+ Permutation(permtrim(list(k))).remove_extra_fixed_points(): v
19
+ for k, v in indexed_obj.items()
20
+ }
21
+ elif is_comp:
22
+ if (
23
+ isinstance(indexed_obj, list)
24
+ or isinstance(indexed_obj, tuple)
25
+ or isinstance(indexed_obj, Composition)
26
+ ):
27
+ return Permutation(permtrim(uncode(list(indexed_obj)))).remove_extra_fixed_points()
25
28
 
26
- if isinstance(indexed_obj, dict): # keys are comps
27
- return {
28
- Permutation(permtrim(uncode(list(k)))): v
29
- for k, v in indexed_obj.items()
30
- }
31
- else:
32
- if (
33
- isinstance(indexed_obj, list)
34
- or isinstance(indexed_obj, tuple)
35
- or isinstance(indexed_obj, Permutation)
36
- ):
37
- return Composition(trimcode(list(indexed_obj)))
29
+ if isinstance(indexed_obj, dict): # keys are comps
30
+ return {
31
+ Permutation(permtrim(uncode(list(k)))).remove_extra_fixed_points(): v
32
+ for k, v in indexed_obj.items()
33
+ }
34
+ else:
35
+ if (
36
+ isinstance(indexed_obj, list)
37
+ or isinstance(indexed_obj, tuple)
38
+ or isinstance(indexed_obj, Permutation)
39
+ ):
40
+ return Composition(trimcode(list(indexed_obj)))
38
41
 
39
- if isinstance(indexed_obj, dict): # keys are comps
40
- return {
41
- Composition(trimcode(permtrim(list(k)))): v
42
- for k, v in indexed_obj.items()
43
- }
42
+ if isinstance(indexed_obj, dict): # keys are comps
43
+ return {
44
+ Composition(trimcode(permtrim(list(k)))): v
45
+ for k, v in indexed_obj.items()
46
+ }
44
47
  raise TypeError
@@ -1,18 +1,12 @@
1
- from ._funcs import (
2
- compute_positive_rep,
3
- schubmult,
4
- single_variable,
5
- mult_poly,
6
- posify,
7
- div_diff
8
- )
9
-
1
+ from ._funcs import compute_positive_rep, div_diff, mult_poly, posify, schub_coprod, schubmult, single_variable
10
2
 
11
3
  __all__ = [
12
4
  "compute_positive_rep",
13
- "schubmult",
14
- "single_variable",
5
+ "div_diff",
6
+ "main",
15
7
  "mult_poly",
16
8
  "posify",
17
- "div_diff"
9
+ "schub_coprod",
10
+ "schubmult",
11
+ "single_variable",
18
12
  ]
@@ -1,5 +1,6 @@
1
1
  import sys
2
+
2
3
  from ._script import main
3
4
 
4
5
  if __name__ == "__main__":
5
- sys.exit(main())
6
+ sys.exit(main(sys.argv))