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
from typing import Iterator
2
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Homogeneous_Variety import Irreducible_Homogeneous_Variety
3
4
5
6
class Orthogonal_Grassmannian ( Irreducible_Homogeneous_Variety ) :
7
8
def __init__( self , k :int , N :int ) -> None :
9
"""
10
Initialize the Grassmannian OGr(k,N).
11
12
INPUT:
13
- ``k`` -- Integer ;
14
- ``N`` -- Integer ;
15
16
OUTPUT: None.
17
"""
18
assert isinstance( N , Integer ) , \
19
TypeError('The input for `N` must be an integer.')
20
assert 5 <= N , \
21
ValueError('The integer `N` must be equal to or greater than 5.')
22
23
assert isinstance( k , Integer ) , \
24
TypeError('The input for `k` must be an integer.')
25
assert k in [ 1 .. floor(N/2) ] , \
26
ValueError('The integer `k` need to be in the range '+str([ 1 .. floor(N/2) ])+'.')
27
28
from Equivariant_Vector_Bundles_On_Homogeneous_Varieties.Base_Space.Homogeneous_Variety import Irreducible_Cartan_Group
29
if N % 2 == 0 :
30
G = Irreducible_Cartan_Group( Cartan_Family='D' , Cartan_Degree=N/2 )
31
if k in [ 1 .. N/2-2 ] : P = G.Maximal_Parabolic_Subgroup( Excluded_Node=k )
32
elif k == N/2-1 : P = G.Parabolic_Subgroup( Excluded_Nodes={N/2-1,N/2} )
33
elif k == N/2 : P = G.Maximal_Parabolic_Subgroup( Excluded_Node=N/2-1 )
34
else :
35
G = Irreducible_Cartan_Group( Cartan_Family='B' , Cartan_Degree=floor(N/2) )
36
P = G.Maximal_Parabolic_Subgroup( Excluded_Node=k )
37
38
super( Orthogonal_Grassmannian , self ).__init__( P )
39
40
41
def __repr__ ( self ) -> tuple[ int ] :
42
"""Returns all attributes which are necessary to initialize the object."""
43
return self.k() , self.N()
44
45
46
def __str__ ( self , Output_Style='Long' ) -> str :
47
"""Returns a one-line string as short description."""
48
if Output_Style == 'Short' : return 'OGr('+str(self.k())+';'+str(self.N())+')'
49
elif Output_Style == 'Long' : return 'Orthogonal grassmannian variety of '+str(self.k())+'-dimensional isotropic linear subspaces' + \
50
' in a '+str(self.N())+'-dimensional ambient vector space.'
51
else : raise ValueError('The input for ``Output_Style`` is inappropriate.')
52
53
54
# Synonym for the method ``Spinor_Bundle``
55
def calS ( self ) -> "Irreducible_Equivariant_Vector_Bundle" :
56
"""Returns the spinor bundle ."""
57
return self.Spinor_Bundle()
58
59
60
def Fano_Index ( self ) -> int :
61
"""Returns the Fano index of ``self``."""
62
for Node , Fano_Index in super( Orthogonal_Grassmannian , self ).Fano_Index() :
63
if Node == self.k() : return Fano_Index
64
raise ValueError('PROBLEM! We could not compute the Fano index.')
65
66
67
def My_Collection ( self , Modus :str ='Consecutive' , Parts :list =[1,2] ) -> "Lefschetz_Collection" :
68
assert isinstance( Modus , str ) , \
69
'The input for `Modus` need to be a string.'
70
71
if Modus in [ 'Consecutive' , 'Con' ] :
72
ConLC = self.Lefschetz_Collection( Starting_Block=[] )
73
ConLC += self.Tautological_Collection( Parts=Parts )
74
ConLC += self.Spinor_Collection()
75
return ConLC
76
77
elif Modus in [ 'Alternating' , 'Alt' ] :
78
ConLC = self.My_Collection( Modus='Consecutive' , Parts=Parts )
79
Stock = dict({})
80
for ColumnCounter in range(ConLC.Width()) :
81
Orbit = ConLC.Subcollection( Columns=[ColumnCounter] )
82
d = max([ Summand.Highest_Weight().to_ambient()[0] for Summand in Orbit[0].Irreducible_Components() ])
83
if not d in Stock.keys() : Stock.update({ d : self.Lefschetz_Collection( Starting_Block=[] ) })
84
Stock[d] += Orbit
85
AltLC = self.Lefschetz_Collection( Starting_Block=[] )
86
for d , Part in sorted(Stock.items()) :
87
AltLC += Part
88
return AltLC
89
90
else :
91
raise ValueError( 'The input for `Modus` is unknown.' )
92
93
94
def Spinor_Bundle ( self , Parity : int or str or None =None ) -> "Irreducible_Equivariant_Vector_Bundle" :
95
"""Returns the spinor bundle."""
96
Cartan_Family = self.Cartan_Family()
97
n = self.Cartan_Degree()
98
fw = self.Basis('fw')
99
if Cartan_Family == 'B' :
100
return self.calU( fw[n] )
101
102
elif Cartan_Family == 'D' :
103
if Parity in [ 1 , '+' ] : return self.calU( fw[n-1] )
104
elif Parity in [ -1 , '-' ] : return self.calU( fw[n] )
105
else : raise ValueError('For the Cartan Family D, there need to be a parity `+` or `-`.')
106
107
else :
108
raise ValueError('Conflict! There are only spinor bundles for Cartan families B_n and D_n respectively.')
109
110
111
def Spinor_Collection ( self ) -> "Lefschetz_Collection" :
112
Cartan_Family = self.Parent_Group().Cartan_Family()
113
n = self.Parent_Group().Cartan_Degree()
114
k = self.k()
115
fw = self.Basis('fw')
116
LC = self.Lefschetz_Collection( Starting_Block=[] , Support_Pattern='Trivial' )
117
if Cartan_Family == 'B' :
118
Starting_Block = []
119
if k == 1 :
120
Starting_Block = [ self.calU( fw[n] ) ]
121
Support_Partition = tuple( [ 1 ] )
122
LC += self.Lefschetz_Collection( Starting_Block=Starting_Block , Support_Pattern=Support_Partition )
123
124
elif k == 2 :
125
if n == 2 :
126
pass
127
128
else :
129
Starting_Block = [ self.calU( fw[n] ) ]
130
Support_Partition = tuple( (2*n-2)*[ 1 ] )
131
LC += self.Lefschetz_Collection( Starting_Block=Starting_Block , Support_Pattern=Support_Partition )
132
133
elif 3 <= k :
134
if k < n : Starting_Block += [ self.calU(fw[n]) ]
135
Starting_Block += [ self.calU( Degree*fw[1]+fw[n] ).Extend_Equivariantly_By( self.calU( (Degree-1)*fw[1]+fw[n] ) )
136
for Degree in range(1,n-k+1)
137
]
138
Support_Partition = tuple( self.Fano_Index()*[ len(Starting_Block) ] )
139
LC += self.Lefschetz_Collection( Starting_Block=Starting_Block , Support_Pattern=Support_Partition )
140
141
if k == 3 :
142
if n == 3 :
143
Starting_Block = [ self.calU( fw[1] ).Extend_Equivariantly_By( self.calO() ) ]
144
Support_Partition = tuple( 2*[ 1 ] )
145
else :
146
Starting_Block = [ self.calU( (n-2)*fw[1]+fw[n] ).Extend_Equivariantly_By( self.calU( (n-3)*fw[1]+fw[n] ) ) ]
147
Support_Partition = tuple( (n-2)*[ 1 ] )
148
LC += self.Lefschetz_Collection( Starting_Block=Starting_Block , Support_Pattern=Support_Partition )
149
150
elif Cartan_Family == 'D' :
151
pass
152
153
return LC
154
155
156
def Spinor_Filtration ( self , Parity :str or None =None , Factor :"Equivariant_Vector_Bundle" or None =None ) -> Iterator[ str ] :
157
"""
158
Returns the filtration on the spinor bundle.
159
160
REFERENCE:
161
- [Kuz08a] Kuznetsov, Alexander: Exceptional collections for Grassmannians of isotropic lines.
162
"""
163
if Factor == None : Factor = self.calO()
164
assert isinstance( Factor , Equivariant_Vector_Bundle ) , \
165
'The input for `Factor` need to be an equivariant vector bundle.'
166
Cartan_Family = self.Cartan_Family()
167
n = self.Cartan_Degree()
168
k = self.k()
169
fw = self.Basis('fw')
170
if Cartan_Family == 'B' :
171
calS = self.calS()
172
calU = self.calU()
173
yield 'F_'+str(k+1)+' = 0'
174
for i in range( k , -1 , -1 ) :
175
Quotient = str( calS * calU.Exterior_Power(i) * Factor )
176
yield '0 --> F_'+str(i+1)+' --> F_'+str(i)+' --> '+str(Quotient)+' --> 0'
177
yield 'F_0 = '+str( Factor.Multiply_By( calS.H0() ) )
178
179
elif Cartan_Family == 'D' :
180
if Parity in [ 1 , '+' ] : ParityStr = '+' ; ParityInt = 1
181
elif Parity in [ -1 , '-' ] : ParityStr = '-' ; ParityInt = -1
182
else : raise ValueError('For the Cartan Family D, there need to be a parity in '+str([ 1 , '+' ])+' or in '+str([ -1 , '-' ])+'.')
183
yield 'F^'+ParityStr+'_'+str(k+1)+' = 0'
184
for i in range( k , -1 , -1 ) :
185
Quotient = str( self.calS( ParityInt * (-1)^i ) * calU.Exterior_Power(i) * Factor )
186
yield '0 --> F^'+ParityStr+'_'+str(i+1)+' --> F^'+ParityStr+'_'+str(i)+' --> '+str(Quotient)+' --> 0'
187
yield 'F_0 = '+str( Factor.Multiply_By( self.calS(Parity).H0() ) )
188
189
else :
190
raise ValueError('Conflict! There are only spinor bundles for Cartan families B_n and D_n respectively.')
191
192
193
def Tautological_Collection ( self , Parts :list =[1,2] ) -> "Lefschetz_Collection" :
194
n = self.Parent_Group().Cartan_Degree()
195
k = self.k()
196
fw = self.Basis('fw')
197
198
assert isinstance( Parts , list ) , \
199
'The input for ``Parts`` need to be a list.'
200
201
Universe = []
202
# Initialise part 2 (if desired)
203
if 2 in Parts :
204
if k == 3 :
205
for Partition in IntegerListsLex( length=3 , \
206
floor=[ n-2 , 0 , 0 ] , ceiling=[ floor(3/2*(n-3)) , ceil(1/2*(n-3)) , 0 ] , \
207
#max_sum=sum([ (k-i)*(n-k) for i in [ 1 .. k-1 ] ]) ,
208
min_slope=-n+3 , max_slope=0 \
209
) :
210
Partition = list(Partition)
211
Universe += [ [ Partition[Counter-1]-Partition[Counter] for Counter in range( 1 , len(Partition) ) ] ]
212
213
# Initialise part 1 (if desired)
214
if 1 in Parts :
215
for Partition in IntegerListsLex( length=k , ceiling=(k-1)*[n-k]+[0] , max_slope=0 ) :
216
Partition = list(Partition)
217
Universe += [ [ Partition[Counter-1]-Partition[Counter] for Counter in range( 1 , len(Partition) ) ] ]
218
219
Universe.reverse()
220
Starting_Block = [ self.calU( sum([ self.Null_Weight() ] + [ Coefficient*fw[Node] for Node , Coefficient in enumerate( Coefficients , start=1 ) ]) )
221
for Coefficients in Universe
222
]
223
Support_Partition = self.Fano_Index() * [ len(Starting_Block) ]
224
return self.Lefschetz_Collection( Starting_Block=Starting_Block , Support_Pattern=Support_Partition )
225
226
227
228
class Quadric_Space ( Orthogonal_Grassmannian ) :
229
230
def __init__( self , Dimension :int ) -> None :
231
"""
232
Initialize the quadratic space of a given dimension.
233
234
INPUT:
235
- ``Dimension`` -- Integer ;
236
237
OUTPUT: None.
238
"""
239
assert isinstance( Dimension , Integer ) , \
240
TypeError('The input for `Dimension` must be an integer.')
241
assert 0 < Dimension , \
242
ValueError('The dimension must be greater than zero.')
243
244
super( Quadric_Space , self ).__init__( k=1 , N=Dimension+2 )
245
246
247
def __repr__ ( self ) -> int :
248
"""Returns all attributes which are necessary to initialize the object."""
249
return self.Dimension()
250
251
252
def __str__ ( self , Output_Style='Long' ) -> str :
253
"""Returns a one-line string as short description."""
254
if Output_Style == 'Short' : return 'Q^'+str(self.Dimension())
255
elif Output_Style == 'Long' : return 'Quadric space of dimension '+str(self.Dimension())+'.'
256
else : raise ValueError('The input for ``Output_Style`` is inappropriate.')
257