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 / Overlying_Structure / Lefschetz_Collection.sage
1842 viewsLicense: GPL3
ubuntu2204
from typing import Iterator1from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Foundation.Structure import Structure2from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Homogeneous_Variety import Irreducible_Homogeneous_Variety3from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Overlying_Structure.Equivariant_Vector_Bundle import Equivariant_Vector_Bundle , \4Irreducible_Equivariant_Vector_Bundle , \5Direct_Sum_Of_Equivariant_Vector_Bundles , \6Extension_Of_Equivariant_Vector_Bundles78910class Lefschetz_Collection ( Structure ) :1112SUPPORT_PATTERN_LABELLING = { True : [ True , 1 , 'x' , 'X' ] ,13False : [ False , 0 , 'o' , 'O' ]14}151617def __add__ ( self , other:"Lefschetz_Collection" ) -> "Lefschetz_Collection" :18"""Returns the concatenation of ``self`` with ``other``."""19assert isinstance( other , self.__class__ ) , \20TypeError('The input for ``other`` must be a Lefschetz collection.')21assert self.Base_Space() == other.Base_Space() , \22ValueError('The base spaces of ``self`` and ``other`` need to coincide.')23assert self.Twist() == other.Twist() , \24ValueError('The twists of ``self`` and ``other`` need to coincide.')2526New_Starting_Block = self.Starting_Block()+other.Starting_Block()2728New_Support_Pattern = dict({})29Row_IDs = list(self.Support_Pattern().keys())+list(other.Support_Pattern().keys())30if 0 < len(Row_IDs) :31for Row_ID in [ min(Row_IDs) .. max(Row_IDs) ] :32Row = []33if Row_ID in self.Support_Pattern().keys() : Row += self.Support_Pattern()[Row_ID]34else : Row += self.Width() * [ False ]35if Row_ID in other.Support_Pattern().keys() : Row += other.Support_Pattern()[Row_ID]36else : Row += other.Width() * [ False ]37New_Support_Pattern.update({ Row_ID : Row })3839return self.__class__( Base_Space=self.Base_Space() , Starting_Block=New_Starting_Block , Twist=self.Twist() , Support_Pattern=New_Support_Pattern )404142def __call__ ( self , *Twists:tuple[int] ) -> "Lefschetz_Collection" :43"""Returns a Lefschetz collection with twisted starting block."""44return self.__class__( Base_Space=self.Base_Space() , Starting_Block=[ Object(*Twists) for Object in self.Starting_Block() ] , Twist=self.Twist() , Support_Pattern=self.Support_Pattern() )454647def __getitem__ ( self , Input:int or slice48) -> Irreducible_Equivariant_Vector_Bundle or Direct_Sum_Of_Equivariant_Vector_Bundles or Extension_Of_Equivariant_Vector_Bundles or \49list[ Irreducible_Equivariant_Vector_Bundle or Direct_Sum_Of_Equivariant_Vector_Bundles or Extension_Of_Equivariant_Vector_Bundles ] :50"""Returns a single datum or slices of data."""51if Input in ZZ :52Index = Input53if Index <= -len(self)-1 : return None54elif Index in [ -len(self) .. -1 ] : Index += len(self)55elif Index in [ 0 .. len(self)-1 ] : pass56else : return None57for Counter , Object in enumerate( self ) :58if Counter == Index : return Object5960elif type(Input) == slice :61Slice = Input62Indices = range(len(self))[Slice]63List = []64for Counter , Object in enumerate( self ) :65if Counter in Indices : List += [ Object ]66return List6768else :69raise ValueError('The variable ``Input`` is inappropriate.')707172def __init__ ( self , \73Base_Space:Irreducible_Homogeneous_Variety , \74Starting_Block:list[ Equivariant_Vector_Bundle ] , \75Twist:Irreducible_Equivariant_Vector_Bundle or None=None , \76Support_Pattern:list or str or None='Trivial'77) -> None :78"""79Initialize a Lefschetz collection over an irreducible homogeneous variety.8081INPUT:82- ``Base_Space`` -- Irreducible Homogeneous Variety;83- ``Starting_Block`` -- List;84- ``Twist`` -- Vector bundle over an irreducible homogeneous variety;85- ``Support_Pattern`` -- Tuple;8687OUTPUT: None.88"""89# Base space90assert isinstance( Base_Space , Irreducible_Homogeneous_Variety ) , \91TypeError('The input for ``base space`` must be an irreducible homogeneous variety.')92self._Base_Space = Base_Space9394# Starting block95if isinstance( Starting_Block , tuple ) : Starting_Block = list(Starting_Block)96self._Starting_Block = []97if isinstance( Starting_Block , list ) :98for Object_Counter , Object in enumerate( Starting_Block , start=1 ) :99assert isinstance( Object , ( Irreducible_Equivariant_Vector_Bundle , Direct_Sum_Of_Equivariant_Vector_Bundles , Extension_Of_Equivariant_Vector_Bundles ) ) , \100'The '+str(Object_Counter)+'-th object need to be an equivariant vector bundle.'101assert self._Base_Space == Object.Base_Space() , \102ValueError('The base space of the '+str(Object_Counter)+'-th object does not coincide with the given base space.')103self._Starting_Block += [ Object ]104else : raise ValueError( 'The input for ``Starting_Block`` is inappropriate.' )105106# Twist107if Twist == None :108if self._Base_Space.Parabolic_Subgroup().Is_Maximal() : Twist = self._Base_Space.calO(1)109else : raise ValueError( 'For a non-maximal paralic subgroup, one need to clearify the twist explicitly.' )110assert isinstance( Twist , Irreducible_Equivariant_Vector_Bundle ) , \111TypeError('The input for ``Twist`` must be a vector bundle over an irreducible homogeneous variety.')112assert Twist.Is_Line_Bundle() , \113ValueError('The input for ``Twist`` need to be a line bundle.')114self._Twist = Twist115116# Support pattern117if Support_Pattern in [ 'Trivial' , None ] :118self._Support_Pattern = { 0 : len(self._Starting_Block) * [ True ] }119120elif Support_Pattern in [ 'Maximal' , 'Max' , 'Maximal Length' , infinity ] :121raise ValueError('The method constructing the maximal support pattern is yet not implemented.')122123elif isinstance( Support_Pattern , ( tuple , list ) ) :124Support_Pattern = list(Support_Pattern)125Cases = []126for Entry_Counter , Entry in enumerate( Support_Pattern , start=1 ) :127128if Entry in ZZ :129if not 0 <= Entry :130raise ValueError('If the '+str(Entry_Counter)+'-th entry of the input ``Support_Pattern`` is an integer, ' \131+ 'then it must be non-negative.')132if not Entry <= len(self._Starting_Block) :133raise ValueError('If the '+str(Entry_Counter)+'-th entry of the input ``Support_Pattern`` is an integer, ' \134+ 'then it must be bounded by the length of the starting block; namely <= '+str(len(self._Starting_Block))+'.'135)136Label = 'Support partition'137elif instance( Entry , [ tuple , list ] ) :138Entry = list(Entry)139140for Subentry_Counter , Subentry in enumerate( Entry ) :141if not ( Subentry in self.SUPPORT_PATTERN_LABELLING[True] or Subentry in self.SUPPORT_PATTERN_LABELLING[False] ) :142raise ValueError('If the '+str(Entry_Counter)+'-th entry of the input ``Support_Pattern`` is a tuple or a list, ' \143+ 'then it must contain labellings '+str(self.SUPPORT_PATTERN_LABELLING[True])+' or '+str(self.SUPPORT_PATTERN_LABELLING[False])+'.'144)145if not len(Entry) <= len(self._Starting_Block) :146raise ValueError('If the '+str(Entry_Counter)+'-th entry of the input ``Support_Pattern`` is an row with labellings, ' \147+ 'then its length must be bounded by the length of the starting block; namely <= '+str(len(self._Starting_Block))+'.'148)149Label = 'Grid'150151if not Label in Cases : Cases += [ Label ]152153if len( Cases ) == 0 : Case = 'Empty support pattern'154elif len( Cases ) == 1 : Case = Cases[0]155else : raise ValueError( 'The entries of the input ``Support_Pattern`` are inappropriate.' )156157if Case == 'Empty support pattern' :158self._Support_Pattern = dict({})159elif Case == 'Support partition' :160self._Support_Pattern = { Row_Counter : Row_Width*[ True ] + (len(self._Starting_Block)-Row_Width)*[ False ]161for Row_Counter , Row_Width in enumerate( Support_Pattern )162}163elif Case == 'Grid' :164self._Support_Pattern = { Row_Counter : [ Entry in self.SUPPORT_PATTERN_LABELLING[True] for Entry in Row ] + (len(self._Starting_Block)-len(Row))*[ False ]165for Row_Counter , Row in enumerate( Support_Pattern )166}167168elif isinstance( Support_Pattern , dict ) :169self._Support_Pattern = dict({})170for Row_ID , Row in Support_Pattern.items() :171if not Row_ID in ZZ :172raise ValueError('If the input ``Support_Pattern`` is an dictionary, then the keys must be integers.')173if not type( Row ) in [ list ] :174raise ValueError('If the input ``Support_Pattern`` is an dictionary, then the values must be lists.')175if not len(Row) <= len(self._Starting_Block) :176raise ValueError('If the input ``Support_Pattern`` is an dictionary, ' \177+'then the length of the rows must be bounded by the length of the starting block, namely <= '+str(len(self._Starting_Block))+'.')178for Entry_Counter , Entry in enumerate( Row , start=1 ) :179if ( not Entry in self.SUPPORT_PATTERN_LABELLING[True] ) and ( not Entry in self.SUPPORT_PATTERN_LABELLING[False] ) :180raise ValueError('If the input ``Support_Pattern`` is an dictionary, then the '+str(Entry_Counter)+'-th entry in the row '+str(Row_ID) \181+ 'must be a labelling of the form '+str(self.SUPPORT_PATTERN_LABELLING[True])+' or '+str(self.SUPPORT_PATTERN_LABELLING[False])+'.'182)183for Row_ID , Row in Support_Pattern.items() :184Adjusted_Row = [ Entry in self.SUPPORT_PATTERN_LABELLING[True] for Entry in Row ] + (len(self._Starting_Block)-len(Row))*[ False ]185if True in Adjusted_Row : self._Support_Pattern.update({ Row_ID : Adjusted_Row })186187if 0 < len( self._Support_Pattern.keys() ) :188for Row_ID in [ min(self._Support_Pattern.keys()) .. max(self._Support_Pattern.keys()) ] :189if not Row_ID in self._Support_Pattern.keys() :190self._Support_Pattern.update({ Row_ID : len(self._Starting_Block)*[ False ] })191192Sorted_Row_IDs = sorted( self._Support_Pattern.keys() )193self._Support_Pattern = { Row_ID : self._Support_Pattern[Row_ID] for Row_ID in Sorted_Row_IDs }194195else :196raise TypeError( 'The input for ``Support_Pattern`` is inappropriate.' )197198# Gram matrix199self._Gram_Matrix = dict({})200201202def __iter__ ( self ) -> Iterator[ Equivariant_Vector_Bundle ] :203"""Returns a generator for the objects of ``self``."""204for yPos , Row in self.Support_Pattern().items() :205for xPos , Object_Is_Accessible in enumerate( Row ) :206if Object_Is_Accessible :207yield self.Starting_Block(xPos) * self.Twist()^yPos208209210def __len__ ( self ) -> int :211"""Returns the number of objects of ``self``."""212return sum([ sum([ 1 for Object_Is_Accessible in Row if Object_Is_Accessible ]) for Row in self.Support_Pattern().values() ])213214215def __lshift__ ( self , Shift:int=1 ) -> "Lefschetz_Collection" :216"""Returns the left shift of ``self``."""217return self >> -Shift218219220def __repr__ ( self ) :221"""Returns all attributes which are necessary to initialize the object."""222return self.Base_Space() , self.Starting_Block() , self.Twist() , self.Support_Pattern()223224225def __rshift__ ( self , Shift:int=1 ) -> "Lefschetz_Collection" :226"""Returns a sheft of ``self``."""227assert Shift in ZZ , \228TypeError('The input for ``Shift`` need to be an integer.')229New_Support_Pattern = { Row_ID+Shift : Row for Row_ID , Row in self.Support_Pattern().items() }230return self.__class__( Base_Space=self.Base_Space() , Starting_Block=self.Starting_Block() , Twist=self.Twist() , Support_Pattern=New_Support_Pattern )(-Shift)231232233def __str__ ( self ) -> str :234"""Returns a one-line string as short description."""235return 'Lefschetz collection consisting of '+str(len(self))+' objects in a grid with width = '+str(self.Width())+' and height = '+str(self.Height())236237238def Base_Space ( self ) -> Irreducible_Homogeneous_Variety :239"""Returns the attribute ``_Base_Space``."""240return self._Base_Space241242243# Synonym for the method ``Row`` :244def Block ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :245"""Returns a single block (= row)."""246self.Row( Input )247248249def Column ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :250"""Returns a single column."""251Width = self.Width()252if Input in ZZ :253if Input <= -Width-1 :254Start_Iteration = False255elif Input in [ -Width .. -1 ] :256Start_Iteration = True257xPos = Input + Width258elif Input in [ 0 .. Width-1 ] :259Start_Iteration = True260xPos = Input261elif Width <= Input :262Start_Iteration = False263264if Start_Iteration :265for yPos , Row in self.Support_Pattern().items() :266Object_Is_Accessible = Row[xPos]267if Object_Is_Accessible : yield self.Starting_Block(xPos)(yPos)268269else :270raise TypeError('The input data must be an integer in the range '+str( [ -Width .. Width-1 ] )+'.')271272273def Gram_Matrix ( self , Base_Ring:'Ring'=ZZ , Compute_Now:bool=False ) -> Matrix :274"""275Returns a Gram matrix associated to the computations of EXT( E_p , E_q ) (p: row , q: column).276For the entry in the p-th row and q-th column, it is the dim Euler_Sum( E_p , E_q ) = dim ( sum_i (-1)^i EXT^i( E_p , E_q ) ).277"""278if Compute_Now == True :279WCR = self.Base_Space().Parent_Group().Weyl_Character_Ring()280if Base_Ring == ZZ : self._Gram_Matrix.update({ ZZ : Matrix( ZZ , [ [ E1.Euler_Sum(E2).degree() for E2 in self ] for E1 in self ] ) })281elif Base_Ring == WCR : self._Gram_Matrix.update({ WCR : [ [ E1.Euler_Sum(E2) for E2 in self ] for E1 in self ] })282else : raise ValueError("The input for `Base_Ring` is inappropriate.")283284return self._Gram_Matrix[Base_Ring]285286else :287if Base_Ring in self._Gram_Matrix.keys() : return self._Gram_Matrix[Base_Ring]288else : return self.Gram_Matrix( Base_Ring=Base_Ring , Compute_Now=True )289290291def Grid ( self , Labelling:list or None=None ) -> list[ list[ str ] ] :292"""Returns a grid of the objects of ``self``."""293if Labelling == None : Labelling = [ 'E'+str(xPos) for xPos in range(self.Width()) ]294assert type(Labelling) == list , TypeError('The input for ``Labelling`` must be a list.')295assert len(Labelling) == self.Width() , ValueError('The ``Labelling`` must be of length '+str(len(self.Width()))+'.')296for Label_Counter , Label in enumerate( Labelling , start=1 ) :297assert type(Label) == str , TypeError('The '+str(Label_Counter)+'-th label must be a string.')298299Table = []300for yPos , self_Row in self.Support_Pattern().items() :301Table_Row = []302for xPos , Object_Is_Accessible in enumerate( self_Row ) :303if Object_Is_Accessible :304Label = Labelling[xPos]305if not yPos == 0: Twist = '('+str(yPos)+')'306else : Twist = ''307Table_Row_Entry = Label+Twist308else : Table_Row_Entry = ''309Table_Row += [ Table_Row_Entry ]310Table += [ Table_Row ]311312if 0 < len(self) : return table( Table )313314315def Has_Maximal_Expected_Length ( self ) -> bool :316"""Tests if ``self`` is maximal; i.e. len(self) == rk K_0(X)."""317return len(self) == self.Base_Space().Grothendieck_Group().rank()318319320def Height ( self ) -> int :321"""Returns the height of ``self``."""322return len(self.Support_Pattern().keys())323324325def Is_Exceptional ( self , Test_Numerically:bool=False ) -> bool :326"""327Tests if the Lefschetz collection is (numerically) exceptional.328329INPUT:330- ``self`` -- LefschetzCollection.331332OUTPUT:333- Boolean; return True if ``self`` is exceptional, otherwise False as soon as possible.334335ALGORITHM:336Compare to Lemma 2.2. in [Kuz2006]_337338REFERENCE:339- [Kuz2006] Alexander Kuznetsov: Exceptional collections for Grassmannians of isotropic lines; 2006.340"""341assert type(Test_Numerically) == bool , \342TypeError('The input for ``Test_Numerically`` need to be boolean.')343344# Test if the accessible objects are exceptional.345# Let E be from the starting block.346# If E is accessible in the same row (i.e. E(y) is object of ``self`` for some y), then test if E is exceptional.347# NOTE: EXT( E(y) , E(y) ) = EXT( E , E )348for xPos in range(self.Width()) :349# Test if the object is accessible in some row.350Object_Is_Accessible_In_Same_Row = False351for Row in self.Support_Pattern().values() :352if Row[xPos] == True : Object_Is_Accessible_In_Same_Row = True ; break353# If the object is accessible in some row, then test if it is exceptional.354if Object_Is_Accessible_In_Same_Row :355Obj = self.Starting_Block(xPos)356if not Obj.Is_Exceptional(Test_Numerically) : return False357358# Test for accessible objects of the same row, if latter ones are semi-orthogonal to previous ones.359# Let E_1 , E_2 be from the starting block and E_1 is positioned before E_2.360# If E_1 and E_2 are simultaneously accessible in the same row (i.e. E_1(y) and E_2(y) are both objects of ``self`` for some y), then test if E_2 is semi-orthogonal to E_1.361# NOTE: EXT( E_2(y) , E_1(y) ) = EXT( E_2 , E_1 )362for xPos1 in range(self.Width()) :363for xPos2 in range(self.Width())[ xPos1+1 : ] :364# Test if there is a row where both objects are simultaneously accessible.365Both_Objects_Are_Simultaneously_Accessible_In_The_Same_Row = False366for Row in self.Support_Pattern().values() :367if Row[xPos1] == True and Row[xPos2] == True : Both_Objects_Are_Simultaneously_Accessible_In_The_Same_Row = True ; break368# If both objects are simultaneously accessible in the same row, then check semi-orthogonality.369if Both_Objects_Are_Simultaneously_Accessible_In_The_Same_Row :370Obj1 = self.Starting_Block(xPos1)371Obj2 = self.Starting_Block(xPos2)372for Obj2_Is_SemiOrthogonal_To_Obj1 in Obj2.Is_SemiOrthogonal_To( Obj1 , Test_Numerically ) :373if not Obj2_Is_SemiOrthogonal_To_Obj1 : return False374375# Test for accessible objects of the same row, if latter ones are semi-orthogonal to previous ones.376# Let E_1 , E_2 be from the starting block.377# If E_1 and E_2 are simultaneously accessible with respect to the row-difference yDelta (i.e. E_1(y_1) and E_2(y_2) are both objects of ``self``378# for some y_1 and y_2 with yDela = y_2-y_1), then test if E_2(yDelta) is semi-orthogonal to E_1.379# NOTE: EXT( E_2(y_2) , E_1(y_1) ) = EXT( E_2(yDelta) , E_1 )380for xPos1 in range(self.Width()) :381for xPos2 in range(self.Width()) :382for yDelta in range(self.Height())[ 1 : ] :383# Test if there are two rows with yDelta difference where both objects are simultaneously accessible.384Both_Objects_Are_Simultaneously_Accessible_In_Rows_With_Difference_yDelta = False385for Row1_ID in self.Support_Pattern().keys() :386Row2_ID = Row1_ID + yDelta387if not Row2_ID in self.Support_Pattern().keys() : break388Row1 = self.Support_Pattern()[Row1_ID]389Row2 = self.Support_Pattern()[Row2_ID]390if Row1[xPos1] == True and Row2[xPos2] == True : Both_Objects_Are_Simultaneously_Accessible_In_Rows_With_Difference_yDelta = True ; break391392# If both objects are simultaneously accessible with respect to yDelta, then check semi-orthogonality.393if Both_Objects_Are_Simultaneously_Accessible_In_Rows_With_Difference_yDelta :394Obj1 = self.Starting_Block(xPos1)395Obj2 = self.Starting_Block(xPos2) * self.Twist()^yDelta396for Obj2_Is_SemiOrthogonal_To_Obj1 in Obj2.Is_SemiOrthogonal_To( Obj1 , Test_Numerically ) :397if not Obj2_Is_SemiOrthogonal_To_Obj1 : return False398399if 0 < len(self) : return True400401402def Is_Numerically_Exceptional ( self ) -> bool :403"""Tests if the Lefschetz collection is numerically exceptional."""404return self.Is_Exceptional( Test_Numerically=True )405406407def Numerical_Left_Dual ( self , Index:int ) -> Equivariant_Vector_Bundle :408"""Returns the i-th numerical left dual with respect to ``self.``"""409l = len(self)-1410assert Index in [ 0 .. l ] , \411'The input for ``Index`` need to be in the range from 0 to '+str(l)+'.'412LD = LC[l-Index]413for j in range(l-Index+1,l+1) :414LD = self[j].Numerical_Right_Mutation( LD )415return LD416417418def Numerical_Right_Dual ( self , Index:int ) -> Equivariant_Vector_Bundle :419"""Returns the i-th numerical right dual with respect to ``self.``"""420l = len(self)-1421assert Index in [ 0 .. l ] , \422'The input for ``Index`` need to be in the range from 0 to '+str(l)+'.'423RD = LC[l-Index]424for j in range(l-Index-1,0,-1) :425RD = self[j].Numerical_Left_Mutation( RD )426return RD427428429# Synonyms for the method ``Column`` :430def Orbit ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :431"""Returns a single orbit (= column)."""432self.Column( Input )433434435def Row ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :436"""Returns a single row."""437Height = self.Height()438if Input in ZZ :439if Input <= -Height-1 :440Start_Iteration = False441elif Input in [ -Height .. -1 ] :442Start_Iteration = True443yPos = Input + Height444elif Input in [ 0 .. Height-1 ] :445Start_Iteration = True446yPos = Input447elif Height <= Input :448Start_Iteration = False449450if Start_Iteration :451for xPos , Object_Is_Accessible in enumerate( self.Support_Pattern()[yPos] ) :452if Object_Is_Accessible : yield self.Starting_Block(xPos)(yPos)453454else :455raise TypeError('The input data must be an integer in the range '+str( [ -Height .. Height-1 ] )+'.')456457458def Subcollection( self , Columns:list or None=None , Rows:list or None=None ) -> "Lefschetz_Collection" :459"""Returns the subcollection of the given columns and rows."""460if Columns == None : Columns = range( len( self.Starting_Block() ) )461assert type(Columns) in [ list , range ] , \462TypeError('The input for ``Columns`` need to be a list or a range.')463if Rows == None : Rows = list( self.Support_Pattern().keys() )464assert type(Rows) in [ list , range ] , \465TypeError('The input for ``Rows`` need to be a list or a range.')466467New_Starting_Block = [ Object for Object_Counter , Object in enumerate( self.Starting_Block() ) if Object_Counter in Columns ]468New_Support_Pattern = { Row_ID : [ Value for Column_Counter , Value in enumerate( Row ) if Column_Counter in Columns ] \469for Row_ID , Row in self.Support_Pattern().items() \470if Row_ID in Rows471}472return self.__class__( Base_Space=self.Base_Space() , Starting_Block=New_Starting_Block , Twist=self.Twist() , Support_Pattern=New_Support_Pattern )473474475def Support_Pattern ( self ) -> list[ list[ bool ] ] :476"""Returns the attribute ``_Support_Pattern``."""477return self._Support_Pattern478479480def Starting_Block ( self , Input:None or int or slice=None ) -> Equivariant_Vector_Bundle or list[ Equivariant_Vector_Bundle ] :481"""Returns the attribute ``_Starting_Block``."""482if Input == None : return self._Starting_Block483elif Input in ZZ :484Index = Input % len(self._Starting_Block)485return self._Starting_Block[Index]486elif type(Input) == slice :487Slice = Input488return self._Starting_Block[Slice]489else : raise ValueError('The input data is inappropriate.')490491492def Twist ( self ) -> Irreducible_Equivariant_Vector_Bundle :493"""Returns the attribute ``_Twist``."""494return self._Twist495496497def Width ( self ) -> int :498"""Returns the width of ``self``."""499return len(self.Starting_Block())500501502def Mutate ( self , Dictionary:dict , Base_Ring:'Ring'=ZZ , Basis=None , Gram_Matrix=None ) -> ( list[ list[ 'Ring element' ] ] , list[ list[ 'Ring element' ] ] ) :503"""Describes the left mutation on the K_0-level."""504# ..ToDo: Implement test for thoses objects, which are mutated through, are exceptional.505506Length = len(self)507508WCR = self.Base_Space().Parent_Group().Weyl_Character_Ring()509if Base_Ring == ZZ : pass510elif Base_Ring == WCR : pass511else : raise ValueError('The input for ``Base_Ring`` is inappropriate.')512513if Basis == None : Basis = [ i*[ Base_Ring(0) ] + [ Base_Ring(1) ] + (Length-1-i)*[ Base_Ring(0) ] for i in range(Length) ]514515assert type(Basis) == list , \516TypeError('The input for ``Basis`` must be a list.')517for Element_Counter , Element in enumerate( Basis , start=1 ) :518assert type(Element) == list , \519ValueError('The '+str(Element_Counter)+'-th element is not a list.')520for Entry_Counter , Entry in enumerate( Element , start=1 ) :521assert Entry in Base_Ring , \522ValueError('The '+str(Entry_Counter)+'-th entry of the '+str(Element_Counter)+'-th element is not an object of the base ring, namely '+str(Base_Ring)+'.')523524if Gram_Matrix == None : Gram_Matrix = self.Gram_Matrix( Base_Ring )525526for Row_Counter , Row in enumerate( Gram_Matrix , start=1 ) :527for Column_Counter , Entry in enumerate( Row , start=1 ) :528assert Entry in Base_Ring , \529ValueError('The '+str(Column_Counter)+'-th entry of the '+str(Row_Counter)+'-th row is not an object of the base ring, namely '+str(Base_Ring)+'.')530assert Column_Counter == Length , \531ValueError('The Gram matrix does not have rows of length '+str(Length)+'.')532assert Row_Counter == Length , \533ValueError('The Gram matrix does not have columns of length '+str(Length)+'.')534535Bases = dict({})536Gram_Matrices = dict({})537538Timer = 0539Bases.update({ Timer : Basis })540Gram_Matrices.update({ Timer : Gram_Matrix })541542for Mutation_Counter , ( Start , End ) in enumerate( Dictionary.items() , start=1 ) :543assert Start in range(Length) , \544ValueError('The '+str(Mutation_Counter)+'-th key of the mutation dictionary is not an element in the range '+str([ 0 .. Length-1 ])+'.')545assert End in range(Length) , \546ValueError('The '+str(Mutation_Counter)+'-th value of the mutation dictionary is not an element in the range '+str([ 0 .. Length-1 ])+'.')547548Index = Start549while Index != End :550Timer += 1551if End <= Start : # Left mutation552# Mutation triangle: 0 ----> EXT( E , F ) * E --ev--> F ----> LL_E(F) ----> 0553# i.e. [ LL_E(F) ] = [ F ] - EXT( E , F ) * [ E ] in K_0( self.Base_Space() )554e = Bases[Timer-1][ Index-1 ] # The object which is mutated through555f = Bases[Timer-1][ Index ] # The object which is mutated556chi = Gram_Matrices[Timer-1][ Index-1 ][ Index ]557mutation = [ f[i] - chi * e[i] for i in range(Length) ]558559Bases.update({ Timer : Bases[Timer-1][ : Index-1 ] + [ mutation , e ] + Bases[Timer-1][ Index+1 : ] })560Gram_Matrices.update({ Timer : [ [ sum([ Base_Ring(0) ] + [ Bases[Timer][ Row_Index ][j] * Gram_Matrix[j][i] * Bases[Timer][ Column_Index ][i]561for i in range(Length)562for j in range(Length)563])564for Column_Index in range(Length)565]566for Row_Index in range(Length)567]568})569Index -= 1570571else : # Right mutation572# Mutation triangle: 0 ----> RR_F(E) ----> E --coev--> EXT( F , E )^vee * F ----> 0 ???573# i.e. [ RR_F(E) ] = ?574#e = ? # The object which is mutated575#f = ? # The object which is mutated through576#chi = ?577#mutation = ?578579Bases.update({ Timer : Bases[Timer-1][ : Index-1 ] + [ f , mutation ] + Bases[Timer-1][ Index+1 : ] })580#Gram_Matrices.update({ Timer : ? })581582raise ValueError('The method for right mutations is yet not implemented.')583Index += 1584585return Bases[Timer] , Gram_Matrices[Timer]586587588def Test_For_Extension ( self ,589New_Object :Equivariant_Vector_Bundle ,590Relevant_Columns :set[ int ] or None =None ,591Test_Numerically :bool =True ,592Test_If_Self_Is_Exceptional :bool =True593) -> Iterator[ int ] :594"""Test if ``New_Object`` can be inserted to ``self`` at the columns ``Relevant_Columns``."""595596assert isinstance( New_Object , Equivariant_Vector_Bundle ) , \597'The input for `New_Object` need to be an equivariant vector bundle.'598New_Orbit = New_Object.Maximal_Exceptional_Orbit( Test_Numerically=Test_Numerically )599600if Relevant_Columns == None : Relevant_Columns = set(range(self.Width()+1))601assert isinstance( Relevant_Columns , set ) , \602'If the input for `Relevant_Columns` is not None, then it need to be a set.'603assert Relevant_Columns.issubset( set(range(self.Width()+1)) ) , \604'The relevant columns need to be in the range from 0 to '+str(self.Width()+1)+'.'605606if Test_If_Self_Is_Exceptional == True :607assert self.Is_Exceptional( Test_Numerically=Test_Numerically ) , \608'The collection `self` is not exceptional.'609610def Test_For ( xPos1 , yPos1 ) :611Object1 = New_Object(yPos1)612for yPos2 , Row in self.Support_Pattern().items() :613for xPos2 , Object2_Is_Accessible in enumerate( Row ) :614if Object2_Is_Accessible :615Object2 = self.Starting_Block(xPos2)(yPos2)616#if not xPos2 in Already_Tested.keys() : Already_Tested.update({ xPos2 : ( set({}) , set({}) ) })617if yPos2 < yPos1 or ( yPos2 == yPos1 and xPos2 < xPos1 ) :618#if not yPos1-yPos2 in Already_Tested[xPos2][0] :619# Already_Tested[xPos2][0].add( yPos1-yPos2 )620if not next( Object1.Is_SemiOrthogonal_To( Object2 , Test_Numerically=Test_Numerically ) ) : return False621else :622#if not yPos2-yPos1 in Already_Tested[xPos2][1] :623# Already_Tested[xPos2][1].add( yPos2-yPos1 )624if not next( Object2.Is_SemiOrthogonal_To( Object1 , Test_Numerically=Test_Numerically ) ) : return False625return True626627for Tested_xPos in Relevant_Columns :628#Already_Tested = dict({})629yield ( Tested_xPos , [ Tested_yPos for Tested_yPos in range(len(New_Orbit)) if Test_For( Tested_xPos , Tested_yPos ) ] )630631632def Test_For_SemiOrthogonal_Relations ( self ) :633G = self.Base_Space().Parent_Group()634635for x1 , Obj1 in enumerate( self.Starting_Block() ) :636for x2 , Obj2 in enumerate( self.Starting_Block() ) :637Done = []638for y1 , Row1 in LC.Support_Pattern().items() :639if Row1[x1] == True :640for y2 , Row2 in LC.Support_Pattern().items() :641if Row2[x2] == True :642y = y1-y2643if not y in Done :644if 0 < y : Position = 'LowerHalf'645elif y == 0 and x2 < x1 : Position = 'LowerHalf'646elif y == 0 and x2 == x1 : Position = 'Diagonal'647else : Position = 'UpperHalf'648649if Position == 'LowerHalf' or Position == 'Diagonal' :650Done += [y]651EXT_Space = Obj1(y).EXT(Obj2)652Euler_Sum = Obj1(y).Euler_Sum(Obj2)653654if Position == 'LowerHalf' :655if EXT_Space == dict({}) : SemiOrthogonal_Relation = 'Correct.'656elif Euler_Sum == G.rmV(0) : SemiOrthogonal_Relation = 'Numerically correct.'657else : SemiOrthogonal_Relation = 'Not correct.'658659elif Position == 'Diagonal' :660if EXT_Space == { 0 : G.rmV(1) } : SemiOrthogonal_Relation = 'Correct.'661elif Euler_Sum == G.rmV(1) : SemiOrthogonal_Relation = 'Numerically correct.'662else : SemiOrthogonal_Relation = 'Not correct.'663664yield ( x1 , x2 , y , SemiOrthogonal_Relation , EXT_Space , Euler_Sum )665666667