Beispiel #1
0
    def _make_CPRFanoToricVariety(self, name, coordinate_names, base_ring):
        """
        Construct a (crepant partially resolved) Fano toric variety
        and cache the result.

        INPUT:

        - ``name`` -- string. One of the pre-defined names in the
          ``toric_varieties_rays_cones`` data structure.

        - ``coordinate_names`` -- A string describing the names of the
          homogeneous coordinates of the toric variety.

        - ``base_ring`` -- a ring (default: `\QQ`). The base ring for
          the toric variety.

        OUTPUT:

        A :class:`CPR-Fano toric variety
        <sage.schemes.toric.fano_variety.CPRFanoToricVariety_field>`.

        EXAMPLES::

            sage: toric_varieties.P2()           # indirect doctest
            2-d CPR-Fano toric variety covered by 3 affine patches
        """
        rays, cones = toric_varieties_rays_cones[name]
        if coordinate_names is None:
            dict_key = (name, base_ring)
        else:
            coordinate_names = normalize_names(coordinate_names, len(rays),
                                               DEFAULT_PREFIX)
            dict_key = (name, base_ring) + tuple(coordinate_names)
        if dict_key not in self.__dict__:
            polytope = LatticePolytope( matrix(rays).transpose() )
            points = map(tuple, polytope.points().columns())
            ray2point = [points.index(r) for r in rays]
            charts = [ [ray2point[i] for i in c] for c in cones ]
            self.__dict__[dict_key] = \
                CPRFanoToricVariety(Delta_polar=polytope,
                                    coordinate_points=ray2point,
                                    charts=charts,
                                    coordinate_names=coordinate_names,
                                    base_ring=base_ring,
                                    check=self._check)
        return self.__dict__[dict_key]
Beispiel #2
0
    def P(self, n, names='z+', base_ring=QQ):
        r"""
        Construct the ``n``-dimensional projective space `\mathbb{P}^n`.

        INPUT:

        - ``n`` -- positive integer. The dimension of the projective space.

        - ``names`` -- string. Names for the homogeneous
          coordinates. See
          :func:`~sage.schemes.toric.variety.normalize_names`
          for acceptable formats.

        - ``base_ring`` -- a ring (default: `\QQ`). The base ring for
          the toric variety.

        OUTPUT:

        A :class:`CPR-Fano toric variety
        <sage.schemes.toric.fano_variety.CPRFanoToricVariety_field>`.

        EXAMPLES::

            sage: P3 = toric_varieties.P(3)
            sage: P3
            3-d CPR-Fano toric variety covered by 4 affine patches
            sage: P3.fan().rays()
            N( 1,  0,  0),
            N( 0,  1,  0),
            N( 0,  0,  1),
            N(-1, -1, -1)
            in 3-d lattice N
            sage: P3.gens()
            (z0, z1, z2, z3)
        """
        # We are going to eventually switch off consistency checks, so we need
        # to be sure that the input is acceptable.
        try:
            n = ZZ(n)   # make sure that we got a "mathematical" integer
        except TypeError:
            raise TypeError("dimension of the projective space must be a "
                            "positive integer!\nGot: %s" % n)
        if n <= 0:
            raise ValueError("only projective spaces of positive dimension "
                             "can be constructed!\nGot: %s" % n)
        m = identity_matrix(n).augment(matrix(n, 1, [-1]*n))
        charts = [ range(0,i)+range(i+1,n+1) for i in range(0,n+1) ]
        return CPRFanoToricVariety(Delta_polar=LatticePolytope(m),
                                   charts=charts, check=self._check,
                                   coordinate_names=names, base_ring=base_ring)
Beispiel #3
0
def integral_elements_in_box(K, C):
    r"""
    Return all integral elements of the totally real field `K` whose
    embeddings lie *numerically* within the bounds specified by the
    list `C`.  The output is architecture dependent, and one may want
    to expand the bounds that define C by some epsilon.

    INPUT:

    - `K` -- a totally real number field
    - `C` -- a list [[lower, upper], ...] of lower and upper bounds,
      for each embedding


    EXAMPLES::

        sage: x = polygen(QQ)
        sage: K.<alpha> = NumberField(x^2-2)
        sage: eps = 10e-6
        sage: C = [[0-eps,5+eps],[0-eps,10+eps]]
        sage: ls = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C)
        sage: sorted([ a.trace() for a in ls ])
        [0, 2, 4, 4, 4, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 10, 12, 12, 14]
        sage: len(ls)
        19

        sage: v = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C)
        sage: sorted(v)
         [0, -alpha + 2, 1, -alpha + 3, 2, 3, alpha + 2, 4, alpha + 3, 5, alpha + 4, 2*alpha + 3, alpha + 5, 2*alpha + 4, alpha + 6, 2*alpha + 5, 2*alpha + 6, 3*alpha + 5, 2*alpha + 7]

    A cubic field::

        sage: x = polygen(QQ)
        sage: K.<a> = NumberField(x^3 - 16*x +16)
        sage: eps = 10e-6
        sage: C = [[0-eps,5+eps]]*3
        sage: v = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C)

    Note that the output is platform dependent (sometimes a 5 is listed below, and
    sometimes it isn't)::

        sage: sorted(v)
        [-1/2*a + 2, 1/4*a^2 + 1/2*a, 0, 1, 2, 3, 4,...-1/4*a^2 - 1/2*a + 5, 1/2*a + 3, -1/4*a^2 + 5]
    """
    d = K.degree()
    Z_F = K.maximal_order()
    Foo = K.real_embeddings()
    B = K.reduced_basis()

    import numpy
    import numpy.linalg
    L = numpy.array([ [v(b) for b in B] for v in Foo])
    Linv = numpy.linalg.inv(L)
    Vi = [[C[0][0]],[C[0][1]]]
    for i in range(1,d):
        Vi = sum([ [v + [C[i][0]], v + [C[i][1]]] for v in Vi], [])
    V = numpy.matrix(Linv)*(numpy.matrix(Vi).transpose())
    j = 0
    while j < 2**d:
        for i in range(d):
            if V[i,j] < V[i,j+1]:
                V[i,j] = math.floor(V[i,j])
                V[i,j+1] = math.ceil(V[i,j+1])
            else:
                V[i,j] = math.ceil(V[i,j])
                V[i,j+1] = math.floor(V[i,j+1])
        j += 2
    W0 = (Linv*numpy.array([Vi[0]]*d)).transpose()
    W = (Linv*numpy.array([Vi[2**i] for i in range(d)])).transpose()
    for j in range(d):
        for i in range(d):
            if W[i,j] < W0[i,j]:
                W[i,j] = math.floor(W[i,j])
                W0[i,j] = math.ceil(W0[i,j])
            else:
                W[i,j] = math.ceil(W[i,j])
                W0[i,j] = math.floor(W0[i,j])
    M = [[int(V[i,j]) for i in range(V.shape[0])] for j in range(V.shape[1])]
    M += [[int(W0[i,j]) for j in range(W0.shape[0])] for i in range(W0.shape[0])]
    M += [[int(W[i,j]) for j in range(W.shape[1])] for i in range(W.shape[0])]

    from sage.matrix.constructor import matrix
    M = (matrix(IntegerRing(),len(M),len(M[0]), M).transpose()).columns()

    i = 0
    while i < len(M):
        j = i+1
        while j < len(M):
            if M[i] == M[j]:
                M.pop(j)
            else:
                j += 1
        i += 1

    from sage.geometry.lattice_polytope import LatticePolytope
    P = LatticePolytope(matrix(M).transpose())
    S = []

    try:
        pts = P.points().transpose()
    except ValueError:
        return []

    for p in pts:
        theta = sum([ p.list()[i]*B[i] for i in range(d)])
        inbounds = True
        for i in range(d):
            inbounds = inbounds and Foo[i](theta) >= C[i][0] and Foo[i](theta) <= C[i][1]

        if inbounds:
            S.append(theta)

    return S
Beispiel #4
0
def integral_elements_in_box(K, C):
    r"""
    Return all integral elements of the totally real field `K` whose
    embeddings lie *numerically* within the bounds specified by the
    list `C`.  The output is architecture dependent, and one may want
    to expand the bounds that define C by some epsilon.

    INPUT:

    - `K` -- a totally real number field
    - `C` -- a list [[lower, upper], ...] of lower and upper bounds,
      for each embedding


    EXAMPLES::

        sage: x = polygen(QQ)
        sage: K.<alpha> = NumberField(x^2-2)
        sage: eps = 10e-6
        sage: C = [[0-eps,5+eps],[0-eps,10+eps]]
        sage: ls = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C)
        sage: sorted([ a.trace() for a in ls ])
        [0, 2, 4, 4, 4, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 10, 12, 12, 14]
        sage: len(ls)
        19

        sage: v = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C)
        sage: sorted(v)
         [0, -alpha + 2, 1, -alpha + 3, 2, 3, alpha + 2, 4, alpha + 3, 5, alpha + 4, 2*alpha + 3, alpha + 5, 2*alpha + 4, alpha + 6, 2*alpha + 5, 2*alpha + 6, 3*alpha + 5, 2*alpha + 7]

    A cubic field::

        sage: x = polygen(QQ)
        sage: K.<a> = NumberField(x^3 - 16*x +16)
        sage: eps = 10e-6
        sage: C = [[0-eps,5+eps]]*3
        sage: v = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C)

    Note that the output is platform dependent (sometimes a 5 is listed
    below, and sometimes it isn't)::

        sage: sorted(v)
        [-1/2*a + 2, 1/4*a^2 + 1/2*a, 0, 1, 2, 3, 4,...-1/4*a^2 - 1/2*a + 5, 1/2*a + 3, -1/4*a^2 + 5]
    """
    d = K.degree()
    Z_F = K.maximal_order()
    Foo = K.real_embeddings()
    B = K.reduced_basis()

    import numpy
    import numpy.linalg
    L = numpy.array([ [v(b) for b in B] for v in Foo])
    Linv = numpy.linalg.inv(L)
    Vi = [[C[0][0]],[C[0][1]]]
    for i in range(1,d):
        Vi = sum([ [v + [C[i][0]], v + [C[i][1]]] for v in Vi], [])
    V = numpy.matrix(Linv)*(numpy.matrix(Vi).transpose())
    j = 0
    while j < 2**d:
        for i in range(d):
            if V[i,j] < V[i,j+1]:
                V[i,j] = math.floor(V[i,j])
                V[i,j+1] = math.ceil(V[i,j+1])
            else:
                V[i,j] = math.ceil(V[i,j])
                V[i,j+1] = math.floor(V[i,j+1])
        j += 2
    W0 = (Linv*numpy.array([Vi[0]]*d)).transpose()
    W = (Linv*numpy.array([Vi[2**i] for i in range(d)])).transpose()
    for j in range(d):
        for i in range(d):
            if W[i,j] < W0[i,j]:
                W[i,j] = math.floor(W[i,j])
                W0[i,j] = math.ceil(W0[i,j])
            else:
                W[i,j] = math.ceil(W[i,j])
                W0[i,j] = math.floor(W0[i,j])
    M = [[int(V[i,j]) for i in range(V.shape[0])] for j in range(V.shape[1])]
    M += [[int(W0[i,j]) for j in range(W0.shape[0])] for i in range(W0.shape[0])]
    M += [[int(W[i,j]) for j in range(W.shape[1])] for i in range(W.shape[0])]

    from sage.matrix.constructor import matrix
    M = (matrix(IntegerRing(),len(M),len(M[0]), M).transpose()).columns()

    i = 0
    while i < len(M):
        j = i+1
        while j < len(M):
            if M[i] == M[j]:
                M.pop(j)
            else:
                j += 1
        i += 1

    from sage.geometry.lattice_polytope import LatticePolytope
    P = LatticePolytope(M)
    S = []

    try:
        pts = P.points()
    except ValueError:
        return []

    for p in pts:
        theta = sum([ p.list()[i]*B[i] for i in range(d)])
        inbounds = True
        for i in range(d):
            inbounds = inbounds and Foo[i](theta) >= C[i][0] and Foo[i](theta) <= C[i][1]

        if inbounds:
            S.append(theta)

    return S
Beispiel #5
0
    def lattice_polytope(self, envelope=False):
        r"""
        Return an encompassing lattice polytope.

        INPUT:

        - ``envelope`` -- boolean (default: ``False``). If the
          polyhedron has non-integral vertices, this option decides
          whether to return a strictly larger lattice polytope or
          raise a ``ValueError``. This option has no effect if the
          polyhedron has already integral vertices.

        OUTPUT:

        A :class:`LatticePolytope
        <sage.geometry.lattice_polytope.LatticePolytopeClass>`. If the
        polyhedron is compact and has integral vertices, the lattice
        polytope equals the polyhedron. If the polyhedron is compact
        but has at least one non-integral vertex, a strictly larger
        lattice polytope is returned.

        If the polyhedron is not compact, a ``NotImplementedError`` is
        raised.

        If the polyhedron is not integral and ``envelope=False``, a
        ``ValueError`` is raised.

        ALGORITHM:

        For each non-integral vertex, a bounding box of integral
        points is added and the convex hull of these integral points
        is returned.

        EXAMPLES:

        First, a polyhedron with integral vertices::

            sage: P = Polyhedron( vertices = [(1, 0), (0, 1), (-1, 0), (0, -1)])
            sage: lp = P.lattice_polytope(); lp
            2-d reflexive polytope #3 in 2-d lattice M
            sage: lp.vertices()
            M(-1,  0),
            M( 0, -1),
            M( 0,  1),
            M( 1,  0)
            in 2-d lattice M

        Here is a polyhedron with non-integral vertices::

            sage: P = Polyhedron( vertices = [(1/2, 1/2), (0, 1), (-1, 0), (0, -1)])
            sage: lp = P.lattice_polytope()
            Traceback (most recent call last):
            ...
            ValueError: Some vertices are not integral. You probably want
            to add the argument "envelope=True" to compute an enveloping
            lattice polytope.
            sage: lp = P.lattice_polytope(True); lp
            2-d reflexive polytope #5 in 2-d lattice M
            sage: lp.vertices()
            M(-1,  0),
            M( 0, -1),
            M( 1,  1),
            M( 0,  1),
            M( 1,  0)
            in 2-d lattice M
        """
        if not self.is_compact():
            raise NotImplementedError('only compact lattice polytopes are allowed')

        try:
            vertices = self.vertices_matrix(ZZ).columns()
        except TypeError:
            if not envelope:
                raise ValueError('Some vertices are not integral. '
                    'You probably want to add the argument '
                    '"envelope=True" to compute an enveloping lattice polytope.')
            from sage.arith.misc import integer_ceil as ceil
            from sage.arith.misc import integer_floor as floor
            vertices = []
            for v in self.vertex_generator():
                vbox = [ set([floor(x), ceil(x)]) for x in v ]
                vertices.extend( itertools.product(*vbox) )

        # construct the (enveloping) lattice polytope
        from sage.geometry.lattice_polytope import LatticePolytope
        return LatticePolytope(vertices)