[sage-devel] Bug in cohomology calculation of a toric divisor

21 views
Skip to first unread message

Leif Jacob

unread,
Mar 3, 2026, 7:51:43 AM (yesterday) Mar 3
to sage-...@googlegroups.com

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))
D.cohomology(dim=True)

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

Reply all
Reply to author
Forward
0 new messages