In [1]:
# The fastest way to get the ambient space in some "normalized" representation.
Delta = ReflexivePolytope(3, 1529)
P = CPRFanoToricVariety(Delta)
P

3-d CPR-Fano toric variety covered by 12 affine patches
In [2]:
Delta.nef_partitions()

[ Nef-partition {0, 1, 2, 3, 4, 7} U {5, 6, 8, 9, 10, 11}, Nef-partition {0, 1, 2, 3, 4, 5, 6, 8, 9} U {7, 10, 11} (projection) ]
In [3]:
Delta.polar()

3-d reflexive polytope in 3-d lattice N
In [4]:
Delta.polar().nef_partitions()

[ Nef-partition {0, 1, 4, 7, 11, 12, 13} U {2, 3, 5, 6, 8, 9, 10} ]
In [5]:
Delta.plot3d()

In [6]:
#Delta.faces()

In [7]:
P.fan().rays()

N(-1, -1, -1), N(-1, 0, 0), N( 1, 0, 1), N( 1, 0, 0), N( 0, -1, 0), N( 1, 1, 1), N( 0, 0, -1), N( 0, -1, 1), N( 0, 1, -1), N( 0, 1, 0), N( 1, 1, 0), N( 0, 0, 1), N(-1, 0, -1), N(-1, -1, 0) in 3-d lattice N
In [8]:
# Successive blowups are more convenient to see "P3 coordinates" inside
P3 = toric_varieties.P(3)
Sigma = P3.fan().subdivide(sum(sigma.rays()) for sigma in P3.fan())    # Blow up points
Sigma = Sigma.subdivide(sum(sigma.rays()) for sigma in P3.fan(2))      # Blow up lines
P = CPRFanoToricVariety(
Delta_polar=LatticePolytope(Sigma.rays()),
charts=[sigma.ambient_ray_indices() for sigma in Sigma])
P.plot(mode="generators", wall_label=None)

In [9]:
P.Delta().index()

1529
In [10]:
X = P.anticanonical_hypersurface()
show(X)

$\text{Closed subscheme of } \mathbb{P}_{\Delta^{3}_{1529}} \text{ defined by } a_{3} z_{0}^{2} z_{1} z_{2} z_{5} z_{6} z_{7}^{2} z_{8}^{2} z_{9}^{2} z_{10} z_{11} + a_{5} z_{0} z_{1}^{2} z_{2} z_{4} z_{6} z_{7}^{2} z_{8}^{2} z_{9} z_{10}^{2} z_{12} + a_{8} z_{0}^{2} z_{1} z_{3} z_{5} z_{6}^{2} z_{7} z_{8}^{2} z_{9} z_{11}^{2} z_{12} + a_{6} z_{0} z_{1}^{2} z_{3} z_{4} z_{6}^{2} z_{7} z_{8}^{2} z_{10} z_{11} z_{12}^{2} + a_{4} z_{0} z_{1} z_{2}^{2} z_{4} z_{5} z_{7}^{2} z_{8} z_{9}^{2} z_{10}^{2} z_{13} + a_{7} z_{0}^{2} z_{2} z_{3} z_{5}^{2} z_{6} z_{7} z_{8} z_{9}^{2} z_{11}^{2} z_{13} + a_{12} z_{0} z_{1} z_{2} z_{3} z_{4} z_{5} z_{6} z_{7} z_{8} z_{9} z_{10} z_{11} z_{12} z_{13} + a_{9} z_{1}^{2} z_{2} z_{3} z_{4}^{2} z_{6} z_{7} z_{8} z_{10}^{2} z_{12}^{2} z_{13} + a_{0} z_{0} z_{1} z_{3}^{2} z_{4} z_{5} z_{6}^{2} z_{8} z_{11}^{2} z_{12}^{2} z_{13} + a_{11} z_{0} z_{2}^{2} z_{3} z_{4} z_{5}^{2} z_{7} z_{9}^{2} z_{10} z_{11} z_{13}^{2} + a_{10} z_{1} z_{2}^{2} z_{3} z_{4}^{2} z_{5} z_{7} z_{9} z_{10}^{2} z_{12} z_{13}^{2} + a_{2} z_{0} z_{2} z_{3}^{2} z_{4} z_{5}^{2} z_{6} z_{9} z_{11}^{2} z_{12} z_{13}^{2} + a_{1} z_{1} z_{2} z_{3}^{2} z_{4}^{2} z_{5} z_{6} z_{10} z_{11} z_{12}^{2} z_{13}^{2}$
In [11]:
# "Standalone" homogeneous polynomial of the family.
# fraction_field is needed to use these parameters in toric setup later
Rm = PolynomialRing(QQ, "m0, m1, m2, m3, p").fraction_field()
Rm.inject_variables()
m = Rm.gens()[:-1]
Rx = PolynomialRing(Rm, 4, "x")
x = Rx.gens()
I = range(4)
A3 = (sum(m[i]^2 * x[i] for i in I) * sum(1 / x[i] for i in I) - p^2) * prod(x)
show(A3)

Defining m0, m1, m2, m3, p
$m_{0}^{2} x_{0}^{2} x_{1} x_{2} + m_{1}^{2} x_{0} x_{1}^{2} x_{2} + m_{2}^{2} x_{0} x_{1} x_{2}^{2} + m_{0}^{2} x_{0}^{2} x_{1} x_{3} + m_{1}^{2} x_{0} x_{1}^{2} x_{3} + m_{0}^{2} x_{0}^{2} x_{2} x_{3} + (m_{0}^{2} + m_{1}^{2} + m_{2}^{2} + m_{3}^{2} - p^{2}) x_{0} x_{1} x_{2} x_{3} + m_{1}^{2} x_{1}^{2} x_{2} x_{3} + m_{2}^{2} x_{0} x_{2}^{2} x_{3} + m_{2}^{2} x_{1} x_{2}^{2} x_{3} + m_{3}^{2} x_{0} x_{1} x_{3}^{2} + m_{3}^{2} x_{0} x_{2} x_{3}^{2} + m_{3}^{2} x_{1} x_{2} x_{3}^{2}$
In [12]:
# Antocanonical hypersurface of the blowup with only "original" P3 coordinates visible.
show(X.defining_polynomials()[0].subs(dict(zip(X.coordinate_ring().gens()[4:], [1]*10))))

$a_{3} z_{0}^{2} z_{1} z_{2} + a_{5} z_{0} z_{1}^{2} z_{2} + a_{4} z_{0} z_{1} z_{2}^{2} + a_{8} z_{0}^{2} z_{1} z_{3} + a_{6} z_{0} z_{1}^{2} z_{3} + a_{7} z_{0}^{2} z_{2} z_{3} + a_{12} z_{0} z_{1} z_{2} z_{3} + a_{9} z_{1}^{2} z_{2} z_{3} + a_{11} z_{0} z_{2}^{2} z_{3} + a_{10} z_{1} z_{2}^{2} z_{3} + a_{0} z_{0} z_{1} z_{3}^{2} + a_{2} z_{0} z_{2} z_{3}^{2} + a_{1} z_{1} z_{2} z_{3}^{2}$
In [13]:
# The matching is "mi^2 coefficients for monomials with zi^2"
a = [1]*13
a[3] = a[7] = a[8] = m0^2
a[5] = a[6] = a[9] = m1^2
a[4] = a[10] = a[11] = m2^2
a[0] = a[1] = a[2] = m3^2
a[12] = m0^2 + m1^2 + m2^2 + m3^2 - p^2
# This is the family of interest realized in a toric variety.
X = P.anticanonical_hypersurface(coefficients=a)
# X lives in a slightly different space - its coordinate ring includes variables for coefficients
P = X.ambient_space()
show(X.defining_polynomials()[0].subs(dict(zip(X.coordinate_ring().gens()[4:], [1]*10))))

$m_{0}^{2} z_{0}^{2} z_{1} z_{2} + m_{1}^{2} z_{0} z_{1}^{2} z_{2} + m_{2}^{2} z_{0} z_{1} z_{2}^{2} + m_{0}^{2} z_{0}^{2} z_{1} z_{3} + m_{1}^{2} z_{0} z_{1}^{2} z_{3} + m_{0}^{2} z_{0}^{2} z_{2} z_{3} + (m_{0}^{2} + m_{1}^{2} + m_{2}^{2} + m_{3}^{2} - p^{2}) z_{0} z_{1} z_{2} z_{3} + m_{1}^{2} z_{1}^{2} z_{2} z_{3} + m_{2}^{2} z_{0} z_{2}^{2} z_{3} + m_{2}^{2} z_{1} z_{2}^{2} z_{3} + m_{3}^{2} z_{0} z_{1} z_{3}^{2} + m_{3}^{2} z_{0} z_{2} z_{3}^{2} + m_{3}^{2} z_{1} z_{2} z_{3}^{2}$
In [14]:
# Helper function for constructing subfamilies
def m_to_a(*m):
a = [1]*13
a[3] = a[7] = a[8] = m[0]^2
a[5] = a[6] = a[9] = m[1]^2
a[4] = a[10] = a[11] = m[2]^2
a[0] = a[1] = a[2] = m[3]^2
a[12] = m[0]^2 + m[1]^2 + m[2]^2 + m[3]^2 - p^2
return a

show(m_to_a(m0,m1,m2,m3))
show(m_to_a(m0,m0,m2,m2))

$\left[m_{3}^{2}, m_{3}^{2}, m_{3}^{2}, m_{0}^{2}, m_{2}^{2}, m_{1}^{2}, m_{1}^{2}, m_{0}^{2}, m_{0}^{2}, m_{1}^{2}, m_{2}^{2}, m_{2}^{2}, m_{0}^{2} + m_{1}^{2} + m_{2}^{2} + m_{3}^{2} - p^{2}\right]$
$\left[m_{2}^{2}, m_{2}^{2}, m_{2}^{2}, m_{0}^{2}, m_{2}^{2}, m_{0}^{2}, m_{0}^{2}, m_{0}^{2}, m_{0}^{2}, m_{0}^{2}, m_{2}^{2}, m_{2}^{2}, 2 m_{0}^{2} + 2 m_{2}^{2} - p^{2}\right]$
In [15]:
# Fibration code predates toric varieties in Sage, so needs different steps to set up.
from fibration import *
from elliptic_fibration import *

In [16]:
Delta_polar = P.Delta_polar()
slices = reflexive_slices(Delta_polar, symmetries=True)
len(slices)

2
In [17]:
# These are normals for symmetric fibrations, 6 hexagons and 3 quadrangles
for s in slices:
print s.symmetries

((0, 1, -1), (0, 0, 1), (1, 0, -1), (0, 1, 0), (1, -1, 0), (1, 0, 0)) ((1, -1, -1), (1, 1, -1), (1, -1, 1))
In [18]:
# The first (i.e. 0-th) slice is the hexagon that seemed to be of bigger interest.
fib = EllipticFibration(Delta_polar, slices[0].normal, extra_parameters=["m0", "m1", "m2", "m3", "p"])

In [19]:
show(fib.hypersurface())

$a_{3} z_{0}^{2} z_{1} z_{2} z_{5} z_{6} z_{7}^{2} z_{8}^{2} z_{9}^{2} z_{10} z_{11} + a_{5} z_{0} z_{1}^{2} z_{2} z_{4} z_{6} z_{7}^{2} z_{8}^{2} z_{9} z_{10}^{2} z_{12} + a_{8} z_{0}^{2} z_{1} z_{3} z_{5} z_{6}^{2} z_{7} z_{8}^{2} z_{9} z_{11}^{2} z_{12} + a_{6} z_{0} z_{1}^{2} z_{3} z_{4} z_{6}^{2} z_{7} z_{8}^{2} z_{10} z_{11} z_{12}^{2} + a_{4} z_{0} z_{1} z_{2}^{2} z_{4} z_{5} z_{7}^{2} z_{8} z_{9}^{2} z_{10}^{2} z_{13} + a_{7} z_{0}^{2} z_{2} z_{3} z_{5}^{2} z_{6} z_{7} z_{8} z_{9}^{2} z_{11}^{2} z_{13} + a_{12} z_{0} z_{1} z_{2} z_{3} z_{4} z_{5} z_{6} z_{7} z_{8} z_{9} z_{10} z_{11} z_{12} z_{13} + a_{9} z_{1}^{2} z_{2} z_{3} z_{4}^{2} z_{6} z_{7} z_{8} z_{10}^{2} z_{12}^{2} z_{13} + a_{0} z_{0} z_{1} z_{3}^{2} z_{4} z_{5} z_{6}^{2} z_{8} z_{11}^{2} z_{12}^{2} z_{13} + a_{11} z_{0} z_{2}^{2} z_{3} z_{4} z_{5}^{2} z_{7} z_{9}^{2} z_{10} z_{11} z_{13}^{2} + a_{10} z_{1} z_{2}^{2} z_{3} z_{4}^{2} z_{5} z_{7} z_{9} z_{10}^{2} z_{12} z_{13}^{2} + a_{2} z_{0} z_{2} z_{3}^{2} z_{4} z_{5}^{2} z_{6} z_{9} z_{11}^{2} z_{12} z_{13}^{2} + a_{1} z_{1} z_{2} z_{3}^{2} z_{4}^{2} z_{5} z_{6} z_{10} z_{11} z_{12}^{2} z_{13}^{2}$
In [20]:
%%time
j = fib.j()
print(j.numerator().degree(), j.denominator().degree())
print(fib._degree_shift)


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
fib.singular_fibers_summary()


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
fib.plot3d().show(frame=False)


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
# Intersection matrix of torically induced divisors on K3, in our case there is one divisor per point,
# each edge corresponds to a simple intersection. Note that there are no edges 3-6 and 2-7.
M=intersection_matrix(Delta_polar); M


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
M.dimensions()


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
curves = [X.intersection(P.subscheme(z)) for z in P.gens()]


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
# Simplify curve equations and check that they all are given as (polynomial, monomial)
curves = [P.subscheme(c.defining_ideal().groebner_basis()) for c in curves]
for c in curves:
I = c.defining_ideal()
print(I.gens())
assert(I.ngens() == 2)
assert(len(I.gen(1).monomials()) == 1)


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
# No intersection between 0 and 1
pts = curves[0].intersection(curves[1])
pts.dimension()


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
# Some intersection between 0 and 8
pts = curves[0].intersection(curves[8])
pts.dimension()



Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
# Equations for the intersection in all charts where it is visible
# (no claims that these points are the same or different)
for i in range(P.fan().ngenerating_cones()):
ap = pts.affine_patch(i)
if ap.dimension() != -1:
print(i, ap.defining_ideal().groebner_basis())


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
cm = matrix(ZZ, len(curves))
for i in range(len(curves)):
for j in range(i + 1, len(curves)):
if curves[i].intersection(curves[j]).dimension() == 0:
cm[i, j] = cm [j, i] = 1
cm


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [ ]:
# Assuming that all intersections are 0 or 1 and all self-intersections are -2, we recover the correct intersection matrix
M - cm


Jupyter Kernel terminated: This might be caused by running out of memory or hitting a bug in some library (e.g., forking too many processes, trying to access invalid memory, etc.). Consider restarting or upgrading your project or running the relevant code directly in a terminal to track down the cause, as explained here.

In [1]:
c = curves[0]
c

--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-1-f989cd57b657> in <module>() ----> 1 c = curves[Integer(0)] 2 c NameError: name 'curves' is not defined 
In [35]:
I = c.defining_ideal()
I

Ideal (m0^2*z0^2*z1*z2*z5*z6*z7^2*z8^2*z9^2*z10*z11 + m1^2*z0*z1^2*z2*z4*z6*z7^2*z8^2*z9*z10^2*z12 + m0^2*z0^2*z1*z3*z5*z6^2*z7*z8^2*z9*z11^2*z12 + m1^2*z0*z1^2*z3*z4*z6^2*z7*z8^2*z10*z11*z12^2 + m2^2*z0*z1*z2^2*z4*z5*z7^2*z8*z9^2*z10^2*z13 + m0^2*z0^2*z2*z3*z5^2*z6*z7*z8*z9^2*z11^2*z13 + (m0^2 + m1^2 + m2^2 + m3^2 - p^2)*z0*z1*z2*z3*z4*z5*z6*z7*z8*z9*z10*z11*z12*z13 + m1^2*z1^2*z2*z3*z4^2*z6*z7*z8*z10^2*z12^2*z13 + m3^2*z0*z1*z3^2*z4*z5*z6^2*z8*z11^2*z12^2*z13 + m2^2*z0*z2^2*z3*z4*z5^2*z7*z9^2*z10*z11*z13^2 + m2^2*z1*z2^2*z3*z4^2*z5*z7*z9*z10^2*z12*z13^2 + m3^2*z0*z2*z3^2*z4*z5^2*z6*z9*z11^2*z12*z13^2 + m3^2*z1*z2*z3^2*z4^2*z5*z6*z10*z11*z12^2*z13^2, z8) of Multivariate Polynomial Ring in z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13 over Fraction Field of Multivariate Polynomial Ring in m0, m1, m2, m3, p over Rational Field
In [44]:
sp = SR(I.groebner_basis()[0])
sp

m3^2*z1*z10*z11*z12^2*z13^2*z2*z3^2*z4^2*z5*z6/m2^2 + m3^2*z0*z11^2*z12*z13^2*z2*z3^2*z4*z5^2*z6*z9/m2^2 + z1*z10^2*z12*z13^2*z2^2*z3*z4^2*z5*z7*z9 + z0*z10*z11*z13^2*z2^2*z3*z4*z5^2*z7*z9^2
In [46]:
P.subscheme(I.groebner_basis())

Closed subscheme of 3-d CPR-Fano toric variety covered by 24 affine patches defined by: z0*z2^2*z3*z4*z5^2*z7*z9^2*z10*z11*z13^2 + z1*z2^2*z3*z4^2*z5*z7*z9*z10^2*z12*z13^2 + m3^2/m2^2*z0*z2*z3^2*z4*z5^2*z6*z9*z11^2*z12*z13^2 + m3^2/m2^2*z1*z2*z3^2*z4^2*z5*z6*z10*z11*z12^2*z13^2, z8
In [45]:
sp.factor_list()

[(m3^2*z11*z12*z3*z6 + m2^2*z10*z2*z7*z9, 1), (z1*z10*z12*z4 + z0*z11*z5*z9, 1), (m2, -2), (z13, 2), (z2, 1), (z3, 1), (z4, 1), (z5, 1)]
In [22]:
im16 = diagonal_matrix(ZZ, [-2]*20)

cones = P.fan().cones(dim=1)
# The first 4 divisors are coordinate planes from P3
# The next 4 are blown up fixed points
# P1xP1 divisors correspond to the last 6 which are blown up torus invariant lines
# (on the polytope plot they correspond to vertices with 4 edges)
for i in range(6):
# Two lines in P1xP1 intersect each other
im16[8 + 2 * i, 9 + 2 * i] = im16[9 + 2 * i, 8 + 2 * i] = 1
r1 = ars.pop()
for r2 in ars:
ars.remove(r2)
break
# Now r1 and r2 are "opposite"
k = r1.ambient_ray_indices()[0]
im16[k, 8 + 2 * i] = im16[8 + 2 * i, k] = 1
k = r2.ambient_ray_indices()[0]
im16[k, 8 + 2 * i] = im16[8 + 2 * i, k] = 1
# And ars contains another "opposite pair"
k = ars[0].ambient_ray_indices()[0]
im16[k, 9 + 2 * i] = im16[9 + 2 * i, k] = 1
k = ars[1].ambient_ray_indices()[0]
im16[k, 9 + 2 * i] = im16[9 + 2 * i, k] = 1

print(im16.str())

In [23]:
im16.rank()

16
In [24]:
# Sections form 2 chains, 2-13-3 and 6-8-7, so there are 2 cases: "end" and "middle"
fib.sections()

[2 (toric), 3 (toric), 6 (toric), 7 (toric), 8 (toric), 13 (toric)]
In [25]:
s = fib.sections()[0]
s

2 (toric)
In [26]:
# F - fiber, S - section, T_n - top divisors, B_n - bottom divisors, S_n - slice divisors
print s.decorated_intersection_matrix()

F S T_ T_ T_ B_ B_ B_ S_ S_ S_ 0 5 11 1 4 12 7 8 13 F [ 0 1 0 0 0 0 0 0 1 1 1] F S [ 1 -2 0 0 0 0 0 0 0 0 1] S T_0 [ 0 0 -2 0 1 0 0 0 0 1 0] T_0 T_5 [ 0 0 0 -2 1 0 0 0 0 0 1] T_5 T_11 [ 0 0 1 1 -2 0 0 0 0 0 0] T_11 B_1 [ 0 0 0 0 0 -2 0 1 0 1 0] B_1 B_4 [ 0 0 0 0 0 0 -2 1 0 0 1] B_4 B_12 [ 0 0 0 0 0 1 1 -2 0 0 0] B_12 S_7 [ 1 0 0 0 0 0 0 0 -2 1 0] S_7 S_8 [ 1 0 1 0 0 1 0 0 1 -2 0] S_8 S_13 [ 1 1 0 1 0 0 1 0 0 0 -2] S_13 F S T_ T_ T_ B_ B_ B_ S_ S_ S_ 0 5 11 1 4 12 7 8 13
In [27]:
proj = s._ef.slice().normal * s._ef.polytope().points()
D_fiber = [(pt, proj[pt]) for pt in s._ef.polytope().skeleton_points() if proj[pt] > 0]
D_fiber

[(0, 1), (5, 1), (9, 1), (11, 1)]
In [28]:
s = fib.sections()[-1]
s

13 (toric)
In [29]:
# F - fiber, S - section, T_n - top divisors, B_n - bottom divisors, S_n - slice divisors
print s.decorated_intersection_matrix()

F S T_ T_ T_ B_ B_ B_ S_ S_ S_ 0 9 11 1 10 12 6 7 8 F [ 0 1 0 0 0 0 0 0 1 1 1] F S [ 1 -2 0 0 0 0 0 0 0 0 0] S T_0 [ 0 0 -2 1 1 0 0 0 0 0 1] T_0 T_9 [ 0 0 1 -2 0 0 0 0 0 1 0] T_9 T_11 [ 0 0 1 0 -2 0 0 0 1 0 0] T_11 B_1 [ 0 0 0 0 0 -2 1 1 0 0 1] B_1 B_10 [ 0 0 0 0 0 1 -2 0 0 1 0] B_10 B_12 [ 0 0 0 0 0 1 0 -2 1 0 0] B_12 S_6 [ 1 0 0 0 1 0 0 1 -2 0 1] S_6 S_7 [ 1 0 0 1 0 0 1 0 0 -2 1] S_7 S_8 [ 1 0 1 0 0 1 0 0 1 1 -2] S_8 F S T_ T_ T_ B_ B_ B_ S_ S_ S_ 0 9 11 1 10 12 6 7 8
In [30]:
# Since we have used the same Delta/Delta_polar and there are no points apart from vertices and the origin,
# coordinates and coefficients are the same and we can use the same a-matching.
fib.set_coefficients(dict(zip(fib.coefficients_ring().gens()[:13], a)))
show(fib.hypersurface())

$m_{0}^{2} z_{0}^{2} z_{1} z_{2} z_{5} z_{6} z_{7}^{2} z_{8}^{2} z_{9}^{2} z_{10} z_{11} + m_{1}^{2} z_{0} z_{1}^{2} z_{2} z_{4} z_{6} z_{7}^{2} z_{8}^{2} z_{9} z_{10}^{2} z_{12} + m_{0}^{2} z_{0}^{2} z_{1} z_{3} z_{5} z_{6}^{2} z_{7} z_{8}^{2} z_{9} z_{11}^{2} z_{12} + m_{1}^{2} z_{0} z_{1}^{2} z_{3} z_{4} z_{6}^{2} z_{7} z_{8}^{2} z_{10} z_{11} z_{12}^{2} + m_{2}^{2} z_{0} z_{1} z_{2}^{2} z_{4} z_{5} z_{7}^{2} z_{8} z_{9}^{2} z_{10}^{2} z_{13} + m_{0}^{2} z_{0}^{2} z_{2} z_{3} z_{5}^{2} z_{6} z_{7} z_{8} z_{9}^{2} z_{11}^{2} z_{13} + (m_{0}^{2} + m_{1}^{2} + m_{2}^{2} + m_{3}^{2} - p^{2}) z_{0} z_{1} z_{2} z_{3} z_{4} z_{5} z_{6} z_{7} z_{8} z_{9} z_{10} z_{11} z_{12} z_{13} + m_{1}^{2} z_{1}^{2} z_{2} z_{3} z_{4}^{2} z_{6} z_{7} z_{8} z_{10}^{2} z_{12}^{2} z_{13} + m_{3}^{2} z_{0} z_{1} z_{3}^{2} z_{4} z_{5} z_{6}^{2} z_{8} z_{11}^{2} z_{12}^{2} z_{13} + m_{2}^{2} z_{0} z_{2}^{2} z_{3} z_{4} z_{5}^{2} z_{7} z_{9}^{2} z_{10} z_{11} z_{13}^{2} + m_{2}^{2} z_{1} z_{2}^{2} z_{3} z_{4}^{2} z_{5} z_{7} z_{9} z_{10}^{2} z_{12} z_{13}^{2} + m_{3}^{2} z_{0} z_{2} z_{3}^{2} z_{4} z_{5}^{2} z_{6} z_{9} z_{11}^{2} z_{12} z_{13}^{2} + m_{3}^{2} z_{1} z_{2} z_{3}^{2} z_{4}^{2} z_{5} z_{6} z_{10} z_{11} z_{12}^{2} z_{13}^{2}$
In [31]:
#fib.hypersurface()

In [32]:
show(fib.fiber())

$(m_{0}^{2} t^{2} + m_{1}^{2} t) z_{3} z_{6}^{2} z_{7} z_{8}^{2} + (m_{0}^{2} t^{2} + m_{1}^{2} t) z_{2} z_{6} z_{7}^{2} z_{8}^{2} + (m_{3}^{2} t) z_{3}^{2} z_{6}^{2} z_{8} z_{13} + (m_{0}^{2} t^{2} + m_{0}^{2} t + m_{1}^{2} t + m_{2}^{2} t + m_{3}^{2} t - p^{2} t + m_{1}^{2}) z_{2} z_{3} z_{6} z_{7} z_{8} z_{13} + (m_{2}^{2} t) z_{2}^{2} z_{7}^{2} z_{8} z_{13} + (m_{3}^{2} t + m_{3}^{2}) z_{2} z_{3}^{2} z_{6} z_{13}^{2} + (m_{2}^{2} t + m_{2}^{2}) z_{2}^{2} z_{3} z_{7} z_{13}^{2}$
In [33]:
j = fib.j()

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-33-4c0091c2dd0b> in <module>() ----> 1 j = fib.j() /ext/sage/sage-8.1/src/sage/misc/cachefunc.pyx in sage.misc.cachefunc.CachedMethodCallerNoArgs.__call__ (build/cythonized/sage/misc/cachefunc.c:13511)() 2377 if self.cache is None: 2378 f = self.f -> 2379 self.cache = f(self._instance) 2380 return self.cache 2381 /home/user/elliptic_fibration.pyc in j(self) 877 y^2 = x^3 + g2*x + g3. 878 """ --> 879 return 4 * self.g2()**3 / self.delta() 880 881 def plot3d(self): /home/user/elliptic_fibration.pyc in g2(self) 832 return self._g2 833 except AttributeError: --> 834 self._compute_invariants() 835 return self._g2 836 /home/user/elliptic_fibration.pyc in _compute_invariants(self, d) 771 else: 772 f0 = SingularFiber(self._top, degenerate=True) --> 773 d = degree_shift(f0) 774 self._f_0 = f0 775 /home/user/elliptic_fibration.pyc in degree_shift(f0) 755 d = (evo[2] - dvo) / 6 756 if not d.is_integral(): --> 757 raise ValueError("degree shift %s is not integer!" % d) 758 if (g2vo + 2 * d < evo[0] 759 or g3vo + 3 * d < evo[1] ValueError: degree shift -1/3 is not integer! 
In [34]:
# The normalization above (and raising an exception) is necessary for other applications of this code.
# It fails here because the subfamily has more comlicated singular fibers over zero and infinity than the full family.
# Nevertheless, the j invariant (and probably simpler g2 and g3) are accessible on subsequent calls without normalization.
# Moreover, we can try to compute invariants with the same degree shift as in the generic case above.
fib._compute_invariants(0)
# It is possible that the current code never needs this shift at all, but it is not obvious.
j = fib.j()
j.numerator().degree(), j.denominator().degree()

(48, 42)
In [35]:
fib.singular_fibers_summary()

'8x I_1, I_2 at (-m1^2)/m0^2, I_2 at -1, I_6 at +Infinity, I_6 at 0'
In [36]:
fib.show()

A fibration of $\Delta^{3}_{2355}$ corresponding to 2-dimensional reflexive slice of a 3-dimensional polytope.
Points: [2, 3, 6, 7, 8, 13, 14]
Skeleton points: [2, 3, 6, 7, 8, 13]
Normal to the slice hyperplane: (1, -1, 0)
Vertices of the slice polytope:
M(-1, -1),
M(-1, 0),
M( 0, -1),
M( 1, 1),
M( 0, 1),
M( 1, 0)
in 2-d lattice M
Coordinate points: $\left(\begin{array}{rrrrrrrrrrrrrr} 1 & 0 & 0 & -1 & -1 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & -1 & -1 \\ 0 & 1 & 0 & -1 & 0 & -1 & 0 & 1 & 1 & 0 & 1 & -1 & 0 & -1 \\ 0 & 0 & 1 & -1 & 0 & 0 & -1 & 1 & 0 & 1 & 1 & -1 & -1 & 0 \end{array}\right)$
Monomial points: $\left(\begin{array}{rrrrrrrrrrrrr} 0 & -1 & 0 & 1 & 0 & 0 & 0 & 1 & 1 & -1 & -1 & 0 & 0 \\ 0 & 0 & -1 & 0 & 0 & 1 & 1 & -1 & 0 & 1 & 0 & -1 & 0 \\ -1 & 0 & 0 & 0 & 1 & 0 & -1 & 0 & -1 & 0 & 1 & 1 & 0 \end{array}\right)$
Equation of a hypersurface: $m_{0}^{2} z_{0}^{2} z_{1} z_{2} z_{5} z_{6} z_{7}^{2} z_{8}^{2} z_{9}^{2} z_{10} z_{11} + m_{1}^{2} z_{0} z_{1}^{2} z_{2} z_{4} z_{6} z_{7}^{2} z_{8}^{2} z_{9} z_{10}^{2} z_{12} + m_{0}^{2} z_{0}^{2} z_{1} z_{3} z_{5} z_{6}^{2} z_{7} z_{8}^{2} z_{9} z_{11}^{2} z_{12} + m_{1}^{2} z_{0} z_{1}^{2} z_{3} z_{4} z_{6}^{2} z_{7} z_{8}^{2} z_{10} z_{11} z_{12}^{2} + m_{2}^{2} z_{0} z_{1} z_{2}^{2} z_{4} z_{5} z_{7}^{2} z_{8} z_{9}^{2} z_{10}^{2} z_{13} + m_{0}^{2} z_{0}^{2} z_{2} z_{3} z_{5}^{2} z_{6} z_{7} z_{8} z_{9}^{2} z_{11}^{2} z_{13} + (m_{0}^{2} + m_{1}^{2} + m_{2}^{2} + m_{3}^{2} - p^{2}) z_{0} z_{1} z_{2} z_{3} z_{4} z_{5} z_{6} z_{7} z_{8} z_{9} z_{10} z_{11} z_{12} z_{13} + m_{1}^{2} z_{1}^{2} z_{2} z_{3} z_{4}^{2} z_{6} z_{7} z_{8} z_{10}^{2} z_{12}^{2} z_{13} + m_{3}^{2} z_{0} z_{1} z_{3}^{2} z_{4} z_{5} z_{6}^{2} z_{8} z_{11}^{2} z_{12}^{2} z_{13} + m_{2}^{2} z_{0} z_{2}^{2} z_{3} z_{4} z_{5}^{2} z_{7} z_{9}^{2} z_{10} z_{11} z_{13}^{2} + m_{2}^{2} z_{1} z_{2}^{2} z_{3} z_{4}^{2} z_{5} z_{7} z_{9} z_{10}^{2} z_{12} z_{13}^{2} + m_{3}^{2} z_{0} z_{2} z_{3}^{2} z_{4} z_{5}^{2} z_{6} z_{9} z_{11}^{2} z_{12} z_{13}^{2} + m_{3}^{2} z_{1} z_{2} z_{3}^{2} z_{4}^{2} z_{5} z_{6} z_{10} z_{11} z_{12}^{2} z_{13}^{2}$
Projection to the base: $\left(z_{0} z_{5} z_{9} z_{11}, z_{1} z_{4} z_{10} z_{12}\right)$
Coordinate on the base: $z_{0}$
Fiber over $\left(t^{ 1 }, 1\right)$: $(m_{0}^{2} t^{2} + m_{1}^{2} t) z_{3} z_{6}^{2} z_{7} z_{8}^{2} + (m_{0}^{2} t^{2} + m_{1}^{2} t) z_{2} z_{6} z_{7}^{2} z_{8}^{2} + (m_{3}^{2} t) z_{3}^{2} z_{6}^{2} z_{8} z_{13} + (m_{0}^{2} t^{2} + m_{0}^{2} t + m_{1}^{2} t + m_{2}^{2} t + m_{3}^{2} t - p^{2} t + m_{1}^{2}) z_{2} z_{3} z_{6} z_{7} z_{8} z_{13} + (m_{2}^{2} t) z_{2}^{2} z_{7}^{2} z_{8} z_{13} + (m_{3}^{2} t + m_{3}^{2}) z_{2} z_{3}^{2} z_{6} z_{13}^{2} + (m_{2}^{2} t + m_{2}^{2}) z_{2}^{2} z_{3} z_{7} z_{13}^{2}$
Top: ExtA3, generic $F_0$: $I_{4}$
Bottom: ExtA3, generic $F_\infty$: $I_{4}$
In [37]:
%%time

# Singular fibers (some of them) for different subfamilies
Ms = [
(m0, m1, m2, m3),
(m0, m0, m2, m3),
(m0, m0, m2, m2),
(m0, m0, m0, m0),
]
for M in Ms:
fib.set_coefficients(dict(zip(fib.coefficients_ring().gens()[:13], m_to_a(*M))))
fib._compute_invariants(0)
print fib.singular_fibers_summary()

8x I_1, I_2 at (-m1^2)/m0^2, I_2 at -1, I_6 at +Infinity, I_6 at 0 8x I_1, I_4 at -1, I_6 at +Infinity, I_6 at 0 4x I_1, I_4 at -1, I_6 at +Infinity, I_6 at 0 4x I_1, I_4 at -1, I_6 at +Infinity, I_6 at 0 CPU times: user 9.48 s, sys: 128 ms, total: 9.61 s Wall time: 10.6 s
In [41]:
SR(fib.fiber()).subs(t=-1).factor()

-(m0^2*z3^2*z6^2 + 2*m0^2*z2*z3*z6*z7 - p^2*z2*z3*z6*z7 + m0^2*z2^2*z7^2)*z13*z8
In [ ]:
## the euler characteristic looks wrong. Some multiplicities are coming out right and the index of the fiber at 0 should increase.
# by explicitely looking at the j-invariant we could determine the missing fibers

In [ ]:
# The other slice
fib = EllipticFibration(Delta_polar, slices[1].normal, extra_parameters=["m0", "m1", "m2", "m3", "p"])
fib.hypersurface()

In [ ]:
fib.show()

In [ ]:
%%time
j = fib.j()
print(j.numerator().degree(), j.denominator().degree())
print(fib._degree_shift)

In [ ]:
fib.singular_fibers_summary()

In [ ]:
fib.set_coefficients(dict(zip(fib.coefficients_ring().gens()[:13], a)))
fib.hypersurface()

In [ ]:
fib._compute_invariants(0)

In [ ]:
fib.singular_fibers_summary()

In [ ]:
fib.sections()

In [ ]:
%%time

# Singular fibers (some of them) for different subfamilies
Ms = [
(m0, m1, m2, m3),
(m0, m0, m2, m3),
(m0, m0, m2, m2),
(m0, m0, m0, m0),
]
for M in Ms:
fib.set_coefficients(dict(zip(fib.coefficients_ring().gens()[:13], m_to_a(*M))))
fib._compute_invariants(0)
print fib.singular_fibers_summary()

In [ ]:
LatticeDiagram?

In [ ]:
Mnew=matrix(ZZ,[[-2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 1, 1, 0], [0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1], [0, 0, 0, -2,
0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 1], [0, 0, 0, 0, 0, -2, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, -2, 0, 1,
0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0], [1,
0, 0, 0, 0, 0, 1, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 1, 0,
0, 1, 0, 0, 0, 0, -2, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, -2, 0, 0, 0, 1,
0, 0, 0], [0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2, 1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, -2, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0, 0], [0,
0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0], [0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, -2, 0, 0], [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2, 0], [0, 0, 1, 0, 1, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2]])


In [ ]:
Mnew.is_symmetric()

In [ ]:
Mnew.rank()

In [ ]:
# the matrix Mnew is similar to the one constructed by Andrey. This can be seen by checking that they both have the same Jordan form.

In [ ]:
Jnew,Pnew=Mnew.jordan_form(transformation=True);
J16,P16=im16.jordan_form(transformation=True);