16
16
# https://www.gnu.org/licenses/
17
17
# ****************************************************************************
18
18
19
- from sage .sets .family import Family
19
+ from sage .sets .family import Family , AbstractFamily
20
20
from sage .combinat .free_module import CombinatorialFreeModule
21
21
from sage .categories .modules import Modules
22
22
from copy import copy
@@ -103,23 +103,75 @@ class RepresentationByMorphism(CombinatorialFreeModule, Representation_abstract)
103
103
104
104
- ``lie_algebra`` -- a Lie algebra
105
105
- ``f`` -- the Lie algebra morphism defining the action of the basis
106
- elements of ``lie_algebra`` encoded as a ``dict`` with keys being
107
- indices of the basis of ``lie_algebra`` and the values being the
108
- corresponding matrix defining the action
106
+ elements of ``lie_algebra``
107
+ - ``index_set`` -- (optional) the index set of the module basis
108
+ - ``on_basis`` -- (default: ``False``) the function ``f`` defines a
109
+ map from the basis elements or from a generic element of ``lie_algebra``
110
+
111
+ If ``f`` is encoded as a ``dict`` or ``Family``, then the keys must
112
+ be indices of the basis of ``lie_algebra`` and the values being the
113
+ corresponding matrix defining the action. This sets ``on_basis=True``.
109
114
110
115
EXAMPLES::
111
116
112
117
sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'y':1}})
113
- sage: f = ( {x: Matrix([[1,0],[0,0]]), y: Matrix([[0,1],[0,0]])})
118
+ sage: f = {x: Matrix([[1,0],[0,0]]), y: Matrix([[0,1],[0,0]])}
114
119
sage: L.representation(f)
115
120
Representation of Lie algebra on 2 generators (x, y) over Rational Field defined by:
116
121
[1 0]
117
122
x |--> [0 0]
118
123
[0 1]
119
124
y |--> [0 0]
125
+
126
+ We construct the direct sum of two copies of the trivial representation
127
+ for an infinite dimensional Lie algebra::
128
+
129
+ sage: L = lie_algebras.Affine(QQ, ['E',6,1])
130
+ sage: R = L.representation(lambda b: matrix.zero(QQ, 2), index_set=['a','b'])
131
+ sage: x = L.an_element()
132
+ sage: v = R.an_element(); v
133
+ 2*R['a'] + 2*R['b']
134
+ sage: x * v
135
+ 0
136
+
137
+ We construct a finite dimensional representation of the affline Lie algebra
138
+ of type `A_2^{(1)}`::
139
+
140
+ sage: L = lie_algebras.Affine(QQ, ['A',2,1]).derived_subalgebra()
141
+ sage: Phi_plus = list(RootSystem(['A',2]).root_lattice().positive_roots())
142
+ sage: def aff_action(key):
143
+ ....: mat = matrix.zero(QQ, 3)
144
+ ....: if key == 'c': # central element
145
+ ....: return mat
146
+ ....: b, ell = key
147
+ ....: if b in Phi_plus: # positive root
148
+ ....: ind = tuple(sorted(b.to_ambient().support()))
149
+ ....: mat[ind] = 1
150
+ ....: if ind[0] + 1 != ind[1]:
151
+ ....: mat[ind] = -1
152
+ ....: elif -b in Phi_plus: # negative root
153
+ ....: ind = tuple(sorted(b.to_ambient().support(), reverse=True))
154
+ ....: mat[ind] = 1
155
+ ....: if ind[0] - 1 != ind[1]:
156
+ ....: mat[ind] = -1
157
+ ....: else: # must be in the Cartan
158
+ ....: i = b.leading_support()
159
+ ....: mat[i,i] = -1
160
+ ....: mat[i-1,i-1] = 1
161
+ ....: return mat
162
+ sage: F = Family(L.basis(), aff_action, name="lifted natural repr")
163
+ sage: R = L.representation(index_set=range(1,4), on_basis=F)
164
+ sage: x = L.an_element(); x
165
+ (E[alpha[2]] + E[alpha[1]] + h1 + h2 + E[-alpha[2]] + E[-alpha[1]])#t^0
166
+ + (E[-alpha[1] - alpha[2]])#t^1 + (E[alpha[1] + alpha[2]])#t^-1 + c
167
+ sage: v = R.an_element(); v
168
+ 2*R[1] + 2*R[2] + 3*R[3]
169
+ sage: x * v
170
+ R[1] + 5*R[2] - 3*R[3]
171
+ sage: R._test_representation() # verify that it is a representation
120
172
"""
121
173
@staticmethod
122
- def __classcall_private__ (cls , lie_algebra , f , ** kwargs ):
174
+ def __classcall_private__ (cls , lie_algebra , f = None , index_set = None , on_basis = False , ** kwargs ):
123
175
r"""
124
176
Normalize inpute to ensure a unique representation.
125
177
@@ -128,24 +180,69 @@ def __classcall_private__(cls, lie_algebra, f, **kwargs):
128
180
sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'y':1}})
129
181
sage: f1 = {'x': Matrix([[1,0],[0,0]]), 'y': Matrix([[0,1],[0,0]])}
130
182
sage: R1 = L.representation(f1)
131
- sage: f2 = Family({x: Matrix([[1,0],[0,0]]), y: Matrix([[0,1],[0,0]])})
183
+ sage: f2 = Family({x: Matrix([[1,0],[0,0]]), y: Matrix(QQ, [[0,1],[0,0]])})
132
184
sage: R2 = L.representation(f2)
133
185
sage: R1 is R2
134
186
True
187
+
188
+ TESTS::
189
+
190
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'y':1}})
191
+ sage: f = {'x': Matrix([[1,0]]), 'y': Matrix([[0,1]])}
192
+ sage: R = L.representation(f)
193
+ Traceback (most recent call last):
194
+ ...
195
+ ValueError: all matrices must be square
196
+
197
+ sage: f = {'x': Matrix([[1,0],[0,0]]), 'y': Matrix([[0]])}
198
+ sage: R = L.representation(f)
199
+ Traceback (most recent call last):
200
+ ...
201
+ ValueError: all matrices must be square of size 2
135
202
"""
136
- C = Modules (lie_algebra .base_ring ()).WithBasis ().FiniteDimensional ()
203
+ from sage .sets .finite_enumerated_set import FiniteEnumeratedSet
204
+ base = lie_algebra .base_ring ()
205
+ C = Modules (base ).WithBasis ().FiniteDimensional ()
137
206
C = C .or_subcategory (kwargs .pop ('category' , C ))
138
207
B = lie_algebra .basis ()
139
- data = {}
140
- for k , mat in f .items ():
141
- if k in B :
142
- k = k .leading_support ()
143
- data [k ] = copy (mat )
144
- data [k ].set_immutable ()
145
- f = Family (data )
146
- return super (cls , RepresentationByMorphism ).__classcall__ (cls , lie_algebra , f , category = C , ** kwargs )
147
-
148
- def __init__ (self , lie_algebra , f , category , ** kwargs ):
208
+ if not isinstance (on_basis , bool ):
209
+ f = on_basis
210
+ on_basis = True
211
+ if isinstance (f , AbstractFamily ):
212
+ if f .cardinality () < float ('inf' ):
213
+ f = dict (f )
214
+ on_basis = True
215
+ if isinstance (f , dict ):
216
+ data = {}
217
+ dim = None
218
+ for k , mat in f .items ():
219
+ if k in B :
220
+ k = k .leading_support ()
221
+ if not mat .is_square ():
222
+ raise ValueError ("all matrices must be square" )
223
+ if dim is None :
224
+ dim = mat .nrows ()
225
+ elif mat .nrows () != dim or mat .ncols () != dim :
226
+ raise ValueError ("all matrices must be square of size {}" .format (dim ))
227
+ data [k ] = mat .change_ring (base )
228
+ data [k ].set_immutable ()
229
+
230
+ if index_set is None :
231
+ index_set = FiniteEnumeratedSet (range (dim ))
232
+ f = Family (data )
233
+ on_basis = True
234
+
235
+ if f is None :
236
+ raise ValueError ("either 'f' or 'on_basis' must be specified" )
237
+ if index_set is None :
238
+ raise ValueError ("the index set needs to be specified" )
239
+
240
+ index_set = FiniteEnumeratedSet (index_set )
241
+
242
+ return super (cls , RepresentationByMorphism ).__classcall__ (cls , lie_algebra ,
243
+ f , index_set , on_basis , category = C , ** kwargs )
244
+
245
+ def __init__ (self , lie_algebra , f , index_set , on_basis , category , ** kwargs ):
149
246
r"""
150
247
Initialize ``self``.
151
248
@@ -156,20 +253,17 @@ def __init__(self, lie_algebra, f, category, **kwargs):
156
253
sage: R = L.representation(f)
157
254
sage: TestSuite(R).run()
158
255
"""
159
- it = iter (f )
160
- mat = next (it )
161
- if not mat .is_square ():
162
- raise ValueError ("all matrices must be square" )
163
- dim = mat .nrows ()
164
- self ._mat_space = mat .parent ()
165
- from sage .sets .finite_enumerated_set import FiniteEnumeratedSet
166
- if any (mat .nrows () != dim or mat .ncols () != dim for mat in it ):
167
- raise ValueError ("all matrices must be square of size {}" .format (dim ))
168
- self ._f = dict (f )
256
+ if on_basis :
257
+ self ._family = f
258
+ self ._f = f .__getitem__
259
+ else :
260
+ self ._f = f
261
+ prefix = kwargs .pop ("prefix" , 'R' )
262
+ self ._on_basis = on_basis
169
263
170
- I = FiniteEnumeratedSet (range (dim ))
171
264
Representation_abstract .__init__ (self , lie_algebra )
172
- CombinatorialFreeModule .__init__ (self , lie_algebra .base_ring (), I , prefix = 'R' , category = category )
265
+ CombinatorialFreeModule .__init__ (self , lie_algebra .base_ring (), index_set ,
266
+ category = category , prefix = prefix , ** kwargs )
173
267
174
268
def _repr_ (self ):
175
269
r"""
@@ -185,12 +279,28 @@ def _repr_(self):
185
279
x |--> [0 0]
186
280
[0 1]
187
281
y |--> [0 0]
282
+
283
+ sage: L = lie_algebras.Affine(QQ, ['E',6,1])
284
+ sage: F = Family(L.basis(), lambda b: matrix.zero(QQ, 2), name="zero map")
285
+ sage: L.representation(F, index_set=['a','b'], on_basis=True)
286
+ Representation of Affine Kac-Moody algebra of ['E', 6] in the Chevalley basis defined by:
287
+ Lazy family (zero map(i))_{i in Lazy family...}
288
+
289
+ sage: L.representation(lambda b: matrix.zero(QQ, 2), index_set=['a','b'])
290
+ Representation of Affine Kac-Moody algebra of ['E', 6] in the Chevalley basis defined by:
291
+ <function <lambda> at 0x...>
188
292
"""
189
293
ret = "Representation of {} defined by:" .format (self ._lie_algebra )
190
294
from sage .typeset .ascii_art import ascii_art
191
- B = self ._lie_algebra .basis ()
192
- for k in self ._f :
193
- ret += '\n ' + repr (ascii_art (B [k ], self ._f [k ], sep = " |--> " , sep_baseline = 0 ))
295
+ if self ._on_basis :
296
+ B = self ._lie_algebra .basis ()
297
+ if B .cardinality () < float ('inf' ):
298
+ for k in B .keys ():
299
+ ret += '\n ' + repr (ascii_art (B [k ], self ._f (k ), sep = " |--> " , sep_baseline = 0 ))
300
+ else :
301
+ ret += '\n ' + repr (self ._family )
302
+ else :
303
+ ret += '\n ' + repr (self ._f )
194
304
return ret
195
305
196
306
class Element (CombinatorialFreeModule .Element ):
@@ -220,14 +330,28 @@ def _acted_upon_(self, scalar, self_on_left=False):
220
330
4*R[0] + 5*R[1]
221
331
sage: (1/3*x - 5*y) * v
222
332
-71/3*R[0]
333
+
334
+ sage: L = lie_algebras.Affine(QQ, ['E',6,1])
335
+ sage: F = Family(L.basis(), lambda b: matrix.zero(QQ, 2), name="zero map")
336
+ sage: R = L.representation(F, index_set=['a','b'], on_basis=True)
337
+ sage: R.an_element()
338
+ 2*R['a'] + 2*R['b']
339
+ sage: L.an_element() * R.an_element()
340
+ 0
223
341
"""
224
342
P = self .parent ()
225
343
if scalar in P ._lie_algebra :
226
344
if self_on_left :
227
345
return None
346
+ if not self : # we are (already) the zero vector
347
+ return self
228
348
scalar = P ._lie_algebra (scalar )
229
- f = P ._f
230
- mat = P ._mat_space .sum (scalar [k ] * f [k ] for k in f if scalar [k ])
349
+ if not scalar : # we are acting by zero
350
+ return P .zero ()
351
+ if P ._on_basis :
352
+ mat = sum (c * P ._f (k ) for k , c in scalar .monomial_coefficients (copy = False ).items ())
353
+ else :
354
+ mat = P ._f (scalar )
231
355
return P .from_vector (mat * self .to_vector ())
232
356
233
357
return super ()._acted_upon_ (scalar , self_on_left )
@@ -249,7 +373,7 @@ class TrivialRepresentation(CombinatorialFreeModule, Representation_abstract):
249
373
250
374
- :wikipedia:`Trivial_representation`
251
375
"""
252
- def __init__ (self , lie_algebra ):
376
+ def __init__ (self , lie_algebra , ** kwargs ):
253
377
r"""
254
378
Initialize ``self``.
255
379
@@ -262,7 +386,7 @@ def __init__(self, lie_algebra):
262
386
R = lie_algebra .base_ring ()
263
387
cat = Modules (R ).WithBasis ().FiniteDimensional ()
264
388
Representation_abstract .__init__ (self , lie_algebra )
265
- CombinatorialFreeModule .__init__ (self , R , ['v' ], prefix = 'T' , category = cat )
389
+ CombinatorialFreeModule .__init__ (self , R , ['v' ], prefix = 'T' , category = cat , ** kwargs )
266
390
267
391
def _repr_ (self ):
268
392
r"""
0 commit comments