Environment to perform calculations of equivariant vector bundles on homogeneous varieties
Equivariant_Vector_Bundles_On_Homogeneous_Varieties__0-2 / src / Equivariant_Vector_Bundles_On_Homogeneous_Varieties / Base_Space / Parabolic_Subgroup.sage
1842 viewsLicense: GPL3
ubuntu2204
from typing import Iterator1from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Foundation.Structure import Structure , Irreducible_Structure2from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Cartan_Group import Irreducible_Cartan_Group , Direct_Sum_Of_Cartan_Groups3456class Parabolic_Subgroup ( Structure ) :7pass891011class Parabolic_Subgroup_In_Irreducible_Cartan_Group ( Irreducible_Structure , Parabolic_Subgroup ) :1213def __init__( self , Parent_Group:Irreducible_Cartan_Group , Included_Nodes:set=set([]) ) -> None :14"""15Initialize an algebraic group of given cartan type over a base field.1617INPUT:18- ``Parent_Group`` -- Irreducible_Cartan_Group;19The parent group G20- ``Included_Nodes`` -- set;21A parabolic subgroup is uniquely determined by taking the Borel subgroup B ⊂ G and adding the negative roots which are marked.2223OUTPUT: None.24"""25assert type( Parent_Group ) == Irreducible_Cartan_Group , \26TypeError('The parent group must be an irreducible Cartan group.')27self._Parent_Group = Parent_Group2829assert type( Included_Nodes ) == set , \30TypeError('The included nodes must be given as set.')31Nodes = set( Parent_Group.Cartan_Type().index_set() )32assert Included_Nodes.issubset( Nodes ) , \33ValueError('The set of included nodes must be a subset of all admissible nodes ' + str(Nodes) + '.')34self._Included_Nodes = Included_Nodes353637def __repr__ ( self ) -> ( Irreducible_Cartan_Group , set ) :38"""Returns all attributes which are necessary to initialize the object."""39return self.Parent_Group() , self.Included_Nodes()404142def __str__ ( self ) -> str :43"""Returns a one-line string as short description."""44return 'Parabolic subgroup P(' + str( self.Included_Nodes() ) + ') in irreducible Cartan group of type ' + self.Parent_Group().Cartan_String() + '.'454647def Cartan_Data ( self ) -> ( str , int ) :48"""Returns the Cartan data of each irreducible component of ``self``."""49for Connected_Component in self.Connected_Components_Of_Included_Nodes() :50Cartan_Subtype = self.Parent_Group().Cartan_Type().subtype( Connected_Component )51yield Cartan_Subtype.type() , len(Cartan_Subtype.index_set())525354def Cartan_String ( self ) -> str :55"""Returns the Cartan string of ``self``."""56return 'x'.join([ Cartan_Family+str(Cartan_Degree) for Cartan_Family , Cartan_Degree in self.Cartan_Data() ])575859def Cartan_Type ( self ) -> CartanType :60"""Returns the Cartan type of ``self``."""61return CartanType( self.Cartan_String() )626364def Connected_Components_Of_Included_Nodes ( self ) -> Iterator[list]:65"""66Returns the included nodes subdivided into lists of connected components67(i.e. lists of nodes which are connected by edges).68"""69return ( list( Dict.keys() ) for Dict in self.Relabelling(Decomposition_Style='Fine') )707172def Dimension ( self ) -> int :73"""74Returns the dimension of ``self``.7576INPUT:77- ``self`` -- ParabolicSubgroup; the parabolic subgroup P of a Cartan group G.7879OUTPUT:80- ``Output`` -- Integer; the dimension of ``self``.8182ALGORITHM:83Thanks to the post by Pieter Belmans concerning the dimension of partial flag varieties84from Jun 14th, 2017 on his blog (cf. to [Blog_PieterBelmans]_). The link is85https://pbelmans.ncag.info/blog/2017/06/14/dimensions-of-partial-flag-varieties/86(Date: Apr 21st, 2021).8788For the Borel group B ⊂ G: dim B = # of positive roots + rank (which accounts for the center)89For P: dim P = dim B + # of negative roots which are added to construct P9091REFERENCE:92[Blog_PieterBelmans] https://pbelmans.ncag.info/blog/93"""94Rank = self.Parent_Group().Cartan_Type().dynkin_diagram().rank()95Number_Of_Positive_Roots = len( list( self.Parent_Group().Cartan_Type().root_system().root_lattice().positive_roots() ) )96Number_Of_Available_Negative_Roots = len( self.Negative_Roots() )97return Rank + Number_Of_Positive_Roots + Number_Of_Available_Negative_Roots9899100def Excluded_Nodes ( self , Output_Type:set or list or str=set ) -> set or list or str :101"""Returns the excluded nodes."""102Nodes = set( self.Parent_Group().Cartan_Type().index_set() )103Output = list(Nodes.difference(self.Included_Nodes()))104Output.sort()105if Output_Type != set :106if Output_Type == list : return Output107elif Output_Type == str : return ','.join(Output)108else : raise TypeError('The input for ``Output_Type`` is inappropriate.')109else :110return set(Output)111112113def Included_Nodes ( self , Output_Type:set or list or str=set ) -> set or list or str :114"""Returns the attribute ``_Included_Nodes``."""115Output = list(self._Included_Nodes)116Output.sort()117if Output_Type != set :118if Output_Type == list : return Output119elif Output_Type == str : return ','.join(Output)120else : raise TypeError('The input for ``Output_Type`` is inappropriate.')121else :122return set(Output)123124125def Initialize_As_Cartan_Group ( self ) -> Irreducible_Cartan_Group or Reducible_Cartan_Group :126"""127Returns the Cartan group associated to the Cartan string of ``self``.128Thus, one has access to the methods of the class ``Cartan_Group`` and its subclasses.129"""130Components = [ Irreducible_Cartan_Group( Cartan_Family , Cartan_Degree ) for Cartan_Family , Cartan_Degree in self.Cartan_Data() ]131if len(Components) == 1 : return Components[0]132else : return Direct_Sum_Of_Cartan_Groups( Components )133134135# Synonym for the method ``Is_Minimal``136def Is_Borel ( self ) -> bool :137"""Test if ``self`` is Borel (i.e. it is minimal)."""138return self.Is_Minimal()139140141def Is_Complete ( self ) -> bool :142"""Test if ``self`` is complete (i.e. all nodes are included; or equivalently, no node is excluded)."""143return len( self.Excluded_Nodes(Output_Type=list) ) == 0144145146def Is_Maximal ( self ) -> bool :147"""Test if ``self`` is maximal (i.e. almost all nodes are included; or equivalently, there is only one node excluded)."""148return len( self.Excluded_Nodes(Output_Type=list) ) == 1149150151def Is_Minimal ( self ) -> bool :152"""Test if ``self`` is minimal (i.e. no node is included; or equivalently, all nodes are excluded)."""153return len( self.Included_Nodes(Output_Type=list) ) == 0154155156# Synonym for the method ``Is_Complete``157def Is_Parent_Group ( self ) -> bool :158"""Test if ``self`` coincides with the parent group (i.e. it is complete)."""159return self.Is_Complete()160161162def Negative_Roots ( self ) -> list :163"""Returns a list of all negative roots which are available for ``self``."""164return [ Negative_Root for Negative_Root in list( self.Parent_Group().Cartan_Type().root_system().root_lattice().negative_roots() )165if not False in [ Node in self.Included_Nodes() for Node , Coefficient in Negative_Root ]166]167168169def Parent_Group ( self ) -> Irreducible_Cartan_Group :170"""Returns the attribute ``_Parent_Group``."""171return self._Parent_Group172173174def Relabelling ( self , Decomposition_Style:'Fine' or 'Coarse'='Coarse' ) -> dict or list[dict] :175"""Returns the relabelling of the included nodes with respect to the parent group."""176if Decomposition_Style == 'Coarse' :177return { Included_Node : Counter for Counter , Included_Node in enumerate( self.Included_Nodes(Output_Type=list) , start=1 ) }178179elif Decomposition_Style == 'Fine' :180Connected_Components = []181Included_Nodes = self.Included_Nodes(Output_Type=list)182Cartan_Family = self.Parent_Group().Cartan_Family()183Cartan_Degree = self.Parent_Group().Cartan_Degree()184End = Cartan_Degree185186# For the case "Cartan_Family == E", the Dynkin-diagram-ordering is sligthly is different from a lexicographical-ordering.187# In particluar, th second node is onyl one-connected to the fourth one and NOT between the third and fourth one.188if not Cartan_Family == 'E' :189Included_Nodes_In_Order_As_Given_By_Dynkin_Diagram = Included_Nodes190else :191Included_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 ]192193# We establish connected components of all included nodes194for Node_Counter , Current_Node in enumerate( Included_Nodes_In_Order_As_Given_By_Dynkin_Diagram , start=1 ) :195Is_Current_Node_In_Some_Connected_Component = False196197# The first included nodes gives arise to the first connected component ...198if Node_Counter == 1 :199Connected_Components += [ [ Current_Node ] ]200Is_Current_Node_In_Some_Connected_Component = True201202# Is the currently considered node element of an already existing connected component?203else :204if Cartan_Family == 'D' :205for Connected_Component in Connected_Components :206if ( ( 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)207( Current_Node == End-1 and End-1 in Connected_Component ) or # (n-1)-th node is connected with the (n-2)-th node208( Current_Node == End and End-2 in Connected_Component ) # n-th node is connected with the (n-2)-th node209) :210Connected_Component += [ Current_Node ]211Is_Current_Node_In_Some_Connected_Component = True212break213214elif Cartan_Family == 'E' :215for Connected_Component in Connected_Components :216if ( ( Current_Node == 3 and Current_Node-2 in Connected_Component ) or # 3rd node217( Current_Node == 4 and Current_Node-1 in Connected_Component ) or # 4th node218( Current_Node == 2 and Current_Node+2 in Connected_Component ) or # 2nd node219( 5 <= Current_Node and Current_Node-1 in Connected_Component ) # 5th/ 6th/ ... node220) :221Connected_Component += [ Current_Node ]222Is_Current_Node_In_Some_Connected_Component = True223break224225else :226for Connected_Component in Connected_Components :227if Current_Node-1 in Connected_Component :228Connected_Component += [ Current_Node ]229Is_Current_Node_In_Some_Connected_Component = True230break231232# If the currently considered node seems to be not element of one of the existing connected components.233# Hence, we establish a new connected component ...234if not Is_Current_Node_In_Some_Connected_Component : Connected_Components += [ [ Current_Node ] ]235236Relabelling = []237for Connected_Component in Connected_Components :238Connected_Component.sort()239Relabelling += [ { Included_Node : Node_Counter_In_Connected_Component for Node_Counter_In_Connected_Component , Included_Node in enumerate( Connected_Component , start=1 ) } ]240return Relabelling241242else : raise ValueError('The input for ``Decomposition_Style`` is inappropriate.')243244245246#class Parabolic_Subgroup_In_Direct_Sum_Of_Cartan_Groups ( Direct_Sum_Of_Structures , Parabolic_Subgroup ) :247#248# def Dimension ( self ) -> int :249# """Returns the dimension of ``self``."""250# return sum([ Component.Dimension() for Component in self.Components() ])251252