Skip to content

F-theory helper functions

These are the lower-level toric geometry functions used to construct orientifolds and F-theory uplifts. Most users will only need the classes and functions documented in F-theory and orientifolds.

Helper functions for Calabi-Yau orientifolds and their F-theory uplifts.

This module collects the lower-level toric geometry routines used by CY_orientifold and F_Theory_Uplift: GLSM charges, Newton polytopes and sections of toric divisors, Cartier and nef checks, normal fans and their refinements, \(\mathbb{Z}_2\) torus actions, Hodge numbers of codimension-two complete intersections, and assorted array utilities.

Unless stated otherwise, cones are tuples of one-indexed ray labels, and a toric divisor \(D = \sum_\rho a_\rho D_\rho\) is given by its coefficient vector \((a_\rho)\) in the basis of toric prime divisors, ordered like the rays.

Functions:

  • BL –

    Return the base locus of a toric divisor.

  • Cartier_index –

    Return the Cartier index of a toric Weil divisor.

  • Gorenstein_index –

    Return the index of a reflexive Gorenstein cone.

  • Newton_Polytope –

    Return the Newton polytope of a toric divisor.

  • O3O7_line_bundle –

    Return the orientifold line bundle on the toric orbifold.

  • O7_cones –

    Return the cones with a given number of rays whose rays are all O7-planes.

  • Z2_fixed_locus –

    Return the cones whose toric strata are fixed by a finite torus action.

  • array_to_latex –

    Convert a 2D array into a LaTeX pmatrix.

  • attempt_to_make_Cartier –

    Attempt to refine a fan so that a divisor becomes Cartier and nef.

  • attempt_to_make_nef –

    Attempt to find a triangulation on which a divisor is nef.

  • base_locus –

    Return the minimal sets of toric coordinates on which all sections vanish.

  • basis –

    Return the indices of rows that form a basis of the row span.

  • basis_H2_toric_fan –

    Return ray labels whose divisor classes form a basis of the class group.

  • compute_partition –

    Shift two toric divisors so that they partition the anticanonical divisor.

  • contains_row –

    Check whether a vector appears as a row of a 2D array.

  • contains_rows –

    Check whether every row of one 2D array appears as a row of another.

  • divisor_intersections –

    Compute the classes of the toric curves on a complete intersection.

  • dual_face_Cayley_polytope –

    Return the face of the dual Cayley polytope dual to a given face.

  • find_cone –

    Return the face of a simplicial cone that contains a given vector.

  • find_cone_general –

    Return the face of a cone that contains a given vector.

  • find_trilayer_vertex_polytope –

    Return the distinguished vertex of a trilayer polytope.

  • find_trilayer_vertex_vertices –

    Return the distinguished vertex of a trilayer polytope from its vertices.

  • flatten –

    Flatten a nested list by a given number of levels.

  • generic_section_factorizes –

    Check whether the generic section of a toric divisor factorizes.

  • get_index –

    Return the indices of the rows of arr equal to target.

  • get_indices –

    Return the indices of the rows of arr that appear among targets.

  • get_lower_dimensional_cones –

    Return all faces with a given number of rays of a collection of cones.

  • get_same_rows –

    Return the rows of A that also appear as rows of B.

  • glsm_from_points –

    Return a GLSM charge matrix for a point configuration.

  • h11_2_part –

    Compute \(h^{1,1}\) of a Calabi-Yau defined by a two-part nef partition.

  • h21_2_part –

    Compute \(h^{2,1}\) of a fourfold defined by a two-part nef partition.

  • inequivalent_Z2_actions –

    Return the \(\mathbb{Z}_2\) torus actions up to lattice symmetries.

  • integral_gale_transform –

    Return an integral Gale transform of a point configuration.

  • is_Cartier –

    Check whether a toric Weil divisor is Cartier.

  • is_Gorenstein –

    Check whether a cone is Gorenstein.

  • is_ample –

    Check whether a toric divisor is ample.

  • is_effective –

    Check whether a toric divisor has a nonzero global section.

  • is_nef –

    Check whether a toric divisor is nef.

  • is_partition –

    Check whether two toric divisors can be shifted to a partition of \(-K\).

  • is_reflexive_Gorenstein –

    Check whether a cone and its dual are both Gorenstein.

  • lattice_refinement –

    Return the change of basis to a refined lattice.

  • linebundle_weights_from_Newton_Polytope –

    Return the divisor coefficients determined by a Newton polytope.

  • make_simplicial –

    Return a simplicial refinement of a fan.

  • moving_cone –

    Return the moving cone of a toric variety.

  • nested_sum –

    Return all sums of one element from each list, as a nested list.

  • normal_fan –

    Construct the normal fan of a polytope or of a Minkowski sum of polytopes.

  • points_from_glsm –

    Return a point configuration with the given GLSM charges.

  • points_not_interior_to_facets_and_codim2_faces –

    Return the lattice points not interior to faces of codimension one or two.

  • refine_fan –

    Insert new rays into a simplicial fan by star subdivisions.

  • row_difference –

    Return the rows of A that do not appear as rows of B.

  • same_rows –

    Check whether two 2D arrays have the same rows, ignoring order.

  • sections –

    Return the exponent vectors of the monomial sections of a toric divisor.

  • solve_over_integers –

    Find an integer solution of the linear system \(M x = -b\).

  • sums_to_anticanonical –

    Check whether the sum of two toric divisors is linearly equivalent to \(-K\).

  • toric_orbifold –

    Return the rays of the quotient of a toric variety by a finite torus action.

  • trilayer_5d_Ftheory_uplift –

    Construct the polytope of the F-theory uplift of a trilayer orientifold.

  • trilayer_normal_form –

    Bring a trilayer polytope into trilayer normal form.

BL

BL(fan, lb)

Return the base locus of a toric divisor.

This computes the sections of the divisor with sections and passes them to base_locus, restricting to the cones of fan. The divisor must have at least one section.

Parameters:

  • fan (Fan) –

    The toric fan.

  • lb (ndarray) –

    The divisor coefficients.

Returns:

  • list[tuple[int, ...]] –

    The minimal cones \(\sigma\) of the fan such that all sections vanish on the orbit closure \(V(\sigma)\). The base locus is the union of these orbit closures.

Examples:

On the Hirzebruch surface \(\mathbb{F}_1\), the exceptional curve \(D_2\) is its own base locus, while the fiber \(D_1\) is base point free.

>>> import numpy as np
>>> from cytools.vector_config import VectorConfiguration
>>> from cytools.f_theory.Uplift_functions import BL
>>> fan = VectorConfiguration([[1, 0], [0, 1], [-1, 1], [0, -1]]).triangulate()
>>> BL(fan, np.array([0, 1, 0, 0])), BL(fan, np.array([1, 0, 0, 0]))
([(2,)], [])

Cartier_index

Cartier_index(toric_fan, weights)

Return the Cartier index of a toric Weil divisor.

For each maximal cone \(\sigma\), solve for the local data \(m_\sigma\) with \(\langle m_\sigma, v_\rho \rangle = -a_\rho\) for all rays \(\rho \in \sigma\) (by least squares, in floating point). If there is no solution for some cone, the divisor is not \(\mathbb{Q}\)-Cartier. Otherwise, the Cartier index is the smallest positive integer \(k\) such that all \(k\, m_\sigma\) are integral.

Parameters:

  • toric_fan (Fan) –

    The toric fan.

  • weights (ArrayLike) –

    The divisor coefficients \(a_\rho\).

Returns:

  • int | None –

    The Cartier index, or None if the divisor is not \(\mathbb{Q}\)-Cartier.

Examples:

>>> from cytools.vector_config import VectorConfiguration
>>> from cytools.f_theory.Uplift_functions import Cartier_index
>>> fan = VectorConfiguration([[1, 0], [1, 2]]).triangulate()
>>> Cartier_index(fan, [1, 0])
np.int64(2)

Gorenstein_index

Gorenstein_index(cone)

Return the index of a reflexive Gorenstein cone.

This is the pairing \(\langle m, n \rangle\) between the Gorenstein functional \(n\) of the cone and the Gorenstein functional \(m\) of its dual.

Parameters:

  • cone (Cone) –

    A reflexive Gorenstein cone.

Returns:

  • int –

    The Gorenstein index.

Raises:

  • ValueError –

    If the cone is not reflexive Gorenstein.

Examples:

The cone over a reflexive polygon is reflexive Gorenstein of index 1.

>>> from cytools import Cone
>>> from cytools.f_theory.Uplift_functions import Gorenstein_index
>>> Gorenstein_index(Cone([[1, 0, 1], [0, 1, 1], [-1, 0, 1], [0, -1, 1]]))
np.int64(1)

Newton_Polytope

Newton_Polytope(pts, weights)

Return the Newton polytope of a toric divisor.

For a divisor \(D = \sum_\rho a_\rho D_\rho\), this is the polytope \(P_D = \{m \in M_\mathbb{R} : \langle m, v_\rho \rangle \geq -a_\rho\}\), whose lattice points correspond to the monomial global sections of \(\mathcal{O}(D)\). It is constructed as an HPolytope, i.e. as the convex hull of the lattice points satisfying the inequalities, so it has no lattice points if \(D\) is not effective.

Parameters:

  • pts (ArrayLike) –

    The rays \(v_\rho\) of the toric fan, one per row.

  • weights (ArrayLike) –

    The divisor coefficients \(a_\rho\).

Returns:

  • HPolytope –

    The Newton polytope of the divisor.

Examples:

We construct the Newton polytope of the anticanonical divisor of \(\mathbb{P}^2\).

>>> from cytools.f_theory.Uplift_functions import Newton_Polytope
>>> Newton_Polytope([[1, 0], [0, 1], [-1, -1]], [1, 1, 1]).vertices()
array([[-1, -1],
       [-1,  2],
       [ 2, -1]])

O3O7_line_bundle

O3O7_line_bundle(pts_CY_ambient, q, rescalings)

Return the orientifold line bundle on the toric orbifold.

Pick the first lattice point \(m\) of the Newton polytope of the anticanonical divisor with \(\langle m, q \rangle\) odd, i.e. a monomial of the Calabi-Yau equation that is odd under the \(\mathbb{Z}_2\) action. Its exponents \(\langle m, v_\rho \rangle + 1\) are divided by the ray rescalings of the orbifold (and rounded to the nearest integer) to obtain the divisor coefficients on the orbifold.

Parameters:

  • pts_CY_ambient (ndarray) –

    The rays \(v_\rho\) of the toric fan of the Calabi-Yau ambient variety, one per row.

  • q (ArrayLike) –

    The integer vector such that \(q/2\) defines the \(\mathbb{Z}_2\) action.

  • rescalings (ArrayLike) –

    The ray rescalings of the orbifold, as returned by toric_orbifold.

Returns:

  • ndarray | None –

    The divisor coefficients of the line bundle on the orbifold, or None if no monomial is odd under the action.

O7_cones

O7_cones(vc_orbifold, O7_labels, d)

Return the cones with a given number of rays whose rays are all O7-planes.

Parameters:

  • vc_orbifold (Fan) –

    The toric fan of the orbifold. It is assumed to be simplicial.

  • O7_labels (Iterable[int]) –

    The labels of the rays whose divisors are O7-planes.

  • d (int) –

    The number of rays of the cones.

Returns:

  • list[tuple[int, ...]] –

    The d-ray cones of the fan whose rays are all in O7_labels, in arbitrary order.

Z2_fixed_locus

Z2_fixed_locus(vc_triangulation, q, cone_dimension=None, denominator=2)

Return the cones whose toric strata are fixed by a finite torus action.

A cone is selected if the sum of its generators plus \(q\) is divisible by denominator in every component. If cone_dimension is not specified, all proper faces of the maximal cones are considered (the maximal cones themselves are excluded). Faces are enumerated as subsets of the generators, so the fan is assumed to be simplicial.

Parameters:

  • vc_triangulation (Fan) –

    The toric fan of the ambient variety.

  • q (ArrayLike) –

    The integer vector such that \(q/k\) generates the action, where \(k\) is denominator.

  • cone_dimension (int | None, default: None ) –

    If specified, only cones with this number of rays are considered.

  • denominator (int, default: 2 ) –

    The denominator \(k\) of the fractional vector \(q/k\).

Returns:

  • list[tuple[int, ...]] –

    The fixed cones, as tuples of ray labels.

array_to_latex

array_to_latex(arr)

Convert a 2D array into a LaTeX pmatrix.

Parameters:

Returns:

  • str –

    The LaTeX code of the matrix.

Raises:

  • ValueError –

    If arr has more than two dimensions.

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import array_to_latex
>>> print(array_to_latex(np.array([[1, 2], [3, 4]])))
\begin{pmatrix}
  1 & 2 \\
  3 & 4 \\
\end{pmatrix}

attempt_to_make_Cartier

attempt_to_make_Cartier(tri, D)

Attempt to refine a fan so that a divisor becomes Cartier and nef.

If the divisor is already Cartier, the inputs are returned unchanged. Otherwise, the facet normals of its Newton polytope that are not yet rays of the fan are added as new vectors, with coefficients given by the constant terms of the corresponding facet inequalities (so that the Newton polytope does not change). The enlarged vector configuration is triangulated, and the result is passed to attempt_to_make_nef. The result is not checked.

Parameters:

  • tri (Fan) –

    The toric fan.

  • D (ArrayLike) –

    The divisor coefficients.

Returns:

  • tuple[Fan, ndarray] –

    The new fan and the divisor coefficients on it, with the coefficients of the new vectors appended after the original ones.

attempt_to_make_nef

attempt_to_make_nef(toric_variety, line_bundle, epsilon=1e-05)

Attempt to find a triangulation on which a divisor is nef.

The vector configuration of toric_variety is triangulated with heights \(h = a/\epsilon + h_0 + \epsilon\,(1 + \sin(i + 1))\), where \(a\) are the divisor coefficients, \(h_0\) the heights of toric_variety, and \(i\) the index of the vector. The divisor is nef on the regular subdivision induced by the heights \(a\) and on its refinements, and for small enough \(\epsilon\) the other two terms only refine this subdivision to a triangulation. The result is not checked.

Parameters:

  • toric_variety (Fan) –

    A regular fan. Its heights and its vector configuration are used.

  • line_bundle (ArrayLike) –

    The divisor coefficients \(a\), one per vector of the vector configuration.

  • epsilon (float, default: 1e-05 ) –

    The size \(\epsilon\) of the perturbation.

Returns:

  • Fan –

    The triangulation of the vector configuration. Not all of the vectors are necessarily used.

base_locus

base_locus(sections, cones=None, dim=4)

Return the minimal sets of toric coordinates on which all sections vanish.

All sections vanish on the locus \(\{x_\rho = 0 : \rho \in S\}\) if every section contains some \(x_\rho\) with \(\rho \in S\) with a positive exponent. The minimal such sets \(S\) are found by checking candidate sets of increasing size and skipping supersets of sets already found.

Parameters:

  • sections (ndarray) –

    The exponent matrix of the sections, with one row per coordinate and one column per section, as returned by sections.

  • cones (list[tuple[int, ...]] | None, default: None ) –

    The maximal cones of a simplicial fan. If specified, only faces of these cones are considered as candidate sets. If not specified, all sets of at most dim coordinates are considered.

  • dim (int, default: 4 ) –

    The maximum number of coordinates in a candidate set when cones is not specified.

Returns:

  • list[tuple[int, ...]] –

    The minimal sets, as tuples of one-indexed ray labels, in order of increasing size.

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import base_locus
>>> base_locus(np.array([[1, 1], [1, 0], [0, 1]]))
[(1,), (2, 3)]

basis

basis(points)

Return the indices of rows that form a basis of the row span.

The rows are scanned in order, and each row that is linearly independent of the previously selected ones is added, until the rank of the matrix is reached.

Parameters:

  • points (ndarray) –

    The 2D array whose rows are considered.

Returns:

  • list[int] –

    The indices of the selected rows.

Raises:

  • ValueError –

    If no basis could be found (e.g. if points has no rows).

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import basis
>>> basis(np.array([[1, 0], [2, 0], [0, 1]]))
[0, 2]

basis_H2_toric_fan

basis_H2_toric_fan(toric_fan)

Return ray labels whose divisor classes form a basis of the class group.

Find the first smooth maximal cone \(\sigma\) of the fan. Since its generators form a basis of the lattice, every divisor is linearly equivalent to a unique integral combination of the toric prime divisors \(D_\rho\) with \(\rho \notin \sigma\), so their classes form a \(\mathbb{Z}\)-basis of the divisor class group. The rays are assumed to be labeled \(1, \ldots, n\).

Parameters:

  • toric_fan (Fan) –

    The toric fan.

Returns:

  • ndarray –

    The labels of the rays not in \(\sigma\), in increasing order.

Raises:

  • ValueError –

    If the fan has no smooth maximal cone.

Examples:

>>> from cytools.vector_config import VectorConfiguration
>>> from cytools.f_theory.Uplift_functions import basis_H2_toric_fan
>>> fan = VectorConfiguration([[1, 0], [0, 1], [-1, 1], [0, -1]]).triangulate()
>>> basis_H2_toric_fan(fan)
array([3, 4])

compute_partition

compute_partition(divisors, rays)

Shift two toric divisors so that they partition the anticanonical divisor.

Look for characters \(m_1, m_2 \in M\) such that the shifted divisors \(D_i + \operatorname{div}(\chi^{m_i})\), with coefficients \(a_{i,\rho} + \langle m_i, v_\rho \rangle\), are effective and sum to the anticanonical divisor \(\sum_\rho D_\rho\). Since the shifted coefficients are non-negative integers that add up to one on every ray, the two divisors then partition the set of toric prime divisors. The characters are found by solving an integer linear program with scipy.optimize.milp.

Parameters:

  • divisors (list[ndarray]) –

    The coefficient vectors of the two divisors. Exactly two divisors are currently supported.

  • rays (ndarray) –

    The ray generators \(v_\rho\) of the toric fan, one per row.

Returns:

  • tuple[bool, ndarray | None] –

    Whether such a shift exists and, if it does, an integer array of shape (2, len(rays)) whose rows are the shifted divisor coefficient vectors (otherwise None).

Examples:

We shift two divisors on the Hirzebruch surface \(\mathbb{F}_1\) into a partition of the anticanonical divisor.

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import compute_partition
>>> rays = np.array([[1, 0], [0, 1], [-1, 1], [0, -1]])
>>> compute_partition([np.array([2, 0, 0, 0]), np.array([-1, 1, 1, 1])], rays)
(True, array([[1, 0, 1, 0],
       [0, 1, 0, 1]]))

contains_row

contains_row(arr, target)

Check whether a vector appears as a row of a 2D array.

Parameters:

  • arr (ndarray) –

    The 2D array to search.

  • target (ndarray) –

    The 1D array to look for.

Returns:

  • bool –

    Whether target is equal to some row of arr.

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import contains_row
>>> contains_row(np.array([[1, 0], [0, 1]]), np.array([0, 1]))
np.True_

contains_rows

contains_rows(arr, targets)

Check whether every row of one 2D array appears as a row of another.

Parameters:

  • arr (ndarray) –

    The 2D array to search.

  • targets (ndarray) –

    The 2D array whose rows to look for.

Returns:

  • bool –

    Whether every row of targets is equal to some row of arr.

divisor_intersections

divisor_intersections(fan, intersection_dict, divisors, basis_set, as_LLL=True)

Compute the classes of the toric curves on a complete intersection.

Let \(X\) be the \(d\)-dimensional toric variety of fan and \(Y = D_1 \cap \cdots \cap D_k\) the complete intersection of the given divisors. For each cone \(s\) with \(d - k - 1\) rays, \(C_s = V(s) \cdot D_1 \cdots D_k\) is a curve on \(Y\), and its class is recorded by the intersection numbers \(D_i \cdot C_s\) with the basis divisors \(i \in\) basis_set (e.g. obtained with basis_H2_toric_fan). These are computed from intersection_dict by expanding each \(D_a\) in terms of the toric prime divisors in the star of \(s\). If some \(D_a\) has no nonzero coefficient on these prime divisors, or none of them is a basis divisor, the row is left as zero.

Parameters:

  • fan (Fan) –

    The toric fan.

  • intersection_dict (dict[tuple[int, ...], float]) –

    The intersection numbers of the toric variety, with sorted tuples of ray labels as keys, as returned by the intersection_numbers method of the fan.

  • divisors (list[ndarray]) –

    The coefficient vectors of the divisors \(D_a\).

  • basis_set (set[int]) –

    The labels of the basis divisors.

  • as_LLL (bool, default: True ) –

    Whether to return an LLL-reduced basis of the lattice generated by the curve classes instead of the classes themselves.

Returns:

  • ndarray –

    If as_LLL is false, the curve classes, with one row per cone \(s\) (in arbitrary order) and one column per basis divisor (in the iteration order of basis_set). If as_LLL is true, the nonzero rows of the LLL reduction of this matrix.

dual_face_Cayley_polytope

dual_face_Cayley_polytope(Cdvert, f)

Return the face of the dual Cayley polytope dual to a given face.

The dual face is the convex hull of the vertices of the dual Cayley polytope that pair to zero with every vertex of f.

Parameters:

  • Cdvert (ndarray) –

    The vertices of the dual Cayley polytope, one per row.

  • f (PolytopeFace) –

    A face of the Cayley polytope.

Returns:

find_cone

find_cone(new_ray, current_cones, all_vectors, tol=1e-10)

Return the face of a simplicial cone that contains a given vector.

For each cone in turn, the coefficients expressing new_ray in terms of the generators of the cone are computed. For the first cone where they are all non-negative (up to tol), return the labels of the generators with positive coefficients, which generate the smallest face of the cone containing the vector. The cones must be simplicial and full-dimensional.

Parameters:

  • new_ray (ndarray) –

    The vector to locate.

  • current_cones (Iterable[tuple[int, ...]]) –

    The cones, as tuples of one-indexed labels.

  • all_vectors (ndarray) –

    The vectors, where the vector with label i is in row i - 1.

  • tol (float, default: 1e-10 ) –

    The numerical tolerance for the signs of the coefficients.

Returns:

  • frozenset[int] | None –

    The labels of the generators of the face, or None if no cone contains the vector.

Examples:

>>> import numpy as np
>>> from cytools.vector_config import VectorConfiguration
>>> from cytools.f_theory.Uplift_functions import find_cone
>>> fan = VectorConfiguration([[1, 0], [0, 1], [-1, 1], [0, -1]]).triangulate()
>>> find_cone(np.array([1, 1]), fan.cones(), fan.vectors())
frozenset({1, 2})

find_cone_general

find_cone_general(new_ray, current_cones, all_vectors)

Return the face of a cone that contains a given vector.

For each cone in turn, solve for non-negative coefficients expressing new_ray in terms of the generators of the cone (with scipy.optimize.nnls). For the first cone where this succeeds, return the labels of the generators with positive coefficients. Unlike find_cone, this also works for cones that are not simplicial or not full-dimensional, but for non-simplicial cones the returned labels need not generate the smallest face containing the vector.

Parameters:

  • new_ray (ndarray) –

    The vector to locate.

  • current_cones (Iterable[tuple[int, ...]]) –

    The cones, as tuples of one-indexed labels.

  • all_vectors (ndarray) –

    The vectors, where the vector with label i is in row i - 1.

Returns:

  • frozenset[int] | None –

    The labels of the generators, or None if no cone contains the vector.

find_trilayer_vertex_polytope

find_trilayer_vertex_polytope(p, as_index=False)

Return the distinguished vertex of a trilayer polytope.

A polytope is trilayer (see Polytope.is_trilayer) if one of its vertices has GLSM charge equal to half of the anticanonical class of the vertex configuration. This function finds that vertex.

Parameters:

  • p (Polytope) –

    A trilayer polytope.

  • as_index (bool, default: False ) –

    Whether to return the index of the vertex in p.vertices() instead of its coordinates.

Returns:

  • ndarray | int –

    The distinguished vertex, or its index if as_index is true.

Examples:

>>> from cytools import Polytope
>>> from cytools.f_theory.Uplift_functions import find_trilayer_vertex_polytope
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[-1,-1,-1,-4],[0,0,0,1]])
>>> find_trilayer_vertex_polytope(p)
array([0, 0, 0, 1])

find_trilayer_vertex_vertices

find_trilayer_vertex_vertices(V, as_vertex_index=False)

Return the distinguished vertex of a trilayer polytope from its vertices.

This is the same as find_trilayer_vertex_polytope, but takes the vertices of the polytope as input.

Parameters:

  • V (ndarray) –

    The vertices of a trilayer polytope, one per row.

  • as_vertex_index (bool, default: False ) –

    Whether to return the index of the vertex in V instead of its coordinates.

Returns:

  • ndarray | int –

    The distinguished vertex, or its index if as_vertex_index is true.

flatten

flatten(lst, depth)

Flatten a nested list by a given number of levels.

Only elements of type list are flattened; other elements, such as tuples or arrays, are kept as they are.

Parameters:

  • lst (list) –

    The nested list.

  • depth (int) –

    The number of levels to flatten.

Returns:

  • list –

    The flattened list.

Examples:

>>> from cytools.f_theory.Uplift_functions import flatten
>>> flatten([[1, [2]], [3]], 1)
[1, [2], 3]

generic_section_factorizes

generic_section_factorizes(points, linebundle_weights)

Check whether the generic section of a toric divisor factorizes.

Compute the exponents of the toric coordinates \(x_\rho\) in all monomial sections of the divisor, and return True if some coordinate has exponent zero in every section, or if the divisor has no sections at all. Otherwise, return False.

Parameters:

  • points (ndarray) –

    The rays of the toric fan, one per row.

  • linebundle_weights (ndarray) –

    The divisor coefficients.

Returns:

  • bool –

    Whether the generic section factorizes, according to the criterion above.

get_index

get_index(arr, target)

Return the indices of the rows of arr equal to target.

Parameters:

  • arr (ndarray) –

    The 2D array to search.

  • target (ndarray) –

    The 1D target row.

Returns:

  • ndarray –

    The sorted indices of the rows of arr equal to target.

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import get_index
>>> get_index(np.array([[1, 0], [0, 1], [1, 1], [0, 1]]), np.array([0, 1]))
array([1, 3])

get_indices

get_indices(arr, targets)

Return the indices of the rows of arr that appear among targets.

Parameters:

  • arr (ndarray) –

    The 2D array to search.

  • targets (ndarray) –

    A single target row (1D array) or several target rows (2D array).

Returns:

  • ndarray –

    The sorted indices of the rows of arr that are equal to some target row.

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import get_indices
>>> arr = np.array([[1, 0], [0, 1], [1, 1], [0, 1]])
>>> get_indices(arr, np.array([[0, 1], [1, 1]]))
array([1, 2, 3])

get_lower_dimensional_cones

get_lower_dimensional_cones(cones, d)

Return all faces with a given number of rays of a collection of cones.

Every d-element subset of the rays of each cone is returned once. Since all subsets are taken, these are exactly the d-ray faces only if the cones are simplicial.

Parameters:

  • cones (Iterable[tuple[int, ...]]) –

    The cones, as tuples of ray labels.

  • d (int) –

    The number of rays of the faces.

Returns:

  • list[tuple[int, ...]] –

    The distinct d-ray faces, in arbitrary order.

Examples:

>>> from cytools.f_theory.Uplift_functions import get_lower_dimensional_cones
>>> sorted(get_lower_dimensional_cones([(1, 2, 3), (2, 3, 4)], 2))
[(1, 2), (1, 3), (2, 3), (2, 4), (3, 4)]

get_same_rows

get_same_rows(A, B)

Return the rows of A that also appear as rows of B.

The rows are returned in the order in which they appear in A. A row of A is repeated once for each row of B that it matches.

Parameters:

  • A (ndarray) –

    The 2D array whose rows are returned.

  • B (ndarray) –

    The 2D array to compare against.

Returns:

  • ndarray –

    The rows of A that appear in B.

glsm_from_points

glsm_from_points(pts)

Return a GLSM charge matrix for a point configuration.

The rows of the returned matrix form a \(\mathbb{Z}\)-basis of the lattice of integer linear relations \(\sum_i q_i v_i = 0\) among the points \(v_i\), computed with the Smith normal form. Column \(i\) contains the charges of point \(i\).

Parameters:

  • pts (ArrayLike) –

    The points \(v_i\), one per row.

Returns:

  • ndarray –

    The GLSM charge matrix, of shape (n - r, n), where n is the number of points and r the rank of the configuration.

Examples:

>>> from cytools.f_theory.Uplift_functions import glsm_from_points
>>> glsm_from_points([[1, 0], [0, 1], [-1, -1]])
array([[1, 1, 1]])

h11_2_part

h11_2_part(Cay, Cayd, det=False)

Compute \(h^{1,1}\) of a Calabi-Yau defined by a two-part nef partition.

The Calabi-Yau is the complete intersection of two hypersurfaces defined by a two-part nef partition, which is encoded by the Cayley polytope Cay and its dual Cayd. The Hodge number is computed with a combinatorial formula that counts the lattice points of faces of the two Cayley polytopes and of their dilations by a factor of two. Exchanging the two polytopes computes \(h^{1,1}\) of the mirror instead, which for Calabi-Yau fourfolds is \(h^{3,1}\) of the original Calabi-Yau.

Parameters:

  • Cay (Polytope) –

    The Cayley polytope.

  • Cayd (Polytope) –

    The dual Cayley polytope.

  • det (bool, default: False ) –

    Whether to print the running total after each group of contributions.

Returns:

  • int –

    The Hodge number \(h^{1,1}\).

h21_2_part

h21_2_part(Cay, Cayd, det=False)

Compute \(h^{2,1}\) of a fourfold defined by a two-part nef partition.

The Calabi-Yau fourfold is the complete intersection of two hypersurfaces in a six-dimensional toric variety defined by a two-part nef partition, which is encoded by the Cayley polytope Cay and its dual Cayd. The Hodge number is computed with a combinatorial formula that counts the lattice points of faces of the two Cayley polytopes and of their dilations by a factor of two. The face dimensions that enter the formula are specific to this fourfold case.

Parameters:

  • Cay (Polytope) –

    The Cayley polytope.

  • Cayd (Polytope) –

    The dual Cayley polytope.

  • det (bool, default: False ) –

    Whether to print the running total after each group of contributions.

Returns:

  • int –

    The Hodge number \(h^{2,1}\).

inequivalent_Z2_actions

inequivalent_Z2_actions(lattice_symmetries)

Return the \(\mathbb{Z}_2\) torus actions up to lattice symmetries.

The \(\mathbb{Z}_2\) subgroups of the torus are generated by \(q/2\) with \(q \in \{0, 1\}^n\) nonzero. Two such vectors are equivalent if \(s q \equiv q'\) modulo 2 for some symmetry \(s\). One representative of each equivalence class is returned.

Parameters:

  • lattice_symmetries (list[ndarray]) –

    The lattice symmetry group, as square integer matrices acting from the left. It should include the identity, e.g. as returned by Polytope.automorphisms with action="left".

Returns:

  • ndarray –

    The representatives \(q\), as 0/1 vectors, one per row.

Examples:

With only the symmetry that exchanges the two coordinates, \((1, 0)\) and \((0, 1)\) are equivalent.

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import inequivalent_Z2_actions
>>> inequivalent_Z2_actions([np.eye(2, dtype=int), np.array([[0, 1], [1, 0]])])
array([[0, 1],
       [1, 1]])

integral_gale_transform

integral_gale_transform(points)

Return an integral Gale transform of a point configuration.

The points are lifted by appending a coordinate equal to \(1\), and a basis of the rational nullspace of the lifted configuration is computed with SymPy and scaled to be integral. The rows of the result form a basis of the affine dependencies \(\sum_i c_i p_i = 0\), \(\sum_i c_i = 0\) among the points \(p_i\), and its columns are the Gale vectors of the points.

Parameters:

  • points (ArrayLike) –

    The points, one per row, as an array of shape (n, d).

Returns:

  • ndarray –

    The Gale transform, of shape (n - d - 1, n) if the points affinely span \(\mathbb{R}^d\).

Raises:

  • ValueError –

    If there are not more than d + 1 points.

Warning

The nullspace is currently computed from a floating-point matrix, so its non-integral entries are truncated instead of being scaled to integers. This gives incorrect results whenever the nullspace basis found by SymPy has non-integral entries.

Examples:

>>> from cytools.f_theory.Uplift_functions import integral_gale_transform
>>> integral_gale_transform([[0, 0], [1, 0], [0, 1], [1, 1]])
array([[ 1, -1, -1,  1]])

is_Cartier

is_Cartier(toric_fan, weights, return_Q_Cartier_data=False, decimals=10)

Check whether a toric Weil divisor is Cartier.

For each maximal cone \(\sigma\), solve for the local data \(m_\sigma\) with \(\langle m_\sigma, v_\rho \rangle = -a_\rho\) for all rays \(\rho \in \sigma\) (by least squares, in floating point). The divisor is Cartier if all of these exist and are integral.

Parameters:

  • toric_fan (Fan) –

    The toric fan.

  • weights (ArrayLike) –

    The divisor coefficients \(a_\rho\).

  • return_Q_Cartier_data (bool, default: False ) –

    Whether to keep going and return the local data if the divisor is not Cartier.

  • decimals (int, default: 10 ) –

    The number of decimals to which non-integral local data is rounded.

Returns:

  • tuple[bool, list | None] –

    Whether the divisor is Cartier, and a list with the local data \(m_\sigma\) for each maximal cone, in the order of toric_fan.cones(). If the divisor is not Cartier and return_Q_Cartier_data is false, the list is None. Otherwise, each entry is an integer array if \(m_\sigma\) is integral, a rounded float array if it is non-integral, and None if it does not exist.

Examples:

>>> from cytools.vector_config import VectorConfiguration
>>> from cytools.f_theory.Uplift_functions import is_Cartier
>>> fan = VectorConfiguration([[1, 0], [1, 2]]).triangulate()
>>> is_Cartier(fan, [1, 0])
(False, None)
>>> is_Cartier(fan, [1, 0], return_Q_Cartier_data=True)
(False, [array([-1. ,  0.5])])

is_Gorenstein

is_Gorenstein(cone)

Check whether a cone is Gorenstein.

A cone is Gorenstein if there is an integral linear functional \(n\) that takes the value \(1\) on the primitive generators of all of its extremal rays. The functional is computed from the Smith normal form of the matrix of extremal rays.

Parameters:

  • cone (Cone) –

    The cone to test.

Returns:

  • tuple[bool, ndarray | None] –

    Whether the cone is Gorenstein and, if it is, the functional \(n\) (otherwise None).

Warning

The candidate functional is currently not checked against all of the equations, so this function can return True, together with an invalid functional, for cones that are not Gorenstein (e.g. the cone generated by \((1, 0)\) and \((2, 3)\)).

is_ample

is_ample(toric_fan, weights)

Check whether a toric divisor is ample.

The divisor is ample if its coefficient vector lies in the interior of the secondary cone of the fan, i.e. if it pairs positively with all of the secondary cone hyperplanes.

Parameters:

  • toric_fan (Fan) –

    The toric fan.

  • weights (ArrayLike) –

    The divisor coefficients.

Returns:

  • bool –

    Whether the divisor is ample.

is_effective

is_effective(points, weights)

Check whether a toric divisor has a nonzero global section.

This is the case if its Newton polytope (see Newton_Polytope) contains a lattice point, i.e. if the divisor is linearly equivalent to an effective torus-invariant divisor.

Parameters:

  • points (ndarray) –

    The rays of the toric fan, one per row.

  • weights (ArrayLike) –

    The divisor coefficients.

Returns:

  • bool –

    Whether the divisor has a nonzero global section.

is_nef

is_nef(toric_fan, weights)

Check whether a toric divisor is nef.

The divisor is nef if its coefficient vector lies in the closure of the secondary cone of the fan, i.e. if it pairs non-negatively with all of the secondary cone hyperplanes.

Parameters:

  • toric_fan (Fan) –

    The toric fan.

  • weights (ArrayLike) –

    The divisor coefficients.

Returns:

  • bool –

    Whether the divisor is nef.

Examples:

On the Hirzebruch surface \(\mathbb{F}_1\), the fiber is nef while the exceptional curve is not.

>>> from cytools.vector_config import VectorConfiguration
>>> from cytools.f_theory.Uplift_functions import is_nef
>>> fan = VectorConfiguration([[1, 0], [0, 1], [-1, 1], [0, -1]]).triangulate()
>>> is_nef(fan, [1, 0, 0, 0]), is_nef(fan, [0, 1, 0, 0])
(np.True_, np.False_)

is_partition

is_partition(points, L1, L2)

Check whether two toric divisors can be shifted to a partition of \(-K\).

Look for characters \(m_1, m_2\) such that the shifted divisors \(L_i + \operatorname{div}(\chi^{m_i})\), with coefficients \(L_{i,\rho} + \langle m_i, v_\rho \rangle\), have all coefficients in \(\{0, 1\}\) and sum to the anticanonical divisor \(\sum_\rho D_\rho\). First, a character \(m\) with \(L_1 + L_2 + \operatorname{div}(\chi^m) = -K\) is found with sums_to_anticanonical. Then \(m_2\) is searched for by prescribing each of the two allowed values of \(\langle m_2, v_\rho \rangle\) on a basis of rays (see basis), and \(m_1 = m - m_2\).

Parameters:

  • points (ndarray) –

    The rays \(v_\rho\) of the toric fan, one per row.

  • L1 (ndarray) –

    The coefficients of the first divisor.

  • L2 (ndarray) –

    The coefficients of the second divisor.

Returns:

  • tuple[bool, bool, ndarray, ndarray] –

    A tuple (is_partition, sums_to_anticanonical, m1, m2). If the sum is not linearly equivalent to \(-K\), m1 and m2 are zero. If it is but no partition is found, m1 is zero and m2 is \(m\).

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import is_partition
>>> rays = np.array([[1, 0], [0, 1], [-1, 1], [0, -1]])
>>> is_partition(rays, np.array([2, 0, 0, 0]), np.array([-1, 1, 1, 1]))
(True, True, array([-1,  0]), array([1, 0]))

is_reflexive_Gorenstein

is_reflexive_Gorenstein(cone)

Check whether a cone and its dual are both Gorenstein.

See is_Gorenstein.

Parameters:

  • cone (Cone) –

    The cone to test.

Returns:

  • bool –

    Whether the cone is reflexive Gorenstein.

lattice_refinement

lattice_refinement(q, denominator=2)

Return the change of basis to a refined lattice.

The refined lattice is \(N' = \mathbb{Z}^n + \mathbb{Z}\, q/k\), where \(k\) is denominator. The returned integer matrix \(\Lambda\) maps a vector of the original lattice \(\mathbb{Z}^n\) to its coordinates with respect to an LLL-reduced basis of \(N'\). Its determinant is \(\pm[N' : \mathbb{Z}^n]\).

Parameters:

  • q (ArrayLike) –

    The integer vector defining the refinement.

  • denominator (int, default: 2 ) –

    The denominator \(k\) of the fractional vector \(q/k\).

Returns:

  • ndarray –

    The integer matrix \(\Lambda\).

Examples:

>>> from cytools.f_theory.Uplift_functions import lattice_refinement
>>> lattice_refinement([1, 1])
array([[ 1,  1],
       [ 1, -1]])

linebundle_weights_from_Newton_Polytope

linebundle_weights_from_Newton_Polytope(vectors, Newton_polytope)

Return the divisor coefficients determined by a Newton polytope.

The coefficient of each ray is \(a_\rho = \max_m (-\langle m, v_\rho \rangle)\), with \(m\) ranging over the lattice points of the polytope. This is the smallest divisor whose Newton polytope contains the given one.

Parameters:

  • vectors (ndarray) –

    The rays \(v_\rho\) of the toric fan, one per row.

  • Newton_polytope (Polytope) –

    The Newton polytope.

Returns:

  • ndarray –

    The divisor coefficients \(a_\rho\).

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import (
...     Newton_Polytope,
...     linebundle_weights_from_Newton_Polytope,
... )
>>> rays = np.array([[1, 0], [0, 1], [-1, -1]])
>>> newton_polytope = Newton_Polytope(rays, [1, 1, 1])
>>> linebundle_weights_from_Newton_Polytope(rays, newton_polytope)
array([1, 1, 1])

make_simplicial

make_simplicial(fan)

Return a simplicial refinement of a fan.

Each maximal cone with more rays than the dimension of the fan is replaced by the cones of a fine triangulation of its generators, and the simplicial cones are kept. The cones are triangulated independently of each other, so the result is only guaranteed to be a fan if non-simplicial cones do not share non-simplicial faces.

Parameters:

  • fan (Fan) –

    The toric fan.

Returns:

  • Fan –

    The simplicial refinement, with the same vector configuration.

moving_cone

moving_cone(toric_variety)

Return the moving cone of a toric variety.

The moving cone is the intersection, over all rays \(\rho\), of the cones generated by the classes of the toric prime divisors other than \(D_\rho\). The returned cone lives in the space \(\mathbb{R}^n\) of divisor coefficients: it is the preimage of the moving cone under the map to the divisor class group, so its lineality space contains the principal divisors.

Parameters:

  • toric_variety (Fan) –

    The toric fan. Only its rays are used.

Returns:

  • Cone –

    The moving cone, in the space of divisor coefficients.

nested_sum

nested_sum(lists, depth=0, acc=0)

Return all sums of one element from each list, as a nested list.

The entry at position [i_0][i_1]... of the result is acc + lists[depth][i_0] + lists[depth + 1][i_1] + ....

Parameters:

  • lists (list) –

    The lists (or arrays) whose elements are summed.

  • depth (int, default: 0 ) –

    The index of the first list to use. This is used for the recursion.

  • acc (Any, default: 0 ) –

    The partial sum accumulated so far. This is used for the recursion.

Returns:

  • list –

    The sums, as a list nested len(lists) - depth levels deep. If depth equals len(lists), acc itself is returned.

Examples:

>>> from cytools.f_theory.Uplift_functions import nested_sum
>>> nested_sum([[1, 2], [10, 20]])
[[11, 21], [12, 22]]

normal_fan

normal_fan(polytopes, inequalities=None, maximal_refinement=False, triangulate_refinement=False, return_unrefined_fan=False)

Construct the normal fan of a polytope or of a Minkowski sum of polytopes.

The rays of the normal fan are the inward facet normals \(u\) of the polytope \(P\) (or of the Minkowski sum \(P = P_0 + P_1 + \cdots\) if a list of polytopes is given), and there is one maximal cone for each vertex of \(P\), generated by the normals of the facets containing it. The weight of a ray \(u\) for a polytope \(P_j\) is \(w_j(u) = -\min_{m \in P_j} \langle m, u \rangle\), so that \(P_j\) is the Newton polytope of the divisor \(\sum_u w_j(u) D_u\) on the toric variety of the normal fan.

If maximal_refinement is true, the normal fan of a list of two polytopes is also refined using inequalities \(= (a_0, a_1, c)\). If some ray of the normal fan does not satisfy \(0 \leq a_0 (1 - w_0(u)) - w_1(u) < c\), only None values are returned. Otherwise, the primitive vectors along all lattice points \(u \neq 0\) of the support of the normal fan with \(a_0 w_0(u) + a_1 w_1(u) \leq c\) are added as new rays.

Parameters:

  • polytopes (Polytope | list[Polytope]) –

    A lattice polytope, or a list of lattice polytopes whose Minkowski sum is used.

  • inequalities (ArrayLike | None, default: None ) –

    The coefficients \((a_0, a_1, c)\) that define the refinement. Required if maximal_refinement is true.

  • maximal_refinement (bool, default: False ) –

    Whether to construct the refinement. This requires polytopes to be a list of two polytopes.

  • triangulate_refinement (bool, default: False ) –

    Whether to return the refined fan, obtained by star subdividing a simplicial refinement of the normal fan at the new rays, instead of only its rays. Only used if maximal_refinement is true.

  • return_unrefined_fan (bool, default: False ) –

    Whether to also return the normal fan. Only used if maximal_refinement is true.

Returns:

  • tuple –

    If maximal_refinement is false, a tuple (fan, weights, cones) with the normal fan, the ray weights, and its maximal cones as lists of one-indexed ray labels. The weights form a 1D array for a single polytope, and an array of shape (num_rays, len(polytopes)) for a list. If maximal_refinement is true, a tuple (rays, weights) with the rays of the refinement (the rays of the normal fan first) and their weights. If triangulate_refinement is true, rays is replaced by the refined fan, and if return_unrefined_fan is true, the normal fan is appended to the tuple. If the check above fails, all entries are None.

Raises:

  • Exception –

    If maximal_refinement is true but inequalities is not specified.

Examples:

We construct the normal fan of the unit square, whose Newton polytope weights are those of the divisor \(D_3 + D_4\).

>>> from cytools import Polytope
>>> from cytools.f_theory.Uplift_functions import normal_fan
>>> fan, weights, cones = normal_fan(Polytope([[0, 0], [1, 0], [0, 1], [1, 1]]))
>>> fan.vectors()
array([[ 1,  0],
       [ 0,  1],
       [-1,  0],
       [ 0, -1]])
>>> weights
array([0, 0, 1, 1])

points_from_glsm

points_from_glsm(glsm)

Return a point configuration with the given GLSM charges.

This inverts glsm_from_points up to a change of lattice basis: the columns of the returned matrix form a \(\mathbb{Z}\)-basis of the integer kernel of glsm, so the rows are points whose integer linear relations are generated by the rows of glsm.

Parameters:

  • glsm (ArrayLike) –

    The GLSM charge matrix, with one column per point.

Returns:

  • ndarray –

    The points, one per row, of shape (n, n - r), where n is the number of columns of glsm and r its rank.

Examples:

>>> from cytools.f_theory.Uplift_functions import points_from_glsm
>>> points_from_glsm([[1, 1, 1]])
array([[-1, -1],
       [ 1,  0],
       [ 0,  1]])

points_not_interior_to_facets_and_codim2_faces

points_not_interior_to_facets_and_codim2_faces(p)

Return the lattice points not interior to faces of codimension one or two.

Start from the points not interior to facets (see Polytope.pts_not_facets) and remove the points interior to codimension-two faces, keeping the order of the remaining points.

Parameters:

Returns:

  • ndarray –

    The selected lattice points, one per row.

refine_fan

refine_fan(fan, blowups_or_all_vectors=None)

Insert new rays into a simplicial fan by star subdivisions.

If blowups_or_all_vectors is specified, its rows that are not yet in the vector configuration of the fan are appended to it, keeping the cones of the fan. Then, each vector of the vector configuration that is not a ray of the fan is inserted: the smallest cone \(\tau\) containing it is found, and every cone \(\tau \cup c\), with \(c\) in the link of \(\tau\), is replaced by the cones \(\tau' \cup c \cup \{\rho\}\), where \(\rho\) is the new ray and \(\tau'\) ranges over the facets of \(\tau\).

Parameters:

  • fan (Fan) –

    The simplicial toric fan.

  • blowups_or_all_vectors (ndarray | None, default: None ) –

    The new rays, one per row, or a full vector configuration containing both the old and the new rays. If not specified, the vectors of the vector configuration of fan that are not rays of the fan are inserted.

Returns:

  • Fan –

    The refined fan.

Examples:

We blow up the torus-fixed point of the first cone of \(\mathbb{F}_1\).

>>> import numpy as np
>>> from cytools.vector_config import VectorConfiguration
>>> from cytools.f_theory.Uplift_functions import refine_fan
>>> fan = VectorConfiguration([[1, 0], [0, 1], [-1, 1], [0, -1]]).triangulate()
>>> refine_fan(fan, np.array([[1, 1]])).cones()
((1, 4), (1, 5), (2, 3), (2, 5), (3, 4))

row_difference

row_difference(A, B)

Return the rows of A that do not appear as rows of B.

The rows are returned in the order in which they appear in A, including repeated rows.

Parameters:

  • A (ndarray) –

    The 2D array whose rows are returned.

  • B (ndarray) –

    The 2D array of rows to exclude.

Returns:

  • ndarray –

    The rows of A that are not rows of B.

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import row_difference
>>> row_difference(np.array([[1, 0], [0, 1], [1, 1]]), np.array([[0, 1]]))
array([[1, 0],
       [1, 1]])

same_rows

same_rows(A, B)

Check whether two 2D arrays have the same rows, ignoring order.

Rows are compared with multiplicity, so each distinct row must appear the same number of times in both arrays.

Parameters:

  • A (ndarray) –

    The first 2D array.

  • B (ndarray) –

    The second 2D array.

Returns:

  • bool –

    Whether A and B contain the same rows with the same multiplicities.

sections

sections(points, weights)

Return the exponent vectors of the monomial sections of a toric divisor.

Each lattice point \(m\) of the Newton polytope (see Newton_Polytope) corresponds to the section \(\prod_\rho x_\rho^{\langle m, v_\rho \rangle + a_\rho}\).

Parameters:

  • points (ndarray) –

    The rays \(v_\rho\) of the toric fan, one per row.

  • weights (ndarray) –

    The divisor coefficients \(a_\rho\).

Returns:

  • ndarray –

    The exponent matrix, with one row per ray and one column per section. If the divisor has no sections, an empty 1D array is returned.

Examples:

The divisor \(D_1\) on \(\mathbb{P}^2\) has the sections \(x_3\), \(x_2\), and \(x_1\).

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import sections
>>> sections(np.array([[1, 0], [0, 1], [-1, -1]]), np.array([1, 0, 0]))
array([[0, 0, 1],
       [0, 1, 0],
       [1, 0, 0]])

solve_over_integers

solve_over_integers(M, b)

Find an integer solution of the linear system \(M x = -b\).

The system is solved with the Smith normal form of \(M\). Note the sign: the system that is solved is \(M x = -b\), not \(M x = b\). If an inconsistent equation of the form \(0 = c\) with \(c \neq 0\) is encountered, PROBLEM is printed.

Parameters:

  • M (ArrayLike) –

    The integer matrix \(M\).

  • b (ArrayLike) –

    The integer vector \(b\).

Returns:

  • tuple[bool, ndarray | None] –

    Whether an integer solution exists and, if it does, a solution \(x\) (otherwise None).

Examples:

>>> from cytools.f_theory.Uplift_functions import solve_over_integers
>>> solve_over_integers([[1, 0], [0, 2]], [3, 4])
(True, array([-3, -2]))
>>> solve_over_integers([[1, 0], [0, 2]], [3, 3])
(False, None)

sums_to_anticanonical

sums_to_anticanonical(pts, L1, L2)

Check whether the sum of two toric divisors is linearly equivalent to \(-K\).

Look for a character \(m\) such that \(L_1 + L_2 + \operatorname{div}(\chi^m)\) is the anticanonical divisor \(\sum_\rho D_\rho\), i.e. \(\langle m, v_\rho \rangle = 1 - L_{1,\rho} - L_{2,\rho}\) for all rays. The system is solved by least squares, and the rounded solution is then checked exactly.

Parameters:

  • pts (ndarray) –

    The rays \(v_\rho\) of the toric fan, one per row.

  • L1 (ArrayLike) –

    The coefficients of the first divisor.

  • L2 (ArrayLike) –

    The coefficients of the second divisor.

Returns:

  • tuple[bool, ndarray | None] –

    Whether the sum is linearly equivalent to the anticanonical divisor and, if it is, the character \(m\) (otherwise None).

Examples:

>>> import numpy as np
>>> from cytools.f_theory.Uplift_functions import sums_to_anticanonical
>>> rays = np.array([[1, 0], [0, 1], [-1, 1], [0, -1]])
>>> sums_to_anticanonical(rays, [0, 1, 1, 0], [0, 0, 1, 1])
(True, array([1, 0]))

toric_orbifold

toric_orbifold(pts_CY_ambient, q, denominator=2)

Return the rays of the quotient of a toric variety by a finite torus action.

The quotient by the subgroup of the torus generated by \(q/k\), where \(k\) is denominator, has the same fan but with respect to the refined lattice \(N' = \mathbb{Z}^n + \mathbb{Z}\, q/k\). The rays are expressed in a basis of \(N'\) (see lattice_refinement) and then made primitive, so each original ray is \(v_\rho = r_\rho u_\rho\) with \(u_\rho\) primitive in \(N'\).

Parameters:

  • pts_CY_ambient (ndarray) –

    The rays \(v_\rho\) of the toric fan of the Calabi-Yau ambient variety, one per row.

  • q (ArrayLike) –

    The integer vector defining the torus action.

  • denominator (int, default: 2 ) –

    The denominator \(k\) of the fractional vector \(q/k\).

Returns:

  • tuple[ndarray, ndarray] –

    The primitive rays \(u_\rho\) of the orbifold, one per row, and the rescalings \(r_\rho\).

Examples:

>>> from cytools.f_theory.Uplift_functions import toric_orbifold
>>> toric_orbifold([[1, 0], [0, 1], [-1, -1]], [1, 1])
(array([[ 1,  1],
       [ 1, -1],
       [-1,  0]]), array([1, 1, 2]))

trilayer_5d_Ftheory_uplift

trilayer_5d_Ftheory_uplift(p, verbosity=1)

Construct the polytope of the F-theory uplift of a trilayer orientifold.

The polytope is first brought to trilayer normal form (see trilayer_normal_form). The lattice points of its top layer (first coordinate \(1\)), with the first coordinate dropped, are the rays of the toric base \(B\). The exceptional divisors corresponding to the points of the middle layer (first coordinate \(0\)) that are not interior to facets are blown down.

The rays of the base are then taken to be the primitive vectors along the lattice points \(u\) of the normal fan of the Newton polytope of \(-2K_B\) with weight \(1 \leq w(u) \leq 2\) (see normal_fan). The O7-plane divisors are the base divisors on which all sections of \(-2K_B\) vanish, with some section vanishing to first order. The uplift polytope is the convex hull of the base rays lifted to \((u, 0, 1)\), the rays \(v_x = (0, 3, 1)\), \(v_y = (0, -2, -1)\), and \(v_z = (0, 0, 1)\) of the \(\mathbb{P}_{2,3,1}\) fiber (where \(0\) denotes the origin of the base lattice), and the rays \(\hat{u} + v_x + 2 v_y\) and \(2 \hat{u} + 2 v_x + 3 v_y\) for each lifted O7-plane ray \(\hat{u}\), which resolve the \(D_4\) singularities over the O7-planes.

Parameters:

  • p (Polytope) –

    A reflexive trilayer polytope.

  • verbosity (int, default: 1 ) –

    The verbosity level. If positive, the number of blown-down exceptional divisors is printed.

Returns:

  • Polytope –

    The uplift polytope, of dimension p.dim() + 1 (five for a four-dimensional p).

Raises:

trilayer_normal_form

trilayer_normal_form(p)

Bring a trilayer polytope into trilayer normal form.

Apply a \(GL(n, \mathbb{Z})\) transformation that maps the distinguished vertex (see find_trilayer_vertex_polytope) to \((-1, 0, \ldots, 0)\) and all other vertices to points with first coordinate \(1\). The lattice points of the resulting polytope then lie in the three layers \(x_0 \in \{-1, 0, 1\}\).

Parameters:

Returns:

  • Polytope –

    The polytope in trilayer normal form.

Examples:

>>> from cytools import Polytope
>>> from cytools.f_theory.Uplift_functions import trilayer_normal_form
>>> p = Polytope([[1,0,0,0],[0,1,0,0],[0,0,1,0],[-1,-1,-1,-4],[0,0,0,1]])
>>> trilayer_normal_form(p).vertices()
array([[-1,  0,  0,  0],
       [ 1, -1, -1, -3],
       [ 1,  0,  0,  1],
       [ 1,  0,  1,  1],
       [ 1,  1,  0,  1]])