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.py
1842 viewsLicense: GPL3
ubuntu2204
12# This file was *autogenerated* from the file Lefschetz_Collection.sage3from sage.all_cmdline import * # import sage library45_sage_const_1 = Integer(1); _sage_const_0 = Integer(0)6from typing import Iterator7from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Foundation.Structure import Structure8from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Homogeneous_Variety import Irreducible_Homogeneous_Variety9from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Overlying_Structure.Equivariant_Vector_Bundle import Equivariant_Vector_Bundle , Irreducible_Equivariant_Vector_Bundle , Direct_Sum_Of_Equivariant_Vector_Bundles , Extension_Of_Equivariant_Vector_Bundles10111213class Lefschetz_Collection ( Structure ) :1415SUPPORT_PATTERN_LABELLING = { True : [ True , _sage_const_1 , 'x' , 'X' ] ,16False : [ False , _sage_const_0 , 'o' , 'O' ]17}181920def __add__ ( self , other:"Lefschetz_Collection" ) -> "Lefschetz_Collection" :21"""Returns the concatenation of ``self`` with ``other``."""22assert isinstance( other , self.__class__ ) , TypeError('The input for ``other`` must be a Lefschetz collection.')23assert self.Base_Space() == other.Base_Space() , ValueError('The base spaces of ``self`` and ``other`` need to coincide.')24assert self.Twist() == other.Twist() , ValueError('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 _sage_const_0 < len(Row_IDs) :31for Row_ID in (ellipsis_range( min(Row_IDs) ,Ellipsis, 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 list[ Irreducible_Equivariant_Vector_Bundle or Direct_Sum_Of_Equivariant_Vector_Bundles or Extension_Of_Equivariant_Vector_Bundles ] :49"""Returns a single datum or slices of data."""50if Input in ZZ :51Index = Input52if Index <= -len(self)-_sage_const_1 : return None53elif Index in (ellipsis_range( -len(self) ,Ellipsis, -_sage_const_1 )) : Index += len(self)54elif Index in (ellipsis_range( _sage_const_0 ,Ellipsis, len(self)-_sage_const_1 )) : pass55else : return None56for Counter , Object in enumerate( self ) :57if Counter == Index : return Object5859elif type(Input) == slice :60Slice = Input61Indices = range(len(self))[Slice]62List = []63for Counter , Object in enumerate( self ) :64if Counter in Indices : List += [ Object ]65return List6667else :68raise ValueError('The variable ``Input`` is inappropriate.')697071def __init__ ( self , Base_Space:Irreducible_Homogeneous_Variety , Starting_Block:list[ Equivariant_Vector_Bundle ] , Twist:Irreducible_Equivariant_Vector_Bundle or None=None , Support_Pattern:list or str or None='Trivial'72) -> None :73"""74Initialize a Lefschetz collection over an irreducible homogeneous variety.7576INPUT:77- ``Base_Space`` -- Irreducible Homogeneous Variety;78- ``Starting_Block`` -- List;79- ``Twist`` -- Vector bundle over an irreducible homogeneous variety;80- ``Support_Pattern`` -- Tuple;8182OUTPUT: None.83"""84# Base space85assert isinstance( Base_Space , Irreducible_Homogeneous_Variety ) , TypeError('The input for ``base space`` must be an irreducible homogeneous variety.')86self._Base_Space = Base_Space8788# Starting block89if isinstance( Starting_Block , tuple ) : Starting_Block = list(Starting_Block)90self._Starting_Block = []91if isinstance( Starting_Block , list ) :92for Object_Counter , Object in enumerate( Starting_Block , start=_sage_const_1 ) :93assert isinstance( Object , ( Irreducible_Equivariant_Vector_Bundle , Direct_Sum_Of_Equivariant_Vector_Bundles , Extension_Of_Equivariant_Vector_Bundles ) ) , 'The '+str(Object_Counter)+'-th object need to be an equivariant vector bundle.'94assert self._Base_Space == Object.Base_Space() , ValueError('The base space of the '+str(Object_Counter)+'-th object does not coincide with the given base space.')95self._Starting_Block += [ Object ]96else : raise ValueError( 'The input for ``Starting_Block`` is inappropriate.' )9798# Twist99if Twist == None :100if self._Base_Space.Parabolic_Subgroup().Is_Maximal() : Twist = self._Base_Space.calO(_sage_const_1 )101else : raise ValueError( 'For a non-maximal paralic subgroup, one need to clearify the twist explicitly.' )102assert isinstance( Twist , Irreducible_Equivariant_Vector_Bundle ) , TypeError('The input for ``Twist`` must be a vector bundle over an irreducible homogeneous variety.')103assert Twist.Is_Line_Bundle() , ValueError('The input for ``Twist`` need to be a line bundle.')104self._Twist = Twist105106# Support pattern107if Support_Pattern in [ 'Trivial' , None ] :108self._Support_Pattern = { _sage_const_0 : len(self._Starting_Block) * [ True ] }109110elif Support_Pattern in [ 'Maximal' , 'Max' , 'Maximal Length' , infinity ] :111raise ValueError('The method constructing the maximal support pattern is yet not implemented.')112113elif isinstance( Support_Pattern , ( tuple , list ) ) :114Support_Pattern = list(Support_Pattern)115Cases = []116for Entry_Counter , Entry in enumerate( Support_Pattern , start=_sage_const_1 ) :117118if Entry in ZZ :119if not _sage_const_0 <= Entry :120raise ValueError('If the '+str(Entry_Counter)+'-th entry of the input ``Support_Pattern`` is an integer, ' + 'then it must be non-negative.')121if not Entry <= len(self._Starting_Block) :122raise ValueError('If the '+str(Entry_Counter)+'-th entry of the input ``Support_Pattern`` is an integer, ' + 'then it must be bounded by the length of the starting block; namely <= '+str(len(self._Starting_Block))+'.'123)124Label = 'Support partition'125elif instance( Entry , [ tuple , list ] ) :126Entry = list(Entry)127128for Subentry_Counter , Subentry in enumerate( Entry ) :129if not ( Subentry in self.SUPPORT_PATTERN_LABELLING[True] or Subentry in self.SUPPORT_PATTERN_LABELLING[False] ) :130raise ValueError('If the '+str(Entry_Counter)+'-th entry of the input ``Support_Pattern`` is a tuple or a list, ' + 'then it must contain labellings '+str(self.SUPPORT_PATTERN_LABELLING[True])+' or '+str(self.SUPPORT_PATTERN_LABELLING[False])+'.'131)132if not len(Entry) <= len(self._Starting_Block) :133raise ValueError('If the '+str(Entry_Counter)+'-th entry of the input ``Support_Pattern`` is an row with labellings, ' + 'then its length must be bounded by the length of the starting block; namely <= '+str(len(self._Starting_Block))+'.'134)135Label = 'Grid'136137if not Label in Cases : Cases += [ Label ]138139if len( Cases ) == _sage_const_0 : Case = 'Empty support pattern'140elif len( Cases ) == _sage_const_1 : Case = Cases[_sage_const_0 ]141else : raise ValueError( 'The entries of the input ``Support_Pattern`` are inappropriate.' )142143if Case == 'Empty support pattern' :144self._Support_Pattern = dict({})145elif Case == 'Support partition' :146self._Support_Pattern = { Row_Counter : Row_Width*[ True ] + (len(self._Starting_Block)-Row_Width)*[ False ]147for Row_Counter , Row_Width in enumerate( Support_Pattern )148}149elif Case == 'Grid' :150self._Support_Pattern = { Row_Counter : [ Entry in self.SUPPORT_PATTERN_LABELLING[True] for Entry in Row ] + (len(self._Starting_Block)-len(Row))*[ False ]151for Row_Counter , Row in enumerate( Support_Pattern )152}153154elif isinstance( Support_Pattern , dict ) :155self._Support_Pattern = dict({})156for Row_ID , Row in Support_Pattern.items() :157if not Row_ID in ZZ :158raise ValueError('If the input ``Support_Pattern`` is an dictionary, then the keys must be integers.')159if not type( Row ) in [ list ] :160raise ValueError('If the input ``Support_Pattern`` is an dictionary, then the values must be lists.')161if not len(Row) <= len(self._Starting_Block) :162raise ValueError('If the input ``Support_Pattern`` is an dictionary, ' +'then the length of the rows must be bounded by the length of the starting block, namely <= '+str(len(self._Starting_Block))+'.')163for Entry_Counter , Entry in enumerate( Row , start=_sage_const_1 ) :164if ( not Entry in self.SUPPORT_PATTERN_LABELLING[True] ) and ( not Entry in self.SUPPORT_PATTERN_LABELLING[False] ) :165raise ValueError('If the input ``Support_Pattern`` is an dictionary, then the '+str(Entry_Counter)+'-th entry in the row '+str(Row_ID) + 'must be a labelling of the form '+str(self.SUPPORT_PATTERN_LABELLING[True])+' or '+str(self.SUPPORT_PATTERN_LABELLING[False])+'.'166)167for Row_ID , Row in Support_Pattern.items() :168Adjusted_Row = [ Entry in self.SUPPORT_PATTERN_LABELLING[True] for Entry in Row ] + (len(self._Starting_Block)-len(Row))*[ False ]169if True in Adjusted_Row : self._Support_Pattern.update({ Row_ID : Adjusted_Row })170171if _sage_const_0 < len( self._Support_Pattern.keys() ) :172for Row_ID in (ellipsis_range( min(self._Support_Pattern.keys()) ,Ellipsis, max(self._Support_Pattern.keys()) )) :173if not Row_ID in self._Support_Pattern.keys() :174self._Support_Pattern.update({ Row_ID : len(self._Starting_Block)*[ False ] })175176Sorted_Row_IDs = sorted( self._Support_Pattern.keys() )177self._Support_Pattern = { Row_ID : self._Support_Pattern[Row_ID] for Row_ID in Sorted_Row_IDs }178179else :180raise TypeError( 'The input for ``Support_Pattern`` is inappropriate.' )181182# Gram matrix183self._Gram_Matrix = dict({})184185186def __iter__ ( self ) -> Iterator[ Equivariant_Vector_Bundle ] :187"""Returns a generator for the objects of ``self``."""188for yPos , Row in self.Support_Pattern().items() :189for xPos , Object_Is_Accessible in enumerate( Row ) :190if Object_Is_Accessible :191yield self.Starting_Block(xPos) * self.Twist()**yPos192193194def __len__ ( self ) -> int :195"""Returns the number of objects of ``self``."""196return sum([ sum([ _sage_const_1 for Object_Is_Accessible in Row if Object_Is_Accessible ]) for Row in self.Support_Pattern().values() ])197198199def __lshift__ ( self , Shift:int=_sage_const_1 ) -> "Lefschetz_Collection" :200"""Returns the left shift of ``self``."""201return self >> -Shift202203204def __repr__ ( self ) :205"""Returns all attributes which are necessary to initialize the object."""206return self.Base_Space() , self.Starting_Block() , self.Twist() , self.Support_Pattern()207208209def __rshift__ ( self , Shift:int=_sage_const_1 ) -> "Lefschetz_Collection" :210"""Returns a sheft of ``self``."""211assert Shift in ZZ , TypeError('The input for ``Shift`` need to be an integer.')212New_Support_Pattern = { Row_ID+Shift : Row for Row_ID , Row in self.Support_Pattern().items() }213return self.__class__( Base_Space=self.Base_Space() , Starting_Block=self.Starting_Block() , Twist=self.Twist() , Support_Pattern=New_Support_Pattern )(-Shift)214215216def __str__ ( self ) -> str :217"""Returns a one-line string as short description."""218return 'Lefschetz collection consisting of '+str(len(self))+' objects in a grid with width = '+str(self.Width())+' and height = '+str(self.Height())219220221def Base_Space ( self ) -> Irreducible_Homogeneous_Variety :222"""Returns the attribute ``_Base_Space``."""223return self._Base_Space224225226# Synonym for the method ``Row`` :227def Block ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :228"""Returns a single block (= row)."""229self.Row( Input )230231232def Column ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :233"""Returns a single column."""234Width = self.Width()235if Input in ZZ :236if Input <= -Width-_sage_const_1 :237Start_Iteration = False238elif Input in (ellipsis_range( -Width ,Ellipsis, -_sage_const_1 )) :239Start_Iteration = True240xPos = Input + Width241elif Input in (ellipsis_range( _sage_const_0 ,Ellipsis, Width-_sage_const_1 )) :242Start_Iteration = True243xPos = Input244elif Width <= Input :245Start_Iteration = False246247if Start_Iteration :248for yPos , Row in self.Support_Pattern().items() :249Object_Is_Accessible = Row[xPos]250if Object_Is_Accessible : yield self.Starting_Block(xPos)(yPos)251252else :253raise TypeError('The input data must be an integer in the range '+str( (ellipsis_range( -Width ,Ellipsis, Width-_sage_const_1 )) )+'.')254255256def Gram_Matrix ( self , Base_Ring:'Ring'=ZZ , Compute_Now:bool=False ) -> Matrix :257"""258Returns a Gram matrix associated to the computations of EXT( E_p , E_q ) (p: row , q: column).259For 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 ) ).260"""261if Compute_Now == True :262WCR = self.Base_Space().Parent_Group().Weyl_Character_Ring()263if Base_Ring == ZZ : self._Gram_Matrix.update({ ZZ : Matrix( ZZ , [ [ E1.Euler_Sum(E2).degree() for E2 in self ] for E1 in self ] ) })264elif Base_Ring == WCR : self._Gram_Matrix.update({ WCR : [ [ E1.Euler_Sum(E2) for E2 in self ] for E1 in self ] })265else : raise ValueError("The input for `Base_Ring` is inappropriate.")266267return self._Gram_Matrix[Base_Ring]268269else :270if Base_Ring in self._Gram_Matrix.keys() : return self._Gram_Matrix[Base_Ring]271else : return self.Gram_Matrix( Base_Ring=Base_Ring , Compute_Now=True )272273274def Grid ( self , Labelling:list or None=None ) -> list[ list[ str ] ] :275"""Returns a grid of the objects of ``self``."""276if Labelling == None : Labelling = [ 'E'+str(xPos) for xPos in range(self.Width()) ]277assert type(Labelling) == list , TypeError('The input for ``Labelling`` must be a list.')278assert len(Labelling) == self.Width() , ValueError('The ``Labelling`` must be of length '+str(len(self.Width()))+'.')279for Label_Counter , Label in enumerate( Labelling , start=_sage_const_1 ) :280assert type(Label) == str , TypeError('The '+str(Label_Counter)+'-th label must be a string.')281282Table = []283for yPos , self_Row in self.Support_Pattern().items() :284Table_Row = []285for xPos , Object_Is_Accessible in enumerate( self_Row ) :286if Object_Is_Accessible :287Label = Labelling[xPos]288if not yPos == _sage_const_0 : Twist = '('+str(yPos)+')'289else : Twist = ''290Table_Row_Entry = Label+Twist291else : Table_Row_Entry = ''292Table_Row += [ Table_Row_Entry ]293Table += [ Table_Row ]294295if _sage_const_0 < len(self) : return table( Table )296297298def Has_Maximal_Expected_Length ( self ) -> bool :299"""Tests if ``self`` is maximal; i.e. len(self) == rk K_0(X)."""300return len(self) == self.Base_Space().Grothendieck_Group().rank()301302303def Height ( self ) -> int :304"""Returns the height of ``self``."""305return len(self.Support_Pattern().keys())306307308def Is_Exceptional ( self , Test_Numerically:bool=False ) -> bool :309"""310Tests if the Lefschetz collection is (numerically) exceptional.311312INPUT:313- ``self`` -- LefschetzCollection.314315OUTPUT:316- Boolean; return True if ``self`` is exceptional, otherwise False as soon as possible.317318ALGORITHM:319Compare to Lemma 2.2. in [Kuz2006]_320321REFERENCE:322- [Kuz2006] Alexander Kuznetsov: Exceptional collections for Grassmannians of isotropic lines; 2006.323"""324assert type(Test_Numerically) == bool , TypeError('The input for ``Test_Numerically`` need to be boolean.')325326# Test if the accessible objects are exceptional.327# Let E be from the starting block.328# 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.329# NOTE: EXT( E(y) , E(y) ) = EXT( E , E )330for xPos in range(self.Width()) :331# Test if the object is accessible in some row.332Object_Is_Accessible_In_Same_Row = False333for Row in self.Support_Pattern().values() :334if Row[xPos] == True : Object_Is_Accessible_In_Same_Row = True ; break335# If the object is accessible in some row, then test if it is exceptional.336if Object_Is_Accessible_In_Same_Row :337Obj = self.Starting_Block(xPos)338if not Obj.Is_Exceptional(Test_Numerically) : return False339340# Test for accessible objects of the same row, if latter ones are semi-orthogonal to previous ones.341# Let E_1 , E_2 be from the starting block and E_1 is positioned before E_2.342# 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.343# NOTE: EXT( E_2(y) , E_1(y) ) = EXT( E_2 , E_1 )344for xPos1 in range(self.Width()) :345for xPos2 in range(self.Width())[ xPos1+_sage_const_1 : ] :346# Test if there is a row where both objects are simultaneously accessible.347Both_Objects_Are_Simultaneously_Accessible_In_The_Same_Row = False348for Row in self.Support_Pattern().values() :349if Row[xPos1] == True and Row[xPos2] == True : Both_Objects_Are_Simultaneously_Accessible_In_The_Same_Row = True ; break350# If both objects are simultaneously accessible in the same row, then check semi-orthogonality.351if Both_Objects_Are_Simultaneously_Accessible_In_The_Same_Row :352Obj1 = self.Starting_Block(xPos1)353Obj2 = self.Starting_Block(xPos2)354for Obj2_Is_SemiOrthogonal_To_Obj1 in Obj2.Is_SemiOrthogonal_To( Obj1 , Test_Numerically ) :355if not Obj2_Is_SemiOrthogonal_To_Obj1 : return False356357# Test for accessible objects of the same row, if latter ones are semi-orthogonal to previous ones.358# Let E_1 , E_2 be from the starting block.359# 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``360# 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.361# NOTE: EXT( E_2(y_2) , E_1(y_1) ) = EXT( E_2(yDelta) , E_1 )362for xPos1 in range(self.Width()) :363for xPos2 in range(self.Width()) :364for yDelta in range(self.Height())[ _sage_const_1 : ] :365# Test if there are two rows with yDelta difference where both objects are simultaneously accessible.366Both_Objects_Are_Simultaneously_Accessible_In_Rows_With_Difference_yDelta = False367for Row1_ID in self.Support_Pattern().keys() :368Row2_ID = Row1_ID + yDelta369if not Row2_ID in self.Support_Pattern().keys() : break370Row1 = self.Support_Pattern()[Row1_ID]371Row2 = self.Support_Pattern()[Row2_ID]372if Row1[xPos1] == True and Row2[xPos2] == True : Both_Objects_Are_Simultaneously_Accessible_In_Rows_With_Difference_yDelta = True ; break373374# If both objects are simultaneously accessible with respect to yDelta, then check semi-orthogonality.375if Both_Objects_Are_Simultaneously_Accessible_In_Rows_With_Difference_yDelta :376Obj1 = self.Starting_Block(xPos1)377Obj2 = self.Starting_Block(xPos2) * self.Twist()**yDelta378for Obj2_Is_SemiOrthogonal_To_Obj1 in Obj2.Is_SemiOrthogonal_To( Obj1 , Test_Numerically ) :379if not Obj2_Is_SemiOrthogonal_To_Obj1 : return False380381if _sage_const_0 < len(self) : return True382383384def Is_Numerically_Exceptional ( self ) -> bool :385"""Tests if the Lefschetz collection is numerically exceptional."""386return self.Is_Exceptional( Test_Numerically=True )387388389def Numerical_Left_Dual ( self , Index:int ) -> Equivariant_Vector_Bundle :390"""Returns the i-th numerical left dual with respect to ``self.``"""391l = len(self)-_sage_const_1392assert Index in (ellipsis_range( _sage_const_0 ,Ellipsis, l )) , 'The input for ``Index`` need to be in the range from 0 to '+str(l)+'.'393LD = LC[l-Index]394for j in range(l-Index+_sage_const_1 ,l+_sage_const_1 ) :395LD = self[j].Numerical_Right_Mutation( LD )396return LD397398399def Numerical_Right_Dual ( self , Index:int ) -> Equivariant_Vector_Bundle :400"""Returns the i-th numerical right dual with respect to ``self.``"""401l = len(self)-_sage_const_1402assert Index in (ellipsis_range( _sage_const_0 ,Ellipsis, l )) , 'The input for ``Index`` need to be in the range from 0 to '+str(l)+'.'403RD = LC[l-Index]404for j in range(l-Index-_sage_const_1 ,_sage_const_0 ,-_sage_const_1 ) :405RD = self[j].Numerical_Left_Mutation( RD )406return RD407408409# Synonyms for the method ``Column`` :410def Orbit ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :411"""Returns a single orbit (= column)."""412self.Column( Input )413414415def Row ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :416"""Returns a single row."""417Height = self.Height()418if Input in ZZ :419if Input <= -Height-_sage_const_1 :420Start_Iteration = False421elif Input in (ellipsis_range( -Height ,Ellipsis, -_sage_const_1 )) :422Start_Iteration = True423yPos = Input + Height424elif Input in (ellipsis_range( _sage_const_0 ,Ellipsis, Height-_sage_const_1 )) :425Start_Iteration = True426yPos = Input427elif Height <= Input :428Start_Iteration = False429430if Start_Iteration :431for xPos , Object_Is_Accessible in enumerate( self.Support_Pattern()[yPos] ) :432if Object_Is_Accessible : yield self.Starting_Block(xPos)(yPos)433434else :435raise TypeError('The input data must be an integer in the range '+str( (ellipsis_range( -Height ,Ellipsis, Height-_sage_const_1 )) )+'.')436437438def Subcollection( self , Columns:list or None=None , Rows:list or None=None ) -> "Lefschetz_Collection" :439"""Returns the subcollection of the given columns and rows."""440if Columns == None : Columns = range( len( self.Starting_Block() ) )441assert type(Columns) in [ list , range ] , TypeError('The input for ``Columns`` need to be a list or a range.')442if Rows == None : Rows = list( self.Support_Pattern().keys() )443assert type(Rows) in [ list , range ] , TypeError('The input for ``Rows`` need to be a list or a range.')444445New_Starting_Block = [ Object for Object_Counter , Object in enumerate( self.Starting_Block() ) if Object_Counter in Columns ]446New_Support_Pattern = { Row_ID : [ Value for Column_Counter , Value in enumerate( Row ) if Column_Counter in Columns ] for Row_ID , Row in self.Support_Pattern().items() if Row_ID in Rows447}448return self.__class__( Base_Space=self.Base_Space() , Starting_Block=New_Starting_Block , Twist=self.Twist() , Support_Pattern=New_Support_Pattern )449450451def Support_Pattern ( self ) -> list[ list[ bool ] ] :452"""Returns the attribute ``_Support_Pattern``."""453return self._Support_Pattern454455456def Starting_Block ( self , Input:None or int or slice=None ) -> Equivariant_Vector_Bundle or list[ Equivariant_Vector_Bundle ] :457"""Returns the attribute ``_Starting_Block``."""458if Input == None : return self._Starting_Block459elif Input in ZZ :460Index = Input % len(self._Starting_Block)461return self._Starting_Block[Index]462elif type(Input) == slice :463Slice = Input464return self._Starting_Block[Slice]465else : raise ValueError('The input data is inappropriate.')466467468def Twist ( self ) -> Irreducible_Equivariant_Vector_Bundle :469"""Returns the attribute ``_Twist``."""470return self._Twist471472473def Width ( self ) -> int :474"""Returns the width of ``self``."""475return len(self.Starting_Block())476477478def Mutate ( self , Dictionary:dict , Base_Ring:'Ring'=ZZ , Basis=None , Gram_Matrix=None ) -> ( list[ list[ 'Ring element' ] ] , list[ list[ 'Ring element' ] ] ) :479"""Describes the left mutation on the K_0-level."""480# ..ToDo: Implement test for thoses objects, which are mutated through, are exceptional.481482Length = len(self)483484WCR = self.Base_Space().Parent_Group().Weyl_Character_Ring()485if Base_Ring == ZZ : pass486elif Base_Ring == WCR : pass487else : raise ValueError('The input for ``Base_Ring`` is inappropriate.')488489if Basis == None : Basis = [ i*[ Base_Ring(_sage_const_0 ) ] + [ Base_Ring(_sage_const_1 ) ] + (Length-_sage_const_1 -i)*[ Base_Ring(_sage_const_0 ) ] for i in range(Length) ]490491assert type(Basis) == list , TypeError('The input for ``Basis`` must be a list.')492for Element_Counter , Element in enumerate( Basis , start=_sage_const_1 ) :493assert type(Element) == list , ValueError('The '+str(Element_Counter)+'-th element is not a list.')494for Entry_Counter , Entry in enumerate( Element , start=_sage_const_1 ) :495assert Entry in Base_Ring , ValueError('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)+'.')496497if Gram_Matrix == None : Gram_Matrix = self.Gram_Matrix( Base_Ring )498499for Row_Counter , Row in enumerate( Gram_Matrix , start=_sage_const_1 ) :500for Column_Counter , Entry in enumerate( Row , start=_sage_const_1 ) :501assert Entry in Base_Ring , ValueError('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)+'.')502assert Column_Counter == Length , ValueError('The Gram matrix does not have rows of length '+str(Length)+'.')503assert Row_Counter == Length , ValueError('The Gram matrix does not have columns of length '+str(Length)+'.')504505Bases = dict({})506Gram_Matrices = dict({})507508Timer = _sage_const_0509Bases.update({ Timer : Basis })510Gram_Matrices.update({ Timer : Gram_Matrix })511512for Mutation_Counter , ( Start , End ) in enumerate( Dictionary.items() , start=_sage_const_1 ) :513assert Start in range(Length) , ValueError('The '+str(Mutation_Counter)+'-th key of the mutation dictionary is not an element in the range '+str((ellipsis_range( _sage_const_0 ,Ellipsis, Length-_sage_const_1 )))+'.')514assert End in range(Length) , ValueError('The '+str(Mutation_Counter)+'-th value of the mutation dictionary is not an element in the range '+str((ellipsis_range( _sage_const_0 ,Ellipsis, Length-_sage_const_1 )))+'.')515516Index = Start517while Index != End :518Timer += _sage_const_1519if End <= Start : # Left mutation520# Mutation triangle: 0 ----> EXT( E , F ) * E --ev--> F ----> LL_E(F) ----> 0521# i.e. [ LL_E(F) ] = [ F ] - EXT( E , F ) * [ E ] in K_0( self.Base_Space() )522e = Bases[Timer-_sage_const_1 ][ Index-_sage_const_1 ] # The object which is mutated through523f = Bases[Timer-_sage_const_1 ][ Index ] # The object which is mutated524chi = Gram_Matrices[Timer-_sage_const_1 ][ Index-_sage_const_1 ][ Index ]525mutation = [ f[i] - chi * e[i] for i in range(Length) ]526527Bases.update({ Timer : Bases[Timer-_sage_const_1 ][ : Index-_sage_const_1 ] + [ mutation , e ] + Bases[Timer-_sage_const_1 ][ Index+_sage_const_1 : ] })528Gram_Matrices.update({ Timer : [ [ sum([ Base_Ring(_sage_const_0 ) ] + [ Bases[Timer][ Row_Index ][j] * Gram_Matrix[j][i] * Bases[Timer][ Column_Index ][i]529for i in range(Length)530for j in range(Length)531])532for Column_Index in range(Length)533]534for Row_Index in range(Length)535]536})537Index -= _sage_const_1538539else : # Right mutation540# Mutation triangle: 0 ----> RR_F(E) ----> E --coev--> EXT( F , E )^vee * F ----> 0 ???541# i.e. [ RR_F(E) ] = ?542#e = ? # The object which is mutated543#f = ? # The object which is mutated through544#chi = ?545#mutation = ?546547Bases.update({ Timer : Bases[Timer-_sage_const_1 ][ : Index-_sage_const_1 ] + [ f , mutation ] + Bases[Timer-_sage_const_1 ][ Index+_sage_const_1 : ] })548#Gram_Matrices.update({ Timer : ? })549550raise ValueError('The method for right mutations is yet not implemented.')551Index += _sage_const_1552553return Bases[Timer] , Gram_Matrices[Timer]554555556def Test_For_Extension ( self ,557New_Object :Equivariant_Vector_Bundle ,558Relevant_Columns :set[ int ] or None =None ,559Test_Numerically :bool =True ,560Test_If_Self_Is_Exceptional :bool =True561) -> Iterator[ int ] :562"""Test if ``New_Object`` can be inserted to ``self`` at the columns ``Relevant_Columns``."""563564assert isinstance( New_Object , Equivariant_Vector_Bundle ) , 'The input for `New_Object` need to be an equivariant vector bundle.'565New_Orbit = New_Object.Maximal_Exceptional_Orbit( Test_Numerically=Test_Numerically )566567if Relevant_Columns == None : Relevant_Columns = set(range(self.Width()+_sage_const_1 ))568assert isinstance( Relevant_Columns , set ) , 'If the input for `Relevant_Columns` is not None, then it need to be a set.'569assert Relevant_Columns.issubset( set(range(self.Width()+_sage_const_1 )) ) , 'The relevant columns need to be in the range from 0 to '+str(self.Width()+_sage_const_1 )+'.'570571if Test_If_Self_Is_Exceptional == True :572assert self.Is_Exceptional( Test_Numerically=Test_Numerically ) , 'The collection `self` is not exceptional.'573574def Test_For ( xPos1 , yPos1 ) :575Object1 = New_Object(yPos1)576for yPos2 , Row in self.Support_Pattern().items() :577for xPos2 , Object2_Is_Accessible in enumerate( Row ) :578if Object2_Is_Accessible :579Object2 = self.Starting_Block(xPos2)(yPos2)580#if not xPos2 in Already_Tested.keys() : Already_Tested.update({ xPos2 : ( set({}) , set({}) ) })581if yPos2 < yPos1 or ( yPos2 == yPos1 and xPos2 < xPos1 ) :582#if not yPos1-yPos2 in Already_Tested[xPos2][0] :583# Already_Tested[xPos2][0].add( yPos1-yPos2 )584if not next( Object1.Is_SemiOrthogonal_To( Object2 , Test_Numerically=Test_Numerically ) ) : return False585else :586#if not yPos2-yPos1 in Already_Tested[xPos2][1] :587# Already_Tested[xPos2][1].add( yPos2-yPos1 )588if not next( Object2.Is_SemiOrthogonal_To( Object1 , Test_Numerically=Test_Numerically ) ) : return False589return True590591for Tested_xPos in Relevant_Columns :592#Already_Tested = dict({})593yield ( Tested_xPos , [ Tested_yPos for Tested_yPos in range(len(New_Orbit)) if Test_For( Tested_xPos , Tested_yPos ) ] )594595596def Test_For_SemiOrthogonal_Relations ( self ) :597G = self.Base_Space().Parent_Group()598599for x1 , Obj1 in enumerate( self.Starting_Block() ) :600for x2 , Obj2 in enumerate( self.Starting_Block() ) :601Done = []602for y1 , Row1 in LC.Support_Pattern().items() :603if Row1[x1] == True :604for y2 , Row2 in LC.Support_Pattern().items() :605if Row2[x2] == True :606y = y1-y2607if not y in Done :608if _sage_const_0 < y : Position = 'LowerHalf'609elif y == _sage_const_0 and x2 < x1 : Position = 'LowerHalf'610elif y == _sage_const_0 and x2 == x1 : Position = 'Diagonal'611else : Position = 'UpperHalf'612613if Position == 'LowerHalf' or Position == 'Diagonal' :614Done += [y]615EXT_Space = Obj1(y).EXT(Obj2)616Euler_Sum = Obj1(y).Euler_Sum(Obj2)617618if Position == 'LowerHalf' :619if EXT_Space == dict({}) : SemiOrthogonal_Relation = 'Correct.'620elif Euler_Sum == G.rmV(_sage_const_0 ) : SemiOrthogonal_Relation = 'Numerically correct.'621else : SemiOrthogonal_Relation = 'Not correct.'622623elif Position == 'Diagonal' :624if EXT_Space == { _sage_const_0 : G.rmV(_sage_const_1 ) } : SemiOrthogonal_Relation = 'Correct.'625elif Euler_Sum == G.rmV(_sage_const_1 ) : SemiOrthogonal_Relation = 'Numerically correct.'626else : SemiOrthogonal_Relation = 'Not correct.'627628yield ( x1 , x2 , y , SemiOrthogonal_Relation , EXT_Space , Euler_Sum )629630631632