@@ -3031,33 +3031,53 @@ def plethysm(self, x, include=None, exclude=None):
3031
3031
3032
3032
- ``x`` -- a symmetric function over the same base ring as
3033
3033
``self``
3034
-
3035
3034
- ``include`` -- a list of variables to be treated as
3036
3035
degree one elements instead of the default degree one elements
3037
-
3038
3036
- ``exclude`` -- a list of variables to be excluded
3039
3037
from the default degree one elements
3040
3038
3039
+ OUTPUT:
3040
+
3041
+ An element in the parent of ``x`` or the base ring `R` of ``self``
3042
+ when ``x`` is in `R`.
3043
+
3041
3044
EXAMPLES::
3042
3045
3043
3046
sage: Sym = SymmetricFunctions(QQ)
3044
3047
sage: s = Sym.s()
3045
3048
sage: h = Sym.h()
3046
- sage: s ( h([3])( h([2]) ) )
3049
+ sage: h3h2 = h[3](h[2]); h3h2
3050
+ h[2, 2, 2] - 2*h[3, 2, 1] + h[3, 3] + h[4, 1, 1] - h[5, 1] + h[6]
3051
+ sage: s(h3h2)
3047
3052
s[2, 2, 2] + s[4, 2] + s[6]
3048
3053
sage: p = Sym.p()
3049
- sage: p([3])( s([2,1]) )
3054
+ sage: p3s21 = p[3](s[2,1]); p3s21
3055
+ s[2, 2, 2, 1, 1, 1] - s[2, 2, 2, 2, 1] - s[3, 2, 1, 1, 1, 1]
3056
+ + s[3, 2, 2, 2] + s[3, 3, 1, 1, 1] - s[3, 3, 2, 1] + 2*s[3, 3, 3]
3057
+ + s[4, 1, 1, 1, 1, 1] - s[4, 3, 2] + s[4, 4, 1] - s[5, 1, 1, 1, 1]
3058
+ + s[5, 2, 2] - s[5, 4] + s[6, 1, 1, 1] - s[6, 2, 1] + s[6, 3]
3059
+ sage: p(p3s21)
3050
3060
1/3*p[3, 3, 3] - 1/3*p[9]
3051
3061
sage: e = Sym.e()
3052
- sage: e( [3])( e( [2]) )
3062
+ sage: e[3](e [2])
3053
3063
e[3, 3] + e[4, 1, 1] - 2*e[4, 2] - e[5, 1] + e[6]
3054
3064
3055
- ::
3065
+ Note that the output is in the basis of the input ``x``::
3066
+
3067
+ sage: s[2,1](h[3])
3068
+ h[4, 3, 2] - h[4, 4, 1] - h[5, 2, 2] + h[5, 3, 1] + h[5, 4]
3069
+ + h[6, 2, 1] - 2*h[6, 3] - h[7, 1, 1] + h[7, 2] + h[8, 1] - h[9]
3070
+
3071
+ sage: h[2,1](s[3])
3072
+ s[4, 3, 2] + s[4, 4, 1] + s[5, 2, 2] + s[5, 3, 1] + s[5, 4]
3073
+ + s[6, 2, 1] + 2*s[6, 3] + 2*s[7, 2] + s[8, 1] + s[9]
3074
+
3075
+ Examples over a polynomial ring::
3056
3076
3057
3077
sage: R.<t> = QQ[]
3058
3078
sage: s = SymmetricFunctions(R).s()
3059
3079
sage: a = s([3])
3060
- sage: f = t* s([2])
3080
+ sage: f = t * s([2])
3061
3081
sage: a(f)
3062
3082
t^3*s[2, 2, 2] + t^3*s[4, 2] + t^3*s[6]
3063
3083
sage: f(a)
@@ -3069,6 +3089,12 @@ def plethysm(self, x, include=None, exclude=None):
3069
3089
sage: s(1).plethysm(s(0))
3070
3090
s[]
3071
3091
3092
+ When ``x`` is a constant, then it is returned as an element
3093
+ of the base ring::
3094
+
3095
+ sage: s[3](2).parent() is R
3096
+ True
3097
+
3072
3098
Sage also handles plethysm of tensor products of symmetric functions::
3073
3099
3074
3100
sage: s = SymmetricFunctions(QQ).s()
@@ -3080,8 +3106,8 @@ def plethysm(self, x, include=None, exclude=None):
3080
3106
s[1, 1, 1] # s[3] + s[2, 1] # s[2, 1] + s[3] # s[1, 1, 1]
3081
3107
3082
3108
One can use this to work with symmetric functions in two sets of
3083
- commuting variables. For example, we verify the Cauchy identities (in
3084
- degree 5)::
3109
+ commuting variables. For example, we verify the Cauchy identities
3110
+ (in degree 5)::
3085
3111
3086
3112
sage: m = SymmetricFunctions(QQ).m()
3087
3113
sage: P5 = Partitions(5)
@@ -3142,39 +3168,41 @@ def plethysm(self, x, include=None, exclude=None):
3142
3168
Check that we can compute the plethysm with a constant::
3143
3169
3144
3170
sage: p[2,2,1](2)
3145
- 8*p[]
3171
+ 8
3146
3172
3147
3173
sage: p[2,2,1](int(2))
3148
- 8*p[]
3174
+ 8
3149
3175
3150
3176
sage: p[2,2,1](a1)
3151
- a1^5*p[]
3177
+ a1^5
3152
3178
3153
3179
sage: X = algebras.Shuffle(QQ, 'ab')
3154
3180
sage: Y = algebras.Shuffle(QQ, 'bc')
3155
- sage: T = tensor([X,Y])
3181
+ sage: T = tensor([X, Y])
3156
3182
sage: s = SymmetricFunctions(T).s()
3157
- sage: s(2*T.one() )
3158
- (2 *B[]#B[])*s []
3183
+ sage: s[2](5 )
3184
+ 15 *B[] # B []
3159
3185
3160
3186
.. TODO::
3161
3187
3162
3188
The implementation of plethysm in
3163
3189
:class:`sage.data_structures.stream.Stream_plethysm` seems
3164
3190
to be faster. This should be investigated.
3165
3191
"""
3192
+ from sage .structure .element import parent as get_parent
3193
+ Px = get_parent (x )
3166
3194
parent = self .parent ()
3195
+ R = parent .base_ring ()
3196
+
3167
3197
if not self :
3168
- return self
3198
+ return R ( 0 )
3169
3199
3170
- R = parent .base_ring ()
3171
3200
tHA = HopfAlgebrasWithBasis (R ).TensorProducts ()
3172
- from sage .structure .element import parent as get_parent
3173
- Px = get_parent (x )
3174
3201
tensorflag = Px in tHA
3175
3202
if not is_SymmetricFunction (x ):
3176
- if Px is R : # Handle stuff that is directly in the base ring
3177
- x = parent (x )
3203
+ if R .has_coerce_map_from (Px ) or x in R :
3204
+ x = R (x )
3205
+ Px = R
3178
3206
elif (not tensorflag or any (not isinstance (factor , SymmetricFunctionAlgebra_generic )
3179
3207
for factor in Px ._sets )):
3180
3208
from sage .rings .lazy_series import LazySymmetricFunction
@@ -3198,13 +3226,15 @@ def plethysm(self, x, include=None, exclude=None):
3198
3226
3199
3227
if tensorflag :
3200
3228
tparents = Px ._sets
3201
- s = sum (d * prod (sum (_raise_variables (c , r , degree_one )
3202
- * tensor ([p [r ].plethysm (base (la ))
3203
- for base , la in zip (tparents , trm )])
3204
- for trm , c in x )
3205
- for r in mu )
3206
- for mu , d in p (self ))
3207
- return tensor ([parent ]* len (tparents ))(s )
3229
+ lincomb = Px .linear_combination
3230
+ elt = lincomb ((prod (lincomb ((tensor ([p [r ].plethysm (base (la ))
3231
+ for base , la in zip (tparents , trm )]),
3232
+ _raise_variables (c , r , degree_one ))
3233
+ for trm , c in x )
3234
+ for r in mu ),
3235
+ d )
3236
+ for mu , d in p (self ))
3237
+ return Px (elt )
3208
3238
3209
3239
# Takes a symmetric function f, and an n and returns the
3210
3240
# symmetric function with all of its basis partitions scaled
@@ -3218,7 +3248,11 @@ def pn_pleth(f, n):
3218
3248
def f (part ):
3219
3249
return p .prod (pn_pleth (p_x .map_coefficients (lambda c : _raise_variables (c , i , degree_one )), i )
3220
3250
for i in part )
3221
- return parent (p ._apply_module_morphism (p (self ), f , codomain = p ))
3251
+ ret = p ._apply_module_morphism (p (self ), f , codomain = p )
3252
+ if Px is R :
3253
+ # special case for things in the base ring
3254
+ return next (iter (ret ._monomial_coefficients .values ()))
3255
+ return Px (ret )
3222
3256
3223
3257
__call__ = plethysm
3224
3258
@@ -6202,21 +6236,20 @@ def _nonnegative_coefficients(x):
6202
6236
return x >= 0
6203
6237
6204
6238
def _variables_recursive (R , include = None , exclude = None ):
6205
- """
6239
+ r """
6206
6240
Return all variables appearing in the ring ``R``.
6207
6241
6208
6242
INPUT:
6209
6243
6210
6244
- ``R`` -- a :class:`Ring`
6211
- - ``include``, ``exclude`` (optional, default ``None``) --
6212
- iterables of variables in ``R``
6245
+ - ``include``, ``exclude`` -- (optional) iterables of variables in ``R``
6213
6246
6214
6247
OUTPUT:
6215
6248
6216
- - If ``include`` is specified, only these variables are returned
6217
- as elements of ``R``. Otherwise, all variables in ``R``
6218
- (recursively) with the exception of those in ``exclude`` are
6219
- returned.
6249
+ If ``include`` is specified, only these variables are returned
6250
+ as elements of ``R``. Otherwise, all variables in ``R``
6251
+ (recursively) with the exception of those in ``exclude`` are
6252
+ returned.
6220
6253
6221
6254
EXAMPLES::
6222
6255
@@ -6251,15 +6284,15 @@ def _variables_recursive(R, include=None, exclude=None):
6251
6284
except AttributeError :
6252
6285
try :
6253
6286
degree_one = R .gens ()
6254
- except NotImplementedError :
6287
+ except ( NotImplementedError , AttributeError ) :
6255
6288
degree_one = []
6256
6289
if exclude is not None :
6257
6290
degree_one = [g for g in degree_one if g not in exclude ]
6258
6291
6259
6292
return [g for g in degree_one if g != R .one ()]
6260
6293
6261
6294
def _raise_variables (c , n , variables ):
6262
- """
6295
+ r """
6263
6296
Replace the given variables in the ring element ``c`` with their
6264
6297
``n``-th power.
6265
6298
@@ -6276,6 +6309,9 @@ def _raise_variables(c, n, variables):
6276
6309
sage: S.<t> = R[]
6277
6310
sage: _raise_variables(2*a + 3*b*t, 2, [a, t])
6278
6311
3*b*t^2 + 2*a^2
6279
-
6280
6312
"""
6281
- return c .subs (** {str (g ): g ** n for g in variables })
6313
+ try :
6314
+ return c .subs (** {str (g ): g ** n for g in variables })
6315
+ except AttributeError :
6316
+ return c
6317
+
0 commit comments