From 0cc3eaf874ff53e07c7f9d24e221a23796ea3ec5 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 1 Feb 2024 21:31:02 +0100 Subject: [PATCH 01/10] provide a construction functor --- src/sage/combinat/sf/elementary.py | 1 + src/sage/combinat/sf/homogeneous.py | 1 + src/sage/combinat/sf/macdonald.py | 5 ++ src/sage/combinat/sf/monomial.py | 1 + src/sage/combinat/sf/powersum.py | 1 + src/sage/combinat/sf/schur.py | 1 + src/sage/combinat/sf/sf.py | 1 - src/sage/combinat/sf/sfa.py | 78 ++++++++++++++++++++++++++++- 8 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/sf/elementary.py b/src/sage/combinat/sf/elementary.py index f0942314323..878cfe4f73f 100644 --- a/src/sage/combinat/sf/elementary.py +++ b/src/sage/combinat/sf/elementary.py @@ -50,6 +50,7 @@ def __init__(self, Sym): sage: TestSuite(e).run(skip=['_test_associativity', '_test_distributivity', '_test_prod']) sage: TestSuite(e).run(elements = [e[1,1]+e[2], e[1]+2*e[1,1]]) """ + self._descriptor = (("elementary",),) classical.SymmetricFunctionAlgebra_classical.__init__(self, Sym, "elementary", 'e') def _dual_basis_default(self): diff --git a/src/sage/combinat/sf/homogeneous.py b/src/sage/combinat/sf/homogeneous.py index 29cf294ea80..d21dd197c58 100644 --- a/src/sage/combinat/sf/homogeneous.py +++ b/src/sage/combinat/sf/homogeneous.py @@ -52,6 +52,7 @@ def __init__(self, Sym): sage: TestSuite(h).run(skip=['_test_associativity', '_test_distributivity', '_test_prod']) sage: TestSuite(h).run(elements = [h[1,1]+h[2], h[1]+2*h[1,1]]) """ + self._descriptor = (("homogeneous",),) classical.SymmetricFunctionAlgebra_classical.__init__(self, Sym, "homogeneous", 'h') def _dual_basis_default(self): diff --git a/src/sage/combinat/sf/macdonald.py b/src/sage/combinat/sf/macdonald.py index 1358c5779df..a467ad29eef 100644 --- a/src/sage/combinat/sf/macdonald.py +++ b/src/sage/combinat/sf/macdonald.py @@ -1082,6 +1082,7 @@ def __init__(self, macdonald): sage: TestSuite(Q).run(elements = [Q.t*Q[1,1]+Q.q*Q[2], Q[1]+(Q.q+Q.t)*Q[1,1]]) # long time (depends on previous) """ MacdonaldPolynomials_generic.__init__(self, macdonald) + self._descriptor = (("macdonald", {"q": self.q, "t": self.t}), ("Q",)) self._J = macdonald.J() self._P = macdonald.P() @@ -1118,6 +1119,7 @@ def __init__(self, macdonald): self._self_to_s_cache = _j_to_s_cache self._s_to_self_cache = _s_to_j_cache MacdonaldPolynomials_generic.__init__(self, macdonald) + self._descriptor = (("macdonald", {"q": self.q, "t": self.t}), ("J",)) def _s_cache(self, n): r""" @@ -1218,6 +1220,7 @@ def __init__(self, macdonald): """ MacdonaldPolynomials_generic.__init__(self, macdonald) + self._descriptor = (("macdonald", {"q": self.q, "t": self.t}), ("H",)) self._m = self._sym.m() self._Lmunu = macdonald.Ht()._Lmunu if not self.t: @@ -1440,6 +1443,7 @@ def __init__(self, macdonald): """ MacdonaldPolynomials_generic.__init__(self, macdonald) + self._descriptor = (("macdonald", {"q": self.q, "t": self.t}), ("Ht",)) self._self_to_m_cache = _ht_to_m_cache self._m = self._sym.m() category = ModulesWithBasis(self.base_ring()) @@ -1735,6 +1739,7 @@ def __init__(self, macdonald): """ MacdonaldPolynomials_generic.__init__(self, macdonald) + self._descriptor = (("macdonald", {"q": self.q, "t": self.t}), ("S",)) self._s = macdonald._s self._self_to_s_cache = _S_to_s_cache self._s_to_self_cache = _s_to_S_cache diff --git a/src/sage/combinat/sf/monomial.py b/src/sage/combinat/sf/monomial.py index 583008830af..18d25b1af25 100644 --- a/src/sage/combinat/sf/monomial.py +++ b/src/sage/combinat/sf/monomial.py @@ -45,6 +45,7 @@ def __init__(self, Sym): sage: TestSuite(m).run(skip=['_test_associativity', '_test_distributivity', '_test_prod']) sage: TestSuite(m).run(elements = [m[1,1]+m[2], m[1]+2*m[1,1]]) """ + self._descriptor = (("monomial",),) classical.SymmetricFunctionAlgebra_classical.__init__(self, Sym, "monomial", 'm') def _dual_basis_default(self): diff --git a/src/sage/combinat/sf/powersum.py b/src/sage/combinat/sf/powersum.py index 8d7f744e75f..ea7ca6bcc1f 100644 --- a/src/sage/combinat/sf/powersum.py +++ b/src/sage/combinat/sf/powersum.py @@ -44,6 +44,7 @@ def __init__(self, Sym): sage: TestSuite(p).run(skip=['_test_associativity', '_test_distributivity', '_test_prod']) sage: TestSuite(p).run(elements = [p[1,1]+p[2], p[1]+2*p[1,1]]) """ + self._descriptor = (("powersum",),) classical.SymmetricFunctionAlgebra_classical.__init__(self, Sym, "powersum", 'p') def coproduct_on_generators(self, i): diff --git a/src/sage/combinat/sf/schur.py b/src/sage/combinat/sf/schur.py index 40e1de75812..672bac86c91 100644 --- a/src/sage/combinat/sf/schur.py +++ b/src/sage/combinat/sf/schur.py @@ -48,6 +48,7 @@ def __init__(self, Sym): sage: TestSuite(s).run(skip=['_test_associativity', '_test_distributivity', '_test_prod']) sage: TestSuite(s).run(elements = [s[1,1]+s[2], s[1]+2*s[1,1]]) """ + self._descriptor = (("schur",),) classical.SymmetricFunctionAlgebra_classical.__init__(self, Sym, "Schur", 's') def _dual_basis_default(self): diff --git a/src/sage/combinat/sf/sf.py b/src/sage/combinat/sf/sf.py index ad86bfd6c7f..5dc923f8df2 100644 --- a/src/sage/combinat/sf/sf.py +++ b/src/sage/combinat/sf/sf.py @@ -845,7 +845,6 @@ class function on the symmetric group where the elements - Devise a mechanism so that pickling bases of symmetric functions pickles the coercions which have a cache. """ - def __init__(self, R): r""" Initialization of ``self``. diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 2b42ebb7be6..5d985031f7e 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -1786,7 +1786,6 @@ class SymmetricFunctionAlgebra_generic(CombinatorialFreeModule): sage: s(m([2,1])) -2*s[1, 1, 1] + s[2, 1] """ - def __init__(self, Sym, basis_name=None, prefix=None, graded=True): r""" Initializes the symmetric function algebra. @@ -3013,6 +3012,21 @@ def coproduct_by_coercion(self, elt): return self.tensor_square().sum(coeff * tensor([self(s[x]), self(s[y])]) for ((x,y), coeff) in s(elt).coproduct()) + def construction(self): + """ + Return a pair ``(F, R)``, where ``F`` is a + :class:`SymmetricFunctionsFunctor` and `R` is a ring, such + that ``F(R)`` returns ``self``. + + EXAMPLES:: + + sage: s = SymmetricFunctions(ZZ).s() + sage: F, R = s.construction() + sage: F(QQ) + Symmetric Functions over Rational Field in the Schur basis + """ + return SymmetricFunctionsFunctor(self._descriptor), self.base_ring() + class SymmetricFunctionAlgebra_generic_Element(CombinatorialFreeModule.Element): r""" @@ -3033,7 +3047,6 @@ class SymmetricFunctionAlgebra_generic_Element(CombinatorialFreeModule.Element): m[1, 1, 1] + m[2, 1] + m[3] sage: m.set_print_style('lex') """ - def factor(self): """ Return the factorization of this symmetric function. @@ -6375,6 +6388,67 @@ def exponential_specialization(self, t=None, q=1): SymmetricFunctionAlgebra_generic.Element = SymmetricFunctionAlgebra_generic_Element +from sage.categories.pushout import ConstructionFunctor +from sage.categories.commutative_rings import CommutativeRings +from sage.categories.functor import Functor + +class SymmetricFunctionsFunctor(ConstructionFunctor): + rank = 9 + + def __init__(self, descriptor): + self._descriptor = descriptor + Functor.__init__(self, CommutativeRings(), CommutativeRings()) + + def _apply_functor(self, R): + """ + Apply the functor to an object of ``self``'s domain. + + EXAMPLES:: + + sage: s = SymmetricFunctions(ZZ).s() + sage: F, R = s.construction() + sage: F(QQ) + Symmetric Functions over Rational Field in the Schur basis + """ + from sage.combinat.sf.sf import SymmetricFunctions + S = SymmetricFunctions(R) + for method, *params in self._descriptor: + if params: + assert len(params) == 1 + S = S.__getattribute__(method)(**params[0]) + else: + S = S.__getattribute__(method)() + return S + + def _apply_functor_to_morphism(self, f): + """ + Apply the functor ``self`` to the ring morphism `f`. + + """ + dom = self(f.domain()) + codom = self(f.codomain()) + + def action(x): + return codom._from_dict({a: f(b) + for a, b in x.monomial_coefficients().items()}) + return dom.module_morphism(function=action, codomain=codom) + + def __eq__(self, other): + if not isinstance(other, SymmetricFunctionsFunctor): + return False + return self.vars == other.vars + + def _repr_(self): + """ + TESTS:: + + sage: R. = ZZ[] + sage: H = SymmetricFunctions(R).macdonald().H() + sage: F, R = H.construction() + sage: F + (('macdonald', {'q': q, 't': t}), ('H',)) + """ + return repr(self._descriptor) ################### def _lmax(x): From 693c051110c5783433217ad45beed457bb1fdf86 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 6 Feb 2024 11:04:26 +0100 Subject: [PATCH 02/10] more constructions --- src/sage/combinat/sf/character.py | 2 ++ src/sage/combinat/sf/hall_littlewood.py | 10 +++++++++- src/sage/combinat/sf/hecke.py | 8 ++++++-- src/sage/combinat/sf/jack.py | 12 ++++++++++-- src/sage/combinat/sf/macdonald.py | 11 ++++++++--- src/sage/combinat/sf/orthogonal.py | 2 +- src/sage/combinat/sf/symplectic.py | 1 + src/sage/combinat/sf/witt.py | 1 + 8 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/sage/combinat/sf/character.py b/src/sage/combinat/sf/character.py index 3bd8ab5e0a1..827e7ad33ae 100644 --- a/src/sage/combinat/sf/character.py +++ b/src/sage/combinat/sf/character.py @@ -224,6 +224,7 @@ def __init__(self, Sym, pfix): SFA_generic.__init__(self, Sym, basis_name="induced trivial symmetric group character", prefix=pfix, graded=False) + self._descriptor = (("ht",),) self._other = Sym.complete() self._p = Sym.powersum() @@ -451,6 +452,7 @@ def __init__(self, Sym, pfix): SFA_generic.__init__(self, Sym, basis_name="irreducible symmetric group character", prefix=pfix, graded=False) + self._descriptor = (("st",),) self._other = Sym.Schur() self._p = Sym.powersum() diff --git a/src/sage/combinat/sf/hall_littlewood.py b/src/sage/combinat/sf/hall_littlewood.py index c3376537a35..cf19404b4eb 100644 --- a/src/sage/combinat/sf/hall_littlewood.py +++ b/src/sage/combinat/sf/hall_littlewood.py @@ -77,7 +77,11 @@ def __repr__(self): """ return self._name + " over %s" % self._sym.base_ring() - def __init__(self, Sym, t='t'): + @staticmethod + def __classcall__(cls, Sym, t='t'): + return super().__classcall__(cls, Sym, Sym.base_ring()(t)) + + def __init__(self, Sym, t): """ Initialize ``self``. @@ -708,6 +712,7 @@ def __init__(self, hall_littlewood): sage: TestSuite(P).run(elements = [P.t*P[1,1]+P[2], P[1]+(1+P.t)*P[1,1]]) """ HallLittlewood_generic.__init__(self, hall_littlewood) + self._descriptor = (("hall_littlewood", {"t": self.t}), ("P",)) self._self_to_s_cache = p_to_s_cache self._s_to_self_cache = s_to_p_cache @@ -846,6 +851,7 @@ def __init__(self, hall_littlewood): (1/(t^2-1))*HLQ[1, 1] - (1/(t-1))*HLQ[2] """ HallLittlewood_generic.__init__(self, hall_littlewood) + self._descriptor = (("hall_littlewood", {"t": self.t}), ("Q",)) self._P = self._hall_littlewood.P() # temporary until Hom(GradedHopfAlgebrasWithBasis work better) @@ -942,6 +948,8 @@ def __init__(self, hall_littlewood): [ 0 0 1] """ HallLittlewood_generic.__init__(self, hall_littlewood) + self._descriptor = (("hall_littlewood", {"t": self.t}), ("Qp",)) + self._self_to_s_cache = qp_to_s_cache self._s_to_self_cache = s_to_qp_cache diff --git a/src/sage/combinat/sf/hecke.py b/src/sage/combinat/sf/hecke.py index 5cea11ccb2c..f2071d5f4b6 100644 --- a/src/sage/combinat/sf/hecke.py +++ b/src/sage/combinat/sf/hecke.py @@ -121,8 +121,11 @@ class HeckeCharacter(SymmetricFunctionAlgebra_multiplicative): - [Ram1991]_ - [RR1997]_ """ + @staticmethod + def __classcall__(cls, Sym, q='q'): + return super().__classcall__(cls, Sym, Sym.base_ring()(q)) - def __init__(self, sym, q='q'): + def __init__(self, sym, q): r""" Initialize ``self``. @@ -156,10 +159,11 @@ def __init__(self, sym, q='q'): ....: for mu in Partitions(n)) True """ - self.q = sym.base_ring()(q) + self.q = q SymmetricFunctionAlgebra_multiplicative.__init__(self, sym, basis_name="Hecke character with q={}".format(self.q), prefix="qbar") + self._descriptor = (("qbar", {"q": self.q}),) self._p = sym.power() # temporary until Hom(GradedHopfAlgebrasWithBasis work better) diff --git a/src/sage/combinat/sf/jack.py b/src/sage/combinat/sf/jack.py index a7a0fec6186..601f6468337 100644 --- a/src/sage/combinat/sf/jack.py +++ b/src/sage/combinat/sf/jack.py @@ -50,8 +50,11 @@ class Jack(UniqueRepresentation): + @staticmethod + def __classcall__(cls, Sym, t='t'): + return super().__classcall__(cls, Sym, Sym.base_ring()(t)) - def __init__(self, Sym, t='t'): + def __init__(self, Sym, t): r""" The family of Jack symmetric functions including the `P`, `Q`, `J`, `Qp` bases. The default parameter is ``t``. @@ -70,7 +73,7 @@ def __init__(self, Sym, t='t'): Jack polynomials with t=1 over Rational Field """ self._sym = Sym - self.t = Sym.base_ring()(t) + self.t = t self._name_suffix = "" if str(t) != 't': self._name_suffix += " with t=%s" % t @@ -874,6 +877,7 @@ def __init__(self, jack): self._m_to_self_cache = m_to_p_cache self._self_to_m_cache = p_to_m_cache JackPolynomials_generic.__init__(self, jack) + self._descriptor = (("jack", {"t": self.t}), ("P",)) def _m_cache(self, n): r""" @@ -1076,6 +1080,7 @@ def __init__(self, jack): self._name = "Jack polynomials in the J basis" self._prefix = "JackJ" JackPolynomials_generic.__init__(self, jack) + self._descriptor = (("jack", {"t": self.t}), ("J",)) # Should be shared with _q (and possibly other bases in Macdo/HL) as BasesByRenormalization self._P = self._jack.P() @@ -1112,6 +1117,7 @@ def __init__(self, jack): self._name = "Jack polynomials in the Q basis" self._prefix = "JackQ" JackPolynomials_generic.__init__(self, jack) + self._descriptor = (("jack", {"t": self.t}), ("Q",)) # Should be shared with _j (and possibly other bases in Macdo/HL) as BasesByRenormalization self._P = self._jack.P() @@ -1150,6 +1156,7 @@ def __init__(self, jack): self._name = "Jack polynomials in the Qp basis" self._prefix = "JackQp" JackPolynomials_generic.__init__(self, jack) + self._descriptor = (("jack", {"t": self.t}), ("Qp",)) self._P = self._jack.P() self._self_to_h_cache = qp_to_h_cache self._h_to_self_cache = h_to_qp_cache @@ -1354,6 +1361,7 @@ def __init__(self, Sym): #self._self_to_m_cache = {} and we don't need to compute it separately for zonals sfa.SymmetricFunctionAlgebra_generic.__init__(self, self._sym, prefix="Z", basis_name="zonal") + self._descriptor = (("zonal",),) category = sage.categories.all.ModulesWithBasis(self._sym.base_ring()) self .register_coercion(SetMorphism(Hom(self._P, self, category), self.sum_of_terms)) self._P.register_coercion(SetMorphism(Hom(self, self._P, category), self._P.sum_of_terms)) diff --git a/src/sage/combinat/sf/macdonald.py b/src/sage/combinat/sf/macdonald.py index a467ad29eef..03ec0bcc5a2 100644 --- a/src/sage/combinat/sf/macdonald.py +++ b/src/sage/combinat/sf/macdonald.py @@ -97,7 +97,11 @@ def __repr__(self): """ return self._name - def __init__(self, Sym, q='q', t='t'): + @staticmethod + def __classcall__(cls, Sym, q='q', t='t'): + return super().__classcall__(cls, Sym, Sym.base_ring()(q), Sym.base_ring()(t)) + + def __init__(self, Sym, q, t): r""" Macdonald Symmetric functions including `P`, `Q`, `J`, `H`, `Ht` bases also including the S basis which is the plethystic transformation @@ -119,8 +123,8 @@ def __init__(self, Sym, q='q', t='t'): """ self._sym = Sym self._s = Sym.s() - self.q = Sym.base_ring()(q) - self.t = Sym.base_ring()(t) + self.q = q + self.t = t self._name_suffix = "" if str(q) != 'q': self._name_suffix += " with q=%s" % q @@ -1012,6 +1016,7 @@ def __init__(self, macdonald): sage: TestSuite(P).run(elements = [P.t*P[1,1]+P.q*P[2], P[1]+(P.q+P.t)*P[1,1]]) # long time (depends on previous) """ MacdonaldPolynomials_generic.__init__(self, macdonald) + self._descriptor = (("macdonald", {"q": self.q, "t": self.t}), ("P",)) self._J = macdonald.J() # temporary until Hom(GradedHopfAlgebrasWithBasis work better) diff --git a/src/sage/combinat/sf/orthogonal.py b/src/sage/combinat/sf/orthogonal.py index 3ab5f56debc..b6c3576a557 100644 --- a/src/sage/combinat/sf/orthogonal.py +++ b/src/sage/combinat/sf/orthogonal.py @@ -170,7 +170,7 @@ def __init__(self, Sym): """ sfa.SymmetricFunctionAlgebra_generic.__init__(self, Sym, "orthogonal", 'o', graded=False) - + self._descriptor = (("o",),) # We make a strong reference since we use it for our computations # and so we can define the coercion below (only codomains have # strong references) diff --git a/src/sage/combinat/sf/symplectic.py b/src/sage/combinat/sf/symplectic.py index f6db1782489..a6eebc438af 100644 --- a/src/sage/combinat/sf/symplectic.py +++ b/src/sage/combinat/sf/symplectic.py @@ -178,6 +178,7 @@ def __init__(self, Sym): """ sfa.SymmetricFunctionAlgebra_generic.__init__(self, Sym, "symplectic", 'sp', graded=False) + self._descriptor = (("sp",),) # We make a strong reference since we use it for our computations # and so we can define the coercion below (only codomains have diff --git a/src/sage/combinat/sf/witt.py b/src/sage/combinat/sf/witt.py index 138b2647826..1f5ed292bd0 100644 --- a/src/sage/combinat/sf/witt.py +++ b/src/sage/combinat/sf/witt.py @@ -407,6 +407,7 @@ def __init__(self, Sym, coerce_h=True, coerce_e=False, coerce_p=False): sage: TestSuite(w).run(skip=['_test_associativity', '_test_distributivity', '_test_prod']) sage: TestSuite(w).run(elements = [w[1,1]+w[2], w[1]+2*w[1,1]]) """ + self._descriptor = (("w",),) self._coerce_h = coerce_h self._coerce_e = coerce_e self._coerce_p = coerce_p From 7d7ccebe07f2b81049b619f3e4b493f45195cca5 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 6 Feb 2024 14:08:21 +0100 Subject: [PATCH 03/10] fix oversight in factorization of symmetric function: unit should be in the base ring --- src/sage/combinat/sf/sfa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 8a73014fe6b..0fd2d890b88 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -3103,7 +3103,7 @@ def factor(self): poly = _to_polynomials([self], self.base_ring())[0] factors = poly.factor() - unit = factors.unit() + unit = self.base_ring()(factors.unit()) if factors.universe() == self.base_ring(): return Factorization(factors, unit=unit) factors = [(_from_polynomial(factor, M), exponent) From 7bd1c5b32534a5ae4a520bc1a5c99dcf05a0d3cf Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 6 Feb 2024 14:31:39 +0100 Subject: [PATCH 04/10] skip construction for dual and orthotriang --- src/sage/combinat/sf/dual.py | 5 ++++- src/sage/combinat/sf/orthotriang.py | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/sf/dual.py b/src/sage/combinat/sf/dual.py index 6a68eb7dfe6..58b69743c7b 100644 --- a/src/sage/combinat/sf/dual.py +++ b/src/sage/combinat/sf/dual.py @@ -74,7 +74,7 @@ def __init__(self, dual_basis, scalar, scalar_name="", basis_name=None, prefix=N sage: e = SymmetricFunctions(QQ).e() sage: f = e.dual_basis(prefix = "m", basis_name="Forgotten symmetric functions"); f Symmetric Functions over Rational Field in the Forgotten symmetric functions basis - sage: TestSuite(f).run(elements = [f[1,1]+2*f[2], f[1]+3*f[1,1]]) + sage: TestSuite(f).run(skip='_test_construction', elements = [f[1,1]+2*f[2], f[1]+3*f[1,1]]) sage: TestSuite(f).run() # long time (11s on sage.math, 2011) This class defines canonical coercions between ``self`` and @@ -157,6 +157,9 @@ def __init__(self, dual_basis, scalar, scalar_name="", basis_name=None, prefix=N self.register_coercion(SetMorphism(Hom(self._dual_basis, self, category), self._dual_to_self)) self._dual_basis.register_coercion(SetMorphism(Hom(self, self._dual_basis, category), self._self_to_dual)) + def construction(self): + raise NotImplementedError + def _dual_to_self(self, x): """ Coerce an element of the dual of ``self`` canonically into ``self``. diff --git a/src/sage/combinat/sf/orthotriang.py b/src/sage/combinat/sf/orthotriang.py index 2e1650e57a7..5f2f01b7f6c 100644 --- a/src/sage/combinat/sf/orthotriang.py +++ b/src/sage/combinat/sf/orthotriang.py @@ -84,8 +84,8 @@ def __init__(self, Sym, base, scalar, prefix, basis_name, leading_coeff=None): TESTS:: - sage: TestSuite(s).run(elements = [s[1,1]+2*s[2], s[1]+3*s[1,1]]) - sage: TestSuite(s).run(skip = ["_test_associativity", "_test_prod"]) # long time (7s on sage.math, 2011) + sage: TestSuite(s).run(skip='_test_construction', elements = [s[1,1]+2*s[2], s[1]+3*s[1,1]]) + sage: TestSuite(s).run(skip = ["_test_associativity", "_test_prod", '_test_construction']) # long time (7s on sage.math, 2011) Note: ``s.an_element()`` is of degree 4; so we skip ``_test_associativity`` and ``_test_prod`` which involve @@ -102,6 +102,9 @@ def __init__(self, Sym, base, scalar, prefix, basis_name, leading_coeff=None): self.register_coercion(SetMorphism(Hom(base, self), self._base_to_self)) base.register_coercion(SetMorphism(Hom(self, base), self._self_to_base)) + def construction(self): + raise NotImplementedError + def _base_to_self(self, x): """ Coerce a symmetric function in base ``x`` into ``self``. From 71c12598d9bfda998499150aaa92055551086a7e Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 9 Feb 2024 16:51:44 +0100 Subject: [PATCH 05/10] add change_ring, add doctests demonstrating that coercions with different base rings work now --- src/sage/combinat/sf/sfa.py | 40 ++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 0fd2d890b88..07daa75375a 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -170,21 +170,22 @@ BACKWARD INCOMPATIBLE CHANGES (:trac:`5457`): -The symmetric functions code has been refactored to take -advantage of the coercion systems. This introduced a couple of glitches: +The symmetric functions code has been refactored to take advantage of +the coercion systems. This introduced a couple of glitches, in +particular, on some bases changes, coefficients in Jack polynomials +are not normalized -- On some bases changes, coefficients in Jack polynomials are not normalized +However, conversions and coercions are now also defined between +symmetric functions over different coefficient rings:: -- Except in a few cases, conversions and coercions are only defined - between symmetric functions over the same coefficient ring. E.g. - the following does not work anymore:: + sage: S = SymmetricFunctions(QQ) + sage: S2 = SymmetricFunctions(QQ['t']) + sage: S3 = SymmetricFunctions(ZZ) + sage: S.m()[1] + S2.m()[2] + m[1] + m[2] - sage: s = SymmetricFunctions(QQ) - sage: s2 = SymmetricFunctions(QQ['t']) - sage: s([1]) + s2([2]) # todo: not implemented - - This feature will probably come back at some point through - improvements to the Sage coercion system. + sage: S.m()(S3.sp()[2,1]) + -m[1] + 2*m[1, 1, 1] + m[2, 1] Backward compatibility should be essentially retained. @@ -3028,6 +3029,21 @@ def construction(self): """ return SymmetricFunctionsFunctor(self._descriptor), self.base_ring() + def change_ring(self, R): + r""" + Return the base change of ``self`` to `R`. + + EXAMPLES:: + + sage: s = SymmetricFunctions(ZZ).s() + sage: s.change_ring(QQ) + Symmetric Functions over Rational Field in the Schur basis + """ + if R is self.base_ring(): + return self + functor, _ = self.construction() + return functor(R) + class SymmetricFunctionAlgebra_generic_Element(CombinatorialFreeModule.Element): r""" From 4c1d4557226a50cfff1dc5facfc44e32517dc798 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 9 Feb 2024 17:26:00 +0100 Subject: [PATCH 06/10] correct equality --- src/sage/combinat/sf/sfa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 07daa75375a..8db655bb658 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -6455,7 +6455,7 @@ def action(x): def __eq__(self, other): if not isinstance(other, SymmetricFunctionsFunctor): return False - return self.vars == other.vars + return self._descriptor == other._descriptor def _repr_(self): """ From 791c63b728e60048740936ad86a3bf3219a727fd Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 10 Feb 2024 22:59:33 +0100 Subject: [PATCH 07/10] beautify repr, add doctests, deprecate corresponding_basis_over --- src/sage/combinat/sf/sfa.py | 182 +++++++++++++++++++++++++++--------- 1 file changed, 136 insertions(+), 46 deletions(-) diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 8db655bb658..92e39be373f 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -625,6 +625,11 @@ def corresponding_basis_over(self, R): sage: Sym = SymmetricFunctions(QQ) sage: m = Sym.monomial() sage: m.corresponding_basis_over(ZZ) + doctest:warning + ... + DeprecationWarning: S.corresponding_basis_over(R) is deprecated. + Use S.change_ring(R) instead. + See https://github.com/sagemath/sage/issues/37220 for details. Symmetric Functions over Integer Ring in the monomial basis sage: Sym = SymmetricFunctions(CyclotomicField()) @@ -635,7 +640,8 @@ def corresponding_basis_over(self, R): sage: P = ZZ['q','t'] sage: Sym = SymmetricFunctions(P) sage: mj = Sym.macdonald().J() - sage: mj.corresponding_basis_over(Integers(13)) + sage: mj.corresponding_basis_over(Integers(13)['q','t']) + Symmetric Functions over Multivariate Polynomial Ring in q, t over Ring of integers modulo 13 in the Macdonald J basis TESTS: @@ -658,23 +664,40 @@ def corresponding_basis_over(self, R): Symmetric Functions over Universal Cyclotomic Field in the forgotten basis sage: Sym.w().corresponding_basis_over(CyclotomicField()) Symmetric Functions over Universal Cyclotomic Field in the Witt basis - sage: Sym.macdonald().P().corresponding_basis_over(CyclotomicField()) - sage: Sym.macdonald().Q().corresponding_basis_over(CyclotomicField()) - sage: Sym.macdonald().J().corresponding_basis_over(CyclotomicField()) - sage: Sym.macdonald().H().corresponding_basis_over(CyclotomicField()) - sage: Sym.macdonald().Ht().corresponding_basis_over(CyclotomicField()) - sage: Sym.macdonald().S().corresponding_basis_over(CyclotomicField()) - sage: Sym.macdonald(q=1).S().corresponding_basis_over(CyclotomicField()) + sage: Sym.macdonald().P().corresponding_basis_over(CyclotomicField()['q', 't']) + Symmetric Functions over Multivariate Polynomial Ring in q, t over Universal Cyclotomic Field in the Macdonald P basis + sage: Sym.macdonald().Q().corresponding_basis_over(CyclotomicField()['q', 't']) + Symmetric Functions over Multivariate Polynomial Ring in q, t over Universal Cyclotomic Field in the Macdonald Q basis + sage: Sym.macdonald().J().corresponding_basis_over(CyclotomicField()['q', 't']) + Symmetric Functions over Multivariate Polynomial Ring in q, t over Universal Cyclotomic Field in the Macdonald J basis + sage: Sym.macdonald().H().corresponding_basis_over(CyclotomicField()['q', 't']) + Symmetric Functions over Multivariate Polynomial Ring in q, t over Universal Cyclotomic Field in the Macdonald H basis + sage: Sym.macdonald().Ht().corresponding_basis_over(CyclotomicField()['q', 't']) + Symmetric Functions over Multivariate Polynomial Ring in q, t over Universal Cyclotomic Field in the Macdonald Ht basis + sage: Sym.macdonald().S().corresponding_basis_over(CyclotomicField()['q', 't']) + Symmetric Functions over Multivariate Polynomial Ring in q, t over Universal Cyclotomic Field in the Macdonald S basis + sage: Sym.macdonald(q=1).S().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the Macdonald S with q=1 basis sage: Sym.macdonald(q=1,t=3).P().corresponding_basis_over(CyclotomicField()) - sage: Sym.hall_littlewood().P().corresponding_basis_over(CyclotomicField()) - sage: Sym.hall_littlewood().Q().corresponding_basis_over(CyclotomicField()) - sage: Sym.hall_littlewood().Qp().corresponding_basis_over(CyclotomicField()) + Symmetric Functions over Universal Cyclotomic Field in the Macdonald P with q=1 and t=3 basis + sage: Sym.hall_littlewood().P().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the Hall-Littlewood P basis + sage: Sym.hall_littlewood().Q().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the Hall-Littlewood Q basis + sage: Sym.hall_littlewood().Qp().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the Hall-Littlewood Qp basis sage: Sym.hall_littlewood(t=1).P().corresponding_basis_over(CyclotomicField()) - sage: Sym.jack().J().corresponding_basis_over(CyclotomicField()) - sage: Sym.jack().P().corresponding_basis_over(CyclotomicField()) - sage: Sym.jack().Q().corresponding_basis_over(CyclotomicField()) - sage: Sym.jack().Qp().corresponding_basis_over(CyclotomicField()) + Symmetric Functions over Universal Cyclotomic Field in the Hall-Littlewood P with t=1 basis + sage: Sym.jack().J().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the Jack J basis + sage: Sym.jack().P().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the Jack P basis + sage: Sym.jack().Q().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the Jack Q basis + sage: Sym.jack().Qp().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the Jack Qp basis sage: Sym.jack(t=1).J().corresponding_basis_over(CyclotomicField()) + Symmetric Functions over Universal Cyclotomic Field in the Jack J with t=1 basis sage: Sym.zonal().corresponding_basis_over(CyclotomicField()) Symmetric Functions over Universal Cyclotomic Field in the zonal basis sage: Sym.llt(3).hspin().corresponding_basis_over(CyclotomicField()) @@ -688,26 +711,13 @@ def corresponding_basis_over(self, R): rewritten as soon as the bases of ``SymmetricFunctions`` are put on a more robust and systematic footing. """ - from sage.combinat.sf.sf import SymmetricFunctions - from sage.misc.call import attrcall + from sage.misc.superseded import deprecation + deprecation(37220, 'S.corresponding_basis_over(R) is deprecated.' + ' Use S.change_ring(R) instead.') try: - return attrcall(self._basis)(SymmetricFunctions(R)) - except AttributeError: # or except (AttributeError, ValueError): + return self.change_ring(R) + except NotImplementedError: return None - #Alternative code proposed by Florent Hivert, which sadly fails for the - #forgotten basis (which reduces differently than the other ones): - #try: - # parentred1 = self._reduction - # parentred2 = parentred1[1][0]._reduction - # parentred2prime = tuple([parentred2[0], tuple([R]), parentred2[2]]) - # from sage.structure.unique_representation import unreduce - # parent2 = unreduce(*parentred2prime) - # parentred1prime = tuple([parentred1[0], tuple([parent2]), parentred1[2]]) - # return unreduce(*parentred1prime) - #except (AttributeError, ValueError): - # return None - #This code relied heavily on the construction of bases of - #``SymmetricFunctions`` and on their reduction. def skew_schur(self, x): """ @@ -1034,8 +1044,9 @@ def component(i, g): # == h_g[L_i] # Now let's try to find out what basis self is in, and # construct the corresponding basis of symmetric functions # over QQ. - corresponding_parent_over_QQ = self.corresponding_basis_over(QQ) - if corresponding_parent_over_QQ is None: + try: + corresponding_parent_over_QQ = self.change_ring(QQ) + except (NotImplementedError, TypeError): # This is the case where the corresponding basis # over QQ cannot be found. This can have two reasons: # Either the basis depends on variables (like the @@ -1205,8 +1216,9 @@ def component(i, g): # == h_g[L_i] or e_g[L_i] # Now let's try to find out what basis self is in, and # construct the corresponding basis of symmetric functions # over QQ. - corresponding_parent_over_QQ = self.corresponding_basis_over(QQ) - if corresponding_parent_over_QQ is None: + try: + corresponding_parent_over_QQ = self.change_ring(QQ) + except (NotImplementedError, TypeError): # This is the case where the corresponding basis # over QQ cannot be found. This can have two reasons: # Either the basis depends on variables (like the @@ -4115,8 +4127,9 @@ def itensor(self, x): # Now let's try to find out what basis self is in, and # construct the corresponding basis of symmetric functions # over QQ. - corresponding_parent_over_QQ = parent.corresponding_basis_over(QQ) - if corresponding_parent_over_QQ is None: + try: + corresponding_parent_over_QQ = parent.change_ring(QQ) + except (NotImplementedError, TypeError): # This is the case where the corresponding basis # over QQ cannot be found. This can have two reasons: # Either the basis depends on variables (like the @@ -4314,7 +4327,7 @@ def reduced_kronecker_product(self, x): comp_x = comp_parent(x) # Now, comp_self and comp_x are the same as self and x, but in the # Schur basis, which we call comp_parent. - schur_Q = comp_parent.corresponding_basis_over(QQ) + schur_Q = comp_parent.change_ring(QQ) # schur_Q is the Schur basis of the symmetric functions over QQ. result = comp_parent.zero() for lam, a in comp_self: @@ -4756,8 +4769,9 @@ def f(lam, mu): return parent(p._apply_multi_module_morphism(p(self),p(x),f)) comp_parent = parent comp_self = self - corresponding_parent_over_QQ = parent.corresponding_basis_over(QQ) - if corresponding_parent_over_QQ is None: + try: + corresponding_parent_over_QQ = parent.change_ring(QQ) + except (NotImplementedError, TypeError): comp_parent = parent.realization_of().schur() comp_self = comp_parent(self) from sage.combinat.sf.sf import SymmetricFunctions @@ -6412,9 +6426,43 @@ def exponential_specialization(self, t=None, q=1): from sage.categories.functor import Functor class SymmetricFunctionsFunctor(ConstructionFunctor): + """ + A constructor for free Zinbiel algebras. + + EXAMPLES:: + + sage: s = SymmetricFunctions(QQ).s() + sage: s.construction() + (SymmetricFunctionsFunctor[schur], Rational Field) + """ rank = 9 def __init__(self, descriptor): + r""" + Initialise the functor. + + INPUT: + + - ``descriptor`` -- an iterable of pairs ``(family, params)`` + or singletons ``(basis,)``, where ``family`` and ``basis`` + are strings and ``params`` is a dictionary whose keys are + strings. + + .. WARNING: + + Strictly speaking, this is not necessarily a functor on + :class:`CommutativeRings`, but rather a functor on + commutative rings with some distinguished elements. For + example, for the Macdonald polynomials, we have to + specify `q` and `t` in the ring. + + EXAMPLES:: + + sage: from sage.combinat.sf.sfa import SymmetricFunctionsFunctor + sage: R. = ZZ[] + sage: SymmetricFunctionsFunctor((('macdonald', {'q': q, 't': t}), ('H',))) + SymmetricFunctionsFunctor[macdonald(q=q, t=t).H] + """ self._descriptor = descriptor Functor.__init__(self, CommutativeRings(), CommutativeRings()) @@ -6425,7 +6473,7 @@ def _apply_functor(self, R): EXAMPLES:: sage: s = SymmetricFunctions(ZZ).s() - sage: F, R = s.construction() + sage: F, R = s.construction() # indirect doctest sage: F(QQ) Symmetric Functions over Rational Field in the Schur basis """ @@ -6443,6 +6491,27 @@ def _apply_functor_to_morphism(self, f): """ Apply the functor ``self`` to the ring morphism `f`. + EXAMPLES:: + + sage: s = SymmetricFunctions(QQ).s() + sage: F, R = s.construction() + sage: F(ZZ.hom(GF(3))) # indirect doctest + Generic morphism: + From: Symmetric Functions over Integer Ring in the Schur basis + To: Symmetric Functions over Finite Field of size 3 in the Schur basis + + sage: R. = ZZ[] + sage: P = SymmetricFunctions(R).jack().P() + sage: F, R = P.construction() + sage: F(ZZ["t"].hom(GF(3)["t"])) + Generic morphism: + From: Symmetric Functions over Univariate Polynomial Ring in t over Integer Ring in the Jack P basis + To: Symmetric Functions over Univariate Polynomial Ring in t over Finite Field of size 3 in the Jack P basis + + sage: R. = ZZ[] + sage: H = SymmetricFunctions(R).macdonald().H() + sage: F, R = H.construction() + sage: F(ZZ["q", "t"].hom(GF(3)["q", "t"])) # known bug """ dom = self(f.domain()) codom = self(f.codomain()) @@ -6453,6 +6522,20 @@ def action(x): return dom.module_morphism(function=action, codomain=codom) def __eq__(self, other): + """ + EXAMPLES:: + + sage: R. = ZZ[] + sage: S. = QQ[] + sage: T. = QQ[] + sage: PR = SymmetricFunctions(R).jack().P() + sage: PS = SymmetricFunctions(S).jack().P() + sage: PT = SymmetricFunctions(T).jack(t=s).P() + sage: PR.construction()[0] == PS.construction()[0] + True + sage: PR.construction()[0] == PT.construction()[0] + False + """ if not isinstance(other, SymmetricFunctionsFunctor): return False return self._descriptor == other._descriptor @@ -6461,13 +6544,20 @@ def _repr_(self): """ TESTS:: - sage: R. = ZZ[] + sage: R. = ZZ[] sage: H = SymmetricFunctions(R).macdonald().H() sage: F, R = H.construction() sage: F - (('macdonald', {'q': q, 't': t}), ('H',)) + SymmetricFunctionsFunctor[macdonald(q=q, t=t).H] """ - return repr(self._descriptor) + basis = ".".join(method + + ("(" + + ", ".join(key + "=" + repr(param) + for key, param in params[0].items()) + + ")" if params + else "") + for method, *params in self._descriptor) + return "SymmetricFunctionsFunctor[" + basis + "]" ################### def _lmax(x): From 6a209947d608e59fb40a19daaff1df9cf5220e1d Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 10 Feb 2024 23:44:34 +0100 Subject: [PATCH 08/10] provide _descriptor for llt --- src/sage/combinat/sf/llt.py | 2 ++ src/sage/combinat/sf/sfa.py | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/sf/llt.py b/src/sage/combinat/sf/llt.py index 6e0e20d49ba..cc7bfb3e688 100644 --- a/src/sage/combinat/sf/llt.py +++ b/src/sage/combinat/sf/llt.py @@ -645,6 +645,7 @@ def __init__(self, llt): self._m_to_self_cache = m_to_hsp_cache[level] LLT_generic.__init__(self, llt, prefix="HSp%s" % level) + self._descriptor = (("llt", {"k": self.level(), "t": self.t}), ("hspin",)) def _to_m(self, part): r""" @@ -713,6 +714,7 @@ def __init__(self, llt): self._self_to_m_cache = hcosp_to_m_cache[level] self._m_to_self_cache = m_to_hcosp_cache[level] LLT_generic.__init__(self, llt, prefix="HCosp%s" % level) + self._descriptor = (("llt", {"k": self.level(), "t": self.t}), ("hcospin",)) def _to_m(self, part): r""" diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 92e39be373f..79cce5a9292 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -700,10 +700,14 @@ def corresponding_basis_over(self, R): Symmetric Functions over Universal Cyclotomic Field in the Jack J with t=1 basis sage: Sym.zonal().corresponding_basis_over(CyclotomicField()) Symmetric Functions over Universal Cyclotomic Field in the zonal basis - sage: Sym.llt(3).hspin().corresponding_basis_over(CyclotomicField()) - sage: Sym.llt(3).hcospin().corresponding_basis_over(CyclotomicField()) + sage: Sym.llt(3).hspin().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the level 3 LLT spin basis + sage: Sym.llt(3).hcospin().corresponding_basis_over(CyclotomicField()['t']) + Symmetric Functions over Univariate Polynomial Ring in t over Universal Cyclotomic Field in the level 3 LLT cospin basis sage: Sym.llt(3, t=1).hspin().corresponding_basis_over(CyclotomicField()) + Symmetric Functions over Universal Cyclotomic Field in the level 3 LLT spin with t=1 basis sage: Sym.llt(3, t=1).hcospin().corresponding_basis_over(CyclotomicField()) + Symmetric Functions over Universal Cyclotomic Field in the level 3 LLT cospin with t=1 basis .. TODO:: From 77b79c74c7b9ab3333d3b1256078a6aac36ffe0e Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 11 Feb 2024 12:11:45 +0100 Subject: [PATCH 09/10] construction for dual bases --- src/sage/combinat/sf/dual.py | 21 ++++++++++++--------- src/sage/combinat/sf/sfa.py | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/sage/combinat/sf/dual.py b/src/sage/combinat/sf/dual.py index 58b69743c7b..69cada9e2ac 100644 --- a/src/sage/combinat/sf/dual.py +++ b/src/sage/combinat/sf/dual.py @@ -26,7 +26,13 @@ class SymmetricFunctionAlgebra_dual(classical.SymmetricFunctionAlgebra_classical): - def __init__(self, dual_basis, scalar, scalar_name="", basis_name=None, prefix=None): + @staticmethod + def __classcall__(cls, dual_basis, scalar, scalar_name="", basis_name=None, prefix=None): + if prefix is None: + prefix = 'd_'+dual_basis.prefix() + return super().__classcall__(cls, dual_basis, scalar, scalar_name, basis_name, prefix) + + def __init__(self, dual_basis, scalar, scalar_name, basis_name, prefix): r""" Generic dual basis of a basis of symmetric functions. @@ -72,9 +78,9 @@ def __init__(self, dual_basis, scalar, scalar_name="", basis_name=None, prefix=N EXAMPLES:: sage: e = SymmetricFunctions(QQ).e() - sage: f = e.dual_basis(prefix = "m", basis_name="Forgotten symmetric functions"); f + sage: f = e.dual_basis(prefix="m", basis_name="Forgotten symmetric functions"); f Symmetric Functions over Rational Field in the Forgotten symmetric functions basis - sage: TestSuite(f).run(skip='_test_construction', elements = [f[1,1]+2*f[2], f[1]+3*f[1,1]]) + sage: TestSuite(f).run(elements=[f[1,1]+2*f[2], f[1]+3*f[1,1]]) sage: TestSuite(f).run() # long time (11s on sage.math, 2011) This class defines canonical coercions between ``self`` and @@ -123,6 +129,9 @@ def __init__(self, dual_basis, scalar, scalar_name="", basis_name=None, prefix=N self._dual_basis = dual_basis self._scalar = scalar self._scalar_name = scalar_name + if self._scalar == sage.combinat.sf.sfa.zee: + self._descriptor = (self._dual_basis._descriptor + + (("dual_basis", {"prefix": prefix, "basis_name": basis_name}),)) # Set up the cache @@ -145,9 +154,6 @@ def __init__(self, dual_basis, scalar, scalar_name="", basis_name=None, prefix=N self._sym = sage.combinat.sf.sf.SymmetricFunctions(scalar_target) self._p = self._sym.power() - if prefix is None: - prefix = 'd_'+dual_basis.prefix() - classical.SymmetricFunctionAlgebra_classical.__init__(self, self._sym, basis_name=basis_name, prefix=prefix) @@ -157,9 +163,6 @@ def __init__(self, dual_basis, scalar, scalar_name="", basis_name=None, prefix=N self.register_coercion(SetMorphism(Hom(self._dual_basis, self, category), self._dual_to_self)) self._dual_basis.register_coercion(SetMorphism(Hom(self, self._dual_basis, category), self._self_to_dual)) - def construction(self): - raise NotImplementedError - def _dual_to_self(self, x): """ Coerce an element of the dual of ``self`` canonically into ``self``. diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 79cce5a9292..070ae8f64e8 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -6431,7 +6431,7 @@ def exponential_specialization(self, t=None, q=1): class SymmetricFunctionsFunctor(ConstructionFunctor): """ - A constructor for free Zinbiel algebras. + A constructor for algebras of symmetric functions. EXAMPLES:: From 3752688a112b8b089b3e21f2c3d5f79a7468b952 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 11 Feb 2024 16:07:24 +0100 Subject: [PATCH 10/10] fix equality for llt --- src/sage/combinat/sf/llt.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/sf/llt.py b/src/sage/combinat/sf/llt.py index cc7bfb3e688..1e46ddeeae3 100644 --- a/src/sage/combinat/sf/llt.py +++ b/src/sage/combinat/sf/llt.py @@ -91,8 +91,11 @@ class LLT_class(UniqueRepresentation): sage: HS3x(HC3t2[3,1]) 2*HSp3[3, 1] + (-2*x+1)*HSp3[4] """ + @staticmethod + def __classcall__(cls, Sym, k, t='t'): + return super().__classcall__(cls, Sym, k, Sym.base_ring()(t)) - def __init__(self, Sym, k, t='t'): + def __init__(self, Sym, k, t): r""" Class of LLT symmetric function bases @@ -129,7 +132,7 @@ def __init__(self, Sym, k, t='t'): self._k = k self._sym = Sym self._name = "level %s LLT polynomials" % self._k - self.t = Sym.base_ring()(t) + self.t = t self._name_suffix = "" if str(t) != 't': self._name_suffix += " with t=%s" % self.t