schubmult 2.0.2__py3-none-any.whl → 2.0.3__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 (38) hide show
  1. schubmult/__init__.py +1 -1
  2. schubmult/_base_argparse.py +35 -6
  3. schubmult/_tests.py +9 -0
  4. schubmult/sage_integration/__init__.py +1 -0
  5. schubmult/sage_integration/_fast_double_schubert_polynomial_ring.py +68 -11
  6. schubmult/sage_integration/_fast_schubert_polynomial_ring.py +43 -5
  7. schubmult/sage_integration/_indexing.py +11 -4
  8. schubmult/schubmult_double/__init__.py +6 -2
  9. schubmult/schubmult_double/__main__.py +1 -1
  10. schubmult/schubmult_double/_funcs.py +112 -32
  11. schubmult/schubmult_double/_script.py +109 -51
  12. schubmult/schubmult_py/__init__.py +5 -2
  13. schubmult/schubmult_py/__main__.py +1 -1
  14. schubmult/schubmult_py/_funcs.py +54 -9
  15. schubmult/schubmult_py/_script.py +33 -52
  16. schubmult/schubmult_q/__init__.py +1 -0
  17. schubmult/schubmult_q/__main__.py +1 -1
  18. schubmult/schubmult_q/_funcs.py +21 -37
  19. schubmult/schubmult_q/_script.py +19 -16
  20. schubmult/schubmult_q_double/__init__.py +1 -0
  21. schubmult/schubmult_q_double/__main__.py +1 -1
  22. schubmult/schubmult_q_double/_funcs.py +57 -24
  23. schubmult/schubmult_q_double/_script.py +200 -139
  24. {schubmult-2.0.2.dist-info → schubmult-2.0.3.dist-info}/METADATA +4 -4
  25. schubmult-2.0.3.dist-info/RECORD +30 -0
  26. {schubmult-2.0.2.dist-info → schubmult-2.0.3.dist-info}/WHEEL +1 -1
  27. schubmult-2.0.3.dist-info/entry_points.txt +5 -0
  28. {schubmult-2.0.2.dist-info → schubmult-2.0.3.dist-info}/top_level.txt +0 -1
  29. schubmult/schubmult_double/_vars.py +0 -18
  30. schubmult/schubmult_py/_vars.py +0 -3
  31. schubmult/schubmult_q/_vars.py +0 -18
  32. schubmult/schubmult_q_double/_vars.py +0 -21
  33. schubmult-2.0.2.dist-info/RECORD +0 -36
  34. schubmult-2.0.2.dist-info/entry_points.txt +0 -5
  35. tests/__init__.py +0 -0
  36. tests/test_fast_double_schubert.py +0 -145
  37. tests/test_fast_schubert.py +0 -38
  38. {schubmult-2.0.2.dist-info → schubmult-2.0.3.dist-info}/licenses/LICENSE +0 -0
schubmult/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.0.2"
1
+ __version__ = "2.0.3"
@@ -1,7 +1,7 @@
1
1
  from argparse import ArgumentParser, SUPPRESS, RawDescriptionHelpFormatter
2
2
 
3
3
 
4
- def schub_argparse(prog_name, description, quantum=False, yz=False):
4
+ def schub_argparse(prog_name, description, argv, quantum=False, yz=False):
5
5
  parser = ArgumentParser(
6
6
  prog=prog_name,
7
7
  description=description,
@@ -14,7 +14,6 @@ def schub_argparse(prog_name, description, quantum=False, yz=False):
14
14
  """,
15
15
  formatter_class=RawDescriptionHelpFormatter,
16
16
  )
17
-
18
17
  parser.add_argument(
19
18
  "perms",
20
19
  nargs="+",
@@ -139,22 +138,36 @@ def schub_argparse(prog_name, description, quantum=False, yz=False):
139
138
  help="Substitute commuting difference operators for perm1, then apply to Schub indexed by perm2",
140
139
  )
141
140
 
141
+ disp_mode_list = ["basic", "pretty", "latex", "raw"]
142
+
143
+ if not yz and not quantum:
144
+ disp_mode_list = ["basic", "raw"]
145
+
142
146
  parser.add_argument(
143
147
  "--display-mode",
144
148
  type=str,
145
149
  required=False,
146
- choices=["basic", "pretty", "latex"],
150
+ choices=disp_mode_list,
147
151
  default="basic",
148
152
  dest="disp_mode",
149
153
  help="Method of displaying the output. Default basic",
150
154
  )
151
155
 
152
- args = parser.parse_args()
156
+ parser.add_argument(
157
+ "-g",
158
+ action="store_true",
159
+ dest="gen",
160
+ help=SUPPRESS,
161
+ )
162
+
163
+ args = parser.parse_args(argv)
153
164
  args.mulstring = ""
154
165
 
155
166
  if args.mult is not None:
156
167
  args.mulstring = " ".join(args.mult)
157
168
  args.mult = True
169
+ else:
170
+ args.mult = False
158
171
 
159
172
  for perm in args.perms:
160
173
  try:
@@ -163,12 +176,28 @@ def schub_argparse(prog_name, description, quantum=False, yz=False):
163
176
  except Exception as e:
164
177
  print("Permutations must have integer values")
165
178
  raise e
179
+
180
+ if args.gen:
181
+ import json
182
+ import sys
183
+
184
+ argv.pop(argv.index("-g"))
185
+ args.__dict__["cmd_line"] = ["script"] + argv
186
+ del args.__dict__["gen"]
187
+ json.dump(args.__dict__, sys.stdout, ensure_ascii=False, indent=4)
188
+ exit(0)
189
+
166
190
  import sympy
167
191
 
168
- formatter = lambda bob: str(bob) # noqa: E731
169
192
  if args.disp_mode == "latex":
170
- formatter = lambda bob: sympy.latex(sympy.sympify(bob)).replace("\\left", "").replace("\\right", "") # noqa: E731
193
+ formatter = ( # noqa: E731
194
+ lambda bob: sympy.latex(sympy.sympify(bob)).replace("\\left", "").replace("\\right", "")
195
+ ) # noqa: E731
171
196
  elif args.disp_mode == "pretty":
172
197
  formatter = lambda bob: sympy.pretty(sympy.sympify(bob)) # noqa: E731
198
+ elif args.disp_mode == "basic":
199
+ formatter = lambda bob: str(bob) # noqa: E731
200
+ elif args.disp_mode == "raw":
201
+ formatter = None
173
202
 
174
203
  return args, formatter
schubmult/_tests.py ADDED
@@ -0,0 +1,9 @@
1
+ def get_json(file: str):
2
+ import os
3
+ import json
4
+
5
+ script_dir = os.path.dirname(__file__)
6
+ rel_path = f"../tests/{file}.json"
7
+ abs_file_path = os.path.join(script_dir, rel_path)
8
+ with open(abs_file_path, "r") as f:
9
+ return json.load(f)
@@ -1,5 +1,6 @@
1
1
  from sage.all import * # noqa: F403
2
2
 
3
+
3
4
  from ._fast_schubert_polynomial_ring import (
4
5
  FastSchubertPolynomialRing,
5
6
  FastSchubertPolynomial,
@@ -13,17 +13,23 @@ from sage.combinat.composition import (
13
13
  Compositions,
14
14
  Composition,
15
15
  )
16
- from . import (
17
- FastSchubertPolynomialRing_base,
18
- FastSchubertPolynomial,
19
- )
20
- from ._indexing import _coerce_index
21
16
 
17
+ # from . import (
18
+ # FastSchubertPolynomialRing_base,
19
+ # FastSchubertPolynomialRing,
20
+ # FastSchubertPolynomial,
21
+ # )
22
+ import schubmult.sage_integration._fast_schubert_polynomial_ring as bork
23
+ from ._indexing import _coerce_index
22
24
 
25
+ from functools import cache
23
26
  import schubmult.schubmult_q_double as qyz
24
27
  import schubmult.schubmult_double as yz
25
28
  from sympy import sympify
26
29
  import symengine as syme
30
+ from schubmult.perm_lib import permtrim
31
+
32
+ from sage.misc.parser import Parser
27
33
 
28
34
 
29
35
  def FastDoubleSchubertPolynomialRing(
@@ -191,9 +197,51 @@ class FastDoubleSchubertPolynomial_class(CombinatorialFreeModule.Element):
191
197
  return self.map_coefficients(lambda foi: RR(foi.subs(subs_dict)))
192
198
 
193
199
 
200
+ @cache
201
+ def _double_schub_parser(passed):
202
+ fdict = {}
203
+ vardict = {}
204
+ fdict[passed._sc_rep] = passed._element_constructor_
205
+ if passed._quantum:
206
+ QSRing = bork.FastSchubertPolynomialRing(
207
+ passed._base_polynomial_ring.base_ring(),
208
+ len(passed._base_polynomial_ring.gens()),
209
+ passed._base_varname,
210
+ is_quantum=True,
211
+ code_display=passed._ascode,
212
+ q_varname=passed._q_varname,
213
+ )
214
+ fdict[QSRing._sc_rep] = QSRing._element_constructor_
215
+ 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
+ )
222
+ 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
+ )
228
+ fdict[DRing._sc_rep] = DRing._element_constructor_
229
+ fdict[SRing._sc_rep] = SRing._element_constructor_
230
+ for g in passed._base_polynomial_ring.gens():
231
+ vardict[str(g)] = g
232
+ return Parser(make_function=fdict, make_var=vardict)
233
+
234
+
194
235
  class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
195
236
  Element = FastDoubleSchubertPolynomial_class
196
237
 
238
+ #def inject_variables:
239
+
240
+ def parser(self):
241
+ if self._parser is None:
242
+ self._parser = _double_schub_parser(self)
243
+ return self._parser
244
+
197
245
  def __init__(
198
246
  self,
199
247
  R,
@@ -255,14 +303,17 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
255
303
  else GradedBialgebrasWithBasis(self._coeff_polynomial_ring).Commutative()
256
304
  )
257
305
 
306
+ self._sc_rep = f"{'Q' if quantum else ''}DS{base_variable_name}"
307
+
258
308
  CombinatorialFreeModule.__init__(
259
309
  self,
260
310
  self._coeff_polynomial_ring,
261
311
  self._index_wrapper,
262
312
  category=cat,
263
- prefix=f"{'Q' if quantum else ''}S{base_variable_name}",
313
+ prefix=self._sc_rep,
264
314
  )
265
315
  self._populate_coercion_lists_()
316
+ self._parser = None
266
317
 
267
318
  @cached_method
268
319
  def one_basis(self):
@@ -281,7 +332,9 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
281
332
  elif len(x) > 2:
282
333
  raise ValueError("Bad index for element")
283
334
 
284
- if (
335
+ if isinstance(x, str):
336
+ return self.parser().parse(x)
337
+ elif (
285
338
  isinstance(x, list)
286
339
  or isinstance(x, tuple)
287
340
  or isinstance(x, Permutation)
@@ -315,7 +368,7 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
315
368
  )
316
369
  else:
317
370
  return self(x.expand())
318
- elif isinstance(x, FastSchubertPolynomial):
371
+ elif isinstance(x, bork.FastSchubertPolynomial):
319
372
  if (
320
373
  x.base_varname == self._base_varname
321
374
  and x.q_varname == self._q_varname
@@ -447,10 +500,12 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
447
500
  def _coerce_map_from_(self, S):
448
501
  if isinstance(S, MPolynomialRing_base):
449
502
  return True
450
- if isinstance(S, FastSchubertPolynomialRing_base):
503
+ if isinstance(S, bork.FastSchubertPolynomialRing_base):
451
504
  return True
452
505
  if isinstance(S, FastDoubleSchubertPolynomialRing_base):
453
506
  return True
507
+ if isinstance(S, str):
508
+ return True
454
509
  return super().has_coerce_map_from(S)
455
510
 
456
511
  def coproduct_on_basis(self, indm):
@@ -502,8 +557,10 @@ class FastDoubleSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
502
557
  break
503
558
  if not flag:
504
559
  continue
505
- firstperm = Permutation(list(downperm[0:N]))
506
- secondperm = Permutation([downperm[i] - N for i in range(N, len(downperm))])
560
+ firstperm = Permutation(permtrim(list(downperm[0:N])))
561
+ secondperm = Permutation(
562
+ permtrim([downperm[i] - N for i in range(N, len(downperm))])
563
+ )
507
564
  val = TR(val).subs(subs_dict_coprod)
508
565
  total_sum += self._coeff_polynomial_ring(val) * self(
509
566
  (_coerce_index(firstperm, False, self._ascode), indm[1])
@@ -14,7 +14,7 @@ from sage.rings.polynomial.multi_polynomial import MPolynomial
14
14
  from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
15
15
  from ._indexing import _coerce_index
16
16
 
17
-
17
+ from schubmult.perm_lib import permtrim
18
18
  import schubmult.schubmult_q as sq
19
19
  import schubmult.schubmult_q_double as qyz
20
20
  import schubmult.schubmult_py as py
@@ -22,7 +22,12 @@ import schubmult.schubmult_double as yz
22
22
 
23
23
 
24
24
  from sympy import sympify
25
+
26
+ # from sage.misc.parser import Parser
25
27
  import symengine as syme
28
+ import schubmult.sage_integration._fast_double_schubert_polynomial_ring as bork
29
+ from functools import cache
30
+ # FastQuantumDoubleSchubertPolynomialRing = bork.FastQuantumDoubleSchubertPolynomialRing
26
31
 
27
32
 
28
33
  def FastSchubertPolynomialRing(
@@ -161,8 +166,31 @@ class FastSchubertPolynomial_class(CombinatorialFreeModule.Element):
161
166
  )
162
167
 
163
168
 
169
+ @cache
170
+ def _single_schub_parser(passed):
171
+ if passed._quantum:
172
+ q_varname = passed._q_varname
173
+ else:
174
+ q_varname = "q"
175
+ QDRing = bork.FastQuantumDoubleSchubertPolynomialRing(
176
+ passed.base_ring(),
177
+ len(passed._polynomial_ring.gens()),
178
+ passed._base_varname,
179
+ coeff_variable_names="y",
180
+ code_display=passed._ascode,
181
+ q_varname=q_varname,
182
+ )
183
+ return QDRing.parser()
184
+
185
+
164
186
  class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
165
187
  Element = FastSchubertPolynomial_class
188
+
189
+ def parser(self):
190
+ if self._parser is None:
191
+ self._parser = _single_schub_parser(self)
192
+ return self._parser
193
+
166
194
 
167
195
  def __init__(
168
196
  self,
@@ -193,12 +221,15 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
193
221
  index_set = Compositions()
194
222
  self._ascode = True
195
223
 
224
+ self._sc_rep = f"{'Q' if quantum else ''}S{base_variable_name}"
225
+
196
226
  CombinatorialFreeModule.__init__(
197
227
  self,
198
228
  R if not quantum else QR,
199
229
  index_set,
200
230
  category=cat,
201
- prefix=f"QS{base_variable_name}",
231
+ prefix=self._sc_rep,
232
+ bracket="(",
202
233
  )
203
234
  self._q_ring = QR
204
235
  self._base_varname = base_variable_name
@@ -209,6 +240,7 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
209
240
  else PolynomialRing(QR, num_vars, base_variable_name)
210
241
  )
211
242
  self._populate_coercion_lists_()
243
+ self._parser = None
212
244
 
213
245
  def _coerce_map_from_(self, S):
214
246
  if isinstance(S, MPolynomialRing_base):
@@ -217,6 +249,8 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
217
249
  return True
218
250
  if isinstance(S, FastSchubertPolynomialRing_base):
219
251
  return True
252
+ if isinstance(S, str):
253
+ return True
220
254
  return super()._coerce_map_from_(S)
221
255
 
222
256
  @cached_method
@@ -227,7 +261,9 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
227
261
  self._splitter = indices
228
262
 
229
263
  def _element_constructor_(self, x):
230
- if (
264
+ if isinstance(x, str):
265
+ return self.parser().parse(x)
266
+ elif (
231
267
  isinstance(x, list)
232
268
  or isinstance(x, tuple)
233
269
  or isinstance(x, Composition)
@@ -344,8 +380,10 @@ class FastSchubertPolynomialRing_xbasis(CombinatorialFreeModule):
344
380
  break
345
381
  if not flag:
346
382
  continue
347
- firstperm = Permutation(list(downperm[0:N]))
348
- secondperm = Permutation([downperm[i] - N for i in range(N, len(downperm))])
383
+ firstperm = Permutation(permtrim(list(downperm[0:N])))
384
+ secondperm = Permutation(
385
+ permtrim([downperm[i] - N for i in range(N, len(downperm))])
386
+ )
349
387
  total_sum += self.base_ring()(val) * self(
350
388
  _coerce_index(firstperm, False, self._ascode)
351
389
  ).tensor(self(_coerce_index(secondperm, False, self._ascode)))
@@ -11,9 +11,16 @@ def _coerce_index(indexed_obj, is_comp, should_be_comp):
11
11
  if is_comp:
12
12
  return Composition(trimcode(permtrim(uncode(list(indexed_obj)))))
13
13
  else:
14
- return Permutation(permtrim(list(indexed_obj)))
14
+ return Permutation(permtrim(list(indexed_obj))).remove_extra_fixed_points()
15
15
  else:
16
- return indexed_obj
16
+ if not is_comp:
17
+ if isinstance(indexed_obj, Permutation):
18
+ return indexed_obj.remove_extra_fixed_points()
19
+ elif isinstance(indexed_obj, dict):
20
+ {
21
+ Permutation(permtrim(list(k))).remove_extra_fixed_points(): v
22
+ for k, v in indexed_obj.items()
23
+ }
17
24
  else:
18
25
  if is_comp:
19
26
  if (
@@ -21,11 +28,11 @@ def _coerce_index(indexed_obj, is_comp, should_be_comp):
21
28
  or isinstance(indexed_obj, tuple)
22
29
  or isinstance(indexed_obj, Composition)
23
30
  ):
24
- return Permutation(permtrim(uncode(list(indexed_obj))))
31
+ return Permutation(permtrim(uncode(list(indexed_obj)))).remove_extra_fixed_points()
25
32
 
26
33
  if isinstance(indexed_obj, dict): # keys are comps
27
34
  return {
28
- Permutation(permtrim(uncode(list(k)))): v
35
+ Permutation(permtrim(uncode(list(k)))).remove_extra_fixed_points(): v
29
36
  for k, v in indexed_obj.items()
30
37
  }
31
38
  else:
@@ -4,15 +4,19 @@ from ._funcs import (
4
4
  single_variable,
5
5
  mult_poly,
6
6
  posify,
7
- div_diff
7
+ div_diff,
8
+ schub_coprod
8
9
  )
9
10
 
10
11
 
12
+
11
13
  __all__ = [
12
14
  "compute_positive_rep",
13
15
  "schubmult",
14
16
  "single_variable",
15
17
  "mult_poly",
16
18
  "posify",
17
- "div_diff"
19
+ "div_diff",
20
+ "schub_coprod",
21
+ "main"
18
22
  ]
@@ -2,4 +2,4 @@ import sys
2
2
  from ._script import main
3
3
 
4
4
  if __name__ == "__main__":
5
- sys.exit(main())
5
+ sys.exit(main(sys.argv))