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 / Cartan_Group.sage
1842 viewsLicense: GPL3
ubuntu2204
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Foundation.Structure import Irreducible_Structure , Direct_Sum_Of_Structures1234class Cartan_Group ( object ) :56ADMISSIBLE_CARTAN_FAMILIES = { 'A' : ( 1 , +infinity ) ,7'B' : ( 2 , +infinity ) ,8'C' : ( 2 , +infinity ) ,9'D' : ( 3 , +infinity ) ,10'E' : ( 6 , 8 ) ,11'F' : ( 4 , 4 ) ,12'G' : ( 2 , 2 )13}141516def __add__ ( self , other:"Cartan_Group" ) -> "Irreducible_Cartan_Group" or "Direct_Sum_Of_Cartan_Groups" :17"""Returns the coproduct of two Cartan groups."""18assert isinstance( other , type(self).__bases__[1] ) , 'The input for ``other`` need to be an object of the class '+str( type(self).__bases__[1] )+'.'19New_Constituent_Parts = self.Constituent_Parts() + other.Constituent_Parts()20if len(New_Constituent_Parts) == 1 :21Single_Part = New_Constituent_Parts[0]22return Single_Part23else :24return Direct_Sum_Of_Cartan_Groups( New_Constituent_Parts )252627def Cartan_Type ( self ) -> CartanType:28"""Returns the Cartan type."""29return CartanType( self.Cartan_String() )303132@staticmethod33def Constructor ( *Input:tuple ) -> "Irreducible_Cartan_Group" or "Direct_Sum_Of_Cartan_Groups" :3435def Get_Cartan_Group_From_String ( String:str ) -> "Irreducible_Cartan_Group" or "Direct_Sum_Of_Cartan_Groups" :36Summands = []37for String_Part_Counter , String_Part in enumerate( String.split('x') , start=1 ) :38Cartan_Family = String_Part[0]39try : Cartan_Degree = int(String_Part[1:])40except : raise ValueError('The algorithm is not able to extract a Cartan degree from the '+str(String_Part_Counter)+'-th string part `'+String_Part+'`.')41Summands += [ Irreducible_Cartan_Group( Cartan_Family , Cartan_Degree ) ]4243if len(Summands) == 1 :44Single_Summand = Summands[0]45return Single_Summand46else :47return Direct_Sum_Of_Cartan_Groups( Summands )4849def Get_Cartan_Group_From_2Tuple ( Tuple:tuple ) -> "Irreducible_Cartan_Group" :50assert len(Tuple) == 2 , \51ValueError('The algorithm can not extract Cartan data from a tuple of length '+str(len(Tuple))+'; it expects a tuple of length 2.')5253assert type(Tuple[0]) == str , \54TypeError('The algorithm can not extract Cartan family from the first entry of the tuple: Tuple[0] = '+str(Tuple[0])+'.')55Cartan_Family = Tuple[0]5657assert Tuple[1] in ZZ , \58TypeError('The algorithm can not extract Cartan degree from the second entry of the tuple: Tuple[1] = '+str(Tuple[1])+'.')59Cartan_Degree = Tuple[1]6061return Irreducible_Cartan_Group( Cartan_Family , Cartan_Degree )6263if len(Input) == 0 :64return Direct_Sum_Of_Cartan_Groups( [] )6566elif len(Input) == 1 :67Input = Input[0]6869if Input in [ None , 0 , "" ] :70return Direct_Sum_Of_Cartan_Groups( [] )7172elif type(Input) == str :73return Get_Cartan_Group_From_String( Input )7475elif type(Input) == list :76Result = Direct_Sum_Of_Cartan_Groups( [] )77for Entry_Counter , Entry in enumerate( Input , start=1 ) :78if type(Entry) == str : Result += Get_Cartan_Group_From_String( Entry )79elif type(Entry) == tuple : Result += Get_Cartan_Group_From_2Tuple( Entry )80elif type(Entry) == Irreducible_Cartan_Group : Result += Entry81elif type(Entry) == Direct_Sum_Of_Cartan_Groups : Result += Entry82elif Entry in [ None , 0 , "" ] : pass83else : raise TypeError('The '+str(Entry_Counter)+'-th entry of the input is of an inappropriate type.')84if Result.Is_Irreducible() : return Result[0]85else : return Result8687elif len(Input) == 2 :88if type(Input[0]) == str and type(Input[1]) == int : return Get_Cartan_Group_From_2Tuple( *Input )89else : return Cartan_Group.Constructor( list(Input) )9091else :92return Cartan_Group.Constructor( list(Input) )939495# Synonyms for the method ``Weyl_Character``.96def rmV ( self , Highest_Weight:"Weight" ) -> "Weyl_Character" :97"""Returns the Weyl character associated to given highest weights."""98return self.Weyl_Character( Highest_Weight=Highest_Weight )99100101def Weyl_Character ( self , Highest_Weight:"Weight" ) -> "Weyl_Character" :102"""Returns the Weyl character associated to a given highest weight."""103WCR = self.Weyl_Character_Ring()104return WCR( Highest_Weight )105106107def Weyl_Character_Ring ( self , Style:str='coroots' ) -> "Weyl_Character_Ring" :108"""Returns the Weyl character ring associated to the Cartan type of G."""109return WeylCharacterRing( self.Cartan_Type() , style=Style )110111112113class Irreducible_Cartan_Group ( Irreducible_Structure , Cartan_Group ) :114115def __init__ ( self , Cartan_Family:str , Cartan_Degree:int ) -> None :116"""117Initialize an irreducible algebraic group of given cartan type.118119INPUT:120- ``Cartan_Family`` -- str;121- ``Cartan_Degree`` -- int;122123OUTPUT: None.124"""125assert Cartan_Family in self.ADMISSIBLE_CARTAN_FAMILIES.keys() , \126ValueError('The input for ``Cartan_Degree`` need to be a letter from the alphabet '+str(self.ADMISSIBLE_CARTAN_FAMILIES.keys())+'.')127self._Cartan_Family = Cartan_Family128129assert Cartan_Degree in ZZ , \130ValueError('The input for ``Cartan_Degree`` need to be an integer.')131Lower_Bound , Upper_Bound = self.ADMISSIBLE_CARTAN_FAMILIES[Cartan_Family]132assert Lower_Bound <= Cartan_Degree and Cartan_Degree <= Upper_Bound , \133ValueError('If the Cartan family is '+str(Cartan_Family)+', then the input for ``Cartan_Degree`` need to between '+str(Lower_Bound)+' and '+str(Upper_Bound)+'.')134self._Cartan_Degree = Cartan_Degree135136137def __repr__ ( self ) -> ( str , int ) :138"""Returns all attributes which are necessary to initialize the object."""139return self.Cartan_Family() , self.Cartan_Degree()140141142def __str__ ( self ) :143"""Returns a one-line string as short description."""144return 'Irreducible Cartan Group of type '+str(self.Cartan_String())+'.'145146147def __truediv__ ( self , other:"Parabolic_Subgroup_In_Irreducible_Cartan_Group" ) -> "Irreducible_Homogeneous_Variety" :148"""Returns the homogeneous variety G/P."""149from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Parabolic_Subgroup import Parabolic_Subgroup_In_Irreducible_Cartan_Group150assert type( other ) == Parabolic_Subgroup_In_Irreducible_Cartan_Group , \151TypeError('The divisor need to be a parabolic subgroup.')152assert self == other.Parent_Group() , \153ValueError('The parabolic subgroup (divisor) need to have ``self`` as parent group.')154from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Homogeneous_Variety import Irreducible_Homogeneous_Variety155return Irreducible_Homogeneous_Variety( other )156157158def Borel_Subgroup( self ) -> "Parabolic_Subgroup_In_Irreducible_Cartan_Group" :159"""Returns the Borel subgroup of G (= minimal parabolic, i.e. no nodes are included)."""160return self.Parabolic_Subgroup( Included_Nodes=set({}) , Excluded_Nodes=None )161162163def Cartan_Degree ( self ) -> int :164"""Returns the attribute ``_Cartan_Degree``."""165return self._Cartan_Degree166167168def Cartan_Family ( self ) -> str :169"""Returns the attribute ``_Cartan_Family``."""170return self._Cartan_Family171172173def Cartan_String ( self ) -> str :174"""Returns the Cartan string."""175return self.Cartan_Family()+str(self.Cartan_Degree())176177178def Dimension ( self ) -> int :179"""180Return the dimension of ``self`.181182INPUT:183- ``self`` -- Cartan_Group; the Cartan group G.184185OUTPUT:186- ``Output`` -- Integer; the dimension of G187188ALGORITHM:189Thanks to the post by Pieter Belmans concerning the dimension of partial flag varieties190from Jun 14th, 2017 on his blog (cf. to [Blog_PieterBelmans]_). The link is191https://pbelmans.ncag.info/blog/2017/06/14/dimensions-of-partial-flag-varieties/192(Date: Apr 21st, 2021).193194For the Borel group B ⊂ G: dim B = # of positive roots + rank (which accounts for the center)195For G: dim G = # of roots in the root system + rank (which accounts for the center)196i.e. # of roots in the root system = # of positive roots + # negative roots197and # of positive roots = # negative roots198so # of roots in the root system = 2 * # of positive roots199200REFERENCE:201[Blog_PieterBelmans] https://pbelmans.ncag.info/blog/202"""203Rank = self.Cartan_Type().dynkin_diagram().rank()204Number_Of_Positive_Roots = len( list( self.Cartan_Type().root_system().root_lattice().positive_roots() ) )205return Rank + 2 * Number_Of_Positive_Roots206207208def Is_Exceptional ( self ) -> bool :209"""Test if the Cartan family of ``self`` is out of [ E , F , G ]."""210return self.ADMISSIBLE_CARTAN_FAMILIES[self.Cartan_Family()][1] < +infinity211212213def Is_Ordinary ( self ) -> bool :214"""Test if the Cartan family of ``self`` is out of [ A , B , C , D ]."""215return not self.Is_Exceptional()216217218def Maximal_Parabolic_Subgroup ( self , Excluded_Node :int ) -> "Parabolic_Subgroup_In_Irreducible_Cartan_Group" :219"""220Returns the maximal parabolic subgroup associated to the excluded node.221It is the parabolic subgroup obtained by adding all neative roots except the ``ExcludedNode``-th one.222"""223Nodes = set( self.Cartan_Type().index_set() )224assert Excluded_Node in Nodes , \225ValueError('The excluded node neet to be an element of the set of all nodes ' + str(Nodes) + '.')226return self.Parabolic_Subgroup( Included_Nodes=None , Excluded_Nodes={ Excluded_Node } )227228229def Parabolic_Subgroup ( self , Included_Nodes :set[ int ] or None =None , Excluded_Nodes :set[ int ] or None =None ) -> "Parabolic_Subgroup_In_Irreducible_Cartan_Group" :230"""Returns the parabolic subgroup associated to the included nodes.231232INPUT:233- ``self`` -- Irreducible_Cartan_Group; the Cartan group G.234- ``Included_Nodes`` -- set or None (default: None);235- ``Excluded_Nodes`` -- set or None (default: None);236237OUTPUT:238- ``Output`` -- Parabolic subgroup; the parabolic subgroup P ⊂ G associated to the included nodes.239240.. NOTE::241The Borel subgroup B ⊂ G is the minimal parabolic subgroup obtained by all positive roots and the center.242Any further parabolic subgroup is an extension of B by adding a certain amount of negative roots.243So ``Included_Nodes`` is the data which negative roots are taken into account.244"""245Nodes = set( self.Cartan_Type().index_set() )246247# Test the input for ``Included_Nodes`` and ``Excluded_Nodes``248if Included_Nodes == None and Excluded_Nodes == None :249raise ValueError('There need to be an input for either ``Included_Nodes`` or ``Excluded_Nodes``.')250251elif type(Included_Nodes) == set and Excluded_Nodes == None :252assert Included_Nodes.issubset( Nodes ) , \253ValueError('The set of included nodes need to be a subset of set of all nodes ' + str( Nodes ) + '.')254255elif Included_Nodes == None and type(Excluded_Nodes) == set :256assert Excluded_Nodes.issubset( Nodes ) , \257ValueError('The set of excluded nodes need to be a subset of set of all nodes ' + str( Nodes ) + '.')258Included_Nodes = Nodes.difference( Excluded_Nodes )259260elif type(Included_Nodes) == set and type(Excluded_Nodes) == set :261assert Included_Nodes.union(Excluded_Nodes) == Nodes , \262ValueError('The union of included and excluded nodes need to be a the set of all nodes ' + str( Nodes ) + '.')263assert Included_Nodes.intersection(Excluded_Nodes) == set([]) , \264ValueError('The intersection of included and excluded nodes need to be empty.')265266else :267raise ValueError('The inputs for ``Included_Nodes`` and ``Excluded_Nodes`` are of inappropriate values.')268269from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Parabolic_Subgroup import Parabolic_Subgroup_In_Irreducible_Cartan_Group270return Parabolic_Subgroup_In_Irreducible_Cartan_Group( Parent_Group=self , Included_Nodes=Included_Nodes )271272273274class Direct_Sum_Of_Cartan_Groups ( Direct_Sum_Of_Structures , Cartan_Group ) :275276def __init__ ( self , Summands:list[Irreducible_Cartan_Group] ) -> None :277"""278Initialize an algebraic group of given cartan type.279280INPUT:281- ``Input`` -- list[Irreducible_Cartan_Group];282283..ToDo: Do not initalize if len == 0 or == 1.284285OUTPUT: None.286"""287self._Summands = []288for Summand_Counter , Summand in enumerate( Summands , start=1 ) :289assert type(Summand) == Irreducible_Cartan_Group , \290TypeError('The '+str(Summand_Counter)+'-th component need to be an object of the class ``Irreducible_Cartan_Group``.')291self._Summands += [ Summand ]292293294def __repr__ ( self ) -> list[ Irreducible_Cartan_Group ] :295"""Returns all attributes which are necessary to initialize the object."""296return self.Summands()297298299def __str__ ( self ) :300"""Returns a one-line string as short description."""301if len(self) == 0 : return 'Trivial group.'302else : return 'Direct sum of Cartan groups of type '+str(self.Cartan_String())+'.'303304305def Cartan_Degree ( self ) -> list[int] :306"""Returns the Cartan degree of each component of ``self``."""307return [ Summand.Cartan_Degree() for Summand in self.Summands() ]308309310def Cartan_Family ( self ) -> list[str] :311"""Returns the Cartan family of each component of ``self``."""312return [ Summand.Cartan_Family() for Summand in self.Summands() ]313314315def Cartan_String ( self ) -> str :316"""Returns the Cartan string."""317return 'x'.join([ Summand.Cartan_String() for Summand in self.Summands() ])318319320def Dimension ( self ) -> int :321"""Return the dimension of ``self`."""322return sum([ Summand.Dimension() for Summand in self.Summands() ])323324325def Is_Exceptional ( self ) -> list[bool] :326"""Test if the Cartan family of each component of ``self`` is out of [ E , F , G ]."""327return [ Summand.Is_Exceptional() for Summand in self.Summands() ]328329330def Is_Ordinary ( self ) -> list[bool] :331"""Test if the Cartan family of each component of ``self`` is out of [ A , B , C , D ]."""332return [ Summand.Is_Ordinary() for Summand in self.Summands() ]333334335336337338