diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index e1fa796ba3b..006db5d34ab 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -28,6 +28,7 @@ from sage.categories.fields import Fields from sage.categories.modules import Modules from sage.categories.poor_man_map import PoorManMap +from sage.categories.map import Map from sage.structure.element import Element, parent @@ -2062,17 +2063,25 @@ def trailing_term(self, *args, **kwds): """ return self.parent().term(*self.trailing_item(*args, **kwds)) - def map_coefficients(self, f): + def map_coefficients(self, f, new_base_ring=None): """ - Mapping a function on coefficients. + Return the element obtained by applying ``f`` to the non-zero + coefficients of ``self``. + + If ``f`` is a :class:`sage.categories.map.Map`, then the resulting + polynomial will be defined over the codomain of ``f``. Otherwise, the + resulting polynomial will be over the same ring as ``self``. Set + ``new_base_ring`` to override this behaviour. + + An error is raised if the coefficients are not in the new base ring. INPUT: - - ``f`` -- an endofunction on the coefficient ring of the - free module + - ``f`` -- a callable that will be applied to the + coefficients of ``self``. - Return a new element of ``self.parent()`` obtained by applying the - function ``f`` to all of the coefficients of ``self``. + - ``new_base_ring`` (optional) -- if given, the resulting element + will be defined over this ring. EXAMPLES:: @@ -2096,8 +2105,32 @@ def map_coefficients(self, f): sage: a = s([2,1]) + 2*s([3,2]) # needs sage.combinat sage.modules sage: a.map_coefficients(lambda x: x * 2) # needs sage.combinat sage.modules 2*s[2, 1] + 4*s[3, 2] - """ - return self.parent().sum_of_terms( (m, f(c)) for m,c in self ) + + We can map into a different base ring:: + + sage: # needs sage.combinat + sage: e = SymmetricFunctions(QQ).elementary() + sage: a = 1/2*(e([2,1]) + e([1,1,1])); a + 1/2*e[1, 1, 1] + 1/2*e[2, 1] + sage: b = a.map_coefficients(lambda c: 2*c, ZZ); b + e[1, 1, 1] + e[2, 1] + sage: b.parent() + Symmetric Functions over Integer Ring in the elementary basis + sage: b.map_coefficients(lambda c: 1/2*c, ZZ) + Traceback (most recent call last): + ... + TypeError: no conversion of this rational to integer + """ + R = self.parent() + if new_base_ring is not None: + B = new_base_ring + R = R.change_ring(B) + elif isinstance(f, Map): + B = f.codomain() + R = R.change_ring(B) + else: + B = self.base_ring() + return R.sum_of_terms((m, B(f(c))) for m, c in self) def map_support(self, f): """ 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/dual.py b/src/sage/combinat/sf/dual.py index 97f81551f8b..939e6a89c5a 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/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/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/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/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 1358c5779df..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) @@ -1082,6 +1087,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 +1124,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 +1225,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 +1448,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 +1744,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/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/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``. diff --git a/src/sage/combinat/sf/powersum.py b/src/sage/combinat/sf/powersum.py index 9521eaccd32..bfd8bf4f759 100644 --- a/src/sage/combinat/sf/powersum.py +++ b/src/sage/combinat/sf/powersum.py @@ -45,6 +45,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 de6498ec6f2..8a03731e27c 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -170,21 +170,22 @@ BACKWARD INCOMPATIBLE CHANGES (:issue:`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. @@ -1788,7 +1789,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. @@ -3015,6 +3015,36 @@ 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() + + 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""" @@ -3035,7 +3065,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. @@ -3091,7 +3120,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) @@ -6379,6 +6408,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): 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