n environment to decompose the i-th Hochschild cohomology on some homogeneous varieties X=G/P by Hoschild-Kostant-Rosenberg.
Hochschild-Kostant-Rosenberg_decomposition / src / HochschildKostantRosenberg_decomposition / base_space.py
383 viewsLicense: GPL3
ubuntu2204
12# This file was *autogenerated* from the file base_space.sage3from sage.all_cmdline import * # import sage library45_sage_const_1 = Integer(1); _sage_const_2 = Integer(2); _sage_const_3 = Integer(3); _sage_const_6 = Integer(6); _sage_const_8 = Integer(8); _sage_const_4 = Integer(4); _sage_const_0 = Integer(0); _sage_const_7 = Integer(7)6from typing import Iterator78910class irreducible_Cartan_group ( object ) :111213ADMISSIBLE_CARTAN_FAMILIES = { 'A' : ( _sage_const_1 , +infinity ) ,14'B' : ( _sage_const_2 , +infinity ) ,15'C' : ( _sage_const_2 , +infinity ) ,16'D' : ( _sage_const_3 , +infinity ) ,17'E' : ( _sage_const_6 , _sage_const_8 ) ,18'F' : ( _sage_const_4 , _sage_const_4 ) ,19'G' : ( _sage_const_2 , _sage_const_2 )20}212223def __eq__ ( self , other ) -> bool :24"""Tests if ``self`` coincides with ``other``."""25assert isinstance( other , irreducible_Cartan_group ) , 'The input for ``other`` needs to be an irreducible Cartan group.'26return self.__repr__() == other.__repr__()27282930def __init__ ( self , Cartan_family:str , Cartan_degree:sage.rings.integer.Integer ) -> None :31"""Initialise ``self``."""32assert Cartan_family in self.ADMISSIBLE_CARTAN_FAMILIES.keys() , ValueError('The input for ``Cartan_family`` needs to be a letter from the alphabet '+str(self.ADMISSIBLE_CARTAN_FAMILIES.keys())+'.')33self._Cartan_family = Cartan_family3435assert Cartan_degree in ZZ , ValueError('The input for ``Cartan_degree`` needs to be an integer.')36lower_bound , upper_bound = self.ADMISSIBLE_CARTAN_FAMILIES[Cartan_family]37assert lower_bound <= Cartan_degree and Cartan_degree <= upper_bound , ValueError('If the Cartan family is '+str(Cartan_family)+', then the input for ``Cartan_degree`` needs to between '+str(lower_bound)+' and '+str(upper_bound)+'.')38self._Cartan_degree = Cartan_degree394041def __neq__ ( self , other ) -> bool :42"""Tests if ``self`` does NOT coincides with ``other``."""43return not self == other444546def __repr__ ( self ) -> tuple[ str , sage.rings.integer.Integer ] :47"""Returns a developers adjusted description."""48return self._Cartan_family , self._Cartan_degree495051def __str__ ( self ) -> str :52"""Returns a human-readable description."""53return self._Cartan_family+'_'+str(self._Cartan_degree)545556def __truediv__ ( self , other:'maximal_parabolic_subgroup' ) -> 'minimal_irreducible_homogeneous_variety' :57"""Returns the minimal irreducible homogeneous variety X=G/P."""58assert isinstance( other , maximal_parabolic_subgroup ) , 'The input for ``other`` needs to be a minimal parabolic subgroup.'5960assert self == other._parent_group , 'The parent group of ``other`` needs to be self.'6162return minimal_irreducible_homogeneous_variety( parabolic_subgroup=other )636465def Cartan_string ( self ) -> str :66"""Returns the Cartan string ``_Cartan_family``+``_Cartan_degree``."""67return self._Cartan_family+str(self._Cartan_degree)686970def Cartan_type ( self ) -> 'sage.combinat.root_system.type_A.CartanType' or 'sage.combinat.root_system.type_B.CartanType' or 'sage.combinat.root_system.type_D.CartanType' or 'sage.combinat.root_system.type_E.CartanType' or 'sage.combinat.root_system.type_E.CartanType' or 'sage.combinat.root_system.type_F.CartanType' or 'sage.combinat.root_system.type_G.CartanType' :71"""Returns the associated Cartan type."""72return CartanType( self.Cartan_string() )737475def dimension ( self ) -> sage.rings.integer.Integer :76"""77Return the dimension of ``self`.7879INPUT:80- ``self`` -- minimal_irreducible_homogeneous_variety; base space X=G/P.8182OUTPUT:83- ``Output`` -- Integer; the dimension of X=G/P8485ALGORITHM:86Thanks to the post by Pieter Belmans concerning the dimension of partial flag varieties87from Jun 14th, 2017 on his blog (cf. to [Blog_PieterBelmans]_). The link is88https://pbelmans.ncag.info/blog/2017/06/14/dimensions-of-partial-flag-varieties/89(Date: Apr 21st, 2021).9091For the Borel group B ⊂ G: dim B = # of positive roots + rank (which accounts for the center)92For G: dim G = # of roots in the root system + rank (which accounts for the center)93i.e. # of roots in the root system = # of positive roots + # negative roots94and # of positive roots = # negative roots95so # of roots in the root system = 2 * # of positive roots9697REFERENCE:98[Blog_PieterBelmans] https://pbelmans.ncag.info/blog/99"""100rank = self.Cartan_type().dynkin_diagram().rank()101number_of_positive_roots = len( list( self.Cartan_type().root_system().root_lattice().positive_roots() ) )102return rank + _sage_const_2 *number_of_positive_roots103104105def parabolic_subgroup ( self , excluded_node:sage.rings.integer.Integer ) -> 'maximal_parabolic_subgroup' :106"""Returns a maximal parabolic subgroup associated to a given excluded node."""107return maximal_parabolic_subgroup( parent_group=self , excluded_node=excluded_node )108109110def Weyl_character_ring( self ) -> 'sage.combinat.root_system.weyl_characters.WeylCharacterRing_with_category' :111"""Returns the associated Weyl character ring."""112return WeylCharacterRing( self.Cartan_type() , style='coroots' )113114115def Weyl_group( self ) -> 'sage.combinat.root_system.weyl_group.WeylGroup_gens_with_category' :116"""Returns the associated Weyl group."""117return WeylGroup( self.Cartan_type() )118119120121class maximal_parabolic_subgroup ( object ) :122123124def __eq__ ( self , other ) -> bool :125"""Tests if ``self`` coincides with ``other``."""126assert isinstance( other , maximal_parabolic_subgroup ) , 'The input for ``other`` needs to be an irreducible Cartan group.'127return self.__repr__() == other.__repr__()128129130def __init__ ( self , parent_group:irreducible_Cartan_group , excluded_node:sage.rings.integer.Integer ) :131"""Initialise ``self``."""132assert isinstance( parent_group , irreducible_Cartan_group ) , ValueError('The input for ``parent_group`` needs to be an irreducible Cartan group.')133self._parent_group = parent_group134135assert excluded_node in ZZ , ValueError('The input for ``excluded_node`` needs to be an integer.')136assert excluded_node in (ellipsis_range( _sage_const_1 ,Ellipsis, self._parent_group._Cartan_degree )) , ValueError('The input for ``excluded_node`` needs to be in the range from 1 to '+str(self._Cartan_degree)+'.')137self._excluded_node = excluded_node138139140def __neq__ ( self , other ) -> bool :141"""Tests if ``self`` does NOT coincides with ``other``."""142return not self == other143144145def __repr__ ( self ) -> tuple[ irreducible_Cartan_group , sage.rings.integer.Integer ] :146"""Returns a developers adjusted description."""147return self._parent_group , self._excluded_node148149150def __str__ ( self ) -> str :151"""Returns a human-readable description."""152return 'P_'+str(self._excluded_node)153154155def dimension ( self ) -> sage.rings.integer.Integer :156"""157Return the dimension of ``self`.158159INPUT:160- ``self`` -- minimal_irreducible_homogeneous_variety; base space X=G/P.161162OUTPUT:163- ``Output`` -- Integer; the dimension of X=G/P164165ALGORITHM:166Thanks to the post by Pieter Belmans concerning the dimension of partial flag varieties167from Jun 14th, 2017 on his blog (cf. to [Blog_PieterBelmans]_). The link is168https://pbelmans.ncag.info/blog/2017/06/14/dimensions-of-partial-flag-varieties/169(Date: Apr 21st, 2021).170171For the Borel group B ⊂ G: dim B = # of positive roots + rank (which accounts for the center)172For P: dim P = dim B + # of negative roots which are added to construct P173174REFERENCE:175[Blog_PieterBelmans] https://pbelmans.ncag.info/blog/176"""177rank = self._parent_group.Cartan_type().dynkin_diagram().rank()178number_of_positive_roots = len( list( self._parent_group.Cartan_type().root_system().root_lattice().positive_roots() ) )179negative_roots = [ negative_root for negative_root in list( self._parent_group.Cartan_type().root_system().root_lattice().negative_roots() )180if not False in [ node != self._excluded_node for node , coefficient in negative_root ]181]182number_of_available_negative_roots = len( negative_roots )183return rank + number_of_positive_roots + number_of_available_negative_roots184185186def included_nodes ( self ) -> list[ sage.rings.integer.Integer ] :187"""Returns list of included nodes."""188return [ node for node in (ellipsis_range( _sage_const_1 ,Ellipsis, self._parent_group._Cartan_degree )) if node != self._excluded_node ]189190191192class minimal_irreducible_homogeneous_variety ( object ) :193194def __eq__ ( self , other ) -> bool :195"""Tests if ``self`` coincides with ``other``."""196assert isinstance( other , minimal_irreducible_homogeneous_variety ) , 'The input for ``other`` needs to be an irreducible Cartan group.'197return self.__repr__() == other.__repr__()198199200def __init__ ( self , parabolic_subgroup:maximal_parabolic_subgroup ) -> None :201"""Initialise ``self``."""202assert isinstance( parabolic_subgroup , maximal_parabolic_subgroup ) , ValueError('The input for ``parabolic_subgroup`` needs to be a maximal parabolic subgroup.')203self._parabolic_subgroup = parabolic_subgroup204205206def __neq__ ( self , other ) -> bool :207"""Tests if ``self`` does NOT coincides with ``other``."""208return not self == other209210211def __repr__ ( self ) -> maximal_parabolic_subgroup :212"""Returns a developers adjusted description."""213return self._parabolic_subgroup214215216def __str__ ( self ) -> str :217"""Returns a human-readable description."""218return str(self._parabolic_subgroup._parent_group)+'/'+str(self._parabolic_subgroup)219220221def dimension ( self ) -> sage.rings.integer.Integer :222"""223Return the dimension of ``self`.224225INPUT:226- ``self`` -- minimal_irreducible_homogeneous_variety; base space X=G/P.227228OUTPUT:229- ``Output`` -- Integer; the dimension of X=G/P230231ALGORITHM:232For X=G/P, dim X = dim G - dim P233"""234return self._parabolic_subgroup._parent_group.dimension() - self._parabolic_subgroup.dimension()235236237def Fano_index ( self ) -> sage.rings.integer.Integer :238"""239Returns the Fano index of ``self``.240241INPUT:242- ``self`` -- minimal_irreducible_homogeneous_variety; base space X=G/P.243244OUTPUT:245- ``Fano_index`` -- integer; index associated to X = G/P.246247ALGORITHM:248Thanks to the post by Pieter Belmans concerning the index of partial flag varieties249from Aug 23rd, 2018 on his blog (cf. to [Blog_PieterBelmans]_). The link is250https://pbelmans.ncag.info/blog/2018/08/23/index-partial-flag-varieties/251(Date: Apr 26th, 2021).252253The index, i.e. for X=G/P (P maximal), we have Pic(X) ≅ ZZ⋅O_X(1) and therefore define the index as the integer i254such that ω∨_X ≅ O_X(1) ⊗ i.255256To compute it, we use lemma 2.19 and remark 2.20 of [KP2016]. Combined they say the following:257Let β be the simple root corresponding to the chosen maximal parabolic subgroup P, and ξ the associated258fundamental weight. Let ¯β be the maximal root of the same length as β such that the coefficient of β259in the expression of ¯β is 1.260Then the index of G/P equals i_G/P = (ρ,β+¯β)/(ξ,β).261262REFERENCE:263[Blog_PieterBelmans] https://pbelmans.ncag.info/blog/264[KP2016] Kuznetsov, Alexander; Polishchuk, Alexander Exceptional collections on isotropic Grassmannians.265J. Eur. Math. Soc. (JEMS) 18 (2016), no. 3, 507–574.266"""267root_lattice = self._parabolic_subgroup._parent_group.Cartan_type().root_system().root_lattice()268ambient_space = self._parabolic_subgroup._parent_group.Cartan_type().root_system().ambient_space()269beta = root_lattice.simple_root(self._parabolic_subgroup._excluded_node).to_ambient() # The simple root associated to ``excluded_node``270xi = ambient_space.fundamental_weight(self._parabolic_subgroup._excluded_node) # The fundamental weight associated to ``excluded_node``271rho = ambient_space.rho() # Sum of fundamental weights272length = beta.dot_product(beta)273beta_bar = [ alpha for alpha in root_lattice.roots()274if alpha.coefficient(self._parabolic_subgroup._excluded_node) == _sage_const_1 and alpha.to_ambient().dot_product(alpha.to_ambient()) == length275][-_sage_const_1 ].to_ambient()276# The maximal root of the same length as ``beta`` such that the coefficient of ``beta`` in the expression of ``beta_bar`` is 1.277Fano_index = rho.dot_product(beta + beta_bar) / xi.dot_product(beta)278return Fano_index279280281def Kostant_space ( self , i:sage.rings.integer.Integer , j:sage.rings.integer.Integer , restriction:str or None =None ) -> Iterator[ 'sage.combinat.root_system.weight_space.WeightSpace_with_category.element_class' ] :282"""283Returns the K(G,P,i,j) as introduced in [BS2023].284285INPUT:286- ``self`` -- minimal_irreducible_homogeneous_variety, base space X=G/P.287- ``i`` -- integer.288- ``j`` -- integer.289- ``restriction`` -- string.290291OUTPUT:292- ``Weight`` -- sage.combinat.root_system.weight_space.WeightSpace_with_category.element_class; highest weight corresponding to irreducible summand in K(G,P,i,j).293294295REFERENCE:296[BS2023] Belmans, Pieter; Smirnov, Maxim. Hochschild cohomology of generalised Grassmannians.297"""298# basis299fw = dict( self._parabolic_subgroup._parent_group.Cartan_type().root_system().weight_space().fundamental_weights() )300rho = sum(list(fw.values())) # sum of fundamental weights301ambt = { node : vector( QQ , (node-_sage_const_1 )*[ _sage_const_0 ] + [ _sage_const_1 ] + (self._parabolic_subgroup._parent_group._Cartan_degree-node)*[ _sage_const_0 ] )302for node in (ellipsis_range( _sage_const_1 ,Ellipsis, self._parabolic_subgroup._parent_group._Cartan_degree ))303}304base_change = matrix( QQ , [ sum([ omega.to_ambient()[node-_sage_const_1 ]*e for node , e in ambt.items() ])305for omega in fw.values()306]307).transpose().inverse() # Cartan matrix describing base change from ambt to fw308# Weyl group309WG = self._parabolic_subgroup._parent_group.Weyl_group()310sr = WG.simple_reflections()311# Weyl character ring312WCR = self._parabolic_subgroup._parent_group.Weyl_character_ring()313314# integer invariants315dimension = self.dimension() # dimension316Fano_index = self.Fano_index() # Fano index317318for Weyl_element , reduced_description in self.Weyl_group_coset_representatives_of_minimal_length() :319if len(reduced_description) == dimension-i :320# See (1.7): Weight = WeylElement \cdot 0 + ( FanoIndex + j ) * fw[k]321result = Weyl_element.action(rho.to_ambient()) - rho.to_ambient() + (Fano_index+j)*fw[self._parabolic_subgroup._excluded_node].to_ambient()322vector_with_respect_to_ambt_basis = vector( QQ , [ result.coefficient(node) for node in range(self._parabolic_subgroup._parent_group._Cartan_degree) ] )323vector_with_respect_to_fw_basis = base_change*vector_with_respect_to_ambt_basis324weight = sum([ coefficient*fw[node] for node , coefficient in enumerate( vector_with_respect_to_fw_basis , start=_sage_const_1 ) ])325326if restriction in [ None , 'None' , 'none' , '' ] :327yield weight328elif restriction in [ 'Regular' , 'regular' , 'Reg' , 'reg' , 'Non-Singular' , 'non-singular' , 'Non-Sing' , 'non-sing' ] :329if self.is_regular( weight+rho ) : yield weight330else :331raise ValueError('The input for ``restriction`` is anppropriate.')332333334def is_adjoint ( self ) -> bool :335"""Tests if ``self`` is adjoint (cf. grassmannian.info)"""336if self._parabolic_subgroup._parent_group._Cartan_family == 'B' : return self._parabolic_subgroup._excluded_node == _sage_const_2337elif self._parabolic_subgroup._parent_group._Cartan_family == 'C' : return self._parabolic_subgroup._excluded_node == _sage_const_1338elif self._parabolic_subgroup._parent_group._Cartan_family == 'D' : return self._parabolic_subgroup._excluded_node == _sage_const_2 and _sage_const_4 <= self._parabolic_subgroup._parent_group._Cartan_degree339elif self._parabolic_subgroup._parent_group._Cartan_family == 'E' : return ( self._parabolic_subgroup._excluded_node == _sage_const_2 and self._parabolic_subgroup._parent_group._Cartan_degree == _sage_const_6 ) or ( self._parabolic_subgroup._excluded_node == _sage_const_1 and self._parabolic_subgroup._parent_group._Cartan_degree == _sage_const_7 ) or ( self._parabolic_subgroup._excluded_node == _sage_const_8 and self._parabolic_subgroup._parent_group._Cartan_degree == _sage_const_8 )340elif self._parabolic_subgroup._parent_group._Cartan_family == 'F' : return self._parabolic_subgroup._excluded_node == _sage_const_1 and self._parabolic_subgroup._parent_group._Cartan_degree == _sage_const_4341elif self._parabolic_subgroup._parent_group._Cartan_family == 'G' : return self._parabolic_subgroup._excluded_node == _sage_const_2 and self._parabolic_subgroup._parent_group._Cartan_degree == _sage_const_2342else : return False343344345def is_exceptional ( self ) -> bool :346"""Test if the Cartan family of ``self`` is out of [ E , F , G ]."""347return self._parabolic_subgroup._parent_group.ADMISSIBLE_CARTAN_FAMILIES[self._parabolic_subgroup._parent_group._Cartan_family][_sage_const_1 ] < +infinity348349350def is_ordinary ( self ) -> bool :351"""Test if the Cartan family of ``self`` is out of [ A , B , C , D ]."""352return not self.is_exceptional()353354355def is_regular ( self , weight:'sage.combinat.root_system.weight_space.WeightSpace_with_category.element_class' ) -> bool :356"""Tests if a given weight on ``self`` is G-regular (i.e. does not ly on a wall of a Weyl chamber)."""357return not self.is_singular( weight )358359360def is_singular ( self , weight:'sage.combinat.root_system.weight_space.WeightSpace_with_category.element_class' ) -> bool :361"""Tests if a given weight on ``self`` is G-singular (i.e. lies on a wall of a Weyl chamber)."""362assert weight in self._parabolic_subgroup._parent_group.Cartan_type().root_system().weight_space() , ValueError('The weight must be an element of the weight space: '+str(self._parabolic_subgroup._parent_group.Cartan_type().root_system().weight_space()))363# Move ``Weight`` to dominant chamber364weight_in_dominant_chamber = weight.to_dominant_chamber()365# Consider list of reflections of ``weight`` and check whether ``weight`` is invariant under some reflection366reflections = [ weight_in_dominant_chamber.simple_reflection( index ) for index in self._parabolic_subgroup._parent_group.Cartan_type().index_set() ]367return weight_in_dominant_chamber in reflections368369370def Weyl_group_coset_representatives_of_minimal_length ( self ) -> Iterator[ tuple[ 'sage.combinat.root_system.weyl_group.WeylGroup_gens_with_category.element_class' , list ] ] :371"""Returns the Weyl group coset representatives of minimal length"""372WG = self._parabolic_subgroup._parent_group.Weyl_group()373sr = WG.simple_reflections()374identity = sr[_sage_const_1 ]*(sr[_sage_const_1 ].inverse())375376stock = [ [ i+_sage_const_1 for i in w._reduced_word ] for w in WeylGroup( self._parabolic_subgroup._parent_group.Cartan_type() , implementation='permutation' ).iteration('breadth',True) ]377stock = [ ( prod([ identity ] + [ sr[node] for node in reduced_description ]) , reduced_description ) for reduced_description in stock ]378379for Weyl_element_0 , reduced_description_0 in stock :380length_0 = len(reduced_description_0)381382Weyl_element_0_is_coset_representaion_of_minimal_length = True383for node in self._parabolic_subgroup.included_nodes() :384Weyl_element_1 = sr[node]*Weyl_element_0385386for Weyl_element , reduced_description in stock :387if Weyl_element_1 == Weyl_element :388reduced_description_1 = reduced_description389length_1 = len(reduced_description_1)390break391392if length_1 != length_0+_sage_const_1 :393Weyl_element_0_is_coset_representaion_of_minimal_length = False394break395396if Weyl_element_0_is_coset_representaion_of_minimal_length :397yield Weyl_element_0 , reduced_description_0398399400401