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 typing import Iterator
2
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Foundation.Structure import Structure , Irreducible_Structure
3
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Cartan_Group import Irreducible_Cartan_Group , Direct_Sum_Of_Cartan_Groups
4
5
6
7
class Parabolic_Subgroup ( Structure ) :
8
pass
9
10
11
12
class Parabolic_Subgroup_In_Irreducible_Cartan_Group ( Irreducible_Structure , Parabolic_Subgroup ) :
13
14
def __init__( self , Parent_Group:Irreducible_Cartan_Group , Included_Nodes:set=set([]) ) -> None :
15
"""
16
Initialize an algebraic group of given cartan type over a base field.
17
18
INPUT:
19
- ``Parent_Group`` -- Irreducible_Cartan_Group;
20
The parent group G
21
- ``Included_Nodes`` -- set;
22
A parabolic subgroup is uniquely determined by taking the Borel subgroup B ⊂ G and adding the negative roots which are marked.
23
24
OUTPUT: None.
25
"""
26
assert type( Parent_Group ) == Irreducible_Cartan_Group , \
27
TypeError('The parent group must be an irreducible Cartan group.')
28
self._Parent_Group = Parent_Group
29
30
assert type( Included_Nodes ) == set , \
31
TypeError('The included nodes must be given as set.')
32
Nodes = set( Parent_Group.Cartan_Type().index_set() )
33
assert Included_Nodes.issubset( Nodes ) , \
34
ValueError('The set of included nodes must be a subset of all admissible nodes ' + str(Nodes) + '.')
35
self._Included_Nodes = Included_Nodes
36
37
38
def __repr__ ( self ) -> ( Irreducible_Cartan_Group , set ) :
39
"""Returns all attributes which are necessary to initialize the object."""
40
return self.Parent_Group() , self.Included_Nodes()
41
42
43
def __str__ ( self ) -> str :
44
"""Returns a one-line string as short description."""
45
return 'Parabolic subgroup P(' + str( self.Included_Nodes() ) + ') in irreducible Cartan group of type ' + self.Parent_Group().Cartan_String() + '.'
46
47
48
def Cartan_Data ( self ) -> ( str , int ) :
49
"""Returns the Cartan data of each irreducible component of ``self``."""
50
for Connected_Component in self.Connected_Components_Of_Included_Nodes() :
51
Cartan_Subtype = self.Parent_Group().Cartan_Type().subtype( Connected_Component )
52
yield Cartan_Subtype.type() , len(Cartan_Subtype.index_set())
53
54
55
def Cartan_String ( self ) -> str :
56
"""Returns the Cartan string of ``self``."""
57
return 'x'.join([ Cartan_Family+str(Cartan_Degree) for Cartan_Family , Cartan_Degree in self.Cartan_Data() ])
58
59
60
def Cartan_Type ( self ) -> CartanType :
61
"""Returns the Cartan type of ``self``."""
62
return CartanType( self.Cartan_String() )
63
64
65
def Connected_Components_Of_Included_Nodes ( self ) -> Iterator[list]:
66
"""
67
Returns the included nodes subdivided into lists of connected components
68
(i.e. lists of nodes which are connected by edges).
69
"""
70
return ( list( Dict.keys() ) for Dict in self.Relabelling(Decomposition_Style='Fine') )
71
72
73
def Dimension ( self ) -> int :
74
"""
75
Returns the dimension of ``self``.
76
77
INPUT:
78
- ``self`` -- ParabolicSubgroup; the parabolic subgroup P of a Cartan group G.
79
80
OUTPUT:
81
- ``Output`` -- Integer; the dimension of ``self``.
82
83
ALGORITHM:
84
Thanks to the post by Pieter Belmans concerning the dimension of partial flag varieties
85
from Jun 14th, 2017 on his blog (cf. to [Blog_PieterBelmans]_). The link is
86
https://pbelmans.ncag.info/blog/2017/06/14/dimensions-of-partial-flag-varieties/
87
(Date: Apr 21st, 2021).
88
89
For the Borel group B ⊂ G: dim B = # of positive roots + rank (which accounts for the center)
90
For P: dim P = dim B + # of negative roots which are added to construct P
91
92
REFERENCE:
93
[Blog_PieterBelmans] https://pbelmans.ncag.info/blog/
94
"""
95
Rank = self.Parent_Group().Cartan_Type().dynkin_diagram().rank()
96
Number_Of_Positive_Roots = len( list( self.Parent_Group().Cartan_Type().root_system().root_lattice().positive_roots() ) )
97
Number_Of_Available_Negative_Roots = len( self.Negative_Roots() )
98
return Rank + Number_Of_Positive_Roots + Number_Of_Available_Negative_Roots
99
100
101
def Excluded_Nodes ( self , Output_Type:set or list or str=set ) -> set or list or str :
102
"""Returns the excluded nodes."""
103
Nodes = set( self.Parent_Group().Cartan_Type().index_set() )
104
Output = list(Nodes.difference(self.Included_Nodes()))
105
Output.sort()
106
if Output_Type != set :
107
if Output_Type == list : return Output
108
elif Output_Type == str : return ','.join(Output)
109
else : raise TypeError('The input for ``Output_Type`` is inappropriate.')
110
else :
111
return set(Output)
112
113
114
def Included_Nodes ( self , Output_Type:set or list or str=set ) -> set or list or str :
115
"""Returns the attribute ``_Included_Nodes``."""
116
Output = list(self._Included_Nodes)
117
Output.sort()
118
if Output_Type != set :
119
if Output_Type == list : return Output
120
elif Output_Type == str : return ','.join(Output)
121
else : raise TypeError('The input for ``Output_Type`` is inappropriate.')
122
else :
123
return set(Output)
124
125
126
def Initialize_As_Cartan_Group ( self ) -> Irreducible_Cartan_Group or Reducible_Cartan_Group :
127
"""
128
Returns the Cartan group associated to the Cartan string of ``self``.
129
Thus, one has access to the methods of the class ``Cartan_Group`` and its subclasses.
130
"""
131
Components = [ Irreducible_Cartan_Group( Cartan_Family , Cartan_Degree ) for Cartan_Family , Cartan_Degree in self.Cartan_Data() ]
132
if len(Components) == 1 : return Components[0]
133
else : return Direct_Sum_Of_Cartan_Groups( Components )
134
135
136
# Synonym for the method ``Is_Minimal``
137
def Is_Borel ( self ) -> bool :
138
"""Test if ``self`` is Borel (i.e. it is minimal)."""
139
return self.Is_Minimal()
140
141
142
def Is_Complete ( self ) -> bool :
143
"""Test if ``self`` is complete (i.e. all nodes are included; or equivalently, no node is excluded)."""
144
return len( self.Excluded_Nodes(Output_Type=list) ) == 0
145
146
147
def Is_Maximal ( self ) -> bool :
148
"""Test if ``self`` is maximal (i.e. almost all nodes are included; or equivalently, there is only one node excluded)."""
149
return len( self.Excluded_Nodes(Output_Type=list) ) == 1
150
151
152
def Is_Minimal ( self ) -> bool :
153
"""Test if ``self`` is minimal (i.e. no node is included; or equivalently, all nodes are excluded)."""
154
return len( self.Included_Nodes(Output_Type=list) ) == 0
155
156
157
# Synonym for the method ``Is_Complete``
158
def Is_Parent_Group ( self ) -> bool :
159
"""Test if ``self`` coincides with the parent group (i.e. it is complete)."""
160
return self.Is_Complete()
161
162
163
def Negative_Roots ( self ) -> list :
164
"""Returns a list of all negative roots which are available for ``self``."""
165
return [ Negative_Root for Negative_Root in list( self.Parent_Group().Cartan_Type().root_system().root_lattice().negative_roots() )
166
if not False in [ Node in self.Included_Nodes() for Node , Coefficient in Negative_Root ]
167
]
168
169
170
def Parent_Group ( self ) -> Irreducible_Cartan_Group :
171
"""Returns the attribute ``_Parent_Group``."""
172
return self._Parent_Group
173
174
175
def Relabelling ( self , Decomposition_Style:'Fine' or 'Coarse'='Coarse' ) -> dict or list[dict] :
176
"""Returns the relabelling of the included nodes with respect to the parent group."""
177
if Decomposition_Style == 'Coarse' :
178
return { Included_Node : Counter for Counter , Included_Node in enumerate( self.Included_Nodes(Output_Type=list) , start=1 ) }
179
180
elif Decomposition_Style == 'Fine' :
181
Connected_Components = []
182
Included_Nodes = self.Included_Nodes(Output_Type=list)
183
Cartan_Family = self.Parent_Group().Cartan_Family()
184
Cartan_Degree = self.Parent_Group().Cartan_Degree()
185
End = Cartan_Degree
186
187
# For the case "Cartan_Family == E", the Dynkin-diagram-ordering is sligthly is different from a lexicographical-ordering.
188
# In particluar, th second node is onyl one-connected to the fourth one and NOT between the third and fourth one.
189
if not Cartan_Family == 'E' :
190
Included_Nodes_In_Order_As_Given_By_Dynkin_Diagram = Included_Nodes
191
else :
192
Included_Nodes_In_Order_As_Given_By_Dynkin_Diagram = [ Included_Node for Included_Node in [ 1 , 3 , 4 , 2 ] + [ 5 .. End ] if Included_Node in Included_Nodes ]
193
194
# We establish connected components of all included nodes
195
for Node_Counter , Current_Node in enumerate( Included_Nodes_In_Order_As_Given_By_Dynkin_Diagram , start=1 ) :
196
Is_Current_Node_In_Some_Connected_Component = False
197
198
# The first included nodes gives arise to the first connected component ...
199
if Node_Counter == 1 :
200
Connected_Components += [ [ Current_Node ] ]
201
Is_Current_Node_In_Some_Connected_Component = True
202
203
# Is the currently considered node element of an already existing connected component?
204
else :
205
if Cartan_Family == 'D' :
206
for Connected_Component in Connected_Components :
207
if ( ( Current_Node <= End-2 and Current_Node-1 in Connected_Component ) or # k-th node is connected with the (k-1)-th node (k <= n-2)
208
( Current_Node == End-1 and End-1 in Connected_Component ) or # (n-1)-th node is connected with the (n-2)-th node
209
( Current_Node == End and End-2 in Connected_Component ) # n-th node is connected with the (n-2)-th node
210
) :
211
Connected_Component += [ Current_Node ]
212
Is_Current_Node_In_Some_Connected_Component = True
213
break
214
215
elif Cartan_Family == 'E' :
216
for Connected_Component in Connected_Components :
217
if ( ( Current_Node == 3 and Current_Node-2 in Connected_Component ) or # 3rd node
218
( Current_Node == 4 and Current_Node-1 in Connected_Component ) or # 4th node
219
( Current_Node == 2 and Current_Node+2 in Connected_Component ) or # 2nd node
220
( 5 <= Current_Node and Current_Node-1 in Connected_Component ) # 5th/ 6th/ ... node
221
) :
222
Connected_Component += [ Current_Node ]
223
Is_Current_Node_In_Some_Connected_Component = True
224
break
225
226
else :
227
for Connected_Component in Connected_Components :
228
if Current_Node-1 in Connected_Component :
229
Connected_Component += [ Current_Node ]
230
Is_Current_Node_In_Some_Connected_Component = True
231
break
232
233
# If the currently considered node seems to be not element of one of the existing connected components.
234
# Hence, we establish a new connected component ...
235
if not Is_Current_Node_In_Some_Connected_Component : Connected_Components += [ [ Current_Node ] ]
236
237
Relabelling = []
238
for Connected_Component in Connected_Components :
239
Connected_Component.sort()
240
Relabelling += [ { Included_Node : Node_Counter_In_Connected_Component for Node_Counter_In_Connected_Component , Included_Node in enumerate( Connected_Component , start=1 ) } ]
241
return Relabelling
242
243
else : raise ValueError('The input for ``Decomposition_Style`` is inappropriate.')
244
245
246
247
#class Parabolic_Subgroup_In_Direct_Sum_Of_Cartan_Groups ( Direct_Sum_Of_Structures , Parabolic_Subgroup ) :
248
#
249
# def Dimension ( self ) -> int :
250
# """Returns the dimension of ``self``."""
251
# return sum([ Component.Dimension() for Component in self.Components() ])
252