schubmult 2.0.3__py3-none-any.whl → 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- schubmult/__init__.py +94 -1
- schubmult/perm_lib.py +233 -880
- schubmult/poly_lib/__init__.py +31 -0
- schubmult/poly_lib/poly_lib.py +244 -0
- schubmult/poly_lib/schub_poly.py +148 -0
- schubmult/poly_lib/variables.py +204 -0
- schubmult/rings/__init__.py +17 -0
- schubmult/rings/_quantum_schubert_polynomial_ring.py +788 -0
- schubmult/rings/_schubert_polynomial_ring.py +1006 -0
- schubmult/rings/_tensor_schub_ring.py +128 -0
- schubmult/rings/_utils.py +55 -0
- schubmult/{sage_integration → sage}/__init__.py +17 -15
- schubmult/{sage_integration → sage}/_fast_double_schubert_polynomial_ring.py +142 -220
- schubmult/{sage_integration → sage}/_fast_schubert_polynomial_ring.py +78 -72
- schubmult/sage/_indexing.py +51 -0
- schubmult/schub_lib/__init__.py +51 -0
- schubmult/{schubmult_double/_funcs.py → schub_lib/double.py} +618 -798
- schubmult/{schubmult_q/_funcs.py → schub_lib/quantum.py} +70 -72
- schubmult/schub_lib/quantum_double.py +954 -0
- schubmult/schub_lib/schub_lib.py +659 -0
- schubmult/{schubmult_py/_funcs.py → schub_lib/single.py} +58 -48
- schubmult/schub_lib/tests/__init__.py +0 -0
- schubmult/schub_lib/tests/legacy_perm_lib.py +946 -0
- schubmult/schub_lib/tests/test_vs_old.py +109 -0
- schubmult/scripts/__init__.py +0 -0
- schubmult/scripts/schubmult_double.py +378 -0
- schubmult/scripts/schubmult_py.py +84 -0
- schubmult/scripts/schubmult_q.py +109 -0
- schubmult/scripts/schubmult_q_double.py +207 -0
- schubmult/utils/__init__.py +0 -0
- schubmult/{_base_argparse.py → utils/argparse.py} +40 -11
- schubmult/utils/logging.py +16 -0
- schubmult/utils/parsing.py +20 -0
- schubmult/utils/perm_utils.py +135 -0
- schubmult/utils/test_utils.py +65 -0
- schubmult-3.0.0.dist-info/METADATA +1234 -0
- schubmult-3.0.0.dist-info/RECORD +41 -0
- {schubmult-2.0.3.dist-info → schubmult-3.0.0.dist-info}/WHEEL +1 -1
- schubmult-3.0.0.dist-info/entry_points.txt +5 -0
- schubmult/_tests.py +0 -9
- schubmult/sage_integration/_indexing.py +0 -51
- schubmult/schubmult_double/__init__.py +0 -22
- schubmult/schubmult_double/__main__.py +0 -5
- schubmult/schubmult_double/_script.py +0 -474
- schubmult/schubmult_py/__init__.py +0 -13
- schubmult/schubmult_py/__main__.py +0 -5
- schubmult/schubmult_py/_script.py +0 -96
- schubmult/schubmult_q/__init__.py +0 -13
- schubmult/schubmult_q/__main__.py +0 -5
- schubmult/schubmult_q/_script.py +0 -160
- schubmult/schubmult_q_double/__init__.py +0 -17
- schubmult/schubmult_q_double/__main__.py +0 -5
- schubmult/schubmult_q_double/_funcs.py +0 -540
- schubmult/schubmult_q_double/_script.py +0 -398
- schubmult-2.0.3.dist-info/METADATA +0 -455
- schubmult-2.0.3.dist-info/RECORD +0 -30
- schubmult-2.0.3.dist-info/entry_points.txt +0 -5
- {schubmult-2.0.3.dist-info → schubmult-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {schubmult-2.0.3.dist-info → schubmult-3.0.0.dist-info}/top_level.txt +0 -0
@@ -1,35 +1,37 @@
|
|
1
|
+
from functools import cache
|
2
|
+
|
3
|
+
import symengine as syme
|
1
4
|
from sage.all import * # noqa: F403
|
2
|
-
from sage.categories.
|
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.
|
6
|
-
from sage.combinat.permutation import Permutations, Permutation, from_lehmer_code
|
13
|
+
from sage.combinat.permutation import Permutation, Permutations
|
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
|
12
|
-
|
13
|
-
|
14
|
-
Composition,
|
15
|
-
)
|
20
|
+
from sympy import sympify
|
21
|
+
|
22
|
+
import schubmult.perm_lib as pl
|
16
23
|
|
17
24
|
# from . import (
|
18
25
|
# FastSchubertPolynomialRing_base,
|
19
26
|
# FastSchubertPolynomialRing,
|
20
27
|
# FastSchubertPolynomial,
|
21
|
-
# )
|
22
|
-
import schubmult.
|
23
|
-
|
24
|
-
|
25
|
-
from functools import cache
|
26
|
-
import schubmult.schubmult_q_double as qyz
|
27
|
-
import schubmult.schubmult_double as yz
|
28
|
-
from sympy import sympify
|
29
|
-
import symengine as syme
|
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
|
-
from
|
34
|
+
from ._indexing import _coerce_index
|
33
35
|
|
34
36
|
|
35
37
|
def FastDoubleSchubertPolynomialRing(
|
@@ -38,12 +40,13 @@ def FastDoubleSchubertPolynomialRing(
|
|
38
40
|
base_variable_name: str,
|
39
41
|
coeff_variable_names: str | tuple[str],
|
40
42
|
*,
|
41
|
-
indices: tuple[int] =
|
43
|
+
indices: tuple[int] = (1,),
|
42
44
|
code_display: bool = False,
|
43
45
|
q_varname: str = "q",
|
44
46
|
is_quantum: bool = False,
|
45
47
|
):
|
46
|
-
"""
|
48
|
+
"""
|
49
|
+
Wrapper function to return a double Schubert polynomial Ring
|
47
50
|
|
48
51
|
Calls the _xbasis class to return a double or quantum double Schubert
|
49
52
|
polynomial ring with the indicated base ring, number of variables,
|
@@ -58,7 +61,7 @@ def FastDoubleSchubertPolynomialRing(
|
|
58
61
|
X([2, 4, 3, 1]) + X([2, 1, 4, 3], "z")
|
59
62
|
```
|
60
63
|
|
61
|
-
|
64
|
+
Args:
|
62
65
|
R (sage ring): The base ring
|
63
66
|
num_vars (int): Cardinality of the sets of variables
|
64
67
|
base_variable_name (str): Base variable name
|
@@ -68,8 +71,9 @@ def FastDoubleSchubertPolynomialRing(
|
|
68
71
|
q_varname (str, optional): Variable name of the q-ring. Defaults to "q".
|
69
72
|
is_quantum (bool, optional): Whether or not the ring is quantum. Defaults to False.
|
70
73
|
|
71
|
-
|
74
|
+
Returns:
|
72
75
|
FastDoubleSchubertPolynomialRing_xbasis: Basis element generator of the ring
|
76
|
+
|
73
77
|
"""
|
74
78
|
QR = None
|
75
79
|
if is_quantum:
|
@@ -96,7 +100,8 @@ def FastQuantumDoubleSchubertPolynomialRing(
|
|
96
100
|
code_display=False,
|
97
101
|
q_varname="q",
|
98
102
|
):
|
99
|
-
"""
|
103
|
+
"""
|
104
|
+
Quantum double Schubert ring generator
|
100
105
|
|
101
106
|
Wraps FastDoubleSchubertPolynomialRing(), omitting indices and setting
|
102
107
|
is_quantum to True.
|
@@ -111,6 +116,7 @@ def FastQuantumDoubleSchubertPolynomialRing(
|
|
111
116
|
|
112
117
|
Returns:
|
113
118
|
FastDoubleSchubertPolynomialRing_xbasis: Basis element generator of the quantum ring
|
119
|
+
|
114
120
|
"""
|
115
121
|
return FastDoubleSchubertPolynomialRing(
|
116
122
|
R,
|
@@ -118,7 +124,7 @@ def FastQuantumDoubleSchubertPolynomialRing(
|
|
118
124
|
base_variable_name,
|
119
125
|
coeff_variable_names,
|
120
126
|
code_display=code_display,
|
121
|
-
indices=
|
127
|
+
indices=(1,),
|
122
128
|
is_quantum=True,
|
123
129
|
q_varname=q_varname,
|
124
130
|
)
|
@@ -133,8 +139,7 @@ class FastDoubleSchubertPolynomial_class(CombinatorialFreeModule.Element):
|
|
133
139
|
def q_varname(self):
|
134
140
|
if not self.parent().is_quantum:
|
135
141
|
return None
|
136
|
-
|
137
|
-
return self.parent()._q_varname
|
142
|
+
return self.parent()._q_varname
|
138
143
|
|
139
144
|
@property
|
140
145
|
def base_polynomial_ring(self):
|
@@ -148,35 +153,34 @@ class FastDoubleSchubertPolynomial_class(CombinatorialFreeModule.Element):
|
|
148
153
|
def q_ring(self):
|
149
154
|
if not self.parent()._quantum:
|
150
155
|
return None
|
151
|
-
|
152
|
-
return self.parent()._q_ring
|
156
|
+
return self.parent()._q_ring
|
153
157
|
|
158
|
+
# can speed this up
|
154
159
|
def expand(self):
|
155
160
|
if self.parent()._quantum:
|
156
161
|
return sum(
|
157
162
|
[
|
158
163
|
qyz.schubpoly_quantum(
|
159
|
-
|
164
|
+
pl.Permutation(_coerce_index(k[0], self.parent()._ascode, False)),
|
160
165
|
self.parent()._base_polynomial_ring.gens(),
|
161
166
|
self.parent()._coeff_polynomial_rings[k[1]].gens(),
|
162
167
|
self.parent()._q_ring.gens(),
|
163
168
|
v,
|
164
169
|
)
|
165
170
|
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
|
-
]
|
171
|
+
],
|
179
172
|
)
|
173
|
+
return sum(
|
174
|
+
[
|
175
|
+
yz.schubmult_double(
|
176
|
+
{pl.Permutation([]): v},
|
177
|
+
pl.Permutation(_coerce_index(k[0], self.parent()._ascode, False)),
|
178
|
+
self.parent()._base_polynomial_ring.gens(),
|
179
|
+
self.parent()._coeff_polynomial_rings[k[1]].gens(),
|
180
|
+
).get(pl.Permutation([]), 0)
|
181
|
+
for k, v in self.monomial_coefficients().items()
|
182
|
+
],
|
183
|
+
)
|
180
184
|
|
181
185
|
def __eq__(self, other):
|
182
186
|
ss = self.parent().one() * self
|
@@ -202,7 +206,7 @@ def _double_schub_parser(passed):
|
|
202
206
|
fdict = {}
|
203
207
|
vardict = {}
|
204
208
|
fdict[passed._sc_rep] = passed._element_constructor_
|
205
|
-
if passed._quantum:
|
209
|
+
if passed._quantum:
|
206
210
|
QSRing = bork.FastSchubertPolynomialRing(
|
207
211
|
passed._base_polynomial_ring.base_ring(),
|
208
212
|
len(passed._base_polynomial_ring.gens()),
|
@@ -211,31 +215,31 @@ def _double_schub_parser(passed):
|
|
211
215
|
code_display=passed._ascode,
|
212
216
|
q_varname=passed._q_varname,
|
213
217
|
)
|
214
|
-
fdict[QSRing._sc_rep] = QSRing._element_constructor_
|
218
|
+
fdict[QSRing._sc_rep] = QSRing._element_constructor_
|
215
219
|
SRing = bork.FastSchubertPolynomialRing(
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
220
|
+
passed._base_polynomial_ring.base_ring().base_ring(),
|
221
|
+
len(passed._base_polynomial_ring.gens()),
|
222
|
+
passed._base_varname,
|
223
|
+
is_quantum=False,
|
224
|
+
code_display=passed._ascode,
|
225
|
+
)
|
222
226
|
DRing = FastDoubleSchubertPolynomialRing(
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
227
|
+
passed._base_polynomial_ring.base_ring().base_ring(),
|
228
|
+
len(passed._base_polynomial_ring.gens()),
|
229
|
+
passed._base_varname,
|
230
|
+
coeff_variable_names=tuple(passed._varlist),
|
231
|
+
)
|
228
232
|
fdict[DRing._sc_rep] = DRing._element_constructor_
|
229
|
-
fdict[SRing._sc_rep] = SRing._element_constructor_
|
233
|
+
fdict[SRing._sc_rep] = SRing._element_constructor_
|
230
234
|
for g in passed._base_polynomial_ring.gens():
|
231
|
-
|
235
|
+
vardict[str(g)] = g
|
232
236
|
return Parser(make_function=fdict, make_var=vardict)
|
233
237
|
|
234
238
|
|
235
239
|
class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
|
236
240
|
Element = FastDoubleSchubertPolynomial_class
|
237
241
|
|
238
|
-
#def inject_variables:
|
242
|
+
# def inject_variables:
|
239
243
|
|
240
244
|
def parser(self):
|
241
245
|
if self._parser is None:
|
@@ -266,21 +270,22 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
|
|
266
270
|
if isinstance(coeff_variable_names, tuple):
|
267
271
|
self._mixed = True
|
268
272
|
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
|
-
}
|
273
|
+
self._coeff_polynomial_rings = {name: PolynomialRing(R if not quantum else QR, num_vars, name) for name in self._varlist}
|
273
274
|
|
274
275
|
self._coeff_polynomial_ring = R if not quantum else QR
|
275
276
|
for name, CR in self._coeff_polynomial_rings.items():
|
276
277
|
self._coeff_polynomial_ring = PolynomialRing(
|
277
|
-
self._coeff_polynomial_ring,
|
278
|
+
self._coeff_polynomial_ring,
|
279
|
+
num_vars,
|
280
|
+
name,
|
278
281
|
)
|
279
282
|
self._coeff_polynomial_ring = FlatteningMorphism(self._coeff_polynomial_ring).codomain()
|
280
283
|
else:
|
281
284
|
self._varlist = [coeff_variable_names]
|
282
285
|
self._coeff_polynomial_ring = PolynomialRing(
|
283
|
-
R if not quantum else QR,
|
286
|
+
R if not quantum else QR,
|
287
|
+
num_vars,
|
288
|
+
coeff_variable_names,
|
284
289
|
)
|
285
290
|
self._coeff_polynomial_rings = {}
|
286
291
|
self._coeff_polynomial_rings[coeff_variable_names] = self._coeff_polynomial_ring
|
@@ -293,18 +298,26 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
|
|
293
298
|
self._ascode = True
|
294
299
|
|
295
300
|
self._base_polynomial_ring = PolynomialRing(
|
296
|
-
self._coeff_polynomial_ring,
|
301
|
+
self._coeff_polynomial_ring,
|
302
|
+
num_vars,
|
303
|
+
base_variable_name,
|
297
304
|
)
|
298
305
|
|
299
306
|
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
|
-
)
|
307
|
+
cat = GradedAlgebrasWithBasis(self._coeff_polynomial_ring).Commutative() if quantum else GradedBialgebrasWithBasis(self._coeff_polynomial_ring).Commutative()
|
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,91 +340,64 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
|
|
326
340
|
def set_coproduct_indices(self, indices):
|
327
341
|
self._splitter = indices
|
328
342
|
|
329
|
-
def _element_constructor_(self,
|
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
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
(
|
351
|
-
_coerce_index(x, self._ascode, self._ascode),
|
352
|
-
self._varlist[0],
|
353
|
-
)
|
354
|
-
): self.base_ring().one()
|
355
|
-
}
|
356
|
-
)
|
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
|
+
)
|
357
359
|
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
|
-
):
|
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):
|
363
361
|
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
|
-
}
|
362
|
+
{(_coerce_index(k[0], x.parent()._ascode, self._ascode), k[1]): v for k, v in x.monomial_coefficients().items()},
|
368
363
|
)
|
369
364
|
else:
|
370
365
|
return self(x.expand())
|
371
366
|
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
|
-
):
|
367
|
+
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
368
|
elem_dict = {}
|
379
369
|
|
380
370
|
for k, v in x.monomial_coefficients().items():
|
381
371
|
if self._quantum:
|
382
|
-
res = qyz.
|
383
|
-
{(
|
384
|
-
|
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))),
|
385
375
|
self._coeff_polynomial_rings[self._varlist[0]].gens(),
|
386
376
|
[
|
387
377
|
0
|
388
378
|
for i in range(
|
389
|
-
len(self._coeff_polynomial_rings[self._varlist[0]].gens())
|
379
|
+
len(self._coeff_polynomial_rings[self._varlist[0]].gens()),
|
390
380
|
)
|
391
381
|
],
|
392
382
|
self._q_ring.gens(),
|
393
383
|
)
|
394
384
|
else:
|
395
|
-
res = yz.
|
396
|
-
{(
|
397
|
-
|
385
|
+
res = yz.schubmult_double(
|
386
|
+
{pl.Permutation([]): self._coeff_polynomial_ring(v)},
|
387
|
+
pl.Permutation(list(_coerce_index(k, x.parent()._ascode, False))),
|
398
388
|
self._coeff_polynomial_rings[self._varlist[0]].gens(),
|
399
389
|
[
|
400
390
|
0
|
401
391
|
for i in range(
|
402
|
-
len(self._coeff_polynomial_rings[self._varlist[0]].gens())
|
392
|
+
len(self._coeff_polynomial_rings[self._varlist[0]].gens()),
|
403
393
|
)
|
404
394
|
],
|
405
395
|
)
|
406
396
|
for k0, c0 in res.items():
|
407
|
-
elem_dict[(_coerce_index(k0, False, self._ascode), self._varlist[0])] = (
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
)
|
412
|
-
+ self._coeff_polynomial_ring(c0)
|
413
|
-
)
|
397
|
+
elem_dict[(_coerce_index(k0, False, self._ascode), self._varlist[0])] = elem_dict.get(
|
398
|
+
(_coerce_index(k0, False, self._ascode), self._varlist[0]),
|
399
|
+
self._coeff_polynomial_ring.zero(),
|
400
|
+
) + self._coeff_polynomial_ring(c0)
|
414
401
|
elem = self._from_dict(elem_dict)
|
415
402
|
else:
|
416
403
|
elem = self(x.expand())
|
@@ -421,25 +408,19 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
|
|
421
408
|
sympy_floff = sympify(str(x))
|
422
409
|
val = syme.sympify(sympy_floff)
|
423
410
|
if self._quantum:
|
424
|
-
result = qyz.
|
425
|
-
{(
|
411
|
+
result = qyz.mult_poly_q_double(
|
412
|
+
{pl.Permutation([]): 1},
|
426
413
|
val,
|
427
414
|
[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
|
-
],
|
415
|
+
[syme.Symbol(str(g)) for g in self._coeff_polynomial_rings[self._varlist[0]].gens()],
|
432
416
|
[syme.Symbol(str(g)) for g in self._q_ring.gens()],
|
433
417
|
)
|
434
418
|
else:
|
435
|
-
result = yz.
|
436
|
-
{(
|
419
|
+
result = yz.mult_poly_double(
|
420
|
+
{pl.Permutation([]): 1},
|
437
421
|
val,
|
438
422
|
[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
|
-
],
|
423
|
+
[syme.Symbol(str(g)) for g in self._coeff_polynomial_rings[self._varlist[0]].gens()],
|
443
424
|
)
|
444
425
|
elem = self._from_dict(
|
445
426
|
{
|
@@ -448,7 +429,7 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
|
|
448
429
|
self._varlist[0],
|
449
430
|
): self._coeff_polynomial_ring(str(v))
|
450
431
|
for k, v in result.items()
|
451
|
-
}
|
432
|
+
},
|
452
433
|
)
|
453
434
|
else:
|
454
435
|
raise TypeError
|
@@ -458,43 +439,33 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
|
|
458
439
|
def some_elements(self):
|
459
440
|
return [
|
460
441
|
self.one(),
|
461
|
-
self(_coerce_index([1], False, self._ascode))
|
462
|
-
|
463
|
-
self(_coerce_index([4, 2, 1, 3], False, self._ascode))
|
464
|
-
- self(_coerce_index([3, 2, 1], False, self._ascode)),
|
442
|
+
self(_coerce_index([1], False, self._ascode)) + 2 * self(_coerce_index([2, 1], False, self._ascode)),
|
443
|
+
self(_coerce_index([4, 2, 1, 3], False, self._ascode)) - self(_coerce_index([3, 2, 1], False, self._ascode)),
|
465
444
|
]
|
466
445
|
|
467
446
|
def product_on_basis(self, left, right):
|
468
|
-
le =
|
469
|
-
ri =
|
470
|
-
var_y = [
|
471
|
-
|
472
|
-
]
|
473
|
-
var_z = [
|
474
|
-
self._coeff_polynomial_ring(g) for g in self._coeff_polynomial_rings[right[1]].gens()
|
475
|
-
]
|
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()]
|
476
451
|
if self._quantum:
|
477
|
-
result = qyz.
|
478
|
-
{
|
479
|
-
|
452
|
+
result = qyz.schubmult_q_double_fast(
|
453
|
+
{pl.Permutation(le): 1},
|
454
|
+
pl.Permutation(ri),
|
480
455
|
var_y,
|
481
456
|
var_z,
|
482
|
-
self._q_ring.gens(),
|
457
|
+
[syme.sympify(str(g)) for g in self._q_ring.gens()],
|
483
458
|
)
|
484
459
|
else:
|
485
|
-
result = yz.
|
486
|
-
{
|
487
|
-
|
460
|
+
result = yz.schubmult_double(
|
461
|
+
{pl.Permutation(le): 1},
|
462
|
+
pl.Permutation(ri),
|
488
463
|
var_y,
|
489
464
|
var_z,
|
490
465
|
)
|
491
466
|
result = {k: v for k, v in result.items() if v != 0}
|
492
467
|
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
|
-
]
|
468
|
+
[self._coeff_polynomial_ring(str(v)) * self(_coerce_index(k, False, self._ascode), left[1]) for k, v in result.items()],
|
498
469
|
)
|
499
470
|
|
500
471
|
def _coerce_map_from_(self, S):
|
@@ -513,70 +484,21 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
|
|
513
484
|
raise NotImplementedError("Quantum double Schubert polynomials have no coproduct")
|
514
485
|
indices = self._splitter
|
515
486
|
indices = sorted(indices)
|
516
|
-
subs_dict_coprod = {}
|
517
|
-
mperm = indm[0]
|
518
|
-
mperm = _coerce_index(mperm, self._ascode, False)
|
519
487
|
RR = self._coeff_polynomial_rings[indm[1]]
|
520
|
-
|
521
|
-
k = len(indices)
|
522
|
-
n = len(mperm)
|
523
|
-
kcd = [indices[i] - i - 1 for i in range(len(indices))] + [n + 1 - k for i in range(k, n)]
|
524
|
-
max_required = max([kcd[i] + i for i in range(len(kcd))])
|
525
|
-
kcd2 = kcd + [0 for i in range(len(kcd), max_required)] + [0]
|
526
|
-
N = len(kcd)
|
527
|
-
kperm = from_lehmer_code(kcd2).inverse()
|
528
|
-
# r = [sum(self.base_ring()._first_ngens(j)) for j in range(100)]
|
529
|
-
vn = [f"soible_{i}" for i in range(N * 2 + 1)]
|
530
|
-
TR = PolynomialRing(self.base_ring(), N * 2 + 1, vn)
|
531
|
-
|
532
|
-
for i in range(N * 2 + 1):
|
533
|
-
if i <= N:
|
534
|
-
subs_dict_coprod[TR.gens()[i]] = self._coeff_polynomial_ring(RR.gens()[i])
|
535
|
-
else:
|
536
|
-
subs_dict_coprod[TR.gens()[i]] = self._coeff_polynomial_ring(RBase.gens()[i - N])
|
537
|
-
|
538
|
-
coeff_dict = {tuple(kperm): 1}
|
539
|
-
coeff_dict = yz.schubmult(
|
540
|
-
coeff_dict,
|
541
|
-
tuple(mperm),
|
542
|
-
list(TR.gens()),
|
543
|
-
RR.gens(),
|
544
|
-
)
|
488
|
+
TR = self._coeff_polynomial_rings[self._varlist[0]]
|
545
489
|
|
546
|
-
|
547
|
-
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()])
|
548
491
|
total_sum = 0
|
549
|
-
for
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
for i in range(N):
|
555
|
-
if downperm[i] > N:
|
556
|
-
flag = False
|
557
|
-
break
|
558
|
-
if not flag:
|
559
|
-
continue
|
560
|
-
firstperm = Permutation(permtrim(list(downperm[0:N])))
|
561
|
-
secondperm = Permutation(
|
562
|
-
permtrim([downperm[i] - N for i in range(N, len(downperm))])
|
563
|
-
)
|
564
|
-
val = TR(val).subs(subs_dict_coprod)
|
565
|
-
total_sum += self._coeff_polynomial_ring(val) * self(
|
566
|
-
(_coerce_index(firstperm, False, self._ascode), indm[1])
|
567
|
-
).tensor(
|
568
|
-
self(
|
569
|
-
(
|
570
|
-
_coerce_index(secondperm, False, self._ascode),
|
571
|
-
self._varlist[0],
|
572
|
-
)
|
573
|
-
)
|
574
|
-
)
|
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]))
|
575
497
|
return total_sum
|
576
498
|
|
577
499
|
def _repr_(self):
|
578
500
|
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"
|
501
|
+
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
502
|
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
503
|
)
|
582
504
|
|