In [1]:
#
#   ReflexivePolytopeFans(polytope, onlyOne=false) generates smooth star triangulations of reflexive lattice polytopes.
#   The parameter "polytope" has to be a reflexive lattice polytope.
#   By default the function returns all of the smooth star triangulations.
#   If "onlyOne" is set to true only one triangulation is returned.
#

import re
import itertools

def ReflexivePolytopeFans(polytope, onlyOne=false):
    
    facets = polytope.facets_lp()
    
    subCones = []
    
    for facet in facets:
        
        points = facet.points()
    
        facetPointConfiguration = PointConfiguration(list(facet.points()),fine=True)
        
        facetCones = []
        
        if onlyOne:
            
            triang = facetPointConfiguration.triangulate()
            
            cones = []
            
            for cone in triang:
                
                conePoints = map(lambda a: tuple(points[a]), cone)
                conePoints.append(tuple([0] * polytope.dim()))
                
                cones.append(Cone(conePoints))
                
            facetCones.append(cones)
        
        else:
            
            iter = facetPointConfiguration.triangulations()
    
            for triang in iter:
            
                cones = []
            
                for cone in triang:
                
                    conePoints = map(lambda a: tuple(points[a]), cone)
                    conePoints.append(tuple([0] * polytope.dim()))
                
                    cones.append(Cone(conePoints))
                
                facetCones.append(cones)
        
        subCones.append(facetCones)
    
    if onlyOne:
        
        return [[item for sublist in [l[0] for l in subCones] for item in sublist]]
        
    else:
    
        return map(lambda l: [item for sublist in l for item in sublist],list(itertools.product(*subCones)))
    
#
#   GetCompleteNefParts(poly, nef) returns a list of indices with respect to poly.points() of the points corresponding
#   to the respective nef partition.
#   The argument poly has to be a reflexive lattice polytope and nef an element of poly.nef_partitions()
#
def GetCompleteNefParts(poly, nef):

    points = poly.points()
    
    part1 = [i for i in range(len(points)) if (points[i] in nef.nabla(0).points()) and not tuple(points[i]) == (0,0,0)]
    part2 = [i for i in range(len(points)) if (points[i] in nef.nabla(1).points()) and not tuple(points[i]) == (0,0,0)]
    
    return [tuple(part1), tuple(part2)]

#
#   CalculateIntersections(polyid, nefid) returns a list of the intersections of the toric divisors on the ambient space
#   corresponding to "polyid" and the nef corresponding to "nefid".
#   The intersections follow the ordering of points used in http://arxiv.org/abs/1411.2615 .
#
def CalculateIntersections(polyid, nefid):
    
    polytope = ReflexivePolytope(3, polyid)
    nef = polytope.nef_partitions()[nefid]
    
    fans = ReflexivePolytopeFans(polytope, onlyOne=True)
    fan = Fan(fans[0])
    variety = ToricVariety(fan)

    nefPart1, nefPart2 = GetCompleteNefParts(polytope, nef)

    polySortPointList = [tuple(point) for point in polytope.points() if not tuple(point) == (0,0,0)]
    generatorList = map(lambda a: tuple(a.rays()[0]), variety.fan(dim=1))
    indices = [polySortPointList.index(gen) for gen in generatorList]

    originIndex = map(tuple, polytope.points()).index((0, 0, 0))

    indices = [index if index < originIndex else index + 1 for index in indices]

    variety = ToricVariety(fan, names=' '.join(['z' + str(index) for index in indices]), coordinate_indices=indices)

    HH = variety.cohomology_ring()
    Dtemp = [ HH(c) for c in variety.fan(dim=1) ]

    D = [1] * (max(indices) + 1)
    for i in range(len(Dtemp)):
    
        D[indices[i]] = Dtemp[i]
    
    nefDiv1 = sum(D[i] for i in nefPart1)
    nefDiv2 = sum(D[i] for i in nefPart2)
    
    return [variety.integrate(nefDiv1 * nefDiv2 * d) for d in D]
In [3]:
#
#   The following cell calculates the intersection numbers of the toric divisors for all complete intersection fibers
#   in three dimensional toric ambient spaces. The data is saved in a dictionary "intersectionDict" and written to the
#   file "intersection.txt". The intersections can be accessed via intersectionDict[(polyid, nefid)] and follow
#   the ordering of points used in http://arxiv.org/abs/1411.2615 .
#

# if you work in a jupyter notebook with widgets, set the following flag to "True"
jupyter = True

npoly = 4319

if jupyter:
    
    from IPython.html.widgets import FloatProgress
    from IPython.display import display

    from  IPython.html.widgets import HTML
    
    boxPolyId = HTML("")
    boxNefId = HTML("")
    display(boxPolyId)
    display(boxNefId)
    
    f = FloatProgress(min=0, max=npoly)
    display(f)

intersectionDict = {}

for polyId in xrange(npoly):
    
    if jupyter:
        
        f.values = polyId
        boxPolyId.value = "polytope id: " + str(polyId)
    
    for nef in enumerate(ReflexivePolytope(3, polyId).nef_partitions()):
        
        if jupyter:
            
            boxNefId.value = "nef id: " + str(nef[0])
        
        intersections = CalculateIntersections(polyId, nef[0])
        intersectionDict[(polyId, nef[0])] = intersections
        
with open("intersection.txt", "w") as f:
    
    f.write("{\n")
    
    for item in sorted(sorted(intersectionDict.items(), key=lambda a: a[0][1]), key=lambda a: a[0][0]):
        
        f.write(str(item[0]) + ": " + str(item[1]) + ",\n")
        
    f.write("}")
In [ ]:
with open("intersection.txt", "r") as f:
    
    print f.read()