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,18 +1,23 @@
1
+ from functools import cache
2
+
3
+ import symengine as syme
1
4
  from sage.all import * # noqa: F403
2
- from sage.categories.graded_bialgebras_with_basis import GradedBialgebrasWithBasis
5
+ from sage.categories.cartesian_product import cartesian_product
3
6
  from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis
7
+ from sage.categories.graded_bialgebras_with_basis import GradedBialgebrasWithBasis
8
+ from sage.combinat.composition import (
9
+ Composition,
10
+ Compositions,
11
+ )
4
12
  from sage.combinat.free_module import CombinatorialFreeModule
5
- from sage.categories.cartesian_product import cartesian_product
6
- from sage.combinat.permutation import Permutations, Permutation, from_lehmer_code
13
+ from sage.combinat.permutation import Permutation, Permutations, from_lehmer_code
7
14
  from sage.misc.cachefunc import cached_method
15
+ from sage.misc.parser import Parser
16
+ from sage.rings.polynomial.flatten import FlatteningMorphism
8
17
  from sage.rings.polynomial.multi_polynomial import MPolynomial
9
18
  from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
10
19
  from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
11
- from sage.rings.polynomial.flatten import FlatteningMorphism
12
- from sage.combinat.composition import (
13
- Compositions,
14
- Composition,
15
- )
20
+ from sympy import sympify
16
21
 
17
22
  # from . import (
18
23
  # FastSchubertPolynomialRing_base,
@@ -20,16 +25,11 @@ from sage.combinat.composition import (
20
25
  # FastSchubertPolynomial,
21
26
  # )
22
27
  import schubmult.sage_integration._fast_schubert_polynomial_ring as bork
23
- from ._indexing import _coerce_index
24
-
25
- from functools import cache
26
- import schubmult.schubmult_q_double as qyz
27
28
  import schubmult.schubmult_double as yz
28
- from sympy import sympify
29
- import symengine as syme
29
+ import schubmult.schubmult_q_double as qyz
30
30
  from schubmult.perm_lib import permtrim
31
31
 
32
- from sage.misc.parser import Parser
32
+ from ._indexing import _coerce_index
33
33
 
34
34
 
35
35
  def FastDoubleSchubertPolynomialRing(
@@ -38,12 +38,13 @@ def FastDoubleSchubertPolynomialRing(
38
38
  base_variable_name: str,
39
39
  coeff_variable_names: str | tuple[str],
40
40
  *,
41
- indices: tuple[int] = tuple([1]),
41
+ indices: tuple[int] = (1,),
42
42
  code_display: bool = False,
43
43
  q_varname: str = "q",
44
44
  is_quantum: bool = False,
45
45
  ):
46
- """Wrapper function to return a double Schubert polynomial Ring
46
+ """
47
+ Wrapper function to return a double Schubert polynomial Ring
47
48
 
48
49
  Calls the _xbasis class to return a double or quantum double Schubert
49
50
  polynomial ring with the indicated base ring, number of variables,
@@ -58,7 +59,7 @@ def FastDoubleSchubertPolynomialRing(
58
59
  X([2, 4, 3, 1]) + X([2, 1, 4, 3], "z")
59
60
  ```
60
61
 
61
- Args:
62
+ Args:
62
63
  R (sage ring): The base ring
63
64
  num_vars (int): Cardinality of the sets of variables
64
65
  base_variable_name (str): Base variable name
@@ -68,8 +69,9 @@ def FastDoubleSchubertPolynomialRing(
68
69
  q_varname (str, optional): Variable name of the q-ring. Defaults to "q".
69
70
  is_quantum (bool, optional): Whether or not the ring is quantum. Defaults to False.
70
71
 
71
- Returns:
72
+ Returns:
72
73
  FastDoubleSchubertPolynomialRing_xbasis: Basis element generator of the ring
74
+
73
75
  """
74
76
  QR = None
75
77
  if is_quantum:
@@ -96,7 +98,8 @@ def FastQuantumDoubleSchubertPolynomialRing(
96
98
  code_display=False,
97
99
  q_varname="q",
98
100
  ):
99
- """Quantum double Schubert ring generator
101
+ """
102
+ Quantum double Schubert ring generator
100
103
 
101
104
  Wraps FastDoubleSchubertPolynomialRing(), omitting indices and setting
102
105
  is_quantum to True.
@@ -111,6 +114,7 @@ def FastQuantumDoubleSchubertPolynomialRing(
111
114
 
112
115
  Returns:
113
116
  FastDoubleSchubertPolynomialRing_xbasis: Basis element generator of the quantum ring
117
+
114
118
  """
115
119
  return FastDoubleSchubertPolynomialRing(
116
120
  R,
@@ -118,7 +122,7 @@ def FastQuantumDoubleSchubertPolynomialRing(
118
122
  base_variable_name,
119
123
  coeff_variable_names,
120
124
  code_display=code_display,
121
- indices=tuple([1]),
125
+ indices=(1,),
122
126
  is_quantum=True,
123
127
  q_varname=q_varname,
124
128
  )
@@ -133,8 +137,7 @@ class FastDoubleSchubertPolynomial_class(CombinatorialFreeModule.Element):
133
137
  def q_varname(self):
134
138
  if not self.parent().is_quantum:
135
139
  return None
136
- else:
137
- return self.parent()._q_varname
140
+ return self.parent()._q_varname
138
141
 
139
142
  @property
140
143
  def base_polynomial_ring(self):
@@ -148,8 +151,7 @@ class FastDoubleSchubertPolynomial_class(CombinatorialFreeModule.Element):
148
151
  def q_ring(self):
149
152
  if not self.parent()._quantum:
150
153
  return None
151
- else:
152
- return self.parent()._q_ring
154
+ return self.parent()._q_ring
153
155
 
154
156
  def expand(self):
155
157
  if self.parent()._quantum:
@@ -163,20 +165,19 @@ class FastDoubleSchubertPolynomial_class(CombinatorialFreeModule.Element):
163
165
  v,
164
166
  )
165
167
  for k, v in self.monomial_coefficients().items()
166
- ]
167
- )
168
- else:
169
- return sum(
170
- [
171
- yz.schubmult(
172
- {(1, 2): v},
173
- tuple(_coerce_index(k[0], self.parent()._ascode, False)),
174
- self.parent()._base_polynomial_ring.gens(),
175
- self.parent()._coeff_polynomial_rings[k[1]].gens(),
176
- ).get((1, 2), 0)
177
- for k, v in self.monomial_coefficients().items()
178
- ]
168
+ ],
179
169
  )
170
+ return sum(
171
+ [
172
+ yz.schubmult(
173
+ {(1, 2): v},
174
+ tuple(_coerce_index(k[0], self.parent()._ascode, False)),
175
+ self.parent()._base_polynomial_ring.gens(),
176
+ self.parent()._coeff_polynomial_rings[k[1]].gens(),
177
+ ).get((1, 2), 0)
178
+ for k, v in self.monomial_coefficients().items()
179
+ ],
180
+ )
180
181
 
181
182
  def __eq__(self, other):
182
183
  ss = self.parent().one() * self
@@ -202,7 +203,7 @@ def _double_schub_parser(passed):
202
203
  fdict = {}
203
204
  vardict = {}
204
205
  fdict[passed._sc_rep] = passed._element_constructor_
205
- if passed._quantum:
206
+ if passed._quantum:
206
207
  QSRing = bork.FastSchubertPolynomialRing(
207
208
  passed._base_polynomial_ring.base_ring(),
208
209
  len(passed._base_polynomial_ring.gens()),
@@ -211,31 +212,31 @@ def _double_schub_parser(passed):
211
212
  code_display=passed._ascode,
212
213
  q_varname=passed._q_varname,
213
214
  )
214
- fdict[QSRing._sc_rep] = QSRing._element_constructor_
215
+ fdict[QSRing._sc_rep] = QSRing._element_constructor_
215
216
  SRing = bork.FastSchubertPolynomialRing(
216
- passed._base_polynomial_ring.base_ring().base_ring(),
217
- len(passed._base_polynomial_ring.gens()),
218
- passed._base_varname,
219
- is_quantum=False,
220
- code_display=passed._ascode,
221
- )
217
+ passed._base_polynomial_ring.base_ring().base_ring(),
218
+ len(passed._base_polynomial_ring.gens()),
219
+ passed._base_varname,
220
+ is_quantum=False,
221
+ code_display=passed._ascode,
222
+ )
222
223
  DRing = FastDoubleSchubertPolynomialRing(
223
- passed._base_polynomial_ring.base_ring().base_ring(),
224
- len(passed._base_polynomial_ring.gens()),
225
- passed._base_varname,
226
- coeff_variable_names=tuple(passed._varlist),
227
- )
224
+ passed._base_polynomial_ring.base_ring().base_ring(),
225
+ len(passed._base_polynomial_ring.gens()),
226
+ passed._base_varname,
227
+ coeff_variable_names=tuple(passed._varlist),
228
+ )
228
229
  fdict[DRing._sc_rep] = DRing._element_constructor_
229
- fdict[SRing._sc_rep] = SRing._element_constructor_
230
+ fdict[SRing._sc_rep] = SRing._element_constructor_
230
231
  for g in passed._base_polynomial_ring.gens():
231
- vardict[str(g)] = g
232
+ vardict[str(g)] = g
232
233
  return Parser(make_function=fdict, make_var=vardict)
233
234
 
234
235
 
235
236
  class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
236
237
  Element = FastDoubleSchubertPolynomial_class
237
238
 
238
- #def inject_variables:
239
+ # def inject_variables:
239
240
 
240
241
  def parser(self):
241
242
  if self._parser is None:
@@ -266,21 +267,22 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
266
267
  if isinstance(coeff_variable_names, tuple):
267
268
  self._mixed = True
268
269
  self._varlist = [*coeff_variable_names]
269
- self._coeff_polynomial_rings = {
270
- name: PolynomialRing(R if not quantum else QR, num_vars, name)
271
- for name in self._varlist
272
- }
270
+ self._coeff_polynomial_rings = {name: PolynomialRing(R if not quantum else QR, num_vars, name) for name in self._varlist}
273
271
 
274
272
  self._coeff_polynomial_ring = R if not quantum else QR
275
273
  for name, CR in self._coeff_polynomial_rings.items():
276
274
  self._coeff_polynomial_ring = PolynomialRing(
277
- self._coeff_polynomial_ring, num_vars, name
275
+ self._coeff_polynomial_ring,
276
+ num_vars,
277
+ name,
278
278
  )
279
279
  self._coeff_polynomial_ring = FlatteningMorphism(self._coeff_polynomial_ring).codomain()
280
280
  else:
281
281
  self._varlist = [coeff_variable_names]
282
282
  self._coeff_polynomial_ring = PolynomialRing(
283
- R if not quantum else QR, num_vars, coeff_variable_names
283
+ R if not quantum else QR,
284
+ num_vars,
285
+ coeff_variable_names,
284
286
  )
285
287
  self._coeff_polynomial_rings = {}
286
288
  self._coeff_polynomial_rings[coeff_variable_names] = self._coeff_polynomial_ring
@@ -293,15 +295,13 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
293
295
  self._ascode = True
294
296
 
295
297
  self._base_polynomial_ring = PolynomialRing(
296
- self._coeff_polynomial_ring, num_vars, base_variable_name
298
+ self._coeff_polynomial_ring,
299
+ num_vars,
300
+ base_variable_name,
297
301
  )
298
302
 
299
303
  self._index_wrapper = cartesian_product([index_set, self._varlist])
300
- cat = (
301
- GradedAlgebrasWithBasis(self._coeff_polynomial_ring).Commutative()
302
- if quantum
303
- else GradedBialgebrasWithBasis(self._coeff_polynomial_ring).Commutative()
304
- )
304
+ cat = GradedAlgebrasWithBasis(self._coeff_polynomial_ring).Commutative() if quantum else GradedBialgebrasWithBasis(self._coeff_polynomial_ring).Commutative()
305
305
 
306
306
  self._sc_rep = f"{'Q' if quantum else ''}DS{base_variable_name}"
307
307
 
@@ -334,12 +334,7 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
334
334
 
335
335
  if isinstance(x, str):
336
336
  return self.parser().parse(x)
337
- elif (
338
- isinstance(x, list)
339
- or isinstance(x, tuple)
340
- or isinstance(x, Permutation)
341
- or isinstance(x, Composition)
342
- ):
337
+ if isinstance(x, list) or isinstance(x, tuple) or isinstance(x, Permutation) or isinstance(x, Composition):
343
338
  # checking the input to avoid symmetrica crashing Sage, see trac 12924
344
339
  if x in self._index_wrapper:
345
340
  elem = self._from_dict({self._index_wrapper((x[0], x[1])): self.base_ring().one()})
@@ -350,31 +345,19 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
350
345
  (
351
346
  _coerce_index(x, self._ascode, self._ascode),
352
347
  self._varlist[0],
353
- )
354
- ): self.base_ring().one()
355
- }
348
+ ),
349
+ ): self.base_ring().one(),
350
+ },
356
351
  )
357
352
  elif isinstance(x, FastDoubleSchubertPolynomial):
358
- if (
359
- x.base_varname == self._base_varname
360
- and (self._quantum == x.parent()._quantum)
361
- and (not self._quantum or x.q_varname == self._q_varname)
362
- ):
353
+ if x.base_varname == self._base_varname and (self._quantum == x.parent()._quantum) and (not self._quantum or x.q_varname == self._q_varname):
363
354
  elem = self._from_dict(
364
- {
365
- (_coerce_index(k[0], x.parent()._ascode, self._ascode), k[1]): v
366
- for k, v in x.monomial_coefficients().items()
367
- }
355
+ {(_coerce_index(k[0], x.parent()._ascode, self._ascode), k[1]): v for k, v in x.monomial_coefficients().items()},
368
356
  )
369
357
  else:
370
358
  return self(x.expand())
371
359
  elif isinstance(x, bork.FastSchubertPolynomial):
372
- if (
373
- x.base_varname == self._base_varname
374
- and x.q_varname == self._q_varname
375
- and (self._quantum == x.parent()._quantum)
376
- and (not self._quantum or x.q_varname == self._q_varname)
377
- ):
360
+ if x.base_varname == self._base_varname and x.q_varname == self._q_varname and (self._quantum == x.parent()._quantum) and (not self._quantum or x.q_varname == self._q_varname):
378
361
  elem_dict = {}
379
362
 
380
363
  for k, v in x.monomial_coefficients().items():
@@ -386,7 +369,7 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
386
369
  [
387
370
  0
388
371
  for i in range(
389
- len(self._coeff_polynomial_rings[self._varlist[0]].gens())
372
+ len(self._coeff_polynomial_rings[self._varlist[0]].gens()),
390
373
  )
391
374
  ],
392
375
  self._q_ring.gens(),
@@ -399,18 +382,15 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
399
382
  [
400
383
  0
401
384
  for i in range(
402
- len(self._coeff_polynomial_rings[self._varlist[0]].gens())
385
+ len(self._coeff_polynomial_rings[self._varlist[0]].gens()),
403
386
  )
404
387
  ],
405
388
  )
406
389
  for k0, c0 in res.items():
407
- elem_dict[(_coerce_index(k0, False, self._ascode), self._varlist[0])] = (
408
- elem_dict.get(
409
- (_coerce_index(k0, False, self._ascode), self._varlist[0]),
410
- self._coeff_polynomial_ring.zero(),
411
- )
412
- + self._coeff_polynomial_ring(c0)
413
- )
390
+ elem_dict[(_coerce_index(k0, False, self._ascode), self._varlist[0])] = elem_dict.get(
391
+ (_coerce_index(k0, False, self._ascode), self._varlist[0]),
392
+ self._coeff_polynomial_ring.zero(),
393
+ ) + self._coeff_polynomial_ring(c0)
414
394
  elem = self._from_dict(elem_dict)
415
395
  else:
416
396
  elem = self(x.expand())
@@ -425,10 +405,7 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
425
405
  {(1, 2): 1},
426
406
  val,
427
407
  [syme.Symbol(str(g)) for g in self._base_polynomial_ring.gens()],
428
- [
429
- syme.Symbol(str(g))
430
- for g in self._coeff_polynomial_rings[self._varlist[0]].gens()
431
- ],
408
+ [syme.Symbol(str(g)) for g in self._coeff_polynomial_rings[self._varlist[0]].gens()],
432
409
  [syme.Symbol(str(g)) for g in self._q_ring.gens()],
433
410
  )
434
411
  else:
@@ -436,10 +413,7 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
436
413
  {(1, 2): 1},
437
414
  val,
438
415
  [syme.Symbol(str(g)) for g in self._base_polynomial_ring.gens()],
439
- [
440
- syme.Symbol(str(g))
441
- for g in self._coeff_polynomial_rings[self._varlist[0]].gens()
442
- ],
416
+ [syme.Symbol(str(g)) for g in self._coeff_polynomial_rings[self._varlist[0]].gens()],
443
417
  )
444
418
  elem = self._from_dict(
445
419
  {
@@ -448,7 +422,7 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
448
422
  self._varlist[0],
449
423
  ): self._coeff_polynomial_ring(str(v))
450
424
  for k, v in result.items()
451
- }
425
+ },
452
426
  )
453
427
  else:
454
428
  raise TypeError
@@ -458,21 +432,15 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
458
432
  def some_elements(self):
459
433
  return [
460
434
  self.one(),
461
- self(_coerce_index([1], False, self._ascode))
462
- + 2 * self(_coerce_index([2, 1], False, self._ascode)),
463
- self(_coerce_index([4, 2, 1, 3], False, self._ascode))
464
- - self(_coerce_index([3, 2, 1], False, self._ascode)),
435
+ self(_coerce_index([1], False, self._ascode)) + 2 * self(_coerce_index([2, 1], False, self._ascode)),
436
+ self(_coerce_index([4, 2, 1, 3], False, self._ascode)) - self(_coerce_index([3, 2, 1], False, self._ascode)),
465
437
  ]
466
438
 
467
439
  def product_on_basis(self, left, right):
468
440
  le = tuple(left[0])
469
441
  ri = tuple(right[0])
470
- var_y = [
471
- self._coeff_polynomial_ring(g) for g in self._coeff_polynomial_rings[left[1]].gens()
472
- ]
473
- var_z = [
474
- self._coeff_polynomial_ring(g) for g in self._coeff_polynomial_rings[right[1]].gens()
475
- ]
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()]
476
444
  if self._quantum:
477
445
  result = qyz.schubmult_db(
478
446
  {tuple(_coerce_index(le, self._ascode, False)): 1},
@@ -490,11 +458,7 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
490
458
  )
491
459
  result = {k: v for k, v in result.items() if v != 0}
492
460
  return sum(
493
- [
494
- self._coeff_polynomial_ring(v)
495
- * self((_coerce_index(k, False, self._ascode), left[1]))
496
- for k, v in result.items()
497
- ]
461
+ [self._coeff_polynomial_ring(v) * self((_coerce_index(k, False, self._ascode), left[1])) for k, v in result.items()],
498
462
  )
499
463
 
500
464
  def _coerce_map_from_(self, S):
@@ -559,24 +523,24 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
559
523
  continue
560
524
  firstperm = Permutation(permtrim(list(downperm[0:N])))
561
525
  secondperm = Permutation(
562
- permtrim([downperm[i] - N for i in range(N, len(downperm))])
526
+ permtrim([downperm[i] - N for i in range(N, len(downperm))]),
563
527
  )
564
528
  val = TR(val).subs(subs_dict_coprod)
565
529
  total_sum += self._coeff_polynomial_ring(val) * self(
566
- (_coerce_index(firstperm, False, self._ascode), indm[1])
530
+ (_coerce_index(firstperm, False, self._ascode), indm[1]),
567
531
  ).tensor(
568
532
  self(
569
533
  (
570
534
  _coerce_index(secondperm, False, self._ascode),
571
535
  self._varlist[0],
572
- )
573
- )
536
+ ),
537
+ ),
574
538
  )
575
539
  return total_sum
576
540
 
577
541
  def _repr_(self):
578
542
  return (
579
- f"Ring of {'quantum' if self._quantum else ''} double Schubert polynomials in {self._base_varname}{',' + self._q_varname if self._quantum else ''} with {len(self._base_polynomial_ring.gens())} variables with"
543
+ f"Ring of {'quantum' if self._quantum else ''} double Schubert polynomials in {self._base_varname}{',' + self._q_varname if self._quantum else ''} with {len(self._base_polynomial_ring.gens())} variables with" # noqa: E501
580
544
  f" coefficient variables {','.join(self._varlist)} over the ring {self._coeff_polynomial_ring.base_ring()} indexed by {'the Lehmer code' if self._ascode else 'permutations'}"
581
545
  )
582
546
 
@@ -1,32 +1,31 @@
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
18
+ from sympy import sympify
16
19
 
17
- from schubmult.perm_lib import permtrim
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
22
-
25
+ from schubmult.perm_lib import permtrim
23
26
 
24
- from sympy import sympify
27
+ from ._indexing import _coerce_index
25
28
 
26
- # from sage.misc.parser import Parser
27
- import symengine as syme
28
- import schubmult.sage_integration._fast_double_schubert_polynomial_ring as bork
29
- from functools import cache
30
29
  # FastQuantumDoubleSchubertPolynomialRing = bork.FastQuantumDoubleSchubertPolynomialRing
31
30
 
32
31
 
@@ -38,9 +37,10 @@ def FastSchubertPolynomialRing(
38
37
  code_display: bool = False,
39
38
  q_varname: str = "q",
40
39
  is_quantum: bool = False,
41
- indices: tuple[int] = tuple([1]),
40
+ indices: tuple[int] = (1,),
42
41
  ):
43
- """Wrapper function to return a double Schubert polynomial Ring
42
+ """
43
+ Wrapper function to return a double Schubert polynomial Ring
44
44
 
45
45
  Calls the _xbasis class to return a (quantum) Schubert
46
46
  polynomial ring with the indicated base ring, number of variables,
@@ -67,6 +67,7 @@ def FastSchubertPolynomialRing(
67
67
 
68
68
  Returns:
69
69
  FastSchubertPolynomialRing_xbasis: Element constructor of the ring
70
+
70
71
  """
71
72
  if is_quantum:
72
73
  QR = PolynomialRing(R, num_vars, q_varname)
@@ -91,7 +92,8 @@ def FastQuantumSchubertPolynomialRing(
91
92
  q_varname: str = "q",
92
93
  code_display: bool = False,
93
94
  ):
94
- """Quantum Schubert ring generator
95
+ """
96
+ Quantum Schubert ring generator
95
97
 
96
98
  Wraps FastSchubertPolynomialRing(), omitting indices and setting
97
99
  is_quantum to True.
@@ -106,6 +108,7 @@ def FastQuantumSchubertPolynomialRing(
106
108
 
107
109
  Returns:
108
110
  FastSchubertPolynomialRing_xbasis: Element constructor of the ring
111
+
109
112
  """
110
113
  return FastSchubertPolynomialRing(
111
114
  R,
@@ -145,25 +148,24 @@ class FastSchubertPolynomial_class(CombinatorialFreeModule.Element):
145
148
  [0 for i in range(100)],
146
149
  self.parent()._q_ring.gens(),
147
150
  v,
148
- )
151
+ ),
149
152
  )
150
153
  for k, v in self.monomial_coefficients().items()
151
- ]
152
- )
153
- else:
154
- return sum(
155
- [
156
- self.parent()._polynomial_ring(
157
- yz.schubmult(
158
- {(1, 2): v},
159
- tuple(_coerce_index(k, self.parent()._ascode, False)),
160
- self.parent()._polynomial_ring.gens(),
161
- [0 for i in range(100)],
162
- ).get((1, 2), 0)
163
- )
164
- for k, v in self.monomial_coefficients().items()
165
- ]
154
+ ],
166
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
+ )
167
169
 
168
170
 
169
171
  @cache
@@ -185,12 +187,12 @@ def _single_schub_parser(passed):
185
187
 
186
188
  class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
187
189
  Element = FastSchubertPolynomial_class
188
-
190
+
189
191
  def parser(self):
190
192
  if self._parser is None:
191
193
  self._parser = _single_schub_parser(self)
192
194
  return self._parser
193
-
195
+
194
196
 
195
197
  def __init__(
196
198
  self,
@@ -263,7 +265,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
263
265
  def _element_constructor_(self, x):
264
266
  if isinstance(x, str):
265
267
  return self.parser().parse(x)
266
- elif (
268
+ if (
267
269
  isinstance(x, list)
268
270
  or isinstance(x, tuple)
269
271
  or isinstance(x, Composition)
@@ -271,7 +273,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
271
273
  ):
272
274
  # checking the input to avoid symmetrica crashing Sage, see trac 12924
273
275
  elem = self._from_dict(
274
- {_coerce_index(x, self._ascode, self._ascode): self.base_ring().one()}
276
+ {_coerce_index(x, self._ascode, self._ascode): self.base_ring().one()},
275
277
  )
276
278
  elif isinstance(x, FastSchubertPolynomial):
277
279
  if (
@@ -283,7 +285,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
283
285
  {
284
286
  _coerce_index(k, x.parent()._ascode, self._ascode): v
285
287
  for k, v in x.monomial_coefficients().items()
286
- }
288
+ },
287
289
  )
288
290
  else:
289
291
  return self(x.expand())
@@ -312,7 +314,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
312
314
  if self._quantum
313
315
  else self.base_ring()(str(v))
314
316
  for k, v in result.items()
315
- }
317
+ },
316
318
  )
317
319
  else:
318
320
  raise TypeError(f"Could not convert {x=} to {self}")
@@ -337,18 +339,17 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
337
339
  tuple(_coerce_index(right, self._ascode, False)),
338
340
  list(self._q_ring.gens()),
339
341
  ).items()
340
- ]
341
- )
342
- else:
343
- return sum(
344
- [
345
- self.base_ring()(v) * self(_coerce_index(k, False, self._ascode))
346
- for k, v in py.schubmult(
347
- {tuple(_coerce_index(left, self._ascode, False)): 1},
348
- tuple(_coerce_index(right, self._ascode, False)),
349
- ).items()
350
- ]
342
+ ],
351
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
+ )
352
353
 
353
354
  def coproduct_on_basis(self, mperm):
354
355
  if self._quantum:
@@ -382,10 +383,10 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
382
383
  continue
383
384
  firstperm = Permutation(permtrim(list(downperm[0:N])))
384
385
  secondperm = Permutation(
385
- permtrim([downperm[i] - N for i in range(N, len(downperm))])
386
+ permtrim([downperm[i] - N for i in range(N, len(downperm))]),
386
387
  )
387
388
  total_sum += self.base_ring()(val) * self(
388
- _coerce_index(firstperm, False, self._ascode)
389
+ _coerce_index(firstperm, False, self._ascode),
389
390
  ).tensor(self(_coerce_index(secondperm, False, self._ascode)))
390
391
  return total_sum
391
392