|
11 | 11 |
|
12 | 12 | from sage.categories.category_types import Category_over_base_ring
|
13 | 13 | from sage.categories.all import Algebras, Coalgebras
|
| 14 | +from sage.categories.tensor import tensor |
| 15 | +from sage.functions.other import floor, ceil |
| 16 | +from sage.rings.integer import Integer |
14 | 17 |
|
15 | 18 | class Bialgebras(Category_over_base_ring):
|
16 | 19 | """
|
@@ -61,76 +64,189 @@ class ParentMethods:
|
61 | 64 |
|
62 | 65 | class ElementMethods:
|
63 | 66 |
|
64 |
| - def convolution_product(h,a,b): |
65 |
| - r""" |
66 |
| - input: h - an element of a Hopf algebra H |
67 |
| - a,b - linear maps from H to H |
68 |
| - output: [a*b](h) |
| 67 | + def adams_operator(self, n): |
69 | 68 | """
|
70 |
| - H = h.parent() |
71 |
| - out = 0 |
72 |
| - for (bimonom,coef) in h.coproduct(): |
73 |
| - out += coef*a(H(bimonom[0]))*b(H(bimonom[1])) |
74 |
| - return out |
| 69 | + Compute the n-th convolution power of the identity morphism `Id` on self. |
| 70 | +
|
| 71 | + INPUT: |
| 72 | +
|
| 73 | + - ``n`` -- a nonnegative integer. |
| 74 | +
|
| 75 | + OUTPUT: |
| 76 | +
|
| 77 | + - the element of self.parent() corresponding to `Id^{*n}(self)`. |
| 78 | +
|
| 79 | + .. SEEALSO:: |
| 80 | +
|
| 81 | + :mod:`sage.categories.hopf_algebras.ElementMethods.convolution_product` |
| 82 | + :mod:`sage.categories.hopf_algebras.ElementMethods.convolution_product` |
| 83 | +
|
| 84 | + (In the literature, this is also called a Hopf power or Sweedler power, cf. [AL2015]_.) |
| 85 | +
|
| 86 | + REFERENCES: |
| 87 | +
|
| 88 | + .. [AL2015] The characteristic polynomial of the Adams operators on graded connected Hopf algebras. |
| 89 | + Marcelo Aguiar and Aaron Lauve. |
| 90 | + Algebra Number Theory, v.9, 2015, n.3, 2015. |
| 91 | +
|
| 92 | + .. TODO:: |
| 93 | +
|
| 94 | + Move to hopf_algebras.py (i.e., remove dependency on modules_with_basis methods). |
| 95 | +
|
| 96 | + TESTS:: |
| 97 | +
|
| 98 | + sage: h = SymmetricFunctions(QQ).h() |
| 99 | + sage: h[5].adams_operator(2) |
| 100 | + 2*h[3, 2] + 2*h[4, 1] + 2*h[5] |
| 101 | + sage: h[5].plethysm(2*h[1]) |
| 102 | + 2*h[3, 2] + 2*h[4, 1] + 2*h[5] |
| 103 | + sage: h([]).adams_operator(0), h([]).adams_operator(1) |
| 104 | + (h[], h[]) |
| 105 | + sage: h[3,2].adams_operator(0), h[3,2].adams_operator(1) |
| 106 | + (0, h[3, 2]) |
| 107 | +
|
| 108 | + sage: S = NonCommutativeSymmetricFunctions(QQ).S() |
| 109 | + sage: S[4].adams_operator(5) |
| 110 | + 5*S[1, 1, 1, 1] + 10*S[1, 1, 2] + 10*S[1, 2, 1] + 10*S[1, 3] + 10*S[2, 1, 1] + 10*S[2, 2] + 10*S[3, 1] + 5*S[4] |
| 111 | +
|
| 112 | + sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() |
| 113 | + sage: m[[1,3],[2]].adams_operator(-2) |
| 114 | + 3*m{{1}, {2, 3}} + 3*m{{1, 2}, {3}} + 6*m{{1, 2, 3}} - 2*m{{1, 3}, {2}} |
75 | 115 |
|
76 |
| - def convolution_power(h, L, n): |
77 |
| - r""" |
78 |
| - input: h - an element of a Hopf algebra H |
79 |
| - L - linear map from H to H |
80 |
| - n - the convolution power to which to take 'L' |
81 |
| - output: [L^*n](h) |
82 | 116 | """
|
83 |
| - from sage.categories.tensor import tensor |
84 |
| - H = h.parent() |
85 |
| - def n_fold_coproduct(h, n): |
86 |
| - H = h.parent() |
87 |
| - if n == 0: |
88 |
| - return H(h.counit()) |
89 |
| - elif n == 1: |
90 |
| - return h |
91 |
| - elif n == 2: |
92 |
| - return h.coproduct() |
93 |
| - else: |
94 |
| - # apply some kind of multilinear recursion |
95 |
| - Hn = tensor([H]*n) # or: tensor([H for i in range(n)]) |
96 |
| - terms = [] |
97 |
| - hh = n_fold_coproduct(h, n-1) |
98 |
| - for (monom,cof) in hh: |
99 |
| - h0 = H(monom[0]).coproduct() |
100 |
| - terms += [(tuple((h00, h01) + monom[1:]), cof0 * cof) for ((h00, h01), cof0) in h0] |
101 |
| - return Hn.sum_of_terms(terms) |
102 |
| - hhh = n_fold_coproduct(h,n) |
103 |
| - out = H.zero() |
104 |
| - for term in hhh: |
105 |
| - out += H.prod(L(H(t)) for t in term[0]) * term[1] |
106 |
| - return out |
107 |
| - |
108 |
| - def hopf_power(h,n=2): |
109 |
| - r""" |
110 |
| - Input: |
111 |
| - h - an element of a Hopf algebra H |
112 |
| - n - the convolution power of the identity morphism to use |
113 |
| - Output: |
114 |
| - the nth convolution power of the identity morphism, applied to h., i.e., [id^*n](h) |
115 |
| -
|
116 |
| - Remark: for historical reasons (see saga of Frobenius-Schur indicators), the second power deserves special attention. |
117 |
| - we use '2' as the default value for 'n' |
| 117 | + if n < 0: |
| 118 | + raise ValueError("cannot take less than 0 coproduct iterations: %s < 0" % str(n)) |
| 119 | + return self.convolution_product([lambda x: x] * n) |
| 120 | + |
| 121 | + def convolution_product(self, *maplist): |
| 122 | + """ |
| 123 | + Given a maplist `(R, S, ..., T)` of length `n`, compute the action of their convolution product on ``self.`` |
| 124 | +
|
| 125 | + MATH:: |
| 126 | +
|
| 127 | + (R*S*\cdots *T)(h) = \mu^{(n-1)} \circ (R \otimes S \otimes\cdot\otimes T) \circ \Delta^{(n-1)}(h) |
| 128 | +
|
| 129 | + where `\Delta^{(k)} := \bigl(\Delta \otimes \mathrm{Id}^{\otimes(k-1)}\bigr) \circ \Delta^{(k-1)}`, |
| 130 | + with `\Delta^{(1)} = \Delta` (the ordinary coproduct) and `\Delta^{(0)} = \mathrm{Id}`; |
| 131 | + and with `\mu^{(k)} := \mu \circ \bigl(\mu^{(k-1)} \otimes \mathrm{Id})` and `\mu^{(1)} = \mu` |
| 132 | + (the ordinary product). See [Sw1969]_. |
| 133 | +
|
| 134 | + (In the literature, one finds, e.g., `\Delta^{(2)}` for what we denote above as `\Delta^{(1)}`. See [KMN2012]_.) |
| 135 | +
|
| 136 | + REFERENCES: |
| 137 | +
|
| 138 | + .. [KMN2012] On the trace of the antipode and higher indicators. |
| 139 | + Yevgenia Kashina and Susan Montgomery and Richard Ng. |
| 140 | + Israel J. Math., v.188, 2012. |
| 141 | +
|
| 142 | + .. [Sw1969] Hopf algebras. |
| 143 | + Moss Sweedler. |
| 144 | + W.A. Benjamin, Math Lec Note Ser., 1969. |
| 145 | +
|
| 146 | + .. TODO:: |
| 147 | +
|
| 148 | + Remove dependency on modules_with_basis methods. |
| 149 | +
|
| 150 | + TESTS:: |
| 151 | +
|
| 152 | + sage: Id = lambda x: x |
| 153 | + sage: Antipode = lambda x: x.antipode() |
| 154 | +
|
| 155 | + sage: h = SymmetricFunctions(QQ).h() |
| 156 | + sage: h[5].convolution_product([Id,Id]) |
| 157 | + 2*h[3, 2] + 2*h[4, 1] + 2*h[5] |
| 158 | + sage: h([]).convolution_product([Id,Antipode]) |
| 159 | + h[] |
| 160 | + sage: h[3,2].convolution_product([Id,Antipode]) |
| 161 | + 0 |
| 162 | +
|
| 163 | + sage: S = NonCommutativeSymmetricFunctions(QQ).S() |
| 164 | + sage: S[4].convolution_product([Id]*5) |
| 165 | + 5*S[1, 1, 1, 1] + 10*S[1, 1, 2] + 10*S[1, 2, 1] + 10*S[1, 3] + 10*S[2, 1, 1] + 10*S[2, 2] + 10*S[3, 1] + 5*S[4] |
| 166 | +
|
| 167 | + sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() |
| 168 | + sage: m[[1,3],[2]].convolution_product([Antipode,Antipode]) |
| 169 | + 3*m{{1}, {2, 3}} + 3*m{{1, 2}, {3}} + 6*m{{1, 2, 3}} - 2*m{{1, 3}, {2}} |
| 170 | +
|
| 171 | + sage: m[[]].convolution_product([]), m[[1,3],[2]].convolution_product([]) |
| 172 | + (m{}, 0) |
| 173 | +
|
| 174 | + sage: x = GroupAlgebra(SymmetricGroup(7),QQ).an_element(); x |
| 175 | + () + 3*(1,2) + 3*(1,2,3,4,5,6,7) |
| 176 | + sage: x.convolution_product([Id, Antipode, Antipode, Antipode]) |
| 177 | + 4*() + 3*(1,6,4,2,7,5,3) |
| 178 | +
|
118 | 179 | """
|
119 |
| - H = h.parent() |
120 |
| - def Id(x): |
121 |
| - return x |
122 |
| - def S(x): |
123 |
| - return x.antipode() |
124 |
| - |
125 |
| - if n<0: |
126 |
| - L = S |
| 180 | + # be flexible on how the maps are entered... |
| 181 | + if len(maplist)==1 and isinstance(maplist[0], (list,tuple)): |
| 182 | + T = tuple(maplist[0]) |
| 183 | + else: |
| 184 | + T = maplist |
| 185 | + |
| 186 | + H = self.parent() |
| 187 | + n = len(T) |
| 188 | + if n == 0: |
| 189 | + return H.one() * self.counit() |
| 190 | + elif n == 1: |
| 191 | + return T[0](self) |
127 | 192 | else:
|
128 |
| - L = Id |
| 193 | + # We apply the maps T_i and products concurrently with coproducts, as this |
| 194 | + # seems to be faster than applying a composition of maps, e.g., (H.nfold_product) * tensor(T) * (H.nfold_coproduct). |
| 195 | + |
| 196 | + i = 0 |
| 197 | + out = tensor((H.one(), self)) |
| 198 | + dom = tensor((H, H)) |
129 | 199 |
|
| 200 | + # ALGORITHM: |
| 201 | + # `convolve` moves terms of the form x # y to x * T_i(y_1) # y_2, writing Delta(y) in Sweedler notation. |
| 202 | + convolve = lambda (x,y): ( ((xy1, y2), c * d) for ((y1, y2), d) in H(y).coproduct() for (xy1, c) in H(x) * T[i](H(y1)) ) |
| 203 | + while i < n-1: |
| 204 | + out = dom.module_morphism(on_basis=lambda t: dom.sum_of_terms(convolve(t)), codomain = dom)(out) |
| 205 | + i += 1 |
| 206 | + |
| 207 | + # Apply final map `T_n` to last term, `y`, and multiply. |
| 208 | + cod = H |
| 209 | + out = dom.module_morphism(on_basis=lambda (x,y): H(x) * T[n-1](H(y)), codomain=cod)(out) |
| 210 | + |
| 211 | + return out |
| 212 | + |
| 213 | + def coproduct_iterated(self, n=1): |
| 214 | + r""" |
| 215 | + Apply `k-1` coproducts to ``self``. |
| 216 | +
|
| 217 | +
|
| 218 | + TESTS:: |
| 219 | +
|
| 220 | + sage: p = SymmetricFunctions(QQ).p() |
| 221 | + sage: p[5,2,2].coproduct_iterated() |
| 222 | + p[] # p[5, 2, 2] + 2*p[2] # p[5, 2] + p[2, 2] # p[5] + p[5] # p[2, 2] + 2*p[5, 2] # p[2] + p[5, 2, 2] # p[] |
| 223 | + sage: p([]).coproduct_iterated(3) |
| 224 | + p[] # p[] # p[] # p[] |
| 225 | +
|
| 226 | + sage: S = NonCommutativeSymmetricFunctions(QQ).S() |
| 227 | + sage: S[4].coproduct_iterated(0) |
| 228 | + S[4] |
| 229 | + sage: S[4].coproduct_iterated(2) |
| 230 | + S[] # S[] # S[4] + S[] # S[1] # S[3] + S[] # S[2] # S[2] + S[] # S[3] # S[1] + S[] # S[4] # S[] + S[1] # S[] # S[3] + S[1] # S[1] # S[2] + S[1] # S[2] # S[1] + S[1] # S[3] # S[] + S[2] # S[] # S[2] + S[2] # S[1] # S[1] + S[2] # S[2] # S[] + S[3] # S[] # S[1] + S[3] # S[1] # S[] + S[4] # S[] # S[] |
| 231 | +
|
| 232 | + sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() |
| 233 | + sage: m[[1,3],[2]].convolution_product([Antipode,Antipode]) |
| 234 | + 3*m{{1}, {2, 3}} + 3*m{{1, 2}, {3}} + 6*m{{1, 2, 3}} - 2*m{{1, 3}, {2}} |
| 235 | +
|
| 236 | + sage: m[[]].coproduct_iterated(3), m[[1,3],[2]].coproduct_iterated(0) |
| 237 | + (m{} # m{} # m{} # m{}, m{{1, 3}, {2}}) |
| 238 | +
|
| 239 | +
|
| 240 | + """ |
| 241 | + if n < 0: |
| 242 | + raise ValueError("cannot take fewer than 0 coproduct iterations: %s < 0" % str(n)) |
130 | 243 | if n==0:
|
131 |
| - return H(h.counit()) |
132 |
| - elif abs(n)==1: |
133 |
| - return L(h) |
| 244 | + return self |
| 245 | + elif n==1: |
| 246 | + return self.coproduct() |
134 | 247 | else:
|
135 |
| - return h.convolution_power(L,abs(n)) |
| 248 | + # Use coassociativity of `\Delta` to perform many coproducts simultaneously. |
| 249 | + fn = floor(Integer(n-1)/2); cn = ceil(Integer(n-1)/2) |
| 250 | + def split(a,b): return tensor([a.coproduct_iterated(fn), b.coproduct_iterated(cn)]) |
| 251 | + return (self.coproduct()).apply_multilinear_morphism(split) |
136 | 252 |
|
0 commit comments