Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Environment to perform calculations of equivariant vector bundles on homogeneous varieties

1842 views
License: GPL3
ubuntu2204
1
2
3
# This file was *autogenerated* from the file Lefschetz_Collection.sage
4
from sage.all_cmdline import * # import sage library
5
6
_sage_const_1 = Integer(1); _sage_const_0 = Integer(0)
7
from typing import Iterator
8
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Foundation.Structure import Structure
9
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Homogeneous_Variety import Irreducible_Homogeneous_Variety
10
from 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_Bundles
11
12
13
14
class Lefschetz_Collection ( Structure ) :
15
16
SUPPORT_PATTERN_LABELLING = { True : [ True , _sage_const_1 , 'x' , 'X' ] ,
17
False : [ False , _sage_const_0 , 'o' , 'O' ]
18
}
19
20
21
def __add__ ( self , other:"Lefschetz_Collection" ) -> "Lefschetz_Collection" :
22
"""Returns the concatenation of ``self`` with ``other``."""
23
assert isinstance( other , self.__class__ ) , TypeError('The input for ``other`` must be a Lefschetz collection.')
24
assert self.Base_Space() == other.Base_Space() , ValueError('The base spaces of ``self`` and ``other`` need to coincide.')
25
assert self.Twist() == other.Twist() , ValueError('The twists of ``self`` and ``other`` need to coincide.')
26
27
New_Starting_Block = self.Starting_Block()+other.Starting_Block()
28
29
New_Support_Pattern = dict({})
30
Row_IDs = list(self.Support_Pattern().keys())+list(other.Support_Pattern().keys())
31
if _sage_const_0 < len(Row_IDs) :
32
for Row_ID in (ellipsis_range( min(Row_IDs) ,Ellipsis, max(Row_IDs) )) :
33
Row = []
34
if Row_ID in self.Support_Pattern().keys() : Row += self.Support_Pattern()[Row_ID]
35
else : Row += self.Width() * [ False ]
36
if Row_ID in other.Support_Pattern().keys() : Row += other.Support_Pattern()[Row_ID]
37
else : Row += other.Width() * [ False ]
38
New_Support_Pattern.update({ Row_ID : Row })
39
40
return self.__class__( Base_Space=self.Base_Space() , Starting_Block=New_Starting_Block , Twist=self.Twist() , Support_Pattern=New_Support_Pattern )
41
42
43
def __call__ ( self , *Twists:tuple[int] ) -> "Lefschetz_Collection" :
44
"""Returns a Lefschetz collection with twisted starting block."""
45
return 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() )
46
47
48
def __getitem__ ( self , Input:int or slice
49
) -> 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 ] :
50
"""Returns a single datum or slices of data."""
51
if Input in ZZ :
52
Index = Input
53
if Index <= -len(self)-_sage_const_1 : return None
54
elif Index in (ellipsis_range( -len(self) ,Ellipsis, -_sage_const_1 )) : Index += len(self)
55
elif Index in (ellipsis_range( _sage_const_0 ,Ellipsis, len(self)-_sage_const_1 )) : pass
56
else : return None
57
for Counter , Object in enumerate( self ) :
58
if Counter == Index : return Object
59
60
elif type(Input) == slice :
61
Slice = Input
62
Indices = range(len(self))[Slice]
63
List = []
64
for Counter , Object in enumerate( self ) :
65
if Counter in Indices : List += [ Object ]
66
return List
67
68
else :
69
raise ValueError('The variable ``Input`` is inappropriate.')
70
71
72
def __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'
73
) -> None :
74
"""
75
Initialize a Lefschetz collection over an irreducible homogeneous variety.
76
77
INPUT:
78
- ``Base_Space`` -- Irreducible Homogeneous Variety;
79
- ``Starting_Block`` -- List;
80
- ``Twist`` -- Vector bundle over an irreducible homogeneous variety;
81
- ``Support_Pattern`` -- Tuple;
82
83
OUTPUT: None.
84
"""
85
# Base space
86
assert isinstance( Base_Space , Irreducible_Homogeneous_Variety ) , TypeError('The input for ``base space`` must be an irreducible homogeneous variety.')
87
self._Base_Space = Base_Space
88
89
# Starting block
90
if isinstance( Starting_Block , tuple ) : Starting_Block = list(Starting_Block)
91
self._Starting_Block = []
92
if isinstance( Starting_Block , list ) :
93
for Object_Counter , Object in enumerate( Starting_Block , start=_sage_const_1 ) :
94
assert 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.'
95
assert 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.')
96
self._Starting_Block += [ Object ]
97
else : raise ValueError( 'The input for ``Starting_Block`` is inappropriate.' )
98
99
# Twist
100
if Twist == None :
101
if self._Base_Space.Parabolic_Subgroup().Is_Maximal() : Twist = self._Base_Space.calO(_sage_const_1 )
102
else : raise ValueError( 'For a non-maximal paralic subgroup, one need to clearify the twist explicitly.' )
103
assert isinstance( Twist , Irreducible_Equivariant_Vector_Bundle ) , TypeError('The input for ``Twist`` must be a vector bundle over an irreducible homogeneous variety.')
104
assert Twist.Is_Line_Bundle() , ValueError('The input for ``Twist`` need to be a line bundle.')
105
self._Twist = Twist
106
107
# Support pattern
108
if Support_Pattern in [ 'Trivial' , None ] :
109
self._Support_Pattern = { _sage_const_0 : len(self._Starting_Block) * [ True ] }
110
111
elif Support_Pattern in [ 'Maximal' , 'Max' , 'Maximal Length' , infinity ] :
112
raise ValueError('The method constructing the maximal support pattern is yet not implemented.')
113
114
elif isinstance( Support_Pattern , ( tuple , list ) ) :
115
Support_Pattern = list(Support_Pattern)
116
Cases = []
117
for Entry_Counter , Entry in enumerate( Support_Pattern , start=_sage_const_1 ) :
118
119
if Entry in ZZ :
120
if not _sage_const_0 <= Entry :
121
raise ValueError('If the '+str(Entry_Counter)+'-th entry of the input ``Support_Pattern`` is an integer, ' + 'then it must be non-negative.')
122
if not Entry <= len(self._Starting_Block) :
123
raise 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))+'.'
124
)
125
Label = 'Support partition'
126
elif instance( Entry , [ tuple , list ] ) :
127
Entry = list(Entry)
128
129
for Subentry_Counter , Subentry in enumerate( Entry ) :
130
if not ( Subentry in self.SUPPORT_PATTERN_LABELLING[True] or Subentry in self.SUPPORT_PATTERN_LABELLING[False] ) :
131
raise 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])+'.'
132
)
133
if not len(Entry) <= len(self._Starting_Block) :
134
raise 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))+'.'
135
)
136
Label = 'Grid'
137
138
if not Label in Cases : Cases += [ Label ]
139
140
if len( Cases ) == _sage_const_0 : Case = 'Empty support pattern'
141
elif len( Cases ) == _sage_const_1 : Case = Cases[_sage_const_0 ]
142
else : raise ValueError( 'The entries of the input ``Support_Pattern`` are inappropriate.' )
143
144
if Case == 'Empty support pattern' :
145
self._Support_Pattern = dict({})
146
elif Case == 'Support partition' :
147
self._Support_Pattern = { Row_Counter : Row_Width*[ True ] + (len(self._Starting_Block)-Row_Width)*[ False ]
148
for Row_Counter , Row_Width in enumerate( Support_Pattern )
149
}
150
elif Case == 'Grid' :
151
self._Support_Pattern = { Row_Counter : [ Entry in self.SUPPORT_PATTERN_LABELLING[True] for Entry in Row ] + (len(self._Starting_Block)-len(Row))*[ False ]
152
for Row_Counter , Row in enumerate( Support_Pattern )
153
}
154
155
elif isinstance( Support_Pattern , dict ) :
156
self._Support_Pattern = dict({})
157
for Row_ID , Row in Support_Pattern.items() :
158
if not Row_ID in ZZ :
159
raise ValueError('If the input ``Support_Pattern`` is an dictionary, then the keys must be integers.')
160
if not type( Row ) in [ list ] :
161
raise ValueError('If the input ``Support_Pattern`` is an dictionary, then the values must be lists.')
162
if not len(Row) <= len(self._Starting_Block) :
163
raise 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))+'.')
164
for Entry_Counter , Entry in enumerate( Row , start=_sage_const_1 ) :
165
if ( not Entry in self.SUPPORT_PATTERN_LABELLING[True] ) and ( not Entry in self.SUPPORT_PATTERN_LABELLING[False] ) :
166
raise 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])+'.'
167
)
168
for Row_ID , Row in Support_Pattern.items() :
169
Adjusted_Row = [ Entry in self.SUPPORT_PATTERN_LABELLING[True] for Entry in Row ] + (len(self._Starting_Block)-len(Row))*[ False ]
170
if True in Adjusted_Row : self._Support_Pattern.update({ Row_ID : Adjusted_Row })
171
172
if _sage_const_0 < len( self._Support_Pattern.keys() ) :
173
for Row_ID in (ellipsis_range( min(self._Support_Pattern.keys()) ,Ellipsis, max(self._Support_Pattern.keys()) )) :
174
if not Row_ID in self._Support_Pattern.keys() :
175
self._Support_Pattern.update({ Row_ID : len(self._Starting_Block)*[ False ] })
176
177
Sorted_Row_IDs = sorted( self._Support_Pattern.keys() )
178
self._Support_Pattern = { Row_ID : self._Support_Pattern[Row_ID] for Row_ID in Sorted_Row_IDs }
179
180
else :
181
raise TypeError( 'The input for ``Support_Pattern`` is inappropriate.' )
182
183
# Gram matrix
184
self._Gram_Matrix = dict({})
185
186
187
def __iter__ ( self ) -> Iterator[ Equivariant_Vector_Bundle ] :
188
"""Returns a generator for the objects of ``self``."""
189
for yPos , Row in self.Support_Pattern().items() :
190
for xPos , Object_Is_Accessible in enumerate( Row ) :
191
if Object_Is_Accessible :
192
yield self.Starting_Block(xPos) * self.Twist()**yPos
193
194
195
def __len__ ( self ) -> int :
196
"""Returns the number of objects of ``self``."""
197
return sum([ sum([ _sage_const_1 for Object_Is_Accessible in Row if Object_Is_Accessible ]) for Row in self.Support_Pattern().values() ])
198
199
200
def __lshift__ ( self , Shift:int=_sage_const_1 ) -> "Lefschetz_Collection" :
201
"""Returns the left shift of ``self``."""
202
return self >> -Shift
203
204
205
def __repr__ ( self ) :
206
"""Returns all attributes which are necessary to initialize the object."""
207
return self.Base_Space() , self.Starting_Block() , self.Twist() , self.Support_Pattern()
208
209
210
def __rshift__ ( self , Shift:int=_sage_const_1 ) -> "Lefschetz_Collection" :
211
"""Returns a sheft of ``self``."""
212
assert Shift in ZZ , TypeError('The input for ``Shift`` need to be an integer.')
213
New_Support_Pattern = { Row_ID+Shift : Row for Row_ID , Row in self.Support_Pattern().items() }
214
return self.__class__( Base_Space=self.Base_Space() , Starting_Block=self.Starting_Block() , Twist=self.Twist() , Support_Pattern=New_Support_Pattern )(-Shift)
215
216
217
def __str__ ( self ) -> str :
218
"""Returns a one-line string as short description."""
219
return 'Lefschetz collection consisting of '+str(len(self))+' objects in a grid with width = '+str(self.Width())+' and height = '+str(self.Height())
220
221
222
def Base_Space ( self ) -> Irreducible_Homogeneous_Variety :
223
"""Returns the attribute ``_Base_Space``."""
224
return self._Base_Space
225
226
227
# Synonym for the method ``Row`` :
228
def Block ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :
229
"""Returns a single block (= row)."""
230
self.Row( Input )
231
232
233
def Column ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :
234
"""Returns a single column."""
235
Width = self.Width()
236
if Input in ZZ :
237
if Input <= -Width-_sage_const_1 :
238
Start_Iteration = False
239
elif Input in (ellipsis_range( -Width ,Ellipsis, -_sage_const_1 )) :
240
Start_Iteration = True
241
xPos = Input + Width
242
elif Input in (ellipsis_range( _sage_const_0 ,Ellipsis, Width-_sage_const_1 )) :
243
Start_Iteration = True
244
xPos = Input
245
elif Width <= Input :
246
Start_Iteration = False
247
248
if Start_Iteration :
249
for yPos , Row in self.Support_Pattern().items() :
250
Object_Is_Accessible = Row[xPos]
251
if Object_Is_Accessible : yield self.Starting_Block(xPos)(yPos)
252
253
else :
254
raise TypeError('The input data must be an integer in the range '+str( (ellipsis_range( -Width ,Ellipsis, Width-_sage_const_1 )) )+'.')
255
256
257
def Gram_Matrix ( self , Base_Ring:'Ring'=ZZ , Compute_Now:bool=False ) -> Matrix :
258
"""
259
Returns a Gram matrix associated to the computations of EXT( E_p , E_q ) (p: row , q: column).
260
For 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 ) ).
261
"""
262
if Compute_Now == True :
263
WCR = self.Base_Space().Parent_Group().Weyl_Character_Ring()
264
if Base_Ring == ZZ : self._Gram_Matrix.update({ ZZ : Matrix( ZZ , [ [ E1.Euler_Sum(E2).degree() for E2 in self ] for E1 in self ] ) })
265
elif Base_Ring == WCR : self._Gram_Matrix.update({ WCR : [ [ E1.Euler_Sum(E2) for E2 in self ] for E1 in self ] })
266
else : raise ValueError("The input for `Base_Ring` is inappropriate.")
267
268
return self._Gram_Matrix[Base_Ring]
269
270
else :
271
if Base_Ring in self._Gram_Matrix.keys() : return self._Gram_Matrix[Base_Ring]
272
else : return self.Gram_Matrix( Base_Ring=Base_Ring , Compute_Now=True )
273
274
275
def Grid ( self , Labelling:list or None=None ) -> list[ list[ str ] ] :
276
"""Returns a grid of the objects of ``self``."""
277
if Labelling == None : Labelling = [ 'E'+str(xPos) for xPos in range(self.Width()) ]
278
assert type(Labelling) == list , TypeError('The input for ``Labelling`` must be a list.')
279
assert len(Labelling) == self.Width() , ValueError('The ``Labelling`` must be of length '+str(len(self.Width()))+'.')
280
for Label_Counter , Label in enumerate( Labelling , start=_sage_const_1 ) :
281
assert type(Label) == str , TypeError('The '+str(Label_Counter)+'-th label must be a string.')
282
283
Table = []
284
for yPos , self_Row in self.Support_Pattern().items() :
285
Table_Row = []
286
for xPos , Object_Is_Accessible in enumerate( self_Row ) :
287
if Object_Is_Accessible :
288
Label = Labelling[xPos]
289
if not yPos == _sage_const_0 : Twist = '('+str(yPos)+')'
290
else : Twist = ''
291
Table_Row_Entry = Label+Twist
292
else : Table_Row_Entry = ''
293
Table_Row += [ Table_Row_Entry ]
294
Table += [ Table_Row ]
295
296
if _sage_const_0 < len(self) : return table( Table )
297
298
299
def Has_Maximal_Expected_Length ( self ) -> bool :
300
"""Tests if ``self`` is maximal; i.e. len(self) == rk K_0(X)."""
301
return len(self) == self.Base_Space().Grothendieck_Group().rank()
302
303
304
def Height ( self ) -> int :
305
"""Returns the height of ``self``."""
306
return len(self.Support_Pattern().keys())
307
308
309
def Is_Exceptional ( self , Test_Numerically:bool=False ) -> bool :
310
"""
311
Tests if the Lefschetz collection is (numerically) exceptional.
312
313
INPUT:
314
- ``self`` -- LefschetzCollection.
315
316
OUTPUT:
317
- Boolean; return True if ``self`` is exceptional, otherwise False as soon as possible.
318
319
ALGORITHM:
320
Compare to Lemma 2.2. in [Kuz2006]_
321
322
REFERENCE:
323
- [Kuz2006] Alexander Kuznetsov: Exceptional collections for Grassmannians of isotropic lines; 2006.
324
"""
325
assert type(Test_Numerically) == bool , TypeError('The input for ``Test_Numerically`` need to be boolean.')
326
327
# Test if the accessible objects are exceptional.
328
# Let E be from the starting block.
329
# 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.
330
# NOTE: EXT( E(y) , E(y) ) = EXT( E , E )
331
for xPos in range(self.Width()) :
332
# Test if the object is accessible in some row.
333
Object_Is_Accessible_In_Same_Row = False
334
for Row in self.Support_Pattern().values() :
335
if Row[xPos] == True : Object_Is_Accessible_In_Same_Row = True ; break
336
# If the object is accessible in some row, then test if it is exceptional.
337
if Object_Is_Accessible_In_Same_Row :
338
Obj = self.Starting_Block(xPos)
339
if not Obj.Is_Exceptional(Test_Numerically) : return False
340
341
# Test for accessible objects of the same row, if latter ones are semi-orthogonal to previous ones.
342
# Let E_1 , E_2 be from the starting block and E_1 is positioned before E_2.
343
# 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.
344
# NOTE: EXT( E_2(y) , E_1(y) ) = EXT( E_2 , E_1 )
345
for xPos1 in range(self.Width()) :
346
for xPos2 in range(self.Width())[ xPos1+_sage_const_1 : ] :
347
# Test if there is a row where both objects are simultaneously accessible.
348
Both_Objects_Are_Simultaneously_Accessible_In_The_Same_Row = False
349
for Row in self.Support_Pattern().values() :
350
if Row[xPos1] == True and Row[xPos2] == True : Both_Objects_Are_Simultaneously_Accessible_In_The_Same_Row = True ; break
351
# If both objects are simultaneously accessible in the same row, then check semi-orthogonality.
352
if Both_Objects_Are_Simultaneously_Accessible_In_The_Same_Row :
353
Obj1 = self.Starting_Block(xPos1)
354
Obj2 = self.Starting_Block(xPos2)
355
for Obj2_Is_SemiOrthogonal_To_Obj1 in Obj2.Is_SemiOrthogonal_To( Obj1 , Test_Numerically ) :
356
if not Obj2_Is_SemiOrthogonal_To_Obj1 : return False
357
358
# 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.
360
# 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``
361
# 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.
362
# NOTE: EXT( E_2(y_2) , E_1(y_1) ) = EXT( E_2(yDelta) , E_1 )
363
for xPos1 in range(self.Width()) :
364
for xPos2 in range(self.Width()) :
365
for yDelta in range(self.Height())[ _sage_const_1 : ] :
366
# Test if there are two rows with yDelta difference where both objects are simultaneously accessible.
367
Both_Objects_Are_Simultaneously_Accessible_In_Rows_With_Difference_yDelta = False
368
for Row1_ID in self.Support_Pattern().keys() :
369
Row2_ID = Row1_ID + yDelta
370
if not Row2_ID in self.Support_Pattern().keys() : break
371
Row1 = self.Support_Pattern()[Row1_ID]
372
Row2 = self.Support_Pattern()[Row2_ID]
373
if Row1[xPos1] == True and Row2[xPos2] == True : Both_Objects_Are_Simultaneously_Accessible_In_Rows_With_Difference_yDelta = True ; break
374
375
# If both objects are simultaneously accessible with respect to yDelta, then check semi-orthogonality.
376
if Both_Objects_Are_Simultaneously_Accessible_In_Rows_With_Difference_yDelta :
377
Obj1 = self.Starting_Block(xPos1)
378
Obj2 = self.Starting_Block(xPos2) * self.Twist()**yDelta
379
for Obj2_Is_SemiOrthogonal_To_Obj1 in Obj2.Is_SemiOrthogonal_To( Obj1 , Test_Numerically ) :
380
if not Obj2_Is_SemiOrthogonal_To_Obj1 : return False
381
382
if _sage_const_0 < len(self) : return True
383
384
385
def Is_Numerically_Exceptional ( self ) -> bool :
386
"""Tests if the Lefschetz collection is numerically exceptional."""
387
return self.Is_Exceptional( Test_Numerically=True )
388
389
390
def Numerical_Left_Dual ( self , Index:int ) -> Equivariant_Vector_Bundle :
391
"""Returns the i-th numerical left dual with respect to ``self.``"""
392
l = len(self)-_sage_const_1
393
assert Index in (ellipsis_range( _sage_const_0 ,Ellipsis, l )) , 'The input for ``Index`` need to be in the range from 0 to '+str(l)+'.'
394
LD = LC[l-Index]
395
for j in range(l-Index+_sage_const_1 ,l+_sage_const_1 ) :
396
LD = self[j].Numerical_Right_Mutation( LD )
397
return LD
398
399
400
def Numerical_Right_Dual ( self , Index:int ) -> Equivariant_Vector_Bundle :
401
"""Returns the i-th numerical right dual with respect to ``self.``"""
402
l = len(self)-_sage_const_1
403
assert Index in (ellipsis_range( _sage_const_0 ,Ellipsis, l )) , 'The input for ``Index`` need to be in the range from 0 to '+str(l)+'.'
404
RD = LC[l-Index]
405
for j in range(l-Index-_sage_const_1 ,_sage_const_0 ,-_sage_const_1 ) :
406
RD = self[j].Numerical_Left_Mutation( RD )
407
return RD
408
409
410
# Synonyms for the method ``Column`` :
411
def Orbit ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :
412
"""Returns a single orbit (= column)."""
413
self.Column( Input )
414
415
416
def Row ( self , Input:int ) -> Iterator[ Equivariant_Vector_Bundle ] :
417
"""Returns a single row."""
418
Height = self.Height()
419
if Input in ZZ :
420
if Input <= -Height-_sage_const_1 :
421
Start_Iteration = False
422
elif Input in (ellipsis_range( -Height ,Ellipsis, -_sage_const_1 )) :
423
Start_Iteration = True
424
yPos = Input + Height
425
elif Input in (ellipsis_range( _sage_const_0 ,Ellipsis, Height-_sage_const_1 )) :
426
Start_Iteration = True
427
yPos = Input
428
elif Height <= Input :
429
Start_Iteration = False
430
431
if Start_Iteration :
432
for xPos , Object_Is_Accessible in enumerate( self.Support_Pattern()[yPos] ) :
433
if Object_Is_Accessible : yield self.Starting_Block(xPos)(yPos)
434
435
else :
436
raise TypeError('The input data must be an integer in the range '+str( (ellipsis_range( -Height ,Ellipsis, Height-_sage_const_1 )) )+'.')
437
438
439
def Subcollection( self , Columns:list or None=None , Rows:list or None=None ) -> "Lefschetz_Collection" :
440
"""Returns the subcollection of the given columns and rows."""
441
if Columns == None : Columns = range( len( self.Starting_Block() ) )
442
assert type(Columns) in [ list , range ] , TypeError('The input for ``Columns`` need to be a list or a range.')
443
if Rows == None : Rows = list( self.Support_Pattern().keys() )
444
assert type(Rows) in [ list , range ] , TypeError('The input for ``Rows`` need to be a list or a range.')
445
446
New_Starting_Block = [ Object for Object_Counter , Object in enumerate( self.Starting_Block() ) if Object_Counter in Columns ]
447
New_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 Rows
448
}
449
return self.__class__( Base_Space=self.Base_Space() , Starting_Block=New_Starting_Block , Twist=self.Twist() , Support_Pattern=New_Support_Pattern )
450
451
452
def Support_Pattern ( self ) -> list[ list[ bool ] ] :
453
"""Returns the attribute ``_Support_Pattern``."""
454
return self._Support_Pattern
455
456
457
def Starting_Block ( self , Input:None or int or slice=None ) -> Equivariant_Vector_Bundle or list[ Equivariant_Vector_Bundle ] :
458
"""Returns the attribute ``_Starting_Block``."""
459
if Input == None : return self._Starting_Block
460
elif Input in ZZ :
461
Index = Input % len(self._Starting_Block)
462
return self._Starting_Block[Index]
463
elif type(Input) == slice :
464
Slice = Input
465
return self._Starting_Block[Slice]
466
else : raise ValueError('The input data is inappropriate.')
467
468
469
def Twist ( self ) -> Irreducible_Equivariant_Vector_Bundle :
470
"""Returns the attribute ``_Twist``."""
471
return self._Twist
472
473
474
def Width ( self ) -> int :
475
"""Returns the width of ``self``."""
476
return len(self.Starting_Block())
477
478
479
def Mutate ( self , Dictionary:dict , Base_Ring:'Ring'=ZZ , Basis=None , Gram_Matrix=None ) -> ( list[ list[ 'Ring element' ] ] , list[ list[ 'Ring element' ] ] ) :
480
"""Describes the left mutation on the K_0-level."""
481
# ..ToDo: Implement test for thoses objects, which are mutated through, are exceptional.
482
483
Length = len(self)
484
485
WCR = self.Base_Space().Parent_Group().Weyl_Character_Ring()
486
if Base_Ring == ZZ : pass
487
elif Base_Ring == WCR : pass
488
else : raise ValueError('The input for ``Base_Ring`` is inappropriate.')
489
490
if 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) ]
491
492
assert type(Basis) == list , TypeError('The input for ``Basis`` must be a list.')
493
for Element_Counter , Element in enumerate( Basis , start=_sage_const_1 ) :
494
assert type(Element) == list , ValueError('The '+str(Element_Counter)+'-th element is not a list.')
495
for Entry_Counter , Entry in enumerate( Element , start=_sage_const_1 ) :
496
assert 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)+'.')
497
498
if Gram_Matrix == None : Gram_Matrix = self.Gram_Matrix( Base_Ring )
499
500
for Row_Counter , Row in enumerate( Gram_Matrix , start=_sage_const_1 ) :
501
for Column_Counter , Entry in enumerate( Row , start=_sage_const_1 ) :
502
assert 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)+'.')
503
assert Column_Counter == Length , ValueError('The Gram matrix does not have rows of length '+str(Length)+'.')
504
assert Row_Counter == Length , ValueError('The Gram matrix does not have columns of length '+str(Length)+'.')
505
506
Bases = dict({})
507
Gram_Matrices = dict({})
508
509
Timer = _sage_const_0
510
Bases.update({ Timer : Basis })
511
Gram_Matrices.update({ Timer : Gram_Matrix })
512
513
for Mutation_Counter , ( Start , End ) in enumerate( Dictionary.items() , start=_sage_const_1 ) :
514
assert 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 )))+'.')
515
assert 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 )))+'.')
516
517
Index = Start
518
while Index != End :
519
Timer += _sage_const_1
520
if End <= Start : # Left mutation
521
# Mutation triangle: 0 ----> EXT( E , F ) * E --ev--> F ----> LL_E(F) ----> 0
522
# i.e. [ LL_E(F) ] = [ F ] - EXT( E , F ) * [ E ] in K_0( self.Base_Space() )
523
e = Bases[Timer-_sage_const_1 ][ Index-_sage_const_1 ] # The object which is mutated through
524
f = Bases[Timer-_sage_const_1 ][ Index ] # The object which is mutated
525
chi = Gram_Matrices[Timer-_sage_const_1 ][ Index-_sage_const_1 ][ Index ]
526
mutation = [ f[i] - chi * e[i] for i in range(Length) ]
527
528
Bases.update({ Timer : Bases[Timer-_sage_const_1 ][ : Index-_sage_const_1 ] + [ mutation , e ] + Bases[Timer-_sage_const_1 ][ Index+_sage_const_1 : ] })
529
Gram_Matrices.update({ Timer : [ [ sum([ Base_Ring(_sage_const_0 ) ] + [ Bases[Timer][ Row_Index ][j] * Gram_Matrix[j][i] * Bases[Timer][ Column_Index ][i]
530
for i in range(Length)
531
for j in range(Length)
532
])
533
for Column_Index in range(Length)
534
]
535
for Row_Index in range(Length)
536
]
537
})
538
Index -= _sage_const_1
539
540
else : # Right mutation
541
# Mutation triangle: 0 ----> RR_F(E) ----> E --coev--> EXT( F , E )^vee * F ----> 0 ???
542
# i.e. [ RR_F(E) ] = ?
543
#e = ? # The object which is mutated
544
#f = ? # The object which is mutated through
545
#chi = ?
546
#mutation = ?
547
548
Bases.update({ Timer : Bases[Timer-_sage_const_1 ][ : Index-_sage_const_1 ] + [ f , mutation ] + Bases[Timer-_sage_const_1 ][ Index+_sage_const_1 : ] })
549
#Gram_Matrices.update({ Timer : ? })
550
551
raise ValueError('The method for right mutations is yet not implemented.')
552
Index += _sage_const_1
553
554
return Bases[Timer] , Gram_Matrices[Timer]
555
556
557
def Test_For_Extension ( self ,
558
New_Object :Equivariant_Vector_Bundle ,
559
Relevant_Columns :set[ int ] or None =None ,
560
Test_Numerically :bool =True ,
561
Test_If_Self_Is_Exceptional :bool =True
562
) -> Iterator[ int ] :
563
"""Test if ``New_Object`` can be inserted to ``self`` at the columns ``Relevant_Columns``."""
564
565
assert isinstance( New_Object , Equivariant_Vector_Bundle ) , 'The input for `New_Object` need to be an equivariant vector bundle.'
566
New_Orbit = New_Object.Maximal_Exceptional_Orbit( Test_Numerically=Test_Numerically )
567
568
if Relevant_Columns == None : Relevant_Columns = set(range(self.Width()+_sage_const_1 ))
569
assert isinstance( Relevant_Columns , set ) , 'If the input for `Relevant_Columns` is not None, then it need to be a set.'
570
assert 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 )+'.'
571
572
if Test_If_Self_Is_Exceptional == True :
573
assert self.Is_Exceptional( Test_Numerically=Test_Numerically ) , 'The collection `self` is not exceptional.'
574
575
def Test_For ( xPos1 , yPos1 ) :
576
Object1 = New_Object(yPos1)
577
for yPos2 , Row in self.Support_Pattern().items() :
578
for xPos2 , Object2_Is_Accessible in enumerate( Row ) :
579
if Object2_Is_Accessible :
580
Object2 = self.Starting_Block(xPos2)(yPos2)
581
#if not xPos2 in Already_Tested.keys() : Already_Tested.update({ xPos2 : ( set({}) , set({}) ) })
582
if yPos2 < yPos1 or ( yPos2 == yPos1 and xPos2 < xPos1 ) :
583
#if not yPos1-yPos2 in Already_Tested[xPos2][0] :
584
# Already_Tested[xPos2][0].add( yPos1-yPos2 )
585
if not next( Object1.Is_SemiOrthogonal_To( Object2 , Test_Numerically=Test_Numerically ) ) : return False
586
else :
587
#if not yPos2-yPos1 in Already_Tested[xPos2][1] :
588
# Already_Tested[xPos2][1].add( yPos2-yPos1 )
589
if not next( Object2.Is_SemiOrthogonal_To( Object1 , Test_Numerically=Test_Numerically ) ) : return False
590
return True
591
592
for Tested_xPos in Relevant_Columns :
593
#Already_Tested = dict({})
594
yield ( Tested_xPos , [ Tested_yPos for Tested_yPos in range(len(New_Orbit)) if Test_For( Tested_xPos , Tested_yPos ) ] )
595
596
597
def Test_For_SemiOrthogonal_Relations ( self ) :
598
G = self.Base_Space().Parent_Group()
599
600
for x1 , Obj1 in enumerate( self.Starting_Block() ) :
601
for x2 , Obj2 in enumerate( self.Starting_Block() ) :
602
Done = []
603
for y1 , Row1 in LC.Support_Pattern().items() :
604
if Row1[x1] == True :
605
for y2 , Row2 in LC.Support_Pattern().items() :
606
if Row2[x2] == True :
607
y = y1-y2
608
if not y in Done :
609
if _sage_const_0 < y : Position = 'LowerHalf'
610
elif y == _sage_const_0 and x2 < x1 : Position = 'LowerHalf'
611
elif y == _sage_const_0 and x2 == x1 : Position = 'Diagonal'
612
else : Position = 'UpperHalf'
613
614
if Position == 'LowerHalf' or Position == 'Diagonal' :
615
Done += [y]
616
EXT_Space = Obj1(y).EXT(Obj2)
617
Euler_Sum = Obj1(y).Euler_Sum(Obj2)
618
619
if Position == 'LowerHalf' :
620
if EXT_Space == dict({}) : SemiOrthogonal_Relation = 'Correct.'
621
elif Euler_Sum == G.rmV(_sage_const_0 ) : SemiOrthogonal_Relation = 'Numerically correct.'
622
else : SemiOrthogonal_Relation = 'Not correct.'
623
624
elif Position == 'Diagonal' :
625
if EXT_Space == { _sage_const_0 : G.rmV(_sage_const_1 ) } : SemiOrthogonal_Relation = 'Correct.'
626
elif Euler_Sum == G.rmV(_sage_const_1 ) : SemiOrthogonal_Relation = 'Numerically correct.'
627
else : SemiOrthogonal_Relation = 'Not correct.'
628
629
yield ( x1 , x2 , y , SemiOrthogonal_Relation , EXT_Space , Euler_Sum )
630
631
632