Hello,
I noticed something in the calculation of the sheaf cohomology of
a toric divisor in sage/schemes/toric/divisor.
The method _sheaf_complex() is supposed to return an abstract
complex, that coincides with the definition of V_D,m from Cox,
Little, Schenck: "Toric Varieties" [CLS2011] (page 402):
V_D,m = U_{σ∈Σ} Conv(u_ρ|ρ∈σ(1), ⟨m,u_ρ⟩ < -a_ρ)
But the current implementation does this
fan = self.parent().scheme().fan()
ray_is_negative = [m * ray + self.coefficient(i) < 0
for i, ray in enumerate(fan.rays())]
def cone_is_negative(cone): # and non-trivial
if cone.is_trivial():
return False
return all(ray_is_negative[i] for i in cone.ambient_ray_indices())
negative_cones = [cone for cone in flatten(fan.cones()) if cone_is_negative(cone)]
return SimplicialComplex([c.ambient_ray_indices() for c in negative_cones])
Here the array negative_cones only consists of cones, where all
rays fulfil ⟨m,u_ρ⟩ < -a_ρ and thus the abstract complex is the
union of those cones. However we are then missing all the
faces/convex hulls coming from a cone, where not all the rays
fulfil ⟨m,u_ρ⟩ < -a_ρ.
Thus, in none smooth cases we can build counterexamples like this
cone:
cone = Cone([[1,1,1],[1,-1,1], [-1,1,1], [-1,-1,1]])
TorVar = ToricVariety(Fan([cone]))
N = TorVar.fan().lattice()
D = -TorVar.divisor(N(1,1,1)) - TorVar.divisor(N(-1,-1,1))
M = TorVar.fan().dual_lattice()
clpx = D._sheaf_complex(M(0,0,0))
print (D._sheaf_cohomology(clpx))
Output: (0,1,0,0)
Which should not happen, because our toric variety was affine, ie
doesn't has higher cohomology. Similarly, we can extend this
problem to a complete toric variety.
r0, r1, r2, r3, r4 = [[0,0,-1],[1,1,1],[1,-1,1], [-1,1,1], [-1,-1,1]]
c0 = Cone([r1,r2,r3,r4])
c1 = Cone([r0, r1, r2])
c2 = Cone([r0, r1, r3])
c3 = Cone([r0, r4, r2])
c4 = Cone([r0, r4, r3])
TorVar = ToricVariety(Fan([c0, c1, c2, c3, c4]))
N = TorVar.fan().lattice()
D = -TorVar.divisor(N(r1)) - TorVar.divisor(N(r4))
Output: (0,1,0,0)
I think that one can fix this problem by maybe using something
like this:
fan = self.parent().scheme().fan()
#once calculate which rays appear as vertices of the abstract complex
ray_is_negative = [m * ray + self.coefficient(i) < 0
for i, ray in enumerate(fan.rays())]
#the set of faces of the abstract complex
simplicial_faces = []
for cone in flatten(fan.cones()):
#by definition, we take the convex hull of the negative rays for each cone
simplicial_faces.append([ray_index for ray_index in cone.ambient_ray_indices() if ray_is_negative[ray_index]])
return SimplicialComplex(simplicial_faces)
Best regards,
Leif Jacob