Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Environment to perform calculations of equivariant vector bundles on homogeneous varieties

1842 views
License: GPL3
ubuntu2204
1
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Foundation.Structure import Irreducible_Structure , Direct_Sum_Of_Structures
2
3
4
5
class Cartan_Group ( object ) :
6
7
ADMISSIBLE_CARTAN_FAMILIES = { 'A' : ( 1 , +infinity ) ,
8
'B' : ( 2 , +infinity ) ,
9
'C' : ( 2 , +infinity ) ,
10
'D' : ( 3 , +infinity ) ,
11
'E' : ( 6 , 8 ) ,
12
'F' : ( 4 , 4 ) ,
13
'G' : ( 2 , 2 )
14
}
15
16
17
def __add__ ( self , other:"Cartan_Group" ) -> "Irreducible_Cartan_Group" or "Direct_Sum_Of_Cartan_Groups" :
18
"""Returns the coproduct of two Cartan groups."""
19
assert isinstance( other , type(self).__bases__[1] ) , 'The input for ``other`` need to be an object of the class '+str( type(self).__bases__[1] )+'.'
20
New_Constituent_Parts = self.Constituent_Parts() + other.Constituent_Parts()
21
if len(New_Constituent_Parts) == 1 :
22
Single_Part = New_Constituent_Parts[0]
23
return Single_Part
24
else :
25
return Direct_Sum_Of_Cartan_Groups( New_Constituent_Parts )
26
27
28
def Cartan_Type ( self ) -> CartanType:
29
"""Returns the Cartan type."""
30
return CartanType( self.Cartan_String() )
31
32
33
@staticmethod
34
def Constructor ( *Input:tuple ) -> "Irreducible_Cartan_Group" or "Direct_Sum_Of_Cartan_Groups" :
35
36
def Get_Cartan_Group_From_String ( String:str ) -> "Irreducible_Cartan_Group" or "Direct_Sum_Of_Cartan_Groups" :
37
Summands = []
38
for String_Part_Counter , String_Part in enumerate( String.split('x') , start=1 ) :
39
Cartan_Family = String_Part[0]
40
try : Cartan_Degree = int(String_Part[1:])
41
except : raise ValueError('The algorithm is not able to extract a Cartan degree from the '+str(String_Part_Counter)+'-th string part `'+String_Part+'`.')
42
Summands += [ Irreducible_Cartan_Group( Cartan_Family , Cartan_Degree ) ]
43
44
if len(Summands) == 1 :
45
Single_Summand = Summands[0]
46
return Single_Summand
47
else :
48
return Direct_Sum_Of_Cartan_Groups( Summands )
49
50
def Get_Cartan_Group_From_2Tuple ( Tuple:tuple ) -> "Irreducible_Cartan_Group" :
51
assert len(Tuple) == 2 , \
52
ValueError('The algorithm can not extract Cartan data from a tuple of length '+str(len(Tuple))+'; it expects a tuple of length 2.')
53
54
assert type(Tuple[0]) == str , \
55
TypeError('The algorithm can not extract Cartan family from the first entry of the tuple: Tuple[0] = '+str(Tuple[0])+'.')
56
Cartan_Family = Tuple[0]
57
58
assert Tuple[1] in ZZ , \
59
TypeError('The algorithm can not extract Cartan degree from the second entry of the tuple: Tuple[1] = '+str(Tuple[1])+'.')
60
Cartan_Degree = Tuple[1]
61
62
return Irreducible_Cartan_Group( Cartan_Family , Cartan_Degree )
63
64
if len(Input) == 0 :
65
return Direct_Sum_Of_Cartan_Groups( [] )
66
67
elif len(Input) == 1 :
68
Input = Input[0]
69
70
if Input in [ None , 0 , "" ] :
71
return Direct_Sum_Of_Cartan_Groups( [] )
72
73
elif type(Input) == str :
74
return Get_Cartan_Group_From_String( Input )
75
76
elif type(Input) == list :
77
Result = Direct_Sum_Of_Cartan_Groups( [] )
78
for Entry_Counter , Entry in enumerate( Input , start=1 ) :
79
if type(Entry) == str : Result += Get_Cartan_Group_From_String( Entry )
80
elif type(Entry) == tuple : Result += Get_Cartan_Group_From_2Tuple( Entry )
81
elif type(Entry) == Irreducible_Cartan_Group : Result += Entry
82
elif type(Entry) == Direct_Sum_Of_Cartan_Groups : Result += Entry
83
elif Entry in [ None , 0 , "" ] : pass
84
else : raise TypeError('The '+str(Entry_Counter)+'-th entry of the input is of an inappropriate type.')
85
if Result.Is_Irreducible() : return Result[0]
86
else : return Result
87
88
elif len(Input) == 2 :
89
if type(Input[0]) == str and type(Input[1]) == int : return Get_Cartan_Group_From_2Tuple( *Input )
90
else : return Cartan_Group.Constructor( list(Input) )
91
92
else :
93
return Cartan_Group.Constructor( list(Input) )
94
95
96
# Synonyms for the method ``Weyl_Character``.
97
def rmV ( self , Highest_Weight:"Weight" ) -> "Weyl_Character" :
98
"""Returns the Weyl character associated to given highest weights."""
99
return self.Weyl_Character( Highest_Weight=Highest_Weight )
100
101
102
def Weyl_Character ( self , Highest_Weight:"Weight" ) -> "Weyl_Character" :
103
"""Returns the Weyl character associated to a given highest weight."""
104
WCR = self.Weyl_Character_Ring()
105
return WCR( Highest_Weight )
106
107
108
def Weyl_Character_Ring ( self , Style:str='coroots' ) -> "Weyl_Character_Ring" :
109
"""Returns the Weyl character ring associated to the Cartan type of G."""
110
return WeylCharacterRing( self.Cartan_Type() , style=Style )
111
112
113
114
class Irreducible_Cartan_Group ( Irreducible_Structure , Cartan_Group ) :
115
116
def __init__ ( self , Cartan_Family:str , Cartan_Degree:int ) -> None :
117
"""
118
Initialize an irreducible algebraic group of given cartan type.
119
120
INPUT:
121
- ``Cartan_Family`` -- str;
122
- ``Cartan_Degree`` -- int;
123
124
OUTPUT: None.
125
"""
126
assert Cartan_Family in self.ADMISSIBLE_CARTAN_FAMILIES.keys() , \
127
ValueError('The input for ``Cartan_Degree`` need to be a letter from the alphabet '+str(self.ADMISSIBLE_CARTAN_FAMILIES.keys())+'.')
128
self._Cartan_Family = Cartan_Family
129
130
assert Cartan_Degree in ZZ , \
131
ValueError('The input for ``Cartan_Degree`` need to be an integer.')
132
Lower_Bound , Upper_Bound = self.ADMISSIBLE_CARTAN_FAMILIES[Cartan_Family]
133
assert Lower_Bound <= Cartan_Degree and Cartan_Degree <= Upper_Bound , \
134
ValueError('If the Cartan family is '+str(Cartan_Family)+', then the input for ``Cartan_Degree`` need to between '+str(Lower_Bound)+' and '+str(Upper_Bound)+'.')
135
self._Cartan_Degree = Cartan_Degree
136
137
138
def __repr__ ( self ) -> ( str , int ) :
139
"""Returns all attributes which are necessary to initialize the object."""
140
return self.Cartan_Family() , self.Cartan_Degree()
141
142
143
def __str__ ( self ) :
144
"""Returns a one-line string as short description."""
145
return 'Irreducible Cartan Group of type '+str(self.Cartan_String())+'.'
146
147
148
def __truediv__ ( self , other:"Parabolic_Subgroup_In_Irreducible_Cartan_Group" ) -> "Irreducible_Homogeneous_Variety" :
149
"""Returns the homogeneous variety G/P."""
150
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Parabolic_Subgroup import Parabolic_Subgroup_In_Irreducible_Cartan_Group
151
assert type( other ) == Parabolic_Subgroup_In_Irreducible_Cartan_Group , \
152
TypeError('The divisor need to be a parabolic subgroup.')
153
assert self == other.Parent_Group() , \
154
ValueError('The parabolic subgroup (divisor) need to have ``self`` as parent group.')
155
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Homogeneous_Variety import Irreducible_Homogeneous_Variety
156
return Irreducible_Homogeneous_Variety( other )
157
158
159
def Borel_Subgroup( self ) -> "Parabolic_Subgroup_In_Irreducible_Cartan_Group" :
160
"""Returns the Borel subgroup of G (= minimal parabolic, i.e. no nodes are included)."""
161
return self.Parabolic_Subgroup( Included_Nodes=set({}) , Excluded_Nodes=None )
162
163
164
def Cartan_Degree ( self ) -> int :
165
"""Returns the attribute ``_Cartan_Degree``."""
166
return self._Cartan_Degree
167
168
169
def Cartan_Family ( self ) -> str :
170
"""Returns the attribute ``_Cartan_Family``."""
171
return self._Cartan_Family
172
173
174
def Cartan_String ( self ) -> str :
175
"""Returns the Cartan string."""
176
return self.Cartan_Family()+str(self.Cartan_Degree())
177
178
179
def Dimension ( self ) -> int :
180
"""
181
Return the dimension of ``self`.
182
183
INPUT:
184
- ``self`` -- Cartan_Group; the Cartan group G.
185
186
OUTPUT:
187
- ``Output`` -- Integer; the dimension of G
188
189
ALGORITHM:
190
Thanks to the post by Pieter Belmans concerning the dimension of partial flag varieties
191
from Jun 14th, 2017 on his blog (cf. to [Blog_PieterBelmans]_). The link is
192
https://pbelmans.ncag.info/blog/2017/06/14/dimensions-of-partial-flag-varieties/
193
(Date: Apr 21st, 2021).
194
195
For the Borel group B ⊂ G: dim B = # of positive roots + rank (which accounts for the center)
196
For G: dim G = # of roots in the root system + rank (which accounts for the center)
197
i.e. # of roots in the root system = # of positive roots + # negative roots
198
and # of positive roots = # negative roots
199
so # of roots in the root system = 2 * # of positive roots
200
201
REFERENCE:
202
[Blog_PieterBelmans] https://pbelmans.ncag.info/blog/
203
"""
204
Rank = self.Cartan_Type().dynkin_diagram().rank()
205
Number_Of_Positive_Roots = len( list( self.Cartan_Type().root_system().root_lattice().positive_roots() ) )
206
return Rank + 2 * Number_Of_Positive_Roots
207
208
209
def Is_Exceptional ( self ) -> bool :
210
"""Test if the Cartan family of ``self`` is out of [ E , F , G ]."""
211
return self.ADMISSIBLE_CARTAN_FAMILIES[self.Cartan_Family()][1] < +infinity
212
213
214
def Is_Ordinary ( self ) -> bool :
215
"""Test if the Cartan family of ``self`` is out of [ A , B , C , D ]."""
216
return not self.Is_Exceptional()
217
218
219
def Maximal_Parabolic_Subgroup ( self , Excluded_Node :int ) -> "Parabolic_Subgroup_In_Irreducible_Cartan_Group" :
220
"""
221
Returns the maximal parabolic subgroup associated to the excluded node.
222
It is the parabolic subgroup obtained by adding all neative roots except the ``ExcludedNode``-th one.
223
"""
224
Nodes = set( self.Cartan_Type().index_set() )
225
assert Excluded_Node in Nodes , \
226
ValueError('The excluded node neet to be an element of the set of all nodes ' + str(Nodes) + '.')
227
return self.Parabolic_Subgroup( Included_Nodes=None , Excluded_Nodes={ Excluded_Node } )
228
229
230
def Parabolic_Subgroup ( self , Included_Nodes :set[ int ] or None =None , Excluded_Nodes :set[ int ] or None =None ) -> "Parabolic_Subgroup_In_Irreducible_Cartan_Group" :
231
"""Returns the parabolic subgroup associated to the included nodes.
232
233
INPUT:
234
- ``self`` -- Irreducible_Cartan_Group; the Cartan group G.
235
- ``Included_Nodes`` -- set or None (default: None);
236
- ``Excluded_Nodes`` -- set or None (default: None);
237
238
OUTPUT:
239
- ``Output`` -- Parabolic subgroup; the parabolic subgroup P ⊂ G associated to the included nodes.
240
241
.. NOTE::
242
The Borel subgroup B ⊂ G is the minimal parabolic subgroup obtained by all positive roots and the center.
243
Any further parabolic subgroup is an extension of B by adding a certain amount of negative roots.
244
So ``Included_Nodes`` is the data which negative roots are taken into account.
245
"""
246
Nodes = set( self.Cartan_Type().index_set() )
247
248
# Test the input for ``Included_Nodes`` and ``Excluded_Nodes``
249
if Included_Nodes == None and Excluded_Nodes == None :
250
raise ValueError('There need to be an input for either ``Included_Nodes`` or ``Excluded_Nodes``.')
251
252
elif type(Included_Nodes) == set and Excluded_Nodes == None :
253
assert Included_Nodes.issubset( Nodes ) , \
254
ValueError('The set of included nodes need to be a subset of set of all nodes ' + str( Nodes ) + '.')
255
256
elif Included_Nodes == None and type(Excluded_Nodes) == set :
257
assert Excluded_Nodes.issubset( Nodes ) , \
258
ValueError('The set of excluded nodes need to be a subset of set of all nodes ' + str( Nodes ) + '.')
259
Included_Nodes = Nodes.difference( Excluded_Nodes )
260
261
elif type(Included_Nodes) == set and type(Excluded_Nodes) == set :
262
assert Included_Nodes.union(Excluded_Nodes) == Nodes , \
263
ValueError('The union of included and excluded nodes need to be a the set of all nodes ' + str( Nodes ) + '.')
264
assert Included_Nodes.intersection(Excluded_Nodes) == set([]) , \
265
ValueError('The intersection of included and excluded nodes need to be empty.')
266
267
else :
268
raise ValueError('The inputs for ``Included_Nodes`` and ``Excluded_Nodes`` are of inappropriate values.')
269
270
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Parabolic_Subgroup import Parabolic_Subgroup_In_Irreducible_Cartan_Group
271
return Parabolic_Subgroup_In_Irreducible_Cartan_Group( Parent_Group=self , Included_Nodes=Included_Nodes )
272
273
274
275
class Direct_Sum_Of_Cartan_Groups ( Direct_Sum_Of_Structures , Cartan_Group ) :
276
277
def __init__ ( self , Summands:list[Irreducible_Cartan_Group] ) -> None :
278
"""
279
Initialize an algebraic group of given cartan type.
280
281
INPUT:
282
- ``Input`` -- list[Irreducible_Cartan_Group];
283
284
..ToDo: Do not initalize if len == 0 or == 1.
285
286
OUTPUT: None.
287
"""
288
self._Summands = []
289
for Summand_Counter , Summand in enumerate( Summands , start=1 ) :
290
assert type(Summand) == Irreducible_Cartan_Group , \
291
TypeError('The '+str(Summand_Counter)+'-th component need to be an object of the class ``Irreducible_Cartan_Group``.')
292
self._Summands += [ Summand ]
293
294
295
def __repr__ ( self ) -> list[ Irreducible_Cartan_Group ] :
296
"""Returns all attributes which are necessary to initialize the object."""
297
return self.Summands()
298
299
300
def __str__ ( self ) :
301
"""Returns a one-line string as short description."""
302
if len(self) == 0 : return 'Trivial group.'
303
else : return 'Direct sum of Cartan groups of type '+str(self.Cartan_String())+'.'
304
305
306
def Cartan_Degree ( self ) -> list[int] :
307
"""Returns the Cartan degree of each component of ``self``."""
308
return [ Summand.Cartan_Degree() for Summand in self.Summands() ]
309
310
311
def Cartan_Family ( self ) -> list[str] :
312
"""Returns the Cartan family of each component of ``self``."""
313
return [ Summand.Cartan_Family() for Summand in self.Summands() ]
314
315
316
def Cartan_String ( self ) -> str :
317
"""Returns the Cartan string."""
318
return 'x'.join([ Summand.Cartan_String() for Summand in self.Summands() ])
319
320
321
def Dimension ( self ) -> int :
322
"""Return the dimension of ``self`."""
323
return sum([ Summand.Dimension() for Summand in self.Summands() ])
324
325
326
def Is_Exceptional ( self ) -> list[bool] :
327
"""Test if the Cartan family of each component of ``self`` is out of [ E , F , G ]."""
328
return [ Summand.Is_Exceptional() for Summand in self.Summands() ]
329
330
331
def Is_Ordinary ( self ) -> list[bool] :
332
"""Test if the Cartan family of each component of ``self`` is out of [ A , B , C , D ]."""
333
return [ Summand.Is_Ordinary() for Summand in self.Summands() ]
334
335
336
337
338